Changed file extensions from .c to .cpp
Fork of USBMIDI by
Revision 3:1c9f95100210, committed 2016-04-29
- Comitter:
- KrissyHam
- Date:
- Fri Apr 29 01:46:03 2016 +0000
- Parent:
- 2:10d694d6ccdc
- Commit message:
- Changed file extensions from .c to .cpp
Changed in this revision
--- a/usbcore.c Sun Feb 20 13:12:22 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,278 +0,0 @@ -/* @license The MIT License - * Copyright (c) 2011 mux, simon - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "usbcore.h" - -#include "mbed.h" - -// Serial Interface Engine -#define SIE_SET_ADDR (0xD0) -#define SIE_SET_STATUS (0xFE) -#define SIE_GET_STATUS (0xFE) -#define SIE_SET_MODE (0xF3) -#define SIE_CLR_BUFFER (0xF2) -#define SIE_VAL_BUFFER (0xFA) -#define SIE_SEL_EP (0x00) -#define SIE_SEL_CLR_EP (0x28) -#define SIE_SET_EP_STAT (0x40) -#define SIE_READ_ERROR (0xFB) -#define SIE_CONFIG_DEVICE (0xD8) - -// EP status -#define EP_FE (1<<0) // Full/Empty -#define EP_ST (1<<1) // Stalled endpoint -#define EP_STP (1<<2) // Setup packet -#define EP_PO (1<<3) // packet overwritten -#define EP_EPN (1<<4) // EP NAKed -#define B_1_FULL (1<<5) // buffer 1 status -#define B_2_FULL (1<<6) // buffer 2 status - -// USB device interrupts -#define DEV_FRAME (1<<0) -#define EP_FAST (1<<1) -#define EP_SLOW (1<<2) -#define DEV_STAT (1<<3) -#define RxENDPKT (1<<6) -#define TxENDPKT (1<<7) -#define EP_RLZED (1<<8) -#define CCEMPTY (0x10) -#define CDFULL (0x20) - -// USB device status bits -#define STAT_CON (1<<0) -#define STAT_CON_CH (1<<1) -#define STAT_SUS (1<<2) -#define STAT_SUS_CH (1<<3) -#define STAT_RST (1<<4) - -// end points interrupts -#define EP0RX_INT (1<<0) -#define EP0TX_INT (1<<1) -#define EP1RX_INT (1<<2) -#define EP1TX_INT (1<<3) -#define EP2RX_INT (1<<4) -#define EP2TX_INT (1<<5) - -// USB control register -#define RD_EN (1<<0) -#define WR_EN (1<<1) -#define PKT_RDY (1<<11) -#define LOG_ENDPOINT(ep) ((ep>>1)<<2) - -// configure state -static int configured = 0; - -// USB interrupt handler -void USB_IRQHandler(void); - -// Serial Interface Engine functions -void sie_command(uint32_t code) { - LPC_USB->USBDevIntClr = CCEMPTY; // clear CCEMPTY - LPC_USB->USBCmdCode = ((code<<16)|(0x05<<8)); // CMD_PHASE=Command - while (!(LPC_USB->USBDevIntSt & CCEMPTY)); // wait for CCEMPTY -} - -void sie_write(uint32_t data) { - LPC_USB->USBDevIntClr = CCEMPTY; // clear CCEMPTY - LPC_USB->USBCmdCode = ((data<<16)|(0x01<<8)); // CMD_PHASE=Write - while (!(LPC_USB->USBDevIntSt & CCEMPTY)); // wait for CCEMPTY -} - -uint8_t sie_read(uint32_t code) { - LPC_USB->USBDevIntClr = CDFULL; // clear CCEMPTY - LPC_USB->USBCmdCode = ((code<<16)|(0x02<<8)); // CMD_PHASE=Read - while (!(LPC_USB->USBDevIntSt & CDFULL)); // wait for CDFULL - return (uint8_t) LPC_USB->USBCmdData; - -} - -// end point functions -void ep_realize(uint8_t ep, uint32_t size) { - LPC_USB->USBDevIntClr = EP_RLZED; // clear EP_RLZED - LPC_USB->USBReEp |= (1<<ep); - LPC_USB->USBEpInd = ep; // set USBEpIn - LPC_USB->USBMaxPSize = size; // writing to EPn pointed to by USBEpInd - while (!(LPC_USB->USBDevIntSt & EP_RLZED)); // wait for EP_RLZED - LPC_USB->USBDevIntClr = EP_RLZED; // clear EP_RLZED -} - -void ep_stall(uint8_t ep) { - sie_command(SIE_SET_EP_STAT+ep); - sie_write(1); -} - -void ep_unstall(uint8_t ep) { - sie_command(SIE_SET_EP_STAT+ep); - sie_write(0); -} - -// initializes a pointer to the endpoint buffer -uint8_t ep_select(uint8_t ep) { - sie_command(SIE_SEL_EP+ep); - return sie_read(SIE_SEL_EP+ep); -} - -uint8_t ep_select_clear(uint8_t ep) { - LPC_USB->USBEpIntClr |= ep; // clear ep interrupt - while (!(LPC_USB->USBDevIntSt & CDFULL)); // wait for cmd finish - return LPC_USB->USBCmdData; -} - -int ep_readable(uint8_t ep) { - uint8_t st = ep_select(ep); - return (st & EP_FE); -} - -int ep_writable(uint8_t ep) { - uint8_t st = ep_select(ep); - return !(st & EP_FE); -} - -int ep_read(uint8_t ep, uint8_t *tbuf) { - uint32_t *buf = (uint32_t*) tbuf; - LPC_USB->USBCtrl = LOG_ENDPOINT(ep)|RD_EN; // RD_EN bit and LOG_ENDPOINT - while (!(LPC_USB->USBRxPLen & PKT_RDY)); // wait for packet to be fetched - int len = LPC_USB->USBRxPLen & 0x3FF; // read and mask packet length - while (!(LPC_USB->USBDevIntSt & RxENDPKT)) { - *buf++ = LPC_USB->USBRxData; - } - LPC_USB->USBCtrl = 0; - LPC_USB->USBDevIntClr |= RxENDPKT; - sie_command(SIE_SEL_EP+ep); // select endpoint - sie_command(SIE_CLR_BUFFER); // clear RX buffer - return len; -} - -void ep_write(uint8_t ep, uint8_t *tbuf, uint32_t len) { - uint32_t *buf = (uint32_t*) tbuf; - LPC_USB->USBCtrl = LOG_ENDPOINT(ep)|WR_EN; // RD_EN bit and LOG_ENDPOINT - LPC_USB->USBTxPLen |= (len & 0x3FF); // write and mask packet length - while (!(LPC_USB->USBDevIntSt & TxENDPKT)) { - LPC_USB->USBTxData = *buf++; - } - LPC_USB->USBCtrl = 0; - LPC_USB->USBDevIntClr |= TxENDPKT; - sie_command(SIE_SEL_EP+ep); // select endpoint - sie_command(SIE_VAL_BUFFER); // validate TX buffer -} - -// USB device controller initialization -void usb_init() { - // USB D+/D- pinsel functions - LPC_PINCON->PINSEL1 &= 0xC3FFFFFF; - LPC_PINCON->PINSEL1 |= 0x14000000; - -#if USB_UP_DEBUG - // USB_UP_LED pinsel function - LPC_PINCON->PINSEL3 &= 0xFFFFFFCF; - LPC_PINCON->PINSEL3 |= 0x00000010; -#endif - - // USB connect pinsel function - LPC_PINCON->PINSEL4 &= 0xFFFCFFFF; - LPC_PINCON->PINSEL4 |= 0x00040000; - LPC_SC->PCONP |= (1UL<<31); // enable the USB controller - LPC_USB->USBClkCtrl |= ((1<<1)|(1<<4)); // enable the AHB and DEV clocks - while ((LPC_USB->USBClkSt & 0x12) != 0x12); // wait for the clocks to init - - NVIC_SetVector(USB_IRQn, (uint32_t)&USB_IRQHandler); - NVIC_EnableIRQ(USB_IRQn); // enable USB interrupts - - usb_reset(); - usb_set_address(0); // default address -} - -void usb_reset() { - ep_realize(EP0, MAX_EP0_PSIZE); - ep_realize(EP1, MAX_EP0_PSIZE); - LPC_USB->USBEpIntClr = 0xFFFFFFFF; // clear end points interrupts - LPC_USB->USBEpIntEn = 0xFFFFFFFF; // enable end points interrupts - LPC_USB->USBEpIntPri = 0x0; // route to EP_SLOW - LPC_USB->USBDevIntClr = 0xFFFFFFFF; // clear USB device interrupts - LPC_USB->USBDevIntEn = (EP_SLOW|DEV_STAT); // enable USB device interrupts -} - -void usb_configure(uint8_t conf) { - sie_command(SIE_CONFIG_DEVICE); - sie_write(conf); - configured = 1; -} - -int usb_configured() { - return configured; -} - -void usb_set_address(uint8_t addr) { - sie_command(SIE_SET_ADDR); - sie_write(addr|0x80); // DEV_EN = 1 -} - -uint8_t usb_get_status() { - sie_command(SIE_GET_STATUS); - return sie_read(SIE_GET_STATUS); -} - -void usb_connect() { - sie_command(SIE_GET_STATUS); // read current status - uint8_t st = sie_read(SIE_GET_STATUS); - - sie_command(SIE_SET_STATUS); // set STAT_CON bit - sie_write(st|STAT_CON); -} - -void USB_IRQHandler(void) { - if (LPC_USB->USBDevIntSt & DEV_STAT) { // DEV_STAT interrupt - LPC_USB->USBDevIntClr |= DEV_STAT; - if (usb_get_status() & STAT_RST) { // bus reset - usb_reset(); - } - return; - } - - if (LPC_USB->USBDevIntSt & EP_SLOW) { // EP_SLOW interrupt - if (LPC_USB->USBEpIntSt & EP0RX_INT) { - if (ep_select_clear(EP0RX_INT) & EP_STP) { // setup transfer - ep0_setup(); - } else { - ep0_out(); - } - } - - if (LPC_USB->USBEpIntSt & EP0TX_INT) { - ep_select_clear(EP0TX_INT); - ep0_in(); - } - - if (LPC_USB->USBEpIntSt & EP2RX_INT) { - ep_select_clear(EP2TX_INT); - ep2_out(); - } - - if (LPC_USB->USBEpIntSt & EP2TX_INT) { - ep_select_clear(EP2TX_INT); - ep2_in(); - } - - // EP_SLOW should be cleared after clearing EPs interrupts - LPC_USB->USBDevIntClr |= EP_SLOW; - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbcore.cpp Fri Apr 29 01:46:03 2016 +0000 @@ -0,0 +1,278 @@ +/* @license The MIT License + * Copyright (c) 2011 mux, simon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "usbcore.h" + +#include "mbed.h" + +// Serial Interface Engine +#define SIE_SET_ADDR (0xD0) +#define SIE_SET_STATUS (0xFE) +#define SIE_GET_STATUS (0xFE) +#define SIE_SET_MODE (0xF3) +#define SIE_CLR_BUFFER (0xF2) +#define SIE_VAL_BUFFER (0xFA) +#define SIE_SEL_EP (0x00) +#define SIE_SEL_CLR_EP (0x28) +#define SIE_SET_EP_STAT (0x40) +#define SIE_READ_ERROR (0xFB) +#define SIE_CONFIG_DEVICE (0xD8) + +// EP status +#define EP_FE (1<<0) // Full/Empty +#define EP_ST (1<<1) // Stalled endpoint +#define EP_STP (1<<2) // Setup packet +#define EP_PO (1<<3) // packet overwritten +#define EP_EPN (1<<4) // EP NAKed +#define B_1_FULL (1<<5) // buffer 1 status +#define B_2_FULL (1<<6) // buffer 2 status + +// USB device interrupts +#define DEV_FRAME (1<<0) +#define EP_FAST (1<<1) +#define EP_SLOW (1<<2) +#define DEV_STAT (1<<3) +#define RxENDPKT (1<<6) +#define TxENDPKT (1<<7) +#define EP_RLZED (1<<8) +#define CCEMPTY (0x10) +#define CDFULL (0x20) + +// USB device status bits +#define STAT_CON (1<<0) +#define STAT_CON_CH (1<<1) +#define STAT_SUS (1<<2) +#define STAT_SUS_CH (1<<3) +#define STAT_RST (1<<4) + +// end points interrupts +#define EP0RX_INT (1<<0) +#define EP0TX_INT (1<<1) +#define EP1RX_INT (1<<2) +#define EP1TX_INT (1<<3) +#define EP2RX_INT (1<<4) +#define EP2TX_INT (1<<5) + +// USB control register +#define RD_EN (1<<0) +#define WR_EN (1<<1) +#define PKT_RDY (1<<11) +#define LOG_ENDPOINT(ep) ((ep>>1)<<2) + +// configure state +static int configured = 0; + +// USB interrupt handler +void USB_IRQHandler(void); + +// Serial Interface Engine functions +void sie_command(uint32_t code) { + LPC_USB->USBDevIntClr = CCEMPTY; // clear CCEMPTY + LPC_USB->USBCmdCode = ((code<<16)|(0x05<<8)); // CMD_PHASE=Command + while (!(LPC_USB->USBDevIntSt & CCEMPTY)); // wait for CCEMPTY +} + +void sie_write(uint32_t data) { + LPC_USB->USBDevIntClr = CCEMPTY; // clear CCEMPTY + LPC_USB->USBCmdCode = ((data<<16)|(0x01<<8)); // CMD_PHASE=Write + while (!(LPC_USB->USBDevIntSt & CCEMPTY)); // wait for CCEMPTY +} + +uint8_t sie_read(uint32_t code) { + LPC_USB->USBDevIntClr = CDFULL; // clear CCEMPTY + LPC_USB->USBCmdCode = ((code<<16)|(0x02<<8)); // CMD_PHASE=Read + while (!(LPC_USB->USBDevIntSt & CDFULL)); // wait for CDFULL + return (uint8_t) LPC_USB->USBCmdData; + +} + +// end point functions +void ep_realize(uint8_t ep, uint32_t size) { + LPC_USB->USBDevIntClr = EP_RLZED; // clear EP_RLZED + LPC_USB->USBReEp |= (1<<ep); + LPC_USB->USBEpInd = ep; // set USBEpIn + LPC_USB->USBMaxPSize = size; // writing to EPn pointed to by USBEpInd + while (!(LPC_USB->USBDevIntSt & EP_RLZED)); // wait for EP_RLZED + LPC_USB->USBDevIntClr = EP_RLZED; // clear EP_RLZED +} + +void ep_stall(uint8_t ep) { + sie_command(SIE_SET_EP_STAT+ep); + sie_write(1); +} + +void ep_unstall(uint8_t ep) { + sie_command(SIE_SET_EP_STAT+ep); + sie_write(0); +} + +// initializes a pointer to the endpoint buffer +uint8_t ep_select(uint8_t ep) { + sie_command(SIE_SEL_EP+ep); + return sie_read(SIE_SEL_EP+ep); +} + +uint8_t ep_select_clear(uint8_t ep) { + LPC_USB->USBEpIntClr |= ep; // clear ep interrupt + while (!(LPC_USB->USBDevIntSt & CDFULL)); // wait for cmd finish + return LPC_USB->USBCmdData; +} + +int ep_readable(uint8_t ep) { + uint8_t st = ep_select(ep); + return (st & EP_FE); +} + +int ep_writable(uint8_t ep) { + uint8_t st = ep_select(ep); + return !(st & EP_FE); +} + +int ep_read(uint8_t ep, uint8_t *tbuf) { + uint32_t *buf = (uint32_t*) tbuf; + LPC_USB->USBCtrl = LOG_ENDPOINT(ep)|RD_EN; // RD_EN bit and LOG_ENDPOINT + while (!(LPC_USB->USBRxPLen & PKT_RDY)); // wait for packet to be fetched + int len = LPC_USB->USBRxPLen & 0x3FF; // read and mask packet length + while (!(LPC_USB->USBDevIntSt & RxENDPKT)) { + *buf++ = LPC_USB->USBRxData; + } + LPC_USB->USBCtrl = 0; + LPC_USB->USBDevIntClr |= RxENDPKT; + sie_command(SIE_SEL_EP+ep); // select endpoint + sie_command(SIE_CLR_BUFFER); // clear RX buffer + return len; +} + +void ep_write(uint8_t ep, uint8_t *tbuf, uint32_t len) { + uint32_t *buf = (uint32_t*) tbuf; + LPC_USB->USBCtrl = LOG_ENDPOINT(ep)|WR_EN; // RD_EN bit and LOG_ENDPOINT + LPC_USB->USBTxPLen |= (len & 0x3FF); // write and mask packet length + while (!(LPC_USB->USBDevIntSt & TxENDPKT)) { + LPC_USB->USBTxData = *buf++; + } + LPC_USB->USBCtrl = 0; + LPC_USB->USBDevIntClr |= TxENDPKT; + sie_command(SIE_SEL_EP+ep); // select endpoint + sie_command(SIE_VAL_BUFFER); // validate TX buffer +} + +// USB device controller initialization +void usb_init() { + // USB D+/D- pinsel functions + LPC_PINCON->PINSEL1 &= 0xC3FFFFFF; + LPC_PINCON->PINSEL1 |= 0x14000000; + +#if USB_UP_DEBUG + // USB_UP_LED pinsel function + LPC_PINCON->PINSEL3 &= 0xFFFFFFCF; + LPC_PINCON->PINSEL3 |= 0x00000010; +#endif + + // USB connect pinsel function + LPC_PINCON->PINSEL4 &= 0xFFFCFFFF; + LPC_PINCON->PINSEL4 |= 0x00040000; + LPC_SC->PCONP |= (1UL<<31); // enable the USB controller + LPC_USB->USBClkCtrl |= ((1<<1)|(1<<4)); // enable the AHB and DEV clocks + while ((LPC_USB->USBClkSt & 0x12) != 0x12); // wait for the clocks to init + + NVIC_SetVector(USB_IRQn, (uint32_t)&USB_IRQHandler); + NVIC_EnableIRQ(USB_IRQn); // enable USB interrupts + + usb_reset(); + usb_set_address(0); // default address +} + +void usb_reset() { + ep_realize(EP0, MAX_EP0_PSIZE); + ep_realize(EP1, MAX_EP0_PSIZE); + LPC_USB->USBEpIntClr = 0xFFFFFFFF; // clear end points interrupts + LPC_USB->USBEpIntEn = 0xFFFFFFFF; // enable end points interrupts + LPC_USB->USBEpIntPri = 0x0; // route to EP_SLOW + LPC_USB->USBDevIntClr = 0xFFFFFFFF; // clear USB device interrupts + LPC_USB->USBDevIntEn = (EP_SLOW|DEV_STAT); // enable USB device interrupts +} + +void usb_configure(uint8_t conf) { + sie_command(SIE_CONFIG_DEVICE); + sie_write(conf); + configured = 1; +} + +int usb_configured() { + return configured; +} + +void usb_set_address(uint8_t addr) { + sie_command(SIE_SET_ADDR); + sie_write(addr|0x80); // DEV_EN = 1 +} + +uint8_t usb_get_status() { + sie_command(SIE_GET_STATUS); + return sie_read(SIE_GET_STATUS); +} + +void usb_connect() { + sie_command(SIE_GET_STATUS); // read current status + uint8_t st = sie_read(SIE_GET_STATUS); + + sie_command(SIE_SET_STATUS); // set STAT_CON bit + sie_write(st|STAT_CON); +} + +void USB_IRQHandler(void) { + if (LPC_USB->USBDevIntSt & DEV_STAT) { // DEV_STAT interrupt + LPC_USB->USBDevIntClr |= DEV_STAT; + if (usb_get_status() & STAT_RST) { // bus reset + usb_reset(); + } + return; + } + + if (LPC_USB->USBDevIntSt & EP_SLOW) { // EP_SLOW interrupt + if (LPC_USB->USBEpIntSt & EP0RX_INT) { + if (ep_select_clear(EP0RX_INT) & EP_STP) { // setup transfer + ep0_setup(); + } else { + ep0_out(); + } + } + + if (LPC_USB->USBEpIntSt & EP0TX_INT) { + ep_select_clear(EP0TX_INT); + ep0_in(); + } + + if (LPC_USB->USBEpIntSt & EP2RX_INT) { + ep_select_clear(EP2TX_INT); + ep2_out(); + } + + if (LPC_USB->USBEpIntSt & EP2TX_INT) { + ep_select_clear(EP2TX_INT); + ep2_in(); + } + + // EP_SLOW should be cleared after clearing EPs interrupts + LPC_USB->USBDevIntClr |= EP_SLOW; + } +}
--- a/usbdevice.c Sun Feb 20 13:12:22 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -/* @license The MIT License - * Copyright (c) 2011 mux, simon - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "usbcore.h" -#include "mbed.h" - -#define STANDARD_DEVICE_REQUEST (0x00) -#define STANDARD_INTERFACE_REQUEST (0x01) -#define STANDARD_ENDPOINT_REQUEST (0x02) -#define CLASS_DEVICE_REQUEST (0x20) -#define CLASS_INTERFACE_REQUEST (0x21) -#define CLASS_ENDPOINT_REQUEST (0x22) -#define VENDOR_DEVICE_REQUEST (0x40) -#define VENDOR_INTERFACE_REQUEST (0x41) -#define VENDOR_ENDPOINT_REQUEST (0x42) -#define GET_STATUS (0x00) -#define CLEAR_FEATURE (0x01) -#define SET_FEATURE (0x03) -#define SET_ADDRESS (0x05) -#define GET_DESCRIPTOR (0x06) -#define SET_DESCRIPTOR (0x07) -#define GET_CONFIGURATION (0x08) -#define SET_CONFIGURATION (0x09) -#define DEVICE_DESCRIPTOR (0x01) -#define CONFIG_DESCRIPTOR (0x02) -#define STRING_DESCRIPTOR (0x03) -#define INTERFACE_DESCRIPTOR (0x04) -#define ENDPOINT_DESCRIPTOR (0x05) -#define QUALIFIER_DESCRIPTOR (0x06) -#define unpack(x) (x & 0xFF),((x >> 8) & 0xFF) - -// setup packet -struct { - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -} __attribute__((packed)) setup = {0}; - -// data packet -struct { - uint8_t *data; - uint8_t size; - uint8_t sent; -} transfer = {0}; - -uint8_t device_descriptor[] = { - 0x12, // Descriptor size in bytes (12h) - DEVICE_DESCRIPTOR, // The constant DEVICE (01h) - unpack(0x0200), // US2B specification release number (BCD) - 0x00, // Class code - 0x00, // Subclass code - 0x00, // Protocol Code - MAX_EP0_PSIZE, // Maximum packet size for endpoint zero - unpack(0x0763), // Vendor ID - unpack(0x0198), // Product ID - unpack(0x0001), // Device release number (BCD) - 0x00, // Index of string descriptor for the manufacturer - 0x00, // Index of string descriptor for the product - 0x00, // Index of string descriptor for the serial number - 0x01, // Number of possible configurations -}; - -uint8_t config_descriptor[]={ - 0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50, // configuration descriptor - // The Audio Interface Collection - 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Standard AC Interface Descriptor - 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // Class-specific AC Interface Descriptor - 0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // MIDIStreaming Interface Descriptors - 0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, // Class-Specific MS Interface Header Descriptor - - // MIDI IN JACKS - 0x06, 0x24, 0x02, 0x01, 0x01, 0x00, - 0x06, 0x24, 0x02, 0x02, 0x02, 0x00, - - // MIDI OUT JACKS - 0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, - 0x09, 0x24, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x00, - - // OUT endpoint descriptor - 0x09, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x25, 0x01, 0x01, 0x01, - - // IN endpoint descriptor - 0x09, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x25, 0x01, 0x01, 0x03, -}; - -void ep0_in(); - -void data_in_stage(uint8_t *desc, uint8_t length) { - transfer.sent = 0; - transfer.data = desc; - transfer.size = length; - ep0_in(); -} - -void status_in_stage() { - ep_write(EP1, 0, 0); // ZLEP for status stage -} - -void ep0_setup() { - ep_read(EP0,(uint8_t*) &setup); - - switch (setup.bmRequestType & 0x7f) { // mask direction - case STANDARD_DEVICE_REQUEST: - switch (setup.bRequest) { - case GET_DESCRIPTOR: - switch ((setup.wValue>>8)) { - case DEVICE_DESCRIPTOR: // device descriptor request - case QUALIFIER_DESCRIPTOR: // device qualifier descriptor - data_in_stage(device_descriptor, sizeof(device_descriptor)); - break; - case CONFIG_DESCRIPTOR: // configuration descriptor - data_in_stage(config_descriptor, setup.wLength); - break; - case STRING_DESCRIPTOR: - break; - default: - break; - } - break; - case SET_ADDRESS: - usb_set_address((uint8_t) (setup.wValue & 0xFF)); - status_in_stage(); - break; - case SET_CONFIGURATION: - if (!setup.wValue) { - break; - } - ep_realize(EP4, MAX_EPn_PSIZE); - ep_realize(EP5, MAX_EPn_PSIZE); - status_in_stage(); - usb_configure(1); - break; - default: - break; - } - break; - default: - break; - } -} - -void ep0_in() { - if ((setup.bmRequestType & 0x80) && transfer.size) { // device to host - if (transfer.size > MAX_EP0_PSIZE) { - transfer.sent = MAX_EP0_PSIZE; - } else { - transfer.sent = transfer.size; - } - ep_write(EP1, transfer.data, transfer.sent); - transfer.data += transfer.sent; - transfer.size -= transfer.sent; - } -} - -void ep0_out() { - uint8_t buf[64]; - ep_read(EP0, buf); -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbdevice.cpp Fri Apr 29 01:46:03 2016 +0000 @@ -0,0 +1,181 @@ +/* @license The MIT License + * Copyright (c) 2011 mux, simon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "usbcore.h" +#include "mbed.h" + +#define STANDARD_DEVICE_REQUEST (0x00) +#define STANDARD_INTERFACE_REQUEST (0x01) +#define STANDARD_ENDPOINT_REQUEST (0x02) +#define CLASS_DEVICE_REQUEST (0x20) +#define CLASS_INTERFACE_REQUEST (0x21) +#define CLASS_ENDPOINT_REQUEST (0x22) +#define VENDOR_DEVICE_REQUEST (0x40) +#define VENDOR_INTERFACE_REQUEST (0x41) +#define VENDOR_ENDPOINT_REQUEST (0x42) +#define GET_STATUS (0x00) +#define CLEAR_FEATURE (0x01) +#define SET_FEATURE (0x03) +#define SET_ADDRESS (0x05) +#define GET_DESCRIPTOR (0x06) +#define SET_DESCRIPTOR (0x07) +#define GET_CONFIGURATION (0x08) +#define SET_CONFIGURATION (0x09) +#define DEVICE_DESCRIPTOR (0x01) +#define CONFIG_DESCRIPTOR (0x02) +#define STRING_DESCRIPTOR (0x03) +#define INTERFACE_DESCRIPTOR (0x04) +#define ENDPOINT_DESCRIPTOR (0x05) +#define QUALIFIER_DESCRIPTOR (0x06) +#define unpack(x) (x & 0xFF),((x >> 8) & 0xFF) + +// setup packet +struct { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} __attribute__((packed)) setup = {0}; + +// data packet +struct { + uint8_t *data; + uint8_t size; + uint8_t sent; +} transfer = {0}; + +uint8_t device_descriptor[] = { + 0x12, // Descriptor size in bytes (12h) + DEVICE_DESCRIPTOR, // The constant DEVICE (01h) + unpack(0x0200), // US2B specification release number (BCD) + 0x00, // Class code + 0x00, // Subclass code + 0x00, // Protocol Code + MAX_EP0_PSIZE, // Maximum packet size for endpoint zero + unpack(0x0763), // Vendor ID + unpack(0x0198), // Product ID + unpack(0x0001), // Device release number (BCD) + 0x00, // Index of string descriptor for the manufacturer + 0x00, // Index of string descriptor for the product + 0x00, // Index of string descriptor for the serial number + 0x01, // Number of possible configurations +}; + +uint8_t config_descriptor[]={ + 0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50, // configuration descriptor + // The Audio Interface Collection + 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Standard AC Interface Descriptor + 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // Class-specific AC Interface Descriptor + 0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // MIDIStreaming Interface Descriptors + 0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, // Class-Specific MS Interface Header Descriptor + + // MIDI IN JACKS + 0x06, 0x24, 0x02, 0x01, 0x01, 0x00, + 0x06, 0x24, 0x02, 0x02, 0x02, 0x00, + + // MIDI OUT JACKS + 0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, + 0x09, 0x24, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x00, + + // OUT endpoint descriptor + 0x09, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x25, 0x01, 0x01, 0x01, + + // IN endpoint descriptor + 0x09, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x25, 0x01, 0x01, 0x03, +}; + +void ep0_in(); + +void data_in_stage(uint8_t *desc, uint8_t length) { + transfer.sent = 0; + transfer.data = desc; + transfer.size = length; + ep0_in(); +} + +void status_in_stage() { + ep_write(EP1, 0, 0); // ZLEP for status stage +} + +void ep0_setup() { + ep_read(EP0,(uint8_t*) &setup); + + switch (setup.bmRequestType & 0x7f) { // mask direction + case STANDARD_DEVICE_REQUEST: + switch (setup.bRequest) { + case GET_DESCRIPTOR: + switch ((setup.wValue>>8)) { + case DEVICE_DESCRIPTOR: // device descriptor request + case QUALIFIER_DESCRIPTOR: // device qualifier descriptor + data_in_stage(device_descriptor, sizeof(device_descriptor)); + break; + case CONFIG_DESCRIPTOR: // configuration descriptor + data_in_stage(config_descriptor, setup.wLength); + break; + case STRING_DESCRIPTOR: + break; + default: + break; + } + break; + case SET_ADDRESS: + usb_set_address((uint8_t) (setup.wValue & 0xFF)); + status_in_stage(); + break; + case SET_CONFIGURATION: + if (!setup.wValue) { + break; + } + ep_realize(EP4, MAX_EPn_PSIZE); + ep_realize(EP5, MAX_EPn_PSIZE); + status_in_stage(); + usb_configure(1); + break; + default: + break; + } + break; + default: + break; + } +} + +void ep0_in() { + if ((setup.bmRequestType & 0x80) && transfer.size) { // device to host + if (transfer.size > MAX_EP0_PSIZE) { + transfer.sent = MAX_EP0_PSIZE; + } else { + transfer.sent = transfer.size; + } + ep_write(EP1, transfer.data, transfer.sent); + transfer.data += transfer.sent; + transfer.size -= transfer.sent; + } +} + +void ep0_out() { + uint8_t buf[64]; + ep_read(EP0, buf); +}