More updates to PWM to ensure S2 and C3 compatibility
New IDF parameter in 2.0.0 for LEDC allows PWM signal to be inverted! Need to ensure flags.output_inverted is set to 0! Also: Deleted old PWM class, which was saved for backwards compatibility. This "breaks" HomeSpan for those using the old PWM class (instead of LedPin). Also: Added checks to ensure that frequency is achievable (for S2 and C3, the 14-bit duty resolution is insufficient to allow frequencies slower than 5 Hz - this is not a practical limit when using LedPin to drive actual LEDs and lights).
This commit is contained in:
parent
7255a9530f
commit
0ccb1d34a0
Binary file not shown.
|
|
@ -19,15 +19,16 @@ LedC::LedC(uint8_t pin, uint16_t freq){
|
|||
timerList[nTimer][nMode]->timer_num=(ledc_timer_t)nTimer;
|
||||
timerList[nTimer][nMode]->freq_hz=freq;
|
||||
timerList[nTimer][nMode]->clk_cfg=LEDC_USE_APB_CLK;
|
||||
|
||||
|
||||
int res=LEDC_TIMER_BIT_MAX-1; // find the maximum possible resolution
|
||||
while(getApbFrequency()/(freq*pow(2,res))<1)
|
||||
res--;
|
||||
|
||||
Serial.println(getApbFrequency()/(freq*pow(2,res)));
|
||||
|
||||
timerList[nTimer][nMode]->duty_resolution=(ledc_timer_bit_t)res;
|
||||
ledc_timer_config(timerList[nTimer][nMode]);
|
||||
if(ledc_timer_config(timerList[nTimer][nMode])!=0){
|
||||
Serial.printf("\n*** ERROR: Frequency=%d Hz is out of allowed range ---",freq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(timerList[nTimer][nMode]->freq_hz==freq){ // if timer matches desired frequency (always true if newly-created above)
|
||||
|
|
@ -36,6 +37,7 @@ LedC::LedC(uint8_t pin, uint16_t freq){
|
|||
channelList[nChannel][nMode]->channel=(ledc_channel_t)nChannel;
|
||||
channelList[nChannel][nMode]->timer_sel=(ledc_timer_t)nTimer;
|
||||
channelList[nChannel][nMode]->intr_type=LEDC_INTR_DISABLE;
|
||||
channelList[nChannel][nMode]->flags.output_invert=0;
|
||||
channelList[nChannel][nMode]->hpoint=0;
|
||||
channelList[nChannel][nMode]->gpio_num=pin;
|
||||
timer=timerList[nTimer][nMode];
|
||||
|
|
@ -77,9 +79,9 @@ void LedPin::set(float level){
|
|||
|
||||
if(level>100)
|
||||
level=100;
|
||||
|
||||
channel->duty=level*(pow(2,(int)timer->duty_resolution)-1);
|
||||
channel->duty/=100;
|
||||
|
||||
float d=level*(pow(2,(int)timer->duty_resolution)-1)/100.0;
|
||||
channel->duty=d;
|
||||
ledc_channel_config(channel);
|
||||
|
||||
}
|
||||
|
|
@ -190,102 +192,3 @@ void ServoPin::set(double degrees){
|
|||
|
||||
ledc_channel_config_t *LedC::channelList[LEDC_CHANNEL_MAX][LEDC_SPEED_MODE_MAX]={};
|
||||
ledc_timer_config_t *LedC::timerList[LEDC_TIMER_MAX][LEDC_SPEED_MODE_MAX]={};
|
||||
|
||||
////////////////////////////
|
||||
|
||||
//*****************************************************************
|
||||
// DEPRECATED - INCLUDED FOR BACKWARDS COMPATIBILITY FOR ESP32 ONLY
|
||||
//*****************************************************************
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
PwmPin::PwmPin(uint8_t channel, uint8_t pin){
|
||||
this->channel=channel & 0x0F;
|
||||
this->pin=pin;
|
||||
|
||||
ledc_timer_config_t ledTimer;
|
||||
ledTimer.timer_num=LEDC_TIMER_0;
|
||||
ledTimer.speed_mode=(this->channel)<8?LEDC_HIGH_SPEED_MODE:LEDC_LOW_SPEED_MODE;
|
||||
ledTimer.duty_resolution=LEDC_TIMER_10_BIT;
|
||||
ledTimer.freq_hz=5000;
|
||||
ledc_timer_config(&ledTimer);
|
||||
|
||||
ledChannel.gpio_num=pin;
|
||||
ledChannel.speed_mode=(this->channel)<8?LEDC_HIGH_SPEED_MODE:LEDC_LOW_SPEED_MODE;
|
||||
ledChannel.channel=(ledc_channel_t)(this->channel&0x07);
|
||||
ledChannel.intr_type=LEDC_INTR_DISABLE;
|
||||
ledChannel.timer_sel=LEDC_TIMER_0;
|
||||
ledChannel.duty=0;
|
||||
ledChannel.hpoint=0;
|
||||
ledc_channel_config(&ledChannel);
|
||||
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
void PwmPin::set(uint8_t channel, uint8_t level){
|
||||
ledChannel.duty=level*1023;
|
||||
ledChannel.duty/=100;
|
||||
ledChannel.duty&=0x03FF;
|
||||
ledc_channel_config(&ledChannel);
|
||||
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
void PwmPin::HSVtoRGB(float h, float s, float v, float *r, float *g, float *b ){
|
||||
|
||||
// The algorithm below was provided on the web at https://www.cs.rit.edu/~ncs/color/t_convert.html
|
||||
// h = [0,360]
|
||||
// s = [0,1]
|
||||
// v = [0,1]
|
||||
|
||||
int i;
|
||||
float f, p, q, t;
|
||||
|
||||
if( s == 0 ){
|
||||
*r = *g = *b = v;
|
||||
return;
|
||||
}
|
||||
|
||||
h /= 60;
|
||||
i = floor( h ) ;
|
||||
f = h - i;
|
||||
p = v * ( 1 - s );
|
||||
q = v * ( 1 - s * f );
|
||||
t = v * ( 1 - s * ( 1 - f ) );
|
||||
switch( i % 6 ) {
|
||||
case 0:
|
||||
*r = v;
|
||||
*g = t;
|
||||
*b = p;
|
||||
break;
|
||||
case 1:
|
||||
*r = q;
|
||||
*g = v;
|
||||
*b = p;
|
||||
break;
|
||||
case 2:
|
||||
*r = p;
|
||||
*g = v;
|
||||
*b = t;
|
||||
break;
|
||||
case 3:
|
||||
*r = p;
|
||||
*g = q;
|
||||
*b = v;
|
||||
break;
|
||||
case 4:
|
||||
*r = t;
|
||||
*g = p;
|
||||
*b = v;
|
||||
break;
|
||||
case 5:
|
||||
*r = v;
|
||||
*g = p;
|
||||
*b = q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -65,20 +65,3 @@ class ServoPin : public LedC {
|
|||
|
||||
void set(double degrees); // sets the Servo to degrees, where degrees is bounded by [minDegrees,maxDegrees]
|
||||
};
|
||||
|
||||
//*******************************************************
|
||||
// DEPRECATED - INCLUDED FOR BACKWARDS COMPATIBILITY ONLY
|
||||
//*******************************************************
|
||||
|
||||
class PwmPin {
|
||||
uint8_t channel;
|
||||
uint8_t pin;
|
||||
ledc_channel_config_t ledChannel;
|
||||
|
||||
public:
|
||||
PwmPin(uint8_t channel, uint8_t pin); // assigns pin to be output of one of 16 PWM channels (0-15)
|
||||
void set(uint8_t channel, uint8_t level); // sets the PWM duty to level (0-100)
|
||||
int getPin(){return pin;} // returns the pin number
|
||||
|
||||
static void HSVtoRGB(float h, float s, float v, float *r, float *g, float *b ); // converts Hue/Saturation/Brightness to R/G/B
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "PwmPin.h"
|
||||
#include <soc/ledc_reg.h>
|
||||
#include "esp_rom_gpio.h"
|
||||
|
||||
void setup(){
|
||||
|
||||
|
|
@ -14,49 +15,78 @@ void setup(){
|
|||
|
||||
Serial.println("Starting...");
|
||||
|
||||
LedPin led12(12,99,500);
|
||||
LedPin led5(5,20,20000);
|
||||
LedPin led6(6,20,5000);
|
||||
// LedPin led3(17,50,1);
|
||||
// LedPin led2(16,10,8000);
|
||||
// LedPin led4(23,100,2);
|
||||
// LedPin led5(22,0,3000);
|
||||
// LedPin led6(14,0,1);
|
||||
// LedPin led7(32,0,1850);
|
||||
// LedPin led8(15);
|
||||
// LedPin led9(33);
|
||||
// LedPin led10(27);
|
||||
// ServoPin led14(25);
|
||||
// LedPin led11(12,100,23);
|
||||
// LedPin led12(13,100);
|
||||
// LedPin led13(26);
|
||||
// LedPin led15(4,0);
|
||||
LedPin *led[20];
|
||||
|
||||
Serial.printf("HELLO\n");
|
||||
// int p[]={33,27,4,32,18,19,16,17,5};
|
||||
int p[]={11,7,3,1,38,33,9};
|
||||
|
||||
// led16.set(20);
|
||||
// led0.set(5);
|
||||
// led14.set(100);
|
||||
|
||||
// Serial.println(led0.getPin());
|
||||
// Serial.println(led14.getPin());
|
||||
// Serial.println(led15.getPin());
|
||||
// Serial.println(led16.getPin());
|
||||
|
||||
Serial.printf("RES0: %d\n",REG_GET_FIELD(LEDC_LSTIMER0_CONF_REG,LEDC_LSTIMER0_DUTY_RES));
|
||||
Serial.printf("RES1: %d\n",REG_GET_FIELD(LEDC_LSTIMER1_CONF_REG,LEDC_LSTIMER1_DUTY_RES));
|
||||
Serial.printf("RES2: %d\n",REG_GET_FIELD(LEDC_LSTIMER2_CONF_REG,LEDC_LSTIMER2_DUTY_RES));
|
||||
Serial.printf("DIV0: %d\n",REG_GET_FIELD(LEDC_LSTIMER0_CONF_REG,LEDC_CLK_DIV_LSTIMER0)>>8);
|
||||
Serial.printf("DIV1: %d\n",REG_GET_FIELD(LEDC_LSTIMER1_CONF_REG,LEDC_CLK_DIV_LSTIMER1)>>8);
|
||||
Serial.printf("DIV2: %d\n",REG_GET_FIELD(LEDC_LSTIMER2_CONF_REG,LEDC_CLK_DIV_LSTIMER2)>>8);
|
||||
|
||||
// uint32_t v=REG_READ(LEDC_HSTIMER0_CONF_REG);
|
||||
// Serial.printf("HS %d %d %d %d\n",(v>>25)&1,v&0x1f,(v>>13)&0x3FF,(v>>5)&0xFF);
|
||||
|
||||
// v=REG_READ(LEDC_LSTIMER0_CONF_REG);
|
||||
// Serial.printf("LS %d %d %d %d %d\n",(v>>25)&1,v&0x1f,(v>>13)&0x3FF,(v>>5)&0xFF,REG_READ(LEDC_CONF_REG));
|
||||
for(int i=0;i<sizeof(p)/4;i++)
|
||||
led[i]=new LedPin(p[i],20,5000+i);
|
||||
|
||||
new LedPin(10,200,65535);
|
||||
new LedPin(5,200,65535);
|
||||
|
||||
//Serial.printf("HSTIMER0: %d %d %d %d\n",
|
||||
// REG_GET_FIELD(LEDC_HSTIMER0_CONF_REG,LEDC_TICK_SEL_HSTIMER0),
|
||||
// REG_GET_FIELD(LEDC_HSTIMER0_CONF_REG,LEDC_DIV_NUM_HSTIMER0)>>8,
|
||||
// REG_GET_FIELD(LEDC_HSTIMER0_CONF_REG,LEDC_DIV_NUM_HSTIMER0)&0xFF,
|
||||
// REG_GET_FIELD(LEDC_HSTIMER0_CONF_REG,LEDC_HSTIMER0_DUTY_RES)
|
||||
// );
|
||||
//
|
||||
//Serial.printf("HSCHAN0: %d %d %d %d %d\n",
|
||||
// REG_READ(LEDC_HSCH0_CONF0_REG),
|
||||
// REG_READ(LEDC_HSCH0_HPOINT_REG),
|
||||
// REG_READ(LEDC_HSCH0_DUTY_REG)>>4,
|
||||
// REG_READ(LEDC_HSCH0_DUTY_REG)&0xF,
|
||||
// REG_GET_FIELD(LEDC_HSCH0_CONF1_REG,LEDC_DUTY_INC_HSCH0)
|
||||
// );
|
||||
//
|
||||
//Serial.printf("LSTIMER0: %d %d %d %d\n",
|
||||
// REG_GET_FIELD(LEDC_LSTIMER0_CONF_REG,LEDC_TICK_SEL_LSTIMER0),
|
||||
// REG_GET_FIELD(LEDC_LSTIMER0_CONF_REG,LEDC_DIV_NUM_LSTIMER0)>>8,
|
||||
// REG_GET_FIELD(LEDC_LSTIMER0_CONF_REG,LEDC_DIV_NUM_LSTIMER0)&0xFF,
|
||||
// REG_GET_FIELD(LEDC_LSTIMER0_CONF_REG,LEDC_LSTIMER0_DUTY_RES)
|
||||
// );
|
||||
//
|
||||
//delay(100);
|
||||
//
|
||||
//Serial.printf("LSCHAN0: %d %d %d %d %d\n",
|
||||
// REG_READ(LEDC_LSCH0_CONF0_REG),
|
||||
// REG_READ(LEDC_LSCH0_HPOINT_REG),
|
||||
// REG_READ(LEDC_LSCH0_DUTY_REG)>>4,
|
||||
// REG_READ(LEDC_LSCH0_DUTY_REG)&0xF,
|
||||
// REG_GET_FIELD(LEDC_LSCH0_CONF1_REG,LEDC_DUTY_INC_LSCH0)
|
||||
// );
|
||||
//
|
||||
//Serial.printf("LOW CLOCK: %d\n",REG_READ(LEDC_CONF_REG));
|
||||
//
|
||||
//Serial.printf("GPIO 32: %d %d %d %d\n",
|
||||
// REG_GET_FIELD(GPIO_FUNC32_OUT_SEL_CFG_REG,GPIO_FUNC32_OEN_INV_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC32_OUT_SEL_CFG_REG,GPIO_FUNC32_OEN_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC32_OUT_SEL_CFG_REG,GPIO_FUNC32_OUT_INV_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC32_OUT_SEL_CFG_REG,GPIO_FUNC32_OUT_SEL)
|
||||
// );
|
||||
//
|
||||
//Serial.printf("GPIO 5: %d %d %d %d\n",
|
||||
// REG_GET_FIELD(GPIO_FUNC5_OUT_SEL_CFG_REG,GPIO_FUNC5_OEN_INV_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC5_OUT_SEL_CFG_REG,GPIO_FUNC5_OEN_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC5_OUT_SEL_CFG_REG,GPIO_FUNC5_OUT_INV_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC5_OUT_SEL_CFG_REG,GPIO_FUNC5_OUT_SEL)
|
||||
// );
|
||||
//
|
||||
//Serial.printf("GPIO 4: %d %d %d %d\n",
|
||||
// REG_GET_FIELD(GPIO_FUNC4_OUT_SEL_CFG_REG,GPIO_FUNC4_OEN_INV_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC4_OUT_SEL_CFG_REG,GPIO_FUNC4_OEN_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC4_OUT_SEL_CFG_REG,GPIO_FUNC4_OUT_INV_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC4_OUT_SEL_CFG_REG,GPIO_FUNC4_OUT_SEL)
|
||||
// );
|
||||
//
|
||||
//Serial.printf("GPIO 33: %d %d %d %d\n",
|
||||
// REG_GET_FIELD(GPIO_FUNC33_OUT_SEL_CFG_REG,GPIO_FUNC33_OEN_INV_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC33_OUT_SEL_CFG_REG,GPIO_FUNC33_OEN_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC33_OUT_SEL_CFG_REG,GPIO_FUNC33_OUT_INV_SEL),
|
||||
// REG_GET_FIELD(GPIO_FUNC33_OUT_SEL_CFG_REG,GPIO_FUNC33_OUT_SEL)
|
||||
// );
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue