️ PWM for ESP32 I2S expander (#24193)

This commit is contained in:
John Robertson
2022-06-04 07:26:08 +01:00
committed by Scott Lahteine
parent 7677368aaf
commit c34dd64469
14 changed files with 104 additions and 46 deletions

View File

@@ -65,6 +65,7 @@ portMUX_TYPE MarlinHAL::spinlock = portMUX_INITIALIZER_UNLOCKED;
// ------------------------
uint16_t MarlinHAL::adc_result;
pwm_pin_t MarlinHAL::pwm_pin_data[MAX_EXPANDER_BITS];
// ------------------------
// Private Variables
@@ -330,21 +331,46 @@ int8_t get_pwm_channel(const pin_t pin, const uint32_t freq, const uint16_t res)
}
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=_BV(PWM_RESOLUTION)-1*/, const bool invert/*=false*/) {
const int8_t cid = get_pwm_channel(pin, PWM_FREQUENCY, PWM_RESOLUTION);
if (cid >= 0) {
uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, _BV(PWM_RESOLUTION)-1);
ledcWrite(cid, duty);
}
#if ENABLED(I2S_STEPPER_STREAM)
if (pin > 127) {
const uint8_t pinlo = pin & 0x7F;
pwm_pin_t &pindata = pwm_pin_data[pinlo];
const uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, pindata.pwm_cycle_ticks);
if (duty == 0 || duty == pindata.pwm_cycle_ticks) { // max or min (i.e., on/off)
pindata.pwm_duty_ticks = 0; // turn off PWM for this pin
duty ? SBI32(i2s_port_data, pinlo) : CBI32(i2s_port_data, pinlo); // set pin level
}
else
pindata.pwm_duty_ticks = duty; // PWM duty count = # of 4µs ticks per full PWM cycle
}
else
#endif
{
const int8_t cid = get_pwm_channel(pin, PWM_FREQUENCY, PWM_RESOLUTION);
if (cid >= 0) {
const uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, _BV(PWM_RESOLUTION)-1);
ledcWrite(cid, duty);
}
}
}
int8_t MarlinHAL::set_pwm_frequency(const pin_t pin, const uint32_t f_desired) {
const int8_t cid = channel_for_pin(pin);
if (cid >= 0) {
if (f_desired == ledcReadFreq(cid)) return cid; // no freq change
ledcDetachPin(chan_pin[cid]);
chan_pin[cid] = 0; // remove old freq channel
}
return get_pwm_channel(pin, f_desired, PWM_RESOLUTION); // try for new one
#if ENABLED(I2S_STEPPER_STREAM)
if (pin > 127) {
pwm_pin_data[pin & 0x7F].pwm_cycle_ticks = 1000000UL / f_desired / 4; // # of 4µs ticks per full PWM cycle
return 0;
}
else
#endif
{
const int8_t cid = channel_for_pin(pin);
if (cid >= 0) {
if (f_desired == ledcReadFreq(cid)) return cid; // no freq change
ledcDetachPin(chan_pin[cid]);
chan_pin[cid] = 0; // remove old freq channel
}
return get_pwm_channel(pin, f_desired, PWM_RESOLUTION); // try for new one
}
}
// use hardware PWM if avail, if not then ISR