Before switch to GPIO functions over raw register manipulation for USART

This commit is contained in:
Ea-r-th
2025-09-10 00:41:08 -07:00
parent 55f03031b3
commit 316edd32d8
8 changed files with 137 additions and 63 deletions

View File

@@ -13,16 +13,7 @@
//Universal structs and defines ---------------------------
enum class AF_Mask : uint8_t{
AF0,
AF1,
AF2,
AF3,
AF4,
AF5,
AF6,
AF7
};
//---------------------------------------------------------

View File

@@ -11,16 +11,42 @@
#include "SHAL_EXTI_CALLBACK.h"
enum class PinMode : uint8_t{
INPUT_MODE,
OUTPUT_MODE,
ALTERNATE_FUNCTION_MODE,
ANALOG_MODE,
INVALID
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,
};
unsigned long getPinMode(PinMode mode);
enum class TriggerMode : uint8_t{
RISING_EDGE,
@@ -28,6 +54,8 @@ enum class TriggerMode : uint8_t{
RISING_FALLING_EDGE
};
//Abstraction of GPIO registers
class GPIO{
@@ -39,6 +67,14 @@ public:
void setHigh();
void setLow();
void setAlternateFunction(GPIO_Alternate_Function AF) volatile;
void setPinType(PinType type) volatile;
void setOutputSpeed(OutputSpeed speed) volatile;
void setInternalResistor(InternalResistorType type) volatile;
private:
friend class GPIOManager;

View File

@@ -2,10 +2,13 @@
// Created by Luca on 9/9/2025.
//
#ifndef SHMINGO_HAL_SHAL_I2C_REG_F072XB_H
#define SHMINGO_HAL_SHAL_I2C_REG_F072XB_H
#ifndef SHAL_I2C_REG_F072XB_H
#define SHAL_I2C_REG_F072XB_H
#include "SHAL_CORE.h"
#include <cassert>
#include "SHAL_I2C_TYPES.h"
enum class I2C_Pair : uint8_t{
//I2C_1
@@ -15,6 +18,39 @@ enum class I2C_Pair : uint8_t{
//I2C_2
SCL2B10_SDA2B11, //AF1
SCL2B13_SDA2B14, //AF5
NUM_PAIRS,
INVALID
};
#endif //SHMINGO_HAL_SHAL_I2C_REG_F072XB_H
constexpr SHAL_I2C_Pair getI2CPair(const I2C_Pair pair){
switch(pair){
case I2C_Pair::SCL1B6_SDA1B7: return {I2C1,GPIO_Key::B6,GPIO_Key::B7,AF_Mask::AF1,AF_Mask::AF1};
case I2C_Pair::SCL1B8_SDA1B9: return {I2C1,GPIO_Key::B8,GPIO_Key::B9,AF_Mask::AF1,AF_Mask::AF1};
case I2C_Pair::SCL2B10_SDA2B11: return {I2C2,GPIO_Key::B10,GPIO_Key::B11,AF_Mask::AF1,AF_Mask::AF1};
case I2C_Pair::SCL2B13_SDA2B14: return {I2C2,GPIO_Key::B13,GPIO_Key::B14,AF_Mask::AF5,AF_Mask::AF5};
case I2C_Pair::NUM_PAIRS:
case I2C_Pair::INVALID:
assert(false);
return {nullptr,GPIO_Key::INVALID,GPIO_Key::INVALID,AF_Mask::AF0,AF_Mask::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();
}
#endif //SHAL_I2C_REG_F072XB_H

View File

@@ -38,19 +38,19 @@ enum class UART_Pair : uint8_t{
constexpr SHAL_UART_Pair getUARTPair(const UART_Pair pair){
switch(pair){
case UART_Pair::Tx1A9_Rx1A10: return {USART1,GPIO_Key::A9,GPIO_Key::A10,AF_Mask::AF1,AF_Mask::AF1};
case UART_Pair::Tx1B6_Rx1B7: return {USART1,GPIO_Key::B6,GPIO_Key::B7,AF_Mask::AF0,AF_Mask::AF0};
case UART_Pair::Tx2A2_Rx2A3: return {USART2,GPIO_Key::A2,GPIO_Key::A3,AF_Mask::AF1,AF_Mask::AF1};
case UART_Pair::Tx2A14_Rx2A15: return {USART2,GPIO_Key::A14,GPIO_Key::A15,AF_Mask::AF1,AF_Mask::AF1};
case UART_Pair::Tx3B10_Rx3B11: return {USART3,GPIO_Key::B10,GPIO_Key::B11,AF_Mask::AF4,AF_Mask::AF4};
case UART_Pair::Tx3C4_Rx3C5: return {USART3,GPIO_Key::C4,GPIO_Key::C5,AF_Mask::AF1,AF_Mask::AF1};
case UART_Pair::Tx3C10_Rx3C11: return {USART3,GPIO_Key::C10,GPIO_Key::C11,AF_Mask::AF1,AF_Mask::AF1};
case UART_Pair::Tx4A0_Rx4A1: return {USART4,GPIO_Key::A0,GPIO_Key::A1,AF_Mask::AF4,AF_Mask::AF4};
case UART_Pair::Tx4C10_Rx4C11: return {USART4,GPIO_Key::C10,GPIO_Key::C11,AF_Mask::AF0,AF_Mask::AF0};
case UART_Pair::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,AF_Mask::AF0,AF_Mask::AF0};
return {nullptr, GPIO_Key::INVALID, GPIO_Key::INVALID, GPIO_Alternate_Function::AF0, GPIO_Alternate_Function::AF0};
}
__builtin_unreachable();
}
@@ -101,16 +101,16 @@ constexpr SHAL_UART_ENABLE_REG getUARTEnableReg(const UART_Pair pair){
__builtin_unreachable();
}
constexpr uint32_t getAFMask(const AF_Mask mask){
constexpr uint32_t getAFMask(const GPIO_Alternate_Function mask){
switch(mask){
case AF_Mask::AF0: return 0x00;
case AF_Mask::AF1: return 0x01;
case AF_Mask::AF2: return 0x02;
case AF_Mask::AF3: return 0x03;
case AF_Mask::AF4: return 0x04;
case AF_Mask::AF5: return 0x05;
case AF_Mask::AF6: return 0x06;
case AF_Mask::AF7: return 0x07;
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();
}

View File

@@ -15,8 +15,8 @@ struct SHAL_UART_Pair{
USART_TypeDef* USARTReg;
GPIO_Key TxKey;
GPIO_Key RxKey;
AF_Mask TxMask;
AF_Mask RxMask;
GPIO_Alternate_Function TxMask;
GPIO_Alternate_Function RxMask;
};
struct SHAL_UART_ENABLE_REG{

View File

@@ -5,24 +5,6 @@
#include "SHAL_GPIO.h"
#include "SHAL_EXTI_CALLBACK.h"
unsigned long getPinMode(PinMode mode){
switch(mode){
case PinMode::INPUT_MODE:
return 0b00;
case PinMode::OUTPUT_MODE:
return 0b01;
case PinMode::ALTERNATE_FUNCTION_MODE:
return 0b10;
case PinMode::ANALOG_MODE:
return 0b11;
case PinMode::INVALID:
assert(false);
return 0;
}
__builtin_unreachable();
}
GPIO::GPIO() : m_GPIO_KEY(GPIO_Key::INVALID){
@@ -41,8 +23,8 @@ GPIO::GPIO(GPIO_Key key, PinMode pinMode) : m_GPIO_KEY(key) {
*gpioEnable |= (1 << gpioOffset); //Set enable flag
gpioRegister->MODER &= ~(0b11 << (2 * registerOffset)); //Clear any previous mode
gpioRegister->MODER |= (getPinMode(pinMode) << (2 * registerOffset)); //Set mode based on pinmode bit structure
gpioRegister->MODER &= ~(0x03 << (2 * registerOffset)); //Clear any previous mode
gpioRegister->MODER |= (static_cast<uint8_t>(pinMode) << (2 * registerOffset)); //Set mode based on pinmode bit structure
}
void GPIO::setLow() {
@@ -60,6 +42,31 @@ void GPIO::toggle() volatile {
gpioPeripheral.reg->ODR ^= (1 << gpioPeripheral.global_offset);
}
void 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 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 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 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));
}
GPIO& GPIOManager::get(GPIO_Key key, PinMode pinMode) {

View File

@@ -0,0 +1,4 @@
//
// Created by Luca on 9/9/2025.
//

View File

@@ -20,7 +20,7 @@ int main() {
uart2->begin(115200);
useGPIOAsInterrupt(GPIO_Key::C3,TriggerMode::RISING_EDGE,c3Interrupt);
useGPIOAsInterrupt(GPIO_Key::C3,TriggerMode::RISING_EDGE, c3Interrupt);
Timer timer2 = getTimer(Timer_Key::S_TIM2);