diff --git a/bsp/hc_sr04.h b/bsp/hc_sr04.h index bbcf6189..30ca1436 100644 --- a/bsp/hc_sr04.h +++ b/bsp/hc_sr04.h @@ -26,6 +26,8 @@ typedef void(*timer_callback_t)(void); void hc_sr04_init(us_callback_t us_callback, timer_callback_t timer_callback, NRF_TIMER_Type *us_on, NRF_TIMER_Type *us_read); void hc_sr04_start(void); +void hc_sr04_stop(void); +void hc_sr04_on_set_trigger(double duration_ms, double offset_ms); void hfclk_init(void); diff --git a/bsp/nrf52833/hc_sr04.c b/bsp/nrf52833/hc_sr04.c index dd839736..eac3fdd0 100644 --- a/bsp/nrf52833/hc_sr04.c +++ b/bsp/nrf52833/hc_sr04.c @@ -28,22 +28,17 @@ #define US_READ_CH_LoToHi 1UL #define US_READ_CH_HiToLo 2UL -// Defines for setting up the trigger pulse width and frequency -#define PULSE_DURATION_MS 0.01 -#define PULSE_OFFSET_MS 200 +// Timer0 interrupt prioprity #define TIMER0_INT_PRIORITY 2 - //=========================== prototypes ======================================= void hc_sr04_gpio(void); void hc_sr04_timers(void); -void hc_sr04_on_set_trigger(double duration_ms, double offset_ms); //=========================== variables ======================================= typedef struct { - us_callback_t us_callback; // Function pointer, stores the callback to use in the GPIOTE_IRQn handler. timer_callback_t timer_callback; // Function pointer, stores the callback to use in the GPIOTE_IRQn handler. @@ -51,7 +46,6 @@ typedef struct { NRF_TIMER_Type *us_read_timer; // Pointer to the TIMER structure used for reading the range on the US sensor volatile uint32_t us_reading; // Variable to store pulse duration of the US echo pin - } us_vars_t; static us_vars_t us_vars; @@ -78,22 +72,17 @@ void hc_sr04_init(us_callback_t us_callback, timer_callback_t timer_callback, NR // initialize timers for US on and US read hc_sr04_timers(); - - // initial timer settings for the trigger pulse - hc_sr04_on_set_trigger(PULSE_DURATION_MS, PULSE_OFFSET_MS); - } /** * @brief This function is public and it sets the PPI channels to allow the US trigger and US echo. Ranging starts by calling this function */ -void hc_sr04_start(void) { - +void hc_sr04_start(void) { // get endpoint addresses - uint32_t us_power_task_addr = (uint32_t)&NRF_GPIOTE->TASKS_OUT[US_ON_CH]; + uint32_t us_power_task_addr = (uint32_t)&NRF_GPIOTE->TASKS_OUT[US_ON_CH]; - uint32_t us_read_event_low_high_addr = (uint32_t)&NRF_GPIOTE->EVENTS_IN[US_READ_CH_LoToHi]; - uint32_t us_read_event_high_low_addr = (uint32_t)&NRF_GPIOTE->EVENTS_IN[US_READ_CH_HiToLo]; + uint32_t us_read_event_low_high_addr = (uint32_t)&NRF_GPIOTE->EVENTS_IN[US_READ_CH_LoToHi]; + uint32_t us_read_event_high_low_addr = (uint32_t)&NRF_GPIOTE->EVENTS_IN[US_READ_CH_HiToLo]; uint32_t timer3_task_start_addr = (uint32_t)&us_vars.us_read_timer->TASKS_START; uint32_t timer3_task_clear_addr = (uint32_t)&us_vars.us_read_timer->TASKS_CLEAR; @@ -129,16 +118,39 @@ void hc_sr04_start(void) { us_vars.us_on_timer->TASKS_START = (TIMER_TASKS_START_TASKS_START_Trigger << TIMER_TASKS_START_TASKS_START_Pos); } +/** + * @brief This function is public and it disables the PPI channels to stop the US trigger and ranging. + */ +void hc_sr04_stop(void) { + // Stop the US ON timer + us_vars.us_on_timer->TASKS_STOP = (TIMER_TASKS_STOP_TASKS_STOP_Trigger << TIMER_TASKS_STOP_TASKS_STOP_Pos); + + // disable PPI channels for US ranging + NRF_PPI->CHENCLR = (PPI_CHENCLR_CH0_Enabled << PPI_CHENSET_CH0_Pos) | + (PPI_CHENCLR_CH1_Enabled << PPI_CHENSET_CH1_Pos) | + (PPI_CHENCLR_CH2_Enabled << PPI_CHENSET_CH2_Pos) | + (PPI_CHENCLR_CH3_Enabled << PPI_CHENSET_CH3_Pos); +} + +/** + * @brief This function is private and it sets the compare registers for US trigger timer + */ +void hc_sr04_on_set_trigger(double duration_ms, double offset_ms) { + + // Set compare values for US on + us_vars.us_on_timer->CC[0] = offset_ms * 1000; // first compare register for setting the offset and start of the pulse + us_vars.us_on_timer->CC[1] = (offset_ms + duration_ms) * 1000; // second compare for pulse duration + +} + /** * @brief This function is public and it enables HFCLK */ -void hfclk_init(void) { - +void hfclk_init(void) { // Configure the external High-frequency Clock. (Needed for correct operation) NRF_CLOCK->EVENTS_HFCLKSTARTED = 0x00; // Clear the flag NRF_CLOCK->TASKS_HFCLKSTART = 0x01; // Start the clock while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {;} // Wait for the clock to actually start. - } //=========================== private ========================================== @@ -147,7 +159,6 @@ void hfclk_init(void) { * @brief Function for initializing GPIOTE for US trigger and US echo signals. */ void hc_sr04_gpio(void) { - //configure US_ON as an output PIN which toggles NRF_GPIOTE->CONFIG[US_ON_CH] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | (US_ON_PIN << GPIOTE_CONFIG_PSEL_Pos) | @@ -175,14 +186,12 @@ void hc_sr04_gpio(void) { NVIC_ClearPendingIRQ(GPIOTE_IRQn); // Clear the flag for any pending radio interrupt NVIC_EnableIRQ(GPIOTE_IRQn); - } /** * @brief This function is private and it sets up the Bitmode and Prescaler for US trigger and US echo timers */ void hc_sr04_timers(void) { - // configure the Timer for US on us_vars.us_on_timer->BITMODE = TIMER_BITMODE_BITMODE_32Bit; us_vars.us_on_timer->PRESCALER = 4UL; @@ -191,33 +200,20 @@ void hc_sr04_timers(void) { us_vars.us_read_timer->BITMODE = TIMER_BITMODE_BITMODE_32Bit; us_vars.us_read_timer->PRESCALER = 4UL; -} - -/** - * @brief This function is private and it sets the compare registers for US trigger timer - */ -void hc_sr04_on_set_trigger(double duration_ms, double offset_ms) { - - // Set compare values for US on - us_vars.us_on_timer->CC[0] = offset_ms * 1000; // first compare register for setting the offset and start of the pulse - us_vars.us_on_timer->CC[1] = (offset_ms + duration_ms) * 1000; // second compare for pulse duration - - // set Timer to clear after the trigger pulse + // set ON Timer to clear after the trigger pulse us_vars.us_on_timer->SHORTS = (TIMER_SHORTS_COMPARE1_CLEAR_Enabled << TIMER_SHORTS_COMPARE1_CLEAR_Pos); - // Configure the Interruptions + // Configure the Interruptions for the Timer0 used as the ON US sensor timer NVIC_DisableIRQ(TIMER0_IRQn); // enable interrupts on Compare 1 us_vars.us_on_timer->INTENSET = (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos); NVIC_SetPriority(TIMER0_IRQn, TIMER0_INT_PRIORITY); - + NVIC_ClearPendingIRQ(TIMER0_IRQn); // Clear the flag for any pending radio interrupt - // enable interupts NVIC_EnableIRQ(TIMER0_IRQn); - } //=========================== interrupt handlers ==============================