| 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
ssp.c
Go to the documentation of this file.
1 /*
2 * @brief SSP example
3 * This example show how to use the SSP in 3 modes : Polling, Interrupt and DMA
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
113 /*****************************************************************************
114 * Private types/enumerations/variables
115 ****************************************************************************/
116
117 #define LPC_SSP LPC_SSP1
118 #define SSP_IRQ SSP1_IRQn
119 #define LPC_GPDMA_SSP_TX GPDMA_CONN_SSP1_Tx
120 #define LPC_GPDMA_SSP_RX GPDMA_CONN_SSP1_Rx
121 #define SSPIRQHANDLER SSP1_IRQHandler
122
123 #define BUFFER_SIZE (0x100)
124 #define SSP_DATA_BITS (SSP_BITS_8)
125 #define SSP_DATA_BIT_NUM(databits) (databits + 1)
126 #define SSP_DATA_BYTES(databits) (((databits) > SSP_BITS_8) ? 2 : 1)
127 #define SSP_LO_BYTE_MSK(databits) ((SSP_DATA_BYTES(databits) > 1) ? 0xFF : (0xFF >> \
128 (8 - SSP_DATA_BIT_NUM(databits))))
129 #define SSP_HI_BYTE_MSK(databits) ((SSP_DATA_BYTES(databits) > 1) ? (0xFF >> \
130 (16 - SSP_DATA_BIT_NUM(databits))) : 0)
131
132 #define SSP_MODE_SEL (0x31)
133 #define SSP_TRANSFER_MODE_SEL (0x32)
134 #define SSP_MASTER_MODE_SEL (0x31)
135 #define SSP_SLAVE_MODE_SEL (0x32)
136 #define SSP_POLLING_SEL (0x31)
137 #define SSP_INTERRUPT_SEL (0x32)
138 #define SSP_DMA_SEL (0x33)
139
140 /* Tx buffer */
141 static uint8_t Tx_Buf[BUFFER_SIZE];
142
143 /* Rx buffer */
144 static uint8_t Rx_Buf[BUFFER_SIZE];
145
146 static SSP_ConfigFormat ssp_format;
147 static Chip_SSP_DATA_SETUP_T xf_setup;
148 static volatile uint8_t isXferCompleted = 0;
149 static uint8_t dmaChSSPTx, dmaChSSPRx;
150 static volatile uint8_t isDmaTxfCompleted = 0;
151 static volatile uint8_t isDmaRxfCompleted = 0;
152
153 #if defined(DEBUG_ENABLE)
154 static char sspWaitingMenu[] = "SSP Polling: waiting for transfer ...\n\r";
155 static char sspIntWaitingMenu[] = "SSP Interrupt: waiting for transfer ...\n\r";
156 static char sspDMAWaitingMenu[] = "SSP DMA: waiting for transfer ...\n\r";
157
158 static char sspPassedMenu[] = "SSP: Transfer PASSED\n\r";
159 static char sspFailedMenu[] = "SSP: Transfer FAILED\n\r";
160
161 static char sspTransferModeSel[] = "\n\rPress 1-3 or 'q' to quit\n\r"
162 "\t 1: SSP Polling Read Write\n\r"
163 "\t 2: SSP Int Read Write\n\r"
164 "\t 3: SSP DMA Read Write\n\r";
165
166 static char helloMenu[] = "Hello NXP Semiconductors \n\r";
167 static char sspMenu[] = "SSP demo \n\r";
168 static char sspMainMenu[] = "\t 1: Select SSP Mode (Master/Slave)\n\r"
169 "\t 2: Select Transfer Mode\n\r";
170 static char sspSelectModeMenu[] = "\n\rPress 1-2 to select or 'q' to quit:\n\r"
171 "\t 1: Master \n\r"
172 "\t 2: Slave\n\r";
173 #endif /* defined(DEBUG_ENABLE) */
174
175 /*****************************************************************************
176 * Public types/enumerations/variables
177 ****************************************************************************/
178
179 /*****************************************************************************
180 * Private functions
181 ****************************************************************************/
182
183 /* Initialize buffer */
184 static void Buffer_Init(void)
185 {
186 uint16_t i;
187 uint8_t ch = 0;
188
189 for (i = 0; i < BUFFER_SIZE; i++) {
190 Tx_Buf[i] = ch++;
191 Rx_Buf[i] = 0xAA;
192 }
193 }
194
195 /* Verify buffer after transfer */
196 static uint8_t Buffer_Verify(void)
197 {
198 uint16_t i;
199 uint8_t *src_addr = (uint8_t *) &Tx_Buf[0];
200 uint8_t *dest_addr = (uint8_t *) &Rx_Buf[0];
201
202 for ( i = 0; i < BUFFER_SIZE; i++ ) {
203
204 if (((*src_addr) & SSP_LO_BYTE_MSK(ssp_format.bits)) !=
205 ((*dest_addr) & SSP_LO_BYTE_MSK(ssp_format.bits))) {
206 return 1;
207 }
208 src_addr++;
209 dest_addr++;
210
211 if (SSP_DATA_BYTES(ssp_format.bits) == 2) {
212 if (((*src_addr) & SSP_HI_BYTE_MSK(ssp_format.bits)) !=
213 ((*dest_addr) & SSP_HI_BYTE_MSK(ssp_format.bits))) {
214 return 1;
215 }
216 src_addr++;
217 dest_addr++;
218 i++;
219 }
220 }
221 return 0;
222 }
223
224 /* Select the Transfer mode : Polling, Interrupt or DMA */
225 static void appSSPTest(void)
226 {
227 int key;
228
229 DEBUGOUT(sspTransferModeSel);
230
231 dmaChSSPTx = Chip_DMA_GetFreeChannel(LPC_GPDMA, LPC_GPDMA_SSP_TX);
232 dmaChSSPRx = Chip_DMA_GetFreeChannel(LPC_GPDMA, LPC_GPDMA_SSP_RX);
233
234 xf_setup.length = BUFFER_SIZE;
235 xf_setup.tx_data = Tx_Buf;
236 xf_setup.rx_data = Rx_Buf;
237
238 while (1) {
239 key = 0xFF;
240 do {
241 key = DEBUGIN();
242 } while ((key & 0xFF) == 0xFF);
243
244 Buffer_Init();
245
246 switch (key) {
247 case SSP_POLLING_SEL: /* SSP Polling Read Write Mode */
248 DEBUGOUT(sspWaitingMenu);
249 xf_setup.rx_cnt = xf_setup.tx_cnt = 0;
250
251 Chip_SSP_RWFrames_Blocking(LPC_SSP, &xf_setup);
252
253 if (Buffer_Verify() == 0) {
254 DEBUGOUT(sspPassedMenu);
255 }
256 else {
257 DEBUGOUT(sspFailedMenu);
258 }
259 break;
260
261 case SSP_INTERRUPT_SEL:
262 DEBUGOUT(sspIntWaitingMenu);
263
264 isXferCompleted = 0;
265 xf_setup.rx_cnt = xf_setup.tx_cnt = 0;
266
267 Chip_SSP_Int_FlushData(LPC_SSP);/* flush dummy data from SSP FiFO */
268 if (SSP_DATA_BYTES(ssp_format.bits) == 1) {
269 Chip_SSP_Int_RWFrames8Bits(LPC_SSP, &xf_setup);
270 }
271 else {
272 Chip_SSP_Int_RWFrames16Bits(LPC_SSP, &xf_setup);
273 }
274
275 Chip_SSP_Int_Enable(LPC_SSP); /* enable interrupt */
276 while (!isXferCompleted) {}
277
278 if (Buffer_Verify() == 0) {
279 DEBUGOUT(sspPassedMenu);
280 }
281 else {
282 DEBUGOUT(sspFailedMenu);
283 }
284 break;
285
286 case SSP_DMA_SEL: /* SSP DMA Read and Write: fixed on 8bits */
287 DEBUGOUT(sspDMAWaitingMenu);
288 isDmaTxfCompleted = isDmaRxfCompleted = 0;
289 Chip_SSP_DMA_Enable(LPC_SSP);
290 /* data Tx_Buf --> SSP */
291 Chip_DMA_Transfer(LPC_GPDMA, dmaChSSPTx,
292 (uint32_t) &Tx_Buf[0],
293 LPC_GPDMA_SSP_TX,
294 GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA,
295 BUFFER_SIZE);
296 /* data SSP --> Rx_Buf */
297 Chip_DMA_Transfer(LPC_GPDMA, dmaChSSPRx,
298 LPC_GPDMA_SSP_RX,
299 (uint32_t) &Rx_Buf[0],
300 GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA,
301 BUFFER_SIZE);
302
303 while (!isDmaTxfCompleted || !isDmaRxfCompleted) {}
304 if (Buffer_Verify() == 0) {
305 DEBUGOUT(sspPassedMenu);
306 }
307 else {
308 DEBUGOUT(sspFailedMenu);
309 }
310 Chip_SSP_DMA_Disable(LPC_SSP);
311 break;
312
313 case 'q':
314 case 'Q':
315 Chip_DMA_Stop(LPC_GPDMA, dmaChSSPTx);
316 Chip_DMA_Stop(LPC_GPDMA, dmaChSSPRx);
317 return;
318
319 default:
320 break;
321 }
322
323 DEBUGOUT(sspTransferModeSel);
324 }
325
326 }
327
328 /* Select the SSP mode : Master or Slave */
329 static void appSSPSelectModeMenu(void)
330 {
331 int key;
332
333 DEBUGOUT(sspSelectModeMenu);
334
335 while (1) {
336 key = 0xFF;
337 do {
338 key = DEBUGIN();
339 } while ((key & 0xFF) == 0xFF);
340
341 switch (key) {
342 case SSP_MASTER_MODE_SEL: /* Master */
343 Chip_SSP_SetMaster(LPC_SSP, 1);
344 DEBUGOUT("Master Mode\n\r");
345 return;
346
347 case SSP_SLAVE_MODE_SEL: /* Slave */
348 Chip_SSP_SetMaster(LPC_SSP, 0);
349 DEBUGOUT("Slave Mode\n\r");
350 return;
351
352 case 'q':
353 return;
354
355 default:
356 break;
357 }
358 DEBUGOUT(sspSelectModeMenu);
359 }
360
361 }
362
363 /* The main menu of the example. Allow user select the SSP mode (master or slave) and Transfer
364 mode (Polling, Interrupt or DMA) */
365 static void appSSPMainMenu(void)
366 {
367 int key;
368
369 DEBUGOUT(helloMenu);
370 DEBUGOUT(sspMenu);
371 DEBUGOUT(sspMainMenu);
372
373 while (1) {
374 key = 0xFF;
375 do {
376 key = DEBUGIN();
377 } while ((key & 0xFF) == 0xFF);
378
379 switch (key) {
380 case SSP_MODE_SEL: /* Select SSP Mode */
381 appSSPSelectModeMenu();
382 break;
383
384 case SSP_TRANSFER_MODE_SEL: /* Select Transfer Mode */
385 appSSPTest();
386 break;
387
388 default:
389 break;
390 }
391 DEBUGOUT(sspMainMenu);
392 }
393 }
394
395 /*****************************************************************************
396 * Public functions
397 ****************************************************************************/
398
403 void SSPIRQHANDLER(void)
404 {
405 Chip_SSP_Int_Disable(LPC_SSP); /* Disable all interrupt */
406 if (SSP_DATA_BYTES(ssp_format.bits) == 1) {
407 Chip_SSP_Int_RWFrames8Bits(LPC_SSP, &xf_setup);
408 }
409 else {
410 Chip_SSP_Int_RWFrames16Bits(LPC_SSP, &xf_setup);
411 }
412
413 if ((xf_setup.rx_cnt != xf_setup.length) || (xf_setup.tx_cnt != xf_setup.length)) {
414 Chip_SSP_Int_Enable(LPC_SSP); /* enable all interrupts */
415 }
416 else {
417 isXferCompleted = 1;
418 }
419 }
420
425 void DMA_IRQHandler(void)
426 {
427 if (Chip_DMA_Interrupt(LPC_GPDMA, dmaChSSPTx) == SUCCESS) {
428 isDmaTxfCompleted = 1;
429 }
430
431 if (Chip_DMA_Interrupt(LPC_GPDMA, dmaChSSPRx) == SUCCESS) {
432 isDmaRxfCompleted = 1;
433 }
434 }
435
440 int main(void)
441 {
442 Board_Init();
443
444 /* SSP initialization */
445 Board_SSP_Init(LPC_SSP);
446
447 Chip_SSP_Init(LPC_SSP);
448
449 ssp_format.frameFormat = SSP_FRAMEFORMAT_SPI;
450 ssp_format.bits = SSP_DATA_BITS;
451 ssp_format.clockMode = SSP_CLOCK_MODE0;
452 Chip_SSP_SetFormat(LPC_SSP, &ssp_format);
453
454 Chip_SSP_Enable(LPC_SSP);
455
456 /* Initialize GPDMA controller */
457 Chip_GPDMA_Init(LPC_GPDMA);
458
459 /* Setting GPDMA interrupt */
460 NVIC_DisableIRQ(DMA_IRQn);
461 NVIC_SetPriority(DMA_IRQn, ((0x01 << 3) | 0x01));
462 NVIC_EnableIRQ(DMA_IRQn);
463
464 /* Setting SSP interrupt */
465 NVIC_EnableIRQ(SSP_IRQ);
466
467 appSSPMainMenu();
468
469 /* DeInitialize SSP peripheral */
470 Chip_SSP_DeInit(LPC_SSP);
471
472 return 0;
473 }
474