示例#1
0
static inline void lpc_usb_open_ep(CORE* core, int num, USB_EP_TYPE type, unsigned int size)
{
    unsigned int i;
    if (ep_data(core, num) != NULL)
    {
        error(ERROR_ALREADY_CONFIGURED);
        return;
    }

    EP* ep = malloc(sizeof(EP));
    if (ep == NULL)
        return;
    ep->io = NULL;
    ep->fifo = (void*)USB_FREE_BUF_BASE;
    ep->io_active = false;
    ep->mps = size;

    //find free addr in FIFO
    for (i = 0; i < USB_EP_COUNT_MAX; ++i)
    {
        if (core->usb.in[i])
            ep->fifo += ((core->usb.in[i]->mps + 63) & ~63);
        if (core->usb.out[i])
            ep->fifo += ((core->usb.out[i]->mps + 63) & ~63);
    }

    num & USB_EP_IN ? (core->usb.in[USB_EP_NUM(num)] = ep) : (core->usb.out[USB_EP_NUM(num)] = ep);
    if (type == USB_EP_ISOCHRON)
        *USB_EP_LISTSTS(num, 0) |= USB_EP_LISTST_T;
    if (USB_EP_NUM(num))
        *USB_EP_LISTSTS(num, 0) &= ~USB_EP_LISTST_D;
    LPC_USB->INTEN |= USB_EP_INT_BIT(num);
}
示例#2
0
static inline void lpc_usb_close_ep(CORE* core, int num)
{
    if (!lpc_usb_ep_flush(core, num))
        return;
    *USB_EP_LISTSTS(num, 0) |= USB_EP_LISTST_D;
    LPC_USB->INTEN &= ~USB_EP_INT_BIT(num);

    EP* ep = ep_data(core, num);
    free(ep);
    num & USB_EP_IN ? (core->usb.in[USB_EP_NUM(num)] = NULL) : (core->usb.out[USB_EP_NUM(num)] = NULL);
}
示例#3
0
static inline void stm32_otg_tx(EXO* exo, int num)
{
    EP* ep = exo->usb.in[USB_EP_NUM(num)];

    int size = ep->io->data_size - ep->size;
    if (size > ep->mps)
        size = ep->mps;
    OTG_FS_DEVICE->INEP[USB_EP_NUM(num)].TSIZ = (1 << OTG_FS_DEVICE_ENDPOINT_TSIZ_PKTCNT_POS) | (size << OTG_FS_DEVICE_ENDPOINT_TSIZ_XFRSIZ_POS);
    OTG_FS_DEVICE->INEP[USB_EP_NUM(num)].CTL |= OTG_FS_DEVICE_ENDPOINT_CTL_EPENA | OTG_FS_DEVICE_ENDPOINT_CTL_CNAK;

    memcpy4((void*)(OTG_FS_FIFO_BASE + USB_EP_NUM(num) * 0x1000), io_data(ep->io) +  ep->size, size);
    ep->size += size;
}
示例#4
0
static inline void stm32_otg_close_ep(EXO* exo, int num)
{
    if (!stm32_otg_ep_flush(exo, num))
        return;
    ep_reg_data(num)->CTL &= ~OTG_FS_DEVICE_ENDPOINT_CTL_USBAEP;
    EP* ep = ep_data(exo, num);

    ep->mps = 0;
    if (num & USB_EP_IN)
    {
        OTG_FS_DEVICE->AINTMSK &= ~(1 << USB_EP_NUM(num));
        OTG_FS_DEVICE->EIPEMPMSK &= ~(1 << USB_EP_NUM(num));
    }
    kfree(ep);
    num & USB_EP_IN ? (exo->usb.in[USB_EP_NUM(num)] = NULL) : (exo->usb.out[USB_EP_NUM(num)] = NULL);
}
示例#5
0
void lpc_usb_rx_prepare(CORE* core, int num)
{
    EP* ep = core->usb.out[USB_EP_NUM(num)];

    *USB_EP_LISTSTS(num, 0) &= ~(USB_EP_LISTST_OFFSET_MASK | USB_EP_LISTST_NBYTES_MASK);
    *USB_EP_LISTSTS(num, 0) |= USB_EP_LISTST_OFFSET_SET(ep->fifo) | USB_EP_LISTST_NBYTES_SET(ep->mps);
    *USB_EP_LISTSTS(num, 0) |= USB_EP_LISTST_A;
}
示例#6
0
void hidd_kbd_class_configured(USBD* usbd, USB_CONFIGURATION_DESCRIPTOR* cfg)
{
    USB_INTERFACE_DESCRIPTOR* iface;
    USB_ENDPOINT_DESCRIPTOR* ep;
    uint8_t in_ep, hid_iface;
    unsigned in_ep_size;
    in_ep = in_ep_size = hid_iface = 0;

    //check control/data ep here
    for (iface = usb_get_first_interface(cfg); iface != NULL; iface = usb_get_next_interface(cfg, iface))
    {
        if (iface->bInterfaceClass == HID_INTERFACE_CLASS && iface->bInterfaceSubClass == HID_SUBCLASS_BOOT_INTERFACE &&
            iface->bInterfaceProtocol == HID_PROTOCOL_KEYBOARD)
        {
            ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, iface, USB_ENDPOINT_DESCRIPTOR_TYPE);
            if (ep != NULL)
            {
                in_ep = USB_EP_NUM(ep->bEndpointAddress);
                in_ep_size = ep->wMaxPacketSize;
                hid_iface = iface->bInterfaceNumber;
                break;
            }
        }
    }

    //No HID descriptors in interface
    if (in_ep == 0)
        return;
    HIDD_KBD* hidd = (HIDD_KBD*)malloc(sizeof(HIDD_KBD));
    if (hidd == NULL)
        return;
    hidd->io = io_create(in_ep_size);

    if (hidd->io == NULL)
    {
        hidd_kbd_destroy(hidd);
        return;
    }
    hidd->iface = hid_iface;
    hidd->in_ep = in_ep;
    hidd->suspended = false;
    hidd->over = false;
    hidd->idle = 0;
    hidd->boot_protocol = 1;
    hidd->state = USB_HID_KBD_IDLE;
    memset(&hidd->kbd, 0x00, sizeof(BOOT_KEYBOARD));

