Skip to content

Commit d2b435b

Browse files
MitchBradleybdring
andauthored
Use local UART driver not HardwareSerial (#857)
* Use local UART driver not HardwareSerial The HardwareSerial driver is broken in Arduino framework versions 1.0.5 and 1.0.6 . espressif/arduino-esp32#5005 Instead of waiting for a fix, I wrote a very simple UART driver that does exactly what we need with no unnecessary bells and whistles to cause problems. * Added missing files, changed method signatures The methods implemented by the UART class now have the same signatures as the HardwareSerial class, so it will be easy to switch back if we need to. * Incorporated suggestions from Stefan * Fixed TX_IDLE_NUM bug reported by mstrens * Quick test for Bf: problem This is not the final solution. * Fixed stupid typo in last commit * Another test - check for client_buffer space * Use the esp-idf uart driver You can revert to the direct driver for testing by defining DIRECT_UART * Uart class now supports VFD and TMC * data bits, stop bits, parity as enum classes The constants for data bits, stop bits, and parity were changed to enum classes so the compiler can check for argument order mismatches. * Set half duplex after uart init * Init TMC UART only once * rx/tx pin order mixup, missing _uart_started * Test: use Arduino Serial This reverts to the Arduino serial driver for UI communication, leaving the VFS comms on the Uart class on top of the esp_idf UART driver. You can switch back and forth with the define REVERT_TO_SERIAL line in Serial.cpp * REVERT_TO_ARDUINO_SERIAL off by default * Added debug messages * Update Grbl.h * Update platformio.ini Co-authored-by: bdring <[email protected]>
1 parent 05438c0 commit d2b435b

23 files changed

+434
-283
lines changed

Diff for: Grbl_Esp32/src/Grbl.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ void grbl_init() {
3030
WiFi.enableSTA(false);
3131
WiFi.enableAP(false);
3232
WiFi.mode(WIFI_OFF);
33-
serial_init(); // Setup serial baud rate and interrupts
33+
client_init(); // Setup serial baud rate and interrupts
3434
display_init();
3535
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Grbl_ESP32 Ver %s Date %s", GRBL_VERSION, GRBL_VERSION_BUILD); // print grbl_esp32 verion info
3636
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Compiled with ESP32 SDK:%s", ESP.getSdkVersion()); // print the SDK version
@@ -40,7 +40,7 @@ void grbl_init() {
4040
#endif
4141
settings_init(); // Load Grbl settings from non-volatile storage
4242
stepper_init(); // Configure stepper pins and interrupt timers
43-
system_ini(); // Configure pinout pins and pin-change interrupt (Renamed due to conflict with esp32 files)
43+
system_ini(); // Configure pinout pins and pin-change interrupt (Renamed due to conflict with esp32 files)
4444
init_motors();
4545
memset(sys_position, 0, sizeof(sys_position)); // Clear machine position.
4646
machine_init(); // weak definition in Grbl.cpp does nothing
@@ -93,8 +93,8 @@ static void reset_variables() {
9393
sys_rt_s_override = SpindleSpeedOverride::Default;
9494

9595
// Reset Grbl primary systems.
96-
serial_reset_read_buffer(CLIENT_ALL); // Clear serial read buffer
97-
gc_init(); // Set g-code parser to default state
96+
client_reset_read_buffer(CLIENT_ALL);
97+
gc_init(); // Set g-code parser to default state
9898
spindle->stop();
9999
coolant_init();
100100
limits_init();

Diff for: Grbl_Esp32/src/Grbl.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
// Grbl versioning system
2424
const char* const GRBL_VERSION = "1.3a";
25-
const char* const GRBL_VERSION_BUILD = "20210401";
25+
const char* const GRBL_VERSION_BUILD = "20210413";
2626

2727
//#include <sdkconfig.h>
2828
#include <Arduino.h>
@@ -51,8 +51,9 @@ const char* const GRBL_VERSION_BUILD = "20210401";
5151
#include "Limits.h"
5252
#include "MotionControl.h"
5353
#include "Protocol.h"
54-
#include "Report.h"
54+
#include "Uart.h"
5555
#include "Serial.h"
56+
#include "Report.h"
5657
#include "Pins.h"
5758
#include "Spindles/Spindle.h"
5859
#include "Motors/Motors.h"

Diff for: Grbl_Esp32/src/I2SOut.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "WebUI/ESPResponse.h"
4949
#include "Probe.h"
5050
#include "System.h"
51+
#include "Serial.h"
5152
#include "Report.h"
5253

5354
#include <FreeRTOS.h>

Diff for: Grbl_Esp32/src/Limits.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,12 @@ void IRAM_ATTR isr_limit_switches() {
5555
# ifdef HARD_LIMIT_FORCE_STATE_CHECK
5656
// Check limit pin state.
5757
if (limits_get_state()) {
58+
grbl_msg_sendf(CLIENT_ALL, MsgLevel::Debug, "Hard limits");
5859
mc_reset(); // Initiate system kill.
5960
sys_rt_exec_alarm = ExecAlarm::HardLimit; // Indicate hard limit critical event
6061
}
6162
# else
63+
grbl_msg_sendf(CLIENT_ALL, MsgLevel::Debug, "Hard limits");
6264
mc_reset(); // Initiate system kill.
6365
sys_rt_exec_alarm = ExecAlarm::HardLimit; // Indicate hard limit critical event
6466
# endif
@@ -195,7 +197,8 @@ void limits_go_home(uint8_t cycle_mask) {
195197

196198
if (sys_rt_exec_alarm != ExecAlarm::None) {
197199
motors_set_homing_mode(cycle_mask, false); // tell motors homing is done...failed
198-
mc_reset(); // Stop motors, if they are running.
200+
grbl_msg_sendf(CLIENT_ALL, MsgLevel::Debug, "Homing fail");
201+
mc_reset(); // Stop motors, if they are running.
199202
protocol_execute_realtime();
200203
return;
201204
} else {
@@ -351,6 +354,7 @@ void limits_soft_check(float* target) {
351354
}
352355
} while (sys.state != State::Idle);
353356
}
357+
grbl_msg_sendf(CLIENT_ALL, MsgLevel::Debug, "Soft limits");
354358
mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown.
355359
sys_rt_exec_alarm = ExecAlarm::SoftLimit; // Indicate soft limit critical event
356360
protocol_execute_realtime(); // Execute to enter critical event loop and system abort
@@ -367,7 +371,7 @@ void limitCheckTask(void* pvParameters) {
367371
AxisMask switch_state;
368372
switch_state = limits_get_state();
369373
if (switch_state) {
370-
//grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Limit Switch State %08d", switch_state);
374+
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Debug, "Limit Switch State %08d", switch_state);
371375
mc_reset(); // Initiate system kill.
372376
sys_rt_exec_alarm = ExecAlarm::HardLimit; // Indicate hard limit critical event
373377
}

Diff for: Grbl_Esp32/src/MotionControl.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ void mc_override_ctrl_update(uint8_t override_state) {
499499
// lost, since there was an abrupt uncontrolled deceleration. Called at an interrupt level by
500500
// realtime abort command and hard limits. So, keep to a minimum.
501501
void mc_reset() {
502+
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Debug, "mc_reset()");
502503
// Only this function can set the system reset. Helps prevent multiple kill calls.
503504
if (!sys_rt_exec_state.bit.reset) {
504505
sys_rt_exec_state.bit.reset = true;

Diff for: Grbl_Esp32/src/Motors/TrinamicUartDriver.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "Motor.h"
2323
#include "StandardStepper.h"
24+
#include "../Uart.h"
2425

2526
#include <TMCStepper.h> // https://github.com/teemuatlut/TMCStepper
2627

@@ -63,7 +64,7 @@ const double TRINAMIC_UART_FCLK = 12700000.0; // Internal clock Approx (Hz) use
6364
# define TMC_UART_TX UNDEFINED_PIN
6465
#endif
6566

66-
extern HardwareSerial tmc_serial;
67+
extern Uart tmc_serial;
6768

6869
namespace Motors {
6970

@@ -75,6 +76,9 @@ namespace Motors {
7576
};
7677

7778
class TrinamicUartDriver : public StandardStepper {
79+
private:
80+
static bool _uart_started;
81+
7882
public:
7983
TrinamicUartDriver(uint8_t axis_index,
8084
uint8_t step_pin,
@@ -128,4 +132,4 @@ namespace Motors {
128132
// void config_message() override;
129133
};
130134

131-
}
135+
}

Diff for: Grbl_Esp32/src/Motors/TrinamicUartDriverClass.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@
2626

2727
#include <TMCStepper.h>
2828

29-
HardwareSerial tmc_serial(TMC_UART);
29+
Uart tmc_serial(TMC_UART);
3030

3131
namespace Motors {
3232

33+
bool TrinamicUartDriver::_uart_started = false;
34+
3335
TrinamicUartDriver* TrinamicUartDriver::List = NULL; // a static ist of all drivers for stallguard reporting
3436

3537
/* HW Serial Constructor. */
@@ -41,9 +43,11 @@ namespace Motors {
4143
_r_sense = r_sense;
4244
this->addr = addr;
4345

44-
uart_set_pin(TMC_UART, TMC_UART_TX, TMC_UART_RX, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
45-
tmc_serial.begin(115200, SERIAL_8N1, TMC_UART_RX, TMC_UART_TX);
46-
tmc_serial.setRxBufferSize(128);
46+
if (!_uart_started) {
47+
tmc_serial.setPins(TMC_UART_TX, TMC_UART_RX);
48+
tmc_serial.begin(115200, Uart::Data::Bits8, Uart::Stop::Bits1, Uart::Parity::None);
49+
_uart_started = true;
50+
}
4751
hw_serial_init();
4852

4953
link = List;
@@ -231,7 +235,7 @@ namespace Motors {
231235
tmcstepper->en_spreadCycle(false);
232236
tmcstepper->pwm_autoscale(false);
233237
tmcstepper->TCOOLTHRS(calc_tstep(homing_feed_rate->get(), 150.0));
234-
tmcstepper->SGTHRS(constrain(axis_settings[_axis_index]->stallguard->get(),0,255));
238+
tmcstepper->SGTHRS(constrain(axis_settings[_axis_index]->stallguard->get(), 0, 255));
235239
break;
236240
default:
237241
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Unknown Trinamic mode:d", _mode);
@@ -394,4 +398,4 @@ namespace Motors {
394398
#endif
395399
}
396400
}
397-
}
401+
}

Diff for: Grbl_Esp32/src/ProcessSettings.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ Error toggle_check_mode(const char* value, WebUI::AuthenticationLevel auth_level
192192
// is idle and ready, regardless of alarm locks. This is mainly to keep things
193193
// simple and consistent.
194194
if (sys.state == State::CheckMode) {
195+
grbl_msg_sendf(CLIENT_ALL, MsgLevel::Debug, "Check mode");
195196
mc_reset();
196197
report_feedback_message(Message::Disabled);
197198
} else {

Diff for: Grbl_Esp32/src/Protocol.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ bool can_park() {
103103
GRBL PRIMARY LOOP:
104104
*/
105105
void protocol_main_loop() {
106-
serial_reset_read_buffer(CLIENT_ALL);
106+
client_reset_read_buffer(CLIENT_ALL);
107107
empty_lines();
108108
//uint8_t client = CLIENT_SERIAL; // default client
109109
// Perform some machine checks to make sure everything is good to go.
@@ -135,7 +135,7 @@ void protocol_main_loop() {
135135
// Primary loop! Upon a system abort, this exits back to main() to reset the system.
136136
// This is also where Grbl idles while waiting for something to do.
137137
// ---------------------------------------------------------------------------------
138-
uint8_t c;
138+
int c;
139139
for (;;) {
140140
#ifdef ENABLE_SD_CARD
141141
if (SD_ready_next) {
@@ -157,7 +157,7 @@ void protocol_main_loop() {
157157
uint8_t client = CLIENT_SERIAL;
158158
char* line;
159159
for (client = 0; client < CLIENT_COUNT; client++) {
160-
while ((c = serial_read(client)) != SERIAL_NO_DATA) {
160+
while ((c = client_read(client)) != -1) {
161161
Error res = add_char_to_line(c, client);
162162
switch (res) {
163163
case Error::Ok:

Diff for: Grbl_Esp32/src/Report.cpp

+2-24
Original file line numberDiff line numberDiff line change
@@ -54,30 +54,8 @@ EspClass esp;
5454
#endif
5555
const int DEFAULTBUFFERSIZE = 64;
5656

57-
// this is a generic send function that everything should use, so interfaces could be added (Bluetooth, etc)
5857
void grbl_send(uint8_t client, const char* text) {
59-
if (client == CLIENT_INPUT) {
60-
return;
61-
}
62-
#ifdef ENABLE_BLUETOOTH
63-
if (WebUI::SerialBT.hasClient() && (client == CLIENT_BT || client == CLIENT_ALL)) {
64-
WebUI::SerialBT.print(text);
65-
//delay(10); // possible fix for dropped characters
66-
}
67-
#endif
68-
#if defined(ENABLE_WIFI) && defined(ENABLE_HTTP) && defined(ENABLE_SERIAL2SOCKET_OUT)
69-
if (client == CLIENT_WEBUI || client == CLIENT_ALL) {
70-
WebUI::Serial2Socket.write((const uint8_t*)text, strlen(text));
71-
}
72-
#endif
73-
#if defined(ENABLE_WIFI) && defined(ENABLE_TELNET)
74-
if (client == CLIENT_TELNET || client == CLIENT_ALL) {
75-
WebUI::telnet_server.write((const uint8_t*)text, strlen(text));
76-
}
77-
#endif
78-
if (client == CLIENT_SERIAL || client == CLIENT_ALL) {
79-
Serial.print(text);
80-
}
58+
client_write(client, text);
8159
}
8260

8361
// This is a formating version of the grbl_send(CLIENT_ALL,...) function that work like printf
@@ -658,7 +636,7 @@ void report_realtime_status(uint8_t client) {
658636
}
659637
# endif //ENABLE_BLUETOOTH
660638
if (client == CLIENT_SERIAL) {
661-
bufsize = serial_get_rx_buffer_available(CLIENT_SERIAL);
639+
bufsize = client_get_rx_buffer_available(CLIENT_SERIAL);
662640
}
663641
sprintf(temp, "|Bf:%d,%d", plan_get_block_buffer_available(), bufsize);
664642
strcat(status, temp);

0 commit comments

Comments
 (0)