FSM thermostat
port_system.c File Reference

File that defines the functions that are related to the access to the specific HW of the microcontroller. More...

#include "port_system.h"

Go to the source code of this file.

Macros

#define HSI_VALUE   ((uint32_t)16000000)
 

Functions

void SystemInit (void)
 Setup the microcontroller system Initialize the FPU setting, vector table location and External memory configuration. More...
 
void system_clock_config (void)
 System Clock Configuration. More...
 
size_t port_system_init ()
 This function is based on the initialization of the HAL Library; it must be the first thing to be executed in the main program (before to call any other functions), it performs the following: More...
 
uint32_t port_system_get_millis ()
 Get the count of the System tick in milliseconds. More...
 
void port_system_set_millis (uint32_t ms)
 Sets the number of milliseconds since the system started. More...
 
void port_system_delay_ms (uint32_t ms)
 Wait for some milliseconds. More...
 
void port_system_delay_until_ms (uint32_t *p_t, uint32_t ms)
 Wait for some milliseconds from a time reference. More...
 
void port_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 port_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 port_system_gpio_exti_enable (uint8_t pin, uint8_t priority, uint8_t subpriority)
 Enable interrupts of a GPIO line (pin) More...
 
void port_system_gpio_exti_disable (uint8_t pin)
 Disable interrupts of a GPIO line (pin) More...
 
void port_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_adc_single_ch_init (ADC_TypeDef *p_adc, uint8_t channel, uint32_t cr_mode)
 Configure the ADC peripheral for a single channel. More...
 
void port_system_adc_interrupt_enable (uint8_t priority, uint8_t subpriority)
 Enable the ADC global interrupts in NVIC. ADC1, ADC2, and ADC3 share the same interrupt. More...
 
void port_system_adc_enable (ADC_TypeDef *p_adc)
 Enable the ADC peripheral to work. More...
 
void port_system_adc_disable (ADC_TypeDef *p_adc)
 Disable the ADC peripheral. More...
 
void port_system_adc_start_conversion (ADC_TypeDef *p_adc, uint8_t channel)
 Start the conversion of the ADC peripheral. 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

File that defines the functions that are related to the access to the specific HW of the microcontroller.

Author
Sistemas Digitales II
Date
2024-01-01

Definition in file port_system.c.

Macro Definition Documentation

◆ HSI_VALUE

#define HSI_VALUE   ((uint32_t)16000000)

Value of the Internal oscillator in Hz

Definition at line 12 of file port_system.c.

Function Documentation

◆ port_system_adc_disable()

void port_system_adc_disable ( ADC_TypeDef *  p_adc)

Disable the ADC peripheral.

It disables the given ADC peripheral in CR2 register.

Parameters
p_adcADC peripheral (CMSIS struct like)

Definition at line 368 of file port_system.c.

◆ port_system_adc_enable()

void port_system_adc_enable ( ADC_TypeDef *  p_adc)

Enable the ADC peripheral to work.

It enables the given ADC peripheral in CR2 register. It waits until the ADC stabilizes (10 us aprox).

Parameters
p_adcADC peripheral (CMSIS struct like)

Definition at line 357 of file port_system.c.

◆ port_system_adc_interrupt_enable()

void port_system_adc_interrupt_enable ( uint8_t  priority,
uint8_t  subpriority 
)

Enable the ADC global interrupts in NVIC. ADC1, ADC2, and ADC3 share the same interrupt.

Parameters
priority
subpriority

Definition at line 351 of file port_system.c.

◆ port_system_adc_single_ch_init()

void port_system_adc_single_ch_init ( ADC_TypeDef *  p_adc,
uint8_t  channel,
uint32_t  cr_mode 
)

Configure the ADC peripheral for a single channel.

==============================================================================
                ##### Steps to configure the ADC peripheral #####
