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