#if (USBD_HID_DEBUG_REQUESTS)
    printf("Found USB HID device class, EP%d, iface: %d\n", hidd->in_ep, hidd->iface);
#endif //USBD_HID_DEBUG_REQUESTS

    usbd_register_interface(usbd, hidd->iface, &__HIDD_KBD_CLASS, hidd);
    usbd_register_endpoint(usbd, hidd->iface, hidd->in_ep);
    usbd_usb_ep_open(usbd, USB_EP_IN | hidd->in_ep, USB_EP_INTERRUPT, in_ep_size);
}
示例#7
0
static inline void stm32_otg_write(EXO* exo, IPC* ipc)
{
    unsigned int ep_num = USB_EP_NUM(ipc->param1);
    EP* ep = exo->usb.in[ep_num];
    if (stm32_usb_io_prepare(exo, ipc))
    {
        ep->size = 0;
        ep->io_active = true;
        stm32_otg_tx(exo, USB_EP_IN | ep_num);
    }
}
示例#8
0
static inline void lpc_usb_write(CORE* core, IPC* ipc)
{
    unsigned int num = ipc->param1;
    EP* ep = core->usb.in[USB_EP_NUM(num)];
    if (lpc_usb_io_prepare(core, ipc))
    {
        ep->size = 0;
        ep->io_active = true;
        lpc_usb_tx(core, num);
    }
}
示例#9
0
static inline void lpc_usb_read(CORE* core, IPC* ipc)
{
    unsigned int num = ipc->param1;
    EP* ep = core->usb.out[USB_EP_NUM(num)];
    if (lpc_usb_io_prepare(core, ipc))
    {
        ep->io->data_size = 0;
        ep->size = ipc->param3;
        ep->io_active = true;
        lpc_usb_rx_prepare(core, num);
    }
}
示例#10
0
static inline void stm32_otg_read(EXO* exo, IPC* ipc)
{
    unsigned int ep_num = USB_EP_NUM(ipc->param1);
    EP* ep = exo->usb.out[ep_num];
    __disable_irq();
    if (stm32_usb_io_prepare(exo, ipc))
    {
        ep->io->data_size = 0;
        ep->size = ipc->param3;
        ep->io_active = true;
        stm32_otg_rx_prepare(exo, ep_num);
    }
    __enable_irq();
}
示例#11
0
static inline void lpc_usb_tx(CORE* core, int num)
{
    EP* ep = core->usb.in[USB_EP_NUM(num)];

    int size = ep->io->data_size - ep->size;
    if (size > ep->mps)
        size = ep->mps;

    memcpy(ep->fifo, io_data(ep->io) + ep->size, size);
    ep->size += size;

    *USB_EP_LISTSTS(num, 0) &= ~(USB_EP_LISTST_OFFSET_MASK | USB_EP_LISTST_NBYTES_MASK);
    *USB_EP_LISTSTS(num, 0) |= USB_EP_LISTST_OFFSET_SET(ep->fifo) | USB_EP_LISTST_NBYTES_SET(size);
    *USB_EP_LISTSTS(num, 0) |= USB_EP_LISTST_A;
}
示例#12
0
static inline void lpc_usb_out(CORE* core, int num)
{
    EP* ep = core->usb.out[USB_EP_NUM(num)];
    unsigned int cnt = ep->mps - (((*USB_EP_LISTSTS(num, 0)) & USB_EP_LISTST_NBYTES_MASK) >> USB_EP_LISTST_NBYTES_POS);

    io_data_append(ep->io, ep->fifo, cnt);
    if (ep->io->data_size >= ep->size || cnt < ep->mps)
    {
        ep->io_active = false;
        iio_complete(core->usb.device, HAL_IO_CMD(HAL_USB, IPC_READ), num, ep->io);
        ep->io = NULL;
    }
    else
        lpc_usb_rx_prepare(core, num);
}
示例#13
0
static inline void lpc_usb_in(CORE* core, int num)
{
    EP* ep = core->usb.in[USB_EP_NUM(num)];
    //handle STATUS in for set address
    if (core->usb.addr && ep->size == 0)
    {
        LPC_USB->DEVCMDSTAT |= core->usb.addr;
        core->usb.addr = 0;
    }

    if (ep->size >= ep->io->data_size)
    {
        ep->io_active = false;
        iio_complete(core->usb.device, HAL_IO_CMD(HAL_USB, IPC_WRITE), USB_EP_IN | num, ep->io);
        ep->io = NULL;
    }
    else
        lpc_usb_tx(core, num);
}
示例#14
0
static inline void lpc_usb_ep_request(CORE* core, IPC* ipc)
{
    if (USB_EP_NUM(ipc->param1) >= USB_EP_COUNT_MAX)
    {
        error(ERROR_INVALID_PARAMS);
        return;
    }
    switch (HAL_ITEM(ipc->cmd))
    {
    case IPC_OPEN:
        lpc_usb_open_ep(core, ipc->param1, ipc->param2, ipc->param3);
        break;
    case IPC_CLOSE:
        lpc_usb_close_ep(core, ipc->param1);
        break;
    case IPC_FLUSH:
        lpc_usb_ep_flush(core, ipc->param1);
        break;
    case USB_EP_SET_STALL:
        lpc_usb_ep_set_stall(core, ipc->param1);
        break;
    case USB_EP_CLEAR_STALL:
        lpc_usb_ep_clear_stall(core, ipc->param1);
        break;
    case USB_EP_IS_STALL:
        ipc->param2 = lpc_usb_ep_is_stall(ipc->param1);
        break;
    case IPC_READ:
        lpc_usb_read(core, ipc);
        break;
    case IPC_WRITE:
        lpc_usb_write(core, ipc);
        //posted with io, no return IPC
        break;
    default:
        error(ERROR_NOT_SUPPORTED);
        break;
    }
}
示例#15
0
static void stm32_otg_ep_request(EXO* exo, IPC* ipc)
{
    if (USB_EP_NUM(ipc->param1) >= USB_EP_COUNT_MAX)
    {
        kerror(ERROR_INVALID_PARAMS);
        return;
    }
    switch (HAL_ITEM(ipc->cmd))
    {
    case IPC_OPEN:
        stm32_otg_open_ep(exo, ipc->param1, ipc->param2, ipc->param3);
        break;
    case IPC_CLOSE:
        stm32_otg_close_ep(exo, ipc->param1);
        break;
    case IPC_FLUSH:
        stm32_otg_ep_flush(exo, ipc->param1);
        break;
    case USB_EP_SET_STALL:
        stm32_otg_ep_set_stall(exo, ipc->param1);
        break;
    case USB_EP_CLEAR_STALL:
        stm32_otg_ep_clear_stall(exo, ipc->param1);
        break;
    case USB_EP_IS_STALL:
        ipc->param2 = stm32_otg_ep_is_stall(ipc->param1);
        break;
    case IPC_READ:
        stm32_otg_read(exo, ipc);
        break;
    case IPC_WRITE:
        stm32_otg_write(exo, ipc);
        break;
    default:
        kerror(ERROR_NOT_SUPPORTED);
        break;
    }
}
示例#16
0
static inline EP* ep_data(CORE* core, unsigned int num)
{
    return (num & USB_EP_IN) ? (core->usb.in[USB_EP_NUM(num)]) : (core->usb.out[USB_EP_NUM(num)]);
}
示例#17
0
void mscd_class_configured(USBD* usbd, USB_CONFIGURATION_DESCRIPTOR* cfg)
{
    USB_INTERFACE_DESCRIPTOR* iface;
    USB_ENDPOINT_DESCRIPTOR* ep;
    void* config;
    int i;
    unsigned int ep_num, ep_size, iface_num, lun_count;
    ep_num = 0;

    //check control/data ep here
    for (iface = usb_get_first_interface(cfg); iface != NULL; iface = usb_get_next_interface(cfg, iface))
    {
        ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, iface, USB_ENDPOINT_DESCRIPTOR_TYPE);
        if (ep != NULL && iface->bInterfaceClass == MSC_INTERFACE_CLASS)
        {
            ep_num = USB_EP_NUM(ep->bEndpointAddress);
            ep_size = ep->wMaxPacketSize;
            iface_num = iface->bInterfaceNumber;
            break;
        }
    }

    //No MSC interface
    if (ep_num == 0)
        return;
    i = usbd_get_cfg(usbd, iface_num);
    config = usbd_get_cfg_data(usbd, i);
    lun_count = 0;
    if (usbd_get_cfg_data_size(usbd, i) > (int)sizeof(uint32_t))
        lun_count = MSC_LUN_COUNT(config);
    if ((config == NULL) || (usbd_get_cfg_data_size(usbd, i) < (int)((sizeof(SCSI_STORAGE_DESCRIPTOR)) * lun_count + sizeof(uint32_t))) || (lun_count == 0))
    {
#if (USBD_MSC_DEBUG_ERRORS)
        printf("MSCD: Failed to read user configuration\n");
#endif //USBD_MSC_DEBUG_ERRORS
        return;
    }
    MSCD* mscd = (MSCD*)malloc(sizeof(MSCD) + sizeof(void*) * lun_count);
    if (mscd == NULL)
        return;

    mscd->iface_num = iface_num;
    mscd->ep_num = ep_num;
    mscd->ep_size = ep_size;
    mscd->usbd = usbd;

    mscd->control = io_create(ep_size);
    mscd->data = io_create(USBD_MSC_IO_SIZE + sizeof(STORAGE_STACK));
    mscd->lun_count = lun_count;
    mscd->io_busy_mask = 0x00000000;
    mscd->io_owner = -1;
    mscd->cbw = io_data(mscd->control);
    for (i = 0; i < mscd->lun_count; ++i)
        MSCD_SCSI(mscd)[i] = scsis_create(mscd_host_cb, mscd, i, MSC_LUN_CONFIGURATION(config, i));
    if (mscd->control == NULL || mscd->data == NULL || MSCD_SCSI(mscd)[mscd->lun_count - 1] == NULL)
    {
#if (USBD_MSC_DEBUG_ERRORS)
        printf("MSCD: Out of memory\n");
#endif //USBD_MSC_DEBUG_ERRORS
        mscd_destroy(mscd);
        return;
    }

    for (i = 0; i < mscd->lun_count; ++i)
        scsis_init(MSCD_SCSI(mscd)[i]);

