diff --git a/ECU/Application/Inc/StateData.h b/ECU/Application/Inc/StateData.h index 5094af7e..0da61b53 100644 --- a/ECU/Application/Inc/StateData.h +++ b/ECU/Application/Inc/StateData.h @@ -19,27 +19,48 @@ * logic to access and modify the ECU's operational data. */ typedef struct ECU_StateData { - // DON'T TOUCH YET - GR_OLD_ECU_STATUS_1_MSG ecuStatus1; - GR_OLD_ECU_STATUS_2_MSG ecuStatus2; - GR_OLD_ECU_STATUS_3_MSG ecuStatus3; + // TODO: Remove unneeded states int32_t dischargeStartMillis; uint32_t lastECUStatusMsgTick; uint32_t lastTSSIFlash; int32_t last_drive_active_control_ms; + float min_amk_heat_cap_throttle_percent; + float ts_voltage; + float max_cell_temp; /** Temperature of hottest cell, celsius */ + + float vehicle_speed; /** Vehicle speed, MPH */ + float fr_wheel_rpm; /** FR wheel, RPM */ + float fl_wheel_rpm; /** FL wheel, RPM */ + float rr_wheel_rpm; /** RRv wheel, RPM */ + float rl_wheel_rpm; /** RL wheel, RPM */ + + // 0.5V when things go to shit (X_OK low) + // 3V when things almost poggers (X_OK high but SDC not reset) + // 2.4V when things are actually poggers (X_OK high and SDC is not triggered) + float ams_sense; + float imd_sense; + float bspd_sense; + + float estop_sense; uint16_t driving_heat_capacity_1; uint16_t driving_heat_capacity_2; uint16_t APPS1_Signal; uint16_t APPS2_Signal; uint16_t Brake_R_Signal; uint16_t Brake_F_Signal; + uint16_t STEERING_ANGLE_SIGNAL; + int8_t ping_block[3]; /** Node timeout status bits (1=OK, 0=Timeout) */ + uint8_t powerlevel_torquemap; /** Power lvl (4b) & torque map (4b) */ + uint8_t tractivebattery_soc; /** Accumulator SoC, 20x/51=% */ + uint8_t glv_soc; /** GLV SoC, 20x/51=% */ uint8_t acu_error_warning_bits; uint8_t inverter_fault_map; bool bse_apps_violation; bool ts_active_button_engaged; bool rtd_button_engaged; + GR_ECU_State ecu_state; } ECU_StateData; // FIXME Add comments to each data field with descriptions and // rules (eg -1 = invalid?, etc) // Will also need to add information from ADC into this struct diff --git a/ECU/Application/Inc/StateTicks.h b/ECU/Application/Inc/StateTicks.h index 6844ceb8..f2f5161b 100644 --- a/ECU/Application/Inc/StateTicks.h +++ b/ECU/Application/Inc/StateTicks.h @@ -22,7 +22,7 @@ void ECU_State_Tick(void); * * @return void */ -void ECU_GLV_Off(ECU_StateData *stateData); +void ECU_GLV_Off(volatile ECU_StateData *stateData); /** * @brief State handler for the GLV On state. @@ -33,7 +33,7 @@ void ECU_GLV_Off(ECU_StateData *stateData); * * @return void */ -void ECU_GLV_On(ECU_StateData *stateData); +void ECU_GLV_On(volatile ECU_StateData *stateData); /** * @brief State handler for the Precharge Engaged state. @@ -44,7 +44,7 @@ void ECU_GLV_On(ECU_StateData *stateData); * * @return void */ -void ECU_Precharge_Engaged(ECU_StateData *stateData); +void ECU_Precharge_Engaged(volatile ECU_StateData *stateData); /** * @brief State handler for the Precharge Complete state. @@ -55,7 +55,7 @@ void ECU_Precharge_Engaged(ECU_StateData *stateData); * * @return void */ -void ECU_Precharge_Complete(ECU_StateData *stateData); +void ECU_Precharge_Complete(volatile ECU_StateData *stateData); /** * @brief State handler for the Precharge Fault state. @@ -66,7 +66,19 @@ void ECU_Precharge_Complete(ECU_StateData *stateData); * * @return void */ -void ECU_Drive_Active(ECU_StateData *stateData); +void ECU_Drive_Active(volatile ECU_StateData *stateData); + +/** + * @brief Init function for ECU_Tractive_System_Discharge_Start. + * + * Resets Tractive System discharge timer and switches on the Tractive System + * Discharge state. + * + * @param stateData Pointer to the ECU state data structure. + * + * @return void + */ +void ECU_Tractive_System_Discharge_Start(volatile ECU_StateData *stateData); /** * @brief State handler for the Tractive System Discharge state. @@ -78,6 +90,6 @@ void ECU_Drive_Active(ECU_StateData *stateData); * * @return void */ -void ECU_Tractive_System_Discharge(ECU_StateData *stateData); +void ECU_Tractive_System_Discharge(volatile ECU_StateData *stateData); #endif diff --git a/ECU/Application/Inc/StateUtils.h b/ECU/Application/Inc/StateUtils.h index 7dcfeedf..b509a9a3 100644 --- a/ECU/Application/Inc/StateUtils.h +++ b/ECU/Application/Inc/StateUtils.h @@ -20,11 +20,11 @@ #define APPS_OFFSET 250.0f // TODO: Need to be experimentally determined // Checks stateData for critical errors -bool CriticalError(const ECU_StateData *stateData); -bool CommunicationError(const ECU_StateData *stateData); -bool APPS_BSE_Violation(const ECU_StateData *stateData); -bool PressingBrake(const ECU_StateData *stateData); -float CalcBrakePercent(const ECU_StateData *stateData); -float CalcPedalTravel(const ECU_StateData *stateData); +bool CriticalError(volatile const ECU_StateData *stateData); +bool CommunicationError(volatile const ECU_StateData *stateData); +bool APPS_BSE_Violation(volatile const ECU_StateData *stateData); +bool PressingBrake(volatile const ECU_StateData *stateData); +float CalcBrakePercent(volatile const ECU_StateData *stateData); +float CalcPedalTravel(volatile const ECU_StateData *stateData); #endif diff --git a/ECU/Application/Src/StateTicks.c b/ECU/Application/Src/StateTicks.c index a8cf0738..c075b17a 100644 --- a/ECU/Application/Src/StateTicks.c +++ b/ECU/Application/Src/StateTicks.c @@ -14,13 +14,21 @@ * * @remark Intentionally not a globally accessible variable */ -ECU_StateData stateLump = {0}; +volatile ECU_StateData stateLump = {0}; + +#define ECU_STATUS_MSG_PERIOD (100) +#define TRACTIVE_SYSTEM_MAX_DISCHARGE_TIME (10000) // TODO: determine an appropriate wait time void ECU_State_Tick(void) { - LOGOMATIC("ECU Current State: %d\n", stateLump.ecuStatus1.ecu_status); + if (stateLump.lastECUStatusMsgTick >= ECU_STATUS_MSG_PERIOD) { + LOGOMATIC("ECU Current State: %d\n", stateLump.ecu_state); + stateLump.lastECUStatusMsgTick = 0; + } else { + stateLump.lastECUStatusMsgTick++; + } - switch (stateLump.ecuStatus1.ecu_status) { + switch (stateLump.ecu_state) { case GR_GLV_OFF: ECU_GLV_Off(&stateLump); break; @@ -40,9 +48,9 @@ void ECU_State_Tick(void) ECU_Tractive_System_Discharge(&stateLump); break; default: - LOGOMATIC("ECU Current State Unknown: %d\n", stateLump.ecuStatus1.ecu_status); + LOGOMATIC("ECU Current State Unknown: %d\n", stateLump.ecu_state); LOGOMATIC("ECU: Resetting to GLV On\n"); - stateLump.ecuStatus1.ecu_status = GR_GLV_ON; + stateLump.ecu_state = GR_GLV_ON; break; } } @@ -54,52 +62,46 @@ transitioning state */ -void ECU_GLV_Off(ECU_StateData *stateData) +void ECU_GLV_Off(volatile ECU_StateData *stateData) { UNUSED(stateData); // TODO Implement functionality // ERROR --> GLV_OFF should never be reached } -void ECU_GLV_On(ECU_StateData *stateData) +void ECU_GLV_On(volatile ECU_StateData *stateData) { - UNUSED(stateData); - /* - if(stateData->TractiveSystemVoltage >= 60){ // should never happen but - has to be accounted for stateData->currentState = GR_TS_DISCHARGE; - emit an error - break; + if (stateData->ts_voltage >= 60) { // should never happen but has to be accounted for + ECU_Tractive_System_Discharge_Start(stateData); + // emit an error + return; } - */ // TODO Implement functionality if (stateData->ts_active_button_engaged) { - stateData->ecuStatus1.ecu_status = GR_PRECHARGE_ENGAGED; + stateData->ecu_state = GR_PRECHARGE_ENGAGED; } } -void ECU_Precharge_Engaged(ECU_StateData *stateData) +void ECU_Precharge_Engaged(volatile ECU_StateData *stateData) { - UNUSED(stateData); - if (stateData->ecuStatus2.ts_voltage > 60) { - // Go to TS discharge - stateData->ecuStatus1.ecu_status = GR_TS_DISCHARGE; - // Emit an error + if (stateData->ts_voltage >= 60) { + ECU_Tractive_System_Discharge_Start(stateData); + // emit an error return; } // TODO Implement functionality - /*if(not TS Active || Communication Error (CAN)){ - stateData->currentState = GR_TS_DISCHARGE - break; - }*/ + if (!stateData->ts_active_button_engaged || CommunicationError(stateData)) { + ECU_Tractive_System_Discharge_Start(stateData); + return; + } /*if(1 Isolation relay close && second isolation relay close){ --> CAN! stateData->currentState = GR_PRECHARGE_COMPLETE }*/ } -void ECU_Precharge_Complete(ECU_StateData *stateData) +void ECU_Precharge_Complete(volatile ECU_StateData *stateData) { - UNUSED(stateData); // TODO Implement functionality /* On but idle @@ -111,7 +113,7 @@ void ECU_Precharge_Complete(ECU_StateData *stateData) if (TS pressed or critical error) { stateData->currentState = GR_TS_DISCHARGE emit error - break; + return; } */ /* @@ -121,11 +123,19 @@ void ECU_Precharge_Complete(ECU_StateData *stateData) */ // Pseudocode + if (stateData->ts_active_button_engaged || CriticalError(stateData)) { + ECU_Tractive_System_Discharge_Start(stateData); + // emit an error + return; + } + + if (PressingBrake(stateData) && stateData->rtd_button_engaged) { + stateData->ecu_state = GR_DRIVE_ACTIVE; + } } -void ECU_Drive_Active(ECU_StateData *stateData) +void ECU_Drive_Active(volatile ECU_StateData *stateData) { - UNUSED(stateData); // TODO Implement functionality /* If APPS/BSE Violation --> Don't drive until resolved (no state @@ -151,21 +161,51 @@ void ECU_Drive_Active(ECU_StateData *stateData) - calcPedalTravel func :p - make tuna-ble function */ + + if (!stateData->ts_active_button_engaged || CriticalError(stateData)) { + ECU_Tractive_System_Discharge_Start(stateData); + return; + } + + if (!stateData->rtd_button_engaged) { + stateData->ecu_state = GR_PRECHARGE_COMPLETE; + // emit a warning if not moving + return; + } } -void ECU_Tractive_System_Discharge(ECU_StateData *stateData) +void ECU_Tractive_System_Discharge_Start(volatile ECU_StateData *stateData) +{ + stateData->ecu_state = GR_TS_DISCHARGE; + LOGOMATIC("tell the BCU to discharge TS"); + stateData->dischargeStartMillis = 0; +} + +void ECU_Tractive_System_Discharge(volatile ECU_StateData *stateData) { - UNUSED(stateData); // TODO Implement functionality of state itself /* Discharge the tractive system to below 60 volts If TS voltage < 60 --> stateData->GLV_ON */ - if (stateData->ecuStatus2.ts_voltage < 60) { - stateData->ecuStatus1.ecu_status = GR_GLV_ON; + // TODO: Discharge TC through CAN + LOGOMATIC("CAN: please discharge the Tractive System"); + if (stateData->ts_voltage < 60) { + stateData->ecu_state = GR_GLV_ON; + stateData->dischargeStartMillis = 0; + return; } /* If TS fails to discharge over time then stay and emit a warning, see #129 */ + // TODO: Determine the maximum time to wait for TC to discharge. + if (stateData->dischargeStartMillis > TRACTIVE_SYSTEM_MAX_DISCHARGE_TIME) { + // TODO: Research appropriate ways to buffer warning messages. + LOGOMATIC("Tractive System fails to discharge in time."); + } + + if (stateData->dischargeStartMillis < INT32_MAX) { + stateData->dischargeStartMillis++; + } } diff --git a/ECU/Application/Src/StateUtils.c b/ECU/Application/Src/StateUtils.c index 6e8b4604..a9dbd990 100644 --- a/ECU/Application/Src/StateUtils.c +++ b/ECU/Application/Src/StateUtils.c @@ -6,47 +6,66 @@ #include "StateData.h" #include "Unused.h" +// use estop_sense to detect close(?) void setSoftwareLatch(bool close) { UNUSED(close); // TODO Implement functionality // LOGOMATIC("Setting software latch to %d\n", close); /* - if (close && !HAL_GPIO_ReadPin(SOFTWARE_OK_CONTROL_GPIO_Port, + if (close && !HAL_GPIO_IsInputPinSet(SOFTWARE_OK_CONTROL_GPIO_Port, SOFTWARE_OK_CONTROL_Pin)) // Avoid writing pins that are already written too { HAL_GPIO_WritePin(SOFTWARE_OK_CONTROL_GPIO_Port, SOFTWARE_OK_CONTROL_Pin, GPIO_PIN_SET); } - else if (!close && HAL_GPIO_ReadPin(SOFTWARE_OK_CONTROL_GPIO_Port, + else if (!close && HAL_GPIO_IsInputPinSet(SOFTWARE_OK_CONTROL_GPIO_Port, SOFTWARE_OK_CONTROL_Pin)) { HAL_GPIO_WritePin(SOFTWARE_OK_CONTROL_GPIO_Port, SOFTWARE_OK_CONTROL_Pin, GPIO_PIN_RESET); } - */ +<<<<<<< HEAD + */ + /* + if (close && !LL_GPIO_IsInputPinSet(SOFTWARE_OK_CONTROL_GPIO_Port, + SOFTWARE_OK_CONTROL_Pin)) // Avoid writing pins that are already + written too + { + HAL_GPIO_WritePin(SOFTWARE_OK_CONTROL_GPIO_Port, + SOFTWARE_OK_CONTROL_Pin, GPIO_PIN_SET); + } + else if (!close && HAL_GPIO_IsInputPinSet(SOFTWARE_OK_CONTROL_GPIO_Port, + SOFTWARE_OK_CONTROL_Pin)) + { + HAL_GPIO_WritePin(SOFTWARE_OK_CONTROL_GPIO_Port, + SOFTWARE_OK_CONTROL_Pin, GPIO_PIN_RESET); + */ } -bool CriticalError(const ECU_StateData *stateData) +bool CriticalError(volatile const ECU_StateData *stateData) { - if (stateData->ecuStatus1.max_cell_temp > 60) { + if (stateData->max_cell_temp > 60) { + return true; + } + if (stateData->ts_voltage > 600) { return true; } - if (stateData->ecuStatus2.ts_voltage > 600) { + if (stateData->bse_apps_violation) { return true; } return false; } -bool CommunicationError(const ECU_StateData *stateData) +bool CommunicationError(volatile const ECU_StateData *stateData) { UNUSED(stateData); // TODO: implement COMMS errors return false; } -bool APPS_BSE_Violation(const ECU_StateData *stateData) +bool APPS_BSE_Violation(volatile const ECU_StateData *stateData) { // Checks 2 * APPS_1 is within 10% of APPS_2 and break + throttle at the // same time @@ -54,19 +73,19 @@ bool APPS_BSE_Violation(const ECU_StateData *stateData) (PressingBrake(stateData) && CalcPedalTravel(stateData) >= 0.25f); } -bool PressingBrake(const ECU_StateData *stateData) +bool PressingBrake(volatile const ECU_StateData *stateData) { return (stateData->Brake_F_Signal - BRAKE_F_MIN > BSE_DEADZONE * (BRAKE_F_MAX - BRAKE_F_MIN)) && (stateData->Brake_R_Signal - BRAKE_R_MIN > BSE_DEADZONE * (BRAKE_R_MAX - BRAKE_R_MIN)); // Ideally TCM receives values of 0 after this is no longer called xD. } -float CalcBrakePercent(const ECU_StateData *stateData) // THIS IS NOT ACTUALLY BRAKE TRAVEL, - // PRESSURE SENSORS CAPTURE BRAKE TRAVEL +float CalcBrakePercent(volatile const ECU_StateData *stateData) // THIS IS NOT ACTUALLY BRAKE TRAVEL, + // PRESSURE SENSORS CAPTURE BRAKE TRAVEL { return (float)(stateData->Brake_F_Signal + stateData->Brake_R_Signal - BRAKE_R_MIN - BRAKE_F_MIN) / (BRAKE_F_MAX - BRAKE_F_MIN + BRAKE_R_MAX - BRAKE_R_MIN); } -float CalcPedalTravel(const ECU_StateData *stateData) +float CalcPedalTravel(volatile const ECU_StateData *stateData) { return (float)(stateData->APPS1_Signal + stateData->APPS2_Signal - THROTTLE_MIN_2 - THROTTLE_MIN_1) / (THROTTLE_MAX_1 + THROTTLE_MAX_2 - THROTTLE_MIN_1 - THROTTLE_MIN_2); } diff --git a/ECU/CMakeLists.txt b/ECU/CMakeLists.txt index bf16105f..7c17f935 100644 --- a/ECU/CMakeLists.txt +++ b/ECU/CMakeLists.txt @@ -77,6 +77,7 @@ target_link_libraries( ${GR_PROJECT_NAME}_USER_CODE INTERFACE GR_OLD_CAN_MESSAGES + ADC ) target_include_directories( diff --git a/ECU/Core/Src/main.c b/ECU/Core/Src/main.c index 1897c985..15b48cf7 100644 --- a/ECU/Core/Src/main.c +++ b/ECU/Core/Src/main.c @@ -19,10 +19,14 @@ /* Includes ------------------------------------------------------------------*/ #include "main.h" +#include "StateData.h" +#include "StateTicks.h" #include "adc.h" #include "dma.h" #include "fdcan.h" #include "gpio.h" +#include "gr_adc.h" +#include "malloc.h" #include "usart.h" /* Private includes ----------------------------------------------------------*/ @@ -52,6 +56,58 @@ /* USER CODE END PV */ +/* +RELAVANT PORTS AND PINS + +-- ANALOG IN -- +ADC 1 (ADC_1 BUFFERS array is IN ORDER from top to bottom of this list) +BSE_SIGNAL (8): PC0 -> ADC12_IN6 (ADC 1 and ADC 2) +BSPD_SIGNAL (9): PC1 -> ADC12_IN7 +APPS1_SIGNAL (10): PC2 -> ADC12_IN8 +APPS2_SIGNAL (11): PC3 -> ADC12_IN9 +BRAKE_F_SIGNAL (24): PB0 -> ADC1_IN15 +BRAKE_R_SIGNAL (25): PB1 -> ADC1_IN12 +AUX_SIGNAL (36): PB14 -> ADC1_IN5 + + ADC 2 +STEERING_ANGLE_SIGNAL (37): PB15 -> ADC2_IN15 + +-- DIGITAL IN -- +BSPD_SENSE (19): PA5 +IMD_SENSE (20): PA6 +AMS_SENSE (21): PA7 +TS_ACTIVE_BTN_SENSE (54): PC12 +RTD_BTN_SENSE (53): PC11 +INERTIA_SW_SENSE (52): PC10 +ESTOP_SENSE (51): PA15 + +-- DIGITAL OUT -- +RTD_CONTROL (60): PB7 +TSSI_R_CONTROL (59): PB6 +TSSI_G_CONTROL (58): PB5 +BRAKE_CONTROL (57): PB4 +TS_ACTIVE_BTN_LED_CONTROL (43): PA9 +RTD_BTN_LED_CONTROL (42): PA8 +*/ + +// ADC 1/2 +#define WINDOW_SIZE 10 // weighted average for now can extend to other window functions +#define NUM_SIGNALS_ADC1 7 +#define NUM_SIGNALS_ADC2 1 +#define NUM_SIGNALS_DIGITAL 7 +// TODO: check which data size to use (floats...ints...etc) +volatile uint16_t ADC1_buffers[NUM_SIGNALS_ADC1] = {0}; // Contains new values +volatile uint16_t ADC2_buffers[NUM_SIGNALS_ADC2] = {0}; // Contains new values +uint16_t ADC1_outputs[NUM_SIGNALS_ADC1] = {0}; // Updated averages +uint16_t ADC2_outputs[NUM_SIGNALS_ADC2] = {0}; // Updated averages +uint16_t *adcDataValues[(NUM_SIGNALS_ADC1 + NUM_SIGNALS_ADC2)] = {0}; // 2D Array + +// DIGITAL +uint8_t digital_data[NUM_SIGNALS_DIGITAL] = {0}; + +// STATE DATA +extern volatile ECU_StateData stateLump; + /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ @@ -74,6 +130,108 @@ static void ITM_Enable(void) } /* USER CODE END 0 */ +// TODO: state data stores stuff as either FLOATS or BOOLS...check +void read_digital(void) +{ + for (int i = 0; i < NUM_SIGNALS_DIGITAL; i++) { + GPIO_PinState currRead; + if (i == 0) { + currRead = LL_GPIO_IsInputPinSet(GPIOA, LL_GPIO_PIN_5); + } else if (i == 1) { + currRead = LL_GPIO_IsInputPinSet(GPIOA, LL_GPIO_PIN_6); + } else if (i == 2) { + currRead = LL_GPIO_IsInputPinSet(GPIOA, LL_GPIO_PIN_7); + } else if (i == 3) { + currRead = LL_GPIO_IsInputPinSet(GPIOC, LL_GPIO_PIN_12); + } else if (i == 4) { + currRead = LL_GPIO_IsInputPinSet(GPIOC, LL_GPIO_PIN_11); + } else if (i == 5) { + currRead = LL_GPIO_IsInputPinSet(GPIOC, LL_GPIO_PIN_10); + } else if (i == 6) { + currRead = LL_GPIO_IsInputPinSet(GPIOA, LL_GPIO_PIN_15); + } + digital_data[i] = currRead; + } +} + +void write_state_data() +{ + // analog + // TODO: bse signal idk what to do ADC1_outputs[0] + // TODO: bspd signal idk what to do ADC1_outputs[1] + stateLump.APPS1_Signal = ADC1_outputs[2]; + stateLump.APPS2_Signal = ADC1_outputs[3]; + stateLump.Brake_F_Signal = ADC1_outputs[4]; + stateLump.Brake_R_Signal = ADC1_outputs[5]; + // TODO: Aux signal idk what to do with it ADC1_outputs[6] + stateLump.STEERING_ANGLE_SIGNAL = ADC2_outputs[0]; + + // digital + stateLump.bspd_sense = digital_data[0]; + stateLump.imd_sense = digital_data[1]; + stateLump.ams_sense = digital_data[2]; + stateLump.ts_active_button_engaged = digital_data[3]; + stateLump.rtd_button_engaged = digital_data[4]; + stateLump.bspd_sense = digital_data[5]; + // TODO: inertia steering wheel sense? digital_data[6] + stateLump.estop_sense = digital_data[7]; +} + +void ADC_Configure(void) +{ + // Initialize which clock source to use + LL_RCC_SetADCClockSource(LL_RCC_ADC12_CLKSOURCE_SYSCLK); + /* Peripheral clock enable */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC12); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + + // Initialize the ADC1 + ADC_Group_Init(ADC1, PS_8); // TODO: change prescalar l8r + ADC_Init(ADC1, RESOLUTION_12, RIGHT); + ADC_Regular_Group_Init(ADC1, NO_RANKS); + + // TODO: INITIALIZE PIN_PORTS BETTER!!! + // Initialize the pins and channels + Pin_Ports p1 = {0}; + p1.port = GPIOC; + p1.pin = LL_GPIO_PIN_0 | LL_GPIO_PIN_1 | LL_GPIO_PIN_2 | LL_GPIO_PIN_3; + ADC_Init_Pins(&p1); + Pin_Ports p2 = {0}; + p2.port = GPIOB; + p2.pin = LL_GPIO_PIN_0 | LL_GPIO_PIN_1 | LL_GPIO_PIN_14; + ADC_Init_Pins(&p2); + ADC_Channel_Init(ADC1, RANK_1, ADC_CHANNEL_6, SINGLE_ENDED, SAMPLINGTIME_247CYCLES_5); + ADC_Channel_Init(ADC1, RANK_2, ADC_CHANNEL_7, SINGLE_ENDED, SAMPLINGTIME_247CYCLES_5); + ADC_Channel_Init(ADC1, RANK_3, ADC_CHANNEL_8, SINGLE_ENDED, SAMPLINGTIME_247CYCLES_5); + ADC_Channel_Init(ADC1, RANK_4, ADC_CHANNEL_9, SINGLE_ENDED, SAMPLINGTIME_247CYCLES_5); + ADC_Channel_Init(ADC1, RANK_5, ADC_CHANNEL_15, SINGLE_ENDED, SAMPLINGTIME_247CYCLES_5); + ADC_Channel_Init(ADC1, RANK_6, ADC_CHANNEL_12, SINGLE_ENDED, SAMPLINGTIME_247CYCLES_5); + ADC_Channel_Init(ADC1, RANK_7, ADC_CHANNEL_5, SINGLE_ENDED, SAMPLINGTIME_247CYCLES_5); + + // Initialize ADC2 + ADC_Init(ADC2, RESOLUTION_12, RIGHT); + ADC_Regular_Group_Init(ADC2, NO_RANKS); + + // Initialize the pins and channels + Pin_Ports p3 = {0}; + p3.port = GPIOA; + p3.pin = LL_GPIO_PIN_15; + ADC_Init_Pins(&p3); + ADC_Channel_Init(ADC2, RANK_1, ADC_CHANNEL_15, SINGLE_ENDED, SAMPLINGTIME_247CYCLES_5); + + // Initialize DMA (ADC1 = CHANNEL 1, ADC2 = CHANNEL 2) + // DMA reads into buffer + DMA_Init(DMA1, LL_DMA_CHANNEL_1, LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA), (uint16_t)&ADC1_buffers, LL_DMA_PDATAALIGN_HALFWORD, LL_DMA_MDATAALIGN_HALFWORD, NUM_SIGNALS_ADC1, + ADC1, HIGH); + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); + DMA_Init(DMA1, LL_DMA_CHANNEL_2, LL_ADC_DMA_GetRegAddr(ADC2, LL_ADC_DMA_REG_REGULAR_DATA), (uint16_t)&ADC2_buffers, LL_DMA_PDATAALIGN_HALFWORD, LL_DMA_MDATAALIGN_HALFWORD, NUM_SIGNALS_ADC2, + ADC2, HIGH); + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2); + + ADC_Enable_And_Calibrate(ADC1); + ADC_Enable_And_Calibrate(ADC2); +} + /** * @brief The application entry point. * @retval int @@ -112,6 +270,10 @@ int main(void) MX_ADC2_Init(); MX_LPUART1_UART_Init(); /* USER CODE BEGIN 2 */ + ADC_Configure(); + for (int i = 0; i < (NUM_SIGNALS_ADC1 + NUM_SIGNALS_ADC2); i++) { + adcDataValues[i] = malloc(sizeof(uint16_t) * WINDOW_SIZE); + } /* USER CODE END 2 */ @@ -121,11 +283,18 @@ int main(void) /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ + read_digital(); + ADC_UpdateAnalogValues(adcDataValues, ADC1_buffers, NUM_SIGNALS_ADC1, WINDOW_SIZE, ADC1_outputs); + ADC_UpdateAnalogValues(adcDataValues, ADC2_buffers, NUM_SIGNALS_ADC2, WINDOW_SIZE, ADC2_outputs); + write_state_data(); ECU_State_Tick(); LOGOMATIC("Main Loop Tick Complete. I like Pi %f\n", 3.14159265); LL_mDelay(250); // FIXME Reduce or remove delay } /* USER CODE END 3 */ + for (int i = (NUM_SIGNALS_ADC1 + NUM_SIGNALS_ADC2) - 1; i >= 0; i--) { + free(adcDataValues[i]); + } } /** diff --git a/Lib/FancyLayers-RENAME/ADC/Src/gr_adc.c b/Lib/FancyLayers-RENAME/ADC/Src/gr_adc.c index 22eeaf29..db2a98ce 100644 --- a/Lib/FancyLayers-RENAME/ADC/Src/gr_adc.c +++ b/Lib/FancyLayers-RENAME/ADC/Src/gr_adc.c @@ -140,10 +140,10 @@ void DMA_Init(DMA_TypeDef *DMA, DMA_Channel channel, uint32_t src_address, uint3 // NOTE: DMA init is still using NOINCREMENT // TODO: Add int n to consider last n values -int num = 0; -uint8_t filled = 0; void ADC_UpdateAnalogValues(uint16_t **adcDataValues, volatile uint16_t *new_values, int num_signals, int window_size, uint16_t *weighted_output) { + static int num = 0; + static uint8_t filled = 0; for (int i = 0; i < num_signals; ++i) { weighted_output[i] += (new_values[i] - (filled ? adcDataValues[i][num] : 0)) / window_size; // Update the average adcDataValues[i][num] = new_values[i];