Urbanite: Parking aid system
stm32f4_system.c File Reference

This file implements port layer for the system functions in the STM32F4 platform. More...

#include "port_system.h"
#include "stm32f4_system.h"

Macros

#define HSI_VALUE   ((uint32_t)16000000)
 
#define RCC_HSI_CALIBRATION_DEFAULT   0x10U
 
#define TICK_FREQ_1KHZ   1U
 
#define NVIC_PRIORITY_GROUP_0   ((uint32_t)0x00000007)
 
#define NVIC_PRIORITY_GROUP_4   ((uint32_t)0x00000003)
 
#define POWER_REGULATOR_VOLTAGE_SCALE3   0x01
 

Functions

static void system_clock_config (void)
 System Clock Configuration. More...
 
void SystemInit (void)
 Setup the microcontroller system Initialize the FPU setting, vector table location and External memory configuration. More...
 
uint32_t port_system_init ()
 Initializes the system.
 
void port_system_delay_ms (uint32_t ms)
 Delays the program execution for the specified number of milliseconds. More...
 
void port_system_delay_until_ms (uint32_t *p_t, uint32_t ms)
 Delays the program execution until the specified number of milliseconds since the system started. More...
 
uint32_t port_system_get_millis ()
 Returns the number of milliseconds since the system started. More...
 
void port_system_set_millis (uint32_t ms)
 Sets the number of milliseconds since the system started. More...
 
void stm32f4_system_gpio_config (GPIO_TypeDef *p_port, uint8_t pin, uint8_t mode, uint8_t pupd)
 Configure the mode and pull of a GPIO. More...
 
void stm32f4_system_gpio_config_exti (GPIO_TypeDef *p_port, uint8_t pin, uint32_t mode)
 Configure the external interruption or event of a GPIO. More...
 
void stm32f4_system_gpio_exti_enable (uint8_t pin, uint8_t priority, uint8_t subpriority)
 Enable interrupts of a GPIO line (pin) More...
 
void stm32f4_system_gpio_exti_disable (uint8_t pin)
 Disable interrupts of a GPIO line (pin) More...
 
bool stm32f4_system_gpio_read (GPIO_TypeDef *p_port, uint8_t pin)
 Read the digital value of a GPIO. More...
 
void stm32f4_system_gpio_write (GPIO_TypeDef *p_port, uint8_t pin, bool value)
 Write a digital value in a GPIO atomically. More...
 
void stm32f4_system_gpio_toggle (GPIO_TypeDef *p_port, uint8_t pin)
 Toggle the value of a GPIO. More...
 
void stm32f4_system_gpio_config_alternate (GPIO_TypeDef *p_port, uint8_t pin, uint8_t alternate)
 Configure the alternate function of a GPIO. More...
 
void port_system_systick_resume ()
 Resume Tick increment. More...
 
void port_system_systick_suspend ()
 Suspend Tick increment. More...
 
void port_system_power_stop ()
 Set the system in stop mode for low power consumption. More...
 
void port_system_power_sleep ()
 Set the system in sleep mode for low power consumption. More...
 
void port_system_sleep ()
 Enable low power consumption in sleep mode. More...
 

Variables

static volatile uint32_t msTicks = 0
 
uint32_t SystemCoreClock = HSI_VALUE
 
const uint8_t AHBPrescTable [16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}
 
const uint8_t APBPrescTable [8] = {0, 0, 0, 0, 1, 2, 3, 4}
 

Detailed Description

This file implements port layer for the system functions in the STM32F4 platform.

Author
Josué Pagán Ortiz (j.pag.nosp@m.an@u.nosp@m.pm.es)
Date
01-01-2024

Macro Definition Documentation

◆ HSI_VALUE

#define HSI_VALUE   ((uint32_t)16000000)

Value of the Internal oscillator in Hz

◆ NVIC_PRIORITY_GROUP_0

#define NVIC_PRIORITY_GROUP_0   ((uint32_t)0x00000007)

0 bit for pre-emption priority, \ 4 bits for subpriority

◆ NVIC_PRIORITY_GROUP_4

#define NVIC_PRIORITY_GROUP_4   ((uint32_t)0x00000003)

4 bits for pre-emption priority, \ 0 bit for subpriority

◆ POWER_REGULATOR_VOLTAGE_SCALE3

#define POWER_REGULATOR_VOLTAGE_SCALE3   0x01

Scale 3 mode: the maximum value of fHCLK is 120 MHz.

◆ RCC_HSI_CALIBRATION_DEFAULT

#define RCC_HSI_CALIBRATION_DEFAULT   0x10U

Default HSI calibration trimming value

◆ TICK_FREQ_1KHZ

#define TICK_FREQ_1KHZ   1U

Freqency in kHz of the System tick

Function Documentation

◆ port_system_delay_ms()

void port_system_delay_ms ( uint32_t  ms)

