Nano103 BSP  V3.01.002
The Board Support Package for Nano103 Series
spi.c
Go to the documentation of this file.
1 /****************************************************************************/
13 #include "Nano103.h"
14 
47 uint32_t SPI_Open(SPI_T *spi,
48  uint32_t u32MasterSlave,
49  uint32_t u32SPIMode,
50  uint32_t u32DataWidth,
51  uint32_t u32BusClock)
52 {
53  if(u32DataWidth == 32)
54  u32DataWidth = 0;
55 
56  spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode);
57 
58  return ( SPI_SetBusClock(spi, u32BusClock) );
59 }
60 
66 void SPI_Close(SPI_T *spi)
67 {
68  /* Reset SPI */
69  if((uint32_t)spi == SPI0_BASE && (CLK->APBCLK & CLK_APBCLK_SPI0CKEN_Msk))
70  {
71  CLK->APBCLK &= ~CLK_APBCLK_SPI0CKEN_Msk;
72  SYS->IPRST2 |= SYS_IPRST2_SPI0RST_Msk;
73  SYS->IPRST2 &= ~SYS_IPRST2_SPI0RST_Msk;
74  CLK->APBCLK |= CLK_APBCLK_SPI0CKEN_Msk;
75  }
76  else if((uint32_t)spi == SPI1_BASE && (CLK->APBCLK & CLK_APBCLK_SPI1CKEN_Msk))
77  {
78  CLK->APBCLK &= ~CLK_APBCLK_SPI1CKEN_Msk;
79  SYS->IPRST2 |= SYS_IPRST2_SPI1RST_Msk;
80  SYS->IPRST2 &= ~SYS_IPRST2_SPI1RST_Msk;
81  CLK->APBCLK |= CLK_APBCLK_SPI1CKEN_Msk;
82  }
83  else if((uint32_t)spi == SPI2_BASE && (CLK->APBCLK & CLK_APBCLK_SPI2CKEN_Msk))
84  {
85  CLK->APBCLK &= ~CLK_APBCLK_SPI2CKEN_Msk;
86  SYS->IPRST2 |= SYS_IPRST2_SPI2RST_Msk;
87  SYS->IPRST2 &= ~SYS_IPRST2_SPI2RST_Msk;
88  CLK->APBCLK |= CLK_APBCLK_SPI2CKEN_Msk;
89  }
90  else if((uint32_t)spi == SPI3_BASE && (CLK->APBCLK & CLK_APBCLK_SPI3CKEN_Msk))
91  {
92  CLK->APBCLK &= ~CLK_APBCLK_SPI3CKEN_Msk;
93  SYS->IPRST2 |= SYS_IPRST2_SPI3RST_Msk;
94  SYS->IPRST2 &= ~SYS_IPRST2_SPI3RST_Msk;
95  CLK->APBCLK |= CLK_APBCLK_SPI3CKEN_Msk;
96  }
97 }
98 
105 {
107 }
108 
115 {
117 }
118 
125 {
126  spi->SSCTL &= ~SPI_SSCTL_AUTOSS_Msk;
127 }
128 
140 void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
141 {
142  spi->SSCTL = (spi->SSCTL & ~(SPI_SSCTL_SSACTPOL_Msk | SPI_SSCTL_SS_Msk)) | (u32SSPinMask | u32ActiveLevel) | SPI_SSCTL_AUTOSS_Msk;
143 }
144 
151 uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock)
152 {
153  uint32_t u32ClkSrc, u32Div = 0;
154 
155  if(spi == SPI0)
156  {
158  u32ClkSrc = CLK_GetHCLKFreq();
159  else if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI0SEL_Msk) == CLK_CLKSEL1_SPI0SEL_PLL)
160  u32ClkSrc = CLK_GetPLLClockFreq();
161  else if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI0SEL_Msk) == CLK_CLKSEL1_SPI0SEL_HXT)
162  u32ClkSrc = __HXT;
163  else //CLK_CLKSEL1_SPI0SEL_HIRC
164  {
166  u32ClkSrc = __HIRC36M;
167  else
168  {
170  u32ClkSrc = __HIRC16M;
171  else
172  u32ClkSrc = __HIRC12M;
173  }
174  }
175  }
176  else if(spi == SPI1)
177  {
179  u32ClkSrc = CLK_GetHCLKFreq();
180  else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL)
181  u32ClkSrc = CLK_GetPLLClockFreq();
182  else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT)
183  u32ClkSrc = __HXT;
184  else //CLK_CLKSEL2_SPI1SEL_HIRC
185  {
187  u32ClkSrc = __HIRC36M;
188  else
189  {
191  u32ClkSrc = __HIRC16M;
192  else
193  u32ClkSrc = __HIRC12M;
194  }
195  }
196  }
197  else if(spi == SPI2)
198  {
200  u32ClkSrc = CLK_GetHCLKFreq();
201  else if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI2SEL_Msk) == CLK_CLKSEL1_SPI2SEL_PLL)
202  u32ClkSrc = CLK_GetPLLClockFreq();
203  else if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI2SEL_Msk) == CLK_CLKSEL1_SPI2SEL_HXT)
204  u32ClkSrc = __HXT;
205  else //CLK_CLKSEL1_SPI2SEL_HIRC
206  {
208  u32ClkSrc = __HIRC36M;
209  else
210  {
212  u32ClkSrc = __HIRC16M;
213  else
214  u32ClkSrc = __HIRC12M;
215  }
216  }
217  }
218  else
219  {
221  u32ClkSrc = CLK_GetHCLKFreq();
222  else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_PLL)
223  u32ClkSrc = CLK_GetPLLClockFreq();
224  else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI3SEL_Msk) == CLK_CLKSEL2_SPI3SEL_HXT)
225  u32ClkSrc = __HXT;
226  else //CLK_CLKSEL2_SPI3SEL_HIRC
227  {
229  u32ClkSrc = __HIRC36M;
230  else
231  {
233  u32ClkSrc = __HIRC16M;
234  else
235  u32ClkSrc = __HIRC12M;
236  }
237  }
238  }
239  if(u32BusClock > u32ClkSrc)
240  u32BusClock = u32ClkSrc;
241 
242  if(u32BusClock != 0 )
243  {
244  u32Div = (u32ClkSrc / u32BusClock) - 1;
245  if(u32Div > SPI_CLKDIV_DIVIDER_Msk)
246  u32Div = SPI_CLKDIV_DIVIDER_Msk;
247  }
248  else
249  return 0;
250 
251  spi->CLKDIV = (spi->CLKDIV & ~SPI_CLKDIV_DIVIDER_Msk) | u32Div;
252 
253  return ( u32ClkSrc / (u32Div+1) );
254 }
255 
263 void SPI_EnableFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
264 {
266  (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) |
267  (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos));
268 
269  spi->CTL |= SPI_CTL_FIFOM_Msk;
270 }
271 
278 {
279  spi->CTL &= ~SPI_CTL_FIFOM_Msk;
280 }
281 
287 uint32_t SPI_GetBusClock(SPI_T *spi)
288 {
289  uint32_t u32Div;
290  uint32_t u32ClkSrc;
291 
292  if(spi == SPI0)
293  {
295  u32ClkSrc = CLK_GetHCLKFreq();
296  else
297  u32ClkSrc = CLK_GetPLLClockFreq();
298  }
299  if(spi == SPI1)
300  {
302  u32ClkSrc = CLK_GetHCLKFreq();
303  else
304  u32ClkSrc = CLK_GetPLLClockFreq();
305  }
306  if(spi == SPI2)
307  {
309  u32ClkSrc = CLK_GetHCLKFreq();
310  else
311  u32ClkSrc = CLK_GetPLLClockFreq();
312  }
313  else
314  {
316  u32ClkSrc = CLK_GetHCLKFreq();
317  else
318  u32ClkSrc = CLK_GetPLLClockFreq();
319  }
320 
321  u32Div = spi->CLKDIV & SPI_CLKDIV_DIVIDER_Msk;
322  return (u32ClkSrc / (u32Div + 1));
323 }
324 
339 void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask)
340 {
341  if((u32Mask & SPI_IE_MASK) == SPI_IE_MASK)
342  spi->CTL |= SPI_CTL_UNITIEN_Msk;
343 
344  if((u32Mask & SPI_SSTAIEN_MASK) == SPI_SSTAIEN_MASK)
346 
349 
352 
355 
358 }
359 
374 void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask)
375 {
376  if((u32Mask & SPI_IE_MASK) == SPI_IE_MASK)
377  spi->CTL &= ~SPI_CTL_UNITIEN_Msk;
378 
379  if((u32Mask & SPI_SSTAIEN_MASK) == SPI_SSTAIEN_MASK)
380  spi->SSCTL &= ~SPI_SSCTL_SSTAIEN_Msk;
381 
384 
387 
390 
393 }
394 
401 {
402  spi->CTL |= SPI_CTL_WKCLKEN_Msk;
403 }
404 
411 {
412  spi->CTL &= ~SPI_CTL_WKCLKEN_Msk;
413 }
414  /* end of group NANO103_SPI_EXPORTED_FUNCTIONS */
416  /* end of group NANO103_SPI_Driver */
418  /* end of group NANO103_Device_Driver */
420 
421 /*** (C) COPYRIGHT 2015 Nuvoton Technology Corp. ***/
#define SPI_SSCTL_SS_Msk
Definition: Nano103.h:23519
#define CLK_CLKSEL2_SPI1SEL_HCLK
Definition: clk.h:227
void SPI_EnableWakeup(SPI_T *spi)
Enable wake-up function.
Definition: spi.c:400
#define __HXT
#define SPI_CLKDIV_DIVIDER_Msk
Definition: Nano103.h:23516
#define SPI_FIFO_RXTHIEN_MASK
Definition: spi.h:53
#define CLK_APBCLK_SPI0CKEN_Msk
Definition: Nano103.h:5014
#define SPI_CTL_WKCLKEN_Msk
Definition: Nano103.h:23462
#define SPI_FIFOCTL_RXTH_Msk
Definition: Nano103.h:23588
__IO uint32_t SSCTL
Definition: Nano103.h:23396
void SPI_ClearRxFIFO(SPI_T *spi)
Clear Rx FIFO buffer.
Definition: spi.c:104
#define CLK_CLKSEL2_SPI1SEL_Msk
Definition: Nano103.h:5122
#define SYS_IPRST2_SPI0RST_Msk
Definition: Nano103.h:3305
uint32_t SPI_Open(SPI_T *spi, uint32_t u32MasterSlave, uint32_t u32SPIMode, uint32_t u32DataWidth, uint32_t u32BusClock)
This function make SPI module be ready to transfer. By default, the SPI transfer sequence is MSB firs...
Definition: spi.c:47
#define CLK_CLKSEL2_SPI1SEL_HXT
Definition: clk.h:224
#define CLK_CLKSEL1_SPI0SEL_Msk
Definition: Nano103.h:5092
#define CLK_APBCLK_SPI3CKEN_Msk
Definition: Nano103.h:5023
#define __HIRC16M
#define SPI_SSCTL_SSACTPOL_Msk
Definition: Nano103.h:23522
#define SPI_SSTAIEN_MASK
Definition: spi.h:51
void SPI_DisableFIFO(SPI_T *spi)
Disable FIFO mode.
Definition: spi.c:277
#define SPI_FIFO_RXOVIEN_MASK
Definition: spi.h:54
#define SYS_IPRST2_SPI3RST_Msk
Definition: Nano103.h:3314
#define CLK_CLKSEL1_SPI0SEL_PLL
Definition: clk.h:177
uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock)
Set the SPI bus clock. Only available in Master mode.
Definition: spi.c:151
#define SPI_FIFO_TXTHIEN_MASK
Definition: spi.h:52
__IO uint32_t FIFOCTL
Definition: Nano103.h:23408
#define SPI_FIFOCTL_TXTHIEN_Msk
Definition: Nano103.h:23579
void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
Enable the automatic slave select function. Only available in Master mode.
Definition: spi.c:140
#define CLK_CLKSEL2_SPI3SEL_HCLK
Definition: clk.h:231
#define SPI1_BASE
SPI1 register base address.
Definition: Nano103.h:24826
#define SYS_IPRST2_SPI2RST_Msk
Definition: Nano103.h:3311
#define CLK_CLKSEL2_SPI3SEL_Msk
Definition: Nano103.h:5125
#define CLK_CLKSEL1_SPI2SEL_HCLK
Definition: clk.h:183
#define CLK_APBCLK_SPI1CKEN_Msk
Definition: Nano103.h:5017
#define CLK_CLKSEL2_SPI3SEL_PLL
Definition: clk.h:229
void SPI_ClearTxFIFO(SPI_T *spi)
Clear Tx FIFO buffer.
Definition: spi.c:114
void SPI_DisableAutoSS(SPI_T *spi)
Disable the automatic slave select function.
Definition: spi.c:124
#define SPI_CTL_FIFOM_Msk
Definition: Nano103.h:23447
#define SPI_CTL_DWIDTH_Pos
Definition: Nano103.h:23425
void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask)
Enable FIFO related interrupts specified by u32Mask parameter.
Definition: spi.c:339
void SPI_DisableWakeup(SPI_T *spi)
Disable wake-up function.
Definition: spi.c:410
uint32_t CLK_GetPLLClockFreq(void)
This function get PLL frequency. The frequency unit is Hz.
Definition: clk.c:176
#define SPI_FIFOCTL_RXTH_Pos
Definition: Nano103.h:23587
#define SPI_IE_MASK
Definition: spi.h:50
#define CLK_CLKSEL1_SPI0SEL_HXT
Definition: clk.h:176
#define SPI_FIFOCTL_RXTHIEN_Msk
Definition: Nano103.h:23576
void SPI_EnableFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
Enable FIFO mode with user-specified Tx FIFO threshold and Rx FIFO threshold configurations.
Definition: spi.c:263
#define SPI_FIFOCTL_RXFBCLR_Msk
Definition: Nano103.h:23570
uint32_t CLK_GetHCLKFreq(void)
This function get HCLK frequency. The frequency unit is Hz.
Definition: clk.c:126
#define SPI3_BASE
SPI3 register base address.
Definition: Nano103.h:24827
#define SPI0_BASE
SPI0 register base address.
Definition: Nano103.h:24816
#define SPI_SSCTL_AUTOSS_Msk
Definition: Nano103.h:23525
#define SPI_FIFOCTL_TXFBCLR_Msk
Definition: Nano103.h:23573
#define CLK_CLKSEL1_SPI0SEL_HCLK
Definition: clk.h:179
#define CLK_PWRCTL_HIRC0EN_Msk
Definition: Nano103.h:4936
#define CLK_CLKSEL2_SPI3SEL_HXT
Definition: clk.h:228
NANO103 peripheral access layer header file. This file contains all the peripheral register's definit...
#define __HIRC36M
#define CLK_CLKSEL0_HIRCSEL_Msk
Definition: Nano103.h:5071
#define SPI2_BASE
SPI2 register base address.
Definition: Nano103.h:24817
__IO uint32_t CLKDIV
Definition: Nano103.h:23395
#define SYS_IPRST2_SPI1RST_Msk
Definition: Nano103.h:3308
#define SPI_FIFO_TIMEOUIEN_MASK
Definition: spi.h:55
#define SPI_FIFOCTL_TXTH_Msk
Definition: Nano103.h:23591
#define CLK_CLKSEL1_SPI2SEL_HXT
Definition: clk.h:180
#define SPI_FIFOCTL_RXOVIEN_Msk
Definition: Nano103.h:23582
#define SPI2
Pointer to SPI2 register structure.
Definition: Nano103.h:24872
uint32_t SPI_GetBusClock(SPI_T *spi)
Get the actual frequency of SPI bus clock. Only available in Master mode.
Definition: spi.c:287
void SPI_Close(SPI_T *spi)
Reset SPI module and disable SPI peripheral clock.
Definition: spi.c:66
#define SPI_SSCTL_SSTAIEN_Msk
Definition: Nano103.h:23540
#define __HIRC12M
#define CLK_CLKSEL1_SPI2SEL_PLL
Definition: clk.h:181
#define SPI_CTL_UNITIEN_Msk
Definition: Nano103.h:23438
#define SPI_FIFOCTL_RXTOIEN_Msk
Definition: Nano103.h:23585
#define CLK_APBCLK_SPI2CKEN_Msk
Definition: Nano103.h:5020
#define CLK_CLKSEL1_SPI2SEL_Msk
Definition: Nano103.h:5095
#define CLK
Pointer to CLK register structure.
Definition: Nano103.h:24884
#define SPI0
Pointer to SPI0 register structure.
Definition: Nano103.h:24870
#define SYS
Pointer to SYS register structure.
Definition: Nano103.h:24883
__IO uint32_t CTL
Definition: Nano103.h:23393
#define SPI1
Pointer to SPI1 register structure.
Definition: Nano103.h:24871
#define SPI_FIFOCTL_TXTH_Pos
Definition: Nano103.h:23590
void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask)
Disable FIFO related interrupts specified by u32Mask parameter.
Definition: spi.c:374
#define CLK_CLKSEL2_SPI1SEL_PLL
Definition: clk.h:225