LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
spi_17xx_40xx.c
Go to the documentation of this file.
1 /*
2  * @brief LPC17xx/40xx 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_LPC175X_6X)
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 SPI_ExecuteCallback(LPC_SPI_T *pSPI, CHIP_SPI_CALLBACK_T pfunc)
50 {
51  if (pfunc) {
52  (pfunc) ();
53  }
54 }
55 
56 /* Write byte(s) to FIFO buffer */
57 STATIC void SPI_WriteData(LPC_SPI_T *pSPI, CHIP_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  IP_SPI_SendFrame(pSPI, data2write);
69 
70 }
71 
72 /* Read byte(s) from FIFO buffer */
73 STATIC void SPI_ReadData(LPC_SPI_T *pSPI, CHIP_SPI_DATA_SETUP_T *pXfSetup, uint16_t rDat, uint32_t num_bytes)
74 {
75  rDat = IP_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 */
90 {
92  uint16_t rDat = 0x0000;
93  uint8_t bytes = 1;
94 
95  /* Clear status */
97 
98  if (IP_SPI_GetDataSize(pSPI) != SPI_BITS_8) {
99  bytes = 2;
100  }
101 
102  SPI_ExecuteCallback(pSPI, pXfSetup->fnBefTransfer);
103 
104  while (pXfSetup->cnt < pXfSetup->length) {
105  SPI_ExecuteCallback(pSPI, pXfSetup->fnBefFrame);
106 
107  /* write data to buffer */
108  SPI_WriteData(pSPI, pXfSetup, bytes);
109 
110  /* Wait for transfer completes */
111  while (1) {
112  status = IP_SPI_GetStatus(pSPI);
113  /* Check error */
114  if (status & SPI_SR_ERROR) {
115  goto rw_end;
116  }
117  if (status & SPI_SR_SPIF) {
118  break;
119  }
120  }
121 
122  SPI_ExecuteCallback(pSPI, pXfSetup->fnAftFrame);
123 
124  /* Read data*/
125  SPI_ReadData(pSPI, pXfSetup, rDat, bytes);
126  pXfSetup->cnt += bytes;
127  }
128 
129 rw_end:
130  SPI_ExecuteCallback(pSPI, pXfSetup->fnAftTransfer);
131  return pXfSetup->cnt;
132 }
133 
134 /* Clean all data in RX FIFO of SPI */
136 {
137  volatile uint32_t tmp;
138  IP_SPI_GetStatus(pSPI);
139  tmp = IP_SPI_ReceiveFrame(pSPI);
141 }
142 
143 /* SPI Interrupt Read/Write with 8-bit frame width */
144 Status Chip_SPI_Int_RWFrames(LPC_SPI_T *pSPI, CHIP_SPI_DATA_SETUP_T *pXfSetup, uint8_t bytes)
145 {
147  uint16_t rDat = 0x0000;
148 
149  status = IP_SPI_GetStatus(pSPI);
150  /* Check error status */
151  if (status & SPI_SR_ERROR) {
152  return ERROR;
153  }
154 
156  if (status & SPI_SR_SPIF) {
157  SPI_ExecuteCallback(pSPI, pXfSetup->fnAftFrame);
158  if (pXfSetup->cnt < pXfSetup->length) {
159  /* read data */
160  SPI_ReadData(pSPI, pXfSetup, rDat, bytes);
161  pXfSetup->cnt += bytes;
162  }
163  }
164 
165  if (pXfSetup->cnt < pXfSetup->length) {
166  SPI_ExecuteCallback(pSPI, pXfSetup->fnBefFrame);
167 
168  /* Write data */
169  SPI_WriteData(pSPI, pXfSetup, bytes);
170  }
171  else {
172  SPI_ExecuteCallback(pSPI, pXfSetup->fnAftTransfer);
173  }
174  return SUCCESS;
175 }
176 
177 /* SPI Interrupt Read/Write with 8-bit frame width */
179 {
180  return Chip_SPI_Int_RWFrames(pSPI, pXfSetup, 1);
181 }
182 
183 /* SPI Interrupt Read/Write with 16-bit frame width */
185 {
186  return Chip_SPI_Int_RWFrames(pSPI, pXfSetup, 2);
187 }
188 
189 /* Set the clock frequency for SPI interface */
190 void Chip_SPI_SetBitRate(LPC_SPI_T *pSPI, uint32_t bitRate)
191 {
192  uint32_t spiClk, counter;
193  /* Get SPI clock rate */
194  spiClk = Chip_Clock_GetPeripheralClockRate(SYSCTL_PCLK_SPI);
195 
196  counter = spiClk / bitRate;
197  if (counter < 8) {
198  counter = 8;
199  }
200  counter = ((counter + 1) / 2) * 2;
201 
202  if (counter > 254) {
203  counter = 254;
204  }
205 
206  IP_SPI_SetClockCounter(pSPI, counter);
207 }
208 
209 /* Initialize the SPI */
210 void Chip_SPI_Init(LPC_SPI_T *pSPI)
211 {
212  /* Enable SPI clocking. SPI base clock(s) must already be enabled */
213  Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SPI);
214 
217  Chip_SPI_SetBitRate(pSPI, 400000);
218 }
219 
220 /* De-initializes the SPI peripheral */
221 void Chip_SPI_DeInit(LPC_SPI_T *pSPI)
222 {
223  /* Disable SPI clocking */
224  Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SPI);
225 }
226 
227 #endif /*defined(CHIP_LPC175X_6X) */