Hi!
I want to develop a simple program which count pulses in a digital pin in an interval of 10ms. I want to use a timer as a counter to count the pulses, also I want to use another counter to read the amount of pulses that occurs in the pin and reset the first counter.
I'm using MBED STUDIO with the nrf52-dk and the SDK15.0 (which is the default in mbed studio). The counter works well, but the second one doesn't. When I enable the interrupts, that I want use to read the value of the counter, the MCU freeze and never execute the interrupt.
Here is my code:
#include "nrf.h" #include "nrfx_timer.h" #include "mbed.h" #include "app_error.h" #include "nrfx_clock.h" #include "nrfx_ppi.h" #include "nrfx_gpiote.h" #define TIMEOUT_MS 10 #define INPUT_PIN P0_4 DigitalOut led1(LED1); DigitalOut led2(LED2, true); volatile uint32_t count0 = 0; const nrfx_timer_t counter_timer = NRFX_TIMER_INSTANCE(3); const nrfx_timer_t timeout_timer = NRFX_TIMER_INSTANCE(4); nrf_ppi_channel_t ppi_channel1; nrf_ppi_channel_t ppi_channel2; /** * @brief Handler for timer events. */ void timer_handler_read(nrf_timer_event_t event_type, void * p_context) { count0 = nrfx_timer_capture_get(&counter_timer, NRF_TIMER_CC_CHANNEL0); } /** * @brief Handler for counter events. */ void timer_counter_handler(nrf_timer_event_t event_type, void* p_context) { } /** * @brief Handler forin pin. */ static void in_pin_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { } void gpiote_init() { uint32_t err_code = NRF_SUCCESS; if(!nrfx_gpiote_is_init()) { err_code = nrfx_gpiote_init(); APP_ERROR_CHECK(err_code); } nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(true); in_config.pull = NRF_GPIO_PIN_PULLUP; err_code = nrfx_gpiote_in_init(INPUT_PIN, &in_config, in_pin_handler); APP_ERROR_CHECK(err_code); nrfx_gpiote_in_event_enable(INPUT_PIN, false); } void timer_init() { uint32_t err_code = NRF_SUCCESS; //Configure the timer nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG; timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32; timer_cfg.mode = NRF_TIMER_MODE_TIMER; timer_cfg.frequency = NRF_TIMER_FREQ_16MHz; err_code = nrfx_timer_init(&timeout_timer, &timer_cfg, timer_handler_read); APP_ERROR_CHECK(err_code); printf("2 Error code: %d\n\r", err_code); uint32_t time_ticks = nrfx_timer_ms_to_ticks(&timeout_timer, TIMEOUT_MS); printf("Ticks: %d\n\r", time_ticks); nrfx_timer_extended_compare(&timeout_timer, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true); nrfx_timer_enable(&timeout_timer); //Configure TIMER for counting of low to high events on GPIO nrfx_timer_config_t counter_cfg = NRFX_TIMER_DEFAULT_CONFIG; counter_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32; counter_cfg.mode = NRF_TIMER_MODE_COUNTER; err_code = nrfx_timer_init(&counter_timer, &counter_cfg, timer_counter_handler); APP_ERROR_CHECK(err_code); nrfx_timer_enable(&counter_timer); printf("1 Error code: %d\n\r", err_code); } void ppi_init() { uint32_t err_code = NRF_SUCCESS; err_code = nrfx_ppi_channel_alloc(&ppi_channel1); APP_ERROR_CHECK(err_code); err_code = nrfx_ppi_channel_alloc(&ppi_channel2); APP_ERROR_CHECK(err_code); uint32_t gpiote_evt_addr_1 = nrfx_gpiote_in_event_addr_get(INPUT_PIN); uint32_t timer_count_count_task_addr = nrfx_timer_task_address_get(&counter_timer, NRF_TIMER_TASK_COUNT); uint32_t timer_count_capture_task_addr = nrfx_timer_task_address_get(&counter_timer, NRF_TIMER_TASK_CAPTURE0); uint32_t timer_count_clear_task_addr = nrfx_timer_task_address_get(&counter_timer, NRF_TIMER_TASK_CLEAR); uint32_t timer_timeout_compare_event_addr = nrfx_timer_event_address_get(&timeout_timer, NRF_TIMER_EVENT_COMPARE0); err_code = nrfx_ppi_channel_assign(ppi_channel1, gpiote_evt_addr_1, timer_count_count_task_addr); APP_ERROR_CHECK(err_code); err_code = nrfx_ppi_channel_assign(ppi_channel2, timer_timeout_compare_event_addr, timer_count_capture_task_addr); // Capture counter timer using PPI to make sure this is not delayed by BLE interrupt APP_ERROR_CHECK(err_code); err_code = nrfx_ppi_channel_fork_assign(ppi_channel2, timer_count_clear_task_addr); // Clear counter timer using PPI to make sure this is not delayed by BLE interrupt APP_ERROR_CHECK(err_code); err_code = nrfx_ppi_channel_enable(ppi_channel1); APP_ERROR_CHECK(err_code); err_code = nrfx_ppi_channel_enable(ppi_channel2); APP_ERROR_CHECK(err_code); } /** * @brief Function for main application entry. */ int main(void) { if (!nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY)) { nrfx_clock_hfclk_start(); } //Configure in pin gpiote_init(); //Configure the timmers timer_init(); //Configure the PPI ppi_init(); while (1) { led1 = !led1; ThisThread::sleep_for(200ms); printf("Counts 0: %d\n\r", count0); } }
Thanks