diff --git a/Grbl_Esp32/src/GCode.cpp b/Grbl_Esp32/src/GCode.cpp index b1a7a079..94ea3237 100644 --- a/Grbl_Esp32/src/GCode.cpp +++ b/Grbl_Esp32/src/GCode.cpp @@ -1401,10 +1401,11 @@ Error gc_execute_line(char* line, uint8_t client) { if ((gc_block.modal.io_control == IoControl::DigitalOnSync) || (gc_block.modal.io_control == IoControl::DigitalOffSync) || (gc_block.modal.io_control == IoControl::DigitalOnImmediate) || (gc_block.modal.io_control == IoControl::DigitalOffImmediate)) { if (gc_block.values.p < MaxUserDigitalPin) { - if (!sys_io_control( - bit((int)gc_block.values.p), - (gc_block.modal.io_control == IoControl::DigitalOnSync) || (gc_block.modal.io_control == IoControl::DigitalOnImmediate), - (gc_block.modal.io_control == IoControl::DigitalOnSync) || (gc_block.modal.io_control == IoControl::DigitalOffSync))) { + if ((gc_block.modal.io_control == IoControl::DigitalOnSync) || (gc_block.modal.io_control == IoControl::DigitalOffSync)) { + protocol_buffer_synchronize(); + } + bool turnOn = gc_block.modal.io_control == IoControl::DigitalOnSync || gc_block.modal.io_control == IoControl::DigitalOnImmediate; + if (!sys_set_digital((int)gc_block.values.p, turnOn)) { FAIL(Error::PParamMaxExceeded); } } else { @@ -1414,8 +1415,12 @@ Error gc_execute_line(char* line, uint8_t client) { if ((gc_block.modal.io_control == IoControl::SetAnalogSync) || (gc_block.modal.io_control == IoControl::SetAnalogImmediate)) { if (gc_block.values.e < MaxUserDigitalPin) { gc_block.values.q = constrain(gc_block.values.q, 0.0, 100.0); // force into valid range - if (!sys_pwm_control(bit((int)gc_block.values.e), gc_block.values.q, (gc_block.modal.io_control == IoControl::SetAnalogSync))) + if (gc_block.modal.io_control == IoControl::SetAnalogSync) { + protocol_buffer_synchronize(); + } + if (!sys_set_analog((int)gc_block.values.e, gc_block.values.q)) { FAIL(Error::PParamMaxExceeded); + } } else { FAIL(Error::PParamMaxExceeded); } diff --git a/Grbl_Esp32/src/Grbl.h b/Grbl_Esp32/src/Grbl.h index 4cccc59a..44418bed 100644 --- a/Grbl_Esp32/src/Grbl.h +++ b/Grbl_Esp32/src/Grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system const char* const GRBL_VERSION = "1.3a"; -const char* const GRBL_VERSION_BUILD = "20201230"; +const char* const GRBL_VERSION_BUILD = "20210101"; //#include #include diff --git a/Grbl_Esp32/src/MotionControl.cpp b/Grbl_Esp32/src/MotionControl.cpp index 56be3e83..954009a1 100644 --- a/Grbl_Esp32/src/MotionControl.cpp +++ b/Grbl_Esp32/src/MotionControl.cpp @@ -505,8 +505,8 @@ void mc_reset() { coolant_stop(); // turn off all User I/O immediately - sys_io_control(0xFF, LOW, false); - sys_pwm_control(0xFF, 0, false); + sys_digital_all_off(); + sys_analog_all_off(); #ifdef ENABLE_SD_CARD // do we need to stop a running SD job? if (get_sd_state(false) == SDState::BusyPrinting) { diff --git a/Grbl_Esp32/src/System.cpp b/Grbl_Esp32/src/System.cpp index 6b21702c..857ab4e3 100644 --- a/Grbl_Esp32/src/System.cpp +++ b/Grbl_Esp32/src/System.cpp @@ -267,36 +267,29 @@ void system_exec_control_pin(ControlPins pins) { } } -// io_num is the virtual pin# and has nothing to do with the actual esp32 GPIO_NUM_xx -// It uses a mask so all can be turned of in ms_reset -bool sys_io_control(uint8_t io_num_mask, bool turnOn, bool synchronized) { - bool cmd_ok = true; - if (synchronized) - protocol_buffer_synchronize(); - +void sys_digital_all_off() { for (uint8_t io_num = 0; io_num < MaxUserDigitalPin; io_num++) { - if (io_num_mask & bit(io_num)) { - if (!myDigitalOutputs[io_num]->set_level(turnOn)) - cmd_ok = false; - } + myDigitalOutputs[io_num]->set_level(LOW); } - return cmd_ok; } -// io_num is the virtual pin# and has nothing to do with the actual esp32 GPIO_NUM_xx -// It uses a mask so all can be turned of in ms_reset -bool sys_pwm_control(uint8_t io_num_mask, float duty, bool synchronized) { - bool cmd_ok = true; - if (synchronized) - protocol_buffer_synchronize(); +// io_num is the virtual digital pin# +bool sys_set_digital(uint8_t io_num, bool turnOn) { + return myDigitalOutputs[io_num]->set_level(turnOn); +} +// Turn off all analog outputs +void sys_analog_all_off() { for (uint8_t io_num = 0; io_num < MaxUserDigitalPin; io_num++) { - if (io_num_mask & bit(io_num)) { - if (!myAnalogOutputs[io_num]->set_level(duty)) - cmd_ok = false; - } + myAnalogOutputs[io_num]->set_level(0); } - return cmd_ok; +} + +// io_num is the virtual analog pin# +bool sys_set_analog(uint8_t io_num, float percent) { + auto analog = myAnalogOutputs[io_num]; + uint32_t numerator = percent / 100.0 * analog->denominator(); + return analog->set_level(numerator); } /* diff --git a/Grbl_Esp32/src/System.h b/Grbl_Esp32/src/System.h index 6803f7e2..d955f01e 100644 --- a/Grbl_Esp32/src/System.h +++ b/Grbl_Esp32/src/System.h @@ -170,8 +170,9 @@ void system_convert_array_steps_to_mpos(float* position, int32_t* steps); void controlCheckTask(void* pvParameters); void system_exec_control_pin(ControlPins pins); -bool sys_io_control(uint8_t io_num_mask, bool turnOn, bool synchronized); -bool sys_pwm_control(uint8_t io_num_mask, float duty, bool synchronized); +bool sys_set_digital(uint8_t io_num, bool turnOn); +void sys_digital_all_off(); +bool sys_set_analog(uint8_t io_num, float percent); +void sys_analog_all_off(); -int8_t sys_get_next_PWM_chan_num(); -uint8_t sys_calc_pwm_precision(uint32_t freq); +int8_t sys_get_next_PWM_chan_num(); diff --git a/Grbl_Esp32/src/UserOutput.cpp b/Grbl_Esp32/src/UserOutput.cpp index 6a1f9ce0..05b856dd 100644 --- a/Grbl_Esp32/src/UserOutput.cpp +++ b/Grbl_Esp32/src/UserOutput.cpp @@ -64,8 +64,17 @@ namespace UserOutput { if (pin == UNDEFINED_PIN) return; - // determine the highest bit precision allowed by frequency - _resolution_bits = sys_calc_pwm_precision(_pwm_frequency); + // determine the highest resolution (number of precision bits) allowed by frequency + + uint32_t apb_frequency = getApbFrequency(); + + // increase the precision (bits) until it exceeds allow by frequency the max or is 16 + _resolution_bits = 0; + while ((1 << _resolution_bits) < (apb_frequency / _pwm_frequency) && _resolution_bits <= 16) { + ++_resolution_bits; + } + // _resolution_bits is now just barely too high, so drop it down one + --_resolution_bits; init(); } @@ -89,9 +98,7 @@ namespace UserOutput { } // returns true if able to set value - bool AnalogOutput::set_level(float percent) { - float duty; - + bool AnalogOutput::set_level(uint32_t numerator) { // look for errors, but ignore if turning off to prevent mask turn off from generating errors if (_pin == UNDEFINED_PIN) { return false; @@ -102,15 +109,14 @@ namespace UserOutput { return false; } - if (_current_value == percent) + if (_current_value == numerator) { return true; + } - _current_value = percent; + _current_value = numerator; - duty = (percent / 100.0) * (1 << _resolution_bits); - - ledcWrite(_pwm_channel, duty); + ledcWrite(_pwm_channel, numerator); return true; } -} \ No newline at end of file +} diff --git a/Grbl_Esp32/src/UserOutput.h b/Grbl_Esp32/src/UserOutput.h index 10a7ea30..ca0d6e2c 100644 --- a/Grbl_Esp32/src/UserOutput.h +++ b/Grbl_Esp32/src/UserOutput.h @@ -41,17 +41,18 @@ namespace UserOutput { public: AnalogOutput(); AnalogOutput(uint8_t number, uint8_t pin, float pwm_frequency); - bool set_level(float percent); + bool set_level(uint32_t numerator); + uint32_t denominator() { return 1UL << _resolution_bits; }; protected: void init(); void config_message(); - uint8_t _number = UNDEFINED_PIN; - uint8_t _pin = UNDEFINED_PIN; - uint8_t _pwm_channel = -1; // -1 means invalid or not setup - float _pwm_frequency; - uint8_t _resolution_bits; - float _current_value; + uint8_t _number = UNDEFINED_PIN; + uint8_t _pin = UNDEFINED_PIN; + uint8_t _pwm_channel = -1; // -1 means invalid or not setup + float _pwm_frequency; + uint8_t _resolution_bits; + uint32_t _current_value; }; -} \ No newline at end of file +}