This program is an example of of using the MSCUSBHost code with a raw build of ELM Chan Fat Fs. This was done to add both Long File Name Support along with proper time/date stamps (assuming you have a battery hooked up to keep time). This code exposes the Chan API (see main.cpp) and is NOT a c++ class: http://elm-chan.org/fsw/ff/00index_e.html The diskio.c file has the mapping needed to link the filesystem to the MSC stuff
Diff: CHAN_FS/diskio.c
- Revision:
- 0:2dbbafe1b1fb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CHAN_FS/diskio.c Sun Jan 23 18:35:43 2011 +0000 @@ -0,0 +1,180 @@ +/*-----------------------------------------------------------------------*/ +/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */ +/*-----------------------------------------------------------------------*/ +/* This is a stub disk I/O module that acts as front end of the existing */ +/* disk I/O modules and attach it to FatFs module with common interface. */ +/*-----------------------------------------------------------------------*/ + +#include "diskio.h" +#include "usbhost_inc.h" +#include "mbed.h" + +uint32_t _numBlks = 0; +uint32_t _blkSize = 512; + +int initialise_msc(); +void print_inquiry(USB_INT08U *inqReply); + + +int disk_sync() { return 0; } +int disk_sectors() { return _numBlks; } + +DWORD get_fattime(void) +{ + time_t CurrentTimeStamp; + tm *CurrentLocalTime; + DWORD FATFSTimeCode; + + CurrentTimeStamp = time(NULL); + CurrentLocalTime = localtime(&CurrentTimeStamp); + + //Map the tm struct time into the FatFs time code + FATFSTimeCode = ((CurrentLocalTime->tm_year-80)<<25) | + ((CurrentLocalTime->tm_mon+1)<<21) | + ((CurrentLocalTime->tm_mday)<<16) | + ((CurrentLocalTime->tm_hour)<<11) | + ((CurrentLocalTime->tm_min)<<5) | + ((CurrentLocalTime->tm_sec)); + + return FATFSTimeCode; +} + +DSTATUS disk_status(BYTE Drive) +{ + return 0; +} + + +DRESULT disk_ioctl ( + BYTE drv, /* Physical drive nmuber (0..) */ + BYTE ctrl, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) +{ + DRESULT res; + + switch(ctrl) + { + case CTRL_SYNC: + res = RES_OK; + break; + + case GET_SECTOR_SIZE: + res = RES_OK; + *(WORD *)buff = 512; + break; + + case GET_SECTOR_COUNT: + res = RES_OK; + *(DWORD *)buff = (WORD)disk_sectors(); + break; + + case GET_BLOCK_SIZE: + res = RES_OK; + *(DWORD *)buff = 1; + break; + + default: + res = RES_OK; + break; + } + return res; +} + +DSTATUS disk_initialize(BYTE Drive) { + + if ( initialise_msc() != OK ) + return 1; + return 0; +} + +DRESULT disk_write(BYTE Drive,const BYTE * Buffer, DWORD SectorNumber, BYTE SectorCount) +{ + if ( OK == MS_BulkSend(SectorNumber, SectorCount, (USB_INT08U *)Buffer) ) + return RES_OK; + return RES_ERROR; +} + +DRESULT disk_read(BYTE Drive, BYTE * Buffer,DWORD SectorNumber, BYTE SectorCount) +{ + if ( OK == MS_BulkRecv(SectorNumber, SectorCount, (USB_INT08U *)Buffer) ) + return RES_OK; + return RES_ERROR; +} + + + + + +void print_inquiry(USB_INT08U *inqReply) +{ + // see USB Mass Storage Class � UFI Command Specification, + // 4.2 INQUIRY Command + printf("Inquiry reply:\n"); + uint8_t tmp = inqReply[0]&0x1F; + printf("Peripheral device type: %02Xh\n", tmp); + if ( tmp == 0 ) + printf("\t- Direct access (floppy)\n"); + else if ( tmp == 0x1F ) + printf("\t- none (no FDD connected)\n"); + else + printf("\t- unknown type\n"); + tmp = inqReply[1] >> 7; + printf("Removable Media Bit: %d\n", tmp); + tmp = inqReply[2] & 3; + printf("ANSI Version: %02Xh\n", tmp); + if ( tmp != 0 ) + printf("\t- warning! must be 0\n"); + tmp = (inqReply[2]>>3) & 3; + printf("ECMA Version: %02Xh\n", tmp); + if ( tmp != 0 ) + printf("\t- warning! should be 0\n"); + tmp = inqReply[2]>>6; + printf("ISO Version: %02Xh\n", tmp); + if ( tmp != 0 ) + printf("\t- warning! should be 0\n"); + tmp = inqReply[3] & 0xF; + printf("Response Data Format: %02Xh\n", tmp); + if ( tmp != 1 ) + printf("\t- warning! should be 1\n"); + tmp = inqReply[4]; + printf("Additional length: %02Xh\n", tmp); + if ( tmp != 0x1F ) + printf("\t- warning! should be 1Fh\n"); + printf("Vendor Information: '%.8s'\n", &inqReply[8]); + printf("Product Identification: '%.16s'\n", &inqReply[16]); + printf("Product Revision: '%.4s'\n", &inqReply[32]); +} + + + +int initialise_msc() +{ + USB_INT32S rc; + USB_INT08U inquiryResult[INQUIRY_LENGTH]; + + //print_clock(); + Host_Init(); /* Initialize the host controller */ + rc = Host_EnumDev(); /* Enumerate the device connected */ + if (rc != OK) + { + fprintf(stderr, "Could not enumerate device: %d\n", rc); + return rc; + } + + + /* Initialize the mass storage and scsi interfaces */ + rc = MS_Init( &_blkSize, &_numBlks, inquiryResult ); + if (rc != OK) + { + fprintf(stderr, "Could not initialize mass storage interface: %d\n", rc); + return rc; + } + printf("Successfully initialized mass storage interface; %d blocks of size %d\n", _numBlks, _blkSize); + print_inquiry(inquiryResult); + // FATFileSystem supports only 512-byte blocks + return _blkSize == 512 ? OK : 1; +} + + +