Updated GPIO to new format
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#define SHMINGO_HAL_SHAL_CORE_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
//Overall init function for SHAL --------------------------
|
||||
|
||||
@@ -70,45 +71,57 @@ bool SHAL_wait_for_condition_ms(Condition cond, uint32_t timeout_ms) {
|
||||
return false; // timeout
|
||||
}
|
||||
|
||||
//Sets bits starting from offset as the LSB
|
||||
static inline void SHAL_set_bits(volatile uint32_t* reg, uint32_t size, uint32_t bits, uint32_t offset){
|
||||
if(reg == nullptr){
|
||||
return;
|
||||
}
|
||||
uint32_t mask = (1 << (size)) - 1;
|
||||
*reg &= ~(mask << offset);
|
||||
*reg |= bits << offset;
|
||||
}
|
||||
#define SHAL_set_bits(reg, size, bits, offset) \
|
||||
do { \
|
||||
if ((reg) != NULL) { \
|
||||
uint32_t _mask = ((1U << (size)) - 1U); \
|
||||
*(reg) &= ~((uint32_t)(_mask) << (offset)); \
|
||||
*(reg) |= ((uint32_t)(bits) << (offset)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
//Sets bits starting from offset as the LSB (for uint16_t)
|
||||
static inline void SHAL_set_bits_16(volatile uint16_t* reg, uint32_t size, uint32_t bits, uint32_t offset){
|
||||
uint16_t mask = (1 << (size)) - 1;
|
||||
*reg &= ~(mask << offset);
|
||||
*reg |= bits << offset;
|
||||
}
|
||||
#define SHAL_flip_bits(reg, size, offset) \
|
||||
do { \
|
||||
if ((reg) != NULL) { \
|
||||
uint32_t _mask = ((1U << (size)) - 1U); \
|
||||
*(reg) ^= (_mask << (offset)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static inline void SHAL_clear_bitmask(volatile uint32_t* reg, uint32_t mask){
|
||||
*reg &= ~(mask);
|
||||
}
|
||||
#define SHAL_set_bits_16(reg, size, bits, offset) \
|
||||
do { \
|
||||
if ((reg) != NULL) { \
|
||||
uint16_t _mask = (uint16_t)((1U << (size)) - 1U); \
|
||||
*(reg) &= (uint16_t)~((uint16_t)(_mask) << (offset)); \
|
||||
*(reg) |= (uint16_t)((uint16_t)(bits) << (offset)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static inline void SHAL_apply_bitmask(volatile uint32_t* reg, uint32_t mask){
|
||||
SHAL_clear_bitmask(reg,mask);
|
||||
*reg |= mask;
|
||||
}
|
||||
#define SHAL_clear_bitmask(reg, mask) \
|
||||
do { \
|
||||
*(reg) &= ~(mask); \
|
||||
} while (0)
|
||||
|
||||
static inline void SHAL_set_register_value(volatile uint32_t* reg, uint32_t value){
|
||||
if(reg == nullptr){
|
||||
return;
|
||||
}
|
||||
*reg = value;
|
||||
}
|
||||
#define SHAL_apply_bitmask(reg, mask) \
|
||||
do { \
|
||||
SHAL_clear_bitmask((reg), (mask)); \
|
||||
*(reg) |= (mask); \
|
||||
} while (0)
|
||||
|
||||
#define SHAL_set_register_value(reg, value) \
|
||||
do { \
|
||||
if ((reg) != NULL) { \
|
||||
*(reg) = (uint32_t)(value); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SHAL_set_register_value_16(reg, value) \
|
||||
do { \
|
||||
if ((reg) != NULL) { \
|
||||
*(reg) = (uint16_t)(value); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static inline void SHAL_set_register_value_16(volatile uint16_t* reg, uint16_t value){
|
||||
if(reg == nullptr){
|
||||
return;
|
||||
}
|
||||
*reg = value;
|
||||
}
|
||||
|
||||
void SHAL_print_register(const volatile uint32_t* reg);
|
||||
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
#define EXTI_PENDING_REG(line) ((line) < 32 ? EXTI->PR1 : EXTI->PR2)
|
||||
|
||||
static inline SHAL_EXTI_Interrupt_Mask_Register getEXTIInterruptMaskRegister(uint32_t line){
|
||||
uint32_t imr = line < 32 ? EXTI->IMR1 : EXTI->IMR2;
|
||||
return {&imr};
|
||||
volatile uint32_t* reg = line < 32 ? &EXTI->IMR1 : &EXTI->IMR2;
|
||||
return {reg};;
|
||||
}
|
||||
|
||||
static inline SHAL_EXTI_Rising_Trigger_Selection_Register getEXTIRisingTriggerSelectionRegister(uint32_t line){
|
||||
auto reg = line < 32 ? EXTI->RTSR1 : EXTI->RTSR2;
|
||||
return {®};
|
||||
volatile uint32_t* reg = line < 32 ? &EXTI->RTSR1 : &EXTI->RTSR2;
|
||||
return {reg};
|
||||
}
|
||||
|
||||
static inline SHAL_EXTI_Falling_Trigger_Selection_Register getEXTIFallingTriggerSelectionRegister(uint32_t line){
|
||||
auto reg = line < 32 ? EXTI->FTSR1 : EXTI->FTSR2;
|
||||
return {®};
|
||||
volatile uint32_t* reg = line < 32 ? &EXTI->FTSR1 : &EXTI->FTSR2;
|
||||
return {reg};
|
||||
}
|
||||
|
||||
#endif //SHMINGO_HAL_SHAL_EXTI_REG_L432KC_H
|
||||
|
||||
@@ -14,51 +14,43 @@
|
||||
#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(B3) X(B4) X(B5) X(B6) X(B7)
|
||||
|
||||
|
||||
//Build enum map of available SHAL_GPIO pins
|
||||
enum class GPIO_Key : uint8_t {
|
||||
#define X(key) key,
|
||||
AVAILABLE_GPIO
|
||||
#undef X
|
||||
A0,
|
||||
A1,
|
||||
A2,
|
||||
A3,
|
||||
A4,
|
||||
A5,
|
||||
A6,
|
||||
A7,
|
||||
A8,
|
||||
A9,
|
||||
A10,
|
||||
A11,
|
||||
A12,
|
||||
A13,
|
||||
A14,
|
||||
A15,
|
||||
B0,
|
||||
B1,
|
||||
B3 = 19, //Offset to compensate for lack of B2
|
||||
B4,
|
||||
B5,
|
||||
B6,
|
||||
B7,
|
||||
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::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::INVALID:
|
||||
case GPIO_Key::NUM_GPIO:
|
||||
assert(false);
|
||||
return SHAL_GPIO_Peripheral(nullptr,0); //Unreachable
|
||||
}
|
||||
__builtin_unreachable();
|
||||
static volatile GPIO_TypeDef * GPIO_TABLE[2] = { //Lookup table for ADCs
|
||||
GPIOA,
|
||||
GPIOB
|
||||
};
|
||||
|
||||
constexpr uint8_t getGPIOPinNumber(GPIO_Key key){
|
||||
return static_cast<uint8_t>(key) % 16;
|
||||
}
|
||||
|
||||
constexpr SHAL_GPIO_EXTI_Register getGPIOEXTICR(const GPIO_Key g){
|
||||
@@ -96,74 +88,56 @@ constexpr SHAL_GPIO_EXTI_Register getGPIOEXTICR(const GPIO_Key g){
|
||||
__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->AHB2ENR, RCC_AHB2ENR_GPIOAEN_Pos};
|
||||
case GPIO_Key::B0:
|
||||
case GPIO_Key::B1:
|
||||
case GPIO_Key::B3:
|
||||
case GPIO_Key::B4:
|
||||
case GPIO_Key::B5:
|
||||
case GPIO_Key::B6:
|
||||
case GPIO_Key::B7:
|
||||
return {&RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN_Pos};
|
||||
case GPIO_Key::INVALID:
|
||||
case GPIO_Key::NUM_GPIO:
|
||||
assert(false);
|
||||
return SHAL_Peripheral_Register(nullptr,0); //Unreachable
|
||||
}
|
||||
__builtin_unreachable();
|
||||
static inline SHAL_GPIO_RCC_Enable_Register getGPIORCCEnable(const GPIO_Key g){
|
||||
volatile uint32_t* reg = &RCC->AHB2ENR; //register
|
||||
uint32_t offset;
|
||||
offset = (static_cast<uint8_t>(g) / 16) == 0 ? RCC_AHB2ENR_GPIOAEN_Pos : RCC_AHB2ENR_GPIOBEN_Pos;
|
||||
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
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::B3:
|
||||
case GPIO_Key::B4:
|
||||
case GPIO_Key::B5:
|
||||
case GPIO_Key::B6:
|
||||
case GPIO_Key::B7:
|
||||
return 1;
|
||||
case GPIO_Key::INVALID:
|
||||
case GPIO_Key::NUM_GPIO:
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
__builtin_unreachable();
|
||||
return (static_cast<uint8_t>(g) / 16);
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_Mode_Register getGPIOModeRegister(const GPIO_Key key){
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->MODER;
|
||||
uint32_t offset = 2 * static_cast<uint8_t>(key) % 16;
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_Pullup_Pulldown_Register getGPIOPUPDRegister(const GPIO_Key key){
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->PUPDR;
|
||||
uint32_t offset = 2 * static_cast<uint8_t>(key) % 16;
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_Alternate_Function_Register getGPIOAlternateFunctionRegister(const GPIO_Key key){
|
||||
|
||||
uint32_t pinNumber = static_cast<uint8_t>(key); //Number of pin (We need 0-7 to be AFR 1 and 8-15 to be AFR 2
|
||||
uint32_t afrIndex = pinNumber < 8 ? 0 : 1;
|
||||
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->AFR[afrIndex];
|
||||
uint32_t offset = (pinNumber % 8) * 4; //Increment in groups of four
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_Output_Speed_Register getGPIOOutputSpeedRegister(const GPIO_Key key){
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->OSPEEDR;
|
||||
uint32_t offset = 2 * static_cast<uint8_t>(key) % 16;
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_Output_Type_Register getGPIOOutputTypeRegister(const GPIO_Key key){
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->OTYPER;
|
||||
uint32_t offset = static_cast<uint8_t>(key) % 16;
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_Output_Data_Register getGPIOOutputDataRegister(const GPIO_Key key){
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->ODR;
|
||||
uint32_t offset = static_cast<uint8_t>(key) % 16;
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
|
||||
void setAlternateFunction(GPIO_Alternate_Function AF) volatile;
|
||||
|
||||
void setPinType(PinType type) volatile;
|
||||
void setOutputType(PinType type) volatile;
|
||||
|
||||
void setOutputSpeed(OutputSpeed speed) volatile;
|
||||
|
||||
|
||||
@@ -15,14 +15,39 @@ struct SHAL_GPIO_EXTI_Register{
|
||||
IRQn_Type IRQN; //IRQ number for enabling lines
|
||||
};
|
||||
|
||||
struct SHAL_GPIO_Peripheral {
|
||||
GPIO_TypeDef * reg;
|
||||
unsigned long global_offset;
|
||||
struct SHAL_GPIO_RCC_Enable_Register{
|
||||
volatile uint32_t* reg;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct SHAL_Peripheral_Register {
|
||||
struct SHAL_GPIO_Mode_Register {
|
||||
volatile uint32_t* reg;
|
||||
unsigned long offset;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct SHAL_GPIO_Pullup_Pulldown_Register {
|
||||
volatile uint32_t* reg;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct SHAL_GPIO_Alternate_Function_Register {
|
||||
volatile uint32_t* reg;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct SHAL_GPIO_Output_Speed_Register{
|
||||
volatile uint32_t* reg;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct SHAL_GPIO_Output_Type_Register {
|
||||
volatile uint32_t* reg;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct SHAL_GPIO_Output_Data_Register {
|
||||
volatile uint32_t* reg;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct SHAL_GPIO_Port_Info{
|
||||
|
||||
Reference in New Issue
Block a user