53 Commits

Author SHA1 Message Date
Ea-r-th
59e1003262 Made getADCRegister constexpr 2025-09-22 22:36:06 -07:00
Ea-r-th
3480cba21c Fixes 2025-09-22 22:17:59 -07:00
Ea-r-th
03dcfd6bbe Added analogRead to GPIO 2025-09-22 22:12:57 -07:00
Ea-r-th
8214617e3a ADC basic functionality finished 2025-09-22 19:47:15 -07:00
Ea-r-th
f980e62407 Finished ADC methods 2025-09-22 19:36:19 -07:00
Ea-r-th
9550b1b61d Set up ADC files 2025-09-21 14:01:47 -07:00
Ea-r-th
5b66b044b7 Merge branch 'main' of github.com:lucalizaranzu/Shmingo_HAL 2025-09-18 01:23:12 -07:00
Ea-r-th
05465086c4 Final I2C commit 2025-09-18 01:22:09 -07:00
Luca Lizaranzu
cfda94afc1 Merge pull request #1 from lucalizaranzu/I2C
I2C
2025-09-18 01:21:40 -07:00
Ea-r-th
cb232ea55e I2C tested, main file now contains rough sample for use with DHT20 2025-09-18 01:19:03 -07:00
Ea-r-th
8ce717033a Added timeout wait functions to core 2025-09-17 20:07:17 -07:00
Ea-r-th
75132eb040 Changed I2C init order 2025-09-16 03:07:52 -07:00
Ea-r-th
7b32859c88 Added I2C clock config 2025-09-16 00:38:36 -07:00
Ea-r-th
d4136f0761 Added delay functions 2025-09-15 23:48:16 -07:00
Ea-r-th
b2d10f5e5e Unified all current peripheral implementation syntax with macros 2025-09-15 01:20:33 -07:00
Ea-r-th
25b56f9fcd Finished I2C 2025-09-14 23:06:28 -07:00
Ea-r-th
183be36c64 Beginnings of I2C object functions 2025-09-14 17:27:59 -07:00
Ea-r-th
914fbf5a17 Begin I2C implementation and finalize other changes 2025-09-10 01:53:16 -07:00
Ea-r-th
8f3bd7ebd8 Refactored UART frontent retrieval system 2025-09-10 01:43:11 -07:00
Ea-r-th
2f8ba8d9ee Major refactor for entire system - wrong branch but get over it 2025-09-10 01:20:50 -07:00
Ea-r-th
316edd32d8 Before switch to GPIO functions over raw register manipulation for USART 2025-09-10 00:41:08 -07:00
Ea-r-th
55f03031b3 Added files for I2C 2025-09-09 20:11:17 -07:00
9f1aad028d Added friendly reminder 2025-09-08 02:33:01 -07:00
a599aa5a4e EXTI interrupt abstraction feature complete 2025-09-08 02:24:02 -07:00
a02ec044ce Merged branch UART and changed get function 2025-09-08 00:42:54 -07:00
368eac7616 Finished basic UART feature 2025-09-07 22:20:37 -07:00
b2c41e2cb4 Added alternate function inits for USART 2025-09-07 21:30:32 -07:00
84ab921291 Began UART initializer 2025-09-07 03:54:03 -07:00
06f0b9303c Restructured UART directory 2025-09-07 01:59:51 -07:00
465055fc53 Changed UART reg structs 2025-09-07 01:57:22 -07:00
40ee0e6834 Combined USART enums 2025-09-06 20:59:27 -07:00
a0ef9c8b32 Added more enums handling UART/USART functionality 2025-09-06 20:55:25 -07:00
d763965cb8 Created structs and enums for alternate function UART pins 2025-09-06 19:49:36 -07:00
f6e21fbd88 Finished EXTI abstraction 2025-09-05 23:57:26 -07:00
8b4402e4c8 Begin functionality for EXTI callbacks 2025-09-05 21:21:35 -07:00
64fb4e4a23 Added enum for EXTI bitmasks 2025-09-03 01:34:19 -07:00
35bc902187 Bare functionality finished for basic GPIO pin abstraction 2025-09-02 00:12:08 -07:00
db75c06c90 Changed object array to pointer array for GPIOs 2025-09-01 02:29:03 -07:00
0418e3d5c5 Set up GPIO infrastructure 2025-09-01 01:55:18 -07:00
33fc098dfc Changed SHAL_Peripheral to take in a void* of any peripheral struct, and added SHAL_Peripheral_Register for individual registers 2025-08-30 16:57:52 -07:00
2da3413329 Changed bitmask to offset in peripheral struct to support different register patterns 2025-08-30 15:54:42 -07:00
19fbe6c0ad Changed SRC file structure 2025-08-29 23:24:27 -07:00
098e57eb2f Added CORE general include header discerning STM32 platform includes and containing global structs and defines 2025-08-29 23:21:56 -07:00
45abfc6c88 Changed directory structure to eventually support multi-MCU family support - added files 2025-08-29 23:06:44 -07:00
a0cb980e16 Changed directory structure to eventually support multi-MCU family support 2025-08-29 23:06:22 -07:00
9cc3cbece4 Removed unused BUS field from RCC_Peripheral struct 2025-08-29 22:51:31 -07:00
83572b108a Final changes 2025-08-29 16:37:11 -07:00
20fdce6d82 File restructure 2025-08-29 01:49:40 -07:00
d092ccd362 Made timer constructor unaccessable by user 2025-08-28 22:02:08 -07:00
1e966f0688 Finished Timer IRQ abstraction 2025-08-28 20:56:51 -07:00
55ca8d5360 Finished Timer IRQ abstraction 2025-08-28 20:56:30 -07:00
4900cde915 Fixed cmakelists 2025-08-28 13:09:47 -07:00
8979e1b28a Start timer abstractions 2025-08-28 02:47:52 -07:00
57 changed files with 2464 additions and 154 deletions

View File

@@ -23,19 +23,30 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON) set(CMAKE_CXX_EXTENSIONS ON)
set(MX_INCLUDE_DIRECTORIES set(MX_INCLUDE_DIRECTORIES
${CMAKE_CURRENT_SOURCE_DIR}/Core/Include
${CMAKE_CURRENT_SOURCE_DIR}/Core/Include/*
${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include
${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Include ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Include
) )
set(PROJECT_INCLUDE_DIRECTORIES set(PROJECT_INCLUDE_DIRECTORIES
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
SHAL/Include/Core/
SHAL/Include/Peripheral/Timer
SHAL/Include/Peripheral/Timer/Reg
SHAL/Include/Peripheral/GPIO
SHAL/Include/Peripheral/GPIO/Reg
SHAL/Include/Peripheral/UART
SHAL/Include/Peripheral/UART/Reg
SHAL/Include/Peripheral/I2C
SHAL/Include/Peripheral/I2C/Reg
SHAL/Include/Peripheral/ADC
SHAL/Include/Peripheral/ADC/Reg
SHAL/Include/Peripheral/EXT/
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Include
) )
file(GLOB_RECURSE PROJECT_SOURCES file(GLOB_RECURSE PROJECT_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/Core/*.c ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/*.c
${CMAKE_CURRENT_SOURCE_DIR}/Core/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/*.cpp
) )
add_executable(${EXECUTABLE} add_executable(${EXECUTABLE}
@@ -89,4 +100,4 @@ add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
${EXECUTABLE}.hex ${EXECUTABLE}.hex
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${EXECUTABLE}> COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${EXECUTABLE}>
${EXECUTABLE}.bin ${EXECUTABLE}.bin
) )

View File

@@ -1,12 +0,0 @@
#ifndef SHAL_TIM_REG
#define SHAL_TIM_REG
#include "stm32f0xx.h" // Or your device header
enum class S_TIM{ //Sample
S_TIM_1 = 0xFFA0,
S_TIM_2 = 0xFF,
};
#endif

View File

@@ -1,8 +0,0 @@
#ifndef SHAL_TIM_H
#define SHAL_TIM_H
#include "SHAL_TIM_REG.h"
#endif

View File

@@ -1,60 +0,0 @@
#include "SHAL.h"
#include "stm32f0xx.h"
volatile int prev_button = false;
volatile int curr_button = false;
extern "C" void TIM2_IRQHandler(void){
if(TIM2->SR & TIM_SR_UIF){
TIM2->SR &= ~TIM_SR_UIF;
GPIOA->ODR ^= (1 << 4);
}
}
extern "C" void EXTI0_1_IRQHandler(void) {
if (EXTI->PR & (1 << 0)) { //Check pending flag
EXTI->PR |= (1 << 0); //Clear it by writing 1
GPIOA->ODR ^= (1 << 5);
}
}
int main() {
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // Enable SYSCFG clock (needed for EXTI)
TIM2->EGR |= TIM_EGR_UG; //Force update to load PSC/ARR
GPIOA->MODER &= ~(0b11 << (4 * 2));
GPIOA->MODER |= (0b1 << (4 * 2));
GPIOA->MODER &= ~(0x3 << (5 * 2));
GPIOA->MODER |= (0x1 << (5 * 2));
GPIOB->MODER &= ~(0x3 << (0 * 2));
GPIOB->MODER |= (0x0 << (0 * 2));
TIM2->PSC = 8000 - 1; //8MHz base, prescaler
TIM2->ARR = 500 - 1; //500ms, auto reload register
SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR1_EXTI0; // Clear EXTI0 mapping
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PB; // Map PA0 -> EXTI0
EXTI->IMR |= (1 << 0); // Unmask EXTI0
EXTI->RTSR |= (1 << 0); // Trigger on rising edge
TIM2->DIER |= TIM_DIER_UIE; //Interrupt register
TIM2->CR1 |= TIM_CR1_CEN; //Counter enable
NVIC_EnableIRQ(TIM2_IRQn);
NVIC_EnableIRQ(EXTI0_1_IRQn); // EXTI lines 0 and 1 share an IRQ vector
__enable_irq();
while (true) {
__WFI();
}
}

View File

@@ -369,16 +369,16 @@ typedef struct
typedef struct typedef struct
{ {
__IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ __IO uint32_t MODER; /*!< SHAL_GPIO port mode register, Address offset: 0x00 */
__IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ __IO uint32_t OTYPER; /*!< SHAL_GPIO port output type register, Address offset: 0x04 */
__IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ __IO uint32_t OSPEEDR; /*!< SHAL_GPIO port output speed register, Address offset: 0x08 */
__IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ __IO uint32_t PUPDR; /*!< SHAL_GPIO port pull-up/pull-down register, Address offset: 0x0C */
__IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ __IO uint32_t IDR; /*!< SHAL_GPIO port input data register, Address offset: 0x10 */
__IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ __IO uint32_t ODR; /*!< SHAL_GPIO port output data register, Address offset: 0x14 */
__IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x1A */ __IO uint32_t BSRR; /*!< SHAL_GPIO port bit set/reset register, Address offset: 0x1A */
__IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ __IO uint32_t LCKR; /*!< SHAL_GPIO port configuration lock register, Address offset: 0x1C */
__IO uint32_t AFR[2]; /*!< GPIO alternate function low register, Address offset: 0x20-0x24 */ __IO uint32_t AFR[2]; /*!< SHAL_GPIO alternate function low register, Address offset: 0x20-0x24 */
__IO uint32_t BRR; /*!< GPIO bit reset register, Address offset: 0x28 */ __IO uint32_t BRR; /*!< SHAL_GPIO bit reset register, Address offset: 0x28 */
} GPIO_TypeDef; } GPIO_TypeDef;
/** /**
@@ -467,7 +467,7 @@ typedef struct
__IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */
__IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */
__IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */
__IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ __IO uint32_t WUTR; /*!< RTC wakeup TIMER_KEY register, Address offset: 0x14 */
uint32_t RESERVED1; /*!< Reserved, Address offset: 0x18 */ uint32_t RESERVED1; /*!< Reserved, Address offset: 0x18 */
__IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */
uint32_t RESERVED2; /*!< Reserved, Address offset: 0x20 */ uint32_t RESERVED2; /*!< Reserved, Address offset: 0x20 */
@@ -6490,7 +6490,7 @@ typedef struct
/******************************************************************************/ /******************************************************************************/
/* */ /* */
/* General Purpose IOs (GPIO) */ /* General Purpose IOs (SHAL_GPIO) */
/* */ /* */
/******************************************************************************/ /******************************************************************************/
/******************* Bit definition for GPIO_MODER register *****************/ /******************* Bit definition for GPIO_MODER register *****************/
@@ -10933,7 +10933,7 @@ typedef struct
((INSTANCE) == DMA1_Channel6) || \ ((INSTANCE) == DMA1_Channel6) || \
((INSTANCE) == DMA1_Channel7)) ((INSTANCE) == DMA1_Channel7))
/****************************** GPIO Instances ********************************/ /****************************** SHAL_GPIO Instances ********************************/
#define IS_GPIO_ALL_INSTANCE(INSTANCE) (((INSTANCE) == GPIOA) || \ #define IS_GPIO_ALL_INSTANCE(INSTANCE) (((INSTANCE) == GPIOA) || \
((INSTANCE) == GPIOB) || \ ((INSTANCE) == GPIOB) || \
((INSTANCE) == GPIOC) || \ ((INSTANCE) == GPIOC) || \
@@ -10941,14 +10941,14 @@ typedef struct
((INSTANCE) == GPIOE) || \ ((INSTANCE) == GPIOE) || \
((INSTANCE) == GPIOF)) ((INSTANCE) == GPIOF))
/**************************** GPIO Alternate Function Instances ***************/ /**************************** SHAL_GPIO Alternate Function Instances ***************/
#define IS_GPIO_AF_INSTANCE(INSTANCE) (((INSTANCE) == GPIOA) || \ #define IS_GPIO_AF_INSTANCE(INSTANCE) (((INSTANCE) == GPIOA) || \
((INSTANCE) == GPIOB) || \ ((INSTANCE) == GPIOB) || \
((INSTANCE) == GPIOC) || \ ((INSTANCE) == GPIOC) || \
((INSTANCE) == GPIOD) || \ ((INSTANCE) == GPIOD) || \
((INSTANCE) == GPIOE)) ((INSTANCE) == GPIOE))
/****************************** GPIO Lock Instances ***************************/ /****************************** SHAL_GPIO Lock Instances ***************************/
#define IS_GPIO_LOCK_INSTANCE(INSTANCE) (((INSTANCE) == GPIOA) || \ #define IS_GPIO_LOCK_INSTANCE(INSTANCE) (((INSTANCE) == GPIOA) || \
((INSTANCE) == GPIOB)) ((INSTANCE) == GPIOB))
@@ -11192,11 +11192,11 @@ typedef struct
/****************************** TSC Instances *********************************/ /****************************** TSC Instances *********************************/
#define IS_TSC_ALL_INSTANCE(INSTANCE) ((INSTANCE) == TSC) #define IS_TSC_ALL_INSTANCE(INSTANCE) ((INSTANCE) == TSC)
/*********************** UART Instances : IRDA mode ***************************/ /*********************** SHAL_UART Instances : IRDA mode ***************************/
#define IS_IRDA_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \ #define IS_IRDA_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
((INSTANCE) == USART2)) ((INSTANCE) == USART2))
/********************* UART Instances : Smard card mode ***********************/ /********************* SHAL_UART Instances : Smard card mode ***********************/
#define IS_SMARTCARD_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \ #define IS_SMARTCARD_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
((INSTANCE) == USART2)) ((INSTANCE) == USART2))
@@ -11210,35 +11210,35 @@ typedef struct
#define IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \ #define IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
((INSTANCE) == USART2)) ((INSTANCE) == USART2))
/******************** UART Instances : Asynchronous mode **********************/ /******************** SHAL_UART Instances : Asynchronous mode **********************/
#define IS_UART_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \ #define IS_UART_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
((INSTANCE) == USART2) || \ ((INSTANCE) == USART2) || \
((INSTANCE) == USART3) || \ ((INSTANCE) == USART3) || \
((INSTANCE) == USART4)) ((INSTANCE) == USART4))
/******************** UART Instances : Half-Duplex mode **********************/ /******************** SHAL_UART Instances : Half-Duplex mode **********************/
#define IS_UART_HALFDUPLEX_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \ #define IS_UART_HALFDUPLEX_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
((INSTANCE) == USART2) || \ ((INSTANCE) == USART2) || \
((INSTANCE) == USART3) || \ ((INSTANCE) == USART3) || \
((INSTANCE) == USART4)) ((INSTANCE) == USART4))
/****************** UART Instances : Hardware Flow control ********************/ /****************** SHAL_UART Instances : Hardware Flow control ********************/
#define IS_UART_HWFLOW_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \ #define IS_UART_HWFLOW_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
((INSTANCE) == USART2) || \ ((INSTANCE) == USART2) || \
((INSTANCE) == USART3) || \ ((INSTANCE) == USART3) || \
((INSTANCE) == USART4)) ((INSTANCE) == USART4))
/****************** UART Instances : LIN mode ********************/ /****************** SHAL_UART Instances : LIN mode ********************/
#define IS_UART_LIN_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \ #define IS_UART_LIN_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
((INSTANCE) == USART2)) ((INSTANCE) == USART2))
/****************** UART Instances : wakeup from stop mode ********************/ /****************** SHAL_UART Instances : wakeup from stop mode ********************/
#define IS_UART_WAKEUP_FROMSTOP_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \ #define IS_UART_WAKEUP_FROMSTOP_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
((INSTANCE) == USART2)) ((INSTANCE) == USART2))
/* Old macro definition maintained for legacy purpose */ /* Old macro definition maintained for legacy purpose */
#define IS_UART_WAKEUP_INSTANCE IS_UART_WAKEUP_FROMSTOP_INSTANCE #define IS_UART_WAKEUP_INSTANCE IS_UART_WAKEUP_FROMSTOP_INSTANCE
/****************** UART Instances : Driver enable detection ********************/ /****************** SHAL_UART Instances : Driver enable detection ********************/
#define IS_UART_DRIVER_ENABLE_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \ #define IS_UART_DRIVER_ENABLE_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
((INSTANCE) == USART2) || \ ((INSTANCE) == USART2) || \
((INSTANCE) == USART3) || \ ((INSTANCE) == USART3) || \

View File

@@ -47,11 +47,6 @@
*/ */
/* This variable is updated in three ways: /* This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate() 1) by calling CMSIS function SystemCoreClockUpdate()
3) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) by calling HAL API function HAL_RCC_ClockConfig()
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/ */
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */ extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */

View File

@@ -101,7 +101,7 @@
#define __RESTRICT __restrict #define __RESTRICT __restrict
#endif #endif
/* ########################### Core Function Access ########################### */ /* ########################### SHAL Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface /** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{ @{
@@ -374,7 +374,7 @@ __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
/*@} end of CMSIS_Core_RegAccFunctions */ /*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */ /* ########################## SHAL Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions Access to dedicated instructions
@{ @{

View File

@@ -112,7 +112,7 @@
#endif #endif
/* ########################### Core Function Access ########################### */ /* ########################### SHAL Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface /** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{ @{
@@ -770,7 +770,7 @@ __STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
/*@} end of CMSIS_Core_RegAccFunctions */ /*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */ /* ########################## SHAL Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions Access to dedicated instructions
@{ @{

View File

@@ -115,7 +115,7 @@
#endif #endif
/* ########################### Core Function Access ########################### */ /* ########################### SHAL Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface /** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{ @{
@@ -810,7 +810,7 @@ __STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr)
/*@} end of CMSIS_Core_RegAccFunctions */ /*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */ /* ########################## SHAL Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions Access to dedicated instructions
@{ @{

View File

@@ -1033,7 +1033,7 @@ typedef struct
#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
/* Debug Core Register Selector Register Definitions */ /* Debug SHAL Register Selector Register Definitions */
#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
@@ -1109,7 +1109,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
@@ -1138,7 +1138,7 @@ typedef struct
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */
#define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< SHAL Debug Base Address (non-secure address space) */
#define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */
#define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */
#define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */
@@ -1146,7 +1146,7 @@ typedef struct
#define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */
#define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */
#define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */
#define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< SHAL Debug configuration struct (non-secure address space) */
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
#define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */

View File

@@ -1863,7 +1863,7 @@ typedef struct
#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
/* Debug Core Register Selector Register Definitions */ /* Debug SHAL Register Selector Register Definitions */
#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
@@ -1969,7 +1969,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
@@ -2003,7 +2003,7 @@ typedef struct
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */
#define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< SHAL Debug Base Address (non-secure address space) */
#define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */
#define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */
#define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */
@@ -2012,7 +2012,7 @@ typedef struct
#define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */
#define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */
#define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */
#define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< SHAL Debug configuration struct (non-secure address space) */
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
#define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */

View File

@@ -530,7 +530,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */

View File

@@ -644,7 +644,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */

View File

@@ -556,7 +556,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */

View File

@@ -1108,7 +1108,7 @@ typedef struct
#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
/* Debug Core Register Selector Register Definitions */ /* Debug SHAL Register Selector Register Definitions */
#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
@@ -1184,7 +1184,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
@@ -1213,7 +1213,7 @@ typedef struct
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */
#define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< SHAL Debug Base Address (non-secure address space) */
#define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */
#define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */
#define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */
@@ -1221,7 +1221,7 @@ typedef struct
#define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */
#define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */
#define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */
#define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< SHAL Debug configuration struct (non-secure address space) */
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
#define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */

View File

@@ -1296,7 +1296,7 @@ typedef struct
#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
/* Debug Core Register Selector Register Definitions */ /* Debug SHAL Register Selector Register Definitions */
#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
@@ -1379,7 +1379,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */

View File

@@ -1938,7 +1938,7 @@ typedef struct
#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
/* Debug Core Register Selector Register Definitions */ /* Debug SHAL Register Selector Register Definitions */
#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
@@ -2044,7 +2044,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
@@ -2078,7 +2078,7 @@ typedef struct
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */
#define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< SHAL Debug Base Address (non-secure address space) */
#define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */
#define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */
#define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */
@@ -2087,7 +2087,7 @@ typedef struct
#define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */
#define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */
#define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */
#define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< SHAL Debug configuration struct (non-secure address space) */
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
#define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */

View File

@@ -1467,7 +1467,7 @@ typedef struct
#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
/* Debug Core Register Selector Register Definitions */ /* Debug SHAL Register Selector Register Definitions */
#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
@@ -1550,7 +1550,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */

View File

@@ -1675,7 +1675,7 @@ typedef struct
#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
/* Debug Core Register Selector Register Definitions */ /* Debug SHAL Register Selector Register Definitions */
#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
@@ -1758,7 +1758,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */

View File

@@ -653,7 +653,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */

View File

@@ -1276,7 +1276,7 @@ typedef struct
#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ #define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ #define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
/* Debug Core Register Selector Register Definitions */ /* Debug SHAL Register Selector Register Definitions */
#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ #define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ #define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
@@ -1359,7 +1359,7 @@ typedef struct
@{ @{
*/ */
/* Memory mapping of Core Hardware */ /* Memory mapping of SHAL Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */

View File

@@ -0,0 +1,111 @@
/**
******************************************************************************
* @file SHAL_CORE.h
* @author Luca Lizaranzu
* @brief Defines universal macros and objects used across all STM32 families
* Includes for ST Microelectronics pre-made C headers for STM32 device families
******************************************************************************
*/
#ifndef SHMINGO_HAL_SHAL_CORE_H
#define SHMINGO_HAL_SHAL_CORE_H
#include <cstdint>
//Overall init function for SHAL --------------------------
void SHAL_init();
//---------------------------------------------------------
//Universal structs and defines ---------------------------
enum class SHAL_Result{
OKAY,
ERROR
};
typedef bool (*condition_fn_t)(void);
#define SHAL_WAIT_FOR_CONDITION_US(cond, timeout_us) \
SHAL_wait_for_condition_us([&](){ return (cond); }, (timeout_us))
#define SHAL_WAIT_FOR_CONDITION_MS(cond, timeout_ms) \
SHAL_wait_for_condition_ms([&](){ return (cond); }, (timeout_ms))
//Currently configures systick to count down in microseconds
void systick_init();
//Max of 16ms, use SHAL_delay_ms for longer delay
void SHAL_delay_us(uint32_t us);
void SHAL_delay_ms(uint32_t ms);
template<typename Condition>
bool SHAL_wait_for_condition_us(Condition cond, uint32_t timeout_us) {
while (timeout_us--) {
if (cond()) {
return true; // success
}
SHAL_delay_us(1);
}
return false; // timeout
}
template<typename Condition>
bool SHAL_wait_for_condition_ms(Condition cond, uint32_t timeout_ms) {
while (timeout_ms--) {
if (cond()) {
return true; // success
}
SHAL_delay_ms(1);
}
return false; // timeout
}
//---------------------------------------------------------
#if defined(STM32F030x6)
#include "stm32f030x6.h"
#elif defined(STM32F030x8)
#include "stm32f030x8.h"
#elif defined(STM32F031x6)
#include "stm32f031x6.h"
#elif defined(STM32F038xx)
#include "stm32f038xx.h"
#elif defined(STM32F042x6)
#include "stm32f042x6.h"
#elif defined(STM32F048xx)
#include "stm32f048xx.h"
#elif defined(STM32F051x8)
#include "stm32f051x8.h"
#elif defined(STM32F058xx)
#include "stm32f058xx.h"
#elif defined(STM32F070x6)
#include "stm32f070x6.h"
#elif defined(STM32F070xB)
#include "stm32f070xb.h"
#elif defined(STM32F071xB)
#include "stm32f071xb.h"
#elif defined(STM32F072xB)
#include "stm32f072xb.h"
#elif defined(STM32F078xx)
#include "stm32f078xx.h"
#elif defined(STM32F091xC)
#include "stm32f091xc.h"
#elif defined(STM32F098xx)
#include "stm32f098xx.h"
#elif defined(STM32F030xC)
#include "stm32f030xc.h"
#else
#error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)"
#endif
#endif //SHMINGO_HAL_SHAL_CORE_H

View File

@@ -0,0 +1,31 @@
//
// Created by Luca on 9/21/2025.
//
#ifndef SHMINGO_HAL_SHAL_ADC_REG_F072XB_H
#define SHMINGO_HAL_SHAL_ADC_REG_F072XB_H
#include "SHAL_CORE.h"
#include "SHAL_ADC_TYPES.h"
#define SHAL_ADC1 SHAL_ADC(1)
enum class ADC_Key : uint8_t{
S_ADC1,
NUM_ADC,
INVALID
};
constexpr ADC_TypeDef* getADCRegister(ADC_Key key){
switch(key){
case ADC_Key::S_ADC1:
return ADC1;
case ADC_Key::NUM_ADC:
case ADC_Key::INVALID:
return nullptr;
}
__builtin_unreachable();
}
#endif //SHMINGO_HAL_SHAL_ADC_REG_F072XB_H

View File

@@ -0,0 +1,66 @@
//
// Created by Luca on 9/21/2025.
//
#ifndef SHMINGO_HAL_SHAL_ADC_H
#define SHMINGO_HAL_SHAL_ADC_H
#include <cstdint>
#include "SHAL_CORE.h"
#include "SHAL_ADC_REG.h"
class SHAL_ADC {
friend class ADCManager;
public:
SHAL_Result init();
SHAL_Result calibrate();
/// Performs analog to digital conversion on a single channel, one time
/// \param channel Channel to be converted
/// \param time ADC_SampleTime - amount of clock cycles per conversion
/// \return resulting value
uint16_t singleConvertSingle(ADC_Channel channel, ADC_SampleTime time = ADC_SampleTime::C239);
/// Performs analog to digital conversion on multiple channels, one time
/// \param channels Pointer to an array of channels to convert
/// \param numChannels Number of channels to convert
/// \param result Pointer to store converted channel results in
/// \param time ADC_SampleTime - amount of clock cycles per conversion
void multiConvertSingle(ADC_Channel* channels, const int numChannels, uint16_t* result, ADC_SampleTime time = ADC_SampleTime::C239);
private:
SHAL_ADC() = default;
ADC_Key m_ADCKey = ADC_Key::INVALID;
};
#define SHAL_ADC(x) ADCManager::getByIndex(x-1)
class ADCManager{
public:
static SHAL_ADC& get(ADC_Key key);
static SHAL_ADC& getByIndex(int index);
ADCManager() = delete;
private:
inline static SHAL_ADC m_ADCs[static_cast<uint8_t>(ADC_Key::NUM_ADC)] = {};
};
#endif //SHMINGO_HAL_SHAL_ADC_H

View File

@@ -0,0 +1,44 @@
//
// Created by Luca on 9/21/2025.
//
#ifndef SHMINGO_HAL_SHAL_ADC_REG_H
#define SHMINGO_HAL_SHAL_ADC_REG_H
#if defined(STM32F030x6)
#include "stm32f030x6.h"
#elif defined(STM32F030x8)
#include "stm32f030x8.h"
#elif defined(STM32F031x6)
#include "stm32f031x6.h"
#elif defined(STM32F038xx)
#include "stm32f038xx.h"
#elif defined(STM32F042x6)
#include "stm32f042x6.h"
#elif defined(STM32F048xx)
#include "stm32f048xx.h"
#elif defined(STM32F051x8)
#include "stm32f051x8.h"
#elif defined(STM32F058xx)
#include "stm32f058xx.h"
#elif defined(STM32F070x6)
#include "stm32f070x6.h"
#elif defined(STM32F070xB)
#include "stm32f070xb.h"
#elif defined(STM32F071xB)
#include "stm32f071xb.h"
#elif defined(STM32F072xB)
#include "SHAL_ADC_REG_F072xB.h"
#elif defined(STM32F078xx)
#include "stm32f078xx.h"
#elif defined(STM32F091xC)
#include "stm32f091xc.h"
#elif defined(STM32F098xx)
#include "stm32f098xx.h"
#elif defined(STM32F030xC)
#include "stm32f030xc.h"
#else
#error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)"
#endif
#endif //SHMINGO_HAL_SHAL_ADC_REG_H

View File

@@ -0,0 +1,41 @@
//
// Created by Luca on 9/21/2025.
//
#ifndef SHMINGO_HAL_SHAL_ADC_TYPES_H
#define SHMINGO_HAL_SHAL_ADC_TYPES_H
enum class ADC_Channel : uint32_t {
CH0 = ADC_CHSELR_CHSEL0,
CH1 = ADC_CHSELR_CHSEL1,
CH2 = ADC_CHSELR_CHSEL2,
CH3 = ADC_CHSELR_CHSEL3,
CH4 = ADC_CHSELR_CHSEL4,
CH5 = ADC_CHSELR_CHSEL5,
CH6 = ADC_CHSELR_CHSEL6,
CH7 = ADC_CHSELR_CHSEL7,
CH8 = ADC_CHSELR_CHSEL8,
CH9 = ADC_CHSELR_CHSEL9,
CH10 = ADC_CHSELR_CHSEL10,
CH11 = ADC_CHSELR_CHSEL11,
CH12 = ADC_CHSELR_CHSEL12,
CH13 = ADC_CHSELR_CHSEL13,
CH14 = ADC_CHSELR_CHSEL14,
CH15 = ADC_CHSELR_CHSEL15,
CHTemp = ADC_CHSELR_CHSEL16,
CHRef = ADC_CHSELR_CHSEL17,
CHBat = ADC_CHSELR_CHSEL18
};
enum class ADC_SampleTime : uint32_t {
C2 = 0x00, //1.5 cycles per sample
C7 = 0x01, //7.5 cycles
C13 = 0x02, //13.5 cycles
C28 = 0x03, //28.5 cycles
C41 = 0x04, //41.5 cycles
C55 = 0x05, //55.5 cycles
C71 = 0x06, //71.5 cycles
C239 = 0x07 //239.5 cycles
};
#endif //SHMINGO_HAL_SHAL_ADC_TYPES_H

View File

@@ -0,0 +1,41 @@
/**
******************************************************************************
* @file SHAL_TIM.h
* @author Luca Lizaranzu
* @brief Callbacks for external interrupts
******************************************************************************
*/
#ifndef SHAL_EXTI_CALLBACK_H
#define SHAL_EXTI_CALLBACK_H
#include "SHAL_CORE.h"
#include "SHAL_GPIO_REG.h"
#define DEFINE_EXTI_IRQ(EXTI_Channel) \
extern "C" void EXTI##EXTI_Channel##_IRQHandler(void) { \
if (EXTI->PR & (1 << EXTI_Channel)) { \
EXTI->PR |= (1 << EXTI_Channel); /*clear flag */ \
auto cb = EXTI_callbacks[EXTI_Channel]; \
if (cb) cb(); \
}; \
};
#define DEFINE_MULTI_EXTI_IRQ(EXTI_Channel_Min, EXTI_Channel_Max) \
extern "C" void EXTI##EXTI_Channel_Min##_##EXTI_Channel_Max##_IRQHandler(void) { \
for(uint8_t line = EXTI_Channel_Min; line <= EXTI_Channel_Max; line++){ \
if (EXTI->PR & (1 << line)) { \
EXTI->PR |= (1 << line); /*clear flag */ \
auto cb = EXTI_callbacks[line]; \
if (cb) cb(); \
}; \
} \
};
typedef void (*EXTICallback)(); //Typedef for callback function
[[maybe_unused]] static EXTICallback EXTI_callbacks[NUM_EXTI_LINES] = {nullptr}; //Timer IRQ Callback table
void registerEXTICallback(GPIO_Key key, EXTICallback callback);
#endif //SHAL_EXTI_CALLBACK_H

View File

