| 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.c
Go to the documentation of this file.
1 /*
2 * @brief SPI example
3 * This example show how to use the SPI in 2 modes : Polling and Interrupt.
4 *
5 * @note
6 * Copyright(C) NXP Semiconductors, 2012
7 * All rights reserved.
8 *
9 * @par
10 * Software that is described herein is for illustrative purposes only
11 * which provides customers with programming information regarding the
12 * LPC products. This software is supplied "AS IS" without any warranties of
13 * any kind, and NXP Semiconductors and its licensor disclaim any and
14 * all warranties, express or implied, including all implied warranties of
15 * merchantability, fitness for a particular purpose and non-infringement of
16 * intellectual property rights. NXP Semiconductors assumes no responsibility
17 * or liability for the use of the software, conveys no license or rights under any
18 * patent, copyright, mask work right, or any other intellectual property rights in
19 * or to any products. NXP Semiconductors reserves the right to make changes
20 * in the software without notification. NXP Semiconductors also makes no
21 * representation or warranty that such application will be suitable for the
22 * specified use without further testing or modification.
23 *
24 * @par
25 * Permission to use, copy, modify, and distribute this software and its
26 * documentation is hereby granted, under NXP Semiconductors' and its
27 * licensor's relevant copyrights in the software, without fee, provided that it
28 * is used in conjunction with NXP Semiconductors microcontrollers. This
29 * copyright, permission, and disclaimer notice must appear in all copies of
30 * this code.
31 */
32
33 #include "board.h"
34 #include "stdio.h"
35
86 /*****************************************************************************
87 * Private types/enumerations/variables
88 ****************************************************************************/
89 #define BUFFER_SIZE (0x100)
90
91 #define SPI_MASTER_MODE_SEL (0x31)
92 #define SPI_SLAVE_MODE_SEL (0x32)
93 #define SPI_MODE_SEL (SPI_MASTER_MODE_SEL)
94
95 #define SPI_POLLING_SEL (0x31)
96 #define SPI_INTERRUPT_SEL (0x32)
97 #if (SPI_MODE_SEL == SPI_SLAVE_MODE_SEL)
98 #define SPI_TRANSFER_MODE_SEL (SPI_INTERRUPT_SEL)
99 #else
100 #define SPI_TRANSFER_MODE_SEL (SPI_POLLING_SEL)
101 #endif
102
103 #define LPC_SSP LPC_SSP1
104 #define LPC_GPDMA_SSP_TX GPDMA_CONN_SSP1_Tx
105 #define LPC_GPDMA_SSP_RX GPDMA_CONN_SSP1_Rx
106
107 static uint8_t spi_tx_buf[BUFFER_SIZE];
108 static uint8_t spi_rx_buf[BUFFER_SIZE];
109 static CHIP_SPI_CONFIG_FORMAT_T spi_format;
110 static CHIP_SPI_DATA_SETUP_T spi_xf;
111 static volatile uint8_t spi_xfer_completed = 0;
112
113 static uint8_t ssp_tx_buf[BUFFER_SIZE];
114 static uint8_t ssp_rx_buf[BUFFER_SIZE];
115 static SSP_ConfigFormat ssp_format;
116 static uint8_t ssp_dma_tx_ch, ssp_dma_rx_ch;
117 static volatile uint8_t ssp_dma_txf_completed = 0;
118 static volatile uint8_t ssp_dma_rxf_completed = 0;
119
120 /*****************************************************************************
121 * Public types/enumerations/variables
122 ****************************************************************************/
123
124 /*****************************************************************************
125 * Private functions
126 ****************************************************************************/
127
128 /* Initialize buffer */
129 static void bufferInit(uint8_t *tx_buf, uint8_t *rx_buf)
130 {
131 uint16_t i;
132 uint8_t ch = 0;
133
134 for (i = 0; i < BUFFER_SIZE; i++) {
135 tx_buf[i] = ch++;
136 rx_buf[i] = 0xAA;
137 }
138 }
139
140 /* Verify buffer after transfer */
141 static uint8_t bufferVerify(uint8_t *tx_buf, uint8_t *rx_buf)
142 {
143 uint16_t i;
144 for ( i = 0; i < BUFFER_SIZE; i++ ) {
145 if (tx_buf[i] != rx_buf[i]) {
146 return 1;
147 }
148 }
149 return 0;
150 }
151
156 void DMA_IRQHandler(void)
157 {
158 if (Chip_DMA_Interrupt(LPC_GPDMA, ssp_dma_tx_ch) == SUCCESS) {
159 ssp_dma_txf_completed = 1;
160 }
161
162 if (Chip_DMA_Interrupt(LPC_GPDMA, ssp_dma_rx_ch) == SUCCESS) {
163 ssp_dma_rxf_completed = 1;
164 }
165 }
166
167 static void appSSPRun(void)
168 {
169 bufferInit(ssp_tx_buf, ssp_rx_buf);
170 ssp_dma_tx_ch = Chip_DMA_GetFreeChannel(LPC_GPDMA, LPC_GPDMA_SSP_TX);
171 ssp_dma_rx_ch = Chip_DMA_GetFreeChannel(LPC_GPDMA, LPC_GPDMA_SSP_RX);
172 ssp_dma_txf_completed = ssp_dma_rxf_completed = 0;
173 Chip_SSP_DMA_Enable(LPC_SSP);
174 /* data Tx_Buf --> SSP */
175 Chip_DMA_Transfer(LPC_GPDMA, ssp_dma_tx_ch,
176 (uint32_t) &ssp_tx_buf[0],
177 LPC_GPDMA_SSP_TX,
178 GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA,
179 BUFFER_SIZE);
180 /* data SSP --> Rx_Buf */
181 Chip_DMA_Transfer(LPC_GPDMA, ssp_dma_rx_ch,
182 LPC_GPDMA_SSP_RX,
183 (uint32_t) &ssp_rx_buf[0],
184 GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA,
185 BUFFER_SIZE);
186 }
187
188 /* Select the Transfer mode : Polling or Interrupt */
189 static void appSPIRun(void)
190 {
191 spi_xf.cnt = 0;
192 spi_xf.length = BUFFER_SIZE;
193 spi_xf.pTxData = spi_tx_buf;
194 spi_xf.pRxData = spi_rx_buf;
195 bufferInit(spi_tx_buf, spi_rx_buf);
196
197 #if (SPI_TRANSFER_MODE_SEL == SPI_POLLING_SEL)
198 Chip_SPI_RWFrames_Blocking(LPC_SPI, &spi_xf);
199 #else
200 spi_xfer_completed = 0;
201
202 Chip_SPI_Int_FlushData(LPC_SPI); /* flush dummy data from SPI FiFO */
203 Chip_SPI_Int_RWFrames8Bits(LPC_SPI, &spi_xf);
204 Chip_SPI_Int_Enable(LPC_SPI); /* enable interrupt */
205 #endif
206 }
207
208 /*****************************************************************************
209 * Public functions
210 ****************************************************************************/
211 #if (SPI_TRANSFER_MODE_SEL == SPI_INTERRUPT_SEL)
212
216 void SPI_IRQHandler(void)
217 {
218 Chip_SPI_Int_Disable(LPC_SPI); /* Disable all interrupt */
219 Chip_SPI_Int_RWFrames8Bits(LPC_SPI, &spi_xf);
220
221 if (spi_xf.cnt < spi_xf.length) {
222 Chip_SPI_Int_Enable(LPC_SPI); /* enable all interrupts */
223 }
224 else {
225 spi_xfer_completed = 1;
226 }
227 }
228
229 #endif /*(SPI_TRANSFER_MODE_SEL == SPI_INTERRUPT_SEL)*/
230
235 int main(void)
236 {
237 Board_Init();
238
239 #if (SPI_MODE_SEL == SPI_MASTER_MODE_SEL)
240 Board_SPI_Init(true);
241 #else
242 Board_SPI_Init(false);
243 #endif
244 Board_SSP_Init(LPC_SSP);
245
246 /* SPI initialization */
247 Chip_SPI_Init(LPC_SPI);
248 spi_format.bits = SPI_BITS_8;
249 spi_format.clockMode = SPI_CLOCK_MODE0;
250 spi_format.dataOrder = SPI_DATA_MSB_FIRST;
251 Chip_SPI_SetFormat(LPC_SPI, &spi_format);
252
253 /* SSP initialization */
254 Chip_SSP_Init(LPC_SSP);
255 ssp_format.frameFormat = SSP_FRAMEFORMAT_SPI;
256 ssp_format.bits = SSP_BITS_8;
257 ssp_format.clockMode = SSP_CLOCK_MODE0;
258 Chip_SSP_SetFormat(LPC_SSP, &ssp_format);
259 Chip_SSP_Enable(LPC_SSP);
260
261 /* Initialize GPDMA controller */
262 Chip_GPDMA_Init(LPC_GPDMA);
263
264 #if (SPI_MODE_SEL == SPI_MASTER_MODE_SEL)
265 spi_xf.fnBefFrame = Board_SPI_AssertSSEL;
266 spi_xf.fnAftFrame = Board_SPI_DeassertSSEL;
267 spi_xf.fnBefTransfer = NULL;
268 spi_xf.fnAftTransfer = NULL;
269 Chip_SPI_SetMode(LPC_SPI, SPI_MODE_MASTER);
270 Chip_SSP_SetMaster(LPC_SSP, 0);
271 #else
272 spi_xf.fnBefFrame = NULL;
273 spi_xf.fnAftFrame = NULL;
274 spi_xf.fnBefTransfer = NULL;
275 spi_xf.fnAftTransfer = NULL;
276 Chip_SPI_SetMode(LPC_SPI, SPI_MODE_SLAVE);
277 Chip_SSP_SetMaster(LPC_SSP, 1);
278 #endif
279
280 #if (SPI_TRANSFER_MODE_SEL == SPI_INTERRUPT_SEL)
281 /* Setting SPI interrupt */
282 NVIC_EnableIRQ(SPI_IRQn);
283 #endif
284 NVIC_EnableIRQ(DMA_IRQn);
285
286 #if (SPI_MODE_SEL == SPI_MASTER_MODE_SEL)
287 appSSPRun();
288 appSPIRun();
289 #else
290 appSPIRun();
291 appSSPRun();
292 while (!spi_xfer_completed) {}
293 #endif
294 while (!ssp_dma_txf_completed || !ssp_dma_rxf_completed) {}
295 Chip_SSP_DMA_Disable(LPC_SSP);
296
297 if ((bufferVerify(spi_tx_buf, ssp_rx_buf) == 0) &&
298 (bufferVerify(ssp_tx_buf, spi_rx_buf) == 0)) {
299 Board_LED_Set(0, false);
300 }
301 else {
302 Board_LED_Set(0, true);
303 }
304
305 /* DeInitialize SPI peripheral */
306 Chip_SPI_DeInit(LPC_SPI);
307
308 /* DeInitialize SSP peripheral */
309 Chip_SSP_DeInit(LPC_SSP);
310
311 while (1) {}
312 return 0;
313 }
314