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 a92a554..67a5cc2 100644 --- a/SHAL/Include/Peripheral/EXT/Reg/SHAL_EXTI_REG_L432KC.h +++ b/SHAL/Include/Peripheral/EXT/Reg/SHAL_EXTI_REG_L432KC.h @@ -10,6 +10,15 @@ #define EXTI_PENDING_REG(line) ((line) < 32 ? EXTI->PR1 : EXTI->PR2) +static inline SHAL_EXTI_Control_Register getEXTIControlRegister(uint32_t line){ + uint8_t maskOffset = line % 4; //Each register has four 4-bit wide fields + uint8_t registerOffset = line / 4; //Composed of four registers with 4 fields each + + SHAL_EXTI_Control_Register res = {&SYSCFG->EXTICR[registerOffset], maskOffset}; + + return res; +} + static inline SHAL_EXTI_Interrupt_Mask_Register getEXTIInterruptMaskRegister(uint32_t line){ volatile uint32_t* reg = line < 32 ? &EXTI->IMR1 : &EXTI->IMR2; return {reg};; diff --git a/SHAL/Include/Peripheral/EXT/SHAL_EXTI_TYPES.h b/SHAL/Include/Peripheral/EXT/SHAL_EXTI_TYPES.h index e20cc3e..d7c53b3 100644 --- a/SHAL/Include/Peripheral/EXT/SHAL_EXTI_TYPES.h +++ b/SHAL/Include/Peripheral/EXT/SHAL_EXTI_TYPES.h @@ -19,4 +19,9 @@ struct SHAL_EXTI_Falling_Trigger_Selection_Register { volatile uint32_t* reg; }; +struct SHAL_EXTI_Control_Register { + volatile uint32_t* reg; + uint32_t offset; +}; + #endif //SHMINGO_HAL_SHAL_EXTI_TYPES_H 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 6122f2f..67463e4 100644 --- a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h +++ b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h @@ -71,6 +71,10 @@ constexpr uint8_t getGPIOPinNumber(GPIO_Key key){ return static_cast(key) % 16; } +constexpr uint8_t getGPIOPortNUmber(GPIO_Key key){ + return static_cast(key) / 16; +} + constexpr SHAL_GPIO_EXTI_Register getGPIOEXTICR(const GPIO_Key g){ switch(g) { case GPIO_Key::A0: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI0_PA,EXTI0_IRQn}; @@ -158,6 +162,12 @@ static inline SHAL_GPIO_Output_Data_Register getGPIOOutputDataRegister(const GPI return {reg,offset}; } +static inline SHAL_GPIO_Input_Data_Register getGPIOInputDataRegister(const GPIO_Key key){ + volatile uint32_t* reg = &GPIO_TABLE[static_cast(key) / 16]->IDR; + uint32_t offset = static_cast(key) % 16; + return {reg,offset}; +} + constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){ switch(key){ case GPIO_Key::A0: diff --git a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h index c2be634..2192f80 100644 --- a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h +++ b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h @@ -29,6 +29,7 @@ public: /// \return ADC result uint16_t analogRead(SHAL_ADC_SampleTime sampleTime = SHAL_ADC_SampleTime::C8); + uint16_t digitalRead(); void setAlternateFunction(GPIO_Alternate_Function AF) volatile; void setAlternateFunction(GPIO_Alternate_Function_Mapping AF) volatile; diff --git a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO_TYPES.h b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO_TYPES.h index 3dcd53e..10dfef1 100644 --- a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO_TYPES.h +++ b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO_TYPES.h @@ -50,6 +50,11 @@ struct SHAL_GPIO_Output_Data_Register { uint32_t offset; }; +struct SHAL_GPIO_Input_Data_Register { + volatile uint32_t* reg; + uint32_t offset; +}; + struct SHAL_GPIO_Port_Info{ uint8_t number; SHAL_ADC_Channel ADCChannel; diff --git a/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp b/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp index bf460e2..8bacaf1 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp @@ -64,7 +64,6 @@ SHAL_Result SHAL_GPIO::setPinMode(PinMode mode) volatile { SHAL_UART2.sendString(buff); return SHAL_Result::ERROR; } - SHAL_print_register(pinModeReg.reg); SHAL_set_bits(pinModeReg.reg,2,static_cast(mode),pinModeReg.offset); //Set mode @@ -73,31 +72,20 @@ SHAL_Result SHAL_GPIO::setPinMode(PinMode mode) volatile { void SHAL_GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback) { - uint32_t gpioPin = getGPIOPinNumber(m_GPIO_KEY); - setPinMode(PinMode::INPUT_MODE); //Explicitly set mode to input + /* ---- Connect PB6 to EXTI6 via SYSCFG ---- */ + uint32_t port_b_val = 1; // 0=A, 1=B, 2=C, 3=D, etc. + SYSCFG->EXTICR[1] &= ~(0xFUL << 8); // Clear EXTI6 bits (bits 8-11) + SYSCFG->EXTICR[1] |= (port_b_val << 8); // Set EXTI6 to PB6 - RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; //Enable EXT, TODO Add this to a global SHAL_GLOBAL_TYPES.h file - NVIC_EnableIRQ(getGPIOEXTICR(m_GPIO_KEY).IRQN); //Enable IRQN for pin + /* ---- Configure EXTI line 6 ---- */ + EXTI->IMR1 |= (1UL << 6); // Unmask line 6 + EXTI->RTSR1 |= (1UL << 6); // Rising trigger enable + EXTI->FTSR1 &= ~(1UL << 6); // Falling trigger disable - auto ext_imr = getEXTIInterruptMaskRegister(gpioPin); - SHAL_set_bits(ext_imr.reg,1,1,gpioPin); - - 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 - - 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); - } - - if(mode == TriggerMode::FALLING_EDGE || mode == TriggerMode::RISING_FALLING_EDGE) { - auto falling_trigger_selection_reg = getEXTIFallingTriggerSelectionRegister(gpioPin); - SHAL_set_bits(falling_trigger_selection_reg.reg,1,1,gpioPin); - } - - //Set callback - registerEXTICallback(m_GPIO_KEY,callback); + /* ---- Enable NVIC interrupt for EXTI lines [9:5] ---- */ + NVIC_SetPriority(EXTI9_5_IRQn, 2); + NVIC_EnableIRQ(EXTI9_5_IRQn); __enable_irq(); //Enable IRQ just in case } @@ -115,6 +103,15 @@ void SHAL_GPIO::setAlternateFunction(GPIO_Alternate_Function_Mapping AF) volatil SHAL_set_bits(alternateFunctionReg.reg,4,static_cast(AF),alternateFunctionReg.offset); } +uint16_t SHAL_GPIO::digitalRead() { + auto inputDataReg = getGPIOInputDataRegister(m_GPIO_KEY); + + if((*inputDataReg.reg & (1 << 6)) != 0){ + return 1; + } + return 0; +} + SHAL_GPIO& GPIOManager::get(GPIO_Key key) { diff --git a/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp b/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp index d3efe5b..f2ab060 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp @@ -17,11 +17,14 @@ void Timer::start() { auto control_reg = getTimerControlRegister1(m_key); auto event_generation_reg = getTimerEventGenerationRegister(m_key); + auto status_reg = getTimerStatusRegister(m_key); SHAL_apply_bitmask(control_reg.reg, control_reg.counter_enable_mask); //Enable counter SHAL_apply_bitmask(control_reg.reg, control_reg.auto_reload_preload_enable_mask); //Preload enable (buffer) SHAL_apply_bitmask(event_generation_reg.reg, event_generation_reg.update_generation_mask); + SHAL_clear_bitmask(status_reg.reg,status_reg.update_interrupt_flag_mask); + enableInterrupt(); } diff --git a/SHAL/Src/main.cpp b/SHAL/Src/main.cpp index aa0ea6d..6965588 100644 --- a/SHAL/Src/main.cpp +++ b/SHAL/Src/main.cpp @@ -10,27 +10,47 @@ GPIO_Key gpios[6] = { GPIO_Key::A7, }; +uint16_t vals[6] = {0,0,0,0,0,0}; +uint8_t currentSensor = 0; + bool isAlarmBeeping = false; -bool isCalibrateButtonHigh = false; + +bool prevIsCalibrateButtonHigh = false; uint16_t sensorThresholds[6] = {4096,4096,4096,4096,4096,4096}; -void timer2callback(){ - uint16_t val[6]; +int cyclesPerPrint = 4; +int currentCycle = 0; - for(int i = 0; i < 6; i++){ - val[i] = GPIOManager::get(gpios[i]).analogRead(SHAL_ADC_SampleTime::C8); - SHAL_delay_ms(30); +void getSensorData(){ + + vals[currentSensor] = GPIOManager::get(gpios[currentSensor]).analogRead(SHAL_ADC_SampleTime::C8); + + if(currentSensor == 5 && currentCycle == cyclesPerPrint - 1){ + char buff[64]; + sprintf(buff, "%d, %d, %d, %d, %d, %d\r\n", vals[0],vals[1],vals[2],vals[3],vals[4],vals[5]); + SHAL_UART2.sendString(buff); } - char buff[64]; - sprintf(buff, "%d, %d, %d, %d, %d, %d\r\n", val[0],val[1],val[2],val[3],val[4],val[5]); - - SHAL_UART2.sendString(buff); - + currentSensor = (currentSensor + 1) % 6; + currentCycle = (currentCycle + 1) % cyclesPerPrint; } +void calibrateThresholds(){ + + for(int i = 0; i < 6; i++){ + uint16_t sensorVal = GPIOManager::get(gpios[i]).analogRead(SHAL_ADC_SampleTime::C8); + sensorThresholds[i] = sensorVal; + SHAL_delay_ms(80); + } + char buff[80]; + sprintf(buff, "Thresholds: %d, %d, %d, %d, %d, %d\r\n", sensorThresholds[0],sensorThresholds[1],sensorThresholds[2],sensorThresholds[3],sensorThresholds[4],sensorThresholds[5]); + SHAL_UART2.sendString(buff); +} + + + void PWMToggle(){ if(!isAlarmBeeping){ @@ -42,13 +62,14 @@ void PWMToggle(){ isAlarmBeeping = !isAlarmBeeping; } -void buttonCallback(){ +void buttonHoldCallback(){ + PIN(B3).toggle(); -} + SHAL_TIM7.stop(); //Stop this timer -void calibrateSensors(){ - PIN(B3).setHigh(); - SHAL_TIM7.stop(); + SHAL_TIM2.stop(); //Stop reading from ADC + calibrateThresholds(); + SHAL_TIM2.start(); //Restart value checks } int main() { @@ -67,12 +88,9 @@ int main() { PIN(B0).setAlternateFunction(GPIO_Alternate_Function_Mapping::B0_TIM1CH2N); - PIN(B6).setPinMode(PinMode::INPUT_MODE); - PIN(B6).useAsExternalInterrupt(TriggerMode::RISING_FALLING_EDGE,buttonCallback); - SHAL_TIM2.init(4000000,400); - SHAL_TIM2.setCallbackFunc(timer2callback); + SHAL_TIM2.setCallbackFunc(getSensorData); SHAL_TIM2.enableInterrupt(); SHAL_TIM2.start(); @@ -86,13 +104,32 @@ int main() { SHAL_TIM6.enableInterrupt(); SHAL_TIM6.start(); - SHAL_TIM7.init(4000000,3000); - SHAL_TIM7.setCallbackFunc(calibrateSensors); + SHAL_TIM7.init(4000000,6000); + SHAL_TIM7.setCallbackFunc(buttonHoldCallback); SHAL_TIM7.enableInterrupt(); + //SHAL_TIM7.start(); + PIN(B6).setPinMode(PinMode::INPUT_MODE); PIN(B3).setPinMode(PinMode::OUTPUT_MODE); //Test + PIN(B3).setLow(); while (true) { - SHAL_UART2.sendString("HELLO\r\n"); + //Retarded polling based button methods cause EXTI decided to not work on L432KC for some stupid reason at the last second + if(!(PIN(B6).digitalRead() == 1)){ + //SHAL_UART2.sendString("High\r\n"); + if(!prevIsCalibrateButtonHigh){ + SHAL_TIM7.start(); + } + prevIsCalibrateButtonHigh = true; + } + else{ + //SHAL_UART2.sendString("Low\r\n"); + if(prevIsCalibrateButtonHigh){ + //Button released + SHAL_TIM7.stop(); + } + prevIsCalibrateButtonHigh = false; + } + } } \ No newline at end of file