From 303a55459540a46c3b588191fe2f28c73a091334 Mon Sep 17 00:00:00 2001 From: Luca Lizaranzu Date: Mon, 16 Mar 2026 17:10:48 -0700 Subject: [PATCH] uart working but fix send char --- CMakeLists.txt | 10 +- .../UART/Reg/SHAL_UART_REG_H753ZI.h | 112 ++++++++++++++++++ SHAL/Include/Peripheral/UART/SHAL_UART.h | 2 +- SHAL/Include/Peripheral/UART/SHAL_UART_REG.h | 45 +++++++ .../Include/Peripheral/UART/SHAL_UART_TYPES.h | 21 +++- SHAL/Include/SHAL.h | 2 +- .../STM32H7xx/Peripheral/GPIO/SHAL_GPIO.cpp | 2 +- .../STM32H7xx/Peripheral/UART/SHAL_UART.cpp | 95 +++++++++++++++ SHAL/Src/main.cpp | 23 ++-- 9 files changed, 288 insertions(+), 24 deletions(-) create mode 100644 SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG_H753ZI.h create mode 100644 SHAL/Src/STM32H7xx/Peripheral/UART/SHAL_UART.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9408168..3907e43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,8 +37,7 @@ set(PROJECT_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} #[[ -SHAL/Include/Peripheral/UART -SHAL/Include/Peripheral/UART/Reg + SHAL/Include/Peripheral/I2C SHAL/Include/Peripheral/I2C/Reg SHAL/Include/Peripheral/ADC @@ -51,6 +50,8 @@ SHAL/Include/Peripheral/EXT/Reg SHAL/Include/Peripheral/GPIO/Reg SHAL/Include/Peripheral/Timer SHAL/Include/Peripheral/Timer/Reg + SHAL/Include/Peripheral/UART + SHAL/Include/Peripheral/UART/Reg ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Include ) @@ -65,12 +66,13 @@ file(GLOB_RECURSE PROJECT_SOURCES #Temporary manual method of including source files to avoid including broken code ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Peripheral/GPIO/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Peripheral/Timer/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Peripheral/UART/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Src/${MCU_FAMILY}/Core/*.cpp ) add_executable(${EXECUTABLE} -${PROJECT_SOURCES} -${STARTUP_SCRIPT} + ${PROJECT_SOURCES} + ${STARTUP_SCRIPT} ) target_compile_definitions(${EXECUTABLE} PRIVATE diff --git a/SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG_H753ZI.h b/SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG_H753ZI.h new file mode 100644 index 0000000..89e404f --- /dev/null +++ b/SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG_H753ZI.h @@ -0,0 +1,112 @@ +// +// Created by Luca on 9/7/2025. +// + +#ifndef SHAL_UART_REG_F072XB_H +#define SHAL_UART_REG_F072XB_H + +#include +#include + +#include "SHAL_UART_TYPES.h" + +#define NUM_USART_LINES 4 + +#define SHAL_UART1 UART(1) +#define SHAL_UART2 UART(2) +#define SHAL_UART3 UART(3) +#define SHAL_UART4 UART(4) + +//Valid usart Tx and Rx pairings for STM32F072 +enum class UART_Pair_Key : uint8_t{ + //UART2 + Tx2A2_Rx2A3, + Tx3D8_Rx3D9, + + NUM_PAIRS, + INVALID +}; + +static SHAL_UART_Pair getUARTPair(const UART_Pair_Key pair){ + switch(pair){ + case UART_Pair_Key::Tx2A2_Rx2A3: + return {USART2, GPIO_Key::A2, GPIO_Key::A3, GPIO_Alternate_Function::AF7, GPIO_Alternate_Function::AF7}; + case UART_Pair_Key::Tx3D8_Rx3D9: + return {USART3, GPIO_Key::D8, GPIO_Key::D9, GPIO_Alternate_Function::AF7, GPIO_Alternate_Function::AF7}; + case UART_Pair_Key::NUM_PAIRS: + case UART_Pair_Key::INVALID: + assert(false); + return {nullptr, GPIO_Key::INVALID, GPIO_Key::INVALID, GPIO_Alternate_Function::AF0, GPIO_Alternate_Function::AF0}; + default: + __builtin_unreachable(); + } +} + +constexpr SHAL_UART_Enable_Register getUARTEnableReg(const UART_Pair_Key pair){ + switch(pair){ + case UART_Pair_Key::Tx2A2_Rx2A3: + return {&RCC->APB1LENR,RCC_APB1LENR_USART2EN}; + case UART_Pair_Key::Tx3D8_Rx3D9: + return {&RCC->APB1LENR,RCC_APB1LENR_USART3EN}; + case UART_Pair_Key::NUM_PAIRS: + case UART_Pair_Key::INVALID: + assert(false); + return {nullptr, 0}; + } + __builtin_unreachable(); +} + +static SHAL_UART_Control_Register_1 getUARTControlRegister1(const UART_Pair_Key key) { + SHAL_UART_Control_Register_1 res = { + nullptr, + USART_CR1_UE, + USART_CR1_TE, + USART_CR1_RE, + USART_CR1_M0, + USART_CR1_M1 + }; + + res.reg = &getUARTPair(key).USARTReg->CR1; + return res; +}; + +static SHAL_UART_Baud_Rate_Generation_Register getUARTBaudRateRegister(const UART_Pair_Key key) { + SHAL_UART_Baud_Rate_Generation_Register res = {nullptr}; + + res.reg = &getUARTPair(key).USARTReg->BRR; + return res; +} + +static SHAL_UART_ISR getUARTISR(const UART_Pair_Key key) { //TODO Support for multiple alternates for FIFO + SHAL_UART_ISR res = { + nullptr, + USART_ISR_TXE_TXFNF, + USART_ISR_TC, + USART_ISR_BUSY + }; + + res.reg = &getUARTPair(key).USARTReg->ISR; + return res; +} + +static SHAL_UART_Transmit_Data_Register getUARTTransmitDataRegister(const UART_Pair_Key key) { + return {&getUARTPair(key).USARTReg->CR1}; +} + +static + +constexpr uint32_t getAFMask(const GPIO_Alternate_Function mask){ + switch(mask){ + 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(); +} + +#endif //SHMINGO_HAL_SHAL_UART_REG_F072XB_H diff --git a/SHAL/Include/Peripheral/UART/SHAL_UART.h b/SHAL/Include/Peripheral/UART/SHAL_UART.h index b9ffb3a..ff04f5e 100644 --- a/SHAL/Include/Peripheral/UART/SHAL_UART.h +++ b/SHAL/Include/Peripheral/UART/SHAL_UART.h @@ -20,7 +20,7 @@ public: void init(UART_Pair_Key pair); //begins Tx and Usart TODO either modify this function or add a new one that supports Rx - void begin(uint32_t baudRate) volatile; + void begin(uint32_t baudRate, SHAL_USART_Word_Length wordLength) const volatile; //Sends a string void sendString(const char* s) volatile; diff --git a/SHAL/Include/Peripheral/UART/SHAL_UART_REG.h b/SHAL/Include/Peripheral/UART/SHAL_UART_REG.h index cf7b27e..c33122e 100644 --- a/SHAL/Include/Peripheral/UART/SHAL_UART_REG.h +++ b/SHAL/Include/Peripheral/UART/SHAL_UART_REG.h @@ -89,7 +89,52 @@ #elif defined(STM32L4S7xx) #include "stm32l4s7xx.h" #elif defined(STM32L4S9xx) +#elif defined(STM32H743xx) + #include "stm32h743xx.h" +#elif defined(STM32H753xx) + #include "SHAL_UART_REG_H753ZI.h" +#elif defined(STM32H750xx) + #include "stm32h750xx.h" +#elif defined(STM32H742xx) + #include "stm32h742xx.h" +#elif defined(STM32H745xx) + #include "stm32h745xx.h" +#elif defined(STM32H745xG) + #include "stm32h745xg.h" +#elif defined(STM32H755xx) + #include "stm32h755xx.h" +#elif defined(STM32H747xx) + #include "stm32h747xx.h" +#elif defined(STM32H747xG) + #include "stm32h747xg.h" +#elif defined(STM32H757xx) + #include "stm32h757xx.h" +#elif defined(STM32H7B0xx) + #include "stm32h7b0xx.h" +#elif defined(STM32H7B0xxQ) + #include "stm32h7b0xxq.h" +#elif defined(STM32H7A3xx) + #include "stm32h7a3xx.h" +#elif defined(STM32H7B3xx) + #include "stm32h7b3xx.h" +#elif defined(STM32H7A3xxQ) + #include "stm32h7a3xxq.h" +#elif defined(STM32H7B3xxQ) + #include "stm32h7b3xxq.h" +#elif defined(STM32H735xx) + #include "stm32h735xx.h" +#elif defined(STM32H733xx) + #include "stm32h733xx.h" +#elif defined(STM32H730xx) + #include "stm32h730xx.h" +#elif defined(STM32H730xxQ) + #include "stm32h730xxq.h" +#elif defined(STM32H725xx) + #include "stm32h725xx.h" +#elif defined(STM32H723xx) + #include "stm32h723xx.h" #else + #error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)" #endif diff --git a/SHAL/Include/Peripheral/UART/SHAL_UART_TYPES.h b/SHAL/Include/Peripheral/UART/SHAL_UART_TYPES.h index e99657d..a5c100c 100644 --- a/SHAL/Include/Peripheral/UART/SHAL_UART_TYPES.h +++ b/SHAL/Include/Peripheral/UART/SHAL_UART_TYPES.h @@ -27,21 +27,32 @@ struct SHAL_UART_Control_Register_1 { uint32_t usart_enable_mask; uint32_t transmit_enable_mask; uint32_t receive_enable_mask; + uint32_t m0_mask; + uint32_t m1_mask; }; struct SHAL_UART_Baud_Rate_Generation_Register { volatile uint32_t* reg; }; -struct SHAL_UART_Transmit_Data_Register { - volatile uint16_t* reg; -}; - -struct SHAL_UART_ISR_FIFO_Disabled { +struct SHAL_UART_ISR { volatile uint32_t* reg; uint32_t transmit_data_register_empty_mask; + uint32_t transmission_complete_mask; + uint32_t busy_mask; }; +struct SHAL_UART_Transmit_Data_Register { + volatile uint32_t* reg; +}; + +enum class SHAL_USART_Word_Length : uint32_t { //See M bits for USART + Bits_7 = 1 << 28, + Bits_8 = 0, + Bits_9 = 1 << 12 //Universal M bit implementation +}; + + #endif //SHMINGO_HAL_SHAL_UART_TYPES_H diff --git a/SHAL/Include/SHAL.h b/SHAL/Include/SHAL.h index d1f4f7a..fce6277 100644 --- a/SHAL/Include/SHAL.h +++ b/SHAL/Include/SHAL.h @@ -10,7 +10,7 @@ #include "SHAL_TIM.h" #include "SHAL_GPIO.h" -//#include "SHAL_UART.h" +#include "SHAL_UART.h" //#include "SHAL_ADC.h" diff --git a/SHAL/Src/STM32H7xx/Peripheral/GPIO/SHAL_GPIO.cpp b/SHAL/Src/STM32H7xx/Peripheral/GPIO/SHAL_GPIO.cpp index 239114d..4fff8b5 100644 --- a/SHAL/Src/STM32H7xx/Peripheral/GPIO/SHAL_GPIO.cpp +++ b/SHAL/Src/STM32H7xx/Peripheral/GPIO/SHAL_GPIO.cpp @@ -15,7 +15,7 @@ SHAL_GPIO::SHAL_GPIO(GPIO_Key key) : m_GPIO_KEY(key) { auto GPIORCCEnable = getGPIORCCEnable(key); - SHAL_set_register_value(GPIORCCEnable.reg,GPIORCCEnable.mask); + SHAL_apply_bitmask(GPIORCCEnable.reg,GPIORCCEnable.mask); } void SHAL_GPIO::setLow() { diff --git a/SHAL/Src/STM32H7xx/Peripheral/UART/SHAL_UART.cpp b/SHAL/Src/STM32H7xx/Peripheral/UART/SHAL_UART.cpp new file mode 100644 index 0000000..caae3cc --- /dev/null +++ b/SHAL/Src/STM32H7xx/Peripheral/UART/SHAL_UART.cpp @@ -0,0 +1,95 @@ +/** + ****************************************************************************** + * @file SHAL_TIM.h + * @author Luca Lizaranzu + * @brief Related to USART and SHAL_UART abstractions + ****************************************************************************** + */ + + +#include "SHAL_UART.h" +#include "SHAL_GPIO.h" +#include "SHAL_UART_REG.h" + +void SHAL_UART::init(const UART_Pair_Key pair){ + + m_key = pair; + + auto uartPair = getUARTPair(pair); //Get the UART_PAIR information to be initialized + + //Get the SHAL_GPIO pins for this SHAL_UART setup + const GPIO_Key Tx_Key = uartPair.TxKey; //Tx pin + const GPIO_Key Rx_Key = uartPair.RxKey; //Rx pin + + GET_GPIO(Tx_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE); + GET_GPIO(Rx_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE); + + GET_GPIO(Tx_Key).setAlternateFunction(uartPair.TxAlternateFunctionMask); + GET_GPIO(Rx_Key).setAlternateFunction(uartPair.RxAlternateFunctionMask); + + + SHAL_UART_Enable_Register pairUARTEnable = getUARTEnableReg(pair); //Register and mask to enable the SHAL_UART channel + + SHAL_apply_bitmask(pairUARTEnable.reg,pairUARTEnable.mask); + + +} + +void SHAL_UART::begin(uint32_t baudRate, SHAL_USART_Word_Length wordLength) const volatile { + + auto CR = getUARTControlRegister1(m_key); + auto BRR = getUARTBaudRateRegister(m_key); // fix this + + SHAL_clear_bitmask(CR.reg, CR.usart_enable_mask); + + SHAL_apply_bitmask(CR.reg, static_cast(wordLength)); + SHAL_apply_bitmask(CR.reg, CR.receive_enable_mask); + SHAL_apply_bitmask(CR.reg, CR.transmit_enable_mask); + + uint16_t baud = SystemCoreClock / (1 * baudRate); + SHAL_set_bits_16(BRR.reg, 16, baud, 0); + + SHAL_apply_bitmask(CR.reg, CR.usart_enable_mask); //Enable +} + +void SHAL_UART::sendString(const char *s) volatile { + const auto ISR = getUARTISR(m_key); + + while (*s) sendChar(*s++); //Send chars while we haven't reached end of s + + if(!SHAL_WAIT_FOR_CONDITION_US((*ISR.reg & ISR.transmission_complete_mask) != 0, 1000)){ + assert(false); + } +} + +void SHAL_UART::sendChar(char c) volatile { + + /* TODO fix old + auto ISR = getUARTISR(m_key); + + if(!SHAL_WAIT_FOR_CONDITION_US((*ISR.reg & ISR.transmit_data_register_empty_mask) == 0, 20)){ //TODO check if this is too slow for this? Need to check busy reg + assert(false); + } + + + *getUARTTransmitDataRegister(m_key).reg = c; //Send character + */ + /* Wait until TXE (Transmit Data Register Empty) */ + while (!(USART3->ISR & USART_ISR_TXE_TXFNF)) + { + /* spin */ + } + USART3->TDR = (uint32_t)(uint8_t)c; +} + + + +SHAL_UART& UARTManager::get(uint8_t uart) { + + if(uart > NUM_USART_LINES - 1){ + assert(false); + //Memory fault + } + + return m_UARTs[uart]; +} diff --git a/SHAL/Src/main.cpp b/SHAL/Src/main.cpp index fcdd553..5325f96 100644 --- a/SHAL/Src/main.cpp +++ b/SHAL/Src/main.cpp @@ -1,24 +1,23 @@ -#include #include "SHAL.h" int main() { SHAL_init(); - PIN(E9).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE); + PIN(C0).setPinMode(PinMode::OUTPUT_MODE); - PIN(E9).setAlternateFunction(GPIO_Alternate_Function::AF1); + SHAL_UART3.init(UART_Pair_Key::Tx3D8_Rx3D9); + SHAL_UART3.begin(115200,SHAL_USART_Word_Length::Bits_8); - SHAL_TIM1.configurePWM(SHAL_Timer_Channel::CH1,24,2000,5); - - SHAL_TIM1.start(); - - PIN(A3).setPinMode(PinMode::OUTPUT_MODE); - PIN(B0).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE); + SHAL_UART3.sendChar('a'); while (true) { - PIN(A3).toggle(); - PIN(B0).toggle(); + + SHAL_UART3.sendString("Hello"); + + PIN(C0).toggle(); + SHAL_delay_ms(500); } -} + return 0; +} \ No newline at end of file