| 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
MassStorageHost.c
Go to the documentation of this file.
1 /*
2 * @brief Mass Storage Host example
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * Copyright(C) Dean Camera, 2011, 2012
7 * All rights reserved.
8 *
9 * @par
10 * Software that is described herein is for illustrative purposes only
11 * which provides customers with programming information regarding the
12 * LPC products. This software is supplied "AS IS" without any warranties of
13 * any kind, and NXP Semiconductors and its licensor disclaim any and
14 * all warranties, express or implied, including all implied warranties of
15 * merchantability, fitness for a particular purpose and non-infringement of
16 * intellectual property rights. NXP Semiconductors assumes no responsibility
17 * or liability for the use of the software, conveys no license or rights under any
18 * patent, copyright, mask work right, or any other intellectual property rights in
19 * or to any products. NXP Semiconductors reserves the right to make changes
20 * in the software without notification. NXP Semiconductors also makes no
21 * representation or warranty that such application will be suitable for the
22 * specified use without further testing or modification.
23 *
24 * @par
25 * Permission to use, copy, modify, and distribute this software and its
26 * documentation is hereby granted, under NXP Semiconductors' and its
27 * licensor's relevant copyrights in the software, without fee, provided that it
28 * is used in conjunction with NXP Semiconductors microcontrollers. This
29 * copyright, permission, and disclaimer notice must appear in all copies of
30 * this code.
31 */
32
33 #include "MassStorageHost.h"
34 #include "fsusb_cfg.h"
35 #include "ff.h"
36
37 /*****************************************************************************
38 * Private types/enumerations/variables
39 ****************************************************************************/
40
45 static USB_ClassInfo_MS_Host_t FlashDisk_MS_Interface = {
46 .Config = {
47 .DataINPipeNumber = 1,
48 .DataINPipeDoubleBank = false,
49
50 .DataOUTPipeNumber = 2,
51 .DataOUTPipeDoubleBank = false,
52 .PortNumber = 0,
53 },
54 };
55
56 static SCSI_Capacity_t DiskCapacity;
57 static uint8_t buffer[8 * 1024];
58
59 STATIC FATFS fatFS; /* File system object */
60 STATIC FIL fileObj; /* File object */
61
62 /*****************************************************************************
63 * Public types/enumerations/variables
64 ****************************************************************************/
65
66 /*****************************************************************************
67 * Private functions
68 ****************************************************************************/
69
70 /* Function to spin forever when there is an error */
71 static void die(FRESULT rc)
72 {
73 #if 0
74 DEBUGOUT("*******DIE %d*******\r\n", rc);
75 while (1) {}/* Spin for ever */
76 #endif
77 }
78
80 static void SetupHardware(void)
81 {
82 Board_Init();
83 USB_Init(FlashDisk_MS_Interface.Config.PortNumber, USB_MODE_Host);
84 /* Hardware Initialization */
85 Board_Debug_Init();
86
87 /* Create a stdio stream for the serial port for stdin and stdout */
88 Serial_CreateStream(NULL);
89 }
90
91 /* Function to do the read/write to USB Disk */
92 static void USB_ReadWriteFile(void)
93 {
94 FRESULT rc; /* Result code */
95 int i;
96 UINT bw, br;
97 uint8_t *ptr;
98 char debugBuf[64];
99 DIR dir; /* Directory object */
100 FILINFO fno; /* File information object */
101
102 f_mount(0, &fatFS); /* Register volume work area (never fails) */
103
104 rc = f_open(&fileObj, "MESSAGE.TXT", FA_READ);
105 if (rc) {
106 DEBUGOUT("Unable to open MESSAGE.TXT from USB Disk\r\n");
107 die(rc);
108 }
109 else {
110 DEBUGOUT("Opened file MESSAGE.TXT from USB Disk. Printing contents...\r\n\r\n");
111 for (;; ) {
112 /* Read a chunk of file */
113 rc = f_read(&fileObj, buffer, sizeof buffer, &br);
114 if (rc || !br) {
115 break; /* Error or end of file */
116 }
117 ptr = (uint8_t *) buffer;
118 for (i = 0; i < br; i++) { /* Type the data */
119 DEBUGOUT("%c", ptr[i]);
120 }
121 }
122 if (rc) {
123 die(rc);
124 }
125
126 DEBUGOUT("\r\n\r\nClose the file.\r\n");
127 rc = f_close(&fileObj);
128 if (rc) {
129 die(rc);
130 }
131 }
132
133 DEBUGOUT("\r\nCreate a new file (hello.txt).\r\n");
134 rc = f_open(&fileObj, "HELLO.TXT", FA_WRITE | FA_CREATE_ALWAYS);
135 if (rc) {
136 die(rc);
137 }
138 else {
139
140 DEBUGOUT("\r\nWrite a text data. (Hello world!)\r\n");
141
142 rc = f_write(&fileObj, "Hello world!\r\n", 14, &bw);
143 if (rc) {
144 die(rc);
145 }
146 else {
147 sprintf(debugBuf, "%u bytes written.\r\n", bw);
148 DEBUGOUT(debugBuf);
149 }
150 DEBUGOUT("\r\nClose the file.\r\n");
151 rc = f_close(&fileObj);
152 if (rc) {
153 die(rc);
154 }
155 }
156 DEBUGOUT("\r\nOpen root directory.\r\n");
157 rc = f_opendir(&dir, "");
158 if (rc) {
159 die(rc);
160 }
161 else {
162 DEBUGOUT("\r\nDirectory listing...\r\n");
163 for (;; ) {
164 /* Read a directory item */
165 rc = f_readdir(&dir, &fno);
166 if (rc || !fno.fname[0]) {
167 break; /* Error or end of dir */
168 }
169 if (fno.fattrib & AM_DIR) {
170 sprintf(debugBuf, " <dir> %s\r\n", fno.fname);
171 }
172 else {
173 sprintf(debugBuf, " %8lu %s\r\n", fno.fsize, fno.fname);
174 }
175 DEBUGOUT(debugBuf);
176 }
177 if (rc) {
178 die(rc);
179 }
180 }
181 DEBUGOUT("\r\nTest completed.\r\n");
182 USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0);
183 }
184
185 /*****************************************************************************
186 * Public functions
187 ****************************************************************************/
188
192 int main(void)
193 {
194 SetupHardware();
195
196 DEBUGOUT("Mass Storage Host Demo running.\r\n");
197
198 USB_ReadWriteFile();
199
200 DEBUGOUT("Example completed.\r\n");
201 while (1) {}
202 }
203
207 void EVENT_USB_Host_DeviceAttached(const uint8_t corenum)
208 {
209 DEBUGOUT(("Device Attached on port %d\r\n"), corenum);
210 }
211
215 void EVENT_USB_Host_DeviceUnattached(const uint8_t corenum)
216 {
217 DEBUGOUT(("\r\nDevice Unattached on port %d\r\n"), corenum);
218 }
219
223 void EVENT_USB_Host_DeviceEnumerationComplete(const uint8_t corenum)
224 {
225 uint16_t ConfigDescriptorSize;
226 uint8_t ConfigDescriptorData[512];
227
228 if (USB_Host_GetDeviceConfigDescriptor(corenum, 1, &ConfigDescriptorSize, ConfigDescriptorData,
229 sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) {
230 DEBUGOUT("Error Retrieving Configuration Descriptor.\r\n");
231 return;
232 }
233
234 FlashDisk_MS_Interface.Config.PortNumber = corenum;
235 if (MS_Host_ConfigurePipes(&FlashDisk_MS_Interface,
236 ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError) {
237 DEBUGOUT("Attached Device Not a Valid Mass Storage Device.\r\n");
238 return;
239 }
240
241 if (USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 1) != HOST_SENDCONTROL_Successful) {
242 DEBUGOUT("Error Setting Device Configuration.\r\n");
243 return;
244 }
245
246 uint8_t MaxLUNIndex;
247 if (MS_Host_GetMaxLUN(&FlashDisk_MS_Interface, &MaxLUNIndex)) {
248 DEBUGOUT("Error retrieving max LUN index.\r\n");
249 USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0);
250 return;
251 }
252
253 DEBUGOUT(("Total LUNs: %d - Using first LUN in device.\r\n"), (MaxLUNIndex + 1));
254
255 if (MS_Host_ResetMSInterface(&FlashDisk_MS_Interface)) {
256 DEBUGOUT("Error resetting Mass Storage interface.\r\n");
257 USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0);
258 return;
259 }
260
261 SCSI_Request_Sense_Response_t SenseData;
262 if (MS_Host_RequestSense(&FlashDisk_MS_Interface, 0, &SenseData) != 0) {
263 DEBUGOUT("Error retrieving device sense.\r\n");
264 USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0);
265 return;
266 }
267
268 // if (MS_Host_PreventAllowMediumRemoval(&FlashDisk_MS_Interface, 0, true)) {
269 // DEBUGOUT("Error setting Prevent Device Removal bit.\r\n");
270 // USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0);
271 // return;
272 // }
273
274 SCSI_Inquiry_Response_t InquiryData;
275 if (MS_Host_GetInquiryData(&FlashDisk_MS_Interface, 0, &InquiryData)) {
276 DEBUGOUT("Error retrieving device Inquiry data.\r\n");
277 USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0);
278 return;
279 }
280
281 /* DEBUGOUT("Vendor \"%.8s\", Product \"%.16s\"\r\n", InquiryData.VendorID, InquiryData.ProductID); */
282
283 DEBUGOUT("Mass Storage Device Enumerated.\r\n");
284 }
285
287 void EVENT_USB_Host_HostError(const uint8_t corenum, const uint8_t ErrorCode)
288 {
289 USB_Disable(corenum, USB_MODE_Host);
290
291 DEBUGOUT(("Host Mode Error\r\n"
292 " -- Error port %d\r\n"
293 " -- Error Code %d\r\n" ), corenum, ErrorCode);
294
295 for (;; ) {}
296 }
297
301 void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t corenum,
302 const uint8_t ErrorCode,
303 const uint8_t SubErrorCode)
304 {
305 DEBUGOUT(("Dev Enum Error\r\n"
306 " -- Error port %d\r\n"
307 " -- Error Code %d\r\n"
308 " -- Sub Error Code %d\r\n"
309 " -- In State %d\r\n" ),
310 corenum, ErrorCode, SubErrorCode, USB_HostState[corenum]);
311
312 }
313
314 /* Get the disk data structure */
315 DISK_HANDLE_T *FSUSB_DiskInit(void)
316 {
317 return &FlashDisk_MS_Interface;
318 }
319
320 /* Wait for disk to be inserted */
321 int FSUSB_DiskInsertWait(DISK_HANDLE_T *hDisk)
322 {
323 while (USB_HostState[hDisk->Config.PortNumber] != HOST_STATE_Configured) {
324 MS_Host_USBTask(hDisk);
325 USB_USBTask(hDisk->Config.PortNumber, USB_MODE_Host);
326 }
327 return 1;
328 }
329
330 /* Disk acquire function that waits for disk to be ready */
331 int FSUSB_DiskAcquire(DISK_HANDLE_T *hDisk)
332 {
333 DEBUGOUT("Waiting for ready...");
334 for (;; ) {
335 uint8_t ErrorCode = MS_Host_TestUnitReady(hDisk, 0);
336
337 if (!(ErrorCode)) {
338 break;
339 }
340
341 /* Check if an error other than a logical command error (device busy) received */
342 if (ErrorCode != MS_ERROR_LOGICAL_CMD_FAILED) {
343 DEBUGOUT("Failed\r\n");
344 USB_Host_SetDeviceConfiguration(hDisk->Config.PortNumber, 0);
345 return 0;
346 }
347 }
348 DEBUGOUT("Done.\r\n");
349
350 if (MS_Host_ReadDeviceCapacity(hDisk, 0, &DiskCapacity)) {
351 DEBUGOUT("Error retrieving device capacity.\r\n");
352 USB_Host_SetDeviceConfiguration(hDisk->Config.PortNumber, 0);
353 return 0;
354 }
355
356 DEBUGOUT(("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
357 return 1;
358 }
359
360 /* Get sector count */
361 uint32_t FSUSB_DiskGetSectorCnt(DISK_HANDLE_T *hDisk)
362 {
363 return DiskCapacity.Blocks;
364 }
365
366 /* Get Block size */
367 uint32_t FSUSB_DiskGetSectorSz(DISK_HANDLE_T *hDisk)
368 {
369 return DiskCapacity.BlockSize;
370 }
371
372 /* Read sectors */
373 int FSUSB_DiskReadSectors(DISK_HANDLE_T *hDisk, void *buff, uint32_t secStart, uint32_t numSec)
374 {
375 if (MS_Host_ReadDeviceBlocks(hDisk, 0, secStart, numSec, DiskCapacity.BlockSize, buff)) {
376 DEBUGOUT("Error reading device block.\r\n");
377 USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0);
378 return 0;
379 }
380 return 1;
381 }
382
383 /* Write Sectors */
384 int FSUSB_DiskWriteSectors(DISK_HANDLE_T *hDisk, void *buff, uint32_t secStart, uint32_t numSec)
385 {
386 if (MS_Host_WriteDeviceBlocks(hDisk, 0, secStart, numSec, DiskCapacity.BlockSize, buff)) {
387 DEBUGOUT("Error writing device block.\r\n");
388 return 0;
389 }
390 return 1;
391 }
392
393 /* Disk ready function */
394 int FSUSB_DiskReadyWait(DISK_HANDLE_T *hDisk, int tout)
395 {
396 volatile int i = tout * 100;
397 while (i--) { /* Just delay */
398 }
399 return 1;
400 }