Changed SHAL_Peripheral to take in a void* of any peripheral struct, and added SHAL_Peripheral_Register for individual registers

This commit is contained in:
2025-08-30 16:57:52 -07:00
parent 2da3413329
commit 33fc098dfc
11 changed files with 139 additions and 78 deletions

View File

@@ -467,7 +467,7 @@ typedef struct
__IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */
__IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */
__IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */
__IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ __IO uint32_t WUTR; /*!< RTC wakeup TIMER_KEY register, Address offset: 0x14 */
uint32_t RESERVED1; /*!< Reserved, Address offset: 0x18 */ uint32_t RESERVED1; /*!< Reserved, Address offset: 0x18 */
__IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */
uint32_t RESERVED2; /*!< Reserved, Address offset: 0x20 */ uint32_t RESERVED2; /*!< Reserved, Address offset: 0x20 */

View File

@@ -14,6 +14,11 @@
//Universal structs and defines --------------------------- //Universal structs and defines ---------------------------
struct SHAL_Peripheral { struct SHAL_Peripheral {
void* registers;
unsigned long global_offset;
};
struct SHAL_Peripheral_Register {
volatile uint32_t* reg; volatile uint32_t* reg;
unsigned long offset; unsigned long offset;
}; };

View File

@@ -8,6 +8,8 @@
#include <stm32f072xb.h> #include <stm32f072xb.h>
#include <cassert> #include <cassert>
#include "SHAL_CORE.h"
#define AVAILABLE_GPIO \ #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(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(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) \
@@ -22,63 +24,61 @@ enum class GPIO_Key {
INVALID INVALID
}; };
constexpr volatile GPIO_TypeDef* getGPIORegister(GPIO_Key g) {
constexpr SHAL_Peripheral getGPIORegister(const GPIO_Key g){
switch(g) { switch(g) {
case GPIO_Key::A0: case GPIO_Key::A0: return {GPIOA,0};
case GPIO_Key::A1: case GPIO_Key::A1: return {GPIOA,1};
case GPIO_Key::A2: case GPIO_Key::A2: return {GPIOA,2};
case GPIO_Key::A3: case GPIO_Key::A3: return {GPIOA,3};
case GPIO_Key::A4: case GPIO_Key::A4: return {GPIOA,4};
case GPIO_Key::A5: case GPIO_Key::A5: return {GPIOA,5};
case GPIO_Key::A6: case GPIO_Key::A6: return {GPIOA,6};
case GPIO_Key::A7: case GPIO_Key::A7: return {GPIOA,7};
case GPIO_Key::A8: case GPIO_Key::A8: return {GPIOA,8};
case GPIO_Key::A9: case GPIO_Key::A9: return {GPIOA,9};
case GPIO_Key::A10: case GPIO_Key::A10: return {GPIOA,10};
case GPIO_Key::A11: case GPIO_Key::A11: return {GPIOA,11};
case GPIO_Key::A12: case GPIO_Key::A12: return {GPIOA,12};
case GPIO_Key::A13: case GPIO_Key::A13: return {GPIOA,13};
case GPIO_Key::A14: case GPIO_Key::A14: return {GPIOA,14};
case GPIO_Key::A15: case GPIO_Key::A15: return {GPIOA,15};
return GPIOA; case GPIO_Key::B0: return {GPIOB,0};
case GPIO_Key::B0: case GPIO_Key::B1: return {GPIOB,1};
case GPIO_Key::B1: case GPIO_Key::B2: return {GPIOB,2};
case GPIO_Key::B2: case GPIO_Key::B3: return {GPIOB,3};
case GPIO_Key::B3: case GPIO_Key::B4: return {GPIOB,4};
case GPIO_Key::B4: case GPIO_Key::B5: return {GPIOB,5};
case GPIO_Key::B5: case GPIO_Key::B6: return {GPIOB,6};
case GPIO_Key::B6: case GPIO_Key::B7: return {GPIOB,7};
case GPIO_Key::B7: case GPIO_Key::B8: return {GPIOB,8};
case GPIO_Key::B8: case GPIO_Key::B9: return {GPIOB,9};
case GPIO_Key::B9: case GPIO_Key::B10: return {GPIOB,10};
case GPIO_Key::B10: case GPIO_Key::B11: return {GPIOB,11};
case GPIO_Key::B11: case GPIO_Key::B12: return {GPIOB,12};
case GPIO_Key::B12: case GPIO_Key::B13: return {GPIOB,13};
case GPIO_Key::B13: case GPIO_Key::B14: return {GPIOB,14};
case GPIO_Key::B14: case GPIO_Key::B15: return {GPIOB,15};
case GPIO_Key::B15: case GPIO_Key::C0: return {GPIOC,0};
return GPIOB; case GPIO_Key::C1: return {GPIOC,1};
case GPIO_Key::C0: case GPIO_Key::C2: return {GPIOC,2};
case GPIO_Key::C1: case GPIO_Key::C3: return {GPIOC,3};
case GPIO_Key::C2: case GPIO_Key::C4: return {GPIOC,4};
case GPIO_Key::C3: case GPIO_Key::C5: return {GPIOC,5};
case GPIO_Key::C4: case GPIO_Key::C6: return {GPIOC,6};
case GPIO_Key::C5: case GPIO_Key::C7: return {GPIOC,7};
case GPIO_Key::C6: case GPIO_Key::C8: return {GPIOC,8};
case GPIO_Key::C7: case GPIO_Key::C9: return {GPIOC,9};
case GPIO_Key::C8: case GPIO_Key::C10: return {GPIOC,10};
case GPIO_Key::C9: case GPIO_Key::C11: return {GPIOC,11};
case GPIO_Key::C10: case GPIO_Key::C12: return {GPIOC,12};
case GPIO_Key::C11: case GPIO_Key::C13: return {GPIOC,13};
case GPIO_Key::C12: case GPIO_Key::C14: return {GPIOC,14};
case GPIO_Key::C13: case GPIO_Key::C15: return {GPIOC,15};
case GPIO_Key::C14:
case GPIO_Key::C15:
return GPIOC;
case GPIO_Key::INVALID: case GPIO_Key::INVALID:
case GPIO_Key::NUM_GPIO: case GPIO_Key::NUM_GPIO:
assert(false); assert(false);
return nullptr; //Unreachable return SHAL_Peripheral(nullptr,0); //Unreachable
} }
__builtin_unreachable(); __builtin_unreachable();
} }

