Set up GPIO infrastructure
This commit is contained in:
@@ -10,11 +10,15 @@
|
|||||||
|
|
||||||
#include "SHAL_CORE.h"
|
#include "SHAL_CORE.h"
|
||||||
|
|
||||||
|
#define AVAILABLE_PORTS 3
|
||||||
|
#define PINS_PER_PORT 16
|
||||||
|
|
||||||
#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) \
|
||||||
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)
|
X(C0) X(C1) X(C2) X(C3) X(C4) X(C5) X(C6) X(C7) X(C8) X(C9) X(C10) X(C11) X(C12) X(C13) X(C14) X(C15)
|
||||||
|
|
||||||
|
|
||||||
//Build enum map of available GPIO pins
|
//Build enum map of available GPIO pins
|
||||||
enum class GPIO_Key {
|
enum class GPIO_Key {
|
||||||
#define X(key) key,
|
#define X(key) key,
|
||||||
@@ -83,4 +87,126 @@ constexpr SHAL_Peripheral getGPIORegister(const GPIO_Key g){
|
|||||||
__builtin_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 unsigned int 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
|
#endif //SHMINGO_HAL_SHAL_GPIO_REG_F072XB_H
|
||||||
|
|||||||
@@ -11,17 +11,28 @@
|
|||||||
#include "SHAL_GPIO_REG_F072xB.h"
|
#include "SHAL_GPIO_REG_F072xB.h"
|
||||||
|
|
||||||
enum class PinMode {
|
enum class PinMode {
|
||||||
INPUT_MODE = 0b00,
|
INPUT_MODE,
|
||||||
OUTPUT_MODE = 0b01,
|
OUTPUT_MODE,
|
||||||
ALTERNATE_FUNCTION_MODE = 0b10,
|
ALTERNATE_FUNCTION_MODE,
|
||||||
ANALOG_MODE = 0b11
|
ANALOG_MODE,
|
||||||
|
INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class PinValue {
|
unsigned long getPinMode(PinMode mode){
|
||||||
HI = 1,
|
switch(mode){
|
||||||
LOW = 0,
|
case PinMode::INPUT_MODE:
|
||||||
};
|
return 0b00;
|
||||||
|
case PinMode::OUTPUT_MODE:
|
||||||
|
return 0b01;
|
||||||
|
case PinMode::ALTERNATE_FUNCTION_MODE:
|
||||||
|
return 0b10;
|
||||||
|
case PinMode::ANALOG_MODE:
|
||||||
|
return 0b11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Abstraction of GPIO registers
|
||||||
class GPIO{
|
class GPIO{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -36,10 +47,31 @@ private:
|
|||||||
|
|
||||||
friend class GPIOManager;
|
friend class GPIOManager;
|
||||||
|
|
||||||
explicit GPIO(GPIO_Key key);
|
explicit GPIO(GPIO_Key key, PinMode pinMode);
|
||||||
GPIO();
|
GPIO();
|
||||||
|
|
||||||
GPIO_Key GPIO_KEY;
|
GPIO_Key m_GPIO_KEY = GPIO_Key::INVALID;
|
||||||
|
PinMode m_pinMode = PinMode::INVALID;
|
||||||
|
|
||||||
|
GPIO_TypeDef* p_GPIORegister = nullptr;
|
||||||
|
unsigned long m_offset = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define initGPIO(GPIO_KEY, PIN_MODE) GPIOManager::get(GPIO_KEY, PIN_MODE)
|
||||||
|
|
||||||
|
//Manages instances of GPIO objects
|
||||||
|
class GPIOManager{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static GPIO& get(GPIO_Key, PinMode pinMode);
|
||||||
|
GPIOManager() = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
inline static GPIO m_gpios[AVAILABLE_PORTS][PINS_PER_PORT] = {};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //SHMINGO_HAL_SHAL_GPIO_H
|
#endif //SHMINGO_HAL_SHAL_GPIO_H
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define getTimer(timer_key) TimerManager::get(timer_key);
|
|
||||||
|
#define getTimer(timer_key) TimerManager::get(timer_key)
|
||||||
|
|
||||||
//Manages all timers so user does not have to personally initialize
|
//Manages all timers so user does not have to personally initialize
|
||||||
class TimerManager{
|
class TimerManager{
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
#define SHAL_H
|
#define SHAL_H
|
||||||
|
|
||||||
#include "SHAL_TIM.h"
|
#include "SHAL_TIM.h"
|
||||||
|
#include "SHAL_GPIO.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,22 +4,47 @@
|
|||||||
|
|
||||||
#include "SHAL_GPIO.h"
|
#include "SHAL_GPIO.h"
|
||||||
|
|
||||||
GPIO::GPIO() {
|
GPIO::GPIO(){
|
||||||
|
//Do not initialize anything
|
||||||
}
|
}
|
||||||
|
|
||||||
GPIO::GPIO(GPIO_Key key) {
|
GPIO::GPIO(GPIO_Key key, PinMode pinMode) : m_GPIO_KEY(key),
|
||||||
|
p_GPIORegister(static_cast<GPIO_TypeDef*>(getGPIORegister(key).registers)),
|
||||||
|
m_offset(getGPIORegister(key).global_offset){
|
||||||
|
|
||||||
|
volatile unsigned long* gpioEnable = getGPIORCCEnable(key).reg;
|
||||||
|
unsigned long gpioOffset = getGPIORCCEnable(key).offset;
|
||||||
|
|
||||||
|
*gpioEnable |= (1 << gpioOffset);
|
||||||
|
|
||||||
|
p_GPIORegister->MODER |= (getPinMode(pinMode) << (2 * m_offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPIO::setLow() {
|
void GPIO::setLow() {
|
||||||
getGPIORegister(GPIO_KEY)->ODR &= ~(1 << getGPIOAPB(GPIO_KEY).offset);
|
p_GPIORegister->ODR &= ~(1 << m_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPIO::setHigh() {
|
void GPIO::setHigh() {
|
||||||
getGPIORegister(GPIO_KEY)->ODR |= (1 << getGPIOAPB(GPIO_KEY).offset);
|
p_GPIORegister->ODR |= (1 << m_offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPIO::toggle() {
|
void GPIO::toggle() {
|
||||||
|
p_GPIORegister->ODR ^= (1 << m_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GPIO &GPIOManager::get(GPIO_Key key, PinMode pinMode) {
|
||||||
|
|
||||||
|
unsigned int gpioPort = getGPIOPortNumber(key);
|
||||||
|
unsigned long gpioPin = getGPIORegister(key).global_offset; //Use existing structs to get offset
|
||||||
|
|
||||||
|
GPIO curr = m_gpios[gpioPort][gpioPin];
|
||||||
|
|
||||||
|
if(curr.m_GPIO_KEY == GPIO_Key::INVALID || curr.m_pinMode != pinMode){
|
||||||
|
m_gpios[gpioPort][gpioPin] = GPIO(key,pinMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_gpios[gpioPort][gpioPin];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user