USB Device ROM Stack API example program
LPC1549のROM APIを使ったRAMディスクです。PCからはUSBメモリとして見えます。
参考:
http://docs.lpcware.com/usbromlib/v1.0/
Revision 0:ef2c0c52abc4, committed 2014-03-14
- Comitter:
- va009039
- Date:
- Fri Mar 14 09:14:16 2014 +0000
- Commit message:
- first commit
Changed in this revision
diff -r 000000000000 -r ef2c0c52abc4 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Mar 14 09:14:16 2014 +0000 @@ -0,0 +1,16 @@ +#if defined(TARGET_LPC1549) +#include "mbed.h" +#include <rl_usb.h> + +DigitalOut led1(LED1); + +int main() { + usbd_init(); + usbd_connect(1); + while(1) { + led1 = !led1; + wait_ms(500); + } +} + +#endif
diff -r 000000000000 -r ef2c0c52abc4 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Mar 14 09:14:16 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/8e73be2a2ac1 \ No newline at end of file
diff -r 000000000000 -r ef2c0c52abc4 rl_usb.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rl_usb.h Fri Mar 14 09:14:16 2014 +0000 @@ -0,0 +1,41 @@ +/* CMSIS-DAP Interface Firmware + * Copyright (c) 2009-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __RL_USB_H__ +#define __RL_USB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include "usb.h" + +/***************** Functions *************************************************/ + +/* USB Device functions exported from USB Device Core module */ +extern void usbd_init (void); +extern void usbd_connect (uint8_t con); + +/* USB Device user functions imported to USB Mass Storage Class module */ +extern void usbd_msc_init (void); +extern void usbd_msc_read_sect (uint32_t block, uint8_t *buf, uint32_t num_of_blocks); +extern void usbd_msc_write_sect (uint32_t block, uint8_t *buf, uint32_t num_of_blocks); + +#ifdef __cplusplus +} +#endif + +#endif /* __RL_USB_H__ */
diff -r 000000000000 -r ef2c0c52abc4 usb.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usb.c Fri Mar 14 09:14:16 2014 +0000 @@ -0,0 +1,226 @@ +#if defined(TARGET_LPC1549) +#include "LPC15xx.h" +#define ROM_API_ADDR (0x03000200) +#else +#error "target error" +#endif +#include <rl_usb.h> +#include <string.h> + +USBD_API_T* pUsbApi; +USBD_HANDLE_T hUsb; + +uint32_t USBD_MSC_MemorySize; +uint32_t USBD_MSC_BlockSize; +uint32_t USBD_MSC_BlockGroup; +uint32_t USBD_MSC_BlockCount; +uint8_t* USBD_MSC_BlockBuf; +uint8_t USBD_MSC_MediaReady; + +extern void USBD_Init(void); // interface/*/usbd_*.c +extern void USBD_Connect(uint8_t con); + +static USBD_API_INIT_PARAM_T usb_param; +static USB_CORE_DESCS_T desc; +static USBD_MSC_INIT_PARAM_T msc_param; + +static uint8_t usbmem[2048] __attribute__ ((aligned(2048))); +static uint8_t* mem_base; +static uint32_t mem_size; + +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) + +/* USB Standard Device Descriptor */ +static const uint8_t USB_DeviceDescriptor[] = { + 18, /* bLength */ + 1, /* USB_DEVICE_DESCRIPTOR_TYPE, bDescriptorType */ + WBVAL(0x0200), /* 2.00 bcdUSB */ + 0x00, /* bDeviceClass */ + 0x00, /* bDeviceSubClass */ + 0x00, /* bDeviceProtocol */ + 64, /* USB_MAX_PACKET0, bMaxPacketSize0 */ + WBVAL(0x0d28), /* idVendor */ + WBVAL(0x0204), /* idProduct */ + WBVAL(0x0001), /* bcdDevice */ + 1, /* iManufacturer */ + 2, /* iProduct */ + 3, /* iSerialNumber */ + 1 /* bNumConfigurations */ +}; + +/* USB FSConfiguration Descriptor */ +/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ +static const uint8_t USB_FsConfigDescriptor[] = { +/* Configuration 1 */ + 9, /* USB_CONFIGUARTION_DESC_SIZE, bLength */ + 2, /* USB_CONFIGURATION_DESCRIPTOR_TYPE, bDescriptorType */ + WBVAL(9 + 9 + 7 * 2),/* wTotalLength */ + 0x01, /* bNumInterfaces */ + 0x01, /* bConfigurationValue */ + 0x00, /* iConfiguration */ + 0xc0, /* USB_CONFIG_SELF_POWERED, bmAttributes */ + 50, /* USB_CONFIG_POWER_MA(100), bMaxPower */ +/* Interface 0, Alternate Setting 0, MSC Class */ + 9, /* USB_INTERFACE_DESC_SIZE, bLength */ + 4, /* USB_INTERFACE_DESCRIPTOR_TYPE, bDescriptorType */ + 0, /* bInterfaceNumber */ + 0, /* bAlternateSetting */ + 2, /* bNumEndpoints */ + 0x08, /* USB_DEVICE_CLASS_STORAGE, bInterfaceClass */ + 0x06, /* MSC_SUBCLASS_SCSI, bInterfaceSubClass */ + 0x50, /* MSC_PROTOCOL_BULK_ONLY, bInterfaceProtocol */ + 0x05, /* iInterface */ +/* Bulk In Endpoint */ + 7, /* USB_ENDPOINT_DESC_SIZE, bLength */ + 5, /* USB_ENDPOINT_DESCRIPTOR_TYPE, bDescriptorType */ + 0x01, /* MSC_EP_IN, bEndpointAddress */ + 0x02, /* USB_ENDPOINT_TYPE_BULK, bmAttributes */ + WBVAL(64), /* WBVAL(USB_FS_MAX_BULK_PACKET), wMaxPacketSize */ + 0, /* bInterval */ +/* Bulk Out Endpoint */ + 7, /* USB_ENDPOINT_DESC_SIZE, bLength */ + 5, /* USB_ENDPOINT_DESCRIPTOR_TYPE bDescriptorType */ + 0x81, /* MSC_EP_OUT bEndpointAddress */ + 0x02, /* USB_ENDPOINT_TYPE_BULK bmAttributes */ + WBVAL(64), /* WBVAL(USB_FS_MAX_BULK_PACKET) wMaxPacketSize */ + 0, /* bInterval */ +/* Terminator */ + 0 /* bLength */ +}; + +/* USB String Descriptor (optional) */ +static const uint8_t USB_StringDescriptor[] = { + /* Index 0x00: LANGID Codes */ + 4, /* bLength */ + 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ + WBVAL(0x0409),/* US English wLANGID */ + /* Index 0x01: Manufacturer */ + (8*2 + 2), /* bLength (8 Char + Type + lenght) */ + 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ + 'm', 0, 'b', 0, 'e', 0, 'd', 0, '.', 0, 'o', 0, 'r', 0, 'g', 0, /* mbed.org */ + /* Index 0x02: Product */ + (14*2 + 2), /* bLength (14 Char + Type + lenght) */ + 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ + 'M', 0, 'B', 0, 'E', 0, ' ', 0, 'D', 0, /* MBED_ */ + 'C', 0, 'M', 0, 'S', 0, 'I', 0, 'S', 0, '-', 0, 'D', 0, 'A', 0, 'P', 0, /* CMSIS-DAP */ + /* Index 0x03: Serial Number */ + (10*2 + 2), /* bLength (10 Char + Type + lenght) */ + 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ + '0', 0, '1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0, '9', 0, + /* Index 0x04: Interface 0, Alternate Setting 0 */ + (3*2 + 2), /* bLength (3 Char + Type + lenght) */ + 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ + 'M', 0, 'S', 0, 'D', 0, + /* Index 0x05: Interface 1, Alternate Setting 0 */ + (3*2 + 2), /* bLength (3 Char + Type + lenght) */ + 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ + 'U', 0, 'S', 0, 'B', 0, +}; + +static const uint8_t InquiryStr[28] = { + 'M', 'B', 'E', 'D', '.', 'O', 'R', 'G', 'M', 'B', + 'E', 'D', ' ', 'U', 'S', 'B', ' ', 'D', 'I', 'S', + 'K', ' ', ' ', ' ', '1', '.', '0', ' ' +}; + + +static uint8_t MSC_buf[512]; +static void MSC_Read(uint32_t offset, uint8_t** buff_adr, uint32_t length, uint32_t high_offset) +{ + int i, j; + if (offset % 512 == 0) { /* head chunk ? */ + usbd_msc_read_sect(offset / 512, MSC_buf, 1); + } + j = offset % 512; + for (i = 0; i < length; i++, j++) { + (*buff_adr)[i] = MSC_buf[j]; + } +} + +static void MSC_Write(uint32_t offset, uint8_t** buff_adr, uint32_t length, uint32_t high_offset) +{ + int i, j; + j = offset % 512; + for(i = 0; i < length; i++, j++) { + MSC_buf[j] = (*buff_adr)[i]; + } + if ((offset % 512) + length == 512) { /* tail chunk ? */ + usbd_msc_write_sect(offset / 512, MSC_buf, 1); + } +} + +static ErrorCode_t MSC_Verify(uint32_t offset, uint8_t* src, uint32_t length, uint32_t high_offset) +{ + return LPC_OK; +} + +static void USBD_MSC_Init(void) { + ErrorCode_t ret; + + usbd_msc_init(); + memset((void*)&msc_param, 0, sizeof(msc_param)); + msc_param.mem_base = mem_base; + msc_param.mem_size = mem_size; + + /* mass storage paramas */ + msc_param.InquiryStr = InquiryStr; + msc_param.BlockCount = USBD_MSC_BlockCount; + msc_param.BlockSize = USBD_MSC_BlockSize; + msc_param.MemorySize = USBD_MSC_MemorySize; + msc_param.intf_desc = USB_FsConfigDescriptor + 9; + + /* user defined functions */ + msc_param.MSC_Write = MSC_Write; + msc_param.MSC_Read = MSC_Read; + msc_param.MSC_Verify = MSC_Verify; + + ret = pUsbApi->msc->init(hUsb, &msc_param); + if (ret == LPC_OK) { + /* update memory variables */ + mem_base = msc_param.mem_base; + mem_size = msc_param.mem_size; + } +} + +void usbd_init(void) +{ + ErrorCode_t ret; + + USBD_Init(); + + /* get USB API table pointer */ + pUsbApi = (USBD_API_T*)((*(ROM **)ROM_API_ADDR)->pUSBD); + + mem_base = usbmem; + mem_size = sizeof(usbmem); + + /* initilize call back structures */ + memset((void*)&usb_param, 0, sizeof(usb_param)); + usb_param.usb_reg_base = LPC_USB_BASE; + usb_param.mem_base = mem_base; + usb_param.mem_size = mem_size; + usb_param.max_num_ep = 2; + + /* Initialize Descriptor pointers */ + memset((void*)&desc, 0, sizeof(desc)); + desc.device_desc = USB_DeviceDescriptor; + desc.string_desc = USB_StringDescriptor; + desc.full_speed_desc = USB_FsConfigDescriptor; + desc.high_speed_desc = USB_FsConfigDescriptor; + + /* USB Initialization */ + ret = pUsbApi->hw->Init(&hUsb, &desc, &usb_param); + if (ret == LPC_OK) { + mem_base = usb_param.mem_base; + mem_size = usb_param.mem_size; + USBD_MSC_Init(); + } +} + +void usbd_connect(uint8_t con) +{ + USBD_Connect(con); + if (con) { + pUsbApi->hw->Connect(hUsb, 1); + } +}
diff -r 000000000000 -r ef2c0c52abc4 usb.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usb.h Fri Mar 14 09:14:16 2014 +0000 @@ -0,0 +1,108 @@ +#ifndef _USB_H_ +#define _USB_H_ + +typedef enum { + LPC_OK=0, +} ErrorCode_t; + +typedef uint32_t USBD_HANDLE_T; +typedef void* USB_CB_T; +typedef void* USB_PARAM_CB_T; + +typedef struct _USB_CORE_DESCS_T { + const uint8_t *device_desc; + const uint8_t *string_desc; + const uint8_t *full_speed_desc; + const uint8_t *high_speed_desc; + const uint8_t *device_qualifier; +} USB_CORE_DESCS_T; + +typedef struct USBD_API_INIT_PARAM { + uint32_t usb_reg_base; + uint8_t* mem_base; + uint32_t mem_size; + uint8_t max_num_ep; + uint8_t pad0[3]; + USB_CB_T USB_Reset_Event; + USB_CB_T USB_Suspend_Event; + USB_CB_T USB_Resume_Event; + USB_CB_T reserved_sbz; + USB_CB_T USB_SOF_Event; + USB_PARAM_CB_T USB_WakeUpCfg; + USB_PARAM_CB_T USB_Power_Event; + USB_PARAM_CB_T USB_Error_Event; + USB_CB_T USB_Configure_Event; + USB_CB_T USB_Interface_Event; + USB_CB_T USB_Feature_Event; + uint32_t (* virt_to_phys)(void* vaddr); + void (* cache_flush)(uint32_t* start_adr, uint32_t* end_adr); +} USBD_API_INIT_PARAM_T; + +typedef struct USBD_HW_API { + uint32_t (*GetMemSize)(USBD_API_INIT_PARAM_T* param); + ErrorCode_t (*Init)(USBD_HANDLE_T* phUsb, USB_CORE_DESCS_T* pDesc, USBD_API_INIT_PARAM_T* param); + void (*Connect)(USBD_HANDLE_T hUsb, uint32_t con); + void (*ISR)(USBD_HANDLE_T hUsb); +} USBD_HW_API_T; + +typedef struct USBD_CORE_API { + void* dummy; + //TODO +} USBD_CORE_API_T; + +typedef struct USBD_MSC_INIT_PARAM { + uint8_t* mem_base; + uint32_t mem_size; + const uint8_t* InquiryStr; + uint32_t BlockCount; + uint32_t BlockSize; + uint32_t MemorySize; + const uint8_t* intf_desc; + void (*MSC_Write)(uint32_t offset, uint8_t** src, uint32_t length, uint32_t high_offset); + void (*MSC_Read)(uint32_t offset, uint8_t** dst, uint32_t length, uint32_t high_offset); + ErrorCode_t (*MSC_Verify)(uint32_t offset, uint8_t buf[], uint32_t length, uint32_t high_offset); + void (*MSC_GetWriteBuf)(uint32_t offset, uint8_t** buff_adr, uint32_t length, uint32_t high_offset); + ErrorCode_t (*MSC_Ep0_Hdlr)(USBD_HANDLE_T hUsb, void* data, uint32_t event); + uint64_t MemorySize64; +} USBD_MSC_INIT_PARAM_T; + +typedef struct USBD_MSC_API { + uint32_t (*GetMemSize)(USBD_MSC_INIT_PARAM_T* param); + ErrorCode_t (*init)(USBD_HANDLE_T hUsb, USBD_MSC_INIT_PARAM_T* param); +} USBD_MSC_API_T; + +typedef struct USBD_HID_API { + void* dummy; + // TODO +} USBD_HID_API_T; +typedef struct USBD_CDC_API { + void* dummy; + // TODO +} USBD_CDC_API_T; + +typedef struct USBD_API { + const USBD_HW_API_T* hw; + const USBD_CORE_API_T* core; + const USBD_MSC_API_T* msc; + const void* dfu; + const USBD_HID_API_T* hid; + const USBD_CDC_API_T* cdc; + const uint32_t* reserved6; + uint32_t version; +} USBD_API_T; + +typedef struct _ROM { + const USBD_API_T * pUSBD; +} ROM; + +extern USBD_API_T* pUsbApi; +extern USBD_HANDLE_T hUsb; + +extern uint32_t USBD_MSC_MemorySize; +extern uint32_t USBD_MSC_BlockSize; +extern uint32_t USBD_MSC_BlockGroup; +extern uint32_t USBD_MSC_BlockCount; +extern uint8_t* USBD_MSC_BlockBuf; +extern uint8_t USBD_MSC_MediaReady; + +#endif // _USB_H_
diff -r 000000000000 -r ef2c0c52abc4 usbd_LPC1549.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbd_LPC1549.c Fri Mar 14 09:14:16 2014 +0000 @@ -0,0 +1,59 @@ +#include <rl_usb.h> +#include <LPC15xx.h> + +/* + * USB Device Initialize Function + * Called by the User to initialize USB Device + * Return Value: None + */ + +void USBD_Init (void) +{ + /* Set USB PLL input to main oscillator */ + LPC_SYSCON->USBPLLCLKSEL = 0x01; + /* Setup USB PLL (FCLKIN = 12MHz) * 4 = 48MHz + MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2) + FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz + FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */ + LPC_SYSCON->USBPLLCTRL = 3|(1<<6); + + /* Powerup USB PLL */ + LPC_SYSCON->PDRUNCFG &= ~(1<<23); + + /* Wait for PLL to lock */ + while(!(LPC_SYSCON->USBPLLSTAT&0x01)); + + /* enable USB main clock */ + LPC_SYSCON->USBCLKSEL = 0x02; + LPC_SYSCON->USBCLKDIV = 1; + /* Enable AHB clock to the USB block. */ + LPC_SYSCON->SYSAHBCLKCTRL1 |= (1<<23); + /* power UP USB Phy */ + LPC_SYSCON->PDRUNCFG &= ~(1<<9); + /* Reset USB block */ + LPC_SYSCON->PRESETCTRL1 |= (1<23); +} + +/* + * USB Device Connect Function + * Called by the User to Connect/Disconnect USB Device + * Parameters: con: Connect/Disconnect + * Return Value: None + */ + +void USBD_Connect(uint8_t con) +{ + if (con) { + NVIC_EnableIRQ(USB_IRQ_IRQn); + } else { + NVIC_DisableIRQ(USB_IRQ_IRQn); + } +} + +/* + * USB Device Interrupt Service Routine + */ + +void USB_IRQ_IRQHandler(void) { + pUsbApi->hw->ISR(hUsb); +}
diff -r 000000000000 -r ef2c0c52abc4 usbd_user_msc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbd_user_msc.c Fri Mar 14 09:14:16 2014 +0000 @@ -0,0 +1,160 @@ +#include <rl_usb.h> + +// from USBMSD_Ram.cpp http://mbed.org/users/samux/code/RAM_DISK/ +//5 sectors +const uint8_t disk_image_0[] = { + //sector 0: boot sector + 0xEB,0x3C,0x90,0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30, 0x00,0x02,/*bytes per sector: 512*/ 0x08, /*sectors per cluster*/ 0x01,0x00,/*number of reserved sector*/ + 0x01, /* number of FATs*/ 0x10,0x00, /*Maximum number of root directory entries: 16*/ 0x20,0x00, /*Total sector count: 32*/ 0xF0, 0x02,0x00,/*sectors per FAT: 2*/ 0x01,0x00,/*Sectors per track*/ 0x01,0x00, /*Number of heads*/ 0x00,0x00,0x00,0x00, + 0x00,0x01,0x00,0x00,0x00,0x00, 0x29, /*boot signature*/ 0x74,0x19,0x02,0x27, /*volume ID*/ 'M','b','e','d',' ', + 'U','S','B',' ',' ',' ', /*volume label: Mbed USB*/ 0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x33,0xC9, + 0x8E,0xD1,0xBC,0xF0,0x7B,0x8E,0xD9,0xB8,0x00,0x20,0x8E,0xC0,0xFC,0xBD,0x00,0x7C, + 0x38,0x4E,0x24,0x7D,0x24,0x8B,0xC1,0x99,0xE8,0x3C,0x01,0x72,0x1C,0x83,0xEB,0x3A, + 0x66,0xA1,0x1C,0x7C,0x26,0x66,0x3B,0x07,0x26,0x8A,0x57,0xFC,0x75,0x06,0x80,0xCA, + 0x02,0x88,0x56,0x02,0x80,0xC3,0x10,0x73,0xEB,0x33,0xC9,0x8A,0x46,0x10,0x98,0xF7, + 0x66,0x16,0x03,0x46,0x1C,0x13,0x56,0x1E,0x03,0x46,0x0E,0x13,0xD1,0x8B,0x76,0x11, + 0x60,0x89,0x46,0xFC,0x89,0x56,0xFE,0xB8,0x20,0x00,0xF7,0xE6,0x8B,0x5E,0x0B,0x03, + 0xC3,0x48,0xF7,0xF3,0x01,0x46,0xFC,0x11,0x4E,0xFE,0x61,0xBF,0x00,0x00,0xE8,0xE6, + 0x00,0x72,0x39,0x26,0x38,0x2D,0x74,0x17,0x60,0xB1,0x0B,0xBE,0xA1,0x7D,0xF3,0xA6, + 0x61,0x74,0x32,0x4E,0x74,0x09,0x83,0xC7,0x20,0x3B,0xFB,0x72,0xE6,0xEB,0xDC,0xA0, + 0xFB,0x7D,0xB4,0x7D,0x8B,0xF0,0xAC,0x98,0x40,0x74,0x0C,0x48,0x74,0x13,0xB4,0x0E, + 0xBB,0x07,0x00,0xCD,0x10,0xEB,0xEF,0xA0,0xFD,0x7D,0xEB,0xE6,0xA0,0xFC,0x7D,0xEB, + 0xE1,0xCD,0x16,0xCD,0x19,0x26,0x8B,0x55,0x1A,0x52,0xB0,0x01,0xBB,0x00,0x00,0xE8, + 0x3B,0x00,0x72,0xE8,0x5B,0x8A,0x56,0x24,0xBE,0x0B,0x7C,0x8B,0xFC,0xC7,0x46,0xF0, + 0x3D,0x7D,0xC7,0x46,0xF4,0x29,0x7D,0x8C,0xD9,0x89,0x4E,0xF2,0x89,0x4E,0xF6,0xC6, + 0x06,0x96,0x7D,0xCB,0xEA,0x03,0x00,0x00,0x20,0x0F,0xB6,0xC8,0x66,0x8B,0x46,0xF8, + 0x66,0x03,0x46,0x1C,0x66,0x8B,0xD0,0x66,0xC1,0xEA,0x10,0xEB,0x5E,0x0F,0xB6,0xC8, + 0x4A,0x4A,0x8A,0x46,0x0D,0x32,0xE4,0xF7,0xE2,0x03,0x46,0xFC,0x13,0x56,0xFE,0xEB, + 0x4A,0x52,0x50,0x06,0x53,0x6A,0x01,0x6A,0x10,0x91,0x8B,0x46,0x18,0x96,0x92,0x33, + 0xD2,0xF7,0xF6,0x91,0xF7,0xF6,0x42,0x87,0xCA,0xF7,0x76,0x1A,0x8A,0xF2,0x8A,0xE8, + 0xC0,0xCC,0x02,0x0A,0xCC,0xB8,0x01,0x02,0x80,0x7E,0x02,0x0E,0x75,0x04,0xB4,0x42, + 0x8B,0xF4,0x8A,0x56,0x24,0xCD,0x13,0x61,0x61,0x72,0x0B,0x40,0x75,0x01,0x42,0x03, + 0x5E,0x0B,0x49,0x75,0x06,0xF8,0xC3,0x41,0xBB,0x00,0x00,0x60,0x66,0x6A,0x00,0xEB, + 0xB0,0x4E,0x54,0x4C,0x44,0x52,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,0x52,0x65, + 0x6D,0x6F,0x76,0x65,0x20,0x64,0x69,0x73,0x6B,0x73,0x20,0x6F,0x72,0x20,0x6F,0x74, + 0x68,0x65,0x72,0x20,0x6D,0x65,0x64,0x69,0x61,0x2E,0xFF,0x0D,0x0A,0x44,0x69,0x73, + 0x6B,0x20,0x65,0x72,0x72,0x6F,0x72,0xFF,0x0D,0x0A,0x50,0x72,0x65,0x73,0x73,0x20, + 0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20,0x72,0x65,0x73,0x74,0x61, + 0x72,0x74,0x0D,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xCB,0xD8,0x55,0xAA, +}; + +const uint8_t disk_image_1[] = { + //sector 1: FAT 1 + 0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F, +}; + +const uint8_t disk_image_2[] = { + //sector 2: FAT1: two sectors per FAT +}; + +const uint8_t disk_image_3[] = { + //sector 3: root directory + //entry 1 + 'M','b','e','d',' ','U','S','B',' ',' ',' ', 0x28,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + //entry 2 + 0x52,0x45,0x41,0x44,0x4D,0x45,0x20,0x20,0x54,0x58,0x54, /*readme.txt*/ 0x20,0x00,0x00,0x00,0x00, + 0x21,0x00,0xBB,0x32,0x00,0x00, 0xDC,0x83,/*hour/min/doublesec*/ 0x6A,0x3F,/*year/month/day*/ 0x02,0x00, /*starting cluster*/ 0x1e,0x00,0x00,0x00, /*size*/ +}; + +const uint8_t disk_image_4[] = { + //sector 4: data + 'H','e','l','l','o',' ','f','r','o','m',' ','M','b','e','d','!', + '\r','\n','U','S','B',' ','M','S','D',' ','d','e','m','o', +}; + +#define SLOT_SIZE 48 +static int slot[SLOT_SIZE]; +static uint8_t image[SLOT_SIZE][512]; + +static int index_block(int block) { + int i; + for(i = 0; i < SLOT_SIZE; i++) { + if (slot[i] == block) { + return i; + } + } + return -1; +} + +static int block_len(uint8_t* buf) { + int i; + for(i = 512-1; i >= 0; i--) { + if (buf[i] != 0x00) { + return i+1; + } + } + return 0; +} + +static void mem_cpy(uint8_t* dst, const uint8_t* src, int size) +{ + while(size-- > 0) { + *dst++ = *src++; + } +} + +static void mem_set(uint8_t* dst, uint8_t dat, int size) +{ + while(size-- > 0) { + *dst++ = dat; + } +} + +void usbd_msc_read_sect(uint32_t block, uint8_t *buf, uint32_t num_of_blocks) +{ + int i; + i = index_block(block); + if (i != (-1)) { + mem_cpy(buf, image[i], 512); + } else { + mem_set(buf, 0x00, 512); + } +} + +void usbd_msc_write_sect(uint32_t block, uint8_t *buf, uint32_t num_of_blocks) +{ + int i, len; + len = block_len(buf); + i = index_block(block); + if (i != -1) { + if (len == 0) { + slot[i] = -1; + } else { + mem_cpy(image[i], buf, 512); + } + } else { + if (len != 0) { + for(i = 0; i < SLOT_SIZE; i++) { + if (slot[i] == (-1)) { + slot[i] = block; + mem_cpy(image[i], buf, 512); + break; + } + } + } + } +} + +void usbd_msc_init () { + int i; + for(i = 0; i < SLOT_SIZE; i++) { + slot[i] = -1; + mem_set(image[i], 0, 512); + } + for(i = 0; i < 5; i++) { + slot[i] = i; + } + mem_cpy(image[0], disk_image_0, sizeof(disk_image_0)); + mem_cpy(image[1], disk_image_1, sizeof(disk_image_1)); + mem_cpy(image[2], disk_image_2, sizeof(disk_image_2)); + mem_cpy(image[3], disk_image_3, sizeof(disk_image_3)); + mem_cpy(image[4], disk_image_4, sizeof(disk_image_4)); + + USBD_MSC_MemorySize = 65536; + USBD_MSC_BlockSize = 512; + USBD_MSC_BlockGroup = 1; + USBD_MSC_BlockCount = USBD_MSC_MemorySize / USBD_MSC_BlockSize; + //USBD_MSC_BlockBuf = (uint8_t *)usb_buffer; + //USBD_MSC_MediaReady = __TRUE; +}