From 4f6ea165153809b35541700a80e44789d186609c Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Mon, 20 Sep 2021 19:01:08 +0200 Subject: [PATCH] Functional USB reset --- src/hal/avr/cpu.cpp | 17 ++++++++++++++++ src/hal/cpu.h | 3 +++ src/hal/watchdog.h | 4 ++++ src/main.cpp | 47 +++++++++++++++++++++++++-------------------- 4 files changed, 50 insertions(+), 21 deletions(-) diff --git a/src/hal/avr/cpu.cpp b/src/hal/avr/cpu.cpp index 7bef056..db9d93f 100644 --- a/src/hal/avr/cpu.cpp +++ b/src/hal/avr/cpu.cpp @@ -2,9 +2,17 @@ #include #include "../watchdog.h" +#include "lufa_config.h" +#include "Descriptors.h" +#include "lufa/LUFA/Drivers/USB/USB.h" + +#include "../usart.h" + namespace hal { namespace cpu { +bool resetPending = false; + void Init() { } @@ -15,5 +23,14 @@ void Reset() { ; //endless loop while waiting for the watchdog to reset } +void Step() { + if (resetPending) { + hal::usart::usart1.puts("resetPending\n"); + USB_Detach(); + for (;;) + ; //endless loop while waiting for the watchdog to reset + } +} + } // namespace CPU } // namespace hal diff --git a/src/hal/cpu.h b/src/hal/cpu.h index ace6a9e..bdf0472 100644 --- a/src/hal/cpu.h +++ b/src/hal/cpu.h @@ -10,9 +10,12 @@ namespace cpu { #define F_CPU (16000000ul) #endif +extern bool resetPending; + /// CPU init routines (not really necessary for the AVR) void Init(); void Reset(); +void Step(); } // namespace cpu } // namespace hal diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index a560c14..2a2459e 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -37,8 +37,12 @@ public: uint8_t prescalerBits = 0; uint32_t ticks = 1; switch (timeout) { + case 250: + prescalerBits = 4; + break; case 8000: prescalerBits = 9; + break; } configuration config = { prescalerBits, static_cast(ticks - 1) }; diff --git a/src/main.cpp b/src/main.cpp index 9cbf362..476c15e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -100,10 +100,10 @@ void EVENT_USB_Device_ConfigurationChanged(void) { ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface); // LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR); - char str1[] = "ready\n"; - char str0[] = "error\n"; - hal::usart::usart1.puts("EVENT_USB_Device_ConfigurationChanged:"); - hal::usart::usart1.puts(ConfigSuccess ? str1 : str0); + // char str1[] = "ready\n"; + // char str0[] = "error\n"; + // hal::usart::usart1.puts("EVENT_USB_Device_ConfigurationChanged:"); + // hal::usart::usart1.puts(ConfigSuccess ? str1 : str0); } /** Event handler for the library USB Control Request reception event. */ @@ -118,27 +118,28 @@ void EVENT_USB_Device_ControlRequest(void) { * \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced */ void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t *const CDCInterfaceInfo) { - /* You can get changes to the virtual CDC lines in this callback; a common - use-case is to use the Data Terminal Ready (DTR) flag to enable and - disable CDC communications in your application when set to avoid the - application blocking while waiting for a host to become ready and read - in the pending data from the USB endpoints. - */ - hal::usart::usart1.puts("EVENT_CDC_Device_ControLineStateChanged "); - bool HostReady = (CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR) != 0; - char str[50]; - sprintf_P(str, PSTR("DTR:%hu\n"), HostReady); - hal::usart::usart1.puts(str); + // Printing to serial from here will make Windows commit suicide when opening the port + + // hal::usart::usart1.puts("EVENT_CDC_Device_ControLineStateChanged "); + // bool HostReady = (CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR) != 0; + // char str[50]; + // sprintf_P(str, PSTR("DTR:%hu\n"), HostReady); + // hal::usart::usart1.puts(str); } void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t *const CDCInterfaceInfo) { - hal::usart::usart1.puts("EVENT_CDC_Device_LineEncodingChanged "); - char str[50]; - sprintf_P(str, PSTR("baud:%lu\n"), CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); - hal::usart::usart1.puts(str); + // Printing to serial from here will make Windows commit suicide when opening the port + + // hal::usart::usart1.puts("EVENT_CDC_Device_LineEncodingChanged "); + // char str[50]; + // sprintf_P(str, PSTR("baud:%lu\n"), CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); + // hal::usart::usart1.puts(str); + if (CDCInterfaceInfo->State.LineEncoding.BaudRateBPS == 1200) { - *(uint16_t *)0x0800U = 0x7777; - hal::cpu::Reset(); + // *(uint16_t *)0x0800U = 0x7777; //old bootloader? + *(uint16_t *)(RAMEND-1) = 0x7777; + hal::cpu::resetPending = true; + hal::watchdog::Enable(hal::watchdog::configuration::compute(250)); } } } @@ -251,6 +252,8 @@ void setup() { USB_Init(); + _delay_ms(100); + /// Turn off all leds for (uint8_t i = 0; i < config::toolCount; i++) { ml::leds.SetMode(i, ml::Color::green, ml::Mode::off); @@ -477,7 +480,9 @@ void loop() { ms::selector.Step(); mui::userInput.Step(); currentCommand->Step(); + hal::cpu::Step(); + CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); CDC_Device_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask();