Fix and improve STM32F1 serial (#19464)
This commit is contained in:
@ -68,71 +68,49 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SERIAL_PORT == 0
|
||||
#error "SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration."
|
||||
#elif SERIAL_PORT == -1
|
||||
#define MYSERIAL0 UsbSerial
|
||||
#elif SERIAL_PORT == 1
|
||||
#define MYSERIAL0 MSerial1
|
||||
#elif SERIAL_PORT == 2
|
||||
#define MYSERIAL0 MSerial2
|
||||
#elif SERIAL_PORT == 3
|
||||
#define MYSERIAL0 MSerial3
|
||||
#elif SERIAL_PORT == 4
|
||||
#define MYSERIAL0 MSerial4
|
||||
#elif SERIAL_PORT == 5
|
||||
#define MYSERIAL0 MSerial5
|
||||
#define _MSERIAL(X) MSerial##X
|
||||
#define MSERIAL(X) _MSERIAL(X)
|
||||
|
||||
#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY)
|
||||
#define NUM_UARTS 5
|
||||
#else
|
||||
#error "SERIAL_PORT must be from -1 to 5. Please update your configuration."
|
||||
#define NUM_UARTS 3
|
||||
#endif
|
||||
|
||||
#if SERIAL_PORT == -1
|
||||
#define MYSERIAL0 UsbSerial
|
||||
#elif WITHIN(SERIAL_PORT, 1, NUM_UARTS)
|
||||
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
|
||||
#elif NUM_UARTS == 5
|
||||
#error "SERIAL_PORT must be -1 or from 1 to 5. Please update your configuration."
|
||||
#else
|
||||
#error "SERIAL_PORT must be -1 or from 1 to 3. Please update your configuration."
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_PORT_2
|
||||
#if SERIAL_PORT_2 == 0
|
||||
#error "SERIAL_PORT_2 cannot be 0. (Port 0 does not exist.) Please update your configuration."
|
||||
#elif SERIAL_PORT_2 == SERIAL_PORT
|
||||
#error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
|
||||
#elif SERIAL_PORT_2 == -1
|
||||
#if SERIAL_PORT_2 == -1
|
||||
#define MYSERIAL1 UsbSerial
|
||||
#elif SERIAL_PORT_2 == 1
|
||||
#define MYSERIAL1 MSerial1
|
||||
#elif SERIAL_PORT_2 == 2
|
||||
#define MYSERIAL1 MSerial2
|
||||
#elif SERIAL_PORT_2 == 3
|
||||
#define MYSERIAL1 MSerial3
|
||||
#elif SERIAL_PORT_2 == 4
|
||||
#define MYSERIAL1 MSerial4
|
||||
#elif SERIAL_PORT_2 == 5
|
||||
#define MYSERIAL1 MSerial5
|
||||
#elif WITHIN(SERIAL_PORT_2, 1, NUM_UARTS)
|
||||
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
|
||||
#elif NUM_UARTS == 5
|
||||
#error "SERIAL_PORT_2 must be -1 or from 1 to 5. Please update your configuration."
|
||||
#else
|
||||
#error "SERIAL_PORT_2 must be from -1 to 5. Please update your configuration."
|
||||
#error "SERIAL_PORT_2 must be -1 or from 1 to 3. Please update your configuration."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef DGUS_SERIAL_PORT
|
||||
#if DGUS_SERIAL_PORT == 0
|
||||
#error "DGUS_SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration."
|
||||
#elif DGUS_SERIAL_PORT == SERIAL_PORT
|
||||
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
|
||||
#elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
|
||||
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
|
||||
#elif DGUS_SERIAL_PORT == -1
|
||||
#define DGUS_SERIAL UsbSerial
|
||||
#elif DGUS_SERIAL_PORT == 1
|
||||
#define DGUS_SERIAL MSerial1
|
||||
#elif DGUS_SERIAL_PORT == 2
|
||||
#define DGUS_SERIAL MSerial2
|
||||
#elif DGUS_SERIAL_PORT == 3
|
||||
#define DGUS_SERIAL MSerial3
|
||||
#elif DGUS_SERIAL_PORT == 4
|
||||
#define DGUS_SERIAL MSerial4
|
||||
#elif DGUS_SERIAL_PORT == 5
|
||||
#define DGUS_SERIAL MSerial5
|
||||
#ifdef LCD_SERIAL_PORT
|
||||
#if LCD_SERIAL_PORT == -1
|
||||
#define LCD_SERIAL UsbSerial
|
||||
#elif WITHIN(LCD_SERIAL_PORT, 1, NUM_UARTS)
|
||||
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
|
||||
#elif NUM_UARTS == 5
|
||||
#error "LCD_SERIAL_PORT must be -1 or from 1 to 5. Please update your configuration."
|
||||
#else
|
||||
#error "DGUS_SERIAL_PORT must be from -1 to 5. Please update your configuration."
|
||||
#error "LCD_SERIAL_PORT must be -1 or from 1 to 3. Please update your configuration."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// Set interrupt grouping for this MCU
|
||||
void HAL_init();
|
||||
#define HAL_IDLETASK 1
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#ifdef __STM32F1__
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "MarlinSerial.h"
|
||||
#include <libmaple/usart.h>
|
||||
|
||||
@ -53,7 +53,8 @@ static inline __always_inline void my_usart_irq(ring_buffer *rb, ring_buffer *wb
|
||||
rb_push_insert(rb, c);
|
||||
#endif
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
emergency_parser.update(serial.emergency_state, c);
|
||||
if (serial.emergency_parser_enabled())
|
||||
emergency_parser.update(serial.emergency_state, c);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -73,40 +74,120 @@ static inline __always_inline void my_usart_irq(ring_buffer *rb, ring_buffer *wb
|
||||
}
|
||||
}
|
||||
|
||||
#define DEFINE_HWSERIAL_MARLIN(name, n) \
|
||||
MarlinSerial name(USART##n, \
|
||||
BOARD_USART##n##_TX_PIN, \
|
||||
BOARD_USART##n##_RX_PIN); \
|
||||
extern "C" void __irq_usart##n(void) { \
|
||||
// Not every MarlinSerial port should handle emergency parsing.
|
||||
// It would not make sense to parse GCode from TMC responses, for example.
|
||||
constexpr bool serial_handles_emergency(int port) {
|
||||
return false
|
||||
#ifdef SERIAL_PORT
|
||||
|| (SERIAL_PORT) == port
|
||||
#endif
|
||||
#ifdef SERIAL_PORT_2
|
||||
|| (SERIAL_PORT_2) == port
|
||||
#endif
|
||||
#ifdef LCD_SERIAL_PORT
|
||||
|| (LCD_SERIAL_PORT) == port
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
#define DEFINE_HWSERIAL_MARLIN(name, n) \
|
||||
MarlinSerial name(USART##n, \
|
||||
BOARD_USART##n##_TX_PIN, \
|
||||
BOARD_USART##n##_RX_PIN, \
|
||||
serial_handles_emergency(n)); \
|
||||
extern "C" void __irq_usart##n(void) { \
|
||||
my_usart_irq(USART##n->rb, USART##n->wb, USART##n##_BASE, MSerial##n); \
|
||||
}
|
||||
|
||||
#define DEFINE_HWSERIAL_UART_MARLIN(name, n) \
|
||||
MarlinSerial name(UART##n, \
|
||||
BOARD_USART##n##_TX_PIN, \
|
||||
BOARD_USART##n##_RX_PIN); \
|
||||
BOARD_USART##n##_TX_PIN, \
|
||||
BOARD_USART##n##_RX_PIN, \
|
||||
serial_handles_emergency(n)); \
|
||||
extern "C" void __irq_usart##n(void) { \
|
||||
my_usart_irq(USART##n->rb, USART##n->wb, USART##n##_BASE, MSerial##n); \
|
||||
my_usart_irq(UART##n->rb, UART##n->wb, UART##n##_BASE, MSerial##n); \
|
||||
}
|
||||
|
||||
#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1 || DGUS_SERIAL_PORT == 1
|
||||
DEFINE_HWSERIAL_MARLIN(MSerial1, 1);
|
||||
#endif
|
||||
|
||||
#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2 || DGUS_SERIAL_PORT == 2
|
||||
DEFINE_HWSERIAL_MARLIN(MSerial2, 2);
|
||||
#endif
|
||||
|
||||
#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3 || DGUS_SERIAL_PORT == 3
|
||||
DEFINE_HWSERIAL_MARLIN(MSerial3, 3);
|
||||
#endif
|
||||
|
||||
#if SERIAL_PORT == 4 || SERIAL_PORT_2 == 4 || DGUS_SERIAL_PORT == 4
|
||||
// Instantiate all UARTs even if they are not needed
|
||||
// This avoids a bunch of logic to figure out every serial
|
||||
// port which may be in use on the system.
|
||||
DEFINE_HWSERIAL_MARLIN(MSerial1, 1);
|
||||
DEFINE_HWSERIAL_MARLIN(MSerial2, 2);
|
||||
DEFINE_HWSERIAL_MARLIN(MSerial3, 3);
|
||||
#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY)
|
||||
DEFINE_HWSERIAL_UART_MARLIN(MSerial4, 4);
|
||||
#endif
|
||||
|
||||
#if SERIAL_PORT == 5 || SERIAL_PORT_2 == 5 || DGUS_SERIAL_PORT == 5
|
||||
DEFINE_HWSERIAL_UART_MARLIN(MSerial5, 5);
|
||||
#endif
|
||||
|
||||
// Check the type of each serial port by passing it to a template function.
|
||||
// HardwareSerial is known to sometimes hang the controller when an error occurs,
|
||||
// so this case will fail the static assert. All other classes are assumed to be ok.
|
||||
template <typename T>
|
||||
constexpr bool IsSerialClassAllowed(const T&) { return true; }
|
||||
constexpr bool IsSerialClassAllowed(const HardwareSerial&) { return false; }
|
||||
|
||||
#define CHECK_CFG_SERIAL(A) static_assert(IsSerialClassAllowed(A), STRINGIFY(A) " is defined incorrectly");
|
||||
#define CHECK_AXIS_SERIAL(A) static_assert(IsSerialClassAllowed(A##_HARDWARE_SERIAL), STRINGIFY(A) "_HARDWARE_SERIAL must be defined in the form MSerial1, rather than Serial1");
|
||||
|
||||
// If you encounter this error, replace SerialX with MSerialX, for example MSerial3.
|
||||
|
||||
// Non-TMC ports were already validated in HAL.h, so do not require verbose error messages.
|
||||
#ifdef MYSERIAL0
|
||||
CHECK_CFG_SERIAL(MYSERIAL0);
|
||||
#endif
|
||||
#ifdef MYSERIAL1
|
||||
CHECK_CFG_SERIAL(MYSERIAL1);
|
||||
#endif
|
||||
#ifdef LCD_SERIAL
|
||||
CHECK_CFG_SERIAL(LCD_SERIAL);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(X)
|
||||
CHECK_AXIS_SERIAL(X);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(X2)
|
||||
CHECK_AXIS_SERIAL(X2);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(Y)
|
||||
CHECK_AXIS_SERIAL(Y);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(Y2)
|
||||
CHECK_AXIS_SERIAL(Y2);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(Z)
|
||||
CHECK_AXIS_SERIAL(Z);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(Z2)
|
||||
CHECK_AXIS_SERIAL(Z2);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(Z3)
|
||||
CHECK_AXIS_SERIAL(Z3);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(Z4)
|
||||
CHECK_AXIS_SERIAL(Z4);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(E0)
|
||||
CHECK_AXIS_SERIAL(E0);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(E1)
|
||||
CHECK_AXIS_SERIAL(E1);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(E2)
|
||||
CHECK_AXIS_SERIAL(E2);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(E3)
|
||||
CHECK_AXIS_SERIAL(E3);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(E4)
|
||||
CHECK_AXIS_SERIAL(E4);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(E5)
|
||||
CHECK_AXIS_SERIAL(E5);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(E6)
|
||||
CHECK_AXIS_SERIAL(E6);
|
||||
#endif
|
||||
#if AXIS_HAS_HW_SERIAL(E7)
|
||||
CHECK_AXIS_SERIAL(E7);
|
||||
#endif
|
||||
|
||||
#endif // __STM32F1__
|
||||
|
@ -35,15 +35,22 @@
|
||||
|
||||
class MarlinSerial : public HardwareSerial {
|
||||
public:
|
||||
MarlinSerial(struct usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin) :
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
const bool ep_enabled;
|
||||
EmergencyParser::State emergency_state;
|
||||
inline bool emergency_parser_enabled() { return ep_enabled; }
|
||||
#endif
|
||||
|
||||
MarlinSerial(struct usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin, bool TERN_(EMERGENCY_PARSER, ep_capable)) :
|
||||
HardwareSerial(usart_device, tx_pin, rx_pin)
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
, ep_enabled(ep_capable)
|
||||
, emergency_state(EmergencyParser::State::EP_RESET)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
#ifdef UART_IRQ_PRIO
|
||||
// shadow the parent methods to set irq priority after the begin
|
||||
// Shadow the parent methods to set IRQ priority after begin()
|
||||
void begin(uint32 baud) {
|
||||
MarlinSerial::begin(baud, SERIAL_8N1);
|
||||
}
|
||||
@ -53,14 +60,12 @@ public:
|
||||
nvic_irq_set_priority(c_dev()->irq_num, UART_IRQ_PRIO);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
EmergencyParser::State emergency_state;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern MarlinSerial MSerial1;
|
||||
extern MarlinSerial MSerial2;
|
||||
extern MarlinSerial MSerial3;
|
||||
extern MarlinSerial MSerial4;
|
||||
extern MarlinSerial MSerial5;
|
||||
#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY)
|
||||
extern MarlinSerial MSerial4;
|
||||
extern MarlinSerial MSerial5;
|
||||
#endif
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
EmergencyParser::State emergency_state;
|
||||
inline bool emergency_parser_enabled() { return true; }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user