NANO100_BSP V3.04.002
The Board Support Package for Nano100BN Series
NuEdu-Basic01_SPI_Flash_w_PDMA.c
Go to the documentation of this file.
1/**************************************************************************/
12#include <stdio.h>
13#include "Nano100Series.h"
15
29/*---------------------------------------------------------------------------------------------------------*/
30/* Definitons */
31/*---------------------------------------------------------------------------------------------------------*/
32#define SPI_FLASH_PORT SPI0
33
34#define TEST_NUMBER 1 /* page numbers */
35#define TEST_LENGTH 256 /* length */
36#define CH1 1
37#define CH2 2
38
39#define MODE_PER2MEM 1
40#define MODE_MEM2PER 2
41
42/*---------------------------------------------------------------------------------------------------------*/
43/* Global variables */
44/*---------------------------------------------------------------------------------------------------------*/
45volatile uint32_t PDMA_CH1_INT_Flag;
46volatile uint32_t PDMA_CH2_INT_Flag;
48
56{
57 uint32_t status = PDMAGCR->GCRISR;
58
59 /* CH1 */
60 if(status & 0x2)
61 {
62 if(PDMA_GET_CH_INT_STS(1) & 0x2)
63 {
64 PDMA_CH1_INT_Flag = 1;
66 }
67 /* CH2 */
68 }
69 else if(status & 0x4)
70 {
71 if(PDMA_GET_CH_INT_STS(2) & 0x2)
72 {
73 PDMA_CH2_INT_Flag = 1;
75 }
76 }
77
78}
79
88void Open_SPI_Flash(void)
89{
90
91 /* Init GPIO for SPI Flash Port, set PE1, PE2, PE3 and PE4 for SPI0 */
94
95 /* Enable SPI0 IP clock */
96 CLK->APBCLK |= CLK_APBCLK_SPI0_EN_Msk;
97
98 /* Configure SPI_FLASH_PORT as a master, MSB first, clock idle low, TX at falling-edge, RX at rising-edge and 32-bit transaction */
100
101 /* Disable the automatic hardware slave select function. Select the SS pin and configure as low-active. */
102 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk);
103
104 /* Set SPI clock rate = HCLK / (20+1) = 42MHz / 21 = 2MHz */
105 SPI_FLASH_PORT->CLKDIV = (SPI_FLASH_PORT->CLKDIV & ~SPI_CLKDIV_DIVIDER1_Msk) | (0x14 << SPI_CLKDIV_DIVIDER1_Pos);
106
107}
108
117void Init_PDMA_CH1_for_SPI0_TX(uint32_t u32SrcAddr)
118{
119 uint32_t SPI0_TX;
120 PDMA_T *PDMA_CH1;
121
122 // PDMA Channel 1 control registers
123 PDMA_CH1 = (PDMA_T *)((uint32_t) PDMA1_BASE + (0x100 * (CH1-1)));
124
125 // SPI0 TX0 register
126 SPI0_TX = SPI0_BASE + 0x20;
127
128 // Enable DMA IP clock
129 CLK->AHBCLK |= CLK_AHBCLK_DMA_EN_Msk;
130
131 // Enable Channel 1 clock
132 PDMAGCR->GCRCSR |= (CH1 << 9);
133
134 // Set Channel 1 for SPI0_TX
135 PDMAGCR->DSSR0 = (PDMAGCR->DSSR0 & ~DMA_GCR_DSSR0_CH1_SEL_Msk) | (PDMA_SPI0_TX << DMA_GCR_DSSR0_CH1_SEL_Pos);
136
137 // Set Transfer Byte Count
138 PDMA_CH1->BCR = TEST_LENGTH;
139
140 // Set Source Address
141 PDMA_CH1->SAR = u32SrcAddr;
142
143 // Set Destination Address
144 PDMA_CH1->DAR = SPI0_TX;
145
146 // Set Transfer Width = 8 bits, Source Direction = INC, Destination Direction = FIX and Mode = Memory to Peripheral
149
150 // Enable Transfer Block Done Interrupt
151 PDMA_CH1->IER = (PDMA_CH1->IER & ~(PDMA_IER_TABORT_IE_Msk | PDMA_IER_TD_IE_Msk)) | PDMA_IER_TD_IE_Msk;
152
153}
154
163void Init_PDMA_CH2_for_SPI0_RX(uint32_t u32DstAddr)
164{
165 uint32_t SPI0_RX;
166 PDMA_T *PDMA_CH2;
167
168 // PDMA Channel 1 control registers
169 PDMA_CH2 = (PDMA_T *)((uint32_t) PDMA1_BASE + (0x100 * (CH2-1)));
170
171 // SPI0 TX0 register
172 SPI0_RX = SPI0_BASE + 0x10;
173
174 // Enable DMA IP clock
175 CLK->AHBCLK |= CLK_AHBCLK_DMA_EN_Msk;
176
177 // Enable Channel 2 clock
178 PDMAGCR->GCRCSR |= (CH2 << 9);
179
180 // Set Channel 2 for SPI0_RX
181 PDMAGCR->DSSR0 = (PDMAGCR->DSSR0 & ~DMA_GCR_DSSR0_CH2_SEL_Msk) | (PDMA_SPI0_RX << DMA_GCR_DSSR0_CH2_SEL_Pos);
182
183 // Set Transfer Byte Count
184 PDMA_CH2->BCR = TEST_LENGTH;
185
186 // Set Source Address
187 PDMA_CH2->SAR = SPI0_RX;
188
189 // Set Destination Address
190 PDMA_CH2->DAR = u32DstAddr;
191
192 // Set Transfer Width = 8 bits, Source Direction = FIX, Destination Direction = INC and Mode = Peripheral to Memory
195
196 // Enable Transfer Block Done Interrupt
197 PDMA_CH2->IER = (PDMA_CH2->IER & ~(PDMA_IER_TABORT_IE_Msk | PDMA_IER_TD_IE_Msk)) | PDMA_IER_TD_IE_Msk;
198
199}
200
209{
210 unsigned int au32SourceData;
211 unsigned int au32DestinationData;
212
213 // configure transaction length as 8 bits
214 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x08 << SPI_CTL_TX_BIT_LEN_Pos);
215
216 // /CS: active
217 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk) | 0x1;
218
219 // send Command: 0x90, Read Manufacturer/Device ID
220 au32SourceData = 0x90;
221 SPI_FLASH_PORT->TX0 = au32SourceData;
222 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
223
224 // wait
225 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
226
227 // configure transaction length as 24 bits
228 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x18 << SPI_CTL_TX_BIT_LEN_Pos);
229
230 // send 24-bit '0', dummy
231 au32SourceData = 0x0;
232 SPI_FLASH_PORT->TX0 = au32SourceData;
233 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
234
235 // wait
236 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
237
238 // configure transaction length as 16 bits
239 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x10 << SPI_CTL_TX_BIT_LEN_Pos);
240
241 // receive
242 au32SourceData = 0x0;
243 SPI_FLASH_PORT->TX0 = au32SourceData;
244 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
245
246 // wait
247 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
248
249 // /CS: de-active
250 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk);
251
252 // dump Rx register
253 au32DestinationData = SPI_FLASH_PORT->RX0;
254
255 return (au32DestinationData & 0xffff);
256
257}
258
265{
266 unsigned int au32SourceData;
267
268 // configure transaction length as 8 bits
269 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x08 << SPI_CTL_TX_BIT_LEN_Pos);
270
271 // /CS: active
272 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk) | 0x1;
273
274 // send Command: 0x06, Write enable
275 au32SourceData = 0x06;
276 SPI_FLASH_PORT->TX0 = au32SourceData;
277 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
278
279 // wait
280 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
281
282 // /CS: de-active
283 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk);
284
285 // /CS: active
286 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk) | 0x1;
287
288 // send Command: 0xC7, Chip Erase
289 au32SourceData = 0xc7;
290 SPI_FLASH_PORT->TX0 = au32SourceData;
291 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
292
293 // wait
294 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
295
296 // /CS: de-active
297 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk);
298
299}
300
307{
308 unsigned int au32SourceData;
309 unsigned int au32DestinationData;
310
311 // configure transaction length as 16 bits
312 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x10 << SPI_CTL_TX_BIT_LEN_Pos);
313
314 // /CS: active
315 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk) | 0x1;
316
317 // send Command: 0x05, Read status register 1
318 au32SourceData = 0x0500;
319 SPI_FLASH_PORT->TX0 = au32SourceData;
320 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
321
322 // wait
323 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
324
325 // /CS: de-active
326 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk);
327
328 // dump Rx register
329 au32DestinationData = SPI_FLASH_PORT->RX0;
330
331 return (au32DestinationData & 0xFF);
332
333}
334
341{
342 unsigned int au32SourceData;
343 unsigned int au32DestinationData;
344
345 // configure transaction length as 16 bits
346 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x10 << SPI_CTL_TX_BIT_LEN_Pos);
347
348 // /CS: active
349 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk) | 0x1;
350
351 // send Command: 0x35, Read status register 2
352 au32SourceData = 0x3500;
353 SPI_FLASH_PORT->TX0 = au32SourceData;
354 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
355
356 // wait
357 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
358
359 // /CS: de-active
360 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk);
361
362 // dump Rx register
363 au32DestinationData = SPI_FLASH_PORT->RX0;
364
365 return (au32DestinationData & 0xFF);
366
367}
368
375{
376 unsigned int ReturnValue;
377
378 do
379 {
380 ReturnValue = SpiFlash_w_PDMA_ReadStatusReg1();
381 ReturnValue = ReturnValue & 1;
382 }
383 while(ReturnValue!=0); // check the BUSY bit
384
385}
386
396void SpiFlash_w_PDMA_PageProgram(unsigned int StartAddress, unsigned int ByteCount)
397{
398 unsigned int au32SourceData;
399
400 // configure transaction length as 8 bits
401 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x08 << SPI_CTL_TX_BIT_LEN_Pos);
402
403 // /CS: active
404 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk) | 0x1;
405
406 // send Command: 0x06, Write enable
407 au32SourceData = 0x06;
408 SPI_FLASH_PORT->TX0 = au32SourceData;
409 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
410
411 // wait
412 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
413
414 // /CS: de-active
415 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk);
416
417 // /CS: active
418 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk) | 0x1;
419
420 // send Command: 0x02, Page program
421 au32SourceData = 0x02;
422 SPI_FLASH_PORT->TX0 = au32SourceData;
423 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
424
425 // wait
426 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
427
428 // configure transaction length as 24 bits
429 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x18 << SPI_CTL_TX_BIT_LEN_Pos);
430
431 // send 24-bit start address
432 au32SourceData = StartAddress;
433 SPI_FLASH_PORT->TX0 = au32SourceData;
434 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
435
436 // wait
437 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
438
439 // configure transaction length as 8 bits
440 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x08 << SPI_CTL_TX_BIT_LEN_Pos);
441
442 // enable SPI PDMA
443 SPI_FLASH_PORT->DMA = (SPI_FLASH_PORT->DMA & ~(SPI_DMA_RX_DMA_EN_Msk | SPI_DMA_TX_DMA_EN_Msk)) | SPI_DMA_TX_DMA_EN_Msk;
444
445 // SPI go
446 PDMA_CH1_INT_Flag = 0;
447 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
448
449 // wait PDMA done
450 while (1)
451 {
452 if (PDMA_CH1_INT_Flag)
453 {
454 PDMA_CH1_INT_Flag = 0;
455 break;
456 }
457 }
458
459 // /CS: de-active
460 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk);
461
462}
463
473void SpiFlash_w_PDMA_ReadData(unsigned int StartAddress, unsigned int ByteCount)
474{
475 unsigned int au32SourceData;
476
477 // configure transaction length as 8 bits
478 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x08 << SPI_CTL_TX_BIT_LEN_Pos);
479
480 // /CS: active
481 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk) | 0x1;
482
483 // send Command: 0x03, Read data
484 au32SourceData = 0x03;
485 SPI_FLASH_PORT->TX0 = au32SourceData;
486 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
487
488 // wait
489 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
490
491 // configure transaction length as 24 bits
492 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x18 << SPI_CTL_TX_BIT_LEN_Pos);
493
494 // send 24-bit start address
495 au32SourceData = StartAddress;
496 SPI_FLASH_PORT->TX0 = au32SourceData;
497 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
498
499 // wait
500 while (SPI_FLASH_PORT->CTL & SPI_CTL_GO_BUSY_Msk) {}
501
502 // configure transaction length as 8 bits
503 SPI_FLASH_PORT->CTL = (SPI_FLASH_PORT->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (0x08 << SPI_CTL_TX_BIT_LEN_Pos);
504
505 // enable SPI PDMA
506 SPI_FLASH_PORT->DMA = (SPI_FLASH_PORT->DMA & ~(SPI_DMA_RX_DMA_EN_Msk | SPI_DMA_TX_DMA_EN_Msk)) | SPI_DMA_RX_DMA_EN_Msk;
507
508 // SPI go
509 PDMA_CH2_INT_Flag = 0;
510 SPI_FLASH_PORT->CTL |= SPI_CTL_GO_BUSY_Msk;
511
512 // wait PDMA done
513 while (1)
514 {
515 if (PDMA_CH2_INT_Flag)
516 {
517 PDMA_CH2_INT_Flag = 0;
518 break;
519 }
520 }
521
522 // /CS: de-active
523 SPI_FLASH_PORT->SSR = (SPI_FLASH_PORT->SSR & ~SPI_SSR_SSR_Msk);
524
525}
526
527 /* end of group Nano130_Basic01_FUNCTIONS */
529 /* end of group NuEdu-SDK-Nano130_Basic01 */
531 /* end of group NANO100_Library */
533
534/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
535
Nano100 series peripheral access layer header file. This file contains all the peripheral register's ...
#define PDMA_CSR_MODE_SEL_Msk
#define DMA_GCR_DSSR0_CH1_SEL_Pos
#define SPI_CTL_LSB_Msk
#define SPI_CTL_RX_NEG_Msk
#define SPI_DMA_TX_DMA_EN_Msk
#define SPI_CTL_GO_BUSY_Msk
#define SPI_CTL_CLKP_Msk
#define PDMA_CSR_APB_TWS_Msk
#define PDMA_CSR_MODE_SEL_Pos
#define SPI_CTL_TX_BIT_LEN_Msk
#define PDMA_IER_TD_IE_Msk
#define SPI_CTL_TX_NEG_Msk
#define SPI_CTL_SLAVE_Msk
#define PDMA_CSR_SAD_SEL_Msk
#define PDMA_CSR_DAD_SEL_Msk
#define SPI_CTL_TX_BIT_LEN_Pos
#define SPI_DMA_RX_DMA_EN_Msk
#define DMA_GCR_DSSR0_CH2_SEL_Pos
#define PDMA_ISR_TD_IS_Msk
#define SPI_CLKDIV_DIVIDER1_Pos
#define PDMA_IER_TABORT_IE_Msk
NuEdu-Basic01 SPI Flash with PDMA driver header file for NuEdu-SDK-Nano130.
#define CLK_APBCLK_SPI0_EN_Msk
#define CLK_AHBCLK_DMA_EN_Msk
#define PDMA_SAR_INC
Definition: pdma.h:43
#define PDMA_DAR_FIX
Definition: pdma.h:47
#define PDMA_SAR_FIX
Definition: pdma.h:44
#define PDMA_SPI0_TX
Definition: pdma.h:53
#define PDMA_SPI0_RX
Definition: pdma.h:67
#define PDMA_WIDTH_8
Definition: pdma.h:36
#define PDMA_DAR_INC
Definition: pdma.h:46
#define PDMA_GET_CH_INT_STS(u32Ch)
Get PDMA Channel Interrupt Status.
Definition: pdma.h:111
#define PDMA_CLR_CH_INT_FLAG(u32Ch, u32Mask)
Clear PDMA Channel Interrupt Flag.
Definition: pdma.h:124
#define CLK
Pointer to CLK register structure.
#define SYS
Pointer to SYS register structure.
#define PDMAGCR
Pointer to PDMA global control register structure.
#define PDMA1_BASE
PDMA1 register base address.
#define SPI0_BASE
SPI0 register base address.
#define SYS_PE_L_MFP_PE1_MFP_SPI0_SS0
Definition: sys.h:508
#define SYS_PE_L_MFP_PE3_MFP_SPI0_MISO0
Definition: sys.h:501
#define SYS_PE_L_MFP_PE4_MFP_SPI0_MOSI0
Definition: sys.h:498
#define SYS_PE_L_MFP_PE2_MFP_SPI0_SCLK
Definition: sys.h:504
__IO uint32_t IER
__IO uint32_t CSR
__IO uint32_t SAR
__IO uint32_t DAR
__IO uint32_t BCR
unsigned int SpiFlash_w_PDMA_ReadStatusReg2(void)
Read back the Status Register 2 from SPI Flash device.
void SpiFlash_w_PDMA_WaitReady(void)
Waiting for the BUSY bit of SPI Flash that be cleared to 0.
unsigned int SpiFlash_w_PDMA_ReadMidDid(void)
Read back the Manufacturer ID and Device ID from SPI Flash device.
void SpiFlash_w_PDMA_ChipErase(void)
This function do the chip erasing to SPI Flash device.
void PDMA_IRQHandler(void)
PDMA interrupt handler. Check the PDMA interrupt flag and clear the corresponding event flag.
void SpiFlash_w_PDMA_PageProgram(unsigned int StartAddress, unsigned int ByteCount)
This function do the page programming to SPI Flash device.
void Open_SPI_Flash(void)
Open GPIO port for SPI interface and configure this SPI controller as Master, MSB first,...
void Init_PDMA_CH1_for_SPI0_TX(uint32_t u32SrcAddr)
This function initializes the PDMA channel 1 for SPI0 transmitting TX and the data that will be trans...
unsigned int SpiFlash_w_PDMA_ReadStatusReg1(void)
Read back the Status Register 1 from SPI Flash device.
void Init_PDMA_CH2_for_SPI0_RX(uint32_t u32DstAddr)
This function initializes the PDMA channel 2 for SPI0 receiving RX and the receiving data will be sto...
void SpiFlash_w_PDMA_ReadData(unsigned int StartAddress, unsigned int ByteCount)
This function do the data reading from SPI Flash device.