LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ssp_11xx.c
Go to the documentation of this file.
1 /*
2  * @brief LPC11xx 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 "chip.h"
33 
34 /*****************************************************************************
35  * Private types/enumerations/variables
36  ****************************************************************************/
38 #define SSP_Write2BFifo(pSSP, xf_setup) \
39  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, xf_setup) \
47  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, rDat) \
55  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, rDat) \
66  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  else {
117  while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) {
118  /* write data to buffer */
119  if (( IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) {
120  SSP_Write1BFifo(pSSP, xf_setup)
121  }
122 
123  /* Check overrun error */
124  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
125  return ERROR;
126  }
127 
128  /* Check for any data available in RX FIFO */
129  SSP_Read1BFifo(pSSP, xf_setup, rDat)
130  }
131  }
132  if (xf_setup->tx_data) {
133  return xf_setup->tx_cnt;
134  }
135  else if (xf_setup->rx_data) {
136  return xf_setup->rx_cnt;
137  }
138  return 0;
139 }
140 
141 /* SSP Polling Write in blocking mode */
143 {
144  uint32_t tx_cnt = 0, rx_cnt = 0;
145 
146  /* Clear all remaining frames in RX FIFO */
147  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
148  IP_SSP_ReceiveFrame(pSSP);
149  }
150 
151  /* Clear status */
153 
154  if (IP_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
155  uint16_t *wdata16;
156 
157  wdata16 = (uint16_t *) buffer;
158 
159  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
160  /* write data to buffer */
161  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
162  IP_SSP_SendFrame(pSSP, *wdata16);
163  wdata16++;
164  tx_cnt += 2;
165  }
166 
167  /* Check overrun error */
168  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
169  return ERROR;
170  }
171 
172  /* Check for any data available in RX FIFO */
173  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) {
174  IP_SSP_ReceiveFrame(pSSP); /* read dummy data */
175  rx_cnt += 2;
176  }
177  }
178 
179  return tx_cnt;
180  }
181  else {
182  uint8_t *wdata8;
183 
184  wdata8 = buffer;
185 
186  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
187  /* write data to buffer */
188  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
189  IP_SSP_SendFrame(pSSP, *wdata8);
190  wdata8++;
191  tx_cnt++;
192  }
193 
194  /* Check overrun error */
195  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
196  return ERROR;
197  }
198 
199  /* Check for any data available in RX FIFO */
200  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
201  IP_SSP_ReceiveFrame(pSSP); /* read dummy data */
202  rx_cnt++;
203  }
204  }
205 
206  return tx_cnt;
207  }
208 }
209 
210 /* SSP Polling Read in blocking mode */
212 {
213  uint32_t rx_cnt = 0, tx_cnt = 0;
214 
215  /* Clear all remaining frames in RX FIFO */
216  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
217  IP_SSP_ReceiveFrame(pSSP);
218  }
219 
220  /* Clear status */
222 
223  if (IP_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
224  uint16_t *rdata16;
225 
226  rdata16 = (uint16_t *) buffer;
227 
228  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
229  /* write data to buffer */
230  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
231  IP_SSP_SendFrame(pSSP, 0xFFFF); /* just send dummy data */
232  tx_cnt += 2;
233  }
234 
235  /* Check overrun error */
236  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
237  return ERROR;
238  }
239 
240  /* Check for any data available in RX FIFO */
241  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
242  *rdata16 = IP_SSP_ReceiveFrame(pSSP);
243  rdata16++;
244  rx_cnt += 2;
245  }
246  }
247 
248  return rx_cnt;
249  }
250  else {
251  uint8_t *rdata8;
252 
253  rdata8 = buffer;
254 
255  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
256  /* write data to buffer */
257  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
258  IP_SSP_SendFrame(pSSP, 0xFF); /* just send dummy data */
259  tx_cnt++;
260  }
261 
262  /* Check overrun error */
263  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
264  return ERROR;
265  }
266 
267  /* Check for any data available in RX FIFO */
268  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
269  *rdata8 = IP_SSP_ReceiveFrame(pSSP);
270  rdata8++;
271  rx_cnt++;
272  }
273  }
274 
275  return rx_cnt;
276  }
277 }
278 
279 /* Clean all data in RX FIFO of SSP */
281 {
282  if (IP_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {
283  while (IP_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {}
284  }
285 
286  /* Clear all remaining frames in RX FIFO */
287  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
288  IP_SSP_ReceiveFrame(pSSP);
289  }
290 
291  /* Clear status */
293 }
294 
295 /* SSP Interrupt Read/Write with 8-bit frame width */
297 {
298  uint16_t rDat;
299 
300  /* Check overrun error in RIS register */
301  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
302  return ERROR;
303  }
304 
305  if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
306  /* check if RX FIFO contains data */
307  SSP_Read1BFifo(pSSP, xf_setup, rDat)
308 
309  while ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
310  /* Write data to buffer */
311  SSP_Write1BFifo(pSSP, xf_setup)
312 
313  /* Check overrun error in RIS register */
314  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
315  return ERROR;
316  }
317 
318  /* Check for any data available in RX FIFO */
319  SSP_Read1BFifo(pSSP, xf_setup, rDat)
320  }
321  return SUCCESS;
322  }
323 
324  return ERROR;
325 }
326 
327 /* SSP Interrupt Read/Write with 16-bit frame width */
329 {
330  uint16_t rDat;
331 
332  /* Check overrun error in RIS register */
333  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
334  return ERROR;
335  }
336 
337  if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
338  /* check if RX FIFO contains data */
339  SSP_Read2BFifo(pSSP, xf_setup, rDat)
340 
341  while ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
342  /* Write data to buffer */
343  SSP_Write2BFifo(pSSP, xf_setup)
344 
345  /* Check overrun error in RIS register */
346  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
347  return ERROR;
348  }
349 
350  /* Check for any data available in RX FIFO */
351  SSP_Read2BFifo(pSSP, xf_setup, rDat)
352  }
353  return SUCCESS;
354  }
355 
356  return ERROR;
357 }
358 
359 /* Set the SSP operating modes, master or slave */
360 void Chip_SSP_SetMaster(LPC_SSP_T *pSSP, bool master)
361 {
362  if (master) {
364  }
365  else {
367  }
368 }
369 
370 /* Set the clock frequency for SSP interface */
372 {
373  uint32_t main_clk, ssp_div;
374  uint32_t ssp_clk, cr0_div, cmp_clk, prescale;
375 
376  main_clk = Chip_Clock_GetMainClockRate();
377 #ifdef SSP1_SUPPORT
378  if (pSSP == LPC_SSP1) {
379  ssp_div = Chip_Clock_GetSSP1ClockDiv();
380  }
381  else
382 #endif
383  {
384  ssp_div = Chip_Clock_GetSSP0ClockDiv();
385  }
386 
387  ssp_clk = main_clk / ssp_div;
388 
389  cr0_div = 0;
390  cmp_clk = 0xFFFFFFFF;
391  prescale = 2;
392 
393  while (cmp_clk > bitRate) {
394  cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
395  if (cmp_clk > bitRate) {
396  cr0_div++;
397  if (cr0_div > 0xFF) {
398  cr0_div = 0;
399  prescale += 2;
400  }
401  }
402  }
403 
404  IP_SSP_Set_ClockRate(pSSP, cr0_div, prescale);
405 }
406 
407 /* Initialize the SSP */
409 {
410 #ifdef SSP1_SUPPORT
411  if (pSSP == LPC_SSP1) {
415  }
416  else
417 #endif
418  {
422  }
423 
426  Chip_SSP_SetBitRate(pSSP, 100000);
427 }
428 
429 /* Shutdown the SSP */
431 {
432  IP_SSP_DeInit(pSSP);
433 
434 #ifdef SSP1_SUPPORT
435  if (pSSP == LPC_SSP1) {
438  }
439  else
440 #endif
441  {
444  }
445 
446 }