LPCOpen Platform for LPC18XX/43XX microcontrollers  18XX43XX
LPCOpen Platform for the NXP LPC18XX/43XX family of Microcontrollers
spi_18xx_43xx.c
Go to the documentation of this file.
1 /*
2  * @brief LPC43xx SPI driver
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include "chip.h"
33 
34 #if defined(CHIP_LPC43XX)
35 
36 /*****************************************************************************
37  * Private types/enumerations/variables
38  ****************************************************************************/
39 
40 /*****************************************************************************
41  * Public types/enumerations/variables
42  ****************************************************************************/
43 
44 /*****************************************************************************
45  * Private functions
46  ****************************************************************************/
47 
48 /* Execute callback function */
49 STATIC void executeCallback(LPC_SPI_T *pSPI, SPI_CALLBACK_T pfunc)
50 {
51  if (pfunc) {
52  (pfunc) ();
53  }
54 }
55 
56 /* Write byte(s) to FIFO buffer */
57 STATIC void writeData(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup, uint32_t num_bytes)
58 {
59  uint16_t data2write = 0xFFFF;
60 
61  if ( pXfSetup->pTxData) {
62  data2write = pXfSetup->pTxData[pXfSetup->cnt];
63  if (num_bytes == 2) {
64  data2write |= pXfSetup->pTxData[pXfSetup->cnt + 1] << 8;
65  }
66  }
67 
68  Chip_SPI_SendFrame(pSPI, data2write);
69 
70 }
71 
72 /* Read byte(s) from FIFO buffer */
73 STATIC void readData(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup, uint16_t rDat, uint32_t num_bytes)
74 {
75  rDat = Chip_SPI_ReceiveFrame(pSPI);
76  if (pXfSetup->pRxData) {
77  pXfSetup->pRxData[pXfSetup->cnt] = rDat;
78  if (num_bytes == 2) {
79  pXfSetup->pRxData[pXfSetup->cnt + 1] = rDat >> 8;
80  }
81  }
82 }
83 
84 /*****************************************************************************
85  * Public functions
86  ****************************************************************************/
87 
88 /* SPI Polling Read/Write in blocking mode */
89 uint32_t Chip_SPI_RWFrames_Blocking(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup)
90 {
91  uint32_t status;
92  uint16_t rDat = 0x0000;
93  uint8_t bytes = 1;
94 
95  /* Clear status */
96  Chip_SPI_Int_FlushData(pSPI);
97 
98  if (Chip_SPI_GetDataSize(pSPI) != SPI_BITS_8) {
99  bytes = 2;
100  }
101 
102  executeCallback(pSPI, pXfSetup->fnBefTransfer);
103 
104  while (pXfSetup->cnt < pXfSetup->length) {
105 
106  executeCallback(pSPI, pXfSetup->fnBefFrame);
107 
108  /* write data to buffer */
109  writeData(pSPI, pXfSetup, bytes);
110 
111  /* Wait for transfer completes */
112  while (1) {
113  status = Chip_SPI_GetStatus(pSPI);
114  /* Check error */
115  if (status & SPI_SR_ERROR) {
116  goto rw_end;
117  }
118  if (status & SPI_SR_SPIF) {
119  break;
120  }
121  }
122 
123  executeCallback(pSPI, pXfSetup->fnAftFrame);
124 
125  /* Read data*/
126  readData(pSPI, pXfSetup, rDat, bytes);
127  pXfSetup->cnt += bytes;
128  }
129 
130 rw_end:
131  executeCallback(pSPI, pXfSetup->fnAftTransfer);
132  return pXfSetup->cnt;
133 }
134 
135 /* Clean all data in RX FIFO of SPI */
136 void Chip_SPI_Int_FlushData(LPC_SPI_T *pSPI)
137 {
138  volatile uint32_t tmp;
139  Chip_SPI_GetStatus(pSPI);
140  tmp = Chip_SPI_ReceiveFrame(pSPI);
141  Chip_SPI_Int_ClearStatus(pSPI, SPI_INT_SPIF);
142 }
143 
144 /* SPI Interrupt Read/Write with 8-bit frame width */
145 Status Chip_SPI_Int_RWFrames(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup, uint8_t bytes)
146 {
147  uint32_t status;
148  uint16_t rDat = 0x0000;
149 
150  status = Chip_SPI_GetStatus(pSPI);
151  /* Check error status */
152  if (status & SPI_SR_ERROR) {
153  return ERROR;
154  }
155 
156  Chip_SPI_Int_ClearStatus(pSPI, SPI_INT_SPIF);
157  if (status & SPI_SR_SPIF) {
158  executeCallback(pSPI, pXfSetup->fnAftFrame);
159  if (pXfSetup->cnt < pXfSetup->length) {
160  /* read data */
161  readData(pSPI, pXfSetup, rDat, bytes);
162  pXfSetup->cnt += bytes;
163  }
164  }
165 
166  if (pXfSetup->cnt < pXfSetup->length) {
167 
168  executeCallback(pSPI, pXfSetup->fnBefFrame);
169 
170  /* Write data */
171  writeData(pSPI, pXfSetup, bytes);
172  }
173  else {
174  executeCallback(pSPI, pXfSetup->fnAftTransfer);
175  }
176  return SUCCESS;
177 }
178 
179 /* SPI Interrupt Read/Write with 8-bit frame width */
180 Status Chip_SPI_Int_RWFrames8Bits(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup)
181 {
182  return Chip_SPI_Int_RWFrames(pSPI, pXfSetup, 1);
183 }
184 
185 /* SPI Interrupt Read/Write with 16-bit frame width */
186 Status Chip_SPI_Int_RWFrames16Bits(LPC_SPI_T *pSPI, SPI_DATA_SETUP_T *pXfSetup)
187 {
188  return Chip_SPI_Int_RWFrames(pSPI, pXfSetup, 2);
189 }
190 
191 /* Set the clock frequency for SPI interface */
192 void Chip_SPI_SetBitRate(LPC_SPI_T *pSPI, uint32_t bitRate)
193 {
194  uint32_t spiClk, counter;
195  /* Get SPI clock rate */
196  spiClk = Chip_Clock_GetRate(CLK_SPI);
197 
198  counter = spiClk / bitRate;
199  if (counter < 8) {
200  counter = 8;
201  }
202  counter = ((counter + 1) / 2) * 2;
203 
204  if (counter > 254) {
205  counter = 254;
206  }
207 
208  Chip_SPI_SetClockCounter(pSPI, counter);
209 }
210 
211 /* Initialize the SPI */
212 void Chip_SPI_Init(LPC_SPI_T *pSPI)
213 {
214  Chip_Clock_Enable(CLK_SPI);
215 
216  Chip_SPI_SetMode(pSPI, SPI_MODE_MASTER);
217  pSPI->CR = (pSPI->CR & (~0xF1C)) | SPI_CR_BIT_EN | SPI_BITS_8 | SPI_CLOCK_CPHA0_CPOL0 | SPI_DATA_MSB_FIRST;
218  Chip_SPI_SetBitRate(pSPI, 400000);
219 }
220 
221 /* De-initializes the SPI peripheral */
222 void Chip_SPI_DeInit(LPC_SPI_T *pSPI)
223 {
224  Chip_Clock_Disable(CLK_SPI);
225 }
226 
227 #endif