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