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 
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 
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 
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 
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) {
270  }
271  else {
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);
290  /* data Tx_Buf --> SSP */
292  (uint32_t) &Tx_Buf[0],
295  BUFFER_SIZE);
296  /* data SSP --> Rx_Buf */
299  (uint32_t) &Rx_Buf[0],
301  BUFFER_SIZE);
302 
303  while (!isDmaTxfCompleted || !isDmaRxfCompleted) {}
304  if (Buffer_Verify() == 0) {
305  DEBUGOUT(sspPassedMenu);
306  }
307  else {
308  DEBUGOUT(sspFailedMenu);
309  }
311  break;
312 
313  case 'q':
314  case 'Q':
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 */
344  DEBUGOUT("Master Mode\n\r");
345  return;
346 
347  case SSP_SLAVE_MODE_SEL: /* Slave */
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 */
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) {
408  }
409  else {
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 {
428  isDmaTxfCompleted = 1;
429  }
430 
432  isDmaRxfCompleted = 1;
433  }
434 }
435 
440 int main(void)
441 {
442  Board_Init();
443 
444  /* SSP initialization */
446 
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 
455 
456  /* Initialize GPDMA controller */
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 */
471 
472  return 0;
473 }
474