LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ssp_18xx_43xx.c
Go to the documentation of this file.
1 /*
2  * @brief LPC18xx/43xx SSP driver
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include "ssp_18xx_43xx.h"
33 
34 /*****************************************************************************
35  * Private types/enumerations/variables
36  ****************************************************************************/
38 #define SSP_Write2BFifo(pSSP, \
39  xf_setup) if (xf_setup->tx_data) {IP_SSP_SendFrame(pSSP, \
40  (*(uint16_t *) ((uint32_t) xf_setup->tx_data \
41  + xf_setup->tx_cnt))); } \
42  else {IP_SSP_SendFrame(pSSP, 0xFFFF); } \
43  xf_setup->tx_cnt += 2;
44 
46 #define SSP_Write1BFifo(pSSP, \
47  xf_setup) if (xf_setup->tx_data) {IP_SSP_SendFrame(pSSP, \
48  (*(uint8_t *) ((uint32_t) xf_setup->tx_data \
49  + xf_setup->tx_cnt))); } \
50  else {IP_SSP_SendFrame(pSSP, 0xFF); } \
51  xf_setup->tx_cnt++;
52 
54 #define SSP_Read2BFifo(pSSP, xf_setup, \
55  rDat) while (IP_SSP_GetStatus(pSSP, \
56  SSP_STAT_RNE) == SET && xf_setup->rx_cnt < xf_setup->length) { \
57  rDat = IP_SSP_ReceiveFrame(pSSP); \
58  if (xf_setup->rx_data) { \
59  *(uint16_t *) ((uint32_t) xf_setup->rx_data + xf_setup->rx_cnt) = rDat; \
60  } \
61  xf_setup->rx_cnt += 2; \
62 }
63 
65 #define SSP_Read1BFifo(pSSP, xf_setup, \
66  rDat) while (IP_SSP_GetStatus(pSSP, \
67  SSP_STAT_RNE) == SET && xf_setup->rx_cnt < xf_setup->length) { \
68  rDat = IP_SSP_ReceiveFrame(pSSP); \
69  if (xf_setup->rx_data) { \
70  *(uint8_t *) ((uint32_t) xf_setup->rx_data + xf_setup->rx_cnt) = rDat; \
71  } \
72  xf_setup->rx_cnt++; \
73 }
74 
75 /*****************************************************************************
76  * Public types/enumerations/variables
77  ****************************************************************************/
78 
79 /*****************************************************************************
80  * Private functions
81  ****************************************************************************/
82 
83 /*****************************************************************************
84  * Public functions
85  ****************************************************************************/
86 
87 /* SSP Polling Read/Write in blocking mode */
89 {
90  uint16_t rDat;
91 
92  /* Clear all remaining frames in RX FIFO */
93  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
94  IP_SSP_ReceiveFrame(pSSP);
95  }
96 
97  /* Clear status */
99 
100  if (IP_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
101  while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) {
102  /* write data to buffer */
103  if (( IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) {
104  SSP_Write2BFifo(pSSP, xf_setup)
105  }
106 
107  /* Check overrun error */
108  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
109  return ERROR;
110  }
111 
112  /* Check for any data available in RX FIFO */
113  SSP_Read2BFifo(pSSP, xf_setup, rDat)
114  }
115 
116  if (xf_setup->tx_data) {
117  return xf_setup->tx_cnt;
118  }
119  else if (xf_setup->rx_data) {
120  return xf_setup->rx_cnt;
121  }
122  return 0;
123  }
124  else {
125  while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) {
126  /* write data to buffer */
127  if (( IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) {
128  SSP_Write1BFifo(pSSP, xf_setup)
129  }
130 
131  /* Check overrun error */
132  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
133  return ERROR;
134  }
135 
136  /* Check for any data available in RX FIFO */
137  SSP_Read1BFifo(pSSP, xf_setup, rDat)
138  }
139 
140  if (xf_setup->tx_data) {
141  return xf_setup->tx_cnt;
142  }
143  else if (xf_setup->rx_data) {
144  return xf_setup->rx_cnt;
145  }
146  return 0;
147  }
148 }
149 
150 /* SSP Polling Write in blocking mode */
151 uint32_t Chip_SSP_WriteFrames_Blocking(LPC_SSP_Type *pSSP, uint8_t *buffer, uint32_t buffer_len)
152 {
153  uint32_t tx_cnt = 0, rx_cnt = 0;
154 
155  /* Clear all remaining frames in RX FIFO */
156  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
157  IP_SSP_ReceiveFrame(pSSP);
158  }
159 
160  /* Clear status */
162 
163  if (IP_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
164  uint16_t *wdata16;
165 
166  wdata16 = (uint16_t *) buffer;
167 
168  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
169  /* write data to buffer */
170  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
171  IP_SSP_SendFrame(pSSP, *wdata16);
172  wdata16++;
173  tx_cnt += 2;
174  }
175 
176  /* Check overrun error */
177  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
178  return ERROR;
179  }
180 
181  /* Check for any data available in RX FIFO */
182  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) {
183  IP_SSP_ReceiveFrame(pSSP); /* read dummy data */
184  rx_cnt += 2;
185  }
186  }
187 
188  return tx_cnt;
189  }
190  else {
191  uint8_t *wdata8;
192 
193  wdata8 = buffer;
194 
195  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
196  /* write data to buffer */
197  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
198  IP_SSP_SendFrame(pSSP, *wdata8);
199  wdata8++;
200  tx_cnt++;
201  }
202 
203  /* Check overrun error */
204  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
205  return ERROR;
206  }
207 
208  /* Check for any data available in RX FIFO */
209  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
210  IP_SSP_ReceiveFrame(pSSP); /* read dummy data */
211  rx_cnt++;
212  }
213  }
214 
215  return tx_cnt;
216  }
217 }
218 
219 /* SSP Polling Read in blocking mode */
220 uint32_t Chip_SSP_ReadFrames_Blocking(LPC_SSP_Type *pSSP, uint8_t *buffer, uint32_t buffer_len)
221 {
222  uint32_t rx_cnt = 0, tx_cnt = 0;
223 
224  /* Clear all remaining frames in RX FIFO */
225  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
226  IP_SSP_ReceiveFrame(pSSP);
227  }
228 
229  /* Clear status */
231 
232  if (IP_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
233  uint16_t *rdata16;
234 
235  rdata16 = (uint16_t *) buffer;
236 
237  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
238  /* write data to buffer */
239  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
240  IP_SSP_SendFrame(pSSP, 0xFFFF); /* just send dummy data */
241  tx_cnt += 2;
242  }
243 
244  /* Check overrun error */
245  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
246  return ERROR;
247  }
248 
249  /* Check for any data available in RX FIFO */
250  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
251  *rdata16 = IP_SSP_ReceiveFrame(pSSP);
252  rdata16++;
253  rx_cnt += 2;
254  }
255  }
256 
257  return rx_cnt;
258  }
259  else {
260  uint8_t *rdata8;
261 
262  rdata8 = buffer;
263 
264  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
265  /* write data to buffer */
266  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
267  IP_SSP_SendFrame(pSSP, 0xFF); /* just send dummy data */
268  tx_cnt++;
269  }
270 
271  /* Check overrun error */
272  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
273  return ERROR;
274  }
275 
276  /* Check for any data available in RX FIFO */
277  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
278  *rdata8 = IP_SSP_ReceiveFrame(pSSP);
279  rdata8++;
280  rx_cnt++;
281  }
282  }
283 
284  return rx_cnt;
285  }
286 }
287 
288 /* Clean all data in RX FIFO of SSP */
290 {
291  if (IP_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {
292  while (IP_SSP_GetStatus(pSSP, SSP_STAT_BSY)) ;
293  }
294 
295  /* Clear all remaining frames in RX FIFO */
296  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
297  IP_SSP_ReceiveFrame(pSSP);
298  }
299 
300  /* Clear status */
302 }
303 
304 /* SSP Interrupt Read/Write with 8-bit frame width */
306 {
307  uint16_t rDat;
308 
309  /* Check overrun error in RIS register */
310  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
311  return ERROR;
312  }
313 
314  if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
315  /* check if RX FIFO contains data */
316  SSP_Read1BFifo(pSSP, xf_setup, rDat)
317 
318  while ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
319  /* Write data to buffer */
320  SSP_Write1BFifo(pSSP, xf_setup)
321 
322  /* Check overrun error in RIS register */
323  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
324  return ERROR;
325  }
326 
327  /* Check for any data available in RX FIFO */
328  SSP_Read1BFifo(pSSP, xf_setup, rDat)
329  }
330  return SUCCESS;
331  }
332 
333  return ERROR;
334 }
335 
336 /* SSP Interrupt Read/Write with 16-bit frame width */
338 {
339  uint16_t rDat;
340 
341  /* Check overrun error in RIS register */
342  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
343  return ERROR;
344  }
345 
346  if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
347  /* check if RX FIFO contains data */
348  SSP_Read2BFifo(pSSP, xf_setup, rDat)
349 
350  while ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
351  /* Write data to buffer */
352  SSP_Write2BFifo(pSSP, xf_setup)
353 
354  /* Check overrun error in RIS register */
355  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
356  return ERROR;
357  }
358 
359  /* Check for any data available in RX FIFO */
360  SSP_Read2BFifo(pSSP, xf_setup, rDat)
361  }
362  return SUCCESS;
363  }
364 
365  return ERROR;
366 }
367 
368 /* Set the SSP operating modes, master or slave */
369 void Chip_SSP_Set_Master(LPC_SSP_Type *pSSP, bool master)
370 {
371  if (master) {
373  }
374  else {
376  }
377 }
378 
379 /* Set the clock frequency for SSP interface */
381 {
382  uint32_t ssp_clk, cr0_div, cmp_clk, prescale;
383 
384  if (pSSP == LPC_SSP0) {
386  }
387  else {
389  }
390 
391  cr0_div = 0;
392  cmp_clk = 0xFFFFFFFF;
393  prescale = 2;
394 
395  while (cmp_clk > bit_rate) {
396  cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
397  if (cmp_clk > bit_rate) {
398  cr0_div++;
399  if (cr0_div > 0xFF) {
400  cr0_div = 0;
401  prescale += 2;
402  }
403  }
404  }
405 
406  IP_SSP_Set_ClockRate(pSSP, cr0_div, prescale);
407 }
408 
409 /* Set up the SSP frame format */
411 {
412  IP_SSP_Set_Format(pSSP, format->bits, format->frameFormat, format->clockFormat);
413 }
414 
415 /* Enable/Disable SSP interrupt */
417 {
418  IP_SSP_Int_Enable(pSSP, SSP_TXIM, NewState);
419 }
420 
421 /* Enable/Disable DMA */
423 {
424  IP_SSP_DMA_Cmd(pSSP, SSP_DMA_RX, NewState);
425  IP_SSP_DMA_Cmd(pSSP, SSP_DMA_TX, NewState);
426 }
427 
428 /* Initialize the SSP */
430 {
433  Chip_SSP_Set_BitRate(pSSP, 100000);
434 }