FSM thermostat
port_system.h File Reference

Header for port_system.c file. More...

#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "stm32f4xx.h"

Go to the source code of this file.

Macros

#define BIT_POS_TO_MASK(x)   (0x01 << (x))
 
#define BASE_MASK_TO_POS(m, p)   ((m) << (p))
 
#define GET_PIN_IRQN(pin)   (pin >= 10 ? EXTI15_10_IRQn : (pin >= 5 ? EXTI9_5_IRQn : (EXTI0_IRQn + pin)))
 
#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
 
#define HIGH   true
 
#define LOW   false
 
#define GPIO_MODE_IN   0x00
 
#define GPIO_MODE_OUT   0x01
 
#define GPIO_MODE_ALTERNATE   0x02
 
#define GPIO_MODE_ANALOG   0x03
 
#define GPIO_PUPDR_NOPULL   0x00
 
#define GPIO_PUPDR_PUP   0x01
 
#define GPIO_PUPDR_PDOWN   0x02
 
#define TRIGGER_RISING_EDGE   0x01U
 
#define TRIGGER_FALLING_EDGE   0x02U
 
#define TRIGGER_BOTH_EDGE   (TRIGGER_RISING_EDGE | TRIGGER_FALLING_EDGE)
 
#define TRIGGER_ENABLE_EVENT_REQ   0x04U
 
#define TRIGGER_ENABLE_INTERR_REQ   0x08U
 
#define ADC_VREF_MV   3300U
 
#define ADC_RESOLUTION_12B   (0x00U << ADC_CR1_RES_Pos)
 
#define ADC_RESOLUTION_10B   (0x01U << ADC_CR1_RES_Pos)
 
#define ADC_RESOLUTION_8B   (0x02U << ADC_CR1_RES_Pos)
 
#define ADC_RESOLUTION_6B   (0x03U << ADC_CR1_RES_Pos)
 
#define ADC_EOC_INTERRUPT_ENABLE   (0x01U << ADC_CR1_EOCIE_Pos)
 

Functions

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: More...
 
uint32_t port_system_get_millis (void)
 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_alternate (GPIO_TypeDef *p_port, uint8_t pin, uint8_t alternate)
 Configure the alternate function 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_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...
 

Detailed Description

Header for port_system.c file.

Author
Sistemas Digitales II
Date
2024-01-01

Definition in file port_system.h.

Macro Definition Documentation

◆ ADC_EOC_INTERRUPT_ENABLE

#define ADC_EOC_INTERRUPT_ENABLE   (0x01U << ADC_CR1_EOCIE_Pos)

End of conversion interrupt enable

Definition at line 66 of file port_system.h.

◆ ADC_RESOLUTION_10B

#define ADC_RESOLUTION_10B   (0x01U << ADC_CR1_RES_Pos)

10-bit resolution

Definition at line 62 of file port_system.h.

◆ ADC_RESOLUTION_12B

#define ADC_RESOLUTION_12B   (0x00U << ADC_CR1_RES_Pos)

12-bit resolution

Definition at line 61 of file port_system.h.

◆ ADC_RESOLUTION_6B

#define ADC_RESOLUTION_6B   (0x03U << ADC_CR1_RES_Pos)

6-bit resolution

Definition at line 64 of file port_system.h.

◆ ADC_RESOLUTION_8B

#define ADC_RESOLUTION_8B   (0x02U << ADC_CR1_RES_Pos)

8-bit resolution

Definition at line 63 of file port_system.h.

◆ ADC_VREF_MV

#define ADC_VREF_MV   3300U

ADC reference voltage in mV

Definition at line 59 of file port_system.h.

◆ BASE_MASK_TO_POS

#define BASE_MASK_TO_POS (   m,
 
)    ((m) << (p))

Move a mask defined in the LSBs to upper positions by shifting left p bits

Definition at line 23 of file port_system.h.

◆ BIT_POS_TO_MASK