Delays the program execution for the specified number of milliseconds.

Parameters
msNumber of milliseconds to delay.

◆ port_system_delay_until_ms()

void port_system_delay_until_ms ( uint32_t *  t,
uint32_t  ms 
)

Delays the program execution until the specified number of milliseconds since the system started.

Parameters
tPointer to the variable that stores the number of milliseconds to delay until.
msNumber of milliseconds to delay until.
Note
This function modifies the value of the variable pointed by t to the number of milliseconds to delay until.
This function is useful to implement periodic tasks.

◆ port_system_get_millis()

uint32_t port_system_get_millis ( void  )

Returns the number of milliseconds since the system started.

Return values
numberof milliseconds since the system started.

◆ port_system_power_sleep()

void port_system_power_sleep ( void  )

Set the system in sleep mode for low power consumption.

The function sets the state of the power regulator in sleep mode.
After that, the function sets the system mode in sleep mode, to enter in sleep mode when calling __WFI() (wait for interruption).
The system remains in this line until an external interruption or timer interruption occurs.

ONLY IF YOU NEED IT! TODO alumnos Version 4:

✅ 1. Copy the following code in the file stm32f4_system.c.

{
MODIFY_REG(PWR->CR, (PWR_CR_PDDS | PWR_CR_LPDS), PWR_CR_LPDS); // Select the regulator state in Stop mode: Set PDDS and LPDS bits according to PWR_Regulator value
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); // Reset SLEEPDEEP bit of Cortex System Control Register
__WFI(); // Select Sleep mode entry : Request Wait For Interrupt
}

◆ port_system_power_stop()

void port_system_power_stop ( void  )

Set the system in stop mode for low power consumption.

The function sets the state of the power regulator in stop mode.
After that, the function sets the system mode in sleep mode, to enter in stop mode when calling __WFI() (wait for interruption).
The system remains in this line until an external interruption or timer interruption occurs.
If an interruption occurs the system wakes up and resets the system mode.

TODO alumnos Version 4:

✅ 1. Copy the following code in the file stm32f4_system.c.

{
MODIFY_REG(PWR->CR, (PWR_CR_PDDS | PWR_CR_LPDS), PWR_CR_LPDS); // Select the regulator state in Stop mode: Set PDDS and LPDS bits according to PWR_Regulator value
SCB->SCR |= ((uint32_t)SCB_SCR_SLEEPDEEP_Msk); // Set SLEEPDEEP bit of Cortex System Control Register
__WFI(); // Select Stop mode entry : Request Wait For Interrupt
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); // Reset SLEEPDEEP bit of Cortex System Control Register
}

◆ port_system_set_millis()

void port_system_set_millis ( uint32_t  ms)

Sets the number of milliseconds since the system started.

Parameters
msNew number of milliseconds since the system started.

◆ port_system_sleep()

void port_system_sleep ( void  )

Enable low power consumption in sleep mode.

TODO alumnos Version 4:

✅ 1. Call function port_system_systick_suspend() to suspend the count of the SysTick.
✅ 2. Call function port_system_power_sleep() to enter sleep in sleep mode.

◆ port_system_systick_resume()

void port_system_systick_resume ( void  )

Resume Tick increment.

The SysTick timer is the source of time base. It is used to generate interrupts at regular time intervals. Once this function is called, the SysTick interrupt will be enabled and so Tick increment is resumed.

TODO alumnos Version 4:

✅ 1. Copy the following code in the file stm32f4_system.c.

{
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
}

◆ port_system_systick_suspend()

void port_system_systick_suspend ( void  )

Suspend Tick increment.

The SysTick timer is the source of time base. It is used to generate interrupts at regular time intervals. Once this function is called, the SysTick interrupt will be disabled so it saves more energy and it does not generate any interruption.

TODO alumnos Version 4:

✅ 1. Copy the following code in the file stm32f4_system.c.

{
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
}

◆ stm32f4_system_gpio_config()

void stm32f4_system_gpio_config ( GPIO_TypeDef *  p_port,
uint8_t  pin,
uint8_t  mode,
uint8_t  pupd 
)

