diff --git a/bsp/hc_sr04.h b/bsp/hc_sr04.h index 44aa97e3e..bbcf6189b 100644 --- a/bsp/hc_sr04.h +++ b/bsp/hc_sr04.h @@ -16,10 +16,17 @@ #include #include - //=========================== public ====================================== + +//=========================== defines ====================================== + +typedef void(*us_callback_t)(uint32_t); +typedef void(*timer_callback_t)(void); + +//=========================== public ====================================== -void us_init(void (*callback_us)(uint32_t), void (*callback_timer)(void), NRF_TIMER_Type *us_on, NRF_TIMER_Type *us_read); -void us_start(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 hfclk_init(void); #endif diff --git a/bsp/nrf52833/hc_sr04.c b/bsp/nrf52833/hc_sr04.c index 7ab7d6712..30b43b901 100644 --- a/bsp/nrf52833/hc_sr04.c +++ b/bsp/nrf52833/hc_sr04.c @@ -33,34 +33,18 @@ #define PULSE_DURATION_MS 0.01 #define PULSE_OFFSET_MS 200 -#ifndef US_GPIOTE_IRQ -#define US_GPIOTE_IRQ (GPIOTE_IRQn) /**< IRQ corresponding to the Timer used */ -#endif - -#ifndef US_GPIOTE_ISR -#define US_GPIOTE_ISR (GPIOTE_IRQHandler) /**< ISR function handler corresponding to the Timer used */ -#endif - -#ifndef US_TIMER_IRQ -#define US_TIMER_IRQ (TIMER0_IRQn) /**< IRQ corresponding to the Timer used */ -#endif - -#ifndef US_TIMER_ISR -#define US_TIMER_ISR (TIMER0_IRQHandler) /**< ISR function handler corresponding to the Timer used */ -#endif - //=========================== prototypes ======================================= -void us_gpio(void); -void us_timers(void); -void us_on_set_trigger(double duration_ms, double offset_ms); +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 { - void (*us_callback)(uint32_t); // Function pointer, stores the callback to use in the GPIOTE_IRQn handler. - void (*timer_callback)(void); // Function pointer, stores the callback to use in the GPIOTE_IRQn handler. + 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. NRF_TIMER_Type *us_on_timer; // Pointer to the TIMER structure used for triggering US sensor NRF_TIMER_Type *us_read_timer; // Pointer to the TIMER structure used for reading the range on the US sensor @@ -78,36 +62,91 @@ static us_vars_t us_vars; /** * @brief Function for initializing variables and calling private functions for using the hc_sr04 US sensor */ -void us_init(void (*callback_us)(uint32_t), void (*callback_timer)(void), NRF_TIMER_Type *us_on, NRF_TIMER_Type *us_read) { +void hc_sr04_init(us_callback_t us_callback, timer_callback_t timer_callback, NRF_TIMER_Type *us_on, NRF_TIMER_Type *us_read) { // Assign the callback function that will be called when ranging is performed. - us_vars.us_callback = callback_us; + us_vars.us_callback = us_callback; // Assign the callback function that will be called when compare 0 is reached. - us_vars.timer_callback = callback_timer; + us_vars.timer_callback = timer_callback; // Assign the Timers for turning ON the US sensor and for US sensor readings us_vars.us_on_timer = us_on; us_vars.us_read_timer = us_read; // initialize GPIOTE for US on and US read - us_gpio(); + hc_sr04_gpio(); // initialize timers for US on and US read - us_timers(); + hc_sr04_timers(); // initial timer settings for the trigger pulse - us_on_set_trigger(PULSE_DURATION_MS, PULSE_OFFSET_MS); + 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) { + + // get endpoint addresses + 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 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; + uint32_t timer3_task_stop_addr = (uint32_t)&us_vars.us_read_timer->TASKS_STOP; + uint32_t timer3_task_capture_addr = (uint32_t)&us_vars.us_read_timer->TASKS_CAPTURE[0]; + + uint32_t timer2_events_compare_0_addr = (uint32_t)&us_vars.us_on_timer->EVENTS_COMPARE[0]; + uint32_t timer2_events_compare_1_addr = (uint32_t)&us_vars.us_on_timer->EVENTS_COMPARE[1]; + + + // set endpoints + NRF_PPI->CH[0].EEP = timer2_events_compare_0_addr; + NRF_PPI->CH[0].TEP = us_power_task_addr; + + NRF_PPI->CH[1].EEP = timer2_events_compare_1_addr; + NRF_PPI->CH[1].TEP = us_power_task_addr; + + NRF_PPI->CH[2].EEP = us_read_event_low_high_addr; + NRF_PPI->CH[2].TEP = timer3_task_clear_addr; + NRF_PPI->FORK[2].TEP = timer3_task_start_addr; + + NRF_PPI->CH[3].EEP = us_read_event_high_low_addr; + NRF_PPI->CH[3].TEP = timer3_task_capture_addr; + NRF_PPI->FORK[3].TEP = timer3_task_stop_addr; + + // enable channels + NRF_PPI->CHENSET = (PPI_CHENSET_CH0_Enabled << PPI_CHENSET_CH0_Pos) | + (PPI_CHENSET_CH1_Enabled << PPI_CHENSET_CH1_Pos) | + (PPI_CHENSET_CH2_Enabled << PPI_CHENSET_CH2_Pos) | + (PPI_CHENSET_CH3_Enabled << PPI_CHENSET_CH3_Pos); +} + +/** + * @brief This function is public and it enables HFCLK + */ +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 ========================================== + /** * @brief Function for initializing GPIOTE for US trigger and US echo signals. */ -void us_gpio(void) { +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) | @@ -129,20 +168,20 @@ void us_gpio(void) { (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos); // Configure the Interruptions - NVIC_DisableIRQ(US_GPIOTE_IRQ); + NVIC_DisableIRQ(GPIOTE_IRQn); // Enable interrupt for the HiToLo edge of the input NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN2_Set << GPIOTE_INTENSET_IN2_Pos); - NVIC_ClearPendingIRQ(US_GPIOTE_IRQ); // Clear the flag for any pending radio interrupt + NVIC_ClearPendingIRQ(GPIOTE_IRQn); // Clear the flag for any pending radio interrupt - NVIC_EnableIRQ(US_GPIOTE_IRQ); + 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 us_timers(void) { +void hc_sr04_timers(void) { // configure the Timer for US on us_vars.us_on_timer->BITMODE = TIMER_BITMODE_BITMODE_32Bit; @@ -157,7 +196,7 @@ void us_timers(void) { /** * @brief This function is private and it sets the compare registers for US trigger timer */ -void us_on_set_trigger(double duration_ms, double offset_ms) { +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 @@ -185,69 +224,13 @@ void us_on_set_trigger(double duration_ms, double 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 us_start(void) { - - // get endpoint addresses - 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 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; - uint32_t timer3_task_stop_addr = (uint32_t)&us_vars.us_read_timer->TASKS_STOP; - uint32_t timer3_task_capture_addr = (uint32_t)&us_vars.us_read_timer->TASKS_CAPTURE[0]; - - uint32_t timer2_events_compare_0_addr = (uint32_t)&us_vars.us_on_timer->EVENTS_COMPARE[0]; - uint32_t timer2_events_compare_1_addr = (uint32_t)&us_vars.us_on_timer->EVENTS_COMPARE[1]; - - - // set endpoints - NRF_PPI->CH[0].EEP = timer2_events_compare_0_addr; - NRF_PPI->CH[0].TEP = us_power_task_addr; - - NRF_PPI->CH[1].EEP = timer2_events_compare_1_addr; - NRF_PPI->CH[1].TEP = us_power_task_addr; - - NRF_PPI->CH[2].EEP = us_read_event_low_high_addr; - NRF_PPI->CH[2].TEP = timer3_task_clear_addr; - NRF_PPI->FORK[2].TEP = timer3_task_start_addr; - - NRF_PPI->CH[3].EEP = us_read_event_high_low_addr; - NRF_PPI->CH[3].TEP = timer3_task_capture_addr; - NRF_PPI->FORK[3].TEP = timer3_task_stop_addr; - - // enable channels - NRF_PPI->CHENSET = (PPI_CHENSET_CH0_Enabled << PPI_CHENSET_CH0_Pos) | - (PPI_CHENSET_CH1_Enabled << PPI_CHENSET_CH1_Pos) | - (PPI_CHENSET_CH2_Enabled << PPI_CHENSET_CH2_Pos) | - (PPI_CHENSET_CH3_Enabled << PPI_CHENSET_CH3_Pos); - - -} - -/** - * @brief This function is public and it enables HFCLK - */ -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. - -} - //=========================== interrupt handlers ============================== /** * @brief ISR for reading ranging value from the sensor. It captures the value of the Timer1 (pulse width) and calls the callback for US reading * */ -void US_GPIOTE_ISR(void){ +void GPIOTE_IRQHandler(void){ if(NRF_GPIOTE->EVENTS_IN[US_READ_CH_HiToLo] != 0) { @@ -265,7 +248,7 @@ void US_GPIOTE_ISR(void){ /** * brief ISR for TIMER0 which is in charge of controling the US sensor trigger pin */ -void US_TIMER_ISR(void){ +void TIMER0_IRQHandler(void){ if((NRF_TIMER0->EVENTS_COMPARE[1] != 0) && ((NRF_TIMER0->INTENSET & TIMER_INTENSET_COMPARE1_Msk) != 0)) { diff --git a/projects/01bsp_us_ranging/01bsp_us_ranging.c b/projects/01bsp_us_ranging/01bsp_us_ranging.c index 8e1dd965a..52248db13 100644 --- a/projects/01bsp_us_ranging/01bsp_us_ranging.c +++ b/projects/01bsp_us_ranging/01bsp_us_ranging.c @@ -44,10 +44,10 @@ int main(void) { //db_board_init(); // initilize the US sensor, set callback and chose the timers - us_init(&us_callback, &timer_callback, timer0, timer1); + hc_sr04_init(&us_callback, &timer_callback, timer0, timer1); // start ranging - us_start(); + hc_sr04_start(); // start high frequency clock needed for PPI hfclk_init();