From 1a225be603a00f82c68272074d92776c10a6f6f7 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Tue, 25 Feb 2020 22:41:35 +0100 Subject: [PATCH] BSB: Receiving works --- bsb/firmware/main.c | 77 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/bsb/firmware/main.c b/bsb/firmware/main.c index e7237e1..4e10dc5 100644 --- a/bsb/firmware/main.c +++ b/bsb/firmware/main.c @@ -30,12 +30,14 @@ static void clock_init(void) rcc_periph_clock_enable(RCC_GPIOB); rcc_periph_clock_enable(RCC_GPIOC); rcc_periph_clock_enable(RCC_USART1); + rcc_periph_clock_enable(RCC_USART3); rcc_periph_clock_enable(RCC_USB); rcc_periph_reset_pulse(RST_GPIOA); rcc_periph_reset_pulse(RST_GPIOB); rcc_periph_reset_pulse(RST_GPIOC); rcc_periph_reset_pulse(RST_USART1); + rcc_periph_reset_pulse(RST_USART3); rcc_periph_reset_pulse(RST_USB); } @@ -84,7 +86,7 @@ void sys_tick_handler(void) static void tick_init(void) { - systick_set_frequency(1000, 72000000); + systick_set_frequency(1000, CPU_CLOCK_MHZ * 1000000); systick_counter_enable(); systick_interrupt_enable(); } @@ -99,10 +101,18 @@ static void delay_ms(uint ms) /*** BSB ***/ #define BSB_MAX_SIZE 32 -#define BSB_RX_TIMEOUT 2 // 1-2 ms => 2-4 byte periods of silence +#define BSB_RX_TIMEOUT 10 // ms + +#define DEBUG_BSB +#ifdef DEBUG_BSB +#define BSB_DEBUG(x...) debug_printf(x) +#else +#define BSB_DEBUG(x...) do { } while (0) +#endif static byte bsb_rx_buf[BSB_MAX_SIZE]; static byte bsb_rx_len; +static u16 bsb_rx_crc; static volatile u32 bsb_rx_timestamp; // Passing received frames to the main loop @@ -116,26 +126,49 @@ struct bsb_stat { u32 rx_invalid; u32 rx_overruns; u32 rx_timeouts; + u32 rx_bad_crc; + u32 rx_ok; }; static struct bsb_stat bsb_stat; +static u16 bsb_crc_update(u16 crc, byte data) +{ + crc = crc ^ (data << 8); + for (uint i=0; i<8; i++) { + if (crc & 0x8000) + crc = (crc << 1) ^ 0x1021; + else + crc <<= 1; + } + return crc; +} + void usart3_isr(void) { u32 status = USART_SR(USART3); if (status & USART_SR_RXNE) { - uint ch = usart_recv(USART3); + uint ch = ~usart_recv(USART3) & 0xff; bsb_rx_timestamp = ms_ticks; + BSB_DEBUG(" %02x", ch); if (status & (USART_SR_FE | USART_SR_ORE | USART_SR_NE)) { bsb_stat.rx_errors++; bsb_rx_len = 0; - } else if (!bsb_rx_len && ch != 0xdc) { - // Waiting for start of frame - bsb_stat.rx_noise++; + } else if (!bsb_rx_len) { + // Start of frame + if (ch == 0xdc) { + bsb_rx_buf[bsb_rx_len++] = ch; + bsb_rx_crc = bsb_crc_update(0, ch); + BSB_DEBUG("<"); + } else { + bsb_stat.rx_noise++; + BSB_DEBUG("?"); + } } else { bsb_rx_buf[bsb_rx_len++] = ch; + bsb_rx_crc = bsb_crc_update(bsb_rx_crc, ch); if (bsb_rx_len < 4) { // First three bytes: SOF, source addr, destination addr } else if (bsb_rx_len == 4) { @@ -143,19 +176,28 @@ void usart3_isr(void) if (bsb_rx_buf[3] < 7 || bsb_rx_buf[3] > BSB_MAX_SIZE) { bsb_stat.rx_invalid++; bsb_rx_len = 0; + BSB_DEBUG("!L"); } } else if (bsb_rx_len == bsb_rx_buf[3]) { - // Received a complete frame: pass it to the main loop - if (bsb_rx_frame_len) { - // The previous one was not sent yet - bsb_stat.rx_overruns++; + // Received a complete frame: check CRC and pass it to the main loop + if (bsb_rx_crc) { + bsb_stat.rx_bad_crc++; + BSB_DEBUG("!C"); } else { - memcpy(bsb_rx_frame, bsb_rx_buf, bsb_rx_buf[3]); - barrier(); - bsb_rx_frame_len = bsb_rx_buf[3]; - bsb_rx_frame_led = 100; + if (bsb_rx_frame_len) { + // The previous one was not sent yet + bsb_stat.rx_overruns++; + BSB_DEBUG("!O"); + } else { + memcpy(bsb_rx_frame, bsb_rx_buf, bsb_rx_buf[3]); + bsb_rx_frame_len = bsb_rx_buf[3]; + bsb_stat.rx_ok++; + BSB_DEBUG("."); + } gpio_clear(GPIOB, GPIO1); + bsb_rx_frame_led = 100; } + bsb_rx_len = 0; } } } @@ -166,7 +208,7 @@ static void bsb_init(void) usart_set_baudrate(USART3, 4800); usart_set_databits(USART3, 9); usart_set_stopbits(USART3, USART_STOPBITS_1); - usart_set_mode(USART3, USART_MODE_TX_RX); + usart_set_mode(USART3, USART_MODE_RX); usart_set_parity(USART3, USART_PARITY_ODD); usart_set_flow_control(USART3, USART_FLOWCONTROL_NONE); @@ -292,7 +334,7 @@ static enum usbd_request_return_codes control_cb( return USBD_REQ_NOTSUPP; // We support reading of statistics via control requests - debug_printf("USB: Control request: Read statistics\n"); + debug_printf("USB: Reading statistics\n"); uint n = MIN(*len, sizeof(bsb_stat)); memcpy(*buf, (char *) &bsb_stat, n); *len = n; @@ -443,9 +485,10 @@ int main(void) // Packet timeouts cm_disable_interrupts(); barrier(); - if (bsb_rx_len && (bsb_rx_timestamp - ms_ticks) >= BSB_RX_TIMEOUT) { + if (bsb_rx_len && ms_ticks - bsb_rx_timestamp >= BSB_RX_TIMEOUT) { bsb_rx_len = 0; bsb_stat.rx_timeouts++; + BSB_DEBUG("!T"); } if (bsb_rx_frame_led) { if (!--bsb_rx_frame_led) -- 2.39.5