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();
}
}