PWM start/stop in RTC callback.

I initially tried calling prst_pwm_init() in main(), and just using start/stop in
the callback, but that led to a weird behavior in the PWM output. It was set to
high after the end of the callback.

Callnig uninit/re-calling init() inside the RTC callback fixed, but more investigation
is required.
This commit is contained in:
rbaron 2021-03-14 15:03:33 +01:00
parent 05dcb9de84
commit fb07a1244c
3 changed files with 28 additions and 25 deletions

View file

@ -3,6 +3,9 @@
#include "nrf_gpio.h" #include "nrf_gpio.h"
// Built-in LED.
#define PRST_LED_PIN NRF_GPIO_PIN_MAP(1, 11)
// Deep sleep. // Deep sleep.
#define PRST_DEEP_SLEEP_IN_SECONDS 2 #define PRST_DEEP_SLEEP_IN_SECONDS 2
@ -11,6 +14,5 @@
// PWM. // PWM.
#define PRST_PWM_PIN NRF_GPIO_PIN_MAP(0, 29) #define PRST_PWM_PIN NRF_GPIO_PIN_MAP(0, 29)
#define PRST_PWM_FREQUENCY 500000
#endif // _PRST_CONFIG_H_ #endif // _PRST_CONFIG_H_

View file

@ -19,12 +19,7 @@
#include "prst/pwm.h" #include "prst/pwm.h"
#include "prst/rtc.h" #include "prst/rtc.h"
// P0.03 #include "prst_config.h"
// #define LED_PIN 3
#define LED_PIN NRF_GPIO_PIN_MAP(1, 11)
// Environmental sensing.
#define SERVICE_UUID 0x181a
#define DEAD_BEEF 0xDEADBEEF #define DEAD_BEEF 0xDEADBEEF
@ -40,11 +35,7 @@ static void log_init(void) {
} }
static void leds_init(void) { static void leds_init(void) {
nrf_gpio_cfg_output(LED_PIN); nrf_gpio_cfg_output(PRST_LED_PIN);
nrf_gpio_pin_toggle(LED_PIN);
nrf_delay_ms(500);
nrf_gpio_pin_toggle(LED_PIN);
nrf_delay_ms(500);
NRF_LOG_INFO("Leds inited"); NRF_LOG_INFO("Leds inited");
} }
@ -67,28 +58,29 @@ static uint8_t data;
static void rtc_callback() { static void rtc_callback() {
NRF_LOG_INFO("rtc callback running...\n"); NRF_LOG_INFO("rtc callback running...\n");
NRF_LOG_FLUSH(); NRF_LOG_FLUSH();
nrf_gpio_pin_set(LED_PIN); nrf_gpio_pin_set(PRST_LED_PIN);
prst_pwm_init();
prst_pwm_start();
// TODO: ADC.
nrf_delay_ms(500);
prst_pwm_stop();
prst_ble_update_adv_data(++data); prst_ble_update_adv_data(++data);
prst_adv_start(); prst_adv_start();
nrf_delay_ms(300); nrf_delay_ms(300);
prst_adv_stop(); prst_adv_stop();
nrf_gpio_pin_clear(LED_PIN); nrf_gpio_pin_clear(PRST_LED_PIN);
} }
int main(void) { int main(void) {
// Initialize.
log_init(); log_init();
leds_init(); leds_init();
power_management_init(); power_management_init();
prst_pwm_init();
prst_pwm_start();
prst_ble_init(); prst_ble_init();
prst_rtc_set_callback(rtc_callback); prst_rtc_set_callback(rtc_callback);
prst_rtc_init(); prst_rtc_init();
// Enter main loop.
for (;;) { for (;;) {
power_manage(); power_manage();
} }
} }

View file

@ -8,11 +8,19 @@
#include "prst_config.h" #include "prst_config.h"
// Each step in the counter will take 1/16e6 s.
#define PRST_PWM_BASE_FREQ NRF_PWM_CLK_16MHz #define PRST_PWM_BASE_FREQ NRF_PWM_CLK_16MHz
// We will count up to 16. It will take 1us at 16MHz.
// With the NRF_PWM_MODE_UP_AND_DOWN count mode, we assume 1us is half the
// output PWM period (total 2us => 500MHz frequency). We set a duty cycle of
// 50% below with PRST_PWM_FLIP_AT_COUNT to be half the max count.
#define PRST_PWM_MAX_COUNT 16
// We will toggle the PWM output when we reach this count.
#define PRST_PWM_FLIP_AT_COUNT PRST_PWM_MAX_COUNT / 2
static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0); static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0);
static nrf_pwm_values_common_t seq_values_[] = {8}; static nrf_pwm_values_common_t seq_values_[] = {PRST_PWM_FLIP_AT_COUNT};
static const nrf_pwm_sequence_t seq_ = { static const nrf_pwm_sequence_t seq_ = {
.values.p_common = seq_values_, .values.p_common = seq_values_,
.length = NRF_PWM_VALUES_LENGTH(seq_values_), .length = NRF_PWM_VALUES_LENGTH(seq_values_),
@ -20,8 +28,6 @@ static const nrf_pwm_sequence_t seq_ = {
.end_delay = 0}; .end_delay = 0};
void prst_pwm_init() { void prst_pwm_init() {
UNUSED_VARIABLE(seq_);
nrf_drv_pwm_config_t const config0 = { nrf_drv_pwm_config_t const config0 = {
.output_pins = .output_pins =
{ {
@ -35,16 +41,19 @@ void prst_pwm_init() {
.base_clock = NRF_PWM_CLK_16MHz, .base_clock = NRF_PWM_CLK_16MHz,
// This is the hal COUNTERTOP. // This is the hal COUNTERTOP.
.count_mode = NRF_PWM_MODE_UP_AND_DOWN, .count_mode = NRF_PWM_MODE_UP_AND_DOWN,
// .top_value = (uint16_t)(1e16 / PRST_PWM_FREQUENCY), .top_value = PRST_PWM_MAX_COUNT,
.top_value = 16,
.load_mode = NRF_PWM_LOAD_COMMON, .load_mode = NRF_PWM_LOAD_COMMON,
.step_mode = NRF_PWM_STEP_AUTO}; .step_mode = NRF_PWM_STEP_AUTO};
APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL)); APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL));
} }
void prst_pwm_start() { void prst_pwm_start() {
// Loop forever.
APP_ERROR_CHECK( APP_ERROR_CHECK(
nrf_drv_pwm_simple_playback(&m_pwm0, &seq_, 1, NRF_DRV_PWM_FLAG_LOOP)); nrf_drv_pwm_simple_playback(&m_pwm0, &seq_, 1, NRF_DRV_PWM_FLAG_LOOP));
} }
void prst_pwm_stop() {} void prst_pwm_stop() {
APP_ERROR_CHECK(nrf_drv_pwm_stop(&m_pwm0, /*wait_until_stopped=*/true));
nrf_drv_pwm_uninit(&m_pwm0);
}