USB Device ROM Stack API example program
LPC1549のROM APIを使ったRAMディスクです。PCからはUSBメモリとして見えます。
参考:
http://docs.lpcware.com/usbromlib/v1.0/
usb.c@0:ef2c0c52abc4, 2014-03-14 (annotated)
- Committer:
- va009039
- Date:
- Fri Mar 14 09:14:16 2014 +0000
- Revision:
- 0:ef2c0c52abc4
first commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:ef2c0c52abc4 | 1 | #if defined(TARGET_LPC1549) |
va009039 | 0:ef2c0c52abc4 | 2 | #include "LPC15xx.h" |
va009039 | 0:ef2c0c52abc4 | 3 | #define ROM_API_ADDR (0x03000200) |
va009039 | 0:ef2c0c52abc4 | 4 | #else |
va009039 | 0:ef2c0c52abc4 | 5 | #error "target error" |
va009039 | 0:ef2c0c52abc4 | 6 | #endif |
va009039 | 0:ef2c0c52abc4 | 7 | #include <rl_usb.h> |
va009039 | 0:ef2c0c52abc4 | 8 | #include <string.h> |
va009039 | 0:ef2c0c52abc4 | 9 | |
va009039 | 0:ef2c0c52abc4 | 10 | USBD_API_T* pUsbApi; |
va009039 | 0:ef2c0c52abc4 | 11 | USBD_HANDLE_T hUsb; |
va009039 | 0:ef2c0c52abc4 | 12 | |
va009039 | 0:ef2c0c52abc4 | 13 | uint32_t USBD_MSC_MemorySize; |
va009039 | 0:ef2c0c52abc4 | 14 | uint32_t USBD_MSC_BlockSize; |
va009039 | 0:ef2c0c52abc4 | 15 | uint32_t USBD_MSC_BlockGroup; |
va009039 | 0:ef2c0c52abc4 | 16 | uint32_t USBD_MSC_BlockCount; |
va009039 | 0:ef2c0c52abc4 | 17 | uint8_t* USBD_MSC_BlockBuf; |
va009039 | 0:ef2c0c52abc4 | 18 | uint8_t USBD_MSC_MediaReady; |
va009039 | 0:ef2c0c52abc4 | 19 | |
va009039 | 0:ef2c0c52abc4 | 20 | extern void USBD_Init(void); // interface/*/usbd_*.c |
va009039 | 0:ef2c0c52abc4 | 21 | extern void USBD_Connect(uint8_t con); |
va009039 | 0:ef2c0c52abc4 | 22 | |
va009039 | 0:ef2c0c52abc4 | 23 | static USBD_API_INIT_PARAM_T usb_param; |
va009039 | 0:ef2c0c52abc4 | 24 | static USB_CORE_DESCS_T desc; |
va009039 | 0:ef2c0c52abc4 | 25 | static USBD_MSC_INIT_PARAM_T msc_param; |
va009039 | 0:ef2c0c52abc4 | 26 | |
va009039 | 0:ef2c0c52abc4 | 27 | static uint8_t usbmem[2048] __attribute__ ((aligned(2048))); |
va009039 | 0:ef2c0c52abc4 | 28 | static uint8_t* mem_base; |
va009039 | 0:ef2c0c52abc4 | 29 | static uint32_t mem_size; |
va009039 | 0:ef2c0c52abc4 | 30 | |
va009039 | 0:ef2c0c52abc4 | 31 | #define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) |
va009039 | 0:ef2c0c52abc4 | 32 | |
va009039 | 0:ef2c0c52abc4 | 33 | /* USB Standard Device Descriptor */ |
va009039 | 0:ef2c0c52abc4 | 34 | static const uint8_t USB_DeviceDescriptor[] = { |
va009039 | 0:ef2c0c52abc4 | 35 | 18, /* bLength */ |
va009039 | 0:ef2c0c52abc4 | 36 | 1, /* USB_DEVICE_DESCRIPTOR_TYPE, bDescriptorType */ |
va009039 | 0:ef2c0c52abc4 | 37 | WBVAL(0x0200), /* 2.00 bcdUSB */ |
va009039 | 0:ef2c0c52abc4 | 38 | 0x00, /* bDeviceClass */ |
va009039 | 0:ef2c0c52abc4 | 39 | 0x00, /* bDeviceSubClass */ |
va009039 | 0:ef2c0c52abc4 | 40 | 0x00, /* bDeviceProtocol */ |
va009039 | 0:ef2c0c52abc4 | 41 | 64, /* USB_MAX_PACKET0, bMaxPacketSize0 */ |
va009039 | 0:ef2c0c52abc4 | 42 | WBVAL(0x0d28), /* idVendor */ |
va009039 | 0:ef2c0c52abc4 | 43 | WBVAL(0x0204), /* idProduct */ |
va009039 | 0:ef2c0c52abc4 | 44 | WBVAL(0x0001), /* bcdDevice */ |
va009039 | 0:ef2c0c52abc4 | 45 | 1, /* iManufacturer */ |
va009039 | 0:ef2c0c52abc4 | 46 | 2, /* iProduct */ |
va009039 | 0:ef2c0c52abc4 | 47 | 3, /* iSerialNumber */ |
va009039 | 0:ef2c0c52abc4 | 48 | 1 /* bNumConfigurations */ |
va009039 | 0:ef2c0c52abc4 | 49 | }; |
va009039 | 0:ef2c0c52abc4 | 50 | |
va009039 | 0:ef2c0c52abc4 | 51 | /* USB FSConfiguration Descriptor */ |
va009039 | 0:ef2c0c52abc4 | 52 | /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ |
va009039 | 0:ef2c0c52abc4 | 53 | static const uint8_t USB_FsConfigDescriptor[] = { |
va009039 | 0:ef2c0c52abc4 | 54 | /* Configuration 1 */ |
va009039 | 0:ef2c0c52abc4 | 55 | 9, /* USB_CONFIGUARTION_DESC_SIZE, bLength */ |
va009039 | 0:ef2c0c52abc4 | 56 | 2, /* USB_CONFIGURATION_DESCRIPTOR_TYPE, bDescriptorType */ |
va009039 | 0:ef2c0c52abc4 | 57 | WBVAL(9 + 9 + 7 * 2),/* wTotalLength */ |
va009039 | 0:ef2c0c52abc4 | 58 | 0x01, /* bNumInterfaces */ |
va009039 | 0:ef2c0c52abc4 | 59 | 0x01, /* bConfigurationValue */ |
va009039 | 0:ef2c0c52abc4 | 60 | 0x00, /* iConfiguration */ |
va009039 | 0:ef2c0c52abc4 | 61 | 0xc0, /* USB_CONFIG_SELF_POWERED, bmAttributes */ |
va009039 | 0:ef2c0c52abc4 | 62 | 50, /* USB_CONFIG_POWER_MA(100), bMaxPower */ |
va009039 | 0:ef2c0c52abc4 | 63 | /* Interface 0, Alternate Setting 0, MSC Class */ |
va009039 | 0:ef2c0c52abc4 | 64 | 9, /* USB_INTERFACE_DESC_SIZE, bLength */ |
va009039 | 0:ef2c0c52abc4 | 65 | 4, /* USB_INTERFACE_DESCRIPTOR_TYPE, bDescriptorType */ |
va009039 | 0:ef2c0c52abc4 | 66 | 0, /* bInterfaceNumber */ |
va009039 | 0:ef2c0c52abc4 | 67 | 0, /* bAlternateSetting */ |
va009039 | 0:ef2c0c52abc4 | 68 | 2, /* bNumEndpoints */ |
va009039 | 0:ef2c0c52abc4 | 69 | 0x08, /* USB_DEVICE_CLASS_STORAGE, bInterfaceClass */ |
va009039 | 0:ef2c0c52abc4 | 70 | 0x06, /* MSC_SUBCLASS_SCSI, bInterfaceSubClass */ |
va009039 | 0:ef2c0c52abc4 | 71 | 0x50, /* MSC_PROTOCOL_BULK_ONLY, bInterfaceProtocol */ |
va009039 | 0:ef2c0c52abc4 | 72 | 0x05, /* iInterface */ |
va009039 | 0:ef2c0c52abc4 | 73 | /* Bulk In Endpoint */ |
va009039 | 0:ef2c0c52abc4 | 74 | 7, /* USB_ENDPOINT_DESC_SIZE, bLength */ |
va009039 | 0:ef2c0c52abc4 | 75 | 5, /* USB_ENDPOINT_DESCRIPTOR_TYPE, bDescriptorType */ |
va009039 | 0:ef2c0c52abc4 | 76 | 0x01, /* MSC_EP_IN, bEndpointAddress */ |
va009039 | 0:ef2c0c52abc4 | 77 | 0x02, /* USB_ENDPOINT_TYPE_BULK, bmAttributes */ |
va009039 | 0:ef2c0c52abc4 | 78 | WBVAL(64), /* WBVAL(USB_FS_MAX_BULK_PACKET), wMaxPacketSize */ |
va009039 | 0:ef2c0c52abc4 | 79 | 0, /* bInterval */ |
va009039 | 0:ef2c0c52abc4 | 80 | /* Bulk Out Endpoint */ |
va009039 | 0:ef2c0c52abc4 | 81 | 7, /* USB_ENDPOINT_DESC_SIZE, bLength */ |
va009039 | 0:ef2c0c52abc4 | 82 | 5, /* USB_ENDPOINT_DESCRIPTOR_TYPE bDescriptorType */ |
va009039 | 0:ef2c0c52abc4 | 83 | 0x81, /* MSC_EP_OUT bEndpointAddress */ |
va009039 | 0:ef2c0c52abc4 | 84 | 0x02, /* USB_ENDPOINT_TYPE_BULK bmAttributes */ |
va009039 | 0:ef2c0c52abc4 | 85 | WBVAL(64), /* WBVAL(USB_FS_MAX_BULK_PACKET) wMaxPacketSize */ |
va009039 | 0:ef2c0c52abc4 | 86 | 0, /* bInterval */ |
va009039 | 0:ef2c0c52abc4 | 87 | /* Terminator */ |
va009039 | 0:ef2c0c52abc4 | 88 | 0 /* bLength */ |
va009039 | 0:ef2c0c52abc4 | 89 | }; |
va009039 | 0:ef2c0c52abc4 | 90 | |
va009039 | 0:ef2c0c52abc4 | 91 | /* USB String Descriptor (optional) */ |
va009039 | 0:ef2c0c52abc4 | 92 | static const uint8_t USB_StringDescriptor[] = { |
va009039 | 0:ef2c0c52abc4 | 93 | /* Index 0x00: LANGID Codes */ |
va009039 | 0:ef2c0c52abc4 | 94 | 4, /* bLength */ |
va009039 | 0:ef2c0c52abc4 | 95 | 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ |
va009039 | 0:ef2c0c52abc4 | 96 | WBVAL(0x0409),/* US English wLANGID */ |
va009039 | 0:ef2c0c52abc4 | 97 | /* Index 0x01: Manufacturer */ |
va009039 | 0:ef2c0c52abc4 | 98 | (8*2 + 2), /* bLength (8 Char + Type + lenght) */ |
va009039 | 0:ef2c0c52abc4 | 99 | 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ |
va009039 | 0:ef2c0c52abc4 | 100 | 'm', 0, 'b', 0, 'e', 0, 'd', 0, '.', 0, 'o', 0, 'r', 0, 'g', 0, /* mbed.org */ |
va009039 | 0:ef2c0c52abc4 | 101 | /* Index 0x02: Product */ |
va009039 | 0:ef2c0c52abc4 | 102 | (14*2 + 2), /* bLength (14 Char + Type + lenght) */ |
va009039 | 0:ef2c0c52abc4 | 103 | 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ |
va009039 | 0:ef2c0c52abc4 | 104 | 'M', 0, 'B', 0, 'E', 0, ' ', 0, 'D', 0, /* MBED_ */ |
va009039 | 0:ef2c0c52abc4 | 105 | 'C', 0, 'M', 0, 'S', 0, 'I', 0, 'S', 0, '-', 0, 'D', 0, 'A', 0, 'P', 0, /* CMSIS-DAP */ |
va009039 | 0:ef2c0c52abc4 | 106 | /* Index 0x03: Serial Number */ |
va009039 | 0:ef2c0c52abc4 | 107 | (10*2 + 2), /* bLength (10 Char + Type + lenght) */ |
va009039 | 0:ef2c0c52abc4 | 108 | 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ |
va009039 | 0:ef2c0c52abc4 | 109 | '0', 0, '1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0, '9', 0, |
va009039 | 0:ef2c0c52abc4 | 110 | /* Index 0x04: Interface 0, Alternate Setting 0 */ |
va009039 | 0:ef2c0c52abc4 | 111 | (3*2 + 2), /* bLength (3 Char + Type + lenght) */ |
va009039 | 0:ef2c0c52abc4 | 112 | 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ |
va009039 | 0:ef2c0c52abc4 | 113 | 'M', 0, 'S', 0, 'D', 0, |
va009039 | 0:ef2c0c52abc4 | 114 | /* Index 0x05: Interface 1, Alternate Setting 0 */ |
va009039 | 0:ef2c0c52abc4 | 115 | (3*2 + 2), /* bLength (3 Char + Type + lenght) */ |
va009039 | 0:ef2c0c52abc4 | 116 | 3, /* USB_STRING_DESCRIPTOR_TYPE, bDescriptorType */ |
va009039 | 0:ef2c0c52abc4 | 117 | 'U', 0, 'S', 0, 'B', 0, |
va009039 | 0:ef2c0c52abc4 | 118 | }; |
va009039 | 0:ef2c0c52abc4 | 119 | |
va009039 | 0:ef2c0c52abc4 | 120 | static const uint8_t InquiryStr[28] = { |
va009039 | 0:ef2c0c52abc4 | 121 | 'M', 'B', 'E', 'D', '.', 'O', 'R', 'G', 'M', 'B', |
va009039 | 0:ef2c0c52abc4 | 122 | 'E', 'D', ' ', 'U', 'S', 'B', ' ', 'D', 'I', 'S', |
va009039 | 0:ef2c0c52abc4 | 123 | 'K', ' ', ' ', ' ', '1', '.', '0', ' ' |
va009039 | 0:ef2c0c52abc4 | 124 | }; |
va009039 | 0:ef2c0c52abc4 | 125 | |
va009039 | 0:ef2c0c52abc4 | 126 | |
va009039 | 0:ef2c0c52abc4 | 127 | static uint8_t MSC_buf[512]; |
va009039 | 0:ef2c0c52abc4 | 128 | static void MSC_Read(uint32_t offset, uint8_t** buff_adr, uint32_t length, uint32_t high_offset) |
va009039 | 0:ef2c0c52abc4 | 129 | { |
va009039 | 0:ef2c0c52abc4 | 130 | int i, j; |
va009039 | 0:ef2c0c52abc4 | 131 | if (offset % 512 == 0) { /* head chunk ? */ |
va009039 | 0:ef2c0c52abc4 | 132 | usbd_msc_read_sect(offset / 512, MSC_buf, 1); |
va009039 | 0:ef2c0c52abc4 | 133 | } |
va009039 | 0:ef2c0c52abc4 | 134 | j = offset % 512; |
va009039 | 0:ef2c0c52abc4 | 135 | for (i = 0; i < length; i++, j++) { |
va009039 | 0:ef2c0c52abc4 | 136 | (*buff_adr)[i] = MSC_buf[j]; |
va009039 | 0:ef2c0c52abc4 | 137 | } |
va009039 | 0:ef2c0c52abc4 | 138 | } |
va009039 | 0:ef2c0c52abc4 | 139 | |
va009039 | 0:ef2c0c52abc4 | 140 | static void MSC_Write(uint32_t offset, uint8_t** buff_adr, uint32_t length, uint32_t high_offset) |
va009039 | 0:ef2c0c52abc4 | 141 | { |
va009039 | 0:ef2c0c52abc4 | 142 | int i, j; |
va009039 | 0:ef2c0c52abc4 | 143 | j = offset % 512; |
va009039 | 0:ef2c0c52abc4 | 144 | for(i = 0; i < length; i++, j++) { |
va009039 | 0:ef2c0c52abc4 | 145 | MSC_buf[j] = (*buff_adr)[i]; |
va009039 | 0:ef2c0c52abc4 | 146 | } |
va009039 | 0:ef2c0c52abc4 | 147 | if ((offset % 512) + length == 512) { /* tail chunk ? */ |
va009039 | 0:ef2c0c52abc4 | 148 | usbd_msc_write_sect(offset / 512, MSC_buf, 1); |
va009039 | 0:ef2c0c52abc4 | 149 | } |
va009039 | 0:ef2c0c52abc4 | 150 | } |
va009039 | 0:ef2c0c52abc4 | 151 | |
va009039 | 0:ef2c0c52abc4 | 152 | static ErrorCode_t MSC_Verify(uint32_t offset, uint8_t* src, uint32_t length, uint32_t high_offset) |
va009039 | 0:ef2c0c52abc4 | 153 | { |
va009039 | 0:ef2c0c52abc4 | 154 | return LPC_OK; |
va009039 | 0:ef2c0c52abc4 | 155 | } |
va009039 | 0:ef2c0c52abc4 | 156 | |
va009039 | 0:ef2c0c52abc4 | 157 | static void USBD_MSC_Init(void) { |
va009039 | 0:ef2c0c52abc4 | 158 | ErrorCode_t ret; |
va009039 | 0:ef2c0c52abc4 | 159 | |
va009039 | 0:ef2c0c52abc4 | 160 | usbd_msc_init(); |
va009039 | 0:ef2c0c52abc4 | 161 | memset((void*)&msc_param, 0, sizeof(msc_param)); |
va009039 | 0:ef2c0c52abc4 | 162 | msc_param.mem_base = mem_base; |
va009039 | 0:ef2c0c52abc4 | 163 | msc_param.mem_size = mem_size; |
va009039 | 0:ef2c0c52abc4 | 164 | |
va009039 | 0:ef2c0c52abc4 | 165 | /* mass storage paramas */ |
va009039 | 0:ef2c0c52abc4 | 166 | msc_param.InquiryStr = InquiryStr; |
va009039 | 0:ef2c0c52abc4 | 167 | msc_param.BlockCount = USBD_MSC_BlockCount; |
va009039 | 0:ef2c0c52abc4 | 168 | msc_param.BlockSize = USBD_MSC_BlockSize; |
va009039 | 0:ef2c0c52abc4 | 169 | msc_param.MemorySize = USBD_MSC_MemorySize; |
va009039 | 0:ef2c0c52abc4 | 170 | msc_param.intf_desc = USB_FsConfigDescriptor + 9; |
va009039 | 0:ef2c0c52abc4 | 171 | |
va009039 | 0:ef2c0c52abc4 | 172 | /* user defined functions */ |
va009039 | 0:ef2c0c52abc4 | 173 | msc_param.MSC_Write = MSC_Write; |
va009039 | 0:ef2c0c52abc4 | 174 | msc_param.MSC_Read = MSC_Read; |
va009039 | 0:ef2c0c52abc4 | 175 | msc_param.MSC_Verify = MSC_Verify; |
va009039 | 0:ef2c0c52abc4 | 176 | |
va009039 | 0:ef2c0c52abc4 | 177 | ret = pUsbApi->msc->init(hUsb, &msc_param); |
va009039 | 0:ef2c0c52abc4 | 178 | if (ret == LPC_OK) { |
va009039 | 0:ef2c0c52abc4 | 179 | /* update memory variables */ |
va009039 | 0:ef2c0c52abc4 | 180 | mem_base = msc_param.mem_base; |
va009039 | 0:ef2c0c52abc4 | 181 | mem_size = msc_param.mem_size; |
va009039 | 0:ef2c0c52abc4 | 182 | } |
va009039 | 0:ef2c0c52abc4 | 183 | } |
va009039 | 0:ef2c0c52abc4 | 184 | |
va009039 | 0:ef2c0c52abc4 | 185 | void usbd_init(void) |
va009039 | 0:ef2c0c52abc4 | 186 | { |
va009039 | 0:ef2c0c52abc4 | 187 | ErrorCode_t ret; |
va009039 | 0:ef2c0c52abc4 | 188 | |
va009039 | 0:ef2c0c52abc4 | 189 | USBD_Init(); |
va009039 | 0:ef2c0c52abc4 | 190 | |
va009039 | 0:ef2c0c52abc4 | 191 | /* get USB API table pointer */ |
va009039 | 0:ef2c0c52abc4 | 192 | pUsbApi = (USBD_API_T*)((*(ROM **)ROM_API_ADDR)->pUSBD); |
va009039 | 0:ef2c0c52abc4 | 193 | |
va009039 | 0:ef2c0c52abc4 | 194 | mem_base = usbmem; |
va009039 | 0:ef2c0c52abc4 | 195 | mem_size = sizeof(usbmem); |
va009039 | 0:ef2c0c52abc4 | 196 | |
va009039 | 0:ef2c0c52abc4 | 197 | /* initilize call back structures */ |
va009039 | 0:ef2c0c52abc4 | 198 | memset((void*)&usb_param, 0, sizeof(usb_param)); |
va009039 | 0:ef2c0c52abc4 | 199 | usb_param.usb_reg_base = LPC_USB_BASE; |
va009039 | 0:ef2c0c52abc4 | 200 | usb_param.mem_base = mem_base; |
va009039 | 0:ef2c0c52abc4 | 201 | usb_param.mem_size = mem_size; |
va009039 | 0:ef2c0c52abc4 | 202 | usb_param.max_num_ep = 2; |
va009039 | 0:ef2c0c52abc4 | 203 | |
va009039 | 0:ef2c0c52abc4 | 204 | /* Initialize Descriptor pointers */ |
va009039 | 0:ef2c0c52abc4 | 205 | memset((void*)&desc, 0, sizeof(desc)); |
va009039 | 0:ef2c0c52abc4 | 206 | desc.device_desc = USB_DeviceDescriptor; |
va009039 | 0:ef2c0c52abc4 | 207 | desc.string_desc = USB_StringDescriptor; |
va009039 | 0:ef2c0c52abc4 | 208 | desc.full_speed_desc = USB_FsConfigDescriptor; |
va009039 | 0:ef2c0c52abc4 | 209 | desc.high_speed_desc = USB_FsConfigDescriptor; |
va009039 | 0:ef2c0c52abc4 | 210 | |
va009039 | 0:ef2c0c52abc4 | 211 | /* USB Initialization */ |
va009039 | 0:ef2c0c52abc4 | 212 | ret = pUsbApi->hw->Init(&hUsb, &desc, &usb_param); |
va009039 | 0:ef2c0c52abc4 | 213 | if (ret == LPC_OK) { |
va009039 | 0:ef2c0c52abc4 | 214 | mem_base = usb_param.mem_base; |
va009039 | 0:ef2c0c52abc4 | 215 | mem_size = usb_param.mem_size; |
va009039 | 0:ef2c0c52abc4 | 216 | USBD_MSC_Init(); |
va009039 | 0:ef2c0c52abc4 | 217 | } |
va009039 | 0:ef2c0c52abc4 | 218 | } |
va009039 | 0:ef2c0c52abc4 | 219 | |
va009039 | 0:ef2c0c52abc4 | 220 | void usbd_connect(uint8_t con) |
va009039 | 0:ef2c0c52abc4 | 221 | { |
va009039 | 0:ef2c0c52abc4 | 222 | USBD_Connect(con); |
va009039 | 0:ef2c0c52abc4 | 223 | if (con) { |
va009039 | 0:ef2c0c52abc4 | 224 | pUsbApi->hw->Connect(hUsb, 1); |
va009039 | 0:ef2c0c52abc4 | 225 | } |
va009039 | 0:ef2c0c52abc4 | 226 | } |