Hi , i am using the nRF52DK and i have a small problem with the pwm driver.
i basically would like that the frequency increases if i press a button or decreases if I press another button while keeping the same 50% duty cycle.
The way i attempted it is that i have an array with different top values that correspond to different frequencies. but I'm struggling to put it in seq_vallues and get the 50%. my code can be seen below.
thanks for your help
#include <stdio.h> #include <string.h> #include "nrf_drv_pwm.h" #include "app_util_platform.h" #include "app_error.h" #include "boards.h" #include "bsp.h" #include "app_timer.h" #include "nrf_drv_clock.h" #include "nrf_drv_gpiote.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0); static nrf_drv_pwm_t m_pwm1 = NRF_DRV_PWM_INSTANCE(1); static nrf_drv_pwm_t m_pwm2 = NRF_DRV_PWM_INSTANCE(2); // This is for tracking PWM instances being used, so we can unintialize only // the relevant ones when switching from one demo to another. #define USED_PWM(idx) (1UL << idx) #define LED2 NRF_GPIO_PIN_MAP(0,18) #define BTN1 NRF_GPIO_PIN_MAP(0,13) #define BTN2 NRF_GPIO_PIN_MAP(0,14) static uint8_t m_used = 0; uint16_t topvalue_array[12] = {16000,1600,8000,525,400,320,268,228,200,178,160,145}; uint16_t PWM_Counter; static uint16_t const m_demo1_top = 400; static uint16_t const m_demo1_step = 25; static uint8_t m_demo1_phase; static nrf_pwm_values_individual_t m_demo1_seq_values; void button_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action){ if(action == NRF_GPIOTE_POLARITY_TOGGLE && pin == BTN2){ nrf_gpio_pin_toggle(LED2); PWM_Counter++; } } static nrf_pwm_sequence_t const m_demo1_seq = { .values.p_individual = &m_demo1_seq_values, .length = NRF_PWM_VALUES_LENGTH(m_demo1_seq_values), .repeats = 0, .end_delay = 0 }; static void PWM_init(void) { nrf_drv_pwm_config_t const config0 = { .output_pins = { BSP_LED_0 | NRF_DRV_PWM_PIN_INVERTED, // channel 0 NRF_DRV_PWM_PIN_NOT_USED, // channel 1 NRF_DRV_PWM_PIN_NOT_USED, // channel 2 NRF_DRV_PWM_PIN_NOT_USED, // channel 3 }, .irq_priority = APP_IRQ_PRIORITY_LOWEST, .base_clock = NRF_PWM_CLK_16MHz, .count_mode = NRF_PWM_MODE_UP, .top_value = topvalue_array[0], .load_mode = NRF_PWM_LOAD_COMMON, .step_mode = NRF_PWM_STEP_AUTO }; APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL)); m_used |= USED_PWM(0); static uint16_t seq_values[] = { topvalue_array[0]/2 }; nrf_pwm_sequence_t const seq = { .values.p_common = seq_values, .length = NRF_PWM_VALUES_LENGTH(seq_values), .repeats = 0, .end_delay = 0 }; (void)nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1, NRF_DRV_PWM_FLAG_LOOP); } static void GPIOTE_init(void) { // Configure LED GPIO nrf_gpio_cfg_output(LED2); nrf_gpio_pin_set(LED2); //Initialize GPIOTE driver nrf_drv_gpiote_init(); //Configure button with pullup and event on both high and low transition nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); config.pull = NRF_GPIO_PIN_PULLUP; nrf_drv_gpiote_in_init(BTN2, &config, button_event_handler); //Assign button config to a GPIOTE channel and assigning the interrupt handler nrf_drv_gpiote_in_event_enable(BTN2, true); //Enable event and interrupt } int main(void) { PWM_Counter = topvalue_array[0]; PWM_init(); GPIOTE_init(); for (;;) { // Wait for an event. __WFE(); // Clear the event register. __SEV(); __WFE(); } }