@@ -0,0 +1,348 @@
//
// Created by Luca on 8/29/2025.
//
#ifndef SHAL_GPIO_REG_F072XB_H
#define SHAL_GPIO_REG_F072XB_H
#include <stm32f072xb.h>
#include <cassert>
#include "SHAL_GPIO_TYPES.h"
#define AVAILABLE_PORTS 3
#define PINS_PER_PORT 16
#define NUM_EXTI_LINES 16
#define AVAILABLE_GPIO \
X(A0) X(A1) X(A2) X(A3) X(A4) X(A5) X(A6) X(A7) X(A8) X(A9) X(A10) X(A11) X(A12) X(A13) X(A14) X(A15) \
X(B0) X(B1) X(B2) X(B3) X(B4) X(B5) X(B6) X(B7) X(B8) X(B9) X(B10) X(B11) X(B12) X(B13) X(B14) X(B15) \
X(C0) X(C1) X(C2) X(C3) X(C4) X(C5) X(C6) X(C7) X(C8) X(C9) X(C10) X(C11) X(C12) X(C13) X(C14) X(C15)
//Build enum map of available SHAL_GPIO pins
enum class GPIO_Key : uint8_t {
#define X(key) key,
AVAILABLE_GPIO
#undef X
NUM_GPIO,
INVALID
};
constexpr SHAL_GPIO_Peripheral getGPIORegister(const GPIO_Key g){
switch(g) {
case GPIO_Key::A0: return {GPIOA,0};
case GPIO_Key::A1: return {GPIOA,1};
case GPIO_Key::A2: return {GPIOA,2};
case GPIO_Key::A3: return {GPIOA,3};
case GPIO_Key::A4: return {GPIOA,4};
case GPIO_Key::A5: return {GPIOA,5};
case GPIO_Key::A6: return {GPIOA,6};
case GPIO_Key::A7: return {GPIOA,7};
case GPIO_Key::A8: return {GPIOA,8};
case GPIO_Key::A9: return {GPIOA,9};
case GPIO_Key::A10: return {GPIOA,10};
case GPIO_Key::A11: return {GPIOA,11};
case GPIO_Key::A12: return {GPIOA,12};
case GPIO_Key::A13: return {GPIOA,13};
case GPIO_Key::A14: return {GPIOA,14};
case GPIO_Key::A15: return {GPIOA,15};
case GPIO_Key::B0: return {GPIOB,0};
case GPIO_Key::B1: return {GPIOB,1};
case GPIO_Key::B2: return {GPIOB,2};
case GPIO_Key::B3: return {GPIOB,3};
case GPIO_Key::B4: return {GPIOB,4};
case GPIO_Key::B5: return {GPIOB,5};
case GPIO_Key::B6: return {GPIOB,6};
case GPIO_Key::B7: return {GPIOB,7};
case GPIO_Key::B8: return {GPIOB,8};
case GPIO_Key::B9: return {GPIOB,9};
case GPIO_Key::B10: return {GPIOB,10};
case GPIO_Key::B11: return {GPIOB,11};
case GPIO_Key::B12: return {GPIOB,12};
case GPIO_Key::B13: return {GPIOB,13};
case GPIO_Key::B14: return {GPIOB,14};
case GPIO_Key::B15: return {GPIOB,15};
case GPIO_Key::C0: return {GPIOC,0};
case GPIO_Key::C1: return {GPIOC,1};
case GPIO_Key::C2: return {GPIOC,2};
case GPIO_Key::C3: return {GPIOC,3};
case GPIO_Key::C4: return {GPIOC,4};
case GPIO_Key::C5: return {GPIOC,5};
case GPIO_Key::C6: return {GPIOC,6};
case GPIO_Key::C7: return {GPIOC,7};
case GPIO_Key::C8: return {GPIOC,8};
case GPIO_Key::C9: return {GPIOC,9};
case GPIO_Key::C10: return {GPIOC,10};
case GPIO_Key::C11: return {GPIOC,11};
case GPIO_Key::C12: return {GPIOC,12};
case GPIO_Key::C13: return {GPIOC,13};
case GPIO_Key::C14: return {GPIOC,14};
case GPIO_Key::C15: return {GPIOC,15};
case GPIO_Key::INVALID:
case GPIO_Key::NUM_GPIO:
assert(false);
return SHAL_GPIO_Peripheral(nullptr,0); //Unreachable
}
__builtin_unreachable();
}
constexpr SHAL_EXTIO_Register getGPIOEXTICR(const GPIO_Key g){
switch(g) {
case GPIO_Key::A0: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI0_PA,EXTI0_1_IRQn};
case GPIO_Key::A1: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI1_PA,EXTI0_1_IRQn};
case GPIO_Key::A2: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI2_PA,EXTI2_3_IRQn};
case GPIO_Key::A3: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI3_PA,EXTI2_3_IRQn};
case GPIO_Key::A4: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI4_PA,EXTI4_15_IRQn};
case GPIO_Key::A5: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI5_PA,EXTI4_15_IRQn};
case GPIO_Key::A6: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI6_PA,EXTI4_15_IRQn};
case GPIO_Key::A7: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI7_PA,EXTI4_15_IRQn};
case GPIO_Key::A8: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI8_PA,EXTI4_15_IRQn};
case GPIO_Key::A9: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI9_PA,EXTI4_15_IRQn};
case GPIO_Key::A10: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI10_PA,EXTI4_15_IRQn};
case GPIO_Key::A11: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI11_PA,EXTI4_15_IRQn};
case GPIO_Key::A12: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI12_PA,EXTI4_15_IRQn};
case GPIO_Key::A13: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI13_PA,EXTI4_15_IRQn};
case GPIO_Key::A14: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI14_PA,EXTI4_15_IRQn};
case GPIO_Key::A15: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI15_PA,EXTI4_15_IRQn};
case GPIO_Key::B0: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI0_PB,EXTI0_1_IRQn};
case GPIO_Key::B1: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI1_PB,EXTI0_1_IRQn};
case GPIO_Key::B2: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI2_PB,EXTI2_3_IRQn};
case GPIO_Key::B3: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI3_PB,EXTI2_3_IRQn};
case GPIO_Key::B4: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI4_PB,EXTI4_15_IRQn};
case GPIO_Key::B5: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI5_PB,EXTI4_15_IRQn};
case GPIO_Key::B6: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI6_PB,EXTI4_15_IRQn};
case GPIO_Key::B7: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI7_PB,EXTI4_15_IRQn};
case GPIO_Key::B8: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI8_PB,EXTI4_15_IRQn};
case GPIO_Key::B9: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI9_PB,EXTI4_15_IRQn};
case GPIO_Key::B10: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI10_PB,EXTI4_15_IRQn};
case GPIO_Key::B11: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI11_PB,EXTI4_15_IRQn};
case GPIO_Key::B12: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI12_PB,EXTI4_15_IRQn};
case GPIO_Key::B13: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI13_PB,EXTI4_15_IRQn};
case GPIO_Key::B14: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI14_PB,EXTI4_15_IRQn};
case GPIO_Key::B15: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI15_PB,EXTI4_15_IRQn};
case GPIO_Key::C0: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI0_PC,EXTI0_1_IRQn};
case GPIO_Key::C1: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI1_PC,EXTI0_1_IRQn};
case GPIO_Key::C2: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI2_PC,EXTI2_3_IRQn};
case GPIO_Key::C3: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI3_PC,EXTI2_3_IRQn};
case GPIO_Key::C4: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI4_PC,EXTI4_15_IRQn};
case GPIO_Key::C5: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI5_PC,EXTI4_15_IRQn};
case GPIO_Key::C6: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI6_PC,EXTI4_15_IRQn};
case GPIO_Key::C7: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI7_PC,EXTI4_15_IRQn};
case GPIO_Key::C8: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI8_PC,EXTI4_15_IRQn};
case GPIO_Key::C9: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI9_PC,EXTI4_15_IRQn};
case GPIO_Key::C10: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI10_PC,EXTI4_15_IRQn};
case GPIO_Key::C11: return {&SYSCFG->EXTICR[2],SYSCFG_EXTICR3_EXTI11_PC,EXTI4_15_IRQn};
case GPIO_Key::C12: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI12_PC,EXTI4_15_IRQn};
case GPIO_Key::C13: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI13_PC,EXTI4_15_IRQn};
case GPIO_Key::C14: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI14_PC,EXTI4_15_IRQn};
case GPIO_Key::C15: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI15_PC,EXTI4_15_IRQn};
case GPIO_Key::INVALID:
case GPIO_Key::NUM_GPIO:
assert(false);
return SHAL_EXTIO_Register(nullptr,0, EXTI4_15_IRQn); //Unreachable
}
__builtin_unreachable();
}
constexpr SHAL_Peripheral_Register getGPIORCCEnable(const GPIO_Key g){
switch(g) {
case GPIO_Key::A0:
case GPIO_Key::A1:
case GPIO_Key::A2:
case GPIO_Key::A3:
case GPIO_Key::A4:
case GPIO_Key::A5:
case GPIO_Key::A6:
case GPIO_Key::A7:
case GPIO_Key::A8:
case GPIO_Key::A9:
case GPIO_Key::A10:
case GPIO_Key::A11:
case GPIO_Key::A12:
case GPIO_Key::A13:
case GPIO_Key::A14:
case GPIO_Key::A15:
return {&RCC->AHBENR, RCC_AHBENR_GPIOAEN_Pos};
case GPIO_Key::B0:
case GPIO_Key::B1:
case GPIO_Key::B2:
case GPIO_Key::B3:
case GPIO_Key::B4:
case GPIO_Key::B5:
case GPIO_Key::B6:
case GPIO_Key::B7:
case GPIO_Key::B8:
case GPIO_Key::B9:
case GPIO_Key::B10:
case GPIO_Key::B11:
case GPIO_Key::B12:
case GPIO_Key::B13:
case GPIO_Key::B14:
case GPIO_Key::B15:
return {&RCC->AHBENR, RCC_AHBENR_GPIOBEN_Pos};
case GPIO_Key::C0:
case GPIO_Key::C1:
case GPIO_Key::C2:
case GPIO_Key::C3:
case GPIO_Key::C4:
case GPIO_Key::C5:
case GPIO_Key::C6:
case GPIO_Key::C7:
case GPIO_Key::C8:
case GPIO_Key::C9:
case GPIO_Key::C10:
case GPIO_Key::C11:
case GPIO_Key::C12:
case GPIO_Key::C13:
case GPIO_Key::C14:
case GPIO_Key::C15:
return {&RCC->AHBENR, RCC_AHBENR_GPIOCEN_Pos};
case GPIO_Key::INVALID:
case GPIO_Key::NUM_GPIO:
assert(false);
return SHAL_Peripheral_Register(nullptr,0); //Unreachable
}
__builtin_unreachable();
}
constexpr uint32_t getGPIOPortNumber(const GPIO_Key g){
switch(g) {
case GPIO_Key::A0:
case GPIO_Key::A1:
case GPIO_Key::A2:
case GPIO_Key::A3:
case GPIO_Key::A4:
case GPIO_Key::A5:
case GPIO_Key::A6:
case GPIO_Key::A7:
case GPIO_Key::A8:
case GPIO_Key::A9:
case GPIO_Key::A10:
case GPIO_Key::A11:
case GPIO_Key::A12:
case GPIO_Key::A13:
case GPIO_Key::A14:
case GPIO_Key::A15:
return 0;
case GPIO_Key::B0:
case GPIO_Key::B1:
case GPIO_Key::B2:
case GPIO_Key::B3:
case GPIO_Key::B4:
case GPIO_Key::B5:
case GPIO_Key::B6:
case GPIO_Key::B7:
case GPIO_Key::B8:
case GPIO_Key::B9:
case GPIO_Key::B10:
case GPIO_Key::B11:
case GPIO_Key::B12:
case GPIO_Key::B13:
case GPIO_Key::B14:
case GPIO_Key::B15:
return 1;
case GPIO_Key::C0:
case GPIO_Key::C1:
case GPIO_Key::C2:
case GPIO_Key::C3:
case GPIO_Key::C4:
case GPIO_Key::C5:
case GPIO_Key::C6:
case GPIO_Key::C7:
case GPIO_Key::C8:
case GPIO_Key::C9:
case GPIO_Key::C10:
case GPIO_Key::C11:
case GPIO_Key::C12:
case GPIO_Key::C13:
case GPIO_Key::C14:
case GPIO_Key::C15:
return 2;
case GPIO_Key::INVALID:
case GPIO_Key::NUM_GPIO:
assert(false);
return 0;
}
__builtin_unreachable();
}
constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){
switch(key){
case GPIO_Key::A0:
case GPIO_Key::B0:
case GPIO_Key::C0:
return {0,ADC_Channel::CH0};
case GPIO_Key::A1:
case GPIO_Key::B1:
case GPIO_Key::C1:
return {1,ADC_Channel::CH1};
case GPIO_Key::A2:
case GPIO_Key::B2:
case GPIO_Key::C2:
return {2,ADC_Channel::CH2};
case GPIO_Key::A3:
case GPIO_Key::B3:
case GPIO_Key::C3:
return {3,ADC_Channel::CH3};
case GPIO_Key::A4:
case GPIO_Key::B4:
case GPIO_Key::C4:
return {4,ADC_Channel::CH4};
case GPIO_Key::A5:
case GPIO_Key::B5:
case GPIO_Key::C5:
return {5,ADC_Channel::CH5};
case GPIO_Key::A6:
case GPIO_Key::B6:
case GPIO_Key::C6:
return {6,ADC_Channel::CH6};
case GPIO_Key::A7:
case GPIO_Key::B7:
case GPIO_Key::C7:
return {7,ADC_Channel::CH7};
case GPIO_Key::A8:
case GPIO_Key::B8:
case GPIO_Key::C8:
return {8,ADC_Channel::CH8};
case GPIO_Key::A9:
case GPIO_Key::B9:
case GPIO_Key::C9:
return {9,ADC_Channel::CH9};
case GPIO_Key::A10:
case GPIO_Key::B10:
case GPIO_Key::C10:
return {10,ADC_Channel::CH10};
case GPIO_Key::A11:
case GPIO_Key::B11:
case GPIO_Key::C11:
return {11,ADC_Channel::CH11};
case GPIO_Key::A12:
case GPIO_Key::B12:
case GPIO_Key::C12:
return {12,ADC_Channel::CH12};
case GPIO_Key::A13:
case GPIO_Key::B13:
case GPIO_Key::C13:
return {13,ADC_Channel::CH13};
case GPIO_Key::A14:
case GPIO_Key::B14:
case GPIO_Key::C14:
return {14,ADC_Channel::CH14};
case GPIO_Key::A15:
case GPIO_Key::B15:
case GPIO_Key::C15:
return {15,ADC_Channel::CH15};
case GPIO_Key::NUM_GPIO:
case GPIO_Key::INVALID:
return {0,ADC_Channel::CH0};
}
__builtin_unreachable();
}
#endif //SHMINGO_HAL_SHAL_GPIO_REG_F072XB_H

View File

@@ -0,0 +1,92 @@
//
// Created by Luca on 8/29/2025.
//
#ifndef SHAL_GPIO_H
#define SHAL_GPIO_H
#include "SHAL_GPIO_REG.h"
#include <cassert>
#include "SHAL_EXTI_CALLBACK.h"
#include "SHAL_ADC.h"
//Abstraction of SHAL_GPIO registers
class SHAL_GPIO{
public:
void toggle() volatile;
//TODO replace stupid offset hack from APB
void setHigh();
void setLow();
/// Uses the ADC to read an analog voltage value
/// \param sampleTime The amount of clock cycles to use for the ADC
/// \return ADC result
uint16_t analogRead(ADC_SampleTime sampleTime = ADC_SampleTime::C239);
void setPinMode(PinMode mode) volatile;
void setAlternateFunction(GPIO_Alternate_Function AF) volatile;
void setPinType(PinType type) volatile;
void setOutputSpeed(OutputSpeed speed) volatile;
void setInternalResistor(InternalResistorType type) volatile;
void useAsExternalInterrupt(TriggerMode mode, EXTICallback callback);
private:
friend class GPIOManager;
explicit SHAL_GPIO(GPIO_Key key);
SHAL_GPIO();
GPIO_Key m_GPIO_KEY = GPIO_Key::INVALID;
};
//Init SHAL_GPIO for normal use
#define PIN_TO_KEY(name) GPIO_Key::name
#define PIN(name) GPIOManager::get(PIN_TO_KEY(name))
#define GET_GPIO(key) GPIOManager::get(key)
#define SET_ANALOGREAD_ADC(x) GPIOManager::setGPIOADC(x)
//Manages instances of SHAL_GPIO objects
class GPIOManager{
public:
static SHAL_GPIO& get(GPIO_Key);
static SHAL_ADC getGPIOADC(){ return m_GPIO_ADC;}
static void setGPIOADC(SHAL_ADC adc){m_GPIO_ADC = adc;}
GPIOManager() = delete;
private:
inline static SHAL_GPIO m_gpios[AVAILABLE_PORTS][PINS_PER_PORT] = {{}};
inline static SHAL_ADC m_GPIO_ADC = SHAL_ADC(1);
};
#endif //SHMINGO_HAL_SHAL_GPIO_H

View File

@@ -0,0 +1,47 @@
//
// Created by Luca on 9/6/2025.
//
#ifndef SHAL_GPIO_REG_H
#define SHAL_GPIO_REG_H
#if defined(STM32F030x6)
#include "stm32f030x6.h"
#elif defined(STM32F030x8)
#include "stm32f030x8.h"
#elif defined(STM32F031x6)
#include "stm32f031x6.h"
#elif defined(STM32F038xx)
#include "stm32f038xx.h"
#elif defined(STM32F042x6)
#include "stm32f042x6.h"
#elif defined(STM32F048xx)
#include "stm32f048xx.h"
#elif defined(STM32F051x8)
#include "stm32f051x8.h"
#elif defined(STM32F058xx)
#include "stm32f058xx.h"
#elif defined(STM32F070x6)
#include "stm32f070x6.h"
#elif defined(STM32F070xB)
#include "stm32f070xb.h"
#elif defined(STM32F071xB)
#include "stm32f071xb.h"
#elif defined(STM32F072xB)
#include "SHAL_GPIO_REG_F072xB.h"
#elif defined(STM32F078xx)
#include "stm32f078xx.h"
#elif defined(STM32F091xC)
#include "stm32f091xc.h"
#elif defined(STM32F098xx)
#include "stm32f098xx.h"
#elif defined(STM32F030xC)
#include "stm32f030xc.h"
#else
#error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)"
#endif
#endif //SHMINGO_HAL_SHAL_GPIO_REG_H

View File

@@ -0,0 +1,76 @@
//
// Created by Luca on 9/6/2025.
//
#ifndef SHAL_GPIO_TYPES_H
#define SHAL_GPIO_TYPES_H
#include "SHAL_CORE.h"
#include "SHAL_ADC.h"
struct SHAL_EXTIO_Register{
volatile uint32_t* EXT_ICR;
uint32_t mask;
IRQn_Type IRQN;
};
struct SHAL_GPIO_Peripheral {
GPIO_TypeDef * reg;
unsigned long global_offset;
};
struct SHAL_Peripheral_Register {
volatile uint32_t* reg;
unsigned long offset;
};
struct SHAL_GPIO_Port_Info{
uint8_t number;
ADC_Channel ADCChannel;
};
enum class PinMode : uint8_t{
INPUT_MODE = 0x00,
OUTPUT_MODE = 0x01,
ALTERNATE_FUNCTION_MODE = 0x02,
ANALOG_MODE = 0x03,
INVALID = 0x00,
};
enum class GPIO_Alternate_Function : uint8_t{
AF0 = 0x00,
AF1 = 0x01,
AF2 = 0x02,
AF3 = 0x03,
AF4 = 0x04,
AF5 = 0x05,
AF6 = 0x06,
AF7 = 0x07,
};
enum class PinType : uint8_t{
PUSH_PULL = 0x00,
OPEN_DRAIN = 0x01,
};
enum class InternalResistorType : uint8_t{
NO_PULL = 0x00,
PULLUP = 0x01,
PULLDOWN = 0x02,
};
enum class OutputSpeed : uint8_t{
LOW_SPEED = 0x00,
MEDIUM_SPEED = 0x01,
HIGH_SPEED = 0x02,
VERY_HIGH_SPEED = 0x03,
};
enum class TriggerMode : uint8_t{
RISING_EDGE,
FALLING_EDGE,
RISING_FALLING_EDGE
};
#endif //SHMINGO_HAL_SHAL_GPIO_TYPES_H

View File

