From 86626085d80b63171593e588a6915a91eb5633fd Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sun, 22 Apr 2012 12:22:08 +1200 Subject: [PATCH] Fixed TRACESWO capture. 'mon traceswo' reports serial number and interface/endpoint no for libusb. Interrupt priorities set so TIM3 for trace is highest priority. Increased trace endpoint packet size to 64. Buffer many trace packets into a single usb packet. Stall on overflow. Fixed stop bit detection in TIM3 interrupt handler. --- src/command.c | 2 ++ src/stm32/cdcacm.c | 8 +++++--- src/stm32/platform.c | 1 + src/stm32/traceswo.c | 32 ++++++++++++++++++++++++++------ 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/command.c b/src/command.c index 1efae36f..a9f3d028 100644 --- a/src/command.c +++ b/src/command.c @@ -166,6 +166,8 @@ void cmd_morse(void) static void cmd_traceswo(void) { + extern char serial_no[9]; traceswo_init(); + gdb_outf("%s:%02X:%02X\n", serial_no, 5, 0x85); } diff --git a/src/stm32/cdcacm.c b/src/stm32/cdcacm.c index 81c1481f..f704a27a 100644 --- a/src/stm32/cdcacm.c +++ b/src/stm32/cdcacm.c @@ -312,7 +312,7 @@ static const struct usb_endpoint_descriptor trace_endp[] = {{ .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = 0x85, .bmAttributes = USB_ENDPOINT_ATTR_BULK, - .wMaxPacketSize = 16, + .wMaxPacketSize = 64, .bInterval = 0, }}; @@ -378,7 +378,7 @@ static const struct usb_config_descriptor config = { .interface = ifaces, }; -static char serial_no[9]; +char serial_no[9]; static const char *usb_strings[] = { "x", @@ -518,7 +518,7 @@ static void cdcacm_set_config(u16 wValue) usbd_ep_setup(0x84, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); /* Trace interface */ - usbd_ep_setup(0x85, USB_ENDPOINT_ATTR_BULK, 16, trace_buf_drain); + usbd_ep_setup(0x85, USB_ENDPOINT_ATTR_BULK, 64, trace_buf_drain); usbd_register_control_callback( USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, @@ -556,7 +556,9 @@ void cdcacm_init(void) usbd_set_control_buffer_size(sizeof(usbd_control_buffer)); usbd_register_set_config_callback(cdcacm_set_config); + nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1); nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); + nvic_set_priority(USB_VBUS_IRQ, 14); nvic_enable_irq(USB_VBUS_IRQ); gpio_set(USB_VBUS_PORT, USB_VBUS_PIN); diff --git a/src/stm32/platform.c b/src/stm32/platform.c index 3923ed13..cec39768 100644 --- a/src/stm32/platform.c +++ b/src/stm32/platform.c @@ -204,6 +204,7 @@ void uart_init(void) /* Enable interrupts */ USART1_CR1 |= USART_CR1_RXNEIE; + nvic_set_priority(NVIC_USART1_IRQ, 14); nvic_enable_irq(NVIC_USART1_IRQ); } diff --git a/src/stm32/traceswo.c b/src/stm32/traceswo.c index f21ce98b..02d0ec8a 100644 --- a/src/stm32/traceswo.c +++ b/src/stm32/traceswo.c @@ -31,6 +31,8 @@ * These can be capture directly to RAM by DMA. * The core can then process the buffer to extract the frame. */ +#include "general.h" + #include #include #include @@ -66,6 +68,7 @@ void traceswo_init(void) timer_slave_set_mode(TIM3, TIM_SMCR_SMS_RM); /* Enable capture interrupt */ + nvic_set_priority(NVIC_TIM3_IRQ, 0); nvic_enable_irq(NVIC_TIM3_IRQ); timer_enable_irq(TIM3, TIM_DIER_CC1IE); @@ -76,14 +79,20 @@ void traceswo_init(void) timer_enable_counter(TIM3); } -static uint8_t trace_usb_buf[16]; +static uint8_t trace_usb_buf[64]; static uint8_t trace_usb_buf_size; void trace_buf_push(uint8_t *buf, int len) { if (usbd_ep_write_packet(0x85, buf, len) != len) { - memcpy(trace_usb_buf, buf, len); - trace_usb_buf_size = len; + if (trace_usb_buf_size + len > 64) { + /* Stall if upstream to too slow. */ + usbd_ep_stall_set(0x85, 1); + trace_usb_buf_size = 0; + return; + } + memcpy(trace_usb_buf + trace_usb_buf_size, buf, len); + trace_usb_buf_size += len; } } @@ -106,6 +115,7 @@ void tim3_isr(void) static uint8_t lastbit; static uint8_t decbuf[17]; static uint8_t decbuf_pos; + static uint8_t halfbit; /* Reset decoder state if capture overflowed */ if (sr & (TIM_SR_CC1OF | TIM_SR_UIF)) { @@ -124,8 +134,7 @@ void tim3_isr(void) duty = TIM_CCR2(TIM3); /* Reset decoder state if crazy shit happened */ - if ((bt && (((duty / bt) > 2) || ((cycle / bt) > 4))) || - (duty == 0)) + if ((bt && ((duty / bt) > 2)) || (duty == 0)) goto flush_and_reset; if (!bt) { @@ -136,19 +145,30 @@ void tim3_isr(void) return; bt = duty; lastbit = 1; + halfbit = 0; timer_set_period(TIM3, duty * 5); timer_clear_flag(TIM3, TIM_SR_UIF); timer_enable_irq(TIM3, TIM_DIER_UIE); } else { /* If high time is extended we need to flip the bit */ - if ((duty / bt) > 1) + if ((duty / bt) > 1) { + if (!halfbit) /* lost sync somehow */ + goto flush_and_reset; + halfbit = 0; lastbit ^= 1; + } decbuf[decbuf_pos >> 3] |= lastbit << (decbuf_pos & 7); decbuf_pos++; } + if (((cycle - duty) / bt) > 2) + goto flush_and_reset; + if (((cycle - duty) / bt) > 1) { /* If low time extended we need to pack another bit. */ + if (halfbit) /* this is a valid stop-bit or we lost sync */ + goto flush_and_reset; + halfbit = 1; lastbit ^= 1; decbuf[decbuf_pos >> 3] |= lastbit << (decbuf_pos & 7); decbuf_pos++;