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
- Committer:
- emh203
- Date:
- 2011-01-23
- Revision:
- 0:2dbbafe1b1fb
File content as of revision 0:2dbbafe1b1fb:
/*-----------------------------------------------------------------------*/
/* 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;
}
Eli Hughes