#if (USBD_MSC_DEBUG_REQUESTS)
    printf("Found USB MSCD class, EP%d, size: %d, iface: %d\n", ep_num, ep_size, iface_num);
#endif //USBD_MSC_DEBUG_REQUESTS

    usbd_register_interface(usbd, iface_num, &__MSCD_CLASS, mscd);
    usbd_register_endpoint(usbd, iface_num, ep_num);

    usbd_usb_ep_open(usbd, USB_EP_IN | ep_num, USB_EP_BULK, ep_size);
    usbd_usb_ep_open(usbd, ep_num, USB_EP_BULK, ep_size);

    mscd_read_cbw(usbd, mscd);
}
示例#18
0
static inline OTG_FS_DEVICE_ENDPOINT_TypeDef* ep_reg_data(int num)
{
    return (num & USB_EP_IN) ? &(OTG_FS_DEVICE->INEP[USB_EP_NUM(num)]) : &(OTG_FS_DEVICE->OUTEP[USB_EP_NUM(num)]);
}
示例#19
0
void cdc_acmd_class_configured(USBD* usbd, USB_CONFIGURATION_DESCRIPTOR* cfg)
{
    USB_INTERFACE_DESCRIPTOR* iface;
    USB_INTERFACE_DESCRIPTOR* diface;
    CDC_UNION_DESCRIPTOR* u;
    USB_ENDPOINT_DESCRIPTOR* ep;
    uint8_t data_ep, data_iface;
    uint16_t data_ep_size;
    uint8_t control_ep, control_iface;
    uint16_t control_ep_size;

    //check control/data ep here
    for (iface = usb_get_first_interface(cfg); iface != NULL; iface = usb_get_next_interface(cfg, iface))
    {
        //also skip RNDIS
        if ((iface->bInterfaceClass != CDC_COMM_INTERFACE_CLASS) || (iface->bInterfaceSubClass != CDC_ACM) || (iface->bInterfaceProtocol == CDC_CP_VENDOR))
            continue;
#if (USBD_CDC_ACM_DEBUG)
        printf("Found USB CDC ACM interface: %d\n", iface->bInterfaceNumber);
#endif //USBD_CDC_ACM_DEBUG
        //find union descriptor
        for (u = usb_interface_get_first_descriptor(cfg, iface, CS_INTERFACE); u != NULL; u = usb_interface_get_next_descriptor(cfg, u, CS_INTERFACE))
        {
            if ((u->bDescriptorSybType == CDC_DESCRIPTOR_UNION) && (u->bControlInterface == iface->bInterfaceNumber) &&
                (u->bFunctionLength > sizeof(CDC_UNION_DESCRIPTOR)))
                break;
        }
        if (u == NULL)
        {
#if (USBD_CDC_ACM_DEBUG)
            printf("USB CDC ACM: Warning - no UNION descriptor, skipping interface\n");
#endif //USBD_CDC_ACM_DEBUG
            continue;
        }
        data_iface = ((uint8_t*)u)[sizeof(CDC_UNION_DESCRIPTOR)];
        diface = usb_find_interface(cfg, data_iface);
        if (diface == NULL)
        {
#if (USBD_CDC_ACM_DEBUG)
            printf("USB CDC ACM: Warning no data interface\n");
#endif //USBD_CDC_ACM_DEBUG
            continue;
        }
#if (USBD_CDC_ACM_DEBUG)
        printf("Found USB CDC ACM data interface: %d\n", data_iface);
#endif //USBD_CDC_ACM_DEBUG

        ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, diface, USB_ENDPOINT_DESCRIPTOR_TYPE);
        if (ep == NULL)
        {
#if (USBD_CDC_ACM_DEBUG)
            printf("USB CDC ACM: Warning no data EP, skipping interface\n");
#endif //USBD_CDC_ACM_DEBUG
            continue;
        }
        data_ep = USB_EP_NUM(ep->bEndpointAddress);
        data_ep_size = ep->wMaxPacketSize;

        control_iface = iface->bInterfaceNumber;
        control_ep = control_ep_size = 0;
        ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, iface, USB_ENDPOINT_DESCRIPTOR_TYPE);
        if (ep != NULL)
        {
            control_ep = USB_EP_NUM(ep->bEndpointAddress);
            control_ep_size = ep->wMaxPacketSize;
        }

        //configuration is ok, applying
        CDC_ACMD* cdc_acmd = (CDC_ACMD*)malloc(sizeof(CDC_ACMD));
        if (cdc_acmd == NULL)
        {
#if (USBD_CDC_ACM_DEBUG)
            printf("USB CDC ACM: Out of memory\n");
#endif //USBD_CDC_ACM_DEBUG
            return;
        }

        cdc_acmd->data_iface = data_iface;
        cdc_acmd->data_ep = data_ep;
        cdc_acmd->data_ep_size = data_ep_size;
        cdc_acmd->tx = cdc_acmd->rx = NULL;
        cdc_acmd->tx_stream = cdc_acmd->rx_stream = cdc_acmd->tx_stream_handle = cdc_acmd->rx_stream_handle = INVALID_HANDLE;
        cdc_acmd->suspended = false;

        cdc_acmd->control_iface = control_iface;
        cdc_acmd->control_ep = control_ep;
        cdc_acmd->control_ep_size = control_ep_size;
        cdc_acmd->notify = NULL;
        cdc_acmd->notify_busy = cdc_acmd->notify_pending = false;
