#include #include #include #include #include #include #include "adc.h" #include "buttons.h" #include "usb.h" #include "ringbuffer.h" #include "uart.h" #include "encoder.h" static const uint32_t button_time = 100; volatile uint32_t tick = 0; RINGBUFFER_STORAGE(usb_to_uart_buf, 64) RINGBUFFER_STORAGE(uart_to_usb_buf, 64) RINGBUFFER_STORAGE(comm_in_buf, 64) RINGBUFFER_STORAGE(comm_out_buf, 64) extern uint32_t *_board_dfu_dbl_tap; static void sys_tick_setup(void); static void fast_reset(void); static void start_bootloader(void); static void erase_app(void); static void sys_tick_setup() { systick_set_reload(168000/2-1); systick_set_clocksource(STK_CSR_CLKSOURCE_AHB); systick_counter_enable(); systick_interrupt_enable(); } void sys_tick_handler() { tick++; } void fast_reset() { *_board_dfu_dbl_tap = 0xf02669ef; scb_reset_system(); } void start_bootloader() { *_board_dfu_dbl_tap = 0xf01669ef; scb_reset_system(); } void erase_app() { *_board_dfu_dbl_tap = 0xf5e80ab4; scb_reset_system(); } int main(void) { #if 0 rcc_clock_setup_pll(&rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_84MHZ]); #else rcc_clock_setup_pll(&rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_84MHZ]); #endif RINGBUFFER_INIT(uart_to_usb_buf, 64); RINGBUFFER_INIT(usb_to_uart_buf, 64); RINGBUFFER_INIT(comm_in_buf, 64); RINGBUFFER_INIT(comm_out_buf, 64); sys_tick_setup(); while(tick < 100) ; adc_setup(); uart_setup(); usb_setup(); buttons_setup(); encoder_setup(); nvic_enable_irq(NVIC_USART3_IRQ); uint32_t last_tick = tick; int last_pos = 0; int watchdog = 1; int watchdog_counter = 0; int print_changes = 0; while (1) { /* Handle control messages through the comms CDC */ char buf[64]; unsigned buf_len = 0; const bool no_comms = watchdog && ringbuffer_empty(usb_to_uart_buf) && ringbuffer_empty(comm_in_buf); if (!no_comms) { watchdog_counter = 0; } while (tick != last_tick) { buttons_tick(); last_tick++; watchdog_counter += no_comms; } if (watchdog_counter >= 35000) { fast_reset(); } for (char c; ringbuffer_get(comm_in_buf, (void *)&c, 1);) { switch (c) { case 'B': // Battery printf("%lu", (unsigned long)adc_bat_voltage()); break; case 'O': // Open buttons_open(button_time); break; case 'C': // Close buttons_close(button_time); break; case 'R': // Report printf("pos: %d", encoder_get()); printf("tick: %lu", tick); break; case 'r': // toggle reporting print_changes = !print_changes; printf("pos reporting: %d", print_changes); break; case 'W': // toggle watchdog watchdog = !watchdog; printf("watchdog: %d", watchdog); break; case 'F': // Flash start_bootloader(); break; case 'E': // Erase erase_app(); break; case 'S': // reStart fast_reset(); break; } } int pos = encoder_get(); if (pos != last_pos && ringbuffer_empty(comm_out_buf)) { if (print_changes) { printf("pos: %d", pos); } last_pos = pos; } /* Send replies */ if ((buf_len = ringbuffer_peek(comm_out_buf, &buf[0], sizeof buf))) { if (usb_write_cdcacm(ACM_COMM, (void *)buf, buf_len, 1)) { ringbuffer_skip(comm_out_buf, buf_len); } } /* Send any available data to the NFC CDC */ if (!ringbuffer_empty(uart_to_usb_buf)) { unsigned len = ringbuffer_peek(uart_to_usb_buf, &buf[0], sizeof buf); if (usb_write_cdcacm(ACM_NFC, &buf[0], len, 1)) { ringbuffer_skip(uart_to_usb_buf, len); } } if (!ringbuffer_empty(usb_to_uart_buf)) { usart_enable_tx_interrupt(USART3); } usbd_poll(g_usbd_dev); __asm__("wfi"); } } void usart3_isr() { while (USART_SR(USART3) & USART_SR_RXNE) { uint8_t c = usart_recv(USART3); ringbuffer_add(uart_to_usb_buf, (void *)&c, 1); } while (USART_SR(USART3) & USART_SR_TXE) { if (ringbuffer_empty(usb_to_uart_buf)) { usart_disable_tx_interrupt(USART3); break; } else { uint8_t c; ringbuffer_get(usb_to_uart_buf, &c, 1); usart_send(USART3, c); } } }