Hi,
This is my first post here. I hope I will follow the structure of a good question.
I want to have a sequence of defined duty cycles (let's say 4 values). The aim is to loop forever between the 4 values in this sequence in order to "smoothly" dim a LED (use of a single output pin). I would like to run PWM by itself to do that without any ISR support by CPU.
I'm working with the NRF52832. I can't use the SDK because we are building our own code.
I have looked at the Nordic datasheet (rev 1.1) and at this post but I still haven't understood how to solve my problem.
Here is what I tried as code:
#include "pwm.h"
#include "nrf52.h"
#include "nrf52_bitfields.h"
#include "nrf_gpio.h"
//#include "app.h"
static uint32_t pwm_max_value = 100;
static uint16_t pwm_seq[4][4]={{10, 10, 10, 10}, {25, 25, 25, 25}, { 50, 50, 50, 50}, {75,75,75,75}}; // Pay attention that it is INVERSE LOGICAL in the sequence (ex: 1= 99%, 90 = 10%)
/** Is PWM Initialized */
static bool m_initialized = false;
void pwm_init()
{
nrf_gpio_cfg_output(BOARD_PWM_OUTPUT_GPIO);
nrf_gpio_pin_clear(BOARD_PWM_OUTPUT_GPIO);
// Select output pin
NRF_PWM0->PSEL.OUT[0] = (BOARD_PWM_OUTPUT_GPIO << PWM_PSEL_OUT_PIN_Pos) |
(PWM_PSEL_OUT_CONNECT_Connected <<
PWM_PSEL_OUT_CONNECT_Pos);
// Enable PWM module
NRF_PWM0->ENABLE = (PWM_ENABLE_ENABLE_Enabled << PWM_ENABLE_ENABLE_Pos);
// Set Mode
NRF_PWM0->MODE = (PWM_MODE_UPDOWN_Up << PWM_MODE_UPDOWN_Pos);
// Set prescaler to set frequency clock of 1MHz (= f_default(16MHz)/PWM_PRESCALER_PRESCALER_DIV_16)
NRF_PWM0->PRESCALER = (PWM_PRESCALER_PRESCALER_DIV_16 <<
PWM_PRESCALER_PRESCALER_Pos);
// Set counter top to have a PWM frequency of 10 KHz (= PWM_PRESCALER_PRESCALER_DIV_16/pwm_max_value)
NRF_PWM0->COUNTERTOP = (pwm_max_value << PWM_COUNTERTOP_COUNTERTOP_Pos);
NRF_PWM0->LOOP = (PWM_LOOP_CNT_Disabled<< PWM_LOOP_CNT_Pos);
NRF_PWM0->DECODER = (PWM_DECODER_LOAD_WaveForm << PWM_DECODER_LOAD_Pos) |
(PWM_DECODER_MODE_RefreshCount << PWM_DECODER_MODE_Pos);
NRF_PWM0->SEQ[0].PTR = ((uint32_t)(pwm_seq) << PWM_SEQ_PTR_PTR_Pos);
NRF_PWM0->SEQ[0].CNT = ((sizeof(pwm_seq) / sizeof(uint16_t)) << PWM_SEQ_CNT_CNT_Pos);
NRF_PWM0->SEQ[0].REFRESH = 1;
NRF_PWM0->SEQ[0].ENDDELAY = 0;
NRF_PWM0->TASKS_SEQSTART[0] = 1;
m_initialized = true;
}
The file pwm.h simply includes the header of pwm_init().
Any comments or suggestions about how I have to do ?
Thanks in advance for your answer,
Best regards,
Florent