Fix ESP32 PWM resolution calculation

This commit is contained in:
Theo Arends 2020-08-02 12:40:15 +02:00
parent 6185941b18
commit e1b825ed75
4 changed files with 48 additions and 34 deletions

View File

@ -28,16 +28,23 @@
#include <Esp.h> #include <Esp.h>
/*********************************************************************************************\
* ESP32 analogWrite support
\*********************************************************************************************/
// webcam uses channel 0, so we offset standard PWM #define PWM_SUPPORTED_CHANNELS 8
#define PWM_CHANNEL_OFFSET 2 #define PWM_CHANNEL_OFFSET 2 // Webcam uses channel 0, so we offset standard PWM
// Analog
uint8_t pwm_channel[8]={99,99,99,99,99,99,99,99}; uint8_t _pwm_channel[PWM_SUPPORTED_CHANNELS] = { 99, 99, 99, 99, 99, 99, 99, 99 };
inline uint32_t pin2chan(uint32_t pin) { inline void analogWriteFreq(uint32_t freq) {
for (uint32_t cnt=0;cnt<8;cnt++) { }
if ((pwm_channel[cnt]<99) && (pwm_channel[cnt]==pin)) { inline void analogWriteRange(uint32_t range) {
}
inline uint32_t _analog_pin2chan(uint32_t pin) {
for (uint32_t cnt = 0; cnt < PWM_SUPPORTED_CHANNELS; cnt++) {
if ((_pwm_channel[cnt] < 99) && (_pwm_channel[cnt] == pin)) {
return cnt; return cnt;
} }
} }
@ -46,43 +53,40 @@ inline uint32_t pin2chan(uint32_t pin) {
inline void analogWrite(uint8_t pin, int val) inline void analogWrite(uint8_t pin, int val)
{ {
uint32_t channel=pin2chan(pin); uint32_t channel = _analog_pin2chan(pin);
ledcWrite(channel+PWM_CHANNEL_OFFSET,val); ledcWrite(channel + PWM_CHANNEL_OFFSET, val);
//Serial.printf("write %d - %d\n",channel,val); // Serial.printf("write %d - %d\n",channel,val);
}
inline void analogWriteFreq(uint32_t freq)
{
}
inline void analogWriteRange(uint32_t range)
{
} }
inline void analogAttach(uint32_t pin, uint32_t channel) { inline void analogAttach(uint32_t pin, uint32_t channel) {
pwm_channel[channel&7]=pin; _pwm_channel[channel &7] = pin;
ledcAttachPin(pin,channel+PWM_CHANNEL_OFFSET); ledcAttachPin(pin, channel + PWM_CHANNEL_OFFSET);
//Serial.printf("attach %d - %d\n",channel,pin); // Serial.printf("attach %d - %d\n",channel,pin);
} }
inline uint32_t pow2(uint32_t x) { inline uint32_t _analog_pow2(uint32_t x) {
uint32_t power = 1,bits=0; uint32_t power = 1;
uint32_t bits = 0;
while (power < x) { while (power < x) {
power*=2; power *= 2;
bits++; bits++;
} }
return bits-1; return bits;
} }
// input range is in full range, ledc needs bits // input range is in full range, ledc needs bits
inline void analogWriteFreqRange(uint32_t channel,uint32_t freq, uint32_t irange) { inline void analogWriteFreqRange(uint32_t channel, uint32_t freq, uint32_t irange) {
uint32_t range=pow2(irange); uint32_t range = _analog_pow2(irange);
for (uint32_t cnt=0;cnt<8;cnt++) { for (uint32_t cnt = 0; cnt < PWM_SUPPORTED_CHANNELS; cnt++) {
if (pwm_channel[cnt]<99) { if (_pwm_channel[cnt] < 99) {
ledcSetup(cnt+PWM_CHANNEL_OFFSET,freq,range); ledcSetup(cnt + PWM_CHANNEL_OFFSET, freq, range);
} }
} }
//Serial.printf("freq - range %d - %d\n",freq,range); // Serial.printf("freq - range %d - %d\n",freq,range);
} }
/*********************************************************************************************/
#define INPUT_PULLDOWN_16 INPUT_PULLUP #define INPUT_PULLDOWN_16 INPUT_PULLUP
typedef double real64_t; typedef double real64_t;

View File

@ -1686,12 +1686,12 @@ void GpioInit(void)
for (uint32_t i = 0; i < MAX_PWMS; i++) { // Basic PWM control only for (uint32_t i = 0; i < MAX_PWMS; i++) { // Basic PWM control only
if (PinUsed(GPIO_PWM1, i)) { if (PinUsed(GPIO_PWM1, i)) {
#ifdef ESP8266
pinMode(Pin(GPIO_PWM1, i), OUTPUT); pinMode(Pin(GPIO_PWM1, i), OUTPUT);
#ifdef ESP32 #else // ESP32
analogAttach(Pin(GPIO_PWM1, i),i); analogAttach(Pin(GPIO_PWM1, i), i);
analogWriteFreqRange(i,Settings.pwm_frequency,Settings.pwm_range); analogWriteFreqRange(i, Settings.pwm_frequency, Settings.pwm_range);
#endif #endif
if (light_type) { if (light_type) {
// force PWM GPIOs to low or high mode, see #7165 // force PWM GPIOs to low or high mode, see #7165
analogWrite(Pin(GPIO_PWM1, i), bitRead(pwm_inverted, i) ? Settings.pwm_range : 0); analogWrite(Pin(GPIO_PWM1, i), bitRead(pwm_inverted, i) ? Settings.pwm_range : 0);

View File

@ -1351,7 +1351,12 @@ void LightInit(void)
for (uint32_t i = 0; i < light_type; i++) { for (uint32_t i = 0; i < light_type; i++) {
Settings.pwm_value[i] = 0; // Disable direct PWM control Settings.pwm_value[i] = 0; // Disable direct PWM control
if (PinUsed(GPIO_PWM1, i)) { if (PinUsed(GPIO_PWM1, i)) {
#ifdef ESP8266
pinMode(Pin(GPIO_PWM1, i), OUTPUT); pinMode(Pin(GPIO_PWM1, i), OUTPUT);
#else // ESP32
analogAttach(Pin(GPIO_PWM1, i), i);
analogWriteFreqRange(i, Settings.pwm_frequency, Settings.pwm_range);
#endif
} }
} }
if (PinUsed(GPIO_ARIRFRCV)) { if (PinUsed(GPIO_ARIRFRCV)) {

View File

@ -148,7 +148,12 @@ void Sm16716ModuleSelected(void)
for (uint32_t i = 0; i < Light.subtype; i++) { for (uint32_t i = 0; i < Light.subtype; i++) {
Settings.pwm_value[i] = 0; // Disable direct PWM control Settings.pwm_value[i] = 0; // Disable direct PWM control
if (PinUsed(GPIO_PWM1, i)) { if (PinUsed(GPIO_PWM1, i)) {
#ifdef ESP8266
pinMode(Pin(GPIO_PWM1, i), OUTPUT); pinMode(Pin(GPIO_PWM1, i), OUTPUT);
#else // ESP32
analogAttach(Pin(GPIO_PWM1, i), i);
analogWriteFreqRange(i, Settings.pwm_frequency, Settings.pwm_range);
#endif
} }
} }
*/ */