LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
spi.c
Go to the documentation of this file.
1 /*
2  * @brief SPI example
3  * This example show how to use the SPI in 2 modes : Polling and Interrupt.
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 
86 /*****************************************************************************
87  * Private types/enumerations/variables
88  ****************************************************************************/
89 #define BUFFER_SIZE (0x100)
90 
91 #define SPI_MASTER_MODE_SEL (0x31)
92 #define SPI_SLAVE_MODE_SEL (0x32)
93 #define SPI_MODE_SEL (SPI_MASTER_MODE_SEL)
94 
95 #define SPI_POLLING_SEL (0x31)
96 #define SPI_INTERRUPT_SEL (0x32)
97 #if (SPI_MODE_SEL == SPI_SLAVE_MODE_SEL)
98 #define SPI_TRANSFER_MODE_SEL (SPI_INTERRUPT_SEL)
99 #else
100 #define SPI_TRANSFER_MODE_SEL (SPI_POLLING_SEL)
101 #endif
102 
103 #define LPC_SSP LPC_SSP1
104 #define LPC_GPDMA_SSP_TX GPDMA_CONN_SSP1_Tx
105 #define LPC_GPDMA_SSP_RX GPDMA_CONN_SSP1_Rx
106 
107 static uint8_t spi_tx_buf[BUFFER_SIZE];
108 static uint8_t spi_rx_buf[BUFFER_SIZE];
111 static volatile uint8_t spi_xfer_completed = 0;
112 
113 static uint8_t ssp_tx_buf[BUFFER_SIZE];
114 static uint8_t ssp_rx_buf[BUFFER_SIZE];
116 static uint8_t ssp_dma_tx_ch, ssp_dma_rx_ch;
117 static volatile uint8_t ssp_dma_txf_completed = 0;
118 static volatile uint8_t ssp_dma_rxf_completed = 0;
119 
120 /*****************************************************************************
121  * Public types/enumerations/variables
122  ****************************************************************************/
123 
124 /*****************************************************************************
125  * Private functions
126  ****************************************************************************/
127 
128 /* Initialize buffer */
129 static void bufferInit(uint8_t *tx_buf, uint8_t *rx_buf)
130 {
131  uint16_t i;
132  uint8_t ch = 0;
133 
134  for (i = 0; i < BUFFER_SIZE; i++) {
135  tx_buf[i] = ch++;
136  rx_buf[i] = 0xAA;
137  }
138 }
139 
140 /* Verify buffer after transfer */
141 static uint8_t bufferVerify(uint8_t *tx_buf, uint8_t *rx_buf)
142 {
143  uint16_t i;
144  for ( i = 0; i < BUFFER_SIZE; i++ ) {
145  if (tx_buf[i] != rx_buf[i]) {
146  return 1;
147  }
148  }
149  return 0;
150 }
151 
156 void DMA_IRQHandler(void)
157 {
160  }
161 
164  }
165 }
166 
167 static void appSSPRun(void)
168 {
174  /* data Tx_Buf --> SSP */
176  (uint32_t) &ssp_tx_buf[0],
179  BUFFER_SIZE);
180  /* data SSP --> Rx_Buf */
183  (uint32_t) &ssp_rx_buf[0],
185  BUFFER_SIZE);
186 }
187 
188 /* Select the Transfer mode : Polling or Interrupt */
189 static void appSPIRun(void)
190 {
191  spi_xf.cnt = 0;
192  spi_xf.length = BUFFER_SIZE;
193  spi_xf.pTxData = spi_tx_buf;
194  spi_xf.pRxData = spi_rx_buf;
196 
197 #if (SPI_TRANSFER_MODE_SEL == SPI_POLLING_SEL)
199 #else
200  spi_xfer_completed = 0;
201 
202  Chip_SPI_Int_FlushData(LPC_SPI); /* flush dummy data from SPI FiFO */
204  Chip_SPI_Int_Enable(LPC_SPI); /* enable interrupt */
205 #endif
206 }
207 
208 /*****************************************************************************
209  * Public functions
210  ****************************************************************************/
211 #if (SPI_TRANSFER_MODE_SEL == SPI_INTERRUPT_SEL)
212 
216 void SPI_IRQHandler(void)
217 {
218  Chip_SPI_Int_Disable(LPC_SPI); /* Disable all interrupt */
220 
221  if (spi_xf.cnt < spi_xf.length) {
222  Chip_SPI_Int_Enable(LPC_SPI); /* enable all interrupts */
223  }
224  else {
225  spi_xfer_completed = 1;
226  }
227 }
228 
229 #endif /*(SPI_TRANSFER_MODE_SEL == SPI_INTERRUPT_SEL)*/
230 
235 int main(void)
236 {
237  Board_Init();
238 
239 #if (SPI_MODE_SEL == SPI_MASTER_MODE_SEL)
240  Board_SPI_Init(true);
241 #else
242  Board_SPI_Init(false);
243 #endif
245 
246  /* SPI initialization */
248  spi_format.bits = SPI_BITS_8;
249  spi_format.clockMode = SPI_CLOCK_MODE0;
250  spi_format.dataOrder = SPI_DATA_MSB_FIRST;
251  Chip_SPI_SetFormat(LPC_SPI, &spi_format);
252 
253  /* SSP initialization */
255  ssp_format.frameFormat = SSP_FRAMEFORMAT_SPI;
256  ssp_format.bits = SSP_BITS_8;
257  ssp_format.clockMode = SSP_CLOCK_MODE0;
258  Chip_SSP_SetFormat(LPC_SSP, &ssp_format);
260 
261  /* Initialize GPDMA controller */
263 
264 #if (SPI_MODE_SEL == SPI_MASTER_MODE_SEL)
267  spi_xf.fnBefTransfer = NULL;
268  spi_xf.fnAftTransfer = NULL;
271 #else
272  spi_xf.fnBefFrame = NULL;
273  spi_xf.fnAftFrame = NULL;
274  spi_xf.fnBefTransfer = NULL;
275  spi_xf.fnAftTransfer = NULL;
278 #endif
279 
280 #if (SPI_TRANSFER_MODE_SEL == SPI_INTERRUPT_SEL)
281  /* Setting SPI interrupt */
282  NVIC_EnableIRQ(SPI_IRQn);
283 #endif
284  NVIC_EnableIRQ(DMA_IRQn);
285 
286 #if (SPI_MODE_SEL == SPI_MASTER_MODE_SEL)
287  appSSPRun();
288  appSPIRun();
289 #else
290  appSPIRun();
291  appSSPRun();
292  while (!spi_xfer_completed) {}
293 #endif
296 
297  if ((bufferVerify(spi_tx_buf, ssp_rx_buf) == 0) &&
299  Board_LED_Set(0, false);
300  }
301  else {
302  Board_LED_Set(0, true);
303  }
304 
305  /* DeInitialize SPI peripheral */
307 
308  /* DeInitialize SSP peripheral */
310 
311  while (1) {}
312  return 0;
313 }
314