Urbanite: Parking aid system
|
Portable functions to interact with the ultrasound FSM library. All portable functions must be implemented in this file. More...
#include <stdio.h>
#include <math.h>
#include "port_ultrasound.h"
#include "port_system.h"
#include "stm32f4_system.h"
#include "stm32f4_ultrasound.h"
Data Structures | |
struct | stm32f4_ultrasound_hw_t |
Structure to define the HW dependencies of aN ultrasound sensor. More... | |
Functions | |
stm32f4_ultrasound_hw_t * | _stm32f4_ultrasound_get (uint32_t ultrasound_id) |
Get the ultrasound struct with the given ID. More... | |
static void | _timer_trigger_setup () |
Configure the timer that controls the duration of the trigger signal. More... | |
static void | _timer_echo_setup (uint32_t ultrasound_id) |
Configure the timer that controls the duration of the echo signal. More... | |
void | _timer_new_measurement_setup () |
Configure the timer that controls the duration of the new measurement. More... | |
void | port_ultrasound_init (uint32_t ultrasound_id) |
Configure the HW specifications of a given ultrasound sensor. More... | |
void | port_ultrasound_start_measurement (uint32_t ultrasound_id) |
Start a new measurement of the ultrasound sensor. More... | |
void | port_ultrasound_stop_trigger_timer (uint32_t ultrasound_id) |
Stop the timer that controls the trigger signal. More... | |
void | port_ultrasound_stop_echo_timer (uint32_t ultrasound_id) |
Stop the timer that controls the echo signal. More... | |
void | port_ultrasound_start_new_measurement_timer () |
Start the timer that controls the new measurement. More... | |
void | port_ultrasound_stop_new_measurement_timer () |
Stop the timer that controls the new measurement. More... | |
void | port_ultrasound_reset_echo_ticks (uint32_t ultrasound_id) |
Reset the time ticks of the echo signal. More... | |
void | port_ultrasound_stop_ultrasound (uint32_t ultrasound_id) |
Stop all the timers of the ultrasound sensor and reset the echo ticks. More... | |
bool | port_ultrasound_get_trigger_ready (uint32_t ultrasound_id) |
Get the readiness of the trigger signal. More... | |
void | port_ultrasound_set_trigger_ready (uint32_t ultrasound_id, bool trigger_ready) |
Set the readiness of the trigger signal. More... | |
bool | port_ultrasound_get_trigger_end (uint32_t ultrasound_id) |
Get the status of the trigger signal. More... | |
void | port_ultrasound_set_trigger_end (uint32_t ultrasound_id, bool trigger_end) |
Set the status of the trigger signal. More... | |
uint32_t | port_ultrasound_get_echo_init_tick (uint32_t ultrasound_id) |
Get the time tick when the init of echo signal was received. More... | |
void | port_ultrasound_set_echo_init_tick (uint32_t ultrasound_id, uint32_t echo_init_tick) |
Set the time tick when the init of echo signal was received. More... | |
uint32_t | port_ultrasound_get_echo_end_tick (uint32_t ultrasound_id) |
Get the time tick when the end of echo signal was received. More... | |
void | port_ultrasound_set_echo_end_tick (uint32_t ultrasound_id, uint32_t echo_end_tick) |
Set the time tick when the end of echo signal was received. More... | |
bool | port_ultrasound_get_echo_received (uint32_t ultrasound_id) |
Get the status of the echo signal. More... | |
void | port_ultrasound_set_echo_received (uint32_t ultrasound_id, bool echo_received) |
Set the status of the echo signal. More... | |
uint32_t | port_ultrasound_get_echo_overflows (uint32_t ultrasound_id) |
Get the number of overflows of the echo signal timer. More... | |
void | port_ultrasound_set_echo_overflows (uint32_t ultrasound_id, uint32_t echo_overflows) |
Set the number of overflows of the echo signal timer. More... | |
void | stm32f4_ultrasound_set_new_trigger_gpio (uint32_t ultrasound_id, GPIO_TypeDef *p_port, uint8_t pin) |
Auxiliary function to change the GPIO and pin of the trigger pin of an ultrasound transceiver. This function is used for testing purposes mainly although it can be used in the final implementation if needed. More... | |
void | stm32f4_ultrasound_set_new_echo_gpio (uint32_t ultrasound_id, GPIO_TypeDef *p_port, uint8_t pin) |
Auxiliary function to change the GPIO and pin of the echo pin of an ultrasound transceiver. This function is used for testing purposes mainly although it can be used in the final implementation if needed. More... | |
Variables | |
static stm32f4_ultrasound_hw_t | ultrasounds_arr [] |
Array of elements that represents the HW characteristics of the ultrasounds connected to the STM32F4 platform. More... | |
Portable functions to interact with the ultrasound FSM library. All portable functions must be implemented in this file.
stm32f4_ultrasound_hw_t* _stm32f4_ultrasound_get | ( | uint32_t | ultrasound_id | ) |
Get the ultrasound struct with the given ID.
ultrasound_id | Ultrasound ID. |
|
static |
Configure the timer that controls the duration of the echo signal.
This function configures the timer as input capture to measure the duration of the echo signal. port_ultrasound_init()
public function to configure the timer.
Follow the example of the section Ejemplo: captura de entrada (input capture)
of the Libro de Fundamentos
to configure the timer as input capture.
Use the timer indicated in the main page.
TODO alumnos:
✅ 1. Enable the clock of the timer that controls the echo signal. Check the reference manual of the STM32F4 to know if the timer is connected to the APB1 or APB2 bus (i.e.
RCC->APB1ENR
orRCC->APB2ENR
).
✅ 2. Disable the counter of the timer (registerCR1
of the timer) because we want to configure it.
✅ 3. Set the values of the prescaler and the auto-reload registers. Configure PSC for a resolution of 1 us (1 MHz) and ARR high enough to avoid too many overflows, e.g. it maximum value.
✅ 4. Set the auto-reload preload bit (ARPE) in the control register (CR1) to enable the auto-reload register. Also enable the update generation bit (UG) in the event generation register (EGR) to force the update of the registers.
✅ 5. Set the direction as input in the Capture/Compare mode register (CCMRx).x
is 1 for channels 1 and 2, and 2 for channels 3 and 4. Check the table "Table 11. Alternate function" in the datasheet to identify the channel related to timer associated to the pin of the echo signal.
✅ 6. Disable digital filtering by clearing the ICxF bits in the Capture/Compare mode register (CCMRx).
✅ 7. Select the edge of the active transition in the Capture/Compare enable register (CCER). Set the bits CCxNP and CCxP to detect both rising and falling edges.
✅ 8. Program the input prescaler to capture each valid transition. Set the ICxPSC bits in the Capture/Compare mode register (CCMRx) to 0.
✅ 9. Enable the Capture/compare enable register (CCER) for the corresponding channel.
✅ 10. Enable the Capture/Compare interrupts bit (CCxIE) for the corresponding channel in the DMA/interrupt enable register (DIER).
✅ 11. Enable the update interrupt bit (UIE) in the DMA/interrupt enable register (DIER).
✅ 12. Set the priority of the timer interrupt in the NVIC using theNVIC_SetPriority()
function and theTIMx_IRQn
interrupt with the level of priority and sub-priority shown in the main page.
ultrasound_id | Ultrasound ID. This ID is used to configure the timer that controls the echo signal of the ultrasound sensor. |
void _timer_new_measurement_setup | ( | ) |
Configure the timer that controls the duration of the new measurement.
This function configures the timer to generate an internal interrupt to control the duration of a measurement. The duration of a measurement is defined in the PORT_PARKING_SENSOR_TIMEOUT_MS
macro. This function is called by the port_ultrasound_init()
public function to configure the timer that controls the duration of the new measurement.
Use the timer indicated in the main page.
TODO alumnos:
✅ 1. Follow the same steps as in the
_timer_trigger_setup()
function to configure the timer that controls the duration of the new measurement.
|
static |
Configure the timer that controls the duration of the trigger signal.
This function configures the timer to generate internal interrupts to control the raise and fall of the trigger signal. The duration of the trigger signal is defined in the PORT_PARKING_SENSOR_TRIGGER_UP_US
macro. This function is called by the port_ultrasound_init()
public function to configure the timer that controls the duration of the trigger signal.
Use the timer indicated in the main page.
There are 2 ways to calculate the ARR
and PSC
values. You can implement any of them to configure the timer duration according to the PORT_PARKING_SENSOR_TRIGGER_UP_US
macro. Do not set the values directly!
Option 1. Efficient algorithm.
This option is the most efficient way to calculate the ARR
and PSC
values. It is based on the fact that the ARR
value is near or equal to its maximum value (65535.0). And only one update of the PSC
is needed. This eliminates the need for a loop, which could be slow if ARR
is much larger than 0xFFFF.
Option 2. Iterative algorithm.
This option, on the other hand, starts with PSC
equals 0
and re-computes in an iterative loop the values of ARR
and PSC
. ⚠️ WARNING! This option is not recommended. You should consider that this option is much slower than the efficient algorithm and this option will make the test_port_ultrasound
take a long time to execute (several seconds up to few minutes).
ARR
and PSC
registers. The math.h
library is included to use the round()
function. ARR
and PSC
registers, cast the result of the round()
function to uint32_t
. TODO alumnos:
✅ 1. Enable the clock of the timer that controls the trigger signal. Check the reference manual of the STM32F4 to know if the timer is connected to the APB1 or APB2 bus (i.e.
RCC->APB1ENR
orRCC->APB2ENR
).
✅ 2. Disable the counter of the timer (registerCR1
of the timer) because we want to configure it.
✅ 3. Enable the autoreload preload (bitARPE
of the registerCR1
) to enable the autoreload register.
✅ 4. Set the counter of the timer to 0 (registerCNT
) to start counting from 0.
✅ 5. Compute the prescaler and the auto-reload register to set the duration of the trigger signal. The duration of the trigger signal is defined in thePORT_PARKING_SENSOR_TRIGGER_UP_US
macro. Use any of the two options to calculate theARR
andPSC
values:Option 1. Efficient algorithm.
➡️ 6a. ConvertSystemCoreClock
to double and store them in local variables. This is to ensure that the subsequent calculations are performed in floating-point arithmetic.
➡️ 6b. Compute an initial value for thePSC
register considering the maximum value ofARR
(65535.0). Store it in a local variable of typedouble
.
💡 Use all variable and numbers asdouble
(i.e., use 1.0 instead of 1).
💡 Use the functionround()
from themath.h
library to round the value of thePSC
. Use round instead of casting todouble
, because casting trunks the decimal value.
➡️ 6c. Re-compute the value of theARR
register with the previously computedPSC
value. Store it in a local variable of typedouble
.
💡 This would makeARR
less than or equal to 65535.0, and we will adjustARR
andPSC
if necessary. This eliminates the need for a loop, which could be slow ifARR
is much larger than 0xFFFF.
💡 Use the functionround()
to round the value of theARR
.
➡️ 6d. Check if the new value ofARR
is greater than 0xFFFF (or 65535.0). If it is, incrementPSC
by 1.0 and recalculateARR
. This is to ensure thatARR
does not exceed 0xFFFF.
💡 Because the re-computed value ofARR
will be close to its maximum, adding 1.0 to thePSC
is enough to ensure that theARR
does not exceeds it maximum value and we do not need to iterate over it, making this algorithm faster than using awhile(){}
loop.
➡️ 6e. Continue in ✅ 7.
Option 2. Iterative algorithm.
➡️ 6a. ConvertSystemCoreClock
to double and store them in local variables. This is to ensure that the subsequent calculations are performed in floating-point arithmetic.
➡️ 6b. Compute an initial value for theARR
register considering a minimum value ofPSC
(0.0). Store it in a local variable of typedouble
.
💡 Use all variable and numbers asdouble
(i.e., use 1.0 instead of 1).
💡 Use the functionround()
from themath.h
library to round the value of theARR
. Use round instead of casting todouble
, because casting trunks the decimal value.
➡️ 6c. If the value ofARR
is greater than 0xFFFF (or 65535.0), increment thePSC
by 1.0 and recalculateARR
. This is to ensure thatARR
does not exceed 0xFFFF.
➡️ 6d. Do this in an iterativewhile(){}
loop.
➡️ 6e. Continue in ✅ 7.
✅ 6. Load the values computed forARR
andPSC
into the corresponding registers of the timer.
💡 Ensure that values are rounded before casting.
✅ 7. ThePSC
andARR
values are currently in the preload registers. To load them into the active registers we need an update event. We achieve this by setting theUG
bit of theEGR
register. It is important to do this at the end of the configuration of the timer.
✅ 8. Clear the update interrupt flag (bitUIF
of the registerSR
) to avoid an unwanted interrupt.
✅ 9. Enable the interrupts of the timer by setting theUIE
bit of theDIER
register.
✅ 10. Set the priority of the timer interrupt in the NVIC using theNVIC_SetPriority()
function and theTIMx_IRQn
interrupt with the level of priority and sub-priority shown in the main page. Do not enable the timer interrupt yet. This will be done when the trigger signal must be sent.
uint32_t port_ultrasound_get_echo_end_tick | ( | uint32_t | ultrasound_id | ) |
Get the time tick when the end of echo signal was received.
TODO alumnos:
✅ 1. Return the value of the field
echo_end_tick
.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
uint32_t port_ultrasound_get_echo_init_tick | ( | uint32_t | ultrasound_id | ) |
Get the time tick when the init of echo signal was received.
TODO alumnos:
✅ 1. Return the value of the field
echo_init_tick
.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
uint32_t port_ultrasound_get_echo_overflows | ( | uint32_t | ultrasound_id | ) |
Get the number of overflows of the echo signal timer.
This function returns the number of overflows of the echo signal timer. It is used to calculate the real time elapsed in the echo signal.
TODO alumnos:
✅ 1. Return the value of the field
echo_overflows
.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
bool port_ultrasound_get_echo_received | ( | uint32_t | ultrasound_id | ) |
Get the status of the echo signal.
This function returns the status of the echo signal. It will be true
if the echo signal has been received (both the init and end ticks).
TODO alumnos:
✅ 1. Return the value of the field
echo_received
.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
bool port_ultrasound_get_trigger_end | ( | uint32_t | ultrasound_id | ) |
Get the status of the trigger signal.
This function returns the status of the trigger signal. It will be true
if the time to trigger the ultrasound sensor has finished.
TODO alumnos:
✅ 1. Return the value of the field
trigger_end
.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
bool port_ultrasound_get_trigger_ready | ( | uint32_t | ultrasound_id | ) |
Get the readiness of the trigger signal.
This function returns the status of readiness the trigger signal. If it is true, the ultrasound sensor is ready to start a new measurement.
TODO alumnos:
✅ 1. Return the value of the field
trigger_ready
.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
void port_ultrasound_init | ( | uint32_t | ultrasound_id | ) |
Configure the HW specifications of a given ultrasound sensor.
Assuming we are using an STM32F4-based platform, this function must call the following functions:
TODO alumnos:
✅ 1. Initialize the fields of the ultrasound struct. Set the variables related to ticks to 0 and the flags to false but the trigger_ready to true.
✅ 2. Configure the trigger pin as output and no pull up neither pull down connection.
✅ 3. Configure the echo pin as alternate function and no pull up neither pull down connection.
✅ 4. Configure the alternate function of the echo pin.
✅ 5. Call the 3 private functions that configure the timers of the trigger, echo and new measurement.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
void port_ultrasound_reset_echo_ticks | ( | uint32_t | ultrasound_id | ) |
Reset the time ticks of the echo signal.
This function resets the time ticks of the echo signal once the distance has been calculated.
TODO alumnos:
✅ 1. Reset the time ticks of the echo signal, and the overflows. Also, reset the flag
echo_received
.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
void port_ultrasound_set_echo_end_tick | ( | uint32_t | ultrasound_id, |
uint32_t | echo_end_tick | ||
) |
Set the time tick when the end of echo signal was received.
This function sets the time tick when the end of echo signal was received. It is called by the ISR of the input capture of the echo signal.
TODO alumnos:
✅ 1. Set the value of the field
echo_end_tick
with the received value.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
echo_end_tick | Time tick when the end of echo signal was received. |
void port_ultrasound_set_echo_init_tick | ( | uint32_t | ultrasound_id, |
uint32_t | echo_init_tick | ||
) |
Set the time tick when the init of echo signal was received.
This function sets the time tick when the init of echo signal was received. It is called by the ISR of the input capture of the echo signal.
TODO alumnos:
✅ 1. Set the value of the field
echo_init_tick
with the received value.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
echo_init_tick | Time tick when the init of echo signal was received. |
void port_ultrasound_set_echo_overflows | ( | uint32_t | ultrasound_id, |
uint32_t | echo_overflows | ||
) |
Set the number of overflows of the echo signal timer.
This function sets the number of overflows of the echo signal timer. It is called by the ISR of the input capture of the echo signal when an overflow occurs to increment the number of overflows.
TODO alumnos:
✅ 1. Set the value of the field
echo_overflows
with the received value.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
echo_overflows | Number of overflows of the echo signal timer. |
void port_ultrasound_set_echo_received | ( | uint32_t | ultrasound_id, |
bool | echo_received | ||
) |
Set the status of the echo signal.
This function sets the status of the echo signal. The ISR of the input capture of the echo signal calls this function to set the status of the echo signal when both the init and end ticks have been received.
TODO alumnos:
✅ 1. Set the value of the field
echo_received
with the received value.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
echo_received | Status of the echo signal. |
void port_ultrasound_set_trigger_end | ( | uint32_t | ultrasound_id, |
bool | trigger_end | ||
) |
Set the status of the trigger signal.
This function sets the status of the trigger signal. It will be true
to indicate that the time to trigger the ultrasound sensor has finished and the trigger signal is low.
TODO alumnos:
✅ 1. Set the value of the field
trigger_end
with the received value.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
trigger_end | Status of the trigger signal. |
void port_ultrasound_set_trigger_ready | ( | uint32_t | ultrasound_id, |
bool | trigger_ready | ||
) |
Set the readiness of the trigger signal.
This function sets the status of readiness of the trigger signal. If it is true, the ultrasound sensor will ready to start a new measurement.
TODO alumnos:
✅ 1. Set the value of the field
trigger_ready
with the received value.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
trigger_ready | Status of the trigger signal. |
void port_ultrasound_start_measurement | ( | uint32_t | ultrasound_id | ) |
Start a new measurement of the ultrasound sensor.
This function prepares the timer of the trigger and the timer of the echo signal to start a new measurement. It also enables the timer that controls the new measurement.
TODO alumnos:
✅ 1. Reset the flag
trigger_ready
to indicate that a new measurement has started.
✅ 2. Reset the counters (CNT
) of the trigger timer, the echo timer, and the new measurement timer. Enclose the configuration of the trigger and echo timers within a conditional statement.
✅ 3. Set the trigger pin to high. You can use theBSRR
or call thestm32f4_system_gpio_write()
function.
✅ 4. Enable the timers interrupts in the NVIC using theNVIC_EnableIRQ()
function and theTIMx_IRQn
interrupts.
✅ 5. Enable the timers of the new measurement, the trigger timer, and the echo timer (registerCR1
of the timers). Enclose the configuration of the trigger and echo timer within a conditional statement.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
void port_ultrasound_start_new_measurement_timer | ( | void | ) |
Start the timer that controls the new measurement.
This function starts the timer that controls the new measurement.
TODO alumnos:
✅ 1. Enable the interrupt of the new measurement timer in the NVIC.
✅ 2. Enable the new measurement timer (registerCR1
of the timer).
void port_ultrasound_stop_echo_timer | ( | uint32_t | ultrasound_id | ) |
Stop the timer that controls the echo signal.
This function stops the timer that controls the echo signal because the echo signal has been received.
TODO alumnos:
✅ 1. Disable the echo timer (register
CR1
of the timer). Enclose the configuration of the echo timer within a conditional statement.
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
void port_ultrasound_stop_new_measurement_timer | ( | void | ) |
Stop the timer that controls the new measurement.
This function stops the timer that controls the new measurement.
TODO alumnos:
✅ 1. Disable the new measurement timer (register
CR1
of the timer).
void port_ultrasound_stop_trigger_timer | ( | uint32_t | ultrasound_id | ) |
Stop the timer that controls the trigger signal.
This function stops the timer that controls the trigger signal because the time to trigger the ultrasound sensor has finished. It also sets the trigger signal to low.
TODO alumnos:
✅ 1. Set the trigger pin to low. You can use the
BSRR
or call thestm32f4_system_gpio_write()
function.
✅ 2. Disable the trigger timer (registerCR1
of the timer).
ultrasound_id | Ultrasound ID. This index is used to select the element of the ultrasound_arr[] array |
void port_ultrasound_stop_ultrasound | ( | uint32_t | ultrasound_id | ) |
Stop all the timers of the ultrasound sensor and reset the echo ticks.
This function calls the functions to stop the trigger and echo timers and to reset the echo ticks.
TODO alumnos:
✅ 1. Call all the 4 functions to stop the trigger timer, the echo timer, the new measurement timer, and to reset the echo ticks.
void stm32f4_ultrasound_set_new_echo_gpio | ( | uint32_t | ultrasound_id, |
GPIO_TypeDef * | p_port, | ||
uint8_t | pin | ||
) |
Auxiliary function to change the GPIO and pin of the echo pin of an ultrasound transceiver. This function is used for testing purposes mainly although it can be used in the final implementation if needed.
ultrasound_id | ID of the echo signal to change. |
p_port | New GPIO port for the echo signal. |
pin | New GPIO pin for the echo signal. |
void stm32f4_ultrasound_set_new_trigger_gpio | ( | uint32_t | ultrasound_id, |
GPIO_TypeDef * | p_port, | ||
uint8_t | pin | ||
) |
Auxiliary function to change the GPIO and pin of the trigger pin of an ultrasound transceiver. This function is used for testing purposes mainly although it can be used in the final implementation if needed.
ultrasound_id | ID of the trigger signal to change. |
p_port | New GPIO port for the trigger signal. |
pin | New GPIO pin for the trigger signal. |
|
static |
Array of elements that represents the HW characteristics of the ultrasounds connected to the STM32F4 platform.
This must be hidden from the user, so it is declared as static. To access the elements of this array, use the function _stm32f4_ultrasound_get()
.