LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 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 
46  .Config = {
47  .DataINPipeNumber = 1,
48  .DataINPipeDoubleBank = false,
49 
50  .DataOUTPipeNumber = 2,
51  .DataOUTPipeDoubleBank = false,
52  .PortNumber = 0,
53  },
54 };
55 
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 */
86 
87  /* Create a stdio stream for the serial port for stdin and stdout */
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 
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 
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 
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 
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 */
316 {
317  return &FlashDisk_MS_Interface;
318 }
319 
320 /* Wait for disk to be inserted */
322 {
324  MS_Host_USBTask(hDisk);
326  }
327  return 1;
328 }
329 
330 /* Disk acquire function that waits for disk to be ready */
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");
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");
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 */
362 {
363  return DiskCapacity.Blocks;
364 }
365 
366 /* Get Block size */
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 */
395 {
396  volatile int i = tout * 100;
397  while (i--) { /* Just delay */
398  }
399  return 1;
400 }