| 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
sdmmc.c
Go to the documentation of this file.
1 /*
2 * @brief SD/MMC example
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 <string.h>
33 #include "board.h"
34 #include "chip.h"
35 #include "ff.h"
36
64 /*****************************************************************************
65 * Private types/enumerations/variables
66 ****************************************************************************/
67
68 #define debugstr(str) DEBUGOUT(str)
69
70 /* buffer size (in byte) for R/W operations */
71 #define BUFFER_SIZE 4096
72
73 STATIC FATFS fatFS; /* File system object */
74 STATIC FIL fileObj; /* File object */
75 STATIC INT buffer[BUFFER_SIZE / 4]; /* Working buffer */
76 STATIC volatile int32_t sdcWaitExit = 0;
77 STATIC SDMMC_EVENT_T *event;
78 STATIC volatile Status eventResult = ERROR;
79
80 /*****************************************************************************
81 * Public types/enumerations/variables
82 ****************************************************************************/
83
84 /* SDMMC card info structure */
85 SDMMC_CARD_T sdCardInfo;
86 volatile uint32_t timerCntms = 0; /* Free running milli second timer */
87
88 /*****************************************************************************
89 * Private functions
90 ****************************************************************************/
91 /* Delay callback for timed SDIF/SDMMC functions */
92 STATIC void waitMs(uint32_t time)
93 {
94 uint32_t init = timerCntms;
95
96 /* In an RTOS, the thread would sleep allowing other threads to run.
97 For standalone operation, we just spin on a timer */
98 while (timerCntms < init + time) {}
99 }
100
106 STATIC void setupEvWakeup(void *pEvent)
107 {
108 #ifdef SDC_DMA_ENABLE
109 /* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */
110 NVIC_ClearPendingIRQ(DMA_IRQn);
111 #endif
112 event = (SDMMC_EVENT_T *)pEvent;
113 sdcWaitExit = 0;
114 eventResult = ERROR;
115 #ifdef SDC_DMA_ENABLE
116 NVIC_EnableIRQ(DMA_IRQn);
117 #endif /*SDC_DMA_ENABLE*/
118 }
119
124 STATIC uint32_t waitEvIRQDriven(void)
125 {
126 /* Wait for event, would be nice to have a timeout, but keep it simple */
127 while (sdcWaitExit == 0) {}
128 if (eventResult) {
129 return 0;
130 }
131
132 return 1;
133 }
134
135 /* Initialize the Timer at 1us */
136 STATIC void initAppTimer(void)
137 {
138 /* Setup Systick to tick every 1 milliseconds */
139 SysTick_Config(SystemCoreClock / 1000);
140 }
141
142 /* Initialize SD/MMC */
143 STATIC void initAppSDMMC()
144 {
145 memset(&sdCardInfo, 0, sizeof(sdCardInfo));
146 sdCardInfo.evsetup_cb = setupEvWakeup;
147 sdCardInfo.waitfunc_cb = waitEvIRQDriven;
148 sdCardInfo.msdelay_func = waitMs;
149
150 Board_SDC_Init();
151
152 Chip_SDC_Init(LPC_SDC);
153 }
154
155 /*****************************************************************************
156 * Public functions
157 ****************************************************************************/
158
164 void die(FRESULT rc)
165 {
166 DEBUGOUT("Failed with rc=%u.\r\n", rc);
167 // for (;; ) {}
168 }
169
174 void SysTick_Handler(void)
175 {
176 timerCntms++;
177 }
178
179 #ifdef SDC_DMA_ENABLE
180
184 void DMA_IRQHandler(void)
185 {
186 eventResult = Chip_DMA_Interrupt(LPC_GPDMA, event->DmaChannel);
187 sdcWaitExit = 1;
188 NVIC_DisableIRQ(DMA_IRQn);
189 }
190 #endif /*SDC_DMA_ENABLE*/
191
196 void SDIO_IRQHandler(void)
197 {
198 int32_t Ret;
199 #ifdef SDC_DMA_ENABLE
200 Ret = Chip_SDMMC_IRQHandler(LPC_SDC, NULL,0,NULL,0);
201 #else
202 if(event->Index < event->Size) {
203 if(event->Dir) { /* receive */
204 Ret = Chip_SDMMC_IRQHandler(LPC_SDC, NULL,0,(uint8_t*)event->Buffer,&event->Index);
205 }
206 else {
207 Ret = Chip_SDMMC_IRQHandler(LPC_SDC, (uint8_t*)event->Buffer,&event->Index,NULL,0);
208 }
209 }
210 else {
211 Ret = Chip_SDMMC_IRQHandler(LPC_SDC, NULL,0,NULL,0);
212 }
213 #endif
214 if(Ret < 0) {
215 eventResult = ERROR;
216 sdcWaitExit = 1;
217 }
218 #ifndef SDC_DMA_ENABLE
219 else if(Ret == 0) {
220 eventResult = SUCCESS;
221 sdcWaitExit = 1;
222 }
223 #endif
224 }
225
230 int main(void)
231 {
232 FRESULT rc; /* Result code */
233 DIR dir; /* Directory object */
234 FILINFO fno; /* File information object */
235 UINT bw, br, i;
236 uint8_t *ptr;
237 char debugBuf[64];
238
239 Board_Init();
240
241 initAppSDMMC();
242
243 /* Initialize Repitetive Timer */
244 initAppTimer();
245
246 debugstr("\r\nHello NXP Semiconductors\r\nSD Card demo\r\n");
247
248 /* Enable SD interrupt */
249 NVIC_EnableIRQ(SDC_IRQn);
250
251 f_mount(0, &fatFS); /* Register volume work area (never fails) */
252
253 debugstr("\r\nOpen an existing file (message.txt).\r\n");
254
255 rc = f_open(&fileObj, "MESSAGE.TXT", FA_READ);
256 if (rc) {
257 die(rc);
258 }
259 else {
260 for (;; ) {
261 /* Read a chunk of file */
262 rc = f_read(&fileObj, buffer, sizeof buffer, &br);
263 if (rc || !br) {
264 break; /* Error or end of file */
265 }
266 ptr = (uint8_t *) buffer;
267 for (i = 0; i < br; i++) { /* Type the data */
268 DEBUGOUT("%c", ptr[i]);
269 }
270 }
271 if (rc) {
272 die(rc);
273 }
274
275 debugstr("\r\nClose the file.\r\n");
276 rc = f_close(&fileObj);
277 if (rc) {
278 die(rc);
279 }
280 }
281
282 debugstr("\r\nCreate a new file (hello.txt).\r\n");
283 rc = f_open(&fileObj, "HELLO.TXT", FA_WRITE | FA_CREATE_ALWAYS);
284 if (rc) {
285 die(rc);
286 }
287 else {
288
289 debugstr("\r\nWrite a text data. (Hello world!)\r\n");
290
291 rc = f_write(&fileObj, "Hello world!\r\n", 14, &bw);
292 if (rc) {
293 die(rc);
294 }
295 else {
296 sprintf(debugBuf, "%u bytes written.\r\n", bw);
297 debugstr(debugBuf);
298 }
299 debugstr("\r\nClose the file.\r\n");
300 rc = f_close(&fileObj);
301 if (rc) {
302 die(rc);
303 }
304 }
305 debugstr("\r\nOpen root directory.\r\n");
306 rc = f_opendir(&dir, "");
307 if (rc) {
308 die(rc);
309 }
310 else {
311 debugstr("\r\nDirectory listing...\r\n");
312 for (;; ) {
313 /* Read a directory item */
314 rc = f_readdir(&dir, &fno);
315 if (rc || !fno.fname[0]) {
316 break; /* Error or end of dir */
317 }
318 if (fno.fattrib & AM_DIR) {
319 sprintf(debugBuf, " <dir> %s\r\n", fno.fname);
320 }
321 else {
322 sprintf(debugBuf, " %8lu %s\r\n", fno.fsize, fno.fname);
323 }
324 debugstr(debugBuf);
325 }
326 if (rc) {
327 die(rc);
328 }
329 }
330 debugstr("\r\nTest completed.\r\n");
331 for (;; ) {}
332 }
333