Hello,
SDK 15.3.0
s140
nrf52840-DK
IDE: SES
I am attempting to use the LPComp + NRFX TIMER 4 to count the rising edge of a signal, the timer is being used to time when the data is complete so I can calculate an reset for the next amount of data.
I need to count the pulse train then calculate the proper value. The pulse train is 88kHz for Max of 50ms that will be counted by LPComp, and the timer is intended to be enabled on the first rising edge after the alignment is complete, and disabled when the timer is triggered after 50ms.
Am I properly "restarting" the timer to be aligned with the pulse train? I am getting much lower counts than I would expect, and I think the timer alignment to the first pulse in the pulse train may be the issue?
The print statement I have is printing in the main loop only if the ready_flag is true. I am only seeing a single print out, so I do not think I am triggering the timer handler on subsequent pulse trains.
Additionally, are any of the functions being called in the LPComp handler, or timer handler appropriate for ISRs?
In the off chance there is a better solution to count and calculate this signal I am open for suggestions of features I am not taking advantage of?
#include "nrf_error.h" #include "app_error.h" #include "boards.h" #include <math.h> #include "nrfx_timer.h" static volatile uint32_t voltage_rising_detected = 0; static volatile uint32_t voltage_rising_total = 0; static float count = 0; static float value = 0; static bool ready_flag = false; static bool aligned_to_signal = false; static bool first_pulse = true; const nrfx_timer_t DATA_COMPLETE_TIMER = NRFX_TIMER_INSTANCE(4); /**@brief Timeout handler for the single shot timer. */ static void data_complete_timer_init() { ret_code_t err_code; uint32_t time_ticks; //Configure DATA_COMPLETE_TIMER nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG; err_code = nrfx_timer_init(&DATA_COMPLETE_TIMER, &timer_cfg, data_complete_timer_handler); APP_ERROR_CHECK(err_code); time_ticks = nrfx_timer_ms_to_ticks(&DATA_COMPLETE_TIMER, 51); nrfx_timer_compare(&DATA_COMPLETE_TIMER, NRF_TIMER_CC_CHANNEL0, time_ticks, false); nrfx_timer_enable(&DATA_COMPLETE_TIMER); } /**@brief Timeout handler for the single shot timer. */ void data_complete_timer_handler(nrf_timer_event_t event_type, void* p_context) { switch (event_type) { case NRF_TIMER_EVENT_COMPARE0: if(aligned_to_signal) { //bsp_board_led_invert(BSP_BOARD_LED_1); count = (float)voltage_rising_total; value = (count * math stuff); voltage_rising_detected = 0; voltage_rising_total = 0; ready_flag = true; first_pulse = true; nrfx_timer_compare_int_disable(&DATA_COMPLETE_TIMER, NRF_TIMER_CC_CHANNEL0); }else{ aligned_to_signal = true; nrfx_lpcomp_enable(); //nrfx_timer_disable(&DATA_COMPLETE_TIMER); nrfx_timer_compare_int_disable(&DATA_COMPLETE_TIMER, NRF_TIMER_CC_CHANNEL0); } break; default: //Do nothing. break; } } /** * @brief LPCOMP event handler is called when LPCOMP detects voltage drop. * * This function is called from interrupt context so it is very important * to return quickly. Don't put busy loops or any other CPU intensive actions here. * It is also not allowed to call soft device functions from it (if LPCOMP IRQ * priority is set to APP_IRQ_PRIORITY_HIGH). */ static void lpcomp_event_handler(nrf_lpcomp_event_t event) { if (event == NRF_LPCOMP_EVENT_UP) { if(aligned_to_signal) { if(first_pulse) { nrfx_timer_clear(&DATA_COMPLETE_TIMER); nrfx_timer_compare_int_enable(&DATA_COMPLETE_TIMER, NRF_TIMER_CC_CHANNEL0); first_pulse = false; } voltage_rising_detected++; voltage_rising_total++; }else{ nrfx_lpcomp_disable(); nrfx_timer_clear(&DATA_COMPLETE_TIMER); nrfx_timer_compare_int_enable(&DATA_COMPLETE_TIMER, NRF_TIMER_CC_CHANNEL0); } } } /** * @brief Print out detection statistics. */ static void print_statistics(void) { if(ready_flag){ printf("value: %f\n", value); ready_flag = false; } } /** * @brief Initialize LPCOMP driver. */ static void lpcomp_init(void) { uint32_t err_code; nrf_drv_lpcomp_config_t config = NRF_DRV_LPCOMP_DEFAULT_CONFIG; config.input = NRF_LPCOMP_INPUT_2; // initialize LPCOMP driver, from this point LPCOMP will be active and provided // event handler will be executed when defined action is detected err_code = nrf_drv_lpcomp_init(&config, lpcomp_event_handler); APP_ERROR_CHECK(err_code); nrfx_lpcomp_enable(); } void init(void) { lpcomp_init(); timer_init(); }