24 Commits

Author SHA1 Message Date
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
44 changed files with 1248 additions and 156 deletions

View File

@@ -29,14 +29,20 @@ set(MX_INCLUDE_DIRECTORIES
set(PROJECT_INCLUDE_DIRECTORIES
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/Core/Include/Timer
${CMAKE_CURRENT_SOURCE_DIR}/Core/Include/Timer/Reg
${CMAKE_CURRENT_SOURCE_DIR}/Core/Include
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/EXT/
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Include
)
file(GLOB_RECURSE PROJECT_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/Core/*.c
${CMAKE_CURRENT_SOURCE_DIR}/Core/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/*.c
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/*.cpp
)
add_executable(${EXECUTABLE}

View File

@@ -1,51 +0,0 @@
#include "SHAL.h"
#include "stm32f0xx.h"
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);
}
}
void tim2Handler(){
GPIOA->ODR ^= (1 << 4);
}
int main() {
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
Timer timer2 = getTimer(Timer_Key::S_TIM2);
timer2.setPrescaler(8000 - 1);
timer2.setARR(500 - 1);
timer2.setCallbackFunc(tim2Handler);
timer2.start();
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // Enable SYSCFG clock (needed for EXTI)
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));
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
NVIC_EnableIRQ(EXTI0_1_IRQn); // EXTI lines 0 and 1 share an IRQ vector
__enable_irq();
while (true) {
__WFI();
}
}

View File

@@ -467,7 +467,7 @@ typedef struct
__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 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 */
__IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */
uint32_t RESERVED2; /*!< Reserved, Address offset: 0x20 */

View File

@@ -47,11 +47,6 @@
*/
/* This variable is updated in three ways:
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 const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */

View File

@@ -101,7 +101,7 @@
#define __RESTRICT __restrict
#endif
/* ########################### Core Function Access ########################### */
/* ########################### SHAL Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\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 */
/* ########################## Core Instruction Access ######################### */
/* ########################## SHAL Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{

View File

@@ -112,7 +112,7 @@
#endif
/* ########################### Core Function Access ########################### */
/* ########################### SHAL Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\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 */
/* ########################## Core Instruction Access ######################### */
/* ########################## SHAL Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{

View File

@@ -115,7 +115,7 @@
#endif
/* ########################### Core Function Access ########################### */
/* ########################### SHAL Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\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 */
/* ########################## Core Instruction Access ######################### */
/* ########################## SHAL Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
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_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_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 DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
@@ -1138,7 +1138,7 @@ typedef struct
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#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 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) */
@@ -1146,7 +1146,7 @@ typedef struct
#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 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)
#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_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_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 ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
@@ -2003,7 +2003,7 @@ typedef struct
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#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 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) */
@@ -2012,7 +2012,7 @@ typedef struct
#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 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)
#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 SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick 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 SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick 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 SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick 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_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_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 DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
@@ -1213,7 +1213,7 @@ typedef struct
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#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 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) */
@@ -1221,7 +1221,7 @@ typedef struct
#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 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)
#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_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_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 ITM_BASE (0xE0000000UL) /*!< ITM 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_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_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 ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
@@ -2078,7 +2078,7 @@ typedef struct
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#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 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) */
@@ -2087,7 +2087,7 @@ typedef struct
#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 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)
#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_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_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 ITM_BASE (0xE0000000UL) /*!< ITM 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_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_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 ITM_BASE (0xE0000000UL) /*!< ITM 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 SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick 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_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_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 ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */

View File

@@ -0,0 +1,60 @@
/**
******************************************************************************
* @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>
//Universal structs and defines ---------------------------
//---------------------------------------------------------
#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,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,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,275 @@
//
// 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 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();
}
#endif //SHMINGO_HAL_SHAL_GPIO_REG_F072XB_H

View File

@@ -0,0 +1,29 @@
//
// Created by Luca on 9/6/2025.
//
#ifndef SHAL_GPIO_TYPES_H
#define SHAL_GPIO_TYPES_H
#include "SHAL_CORE.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;
};
#endif //SHMINGO_HAL_SHAL_GPIO_TYPES_H

View File

@@ -0,0 +1,77 @@
//
// 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"
enum class PinMode : uint8_t{
INPUT_MODE,
OUTPUT_MODE,
ALTERNATE_FUNCTION_MODE,
ANALOG_MODE,
INVALID
};
unsigned long getPinMode(PinMode mode);
enum class TriggerMode : uint8_t{
RISING_EDGE,
FALLING_EDGE,
RISING_FALLING_EDGE
};
//Abstraction of GPIO registers
class GPIO{
public:
void toggle() volatile;
//TODO replace stupid offset hack from APB
void setHigh();
void setLow();
private:
friend class GPIOManager;
explicit GPIO(GPIO_Key key, PinMode pinMode);
GPIO();
GPIO_Key m_GPIO_KEY = GPIO_Key::INVALID;
};
//Init GPIO for normal use
#define initGPIO(GPIO_KEY, PIN_MODE) GPIOManager::get(GPIO_KEY, PIN_MODE)
//Init GPIO for use as an external interrupt
#define useGPIOAsInterrupt(GPIO_KEY, Trigger_Mode, Callback) GPIOManager::getInterruptGPIO(GPIO_KEY, Trigger_Mode, Callback)
//Manages instances of GPIO objects
class GPIOManager{
public:
static GPIO& get(GPIO_Key, PinMode pinMode);
static void getInterruptGPIO(GPIO_Key key, TriggerMode mode, EXTICallback callback);
GPIOManager() = delete;
private:
inline static GPIO m_gpios[AVAILABLE_PORTS][PINS_PER_PORT] = {{}};
};
#endif //SHMINGO_HAL_SHAL_GPIO_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

@@ -1,28 +1,26 @@
/**
******************************************************************************
* @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 <cstdint>
#include <cassert>
#include <stm32f072xb.h>
#include "SHAL_CORE.h"
#include "SHAL_TIM_TYPES.h"
enum class Bus {
AHB,
APB1,
APB2,
INVALID
};
struct RCC_Peripheral {
Bus bus;
volatile uint32_t* reg;
uint32_t bitmask;
};
enum class Timer_Key { //For STM32F072
enum class Timer_Key : uint8_t { //For STM32F072
S_TIM1,
S_TIM2,
S_TIM3,
S_TIM6,
S_TIM7,
S_TIM14,
S_TIM15,
S_TIM16,
@@ -32,20 +30,22 @@ enum class Timer_Key { //For STM32F072
};
//Get timer peripheral struct including bus register, enable mask, timer mask
constexpr RCC_Peripheral getTimerRCC(Timer_Key t) {
//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 {Bus::APB2, &RCC->APB2ENR, RCC_APB2ENR_TIM1EN};
case Timer_Key::S_TIM2: return {Bus::APB1, &RCC->APB1ENR, RCC_APB1ENR_TIM2EN};
case Timer_Key::S_TIM3: return {Bus::APB1, &RCC->APB1ENR, RCC_APB1ENR_TIM3EN};
case Timer_Key::S_TIM14: return {Bus::APB1, &RCC->APB1ENR, RCC_APB1ENR_TIM14EN};
case Timer_Key::S_TIM15: return {Bus::APB2, &RCC->APB2ENR, RCC_APB2ENR_TIM15EN};
case Timer_Key::S_TIM16: return {Bus::APB2, &RCC->APB2ENR, RCC_APB2ENR_TIM16EN};
case Timer_Key::S_TIM17: return {Bus::APB2, &RCC->APB2ENR, RCC_APB2ENR_TIM17EN};
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 {Bus::INVALID, nullptr, 0};; //Unreachable
return {nullptr, 0};; //Unreachable
}
__builtin_unreachable();
@@ -57,6 +57,8 @@ constexpr volatile TIM_TypeDef* getTimerRegister(Timer_Key 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;
@@ -74,6 +76,8 @@ constexpr IRQn_Type getIRQn(Timer_Key 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;

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

@@ -1,7 +1,15 @@
/**
******************************************************************************
* @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.h"
#include "SHAL_TIM_REG_F072xB.h"
#include "SHAL_TIM_CALLBACK.h"
#include <array>
@@ -25,9 +33,9 @@ public:
//Enable interrupts
void enableInterrupt();
//Set timer IRQ callback function
//Set TIMER_KEY IRQ callback function
void setCallbackFunc(TimerCallback callback){
registerTimerCallback(timer, callback);
registerTimerCallback(TIMER_KEY, callback);
}
private:
@@ -35,12 +43,12 @@ private:
explicit Timer(Timer_Key t);
Timer();
Timer_Key timer;
volatile TIM_TypeDef* timer_reg;
Timer_Key TIMER_KEY;
};
#define getTimer(timer_key) TimerManager::get(timer_key);
#define getTimer(timer_key) TimerManager::get(timer_key)
//Manages all timers so user does not have to personally initialize
class TimerManager{

View File

@@ -1,10 +1,16 @@
//
// Created by Luca on 8/28/2025.
//
/**
******************************************************************************
* @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 SHMINGO_HAL_SHAL_TIM_CALLBACK_H
#define SHMINGO_HAL_SHAL_TIM_CALLBACK_H
#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) \
@@ -14,7 +20,7 @@ extern "C" void irq_handler(void) { \
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

View File

@@ -0,0 +1,50 @@
//
// Created by Luca on 9/7/2025.
//
#ifndef SHAL_UART_REG_H
#define SHAL_UART_REG_H
//
// Created by Luca on 9/6/2025.
//
#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,118 @@
//
// 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
//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,AF_Mask::AF1,AF_Mask::AF1};
case UART_Pair::Tx1B6_Rx1B7: return {USART1,GPIO_Key::B6,GPIO_Key::B7,AF_Mask::AF0,AF_Mask::AF0};
case UART_Pair::Tx2A2_Rx2A3: return {USART2,GPIO_Key::A2,GPIO_Key::A3,AF_Mask::AF1,AF_Mask::AF1};
case UART_Pair::Tx2A14_Rx2A15: return {USART2,GPIO_Key::A14,GPIO_Key::A15,AF_Mask::AF1,AF_Mask::AF1};
case UART_Pair::Tx3B10_Rx3B11: return {USART3,GPIO_Key::B10,GPIO_Key::B11,AF_Mask::AF4,AF_Mask::AF4};
case UART_Pair::Tx3C4_Rx3C5: return {USART3,GPIO_Key::C4,GPIO_Key::C5,AF_Mask::AF1,AF_Mask::AF1};
case UART_Pair::Tx3C10_Rx3C11: return {USART3,GPIO_Key::C10,GPIO_Key::C11,AF_Mask::AF1,AF_Mask::AF1};
case UART_Pair::Tx4A0_Rx4A1: return {USART4,GPIO_Key::A0,GPIO_Key::A1,AF_Mask::AF4,AF_Mask::AF4};
case UART_Pair::Tx4C10_Rx4C11: return {USART4,GPIO_Key::C10,GPIO_Key::C11,AF_Mask::AF0,AF_Mask::AF0};
case UART_Pair::NUM_PAIRS:
case UART_Pair::INVALID:
assert(false);
return {nullptr,GPIO_Key::INVALID,GPIO_Key::INVALID,AF_Mask::AF0,AF_Mask::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 AF_Mask mask){
switch(mask){
case AF_Mask::AF0: return 0x00;
case AF_Mask::AF1: return 0x01;
case AF_Mask::AF2: return 0x02;
case AF_Mask::AF3: return 0x03;
case AF_Mask::AF4: return 0x04;
case AF_Mask::AF5: return 0x05;
case AF_Mask::AF6: return 0x06;
case AF_Mask::AF7: return 0x07;
}
__builtin_unreachable();
}
#endif //SHMINGO_HAL_SHAL_UART_REG_F072XB_H

View File

@@ -0,0 +1,37 @@
//
// 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"
enum class AF_Mask : uint8_t{
AF0,
AF1,
AF2,
AF3,
AF4,
AF5,
AF6,
AF7
};
//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;
AF_Mask TxMask;
AF_Mask RxMask;
};
struct SHAL_UART_ENABLE_REG{
volatile uint32_t* reg;
uint32_t mask;
};
#endif //SHMINGO_HAL_SHAL_UART_TYPES_H

View File

@@ -0,0 +1,57 @@
/**
******************************************************************************
* @file SHAL_TIM.h
* @author Luca Lizaranzu
* @brief Relating to UART and USART object abstractions
******************************************************************************
*/
#ifndef SHMINGO_HAL_SHAL_UART_H
#define SHMINGO_HAL_SHAL_UART_H
#include "SHAL_UART_REG.h"
class UART{
friend class UARTManager;
public:
//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:
UART() = default; //Initializer for array
//Creates a UART based on a pair of two valid U(S)ART pins
explicit UART(UART_Pair pair);
UART_Pair m_UARTPair = UART_Pair::INVALID;
};
#define getUART(uart_pair) UARTManager::get(uart_pair)
class UARTManager{
public:
static UART& get(UART_Pair pair);
UARTManager() = delete;
private:
inline static UART m_UARTs[NUM_USART_LINES] = {};
};
#endif //SHMINGO_HAL_SHAL_UART_H

View File

@@ -8,7 +8,8 @@
#ifndef SHAL_H
#define SHAL_H
#include "Core/Include/Timer/SHAL_TIM.h"
#include "SHAL_TIM.h"
#include "SHAL_GPIO.h"
#include "SHAL_UART.h"
#endif

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,118 @@
//
// Created by Luca on 8/30/2025.
//
#include "SHAL_GPIO.h"
#include "SHAL_EXTI_CALLBACK.h"
unsigned long getPinMode(PinMode mode){
switch(mode){
case PinMode::INPUT_MODE:
return 0b00;
case PinMode::OUTPUT_MODE:
return 0b01;
case PinMode::ALTERNATE_FUNCTION_MODE:
return 0b10;
case PinMode::ANALOG_MODE:
return 0b11;
case PinMode::INVALID:
assert(false);
return 0;
}
__builtin_unreachable();
}
GPIO::GPIO() : m_GPIO_KEY(GPIO_Key::INVALID){
//Do not initialize anything
}
GPIO::GPIO(GPIO_Key key, PinMode pinMode) : m_GPIO_KEY(key) {
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(key);
auto gpioRegister = gpioPeripheral.reg;
unsigned long registerOffset = gpioPeripheral.global_offset;
volatile unsigned long* gpioEnable = getGPIORCCEnable(key).reg;
unsigned long gpioOffset = getGPIORCCEnable(key).offset;
*gpioEnable |= (1 << gpioOffset); //Set enable flag
gpioRegister->MODER &= ~(0b11 << (2 * registerOffset)); //Clear any previous mode
gpioRegister->MODER |= (getPinMode(pinMode) << (2 * registerOffset)); //Set mode based on pinmode bit structure
}
void GPIO::setLow() {
auto gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->ODR &= ~(1 << gpioPeripheral.global_offset);
}
void GPIO::setHigh() {
auto gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->ODR |= (1 << gpioPeripheral.global_offset);
}
void GPIO::toggle() volatile {
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->ODR ^= (1 << gpioPeripheral.global_offset);
}
GPIO& GPIOManager::get(GPIO_Key key, PinMode pinMode) {
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] = GPIO(key,pinMode);
}
return m_gpios[gpioPort][gpioPin];
}
void GPIOManager::getInterruptGPIO(GPIO_Key key, TriggerMode triggerMode, EXTICallback callback) {
uint32_t gpioPort = getGPIOPortNumber(key);
uint32_t 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] = GPIO(key,PinMode::INPUT_MODE); //Hardcode input mode for interrupt
}
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGCOMPEN; //Enable EXT, TODO check if this is different across STM32 models
NVIC_EnableIRQ(getGPIOEXTICR(key).IRQN); //Enable IRQN for pin
EXTI->IMR |= (1 << gpioPin); //Enable correct EXTI line
SHAL_EXTIO_Register EXTILineEnable = getGPIOEXTICR(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(triggerMode){
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(key,callback);
__enable_irq(); //Enable IRQ just in case
}

View File

@@ -2,39 +2,39 @@
// Created by Luca on 8/28/2025.
//
#include "Core/Include/Timer/SHAL_TIM.h"
#include "SHAL_TIM.h"
#include <cassert>
Timer::Timer(Timer_Key t) : timer(t), timer_reg(getTimerRegister(t)){
RCC_Peripheral rcc = getTimerRCC(timer);
*rcc.reg |= rcc.bitmask;
Timer::Timer(Timer_Key t) : TIMER_KEY(t){
TIM_RCC_Enable rcc = getTimerRCC(TIMER_KEY);
*rcc.busEnableReg |= (1 << rcc.offset);
}
Timer::Timer() : timer(Timer_Key::S_TIM_INVALID), timer_reg(nullptr){
Timer::Timer() : TIMER_KEY(Timer_Key::S_TIM_INVALID){
}
void Timer::start() {
timer_reg->CR1 |= TIM_CR1_CEN;
timer_reg->EGR |= TIM_EGR_UG; //load prescaler reg and ARR
getTimerRegister(TIMER_KEY)->CR1 |= TIM_CR1_CEN;
getTimerRegister(TIMER_KEY)->EGR |= TIM_EGR_UG; //load prescaler reg and ARR
enableInterrupt();
}
void Timer::stop() {
timer_reg->CR1 &= ~TIM_CR1_CEN;
getTimerRegister(TIMER_KEY)->CR1 &= ~TIM_CR1_CEN;
}
void Timer::setPrescaler(uint16_t presc) {
timer_reg->PSC = presc;
getTimerRegister(TIMER_KEY)->PSC = presc;
}
void Timer::setARR(uint16_t arr) {
timer_reg->ARR = arr;
getTimerRegister(TIMER_KEY)->ARR = arr;
}
void Timer::enableInterrupt() {
timer_reg->DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(getIRQn(timer));
getTimerRegister(TIMER_KEY)->DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(getIRQn(TIMER_KEY));
}
@@ -46,8 +46,8 @@ Timer &TimerManager::get(Timer_Key timer_key) {
Timer& selected = timers[static_cast<int>(timer_key)];
//Timer queried is not initialized yet (defaults to invalid)
if(selected.timer == Timer_Key::S_TIM_INVALID){
timers[static_cast<int>(timer_key)] = Timer(timer_key); //Initialize timer
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,82 @@
/**
******************************************************************************
* @file SHAL_TIM.h
* @author Luca Lizaranzu
* @brief Related to USART and UART abstractions
******************************************************************************
*/
#include "SHAL_UART.h"
#include "SHAL_GPIO.h"
UART::UART(const UART_Pair pair) : m_UARTPair(pair){
SHAL_UART_Pair uart_pair = getUARTPair(pair); //Get the UART_PAIR information to be initialized
//Get the GPIO pins for this UART setup
GPIO_Key Tx_Key = uart_pair.TxKey; //Tx pin
GPIO_Key Rx_Key = uart_pair.RxKey; //Rx pin
uint8_t Tx_Pin = getGPIORegister(Tx_Key).global_offset;
uint8_t Rx_Pin = getGPIORegister(Rx_Key).global_offset;
initGPIO(Tx_Key,PinMode::ALTERNATE_FUNCTION_MODE); //Initialize Tx GPIO with alternate function (initializes GPIO port as well)
initGPIO(Rx_Key,PinMode::ALTERNATE_FUNCTION_MODE); //Initialize Rx GPIO with alternate function
//Determine which AFR register (high or low) to write depending on pin
uint8_t TxAFR = Tx_Pin < 8 ? 0 : 1; //Use AFR[0] if pin < 8, AFR[1] if pin >= 8
uint8_t RxAFR = Rx_Pin < 8 ? 0 : 1;
/*Apply Alternate Function masks to the AFR registers for each GPIO to enable alternate functions
* The AFR register for GPIO_Typedef* is actually two registers - a low reg and high reg.
* The low reg handles pins 0-7, and the high reg handles 8-15.
* Each pin gets 4 bits in the register for AFR0 - AFR7. Hence 8 * 4 = 32 bits.
* Each AFR is a different function, look at the DATASHEET (not reference manual) to find these alternate function mappings
*/
getGPIORegister(Tx_Key).reg->AFR[TxAFR] |= getAFMask(uart_pair.TxMask) << (4 * (Tx_Pin % 8));
getGPIORegister(Rx_Key).reg->AFR[RxAFR] |= getAFMask(uart_pair.RxMask) << (4 * (Rx_Pin % 8));
SHAL_UART_ENABLE_REG pairUARTEnable = getUARTEnableReg(pair); //Register and mask to enable the UART channel
*pairUARTEnable.reg |= pairUARTEnable.mask; //Enable UART line
}
void 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!
usart->CR1 |= USART_CR1_UE;
}
void UART::sendString(const char *s) volatile {
while (*s) sendChar(*s++); //Send chars while we haven't reached end of s
}
void 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
}
UART& UARTManager::get(UART_Pair pair) {
//Reassign if pair doesn't match
if(m_UARTs[getUARTChannel(pair)].m_UARTPair != pair) {
m_UARTs[getUARTChannel(pair)] = UART(pair);
}
return m_UARTs[getUARTChannel(pair)];
}

View File

@@ -12,7 +12,7 @@
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* 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
* be called whenever the core clock is changed
@@ -91,11 +91,6 @@
*/
/* This variable is updated in three ways:
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;
@@ -136,7 +131,7 @@ void SystemInit(void)
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* 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.
*
* @note Each time the core clock (HCLK) changes, this function must be called

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

@@ -0,0 +1,38 @@
#include "SHAL.h"
#include "stm32f0xx.h"
volatile GPIO* blueLED = nullptr;
volatile GPIO* greenLED = nullptr;
volatile UART* uart2;
void c3Interrupt(){
greenLED->toggle();
}
void tim2Handler(){
blueLED->toggle();
}
int main() {
uart2 = &getUART(UART_Pair::Tx2A2_Rx2A3);
uart2->begin(115200);
useGPIOAsInterrupt(GPIO_Key::C3,TriggerMode::RISING_EDGE,c3Interrupt);
Timer timer2 = getTimer(Timer_Key::S_TIM2);
blueLED = &initGPIO(GPIO_Key::A4, PinMode::OUTPUT_MODE);
greenLED = &initGPIO(GPIO_Key::A5, PinMode::OUTPUT_MODE);
timer2.setPrescaler(8000 - 1);
timer2.setARR(1500 - 1);
timer2.setCallbackFunc(tim2Handler);
timer2.start();
while (true) {
__WFI();
}
}