==============================================================================
(#) Enable the ADC and GPIO clocks
(#) Set the prescaler in the Common Control Register (CCR)
(#) Set the Scan mode and Resolution in the Control Register 1 (CR1)
(#) Set the Continuous Conversion, EOC, and Data Alignment in Control Register 2 (CR2)
(#) Set the Sampling Time for the channel(s) in the ADC_SMPRx
(#) Set the Regular channel sequence length in ADC_SQR1

It configures the given ADC peripheral and the common configuration for all the channels.

The current implementation only supports setting the resolution and interrupt of EOC. Most of the configurations are set to default values. DMA is not supported in current implementation. As in example:

Reset Configuration Register 1 (CR1) of the ADC. Current configuration sets the default values for:

  • Analog watchdog enable on regular channels
  • Discontinuous mode on regular channels
  • Discontinuous mode on injected channels
  • Automatic injected group conversion
  • Analog watchdog channel selection
  • Interrupt enable (EOC, EOS, AWD, JEOC, JEOS)
  • ADC analog watchdog interrupt enable
  • Interrupt enable for injected channels
  • Scan mode
  • ADC analog watchdog channel selection
  • Select the channel to convert
    Parameters
    p_adcADC peripheral (CMSIS struct like)
    channelChannel number (from 0 to 15)
    cr_modeControl register mode. Currently, it only supports the end of conversion interrupt.

Definition at line 261 of file port_system.c.

◆ port_system_adc_start_conversion()

void port_system_adc_start_conversion ( ADC_TypeDef *  p_adc,
uint8_t  channel 
)

Start the conversion of the ADC peripheral.

It starts the conversion of the given ADC peripheral in CR2 register.

First it sets the channel sequence in the SQR register. Then, it clears the status register and starts the conversion by setting the SWSTART bit.

Since current implementation does not support DMA, we will only use 1 sequence and put 1 channel in the sequence register at a time.

Parameters
p_adcADC peripheral (CMSIS struct like)
channelChannel number (from 0 to 15)

Definition at line 374 of file port_system.c.

◆ port_system_delay_ms()

void port_system_delay_ms ( uint32_t  ms)

Wait for some milliseconds.

Parameters
msNumber of milliseconds to wait
Return values
None

Definition at line 135 of file port_system.c.

◆ port_system_delay_until_ms()

void port_system_delay_until_ms ( uint32_t *  p_t,
uint32_t  ms 
)

Wait for some milliseconds from a time reference.

Note
It also updates the time reference to the system time at return.
Parameters
p_tPointer to the time reference
msNumber of milliseconds to wait
Return values
None

Definition at line 144 of file port_system.c.

◆ port_system_get_millis()

uint32_t port_system_get_millis ( void  )

Get the count of the System tick in milliseconds.

Definition at line 125 of file port_system.c.

◆ port_system_gpio_config()

void port_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

Definition at line 158 of file port_system.c.

◆ port_system_gpio_config_alternate()

void port_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

Definition at line 249 of file port_system.c.

◆ port_system_gpio_config_exti()

void port_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

Definition at line 181 of file port_system.c.

◆ port_system_gpio_exti_disable()

void port_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

Definition at line 244 of file port_system.c.

◆ port_system_gpio_exti_enable()

void port_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

Definition at line 238 of file port_system.c.

◆ port_system_init()

size_t port_system_init ( void  )

This function is based on the initialization of the HAL Library; it must be the first thing to be executed in the main program (before to call any other functions), it performs the following:

  • Configure the Flash prefetch, instruction and Data caches.
  • Configures the SysTick to generate an interrupt each 1 millisecond, which is clocked by the HSI (at this stage, the clock is not yet configured and thus the system is running from the internal HSI at 16 MHz).
  • Set NVIC Group Priority to 4. NVIC_PRIORITYGROUP_4: 4 bits for preemption priority 0 bits for subpriority
  • Configure the system clock
Note
SysTick is used as time base for the delay functions. When using the HAL, the application needs to ensure that the SysTick time base is always set to 1 millisecond to have correct HAL operation. When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption is no more possible. The pending IRQ priority will be managed only by the subpriority.
Return values
Initstatus

Definition at line 89 of file port_system.c.

◆ port_system_set_millis()

void port_system_set_millis ( uint32_t  ms)

Sets the number of milliseconds since the system started.

Warning
This function must be used only by the SysTick_Handler() ISR in file interr.c.
Parameters
msNew number of milliseconds since the system started.

Definition at line 130 of file port_system.c.

◆ system_clock_config()

void system_clock_config ( void  )

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.
Return values
None

Configure the main internal regulator output voltage

Definition at line 56 of file port_system.c.

◆ 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.

Definition at line 32 of file port_system.c.

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

Definition at line 19 of file port_system.c.

◆ APBPrescTable

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

Prescaler values for APB bus

Definition at line 20 of file port_system.c.

◆ 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.

Definition at line 15 of file port_system.c.

◆ SystemCoreClock

uint32_t SystemCoreClock = HSI_VALUE

Frequency of the System clock

Definition at line 18 of file port_system.c.