LPCOpen Platform for LPC18XX/43XX microcontrollers: C:/w/lpcopen_docs/software/lpc_core/lpc_chip/chip_18xx_43xx/spi_18xx_43xx.c Source File

| LPCOpen Platform for LPC18XX/43XX microcontrollers 18XX43XX LPCOpen Platform for the NXP LPC18XX/43XX family of Microcontrollers

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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