| 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
usbmsdev.c
Go to the documentation of this file.
1 /*
2 * @brief USB Mass Storage Device Dual core 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 "usbmsdev.h"
33
34 /*****************************************************************************
35 * Private types/enumerations/variables
36 ****************************************************************************/
37
42 USB_ClassInfo_MS_Device_t Disk_MS_Interface = {
43 .Config = {
44 .InterfaceNumber = 0,
45
46 .DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
47 .DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
48 .DataINEndpointDoubleBank = false,
49
50 .DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
51 .DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
52 .DataOUTEndpointDoubleBank = false,
53
54 .TotalLUNs = TOTAL_LUNS,
55 .PortNumber = 0,
56 },
57 };
58
59
60 /*****************************************************************************
61 * Public types/enumerations/variables
62 ****************************************************************************/
63
64 /*****************************************************************************
65 * Private functions
66 ****************************************************************************/
67 #ifdef OS_FREE_RTOS
68
69 void usb_msdev_func(void);
70 static xSemaphoreHandle usb_dev_event;
71
72 /* Task that waits for event from USB device, invokes the USBTask
73 * whenever it receives one
74 */
75 static void usb_msdev_task(void *arg)
76 {
77 vSemaphoreCreateBinary(usb_dev_event);
78 if (usb_dev_event == NULL) {
79 DEBUGSTR("Unable to create semaphore!\r\n");
80 while (1) ;
81 }
82 while (1) {
83 xSemaphoreTake(usb_dev_event, 100);
84 usb_msdev_func();
85 }
86 }
87
97 void EVENT_USB_Device_TransferComplete(int logicalEP, int xfer_in)
98 {
99 portBASE_TYPE wake = pdFALSE;
100 if (usb_dev_event) {
101 xSemaphoreGiveFromISR(usb_dev_event, &wake);
102 }
103 portEND_SWITCHING_ISR(wake);
104 }
105
106 /* FreeRTOS USB device task */
107 void usb_device_tasks(void)
108 {
109 /* Start Blinky event Task */
110 xTaskCreate(usb_msdev_task, (signed char *) "USB Task",
111 configMINIMAL_STACK_SIZE + 128, NULL, TASK_PRIO_USBDEVICE,
112 (xTaskHandle *) NULL);
113 }
114 #elif defined(OS_UCOS_III)
115
116 #define USBMSDEV_STACK_SZ (1024)
117 #define USBMSDEV_STACK_SZ_FULL 90u
118 #define USBMSDEV_STACK_SZ_LIMIT (USBMSDEV_STACK_SZ * (100u - USBMSDEV_STACK_SZ_FULL)) / 100u
119
120 void usb_msdev_func(void);
121 static OS_TCB mem_tcb;
122 static CPU_STK mem_stack[USBMSDEV_STACK_SZ];
123
124 /* Task that waits for event from USB device, invokes the USBTask
125 * whenever it receives one
126 */
127 static void usb_msdev_task(void *arg)
128 {
129 OS_ERR ucErr;
130 CPU_TS ucos_timeout;
131
132 while (1) {
133 OSTaskSemPend(100, OS_OPT_PEND_BLOCKING, &ucos_timeout, &ucErr);
134 usb_msdev_func();
135 }
136 }
137
147 void EVENT_USB_Device_TransferComplete(int logicalEP, int xfer_in)
148 {
149 OS_ERR ucErr;
150 OSTaskSemPost(&mem_tcb, OS_OPT_POST_NONE, &ucErr);
151 if (ucErr != OS_ERR_NONE) {
152 DEBUGSTR("OSTaskSemPost failure!\r\n");
153 //while (1);
154 }
155
156 }
157
158 /* uCOS-III USB device task */
159 void usb_device_tasks(void)
160 {
161 OS_ERR ret;
162
163 /* Start USB event Task */
164 OSTaskCreate (
165 &mem_tcb,
166 "USB Task",
167 usb_msdev_task,
168 (void *) 1,
169 TASK_PRIO_USBDEVICE,
170 mem_stack,
171 32,
172 USBMSDEV_STACK_SZ,
173 0,
174 0,
175 (void *)0,
176 (OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
177 (OS_ERR *)&ret);
178 if (ret != OS_ERR_NONE) {
179 DEBUGSTR("Unable to create USB task!\r\n");
180 while (1);
181 }
182 }
183
184 #else /* No OS */
185 #define usb_msdev_func usb_device_tasks
186 #endif
187
188 #ifdef CFG_SDCARD
189 static volatile int32_t sdio_wait_exit = 0;
190
191 /* Delay callback for timed SDIF/SDMMC functions */
192 static void sdmmc_waitms(uint32_t time)
193 {
194 int32_t curr = (int32_t) Chip_RIT_GetCounter(LPC_RITIMER);
195 int32_t final = curr + ((SystemCoreClock / 1000) * time);
196
197 /* If the value is zero let us not worry about it */
198 if (!time) {
199 return;
200 }
201
202 if ((final < 0) && (curr > 0)) {
203 while (Chip_RIT_GetCounter(LPC_RITIMER) < (uint32_t) final) {}
204 }
205 else {
206 while ((int32_t) Chip_RIT_GetCounter(LPC_RITIMER) < final) {}
207 }
208 }
209
215 static void sdmmc_setup_wakeup(uint32_t bits)
216 {
217 /* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */
218 NVIC_ClearPendingIRQ(SDIO_IRQn);
219 sdio_wait_exit = 0;
220 Chip_SDMMC_SetIntMask(LPC_SDMMC, bits);
221 NVIC_EnableIRQ(SDIO_IRQn);
222 }
223
229 static uint32_t sdmmc_irq_driven_wait(void)
230 {
231 uint32_t status;
232
233 /* Wait for event, would be nice to have a timeout, but keep it simple */
234 while (sdio_wait_exit == 0) {}
235
236 /* Get status and clear interrupts */
237 status = Chip_SDMMC_GetIntStatus(LPC_SDMMC);
238
239 return status;
240 }
241
246 void SDIO_IRQHandler(void)
247 {
248 /* All SD based register handling is done in the callback
249 function. The SDIO interrupt is not enabled as part of this
250 driver and needs to be enabled/disabled in the callbacks or
251 application as needed. This is to allow flexibility with IRQ
252 handling for applicaitons and RTOSes. */
253 /* Set wait exit flag to tell wait function we are ready. In an RTOS,
254 this would trigger wakeup of a thread waiting for the IRQ. */
255 NVIC_DisableIRQ(SDIO_IRQn);
256 sdio_wait_exit = 1;
257 }
258 #endif
259
260 /*****************************************************************************
261 * Public functions
262 ****************************************************************************/
263
264 /* USB device initialization */
265 void USBDEV_Init(void)
266 {
267 #ifdef CFG_SDCARD
268 memset(&sdcardinfo, 0, sizeof(sdcardinfo));
269 sdcardinfo.evsetup_cb = sdmmc_setup_wakeup;
270 sdcardinfo.waitfunc_cb = sdmmc_irq_driven_wait;
271 sdcardinfo.msdelay_func = sdmmc_waitms;
272
273 /* SD/MMC initialization */
274 Board_SDMMC_Init();
275
276 /* The SDIO driver needs to know the SDIO clock rate */
277 Chip_SDMMC_Init(LPC_SDMMC);
278
279 /* Wait for a card to be inserted */
280 #ifndef BOARD_NGX_XPLORER_18304330
281 /* NGX board ignored SD_CD pin */
282 /* Wait for a card to be inserted (note CD is not on the SDMMC power rail and can be polled without enabling SD slot power */
283 while (Chip_SDMMC_CardNDetect(LPC_SDMMC) == 0) {}
284 #endif
285
286 /* Acquire the card once ready */
287 if (!Chip_SDMMC_Acquire(LPC_SDMMC, &sdcardinfo)) {
288 DEBUGOUT("Card Acquire failed...\r\n");
289 while(1) {};
290 }
291 #endif
292
293 USB_Init(Disk_MS_Interface.Config.PortNumber, USB_MODE_Device);
294 #if defined(USB_DEVICE_ROM_DRIVER)
295 UsbdMsc_Init();
296 #endif
297 NVIC_SetPriority(USB0_IRQn, IRQ_PRIO_USBDEV);
298 }
299
300 /* USB Device task */
301 void usb_msdev_func(void)
302 {
303 #if !defined(USB_DEVICE_ROM_DRIVER)
304 MS_Device_USBTask(&Disk_MS_Interface);
305 USB_USBTask(Disk_MS_Interface.Config.PortNumber,USB_MODE_Device);
306 #endif
307 }
309 void EVENT_USB_Device_Connect(void)
310 {}
311
313 void EVENT_USB_Device_Disconnect(void)
314 {}
315
317 void EVENT_USB_Device_ConfigurationChanged(void)
318 {
319 bool ConfigSuccess = true;
320
321 ConfigSuccess &= MS_Device_ConfigureEndpoints(&Disk_MS_Interface);
322 }
323
325 void EVENT_USB_Device_ControlRequest(void)
326 {
327 MS_Device_ProcessControlRequest(&Disk_MS_Interface);
328 }
329
332 bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t *const MSInterfaceInfo)
333 {
334 bool CommandSuccess;
335
336 CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
337 return CommandSuccess;
338 }