LPCOpen Platform
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 
33 #ifdef CFG_SDCARD
34 #include "sdmmc.h"
35 
66 /*****************************************************************************
67  * Private types/enumerations/variables
68  ****************************************************************************/
69 
70 #if _USE_XSTRFUNC == 0
71 #include <string.h>
72 #define xstrlen(x) strlen(x)
73 #define xstrcpy(x, y) strcpy(x, y)
74 #define xmemset(x, y, z) memset(x, y, z)
75 #define xstrchr(x, y) strchr(x, y)
76 #endif
77 
78 #ifdef BOARD_HITEX_EVA_18504350
79 #define debugstr(str) board_uart_out_string(str)
80 #else
81 #define debugstr(str) DEBUGSTR(str)
82 #endif
83 
84 /* buffer size (in byte) for R/W operations */
85 #define BUFFER_SIZE 4096
86 
87 static volatile UINT Timer = 0; /* Performance timer (1kHz increment) */
88 static volatile int32_t sdio_wait_exit = 0;
89 static volatile uint32_t u32Milliseconds;
90 static volatile uint32_t timerCntms = 0;
91 
92 #define TIME_INTERVAL 1/* 1ms */
93 
94 /*****************************************************************************
95  * Public types/enumerations/variables
96  ****************************************************************************/
97 
98 /* SDMMC card info structure */
100 
101 /*****************************************************************************
102  * Private functions
103  ****************************************************************************/
104 
105 /* Delay callback for timed SDIF/SDMMC functions */
106 static void sdmmc_waitms(uint32_t time)
107 {
108  /* In an RTOS, the thread would sleep allowing other threads to run. For standalone operation, we just spin on a timer */
109  /* TIM_Waitus(time * 1000); */
110  timerCntms = time;
111  while (timerCntms) {}
112 }
113 
119 static void sdmmc_setup_wakeup(uint32_t bits)
120 {
121  /* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */
122  NVIC_ClearPendingIRQ(SDIO_IRQn);
123  sdio_wait_exit = 0;
124  Chip_SDMMC_SetIntMask(bits);
125  NVIC_EnableIRQ(SDIO_IRQn);
126 }
127 
133 static uint32_t sdmmc_irq_driven_wait(void)
134 {
136 
137  /* Wait for event, would be nice to have a timeout, but keep it simple */
138  while (sdio_wait_exit == 0) {}
139 
140  /* Get status and clear interrupts */
141  status = Chip_SDMMC_GetIntStatus();
142 
143  return status;
144 }
145 
146 /* Initialize the Repetitive Interrupt Timer at 1s */
147 void App_Timer_Init(void)
148 {
149  Chip_RIT_Init();
150  /* Configure time_interval for RIT
151  * In this case: time_interval = 1000 ms = 1s
152  * So, RIT will generate interrupt each 1s
153  */
155  /* Initialize RTC timer */
156  rtc_initialize();
157 }
158 
159 /* Initialize SD/MMC */
160 void App_SDMMC_Init(void)
161 {
162  memset(&sdcardinfo, 0, sizeof(sdcardinfo));
163  sdcardinfo.evsetup_cb = sdmmc_setup_wakeup;
164  sdcardinfo.waitfunc_cb = sdmmc_irq_driven_wait;
165  sdcardinfo.msdelay_func = sdmmc_waitms;
166 
167  /* SD/MMC initialization */
169 
170  /* The SDIO driver needs to know the SDIO clock rate */
171  Chip_Clock_EnableOpts(CLK_MX_SDIO, true, true, 1);
173  Chip_SDMMC_Init();
174 }
175 
176 /*****************************************************************************
177  * Public functions
178  ****************************************************************************/
179 
185 void die(FRESULT rc)
186 {
187  DEBUGOUT("Failed with rc=%u.\n", rc);
188  for (;; ) {}
189 }
190 
195 void SysTick_Handler(void)
196 {
197  u32Milliseconds += 10;
198 }
199 
204 void SDIO_IRQHandler(void)
205 {
206  /* All SD based register handling is done in the callback
207  function. The SDIO interrupt is not enabled as part of this
208  driver and needs to be enabled/disabled in the callbacks or
209  application as needed. This is to allow flexibility with IRQ
210  handling for applicaitons and RTOSes. */
211  /* Set wait exit flag to tell wait function we are ready. In an RTOS,
212  this would trigger wakeup of a thread waiting for the IRQ. */
213  NVIC_DisableIRQ(SDIO_IRQn);
214  sdio_wait_exit = 1;
215 }
216 
221 void RIT_IRQHandler(void)
222 {
223  /* Clear interrupt flag */
225 
226  /* Disk timer function (100Hz) */
227  disk_timerproc();
228  if (timerCntms) {
229  timerCntms--;
230  }
231 
232 }
233 
242 {
243  RTC rtc;
244 
245  /* Get local time */
246  rtc_gettime(&rtc);
247 
248  /* Pack date and time into a DWORD variable */
249  return ((DWORD) (rtc.year - 1980) << 25)
250  | ((DWORD) rtc.month << 21)
251  | ((DWORD) rtc.mday << 16)
252  | ((DWORD) rtc.hour << 11)
253  | ((DWORD) rtc.min << 5)
254  | ((DWORD) rtc.sec >> 1);
255 }
259 #endif /*CFG_SDCARD*/