From 49148e76706e5e24c2ba7f6ccc1d7ec4736ab2f3 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 3 Mar 2021 15:24:13 +0000 Subject: support cheap chinese blue pill boards, make usb dfu compatible with dfuse --- app/Makefile | 29 ++++++++- app/cdcacm.c | 188 ++++++++++++++++++------------------------------------- app/dfu.c | 28 ++++++--- app/dummy_kb.c | 26 ++++++++ app/gdb.script | 2 + app/i2c_bb.c | 70 ++++++++++----------- app/i2c_hw.c | 12 ++-- app/main.c | 34 ++++------ app/project.h | 11 ++-- app/prototypes.h | 20 +++++- app/ring.c | 12 ++-- app/ticker.c | 24 +++---- app/usart.c | 18 +++--- app/usb.c | 139 ++++++++++++++++++++++++++++++++++++++++ app/vuart.c | 45 +++++++------ 15 files changed, 388 insertions(+), 270 deletions(-) create mode 100644 app/dummy_kb.c create mode 100644 app/gdb.script create mode 100644 app/usb.c (limited to 'app') diff --git a/app/Makefile b/app/Makefile index dc5503b..e264ad4 100644 --- a/app/Makefile +++ b/app/Makefile @@ -24,7 +24,7 @@ PROG=serial_over_dp V=1 default: ${PROG}.elf -CSRCS= main.c cdcacm.c dfu.c i2c_bb.c vuart.c ring.c usart.c i2c_hw.c ticker.c ddc.c +CSRCS= main.c cdcacm.c dfu.c i2c_bb.c vuart.c ring.c usart.c i2c_hw.c ticker.c ddc.c dummy_kb.c usb.c HSRCS = project.h @@ -38,14 +38,37 @@ VID=$(shell printf '\#include "id.h"\nID_VENDOR' | ${CC} -I.. -E - | grep -v ^\# INCLUDES += -I.. -dfu:${PROG}.dfu - dfu-util -R -a 0 -d ${VID}:${DID} -s 0x08002000:leave -D $< + +%.bin: %.elf + $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin + +%.dfu:%.bin + ../tools/dfuse-pack.py -D 0x483:0xff03 -b 0x08002000:$< $@ + +dfu:${PROG}.bin + dfu-util -R -a 0 -d 0483:ff03,0483:df11 -s 0x08002000:leave -D $< program: ${PROG}.elf echo halt | nc -t localhost 4444 echo flash write_image erase ${PWD}/$< 0x2000 | nc -t localhost 4444 echo reset run | nc -t localhost 4444 +ds: + $(Q)$(OOCD) -f $(OOCD_INTERFACE) \ + -f $(OOCD_BOARD) \ + +debug: ${PROG}.elf + ${PREFIX}-gdb -x gdb.script ${PROG}.elf + +reset: + $(Q)$(OOCD) -f $(OOCD_INTERFACE) \ + -f $(OOCD_BOARD) \ + -c "init" -c "reset run" \ + -c shutdown + + + + protos: echo -n > prototypes.h ${CPROTO} $(INCLUDES) $(DEFINES) -e -v ${CSRCS} > prototypes.h.tmp diff --git a/app/cdcacm.c b/app/cdcacm.c index b300241..f6a1b0f 100644 --- a/app/cdcacm.c +++ b/app/cdcacm.c @@ -9,30 +9,17 @@ static uint8_t cdcacm_rx_ring_buf[BUFFER_SIZE]; ring_t cdcacm_tx_ring; static uint8_t cdcacm_tx_ring_buf[BUFFER_SIZE]; +static int cdcacm_ready = 0; -static const struct usb_device_descriptor dev = { - .bLength = USB_DT_DEVICE_SIZE, - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = 0x0200, - .bDeviceClass = USB_CLASS_CDC, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, - .bMaxPacketSize0 = 64, - .idVendor = ID_VENDOR, - .idProduct = ID_PRODUCT, - .bcdDevice = 0x0200, - .iManufacturer = 1, - .iProduct = 2, - .iSerialNumber = 3, - .bNumConfigurations = 1, -}; - +#define COMM_EP 0x83 +#define DATA_IN 0x01 +#define DATA_OUT 0x82 static const struct usb_endpoint_descriptor comm_endp[] = { { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x83, + .bEndpointAddress = COMM_EP, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 16, .bInterval = 255, @@ -43,7 +30,7 @@ static const struct usb_endpoint_descriptor data_endp[] = { { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x01, + .bEndpointAddress = DATA_IN, .bmAttributes = USB_ENDPOINT_ATTR_BULK, .wMaxPacketSize = 64, .bInterval = 1, @@ -51,7 +38,7 @@ static const struct usb_endpoint_descriptor data_endp[] = { { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x82, + .bEndpointAddress = DATA_OUT, .bmAttributes = USB_ENDPOINT_ATTR_BULK, .wMaxPacketSize = 64, .bInterval = 1, @@ -63,7 +50,7 @@ static const struct { struct usb_cdc_call_management_descriptor call_mgmt; struct usb_cdc_acm_descriptor acm; struct usb_cdc_union_descriptor cdc_union; -} __attribute__ ( (packed)) cdcacm_functional_descriptors = { +} __attribute__ ((packed)) cdcacm_functional_descriptors = { .header = { .bFunctionLength = sizeof (struct usb_cdc_header_descriptor), .bDescriptorType = CS_INTERFACE, @@ -76,7 +63,7 @@ static const struct { .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT, .bmCapabilities = 0, - .bDataInterface = 1, + .bDataInterface = 3, }, .acm = { .bFunctionLength = sizeof (struct usb_cdc_acm_descriptor), @@ -88,15 +75,15 @@ static const struct { .bFunctionLength = sizeof (struct usb_cdc_union_descriptor), .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_UNION, - .bControlInterface = 0, - .bSubordinateInterface0 = 1, + .bControlInterface = 2, + .bSubordinateInterface0 = 3, } }; -static const struct usb_interface_descriptor comm_iface = { +const struct usb_interface_descriptor comm_iface = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, + .bInterfaceNumber = 2, .bAlternateSetting = 0, .bNumEndpoints = 1, .bInterfaceClass = USB_CLASS_CDC, @@ -108,10 +95,10 @@ static const struct usb_interface_descriptor comm_iface = { .extralen = sizeof (cdcacm_functional_descriptors) }; -static const struct usb_interface_descriptor data_iface = { +const struct usb_interface_descriptor data_iface = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 1, + .bInterfaceNumber = 3, .bAlternateSetting = 0, .bNumEndpoints = 2, .bInterfaceClass = USB_CLASS_DATA, @@ -121,71 +108,30 @@ static const struct usb_interface_descriptor data_iface = { .endpoint = data_endp, }; -static const struct usb_interface ifaces[] = { - { - .num_altsetting = 1, - .altsetting = &comm_iface, - }, - { - .num_altsetting = 1, - .altsetting = &data_iface, - }, -#ifdef INCLUDE_DFU_INTERFACE - { - .num_altsetting = 1, - .altsetting = &dfu_iface, - }, -#endif -}; - -static const struct usb_config_descriptor config = { - .bLength = USB_DT_CONFIGURATION_SIZE, - .bDescriptorType = USB_DT_CONFIGURATION, - .wTotalLength = 0, -#ifdef INCLUDE_DFU_INTERFACE - .bNumInterfaces = 3, -#else - .bNumInterfaces = 2, -#endif - .bConfigurationValue = 1, - .iConfiguration = 0, - .bmAttributes = 0x80, - .bMaxPower = 0x32, - .interface = ifaces, -}; -static const char *usb_strings[] = { - "Meh", - "Fish", - "Soup", -#ifdef INCLUDE_DFU_INTERFACE - "DFU", -#endif +const struct usb_iface_assoc_descriptor cdc_iface_assoc = { + .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + .bFirstInterface = 2, + .bInterfaceCount = 2, + .bFunctionClass = USB_CLASS_CDC, + .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, + .bFunctionProtocol = USB_CDC_PROTOCOL_AT, + .iFunction = 6, }; -/* Buffer to be used for control requests. */ -uint8_t usbd_control_buffer[128]; - -usbd_device *usbd_dev; - -static int cdcacm_control_request (usbd_device *usbd_dev, - struct usb_setup_data *req, - uint8_t **buf, - uint16_t *len, - usbd_control_complete_callback *complete) +int cdcacm_control_request (usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, + uint16_t *len, + usbd_control_complete_callback *complete) { (void) complete; (void) buf; (void) usbd_dev; -#ifdef INCLUDE_DFU_INTERFACE - - if (dfu_control_request (usbd_dev, req, buf, len, complete)) { - return 1; - } -#endif switch (req->bRequest) { case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { @@ -194,24 +140,12 @@ static int cdcacm_control_request (usbd_device *usbd_dev, * even though it's optional in the CDC spec, and we don't * advertise it in the ACM functional descriptor. */ - char local_buf[10]; - struct usb_cdc_notification *notif = (void *) local_buf; - /* We echo signals back to host as notification. */ - notif->bmRequestType = 0xA1; - notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE; - notif->wValue = 0; - notif->wIndex = 0; - notif->wLength = 2; - local_buf[8] = req->wValue & 3; - local_buf[9] = 0; - // usbd_ep_write_packet(0x83, buf, 10); return 1; } - case USB_CDC_REQ_SET_LINE_CODING: - if (*len < sizeof (struct usb_cdc_line_coding)) { + case USB_CDC_REQ_SET_LINE_CODING: + if (*len < sizeof (struct usb_cdc_line_coding)) return 0; - } return 1; } @@ -220,69 +154,67 @@ static int cdcacm_control_request (usbd_device *usbd_dev, } + void cdcacm_tick (void) { - unsigned ep = 0x82; + unsigned ep = DATA_OUT; uint8_t buf[16]; uint8_t *ptr = buf; size_t n = 0; - if (ring_empty (&cdcacm_tx_ring)) { + if (!cdcacm_ready) return; - } - if ( (*USB_EP_REG (ep & 0x7f) & USB_EP_TX_STAT) == USB_EP_TX_STAT_VALID) { + if (ring_empty (&cdcacm_tx_ring)) + return; + + /* Return if endpoint is already enabled. */ + if ((*USB_EP_REG (ep & 0x7f) & USB_EP_TX_STAT) == USB_EP_TX_STAT_VALID) return; - } while (!ring_read_byte (&cdcacm_tx_ring, ptr++)) { n++; + + if (n == sizeof (buf)) break; } - usbd_ep_write_packet (usbd_dev, ep, buf, n); + usbd_ep_write_packet (usb_device, ep, buf, n); +} + +int cdcacm_write (char *ptr, int len) +{ + int ret; + + ret = ring_write (&cdcacm_tx_ring, (uint8_t *) ptr, len); + return ret; } + static void cdcacm_data_rx_cb (usbd_device *usbd_dev, uint8_t ep) { (void) ep; uint8_t buf[64]; - int len = usbd_ep_read_packet (usbd_dev, 0x01, buf, 64); + int len = usbd_ep_read_packet (usbd_dev, DATA_IN, buf, 64); - if (len) { + if (len) ring_write (&cdcacm_rx_ring, buf, len); - } } -static void cdcacm_set_config (usbd_device *usbd_dev, uint16_t wValue) +void cdcacm_set_config (usbd_device *usbd_dev, uint16_t wValue) { (void) wValue; - usbd_ep_setup (usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); - usbd_ep_setup (usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); - usbd_ep_setup (usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); - usbd_register_control_callback (usbd_dev, - USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, - USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, - cdcacm_control_request); + + usbd_ep_setup (usbd_dev, DATA_IN, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); + usbd_ep_setup (usbd_dev, DATA_OUT, USB_ENDPOINT_ATTR_BULK, 64, NULL); + usbd_ep_setup (usbd_dev, COMM_EP, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + cdcacm_ready = 1; } -void usb_init (void) +void cdcacm_rings_init (void) { ring_init (&cdcacm_rx_ring, cdcacm_rx_ring_buf, sizeof (cdcacm_rx_ring_buf)); ring_init (&cdcacm_tx_ring, cdcacm_tx_ring_buf, sizeof (cdcacm_tx_ring_buf)); - usbd_dev = usbd_init (&stm32f103_usb_driver, - &dev, - &config, - usb_strings, -#ifdef INCLUDE_DFU_INTERFACE - 4, -#else - 3, -#endif - usbd_control_buffer, - sizeof (usbd_control_buffer)); - usbd_register_set_config_callback (usbd_dev, cdcacm_set_config); } - diff --git a/app/dfu.c b/app/dfu.c index dcde674..b0715be 100644 --- a/app/dfu.c +++ b/app/dfu.c @@ -1,13 +1,9 @@ #include "project.h" -#ifdef INCLUDE_DFU_INTERFACE - -extern uint32_t dfu_flag; - const struct usb_dfu_descriptor dfu_function = { .bLength = sizeof (struct usb_dfu_descriptor), .bDescriptorType = DFU_FUNCTIONAL, - .bmAttributes = USB_DFU_CAN_DOWNLOAD, + .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH, .wDetachTimeout = 255, .wTransferSize = 1024, .bcdDFUVersion = 0x011A, @@ -16,25 +12,37 @@ const struct usb_dfu_descriptor dfu_function = { const struct usb_interface_descriptor dfu_iface = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 2, + .bInterfaceNumber = 1, .bAlternateSetting = 0, .bNumEndpoints = 0, .bInterfaceClass = 0xFE, .bInterfaceSubClass = 1, .bInterfaceProtocol = 1, .iInterface = 4, - .extra = &dfu_function, .extralen = sizeof (dfu_function), }; +const struct usb_iface_assoc_descriptor dfu_iface_assoc = { + .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + .bFirstInterface = 1, + .bInterfaceCount = 1, + .bFunctionClass = 0xfe, + .bFunctionSubClass = 1, + .bFunctionProtocol = 1, + .iFunction = 5, +}; + + static int dfu_detach_complete (usbd_device *usbd_dev, struct usb_setup_data *req) { (void) req; (void) usbd_dev; dfu_flag = 0xfee1dead; + scb_reset_core(); return 1; } @@ -48,7 +56,7 @@ dfu_control_request (usbd_device *usbd_dev, struct usb_setup_data *req, (void) len; (void) usbd_dev; - if ( (req->bmRequestType & 0x7F) != 0x21) { + if ((req->bmRequestType & 0x7F) != 0x21) { return 0; /* Only accept class request. */ } @@ -63,11 +71,13 @@ dfu_control_request (usbd_device *usbd_dev, struct usb_setup_data *req, *len = 6; return 1; } + case DFU_GETSTATE: /* Return state with no state transision. */ *buf[0] = STATE_APP_IDLE; *len = 1; return 1; + case DFU_DETACH: *complete = dfu_detach_complete; return 1; @@ -75,4 +85,4 @@ dfu_control_request (usbd_device *usbd_dev, struct usb_setup_data *req, return 0; } -#endif + diff --git a/app/dummy_kb.c b/app/dummy_kb.c new file mode 100644 index 0000000..a1d61c7 --- /dev/null +++ b/app/dummy_kb.c @@ -0,0 +1,26 @@ +#include "project.h" + +const struct usb_interface_descriptor dummy_kb_iface = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, +}; + + +const struct usb_iface_assoc_descriptor dummy_kb_iface_assoc = { + .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + .bFirstInterface = 0, + .bInterfaceCount = 1, + .bFunctionClass = 0xff, + .bFunctionSubClass = 0, + .bFunctionProtocol = 0, + .iFunction = 4, +}; + diff --git a/app/gdb.script b/app/gdb.script new file mode 100644 index 0000000..7cf9d09 --- /dev/null +++ b/app/gdb.script @@ -0,0 +1,2 @@ +target remote localhost:3333 +cont diff --git a/app/i2c_bb.c b/app/i2c_bb.c index f392b5e..cfa6742 100644 --- a/app/i2c_bb.c +++ b/app/i2c_bb.c @@ -106,57 +106,54 @@ static void i2c_bb_sm (int od, int d, int oc, int c) } // Check for STOP - if (oc && c && !od && d) { + if (oc && c && !od && d) state = ST_LOST; - } switch (state) { case ST_LOST: i2c_bb_sda (1); i2c_bb_scl (1); break; + case ST_ADDRESS_7...ST_ADDRESS_0: - if (! (!oc && c)) { + if (! (!oc && c)) break; - } //rising scl of a7...a0 sr = (sr << 1) | !!d; if (state == ST_ADDRESS_0) { - if ( (sr & ~I2C_READ) == OUR_ADDRESS) { + if ((sr & ~I2C_READ) == OUR_ADDRESS) { state++; rnw = d; - } else { + } else state = ST_LOST; - } - } else { + } else state++; - } break; + case ST_ADDRESS_ACK: - if (! (oc && !c)) { + if (! (oc && !c)) break; - } //falling scl of a0 i2c_bb_sda (0); - if (rnw) { + if (rnw) state++; - } else { + + else state = ST_PREP_REG_7; - } break; + case ST_OUT_7: - if (! (oc && !c)) { + if (! (oc && !c)) break; - } //falling scl of ack i2c_bb_sda (1); @@ -168,32 +165,32 @@ static void i2c_bb_sm (int od, int d, int oc, int c) i2c_bb_scl (1); state++; break; + case ST_OUT_6...ST_OUT_0: - if (! (oc && !c)) { + if (! (oc && !c)) break; - } //falling scl of d6...d0 i2c_bb_sda (sr & 0x80); sr <<= 1; state++; break; + case ST_PREP_OUT_ACK: - if (! (oc && !c)) { + if (! (oc && !c)) break; - } //falling scl of d0 i2c_bb_sda (1); state++; break; + case ST_OUT_ACK: - if (! (!oc && c)) { + if (! (!oc && c)) break; - } //rising scl of ack @@ -207,74 +204,74 @@ static void i2c_bb_sm (int od, int d, int oc, int c) } break; + case ST_PREP_REG_7: - if (! (oc && !c)) { + if (! (oc && !c)) break; - } //falling scl of ack i2c_bb_sda (1); sr = 0; state++; break; + case ST_REG_7...ST_REG_0: - if (! (!oc && c)) { + if (! (!oc && c)) break; - } //rising scl of r7..r0 sr = (sr << 1) | !!d; state++; break; + case ST_REG_ACK: - if (! (oc && !c)) { + if (! (oc && !c)) break; - } //falling scl of r0 reg = sr; i2c_bb_sda (0); state = ST_PREP_IN_7; break; + case ST_PREP_IN_7: - if (! (oc && !c)) { + if (! (oc && !c)) break; - } //falling scl of ack i2c_bb_sda (1); sr = 0; state++; break; + case ST_IN_7...ST_IN_0: - if (! (!oc && c)) { + if (! (!oc && c)) break; - } //rising scl of i7..i0 sr = (sr << 1) | !!d; state++; break; + case ST_IN_ACK: - if (! (oc && !c)) { + if (! (oc && !c)) break; - } //falling scl of i0 i2c_bb_sda (0); state++; break; + case ST_REG_WRITE: - if (! (oc && !c)) { + if (! (oc && !c)) break; - } //falling scl of ack i2c_bb_sda (1); @@ -286,6 +283,7 @@ static void i2c_bb_sm (int od, int d, int oc, int c) sr = 0; state = ST_IN_7; break; + default: state = ST_LOST; } diff --git a/app/i2c_hw.c b/app/i2c_hw.c index 11e796e..9b77009 100644 --- a/app/i2c_hw.c +++ b/app/i2c_hw.c @@ -34,11 +34,11 @@ void i2c1_ev_isr (void) } if (sr1 & I2C_SR1_TxE) { - if (device) { + if (device) v = ddc_read (reg++); - } else { + + else v = vuart_read (reg++); - } I2C_DR (I2C) = v; } @@ -50,11 +50,11 @@ void i2c1_ev_isr (void) reg = v; next_is_reg = 0; } else { - if (reg == 0x10) { + if (reg == 0x10) vuart_write (0, v); - } else { + + else vuart_write (reg++, v); - } } } diff --git a/app/main.c b/app/main.c index b98bd82..2ac458f 100644 --- a/app/main.c +++ b/app/main.c @@ -15,39 +15,27 @@ int main (void) rcc_periph_clock_enable (RCC_USART1); rcc_periph_clock_enable (RCC_AFIO); rcc_periph_clock_enable (RCC_I2C1); -#if 0 - nvic_set_priority (NVIC_I2C1_EV_IRQ, 0x38); - nvic_set_priority (NVIC_I2C1_ER_IRQ, 0x39); - nvic_set_priority (NVIC_USART1_IRQ, 0x44); - nvic_set_priority (NVIC_SYSTICK_IRQ, 0xff); -#else nvic_set_priority (NVIC_I2C1_EV_IRQ, 0xff); nvic_set_priority (NVIC_I2C1_ER_IRQ, 0xff); nvic_set_priority (NVIC_SYSTICK_IRQ, 0x80); nvic_set_priority (NVIC_USART1_IRQ, 0x40); -#endif + nvic_set_priority (NVIC_USB_HP_CAN_TX_IRQ, 0x40); + nvic_set_priority (NVIC_USB_LP_CAN_RX0_IRQ, 0x40); + gpio_set_mode (LED1_BANK, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, LED1_GPIO); gpio_set_mode (LED2_BANK, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, LED2_GPIO); usart_init(); ticker_init(); - printf ("Morning chaps!\r\n"); -#ifdef USB + cdcacm_rings_init(); usb_init(); -#endif -#ifdef I2C_BIT_BANG - i2c_bb_init(); -#else + + printf ("Morning chaps!\r\n"); + i2c_hw_init(); -#endif - - for (;;) { -#ifdef USB - usbd_poll (usbd_dev); -#endif -#ifdef I2C_BIT_BANG - i2c_bb_poll(); -#endif - } + + printf ("Ready\n"); + + for (;;); return 0; } diff --git a/app/project.h b/app/project.h index 3df1a38..f4b113b 100644 --- a/app/project.h +++ b/app/project.h @@ -10,16 +10,11 @@ #include #include #include +#include +#include #include -#define INCLUDE_DFU_INTERFACE #undef I2C_BIT_BANG -#define USB - -#ifdef INCLUDE_DFU_INTERFACE -#include -#include -#endif #include #include @@ -33,3 +28,5 @@ #include "ring.h" #include "prototypes.h" + +extern uint32_t dfu_flag; diff --git a/app/prototypes.h b/app/prototypes.h index a877992..a432df4 100644 --- a/app/prototypes.h +++ b/app/prototypes.h @@ -3,13 +3,18 @@ extern int main(void); /* cdcacm.c */ extern ring_t cdcacm_rx_ring; extern ring_t cdcacm_tx_ring; -extern uint8_t usbd_control_buffer[128]; -extern usbd_device *usbd_dev; +extern const struct usb_interface_descriptor comm_iface; +extern const struct usb_interface_descriptor data_iface; +extern const struct usb_iface_assoc_descriptor cdc_iface_assoc; +extern int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete); extern void cdcacm_tick(void); -extern void usb_init(void); +extern int cdcacm_write(char *ptr, int len); +extern void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue); +extern void cdcacm_rings_init(void); /* dfu.c */ extern const struct usb_dfu_descriptor dfu_function; extern const struct usb_interface_descriptor dfu_iface; +extern const struct usb_iface_assoc_descriptor dfu_iface_assoc; extern int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete); /* i2c_bb.c */ extern void i2c_bb_init(void); @@ -42,3 +47,12 @@ extern void sys_tick_handler(void); extern void ticker_init(void); /* ddc.c */ extern uint8_t ddc_read(uint8_t v); +/* dummy_kb.c */ +extern const struct usb_interface_descriptor dummy_kb_iface; +extern const struct usb_iface_assoc_descriptor dummy_kb_iface_assoc; +/* usb.c */ +extern uint8_t usbd_control_buffer[128]; +extern usbd_device *usb_device; +extern void usb_hp_can_tx_isr(void); +extern void usb_lp_can_rx0_isr(void); +extern void usb_init(void); diff --git a/app/ring.c b/app/ring.c index e3a6209..26bba3a 100644 --- a/app/ring.c +++ b/app/ring.c @@ -6,9 +6,8 @@ ring_next (ring_t *r, size_t p) { p++; - if (p >= r->size) { + if (p >= r->size) p -= r->size; - } return p; } @@ -27,9 +26,8 @@ ring_write_byte (ring_t *r, uint8_t c) { size_t n = ring_next (r, r->write); - if (n == r->read) { + if (n == r->read) return -1; - } r->data[r->write] = c; r->write = n; @@ -46,9 +44,8 @@ ring_read_byte (ring_t *r, uint8_t *c) { size_t n = ring_next (r, r->read); - if (r->read == r->write) { + if (r->read == r->write) return -1; - } *c = r->data[r->read]; r->read = n; @@ -59,9 +56,8 @@ int ring_write (ring_t *r, uint8_t *buf, size_t len) { while (len--) { - if (ring_write_byte (r, * (buf++))) { + if (ring_write_byte (r, * (buf++))) return -1; - } } return 0; diff --git a/app/ticker.c b/app/ticker.c index 05990d2..a28824c 100644 --- a/app/ticker.c +++ b/app/ticker.c @@ -13,9 +13,8 @@ delay_us (uint32_t d) { d *= scale; - while (d--) { + while (d--) __asm__ ("nop"); - } } void @@ -24,25 +23,23 @@ sys_tick_handler (void) ticks++; cdcacm_tick(); - if (led1) { + if (led1) led1--; - } - if (led2) { + if (led2) led2--; - } - if (led1) { + if (led1) gpio_clear (LED1_BANK, LED1_GPIO); - } else { + + else gpio_set (LED1_BANK, LED1_GPIO); - } - if (led2) { + if (led2) gpio_clear (LED2_BANK, LED2_GPIO); - } else { + + else gpio_set (LED2_BANK, LED2_GPIO); - } } @@ -63,9 +60,8 @@ ticker_init (void) scale--; v = ticks; - while (v == ticks) { + while (v == ticks) ; - } delay_us (1000); w = ticks; diff --git a/app/usart.c b/app/usart.c index ecd8e56..8659ab0 100644 --- a/app/usart.c +++ b/app/usart.c @@ -14,30 +14,28 @@ usart1_isr (void) uint8_t data; /* Check if we were called because of RXNE. */ - if ( ( (USART_CR1 (USART1) & USART_CR1_RXNEIE) != 0) && - ( (USART_SR (USART1) & USART_SR_RXNE) != 0)) { + if (((USART_CR1 (USART1) & USART_CR1_RXNEIE) != 0) && + ((USART_SR (USART1) & USART_SR_RXNE) != 0)) { /* Retrieve the data from the peripheral. */ data = usart_recv (USART1); ring_write_byte (&usart_rx_ring, data); } /* Check if we were called because of TXE. */ - if ( ( (USART_CR1 (USART1) & USART_CR1_TXEIE) != 0) && - ( (USART_SR (USART1) & USART_SR_TXE) != 0)) { + if (((USART_CR1 (USART1) & USART_CR1_TXEIE) != 0) && + ((USART_SR (USART1) & USART_SR_TXE) != 0)) { if (ring_read_byte (&usart_tx_ring, &data)) { /*No more data, Disable the TXE interrupt, it's no longer needed. */ USART_CR1 (USART1) &= ~USART_CR1_TXEIE; - } else { + } else usart_send (USART1, data); - } } } void usart_kick (void) { - if (!ring_empty (&usart_tx_ring)) { + if (!ring_empty (&usart_tx_ring)) USART_CR1 (USART1) |= USART_CR1_TXEIE; - } } @@ -49,10 +47,10 @@ _write (int file, char *ptr, int len) if (file == 1) { ret = ring_write (&usart_tx_ring, (uint8_t *) ptr, len); usart_kick(); + ring_write (&cdcacm_tx_ring, (uint8_t *) ptr, len); - if (ret < 0) { + if (ret < 0) ret = -ret; - } return ret; } diff --git a/app/usb.c b/app/usb.c new file mode 100644 index 0000000..8023ea3 --- /dev/null +++ b/app/usb.c @@ -0,0 +1,139 @@ +#include "project.h" + +#define USB_DM GPIO11 +#define USB_DM_PORT GPIOA +#define USB_DP GPIO12 +#define USB_DP_PORT GPIOA + +/* Buffer to be used for control requests. */ +uint8_t usbd_control_buffer[128]; +usbd_device *usb_device; + +static const struct usb_device_descriptor dev = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0xef, + .bDeviceSubClass = 0x02, + .bDeviceProtocol = 0x01, + .bMaxPacketSize0 = 64, + .idVendor = 0x0483, + .idProduct = 0xff03, + .bcdDevice = 0x0200, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + + +static const struct usb_interface ifaces[] = { + { + .num_altsetting = 1, + .altsetting = &dummy_kb_iface, + .iface_assoc = &dummy_kb_iface_assoc, + }, + { + .num_altsetting = 1, + .altsetting = &dfu_iface, + .iface_assoc = &dfu_iface_assoc, + }, + { + .num_altsetting = 1, + .altsetting = &comm_iface, + .iface_assoc = &cdc_iface_assoc, + }, + { + .num_altsetting = 1, + .altsetting = &data_iface, + }, +}; + +static const struct usb_config_descriptor config = { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 4, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0x80, + .bMaxPower = 0x32, + .interface = ifaces, +}; + +static const char *usb_strings[] = { + VENDOR_NAME, /*1*/ + PRODUCT_NAME, /*2*/ + SERIAL_NUMBER, /*3*/ + "dummy device", /*4*/ + "DFU interface", /*5*/ + "Debug interface", /*6*/ +}; +#define N_USB_STRINGS (sizeof(usb_strings)/sizeof(usb_strings[0])) + +void usb_hp_can_tx_isr (void) +{ + usbd_poll (usb_device); +} + +void usb_lp_can_rx0_isr (void) +{ + usbd_poll (usb_device); +} + +static int control_request (usbd_device *usbd_dev, + struct usb_setup_data *req, + uint8_t **buf, + uint16_t *len, + usbd_control_complete_callback *complete) +{ + if (dfu_control_request (usbd_dev, req, buf, len, complete)) + return 1; + + return cdcacm_control_request (usbd_dev, req, buf, len, complete); +} + +static void set_config (usbd_device *usbd_dev, uint16_t wValue) +{ + + cdcacm_set_config (usbd_dev, wValue); + + usbd_register_control_callback (usbd_dev, + USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + control_request); + +} + + + +void usb_init (void) +{ + /*Force USB reset */ + gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO12); + gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); + gpio_clear (GPIOA, GPIO12); + gpio_clear (GPIOA, GPIO13); + delay_us (50000); + gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO12); + gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO13); + + + usb_device = usbd_init (&stm32f103_usb_driver, + &dev, + &config, + usb_strings, + N_USB_STRINGS, + usbd_control_buffer, + sizeof (usbd_control_buffer)); + + usbd_register_set_config_callback (usb_device, set_config); + + nvic_enable_irq (NVIC_USB_HP_CAN_TX_IRQ); + nvic_enable_irq (NVIC_USB_LP_CAN_RX0_IRQ); + + + +} + + diff --git a/app/vuart.c b/app/vuart.c index 5aaf2d3..3c4ab79 100644 --- a/app/vuart.c +++ b/app/vuart.c @@ -82,25 +82,18 @@ static void vuart_xmit (uint8_t c) led1 = 100; ring_write_byte (&usart_tx_ring, c); usart_kick(); -#ifdef USB ring_write_byte (&cdcacm_tx_ring, c); -#endif } static int vuart_recv_empty (void) { - if (!ring_empty (&usart_rx_ring)) { + if (!ring_empty (&usart_rx_ring)) return 0; - } - -#ifdef USB - if (!ring_empty (&cdcacm_rx_ring)) { + if (!ring_empty (&cdcacm_rx_ring)) return 0; - } -#endif return 1; } @@ -114,25 +107,22 @@ static int vuart_recv (uint8_t *c) return 0; } -#ifdef USB - if (!ring_read_byte (&cdcacm_rx_ring, c)) { led2 = 100; return 0; } -#endif return -1; } static void update_lsr (void) { - if (vuart_recv_empty()) { + if (vuart_recv_empty()) lsr &= ~LSR_DA; - } else { + + else lsr |= LSR_DA; - } } uint8_t vuart_read (unsigned reg) @@ -147,28 +137,33 @@ uint8_t vuart_read (unsigned reg) vuart_recv (&val); update_lsr(); return val; - } else { + } else return dllr; - } case IER: //case DLLH: return (lcr & LCR_DLAB) ? dlhr : ier; + case IIR: return iir; + case LCR: return lcr; + case MCR: return mcr; + case LSR: update_lsr(); val = lsr; lsr &= 0xe1; return val; + case MSR: val = msr; msr &= 0xf0; return val; + case SR: return sr; } @@ -183,29 +178,33 @@ void vuart_write (unsigned reg, uint8_t val) case RXR: //case DLLR: - if (! (lcr & LCR_DLAB)) { + if (! (lcr & LCR_DLAB)) vuart_xmit (val); - } else { + + else dllr = val; - } break; + case IER: //case DLHR: - if (! (lcr & LCR_DLAB)) { + if (! (lcr & LCR_DLAB)) ier = val & 0xf; - } else { + + else dlhr = val; - } break; + case LCR: lcr = val; break; + case MCR: mcr = val & 0x1f; break; + case SR: sr = val; break; -- cgit v1.2.3