LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ssp_13xx.c
Go to the documentation of this file.
1 /*
2  * @brief LPC13xx 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  ****************************************************************************/
37 
39 {
40  if (xf_setup->tx_data) {
41  IP_SSP_SendFrame(pSSP, (*(uint16_t *) ((uint32_t) xf_setup->tx_data +
42  xf_setup->tx_cnt)));
43  }
44  else {
45  IP_SSP_SendFrame(pSSP, 0xFFFF);
46  }
47 
48  xf_setup->tx_cnt += 2;
49 }
50 
53 {
54  if (xf_setup->tx_data) {
55  IP_SSP_SendFrame(pSSP, (*(uint8_t *) ((uint32_t) xf_setup->tx_data + xf_setup->tx_cnt)));
56  }
57  else {
58  IP_SSP_SendFrame(pSSP, 0xFF);
59  }
60 
61  xf_setup->tx_cnt++;
62 }
63 
66 {
67  uint16_t rDat;
68 
69  while ((IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) &&
70  (xf_setup->rx_cnt < xf_setup->length)) {
71  rDat = IP_SSP_ReceiveFrame(pSSP);
72  if (xf_setup->rx_data) {
73  *(uint16_t *) ((uint32_t) xf_setup->rx_data + xf_setup->rx_cnt) = rDat;
74  }
75 
76  xf_setup->rx_cnt += 2;
77  }
78 }
79 
82 {
83  uint16_t rDat;
84 
85  while ((IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) &&
86  (xf_setup->rx_cnt < xf_setup->length)) {
87  rDat = IP_SSP_ReceiveFrame(pSSP);
88  if (xf_setup->rx_data) {
89  *(uint8_t *) ((uint32_t) xf_setup->rx_data + xf_setup->rx_cnt) = rDat;
90  }
91 
92  xf_setup->rx_cnt++;
93  }
94 }
95 
96 /*****************************************************************************
97  * Public types/enumerations/variables
98  ****************************************************************************/
99 
100 /*****************************************************************************
101  * Private functions
102  ****************************************************************************/
103 
104 /*****************************************************************************
105  * Public functions
106  ****************************************************************************/
107 
108 /* SSP Polling Read/Write in blocking mode */
110 {
111  /* Clear all remaining frames in RX FIFO */
112  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
113  IP_SSP_ReceiveFrame(pSSP);
114  }
115 
116  /* Clear status */
118 
119  if (IP_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
120  while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) {
121  /* write data to buffer */
122  if (( IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) {
123  SSP_Write2BFifo(pSSP, xf_setup);
124  }
125 
126  /* Check overrun error */
127  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
128  return ERROR;
129  }
130 
131  /* Check for any data available in RX FIFO */
132  SSP_Read2BFifo(pSSP, xf_setup);
133  }
134  }
135  else {
136  while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) {
137  /* write data to buffer */
138  if (( IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) {
139  SSP_Write1BFifo(pSSP, xf_setup);
140  }
141 
142  /* Check overrun error */
143  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
144  return ERROR;
145  }
146 
147  /* Check for any data available in RX FIFO */
148  SSP_Read1BFifo(pSSP, xf_setup);
149  }
150  }
151  if (xf_setup->tx_data) {
152  return xf_setup->tx_cnt;
153  }
154  else if (xf_setup->rx_data) {
155  return xf_setup->rx_cnt;
156  }
157 
158  return 0;
159 }
160 
161 /* SSP Polling Write in blocking mode */
163 {
164  uint32_t tx_cnt = 0, rx_cnt = 0;
165 
166  /* Clear all remaining frames in RX FIFO */
167  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
168  IP_SSP_ReceiveFrame(pSSP);
169  }
170 
171  /* Clear status */
173 
174  if (IP_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
175  uint16_t *wdata16;
176 
177  wdata16 = (uint16_t *) buffer;
178 
179  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
180  /* write data to buffer */
181  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
182  IP_SSP_SendFrame(pSSP, *wdata16);
183  wdata16++;
184  tx_cnt += 2;
185  }
186 
187  /* Check overrun error */
188  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
189  return ERROR;
190  }
191 
192  /* Check for any data available in RX FIFO */
193  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) {
194  IP_SSP_ReceiveFrame(pSSP); /* read dummy data */
195  rx_cnt += 2;
196  }
197  }
198  }
199  else {
200  uint8_t *wdata8;
201 
202  wdata8 = buffer;
203 
204  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
205  /* write data to buffer */
206  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
207  IP_SSP_SendFrame(pSSP, *wdata8);
208  wdata8++;
209  tx_cnt++;
210  }
211 
212  /* Check overrun error */
213  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
214  return ERROR;
215  }
216 
217  /* Check for any data available in RX FIFO */
218  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
219  IP_SSP_ReceiveFrame(pSSP); /* read dummy data */
220  rx_cnt++;
221  }
222  }
223  }
224 
225  return tx_cnt;
226 
227 }
228 
229 /* SSP Polling Read in blocking mode */
231 {
232  uint32_t rx_cnt = 0, tx_cnt = 0;
233 
234  /* Clear all remaining frames in RX FIFO */
235  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
236  IP_SSP_ReceiveFrame(pSSP);
237  }
238 
239  /* Clear status */
241 
242  if (IP_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
243  uint16_t *rdata16;
244 
245  rdata16 = (uint16_t *) buffer;
246 
247  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
248  /* write data to buffer */
249  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
250  IP_SSP_SendFrame(pSSP, 0xFFFF); /* just send dummy data */
251  tx_cnt += 2;
252  }
253 
254  /* Check overrun error */
255  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
256  return ERROR;
257  }
258 
259  /* Check for any data available in RX FIFO */
260  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
261  *rdata16 = IP_SSP_ReceiveFrame(pSSP);
262  rdata16++;
263  rx_cnt += 2;
264  }
265  }
266  }
267  else {
268  uint8_t *rdata8;
269 
270  rdata8 = buffer;
271 
272  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
273  /* write data to buffer */
274  if ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
275  IP_SSP_SendFrame(pSSP, 0xFF); /* just send dummy data */
276  tx_cnt++;
277  }
278 
279  /* Check overrun error */
280  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
281  return ERROR;
282  }
283 
284  /* Check for any data available in RX FIFO */
285  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
286  *rdata8 = IP_SSP_ReceiveFrame(pSSP);
287  rdata8++;
288  rx_cnt++;
289  }
290  }
291  }
292 
293  return rx_cnt;
294 
295 }
296 
297 /* Clean all data in RX FIFO of SSP */
299 {
300  if (IP_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {
301  while (IP_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {}
302  }
303 
304  /* Clear all remaining frames in RX FIFO */
305  while (IP_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
306  IP_SSP_ReceiveFrame(pSSP);
307  }
308 
309  /* Clear status */
311 }
312 
313 /* SSP Interrupt Read/Write with 8-bit frame width */
315 {
316  /* Check overrun error in RIS register */
317  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
318  return ERROR;
319  }
320 
321  if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
322  /* check if RX FIFO contains data */
323  SSP_Read1BFifo(pSSP, xf_setup);
324 
325  while ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
326  /* Write data to buffer */
327  SSP_Write1BFifo(pSSP, xf_setup);
328 
329  /* Check overrun error in RIS register */
330  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
331  return ERROR;
332  }
333 
334  /* Check for any data available in RX FIFO */
335  SSP_Read1BFifo(pSSP, xf_setup);
336  }
337 
338  return SUCCESS;
339  }
340 
341  return ERROR;
342 }
343 
344 /* SSP Interrupt Read/Write with 16-bit frame width */
346 {
347  /* Check overrun error in RIS register */
348  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
349  return ERROR;
350  }
351 
352  if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
353  /* check if RX FIFO contains data */
354  SSP_Read2BFifo(pSSP, xf_setup);
355 
356  while ((IP_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
357  /* Write data to buffer */
358  SSP_Write2BFifo(pSSP, xf_setup);
359 
360  /* Check overrun error in RIS register */
361  if (IP_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
362  return ERROR;
363  }
364 
365  /* Check for any data available in RX FIFO */
366  SSP_Read2BFifo(pSSP, xf_setup);
367  }
368 
369  return SUCCESS;
370  }
371 
372  return ERROR;
373 }
374 
375 /* Set the SSP operating modes, master or slave */
376 void Chip_SSP_SetMaster(LPC_SSP_T *pSSP, bool master)
377 {
378  if (master) {
380  }
381  else {
383  }
384 }
385 
386 /* Set the clock frequency for SSP interface */
388 {
389  uint32_t main_clk, ssp_div;
390  uint32_t ssp_clk, cr0_div, cmp_clk, prescale;
391 
392  main_clk = Chip_Clock_GetMainClockRate();
393 
394  if (pSSP == LPC_SSP1) {
395  ssp_div = Chip_Clock_GetSSP1ClockDiv();
396  }
397  else {
398  ssp_div = Chip_Clock_GetSSP0ClockDiv();
399  }
400 
401  ssp_clk = main_clk / ssp_div;
402 
403  cr0_div = 0;
404  cmp_clk = 0xFFFFFFFF;
405  prescale = 2;
406 
407  while (cmp_clk > bitRate) {
408  cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
409  if (cmp_clk > bitRate) {
410  cr0_div++;
411  if (cr0_div > 0xFF) {
412  cr0_div = 0;
413  prescale += 2;
414  }
415  }
416  }
417 
418  IP_SSP_Set_ClockRate(pSSP, cr0_div, prescale);
419 }
420 
421 /* Initialize the SSP */
423 {
424  if (pSSP == LPC_SSP1) {
428  }
429  else {
433  }
434 
437  Chip_SSP_SetBitRate(pSSP, 100000);
438 }
439 
440 /* Shutdown the SSP */
442 {
443  IP_SSP_DeInit(pSSP);
444 
445  if (pSSP == LPC_SSP1) {
448  }
449  else {
452  }
453 }