USB Device ROM Stack API example program
LPC1549のROM APIを使ったRAMディスクです。PCからはUSBメモリとして見えます。
参考:
http://docs.lpcware.com/usbromlib/v1.0/
Diff: usb.c
- Revision:
- 0:ef2c0c52abc4
--- /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); + } +}