Compare commits
44 Commits
ed8db95818
...
I2C
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb232ea55e | ||
|
|
8ce717033a | ||
|
|
75132eb040 | ||
|
|
7b32859c88 | ||
|
|
d4136f0761 | ||
|
|
b2d10f5e5e | ||
|
|
25b56f9fcd | ||
|
|
183be36c64 | ||
|
|
914fbf5a17 | ||
|
|
8f3bd7ebd8 | ||
|
|
2f8ba8d9ee | ||
|
|
316edd32d8 | ||
|
|
55f03031b3 | ||
| 9f1aad028d | |||
| a599aa5a4e | |||
| a02ec044ce | |||
| 368eac7616 | |||
| b2c41e2cb4 | |||
| 84ab921291 | |||
| 06f0b9303c | |||
| 465055fc53 | |||
| 40ee0e6834 | |||
| a0ef9c8b32 | |||
| d763965cb8 | |||
| f6e21fbd88 | |||
| 8b4402e4c8 | |||
| 64fb4e4a23 | |||
| 35bc902187 | |||
| db75c06c90 | |||
| 0418e3d5c5 | |||
| 33fc098dfc | |||
| 2da3413329 | |||
| 19fbe6c0ad | |||
| 098e57eb2f | |||
| 45abfc6c88 | |||
| a0cb980e16 | |||
| 9cc3cbece4 | |||
| 83572b108a | |||
| 20fdce6d82 | |||
| d092ccd362 | |||
| 1e966f0688 | |||
| 55ca8d5360 | |||
| 4900cde915 | |||
| 8979e1b28a |
@@ -23,19 +23,28 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS ON)
|
||||
|
||||
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/Include
|
||||
)
|
||||
|
||||
set(PROJECT_INCLUDE_DIRECTORIES
|
||||
${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/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}
|
||||
|
||||
@@ -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
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef SHAL_TIM_H
|
||||
#define SHAL_TIM_H
|
||||
|
||||
#include "SHAL_TIM_REG.h"
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -369,16 +369,16 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */
|
||||
__IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */
|
||||
__IO uint32_t OSPEEDR; /*!< 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 IDR; /*!< GPIO port input data register, Address offset: 0x10 */
|
||||
__IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */
|
||||
__IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x1A */
|
||||
__IO uint32_t LCKR; /*!< 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 BRR; /*!< GPIO bit reset register, Address offset: 0x28 */
|
||||
__IO uint32_t MODER; /*!< SHAL_GPIO port mode register, Address offset: 0x00 */
|
||||
__IO uint32_t OTYPER; /*!< SHAL_GPIO port output type register, Address offset: 0x04 */
|
||||
__IO uint32_t OSPEEDR; /*!< SHAL_GPIO port output speed register, Address offset: 0x08 */
|
||||
__IO uint32_t PUPDR; /*!< SHAL_GPIO port pull-up/pull-down register, Address offset: 0x0C */
|
||||
__IO uint32_t IDR; /*!< SHAL_GPIO port input data register, Address offset: 0x10 */
|
||||
__IO uint32_t ODR; /*!< SHAL_GPIO port output data register, Address offset: 0x14 */
|
||||
__IO uint32_t BSRR; /*!< SHAL_GPIO port bit set/reset register, Address offset: 0x1A */
|
||||
__IO uint32_t LCKR; /*!< SHAL_GPIO port configuration lock register, Address offset: 0x1C */
|
||||
__IO uint32_t AFR[2]; /*!< SHAL_GPIO alternate function low register, Address offset: 0x20-0x24 */
|
||||
__IO uint32_t BRR; /*!< SHAL_GPIO bit reset register, Address offset: 0x28 */
|
||||
} GPIO_TypeDef;
|
||||
|
||||
/**
|
||||
@@ -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 */
|
||||
@@ -6490,7 +6490,7 @@ typedef struct
|
||||
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* General Purpose IOs (GPIO) */
|
||||
/* General Purpose IOs (SHAL_GPIO) */
|
||||
/* */
|
||||
/******************************************************************************/
|
||||
/******************* Bit definition for GPIO_MODER register *****************/
|
||||
@@ -10933,7 +10933,7 @@ typedef struct
|
||||
((INSTANCE) == DMA1_Channel6) || \
|
||||
((INSTANCE) == DMA1_Channel7))
|
||||
|
||||
/****************************** GPIO Instances ********************************/
|
||||
/****************************** SHAL_GPIO Instances ********************************/
|
||||
#define IS_GPIO_ALL_INSTANCE(INSTANCE) (((INSTANCE) == GPIOA) || \
|
||||
((INSTANCE) == GPIOB) || \
|
||||
((INSTANCE) == GPIOC) || \
|
||||
@@ -10941,14 +10941,14 @@ typedef struct
|
||||
((INSTANCE) == GPIOE) || \
|
||||
((INSTANCE) == GPIOF))
|
||||
|
||||
/**************************** GPIO Alternate Function Instances ***************/
|
||||
/**************************** SHAL_GPIO Alternate Function Instances ***************/
|
||||
#define IS_GPIO_AF_INSTANCE(INSTANCE) (((INSTANCE) == GPIOA) || \
|
||||
((INSTANCE) == GPIOB) || \
|
||||
((INSTANCE) == GPIOC) || \
|
||||
((INSTANCE) == GPIOD) || \
|
||||
((INSTANCE) == GPIOE))
|
||||
|
||||
/****************************** GPIO Lock Instances ***************************/
|
||||
/****************************** SHAL_GPIO Lock Instances ***************************/
|
||||
#define IS_GPIO_LOCK_INSTANCE(INSTANCE) (((INSTANCE) == GPIOA) || \
|
||||
((INSTANCE) == GPIOB))
|
||||
|
||||
@@ -11192,11 +11192,11 @@ typedef struct
|
||||
/****************************** TSC Instances *********************************/
|
||||
#define IS_TSC_ALL_INSTANCE(INSTANCE) ((INSTANCE) == TSC)
|
||||
|
||||
/*********************** UART Instances : IRDA mode ***************************/
|
||||
/*********************** SHAL_UART Instances : IRDA mode ***************************/
|
||||
#define IS_IRDA_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
|
||||
((INSTANCE) == USART2))
|
||||
|
||||
/********************* UART Instances : Smard card mode ***********************/
|
||||
/********************* SHAL_UART Instances : Smard card mode ***********************/
|
||||
#define IS_SMARTCARD_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
|
||||
((INSTANCE) == USART2))
|
||||
|
||||
@@ -11210,35 +11210,35 @@ typedef struct
|
||||
#define IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
|
||||
((INSTANCE) == USART2))
|
||||
|
||||
/******************** UART Instances : Asynchronous mode **********************/
|
||||
/******************** SHAL_UART Instances : Asynchronous mode **********************/
|
||||
#define IS_UART_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
|
||||
((INSTANCE) == USART2) || \
|
||||
((INSTANCE) == USART3) || \
|
||||
((INSTANCE) == USART4))
|
||||
|
||||
/******************** UART Instances : Half-Duplex mode **********************/
|
||||
/******************** SHAL_UART Instances : Half-Duplex mode **********************/
|
||||
#define IS_UART_HALFDUPLEX_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
|
||||
((INSTANCE) == USART2) || \
|
||||
((INSTANCE) == USART3) || \
|
||||
((INSTANCE) == USART4))
|
||||
|
||||
/****************** UART Instances : Hardware Flow control ********************/
|
||||
/****************** SHAL_UART Instances : Hardware Flow control ********************/
|
||||
#define IS_UART_HWFLOW_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
|
||||
((INSTANCE) == USART2) || \
|
||||
((INSTANCE) == USART3) || \
|
||||
((INSTANCE) == USART4))
|
||||
|
||||
/****************** UART Instances : LIN mode ********************/
|
||||
/****************** SHAL_UART Instances : LIN mode ********************/
|
||||
#define IS_UART_LIN_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
|
||||
((INSTANCE) == USART2))
|
||||
|
||||
/****************** UART Instances : wakeup from stop mode ********************/
|
||||
/****************** SHAL_UART Instances : wakeup from stop mode ********************/
|
||||
#define IS_UART_WAKEUP_FROMSTOP_INSTANCE(INSTANCE) (((INSTANCE) == USART1) || \
|
||||
((INSTANCE) == USART2))
|
||||
/* Old macro definition maintained for legacy purpose */
|
||||
#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) || \
|
||||
((INSTANCE) == USART2) || \
|
||||
((INSTANCE) == USART3) || \
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
@{
|
||||
|
||||
@@ -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
|
||||
@{
|
||||
|
||||
@@ -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
|
||||
@{
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
105
SHAL/Include/Core/SHAL_CORE.h
Normal file
105
SHAL/Include/Core/SHAL_CORE.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @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 ---------------------------
|
||||
|
||||
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
|
||||
41
SHAL/Include/Peripheral/EXT/SHAL_EXTI_CALLBACK.h
Normal file
41
SHAL/Include/Peripheral/EXT/SHAL_EXTI_CALLBACK.h
Normal 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
|
||||
47
SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG.h
Normal file
47
SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG.h
Normal 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
|
||||
275
SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_F072xB.h
Normal file
275
SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_F072xB.h
Normal 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 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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //SHMINGO_HAL_SHAL_GPIO_REG_F072XB_H
|
||||
71
SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_TYPES.h
Normal file
71
SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_TYPES.h
Normal file
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// 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;
|
||||
};
|
||||
|
||||
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
|
||||
82
SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h
Normal file
82
SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h
Normal file
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// 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"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Abstraction of SHAL_GPIO registers
|
||||
class SHAL_GPIO{
|
||||
|
||||
public:
|
||||
|
||||
void toggle() volatile;
|
||||
|
||||
//TODO replace stupid offset hack from APB
|
||||
void setHigh();
|
||||
void setLow();
|
||||
|
||||
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 GPIO_A
|
||||
|
||||
//Manages instances of SHAL_GPIO objects
|
||||
class GPIOManager{
|
||||
|
||||
public:
|
||||
|
||||
static SHAL_GPIO& get(GPIO_Key);
|
||||
|
||||
|
||||
GPIOManager() = delete;
|
||||
|
||||
private:
|
||||
|
||||
inline static SHAL_GPIO m_gpios[AVAILABLE_PORTS][PINS_PER_PORT] = {{}};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //SHMINGO_HAL_SHAL_GPIO_H
|
||||
44
SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG.h
Normal file
44
SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG.h
Normal 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
|
||||
94
SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG_F072xB.h
Normal file
94
SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG_F072xB.h
Normal 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
|
||||
40
SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_TYPES.h
Normal file
40
SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_TYPES.h
Normal 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
|
||||
75
SHAL/Include/Peripheral/I2C/SHAL_I2C.h
Normal file
75
SHAL/Include/Peripheral/I2C/SHAL_I2C.h
Normal 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
|
||||
44
SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG.h
Normal file
44
SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG.h
Normal 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
|
||||
106
SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_F072xB.h
Normal file
106
SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_F072xB.h
Normal 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
|
||||
15
SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_TYPES.h
Normal file
15
SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_TYPES.h
Normal 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
|
||||
73
SHAL/Include/Peripheral/Timer/SHAL_TIM.h
Normal file
73
SHAL/Include/Peripheral/Timer/SHAL_TIM.h
Normal 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
|
||||
32
SHAL/Include/Peripheral/Timer/SHAL_TIM_CALLBACK.h
Normal file
32
SHAL/Include/Peripheral/Timer/SHAL_TIM_CALLBACK.h
Normal 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
|
||||
46
SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG.h
Normal file
46
SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG.h
Normal 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
|
||||
123
SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG_F072xB.h
Normal file
123
SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG_F072xB.h
Normal 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
|
||||
27
SHAL/Include/Peripheral/UART/Reg/SHAL_UART_TYPES.h
Normal file
27
SHAL/Include/Peripheral/UART/Reg/SHAL_UART_TYPES.h
Normal 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
|
||||
57
SHAL/Include/Peripheral/UART/SHAL_UART.h
Normal file
57
SHAL/Include/Peripheral/UART/SHAL_UART.h
Normal 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
|
||||
@@ -8,7 +8,9 @@
|
||||
#ifndef SHAL_H
|
||||
#define SHAL_H
|
||||
|
||||
|
||||
|
||||
#include "SHAL_TIM.h"
|
||||
#include "SHAL_GPIO.h"
|
||||
#include "SHAL_UART.h"
|
||||
#include "SHAL_I2C.h"
|
||||
|
||||
#endif
|
||||
42
SHAL/Src/Core/SHAL_CORE.cpp
Normal file
42
SHAL/Src/Core/SHAL_CORE.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
40
SHAL/Src/EXT/SHAL_EXTI_CALLBACK.cpp
Normal file
40
SHAL/Src/EXT/SHAL_EXTI_CALLBACK.cpp
Normal 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;
|
||||
}
|
||||
121
SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp
Normal file
121
SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// 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
|
||||
}
|
||||
|
||||
|
||||
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];
|
||||
}
|
||||
142
SHAL/Src/Peripheral/I2C/SHAL_I2C.cpp
Normal file
142
SHAL/Src/Peripheral/I2C/SHAL_I2C.cpp
Normal 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];
|
||||
}
|
||||
63
SHAL/Src/Peripheral/Timer/SHAL_TIM.cpp
Normal file
63
SHAL/Src/Peripheral/Timer/SHAL_TIM.cpp
Normal 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)];
|
||||
}
|
||||
|
||||
|
||||
17
SHAL/Src/Peripheral/Timer/SHAL_TIM_CALLBACK.cpp
Normal file
17
SHAL/Src/Peripheral/Timer/SHAL_TIM_CALLBACK.cpp
Normal 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;
|
||||
}
|
||||
75
SHAL/Src/Peripheral/UART/SHAL_UART.cpp
Normal file
75
SHAL/Src/Peripheral/UART/SHAL_UART.cpp
Normal 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];
|
||||
}
|
||||
@@ -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
|
||||
91
SHAL/Src/main.cpp
Normal file
91
SHAL/Src/main.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#include "SHAL.h"
|
||||
#include "stm32f0xx.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user