@@ -0,0 +1,94 @@
//
// Created by Luca on 9/9/2025.
//
#ifndef SHAL_I2C_REG_F072XB_H
#define SHAL_I2C_REG_F072XB_H
#include "SHAL_CORE.h"
#include <cassert>
#include "SHAL_I2C_TYPES.h"
#define NUM_I2C_BUSES 2
#define SHAL_I2C1 I2C(1)
#define SHAL_I2C2 I2C(2)
enum class I2C_Pair : uint8_t{
//I2C_1
SCL1B6_SDA1B7, //AF1
SCL1B8_SDA1B9, //AF1
//I2C_2
SCL2B10_SDA2B11, //AF1
SCL2B13_SDA2B14, //AF5
NUM_PAIRS,
INVALID
};
constexpr SHAL_I2C_Pair getI2CPair(const I2C_Pair pair){
switch(pair){
case I2C_Pair::SCL1B6_SDA1B7: return {I2C1,GPIO_Key::B6,GPIO_Key::B7,GPIO_Alternate_Function::AF1,GPIO_Alternate_Function::AF1};
case I2C_Pair::SCL1B8_SDA1B9: return {I2C1,GPIO_Key::B8,GPIO_Key::B9,GPIO_Alternate_Function::AF1,GPIO_Alternate_Function::AF1};
case I2C_Pair::SCL2B10_SDA2B11: return {I2C2,GPIO_Key::B10,GPIO_Key::B11,GPIO_Alternate_Function::AF1,GPIO_Alternate_Function::AF1};
case I2C_Pair::SCL2B13_SDA2B14: return {I2C2,GPIO_Key::B13,GPIO_Key::B14,GPIO_Alternate_Function::AF5,GPIO_Alternate_Function::AF5};
case I2C_Pair::NUM_PAIRS:
case I2C_Pair::INVALID:
assert(false);
return {nullptr,GPIO_Key::INVALID,GPIO_Key::INVALID,GPIO_Alternate_Function::AF0,GPIO_Alternate_Function::AF0};
}
__builtin_unreachable();
}
constexpr SHAL_I2C_Enable_Reg getI2CEnableReg(const I2C_Pair pair){
switch(pair){
case I2C_Pair::SCL1B6_SDA1B7:
case I2C_Pair::SCL1B8_SDA1B9:
return {&RCC->APB1ENR,RCC_APB1ENR_I2C1EN};
case I2C_Pair::SCL2B10_SDA2B11:
case I2C_Pair::SCL2B13_SDA2B14:
return {&RCC->APB1ENR,RCC_APB1ENR_I2C2EN};
case I2C_Pair::NUM_PAIRS:
case I2C_Pair::INVALID:
assert(false);
return {nullptr, 0};
}
__builtin_unreachable();
}
constexpr SHAL_I2C_Reset_Reg getI2CResetReg(const I2C_Pair pair){
switch(pair){
case I2C_Pair::SCL1B6_SDA1B7:
case I2C_Pair::SCL1B8_SDA1B9:
return {&RCC->APB1RSTR,RCC_APB1RSTR_I2C1RST};
case I2C_Pair::SCL2B10_SDA2B11:
case I2C_Pair::SCL2B13_SDA2B14:
return {&RCC->APB1RSTR,RCC_APB1RSTR_I2C2RST};
case I2C_Pair::NUM_PAIRS:
case I2C_Pair::INVALID:
assert(false);
return {nullptr, 0};
}
__builtin_unreachable();
}
//Gets all the bits in the I2C timer register, these values should rarely be manually set, but I wanted to support it anyway
constexpr SHAL_I2C_Timing_Reg getI2CTimerReg(const I2C_Pair pair){
switch(pair){
case I2C_Pair::SCL1B6_SDA1B7:
case I2C_Pair::SCL1B8_SDA1B9:
return {&I2C1->TIMINGR,31,23,19,15,7};
case I2C_Pair::SCL2B10_SDA2B11:
case I2C_Pair::SCL2B13_SDA2B14:
return {&I2C2->TIMINGR,31,23,19,15,7};
case I2C_Pair::NUM_PAIRS:
case I2C_Pair::INVALID:
assert(false);
__builtin_unreachable();
}
__builtin_unreachable();
}
#endif //SHAL_I2C_REG_F072XB_H

View File

@@ -0,0 +1,75 @@
//
// Created by Luca on 9/9/2025.
//
#ifndef SHMINGO_HAL_SHAL_I2C_H
#define SHMINGO_HAL_SHAL_I2C_H
#include <cstdio>
#include "SHAL_CORE.h"
#include "SHAL_I2C_REG.h"
class SHAL_I2C{
friend class I2CManager;
public:
void init(I2C_Pair pair) volatile;
/// General I2C function to send commands to a device, then read back any returned data if necessary
/// \param addr address of slave device
/// \param writeData pointer to array of write commands
/// \param writeLen number of write commands
/// \param readData pointer to buffer to write received data to
/// \param readLen number of bytes to be read
void masterWriteRead(uint8_t addr,const uint8_t* writeData, size_t writeLen, uint8_t* readData, size_t readLen);
uint8_t masterWriteReadByte(uint8_t addr, const uint8_t* writeData, size_t writeLen);
/// Function to write an array of commands to an I2C device
/// \param addr Address of slave device
/// \param writeData Pointer to array of commands
/// \param writeLen Number of commands
void masterWrite(uint8_t addr, const uint8_t* writeData, uint8_t writeLen);
/// Function to read bytes from an I2C device
/// \param addr Address of slave device
/// \param readBuffer Pointer to buffer where data will be placed
/// \param bytesToRead Number of bytes to read
void masterRead(uint8_t addr, uint8_t* readBuffer, uint8_t bytesToRead);
//Manually set the clock configuration. Refer to your MCU's reference manual for examples
void setClockConfig(uint8_t prescaler, uint8_t dataSetupTime, uint8_t dataHoldTime, uint8_t SCLHighPeriod, uint8_t SCLLowPeriod);
//Set clock configuration based on a value calculated from STM32CubeMX, or other similar tools
void setClockConfig(uint32_t configuration);
private:
SHAL_I2C() = default;
I2C_Pair m_I2CPair = I2C_Pair::INVALID; //Initialize to invalid
};
#define I2C(num) I2CManager::get(num)
class I2CManager{
public:
static SHAL_I2C& get(uint8_t i2c);
I2CManager() = delete;
private:
inline static SHAL_I2C m_I2CBuses[NUM_I2C_BUSES] = {};
};
#endif //SHMINGO_HAL_SHAL_I2C_H

View File

@@ -0,0 +1,44 @@
//
// Created by Luca on 9/9/2025.
//
#ifndef SHAL_I2C_REG_H
#define SHAL_I2C_REG_H
#if defined(STM32F030x6)
#include "stm32f030x6.h"
#elif defined(STM32F030x8)
#include "stm32f030x8.h"
#elif defined(STM32F031x6)
#include "stm32f031x6.h"
#elif defined(STM32F038xx)
#include "stm32f038xx.h"
#elif defined(STM32F042x6)
#include "stm32f042x6.h"
#elif defined(STM32F048xx)
#include "stm32f048xx.h"
#elif defined(STM32F051x8)
#include "stm32f051x8.h"
#elif defined(STM32F058xx)
#include "stm32f058xx.h"
#elif defined(STM32F070x6)
#include "stm32f070x6.h"
#elif defined(STM32F070xB)
#include "stm32f070xb.h"
#elif defined(STM32F071xB)
#include "stm32f071xb.h"
#elif defined(STM32F072xB)
#include "SHAL_I2C_REG_F072xB.h"
#elif defined(STM32F078xx)
#include "stm32f078xx.h"
#elif defined(STM32F091xC)
#include "stm32f091xc.h"
#elif defined(STM32F098xx)
#include "stm32f098xx.h"
#elif defined(STM32F030xC)
#include "stm32f030xc.h"
#else
#error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)"
#endif
#endif //SHAL_I2C_REG_H

View File

@@ -0,0 +1,40 @@
//
// Created by Luca on 9/9/2025.
//
#ifndef SHMINGO_HAL_SHAL_I2C_TYPES_H
#define SHMINGO_HAL_SHAL_I2C_TYPES_H
#include "SHAL_CORE.h"
#include "SHAL_GPIO_REG.h"
//Information necessary for I2C
struct SHAL_I2C_Pair {
I2C_TypeDef* I2CReg;
GPIO_Key SCL_Key;
GPIO_Key SDA_Key;
GPIO_Alternate_Function SCL_Mask;
GPIO_Alternate_Function SDA_Mask;
};
struct SHAL_I2C_Enable_Reg{
volatile uint32_t* reg;
uint32_t mask;
};
struct SHAL_I2C_Reset_Reg{
volatile uint32_t* reg;
uint32_t mask;
};
//Manual values for I2C timer register
struct SHAL_I2C_Timing_Reg{
volatile uint32_t* reg;
uint8_t prescaler_offset;
uint8_t dataSetupTime_offset;
uint8_t dataHoldTime_offset;
uint8_t SCLHighPeriod_offset;
uint8_t SCLLowPeriod_offset;
};
#endif //SHMINGO_HAL_SHAL_I2C_TYPES_H

View File

@@ -0,0 +1,106 @@
/**
******************************************************************************
* @file SHAL_TIM_REG.h
* @author Luca Lizaranzu
* @brief Defines universal macros and objects used across all STM32 families
******************************************************************************
*/
#ifndef SHAL_TIM_REG_H
#define SHAL_TIM_REG_H
#include <cassert>
#include <stm32f072xb.h>
#include "SHAL_CORE.h"
#include "SHAL_TIM_TYPES.h"
enum class Timer_Key : uint8_t { //For STM32F072
S_TIM1,
S_TIM2,
S_TIM3,
S_TIM6,
S_TIM7,
S_TIM14,
S_TIM15,
S_TIM16,
S_TIM17,
NUM_TIMERS,
S_TIM_INVALID
};
#define SHAL_TIM1 TimerManager::get(Timer_Key::S_TIM1)
#define SHAL_TIM2 TimerManager::get(Timer_Key::S_TIM2)
#define SHAL_TIM3 TimerManager::get(Timer_Key::S_TIM3)
#define SHAL_TIM6 TimerManager::get(Timer_Key::S_TIM6)
#define SHAL_TIM7 TimerManager::get(Timer_Key::S_TIM7)
#define SHAL_TIM14 TimerManager::get(Timer_Key::S_TIM14)
#define SHAL_TIM15 TimerManager::get(Timer_Key::S_TIM15)
#define SHAL_TIM16 TimerManager::get(Timer_Key::S_TIM16)
#define SHAL_TIM17 TimerManager::get(Timer_Key::S_TIM17)
//Get TIMER_KEY peripheral struct including bus register, enable mask, TIMER_KEY mask
constexpr TIM_RCC_Enable getTimerRCC(Timer_Key t) {
switch(t) {
case Timer_Key::S_TIM1: return {&RCC->APB2ENR, RCC_APB2ENR_TIM1EN_Pos};
case Timer_Key::S_TIM2: return {&RCC->APB1ENR, RCC_APB1ENR_TIM2EN_Pos};
case Timer_Key::S_TIM3: return {&RCC->APB1ENR, RCC_APB1ENR_TIM3EN_Pos};
case Timer_Key::S_TIM6: return {&RCC->APB1ENR, RCC_APB1ENR_TIM6EN_Pos};
case Timer_Key::S_TIM7: return {&RCC->APB1ENR, RCC_APB1ENR_TIM7EN_Pos};
case Timer_Key::S_TIM14: return {&RCC->APB1ENR, RCC_APB1ENR_TIM14EN_Pos};
case Timer_Key::S_TIM15: return {&RCC->APB2ENR, RCC_APB2ENR_TIM15EN_Pos};
case Timer_Key::S_TIM16: return {&RCC->APB2ENR, RCC_APB2ENR_TIM16EN_Pos};
case Timer_Key::S_TIM17: return {&RCC->APB2ENR, RCC_APB2ENR_TIM17EN_Pos};
case Timer_Key::NUM_TIMERS:
case Timer_Key::S_TIM_INVALID:
assert(false);
return {nullptr, 0};; //Unreachable
}
__builtin_unreachable();
}
//Get actual register value based on enum
constexpr volatile TIM_TypeDef* getTimerRegister(Timer_Key t) {
switch(t) {
case Timer_Key::S_TIM1: return TIM1;
case Timer_Key::S_TIM2: return TIM2;
case Timer_Key::S_TIM3: return TIM3;
case Timer_Key::S_TIM6: return TIM6;
case Timer_Key::S_TIM7: return TIM7;
case Timer_Key::S_TIM14: return TIM14;
case Timer_Key::S_TIM15: return TIM15;
case Timer_Key::S_TIM16: return TIM16;
case Timer_Key::S_TIM17: return TIM17;
case Timer_Key::NUM_TIMERS:
case Timer_Key::S_TIM_INVALID:
assert(false);
return nullptr; //Unreachable
}
__builtin_unreachable();
}
constexpr IRQn_Type getIRQn(Timer_Key t) {
switch(t) {
case Timer_Key::S_TIM1: return TIM1_BRK_UP_TRG_COM_IRQn;
case Timer_Key::S_TIM2: return TIM2_IRQn;
case Timer_Key::S_TIM3: return TIM3_IRQn;
case Timer_Key::S_TIM6: return TIM6_DAC_IRQn;
case Timer_Key::S_TIM7: return TIM7_IRQn;
case Timer_Key::S_TIM14: return TIM14_IRQn;
case Timer_Key::S_TIM15: return TIM15_IRQn;
case Timer_Key::S_TIM16: return TIM16_IRQn;
case Timer_Key::S_TIM17: return TIM17_IRQn;
case Timer_Key::NUM_TIMERS:
case Timer_Key::S_TIM_INVALID:
assert(false);
return TIM1_BRK_UP_TRG_COM_IRQn; //Unreachable
}
__builtin_unreachable();
}
#endif

View File

