diff --git a/CMakeLists.txt b/CMakeLists.txt index 865579b..65b4ebd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set(MCU_FAMILY "STM32L4xx" CACHE STRING "MCU family") set(MCU_MODEL "STM32L432xx" CACHE STRING "MCU model") set(CPU_PARAMETERS - -mcpu=cortex-m0 + -mcpu=cortex-m4 -mthumb) set(STARTUP_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/MX/L432KC/startup_stm32l432kcux.s) diff --git a/SHAL/Include/Core/SHAL_CORE.h b/SHAL/Include/Core/SHAL_CORE.h index 9a34e75..5f30305 100644 --- a/SHAL/Include/Core/SHAL_CORE.h +++ b/SHAL/Include/Core/SHAL_CORE.h @@ -72,6 +72,9 @@ bool SHAL_wait_for_condition_ms(Condition cond, uint32_t timeout_ms) { //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; @@ -93,7 +96,19 @@ static inline void SHAL_apply_bitmask(volatile uint32_t* reg, uint32_t mask){ *reg |= mask; } +static inline void SHAL_set_register_value(volatile uint32_t* reg, uint32_t value){ + if(reg == nullptr){ + return; + } + *reg = value; +} +static inline void SHAL_set_register_value_16(volatile uint16_t* reg, uint16_t value){ + if(reg == nullptr){ + return; + } + *reg = value; +} //--------------------------------------------------------- diff --git a/SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_L432KC.h b/SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_L432KC.h index 67fb30d..6a833e5 100644 --- a/SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_L432KC.h +++ b/SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_L432KC.h @@ -43,11 +43,11 @@ enum class ADC_Key : uint8_t{ INVALID = 255 }; -enum class ADC_Clock_Source : uint8_t { - SHAL_SYSCLK, - SHAL_PLLSAI1, - SHAL_PLL, - SHAL_MSI +enum class ADC_Clock_Source : uint32_t { + SHAL_NO_CLOCK = 0x00, + SHAL_PLLSAI1 = 0x01, + SHAL_PLLSYS = 0x02, + SHAL_SYSCLK = 0x03, }; static volatile ADC_TypeDef* ADC_TABLE[1] = { //Lookup table for ADCs @@ -59,15 +59,21 @@ static inline SHAL_ADC_Common_Control_Reg getADCCommonControl() { } static inline SHAL_ADC_RCC_Enable_Reg getADCRCCEnableRegister(ADC_Key key){ - SHAL_ADC_RCC_Enable_Reg res = {nullptr, RCC_AHB2ENR_ADCEN}; + SHAL_ADC_RCC_Enable_Reg res = {&RCC->AHB2ENR, RCC_AHB2ENR_ADCEN}; - res.reg = &(ADC_TABLE[static_cast(key)]->ISR); return res; } static inline SHAL_ADC_Control_Reg getADCControlReg(ADC_Key key) { - SHAL_ADC_Control_Reg res = {nullptr, ADC_CR_ADEN, ADC_CR_ADDIS, ADC_CR_ADCAL, ADC_CR_ADSTART}; + SHAL_ADC_Control_Reg res = {nullptr, ADC_CR_ADEN, + ADC_CR_ADSTP, + ADC_CR_ADDIS, + ADC_CR_ADCAL, + ADC_CR_ADSTART, + ADC_CR_DEEPPWD, + ADC_CR_ADVREGEN, + ADC_CR_ADCALDIF}; res.reg = &(ADC_TABLE[static_cast(key)]->CR); return res; @@ -95,19 +101,9 @@ static inline SHAL_ADC_Data_Reg getADCDataReg(ADC_Key key){ return res; } -static inline SHAL_ADC_Clock_Reg getADCClockSelectRegister(ADC_Clock_Source clockSource) { - SHAL_ADC_Clock_Reg res = {&RCC->CCIPR, RCC_CCIPR_ADCSEL_Msk, 1U << RCC_CCIPR_ADCSEL_Pos}; //Default to PLLSAI1 +static inline SHAL_ADC_Clock_Reg getADCClockSelectRegister() { + SHAL_ADC_Clock_Reg res = {&RCC->CCIPR, RCC_CCIPR_ADCSEL_Pos}; //Position - switch(clockSource){ - case ADC_Clock_Source::SHAL_PLLSAI1: - res.mask = 1U << RCC_CCIPR_ADCSEL_Pos; - case ADC_Clock_Source::SHAL_PLL: - res.mask = 2U << RCC_CCIPR_ADCSEL_Pos; - case ADC_Clock_Source::SHAL_SYSCLK: - res.mask = 3U << RCC_CCIPR_ADCSEL_Pos; - case ADC_Clock_Source::SHAL_MSI: - break; //TODO implement this - } return res; } diff --git a/SHAL/Include/Peripheral/ADC/SHAL_ADC.h b/SHAL/Include/Peripheral/ADC/SHAL_ADC.h index c80224a..8cf6af1 100644 --- a/SHAL/Include/Peripheral/ADC/SHAL_ADC.h +++ b/SHAL/Include/Peripheral/ADC/SHAL_ADC.h @@ -16,7 +16,7 @@ class SHAL_ADC { public: - SHAL_Result init(); + SHAL_Result init(ADC_Key key); SHAL_Result calibrate(); @@ -54,6 +54,9 @@ private: //Disables peripheral SHAL_Result disable(); + //Wake up ADC from initial deep sleep state + SHAL_Result wakeFromDeepSleep(); + SHAL_Result startConversion(); /// Adds an ADC channel to the conversion sequence diff --git a/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h b/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h index 90df597..88b92d9 100644 --- a/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h +++ b/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h @@ -23,9 +23,13 @@ struct SHAL_ADC_RCC_Enable_Reg { struct SHAL_ADC_Control_Reg { volatile uint32_t* reg; uint32_t enable_mask; + uint32_t stop_mask; uint32_t disable_mask; uint32_t calibration_mask; uint32_t start_mask; + uint32_t deep_power_down_mask; + uint32_t voltage_regulator_mask; + uint32_t differential_mode_mask; }; //Register controlling ADC configuration @@ -54,8 +58,7 @@ struct SHAL_ADC_ISR_Reg { //Register controlling the clock source for the ADC struct SHAL_ADC_Clock_Reg { volatile uint32_t* reg; - uint32_t clear; - uint32_t mask; + uint32_t offset; }; //Register controlling the sampling time of ADC samples diff --git a/SHAL/Include/Peripheral/EXT/Reg/SHAL_EXTI_REG_L432KC.h b/SHAL/Include/Peripheral/EXT/Reg/SHAL_EXTI_REG_L432KC.h index 5dc2479..697e818 100644 --- a/SHAL/Include/Peripheral/EXT/Reg/SHAL_EXTI_REG_L432KC.h +++ b/SHAL/Include/Peripheral/EXT/Reg/SHAL_EXTI_REG_L432KC.h @@ -11,7 +11,7 @@ #define EXTI_PENDING_REG(line) ((line) < 32 ? EXTI->PR1 : EXTI->PR2) static inline SHAL_EXTI_Interrupt_Mask_Register getEXTIInterruptMaskRegister(uint32_t line){ - auto imr = line < 32 ? EXTI->IMR1 : EXTI->IMR2; + uint32_t imr = line < 32 ? EXTI->IMR1 : EXTI->IMR2; return {&imr}; } diff --git a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h index 582bcd0..0190e8e 100644 --- a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h +++ b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h @@ -10,7 +10,7 @@ #include "SHAL_GPIO_TYPES.h" -#define AVAILABLE_PORTS 3 +#define AVAILABLE_PORTS 2 #define PINS_PER_PORT 16 #define NUM_EXTI_LINES 16 @@ -157,6 +157,7 @@ constexpr uint32_t getGPIOPortNumber(const GPIO_Key g){ 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); diff --git a/SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG_L432KC.h b/SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG_L432KC.h index 74fca42..80b962f 100644 --- a/SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG_L432KC.h +++ b/SHAL/Include/Peripheral/UART/Reg/SHAL_UART_REG_L432KC.h @@ -81,14 +81,14 @@ static inline SHAL_UART_Control_Register_1 getUARTControlRegister1(UART_Pair_Key }; static inline SHAL_UART_Baud_Rate_Generation_Register getUARTBaudRateGenerationRegister(UART_Pair_Key key){ - SHAL_UART_Baud_Rate_Generation_Register res = {nullptr, 1UL << 15}; //TODO un-hardcode if other devices have wider baud rate allowances + SHAL_UART_Baud_Rate_Generation_Register res = {nullptr}; //TODO un-hardcode if other devices have wider baud rate allowances res.reg = &getUARTPair(key).USARTReg->BRR; return res; }; static inline SHAL_UART_Transmit_Data_Register getUARTTransmitDataRegister(UART_Pair_Key key){ - SHAL_UART_Transmit_Data_Register res = {nullptr, 1UL << 15}; //TODO un-hardcode if other devices have wider baud rate allowances + SHAL_UART_Transmit_Data_Register res = {nullptr}; //TODO un-hardcode if other devices have wider baud rate allowances res.reg = &getUARTPair(key).USARTReg->TDR; return res; diff --git a/SHAL/Include/Peripheral/UART/SHAL_UART_TYPES.h b/SHAL/Include/Peripheral/UART/SHAL_UART_TYPES.h index 11dee29..4ecf8f4 100644 --- a/SHAL/Include/Peripheral/UART/SHAL_UART_TYPES.h +++ b/SHAL/Include/Peripheral/UART/SHAL_UART_TYPES.h @@ -33,12 +33,10 @@ struct SHAL_UART_Control_Register_1 { struct SHAL_UART_Baud_Rate_Generation_Register { volatile uint32_t* reg; - uint32_t offset; }; struct SHAL_UART_Transmit_Data_Register { volatile uint16_t* reg; - uint16_t offset; }; struct SHAL_UART_ISR_FIFO_Disabled { diff --git a/SHAL/Src/STM32L4XX/Core/SHAL_CORE.cpp b/SHAL/Src/STM32L4XX/Core/SHAL_CORE.cpp index 8f46a8f..159c084 100644 --- a/SHAL/Src/STM32L4XX/Core/SHAL_CORE.cpp +++ b/SHAL/Src/STM32L4XX/Core/SHAL_CORE.cpp @@ -3,9 +3,20 @@ // #include "SHAL_CORE.h" +#include "SHAL_GPIO.h" +#include "SHAL_ADC.h" void SHAL_init(){ - systick_init(); //Just this for now + systick_init(); + + + for(auto i = static_cast(ADC_Key::S_ADC1); i < static_cast(ADC_Key::NUM_ADC); i++){ //Init all ADCs + auto adc_key = static_cast(i); + + ADCManager::getByIndex(i).init(adc_key); + } + SET_ANALOGREAD_ADC(SHAL_ADC1); //Default ADC1 for analogread calls + } diff --git a/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp b/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp index 42025e2..9b0e00e 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp @@ -3,30 +3,41 @@ // #include "SHAL_ADC.h" - +#include "SHAL_GPIO.h" +#include "SHAL_UART.h" +#include //Can hard code registers on F0 because all F0 devices have only one ADC, and use only one clock -SHAL_Result SHAL_ADC::init() { +SHAL_Result SHAL_ADC::init(ADC_Key key) { - if(m_ADCKey == ADC_Key::INVALID || m_ADCKey == ADC_Key::NUM_ADC){ + m_ADCKey = key; + + if(!isValid()){ + SHAL_UART2.sendString("Not valid\r\n"); return SHAL_Result::ERROR; } + SHAL_UART2.sendString("Init called\r\n"); + PIN(B4).toggle(); + SHAL_delay_ms(100); + PIN(B4).toggle(); + SHAL_ADC_RCC_Enable_Reg clock_reg = getADCRCCEnableRegister(m_ADCKey); //Clock enable - *clock_reg.reg |= clock_reg.mask; + SHAL_apply_bitmask(clock_reg.reg,clock_reg.mask); - SHAL_ADC_Control_Reg control_reg = getADCControlReg(m_ADCKey); + auto clock_select_register = getADCClockSelectRegister(); - if (*control_reg.reg & control_reg.enable_mask) { - //request disable: ADEN=1 -> set ADDIS to disable - *control_reg.reg |= control_reg.disable_mask; - //wait until ADEN cleared (ISR.ADREADY == 0) - if(!SHAL_WAIT_FOR_CONDITION_MS((*control_reg.reg & control_reg.enable_mask) == 0, 100)){ - return SHAL_Result::ERROR; - } - } + SHAL_set_bits(clock_select_register.reg, 2, static_cast(ADC_Clock_Source::SHAL_SYSCLK),clock_select_register.offset); //Set ADC clock + + wakeFromDeepSleep(); if(calibrate() != SHAL_Result::OKAY){ //Calibrate + SHAL_UART2.sendString("Calibration failed"); + return SHAL_Result::ERROR; + } + + if(enable() != SHAL_Result::OKAY){ + SHAL_UART2.sendString("Could not enable from init\r\n"); return SHAL_Result::ERROR; } @@ -37,19 +48,31 @@ SHAL_Result SHAL_ADC::init() { } SHAL_Result SHAL_ADC::calibrate() { - - if(disable() != SHAL_Result::OKAY){ //Disable the ADC - return SHAL_Result::ERROR; - } - SHAL_ADC_Control_Reg control_reg = getADCControlReg(m_ADCKey); - *control_reg.reg |= control_reg.calibration_mask; - - if(!SHAL_WAIT_FOR_CONDITION_US(((*control_reg.reg & control_reg.calibration_mask) == 0),500)){ //Wait for calibration + if(disable() != SHAL_Result::OKAY){ return SHAL_Result::ERROR; } + SHAL_delay_us(1000); + + if ((*control_reg.reg & (control_reg.enable_mask | control_reg.disable_mask)) != 0) { + return SHAL_Result::ERROR; + } + + SHAL_clear_bitmask(control_reg.reg, control_reg.differential_mode_mask); + + SHAL_apply_bitmask(control_reg.reg, control_reg.calibration_mask); + + if ((*control_reg.reg & control_reg.calibration_mask) == 0) { + return SHAL_Result::ERROR; + } + + if (!SHAL_WAIT_FOR_CONDITION_US(((*control_reg.reg & control_reg.calibration_mask) != 0),500)) { //Wait for conversion + return SHAL_Result::ERROR; //Failed sequence + } + + SHAL_UART2.sendString("Calibration OK\r\n"); return SHAL_Result::OKAY; } @@ -118,33 +141,70 @@ SHAL_Result SHAL_ADC::multiConvertSingle(SHAL_ADC_Channel* channels, const int n SHAL_Result SHAL_ADC::enable() { if(!isValid()){ + SHAL_UART2.sendString("Enable failed: Invalid \r\n"); return SHAL_Result::ERROR; } SHAL_ADC_Control_Reg control_reg = getADCControlReg(m_ADCKey); SHAL_ADC_ISR_Reg ISR_reg = getADCISRReg(m_ADCKey); - *control_reg.reg |= control_reg.enable_mask; //Enable - - if(!SHAL_WAIT_FOR_CONDITION_MS((*ISR_reg.reg & ISR_reg.ready_mask) != 0, 100)){ + if(!SHAL_WAIT_FOR_CONDITION_MS((*control_reg.reg & control_reg.calibration_mask) == 0, 100)) { return SHAL_Result::ERROR; } + if (*control_reg.reg & control_reg.enable_mask) { + return SHAL_Result::OKAY; //Not an error + } + + if (*control_reg.reg & control_reg.disable_mask) { + return SHAL_Result::ERROR; + } + + //Clear ADRDY flag by writing 1 to it + SHAL_apply_bitmask(ISR_reg.reg, ISR_reg.ready_mask); + + //Enable the ADC by setting ADEN + SHAL_apply_bitmask(control_reg.reg, control_reg.enable_mask); + + if(!SHAL_WAIT_FOR_CONDITION_MS((*ISR_reg.reg & ISR_reg.ready_mask) != 0, 100)) { + return SHAL_Result::ERROR; + } + + //Clear ADRDY again + SHAL_apply_bitmask(ISR_reg.reg, ISR_reg.ready_mask); + + return SHAL_Result::OKAY; +} + +SHAL_Result SHAL_ADC::wakeFromDeepSleep() { + SHAL_ADC_Control_Reg control_reg = getADCControlReg(m_ADCKey); //ADC Control register + + SHAL_clear_bitmask(control_reg.reg,control_reg.deep_power_down_mask); //Wake ADC from sleep + + SHAL_apply_bitmask(control_reg.reg,control_reg.voltage_regulator_mask); + + SHAL_delay_us(50); //Wait for regulator to stabilize + return SHAL_Result::OKAY; } SHAL_Result SHAL_ADC::disable() { - if(!isValid()){ return SHAL_Result::ERROR; } - SHAL_ADC_Control_Reg control_reg = getADCControlReg(m_ADCKey); + auto control_reg = getADCControlReg(m_ADCKey); + + //Stop any ongoing conversion + if (*control_reg.reg & control_reg.start_mask) { + SHAL_apply_bitmask(control_reg.reg, control_reg.stop_mask); + } + + //Only disable if ADC is enabled otherwise it hangs if (*control_reg.reg & control_reg.enable_mask) { - //request disable: ADEN=1 -> set ADDIS to disable - *control_reg.reg |= control_reg.disable_mask; - //wait until ADEN cleared (ISR.ADREADY == 0) - if(!SHAL_WAIT_FOR_CONDITION_MS((*control_reg.reg & control_reg.enable_mask) == 0, 100)){ + SHAL_apply_bitmask(control_reg.reg, control_reg.disable_mask); + + if (!SHAL_WAIT_FOR_CONDITION_MS(((*control_reg.reg & (control_reg.enable_mask | control_reg.disable_mask)) == 0),500)){ return SHAL_Result::ERROR; } } @@ -152,6 +212,7 @@ SHAL_Result SHAL_ADC::disable() { return SHAL_Result::OKAY; } + SHAL_Result SHAL_ADC::startConversion() { auto control_reg = getADCControlReg(m_ADCKey); @@ -186,8 +247,8 @@ SHAL_Result SHAL_ADC::configureAlignment(SHAL_ADC_Alignment alignment) { SHAL_ADC_Config_Reg config_reg = getADCConfigReg(m_ADCKey); - *config_reg.reg &= ~(0x1UL << config_reg.alignment_offset); //TODO check if this needs to be abstracted (Do other platforms have >2 resolution possibilities? - *config_reg.reg |= static_cast(alignment) << config_reg.alignment_offset; + //TODO check if this needs to be abstracted (Do other platforms have >2 resolution possibilities? + SHAL_set_bits(config_reg.reg,1,static_cast(alignment),config_reg.alignment_offset); return SHAL_Result::OKAY; } @@ -220,9 +281,13 @@ SHAL_Result SHAL_ADC::addADCChannelToSequence(SHAL_ADC_Channel channel, uint32_t uint32_t bitSectionOffset = sequenceRegisters.offsets[bitSection]; SHAL_set_bits(sequenceReg,5,channelNum,bitSectionOffset); + + return SHAL_Result::OKAY; } + + SHAL_ADC &ADCManager::get(ADC_Key key) { return m_ADCs[static_cast(key)]; } diff --git a/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp b/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp index e1077bd..9153115 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp @@ -83,9 +83,6 @@ void SHAL_GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback) SHAL_GPIO_EXTI_Register EXTILineEnable = getGPIOEXTICR(m_GPIO_KEY); *EXTILineEnable.EXT_ICR |= EXTILineEnable.mask; //Set bits to enable correct port on correct line TODO Find way to clear bits before - uint32_t rising_mask = 0x00; - uint32_t falling_mask = 0x00; - if(mode == TriggerMode::RISING_EDGE || mode == TriggerMode::RISING_FALLING_EDGE) { auto rising_trigger_selection_reg = getEXTIRisingTriggerSelectionRegister(gpioPin); SHAL_set_bits(rising_trigger_selection_reg.reg, 1, 1, gpioPin); diff --git a/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp b/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp index d2d3327..838544a 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp @@ -31,12 +31,12 @@ void Timer::stop() { void Timer::setPrescaler(uint16_t presc) { auto prescaler_reg = getTimerPrescalerRegister(m_key); - SHAL_set_bits(prescaler_reg.reg, 16, presc, prescaler_reg.offset); + SHAL_set_register_value(prescaler_reg.reg,presc); } void Timer::setARR(uint16_t arr) { auto autoreload_reg = getTimerAutoReloadRegister(m_key); - SHAL_set_bits(autoreload_reg.reg, 16, arr, autoreload_reg.offset); + SHAL_set_register_value(autoreload_reg.reg,arr); } void Timer::enableInterrupt() { diff --git a/SHAL/Src/STM32L4XX/Peripheral/UART/SHAL_UART.cpp b/SHAL/Src/STM32L4XX/Peripheral/UART/SHAL_UART.cpp index 3d78e46..be54fb0 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/UART/SHAL_UART.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/UART/SHAL_UART.cpp @@ -48,26 +48,30 @@ void SHAL_UART::begin(uint32_t baudRate) volatile { auto baud_rate_reg = getUARTBaudRateGenerationRegister(m_key); - unsigned long adjustedBaudRate = 8000000 / baudRate; - SHAL_set_bits(baud_rate_reg.reg,16,adjustedBaudRate,baud_rate_reg.offset); //MAKE SURE ANY FUNCTION THAT CHANGES CLOCK UPDATES THIS! //TODO DO NOT HARDCODE THIS SHIT + uint32_t adjustedBaudRate = SystemCoreClock / baudRate; - SHAL_apply_bitmask(control_reg.reg, control_reg.usart_enable_mask); //Clear enable bit (turn off usart) + SHAL_set_register_value(baud_rate_reg.reg,adjustedBaudRate); + + SHAL_apply_bitmask(control_reg.reg, control_reg.usart_enable_mask); //Turn on usart } void SHAL_UART::sendString(const char *s) volatile { - while (*s) sendChar(*s++); //Send chars while we haven't reached end of s + while (*s) {//Send chars while we haven't reached end of s + sendChar(*s++); + } } void SHAL_UART::sendChar(char c) volatile { auto ISR_non_fifo = getUARTISRFifoDisabled(m_key); - if(!SHAL_WAIT_FOR_CONDITION_US((*ISR_non_fifo.reg & ISR_non_fifo.transmit_data_register_empty_mask) == 0, 500)){ + if(!SHAL_WAIT_FOR_CONDITION_MS((*ISR_non_fifo.reg & ISR_non_fifo.transmit_data_register_empty_mask) != 0, 500)){ + PIN(B3).toggle(); return; } auto transmit_reg = getUARTTransmitDataRegister(m_key); - SHAL_set_bits_16(transmit_reg.reg,16,static_cast(c),transmit_reg.offset); + SHAL_set_register_value_16(transmit_reg.reg, static_cast(c)); } diff --git a/SHAL/Src/main.cpp b/SHAL/Src/main.cpp index d123c08..b87e639 100644 --- a/SHAL/Src/main.cpp +++ b/SHAL/Src/main.cpp @@ -1,12 +1,50 @@ #include "SHAL.h" #include +#include + +void togglePin() { + + //PIN(B4).toggle(); + //SHAL_UART2.sendString("Test\r\n"); +} + +void timer2callback(){ + auto val = PIN(B7).analogRead(); + + char buf [6]; + sprintf (buf, "%d\r\n", val); + + SHAL_UART2.sendString(buf); +} int main() { + SHAL_init(); + + + PIN(B4).setPinMode(PinMode::OUTPUT_MODE); + PIN(B4).setLow(); + + PIN(B3).setPinMode(PinMode::OUTPUT_MODE); + + SHAL_UART2.init(UART_Pair_Key::Tx2A2_Rx2A3); + + SHAL_UART2.begin(115200); + + + SHAL_UART2.sendString("Hello\r\n"); + + + SHAL_TIM2.init(8000000,1000); + + SHAL_TIM2.setCallbackFunc(timer2callback); + SHAL_TIM2.enableInterrupt(); + SHAL_TIM2.start(); + //End setup while (true) { - __WFI(); + } } diff --git a/gcc-arm-none-eabi.cmake b/gcc-arm-none-eabi.cmake index 28fb92d..66b0179 100644 --- a/gcc-arm-none-eabi.cmake +++ b/gcc-arm-none-eabi.cmake @@ -10,7 +10,7 @@ set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}gcc) set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size) -set(COMMON_FLAGS "-mcpu=cortex-m0 -mthumb -fdata-sections -ffunction-sections") +set(COMMON_FLAGS "-mcpu=cortex-m4 -mthumb -fdata-sections -ffunction-sections") set(CMAKE_C_FLAGS_INIT "${COMMON_FLAGS} --specs=nano.specs") set(CMAKE_CXX_FLAGS_INIT "${COMMON_FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics --specs=nano.specs")