#if (USBD_CDC_ACM_FLOW_CONTROL)
        cdc_acmd->flow_sending = false;
        cdc_acmd->flow_changed = false;
        cdc_acmd->break_count = 0;
#endif //USBD_CDC_ACM_FLOW_CONTROL

#if (USBD_CDC_ACM_TX_STREAM_SIZE)
        cdc_acmd->tx = io_create(cdc_acmd->data_ep_size);
        cdc_acmd->tx_stream = stream_create(USBD_CDC_ACM_RX_STREAM_SIZE);
        cdc_acmd->tx_stream_handle = stream_open(cdc_acmd->tx_stream);
        if (cdc_acmd->tx == NULL || cdc_acmd->tx_stream_handle == INVALID_HANDLE)
        {
#if (USBD_CDC_ACM_DEBUG)
            printf("USB CDC ACM: Out of memory\n");
#endif //USBD_CDC_ACM_DEBUG
            cdc_acmd_destroy(cdc_acmd);
            return;
        }
        cdc_acmd->tx_size = 0;
        cdc_acmd->tx_idle = true;
        usbd_usb_ep_open(usbd, USB_EP_IN | cdc_acmd->data_ep, USB_EP_BULK, cdc_acmd->data_ep_size);
        stream_listen(cdc_acmd->tx_stream, USBD_IFACE(cdc_acmd->data_iface, 0), HAL_USBD_IFACE);
