diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..9a874b5 Binary files /dev/null and b/.DS_Store differ diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000..9265ca9 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/extras/PwmPin.cpp b/src/extras/PwmPin.cpp index 1f85bbe..c9c377e 100644 --- a/src/extras/PwmPin.cpp +++ b/src/extras/PwmPin.cpp @@ -3,56 +3,75 @@ /////////////////// -LedPin::LedPin(uint8_t pin, uint8_t level){ - if(numChannels+ServoPin::numChannels>15){ - Serial.printf("\n*** ERROR: Can't create LedPin(%d) - no open PWM channels ***\n\n",pin); - ledChannel.gpio_num=0; - return; +LedPin::LedPin(uint8_t pin, uint8_t level, uint16_t freq){ + + if(freq==0) + freq=DEFAULT_PWM_FREQ; + + for(int nMode=0;nModespeed_mode=(ledc_mode_t)nMode; + timerList[nTimer][nMode]->timer_num=(ledc_timer_t)nTimer; + timerList[nTimer][nMode]->freq_hz=freq; + + int res=20; // find the maximum possible resolution + while(getApbFrequency()/(freq*pow(2,res))<1) + res--; + + timerList[nTimer][nMode]->duty_resolution=(ledc_timer_bit_t)res; + ledc_timer_config(timerList[nTimer][nMode]); + } + + if(timerList[nTimer][nMode]->freq_hz==freq){ // if timer matches desired frequency (always true if newly-created above) + channelList[nChannel][nMode]=new ledc_channel_config_t; // create new channel instance + channelList[nChannel][nMode]->speed_mode=(ledc_mode_t)nMode; + 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]->hpoint=0; + channelList[nChannel][nMode]->gpio_num=pin; + ledTimer=timerList[nTimer][nMode]; + ledChannel=channelList[nChannel][nMode]; + set(level); + return; + } + + } + } + } } - enabled=true; - - if(numChannels==0){ // first instantiation of an LedPin - ledc_timer_config_t ledTimer; - ledTimer.timer_num=LEDC_TIMER_0; - ledTimer.duty_resolution=LEDC_TIMER_10_BIT; - ledTimer.freq_hz=5000; + Serial.printf("\n*** ERROR: Can't create LedPin(%d) - no open PWM channels and/or Timers ***\n\n",pin); - ledTimer.speed_mode=LEDC_HIGH_SPEED_MODE; // configure both the HIGH-Speed Timer 0 and Low-Speed Timer 0 - ledc_timer_config(&ledTimer); - - ledTimer.speed_mode=LEDC_LOW_SPEED_MODE; - ledc_timer_config(&ledTimer); - } - - ledChannel.gpio_num=pin; - if(numChannels<8){ - ledChannel.speed_mode=LEDC_LOW_SPEED_MODE; - ledChannel.channel=(ledc_channel_t)(7-numChannels); - } else { - ledChannel.speed_mode=LEDC_HIGH_SPEED_MODE; - ledChannel.channel=(ledc_channel_t)(15-numChannels); - } - - numChannels++; - - ledChannel.intr_type=LEDC_INTR_DISABLE; - ledChannel.timer_sel=LEDC_TIMER_0; - ledChannel.hpoint=0; - ledc_channel_config(&ledChannel); - set(level); } /////////////////// void LedPin::set(uint8_t level){ - if(!enabled) + + if(!ledChannel) return; + + Serial.printf("pin=%d, ch=%d, mode=%d, timer=%d, freq=%d, res=%d\n", + ledChannel->gpio_num, + ledChannel->channel, + ledChannel->speed_mode, + ledChannel->timer_sel, + ledTimer->freq_hz, + ledTimer->duty_resolution + ); + + if(level>100) + level=100; - ledChannel.duty=level*1023; - ledChannel.duty/=100; - ledChannel.duty&=0x03FF; - ledc_channel_config(&ledChannel); + ledChannel->duty=level*(pow(2,ledTimer->duty_resolution)-1); + ledChannel->duty/=100; + ledc_channel_config(ledChannel); } @@ -170,6 +189,10 @@ void ServoPin::set(double degrees){ const double ServoPin::micros2duty=65535.0/20000.0; uint8_t LedPin::numChannels=0; uint8_t ServoPin::numChannels=0; +uint8_t LedC::nChannels=0; +vector LedC::timers; +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 ONLY diff --git a/src/extras/PwmPin.h b/src/extras/PwmPin.h index 76b79fb..5281f1c 100644 --- a/src/extras/PwmPin.h +++ b/src/extras/PwmPin.h @@ -22,17 +22,33 @@ #include #include +#include + +using std::vector; + +#define DEFAULT_PWM_FREQ 5000 ///////////////////////////////////// -class LedPin { - boolean enabled=false; - ledc_channel_config_t ledChannel; +class LedC { + + protected: + static uint8_t nChannels; + static vector timers; + static ledc_channel_config_t *channelList[LEDC_CHANNEL_MAX][LEDC_SPEED_MODE_MAX]; + static ledc_timer_config_t *timerList[LEDC_TIMER_MAX][LEDC_SPEED_MODE_MAX]; +}; + +///////////////////////////////////// + +class LedPin : LedC { + ledc_channel_config_t *ledChannel=NULL; + ledc_timer_config_t *ledTimer; public: - LedPin(uint8_t pin, uint8_t level=0); // assigns pin to be output of one of 16 PWM channels within initial level - void set(uint8_t level); // sets the PWM duty to level (0-100) - int getPin(){return ledChannel.gpio_num;} // returns the pin number + LedPin(uint8_t pin, uint8_t level=0, uint16_t freq=DEFAULT_PWM_FREQ); // assigns pin to be output of one of 16 PWM channels initial level and frequency + void set(uint8_t level); // sets the PWM duty to level (0-100) + int getPin(){return(ledChannel?ledChannel->gpio_num:-1);} // returns the pin number static uint8_t numChannels; static void HSVtoRGB(float h, float s, float v, float *r, float *g, float *b ); // converts Hue/Saturation/Brightness to R/G/B diff --git a/src/extras/extras.ino b/src/extras/extras.ino index 1bdb34a..e98d842 100644 --- a/src/extras/extras.ino +++ b/src/extras/extras.ino @@ -3,7 +3,8 @@ // as well as compile and test from this point. This file is ignored when the library is included in other sketches. #include "PwmPin.h" - +#include + void setup(){ Serial.begin(115200); @@ -13,53 +14,37 @@ void setup(){ Serial.println("Starting..."); + LedPin led0(18,100,0); + LedPin led1(19,100,2000); + LedPin led2(16,10,80000); + LedPin led3(17,100,2000); + LedPin led4(23); + LedPin led5(22,0,3000); + LedPin led6(14,0,1); + LedPin led7(32,0,1850); + LedPin led8(15); + LedPin led9(33); + LedPin led10(27); + LedPin led11(12,100,23); + LedPin led12(13,100); + LedPin led13(26); + LedPin led14(25,0); + LedPin led15(4,0); + LedPin led16(5,0); - LedPin yellow(16,10); - LedPin d1(19); - LedPin d2(19); - LedPin d3(19); - LedPin d4(19); - LedPin d5(19); - LedPin d6(19); - LedPin d7(19); - LedPin d8(19); - LedPin d9(19); - LedPin d10(19); - LedPin d11(19); - LedPin d12(19); - LedPin red(17); + led16.set(20); + led0.set(5); + led2.set(100); -// ServoPin servo(18,0,500,2200,-90,90); - ServoPin s0(19); - ServoPin servo(18,45); - ServoPin s1(19); + 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)); - while(1){ - for(int i=0;i<100;i++){ - yellow.set(i); - delay(10); - } - for(int i=100;i>=0;i--){ - red.set(i); - delay(10); - } - } - - while(1){ - double STEP=1; - - for(int i=-100*STEP;i<=100*STEP;i++){ - servo.set((double)i/STEP); - delay(10); - } - - for(int i=100*STEP;i>=-100*STEP;i--){ - servo.set((double)i/STEP); - delay(10); - } - } + while(1); } void loop(){