@@ -0,0 +1,73 @@
/**
******************************************************************************
* @file SHAL_TIM.h
* @author Luca Lizaranzu
* @brief Declarations of TIMER_KEY related objects
******************************************************************************
*/
#ifndef SHAL_TIM_H
#define SHAL_TIM_H
#include "SHAL_TIM_REG_F072xB.h"
#include "SHAL_TIM_CALLBACK.h"
#include <array>
class Timer {
friend class TimerManager;
public:
///
/// \param prescaler The amount of times the base clock has to cycle before the timer adds one to the count
/// \param autoReload The number of timer counts before the count is reset and IRQ is called
void init(uint32_t prescaler, uint32_t autoReload);
//Starts the counter
void start();
//Stops the counter
void stop();
//Set prescaler value
void setPrescaler(uint16_t presc);
//Set auto reload register
void setARR(uint16_t arr);
//Enable interrupts
void enableInterrupt();
//Set TIMER_KEY IRQ callback function
void setCallbackFunc(TimerCallback callback){
registerTimerCallback(TIMER_KEY, callback);
}
private:
explicit Timer(Timer_Key t);
Timer();
Timer_Key TIMER_KEY;
};
#define getTimer(timer_key) TimerManager::get(timer_key)
#define TIM(num) TimerManager::getTimerFromIndex(num)
//Manages all timers so user does not have to personally initialize
class TimerManager{
public:
static Timer& get(Timer_Key);
static Timer& getTimerFromIndex(uint8_t index){return timers[index];}
TimerManager() = delete;
private:
inline static Timer timers[static_cast<int>(Timer_Key::NUM_TIMERS)] = {};
};
#endif

View File

@@ -0,0 +1,32 @@
/**
******************************************************************************
* @file SHAL.h
* @author Luca Lizaranzu
* @brief Utilities for creating and populating the TIMER_KEY IRQ callback table
* globally, see usage in SHAL_TIM.h. Created in use for singleton TIMER_KEY abstractions
******************************************************************************
*/
#ifndef SHAL_TIM_CALLBACK_H
#define SHAL_TIM_CALLBACK_H
#include "SHAL_CORE.h"
#include "SHAL_TIM_REG.h"
#define DEFINE_TIMER_IRQ(key, irq_handler) \
extern "C" void irq_handler(void) { \
auto tim_reg = getTimerRegister(key); \
if (tim_reg->SR & TIM_SR_UIF) { \
tim_reg->SR &= ~TIM_SR_UIF; /* clear flag */ \
auto cb = timer_callbacks[static_cast<int>(key)]; \
if (cb) cb(); \
}; \
};
typedef void (*TimerCallback)(); //Typedef for callback function
[[maybe_unused]] static TimerCallback timer_callbacks[static_cast<int>(Timer_Key::NUM_TIMERS)] = {nullptr}; //Timer IRQ Callback table
void registerTimerCallback(Timer_Key key, TimerCallback callback);
#endif //SHMINGO_HAL_SHAL_TIM_CALLBACK_H

View File

@@ -0,0 +1,44 @@
//
// Created by Luca on 9/7/2025.
//
#ifndef SHMINGO_HAL_SHAL_TIM_REG_H
#define SHMINGO_HAL_SHAL_TIM_REG_H
#if defined(STM32F030x6)
#include "stm32f030x6.h"
#elif defined(STM32F030x8)
#include "stm32f030x8.h"
#elif defined(STM32F031x6)
#include "stm32f031x6.h"
#elif defined(STM32F038xx)
#include "stm32f038xx.h"
#elif defined(STM32F042x6)
#include "stm32f042x6.h"
#elif defined(STM32F048xx)
#include "stm32f048xx.h"
#elif defined(STM32F051x8)
#include "stm32f051x8.h"
#elif defined(STM32F058xx)
#include "stm32f058xx.h"
#elif defined(STM32F070x6)
#include "stm32f070x6.h"
#elif defined(STM32F070xB)
#include "stm32f070xb.h"
#elif defined(STM32F071xB)
#include "stm32f071xb.h"
#elif defined(STM32F072xB)
#include "SHAL_TIM_REG_F072xB.h"
#elif defined(STM32F078xx)
#include "stm32f078xx.h"
#elif defined(STM32F091xC)
#include "stm32f091xc.h"
#elif defined(STM32F098xx)
#include "stm32f098xx.h"
#elif defined(STM32F030xC)
#include "stm32f030xc.h"
#else
#error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)"
#endif
#endif //SHMINGO_HAL_SHAL_TIM_REG_H

View File

@@ -0,0 +1,15 @@
//
// Created by Luca on 9/7/2025.
//
#ifndef SHMINGO_HAL_SHAL_TIM_TYPES_H
#define SHMINGO_HAL_SHAL_TIM_TYPES_H
#include "SHAL_CORE.h"
struct TIM_RCC_Enable{
volatile uint32_t* busEnableReg;
uint32_t offset;
};
#endif //SHMINGO_HAL_SHAL_TIM_TYPES_H

View File

@@ -0,0 +1,123 @@
//
// Created by Luca on 9/7/2025.
//
#ifndef SHAL_UART_REG_F072XB_H
#define SHAL_UART_REG_F072XB_H
#include <stm32f072xb.h>
#include <cassert>
#include "SHAL_UART_TYPES.h"
#define NUM_USART_LINES 4
#define SHAL_UART1 UART(1)
#define SHAL_UART2 UART(2)
#define SHAL_UART3 UART(3)
#define SHAL_UART4 UART(4)
//Valid usart Tx and Rx pairings for STM32F072
enum class UART_Pair : uint8_t{
//UART1
Tx1A9_Rx1A10,
Tx1B6_Rx1B7,
//UART2
Tx2A2_Rx2A3,
Tx2A14_Rx2A15,
//UART3
Tx3B10_Rx3B11,
Tx3C4_Rx3C5,
Tx3C10_Rx3C11,
//UART4
Tx4A0_Rx4A1,
Tx4C10_Rx4C11,
NUM_PAIRS,
INVALID
};
constexpr SHAL_UART_Pair getUARTPair(const UART_Pair pair){
switch(pair){
case UART_Pair::Tx1A9_Rx1A10: return {USART1, GPIO_Key::A9, GPIO_Key::A10, GPIO_Alternate_Function::AF1, GPIO_Alternate_Function::AF1};
case UART_Pair::Tx1B6_Rx1B7: return {USART1, GPIO_Key::B6, GPIO_Key::B7, GPIO_Alternate_Function::AF0, GPIO_Alternate_Function::AF0};
case UART_Pair::Tx2A2_Rx2A3: return {USART2, GPIO_Key::A2, GPIO_Key::A3, GPIO_Alternate_Function::AF1, GPIO_Alternate_Function::AF1};
case UART_Pair::Tx2A14_Rx2A15: return {USART2, GPIO_Key::A14, GPIO_Key::A15, GPIO_Alternate_Function::AF1, GPIO_Alternate_Function::AF1};
case UART_Pair::Tx3B10_Rx3B11: return {USART3, GPIO_Key::B10, GPIO_Key::B11, GPIO_Alternate_Function::AF4, GPIO_Alternate_Function::AF4};
case UART_Pair::Tx3C4_Rx3C5: return {USART3, GPIO_Key::C4, GPIO_Key::C5, GPIO_Alternate_Function::AF1, GPIO_Alternate_Function::AF1};
case UART_Pair::Tx3C10_Rx3C11: return {USART3, GPIO_Key::C10, GPIO_Key::C11, GPIO_Alternate_Function::AF1, GPIO_Alternate_Function::AF1};
case UART_Pair::Tx4A0_Rx4A1: return {USART4, GPIO_Key::A0, GPIO_Key::A1, GPIO_Alternate_Function::AF4, GPIO_Alternate_Function::AF4};
case UART_Pair::Tx4C10_Rx4C11: return {USART4, GPIO_Key::C10, GPIO_Key::C11, GPIO_Alternate_Function::AF0, GPIO_Alternate_Function::AF0};
case UART_Pair::NUM_PAIRS:
case UART_Pair::INVALID:
assert(false);
return {nullptr, GPIO_Key::INVALID, GPIO_Key::INVALID, GPIO_Alternate_Function::AF0, GPIO_Alternate_Function::AF0};
}
__builtin_unreachable();
}
constexpr uint8_t getUARTChannel(const UART_Pair pair){
switch(pair){
case UART_Pair::Tx1A9_Rx1A10:
case UART_Pair::Tx1B6_Rx1B7:
return 0;
case UART_Pair::Tx2A2_Rx2A3:
case UART_Pair::Tx2A14_Rx2A15:
return 1;
case UART_Pair::Tx3B10_Rx3B11:
case UART_Pair::Tx3C4_Rx3C5:
case UART_Pair::Tx3C10_Rx3C11:
return 2;
case UART_Pair::Tx4A0_Rx4A1:
case UART_Pair::Tx4C10_Rx4C11:
return 3;
case UART_Pair::NUM_PAIRS:
case UART_Pair::INVALID:
assert(false);
return 0;
}
__builtin_unreachable();
}
constexpr SHAL_UART_ENABLE_REG getUARTEnableReg(const UART_Pair pair){
switch(pair){
case UART_Pair::Tx1A9_Rx1A10:
case UART_Pair::Tx1B6_Rx1B7:
return {&RCC->APB2ENR,RCC_APB2ENR_USART1EN};
case UART_Pair::Tx2A2_Rx2A3:
case UART_Pair::Tx2A14_Rx2A15:
return {&RCC->APB1ENR,RCC_APB1ENR_USART2EN};
case UART_Pair::Tx3B10_Rx3B11:
case UART_Pair::Tx3C4_Rx3C5:
case UART_Pair::Tx3C10_Rx3C11:
return {&RCC->APB1ENR,RCC_APB1ENR_USART3EN};
case UART_Pair::Tx4A0_Rx4A1:
case UART_Pair::Tx4C10_Rx4C11:
return {&RCC->APB1ENR,RCC_APB1ENR_USART4EN};
case UART_Pair::NUM_PAIRS:
case UART_Pair::INVALID:
assert(false);
return {nullptr, 0};
}
__builtin_unreachable();
}
constexpr uint32_t getAFMask(const GPIO_Alternate_Function mask){
switch(mask){
case GPIO_Alternate_Function::AF0: return 0x00;
case GPIO_Alternate_Function::AF1: return 0x01;
case GPIO_Alternate_Function::AF2: return 0x02;
case GPIO_Alternate_Function::AF3: return 0x03;
case GPIO_Alternate_Function::AF4: return 0x04;
case GPIO_Alternate_Function::AF5: return 0x05;
case GPIO_Alternate_Function::AF6: return 0x06;
case GPIO_Alternate_Function::AF7: return 0x07;
}
__builtin_unreachable();
}
#endif //SHMINGO_HAL_SHAL_UART_REG_F072XB_H

View File

@@ -0,0 +1,57 @@
/**
******************************************************************************
* @file SHAL_TIM.h
* @author Luca Lizaranzu
* @brief Relating to SHAL_UART and USART object abstractions
******************************************************************************
*/
#ifndef SHMINGO_HAL_SHAL_UART_H
#define SHMINGO_HAL_SHAL_UART_H
#include "SHAL_UART_REG.h"
class SHAL_UART{
friend class UARTManager;
public:
void init(UART_Pair pair);
//begins Tx and Usart TODO either modify this function or add a new one that supports Rx
void begin(uint32_t baudRate) volatile;
//Sends a string
void sendString(const char* s) volatile;
//Sends a char
void sendChar(char c) volatile;
private:
SHAL_UART() = default; //Initializer for array
//Creates a SHAL_UART based on a pair of two valid U(S)ART pins
UART_Pair m_UARTPair = UART_Pair::INVALID;
};
#define UART(num) UARTManager::get(num)
class UARTManager{
public:
static SHAL_UART& get(uint8_t uart);
UARTManager() = delete;
private:
inline static SHAL_UART m_UARTs[NUM_USART_LINES] = {};
};
#endif //SHMINGO_HAL_SHAL_UART_H

View File

@@ -0,0 +1,46 @@
//
// Created by Luca on 9/7/2025.
//
#ifndef SHAL_UART_REG_H
#define SHAL_UART_REG_H
#if defined(STM32F030x6)
#include "stm32f030x6.h"
#elif defined(STM32F030x8)
#include "stm32f030x8.h"
#elif defined(STM32F031x6)
#include "stm32f031x6.h"
#elif defined(STM32F038xx)
#include "stm32f038xx.h"
#elif defined(STM32F042x6)
#include "stm32f042x6.h"
#elif defined(STM32F048xx)
#include "stm32f048xx.h"
#elif defined(STM32F051x8)
#include "stm32f051x8.h"
#elif defined(STM32F058xx)
#include "stm32f058xx.h"
#elif defined(STM32F070x6)
#include "stm32f070x6.h"
#elif defined(STM32F070xB)
#include "stm32f070xb.h"
#elif defined(STM32F071xB)
#include "stm32f071xb.h"
#elif defined(STM32F072xB)
#include "SHAL_UART_REG_F072xB.h"
#elif defined(STM32F078xx)
#include "stm32f078xx.h"
#elif defined(STM32F091xC)
#include "stm32f091xc.h"
#elif defined(STM32F098xx)
#include "stm32f098xx.h"
#elif defined(STM32F030xC)
#include "stm32f030xc.h"
#else
#error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)"
#endif
#endif //SHMINGO_HAL_SHAL_UART_REG_H

View File

