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
CHAN_FS/diskio.c@0:2dbbafe1b1fb, 2011-01-23 (annotated)
- Committer:
- emh203
- Date:
- Sun Jan 23 18:35:43 2011 +0000
- Revision:
- 0:2dbbafe1b1fb
1st test version. Test with raw mbed and Samtec USB-RA type A connector wired directly to pins.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
emh203 | 0:2dbbafe1b1fb | 1 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:2dbbafe1b1fb | 2 | /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */ |
emh203 | 0:2dbbafe1b1fb | 3 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:2dbbafe1b1fb | 4 | /* This is a stub disk I/O module that acts as front end of the existing */ |
emh203 | 0:2dbbafe1b1fb | 5 | /* disk I/O modules and attach it to FatFs module with common interface. */ |
emh203 | 0:2dbbafe1b1fb | 6 | /*-----------------------------------------------------------------------*/ |
emh203 | 0:2dbbafe1b1fb | 7 | |
emh203 | 0:2dbbafe1b1fb | 8 | #include "diskio.h" |
emh203 | 0:2dbbafe1b1fb | 9 | #include "usbhost_inc.h" |
emh203 | 0:2dbbafe1b1fb | 10 | #include "mbed.h" |
emh203 | 0:2dbbafe1b1fb | 11 | |
emh203 | 0:2dbbafe1b1fb | 12 | uint32_t _numBlks = 0; |
emh203 | 0:2dbbafe1b1fb | 13 | uint32_t _blkSize = 512; |
emh203 | 0:2dbbafe1b1fb | 14 | |
emh203 | 0:2dbbafe1b1fb | 15 | int initialise_msc(); |
emh203 | 0:2dbbafe1b1fb | 16 | void print_inquiry(USB_INT08U *inqReply); |
emh203 | 0:2dbbafe1b1fb | 17 | |
emh203 | 0:2dbbafe1b1fb | 18 | |
emh203 | 0:2dbbafe1b1fb | 19 | int disk_sync() { return 0; } |
emh203 | 0:2dbbafe1b1fb | 20 | int disk_sectors() { return _numBlks; } |
emh203 | 0:2dbbafe1b1fb | 21 | |
emh203 | 0:2dbbafe1b1fb | 22 | DWORD get_fattime(void) |
emh203 | 0:2dbbafe1b1fb | 23 | { |
emh203 | 0:2dbbafe1b1fb | 24 | time_t CurrentTimeStamp; |
emh203 | 0:2dbbafe1b1fb | 25 | tm *CurrentLocalTime; |
emh203 | 0:2dbbafe1b1fb | 26 | DWORD FATFSTimeCode; |
emh203 | 0:2dbbafe1b1fb | 27 | |
emh203 | 0:2dbbafe1b1fb | 28 | CurrentTimeStamp = time(NULL); |
emh203 | 0:2dbbafe1b1fb | 29 | CurrentLocalTime = localtime(&CurrentTimeStamp); |
emh203 | 0:2dbbafe1b1fb | 30 | |
emh203 | 0:2dbbafe1b1fb | 31 | //Map the tm struct time into the FatFs time code |
emh203 | 0:2dbbafe1b1fb | 32 | FATFSTimeCode = ((CurrentLocalTime->tm_year-80)<<25) | |
emh203 | 0:2dbbafe1b1fb | 33 | ((CurrentLocalTime->tm_mon+1)<<21) | |
emh203 | 0:2dbbafe1b1fb | 34 | ((CurrentLocalTime->tm_mday)<<16) | |
emh203 | 0:2dbbafe1b1fb | 35 | ((CurrentLocalTime->tm_hour)<<11) | |
emh203 | 0:2dbbafe1b1fb | 36 | ((CurrentLocalTime->tm_min)<<5) | |
emh203 | 0:2dbbafe1b1fb | 37 | ((CurrentLocalTime->tm_sec)); |
emh203 | 0:2dbbafe1b1fb | 38 | |
emh203 | 0:2dbbafe1b1fb | 39 | return FATFSTimeCode; |
emh203 | 0:2dbbafe1b1fb | 40 | } |
emh203 | 0:2dbbafe1b1fb | 41 | |
emh203 | 0:2dbbafe1b1fb | 42 | DSTATUS disk_status(BYTE Drive) |
emh203 | 0:2dbbafe1b1fb | 43 | { |
emh203 | 0:2dbbafe1b1fb | 44 | return 0; |
emh203 | 0:2dbbafe1b1fb | 45 | } |
emh203 | 0:2dbbafe1b1fb | 46 | |
emh203 | 0:2dbbafe1b1fb | 47 | |
emh203 | 0:2dbbafe1b1fb | 48 | DRESULT disk_ioctl ( |
emh203 | 0:2dbbafe1b1fb | 49 | BYTE drv, /* Physical drive nmuber (0..) */ |
emh203 | 0:2dbbafe1b1fb | 50 | BYTE ctrl, /* Control code */ |
emh203 | 0:2dbbafe1b1fb | 51 | void *buff /* Buffer to send/receive control data */ |
emh203 | 0:2dbbafe1b1fb | 52 | ) |
emh203 | 0:2dbbafe1b1fb | 53 | { |
emh203 | 0:2dbbafe1b1fb | 54 | DRESULT res; |
emh203 | 0:2dbbafe1b1fb | 55 | |
emh203 | 0:2dbbafe1b1fb | 56 | switch(ctrl) |
emh203 | 0:2dbbafe1b1fb | 57 | { |
emh203 | 0:2dbbafe1b1fb | 58 | case CTRL_SYNC: |
emh203 | 0:2dbbafe1b1fb | 59 | res = RES_OK; |
emh203 | 0:2dbbafe1b1fb | 60 | break; |
emh203 | 0:2dbbafe1b1fb | 61 | |
emh203 | 0:2dbbafe1b1fb | 62 | case GET_SECTOR_SIZE: |
emh203 | 0:2dbbafe1b1fb | 63 | res = RES_OK; |
emh203 | 0:2dbbafe1b1fb | 64 | *(WORD *)buff = 512; |
emh203 | 0:2dbbafe1b1fb | 65 | break; |
emh203 | 0:2dbbafe1b1fb | 66 | |
emh203 | 0:2dbbafe1b1fb | 67 | case GET_SECTOR_COUNT: |
emh203 | 0:2dbbafe1b1fb | 68 | res = RES_OK; |
emh203 | 0:2dbbafe1b1fb | 69 | *(DWORD *)buff = (WORD)disk_sectors(); |
emh203 | 0:2dbbafe1b1fb | 70 | break; |
emh203 | 0:2dbbafe1b1fb | 71 | |
emh203 | 0:2dbbafe1b1fb | 72 | case GET_BLOCK_SIZE: |
emh203 | 0:2dbbafe1b1fb | 73 | res = RES_OK; |
emh203 | 0:2dbbafe1b1fb | 74 | *(DWORD *)buff = 1; |
emh203 | 0:2dbbafe1b1fb | 75 | break; |
emh203 | 0:2dbbafe1b1fb | 76 | |
emh203 | 0:2dbbafe1b1fb | 77 | default: |
emh203 | 0:2dbbafe1b1fb | 78 | res = RES_OK; |
emh203 | 0:2dbbafe1b1fb | 79 | break; |
emh203 | 0:2dbbafe1b1fb | 80 | } |
emh203 | 0:2dbbafe1b1fb | 81 | return res; |
emh203 | 0:2dbbafe1b1fb | 82 | } |
emh203 | 0:2dbbafe1b1fb | 83 | |
emh203 | 0:2dbbafe1b1fb | 84 | DSTATUS disk_initialize(BYTE Drive) { |
emh203 | 0:2dbbafe1b1fb | 85 | |
emh203 | 0:2dbbafe1b1fb | 86 | if ( initialise_msc() != OK ) |
emh203 | 0:2dbbafe1b1fb | 87 | return 1; |
emh203 | 0:2dbbafe1b1fb | 88 | return 0; |
emh203 | 0:2dbbafe1b1fb | 89 | } |
emh203 | 0:2dbbafe1b1fb | 90 | |
emh203 | 0:2dbbafe1b1fb | 91 | DRESULT disk_write(BYTE Drive,const BYTE * Buffer, DWORD SectorNumber, BYTE SectorCount) |
emh203 | 0:2dbbafe1b1fb | 92 | { |
emh203 | 0:2dbbafe1b1fb | 93 | if ( OK == MS_BulkSend(SectorNumber, SectorCount, (USB_INT08U *)Buffer) ) |
emh203 | 0:2dbbafe1b1fb | 94 | return RES_OK; |
emh203 | 0:2dbbafe1b1fb | 95 | return RES_ERROR; |
emh203 | 0:2dbbafe1b1fb | 96 | } |
emh203 | 0:2dbbafe1b1fb | 97 | |
emh203 | 0:2dbbafe1b1fb | 98 | DRESULT disk_read(BYTE Drive, BYTE * Buffer,DWORD SectorNumber, BYTE SectorCount) |
emh203 | 0:2dbbafe1b1fb | 99 | { |
emh203 | 0:2dbbafe1b1fb | 100 | if ( OK == MS_BulkRecv(SectorNumber, SectorCount, (USB_INT08U *)Buffer) ) |
emh203 | 0:2dbbafe1b1fb | 101 | return RES_OK; |
emh203 | 0:2dbbafe1b1fb | 102 | return RES_ERROR; |
emh203 | 0:2dbbafe1b1fb | 103 | } |
emh203 | 0:2dbbafe1b1fb | 104 | |
emh203 | 0:2dbbafe1b1fb | 105 | |
emh203 | 0:2dbbafe1b1fb | 106 | |
emh203 | 0:2dbbafe1b1fb | 107 | |
emh203 | 0:2dbbafe1b1fb | 108 | |
emh203 | 0:2dbbafe1b1fb | 109 | void print_inquiry(USB_INT08U *inqReply) |
emh203 | 0:2dbbafe1b1fb | 110 | { |
emh203 | 0:2dbbafe1b1fb | 111 | // see USB Mass Storage Class � UFI Command Specification, |
emh203 | 0:2dbbafe1b1fb | 112 | // 4.2 INQUIRY Command |
emh203 | 0:2dbbafe1b1fb | 113 | printf("Inquiry reply:\n"); |
emh203 | 0:2dbbafe1b1fb | 114 | uint8_t tmp = inqReply[0]&0x1F; |
emh203 | 0:2dbbafe1b1fb | 115 | printf("Peripheral device type: %02Xh\n", tmp); |
emh203 | 0:2dbbafe1b1fb | 116 | if ( tmp == 0 ) |
emh203 | 0:2dbbafe1b1fb | 117 | printf("\t- Direct access (floppy)\n"); |
emh203 | 0:2dbbafe1b1fb | 118 | else if ( tmp == 0x1F ) |
emh203 | 0:2dbbafe1b1fb | 119 | printf("\t- none (no FDD connected)\n"); |
emh203 | 0:2dbbafe1b1fb | 120 | else |
emh203 | 0:2dbbafe1b1fb | 121 | printf("\t- unknown type\n"); |
emh203 | 0:2dbbafe1b1fb | 122 | tmp = inqReply[1] >> 7; |
emh203 | 0:2dbbafe1b1fb | 123 | printf("Removable Media Bit: %d\n", tmp); |
emh203 | 0:2dbbafe1b1fb | 124 | tmp = inqReply[2] & 3; |
emh203 | 0:2dbbafe1b1fb | 125 | printf("ANSI Version: %02Xh\n", tmp); |
emh203 | 0:2dbbafe1b1fb | 126 | if ( tmp != 0 ) |
emh203 | 0:2dbbafe1b1fb | 127 | printf("\t- warning! must be 0\n"); |
emh203 | 0:2dbbafe1b1fb | 128 | tmp = (inqReply[2]>>3) & 3; |
emh203 | 0:2dbbafe1b1fb | 129 | printf("ECMA Version: %02Xh\n", tmp); |
emh203 | 0:2dbbafe1b1fb | 130 | if ( tmp != 0 ) |
emh203 | 0:2dbbafe1b1fb | 131 | printf("\t- warning! should be 0\n"); |
emh203 | 0:2dbbafe1b1fb | 132 | tmp = inqReply[2]>>6; |
emh203 | 0:2dbbafe1b1fb | 133 | printf("ISO Version: %02Xh\n", tmp); |
emh203 | 0:2dbbafe1b1fb | 134 | if ( tmp != 0 ) |
emh203 | 0:2dbbafe1b1fb | 135 | printf("\t- warning! should be 0\n"); |
emh203 | 0:2dbbafe1b1fb | 136 | tmp = inqReply[3] & 0xF; |
emh203 | 0:2dbbafe1b1fb | 137 | printf("Response Data Format: %02Xh\n", tmp); |
emh203 | 0:2dbbafe1b1fb | 138 | if ( tmp != 1 ) |
emh203 | 0:2dbbafe1b1fb | 139 | printf("\t- warning! should be 1\n"); |
emh203 | 0:2dbbafe1b1fb | 140 | tmp = inqReply[4]; |
emh203 | 0:2dbbafe1b1fb | 141 | printf("Additional length: %02Xh\n", tmp); |
emh203 | 0:2dbbafe1b1fb | 142 | if ( tmp != 0x1F ) |
emh203 | 0:2dbbafe1b1fb | 143 | printf("\t- warning! should be 1Fh\n"); |
emh203 | 0:2dbbafe1b1fb | 144 | printf("Vendor Information: '%.8s'\n", &inqReply[8]); |
emh203 | 0:2dbbafe1b1fb | 145 | printf("Product Identification: '%.16s'\n", &inqReply[16]); |
emh203 | 0:2dbbafe1b1fb | 146 | printf("Product Revision: '%.4s'\n", &inqReply[32]); |
emh203 | 0:2dbbafe1b1fb | 147 | } |
emh203 | 0:2dbbafe1b1fb | 148 | |
emh203 | 0:2dbbafe1b1fb | 149 | |
emh203 | 0:2dbbafe1b1fb | 150 | |
emh203 | 0:2dbbafe1b1fb | 151 | int initialise_msc() |
emh203 | 0:2dbbafe1b1fb | 152 | { |
emh203 | 0:2dbbafe1b1fb | 153 | USB_INT32S rc; |
emh203 | 0:2dbbafe1b1fb | 154 | USB_INT08U inquiryResult[INQUIRY_LENGTH]; |
emh203 | 0:2dbbafe1b1fb | 155 | |
emh203 | 0:2dbbafe1b1fb | 156 | //print_clock(); |
emh203 | 0:2dbbafe1b1fb | 157 | Host_Init(); /* Initialize the host controller */ |
emh203 | 0:2dbbafe1b1fb | 158 | rc = Host_EnumDev(); /* Enumerate the device connected */ |
emh203 | 0:2dbbafe1b1fb | 159 | if (rc != OK) |
emh203 | 0:2dbbafe1b1fb | 160 | { |
emh203 | 0:2dbbafe1b1fb | 161 | fprintf(stderr, "Could not enumerate device: %d\n", rc); |
emh203 | 0:2dbbafe1b1fb | 162 | return rc; |
emh203 | 0:2dbbafe1b1fb | 163 | } |
emh203 | 0:2dbbafe1b1fb | 164 | |
emh203 | 0:2dbbafe1b1fb | 165 | |
emh203 | 0:2dbbafe1b1fb | 166 | /* Initialize the mass storage and scsi interfaces */ |
emh203 | 0:2dbbafe1b1fb | 167 | rc = MS_Init( &_blkSize, &_numBlks, inquiryResult ); |
emh203 | 0:2dbbafe1b1fb | 168 | if (rc != OK) |
emh203 | 0:2dbbafe1b1fb | 169 | { |
emh203 | 0:2dbbafe1b1fb | 170 | fprintf(stderr, "Could not initialize mass storage interface: %d\n", rc); |
emh203 | 0:2dbbafe1b1fb | 171 | return rc; |
emh203 | 0:2dbbafe1b1fb | 172 | } |
emh203 | 0:2dbbafe1b1fb | 173 | printf("Successfully initialized mass storage interface; %d blocks of size %d\n", _numBlks, _blkSize); |
emh203 | 0:2dbbafe1b1fb | 174 | print_inquiry(inquiryResult); |
emh203 | 0:2dbbafe1b1fb | 175 | // FATFileSystem supports only 512-byte blocks |
emh203 | 0:2dbbafe1b1fb | 176 | return _blkSize == 512 ? OK : 1; |
emh203 | 0:2dbbafe1b1fb | 177 | } |
emh203 | 0:2dbbafe1b1fb | 178 | |
emh203 | 0:2dbbafe1b1fb | 179 | |
emh203 | 0:2dbbafe1b1fb | 180 |