Configure the mode and pull of a GPIO.

  ==============================================================================
                          ##### How to use GPIOs #####
  ==============================================================================
  [..]
    (#) Enable the GPIO AHB clock using the RCC->AHB1ENR register.

    (#) Configure the GPIO pin.
        (++) Configure the IO mode.
        (++) Activate Pull-up, Pull-down resistor.
        (++) In case of Output or alternate function mode, configure the speed if needed.
        (++) Configure digital or analog mode.
        (++) In case of external interrupt/event select the type (interrupt or event) and
             the corresponding trigger event (rising or falling or both).

    (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
        mapped to the EXTI line and enable it using.

    (#) To get the level of a pin configured in input mode use the GPIOx_IDR register.

    (#) To set/reset the level of a pin configured in output mode use the GPIOx_BSRR register
        to SET (bits 0..15) or RESET (bits 16..31) the GPIO.
  1. Enable GPIOx clock in AHB1ENR
  2. Set mode in MODER
  3. Set pull up/down configuration
Note
This function performs the GPIO Port Clock Enable. It may occur that a port clock is re-enabled, it does not matter if it was already enabled. *
This function enables the AHB1 peripheral clock. After reset, the peripheral clock (used for registers read/write access) is disabled and the application software has to enable this clock before using it.
Parameters
p_portPort of the GPIO (CMSIS struct like)
pinPin/line of the GPIO (index from 0 to 15)
modeInput, output, alternate, or analog
pupdPull-up, pull-down, or no-pull
Return values
None

◆ stm32f4_system_gpio_config_alternate()

void stm32f4_system_gpio_config_alternate ( GPIO_TypeDef *  p_port,
uint8_t  pin,
uint8_t  alternate 
)

Configure the alternate function of a GPIO.

  1. Create a 4-bit base mask.
  2. Shift left the mask depending on the value of the given **pin modulo 8.**
        💡 The value of pin ranges from 0 to 15. The registers GPIOx_AFRH and GPIOx_AFRL implement 8 groups of 4 bits each. In order to use the value of pin as index to select the corresponding group of bits, we can use the remainder of the division by 8.
  3. Clean and set the bits as shown in the tutorial document.
        💡 Clean the corresponding bit on element 0 or 1 of the AFR array (e.g, GPIOA->AFR[0] for GPIOx_AFRL)
        💡 Set the given value (alternate) of the alternate function, using bit shifting, for example.


💡 You can define your own masks for each alternate function (not recommended), or you can use the macro BASE_MASK_TO_POS(m, p) to get the mask of a base mask. Example:
    A base mask m equals 0x03 (0b 0000 0011 in binary) can be shifted p equals 8 positions BASE_MASK_TO_POS(0x03, 8) resulting in 0x300 (0b 0011 0000 0000 in binary).

Note
The AFR register is a 2-element array representing GPIO alternate function high an low registers (GPIOx_AFRH and GPIOx_AFRL)
AFRLy: Alternate function selection for port x pin y (y = 0..7)
AFRHy: Alternate function selection for port x pin y (y = 8..15)
Parameters
p_portPort of the GPIO (CMSIS struct like)
pinPin/line of the GPIO (index from 0 to 15)
alternateAlternate function number (values from 0 to 15) according to table of the datasheet: "Table 11. Alternate function".
Return values
None

◆ stm32f4_system_gpio_config_exti()

void stm32f4_system_gpio_config_exti ( GPIO_TypeDef *  p_port,
uint8_t  pin,
uint32_t  mode 
)

Configure the external interruption or event of a GPIO.

  1. Enable the System configuration controller clock (SYSCFG). Enable the SYSCFG by setting the bit SYSCFGEN of the peripheral clock enable register (RCC_APB2ENR). The system configuration controller is used here to manage the external interrupt line connection to the GPIOs.
        💡 As usual, you can access to the register (APB2ENR) as element of the structure RCC. You can use the macro RCC_APB2ENR_SYSCFGEN defined in stm32f446xx.h to set the bit. Look for the "RCC_APB2ENR" register in the Reference Manual if you need more information.

  2. Associate the external interruption line to the given port. Clean and set the bits as shown in the tutorial document.
        💡 Depending on the pin number, use the register SYSCFG_EXTICR1, SYSCFG_EXTICR2, SYSCFG_EXTICR3, or SYSCFG_EXTICR4. The structure SYSCFG contains a 4-element array called EXTICR; the first element (EXTICR[0]) configures the register SYSCFG_EXTICR1, and so on.
        💡 To clean the EXTIx bits, you can create a mask depending on the pin value.
        💡 To associate the external interruption to the given port, i.e. to set the EXTIx bits, you can create another mask depending on the port value.

  3. Select the direction of the trigger: rising edge, falling edge, or both, depending on the value of the given mode.
        💡 If rising edge: activate the corresponding bit on the EXTI_RTSR register (element RTSR) of the EXTI structure.
        💡 If falling edge: activate the corresponding bit on the EXTI_FTSR register (element FTSR) of the EXTI structure.
        💡 If both: activate the corresponding bit on both registers.

  4. Select the interrupt and/or event request: depending on the value of the given mode.
        💡 If event request enable: activate the corresponding bit on the EXTI_EMR register (element EMR) of the EXTI structure.
        💡 If interrupt request enable: activate the corresponding bit on the EXTI_IMR register (element IMR) of the EXTI structure.


💡 You can define your own masks for each pin value (not recommended), or you can use the BIT_POS_TO_MASK(pin) macro to get the mask of a pin.

Warning
It is highly recommended to clean the corresponding bit of each register (RSTR, FTSR, EMR, IMR) before activating it.
Parameters
p_portPort of the GPIO (CMSIS struct like)
pinPin/line of the GPIO (index from 0 to 15)
modeTrigger mode can be a combination (OR) of: (i) direction: rising edge (0x01), falling edge (0x02), (ii) event request (0x04), or (iii) interrupt request (0x08).
Return values
None

◆ stm32f4_system_gpio_exti_disable()

void stm32f4_system_gpio_exti_disable ( uint8_t  pin)

Disable interrupts of a GPIO line (pin)

Parameters
pinPin/line of the GPIO (index from 0 to 15)
Return values
None

◆ stm32f4_system_gpio_exti_enable()

void stm32f4_system_gpio_exti_enable ( uint8_t  pin,
uint8_t  priority,
uint8_t  subpriority 
)

Enable interrupts of a GPIO line (pin)

Parameters
pinPin/line of the GPIO (index from 0 to 15)
priorityPriority level (from highest priority: 0, to lowest priority: 15)
subprioritySubpriority level (from highest priority: 0, to lowest priority: 15)
Return values
None

◆ stm32f4_system_gpio_read()

bool stm32f4_system_gpio_read ( GPIO_TypeDef *  p_port,
uint8_t  pin 
)

Read the digital value of a GPIO.

TODO alumnos:

✅ 1. Retrieve the value of the IDR register.
    💡 You must cast the read value to return a bool.
    💡 You might use the BIT_POS_TO_MASK(pin) macro.

✅ 2. Return the value.

Parameters
p_portPort of the GPIO (CMSIS struct like)
pinPin/line of the GPIO (index from 0 to 15)
Returns
true if the GPIO was HIGH
false if the GPIO was LOW

◆ stm32f4_system_gpio_toggle()

void stm32f4_system_gpio_toggle ( GPIO_TypeDef *  p_port,
uint8_t  pin 
)

Toggle the value of a GPIO.

TODO alumnos:

✅ 1. Read the value of the GPIO.

✅ 2. Write the opposite value in the GPIO.
    💡 You might use functions stm32f4_system_gpio_read() and stm32f4_system_gpio_write() to help you.
    💡 You might use the macros HIGH and LOW.

Parameters
p_portPort of the GPIO (CMSIS struct like)
pinPin/line of the GPIO (index from 0 to 15)
Return values
None

◆ stm32f4_system_gpio_write()

void stm32f4_system_gpio_write ( GPIO_TypeDef *  p_port,
uint8_t  pin,
bool  value 
)

Write a digital value in a GPIO atomically.

TODO alumnos:

✅ 1. Set the corresponding bit value of the BSRR register to set or reset the output depending on the given value.
    💡 You might use the macros HIGH and LOW.
    💡 You might use the BIT_POS_TO_MASK(pin) macro.

Note
You can use a +16 offset on the pin index and use the BIT_POS_TO_MASK(pin) macro to get the mask when you go to clear a GPIO. Otherwise, you can calculate the pin mask first and then use a 16-position left shift of the mask.
Parameters
p_portPort of the GPIO (CMSIS struct like)
pinPin/line of the GPIO (index from 0 to 15)
valueBoolean value to set the GPIO to HIGH (1, true) or LOW (0, false)
Return values
None

◆ system_clock_config()

static void system_clock_config ( void  )
static

System Clock Configuration.

Attention
This function should NOT be accesible from the outside to avoid configuration problems.
Note
This function starts a system timer that generates a SysTick every 1 ms.

Configure the main internal regulator output voltage

◆ SystemInit()

void SystemInit ( void  )

Setup the microcontroller system Initialize the FPU setting, vector table location and External memory configuration.

Note
This function is called at startup by CMSIS in startup_stm32f446xx.s.

Variable Documentation

◆ AHBPrescTable

const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}

Prescaler values for AHB bus

◆ APBPrescTable

const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}

Prescaler values for APB bus

◆ msTicks

volatile uint32_t msTicks = 0
static

Variable to store millisecond ticks.

Warning
It must be declared volatile! Just because it is modified in an ISR. Add it to the definition after static.

◆ SystemCoreClock

uint32_t SystemCoreClock = HSI_VALUE

Frequency of the System clock

port_system_systick_suspend
void port_system_systick_suspend(void)
Suspend Tick increment.
Definition: stm32f4_system.c:329
port_system_power_stop
void port_system_power_stop(void)
Set the system in stop mode for low power consumption.
Definition: stm32f4_system.c:335
port_system_power_sleep
void port_system_power_sleep(void)
Set the system in sleep mode for low power consumption.
Definition: stm32f4_system.c:350
port_system_systick_resume
void port_system_systick_resume(void)
Resume Tick increment.
Definition: stm32f4_system.c:323