From 6030ff6f2672d2a87f693516e54bacd95319d50b Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sat, 26 May 2012 22:53:29 +1200 Subject: Separated USB UART interface into separate file. --- src/stm32/Makefile.inc | 8 ++- src/stm32/cdcacm.c | 61 ++++------------------ src/stm32/platform.c | 70 ++------------------------ src/stm32/platform.h | 2 +- src/stm32/usbuart.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 153 insertions(+), 122 deletions(-) create mode 100644 src/stm32/usbuart.c diff --git a/src/stm32/Makefile.inc b/src/stm32/Makefile.inc index 8bc5d35..98f1d00 100644 --- a/src/stm32/Makefile.inc +++ b/src/stm32/Makefile.inc @@ -12,8 +12,9 @@ LDFLAGS = $(LDFLAGS_BOOT) -Wl,-Ttext=0x8002000 SRC += cdcacm.c \ platform.c \ traceswo.c \ + usbuart.c \ -all: blackmagic.bin blackmagic_dfu.bin +all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex blackmagic.bin: blackmagic $(OBJCOPY) -O binary $^ $@ @@ -24,6 +25,9 @@ blackmagic_dfu: usbdfu.o blackmagic_dfu.bin: blackmagic_dfu $(OBJCOPY) -O binary $^ $@ +blackmagic_dfu.hex: blackmagic_dfu + $(OBJCOPY) -O ihex $^ $@ + host_clean: - -rm blackmagic.bin blackmagic_dfu blackmagic_dfu.bin + -rm blackmagic.bin blackmagic_dfu blackmagic_dfu.bin blackmagic_dfu.hex diff --git a/src/stm32/cdcacm.c b/src/stm32/cdcacm.c index 99efaf8..ebdef18 100644 --- a/src/stm32/cdcacm.c +++ b/src/stm32/cdcacm.c @@ -34,11 +34,11 @@ #include #include #include -#include #include #include "platform.h" #include "traceswo.h" +#include "usbuart.h" #define DFU_IF_NO 4 @@ -423,43 +423,17 @@ static int cdcacm_control_request(struct usb_setup_data *req, uint8_t **buf, cdcacm_gdb_dtr = req->wValue & 1; return 1; - case USB_CDC_REQ_SET_LINE_CODING: { + case USB_CDC_REQ_SET_LINE_CODING: if(*len < sizeof(struct usb_cdc_line_coding)) return 0; - if(req->wIndex == 0) - return 1; /* Ignore on GDB Port */ - - if(req->wIndex != 2) - return 0; - - struct usb_cdc_line_coding *coding = (void*)*buf; - usart_set_baudrate(USART1, coding->dwDTERate); - usart_set_databits(USART1, coding->bDataBits); - switch(coding->bCharFormat) { - case 0: - usart_set_stopbits(USART1, USART_STOPBITS_1); - break; - case 1: - usart_set_stopbits(USART1, USART_STOPBITS_1_5); - break; + switch(req->wIndex) { case 2: - usart_set_stopbits(USART1, USART_STOPBITS_2); - break; - } - switch(coding->bParityType) { + usbuart_set_line_coding((struct usb_cdc_line_coding*)*buf); case 0: - usart_set_parity(USART1, USART_PARITY_NONE); - break; - case 1: - usart_set_parity(USART1, USART_PARITY_ODD); - break; - case 2: - usart_set_parity(USART1, USART_PARITY_EVEN); - break; - } - - return 1; + return 1; /* Ignore on GDB Port */ + default: + return 0; } case DFU_GETSTATUS: if(req->wIndex == DFU_IF_NO) { @@ -493,23 +467,6 @@ int cdcacm_get_dtr(void) return cdcacm_gdb_dtr; } -static void cdcacm_data_rx_cb(u8 ep) -{ - (void)ep; - - char buf[CDCACM_PACKET_SIZE]; - int len = usbd_ep_read_packet(0x03, buf, CDCACM_PACKET_SIZE); - - /* Don't bother if uart is disabled. - * This will be the case on mini while we're being debugged. - */ - if(!(RCC_APB2ENR & RCC_APB2ENR_USART1EN)) - return; - - for(int i = 0; i < len; i++) - usart_send_blocking(USART1, buf[i]); -} - static void cdcacm_set_config(u16 wValue) { configured = wValue; @@ -520,8 +477,8 @@ static void cdcacm_set_config(u16 wValue) usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); /* Serial interface */ - usbd_ep_setup(0x03, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, cdcacm_data_rx_cb); - usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, uart_usb_buf_drain); + usbd_ep_setup(0x03, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, usbuart_usb_out_cb); + usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, usbuart_usb_in_cb); usbd_ep_setup(0x84, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); /* Trace interface */ diff --git a/src/stm32/platform.c b/src/stm32/platform.c index 8218894..2a66080 100644 --- a/src/stm32/platform.c +++ b/src/stm32/platform.c @@ -28,11 +28,11 @@ #include #include #include -#include #include #include "platform.h" #include "jtag_scan.h" +#include "usbuart.h" #include @@ -44,9 +44,6 @@ jmp_buf fatal_error_jmpbuf; void morse(const char *msg, char repeat); static void morse_update(void); -#ifdef INCLUDE_UART_INTERFACE -static void uart_init(void); -#endif static void adc_init(void); /* Pins PB[7:5] are used to detect hardware revision. @@ -103,13 +100,8 @@ int platform_init(void) systick_interrupt_enable(); systick_counter_enable(); -#ifdef INCLUDE_UART_INTERFACE - /* On mini hardware, UART and SWD share connector pins. - * Don't enable UART if we're being debugged. */ - if ((platform_hwversion() == 0) || - !(SCS_DEMCR & SCS_DEMCR_TRCENA)) - uart_init(); -#endif + usbuart_init(); + if (platform_hwversion() > 0) { adc_init(); } else { @@ -216,62 +208,6 @@ static void morse_update(void) code >>= 1; bits--; } -#ifdef INCLUDE_UART_INTERFACE -static void uart_init(void) -{ - rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_USART1EN); - - /* UART1 TX to 'alternate function output push-pull' */ - gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9); - - /* Setup UART parameters. */ - usart_set_baudrate(USART1, 38400); - usart_set_databits(USART1, 8); - usart_set_stopbits(USART1, USART_STOPBITS_1); - usart_set_mode(USART1, USART_MODE_TX_RX); - usart_set_parity(USART1, USART_PARITY_NONE); - usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE); - - /* Finally enable the USART. */ - usart_enable(USART1); - - /* Enable interrupts */ - USART1_CR1 |= USART_CR1_RXNEIE; - nvic_set_priority(NVIC_USART1_IRQ, IRQ_PRI_USART1); - nvic_enable_irq(NVIC_USART1_IRQ); -} - -static uint8_t uart_usb_buf[CDCACM_PACKET_SIZE]; -static uint8_t uart_usb_buf_size; - -void uart_usb_buf_drain(uint8_t ep) -{ - if (!uart_usb_buf_size) - return; - - usbd_ep_write_packet(ep, uart_usb_buf, uart_usb_buf_size); - uart_usb_buf_size = 0; -} - -void usart1_isr(void) -{ - char c = usart_recv(USART1); - - /* Try to send now */ - if (usbd_ep_write_packet(0x83, &c, 1) == 1) - return; - - /* We failed, so queue for later */ - if (uart_usb_buf_size == CDCACM_PACKET_SIZE) { - /* Drop if the buffer's full: we have no flow control */ - return; - } - - uart_usb_buf[uart_usb_buf_size++] = c; -} -#endif - static void adc_init(void) { rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); diff --git a/src/stm32/platform.h b/src/stm32/platform.h index 5b546ca..242ea19 100644 --- a/src/stm32/platform.h +++ b/src/stm32/platform.h @@ -31,7 +31,6 @@ #include "gdb_packet.h" -#define INCLUDE_UART_INTERFACE #define INLINE_GPIO #define CDCACM_PACKET_SIZE 64 #define PLATFORM_HAS_TRACESWO @@ -123,6 +122,7 @@ extern const char *morse_msg; int platform_init(void); void morse(const char *msg, char repeat); const char *platform_target_voltage(void); +int platform_hwversion(void); /* */ void cdcacm_init(void); diff --git a/src/stm32/usbuart.c b/src/stm32/usbuart.c new file mode 100644 index 0000000..62e1107 --- /dev/null +++ b/src/stm32/usbuart.c @@ -0,0 +1,134 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2012 Black Sphere Technologies Ltd. + * Written by Gareth McMullin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "platform.h" + +void usbuart_init(void) +{ + /* On mini hardware, UART and SWD share connector pins. + * Don't enable UART if we're being debugged. */ + if ((platform_hwversion() == 1) && (SCS_DEMCR & SCS_DEMCR_TRCENA)) + return; + + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_USART1EN); + + /* UART1 TX to 'alternate function output push-pull' */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9); + + /* Setup UART parameters. */ + usart_set_baudrate(USART1, 38400); + usart_set_databits(USART1, 8); + usart_set_stopbits(USART1, USART_STOPBITS_1); + usart_set_mode(USART1, USART_MODE_TX_RX); + usart_set_parity(USART1, USART_PARITY_NONE); + usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE); + + /* Finally enable the USART. */ + usart_enable(USART1); + + /* Enable interrupts */ + USART1_CR1 |= USART_CR1_RXNEIE; + nvic_set_priority(NVIC_USART1_IRQ, IRQ_PRI_USART1); + nvic_enable_irq(NVIC_USART1_IRQ); +} + +void usbuart_set_line_coding(struct usb_cdc_line_coding *coding) +{ + usart_set_baudrate(USART1, coding->dwDTERate); + usart_set_databits(USART1, coding->bDataBits); + switch(coding->bCharFormat) { + case 0: + usart_set_stopbits(USART1, USART_STOPBITS_1); + break; + case 1: + usart_set_stopbits(USART1, USART_STOPBITS_1_5); + break; + case 2: + usart_set_stopbits(USART1, USART_STOPBITS_2); + break; + } + switch(coding->bParityType) { + case 0: + usart_set_parity(USART1, USART_PARITY_NONE); + break; + case 1: + usart_set_parity(USART1, USART_PARITY_ODD); + break; + case 2: + usart_set_parity(USART1, USART_PARITY_EVEN); + break; + } +} + +void usbuart_usb_out_cb(uint8_t ep) +{ + (void)ep; + + char buf[CDCACM_PACKET_SIZE]; + int len = usbd_ep_read_packet(0x03, buf, CDCACM_PACKET_SIZE); + + /* Don't bother if uart is disabled. + * This will be the case on mini while we're being debugged. + */ + if(!(RCC_APB2ENR & RCC_APB2ENR_USART1EN)) + return; + + for(int i = 0; i < len; i++) + usart_send_blocking(USART1, buf[i]); +} + +static uint8_t uart_usb_buf[CDCACM_PACKET_SIZE]; +static uint8_t uart_usb_buf_size; + +void usbuart_usb_in_cb(uint8_t ep) +{ + if (!uart_usb_buf_size) + return; + + usbd_ep_write_packet(ep, uart_usb_buf, uart_usb_buf_size); + uart_usb_buf_size = 0; +} + +void usart1_isr(void) +{ + char c = usart_recv(USART1); + + /* Try to send now */ + if (usbd_ep_write_packet(0x83, &c, 1) == 1) + return; + + /* We failed, so queue for later */ + if (uart_usb_buf_size == CDCACM_PACKET_SIZE) { + /* Drop if the buffer's full: we have no flow control */ + return; + } + + uart_usb_buf[uart_usb_buf_size++] = c; +} + -- cgit v1.2.3