From c064959e10908ea9a1d5060a6562e7b59dfe7d09 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Fri, 19 Aug 2011 13:33:30 -0400 Subject: usb_cdcacm.c: Cleanups Move the callbacks to the bottom of the file, and mark them static. Replace empty callbacks with NOP_Process in the callback tables. Remove prototype for nonexistent prep_and_reset(). Other miscellaneous fixups. Signed-off-by: Marti Bolivar --- libmaple/usb/usb_cdcacm.c | 402 +++++++++++++++++++++++----------------------- 1 file changed, 202 insertions(+), 200 deletions(-) (limited to 'libmaple/usb') diff --git a/libmaple/usb/usb_cdcacm.c b/libmaple/usb/usb_cdcacm.c index 46d56bb..d2f6eba 100644 --- a/libmaple/usb/usb_cdcacm.c +++ b/libmaple/usb/usb_cdcacm.c @@ -66,13 +66,25 @@ "best." #endif +static void vcomDataTxCb(void); +static void vcomDataRxCb(void); +static uint8* vcomGetSetLineCoding(uint16); + +static void usbInit(void); +static void usbReset(void); +static RESULT usbDataSetup(uint8 request); +static RESULT usbNoDataSetup(uint8 request); +static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting); +static uint8* usbGetDeviceDescriptor(uint16 length); +static uint8* usbGetConfigDescriptor(uint16 length); +static uint8* usbGetStringDescriptor(uint16 length); +static void usbSetConfiguration(void); +static void usbSetDeviceAddress(void); + /* * VCOM config */ -#define VCOM_ID_VENDOR 0x1EAF -#define VCOM_ID_PRODUCT 0x0004 - #define VCOM_CTRL_EPNUM 0x00 #define VCOM_CTRL_RX_ADDR 0x40 #define VCOM_CTRL_TX_ADDR 0x80 @@ -94,8 +106,9 @@ #define VCOM_RX_EPSIZE 0x40 #define VCOM_RX_BUFLEN (VCOM_RX_EPSIZE*3) -#define USB_DEVICE_CLASS_CDC 0x02 -#define USB_DEVICE_SUBCLASS_CDC 0x00 +/* + * CDC ACM Requests + */ #define SET_LINE_CODING 0x20 #define GET_LINE_CODING 0x21 @@ -104,25 +117,14 @@ #define CONTROL_LINE_DTR (0x01) #define CONTROL_LINE_RTS (0x02) -typedef struct { - uint32 bitrate; - uint8 format; - uint8 paritytype; - uint8 datatype; -} USB_Line_Coding; - -typedef enum { - DTR_UNSET, - DTR_HIGH, - DTR_NEGEDGE, - DTR_LOW -} RESET_STATE; - -/* Some forward-declared callbacks */ -void vcomDataTxCb(void); -void vcomDataRxCb(void); -void vcomManagementCb(void); +/* + * Descriptors + */ +#define USB_DEVICE_CLASS_CDC 0x02 +#define USB_DEVICE_SUBCLASS_CDC 0x00 +#define LEAFLABS_ID_VENDOR 0x1EAF +#define MAPLE_ID_PRODUCT 0x0004 const USB_Descriptor_Device usbVcomDescriptor_Device = { .bLength = sizeof(USB_Descriptor_Device), .bDescriptorType = USB_DESCRIPTOR_TYPE_DEVICE, @@ -131,8 +133,8 @@ const USB_Descriptor_Device usbVcomDescriptor_Device = { .bDeviceSubClass = USB_DEVICE_SUBCLASS_CDC, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = 0x40, - .idVendor = VCOM_ID_VENDOR, - .idProduct = VCOM_ID_PRODUCT, + .idVendor = LEAFLABS_ID_VENDOR, + .idProduct = MAPLE_ID_PRODUCT, .bcdDevice = 0x0200, .iManufacturer = 0x01, .iProduct = 0x02, @@ -289,15 +291,31 @@ ONE_DESCRIPTOR String_Descriptor[3] = { {(uint8*)&usbVcomDescriptor_iProduct, USB_DESCRIPTOR_STRING_LEN(8)} }; -uint8 last_request = 0; +/* + * Etc. + */ +typedef enum { + DTR_UNSET, + DTR_HIGH, + DTR_NEGEDGE, + DTR_LOW +} RESET_STATE; + +typedef struct { + uint32 bitrate; + uint8 format; + uint8 paritytype; + uint8 datatype; +} USB_Line_Coding; + +uint8 last_request = 0; USB_Line_Coding line_coding = { .bitrate = 115200, .format = 0x00, /* stop bits-1 */ .paritytype = 0x00, .datatype = 0x08 }; - uint8 vcomBufferRx[VCOM_RX_BUFLEN]; volatile uint32 countTx = 0; volatile uint32 recvBufIn = 0; @@ -307,9 +325,13 @@ volatile uint32 newBytes = 0; RESET_STATE reset_state = DTR_UNSET; uint8 line_dtr_rts = 0; +/* + * Endpoint callbacks + */ + static void (*ep_int_in[7])(void) = {vcomDataTxCb, - vcomManagementCb, + NOP_Process, NOP_Process, NOP_Process, NOP_Process, @@ -326,17 +348,154 @@ static void (*ep_int_out[7])(void) = NOP_Process}; /* - * VCOM callbacks + * Globals required by usb_lib/ + */ + +#define NUM_ENDPTS 0x04 +DEVICE Device_Table = { + .Total_Endpoint = NUM_ENDPTS, + .Total_Configuration = 1 +}; + +#define MAX_PACKET_SIZE 0x40 /* 64B, maximum for USB FS Devices */ +DEVICE_PROP Device_Property = { + .Init = usbInit, + .Reset = usbReset, + .Process_Status_IN = NOP_Process, + .Process_Status_OUT = NOP_Process, + .Class_Data_Setup = usbDataSetup, + .Class_NoData_Setup = usbNoDataSetup, + .Class_Get_Interface_Setting = usbGetInterfaceSetting, + .GetDeviceDescriptor = usbGetDeviceDescriptor, + .GetConfigDescriptor = usbGetConfigDescriptor, + .GetStringDescriptor = usbGetStringDescriptor, + .RxEP_buffer = NULL, + .MaxPacketSize = MAX_PACKET_SIZE +}; + +USER_STANDARD_REQUESTS User_Standard_Requests = { + .User_GetConfiguration = NOP_Process, + .User_SetConfiguration = usbSetConfiguration, + .User_GetInterface = NOP_Process, + .User_SetInterface = NOP_Process, + .User_GetStatus = NOP_Process, + .User_ClearFeature = NOP_Process, + .User_SetEndPointFeature = NOP_Process, + .User_SetDeviceFeature = NOP_Process, + .User_SetDeviceAddress = usbSetDeviceAddress +}; + +/* + * CDC ACM interface + */ + +void usb_cdcacm_enable(gpio_dev *disc_dev, uint8 disc_bit) { + /* Present ourselves to the host */ + gpio_set_mode(disc_dev, disc_bit, GPIO_OUTPUT_PP); + gpio_write_bit(disc_dev, disc_bit, 0); // presents us to the host + + /* initialize USB peripheral */ + usb_init_usblib(ep_int_in, ep_int_out); +} + +void usb_cdcacm_disable(gpio_dev *disc_dev, uint8 disc_bit) { + // These are just guesses about how to do this, but it seems to work. + // TODO: verify this with USB spec + nvic_irq_disable(NVIC_USB_LP_CAN_RX0); + gpio_write_bit(disc_dev, disc_bit, 1); +} + +void usb_cdcacm_putc(char ch) { + while (!usb_cdcacm_tx((uint8*)&ch, 1)) + ; +} + +/* This function is non-blocking. + * + * It copies data from a usercode buffer into the USB peripheral TX + * buffer and return the number placed in that buffer. */ +uint32 usb_cdcacm_tx(const uint8* buf, uint32 len) { + /* Last transmission hasn't finished, abort */ + if (countTx) { + return 0; + } + + // We can only put VCOM_TX_EPSIZE bytes in the buffer + /* FIXME then why are we only copying half as many? */ + if (len > VCOM_TX_EPSIZE / 2) { + len = VCOM_TX_EPSIZE / 2; + } + + // Try to load some bytes if we can + if (len) { + usb_copy_to_pma(buf, len, VCOM_TX_ADDR); + usb_set_ep_tx_count(VCOM_TX_ENDP, len); + countTx += len; + usb_set_ep_tx_stat(VCOM_TX_ENDP, USB_EP_STAT_TX_VALID); + } -void vcomDataTxCb(void) { + return len; +} + +/* returns the number of available bytes are in the recv FIFO */ +uint32 usb_cdcacm_data_available(void) { + return newBytes; +} + +uint16 usb_cdcacm_get_pending() { + return countTx; +} + +/* Nonblocking byte receive. + * + * Copies up to len bytes from our private data buffer (*NOT* the PMA) + * into buf and deq's the FIFO. */ +uint32 usb_cdcacm_rx(uint8* buf, uint32 len) { + static int offset = 0; + int i; + + if (len > newBytes) { + len = newBytes; + } + + for (i = 0; i < len; i++) { + buf[i] = vcomBufferRx[i + offset]; + } + + newBytes -= len; + offset += len; + + /* Re-enable the RX endpoint, which we had set to receive 0 bytes */ + if (newBytes == 0) { + usb_set_ep_rx_count(VCOM_RX_ENDP, VCOM_RX_EPSIZE); + usb_set_ep_rx_stat(VCOM_RX_ENDP, USB_EP_STAT_RX_VALID); + offset = 0; + } + + return len; +} + +uint8 usb_cdcacm_get_dtr() { + return ((line_dtr_rts & CONTROL_LINE_DTR) != 0); +} + +uint8 usb_cdcacm_get_rts() { + return ((line_dtr_rts & CONTROL_LINE_RTS) != 0); +} + +/* + * Callbacks + */ + +static void vcomDataTxCb(void) { /* assumes tx transactions are atomic 64 bytes (nearly certain they are) */ countTx = 0; } #define EXC_RETURN 0xFFFFFFF9 #define DEFAULT_CPSR 0x61000000 -void vcomDataRxCb(void) { +static void vcomDataRxCb(void) { /* FIXME this is mad buggy */ /* setEPRxCount on the previous cycle should garuntee @@ -393,22 +552,16 @@ void vcomDataRxCb(void) { usb_copy_from_pma(vcomBufferRx, newBytes, VCOM_RX_ADDR); } -void vcomManagementCb(void) { - /* unused. This enpoint would callback if we had sent a linestate - changed notification */ -} - -u8* vcomGetSetLineCoding(uint16 length) { +static uint8* vcomGetSetLineCoding(uint16 length) { if (length == 0) { pInformation->Ctrl_Info.Usb_wLength = sizeof(USB_Line_Coding); } return (uint8*)&line_coding; } -void vcomSetLineState(void) { -} +static void usbInit(void) { + pInformation->Current_Configuration = 0; -RESULT usbPowerOn(void) { USB_BASE->CNTR = USB_CNTR_FRES; USBLIB->irq_mask = 0; @@ -417,13 +570,6 @@ RESULT usbPowerOn(void) { USBLIB->irq_mask = USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; USB_BASE->CNTR = USBLIB->irq_mask; - return USB_SUCCESS; -} - -void usbInit(void) { - pInformation->Current_Configuration = 0; - usbPowerOn(); - USB_BASE->ISTR = 0; USBLIB->irq_mask = USB_ISR_MSK; USB_BASE->CNTR = USBLIB->irq_mask; @@ -434,7 +580,7 @@ void usbInit(void) { /* choose addresses to give endpoints the max 64 byte buffers */ #define BTABLE_ADDRESS 0x00 -void usbReset(void) { +static void usbReset(void) { pInformation->Current_Configuration = 0; /* current feature is current bmAttributes */ @@ -483,16 +629,7 @@ void usbReset(void) { countTx = 0; } -void usbStatusIn(void) { - /* adjust the usart line coding - if we wish to couple the CDC line coding - with the real usart port */ -} - -void usbStatusOut(void) { -} - -RESULT usbDataSetup(uint8 request) { +static RESULT usbDataSetup(uint8 request) { uint8 *(*CopyRoutine)(uint16); CopyRoutine = NULL; @@ -521,7 +658,7 @@ RESULT usbDataSetup(uint8 request) { return USB_SUCCESS; } -RESULT usbNoDataSetup(u8 request) { +static RESULT usbNoDataSetup(uint8 request) { uint8 new_signal; /* we support set com feature but dont handle it */ @@ -578,7 +715,7 @@ RESULT usbNoDataSetup(u8 request) { return USB_UNSUPPORT; } -RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) { +static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) { if (alt_setting > 0) { return USB_UNSUPPORT; } else if (interface > 1) { @@ -588,15 +725,15 @@ RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) { return USB_SUCCESS; } -u8* usbGetDeviceDescriptor(u16 length) { +static uint8* usbGetDeviceDescriptor(uint16 length) { return Standard_GetDescriptorData(length, &Device_Descriptor); } -u8* usbGetConfigDescriptor(u16 length) { +static uint8* usbGetConfigDescriptor(uint16 length) { return Standard_GetDescriptorData(length, &Config_Descriptor); } -u8* usbGetStringDescriptor(u16 length) { +static uint8* usbGetStringDescriptor(uint16 length) { uint8 wValue0 = pInformation->USBwValue0; if (wValue0 > 2) { @@ -605,147 +742,12 @@ u8* usbGetStringDescriptor(u16 length) { return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]); } -/* internal callbacks to respond to standard requests */ -void usbSetConfiguration(void) { +static void usbSetConfiguration(void) { if (pInformation->Current_Configuration != 0) { USBLIB->state = USB_CONFIGURED; } } -void usbSetDeviceAddress(void) { +static void usbSetDeviceAddress(void) { USBLIB->state = USB_ADDRESSED; } - -/* - * Globals required by usb_lib/ - */ - -#define NUM_ENDPTS 0x04 -DEVICE Device_Table = - {NUM_ENDPTS, - 1}; - -#define MAX_PACKET_SIZE 0x40 /* 64B, maximum for USB FS Devices */ -DEVICE_PROP Device_Property = - {usbInit, - usbReset, - usbStatusIn, - usbStatusOut, - usbDataSetup, - usbNoDataSetup, - usbGetInterfaceSetting, - usbGetDeviceDescriptor, - usbGetConfigDescriptor, - usbGetStringDescriptor, - 0, - MAX_PACKET_SIZE}; - -USER_STANDARD_REQUESTS User_Standard_Requests = - {NOP_Process, - usbSetConfiguration, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process, - NOP_Process, - usbSetDeviceAddress}; - -/* - * CDC ACM routines - */ - -void usb_cdcacm_enable(gpio_dev *disc_dev, uint8 disc_bit) { - /* Present ourselves to the host */ - gpio_set_mode(disc_dev, disc_bit, GPIO_OUTPUT_PP); - gpio_write_bit(disc_dev, disc_bit, 0); // presents us to the host - - /* initialize USB peripheral */ - usb_init_usblib(ep_int_in, ep_int_out); -} - -void usb_cdcacm_disable(gpio_dev *disc_dev, uint8 disc_bit) { - // These are just guesses about how to do this, but it seems to work. - // TODO: verify this with USB spec - nvic_irq_disable(NVIC_USB_LP_CAN_RX0); - gpio_write_bit(disc_dev, disc_bit, 1); -} - -void usb_cdcacm_putc(char ch) { - while (!usb_cdcacm_tx((uint8*)&ch, 1)) - ; -} - -/* This function is non-blocking. - * - * It copies data from a usercode buffer into the USB peripheral TX - * buffer and return the number placed in that buffer. - */ -uint32 usb_cdcacm_tx(const uint8* buf, uint32 len) { - /* Last transmission hasn't finished, abort */ - if (countTx) { - return 0; - } - - // We can only put VCOM_TX_EPSIZE bytes in the buffer - /* FIXME then why are we only copying half as many? */ - if (len > VCOM_TX_EPSIZE / 2) { - len = VCOM_TX_EPSIZE / 2; - } - - // Try to load some bytes if we can - if (len) { - usb_copy_to_pma(buf, len, VCOM_TX_ADDR); - usb_set_ep_tx_count(VCOM_TX_ENDP, len); - countTx += len; - usb_set_ep_tx_stat(VCOM_TX_ENDP, USB_EP_STAT_TX_VALID); - } - - return len; -} - -/* returns the number of available bytes are in the recv FIFO */ -uint32 usb_cdcacm_data_available(void) { - return newBytes; -} - -uint16 usb_cdcacm_get_pending() { - return countTx; -} - -/* Nonblocking byte receive. - * - * Copies up to len bytes from our private data buffer (*NOT* the PMA) - * into buf and deq's the FIFO. */ -uint32 usb_cdcacm_rx(uint8* buf, uint32 len) { - static int offset = 0; - int i; - - if (len > newBytes) { - len = newBytes; - } - - for (i = 0; i < len; i++) { - buf[i] = vcomBufferRx[i + offset]; - } - - newBytes -= len; - offset += len; - - /* Re-enable the RX endpoint, which we had set to receive 0 bytes */ - if (newBytes == 0) { - usb_set_ep_rx_count(VCOM_RX_ENDP, VCOM_RX_EPSIZE); - usb_set_ep_rx_stat(VCOM_RX_ENDP, USB_EP_STAT_RX_VALID); - offset = 0; - } - - return len; -} - -uint8 usb_cdcacm_get_dtr() { - return ((line_dtr_rts & CONTROL_LINE_DTR) != 0); -} - -uint8 usb_cdcacm_get_rts() { - return ((line_dtr_rts & CONTROL_LINE_RTS) != 0); -} -- cgit v1.2.3