#endif //USBD_CDC_ACM_TX_STREAM_SIZE

#if (USBD_CDC_ACM_RX_STREAM_SIZE)
        cdc_acmd->rx = io_create(cdc_acmd->data_ep_size);
        cdc_acmd->rx_stream = stream_create(USBD_CDC_ACM_RX_STREAM_SIZE);
        cdc_acmd->rx_stream_handle = stream_open(cdc_acmd->rx_stream);
        if (cdc_acmd->rx == NULL || cdc_acmd->rx_stream_handle == INVALID_HANDLE)
        {
#if (USBD_CDC_ACM_DEBUG)
            printf("USB CDC ACM: Out of memory\n");
#endif //USBD_CDC_ACM_DEBUG
            cdc_acmd_destroy(cdc_acmd);
            return;
        }
        cdc_acmd->rx_free = 0;
        usbd_usb_ep_open(usbd, cdc_acmd->data_ep, USB_EP_BULK, cdc_acmd->data_ep_size);
        usbd_usb_ep_read(usbd, cdc_acmd->data_ep, cdc_acmd->rx, cdc_acmd->data_ep_size);
#endif //USBD_CDC_ACM_RX_STREAM_SIZE

        usbd_register_interface(usbd, cdc_acmd->data_iface, &__CDC_ACMD_CLASS, cdc_acmd);
        usbd_register_endpoint(usbd, cdc_acmd->data_iface, cdc_acmd->data_ep);

        if (control_ep_size)
        {
            if (cdc_acmd->control_ep_size < 16)
            {
#if (USBD_CDC_ACM_DEBUG)
                printf("USB CDC ACM: Warning - control endpoint is too small(%d), 16 at least required to fit notify", cdc_acmd->control_ep_size);
#endif //USBD_CDC_ACM_DEBUG
                cdc_acmd->notify = io_create(16);
            }
            else
                cdc_acmd->notify = io_create(cdc_acmd->control_ep_size);
            if (cdc_acmd->notify == NULL)
            {
                cdc_acmd_destroy(cdc_acmd);
                return;
            }
            usbd_usb_ep_open(usbd, USB_EP_IN | cdc_acmd->control_ep, USB_EP_INTERRUPT, cdc_acmd->control_ep_size);
            usbd_register_interface(usbd, cdc_acmd->control_iface, &__CDC_ACMD_CLASS, cdc_acmd);
            usbd_register_endpoint(usbd, cdc_acmd->control_iface, cdc_acmd->control_ep);
            cdc_acmd_notify_serial_state(usbd, cdc_acmd, CDC_SERIAL_STATE_DCD | CDC_SERIAL_STATE_DSR);
        }
        cdc_acmd->DTR = cdc_acmd->RTS = false;
        cdc_acmd->baud.baud = 115200;
        cdc_acmd->baud.data_bits = 8;
        cdc_acmd->baud.parity = 'N';
        cdc_acmd->baud.stop_bits = 1;
    }
}
示例#20
0
static inline void stm32_otg_open_ep(EXO* exo, int num, USB_EP_TYPE type, unsigned int size)
{
    if (ep_data(exo, num) != NULL)
    {
        kerror(ERROR_ALREADY_CONFIGURED);
        return;
    }
    EP* ep = kmalloc(sizeof(EP));
    if (ep == NULL)
        return;
    num & USB_EP_IN ? (exo->usb.in[USB_EP_NUM(num)] = ep) : (exo->usb.out[USB_EP_NUM(num)] = ep);
    ep->io = NULL;
    ep->mps = 0;
    ep->io_active = false;

    int fifo_used, i;
    //enable, NAK
    uint32_t ctl = OTG_FS_DEVICE_ENDPOINT_CTL_USBAEP | OTG_FS_DEVICE_ENDPOINT_CTL_SNAK;
    //setup ep type, DATA0 for bulk/interrupt, EVEN frame for isochronous endpoint
    switch (type)
    {
    case USB_EP_CONTROL:
        ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_EPTYP_CONTROL;
        break;
    case USB_EP_BULK:
        ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_EPTYP_BULK | OTG_FS_DEVICE_ENDPOINT_CTL_DPID;
        break;
    case USB_EP_INTERRUPT:
        ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_EPTYP_INTERRUPT | OTG_FS_DEVICE_ENDPOINT_CTL_DPID;
        break;
    case USB_EP_ISOCHRON:
        ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_EPTYP_ISOCHRONOUS | OTG_FS_DEVICE_ENDPOINT_CTL_SEVNFRM;
        break;
    }

    if (num & USB_EP_IN)
    {
        //setup TX FIFO num for IN endpoint
        fifo_used = OTG_FS_GENERAL->RXFSIZ & 0xffff;
        for (i = 0; i < USB_EP_NUM(num); ++i)
            fifo_used += exo->usb.in[i]->mps / 4;
        if (USB_EP_NUM(num))
            OTG_FS_GENERAL->DIEPTXF[USB_EP_NUM(num) - 1] = ((size / 4)  << OTG_FS_GENERAL_TX0FSIZ_TX0FD_POS) | ((fifo_used * 4) | OTG_FS_GENERAL_TX0FSIZ_TX0FSA_POS);
        else
            OTG_FS_GENERAL->TX0FSIZ = ((size / 4)  << OTG_FS_GENERAL_TX0FSIZ_TX0FD_POS) | ((fifo_used * 4) | OTG_FS_GENERAL_TX0FSIZ_TX0FSA_POS);
        ctl |= USB_EP_NUM(num) << OTG_FS_DEVICE_ENDPOINT_CTL_TXFNUM_POS;
        //enable interrupts for XFRCM
        OTG_FS_DEVICE->AINTMSK |= 1 << USB_EP_NUM(num);
    }

    //EP_OUT0 has differrent mps structure
    if (USB_EP_NUM(num) == 0)
    {
        switch (size)
        {
        case 8:
            ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_MPSIZ0_8;
            break;
        case 16:
            ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_MPSIZ0_16;
            break;
        case 32:
            ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_MPSIZ0_32;
            break;
        default:
            ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_MPSIZ0_64;
        }
    }
    else
        ctl |= size;

    ep->mps = size;
    ep_reg_data(num)->CTL = ctl;
}
示例#21
0
static inline EP* ep_data(EXO* exo, int num)
{
    return (num & USB_EP_IN) ? (exo->usb.in[USB_EP_NUM(num)]) : (exo->usb.out[USB_EP_NUM(num)]);
}