From fb07a1244c940fee4db3b9db8c8b9c83fecfb260 Mon Sep 17 00:00:00 2001 From: rbaron Date: Sun, 14 Mar 2021 15:03:33 +0100 Subject: [PATCH] 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. --- code/b-parasite/config/prst_config.h | 4 +++- code/b-parasite/src/main.c | 28 ++++++++++------------------ code/b-parasite/src/prst/pwm.c | 21 +++++++++++++++------ 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/code/b-parasite/config/prst_config.h b/code/b-parasite/config/prst_config.h index 4f4276d..46a4e71 100644 --- a/code/b-parasite/config/prst_config.h +++ b/code/b-parasite/config/prst_config.h @@ -3,6 +3,9 @@ #include "nrf_gpio.h" +// Built-in LED. +#define PRST_LED_PIN NRF_GPIO_PIN_MAP(1, 11) + // Deep sleep. #define PRST_DEEP_SLEEP_IN_SECONDS 2 @@ -11,6 +14,5 @@ // PWM. #define PRST_PWM_PIN NRF_GPIO_PIN_MAP(0, 29) -#define PRST_PWM_FREQUENCY 500000 #endif // _PRST_CONFIG_H_ \ No newline at end of file diff --git a/code/b-parasite/src/main.c b/code/b-parasite/src/main.c index 43be309..5869e65 100644 --- a/code/b-parasite/src/main.c +++ b/code/b-parasite/src/main.c @@ -19,12 +19,7 @@ #include "prst/pwm.h" #include "prst/rtc.h" -// P0.03 -// #define LED_PIN 3 -#define LED_PIN NRF_GPIO_PIN_MAP(1, 11) - -// Environmental sensing. -#define SERVICE_UUID 0x181a +#include "prst_config.h" #define DEAD_BEEF 0xDEADBEEF @@ -40,11 +35,7 @@ static void log_init(void) { } static void leds_init(void) { - nrf_gpio_cfg_output(LED_PIN); - nrf_gpio_pin_toggle(LED_PIN); - nrf_delay_ms(500); - nrf_gpio_pin_toggle(LED_PIN); - nrf_delay_ms(500); + nrf_gpio_cfg_output(PRST_LED_PIN); NRF_LOG_INFO("Leds inited"); } @@ -67,28 +58,29 @@ static uint8_t data; static void rtc_callback() { NRF_LOG_INFO("rtc callback running...\n"); 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_adv_start(); nrf_delay_ms(300); prst_adv_stop(); - nrf_gpio_pin_clear(LED_PIN); + nrf_gpio_pin_clear(PRST_LED_PIN); } int main(void) { - // Initialize. log_init(); leds_init(); power_management_init(); - prst_pwm_init(); - prst_pwm_start(); prst_ble_init(); prst_rtc_set_callback(rtc_callback); prst_rtc_init(); - // Enter main loop. for (;;) { power_manage(); } -} \ No newline at end of file +} diff --git a/code/b-parasite/src/prst/pwm.c b/code/b-parasite/src/prst/pwm.c index bcafed4..c25fb5b 100644 --- a/code/b-parasite/src/prst/pwm.c +++ b/code/b-parasite/src/prst/pwm.c @@ -8,11 +8,19 @@ #include "prst_config.h" +// Each step in the counter will take 1/16e6 s. #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_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_ = { .values.p_common = seq_values_, .length = NRF_PWM_VALUES_LENGTH(seq_values_), @@ -20,8 +28,6 @@ static const nrf_pwm_sequence_t seq_ = { .end_delay = 0}; void prst_pwm_init() { - UNUSED_VARIABLE(seq_); - nrf_drv_pwm_config_t const config0 = { .output_pins = { @@ -35,16 +41,19 @@ void prst_pwm_init() { .base_clock = NRF_PWM_CLK_16MHz, // This is the hal COUNTERTOP. .count_mode = NRF_PWM_MODE_UP_AND_DOWN, - // .top_value = (uint16_t)(1e16 / PRST_PWM_FREQUENCY), - .top_value = 16, + .top_value = PRST_PWM_MAX_COUNT, .load_mode = NRF_PWM_LOAD_COMMON, .step_mode = NRF_PWM_STEP_AUTO}; APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL)); } void prst_pwm_start() { + // Loop forever. APP_ERROR_CHECK( nrf_drv_pwm_simple_playback(&m_pwm0, &seq_, 1, NRF_DRV_PWM_FLAG_LOOP)); } -void prst_pwm_stop() {} \ No newline at end of file +void prst_pwm_stop() { + APP_ERROR_CHECK(nrf_drv_pwm_stop(&m_pwm0, /*wait_until_stopped=*/true)); + nrf_drv_pwm_uninit(&m_pwm0); +} \ No newline at end of file