LPCOpen Platform for LPC18XX/43XX microcontrollers  18XX43XX
LPCOpen Platform for the NXP LPC18XX/43XX family of Microcontrollers
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 "chip.h"
33 
34 /*****************************************************************************
35  * Private types/enumerations/variables
36  ****************************************************************************/
37 
38 /*****************************************************************************
39  * Public types/enumerations/variables
40  ****************************************************************************/
41 
42 /*****************************************************************************
43  * Private functions
44  ****************************************************************************/
45 
47 {
48  if (xf_setup->tx_data) {
49  Chip_SSP_SendFrame(pSSP, (*(uint16_t *) ((uint32_t) xf_setup->tx_data +
50  xf_setup->tx_cnt)));
51  }
52  else {
53  Chip_SSP_SendFrame(pSSP, 0xFFFF);
54  }
55 
56  xf_setup->tx_cnt += 2;
57 }
58 
61 {
62  if (xf_setup->tx_data) {
63  Chip_SSP_SendFrame(pSSP, (*(uint8_t *) ((uint32_t) xf_setup->tx_data + xf_setup->tx_cnt)));
64  }
65  else {
66  Chip_SSP_SendFrame(pSSP, 0xFF);
67  }
68 
69  xf_setup->tx_cnt++;
70 }
71 
74 {
75  uint16_t rDat;
76 
77  while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) &&
78  (xf_setup->rx_cnt < xf_setup->length)) {
79  rDat = Chip_SSP_ReceiveFrame(pSSP);
80  if (xf_setup->rx_data) {
81  *(uint16_t *) ((uint32_t) xf_setup->rx_data + xf_setup->rx_cnt) = rDat;
82  }
83 
84  xf_setup->rx_cnt += 2;
85  }
86 }
87 
90 {
91  uint16_t rDat;
92 
93  while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) &&
94  (xf_setup->rx_cnt < xf_setup->length)) {
95  rDat = Chip_SSP_ReceiveFrame(pSSP);
96  if (xf_setup->rx_data) {
97  *(uint8_t *) ((uint32_t) xf_setup->rx_data + xf_setup->rx_cnt) = rDat;
98  }
99 
100  xf_setup->rx_cnt++;
101  }
102 }
103 
104 /* Returns clock index for the register interface */
106 {
107  CHIP_CCU_CLK_T clkSSP;
108 
109  if (pSSP == LPC_SSP1) {
110  clkSSP = CLK_MX_SSP1;
111  }
112  else {
113  clkSSP = CLK_MX_SSP0;
114  }
115 
116  return clkSSP;
117 }
118 
119 /* Returns clock index for the peripheral block */
121 {
122  CHIP_CCU_CLK_T clkSSP;
123 
124  if (pSSP == LPC_SSP1) {
125  clkSSP = CLK_APB2_SSP1;
126  }
127  else {
128  clkSSP = CLK_APB0_SSP0;
129  }
130 
131  return clkSSP;
132 }
133 /*****************************************************************************
134  * Public functions
135  ****************************************************************************/
136 
137 /*Set up output clocks per bit for SSP bus*/
138 void Chip_SSP_SetClockRate(LPC_SSP_T *pSSP, uint32_t clk_rate, uint32_t prescale)
139 {
140  uint32_t temp;
141  temp = pSSP->CR0 & (~(SSP_CR0_SCR(0xFF)));
142  pSSP->CR0 = temp | (SSP_CR0_SCR(clk_rate));
143  pSSP->CPSR = prescale;
144 }
145 
146 /* SSP Polling Read/Write in blocking mode */
148 {
149  /* Clear all remaining frames in RX FIFO */
150  while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
151  Chip_SSP_ReceiveFrame(pSSP);
152  }
153 
154  /* Clear status */
156 
157  if (Chip_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
158  while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) {
159  /* write data to buffer */
160  if (( Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) {
161  SSP_Write2BFifo(pSSP, xf_setup);
162  }
163 
164  /* Check overrun error */
165  if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
166  return ERROR;
167  }
168 
169  /* Check for any data available in RX FIFO */
170  SSP_Read2BFifo(pSSP, xf_setup);
171  }
172  }
173  else {
174  while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) {
175  /* write data to buffer */
176  if (( Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) {
177  SSP_Write1BFifo(pSSP, xf_setup);
178  }
179 
180  /* Check overrun error */
181  if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
182  return ERROR;
183  }
184 
185  /* Check for any data available in RX FIFO */
186  SSP_Read1BFifo(pSSP, xf_setup);
187  }
188  }
189  if (xf_setup->tx_data) {
190  return xf_setup->tx_cnt;
191  }
192  else if (xf_setup->rx_data) {
193  return xf_setup->rx_cnt;
194  }
195 
196  return 0;
197 }
198 
199 /* SSP Polling Write in blocking mode */
200 uint32_t Chip_SSP_WriteFrames_Blocking(LPC_SSP_T *pSSP, const uint8_t *buffer, uint32_t buffer_len)
201 {
202  uint32_t tx_cnt = 0, rx_cnt = 0;
203 
204  /* Clear all remaining frames in RX FIFO */
205  while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
206  Chip_SSP_ReceiveFrame(pSSP);
207  }
208 
209  /* Clear status */
211 
212  if (Chip_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
213  uint16_t *wdata16;
214 
215  wdata16 = (uint16_t *) buffer;
216 
217  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
218  /* write data to buffer */
219  if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
220  Chip_SSP_SendFrame(pSSP, *wdata16);
221  wdata16++;
222  tx_cnt += 2;
223  }
224 
225  /* Check overrun error */
226  if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
227  return ERROR;
228  }
229 
230  /* Check for any data available in RX FIFO */
231  while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) {
232  Chip_SSP_ReceiveFrame(pSSP); /* read dummy data */
233  rx_cnt += 2;
234  }
235  }
236  }
237  else {
238  const uint8_t *wdata8;
239 
240  wdata8 = buffer;
241 
242  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
243  /* write data to buffer */
244  if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
245  Chip_SSP_SendFrame(pSSP, *wdata8);
246  wdata8++;
247  tx_cnt++;
248  }
249 
250  /* Check overrun error */
251  if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
252  return ERROR;
253  }
254 
255  /* Check for any data available in RX FIFO */
256  while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
257  Chip_SSP_ReceiveFrame(pSSP); /* read dummy data */
258  rx_cnt++;
259  }
260  }
261  }
262 
263  return tx_cnt;
264 
265 }
266 
267 /* SSP Polling Read in blocking mode */
268 uint32_t Chip_SSP_ReadFrames_Blocking(LPC_SSP_T *pSSP, uint8_t *buffer, uint32_t buffer_len)
269 {
270  uint32_t rx_cnt = 0, tx_cnt = 0;
271 
272  /* Clear all remaining frames in RX FIFO */
273  while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
274  Chip_SSP_ReceiveFrame(pSSP);
275  }
276 
277  /* Clear status */
279 
280  if (Chip_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
281  uint16_t *rdata16;
282 
283  rdata16 = (uint16_t *) buffer;
284 
285  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
286  /* write data to buffer */
287  if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
288  Chip_SSP_SendFrame(pSSP, 0xFFFF); /* just send dummy data */
289  tx_cnt += 2;
290  }
291 
292  /* Check overrun error */
293  if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
294  return ERROR;
295  }
296 
297  /* Check for any data available in RX FIFO */
298  while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
299  *rdata16 = Chip_SSP_ReceiveFrame(pSSP);
300  rdata16++;
301  rx_cnt += 2;
302  }
303  }
304  }
305  else {
306  uint8_t *rdata8;
307 
308  rdata8 = buffer;
309 
310  while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
311  /* write data to buffer */
312  if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
313  Chip_SSP_SendFrame(pSSP, 0xFF); /* just send dummy data */
314  tx_cnt++;
315  }
316 
317  /* Check overrun error */
318  if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
319  return ERROR;
320  }
321 
322  /* Check for any data available in RX FIFO */
323  while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
324  *rdata8 = Chip_SSP_ReceiveFrame(pSSP);
325  rdata8++;
326  rx_cnt++;
327  }
328  }
329  }
330 
331  return rx_cnt;
332 
333 }
334 
335 /* Clean all data in RX FIFO of SSP */
337 {
338  if (Chip_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {
339  while (Chip_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {}
340  }
341 
342  /* Clear all remaining frames in RX FIFO */
343  while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
344  Chip_SSP_ReceiveFrame(pSSP);
345  }
346 
347  /* Clear status */
349 }
350 
351 /* SSP Interrupt Read/Write with 8-bit frame width */
353 {
354  /* Check overrun error in RIS register */
355  if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
356  return ERROR;
357  }
358 
359  if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
360  /* check if RX FIFO contains data */
361  SSP_Read1BFifo(pSSP, xf_setup);
362 
363  while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
364  /* Write data to buffer */
365  SSP_Write1BFifo(pSSP, xf_setup);
366 
367  /* Check overrun error in RIS register */
368  if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
369  return ERROR;
370  }
371 
372  /* Check for any data available in RX FIFO */
373  SSP_Read1BFifo(pSSP, xf_setup);
374  }
375 
376  return SUCCESS;
377  }
378 
379  return ERROR;
380 }
381 
382 /* SSP Interrupt Read/Write with 16-bit frame width */
384 {
385  /* Check overrun error in RIS register */
386  if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
387  return ERROR;
388  }
389 
390  if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
391  /* check if RX FIFO contains data */
392  SSP_Read2BFifo(pSSP, xf_setup);
393 
394  while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
395  /* Write data to buffer */
396  SSP_Write2BFifo(pSSP, xf_setup);
397 
398  /* Check overrun error in RIS register */
399  if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
400  return ERROR;
401  }
402 
403  /* Check for any data available in RX FIFO */
404  SSP_Read2BFifo(pSSP, xf_setup);
405  }
406 
407  return SUCCESS;
408  }
409 
410  return ERROR;
411 }
412 
413 /* Set the SSP operating modes, master or slave */
414 void Chip_SSP_SetMaster(LPC_SSP_T *pSSP, bool master)
415 {
416  if (master) {
418  }
419  else {
421  }
422 }
423 
424 /* Set the clock frequency for SSP interface */
425 void Chip_SSP_SetBitRate(LPC_SSP_T *pSSP, uint32_t bitRate)
426 {
427  uint32_t ssp_clk, cr0_div, cmp_clk, prescale;
428 
430 
431  cr0_div = 0;
432  cmp_clk = 0xFFFFFFFF;
433  prescale = 2;
434 
435  while (cmp_clk > bitRate) {
436  cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
437  if (cmp_clk > bitRate) {
438  cr0_div++;
439  if (cr0_div > 0xFF) {
440  cr0_div = 0;
441  prescale += 2;
442  }
443  }
444  }
445 
446  Chip_SSP_SetClockRate(pSSP, cr0_div, prescale);
447 }
448 
449 /* Initialize the SSP */
451 {
454 
457  Chip_SSP_SetBitRate(pSSP, 100000);
458 }
459 
460 /* De-initializes the SSP peripheral */
462 {
463  Chip_SSP_Disable(pSSP);
464 
467 
468 }
469