I'm using a NRF52810 to control an LED load and need to ramp up PWM frequency over the span of 6 seconds, like 0-1s : 6Hz, 1-2s : 7Hz, 2-3s : 8Hz, 4-5s : 9Hz, 5-6s : 10Hz.
At the moment, this is how I do PWM with fixed frequency:
#include "nrf.h" #include "nrf_gpio.h" #include "nrf_drv_gpiote.h" #include "nrf_drv_rtc.h" #include "nrf_drv_clock.h" #include "nrf_delay.h" #include "nrfx_rtc.h" #include "app_timer.h" #include "low_power_pwm.h" #include "boards.h" #include <stdint.h> #include <stdbool.h> #include "nrf_mtx.h" #include "math.h" int ch1_period; int ch1_ontime; float ch1_frequency; float ch1_dutycycle; float ch1_offset; int ch1_int_offset; int ch1_period_tmr; // keeps track of flash period int ch1_ontime_tmr; // keeps track of LED on-time bool ch1_on_flag = false; bool ch1_enable = false; const nrfx_rtc_t rtc1 = NRF_DRV_RTC_INSTANCE(1); // Create a handle that will point to the RTC1 of nrf device void gpio_init(){ nrf_gpio_cfg_input(switch_mode1, NRF_GPIO_PIN_PULLUP); // configure the mode switch input, with pin pullup nrf_gpio_cfg_output(pwm_1); // configure the CH1 PWM output pin nrf_gpio_pin_clear(pwm_1); // init pin to low which disables the LED driver } void init_group1_flash_patterns(){ ch1_enable = true; ch1_frequency = 6; //specify in Hertz. Decimals are OK. ch1_dutycycle = 25; // specify in "% positive duty cycle". Example: 45 = 45% On, 55% Off } void calc_flash_parameters(){ float z; //determine channel flash pattern periods and flash duty cycles ("ontimes") ch1_period = round((1/ch1_frequency)/.001); // period = frequency X .01sec ch1_ontime = round(1/ch1_frequency/.001 * ch1_dutycycle/100); // reset timers ch1_ontime_tmr = 0; ch1_period_tmr = 0; } // Initialize the low frequency clock which drives the real time counter void lfclk_config(void){ nrf_drv_clock_init(); // Initialize the low frequency clock nrf_drv_clock_lfclk_request(NULL); // Request the clock to not generate events } // RTC1 interrupt handler which will be used to maintain the flash period and duty cycle for the led channel void rtc1_handler(nrfx_rtc_int_type_t int_type){ if(ch1_enable == true){ // Channel 1 handling ch1_period_tmr = ch1_period_tmr + 1; // increment the period timer if(ch1_period_tmr == ch1_period && nrf_gpio_pin_out_read(pwm_1) == false ){ //turn on LED at start of each period nrf_gpio_pin_set(pwm_1); // turn on the LED ch1_ontime_tmr = 0; } ch1_ontime_tmr = ch1_ontime_tmr + 1; if(ch1_ontime_tmr == ch1_ontime && nrf_gpio_pin_out_read(pwm_1) == true){ nrf_gpio_pin_clear(pwm_1); } } } // A function to configure and intialize the RTC1 which is used for generating the interrupt void rtc1_config(void){ nrfx_rtc_config_t rtc1_config = NRFX_RTC_DEFAULT_CONFIG; // Create a struct of type nrfx_rtc_config_t and assign it default values rtc1_config.prescaler = 32; // tick = 32768 / (32 + 1) = 16384Hz = 61usec (all approximate). nrfx_rtc_init(&rtc1, &rtc1_config, rtc1_handler); // Initialize the rtc and pass the configurations along with the interrupt handler nrfx_rtc_tick_enable(&rtc1, true); // Enable a tick interrupt on each tick nrfx_rtc_overflow_disable(&rtc1); // don't know if this is necessary nrfx_rtc_enable(&rtc1); // start the rtc } int main(void){ gpio_init(); // Initialize the gpio if(nrf_gpio_pin_read(switch_mode1) == 0){ //if mode 1 selected on the mode switch init_group1_flash_patterns(); //initialize the flash patterns } max_parameter_violation_check(); lfclk_config(); // low frequency low power clock configuration nrfx_clock_lfclk_start(); rtc1_config(); // rtc1 configuration } I'm stuck on how to implement this dynamic frequency - mostly on the side of triggering when to change the period, a way I think it could be implemented: to reset the the timer every 1000ms, and adjusting parameters for the next frequency. Hence, using another timer as that counter?
I can't seem to wrap my head around how to implement this.