#define BIT_POS_TO_MASK (   x)    (0x01 << (x))

Convert the index of a bit into a mask by left shifting

Definition at line 22 of file port_system.h.

◆ GET_PIN_IRQN

#define GET_PIN_IRQN (   pin)    (pin >= 10 ? EXTI15_10_IRQn : (pin >= 5 ? EXTI9_5_IRQn : (EXTI0_IRQn + pin)))

Compute the IRQ number associated to a GPIO pin

Definition at line 24 of file port_system.h.

◆ GPIO_MODE_ALTERNATE

#define GPIO_MODE_ALTERNATE   0x02

GPIO as alternate function

Definition at line 44 of file port_system.h.

◆ GPIO_MODE_ANALOG

#define GPIO_MODE_ANALOG   0x03

GPIO as analog

Definition at line 45 of file port_system.h.

◆ GPIO_MODE_IN

#define GPIO_MODE_IN   0x00

GPIO as input

Definition at line 42 of file port_system.h.

◆ GPIO_MODE_OUT

#define GPIO_MODE_OUT   0x01

GPIO as output

Definition at line 43 of file port_system.h.

◆ GPIO_PUPDR_NOPULL

#define GPIO_PUPDR_NOPULL   0x00

GPIO no pull up or down

Definition at line 47 of file port_system.h.

◆ GPIO_PUPDR_PDOWN

#define GPIO_PUPDR_PDOWN   0x02

GPIO pull down

Definition at line 49 of file port_system.h.

◆ GPIO_PUPDR_PUP

#define GPIO_PUPDR_PUP   0x01

GPIO pull up

Definition at line 48 of file port_system.h.

◆ HIGH

#define HIGH   true

Logic 1

Definition at line 39 of file port_system.h.

◆ LOW

#define LOW   false

Logic 0

Definition at line 40 of file port_system.h.

◆ NVIC_PRIORITY_GROUP_0

#define NVIC_PRIORITY_GROUP_0   ((uint32_t)0x00000007)

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

Definition at line 30 of file port_system.h.

◆ NVIC_PRIORITY_GROUP_4

#define NVIC_PRIORITY_GROUP_4   ((uint32_t)0x00000003)

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

Definition at line 32 of file port_system.h.

◆ POWER_REGULATOR_VOLTAGE_SCALE3

#define POWER_REGULATOR_VOLTAGE_SCALE3   0x01

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

Definition at line 36 of file port_system.h.

◆ RCC_HSI_CALIBRATION_DEFAULT

#define RCC_HSI_CALIBRATION_DEFAULT   0x10U

Default HSI calibration trimming value

Definition at line 28 of file port_system.h.

◆ TICK_FREQ_1KHZ

#define TICK_FREQ_1KHZ   1U

Freqency in kHz of the System tick

Definition at line 29 of file port_system.h.

◆ TRIGGER_BOTH_EDGE

#define TRIGGER_BOTH_EDGE   (TRIGGER_RISING_EDGE | TRIGGER_FALLING_EDGE)

Interrupt mask for detecting both rising and falling edges

Definition at line 54 of file port_system.h.

◆ TRIGGER_ENABLE_EVENT_REQ

#define TRIGGER_ENABLE_EVENT_REQ   0x04U

Interrupt mask to enable event requests

Definition at line 55 of file port_system.h.

◆ TRIGGER_ENABLE_INTERR_REQ

#define TRIGGER_ENABLE_INTERR_REQ   0x08U

Interrupt mask to enable interrupt request

Definition at line 56 of file port_system.h.

◆ TRIGGER_FALLING_EDGE

#define TRIGGER_FALLING_EDGE   0x02U

Interrupt mask for detecting falling edge

Definition at line 53 of file port_system.h.

◆ TRIGGER_RISING_EDGE

#define TRIGGER_RISING_EDGE   0x01U

Interrupt mask for detecting rising edge

Definition at line 52 of file port_system.h.

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.