From 38ccc769f79844f1e44be5167b060a5af5cc4937 Mon Sep 17 00:00:00 2001 From: rudihorn Date: Tue, 26 May 2020 06:43:29 +0100 Subject: [PATCH] Emergency Parser for STM32 (#18095) --- Marlin/src/HAL/STM32/HAL.cpp | 3 + Marlin/src/HAL/STM32/HAL.h | 37 ++++++------ Marlin/src/HAL/STM32/MarlinSerial.cpp | 80 ++++++++++++++++++++++++++ Marlin/src/HAL/STM32/MarlinSerial.h | 54 +++++++++++++++++ Marlin/src/HAL/STM32/inc/SanityCheck.h | 4 -- Marlin/src/HAL/STM32/usb_serial.cpp | 55 ++++++++++++++++++ Marlin/src/HAL/STM32/usb_serial.h | 21 +++++++ 7 files changed, 232 insertions(+), 22 deletions(-) create mode 100644 Marlin/src/HAL/STM32/MarlinSerial.cpp create mode 100644 Marlin/src/HAL/STM32/MarlinSerial.h create mode 100644 Marlin/src/HAL/STM32/usb_serial.cpp create mode 100644 Marlin/src/HAL/STM32/usb_serial.h diff --git a/Marlin/src/HAL/STM32/HAL.cpp b/Marlin/src/HAL/STM32/HAL.cpp index 37cfb576d1..c09592a564 100644 --- a/Marlin/src/HAL/STM32/HAL.cpp +++ b/Marlin/src/HAL/STM32/HAL.cpp @@ -23,6 +23,7 @@ #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) #include "HAL.h" +#include "usb_serial.h" #include "../../inc/MarlinConfig.h" #include "../shared/Delay.h" @@ -79,6 +80,8 @@ void HAL_init() { #endif SetSoftwareSerialTimerInterruptPriority(); + + TERN_(EMERGENCY_PARSER, USB_Hook_init()); } void HAL_clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); } diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h index 4c64d95153..3319636704 100644 --- a/Marlin/src/HAL/STM32/HAL.h +++ b/Marlin/src/HAL/STM32/HAL.h @@ -30,6 +30,7 @@ #include "../shared/HAL_SPI.h" #include "fastio.h" #include "watchdog.h" +#include "MarlinSerial.h" #include "../../inc/MarlinConfigPre.h" @@ -48,17 +49,17 @@ #elif SERIAL_PORT == -1 #define MYSERIAL0 SerialUSB #elif SERIAL_PORT == 1 - #define MYSERIAL0 Serial1 + #define MYSERIAL0 MSerial1 #elif SERIAL_PORT == 2 - #define MYSERIAL0 Serial2 + #define MYSERIAL0 MSerial2 #elif SERIAL_PORT == 3 - #define MYSERIAL0 Serial3 + #define MYSERIAL0 MSerial3 #elif SERIAL_PORT == 4 - #define MYSERIAL0 Serial4 + #define MYSERIAL0 MSerial4 #elif SERIAL_PORT == 5 - #define MYSERIAL0 Serial5 + #define MYSERIAL0 MSerial5 #elif SERIAL_PORT == 6 - #define MYSERIAL0 Serial6 + #define MYSERIAL0 MSerial6 #else #error "SERIAL_PORT must be from -1 to 6. Please update your configuration." #endif @@ -72,17 +73,17 @@ #elif SERIAL_PORT_2 == -1 #define MYSERIAL1 SerialUSB #elif SERIAL_PORT_2 == 1 - #define MYSERIAL1 Serial1 + #define MYSERIAL1 MSerial1 #elif SERIAL_PORT_2 == 2 - #define MYSERIAL1 Serial2 + #define MYSERIAL1 MSerial2 #elif SERIAL_PORT_2 == 3 - #define MYSERIAL1 Serial3 + #define MYSERIAL1 MSerial3 #elif SERIAL_PORT_2 == 4 - #define MYSERIAL1 Serial4 + #define MYSERIAL1 MSerial4 #elif SERIAL_PORT_2 == 5 - #define MYSERIAL1 Serial5 + #define MYSERIAL1 MSerial5 #elif SERIAL_PORT_2 == 6 - #define MYSERIAL1 Serial6 + #define MYSERIAL1 MSerial6 #else #error "SERIAL_PORT_2 must be from -1 to 6. Please update your configuration." #endif @@ -100,17 +101,17 @@ #elif DGUS_SERIAL_PORT == -1 #define DGUS_SERIAL SerialUSB #elif DGUS_SERIAL_PORT == 1 - #define DGUS_SERIAL Serial1 + #define DGUS_SERIAL MSerial1 #elif DGUS_SERIAL_PORT == 2 - #define DGUS_SERIAL Serial2 + #define DGUS_SERIAL MSerial2 #elif DGUS_SERIAL_PORT == 3 - #define DGUS_SERIAL Serial3 + #define DGUS_SERIAL MSerial3 #elif DGUS_SERIAL_PORT == 4 - #define DGUS_SERIAL Serial4 + #define DGUS_SERIAL MSerial4 #elif DGUS_SERIAL_PORT == 5 - #define DGUS_SERIAL Serial5 + #define DGUS_SERIAL MSerial5 #elif DGUS_SERIAL_PORT == 6 - #define DGUS_SERIAL Serial6 + #define DGUS_SERIAL MSerial6 #else #error "DGUS_SERIAL_PORT must be from -1 to 6. Please update your configuration." #endif diff --git a/Marlin/src/HAL/STM32/MarlinSerial.cpp b/Marlin/src/HAL/STM32/MarlinSerial.cpp new file mode 100644 index 0000000000..1961791e22 --- /dev/null +++ b/Marlin/src/HAL/STM32/MarlinSerial.cpp @@ -0,0 +1,80 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * 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 . + * + */ + +#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) + +#include "../../inc/MarlinConfig.h" +#include "MarlinSerial.h" + +#if ENABLED(EMERGENCY_PARSER) + #include "../../feature/e_parser.h" +#endif + +#define DECLARE_SERIAL_PORT(ser_num) \ + void _rx_complete_irq_ ## ser_num (serial_t * obj); \ + MarlinSerial MSerial ## ser_num (USART ## ser_num, &_rx_complete_irq_ ## ser_num); \ + void _rx_complete_irq_ ## ser_num (serial_t * obj) { MSerial ## ser_num ._rx_complete_irq(obj); } + +#define DECLARE_SERIAL_PORT_EXP(ser_num) DECLARE_SERIAL_PORT(ser_num) + +#if defined(SERIAL_PORT) && SERIAL_PORT >= 0 + DECLARE_SERIAL_PORT_EXP(SERIAL_PORT) +#endif + +#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0 + DECLARE_SERIAL_PORT_EXP(SERIAL_PORT_2) +#endif + +#if defined(DGUS_SERIAL_PORT) && DGUS_SERIAL_PORT >= 0 + DECLARE_SERIAL_PORT_EXP(DGUS_SERIAL_PORT) +#endif + +void MarlinSerial::begin(unsigned long baud, uint8_t config) { + HardwareSerial::begin(baud, config); + // replace the IRQ callback with the one we have defined + #if ENABLED(EMERGENCY_PARSER) + _serial.rx_callback = _rx_callback; + #endif +} + +// This function is Copyright (c) 2006 Nicholas Zambetti. +void MarlinSerial::_rx_complete_irq(serial_t *obj) { + // No Parity error, read byte and store it in the buffer if there is room + unsigned char c; + + if (uart_getc(obj, &c) == 0) { + + rx_buffer_index_t i = (unsigned int)(obj->rx_head + 1) % SERIAL_RX_BUFFER_SIZE; + + // if we should be storing the received character into the location + // just before the tail (meaning that the head would advance to the + // current location of the tail), we're about to overflow the buffer + // and so we don't write the character or advance the head. + if (i != obj->rx_tail) { + obj->rx_buff[obj->rx_head] = c; + obj->rx_head = i; + } + + #if ENABLED(EMERGENCY_PARSER) + emergency_parser.update(emergency_state, c); + #endif + } +} + +#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/STM32/MarlinSerial.h b/Marlin/src/HAL/STM32/MarlinSerial.h new file mode 100644 index 0000000000..290fdce9ee --- /dev/null +++ b/Marlin/src/HAL/STM32/MarlinSerial.h @@ -0,0 +1,54 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * 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 . + * + */ +#pragma once + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(EMERGENCY_PARSER) + #include "../../feature/e_parser.h" +#endif + +typedef void (*usart_rx_callback_t)(serial_t * obj); + +class MarlinSerial : public HardwareSerial { +public: + MarlinSerial(void* peripheral, usart_rx_callback_t rx_callback) : + HardwareSerial(peripheral), _rx_callback(rx_callback) + #if ENABLED(EMERGENCY_PARSER) + , emergency_state(EmergencyParser::State::EP_RESET) + #endif + { } + + void begin(unsigned long baud, uint8_t config); + inline void begin(unsigned long baud) { begin(baud, SERIAL_8N1); } + + void _rx_complete_irq(serial_t* obj); + +protected: + usart_rx_callback_t _rx_callback; + #if ENABLED(EMERGENCY_PARSER) + EmergencyParser::State emergency_state; + #endif +}; + +extern MarlinSerial MSerial1; +extern MarlinSerial MSerial2; +extern MarlinSerial MSerial3; +extern MarlinSerial MSerial4; +extern MarlinSerial MSerial5; diff --git a/Marlin/src/HAL/STM32/inc/SanityCheck.h b/Marlin/src/HAL/STM32/inc/SanityCheck.h index 7734fc0e83..7236b7f4ed 100644 --- a/Marlin/src/HAL/STM32/inc/SanityCheck.h +++ b/Marlin/src/HAL/STM32/inc/SanityCheck.h @@ -28,10 +28,6 @@ // #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" //#endif -#if ENABLED(EMERGENCY_PARSER) - #error "EMERGENCY_PARSER is not yet implemented for STM32. Disable EMERGENCY_PARSER to continue." -#endif - #if ENABLED(FAST_PWM_FAN) #error "FAST_PWM_FAN is not yet implemented for this platform." #endif diff --git a/Marlin/src/HAL/STM32/usb_serial.cpp b/Marlin/src/HAL/STM32/usb_serial.cpp new file mode 100644 index 0000000000..86c164cb93 --- /dev/null +++ b/Marlin/src/HAL/STM32/usb_serial.cpp @@ -0,0 +1,55 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * 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 . + * + */ + +#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC) + +#include "../../inc/MarlinConfigPre.h" + +#if ENABLED(EMERGENCY_PARSER) + +#include "usb_serial.h" +#include "../../feature/e_parser.h" + +EmergencyParser::State emergency_state = EmergencyParser::State::EP_RESET; + +int8_t (*USBD_CDC_Receive_original) (uint8_t *Buf, uint32_t *Len) = nullptr; + +static int8_t USBD_CDC_Receive_hook(uint8_t *Buf, uint32_t *Len) { + for (uint32_t i = 0; i < *Len; i++) + emergency_parser.update(emergency_state, Buf[i]); + return USBD_CDC_Receive_original(Buf, Len); +} + +typedef struct _USBD_CDC_Itf { + int8_t (* Init)(void); + int8_t (* DeInit)(void); + int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length); + int8_t (* Receive)(uint8_t *Buf, uint32_t *Len); + int8_t (* Transferred)(void); +} USBD_CDC_ItfTypeDef; + +extern USBD_CDC_ItfTypeDef USBD_CDC_fops; + +void USB_Hook_init() { + USBD_CDC_Receive_original = USBD_CDC_fops.Receive; + USBD_CDC_fops.Receive = USBD_CDC_Receive_hook; +} + +#endif // EMERGENCY_PARSER +#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC diff --git a/Marlin/src/HAL/STM32/usb_serial.h b/Marlin/src/HAL/STM32/usb_serial.h new file mode 100644 index 0000000000..4243683479 --- /dev/null +++ b/Marlin/src/HAL/STM32/usb_serial.h @@ -0,0 +1,21 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * 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 . + * + */ +#pragma once + +void USB_Hook_init();