@@ -0,0 +1,27 @@
//
// Created by Luca on 9/7/2025.
//
#ifndef SHAL_UART_TYPES_H
#define SHAL_UART_TYPES_H
#include "SHAL_CORE.h"
#include "SHAL_GPIO_REG.h"
//Represents a pair of pins usable for USART Tx + Rx in combination, and their alternate function mapping
struct SHAL_UART_Pair{
USART_TypeDef* USARTReg;
GPIO_Key TxKey;
GPIO_Key RxKey;
GPIO_Alternate_Function TxAlternateFunctionMask;
GPIO_Alternate_Function RxAlternateFunctionMask;
};
struct SHAL_UART_ENABLE_REG{
volatile uint32_t* reg;
uint32_t mask;
};
#endif //SHMINGO_HAL_SHAL_UART_TYPES_H

View File

@@ -8,6 +8,11 @@
#ifndef SHAL_H #ifndef SHAL_H
#define SHAL_H #define SHAL_H
#include "SHAL_TIM.h"
#include "SHAL_GPIO.h"
#include "SHAL_UART.h"
#include "SHAL_I2C.h"
#include "SHAL_ADC.h"

View File

@@ -0,0 +1,42 @@
//
// Created by Luca on 9/15/2025.
//
#include "SHAL_CORE.h"
void SHAL_init(){
systick_init(); //Just this for now
}
void systick_init(){
SysTick->CTRL = 0; //Disable first
SysTick->LOAD = 0xFFFFFF; //Max 24-bit
SysTick->VAL = 0; //Clear
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
}
void SHAL_delay_us(uint32_t us){
uint32_t ticks = us * (SystemCoreClock / 1000000U);
uint32_t start = SysTick->VAL;
//Calculate target value (may wrap around)
uint32_t target = (start >= ticks) ? (start - ticks) : (start + 0x01000000 - ticks);
target &= 0x00FFFFFF;
//Wait until we reach the target
if (start >= ticks) {
//No wraparound case
while (SysTick->VAL > target) {}
} else {
while (SysTick->VAL <= start) {} //Wait for wraparound
while (SysTick->VAL > target) {} //Wait for target
}
}
void SHAL_delay_ms(uint32_t ms){
while(ms-- > 0){
SHAL_delay_us(1000);
}
}

View File

@@ -0,0 +1,40 @@
//
// Created by Luca on 9/3/2025.
//
#include "SHAL_EXTI_CALLBACK.h"
#if defined(STM32F030x6)
#elif defined(STM32F030x8)
#elif defined(STM32F031x6)
#elif defined(STM32F038xx)
#elif defined(STM32F042x6)
#elif defined(STM32F048xx)
#elif defined(STM32F051x8)
#elif defined(STM32F058xx)
#elif defined(STM32F070x6)
#elif defined(STM32F070xB)
#elif defined(STM32F071xB)
#elif defined(STM32F072xB)
DEFINE_MULTI_EXTI_IRQ(0,1);
DEFINE_MULTI_EXTI_IRQ(2,3);
DEFINE_MULTI_EXTI_IRQ(4,15);
#elif defined(STM32F078xx)
#include "stm32f078xx.h"
#elif defined(STM32F091xC)
#include "stm32f091xc.h"
#elif defined(STM32F098xx)
#include "stm32f098xx.h"
#elif defined(STM32F030xC)
#include "stm32f030xc.h"
#else
#error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)"
#endif
//Link function to EXTI line
void registerEXTICallback(GPIO_Key key, EXTICallback callback){
EXTI_callbacks[getGPIORegister(key).global_offset] = callback;
}

View File

@@ -0,0 +1,115 @@
//
// Created by Luca on 9/21/2025.
//
#include "SHAL_ADC.h"
//Can hard code registers on F0 because all F0 devices have only one ADC, and use only one clock
SHAL_Result SHAL_ADC::init() {
if(m_ADCKey == ADC_Key::INVALID || m_ADCKey == ADC_Key::NUM_ADC){
return SHAL_Result::ERROR;
}
ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey);
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; //Enable clock
RCC->CR2 |= RCC_CR2_HSI14ON; //Start peripheral oscillator
if(!SHAL_WAIT_FOR_CONDITION_US(((RCC->CR2 & RCC_CR2_HSI14RDY) != 0),50)){ //Wait for clock OKAY
return SHAL_Result::ERROR;
}
if((ADC_reg->ISR & ADC_ISR_ADRDY) != 0){ //Set ADRDY to 0
ADC_reg->ISR |= ADC_ISR_ADRDY;
}
ADC_reg->CR |= ADC_CR_ADEN; //Enable
if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->ISR & ADC_ISR_ADRDY) != 0),50)){ //Wait for disable
return SHAL_Result::ERROR;
}
if(calibrate() != SHAL_Result::OKAY){ //Calibrate
return SHAL_Result::ERROR;
}
return SHAL_Result::OKAY;
}
SHAL_Result SHAL_ADC::calibrate() {
if(m_ADCKey == ADC_Key::INVALID || m_ADCKey == ADC_Key::NUM_ADC){
return SHAL_Result::ERROR;
}
ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey);
if((ADC_reg->CR & ADC_CR_ADEN) != 0){ //Clear ADEN (enable)
ADC_reg->CR |= ADC_CR_ADDIS;
}
if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->CR & ADC_CR_ADEN) == 0),50)){ //Wait for disable
return SHAL_Result::ERROR;
}
ADC_reg->CFGR1 &= ~ADC_CFGR1_DMAEN; //Clear DMAEN
ADC_reg->CR |= ADC_CR_ADCAL; //Launch calibration by setting ADCAL
if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->CR & ADC_CR_ADCAL) == 0),50)){ //Wait for calibration
return SHAL_Result::ERROR;
}
return SHAL_Result::OKAY;
}
uint16_t SHAL_ADC::singleConvertSingle(ADC_Channel channel, ADC_SampleTime time) {
ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey);
ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_TSEN; //Enable VREFINT and Temp sensor in global ADC struct
ADC_reg->CHSELR = static_cast<uint32_t>(channel); //Enable channel for conversion
ADC_reg->SMPR |= static_cast<uint32_t>(time); //Set sampling time
if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->ISR & ADC_ISR_EOC) != 0),500)){ //Wait for conversion
return 0; //Failed
}
uint16_t result = ADC_reg->DR;
return result;
}
void SHAL_ADC::multiConvertSingle(ADC_Channel* channels, const int numChannels, uint16_t* result, ADC_SampleTime time) {
ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey);
ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_TSEN; //Enable VREFINT and Temp sensor in global ADC struct
for(int i = 0; i < numChannels; i++){ //Enable all channels
ADC_reg->CHSELR = static_cast<uint32_t>(channels[i]);
}
ADC_reg->SMPR |= static_cast<uint32_t>(time); //Set sampling time
for(int i = 0; i < numChannels; i++){
if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->ISR & ADC_ISR_EOC) != 0),500)){ //Wait for conversion
continue; //Failed
}
result[i] = ADC_reg->DR;
}
}
SHAL_ADC &ADCManager::get(ADC_Key key) {
return m_ADCs[static_cast<uint8_t>(key)];
}
SHAL_ADC& ADCManager::getByIndex(int index) {
if(index < static_cast<int>(ADC_Key::NUM_ADC)){
return m_ADCs[index];
}
return m_ADCs[0];
}

View File

@@ -0,0 +1,128 @@
//
// Created by Luca on 8/30/2025.
//
#include "SHAL_GPIO.h"
#include "SHAL_EXTI_CALLBACK.h"
SHAL_GPIO::SHAL_GPIO() : m_GPIO_KEY(GPIO_Key::INVALID){
//Do not initialize anything
}
SHAL_GPIO::SHAL_GPIO(GPIO_Key key) : m_GPIO_KEY(key) {
volatile unsigned long* gpioEnable = getGPIORCCEnable(key).reg;
unsigned long gpioOffset = getGPIORCCEnable(key).offset;
*gpioEnable |= (1 << gpioOffset); //Set enable flag
}
void SHAL_GPIO::setLow() {
auto gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->ODR &= ~(1 << gpioPeripheral.global_offset);
}
void SHAL_GPIO::setHigh() {
auto gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->ODR |= (1 << gpioPeripheral.global_offset);
}
void SHAL_GPIO::toggle() volatile {
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->ODR ^= (1 << gpioPeripheral.global_offset);
}
void SHAL_GPIO::setPinType(PinType type) volatile {
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->OTYPER &= ~(1 << gpioPeripheral.global_offset);
gpioPeripheral.reg->OTYPER |= (static_cast<uint8_t>(type) << gpioPeripheral.global_offset);
}
void SHAL_GPIO::setOutputSpeed(OutputSpeed speed) volatile {
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->OSPEEDR |= (static_cast<uint8_t>(speed) << (2 * gpioPeripheral.global_offset));
}
void SHAL_GPIO::setInternalResistor(InternalResistorType type) volatile {
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->PUPDR &= ~(0x03 << (2 * gpioPeripheral.global_offset));
gpioPeripheral.reg->PUPDR |= (static_cast<uint8_t>(type) << (2 * gpioPeripheral.global_offset));
}
void SHAL_GPIO::setAlternateFunction(GPIO_Alternate_Function AF) volatile {
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
int afrIndex = gpioPeripheral.global_offset < 8 ? 0 : 1; //Get index of AFR
gpioPeripheral.reg->AFR[afrIndex] &= ~(0xF << (gpioPeripheral.global_offset * 4));
gpioPeripheral.reg->AFR[afrIndex] |= (static_cast<int>(AF) << (gpioPeripheral.global_offset * 4));
}
void SHAL_GPIO::setPinMode(PinMode mode) volatile {
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->MODER &= ~(0x03 << (2 * gpioPeripheral.global_offset)); //Clear any previous mode
gpioPeripheral.reg->MODER |= (static_cast<uint8_t>(mode) << (2 * gpioPeripheral.global_offset)); //Set mode based on pinmode bit structure
}
void SHAL_GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback) {
uint32_t gpioPin = getGPIORegister(m_GPIO_KEY).global_offset; //Use existing structs to get offset
setPinMode(PinMode::INPUT_MODE); //Explicitly set mode to input
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGCOMPEN; //Enable EXT, TODO check if this is different across STM32 models
NVIC_EnableIRQ(getGPIOEXTICR(m_GPIO_KEY).IRQN); //Enable IRQN for pin
EXTI->IMR |= (1 << gpioPin); //Enable correct EXTI line
SHAL_EXTIO_Register EXTILineEnable = getGPIOEXTICR(m_GPIO_KEY);
*EXTILineEnable.EXT_ICR |= EXTILineEnable.mask; //Set bits to enable correct port on correct line TODO Find way to clear bits before
uint32_t rising_mask = 0x00;
uint32_t falling_mask = 0x00;
//Set rising and falling edge triggers based on pin offset (enabled EXTI line)
switch(mode){
case TriggerMode::RISING_EDGE:
rising_mask = 1 << gpioPin;
break;
case TriggerMode::FALLING_EDGE:
falling_mask = 1 << gpioPin;
break;
case TriggerMode::RISING_FALLING_EDGE:
falling_mask = 1 << gpioPin;
falling_mask = 1 << gpioPin;
}
//Set triggers
EXTI->RTSR |= rising_mask;
EXTI->FTSR |= falling_mask;
//Set callback
registerEXTICallback(m_GPIO_KEY,callback);
__enable_irq(); //Enable IRQ just in case
}
uint16_t SHAL_GPIO::analogRead(ADC_SampleTime sampleTime) {
ADC_Channel channel = getGPIOPortInfo(m_GPIO_KEY).ADCChannel;
return GPIOManager::getGPIOADC().singleConvertSingle(channel,sampleTime);
}
SHAL_GPIO& GPIOManager::get(GPIO_Key key) {
unsigned int gpioPort = getGPIOPortNumber(key);
unsigned long gpioPin = getGPIORegister(key).global_offset; //Use existing structs to get offset
if (m_gpios[gpioPort][gpioPin].m_GPIO_KEY == GPIO_Key::INVALID){
m_gpios[gpioPort][gpioPin] = SHAL_GPIO(key);
}
return m_gpios[gpioPort][gpioPin];
}

View File

