Nano100BN Series BSP  V3.03.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 
28 /*---------------------------------------------------------------------------------------------------------*/
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 /*---------------------------------------------------------------------------------------------------------*/
45 volatile uint32_t PDMA_CH1_INT_Flag;
46 volatile uint32_t PDMA_CH2_INT_Flag;
48 
55 void PDMA_IRQHandler(void)
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 
88 void 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 
117 void 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
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 
163 void 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
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 
208 unsigned int SpiFlash_w_PDMA_ReadMidDid(void)
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 
396 void 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 
473 void 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 
__IO uint32_t DAR
#define PDMA_CSR_DAD_SEL_Msk
#define SPI_DMA_RX_DMA_EN_Msk
__IO uint32_t CSR
#define SPI_CTL_TX_BIT_LEN_Pos
#define DMA_GCR_DSSR0_CH2_SEL_Msk
unsigned int SpiFlash_w_PDMA_ReadStatusReg1(void)
Read back the Status Register 1 from SPI Flash device.
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...
#define SPI_DMA_TX_DMA_EN_Msk
#define SPI_CTL_SLAVE_Msk
#define PDMA_DAR_FIX
Definition: pdma.h:47
#define CLK
Pointer to CLK register structure.
#define PDMA_SPI0_RX
Definition: pdma.h:67
#define PDMA_IER_TABORT_IE_Msk
#define SPI_CTL_RX_NEG_Msk
#define SPI_CTL_TX_NEG_Msk
#define SPI_CTL_GO_BUSY_Msk
NuEdu-Basic01 SPI Flash with PDMA driver header file for NuEdu-SDK-Nano130.
Nano100 series peripheral access layer header file. This file contains all the peripheral register's ...
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...
#define PDMA_CSR_APB_TWS_Msk
#define PDMA_ISR_TD_IS_Msk
__IO uint32_t IER
#define PDMA_CSR_MODE_SEL_Pos
#define SYS_PE_L_MFP_PE4_MFP_SPI0_MOSI0
Definition: sys.h:498
void SpiFlash_w_PDMA_PageProgram(unsigned int StartAddress, unsigned int ByteCount)
This function do the page programming to SPI Flash device.
#define SPI_CLKDIV_DIVIDER1_Msk
#define PDMA_DAR_INC
Definition: pdma.h:46
void SpiFlash_w_PDMA_ReadData(unsigned int StartAddress, unsigned int ByteCount)
This function do the data reading from SPI Flash device.
#define CLK_AHBCLK_DMA_EN_Msk
#define SPI_CLKDIV_DIVIDER1_Pos
unsigned int SpiFlash_w_PDMA_ReadStatusReg2(void)
Read back the Status Register 2 from SPI Flash device.
unsigned int SpiFlash_w_PDMA_ReadMidDid(void)
Read back the Manufacturer ID and Device ID from SPI Flash device.
#define DMA_GCR_DSSR0_CH1_SEL_Pos
void SpiFlash_w_PDMA_ChipErase(void)
This function do the chip erasing to SPI Flash device.
void SpiFlash_w_PDMA_WaitReady(void)
Waiting for the BUSY bit of SPI Flash that be cleared to 0.
#define SPI_CTL_TX_BIT_LEN_Msk
__IO uint32_t BCR
#define SPI_CTL_LSB_Msk
#define DMA_GCR_DSSR0_CH2_SEL_Pos
#define PDMA_IER_TD_IE_Msk
#define PDMA_GET_CH_INT_STS(u32Ch)
Get PDMA Channel Interrupt Status.
Definition: pdma.h:111
#define PDMA_SAR_INC
Definition: pdma.h:43
#define PDMA_CSR_SAD_SEL_Msk
__IO uint32_t SAR
#define PDMA_CSR_MODE_SEL_Msk
#define PDMAGCR
Pointer to PDMA global control register structure.
#define PDMA_CLR_CH_INT_FLAG(u32Ch, u32Mask)
Clear PDMA Channel Interrupt Flag.
Definition: pdma.h:124
#define DMA_GCR_DSSR0_CH1_SEL_Msk
#define PDMA1_BASE
PDMA1 register base address.
#define SPI_SSR_SSR_Msk
void Open_SPI_Flash(void)
Open GPIO port for SPI interface and configure this SPI controller as Master, MSB first,...
void PDMA_IRQHandler(void)
PDMA interrupt handler. Check the PDMA interrupt flag and clear the corresponding event flag.
#define SYS_PE_L_MFP_PE1_MFP_SPI0_SS0
Definition: sys.h:508
#define PDMA_WIDTH_8
Definition: pdma.h:36
#define PDMA_SPI0_TX
Definition: pdma.h:53
#define SPI0_BASE
SPI0 register base address.
#define PDMA_SAR_FIX
Definition: pdma.h:44
#define CLK_APBCLK_SPI0_EN_Msk
#define SPI_CTL_CLKP_Msk
#define SYS_PE_L_MFP_PE3_MFP_SPI0_MISO0
Definition: sys.h:501
#define SYS_PE_L_MFP_PE2_MFP_SPI0_SCLK
Definition: sys.h:504
#define SYS
Pointer to SYS register structure.