|
|
@ -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
|
|
|
|