uc-sdk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lpc17xx_spi.c
Go to the documentation of this file.
1 /***********************************************************************/
20 /* Peripheral group ----------------------------------------------------------- */
25 /* Includes ------------------------------------------------------------------- */
26 #include "lpc17xx_spi.h"
27 #include "lpc17xx_clkpwr.h"
28 
29 /* If this source file built with example, the LPC17xx FW library configuration
30  * file in each example directory ("lpc17xx_libcfg.h") must be included,
31  * otherwise the default FW library configuration file must be included instead
32  */
33 #ifdef __BUILD_WITH_EXAMPLE__
34 #include "lpc17xx_libcfg.h"
35 #else
36 #include "lpc17xx_libcfg_default.h"
37 #endif /* __BUILD_WITH_EXAMPLE__ */
38 
39 #ifdef _SPI
40 
41 
42 /* Public Functions ----------------------------------------------------------- */
47 /*********************************************************************/
53 void SPI_SetClock (LPC_SPI_TypeDef *SPIx, uint32_t target_clock)
54 {
55  uint32_t spi_pclk;
56  uint32_t prescale, temp;
57 
58  CHECK_PARAM(PARAM_SPIx(SPIx));
59 
60  if (SPIx == LPC_SPI){
62  } else {
63  return;
64  }
65 
66  prescale = 8;
67  // Find closest clock to target clock
68  while (1){
69  temp = target_clock * prescale;
70  if (temp >= spi_pclk){
71  break;
72  }
73  prescale += 2;
74  if(prescale >= 254){
75  break;
76  }
77  }
78 
79  // Write to register
80  SPIx->SPCCR = SPI_SPCCR_COUNTER(prescale);
81 }
82 
83 
84 /*********************************************************************/
90 void SPI_DeInit(LPC_SPI_TypeDef *SPIx)
91 {
92  CHECK_PARAM(PARAM_SPIx(SPIx));
93 
94  if (SPIx == LPC_SPI){
95  /* Set up clock and power for SPI module */
97  }
98 }
99 
100 /*********************************************************************/
105 uint8_t SPI_GetDataSize (LPC_SPI_TypeDef *SPIx)
106 {
107  CHECK_PARAM(PARAM_SPIx(SPIx));
108  return ((SPIx->SPCR)>>8 & 0xF);
109 }
110 
111 /********************************************************************/
120 void SPI_Init(LPC_SPI_TypeDef *SPIx, SPI_CFG_Type *SPI_ConfigStruct)
121 {
122  uint32_t tmp;
123 
124  CHECK_PARAM(PARAM_SPIx(SPIx));
125 
126  if(SPIx == LPC_SPI){
127  /* Set up clock and power for UART module */
129  } else {
130  return;
131  }
132 
133  // Configure SPI, interrupt is disable as default
134  tmp = ((SPI_ConfigStruct->CPHA) | (SPI_ConfigStruct->CPOL) \
135  | (SPI_ConfigStruct->DataOrder) | (SPI_ConfigStruct->Databit) \
136  | (SPI_ConfigStruct->Mode) | SPI_SPCR_BIT_EN) & SPI_SPCR_BITMASK;
137  // write back to SPI control register
138  SPIx->SPCR = tmp;
139 
140  // Set clock rate for SPI peripheral
141  SPI_SetClock(SPIx, SPI_ConfigStruct->ClockRate);
142 
143  // If interrupt flag is set, Write '1' to Clear interrupt flag
144  if (SPIx->SPINT & SPI_SPINT_INTFLAG){
145  SPIx->SPINT = SPI_SPINT_INTFLAG;
146  }
147 }
148 
149 
150 
151 /*****************************************************************************/
163 void SPI_ConfigStructInit(SPI_CFG_Type *SPI_InitStruct)
164 {
165  SPI_InitStruct->CPHA = SPI_CPHA_FIRST;
166  SPI_InitStruct->CPOL = SPI_CPOL_HI;
167  SPI_InitStruct->ClockRate = 1000000;
168  SPI_InitStruct->DataOrder = SPI_DATA_MSB_FIRST;
169  SPI_InitStruct->Databit = SPI_DATABIT_8;
170  SPI_InitStruct->Mode = SPI_MASTER_MODE;
171 }
172 
173 /*********************************************************************/
180 void SPI_SendData(LPC_SPI_TypeDef* SPIx, uint16_t Data)
181 {
182  CHECK_PARAM(PARAM_SPIx(SPIx));
183 
184  SPIx->SPDR = Data & SPI_SPDR_BITMASK;
185 }
186 
187 
188 
189 /*********************************************************************/
194 uint16_t SPI_ReceiveData(LPC_SPI_TypeDef* SPIx)
195 {
196  CHECK_PARAM(PARAM_SPIx(SPIx));
197 
198  return ((uint16_t) (SPIx->SPDR & SPI_SPDR_BITMASK));
199 }
200 
201 /*********************************************************************/
215 int32_t SPI_ReadWrite (LPC_SPI_TypeDef *SPIx, SPI_DATA_SETUP_Type *dataCfg, \
216  SPI_TRANSFER_Type xfType)
217 {
218  uint8_t *rdata8 = NULL;
219  uint8_t *wdata8 = NULL;
220  uint16_t *rdata16 = NULL;
221  uint16_t *wdata16 = NULL;
222  uint32_t stat = 0;
223  uint32_t temp;
224  uint8_t dataword;
225 
226  //read for empty buffer
227  temp = SPIx->SPDR;
228  //dummy to clear status
229  temp = SPIx->SPSR;
230  dataCfg->counter = 0;
231  dataCfg->status = 0;
232 
233  if(SPI_GetDataSize (SPIx) == 8)
234  dataword = 0;
235  else dataword = 1;
236  if (xfType == SPI_TRANSFER_POLLING){
237 
238  if (dataword == 0){
239  rdata8 = (uint8_t *)dataCfg->rx_data;
240  wdata8 = (uint8_t *)dataCfg->tx_data;
241  } else {
242  rdata16 = (uint16_t *)dataCfg->rx_data;
243  wdata16 = (uint16_t *)dataCfg->tx_data;
244  }
245 
246  while(dataCfg->counter < dataCfg->length)
247  {
248  // Write data to buffer
249  if(dataCfg->tx_data == NULL){
250  if (dataword == 0){
251  SPI_SendData(SPIx, 0xFF);
252  } else {
253  SPI_SendData(SPIx, 0xFFFF);
254  }
255  } else {
256  if (dataword == 0){
257  SPI_SendData(SPIx, *wdata8);
258  wdata8++;
259  } else {
260  SPI_SendData(SPIx, *wdata16);
261  wdata16++;
262  }
263  }
264  // Wait for transfer complete
265  while (!((stat = SPIx->SPSR) & SPI_SPSR_SPIF));
266  // Check for error
268  // save status
269  dataCfg->status = stat | SPI_STAT_ERROR;
270  return (dataCfg->counter);
271  }
272  // Read data from SPI dat
273  temp = (uint32_t) SPI_ReceiveData(SPIx);
274 
275  // Store data to destination
276  if (dataCfg->rx_data != NULL)
277  {
278  if (dataword == 0){
279  *(rdata8) = (uint8_t) temp;
280  rdata8++;
281  } else {
282  *(rdata16) = (uint16_t) temp;
283  rdata16++;
284  }
285  }
286  // Increase counter
287  if (dataword == 0){
288  dataCfg->counter++;
289  } else {
290  dataCfg->counter += 2;
291  }
292  }
293 
294  // Return length of actual data transferred
295  // save status
296  dataCfg->status = stat | SPI_STAT_DONE;
297  return (dataCfg->counter);
298  }
299  // Interrupt mode
300  else {
301 
302  // Check if interrupt flag is already set
303  if(SPIx->SPINT & SPI_SPINT_INTFLAG){
304  SPIx->SPINT = SPI_SPINT_INTFLAG;
305  }
306  if (dataCfg->counter < dataCfg->length){
307  // Write data to buffer
308  if(dataCfg->tx_data == NULL){
309  if (dataword == 0){
310  SPI_SendData(SPIx, 0xFF);
311  } else {
312  SPI_SendData(SPIx, 0xFFFF);
313  }
314  } else {
315  if (dataword == 0){
316  SPI_SendData(SPIx, (*(uint8_t *)dataCfg->tx_data));
317  } else {
318  SPI_SendData(SPIx, (*(uint16_t *)dataCfg->tx_data));
319  }
320  }
321  SPI_IntCmd(SPIx, ENABLE);
322  } else {
323  // Save status
324  dataCfg->status = SPI_STAT_DONE;
325  }
326  return (0);
327  }
328 }
329 
330 
331 /********************************************************************/
340 void SPI_IntCmd(LPC_SPI_TypeDef *SPIx, FunctionalState NewState)
341 {
342  CHECK_PARAM(PARAM_SPIx(SPIx));
344 
345  if (NewState == ENABLE)
346  {
347  SPIx->SPCR |= SPI_SPCR_SPIE;
348  }
349  else
350  {
351  SPIx->SPCR &= (~SPI_SPCR_SPIE) & SPI_SPCR_BITMASK;
352  }
353 }
354 
355 
356 /********************************************************************/
362 {
363  CHECK_PARAM(PARAM_SPIx(SPIx));
364 
365  return ((SPIx->SPINT & SPI_SPINT_INTFLAG) ? SET : RESET);
366 }
367 
368 /********************************************************************/
374 {
375  CHECK_PARAM(PARAM_SPIx(SPIx));
376 
377  SPIx->SPINT = SPI_SPINT_INTFLAG;
378 }
379 
380 /********************************************************************/
392 uint32_t SPI_GetStatus(LPC_SPI_TypeDef* SPIx)
393 {
394  CHECK_PARAM(PARAM_SPIx(SPIx));
395 
396  return (SPIx->SPSR & SPI_SPSR_BITMASK);
397 }
398 
399 /********************************************************************/
413 FlagStatus SPI_CheckStatus (uint32_t inputSPIStatus, uint8_t SPIStatus)
414 {
415  CHECK_PARAM(PARAM_SPI_STAT(SPIStatus));
416 
417  return ((inputSPIStatus & SPIStatus) ? SET : RESET);
418 }
419 
420 
425 #endif /* _SPI */
426 
431 /* --------------------------------- End Of File ------------------------------ */