Added alternate function inits for USART
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -13,15 +13,7 @@
|
||||
|
||||
//Universal structs and defines ---------------------------
|
||||
|
||||
struct SHAL_Peripheral {
|
||||
void* registers;
|
||||
unsigned long global_offset;
|
||||
};
|
||||
|
||||
struct SHAL_Peripheral_Register {
|
||||
volatile uint32_t* reg;
|
||||
unsigned long offset;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef SHMINGO_HAL_SHAL_EXTI_CALLBACK_H
|
||||
#define SHMINGO_HAL_SHAL_EXTI_CALLBACK_H
|
||||
#ifndef SHAL_EXTI_CALLBACK_H
|
||||
#define SHAL_EXTI_CALLBACK_H
|
||||
|
||||
#include "SHAL_CORE.h"
|
||||
#include "SHAL_GPIO_REG_F072xB.h"
|
||||
#include "SHAL_GPIO_REG.h"
|
||||
|
||||
#define DEFINE_EXTI_IRQ(EXTI_Channel) \
|
||||
extern "C" void EXTI##EXTI_Channel##_IRQHandler(void) { \
|
||||
@@ -38,4 +38,4 @@ typedef void (*EXTICallback)(); //Typedef for callback function
|
||||
|
||||
void registerEXTICallback(GPIO_Key key, EXTICallback callback);
|
||||
|
||||
#endif //SHMINGO_HAL_SHAL_EXTI_CALLBACK_H
|
||||
#endif //SHAL_EXTI_CALLBACK_H
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Created by Luca on 9/6/2025.
|
||||
//
|
||||
|
||||
#ifndef SHMINGO_HAL_SHAL_GPIO_REG_H
|
||||
#define SHMINGO_HAL_SHAL_GPIO_REG_H
|
||||
#ifndef SHAL_GPIO_REG_H
|
||||
#define SHAL_GPIO_REG_H
|
||||
|
||||
#if defined(STM32F030x6)
|
||||
#include "stm32f030x6.h"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Created by Luca on 8/29/2025.
|
||||
//
|
||||
|
||||
#ifndef SHMINGO_HAL_SHAL_GPIO_REG_F072XB_H
|
||||
#define SHMINGO_HAL_SHAL_GPIO_REG_F072XB_H
|
||||
#ifndef SHAL_GPIO_REG_F072XB_H
|
||||
#define SHAL_GPIO_REG_F072XB_H
|
||||
|
||||
#include <stm32f072xb.h>
|
||||
#include <cassert>
|
||||
@@ -31,7 +31,7 @@ enum class GPIO_Key : uint8_t {
|
||||
|
||||
|
||||
|
||||
constexpr SHAL_Peripheral getGPIORegister(const GPIO_Key g){
|
||||
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};
|
||||
@@ -84,7 +84,7 @@ constexpr SHAL_Peripheral getGPIORegister(const GPIO_Key g){
|
||||
case GPIO_Key::INVALID:
|
||||
case GPIO_Key::NUM_GPIO:
|
||||
assert(false);
|
||||
return SHAL_Peripheral(nullptr,0); //Unreachable
|
||||
return SHAL_GPIO_Peripheral(nullptr,0); //Unreachable
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}
|
||||
@@ -143,7 +143,7 @@ constexpr SHAL_EXTIO_Register getGPIOEXTICR(const GPIO_Key g){
|
||||
case GPIO_Key::INVALID:
|
||||
case GPIO_Key::NUM_GPIO:
|
||||
assert(false);
|
||||
return SHAL_EXTIO_Register(nullptr,0); //Unreachable
|
||||
return SHAL_EXTIO_Register(nullptr,0, EXTI4_15_IRQn); //Unreachable
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Created by Luca on 9/6/2025.
|
||||
//
|
||||
|
||||
#ifndef SHMINGO_HAL_SHAL_GPIO_TYPES_H
|
||||
#define SHMINGO_HAL_SHAL_GPIO_TYPES_H
|
||||
#ifndef SHAL_GPIO_TYPES_H
|
||||
#define SHAL_GPIO_TYPES_H
|
||||
|
||||
#include "SHAL_CORE.h"
|
||||
|
||||
@@ -14,6 +14,16 @@ struct SHAL_EXTIO_Register{
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //SHMINGO_HAL_SHAL_GPIO_TYPES_H
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Created by Luca on 8/29/2025.
|
||||
//
|
||||
|
||||
#ifndef SHMINGO_HAL_SHAL_GPIO_H
|
||||
#define SHMINGO_HAL_SHAL_GPIO_H
|
||||
#ifndef SHAL_GPIO_H
|
||||
#define SHAL_GPIO_H
|
||||
|
||||
#include "SHAL_GPIO_REG.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
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <stm32f072xb.h>
|
||||
|
||||
#include "SHAL_CORE.h"
|
||||
#include "SHAL_TIM_TYPES.h"
|
||||
|
||||
enum class Timer_Key : uint8_t { //For STM32F072
|
||||
S_TIM1,
|
||||
@@ -30,7 +31,7 @@ enum class Timer_Key : uint8_t { //For STM32F072
|
||||
|
||||
|
||||
//Get TIMER_KEY peripheral struct including bus register, enable mask, TIMER_KEY mask
|
||||
constexpr SHAL_Peripheral_Register getTimerRCC(Timer_Key t) {
|
||||
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};
|
||||
|
||||
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
|
||||
@@ -7,10 +7,11 @@
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef SHMINGO_HAL_SHAL_TIM_CALLBACK_H
|
||||
#define SHMINGO_HAL_SHAL_TIM_CALLBACK_H
|
||||
#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) { \
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
// Created by Luca on 9/7/2025.
|
||||
//
|
||||
|
||||
#ifndef SHMINGO_HAL_SHAL_UART_REG_H
|
||||
#define SHMINGO_HAL_SHAL_UART_REG_H
|
||||
#ifndef SHAL_UART_REG_H
|
||||
#define SHAL_UART_REG_H
|
||||
|
||||
//
|
||||
// Created by Luca on 9/6/2025.
|
||||
//
|
||||
|
||||
#ifndef SHMINGO_HAL_SHAL_GPIO_REG_H
|
||||
#define SHMINGO_HAL_SHAL_GPIO_REG_H
|
||||
|
||||
#if defined(STM32F030x6)
|
||||
#include "stm32f030x6.h"
|
||||
@@ -49,9 +47,4 @@
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //SHMINGO_HAL_SHAL_GPIO_REG_H
|
||||
|
||||
|
||||
#endif //SHMINGO_HAL_SHAL_UART_REG_H
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Created by Luca on 9/7/2025.
|
||||
//
|
||||
|
||||
#ifndef SHMINGO_HAL_SHAL_UART_REG_F072XB_H
|
||||
#define SHMINGO_HAL_SHAL_UART_REG_F072XB_H
|
||||
#ifndef SHAL_UART_REG_F072XB_H
|
||||
#define SHAL_UART_REG_F072XB_H
|
||||
|
||||
#include <stm32f072xb.h>
|
||||
#include <cassert>
|
||||
@@ -101,4 +101,17 @@ constexpr SHAL_UART_ENABLE_REG getUARTEnableReg(const UART_Pair pair){
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
constexpr uint32_t getAFMask(const AF_Mask 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;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //SHMINGO_HAL_SHAL_UART_REG_F072XB_H
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
// Created by Luca on 9/7/2025.
|
||||
//
|
||||
|
||||
#ifndef SHMINGO_HAL_SHAL_UART_TYPES_H
|
||||
#define SHMINGO_HAL_SHAL_UART_TYPES_H
|
||||
#ifndef SHAL_UART_TYPES_H
|
||||
#define SHAL_UART_TYPES_H
|
||||
|
||||
#include "SHAL_CORE.h"
|
||||
#include "SHAL_GPIO.h"
|
||||
#include "SHAL_GPIO_REG.h"
|
||||
|
||||
enum class AF_Mask : uint8_t{
|
||||
AF0 = 0x00,
|
||||
AF1 = 0x01,
|
||||
AF2 = 0x02,
|
||||
AF3 = 0x03,
|
||||
AF4 = 0x04,
|
||||
AF5 = 0x05,
|
||||
AF6 = 0x06,
|
||||
AF7 = 0x07
|
||||
AF0,
|
||||
AF1,
|
||||
AF2,
|
||||
AF3,
|
||||
AF4,
|
||||
AF5,
|
||||
AF6,
|
||||
AF7
|
||||
};
|
||||
|
||||
//Represents a pair of pins usable for USART Tx + Rx in combination, and their alternate function mapping
|
||||
|
||||
@@ -16,11 +16,14 @@ class UART{
|
||||
friend class UARTManager;
|
||||
public:
|
||||
|
||||
//begins Tx and Usart TODO either modify this function or add a new one that supports Rx
|
||||
void begin(uint32_t baudRate);
|
||||
|
||||
//Sends a string
|
||||
void sendString(const char* s);
|
||||
|
||||
//Sends a char
|
||||
void sendChar(const char c);
|
||||
void sendChar(char c);
|
||||
|
||||
private:
|
||||
|
||||
@@ -33,11 +36,14 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define initUART(uart_pair) UARTManager::get(uart_pair)
|
||||
|
||||
class UARTManager{
|
||||
|
||||
public:
|
||||
|
||||
static UART& get(UART_Pair);
|
||||
static UART& get(UART_Pair pair);
|
||||
|
||||
|
||||
UARTManager() = delete;
|
||||
|
||||
@@ -10,5 +10,6 @@
|
||||
|
||||
#include "SHAL_TIM.h"
|
||||
#include "SHAL_GPIO.h"
|
||||
#include "SHAL_UART.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,9 +31,9 @@ GPIO::GPIO() : m_GPIO_KEY(GPIO_Key::INVALID){
|
||||
|
||||
GPIO::GPIO(GPIO_Key key, PinMode pinMode) : m_GPIO_KEY(key) {
|
||||
|
||||
SHAL_Peripheral gpioPeripheral = getGPIORegister(key);
|
||||
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(key);
|
||||
|
||||
auto gpioRegister = static_cast<GPIO_TypeDef*>(gpioPeripheral.registers);
|
||||
auto gpioRegister = gpioPeripheral.reg;
|
||||
unsigned long registerOffset = gpioPeripheral.global_offset;
|
||||
|
||||
volatile unsigned long* gpioEnable = getGPIORCCEnable(key).reg;
|
||||
@@ -47,17 +47,17 @@ GPIO::GPIO(GPIO_Key key, PinMode pinMode) : m_GPIO_KEY(key) {
|
||||
|
||||
void GPIO::setLow() {
|
||||
auto gpioPeripheral = getGPIORegister(m_GPIO_KEY);
|
||||
static_cast<GPIO_TypeDef*>(gpioPeripheral.registers)->ODR &= ~(1 << gpioPeripheral.global_offset);
|
||||
gpioPeripheral.reg->ODR &= ~(1 << gpioPeripheral.global_offset);
|
||||
}
|
||||
|
||||
void GPIO::setHigh() {
|
||||
auto gpioPeripheral = getGPIORegister(m_GPIO_KEY);
|
||||
static_cast<GPIO_TypeDef*>(gpioPeripheral.registers)->ODR |= (1 << gpioPeripheral.global_offset);
|
||||
gpioPeripheral.reg->ODR |= (1 << gpioPeripheral.global_offset);
|
||||
}
|
||||
|
||||
void GPIO::toggle() volatile {
|
||||
auto gpioPeripheral = getGPIORegister(m_GPIO_KEY);
|
||||
static_cast<GPIO_TypeDef*>(gpioPeripheral.registers)->ODR ^= (1 << gpioPeripheral.global_offset);
|
||||
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
|
||||
gpioPeripheral.reg->ODR ^= (1 << gpioPeripheral.global_offset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include <cassert>
|
||||
|
||||
Timer::Timer(Timer_Key t) : TIMER_KEY(t){
|
||||
SHAL_Peripheral_Register rcc = getTimerRCC(TIMER_KEY);
|
||||
*rcc.reg |= (1 << rcc.offset);
|
||||
TIM_RCC_Enable rcc = getTimerRCC(TIMER_KEY);
|
||||
*rcc.busEnableReg |= (1 << rcc.offset);
|
||||
}
|
||||
|
||||
Timer::Timer() : TIMER_KEY(Timer_Key::S_TIM_INVALID){
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "SHAL_UART.h"
|
||||
#include "SHAL_GPIO.h"
|
||||
|
||||
UART::UART(const UART_Pair pair){
|
||||
UART::UART(const UART_Pair pair) : m_UARTPair(pair){
|
||||
SHAL_UART_Pair uart_pair = getUARTPair(pair); //Get the UART_PAIR information to be initialized
|
||||
|
||||
//Get the GPIO pins for this UART setup
|
||||
@@ -20,15 +20,55 @@ UART::UART(const UART_Pair pair){
|
||||
initGPIO(Tx_Key,PinMode::ALTERNATE_FUNCTION_MODE); //Initialize Tx GPIO with alternate function (initializes GPIO port as well)
|
||||
initGPIO(Rx_Key,PinMode::ALTERNATE_FUNCTION_MODE); //Initialize Rx GPIO with alternate function
|
||||
|
||||
//Determine which AFR register (high or low) to write depending on pin
|
||||
uint8_t TxAFR = getGPIORegister(Tx_Key).global_offset < 8 ? 0 : 1; //Use AFR[0] if pin < 8, AFR[1] if pin >= 8
|
||||
uint8_t RxAFR = getGPIORegister(Rx_Key).global_offset < 8 ? 0 : 1;
|
||||
|
||||
//Apply Alternate Function masks to the AFR registers for each GPIO to enable alternate functions
|
||||
getGPIORegister(Tx_Key).reg->AFR[TxAFR] |= getAFMask(uart_pair.TxMask);
|
||||
getGPIORegister(Rx_Key).reg->AFR[RxAFR] |= getAFMask(uart_pair.RxMask);
|
||||
|
||||
SHAL_UART_ENABLE_REG pairUARTEnable = getUARTEnableReg(pair); //Register and mask to enable the UART channel
|
||||
|
||||
*pairUARTEnable.reg |= pairUARTEnable.mask; //Enable UART line
|
||||
}
|
||||
|
||||
void UART::begin(uint32_t baudRate) {
|
||||
|
||||
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 = 48000000 / baudRate; //MAKE SURE ANY FUNCTION THAT CHANGES CLOCK UPDATES THIS!
|
||||
|
||||
usart->CR1 |= USART_CR1_UE;
|
||||
|
||||
}
|
||||
|
||||
void UART::sendString(const char *s) {
|
||||
while (*s) sendChar(*s++); //Send chars while we haven't reached end of s
|
||||
}
|
||||
|
||||
void UART::sendChar(char c) {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
UART& UARTManager::get(UART_Pair pair) {
|
||||
|
||||
//Perform logic for reassigning UART object in array
|
||||
//Always reassign since we could be changing to different pins for some reason
|
||||
m_UARTs[getUARTChannel(pair)] = UART(pair);
|
||||
|
||||
return m_UARTs[getUARTChannel(pair)];
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@ void tim2Handler(){
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
UART uart2 = initUART(UART_Pair::Tx2A2_Rx2A3);
|
||||
|
||||
uart2.begin(115200);
|
||||
|
||||
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
|
||||
|
||||
Timer timer2 = getTimer(Timer_Key::S_TIM2);
|
||||
@@ -43,5 +48,6 @@ int main() {
|
||||
|
||||
while (true) {
|
||||
__WFI();
|
||||
uart2.sendString("Hello\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user