diff --git a/Core/Inc/control.h b/Core/Inc/control.h index 2127fc0f..4624523e 100644 --- a/Core/Inc/control.h +++ b/Core/Inc/control.h @@ -19,19 +19,6 @@ #define CONTROL_CANID_PUMP 0x4A0 #define CONTROL_CANID_RADFAN 0x499 -/* Tempeature Constants for Devices */ -#define PUMP_UPPER_MOTOR_TEMP 50 -#define PUMP_LOWER_MOTOR_TEMP 30 - -#define RADFAN_UPPER_MOTOR_TEMP 50 -#define RADFAN_LOWER_MOTOR_TEMP 30 - -#define PUMP_UPPER_CONTROLLER_TEMP 50 -#define PUMP_LOWER_CONTROLLER_TEMP 30 - -#define RADFAN_UPPER_CONTROLLER_TEMP 50 -#define RADFAN_LOWER_CONTROLLER_TEMP 30 - extern osThreadId_t control_handle; extern const osThreadAttr_t control_attributes; @@ -46,14 +33,30 @@ typedef enum { NUM_DEVICES, } device_type_t; +// sub-struct holding upper and lower temperature bounds. +typedef struct { + uint8_t upper_motor_temp_bound; + uint8_t lower_motor_temp_bound; +} device_temp_bounds_t; + +// struct holding the temperature bounds for a single device for each possible state. +typedef struct { + device_temp_bounds_t ready; + device_temp_bounds_t f_reverse; + device_temp_bounds_t f_pit; + device_temp_bounds_t f_performance; + device_temp_bounds_t f_efficiency; + device_temp_bounds_t faulted; + device_temp_bounds_t standard; +} device_config_t; + /* Holds all the information needed to determine and set the state of a device */ typedef struct { pdu_t *pdu; control_func_t control_func; /* function to set device state */ device_type_t device_type; /* Device Type (Pump or Radfan) */ nertimer_t timer; /* Debounce Timer */ - uint16_t upper_temp; /* Upper Tempature Limit */ - uint16_t lower_temp; /* Lower Tempature Limit */ + device_config_t temp_bounds; /* temperature bounds */ } device_control_t; /* Holds arguments for control thread */ diff --git a/Core/Src/control.c b/Core/Src/control.c index 014ca256..86b7cbc3 100644 --- a/Core/Src/control.c +++ b/Core/Src/control.c @@ -6,6 +6,72 @@ bool calypso_states[NUM_DEVICES]; +device_temp_bounds_t const pump0_READY = { 20, 10 }; +device_temp_bounds_t const pump0_F_REVERSE = { 20, 10 }; +device_temp_bounds_t const pump0_F_PIT = { 20, 10 }; +device_temp_bounds_t const pump0_F_PERFORMANCE = { 20, 10 }; +device_temp_bounds_t const pump0_F_EFFICIENCY = { 20, 10 }; +device_temp_bounds_t const pump0_FAULTED = { 20, 10 }; +device_temp_bounds_t const pump0_STANDARD = { 20, 10 }; + +device_temp_bounds_t const pump1_READY = { 20, 10 }; +device_temp_bounds_t const pump1_F_REVERSE = { 20, 10 }; +device_temp_bounds_t const pump1_F_PIT = { 20, 10 }; +device_temp_bounds_t const pump1_F_PERFORMANCE = { 20, 10 }; +device_temp_bounds_t const pump1_F_EFFICIENCY = { 20, 10 }; +device_temp_bounds_t const pump1_FAULTED = { 20, 10 }; +device_temp_bounds_t const pump1_STANDARD = { 20, 10 }; + +device_temp_bounds_t const radfan0_READY = { 20, 10 }; +device_temp_bounds_t const radfan0_F_REVERSE = { 20, 10 }; +device_temp_bounds_t const radfan0_F_PIT = { 20, 10 }; +device_temp_bounds_t const radfan0_F_PERFORMANCE = { 20, 10 }; +device_temp_bounds_t const radfan0_F_EFFICIENCY = { 20, 10 }; +device_temp_bounds_t const radfan0_FAULTED = { 20, 10 }; +device_temp_bounds_t const radfan0_STANDARD = { 20, 10 }; + +device_temp_bounds_t const radfan1_READY = { 20, 10 }; +device_temp_bounds_t const radfan1_F_REVERSE = { 20, 10 }; +device_temp_bounds_t const radfan1_F_PIT = { 20, 10 }; +device_temp_bounds_t const radfan1_F_PERFORMANCE = { 20, 10 }; +device_temp_bounds_t const radfan1_F_EFFICIENCY = { 20, 10 }; +device_temp_bounds_t const radfan1_FAULTED = { 20, 10 }; +device_temp_bounds_t const radfan1_STANDARD = { 20, 10 }; + +device_temp_bounds_t const fanBattBox_READY = { 20, 10 }; +device_temp_bounds_t const fanBattBox_F_REVERSE = { 20, 10 }; +device_temp_bounds_t const fanBattBox_F_PIT = { 20, 10 }; +device_temp_bounds_t const fanBattBox_F_PERFORMANCE = { 20, 10 }; +device_temp_bounds_t const fanBattBox_F_EFFICIENCY = { 20, 10 }; +device_temp_bounds_t const fanBattBox_FAULTED = { 20, 10 }; +device_temp_bounds_t const fanBattBox_STANDARD = { 20, 10 }; + +device_config_t pump0_config = { pump0_READY, pump0_F_REVERSE, + pump0_F_PIT, pump0_F_PERFORMANCE, + pump0_F_EFFICIENCY, pump0_FAULTED, + pump0_STANDARD }; + +device_config_t pump1_config = { pump1_READY, pump1_F_REVERSE, + pump1_F_PIT, pump1_F_PERFORMANCE, + pump1_F_EFFICIENCY, pump1_FAULTED, + pump1_STANDARD }; + +device_config_t radfan0_config = { radfan0_READY, radfan0_F_REVERSE, + radfan0_F_PIT, radfan0_F_PERFORMANCE, + radfan0_F_EFFICIENCY, radfan0_FAULTED, + radfan0_STANDARD }; + +device_config_t radfan1_config = { radfan1_READY, radfan1_F_REVERSE, + radfan1_F_PIT, radfan1_F_PERFORMANCE, + radfan1_F_EFFICIENCY, radfan1_FAULTED, + radfan1_STANDARD }; + +device_config_t fanBattBox_config = { + fanBattBox_READY, fanBattBox_F_REVERSE, fanBattBox_F_PIT, + fanBattBox_F_PERFORMANCE, fanBattBox_F_EFFICIENCY, fanBattBox_FAULTED, + fanBattBox_STANDARD +}; + osThreadId_t control_handle; const osThreadAttr_t control_attributes = { .name = "Control", @@ -18,13 +84,35 @@ static void set_device_on(void *params) { device_control_t *device = (device_control_t *)params; device->control_func(device->pdu, true); -} +}; // callback function to turn device off after debounce static void set_device_off(void *params) { device_control_t *device = (device_control_t *)params; device->control_func(device->pdu, false); +}; + +/** + * @brief Sets the device state dependent on current car state and temperature. + * + * @param device Device whose state is being determined. + * @param device_bounds Temperature bounds of the device for the current car state. + * @param temp Temperature reading to determine the state. + */ +static void set_device_state(device_control_t *device, + device_temp_bounds_t device_bounds, uint16_t temp) +{ + bool above_max_temp = temp > device_bounds.upper_motor_temp_bound; + bool below_min_temp = temp < device_bounds.lower_motor_temp_bound; + + if (above_max_temp) { + debounce(above_max_temp, &(device->timer), 10000, set_device_on, + device); + } else if (below_min_temp || is_timer_active(&device->timer)) { + debounce(below_min_temp, &(device->timer), 10000, + set_device_off, device); + } } /** @@ -56,16 +144,30 @@ static void control_device(device_control_t *device, uint16_t temp) return; } - // set device state based on temps with debounce - if (temp > device->upper_temp || temp < device->lower_temp || - is_timer_active(&device->timer)) { - if (temp > device->upper_temp) { - debounce(temp > device->upper_temp, &(device->timer), - 10000, set_device_on, device); - } else { - debounce(temp < device->lower_temp, &(device->timer), - 10000, set_device_off, device); - } + const curr_state = get_func_state(); + + // Set device state depending on car state and temperature. + switch (curr_state) { + case READY: + set_device_state(device, device->temp_bounds.ready, temp); + break; + case F_PIT: + set_device_state(device, device->temp_bounds.f_pit, temp); + break; + case F_REVERSE: + set_device_state(device, device->temp_bounds.f_reverse, temp); + break; + case F_PERFORMANCE: + set_device_state(device, device->temp_bounds.f_performance, + temp); + break; + case F_EFFICIENCY: + set_device_state(device, device->temp_bounds.f_efficiency, + temp); + break; + case FAULTED: + set_device_state(device, device->temp_bounds.faulted, temp); + break; } } @@ -82,32 +184,28 @@ void vControl(void *params) device_control_t pump0 = { .pdu = pdu, .control_func = write_pump_0, - .upper_temp = PUMP_UPPER_MOTOR_TEMP, - .lower_temp = PUMP_LOWER_MOTOR_TEMP, + .temp_bounds = pump0_config, .device_type = DEVICE_PUMP0, }; device_control_t radfan0 = { .pdu = pdu, .control_func = write_radfan_0, - .upper_temp = RADFAN_UPPER_MOTOR_TEMP, - .lower_temp = RADFAN_LOWER_MOTOR_TEMP, + .temp_bounds = radfan0_config, .device_type = DEVICE_RADFAN0, }; device_control_t pump1 = { .pdu = pdu, .control_func = write_pump_1, - .upper_temp = PUMP_UPPER_CONTROLLER_TEMP, - .lower_temp = PUMP_LOWER_CONTROLLER_TEMP, + .temp_bounds = pump1_config, .device_type = DEVICE_PUMP1, }; device_control_t radfan1 = { .pdu = pdu, .control_func = write_radfan_1, - .upper_temp = RADFAN_UPPER_CONTROLLER_TEMP, - .lower_temp = RADFAN_LOWER_CONTROLLER_TEMP, + .temp_bounds = radfan1_config, .device_type = DEVICE_RADFAN1, };