@@ -0,0 +1,142 @@
//
// Created by Luca on 9/9/2025.
//
#include "SHAL_I2C.h"
#include "SHAL_GPIO.h"
#include "SHAL_UART.h"
void SHAL_I2C::init(I2C_Pair pair) volatile {
m_I2CPair = pair;
SHAL_I2C_Pair I2CPair = getI2CPair(pair); //Get the I2C_PAIR information to be initialized
//Get the SHAL_GPIO pins for this SHAL_I2C setup
GPIO_Key SCL_Key = I2CPair.SCL_Key; //SCL pin
GPIO_Key SDA_Key = I2CPair.SDA_Key; //SDA pin
SHAL_I2C_Enable_Reg pairI2CEnable = getI2CEnableReg(pair); //Register and mask to enable the I2C peripheral
*pairI2CEnable.reg &= ~pairI2CEnable.mask; //Enable I2C peripheral clock
GET_GPIO(SCL_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE); //Implicitly initializes and enables GPIO bus
GET_GPIO(SDA_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE);
GET_GPIO(SCL_Key).setAlternateFunction(I2CPair.SCL_Mask);
GET_GPIO(SDA_Key).setAlternateFunction(I2CPair.SDA_Mask);
//These may be abstracted further to support multiple I2C configurations
GET_GPIO(SCL_Key).setPinType(PinType::OPEN_DRAIN);
GET_GPIO(SDA_Key).setPinType(PinType::OPEN_DRAIN);
GET_GPIO(SCL_Key).setOutputSpeed(OutputSpeed::HIGH_SPEED);
GET_GPIO(SDA_Key).setOutputSpeed(OutputSpeed::HIGH_SPEED);
GET_GPIO(SCL_Key).setInternalResistor(InternalResistorType::PULLUP);
GET_GPIO(SDA_Key).setInternalResistor(InternalResistorType::PULLUP);
SHAL_I2C_Reset_Reg pairI2CReset = getI2CResetReg(pair);
*pairI2CEnable.reg |= pairI2CEnable.mask; //Enable I2C peripheral clock
*pairI2CReset.reg |= pairI2CReset.mask; //Reset peripheral
*pairI2CReset.reg &= ~pairI2CReset.mask; //Reset peripheral
}
void SHAL_I2C::setClockConfig(uint8_t prescaler, uint8_t dataSetupTime, uint8_t dataHoldTime, uint8_t SCLHighPeriod, uint8_t SCLLowPeriod) {
SHAL_I2C_Timing_Reg clockReg = getI2CTimerReg(m_I2CPair);
*clockReg.reg |= (prescaler << clockReg.prescaler_offset);
*clockReg.reg |= (dataSetupTime << clockReg.dataSetupTime_offset);
*clockReg.reg |= (dataHoldTime << clockReg.dataHoldTime_offset);
*clockReg.reg |= (SCLHighPeriod << clockReg.SCLHighPeriod_offset);
*clockReg.reg |= (SCLLowPeriod << clockReg.SCLLowPeriod_offset);
getI2CPair(m_I2CPair).I2CReg->CR1 |= I2C_CR1_PE; //Enable I2C peripheral
}
void SHAL_I2C::setClockConfig(uint32_t configuration) {
*getI2CTimerReg(m_I2CPair).reg = configuration;
getI2CPair(m_I2CPair).I2CReg->CR1 |= I2C_CR1_PE; //Enable I2C peripheral
}
void SHAL_I2C::masterWriteRead(uint8_t addr,const uint8_t* writeData, size_t writeLen, uint8_t* readData, size_t readLen) {
volatile I2C_TypeDef* I2CPeripheral = getI2CPair(m_I2CPair).I2CReg;
if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_BUSY) == 0, 100)){
SHAL_UART2.sendString("I2C timed out waiting for not busy\r\n");
return;
}
//Write phase
if (writeLen > 0) {
//Configure: NBYTES = wlen, write mode, START
I2CPeripheral->CR2 = (addr << 1) | (writeLen << I2C_CR2_NBYTES_Pos) | I2C_CR2_START;
for (size_t i = 0; i < writeLen; i++) {
if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_TXIS) != 0, 100)){
SHAL_UART2.sendString("I2C timed out waiting for TX\r\n");
return;
}
I2CPeripheral->TXDR = writeData[i];
}
//Wait until transfer complete
if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_TC) != 0, 100)){
SHAL_UART2.sendString("I2C timed out waiting for TC\r\n");
return;
}
}
//Read phase
if (readLen > 0) {
SHAL_UART2.sendString("Read initiated\r\n");
I2CPeripheral->CR2 &= ~(I2C_CR2_NBYTES | I2C_CR2_SADD | I2C_CR2_RD_WRN);
I2CPeripheral->CR2 |= (addr << 1) |
I2C_CR2_RD_WRN |
(readLen << I2C_CR2_NBYTES_Pos) |
I2C_CR2_START | I2C_CR2_AUTOEND;
for (size_t i = 0; i < readLen; i++) {
if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_RXNE) != 0 , 100)){
SHAL_UART2.sendString("I2C timed out waiting for RXNE\r\n");
return;
}
SHAL_UART2.sendString("Read byte");
readData[i] = static_cast<uint8_t>(I2CPeripheral->RXDR);
}
}
else{
I2CPeripheral->CR2 |= I2C_CR2_STOP;
}
}
void SHAL_I2C::masterWrite(uint8_t addr, const uint8_t *writeData, uint8_t writeLen) {
masterWriteRead(addr,writeData,writeLen,nullptr,0);
}
void SHAL_I2C::masterRead(uint8_t addr, uint8_t *readBuffer, uint8_t bytesToRead) {
masterWriteRead(addr,nullptr,0,readBuffer,bytesToRead);
}
uint8_t SHAL_I2C::masterWriteReadByte(uint8_t addr, const uint8_t *writeData, size_t writeLen) {
uint8_t val = 0;
masterWriteRead(addr, writeData, writeLen, &val, 1);
return val;
}
SHAL_I2C& I2CManager::get(uint8_t I2CBus) {
if(I2CBus > NUM_I2C_BUSES - 1){
assert(false);
//Memory fault
}
return m_I2CBuses[I2CBus];
}

View File

@@ -0,0 +1,63 @@
//
// Created by Luca on 8/28/2025.
//
#include "SHAL_TIM.h"
#include <cassert>
Timer::Timer(Timer_Key t) : TIMER_KEY(t){
}
Timer::Timer() : TIMER_KEY(Timer_Key::S_TIM_INVALID){
}
void Timer::start() {
getTimerRegister(TIMER_KEY)->CR1 |= TIM_CR1_CEN;
getTimerRegister(TIMER_KEY)->EGR |= TIM_EGR_UG; //load prescaler reg and ARR
enableInterrupt();
}
void Timer::stop() {
getTimerRegister(TIMER_KEY)->CR1 &= ~TIM_CR1_CEN;
}
void Timer::setPrescaler(uint16_t presc) {
getTimerRegister(TIMER_KEY)->PSC = presc;
}
void Timer::setARR(uint16_t arr) {
getTimerRegister(TIMER_KEY)->ARR = arr;
}
void Timer::enableInterrupt() {
getTimerRegister(TIMER_KEY)->DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(getIRQn(TIMER_KEY));
}
void Timer::init(uint32_t prescaler, uint32_t autoReload) {
TIM_RCC_Enable rcc = getTimerRCC(TIMER_KEY);
*rcc.busEnableReg |= (1 << rcc.offset);
setPrescaler(prescaler);
setARR(autoReload);
}
Timer &TimerManager::get(Timer_Key timer_key) {
//Ensure that we don't try to get invalid timers
assert(timer_key != Timer_Key::S_TIM_INVALID && timer_key != Timer_Key::NUM_TIMERS);
Timer& selected = timers[static_cast<int>(timer_key)];
//Timer queried is not initialized yet (defaults to invalid)
if(selected.TIMER_KEY == Timer_Key::S_TIM_INVALID){
timers[static_cast<int>(timer_key)] = Timer(timer_key); //Initialize TIMER_KEY
}
return timers[static_cast<int>(timer_key)];
}

View File

@@ -0,0 +1,17 @@
//
// Created by Luca on 8/28/2025.
//
#include "SHAL_TIM_CALLBACK.h"
DEFINE_TIMER_IRQ(Timer_Key::S_TIM1, TIM1_BRK_UP_TRG_COM_IRQHandler)
DEFINE_TIMER_IRQ(Timer_Key::S_TIM2, TIM2_IRQHandler)
DEFINE_TIMER_IRQ(Timer_Key::S_TIM3, TIM3_IRQHandler)
DEFINE_TIMER_IRQ(Timer_Key::S_TIM14, TIM14_IRQHandler)
DEFINE_TIMER_IRQ(Timer_Key::S_TIM15, TIM15_IRQHandler)
DEFINE_TIMER_IRQ(Timer_Key::S_TIM16, TIM16_IRQHandler)
DEFINE_TIMER_IRQ(Timer_Key::S_TIM17, TIM17_IRQHandler)
void registerTimerCallback(Timer_Key key, TimerCallback callback){
timer_callbacks[static_cast<int>(key)] = callback;
}

View File

@@ -0,0 +1,75 @@
/**
******************************************************************************
* @file SHAL_TIM.h
* @author Luca Lizaranzu
* @brief Related to USART and SHAL_UART abstractions
******************************************************************************
*/
#include "SHAL_UART.h"
#include "SHAL_GPIO.h"
void SHAL_UART::init(const UART_Pair pair){
m_UARTPair = pair;
SHAL_UART_Pair uart_pair = getUARTPair(pair); //Get the UART_PAIR information to be initialized
//Get the SHAL_GPIO pins for this SHAL_UART setup
GPIO_Key Tx_Key = uart_pair.TxKey; //Tx pin
GPIO_Key Rx_Key = uart_pair.RxKey; //Rx pin
GET_GPIO(Tx_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE);
GET_GPIO(Rx_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE);
GET_GPIO(Tx_Key).setAlternateFunction(uart_pair.TxAlternateFunctionMask);
GET_GPIO(Rx_Key).setAlternateFunction(uart_pair.RxAlternateFunctionMask);
SHAL_UART_ENABLE_REG pairUARTEnable = getUARTEnableReg(pair); //Register and mask to enable the SHAL_UART channel
*pairUARTEnable.reg |= pairUARTEnable.mask; //Enable SHAL_UART line
}
void SHAL_UART::begin(uint32_t baudRate) volatile {
USART_TypeDef* usart = getUARTPair(m_UARTPair).USARTReg;
usart->CR1 &= ~USART_CR1_UE; //Disable USART
usart->CR1 = 0; //Clear USART config
usart->CR1 = USART_CR1_TE | USART_CR1_RE; //Tx enable and Rx Enable
usart->BRR = 8000000 / baudRate; //MAKE SURE ANY FUNCTION THAT CHANGES CLOCK UPDATES THIS! //TODO DO NOT HARDCODE THIS SHIT
usart->CR1 |= USART_CR1_UE;
}
void SHAL_UART::sendString(const char *s) volatile {
while (*s) sendChar(*s++); //Send chars while we haven't reached end of s
}
void SHAL_UART::sendChar(char c) volatile {
USART_TypeDef* usart = getUARTPair(m_UARTPair).USARTReg;
while(!(usart->ISR & USART_ISR_TXE)); //Wait for usart to finish what it's doing
usart->TDR = c; //Send character
}
SHAL_UART& UARTManager::get(uint8_t uart) {
if(uart > NUM_USART_LINES - 1){
assert(false);
//Memory fault
}
return m_UARTs[uart];
}

View File

@@ -12,7 +12,7 @@
* *
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick * by the user application to setup the SysTick
* timer or configure other parameters. * TIMER_KEY or configure other parameters.
* *
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed * be called whenever the core clock is changed
@@ -91,11 +91,6 @@
*/ */
/* This variable is updated in three ways: /* This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate() 1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/ */
uint32_t SystemCoreClock = 8000000; uint32_t SystemCoreClock = 8000000;
@@ -136,7 +131,7 @@ void SystemInit(void)
/** /**
* @brief Update SystemCoreClock variable according to Clock Register Values. * @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can * The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure * be used by the user application to setup the SysTick TIMER_KEY or configure
* other parameters. * other parameters.
* *
* @note Each time the core clock (HCLK) changes, this function must be called * @note Each time the core clock (HCLK) changes, this function must be called

89
SHAL/Src/main.cpp Normal file
View File

@@ -0,0 +1,89 @@
#include "SHAL.h"
#include "stm32f0xx.h"
#include <cstdlib>
void c3Interrupt(){
SHAL_UART2.sendString("Begin\r\n");
uint8_t cmd[3] = {0xAC, 0x33, 0x00};
SHAL_I2C1.masterWrite(0x38, cmd, 3);
SHAL_delay_ms(100);
uint8_t dht_buf[7] = {0};
//Read 7 bytes (status + 5 data + CRC)
SHAL_I2C1.masterRead(0x38, dht_buf, 7);
//Parse humidity (20 bits)
uint32_t rawHumidity = ((uint32_t)dht_buf[1] << 12) |
((uint32_t)dht_buf[2] << 4) |
((uint32_t)dht_buf[3] >> 4);
uint32_t rawTemp = (((uint32_t)dht_buf[3] & 0x0F) << 16) |
((uint32_t)dht_buf[4] << 8) |
((uint32_t)dht_buf[5]);
// Use 64-bit intermediate to avoid overflow
uint32_t hum_hundredths = (uint32_t)(((uint64_t)rawHumidity * 10000ULL) >> 20);
int32_t temp_hundredths = (int32_t)((((uint64_t)rawTemp * 20000ULL) >> 20) - 5000);
char out[80];
sprintf(out, "rawH=0x%05lX rawT=0x%05lX\r\n",
(unsigned long)rawHumidity, (unsigned long)rawTemp);
SHAL_UART2.sendString(out);
// print as X.YY
sprintf(out, "Temp: %ld.%02ld C, Hum: %ld.%02ld %%\r\n",
(long)(temp_hundredths / 100), (long)(abs(temp_hundredths % 100)),
(long)(hum_hundredths / 100), (long)(hum_hundredths % 100));
SHAL_UART2.sendString(out);
}
void tim2Handler(){
PIN(A4).toggle();
}
int main() {
SHAL_init();
//Setup UART2 (used by nucleo devices for USB comms)
SHAL_UART2.init(UART_Pair::Tx2A2_Rx2A3);
SHAL_UART2.begin(115200);
SHAL_I2C1.init(I2C_Pair::SCL1B6_SDA1B7);
SHAL_I2C1.setClockConfig(0x2000090E);
//Use pin C3 to trigger a function on external interrupt
PIN(C3).useAsExternalInterrupt(TriggerMode::RISING_EDGE,c3Interrupt);
SHAL_TIM2.init(8000-1,1500-1);
SHAL_TIM2.setCallbackFunc(tim2Handler);
SHAL_TIM2.start();
PIN(A4).setPinMode(PinMode::OUTPUT_MODE);
PIN(A5).setPinMode(PinMode::OUTPUT_MODE);
SHAL_delay_ms(3000); //Wait 100 ms from datasheet
uint8_t cmd = 0x71;
uint8_t status = 0;
SHAL_I2C1.masterWriteRead(0x38, &cmd, 1, &status, 1);
char statusString[32];
sprintf(statusString, "Status = 0x%02X\r\n", status);
SHAL_UART2.sendString(statusString);
SHAL_delay_ms(10);
c3Interrupt();
//End setup
while (true) {
__WFI();
}
}