diff options
| author | hathach <[email protected]> | 2013-11-05 14:55:58 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2013-11-05 14:55:58 +0700 |
| commit | 024858a605c78927f637cadd5e5c5b7764a496bd (patch) | |
| tree | db0a2b755e5849f056518ba03107b42958dcfaf0 | |
| parent | 83d9ececfb1445c46b0a85da073d10ad932e6d4d (diff) | |
complete msc device demo with 8KB ram disk
| -rw-r--r-- | demos/device/device_os_none/mscd_app.c | 98 |
1 files changed, 92 insertions, 6 deletions
diff --git a/demos/device/device_os_none/mscd_app.c b/demos/device/device_os_none/mscd_app.c index 1327e6a45..b92b53e52 100644 --- a/demos/device/device_os_none/mscd_app.c +++ b/demos/device/device_os_none/mscd_app.c @@ -48,7 +48,7 @@ //--------------------------------------------------------------------+
enum
{
- DISK_BLOCK_NUM = 16,
+ DISK_BLOCK_NUM = 16, // 8KB is the smallest size that windows allow to mount
DISK_BLOCK_SIZE = 512
};
@@ -78,9 +78,35 @@ typedef ATTR_PACKED_STRUCT(struct) { uint8_t filesystem_type[8] ; ///< File system type label in ASCII, padded with blank (0x20). Standard values include "FAT," "FAT12," and "FAT16," but nothing is required.
uint8_t reserved2[448] ;
uint16_t fat_signature ; ///< Signature value (0xAA55).
-}fat16_boot_sector_t;
+}fat12_boot_sector_t;
-STATIC_ASSERT(sizeof(fat16_boot_sector_t) == 512, "size is not correct");
+STATIC_ASSERT(sizeof(fat12_boot_sector_t) == 512, "size is not correct");
+
+typedef ATTR_PACKED_STRUCT(struct) {
+ uint8_t name[11];
+
+ ATTR_PACKED_STRUCT(struct){
+ uint8_t readonly : 1;
+ uint8_t hidden : 1;
+ uint8_t system : 1;
+ uint8_t volume_label : 1;
+ uint8_t directory : 1;
+ uint8_t archive : 1;
+ } attr; // Long File Name = 0x0f
+
+ uint8_t reserved;
+ uint8_t created_time_tenths_of_seconds;
+ uint16_t created_time;
+ uint16_t created_date;
+ uint16_t accessed_date;
+ uint16_t cluster_high;
+ uint16_t written_time;
+ uint16_t written_date;
+ uint16_t cluster_low;
+ uint32_t file_size;
+}fat_directory_t;
+
+STATIC_ASSERT(sizeof(fat_directory_t) == 32, "size is not correct");
static scsi_inquiry_data_t mscd_inquiry_data TUSB_CFG_ATTR_USBRAM =
{
@@ -133,7 +159,15 @@ static uint16_t read10(uint8_t coreid, uint8_t lun, scsi_read10_t* p_read10, voi {
uint8_t block_count = __be2h_16(p_read10->block_count);
- (*pp_buffer) = &mscd_app_ramdisk[ __be2le(p_read10->lba)];
+ (*pp_buffer) = mscd_app_ramdisk[ __be2le(p_read10->lba)];
+
+ return block_count*DISK_BLOCK_SIZE;
+}
+
+static uint16_t write10(uint8_t coreid, uint8_t lun, scsi_read10_t* p_read10, void** pp_buffer)
+{
+ uint8_t block_count = __be2h_16(p_read10->block_count);
+ (*pp_buffer) = mscd_app_ramdisk[ __be2le(p_read10->lba)];
return block_count*DISK_BLOCK_SIZE;
}
@@ -182,6 +216,7 @@ msc_csw_status_t tusbd_msc_scsi_received_isr (uint8_t coreid, uint8_t lun, uint8 break;
case SCSI_CMD_WRITE_10:
+ (*p_length) = write10(coreid, lun, (scsi_read10_t*) scsi_cmd, pp_buffer);
break;
default: return MSC_CSW_STATUS_FAILED;
@@ -193,10 +228,26 @@ msc_csw_status_t tusbd_msc_scsi_received_isr (uint8_t coreid, uint8_t lun, uint8 //--------------------------------------------------------------------+
// IMPLEMENTATION
//--------------------------------------------------------------------+
+void fat12_fs_init(uint8_t mscd_app_ramdisk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE]);
+
void msc_dev_app_init (void)
{
- fat16_boot_sector_t* p_boot_fat = (fat16_boot_sector_t* ) &mscd_app_ramdisk[0];
- memclr_(p_boot_fat, sizeof(fat16_boot_sector_t));
+ fat12_fs_init(mscd_app_ramdisk);
+}
+
+//--------------------------------------------------------------------+
+// HELPER
+//--------------------------------------------------------------------+
+void fat12_fs_init(uint8_t mscd_app_ramdisk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE])
+{
+ uint8_t const readme_contents[] =
+"This is tinyusb's MassStorage Class demo.\r\n\r\n\
+If you find any bugs or get any questions, feel free to file an\r\n\
+issue at https://github.com/hathach/tinyusb";
+
+ //------------- Boot Sector -------------//
+ fat12_boot_sector_t* p_boot_fat = (fat12_boot_sector_t* ) mscd_app_ramdisk[0];
+ memclr_(p_boot_fat, sizeof(fat12_boot_sector_t));
memcpy(p_boot_fat->jump_code, "\xEB\x3C\x90", 3);
memcpy(p_boot_fat->oem_name, "MSDOS5.0", 8);
@@ -218,5 +269,40 @@ void msc_dev_app_init (void) memcpy(p_boot_fat->volume_label , "tinyusb msc", 11);
memcpy(p_boot_fat->filesystem_type, "FAT12 ", 8);
p_boot_fat->fat_signature = 0xAA55;
+
+ //------------- FAT12 Table (first 2 entries are F8FF, third entry is cluster end of readme file-------------//
+ memcpy(mscd_app_ramdisk[1], "\xF8\xFF\xFF\xFF\x0F", 5);
+
+ //------------- Root Directory -------------//
+ fat_directory_t* p_entry = (fat_directory_t*) mscd_app_ramdisk[2];
+
+ // first entry is volume label
+ (*p_entry) = (fat_directory_t)
+ {
+ .name = "TINYUSB MSC",
+ .attr.volume_label = 1,
+ };
+
+ p_entry += 1; // advance to second entry, second entry is readme file
+ (*p_entry) = (fat_directory_t)
+ {
+ .name = "README TXT",
+
+ .created_time = 0x6D52,
+ .written_time = 0x6D52,
+
+ .created_date = 0x4365,
+ .accessed_date = 0x4365,
+ .written_date = 0x4365,
+
+ .cluster_high = 0,
+ .cluster_low = 2,
+ .file_size = sizeof(readme_contents)-1 // exculde NULL
+ }; // first entry is volume label
+
+ //------------- Readme Content -------------//
+ memcpy(mscd_app_ramdisk[3], readme_contents, sizeof(readme_contents)-1);
+
}
+
#endif
|
