| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

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 */
89 uint32_t Chip_SPI_RWFrames_Blocking(LPC_SPI_T *pSPI, CHIP_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 (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 */
135 void Chip_SPI_Int_FlushData(LPC_SPI_T *pSPI)
136 {
137 volatile uint32_t tmp;
138 IP_SPI_GetStatus(pSPI);
139 tmp = IP_SPI_ReceiveFrame(pSPI);
140 IP_SPI_ClearIntStatus(pSPI, SPI_INT_SPIF);
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 {
146 uint32_t status;
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
155 IP_SPI_ClearIntStatus(pSPI, SPI_INT_SPIF);
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 */
178 Status Chip_SPI_Int_RWFrames8Bits(LPC_SPI_T *pSPI, CHIP_SPI_DATA_SETUP_T *pXfSetup)
179 {
180 return Chip_SPI_Int_RWFrames(pSPI, pXfSetup, 1);
181 }
182
183 /* SPI Interrupt Read/Write with 16-bit frame width */
184 Status Chip_SPI_Int_RWFrames16Bits(LPC_SPI_T *pSPI, CHIP_SPI_DATA_SETUP_T *pXfSetup)
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
215 IP_SPI_SetMode(pSPI, SPI_MODE_MASTER);
216 IP_SPI_SetFormat(pSPI, SPI_BITS_8, SPI_CLOCK_CPHA0_CPOL0, SPI_DATA_MSB_FIRST);
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) */