LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 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;
79 
80 /*****************************************************************************
81  * Public types/enumerations/variables
82  ****************************************************************************/
83 
84 /* SDMMC card info structure */
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 */
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 
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 */
137 {
138  /* Setup Systick to tick every 1 milliseconds */
139  SysTick_Config(SystemCoreClock / 1000);
140 }
141 
142 /* Initialize SD/MMC */
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 
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 {
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
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 {
212  }
213 #endif
214  if(Ret < 0) {
215  eventResult = ERROR;
216  sdcWaitExit = 1;
217  }
218 #ifndef SDC_DMA_ENABLE
219  else if(Ret == 0) {
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