diff --git a/Application/BSP/BSP_ADC.c b/Application/BSP/BSP_ADC.c index 0d5ac5f..77855d5 100644 --- a/Application/BSP/BSP_ADC.c +++ b/Application/BSP/BSP_ADC.c @@ -3,9 +3,15 @@ #include "adc.h" #include "stdbool.h" -#define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 16) /* Size of array aADCxConvertedData[] */ + +#define TOTAL_ADC_CHANNELS 4 +#define ADC_HISTORY_SIZE 4 +#define ADC_BUFFER_SIZE (TOTAL_ADC_CHANNELS * ADC_HISTORY_SIZE) +#define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) ADC_BUFFER_SIZE) /* Size of array aADCxConvertedData[] */ ALIGN_32BYTES (static uint16_t aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE]); +#define ADC_CHANNEL_DIMMER 1 +#define ADC_CHANNEL_BUS 3 static bool adcIsInitialized = false; @@ -53,4 +59,34 @@ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { /* Invalidate Data Cache to get the updated content of the SRAM on the second half of the ADC converted data buffer: 32 bytes */ SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE/2], ADC_CONVERTED_DATA_BUFFER_SIZE); +} + + + +float BSP_ADC_ReadValue( uint32_t channel, float factor) { + if (!adcIsInitialized) { + return 0; + } + // average the last 4 values of the dimmer ADC + uint32_t sum = 0; + for (int i = 0; i < ADC_HISTORY_SIZE; i++) { + sum += aADCxConvertedData[channel + i * TOTAL_ADC_CHANNELS]; + } + + + //convert raw ADC value to voltage + float voltage = (float)sum / (float)ADC_HISTORY_SIZE / factor; // gemessan an sample pcb + + return voltage; + +} + +float BSP_ADC_ReadDimmerValue() { + return BSP_ADC_ReadValue(ADC_CHANNEL_DIMMER, 4319.619048); + +} + + +float BSP_ADC_ReadBusValue() { + return BSP_ADC_ReadValue(ADC_CHANNEL_BUS, 4046.87186); } \ No newline at end of file diff --git a/Application/BSP/BSP_POWER.c b/Application/BSP/BSP_POWER.c index 0efd64f..907f902 100644 --- a/Application/BSP/BSP_POWER.c +++ b/Application/BSP/BSP_POWER.c @@ -135,6 +135,9 @@ void BSP_POWER_FullPowerMode() { BSP_GPIO_ClsOn(); BSP_GPIO_PeriperalsOn(); + BSP_GPIO_RadioOn(); BSP_ADC_Start(); + osDelay(10); + StartPowerTasks(); } diff --git a/Application/Tasks/LightState.c b/Application/Tasks/LightState.c index 3452b93..268ae11 100644 --- a/Application/Tasks/LightState.c +++ b/Application/Tasks/LightState.c @@ -1,7 +1,7 @@ #include "cmsis_os2.h" #include "LightState.h" #include "BSP_GPIO.h" -#include "BSP_INA.h" +#include "BSP_ADC.h" #include "LightTask.h" #include "ulog.h" @@ -31,16 +31,63 @@ static bool isK15On() // Define the threshold voltage for engine running -#define ENGINE_RUNNING_THRESHOLD 13500 // 13.5V = 13500mV +#define ENGINE_RUNNING_THRESHOLD 13.3 // 13.5V -// Check if the engine is running by checking the voltage of the battery, if above the threshold, the engine is running -static bool isEngineRunning() +// Define thresholds with hysteresis +#define ENGINE_RUNNING_THRESHOLD_HIGH (ENGINE_RUNNING_THRESHOLD + 0.125) +#define ENGINE_RUNNING_THRESHOLD_LOW (ENGINE_RUNNING_THRESHOLD - 0.125) + +// Global variable to store the current engine state +static bool engineRunning = false; + +// Function to initialize the engine state based on the initial voltage +static void initializeEngineState() { - return BSP_INA_Voltage() > ENGINE_RUNNING_THRESHOLD; + float initialVoltage = BSP_ADC_ReadBusValue(); + if (initialVoltage > ENGINE_RUNNING_THRESHOLD) + { + engineRunning = true; + } + else + { + engineRunning = false; + } } +// Ensure the engine state is initialized once +static bool isEngineInitialized = false; + +static bool isEngineRunning() +{ + if (!isEngineInitialized) + { + initializeEngineState(); + isEngineInitialized = true; + } + + float voltage = BSP_ADC_ReadBusValue(); + + if (engineRunning) + { + // If engine is currently running, use the lower threshold to turn it off + if (voltage < ENGINE_RUNNING_THRESHOLD_LOW) + { + engineRunning = false; + } + } + else + { + // If engine is currently off, use the higher threshold to turn it on + if (voltage > ENGINE_RUNNING_THRESHOLD_HIGH) + { + engineRunning = true; + } + + } + return engineRunning; +} // check if the headlight is on and the engine is running to switch the light state // we can check the headlight using the GPIO functions static bool isHeadlightOn() @@ -84,6 +131,6 @@ void LightStateTask(void *argument) } // Delay the task for a certain amount of time (in milliseconds) - osDelay(500); + osDelay(50); } } diff --git a/Application/Tasks/LightTask.c b/Application/Tasks/LightTask.c index 1d37a49..1622d85 100644 --- a/Application/Tasks/LightTask.c +++ b/Application/Tasks/LightTask.c @@ -8,6 +8,8 @@ #include "BSP_EE24.h" #include "LightTask.h" #include "CanDataHandler.h" +#include "BSP_ADC.h" +#define DIMM_DEADZONE_VOLTAGE 0.7 // Memory for the task StaticTask_t LightTask_cb; @@ -30,10 +32,13 @@ static cls_light_ThemeSettings msg_cls_light_ThemeSettings; static cls_light_SaveThemeSettings msg_cls_light_SaveThemeSettings; static cls_light_RequestThemeSetting msg_cls_light_RequestThemeSetting; -static volatile struct LightSettings_s { + typedef struct LightSettings_s { volatile uint8_t brightness; volatile uint8_t theme; -} lightSettings; +} LightSettings_t; + +static volatile LightSettings_t lightSettings = {0}; +static volatile LightSettings_t lightSettings_dimmed = {0}; void LightTask_setBrightness(uint8_t brightness) { lightSettings.brightness = brightness; @@ -57,8 +62,6 @@ void LightTask_start() { void LightTask_func(void *argument) { - osDelay(10); - BSP_EE24_PartRead(BSP_EE24_PART_GLOBAL_LIGHT, (uint8_t*) &lightSettings, sizeof(lightSettings)); uint16_t msg_global_light = GENERATE_CLS_ADDRESS(CLS_CODE_MESSAGE, GLOBAL_CAST_CLS_ADDRESS, CLS_CH_MSG_LIGHT); CLS_BSP_TxHeaderType can_header = CREATE_BSP_CAN_HEADER(msg_global_light, CLS_BSP_DLC_BYTES_2); @@ -68,7 +71,32 @@ void LightTask_func(void *argument) { { tick += 50; osDelayUntil(tick); - CLS_BSP_CAN_AddMessageToSend(&can_header,(uint8_t*)&lightSettings); + + + // calculate the brightness to send + uint8_t brightness = lightSettings.brightness; + // Read ADC battery voltage and dimmer voltage + float v_bus = BSP_ADC_ReadBusValue() - DIMM_DEADZONE_VOLTAGE; + float v_dimm = BSP_ADC_ReadDimmerValue(); + + // calculate the dimmfactor based on the battery voltage and the dimmer voltage + // the dimmfactor shoudl be 0 if the dimmer voltage is 4V. + // the dimmfactor should be 1 if the dimmer voltage is the same as the battery voltage + float dimmfactor; + if (v_dimm >= v_bus) { + dimmfactor = 1.0; + } else if (v_dimm <= 4.0) { + dimmfactor = 0.0; + } else { + dimmfactor = (v_dimm - 4.0) / (v_bus - 4.0); + } + + uint8_t adjustedBrightness = (uint8_t)(brightness * dimmfactor); + lightSettings_dimmed.brightness = adjustedBrightness; + lightSettings_dimmed.theme = lightSettings.theme; + + + CLS_BSP_CAN_AddMessageToSend(&can_header,(uint8_t*)&lightSettings_dimmed); if( settingChangeTime !=0 && tick > settingChangeTime + settingSaveTimeout) { BSP_EE24_PartWrite(BSP_EE24_PART_GLOBAL_LIGHT, (uint8_t*) &lightSettings, sizeof(lightSettings)); diff --git a/CLS_Master.ioc b/CLS_Master.ioc index 152cfc6..093e931 100644 --- a/CLS_Master.ioc +++ b/CLS_Master.ioc @@ -220,7 +220,6 @@ Mcu.IP21=USART1 Mcu.IP22=USART3 Mcu.IP23=USB_DEVICE Mcu.IP24=USB_OTG_HS -Mcu.IP25=VREFBUF Mcu.IP3=DEBUG Mcu.IP4=DMA Mcu.IP5=FATFS @@ -228,7 +227,7 @@ Mcu.IP6=FDCAN1 Mcu.IP7=FDCAN2 Mcu.IP8=FREERTOS Mcu.IP9=I2C1 -Mcu.IPNb=26 +Mcu.IPNb=25 Mcu.Name=STM32H723VGTx Mcu.Package=LQFP100 Mcu.Pin0=PE2 @@ -292,11 +291,10 @@ Mcu.Pin60=VP_RTC_VS_RTC_WakeUp_intern Mcu.Pin61=VP_SYS_VS_tim1 Mcu.Pin62=VP_TIM2_VS_ClockSourceINT Mcu.Pin63=VP_USB_DEVICE_VS_USB_DEVICE_CDC_HS -Mcu.Pin64=VP_VREFBUF_V_VREFBUF Mcu.Pin7=PA2 Mcu.Pin8=PA3 Mcu.Pin9=PA5 -Mcu.PinsNb=65 +Mcu.PinsNb=64 Mcu.ThirdParty0=STMicroelectronics.X-CUBE-EEPRMA1.4.2.0 Mcu.ThirdPartyNb=1 Mcu.UserConstants= @@ -704,7 +702,5 @@ VP_TIM2_VS_ClockSourceINT.Mode=Internal VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT VP_USB_DEVICE_VS_USB_DEVICE_CDC_HS.Mode=CDC_HS VP_USB_DEVICE_VS_USB_DEVICE_CDC_HS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_HS -VP_VREFBUF_V_VREFBUF.Mode=ExternalMode -VP_VREFBUF_V_VREFBUF.Signal=VREFBUF_V_VREFBUF board=custom rtos.0.ip=FREERTOS diff --git a/Core/Inc/main.h b/Core/Inc/main.h index e4d8c7f..2bb6dad 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -107,7 +107,7 @@ void Error_Handler(void); #define CLS_POWER_GPIO_Port GPIOE /* USER CODE BEGIN Private defines */ - +void StartPowerTasks(void); /* USER CODE END Private defines */ #ifdef __cplusplus diff --git a/Core/Src/adc.c b/Core/Src/adc.c index d91be21..2d96a3d 100644 --- a/Core/Src/adc.c +++ b/Core/Src/adc.c @@ -45,7 +45,7 @@ void MX_ADC1_Init(void) /** Common config */ hadc1.Instance = ADC1; - hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; + hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; hadc1.Init.Resolution = ADC_RESOLUTION_16B; hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; @@ -76,7 +76,7 @@ void MX_ADC1_Init(void) */ sConfig.Channel = ADC_CHANNEL_5; sConfig.Rank = ADC_REGULAR_RANK_1; - sConfig.SamplingTime = ADC_SAMPLETIME_32CYCLES_5; + sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; diff --git a/Core/Src/freertos.c b/Core/Src/freertos.c index bb10f89..798a8a8 100644 --- a/Core/Src/freertos.c +++ b/Core/Src/freertos.c @@ -38,6 +38,7 @@ #include "LightTask.h" #include "LightState.h" #include "BSP_GPIO.h" +#include "BSP_ADC.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -139,11 +140,6 @@ void MX_FREERTOS_Init(void) { UsbDataHandler_Start(); ULOG_INFO("Setup CanDataTask"); CanDataTask_start(); - ULOG_INFO("Setup CLS"); - CLS_Init(); - ULOG_INFO("Setup LightTask"); - LightTask_start(); - LightStateTask_start(); /* USER CODE END RTOS_THREADS */ /* USER CODE BEGIN RTOS_EVENTS */ @@ -206,6 +202,18 @@ void StartDefaultTask(void *argument) snprintf(INA_LOG, sizeof(INA_LOG),"Voltage[mV] %.2f Current[mA] %d P[W]: %.2f", voltage_V, current, power_W); ULOG_INFO(INA_LOG); + + + // Read the battery voltage + float bus = BSP_ADC_ReadBusValue(); + float dimm = BSP_ADC_ReadDimmerValue(); + + // Print the battery voltage and dimmer value + char output[64]; + snprintf(output,64,"Bus voltage: %.2fV, Dimmer voltage: %.2fV", bus, dimm); + ULOG_INFO(output); + + } /* USER CODE END StartDefaultTask */ } @@ -226,8 +234,7 @@ void WaitForStartConfirm_Task(void *argument) { osDelayUntil(tick); tick += delayTime; if(BSP_GPIO_K15isSet() || CanDataTask_gotCarCanMessage()) { - BSP_GPIO_ClsOn(); - BSP_GPIO_RadioOn(); + BSP_POWER_FullPowerMode(); ULOG_INFO("Power systems started"); osThreadExit(); @@ -251,5 +258,19 @@ void WaitForStartConfirm_Task(void *argument) { } } + +// this is called from BSP_POWER_FullPowerMode +// this function should start tasks that depend on the power being on +void StartPowerTasks(void) { + + ULOG_INFO("Setup CLS"); + CLS_Init(); + ULOG_INFO("Setup LightTask"); + LightTask_start(); + LightStateTask_start(); + + +} + /* USER CODE END Application */ diff --git a/Core/Src/main.c b/Core/Src/main.c index 090cdee..afd2120 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -135,7 +135,6 @@ int main(void) BSP_GPIO_PeriperalsOn(); BSP_POWER_Init(); - BSP_ADC_Start(); ULOG_INIT(); ULOG_SUBSCRIBE(ULOG_SendLPUART,ULOG_DEBUG_LEVEL); ULOG_DEBUG("Setup Logger"); diff --git a/Core/Src/stm32h7xx_hal_msp.c b/Core/Src/stm32h7xx_hal_msp.c index 5c02cab..1ab8496 100644 --- a/Core/Src/stm32h7xx_hal_msp.c +++ b/Core/Src/stm32h7xx_hal_msp.c @@ -73,18 +73,6 @@ void HAL_MspInit(void) /* PendSV_IRQn interrupt configuration */ HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0); - /** Enable the VREF clock - */ - __HAL_RCC_VREF_CLK_ENABLE(); - - /** Disable the Internal Voltage Reference buffer - */ - HAL_SYSCFG_DisableVREFBUF(); - - /** Configure the internal voltage reference buffer high impedance mode - */ - HAL_SYSCFG_VREFBUF_HighImpedanceConfig(SYSCFG_VREFBUF_HIGH_IMPEDANCE_ENABLE); - /* USER CODE BEGIN MspInit 1 */ /* USER CODE END MspInit 1 */