mirror of https://github.com/arendst/Tasmota.git
Fix ESP32 PWM range
This commit is contained in:
parent
ff37beac6a
commit
1d990ad091
|
@ -54,3 +54,6 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
### Version 8.4.0.1
|
### Version 8.4.0.1
|
||||||
|
|
||||||
|
- Fix ESP32 PWM range
|
||||||
|
- Add Zigbee better support for IKEA Motion Sensor
|
||||||
|
|
|
@ -29,28 +29,63 @@
|
||||||
#include <Esp.h>
|
#include <Esp.h>
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* ESP32 analogWrite support
|
* ESP32 analogWrite emulation support
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#define PWM_SUPPORTED_CHANNELS 8
|
#define PWM_SUPPORTED_CHANNELS 8
|
||||||
#define PWM_CHANNEL_OFFSET 2 // Webcam uses channel 0, so we offset standard PWM
|
#define PWM_CHANNEL_OFFSET 2 // Webcam uses channel 0, so we offset standard PWM
|
||||||
|
|
||||||
uint8_t _pwm_channel[PWM_SUPPORTED_CHANNELS] = { 99, 99, 99, 99, 99, 99, 99, 99 };
|
uint8_t _pwm_channel[PWM_SUPPORTED_CHANNELS] = { 99, 99, 99, 99, 99, 99, 99, 99 };
|
||||||
|
uint32_t _pwm_frequency = 977; // Default 977Hz
|
||||||
inline void analogWriteFreq(uint32_t freq) {
|
uint8_t _pwm_bit_num = 10; // Default 1023
|
||||||
}
|
|
||||||
inline void analogWriteRange(uint32_t range) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32_t _analog_pin2chan(uint32_t pin) {
|
inline uint32_t _analog_pin2chan(uint32_t pin) {
|
||||||
for (uint32_t cnt = 0; cnt < PWM_SUPPORTED_CHANNELS; cnt++) {
|
for (uint32_t channel = 0; channel < PWM_SUPPORTED_CHANNELS; channel++) {
|
||||||
if ((_pwm_channel[cnt] < 99) && (_pwm_channel[cnt] == pin)) {
|
if ((_pwm_channel[channel] < 99) && (_pwm_channel[channel] == pin)) {
|
||||||
return cnt;
|
return channel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void _analogWriteFreqRange(void) {
|
||||||
|
for (uint32_t channel = 0; channel < PWM_SUPPORTED_CHANNELS; channel++) {
|
||||||
|
if (_pwm_channel[channel] < 99) {
|
||||||
|
// uint32_t duty = ledcRead(channel + PWM_CHANNEL_OFFSET);
|
||||||
|
ledcSetup(channel + PWM_CHANNEL_OFFSET, _pwm_frequency, _pwm_bit_num);
|
||||||
|
// ledcWrite(channel + PWM_CHANNEL_OFFSET, duty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Serial.printf("freq - range %d - %d\n",freq,range);
|
||||||
|
}
|
||||||
|
|
||||||
|
// input range is in full range, ledc needs bits
|
||||||
|
inline uint32_t _analogGetResolution(uint32_t x) {
|
||||||
|
uint32_t bits = 0;
|
||||||
|
while (x) {
|
||||||
|
bits++;
|
||||||
|
x >>= 1;
|
||||||
|
}
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void analogWriteRange(uint32_t range) {
|
||||||
|
_pwm_bit_num = _analogGetResolution(range);
|
||||||
|
_analogWriteFreqRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void analogWriteFreq(uint32_t freq) {
|
||||||
|
_pwm_frequency = freq;
|
||||||
|
_analogWriteFreqRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void analogAttach(uint32_t pin, uint32_t channel) {
|
||||||
|
_pwm_channel[channel &7] = pin;
|
||||||
|
ledcAttachPin(pin, channel + PWM_CHANNEL_OFFSET);
|
||||||
|
ledcSetup(channel + PWM_CHANNEL_OFFSET, _pwm_frequency, _pwm_bit_num);
|
||||||
|
// Serial.printf("attach %d - %d\n", channel, pin);
|
||||||
|
}
|
||||||
|
|
||||||
inline void analogWrite(uint8_t pin, int val)
|
inline void analogWrite(uint8_t pin, int val)
|
||||||
{
|
{
|
||||||
uint32_t channel = _analog_pin2chan(pin);
|
uint32_t channel = _analog_pin2chan(pin);
|
||||||
|
@ -58,33 +93,6 @@ inline void analogWrite(uint8_t pin, int val)
|
||||||
// Serial.printf("write %d - %d\n",channel,val);
|
// Serial.printf("write %d - %d\n",channel,val);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void analogAttach(uint32_t pin, uint32_t channel) {
|
|
||||||
_pwm_channel[channel &7] = pin;
|
|
||||||
ledcAttachPin(pin, channel + PWM_CHANNEL_OFFSET);
|
|
||||||
// Serial.printf("attach %d - %d\n",channel,pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32_t _analog_pow2(uint32_t x) {
|
|
||||||
uint32_t power = 1;
|
|
||||||
uint32_t bits = 0;
|
|
||||||
while (power < x) {
|
|
||||||
power *= 2;
|
|
||||||
bits++;
|
|
||||||
}
|
|
||||||
return bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
// input range is in full range, ledc needs bits
|
|
||||||
inline void analogWriteFreqRange(uint32_t channel, uint32_t freq, uint32_t irange) {
|
|
||||||
uint32_t range = _analog_pow2(irange);
|
|
||||||
for (uint32_t cnt = 0; cnt < PWM_SUPPORTED_CHANNELS; cnt++) {
|
|
||||||
if (_pwm_channel[cnt] < 99) {
|
|
||||||
ledcSetup(cnt + PWM_CHANNEL_OFFSET, freq, range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Serial.printf("freq - range %d - %d\n",freq,range);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
#define INPUT_PULLDOWN_16 INPUT_PULLUP
|
#define INPUT_PULLDOWN_16 INPUT_PULLUP
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
### 8.4.0.1 20200730
|
### 8.4.0.1 20200730
|
||||||
|
|
||||||
|
- Fix ESP32 PWM range
|
||||||
- Add Zigbee better support for IKEA Motion Sensor
|
- Add Zigbee better support for IKEA Motion Sensor
|
||||||
|
|
||||||
### 8.4.0 20200730
|
### 8.4.0 20200730
|
||||||
|
|
|
@ -1236,29 +1236,31 @@ void CmndPwmfrequency(void)
|
||||||
{
|
{
|
||||||
if ((1 == XdrvMailbox.payload) || ((XdrvMailbox.payload >= PWM_MIN) && (XdrvMailbox.payload <= PWM_MAX))) {
|
if ((1 == XdrvMailbox.payload) || ((XdrvMailbox.payload >= PWM_MIN) && (XdrvMailbox.payload <= PWM_MAX))) {
|
||||||
Settings.pwm_frequency = (1 == XdrvMailbox.payload) ? PWM_FREQ : XdrvMailbox.payload;
|
Settings.pwm_frequency = (1 == XdrvMailbox.payload) ? PWM_FREQ : XdrvMailbox.payload;
|
||||||
#ifdef ESP8266
|
|
||||||
analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
|
analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
|
||||||
#else
|
|
||||||
analogWriteFreqRange(0,Settings.pwm_frequency,Settings.pwm_range);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
ResponseCmndNumber(Settings.pwm_frequency);
|
ResponseCmndNumber(Settings.pwm_frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndPwmrange(void)
|
void CmndPwmrange(void) {
|
||||||
{
|
// Support only 8 (=255), 9 (=511) and 10 (=1023) bits resolution
|
||||||
if ((1 == XdrvMailbox.payload) || ((XdrvMailbox.payload > 254) && (XdrvMailbox.payload < 1024))) {
|
if ((1 == XdrvMailbox.payload) || ((XdrvMailbox.payload > 254) && (XdrvMailbox.payload < 1024))) {
|
||||||
Settings.pwm_range = (1 == XdrvMailbox.payload) ? PWM_RANGE : XdrvMailbox.payload;
|
uint32_t pwm_range = XdrvMailbox.payload;
|
||||||
|
uint32_t pwm_resolution = 0;
|
||||||
|
while (pwm_range) {
|
||||||
|
pwm_resolution++;
|
||||||
|
pwm_range >>= 1;
|
||||||
|
}
|
||||||
|
pwm_range = (1 << pwm_resolution) - 1;
|
||||||
|
uint32_t old_pwm_range = Settings.pwm_range;
|
||||||
|
Settings.pwm_range = (1 == XdrvMailbox.payload) ? PWM_RANGE : pwm_range;
|
||||||
for (uint32_t i = 0; i < MAX_PWMS; i++) {
|
for (uint32_t i = 0; i < MAX_PWMS; i++) {
|
||||||
if (Settings.pwm_value[i] > Settings.pwm_range) {
|
if (Settings.pwm_value[i] > Settings.pwm_range) {
|
||||||
Settings.pwm_value[i] = Settings.pwm_range;
|
Settings.pwm_value[i] = Settings.pwm_range;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef ESP8266
|
if (Settings.pwm_range != old_pwm_range) { // On ESP32 this prevents loss of duty state
|
||||||
analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h)
|
analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h)
|
||||||
#else
|
}
|
||||||
analogWriteFreqRange(0,Settings.pwm_frequency,Settings.pwm_range);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
ResponseCmndNumber(Settings.pwm_range);
|
ResponseCmndNumber(Settings.pwm_range);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1564,12 +1564,12 @@ void GpioInit(void)
|
||||||
|
|
||||||
// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)gpio_pin, ARRAY_SIZE(gpio_pin), sizeof(gpio_pin[0]));
|
// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)gpio_pin, ARRAY_SIZE(gpio_pin), sizeof(gpio_pin[0]));
|
||||||
|
|
||||||
#ifdef ESP8266
|
|
||||||
if ((2 == Pin(GPIO_TXD)) || (H801 == my_module_type)) { Serial.set_tx(2); }
|
|
||||||
|
|
||||||
analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h)
|
analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h)
|
||||||
analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
|
analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
|
if ((2 == Pin(GPIO_TXD)) || (H801 == my_module_type)) { Serial.set_tx(2); }
|
||||||
|
|
||||||
#ifdef USE_SPI
|
#ifdef USE_SPI
|
||||||
spi_flg = (((PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_CS) > 14)) || (Pin(GPIO_SPI_CS) < 12)) || ((PinUsed(GPIO_SPI_DC) && (Pin(GPIO_SPI_DC) > 14)) || (Pin(GPIO_SPI_DC) < 12)));
|
spi_flg = (((PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_CS) > 14)) || (Pin(GPIO_SPI_CS) < 12)) || ((PinUsed(GPIO_SPI_DC) && (Pin(GPIO_SPI_DC) > 14)) || (Pin(GPIO_SPI_DC) < 12)));
|
||||||
if (spi_flg) {
|
if (spi_flg) {
|
||||||
|
@ -1584,8 +1584,6 @@ void GpioInit(void)
|
||||||
soft_spi_flg = (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO)));
|
soft_spi_flg = (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO)));
|
||||||
#endif // USE_SPI
|
#endif // USE_SPI
|
||||||
#else // ESP32
|
#else // ESP32
|
||||||
analogWriteFreqRange(0, Settings.pwm_frequency, Settings.pwm_range);
|
|
||||||
|
|
||||||
#ifdef USE_SPI
|
#ifdef USE_SPI
|
||||||
if (PinUsed(GPIO_SPI_CS) || PinUsed(GPIO_SPI_DC)) {
|
if (PinUsed(GPIO_SPI_CS) || PinUsed(GPIO_SPI_DC)) {
|
||||||
if ((15 == Pin(GPIO_SPI_CS)) && (!GetPin(12) && !GetPin(13) && !GetPin(14))) { // HSPI
|
if ((15 == Pin(GPIO_SPI_CS)) && (!GetPin(12) && !GetPin(13) && !GetPin(14))) { // HSPI
|
||||||
|
@ -1690,7 +1688,6 @@ void GpioInit(void)
|
||||||
pinMode(Pin(GPIO_PWM1, i), OUTPUT);
|
pinMode(Pin(GPIO_PWM1, i), OUTPUT);
|
||||||
#else // ESP32
|
#else // ESP32
|
||||||
analogAttach(Pin(GPIO_PWM1, i), i);
|
analogAttach(Pin(GPIO_PWM1, i), i);
|
||||||
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
|
||||||
|
|
|
@ -1355,7 +1355,6 @@ void LightInit(void)
|
||||||
pinMode(Pin(GPIO_PWM1, i), OUTPUT);
|
pinMode(Pin(GPIO_PWM1, i), OUTPUT);
|
||||||
#else // ESP32
|
#else // ESP32
|
||||||
analogAttach(Pin(GPIO_PWM1, i), i);
|
analogAttach(Pin(GPIO_PWM1, i), i);
|
||||||
analogWriteFreqRange(i, Settings.pwm_frequency, Settings.pwm_range);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,6 @@ void Sm16716ModuleSelected(void)
|
||||||
pinMode(Pin(GPIO_PWM1, i), OUTPUT);
|
pinMode(Pin(GPIO_PWM1, i), OUTPUT);
|
||||||
#else // ESP32
|
#else // ESP32
|
||||||
analogAttach(Pin(GPIO_PWM1, i), i);
|
analogAttach(Pin(GPIO_PWM1, i), i);
|
||||||
analogWriteFreqRange(i, Settings.pwm_frequency, Settings.pwm_range);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue