USB Device ROM Stack API example program

Dependencies:   mbed

LPC1549のROM APIを使ったRAMディスクです。PCからはUSBメモリとして見えます。

参考:
http://docs.lpcware.com/usbromlib/v1.0/

usb.c

Committer:
va009039
Date:
2014-03-14
Revision:
0:ef2c0c52abc4

File content as of revision 0:ef2c0c52abc4:

#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);
    }        
}