| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

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 */
88 uint32_t Chip_SSP_RWFrames_Blocking(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
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 */
98 IP_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
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 */
142 uint32_t Chip_SSP_WriteFrames_Blocking(LPC_SSP_T *pSSP, uint8_t *buffer, uint32_t buffer_len)
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 */
152 IP_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
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 */
211 uint32_t Chip_SSP_ReadFrames_Blocking(LPC_SSP_T *pSSP, uint8_t *buffer, uint32_t buffer_len)
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 */
221 IP_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
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 */
280 void Chip_SSP_Int_FlushData(LPC_SSP_T *pSSP)
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 */
292 IP_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
293 }
294
295 /* SSP Interrupt Read/Write with 8-bit frame width */
296 Status Chip_SSP_Int_RWFrames8Bits(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
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 */
328 Status Chip_SSP_Int_RWFrames16Bits(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
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) {
363 IP_SSP_Set_Mode(pSSP, SSP_MODE_MASTER);
364 }
365 else {
366 IP_SSP_Set_Mode(pSSP, SSP_MODE_SLAVE);
367 }
368 }
369
370 /* Set the clock frequency for SSP interface */
371 void Chip_SSP_SetBitRate(LPC_SSP_T *pSSP, uint32_t bitRate)
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 */
408 void Chip_SSP_Init(LPC_SSP_T *pSSP)
409 {
410 #ifdef SSP1_SUPPORT
411 if (pSSP == LPC_SSP1) {
412 Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SSP1);
413 Chip_Clock_SetSSP1ClockDiv(1);
414 Chip_SYSCTL_PeriphReset(RESET_SSP1);
415 }
416 else
417 #endif
418 {
419 Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SSP0);
420 Chip_Clock_SetSSP0ClockDiv(1);
421 Chip_SYSCTL_PeriphReset(RESET_SSP0);
422 }
423
424 IP_SSP_Set_Mode(pSSP, SSP_MODE_MASTER);
425 IP_SSP_SetFormat(pSSP, SSP_BITS_8, SSP_FRAMEFORMAT_SPI, SSP_CLOCK_CPHA0_CPOL0);
426 Chip_SSP_SetBitRate(pSSP, 100000);
427 }
428
429 /* Shutdown the SSP */
430 void Chip_SSP_DeInit(LPC_SSP_T *pSSP)
431 {
432 IP_SSP_DeInit(pSSP);
433
434 #ifdef SSP1_SUPPORT
435 if (pSSP == LPC_SSP1) {
436 Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SSP1);
437 Chip_Clock_SetSSP1ClockDiv(0);
438 }
439 else
440 #endif
441 {
442 Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SSP0);
443 Chip_Clock_SetSSP0ClockDiv(0);
444 }
445
446 }