| 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 "rtc.h"
36 #include "ff.h"
37
76 /*****************************************************************************
77 * Private types/enumerations/variables
78 ****************************************************************************/
79 #ifdef BOARD_HITEX_EVA_18504350
80 #define debugstr(str) board_uart_out_string(str)
81 #else
82 #define debugstr(str) DEBUGSTR(str)
83 #endif
84
85 /* buffer size (in byte) for R/W operations */
86 #define BUFFER_SIZE 4096
87
88 static FATFS Fatfs; /* File system object */
89 static FIL Fil; /* File object */
90 static uint32_t Buff[BUFFER_SIZE/sizeof(uint32_t)];
91
92 static volatile UINT Timer = 0; /* Performance timer (1kHz increment) */
93 static volatile int32_t sdio_wait_exit = 0;
94
95 /*****************************************************************************
96 * Public types/enumerations/variables
97 ****************************************************************************/
98
99 /* SDMMC card info structure */
100 mci_card_struct sdcardinfo;
101
102 /*****************************************************************************
103 * Private functions
104 ****************************************************************************/
105
106 /* Delay callback for timed SDIF/SDMMC functions */
107 static void sdmmc_waitms(uint32_t time)
108 {
109 /* In an RTOS, the thread would sleep allowing other threads to run.
110 For standalone operation, we just spin on RI timer */
111 int32_t curr = (int32_t) Chip_RIT_GetCounter(LPC_RITIMER);
112 int32_t final = curr + ((SystemCoreClock / 1000) * time);
113
114 if (final == curr) return;
115
116 if ((final < 0) && (curr > 0)) {
117 while (Chip_RIT_GetCounter(LPC_RITIMER) < (uint32_t) final) {}
118 }
119 else {
120 while ((int32_t) Chip_RIT_GetCounter(LPC_RITIMER) < final) {}
121 }
122
123 return;
124 }
125
131 static void sdmmc_setup_wakeup(void *bits)
132 {
133 uint32_t bit_mask = *((uint32_t *)bits);
134 /* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */
135 NVIC_ClearPendingIRQ(SDIO_IRQn);
136 sdio_wait_exit = 0;
137 Chip_SDIF_SetIntMask(LPC_SDMMC, bit_mask);
138 NVIC_EnableIRQ(SDIO_IRQn);
139 }
140
145 static uint32_t sdmmc_irq_driven_wait(void)
146 {
147 uint32_t status;
148
149 /* Wait for event, would be nice to have a timeout, but keep it simple */
150 while (sdio_wait_exit == 0) {}
151
152 /* Get status and clear interrupts */
153 status = Chip_SDIF_GetIntStatus(LPC_SDMMC);
154
155 return status;
156 }
157
158 /* Initialize SD/MMC */
159 static void App_SDMMC_Init()
160 {
161 memset(&sdcardinfo, 0, sizeof(sdcardinfo));
162 sdcardinfo.card_info.evsetup_cb = sdmmc_setup_wakeup;
163 sdcardinfo.card_info.waitfunc_cb = sdmmc_irq_driven_wait;
164 sdcardinfo.card_info.msdelay_func = sdmmc_waitms;
165
166 /* SD/MMC initialization */
167 Board_SDMMC_Init();
168
169 /* The SDIO driver needs to know the SDIO clock rate */
170 Chip_SDIF_Init(LPC_SDMMC);
171 }
172
173 #ifdef BOARD_HITEX_EVA_18504350
174 /* Initialize the UART for debugging */
175 static void board_uart_debug_init(void)
176 {
177 /* Hitex EVA A4 is sharing Uart port 0 and SDIO pin so it is needed to use Uart port 1 */
178 Board_UART_Init(LPC_UART1);
179 Chip_UART_SetBaud(LPC_UART1, 115200);
180 Chip_UART_ConfigData(LPC_UART1, UART_DATABIT_8, UART_PARITY_NONE, UART_STOPBIT_1); /* default 8-N-1 */
181
182 /* Enable UART Transmit */
183 Chip_UART_TxCmd(LPC_UART1, ENABLE);
184 }
185
186 /* Sends a character on the UART */
187 static void board_uart_out_ch(char ch)
188 {
189 while (Chip_UART_SendByte(LPC_UART1, (uint8_t) ch) == ERROR) {}
190 }
191
192 /* Sends a string on the UART */
193 static void board_uart_out_string(char *str)
194 {
195 while (*str != '\0') {
196 board_uart_out_ch(*str++);
197 }
198 }
199 #endif
200
201 /*****************************************************************************
202 * Public functions
203 ****************************************************************************/
204
210 void die(FRESULT rc)
211 {
212 DEBUGOUT("Failed with rc=%u.\n", rc);
213 /* for (;; ) {} */
214 }
215
220 void SDIO_IRQHandler(void)
221 {
222 /* All SD based register handling is done in the callback
223 function. The SDIO interrupt is not enabled as part of this
224 driver and needs to be enabled/disabled in the callbacks or
225 application as needed. This is to allow flexibility with IRQ
226 handling for applicaitons and RTOSes. */
227 /* Set wait exit flag to tell wait function we are ready. In an RTOS,
228 this would trigger wakeup of a thread waiting for the IRQ. */
229 NVIC_DisableIRQ(SDIO_IRQn);
230 sdio_wait_exit = 1;
231 }
232
237 int main(void)
238 {
239 FRESULT rc; /* Result code */
240 DIR dir; /* Directory object */
241 FILINFO fno; /* File information object */
242 UINT bw, br, i;
243 char debugBuf[64];
244 char *cbuf = (char *) Buff;
245
246 Board_Init();
247 #ifdef BOARD_HITEX_EVA_18504350
248 board_uart_debug_init();
249 #endif
250
251 App_SDMMC_Init();
252
253 /* There is no need to initialize RTC here it is called by fs init
254 but it takes long time hence doing it before calling f_open */
255 debugstr("Initializing RTC (might take few seconds)...");
256 rtc_initialize();
257 debugstr("Done\r\n");
258
259 debugstr("Hello NXP Semiconductors\r\n\r\n***SDCARD demo***\r\n");
260
261 NVIC_DisableIRQ(SDIO_IRQn);
262 /* Enable SD/MMC Interrupt */
263 NVIC_EnableIRQ(SDIO_IRQn);
264
265 f_mount(0, &Fatfs); /* Register volume work area (never fails) */
266
267 debugstr("Opening MESSAGE.TXT from SD Card...");
268 rc = f_open(&Fil, "MESSAGE.TXT", FA_READ);
269 if (rc) {
270 debugstr("Failed.\r\n");
271 die(rc);
272 }
273 debugstr("Done.\r\n");
274
275 debugstr("Printing contents of MESSAGE.TXT...\r\n");
276 for (;; ) {
277 /* Read a chunk of file */
278 rc = f_read(&Fil, (void *)cbuf, BUFFER_SIZE, &br);
279 if (rc || !br) {
280 break; /* Error or end of file */
281 }
282 for (i = 0; i < br; i++) /* Type the data */
283 #ifdef BOARD_HITEX_EVA_18504350
284 {board_uart_out_ch((char) cbuf[i]); }
285 #else
286 {DEBUGOUT("%c", cbuf[i]); }
287 #endif
288 }
289 if (rc) {
290 die(rc);
291 }
292
293 debugstr("Close the file.\r\n");
294 rc = f_close(&Fil);
295 if (rc) {
296 die(rc);
297 }
298
299 debugstr("Create a new file (hello.txt).\r\n");
300 rc = f_open(&Fil, "HELLO.TXT", FA_WRITE | FA_CREATE_ALWAYS);
301 if (rc) {
302 die(rc);
303 }
304
305 debugstr("Write text data \"Hello world!\" to HELLO.TXT\r\n");
306
307 rc = f_write(&Fil, "Hello world!\r\n", 14, &bw);
308 if (rc) {
309 die(rc);
310 }
311
312 sprintf(debugBuf, "%u bytes written.\r\n", bw);
313 debugstr(debugBuf);
314
315 debugstr("Close the file.\r\n");
316 rc = f_close(&Fil);
317 if (rc) {
318 die(rc);
319 }
320
321 debugstr("Open root directory.\r\n");
322 rc = f_opendir(&dir, "");
323 if (rc) {
324 die(rc);
325 }
326
327 debugstr("Directory listing...\r\n");
328 for (;; ) {
329 /* Read a directory item */
330 rc = f_readdir(&dir, &fno);
331 if (rc || !fno.fname[0]) {
332 break; /* Error or end of dir */
333 }
334 if (fno.fattrib & AM_DIR) {
335 sprintf(debugBuf, " <dir> %s\r\n", fno.fname);
336 }
337 else {
338 sprintf(debugBuf, " %8lu %s\r\n", fno.fsize, fno.fname);
339 }
340 debugstr(debugBuf);
341 }
342 if (rc) {
343 die(rc);
344 }
345
346 debugstr("Test completed.\r\n");
347 for (;; ) {}
348 }
349