LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 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 
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 
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 
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) {
265  }
266  else {
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);
284 
286  /* data Tx_Buf --> SSP */
288  (uint32_t) &Tx_Buf[0],
291  BUFFER_SIZE);
292  /* data SSP --> Rx_Buf */
295  (uint32_t) &Rx_Buf[0],
297  BUFFER_SIZE);
298 
299  while (!isDmaTxfCompleted || !isDmaRxfCompleted) {}
300  if (Buffer_Verify() == 0) {
301  DEBUGOUT(sspPassedMenu);
302  }
303  else {
304  DEBUGOUT(sspFailedMenu);
305  }
307  break;
308 
309  case 'q':
310  case 'Q':
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 */
340  DEBUGOUT("Master Mode\n\r");
341  return;
342 
343  case SSP_SLAVE_MODE_SEL: /* Slave */
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 */
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) {
404  }
405  else {
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 {
424  isDmaTxfCompleted = 1;
425  }
426 
428  isDmaRxfCompleted = 1;
429  }
430 }
431 
436 int main(void)
437 {
438  Board_Init();
439 
440  /* SSP initialization */
442 
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 
451 
452  /* Initialize GPDMA controller */
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