View File

@@ -8,6 +8,38 @@
#include "SHAL_CORE.h" #include "SHAL_CORE.h"
#include <cassert> #include <cassert>
#include <stm32f072xb.h> #include "SHAL_GPIO_REG_F072xB.h"
enum class PinMode {
INPUT_MODE = 0b00,
OUTPUT_MODE = 0b01,
ALTERNATE_FUNCTION_MODE = 0b10,
ANALOG_MODE = 0b11
};
enum class PinValue {
HI = 1,
LOW = 0,
};
class GPIO{
public:
void toggle();
//TODO replace stupid offset hack from APB
void setHigh();
void setLow();
private:
friend class GPIOManager;
explicit GPIO(GPIO_Key key);
GPIO();
GPIO_Key GPIO_KEY;
};
#endif //SHMINGO_HAL_SHAL_GPIO_H #endif //SHMINGO_HAL_SHAL_GPIO_H

View File

@@ -29,8 +29,8 @@ enum class Timer_Key { //For STM32F072
}; };
//Get timer peripheral struct including bus register, enable mask, timer mask //Get TIMER_KEY peripheral struct including bus register, enable mask, TIMER_KEY mask
constexpr SHAL_Peripheral getTimerRCC(Timer_Key t) { constexpr SHAL_Peripheral_Register getTimerRCC(Timer_Key t) {
switch(t) { switch(t) {
case Timer_Key::S_TIM1: return {&RCC->APB2ENR, RCC_APB2ENR_TIM1EN_Pos}; 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_TIM2: return {&RCC->APB1ENR, RCC_APB1ENR_TIM2EN_Pos};

View File

@@ -2,7 +2,7 @@
****************************************************************************** ******************************************************************************
* @file SHAL_TIM.h * @file SHAL_TIM.h
* @author Luca Lizaranzu * @author Luca Lizaranzu
* @brief Declarations of timer related objects * @brief Declarations of TIMER_KEY related objects
****************************************************************************** ******************************************************************************
*/ */
@@ -33,9 +33,9 @@ public:
//Enable interrupts //Enable interrupts
void enableInterrupt(); void enableInterrupt();
//Set timer IRQ callback function //Set TIMER_KEY IRQ callback function
void setCallbackFunc(TimerCallback callback){ void setCallbackFunc(TimerCallback callback){
registerTimerCallback(timer, callback); registerTimerCallback(TIMER_KEY, callback);
} }
private: private:
@@ -43,8 +43,7 @@ private:
explicit Timer(Timer_Key t); explicit Timer(Timer_Key t);
Timer(); Timer();
Timer_Key timer; Timer_Key TIMER_KEY;
volatile TIM_TypeDef* timer_reg;
}; };

View File

@@ -2,8 +2,8 @@
****************************************************************************** ******************************************************************************
* @file SHAL.h * @file SHAL.h
* @author Luca Lizaranzu * @author Luca Lizaranzu
* @brief Utilities for creating and populating the timer IRQ callback table * @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 abstractions * globally, see usage in SHAL_TIM.h. Created in use for singleton TIMER_KEY abstractions
****************************************************************************** ******************************************************************************
*/ */

View File

@@ -0,0 +1,25 @@
//
// Created by Luca on 8/30/2025.
//
#include "SHAL_GPIO.h"
GPIO::GPIO() {
}
GPIO::GPIO(GPIO_Key key) {
}
void GPIO::setLow() {
getGPIORegister(GPIO_KEY)->ODR &= ~(1 << getGPIOAPB(GPIO_KEY).offset);
}
void GPIO::setHigh() {
getGPIORegister(GPIO_KEY)->ODR |= (1 << getGPIOAPB(GPIO_KEY).offset);
}
void GPIO::toggle() {
}

View File

@@ -5,36 +5,36 @@
#include "SHAL_TIM.h" #include "SHAL_TIM.h"
#include <cassert> #include <cassert>
Timer::Timer(Timer_Key t) : timer(t), timer_reg(getTimerRegister(t)){ Timer::Timer(Timer_Key t) : TIMER_KEY(t){
SHAL_Peripheral rcc = getTimerRCC(timer); SHAL_Peripheral_Register rcc = getTimerRCC(TIMER_KEY);
*rcc.reg |= (1 << rcc.offset); *rcc.reg |= (1 << rcc.offset);
} }
Timer::Timer() : timer(Timer_Key::S_TIM_INVALID), timer_reg(nullptr){ Timer::Timer() : TIMER_KEY(Timer_Key::S_TIM_INVALID){
} }
void Timer::start() { void Timer::start() {
timer_reg->CR1 |= TIM_CR1_CEN; getTimerRegister(TIMER_KEY)->CR1 |= TIM_CR1_CEN;
timer_reg->EGR |= TIM_EGR_UG; //load prescaler reg and ARR getTimerRegister(TIMER_KEY)->EGR |= TIM_EGR_UG; //load prescaler reg and ARR
enableInterrupt(); enableInterrupt();
} }
void Timer::stop() { void Timer::stop() {
timer_reg->CR1 &= ~TIM_CR1_CEN; getTimerRegister(TIMER_KEY)->CR1 &= ~TIM_CR1_CEN;
} }
void Timer::setPrescaler(uint16_t presc) { void Timer::setPrescaler(uint16_t presc) {
timer_reg->PSC = presc; getTimerRegister(TIMER_KEY)->PSC = presc;
} }
void Timer::setARR(uint16_t arr) { void Timer::setARR(uint16_t arr) {
timer_reg->ARR = arr; getTimerRegister(TIMER_KEY)->ARR = arr;
} }
void Timer::enableInterrupt() { void Timer::enableInterrupt() {
timer_reg->DIER |= TIM_DIER_UIE; getTimerRegister(TIMER_KEY)->DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(getIRQn(timer)); NVIC_EnableIRQ(getIRQn(TIMER_KEY));
} }
@@ -46,8 +46,8 @@ Timer &TimerManager::get(Timer_Key timer_key) {
Timer& selected = timers[static_cast<int>(timer_key)]; Timer& selected = timers[static_cast<int>(timer_key)];
//Timer queried is not initialized yet (defaults to invalid) //Timer queried is not initialized yet (defaults to invalid)
if(selected.timer == Timer_Key::S_TIM_INVALID){ if(selected.TIMER_KEY == Timer_Key::S_TIM_INVALID){
timers[static_cast<int>(timer_key)] = Timer(timer_key); //Initialize timer timers[static_cast<int>(timer_key)] = Timer(timer_key); //Initialize TIMER_KEY
} }
return timers[static_cast<int>(timer_key)]; return timers[static_cast<int>(timer_key)];

View File

@@ -12,7 +12,7 @@
* *
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick * by the user application to setup the SysTick
* timer or configure other parameters. * TIMER_KEY or configure other parameters.
* *
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed * be called whenever the core clock is changed
@@ -136,7 +136,7 @@ void SystemInit(void)
/** /**
* @brief Update SystemCoreClock variable according to Clock Register Values. * @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can * The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure * be used by the user application to setup the SysTick TIMER_KEY or configure
* other parameters. * other parameters.
* *
* @note Each time the core clock (HCLK) changes, this function must be called * @note Each time the core clock (HCLK) changes, this function must be called