From 60caf6a08d8ff44ccf67c8eb5f8158d593ddc56e Mon Sep 17 00:00:00 2001 From: AmirTajaddodi Date: Fri, 3 Oct 2025 22:23:39 -0700 Subject: [PATCH 01/12] abstraction for efuse --- firmware/quintuna/VC/CMakeLists.txt | 2 +- .../quintuna/VC/src/app/app_loadswitches.c | 2 + firmware/quintuna/VC/src/io/io_loadswitches.c | 1 + firmware/shared/src/io/io_efuse/io_efuse.c | 54 +++++++++++ firmware/shared/src/io/io_efuse/io_efuse.h | 66 +++++++++++++ .../src/io/io_efuse/io_efuse_ST/io_efuse_ST.c | 53 ++++++++++ .../src/io/io_efuse/io_efuse_ST/io_efuse_ST.h | 27 ++++++ .../src/io/io_efuse/io_efuse_TI/io_efuse_TI.c | 53 ++++++++++ .../src/io/io_efuse/io_efuse_TI/io_efuse_TI.h | 20 ++++ .../src/io/io_efuse/io_efuse_datatypes.h | 33 +++++++ firmware/shared/src/io/io_loadswitch.c | 53 ---------- firmware/shared/src/io/io_loadswitch.h | 96 ------------------- 12 files changed, 310 insertions(+), 150 deletions(-) create mode 100644 firmware/shared/src/io/io_efuse/io_efuse.c create mode 100644 firmware/shared/src/io/io_efuse/io_efuse.h create mode 100644 firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c create mode 100644 firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h create mode 100644 firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c create mode 100644 firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h create mode 100644 firmware/shared/src/io/io_efuse/io_efuse_datatypes.h delete mode 100644 firmware/shared/src/io/io_loadswitch.c delete mode 100644 firmware/shared/src/io/io_loadswitch.h diff --git a/firmware/quintuna/VC/CMakeLists.txt b/firmware/quintuna/VC/CMakeLists.txt index 377cde7634..d43128b0d0 100644 --- a/firmware/quintuna/VC/CMakeLists.txt +++ b/firmware/quintuna/VC/CMakeLists.txt @@ -28,7 +28,7 @@ list(APPEND IO_SRCS "${SHARED_IO_INCLUDE_DIR}/io_canLogging.c" "${SHARED_IO_INCLUDE_DIR}/io_led.c" "${SHARED_IO_INCLUDE_DIR}/io_time.c" - "${SHARED_IO_INCLUDE_DIR}/io_loadswitch.c" + "${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse.c" "${SHARED_IO_INCLUDE_DIR}/io_potentiometer.c" "${SHARED_IO_INCLUDE_DIR}/io_bootHandler.c" "${SHARED_IO_INCLUDE_DIR}/io_imu.c" diff --git a/firmware/quintuna/VC/src/app/app_loadswitches.c b/firmware/quintuna/VC/src/app/app_loadswitches.c index 4b290b6b9a..adccfa94e5 100644 --- a/firmware/quintuna/VC/src/app/app_loadswitches.c +++ b/firmware/quintuna/VC/src/app/app_loadswitches.c @@ -44,3 +44,5 @@ void app_efuse_broadcast(void) efuse_current_can_setters[efuse](current); } } + +void app_loadswitch_enableFa diff --git a/firmware/quintuna/VC/src/io/io_loadswitches.c b/firmware/quintuna/VC/src/io/io_loadswitches.c index 4eee59564f..fe442dee60 100644 --- a/firmware/quintuna/VC/src/io/io_loadswitches.c +++ b/firmware/quintuna/VC/src/io/io_loadswitches.c @@ -33,3 +33,4 @@ const Efuse *const efuse_channels[NUM_EFUSE_CHANNELS] = { [EFUSE_CHANNEL_DAM] = &dam_efuse, [EFUSE_CHANNEL_FRONT] = &front_efuse, [EFUSE_CHANNEL_RL_PUMP] = &rl_pump_efuse, [EFUSE_CHANNEL_R_RAD] = &r_rad_fan_efuse }; +z` \ No newline at end of file diff --git a/firmware/shared/src/io/io_efuse/io_efuse.c b/firmware/shared/src/io/io_efuse/io_efuse.c new file mode 100644 index 0000000000..f5e5453e49 --- /dev/null +++ b/firmware/shared/src/io/io_efuse/io_efuse.c @@ -0,0 +1,54 @@ +#include "io_efuse.h" +#include "hw_gpio.h" +#include +#include + +void io_efuse_setChannel(const Efuse *channel, const bool enabled) +{ + assert(channel != NULL); + + channel->efuse_functions->set_channel(channel, enabled); +} + +bool io_efuse_isChannelEnabled(const Efuse *channel) +{ + assert(channel->enable_gpio != NULL); + return chann; +} + +float io_efuse_getChannelCurrent(const Efuse *channel) +{ + const AdcChannel *current_sense = channel->sns_adc_channel; + assert(current_sense != NULL); + return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; +} + +void io_STefuse_reset_set(const ST_efuse *efuse, const bool set) +{ + assert(efuse->stby_reset_gpio != NULL); + hw_gpio_writePin(efuse->stby_reset_gpio, set); +} + +void io_STefuse_Reset(const ST_efuse *efuse) +{ + assert(efuse->stby_reset_gpio != NULL); + hw_gpio_writePin(efuse->stby_reset_gpio, false); + hw_gpio_writePin(efuse->stby_reset_gpio, true); + hw_gpio_writePin(efuse->stby_reset_gpio, false); +} + +void io_TIefuse_Reset(const TI_efuse *efuse) +{ + assert(efuse->efuse != NULL); + assert(efuse->efuse->enable_gpio != NULL); + + hw_gpio_writePin(efuse->efuse->enable_gpio, false); + hw_gpio_writePin(efuse->efuse->enable_gpio, true); + hw_gpio_writePin(efuse->efuse->enable_gpio, false); +} + +bool io_TIefuse_pgood(const TI_efuse *efuse) +{ + assert(efuse->pgood != NULL); + return hw_gpio_readPin(efuse->pgood); +} diff --git a/firmware/shared/src/io/io_efuse/io_efuse.h b/firmware/shared/src/io/io_efuse/io_efuse.h new file mode 100644 index 0000000000..411f3aaa55 --- /dev/null +++ b/firmware/shared/src/io/io_efuse/io_efuse.h @@ -0,0 +1,66 @@ +#pragma once + +#include + +#define ADC_VOLTAGE_TO_CURRENT_A 1.720f + +#ifndef TARGET_EMBEDDED +typedef struct +{ + bool enabled; + float current; + bool simulate_fault; +} Efuse; +typedef struct +{ + const Efuse *efuse; + bool pgood; +} TI_efuse; +typedef struct +{ + const Efuse *efuse1; + const Efuse *efuse2; + + bool pgood; + bool set_stby_reset_gpio; +} ST_efuse; +#endif + +/** + * Enable or disable the provided efuse channel. + * @param channel Channel to enable/disable + * @param enabled Enable if enabled is true, disable if false + */ +void io_efuse_setChannel(const Efuse *channel, bool enabled); +/** + * Check of provided efuse channel is enabled + * @param channel Channel to enable/disable + * @return If efuse channel is enabled + */ +bool io_efuse_isChannelEnabled(const Efuse *channel); +/** + * Get the current read from the provided channel + * @param channel Channel to enable/disable + * @return The current read from the provided channel, in A + */ +float io_efuse_getChannelCurrent(const Efuse *channel); + +/** + * @param efuse + * @param set + */ +void io_efuse_reset_set(const ST_efuse *efuse, bool set); + +/** + * Reset the hardfault set by the efuse + * @param efuse Reset the hardfault set by efuse + */ +void io_efuse_Reset(const ST_efuse *efuse); + + +/** + * TI efuse pgood line status + * @param efuse TI efuse in question + * @return status of the pgood line + */ +bool io_TIefuse_pgood(const TI_efuse *efuse); \ No newline at end of file diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c new file mode 100644 index 0000000000..ae8272605b --- /dev/null +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c @@ -0,0 +1,53 @@ +#include "io_efuse_ST.h" +#include "hw_gpio.h" +#include +#include + + +static void io_efuseST_setChannel(const Efuse *channel, const bool enabled); +static bool io_efuseST_isChannelEnabled(const Efuse *channel); +static float io_efuseST_getChannelCurrent(const Efuse *channel); +static void io_efuseST_reset_set(const Efuse *channel, const bool set); +static void io_efuseST_Reset(const Efuse *channel); + + +const EfuseFunctons st_efuse_functions = { + .set_channel = io_efuseST_setChannel, + .is_channel_enabled = io_efuseST_isChannelEnabled, + .get_channel_current = io_efuseST_getChannelCurrent, + .loadswitch_reset_set = io_efuseST_reset_set, + .reset_efuse = io_efuseST_Reset +}; + +static void io_efuseST_setChannel(const Efuse *channel, const bool enabled) +{ + assert(channel->enable_gpio != NULL); + hw_gpio_writePin(channel->enable_gpio, enabled); +} + +static bool io_efuseST_isChannelEnabled(const Efuse *channel) +{ + assert(channel->enable_gpio != NULL); + return hw_gpio_readPin(channel->enable_gpio); +} + +static float io_efuseST_getChannelCurrent(const Efuse *channel) +{ + const AdcChannel *current_sense = channel->sns_adc_channel; + assert(current_sense != NULL); + return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; +} + +static void io_efuseST_reset_set(const Efuse *channel, const bool set) +{ + assert(channel->st->stby_reset_gpio != NULL); + hw_gpio_writePin(channel->st->stby_reset_gpio, set); +} + +static void io_efuseST_Reset(const Efuse *channel) +{ + assert(channel->st->stby_reset_gpio != NULL); + hw_gpio_writePin(channel->st->stby_reset_gpio, false); + hw_gpio_writePin(channel->st->stby_reset_gpio, true); + hw_gpio_writePin(channel->st->stby_reset_gpio, false); +} \ No newline at end of file diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h new file mode 100644 index 0000000000..64f98450e8 --- /dev/null +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include "hw_gpio.h" +#include "hw_adc.h" +#include "io_efuse_datatypes.h" + +/* Forward declarations for types you use here */ + +typedef struct ST_Efuse +{ + const Gpio *stby_reset_gpio; + + /* Portable bit-fields: use 'unsigned' and name the subgroup */ + struct { + uint8_t overload : 1; + uint8_t ovt_stp : 1; + uint8_t under_voltage : 1; + uint8_t short_to_vbat : 1; + uint8_t open_load_off_stat : 1; + uint8_t negative_output_voltage_clamp : 1; + } faults; +}ST_Efuse; + +extern const EfuseFunctons st_efuse_functions; + diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c new file mode 100644 index 0000000000..ec69b477d2 --- /dev/null +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c @@ -0,0 +1,53 @@ +#include "io_efuse_TI.h" +#include "hw_gpio.h" +#include +#include + +static void io_TI_efuse_setChannel(const Efuse *channel, const bool enabled); +static bool io_TI_efuse_isChannelEnabled(const Efuse *channel); +static float io_TI_efuse_getChannelCurrent(const Efuse *channel); +static void io_TI_efuse_Reset(const Efuse *efuse); +static bool io_TI_efuse_pgood(const Efuse *efuse); + +const TI_EfuseFunctons ti_efuse_functions = { + .set_channel = io_TI_efuse_setChannel, + .is_channel_enabled = io_TI_efuse_isChannelEnabled, + .get_channel_current = io_TI_efuse_getChannelCurrent, + .loadswitch_reset_set = NULL + .reset_efuse = io_TI_efuse_Reset, +}; + +static void io_TI_efuse_setChannel(const Efuse *channel, const bool enabled) +{ + assert(channel->enable_gpio != NULL); + hw_gpio_writePin(channel->enable_gpio, enabled); +} + +static bool io_TI_efuse_isChannelEnabled(const Efuse *channel) +{ + assert(channel->enable_gpio != NULL); + return hw_gpio_readPin(channel->enable_gpio); +} + +static float io_TI_efuse_getChannelCurrent(const Efuse *channel) +{ + const AdcChannel *current_sense = channel->sns_adc_channel; + assert(current_sense != NULL); + return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; +} + +static void io_TI_efuse_Reset(const Efuse *efuse) +{ + assert(efuse->efuse != NULL); + assert(efuse->efuse->enable_gpio != NULL); + + hw_gpio_writePin(efuse->efuse->enable_gpio, false); + hw_gpio_writePin(efuse->efuse->enable_gpio, true); + hw_gpio_writePin(efuse->efuse->enable_gpio, false); +} + +static bool io_TI_efuse_pgood(const Efuse *efuse) +{ + assert(efuse->pgood != NULL); + return hw_gpio_readPin(efuse->pgood); +} diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h new file mode 100644 index 0000000000..34806d28b7 --- /dev/null +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include "hw_gpio.h" +#include "hw_adc.h" +#include "io_efuse_datatypes.h" + + +/* Forward declarations for types you use here */ +typedef EfuseFunctons EfuseFunctons; + +typedef struct ST_Efuse +{ + const Gpio *pgood; +}TI_Efuse; + + +extern const EfuseFunctons ti_efuse_functions; + diff --git a/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h new file mode 100644 index 0000000000..073a3675ba --- /dev/null +++ b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h @@ -0,0 +1,33 @@ +#pragma once + +#ifdef TARGET_EMBEDDED +#include "hw_gpio.h" +#include "hw_adc.h" +#include "io_efuse_ST.h" +#include "io_efuse_TI.h" + +#define ADC_VOLTAGE_TO_CURRENT_A 1.720f + +typedef struct{ + + void (*set_channel)(Efuse *channel, bool enabled); + bool (*is_channel_enabled)(const Efuse *channel); + bool (*get_channel_current)(const Efuse *channel); + void (*loadswitch_reset_set) (const Efuse *channel, const bool set); + void (*reset_efuse) (const Efuse *channel); + +} EfuseFunctons; + +typedef struct { + + const Gpio *enable_gpio; + const AdcChannel *sns_adc_channel; + union + { + ST_Efuse st; + TI_Efuse ti; + }; + + EfuseFunctons *efuse_functions; +}Efuse; +#endif \ No newline at end of file diff --git a/firmware/shared/src/io/io_loadswitch.c b/firmware/shared/src/io/io_loadswitch.c deleted file mode 100644 index 620de3f2ad..0000000000 --- a/firmware/shared/src/io/io_loadswitch.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "io_loadswitch.h" -#include "hw_gpio.h" -#include -#include - -void io_loadswitch_setChannel(const Efuse *channel, const bool enabled) -{ - assert(channel->enable_gpio != NULL); - hw_gpio_writePin(channel->enable_gpio, enabled); -} - -bool io_loadswitch_isChannelEnabled(const Efuse *channel) -{ - assert(channel->enable_gpio != NULL); - return hw_gpio_readPin(channel->enable_gpio); -} - -float io_loadswitch_getChannelCurrent(const Efuse *channel) -{ - const AdcChannel *current_sense = channel->sns_adc_channel; - assert(current_sense != NULL); - return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; -} - -void io_STloadswitch_reset_set(const ST_LoadSwitch *loadswitch, const bool set) -{ - assert(loadswitch->stby_reset_gpio != NULL); - hw_gpio_writePin(loadswitch->stby_reset_gpio, set); -} - -void io_STloadswitch_Reset(const ST_LoadSwitch *loadswitch) -{ - assert(loadswitch->stby_reset_gpio != NULL); - hw_gpio_writePin(loadswitch->stby_reset_gpio, false); - hw_gpio_writePin(loadswitch->stby_reset_gpio, true); - hw_gpio_writePin(loadswitch->stby_reset_gpio, false); -} - -void io_TILoadswitch_Reset(const TI_LoadSwitch *loadSwitch) -{ - assert(loadSwitch->efuse != NULL); - assert(loadSwitch->efuse->enable_gpio != NULL); - - hw_gpio_writePin(loadSwitch->efuse->enable_gpio, false); - hw_gpio_writePin(loadSwitch->efuse->enable_gpio, true); - hw_gpio_writePin(loadSwitch->efuse->enable_gpio, false); -} - -bool io_TILoadswitch_pgood(const TI_LoadSwitch *loadSwitch) -{ - assert(loadSwitch->pgood != NULL); - return hw_gpio_readPin(loadSwitch->pgood); -} diff --git a/firmware/shared/src/io/io_loadswitch.h b/firmware/shared/src/io/io_loadswitch.h deleted file mode 100644 index 2623a67088..0000000000 --- a/firmware/shared/src/io/io_loadswitch.h +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once - -#include "io_loadswitch.h" -#include - -#define ADC_VOLTAGE_TO_CURRENT_A 1.720f - -#ifdef TARGET_EMBEDDED -#include "hw_gpios.h" -#include "hw_adcs.h" - -#define ADC_VOLTAGE_TO_CURRENT_A 1.720f - -typedef struct -{ - const Gpio *enable_gpio; - const AdcChannel *sns_adc_channel; -} Efuse; - -typedef struct -{ - const Efuse *efuse1; - const Efuse *efuse2; - const Gpio *stby_reset_gpio; -} ST_LoadSwitch; - -typedef struct -{ - const Efuse *efuse; - const Gpio *pgood; -} TI_LoadSwitch; -#else -typedef struct -{ - bool enabled; - float current; - bool simulate_fault; -} Efuse; -typedef struct -{ - const Efuse *efuse; - bool pgood; -} TI_LoadSwitch; -typedef struct -{ - const Efuse *efuse1; - const Efuse *efuse2; - - bool pgood; - bool set_stby_reset_gpio; -} ST_LoadSwitch; -#endif - -/** - * Enable or disable the provided loadswitch channel. - * @param channel Channel to enable/disable - * @param enabled Enable if enabled is true, disable if false - */ -void io_loadswitch_setChannel(const Efuse *channel, bool enabled); -/** - * Check of provided loadswitch channel is enabled - * @param channel Channel to enable/disable - * @return If loadswitch channel is enabled - */ -bool io_loadswitch_isChannelEnabled(const Efuse *channel); -/** - * Get the current read from the provided channel - * @param channel Channel to enable/disable - * @return The current read from the provided channel, in A - */ -float io_loadswitch_getChannelCurrent(const Efuse *channel); - -/** - * @param loadswitch - * @param set - */ -void io_STloadswitch_reset_set(const ST_LoadSwitch *loadswitch, bool set); - -/** - * Reset the hardfault set by the loadswitch - * @param loadswitch Reset the hardfault set by loadswitch - */ -void io_STloadswitch_Reset(const ST_LoadSwitch *loadswitch); - -/** - * Check if pgood is ok and if not reset the loadswitch - * @param loadswitch Reset the hardfault set by loadswitch - */ -void io_TILoadswitch_Reset(const TI_LoadSwitch *loadSwitch); - -/** - * TI Loadswitch pgood line status - * @param loadSwitch TI Loadswitch in question - * @return status of the pgood line - */ -bool io_TILoadswitch_pgood(const TI_LoadSwitch *loadSwitch); \ No newline at end of file From 48ec46acfb3506d20ffd7a308d4ea0331330ef00 Mon Sep 17 00:00:00 2001 From: AmirTajaddodi Date: Sat, 4 Oct 2025 13:31:39 -0700 Subject: [PATCH 02/12] more efuse changes --- .vscode/settings.json | 9 +- firmware/boot/bootloader.h | 10 +-- firmware/quintuna/VC/CMakeLists.txt | 4 +- .../quintuna/VC/src/app/app_loadswitches.c | 7 +- .../quintuna/VC/src/app/app_loadswitches.h | 2 +- .../quintuna/VC/src/app/app_powerManager.c | 87 +++---------------- .../quintuna/VC/src/app/app_powerManager.h | 2 +- .../quintuna/VC/src/app/app_pumpControl.c | 6 +- firmware/quintuna/VC/src/io/io_efuses.c | 35 ++++++++ firmware/quintuna/VC/src/io/io_efuses.h | 28 ++++++ firmware/quintuna/VC/src/io/io_loadswitches.c | 36 -------- firmware/quintuna/VC/src/io/io_loadswitches.h | 46 ---------- firmware/shared/src/io/io_efuse/io_efuse.c | 39 +++------ firmware/shared/src/io/io_efuse/io_efuse.h | 15 ++-- .../src/io/io_efuse/io_efuse_ST/io_efuse_ST.c | 38 ++++---- .../src/io/io_efuse/io_efuse_ST/io_efuse_ST.h | 26 +++--- .../src/io/io_efuse/io_efuse_TI/io_efuse_TI.c | 35 ++++---- .../src/io/io_efuse/io_efuse_TI/io_efuse_TI.h | 14 +-- .../src/io/io_efuse/io_efuse_datatypes.h | 30 ++++--- 19 files changed, 180 insertions(+), 289 deletions(-) create mode 100644 firmware/quintuna/VC/src/io/io_efuses.c create mode 100644 firmware/quintuna/VC/src/io/io_efuses.h delete mode 100644 firmware/quintuna/VC/src/io/io_loadswitches.c delete mode 100644 firmware/quintuna/VC/src/io/io_loadswitches.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 6e02378205..d69c895613 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,5 +11,12 @@ "--compile-commands-dir=build_fw_dev", // "--compile-commands-dir=build_fw_test", "--query-driver=/usr/local/bin/arm-none-eabi-gcc" - ] + ], + "files.associations": { + "bootloader_VC.C": "cpp", + "io_efuse.h": "c", + "io_efuse_st.h": "c", + "io_efuse_datatypes.h": "c", + "io_efuse_ti.h": "c" + } } diff --git a/firmware/boot/bootloader.h b/firmware/boot/bootloader.h index 02a6645a7f..c2fe65d715 100644 --- a/firmware/boot/bootloader.h +++ b/firmware/boot/bootloader.h @@ -15,11 +15,11 @@ #define APP_VALIDITY_ID_LOWBITS (0x8) #define GO_TO_BOOT (0x9) -void bootloader_preInit(void); -void bootloader_init(void); -_Noreturn void bootloader_runInterfaceTask(void); -_Noreturn void bootloader_runTickTask(void); -_Noreturn void bootloader_runCanTxTask(void); +void bootloader_preInit(void); +void bootloader_init(void); +void bootloader_runInterfaceTask(void); +void bootloader_runTickTask(void); +void bootloader_runCanTxTask(void); void bootloader_boardSpecific_init(void); void bootloader_boardSpecific_tick(void); diff --git a/firmware/quintuna/VC/CMakeLists.txt b/firmware/quintuna/VC/CMakeLists.txt index d43128b0d0..be442f936a 100644 --- a/firmware/quintuna/VC/CMakeLists.txt +++ b/firmware/quintuna/VC/CMakeLists.txt @@ -29,11 +29,13 @@ list(APPEND IO_SRCS "${SHARED_IO_INCLUDE_DIR}/io_led.c" "${SHARED_IO_INCLUDE_DIR}/io_time.c" "${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse.c" + "${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_ST/io_efuse_ST.c" + "${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_TI/io_efuse_TI.c" "${SHARED_IO_INCLUDE_DIR}/io_potentiometer.c" "${SHARED_IO_INCLUDE_DIR}/io_bootHandler.c" "${SHARED_IO_INCLUDE_DIR}/io_imu.c" ) -set(IO_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src/io" "${SHARED_IO_INCLUDE_DIR}" "${SHARED_IO_INCLUDE_QUINTUNA_DIR}") +set(IO_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src/io" "${CMAKE_CURRENT_SOURCE_DIR}/src/io/io_efuse" "${CMAKE_CURRENT_SOURCE_DIR}/src/io/io_efuse/io_efuse_TI" "${CMAKE_CURRENT_SOURCE_DIR}/src/io/io_efuse/io_efuse_ST" "${SHARED_IO_INCLUDE_DIR}" "${SHARED_IO_INCLUDE_QUINTUNA_DIR}") file(GLOB_RECURSE HW_SRCS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/hw/*.c") list(APPEND HW_SRCS diff --git a/firmware/quintuna/VC/src/app/app_loadswitches.c b/firmware/quintuna/VC/src/app/app_loadswitches.c index adccfa94e5..2e76a22467 100644 --- a/firmware/quintuna/VC/src/app/app_loadswitches.c +++ b/firmware/quintuna/VC/src/app/app_loadswitches.c @@ -4,9 +4,8 @@ #include #include -#include "io_loadswitch.h" #include "app_canTx.h" -#include "io_loadswitches.h" +#include "io_efuses.h" static void (*const efuse_enabled_can_setters[NUM_EFUSE_CHANNELS])(bool) = { [EFUSE_CHANNEL_F_INV] = app_canTx_VC_FrontInvertersStatus_set, @@ -35,8 +34,8 @@ void app_efuse_broadcast(void) // run through each efuse, and broadcast the channel status and current for (int efuse = 0; efuse < NUM_EFUSE_CHANNELS; efuse += 1) { - const bool enabled = io_loadswitch_isChannelEnabled(efuse_channels[efuse]); - const float current = io_loadswitch_getChannelCurrent(efuse_channels[efuse]); + const bool enabled = io_efuse_isChannelEnabled(efuse_channels[efuse]); + const float current = io_efuse_getChannelCurrent(efuse_channels[efuse]); assert(efuse_enabled_can_setters[efuse] != NULL); efuse_enabled_can_setters[efuse](enabled); diff --git a/firmware/quintuna/VC/src/app/app_loadswitches.h b/firmware/quintuna/VC/src/app/app_loadswitches.h index ec3fef3da2..70f88d4d47 100644 --- a/firmware/quintuna/VC/src/app/app_loadswitches.h +++ b/firmware/quintuna/VC/src/app/app_loadswitches.h @@ -1,6 +1,6 @@ #pragma once #include -#include "io_loadswitches.h" +#include "io_efuses.h" void app_efuse_broadcast(void); \ No newline at end of file diff --git a/firmware/quintuna/VC/src/app/app_powerManager.c b/firmware/quintuna/VC/src/app/app_powerManager.c index b2bb9b13b4..66c0b560b4 100644 --- a/firmware/quintuna/VC/src/app/app_powerManager.c +++ b/firmware/quintuna/VC/src/app/app_powerManager.c @@ -1,7 +1,7 @@ #include "app_powerManager.h" #include "app_timer.h" -#include "io_loadswitches.h" +#include "io_efuses.h" #include "app_canAlerts.h" #include @@ -12,27 +12,9 @@ static PowerManagerConfig power_manager_state; static TimerChannel sequencing_timer; -typedef union -{ - const ST_LoadSwitch *st; - const TI_LoadSwitch *ti; -} LoadSwitch; - -typedef struct -{ - LoadSwitch loadswitch; - uint8_t retry_num; -} RetryProtocol; - -static RetryProtocol efuses_retry_state[NUM_EFUSE_CHANNELS] = { - [EFUSE_CHANNEL_F_INV] = { .loadswitch.st = &inv_rsm_loadswitch, .retry_num = 0 }, - [EFUSE_CHANNEL_RSM] = { .loadswitch.st = &inv_rsm_loadswitch, .retry_num = 0 }, - [EFUSE_CHANNEL_BMS] = { .loadswitch.st = &inv_bms_loadswitch, .retry_num = 0 }, - [EFUSE_CHANNEL_R_INV] = { .loadswitch.st = &inv_bms_loadswitch, .retry_num = 0 }, - [EFUSE_CHANNEL_DAM] = { .loadswitch.st = &front_loadswitch, .retry_num = 0 }, - [EFUSE_CHANNEL_FRONT] = { .loadswitch.st = &front_loadswitch, .retry_num = 0 }, - [EFUSE_CHANNEL_RL_PUMP] = { .loadswitch.ti = &rl_pump_loadswitch, .retry_num = 0 }, - [EFUSE_CHANNEL_R_RAD] = { .loadswitch.st = &rad_fan_loadswitch, .retry_num = 0 } +static uint8_t efuses_retry_num[NUM_EFUSE_CHANNELS] = { + [EFUSE_CHANNEL_F_INV] = 0, [EFUSE_CHANNEL_RSM] = 0, [EFUSE_CHANNEL_BMS] = 0, [EFUSE_CHANNEL_R_INV] = 0, + [EFUSE_CHANNEL_DAM] = 0, [EFUSE_CHANNEL_FRONT] = 0, [EFUSE_CHANNEL_RL_PUMP] = 0, [EFUSE_CHANNEL_R_RAD] = 0 }; void app_powerManager_updateConfig(const PowerManagerConfig new_power_manager_config) @@ -44,51 +26,6 @@ void app_powerManager_updateConfig(const PowerManagerConfig new_power_manager_co power_manager_state.efuse_configs[EFUSE_CHANNEL_R_RAD].efuse_enable = !app_canAlerts_VC_Info_PcmUnderVoltage_get(); } -static bool STLoadswitch_Status(const ST_LoadSwitch *loadswitch) -{ - assert(loadswitch->efuse1 != NULL && loadswitch->efuse2 != NULL); - - // Checking if ther is an overtemperature/short to ground condition - float vsenseh_efuse1 = io_loadswitch_getChannelCurrent(loadswitch->efuse1) / ADC_VOLTAGE_TO_CURRENT_A; - float vsenseh_efuse2 = io_loadswitch_getChannelCurrent(loadswitch->efuse2) / ADC_VOLTAGE_TO_CURRENT_A; - - if (io_loadswitch_isChannelEnabled(loadswitch->efuse1) && vsenseh_efuse1 >= 3.0f) - { - return false; - } - - if (io_loadswitch_isChannelEnabled(loadswitch->efuse2) && vsenseh_efuse2 >= 3.0f) - { - return false; - } - - // Checking if there is a short to VBAT condition - io_STloadswitch_reset_set(loadswitch, true); - - if (!io_loadswitch_isChannelEnabled(loadswitch->efuse1) && vsenseh_efuse1 > 3.0f) - { - return false; - } - - if (!io_loadswitch_isChannelEnabled(loadswitch->efuse2) && vsenseh_efuse2 > 3.0f) - { - return false; - } - - // reset the stby reset gpio to low - io_STloadswitch_reset_set(loadswitch, false); - return true; -} - -static bool is_efuse_ok(const uint8_t current_efuse_sequence) -{ - if (EFUSE_CHANNEL_RL_PUMP <= current_efuse_sequence) - { - return io_TILoadswitch_pgood(efuses_retry_state[current_efuse_sequence].loadswitch.ti); - } - return STLoadswitch_Status(efuses_retry_state[current_efuse_sequence].loadswitch.st); -} - void app_powerManager_EfuseProtocolTick_100Hz(void) { switch (app_timer_updateAndGetState(&sequencing_timer)) @@ -110,14 +47,14 @@ void app_powerManager_EfuseProtocolTick_100Hz(void) { // check if the efuse is supposed to be on or off const bool desired_efuse_state = power_manager_state.efuse_configs[current_efuse_sequence].efuse_enable; - if (io_loadswitch_isChannelEnabled(efuse_channels[current_efuse_sequence]) == desired_efuse_state) + if (io_efuse_isChannelEnabled(efuse_channels[current_efuse_sequence]) == desired_efuse_state) { // efuse is fine continue; } // todo check this when incrementing the efuse failure - if (efuses_retry_state[current_efuse_sequence].retry_num > + if (efuses_retry_num[current_efuse_sequence].retry_num > power_manager_state.efuse_configs[current_efuse_sequence].max_retry) { // todo over the retry limit activities @@ -128,15 +65,15 @@ void app_powerManager_EfuseProtocolTick_100Hz(void) if (desired_efuse_state == false) { // case 1: on and trying to turn off - io_loadswitch_setChannel(efuse_channels[current_efuse_sequence], desired_efuse_state); + io_efuse_setChannel(efuse_channels[current_efuse_sequence], desired_efuse_state); continue; } // case 2: off and trying to turn on // we update the efuse blown status here because this only shows up when we want it on - if (!is_efuse_ok(current_efuse_sequence)) // todo remove this state? - { - efuses_retry_state[current_efuse_sequence].retry_num++; - } + // if (!is_efuse_ok(current_efuse_sequence)) // todo remove this state? + // { + // efuses_retry_num[current_efuse_sequence].retry_num++; + // } // If we dont know the if the efuse is blown check if it is however if we know its already blown // dont check After this is we begin power sequencing logic as we want to turn on the loads @@ -147,7 +84,7 @@ void app_powerManager_EfuseProtocolTick_100Hz(void) app_timer_init(&sequencing_timer, efuse_retry_timeout); app_timer_restart(&sequencing_timer); } - io_loadswitch_setChannel( + io_efuse_setChannel( efuse_channels[current_efuse_sequence], power_manager_state.efuse_configs[current_efuse_sequence].efuse_enable); } diff --git a/firmware/quintuna/VC/src/app/app_powerManager.h b/firmware/quintuna/VC/src/app/app_powerManager.h index f15031f030..e2d1700e6e 100644 --- a/firmware/quintuna/VC/src/app/app_powerManager.h +++ b/firmware/quintuna/VC/src/app/app_powerManager.h @@ -1,7 +1,7 @@ #pragma once #include -#include "io_loadswitches.h" +#include "io_efuses.h" typedef struct { diff --git a/firmware/quintuna/VC/src/app/app_pumpControl.c b/firmware/quintuna/VC/src/app/app_pumpControl.c index 00277cbff9..c516d08953 100644 --- a/firmware/quintuna/VC/src/app/app_pumpControl.c +++ b/firmware/quintuna/VC/src/app/app_pumpControl.c @@ -1,5 +1,5 @@ #include "app_pumpControl.h" -#include "io_loadswitch.h" +#include "io_efuses.h" #include "io_time.h" #include "io_loadswitches.h" #include @@ -40,9 +40,9 @@ static void pumpControl_stopFlow(void) void app_pumpControl_MonitorPumps(void) { time += 10; - const bool pumps_ok = io_TILoadswitch_pgood(&rl_pump_loadswitch); + const bool pumps_ok = true - const bool pumps_enabled = io_loadswitch_isChannelEnabled(efuse_channels[EFUSE_CHANNEL_RL_PUMP]); + const bool pumps_enabled = true; bool ramp_up_pumps = pumps_ok && pumps_enabled; diff --git a/firmware/quintuna/VC/src/io/io_efuses.c b/firmware/quintuna/VC/src/io/io_efuses.c new file mode 100644 index 0000000000..5d1c9a4e14 --- /dev/null +++ b/firmware/quintuna/VC/src/io/io_efuses.c @@ -0,0 +1,35 @@ +#include "hw_adcs.h" +#include "hw_gpios.h" +#include "hw_i2cs.h" +#include "io_efuses.h" + +static ST_Efuse f_inv_st_efuse = { .stby_reset_gpio = &fr_stby_inv }; +static ST_Efuse rsm_st_efuse = { .stby_reset_gpio = &fr_stby_inv }; +static ST_Efuse bms_st_efuse = { .stby_reset_gpio = &fr_stby_front }; +static ST_Efuse r_inv_st_efuse = { .stby_reset_gpio = &fr_stby_front }; +static ST_Efuse dam_st_efuse = { .stby_reset_gpio = &fr_stby_rear }; +static ST_Efuse front_st_efuse = { .stby_reset_gpio = &fr_stby_rear }; +static TI_Efuse rl_pump_ti_efuse = { .pgood = &rl_pump_pgood }; +static ST_Efuse r_rad_fan_st_efuse = { .stby_reset_gpio = &fr_stby_rad }; + +static Efuse f_inv_efuse = { .enable_gpio = &f_inv_en, .sns_adc_channel = &inv_f_pwr_i_sns, .st = &f_inv_st_efuse }; +static Efuse rsm_efuse = { .enable_gpio = &rsm_en, .sns_adc_channel = &rsm_i_sns, .st = &f_inv_st_efuse }; +static Efuse bms_efuse = { .enable_gpio = &bms_en, .sns_adc_channel = &bms_i_sns, .st = &bms_st_efuse }; +static Efuse r_inv_efuse = { .enable_gpio = &r_inv_en, .sns_adc_channel = &inv_r_pwr_i_sns, .st = &r_inv_st_efuse }; +static Efuse dam_efuse = { .enable_gpio = &dam_en, .sns_adc_channel = &dam_i_sns, .st = &dam_st_efuse }; + +static Efuse front_efuse = { .enable_gpio = &front_en, .sns_adc_channel = &front_i_sns, .st = &front_st_efuse }; + +static Efuse rl_pump_efuse = { .enable_gpio = &rl_pump_en, + .sns_adc_channel = &pump_rl_pwr_i_sns, + .ti = &rl_pump_ti_efuse }; +static Efuse r_rad_fan_efuse = { .enable_gpio = &rr_rad_fan_en, + .sns_adc_channel = &r_rad_fan_i_sns, + .st = &r_rad_fan_st_efuse }; + +Efuse *const efuse_channels[NUM_EFUSE_CHANNELS] = { + [EFUSE_CHANNEL_F_INV] = &f_inv_efuse, [EFUSE_CHANNEL_RSM] = &rsm_efuse, + [EFUSE_CHANNEL_BMS] = &bms_efuse, [EFUSE_CHANNEL_R_INV] = &r_inv_efuse, + [EFUSE_CHANNEL_DAM] = &dam_efuse, [EFUSE_CHANNEL_FRONT] = &front_efuse, + [EFUSE_CHANNEL_RL_PUMP] = &rl_pump_efuse, [EFUSE_CHANNEL_R_RAD] = &r_rad_fan_efuse +}; diff --git a/firmware/quintuna/VC/src/io/io_efuses.h b/firmware/quintuna/VC/src/io/io_efuses.h new file mode 100644 index 0000000000..c3cebf4f86 --- /dev/null +++ b/firmware/quintuna/VC/src/io/io_efuses.h @@ -0,0 +1,28 @@ +#pragma once + +#include "io_efuse/io_efuse.h" + +typedef enum +{ + // INV_RSM loadswitch + EFUSE_CHANNEL_F_INV = 0u, + EFUSE_CHANNEL_RSM, + + // INV_BMS loadswitch + EFUSE_CHANNEL_BMS, + EFUSE_CHANNEL_R_INV, + + // Front loadswitch + EFUSE_CHANNEL_DAM, + EFUSE_CHANNEL_FRONT, + + // TI loadswitches + EFUSE_CHANNEL_RL_PUMP, + + // Radiator Fan loadswitches + EFUSE_CHANNEL_R_RAD, + + NUM_EFUSE_CHANNELS +} LoadswitchChannel; + +extern Efuse *const efuse_channels[NUM_EFUSE_CHANNELS]; diff --git a/firmware/quintuna/VC/src/io/io_loadswitches.c b/firmware/quintuna/VC/src/io/io_loadswitches.c deleted file mode 100644 index fe442dee60..0000000000 --- a/firmware/quintuna/VC/src/io/io_loadswitches.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "io_loadswitches.h" -#include "hw_adcs.h" -#include "hw_gpios.h" -#include "hw_i2cs.h" -#include "io_loadswitch.h" - -static const Efuse f_inv_efuse = { .enable_gpio = &f_inv_en, .sns_adc_channel = &inv_f_pwr_i_sns }; -static const Efuse rsm_efuse = { .enable_gpio = &rsm_en, .sns_adc_channel = &rsm_i_sns }; -static const Efuse bms_efuse = { .enable_gpio = &bms_en, .sns_adc_channel = &bms_i_sns }; -static const Efuse r_inv_efuse = { .enable_gpio = &r_inv_en, .sns_adc_channel = &inv_r_pwr_i_sns }; -static const Efuse dam_efuse = { .enable_gpio = &dam_en, .sns_adc_channel = &dam_i_sns }; -static const Efuse front_efuse = { .enable_gpio = &front_en, .sns_adc_channel = &front_i_sns }; -static const Efuse rl_pump_efuse = { .enable_gpio = &rl_pump_en, .sns_adc_channel = &pump_rl_pwr_i_sns }; -static const Efuse r_rad_fan_efuse = { .enable_gpio = &rr_rad_fan_en, .sns_adc_channel = &r_rad_fan_i_sns }; - -const ST_LoadSwitch inv_rsm_loadswitch = { .efuse1 = &f_inv_efuse, - .efuse2 = &rsm_efuse, - .stby_reset_gpio = &fr_stby_inv }; -const ST_LoadSwitch inv_bms_loadswitch = { .efuse1 = &bms_efuse, - .efuse2 = &r_inv_efuse, - .stby_reset_gpio = &fr_stby_front }; -const ST_LoadSwitch front_loadswitch = { .efuse1 = &dam_efuse, - .efuse2 = &front_efuse, - .stby_reset_gpio = &fr_stby_rear }; -const TI_LoadSwitch rl_pump_loadswitch = { .efuse = &rl_pump_efuse, .pgood = &rl_pump_pgood }; -const ST_LoadSwitch rad_fan_loadswitch = { .efuse1 = NULL, - .efuse2 = &r_rad_fan_efuse, - .stby_reset_gpio = &fr_stby_rad }; - -const Efuse *const efuse_channels[NUM_EFUSE_CHANNELS] = { - [EFUSE_CHANNEL_F_INV] = &f_inv_efuse, [EFUSE_CHANNEL_RSM] = &rsm_efuse, - [EFUSE_CHANNEL_BMS] = &bms_efuse, [EFUSE_CHANNEL_R_INV] = &r_inv_efuse, - [EFUSE_CHANNEL_DAM] = &dam_efuse, [EFUSE_CHANNEL_FRONT] = &front_efuse, - [EFUSE_CHANNEL_RL_PUMP] = &rl_pump_efuse, [EFUSE_CHANNEL_R_RAD] = &r_rad_fan_efuse -}; -z` \ No newline at end of file diff --git a/firmware/quintuna/VC/src/io/io_loadswitches.h b/firmware/quintuna/VC/src/io/io_loadswitches.h deleted file mode 100644 index bb69e76a90..0000000000 --- a/firmware/quintuna/VC/src/io/io_loadswitches.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "io_loadswitch.h" - -typedef enum -{ - // INV_RSM loadswitch - EFUSE_CHANNEL_F_INV = 0u, - EFUSE_CHANNEL_RSM, - - // INV_BMS loadswitch - EFUSE_CHANNEL_BMS, - EFUSE_CHANNEL_R_INV, - - // Front loadswitch - EFUSE_CHANNEL_DAM, - EFUSE_CHANNEL_FRONT, - - // TI loadswitches - EFUSE_CHANNEL_RL_PUMP, - - // Radiator Fan loadswitches - EFUSE_CHANNEL_R_RAD, - - NUM_EFUSE_CHANNELS -} LoadswitchChannel; - -#ifdef TARGET_EMBEDDED -extern const ST_LoadSwitch inv_rsm_loadswitch; -extern const ST_LoadSwitch inv_bms_loadswitch; -extern const ST_LoadSwitch front_loadswitch; -extern const TI_LoadSwitch rl_pump_loadswitch; -extern const TI_LoadSwitch rr_pump_loadswitch; -extern const TI_LoadSwitch f_pump_loadswitch; -extern const ST_LoadSwitch rad_fan_loadswitch; -#elif TARGET_TEST -extern ST_LoadSwitch inv_rsm_loadswitch; -extern ST_LoadSwitch inv_bms_loadswitch; -extern ST_LoadSwitch front_loadswitch; -extern TI_LoadSwitch rl_pump_loadswitch; -extern TI_LoadSwitch rr_pump_loadswitch; -extern TI_LoadSwitch f_pump_loadswitch; -extern ST_LoadSwitch rad_fan_loadswitch; -#endif - -extern const Efuse *const efuse_channels[NUM_EFUSE_CHANNELS]; diff --git a/firmware/shared/src/io/io_efuse/io_efuse.c b/firmware/shared/src/io/io_efuse/io_efuse.c index f5e5453e49..d401433c13 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse.c +++ b/firmware/shared/src/io/io_efuse/io_efuse.c @@ -12,43 +12,24 @@ void io_efuse_setChannel(const Efuse *channel, const bool enabled) bool io_efuse_isChannelEnabled(const Efuse *channel) { - assert(channel->enable_gpio != NULL); - return chann; + assert(channel != NULL); + return channel->efuse_functions->is_channel_enabled(channel); } float io_efuse_getChannelCurrent(const Efuse *channel) { - const AdcChannel *current_sense = channel->sns_adc_channel; - assert(current_sense != NULL); - return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; -} - -void io_STefuse_reset_set(const ST_efuse *efuse, const bool set) -{ - assert(efuse->stby_reset_gpio != NULL); - hw_gpio_writePin(efuse->stby_reset_gpio, set); -} - -void io_STefuse_Reset(const ST_efuse *efuse) -{ - assert(efuse->stby_reset_gpio != NULL); - hw_gpio_writePin(efuse->stby_reset_gpio, false); - hw_gpio_writePin(efuse->stby_reset_gpio, true); - hw_gpio_writePin(efuse->stby_reset_gpio, false); + assert(channel != NULL); + return channel->efuse_functions->get_channel_current(channel); } -void io_TIefuse_Reset(const TI_efuse *efuse) +void io_efuse_reset_set(const Efuse *channel, const bool set) { - assert(efuse->efuse != NULL); - assert(efuse->efuse->enable_gpio != NULL); - - hw_gpio_writePin(efuse->efuse->enable_gpio, false); - hw_gpio_writePin(efuse->efuse->enable_gpio, true); - hw_gpio_writePin(efuse->efuse->enable_gpio, false); + assert(channel != NULL); + channel->efuse_functions->loadswitch_reset_set(channel); } -bool io_TIefuse_pgood(const TI_efuse *efuse) +void io_efuse_reset(const Efuse *channel) { - assert(efuse->pgood != NULL); - return hw_gpio_readPin(efuse->pgood); + assert(channel != NULL); + channel->efuse_functions->reset_efuse(channel); } diff --git a/firmware/shared/src/io/io_efuse/io_efuse.h b/firmware/shared/src/io/io_efuse/io_efuse.h index 411f3aaa55..be9391a9c8 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse.h +++ b/firmware/shared/src/io/io_efuse/io_efuse.h @@ -1,6 +1,9 @@ #pragma once #include +#include "io_efuse_datatypes.h" +#include "io_efuse_ST/io_efuse_ST.h" +#include "io_efuse_TI/io_efuse_TI.h" #define ADC_VOLTAGE_TO_CURRENT_A 1.720f @@ -49,18 +52,10 @@ float io_efuse_getChannelCurrent(const Efuse *channel); * @param efuse * @param set */ -void io_efuse_reset_set(const ST_efuse *efuse, bool set); +void io_efuse_reset_set(const Efuse *channel, bool set); /** * Reset the hardfault set by the efuse * @param efuse Reset the hardfault set by efuse */ -void io_efuse_Reset(const ST_efuse *efuse); - - -/** - * TI efuse pgood line status - * @param efuse TI efuse in question - * @return status of the pgood line - */ -bool io_TIefuse_pgood(const TI_efuse *efuse); \ No newline at end of file +void io_efuse_reset(const Efuse *channel); \ No newline at end of file diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c index ae8272605b..e01afbc964 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c @@ -3,48 +3,44 @@ #include #include - -static void io_efuseST_setChannel(const Efuse *channel, const bool enabled); -static bool io_efuseST_isChannelEnabled(const Efuse *channel); -static float io_efuseST_getChannelCurrent(const Efuse *channel); -static void io_efuseST_reset_set(const Efuse *channel, const bool set); -static void io_efuseST_Reset(const Efuse *channel); - - -const EfuseFunctons st_efuse_functions = { - .set_channel = io_efuseST_setChannel, - .is_channel_enabled = io_efuseST_isChannelEnabled, - .get_channel_current = io_efuseST_getChannelCurrent, - .loadswitch_reset_set = io_efuseST_reset_set, - .reset_efuse = io_efuseST_Reset -}; - -static void io_efuseST_setChannel(const Efuse *channel, const bool enabled) +static void io_efuse_ST_setChannel(const Efuse *channel, const bool enabled); +static bool io_efuse_ST_isChannelEnabled(const Efuse *channel); +static float io_efuse_ST_getChannelCurrent(const Efuse *channel); +static void io_efuse_ST_reset_set(const Efuse *channel, const bool set); +static void io_efuse_ST_Reset(const Efuse *channel); + +const EfuseFunctons st_efuse_functions = { .set_channel = io_efuse_ST_setChannel, + .is_channel_enabled = io_efuse_ST_isChannelEnabled, + .get_channel_current = io_efuse_ST_getChannelCurrent, + .loadswitch_reset_set = io_efuse_ST_reset_set, + .reset_efuse = io_efuse_ST_Reset }; + +static void io_efuse_ST_setChannel(const Efuse *channel, const bool enabled) { assert(channel->enable_gpio != NULL); hw_gpio_writePin(channel->enable_gpio, enabled); } -static bool io_efuseST_isChannelEnabled(const Efuse *channel) +static bool io_efuse_ST_isChannelEnabled(const Efuse *channel) { assert(channel->enable_gpio != NULL); return hw_gpio_readPin(channel->enable_gpio); } -static float io_efuseST_getChannelCurrent(const Efuse *channel) +static float io_efuse_ST_getChannelCurrent(const Efuse *channel) { const AdcChannel *current_sense = channel->sns_adc_channel; assert(current_sense != NULL); return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; } -static void io_efuseST_reset_set(const Efuse *channel, const bool set) +static void io_efuse_ST_reset_set(const Efuse *channel, const bool set) { assert(channel->st->stby_reset_gpio != NULL); hw_gpio_writePin(channel->st->stby_reset_gpio, set); } -static void io_efuseST_Reset(const Efuse *channel) +static void io_efuse_ST_Reset(const Efuse *channel) { assert(channel->st->stby_reset_gpio != NULL); hw_gpio_writePin(channel->st->stby_reset_gpio, false); diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h index 64f98450e8..13920ddfb1 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h @@ -4,24 +4,22 @@ #include #include "hw_gpio.h" #include "hw_adc.h" -#include "io_efuse_datatypes.h" +#include "io_efuse/io_efuse_datatypes.h" -/* Forward declarations for types you use here */ - -typedef struct ST_Efuse +typedef struct __ST_Efuse { - const Gpio *stby_reset_gpio; + const Gpio *stby_reset_gpio; /* Portable bit-fields: use 'unsigned' and name the subgroup */ - struct { - uint8_t overload : 1; - uint8_t ovt_stp : 1; - uint8_t under_voltage : 1; - uint8_t short_to_vbat : 1; - uint8_t open_load_off_stat : 1; - uint8_t negative_output_voltage_clamp : 1; + struct + { + uint8_t overload : 1; + uint8_t ovt_stp : 1; + uint8_t under_voltage : 1; + uint8_t short_to_vbat : 1; + uint8_t open_load_off_stat : 1; + uint8_t negative_output_voltage_clamp : 1; } faults; -}ST_Efuse; +} ST_Efuse; extern const EfuseFunctons st_efuse_functions; - diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c index ec69b477d2..c20ca2c96b 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c @@ -3,18 +3,18 @@ #include #include -static void io_TI_efuse_setChannel(const Efuse *channel, const bool enabled); -static bool io_TI_efuse_isChannelEnabled(const Efuse *channel); +static void io_TI_efuse_setChannel(const Efuse *channel, const bool enabled); +static bool io_TI_efuse_isChannelEnabled(const Efuse *channel); static float io_TI_efuse_getChannelCurrent(const Efuse *channel); -static void io_TI_efuse_Reset(const Efuse *efuse); -static bool io_TI_efuse_pgood(const Efuse *efuse); +static void io_TI_efuse_Reset(const Efuse *efuse); +// static bool io_TI_efuse_pgood(const Efuse *efuse); const TI_EfuseFunctons ti_efuse_functions = { - .set_channel = io_TI_efuse_setChannel, - .is_channel_enabled = io_TI_efuse_isChannelEnabled, - .get_channel_current = io_TI_efuse_getChannelCurrent, - .loadswitch_reset_set = NULL - .reset_efuse = io_TI_efuse_Reset, + .set_channel = io_TI_efuse_setChannel, + .is_channel_enabled = io_TI_efuse_isChannelEnabled, + .get_channel_current = io_TI_efuse_getChannelCurrent, + .loadswitch_reset_set = NULL, + .reset_efuse = io_TI_efuse_Reset, }; static void io_TI_efuse_setChannel(const Efuse *channel, const bool enabled) @@ -39,15 +39,14 @@ static float io_TI_efuse_getChannelCurrent(const Efuse *channel) static void io_TI_efuse_Reset(const Efuse *efuse) { assert(efuse->efuse != NULL); - assert(efuse->efuse->enable_gpio != NULL); - hw_gpio_writePin(efuse->efuse->enable_gpio, false); - hw_gpio_writePin(efuse->efuse->enable_gpio, true); - hw_gpio_writePin(efuse->efuse->enable_gpio, false); + hw_gpio_writePin(efuse->enable_gpio, false); + hw_gpio_writePin(efuse->enable_gpio, true); + hw_gpio_writePin(efuse->enable_gpio, false); } -static bool io_TI_efuse_pgood(const Efuse *efuse) -{ - assert(efuse->pgood != NULL); - return hw_gpio_readPin(efuse->pgood); -} +// static bool io_TI_efuse_pgood(const Efuse *efuse) +// { +// assert(efuse->pgood != NULL); +// return hw_gpio_readPin(efuse->pgood); +// } diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h index 34806d28b7..c53975c9f0 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h @@ -4,17 +4,11 @@ #include #include "hw_gpio.h" #include "hw_adc.h" -#include "io_efuse_datatypes.h" +#include "io_efuse/io_efuse_datatypes.h" - -/* Forward declarations for types you use here */ -typedef EfuseFunctons EfuseFunctons; - -typedef struct ST_Efuse +typedef struct __TI_Efuse { - const Gpio *pgood; -}TI_Efuse; - + const Gpio *pgood; +} TI_Efuse; extern const EfuseFunctons ti_efuse_functions; - diff --git a/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h index 073a3675ba..abaa343713 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h @@ -1,33 +1,35 @@ #pragma once -#ifdef TARGET_EMBEDDED #include "hw_gpio.h" #include "hw_adc.h" -#include "io_efuse_ST.h" -#include "io_efuse_TI.h" +#include "io_efuse_ST/io_efuse_ST.H" +#include "io_efuse_TI/io_efuse_TI.h" #define ADC_VOLTAGE_TO_CURRENT_A 1.720f -typedef struct{ - +typedef struct __Efuse Efuse; +typedef struct __ST_Efuse ST_Efuse; +typedef struct __TI_Efuse TI_Efuse; + +typedef struct +{ void (*set_channel)(Efuse *channel, bool enabled); bool (*is_channel_enabled)(const Efuse *channel); bool (*get_channel_current)(const Efuse *channel); - void (*loadswitch_reset_set) (const Efuse *channel, const bool set); - void (*reset_efuse) (const Efuse *channel); + void (*loadswitch_reset_set)(const Efuse *channel, const bool set); + void (*reset_efuse)(const Efuse *channel); } EfuseFunctons; -typedef struct { - +typedef struct __Efuse +{ const Gpio *enable_gpio; const AdcChannel *sns_adc_channel; - union + union { - ST_Efuse st; - TI_Efuse ti; + ST_Efuse *st; + TI_Efuse *ti; }; EfuseFunctons *efuse_functions; -}Efuse; -#endif \ No newline at end of file +} Efuse; From ce16b5cef889c2efb854dcd9169fcdeba6e07dfa Mon Sep 17 00:00:00 2001 From: Aditya-Dhiman4 Date: Sun, 12 Oct 2025 12:43:46 -0700 Subject: [PATCH 03/12] cleaned up code --- firmware/quintuna/VC/src/io/io_efuses.c | 51 +++++++++++++++---- firmware/shared/src/io/io_efuse/io_efuse.c | 1 + firmware/shared/src/io/io_efuse/io_efuse.h | 24 --------- .../src/io/io_efuse/io_efuse_ST/io_efuse_ST.c | 10 ++-- .../src/io/io_efuse/io_efuse_ST/io_efuse_ST.h | 3 +- .../src/io/io_efuse/io_efuse_TI/io_efuse_TI.c | 4 +- .../src/io/io_efuse/io_efuse_TI/io_efuse_TI.h | 2 +- .../src/io/io_efuse/io_efuse_datatypes.h | 4 +- 8 files changed, 54 insertions(+), 45 deletions(-) diff --git a/firmware/quintuna/VC/src/io/io_efuses.c b/firmware/quintuna/VC/src/io/io_efuses.c index 5d1c9a4e14..d40a8b494d 100644 --- a/firmware/quintuna/VC/src/io/io_efuses.c +++ b/firmware/quintuna/VC/src/io/io_efuses.c @@ -2,6 +2,7 @@ #include "hw_gpios.h" #include "hw_i2cs.h" #include "io_efuses.h" +#include static ST_Efuse f_inv_st_efuse = { .stby_reset_gpio = &fr_stby_inv }; static ST_Efuse rsm_st_efuse = { .stby_reset_gpio = &fr_stby_inv }; @@ -12,20 +13,50 @@ static ST_Efuse front_st_efuse = { .stby_reset_gpio = &fr_stby_rear }; static TI_Efuse rl_pump_ti_efuse = { .pgood = &rl_pump_pgood }; static ST_Efuse r_rad_fan_st_efuse = { .stby_reset_gpio = &fr_stby_rad }; -static Efuse f_inv_efuse = { .enable_gpio = &f_inv_en, .sns_adc_channel = &inv_f_pwr_i_sns, .st = &f_inv_st_efuse }; -static Efuse rsm_efuse = { .enable_gpio = &rsm_en, .sns_adc_channel = &rsm_i_sns, .st = &f_inv_st_efuse }; -static Efuse bms_efuse = { .enable_gpio = &bms_en, .sns_adc_channel = &bms_i_sns, .st = &bms_st_efuse }; -static Efuse r_inv_efuse = { .enable_gpio = &r_inv_en, .sns_adc_channel = &inv_r_pwr_i_sns, .st = &r_inv_st_efuse }; -static Efuse dam_efuse = { .enable_gpio = &dam_en, .sns_adc_channel = &dam_i_sns, .st = &dam_st_efuse }; +static Efuse f_inv_efuse = { .enable_gpio = &f_inv_en, + .sns_adc_channel = &inv_f_pwr_i_sns, + .st = &f_inv_st_efuse, + .efuse_functions = st_efuse_functions }; -static Efuse front_efuse = { .enable_gpio = &front_en, .sns_adc_channel = &front_i_sns, .st = &front_st_efuse }; +static Efuse f_inv_efuse = { .enable_gpio = &f_inv_en, + .sns_adc_channel = &inv_f_pwr_i_sns, + .st = &f_inv_st_efuse, + .efuse_functions = &st_efuse_functions }; + +static Efuse rsm_efuse = { .enable_gpio = &rsm_en, + .sns_adc_channel = &rsm_i_sns, + .st = &f_inv_st_efuse, + .efuse_functions = &st_efuse_functions }; + +static Efuse bms_efuse = { .enable_gpio = &bms_en, + .sns_adc_channel = &bms_i_sns, + .st = &bms_st_efuse, + .efuse_functions = &st_efuse_functions }; + +static Efuse r_inv_efuse = { .enable_gpio = &r_inv_en, + .sns_adc_channel = &inv_r_pwr_i_sns, + .st = &r_inv_st_efuse, + .efuse_functions = &st_efuse_functions }; + +static Efuse dam_efuse = { .enable_gpio = &dam_en, + .sns_adc_channel = &dam_i_sns, + .st = &dam_st_efuse, + .efuse_functions = &st_efuse_functions }; + +static Efuse front_efuse = { .enable_gpio = &front_en, + .sns_adc_channel = &front_i_sns, + .st = &front_st_efuse, + .efuse_functions = &st_efuse_functions }; + +static Efuse rl_pump_efuse = { .enable_gpio = &rl_pump_en, + .sns_adc_channel = &pump_rl_pwr_i_sns, + .ti = &rl_pump_ti_efuse, + .efuse_functions = &ti_efuse_functions }; -static Efuse rl_pump_efuse = { .enable_gpio = &rl_pump_en, - .sns_adc_channel = &pump_rl_pwr_i_sns, - .ti = &rl_pump_ti_efuse }; static Efuse r_rad_fan_efuse = { .enable_gpio = &rr_rad_fan_en, .sns_adc_channel = &r_rad_fan_i_sns, - .st = &r_rad_fan_st_efuse }; + .st = &r_rad_fan_st_efuse, + .efuse_functions = &ti_efuse_functions }; Efuse *const efuse_channels[NUM_EFUSE_CHANNELS] = { [EFUSE_CHANNEL_F_INV] = &f_inv_efuse, [EFUSE_CHANNEL_RSM] = &rsm_efuse, diff --git a/firmware/shared/src/io/io_efuse/io_efuse.c b/firmware/shared/src/io/io_efuse/io_efuse.c index d401433c13..c4933be1dc 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse.c +++ b/firmware/shared/src/io/io_efuse/io_efuse.c @@ -1,4 +1,5 @@ #include "io_efuse.h" +#include "io_efuse_datatypes.h" #include "hw_gpio.h" #include #include diff --git a/firmware/shared/src/io/io_efuse/io_efuse.h b/firmware/shared/src/io/io_efuse/io_efuse.h index be9391a9c8..7aead6632a 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse.h +++ b/firmware/shared/src/io/io_efuse/io_efuse.h @@ -5,30 +5,6 @@ #include "io_efuse_ST/io_efuse_ST.h" #include "io_efuse_TI/io_efuse_TI.h" -#define ADC_VOLTAGE_TO_CURRENT_A 1.720f - -#ifndef TARGET_EMBEDDED -typedef struct -{ - bool enabled; - float current; - bool simulate_fault; -} Efuse; -typedef struct -{ - const Efuse *efuse; - bool pgood; -} TI_efuse; -typedef struct -{ - const Efuse *efuse1; - const Efuse *efuse2; - - bool pgood; - bool set_stby_reset_gpio; -} ST_efuse; -#endif - /** * Enable or disable the provided efuse channel. * @param channel Channel to enable/disable diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c index e01afbc964..6f748da9ea 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c @@ -9,11 +9,11 @@ static float io_efuse_ST_getChannelCurrent(const Efuse *channel); static void io_efuse_ST_reset_set(const Efuse *channel, const bool set); static void io_efuse_ST_Reset(const Efuse *channel); -const EfuseFunctons st_efuse_functions = { .set_channel = io_efuse_ST_setChannel, - .is_channel_enabled = io_efuse_ST_isChannelEnabled, - .get_channel_current = io_efuse_ST_getChannelCurrent, - .loadswitch_reset_set = io_efuse_ST_reset_set, - .reset_efuse = io_efuse_ST_Reset }; +const EfuseFunctions st_efuse_functions = { .set_channel = io_efuse_ST_setChannel, + .is_channel_enabled = io_efuse_ST_isChannelEnabled, + .get_channel_current = io_efuse_ST_getChannelCurrent, + .loadswitch_reset_set = io_efuse_ST_reset_set, + .reset_efuse = io_efuse_ST_Reset }; static void io_efuse_ST_setChannel(const Efuse *channel, const bool enabled) { diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h index 13920ddfb1..53b803135e 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h @@ -19,7 +19,8 @@ typedef struct __ST_Efuse uint8_t short_to_vbat : 1; uint8_t open_load_off_stat : 1; uint8_t negative_output_voltage_clamp : 1; + uint8_t padding : 2; } faults; } ST_Efuse; -extern const EfuseFunctons st_efuse_functions; +extern const EfuseFunctions st_efuse_functions; diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c index c20ca2c96b..b099c25b89 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c @@ -9,7 +9,7 @@ static float io_TI_efuse_getChannelCurrent(const Efuse *channel); static void io_TI_efuse_Reset(const Efuse *efuse); // static bool io_TI_efuse_pgood(const Efuse *efuse); -const TI_EfuseFunctons ti_efuse_functions = { +const EfuseFunctions ti_efuse_functions = { .set_channel = io_TI_efuse_setChannel, .is_channel_enabled = io_TI_efuse_isChannelEnabled, .get_channel_current = io_TI_efuse_getChannelCurrent, @@ -38,7 +38,7 @@ static float io_TI_efuse_getChannelCurrent(const Efuse *channel) static void io_TI_efuse_Reset(const Efuse *efuse) { - assert(efuse->efuse != NULL); + assert(efuse->enable_gpio != NULL); hw_gpio_writePin(efuse->enable_gpio, false); hw_gpio_writePin(efuse->enable_gpio, true); diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h index c53975c9f0..5d0f86597b 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h @@ -11,4 +11,4 @@ typedef struct __TI_Efuse const Gpio *pgood; } TI_Efuse; -extern const EfuseFunctons ti_efuse_functions; +extern const EfuseFunctions ti_efuse_functions; diff --git a/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h index abaa343713..e3ea3aa7cd 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h @@ -19,7 +19,7 @@ typedef struct void (*loadswitch_reset_set)(const Efuse *channel, const bool set); void (*reset_efuse)(const Efuse *channel); -} EfuseFunctons; +} EfuseFunctions; typedef struct __Efuse { @@ -31,5 +31,5 @@ typedef struct __Efuse TI_Efuse *ti; }; - EfuseFunctons *efuse_functions; + EfuseFunctions *efuse_functions; } Efuse; From fe845f4eeb9d5e7452b09b75e6713a87920e24cf Mon Sep 17 00:00:00 2001 From: Aditya-Dhiman4 Date: Tue, 14 Oct 2025 01:54:18 -0700 Subject: [PATCH 04/12] fixed build issues, API is functional, efuse_ok functions may need some work --- .vscode/settings.json | 6 +- firmware/boot/bootloader.h | 10 +-- .../quintuna/VC/src/app/app_loadswitches.c | 2 +- .../quintuna/VC/src/app/app_powerManager.c | 22 ++--- .../quintuna/VC/src/app/app_pumpControl.c | 7 +- .../VC/src/app/states/app_hvInitState.c | 1 - .../quintuna/VC/src/app/states/app_hvState.c | 1 - firmware/quintuna/VC/src/io/io_efuses.c | 90 +++++++++---------- firmware/quintuna/VC/src/io/io_efuses.h | 15 +++- firmware/shared/src/io/io_efuse/io_efuse.c | 24 ++++- firmware/shared/src/io/io_efuse/io_efuse.h | 22 ++++- .../src/io/io_efuse/io_efuse_ST/io_efuse_ST.c | 50 +++++++++-- .../src/io/io_efuse/io_efuse_ST/io_efuse_ST.h | 23 +++-- .../src/io/io_efuse/io_efuse_TI/io_efuse_TI.c | 39 ++++---- .../src/io/io_efuse/io_efuse_TI/io_efuse_TI.h | 3 +- .../src/io/io_efuse/io_efuse_datatypes.h | 29 +++--- 16 files changed, 210 insertions(+), 134 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index d69c895613..7b00bcc77e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,10 +13,10 @@ "--query-driver=/usr/local/bin/arm-none-eabi-gcc" ], "files.associations": { - "bootloader_VC.C": "cpp", + "io_efuses.h": "c", "io_efuse.h": "c", - "io_efuse_st.h": "c", "io_efuse_datatypes.h": "c", - "io_efuse_ti.h": "c" + "app_vehicledynamicsconstants.h": "c", + "app_loadswitches.h": "c" } } diff --git a/firmware/boot/bootloader.h b/firmware/boot/bootloader.h index c2fe65d715..02a6645a7f 100644 --- a/firmware/boot/bootloader.h +++ b/firmware/boot/bootloader.h @@ -15,11 +15,11 @@ #define APP_VALIDITY_ID_LOWBITS (0x8) #define GO_TO_BOOT (0x9) -void bootloader_preInit(void); -void bootloader_init(void); -void bootloader_runInterfaceTask(void); -void bootloader_runTickTask(void); -void bootloader_runCanTxTask(void); +void bootloader_preInit(void); +void bootloader_init(void); +_Noreturn void bootloader_runInterfaceTask(void); +_Noreturn void bootloader_runTickTask(void); +_Noreturn void bootloader_runCanTxTask(void); void bootloader_boardSpecific_init(void); void bootloader_boardSpecific_tick(void); diff --git a/firmware/quintuna/VC/src/app/app_loadswitches.c b/firmware/quintuna/VC/src/app/app_loadswitches.c index 2e76a22467..f8157012ad 100644 --- a/firmware/quintuna/VC/src/app/app_loadswitches.c +++ b/firmware/quintuna/VC/src/app/app_loadswitches.c @@ -44,4 +44,4 @@ void app_efuse_broadcast(void) } } -void app_loadswitch_enableFa +// void app_loadswitch_enableFa diff --git a/firmware/quintuna/VC/src/app/app_powerManager.c b/firmware/quintuna/VC/src/app/app_powerManager.c index 66c0b560b4..86ecf90619 100644 --- a/firmware/quintuna/VC/src/app/app_powerManager.c +++ b/firmware/quintuna/VC/src/app/app_powerManager.c @@ -40,21 +40,23 @@ void app_powerManager_EfuseProtocolTick_100Hz(void) // TODO: what the fuck __attribute__((fallthrough)); case TIMER_STATE_IDLE: - for (LoadswitchChannel current_efuse_sequence = 0; + for (EfuseChannel current_efuse_sequence = 0; current_efuse_sequence < NUM_EFUSE_CHANNELS && app_timer_updateAndGetState(&sequencing_timer) == TIMER_STATE_IDLE; current_efuse_sequence++) { + const Efuse *channel = efuse_channels[current_efuse_sequence]; + // check if the efuse is supposed to be on or off const bool desired_efuse_state = power_manager_state.efuse_configs[current_efuse_sequence].efuse_enable; - if (io_efuse_isChannelEnabled(efuse_channels[current_efuse_sequence]) == desired_efuse_state) + if (io_efuse_isChannelEnabled(channel) == desired_efuse_state) { // efuse is fine continue; } // todo check this when incrementing the efuse failure - if (efuses_retry_num[current_efuse_sequence].retry_num > + if (efuses_retry_num[current_efuse_sequence] > power_manager_state.efuse_configs[current_efuse_sequence].max_retry) { // todo over the retry limit activities @@ -65,15 +67,15 @@ void app_powerManager_EfuseProtocolTick_100Hz(void) if (desired_efuse_state == false) { // case 1: on and trying to turn off - io_efuse_setChannel(efuse_channels[current_efuse_sequence], desired_efuse_state); + io_efuse_setChannel(channel, desired_efuse_state); continue; } // case 2: off and trying to turn on // we update the efuse blown status here because this only shows up when we want it on - // if (!is_efuse_ok(current_efuse_sequence)) // todo remove this state? - // { - // efuses_retry_num[current_efuse_sequence].retry_num++; - // } + if (!io_efuse_ok(channel)) // todo remove this state? + { + efuses_retry_num[current_efuse_sequence]++; + } // If we dont know the if the efuse is blown check if it is however if we know its already blown // dont check After this is we begin power sequencing logic as we want to turn on the loads @@ -84,9 +86,7 @@ void app_powerManager_EfuseProtocolTick_100Hz(void) app_timer_init(&sequencing_timer, efuse_retry_timeout); app_timer_restart(&sequencing_timer); } - io_efuse_setChannel( - efuse_channels[current_efuse_sequence], - power_manager_state.efuse_configs[current_efuse_sequence].efuse_enable); + io_efuse_setChannel(channel, power_manager_state.efuse_configs[current_efuse_sequence].efuse_enable); } break; } diff --git a/firmware/quintuna/VC/src/app/app_pumpControl.c b/firmware/quintuna/VC/src/app/app_pumpControl.c index c516d08953..54f6f03e76 100644 --- a/firmware/quintuna/VC/src/app/app_pumpControl.c +++ b/firmware/quintuna/VC/src/app/app_pumpControl.c @@ -1,7 +1,6 @@ #include "app_pumpControl.h" #include "io_efuses.h" #include "io_time.h" -#include "io_loadswitches.h" #include #define SLOPE (0.5f) @@ -40,11 +39,11 @@ static void pumpControl_stopFlow(void) void app_pumpControl_MonitorPumps(void) { time += 10; - const bool pumps_ok = true - const bool pumps_enabled = true; + const bool pumps_ok = io_efuse_pgood(&rl_pump_efuse); + const bool pumps_enabled = io_efuse_isChannelEnabled(&rl_pump_efuse); - bool ramp_up_pumps = pumps_ok && pumps_enabled; + const bool ramp_up_pumps = pumps_ok && pumps_enabled; if (ramp_up_pumps) pumpControl_rampUp(); diff --git a/firmware/quintuna/VC/src/app/states/app_hvInitState.c b/firmware/quintuna/VC/src/app/states/app_hvInitState.c index f0dcdf2ce5..ffde4ed739 100644 --- a/firmware/quintuna/VC/src/app/states/app_hvInitState.c +++ b/firmware/quintuna/VC/src/app/states/app_hvInitState.c @@ -4,7 +4,6 @@ #include "app_timer.h" #include "app_canAlerts.h" #include "app_warningHandling.h" -#include "io_loadswitches.h" #include "app_canTx.h" #include "app_canRx.h" #include "app_canUtils.h" diff --git a/firmware/quintuna/VC/src/app/states/app_hvState.c b/firmware/quintuna/VC/src/app/states/app_hvState.c index e71948cae6..22162a9b20 100644 --- a/firmware/quintuna/VC/src/app/states/app_hvState.c +++ b/firmware/quintuna/VC/src/app/states/app_hvState.c @@ -3,7 +3,6 @@ #include "app_powerManager.h" #include "app_startSwitch.h" #include "app_warningHandling.h" -#include "io_loadswitches.h" #include #include #include diff --git a/firmware/quintuna/VC/src/io/io_efuses.c b/firmware/quintuna/VC/src/io/io_efuses.c index d40a8b494d..a5ae182801 100644 --- a/firmware/quintuna/VC/src/io/io_efuses.c +++ b/firmware/quintuna/VC/src/io/io_efuses.c @@ -2,7 +2,8 @@ #include "hw_gpios.h" #include "hw_i2cs.h" #include "io_efuses.h" -#include +#include "io_efuse/io_efuse_ST/io_efuse_ST.h" +#include "io_efuse/io_efuse_TI/io_efuse_TI.h" static ST_Efuse f_inv_st_efuse = { .stby_reset_gpio = &fr_stby_inv }; static ST_Efuse rsm_st_efuse = { .stby_reset_gpio = &fr_stby_inv }; @@ -13,52 +14,47 @@ static ST_Efuse front_st_efuse = { .stby_reset_gpio = &fr_stby_rear }; static TI_Efuse rl_pump_ti_efuse = { .pgood = &rl_pump_pgood }; static ST_Efuse r_rad_fan_st_efuse = { .stby_reset_gpio = &fr_stby_rad }; -static Efuse f_inv_efuse = { .enable_gpio = &f_inv_en, - .sns_adc_channel = &inv_f_pwr_i_sns, - .st = &f_inv_st_efuse, - .efuse_functions = st_efuse_functions }; - -static Efuse f_inv_efuse = { .enable_gpio = &f_inv_en, - .sns_adc_channel = &inv_f_pwr_i_sns, - .st = &f_inv_st_efuse, - .efuse_functions = &st_efuse_functions }; - -static Efuse rsm_efuse = { .enable_gpio = &rsm_en, - .sns_adc_channel = &rsm_i_sns, - .st = &f_inv_st_efuse, - .efuse_functions = &st_efuse_functions }; - -static Efuse bms_efuse = { .enable_gpio = &bms_en, - .sns_adc_channel = &bms_i_sns, - .st = &bms_st_efuse, - .efuse_functions = &st_efuse_functions }; - -static Efuse r_inv_efuse = { .enable_gpio = &r_inv_en, - .sns_adc_channel = &inv_r_pwr_i_sns, - .st = &r_inv_st_efuse, - .efuse_functions = &st_efuse_functions }; - -static Efuse dam_efuse = { .enable_gpio = &dam_en, - .sns_adc_channel = &dam_i_sns, - .st = &dam_st_efuse, - .efuse_functions = &st_efuse_functions }; - -static Efuse front_efuse = { .enable_gpio = &front_en, - .sns_adc_channel = &front_i_sns, - .st = &front_st_efuse, - .efuse_functions = &st_efuse_functions }; - -static Efuse rl_pump_efuse = { .enable_gpio = &rl_pump_en, - .sns_adc_channel = &pump_rl_pwr_i_sns, - .ti = &rl_pump_ti_efuse, - .efuse_functions = &ti_efuse_functions }; - -static Efuse r_rad_fan_efuse = { .enable_gpio = &rr_rad_fan_en, - .sns_adc_channel = &r_rad_fan_i_sns, - .st = &r_rad_fan_st_efuse, - .efuse_functions = &ti_efuse_functions }; - -Efuse *const efuse_channels[NUM_EFUSE_CHANNELS] = { +const Efuse f_inv_efuse = { .enable_gpio = &f_inv_en, + .sns_adc_channel = &inv_f_pwr_i_sns, + .st = &f_inv_st_efuse, + .efuse_functions = &st_efuse_functions }; + +const Efuse rsm_efuse = { .enable_gpio = &rsm_en, + .sns_adc_channel = &rsm_i_sns, + .st = &f_inv_st_efuse, + .efuse_functions = &st_efuse_functions }; + +const Efuse bms_efuse = { .enable_gpio = &bms_en, + .sns_adc_channel = &bms_i_sns, + .st = &bms_st_efuse, + .efuse_functions = &st_efuse_functions }; + +const Efuse r_inv_efuse = { .enable_gpio = &r_inv_en, + .sns_adc_channel = &inv_r_pwr_i_sns, + .st = &r_inv_st_efuse, + .efuse_functions = &st_efuse_functions }; + +const Efuse dam_efuse = { .enable_gpio = &dam_en, + .sns_adc_channel = &dam_i_sns, + .st = &dam_st_efuse, + .efuse_functions = &st_efuse_functions }; + +const Efuse front_efuse = { .enable_gpio = &front_en, + .sns_adc_channel = &front_i_sns, + .st = &front_st_efuse, + .efuse_functions = &st_efuse_functions }; + +const Efuse rl_pump_efuse = { .enable_gpio = &rl_pump_en, + .sns_adc_channel = &pump_rl_pwr_i_sns, + .ti = &rl_pump_ti_efuse, + .efuse_functions = &ti_efuse_functions }; + +const Efuse r_rad_fan_efuse = { .enable_gpio = &rr_rad_fan_en, + .sns_adc_channel = &r_rad_fan_i_sns, + .st = &r_rad_fan_st_efuse, + .efuse_functions = &ti_efuse_functions }; + +const Efuse *const efuse_channels[NUM_EFUSE_CHANNELS] = { [EFUSE_CHANNEL_F_INV] = &f_inv_efuse, [EFUSE_CHANNEL_RSM] = &rsm_efuse, [EFUSE_CHANNEL_BMS] = &bms_efuse, [EFUSE_CHANNEL_R_INV] = &r_inv_efuse, [EFUSE_CHANNEL_DAM] = &dam_efuse, [EFUSE_CHANNEL_FRONT] = &front_efuse, diff --git a/firmware/quintuna/VC/src/io/io_efuses.h b/firmware/quintuna/VC/src/io/io_efuses.h index c3cebf4f86..76e67b5722 100644 --- a/firmware/quintuna/VC/src/io/io_efuses.h +++ b/firmware/quintuna/VC/src/io/io_efuses.h @@ -23,6 +23,15 @@ typedef enum EFUSE_CHANNEL_R_RAD, NUM_EFUSE_CHANNELS -} LoadswitchChannel; - -extern Efuse *const efuse_channels[NUM_EFUSE_CHANNELS]; +} EfuseChannel; + +extern const Efuse *const efuse_channels[NUM_EFUSE_CHANNELS]; + +extern const Efuse f_inv_efuse; +extern const Efuse rsm_efuse; +extern const Efuse bms_efuse; +extern const Efuse r_inv_efuse; +extern const Efuse dam_efuse; +extern const Efuse front_efuse; +extern const Efuse rl_pump_efuse; +extern const Efuse r_rad_fan_efuse; diff --git a/firmware/shared/src/io/io_efuse/io_efuse.c b/firmware/shared/src/io/io_efuse/io_efuse.c index c4933be1dc..766d780930 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse.c +++ b/firmware/shared/src/io/io_efuse/io_efuse.c @@ -1,10 +1,10 @@ #include "io_efuse.h" -#include "io_efuse_datatypes.h" +// #include "io_efuse_datatypes.h" #include "hw_gpio.h" #include #include -void io_efuse_setChannel(const Efuse *channel, const bool enabled) +void io_efuse_setChannel(const Efuse *channel, bool enabled) { assert(channel != NULL); @@ -23,10 +23,12 @@ float io_efuse_getChannelCurrent(const Efuse *channel) return channel->efuse_functions->get_channel_current(channel); } -void io_efuse_reset_set(const Efuse *channel, const bool set) +void io_efuse_reset_set(const Efuse *channel, bool set) { assert(channel != NULL); - channel->efuse_functions->loadswitch_reset_set(channel); + assert(channel->efuse_functions->loadswitch_reset_set != NULL); + + channel->efuse_functions->loadswitch_reset_set(channel, set); } void io_efuse_reset(const Efuse *channel) @@ -34,3 +36,17 @@ void io_efuse_reset(const Efuse *channel) assert(channel != NULL); channel->efuse_functions->reset_efuse(channel); } + +bool io_efuse_pgood(const Efuse *channel) +{ + assert(channel != NULL); + assert(channel->efuse_functions->pgood != NULL); + + return channel->efuse_functions->pgood(channel); +} + +bool io_efuse_ok(const Efuse *efuse) +{ + assert(efuse != NULL); + return efuse->efuse_functions->efuse_ok(efuse); +} diff --git a/firmware/shared/src/io/io_efuse/io_efuse.h b/firmware/shared/src/io/io_efuse/io_efuse.h index 7aead6632a..f63903e879 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse.h +++ b/firmware/shared/src/io/io_efuse/io_efuse.h @@ -2,8 +2,10 @@ #include #include "io_efuse_datatypes.h" -#include "io_efuse_ST/io_efuse_ST.h" -#include "io_efuse_TI/io_efuse_TI.h" +// #include "io_efuse_ST/io_efuse_ST.h" +// #include "io_efuse_TI/io_efuse_TI.h" + +typedef struct __Efuse Efuse; /** * Enable or disable the provided efuse channel. @@ -34,4 +36,18 @@ void io_efuse_reset_set(const Efuse *channel, bool set); * Reset the hardfault set by the efuse * @param efuse Reset the hardfault set by efuse */ -void io_efuse_reset(const Efuse *channel); \ No newline at end of file +void io_efuse_reset(const Efuse *channel); + +/** + * @brief Check the pgood status + * @param channel: TI Efuse + * @return status of the pgood line + */ +bool io_efuse_pgood(const Efuse *channel); + +/** + * @brief Check the if the efuse status is ok + * @param efuse: efuse to check status on + * @return True if status is ok, False otherwise + */ +bool io_efuse_ok(const Efuse *efuse); diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c index 6f748da9ea..1228f1e285 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c @@ -1,21 +1,33 @@ #include "io_efuse_ST.h" +#include "io_efuse/io_efuse_datatypes.h" #include "hw_gpio.h" #include #include -static void io_efuse_ST_setChannel(const Efuse *channel, const bool enabled); +/** + * ST Efuse Datasheet: + * https://octopart.com/datasheet/vnd5t100ajtr-e-stmicroelectronics-21218840 + */ + +static float NOMINAL_V = 3.0f; +static uint8_t ST_EFUSE_FAULT_FLAGS = 0x3F; + +static void io_efuse_ST_setChannel(const Efuse *channel, bool enabled); static bool io_efuse_ST_isChannelEnabled(const Efuse *channel); static float io_efuse_ST_getChannelCurrent(const Efuse *channel); -static void io_efuse_ST_reset_set(const Efuse *channel, const bool set); -static void io_efuse_ST_Reset(const Efuse *channel); +static void io_efuse_ST_reset_set(const Efuse *channel, bool set); +static void io_efuse_ST_reset(const Efuse *channel); +static bool io_efuse_ST_ok(const Efuse *efuse); const EfuseFunctions st_efuse_functions = { .set_channel = io_efuse_ST_setChannel, .is_channel_enabled = io_efuse_ST_isChannelEnabled, .get_channel_current = io_efuse_ST_getChannelCurrent, .loadswitch_reset_set = io_efuse_ST_reset_set, - .reset_efuse = io_efuse_ST_Reset }; + .reset_efuse = io_efuse_ST_reset, + .pgood = NULL, + .efuse_ok = io_efuse_ST_ok }; -static void io_efuse_ST_setChannel(const Efuse *channel, const bool enabled) +static void io_efuse_ST_setChannel(const Efuse *channel, bool enabled) { assert(channel->enable_gpio != NULL); hw_gpio_writePin(channel->enable_gpio, enabled); @@ -34,16 +46,38 @@ static float io_efuse_ST_getChannelCurrent(const Efuse *channel) return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; } -static void io_efuse_ST_reset_set(const Efuse *channel, const bool set) +static void io_efuse_ST_reset_set(const Efuse *channel, bool set) { assert(channel->st->stby_reset_gpio != NULL); hw_gpio_writePin(channel->st->stby_reset_gpio, set); } -static void io_efuse_ST_Reset(const Efuse *channel) +static void io_efuse_ST_reset(const Efuse *channel) { assert(channel->st->stby_reset_gpio != NULL); hw_gpio_writePin(channel->st->stby_reset_gpio, false); hw_gpio_writePin(channel->st->stby_reset_gpio, true); hw_gpio_writePin(channel->st->stby_reset_gpio, false); -} \ No newline at end of file +} + +static bool io_efuse_ST_ok(const Efuse *efuse) +{ + assert(efuse != NULL); + + float voltage = io_efuse_ST_getChannelCurrent(efuse) / ADC_VOLTAGE_TO_CURRENT_A; + bool channelEnabled = io_efuse_ST_isChannelEnabled(efuse); + + // Setting faults for st efuse + // TODO: these probably are not correct they must be fixed + efuse->st->faults.flags.under_voltage = (voltage <= 0.0f); + efuse->st->faults.flags.short_to_vbat = (voltage >= NOMINAL_V && channelEnabled); + efuse->st->faults.flags.overload = (voltage > NOMINAL_V && channelEnabled); + efuse->st->faults.flags.ovt_stp = (voltage >= NOMINAL_V && channelEnabled); + efuse->st->faults.flags.negative_output_voltage_clamp = (voltage <= 0.0f && !channelEnabled); + efuse->st->faults.flags.open_load_off_stat = (voltage >= NOMINAL_V); + + // check if any flag is set, then return the status + uint8_t flags = efuse->st->faults.raw & ST_EFUSE_FAULT_FLAGS; + + return !(flags > 0); +} diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h index 53b803135e..387239859f 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h @@ -4,22 +4,27 @@ #include #include "hw_gpio.h" #include "hw_adc.h" -#include "io_efuse/io_efuse_datatypes.h" + +typedef struct __EfuseFunctions EfuseFunctions; typedef struct __ST_Efuse { const Gpio *stby_reset_gpio; /* Portable bit-fields: use 'unsigned' and name the subgroup */ - struct + union { - uint8_t overload : 1; - uint8_t ovt_stp : 1; - uint8_t under_voltage : 1; - uint8_t short_to_vbat : 1; - uint8_t open_load_off_stat : 1; - uint8_t negative_output_voltage_clamp : 1; - uint8_t padding : 2; + struct + { + uint8_t overload : 1; + uint8_t ovt_stp : 1; + uint8_t under_voltage : 1; + uint8_t short_to_vbat : 1; + uint8_t open_load_off_stat : 1; + uint8_t negative_output_voltage_clamp : 1; + uint8_t padding : 2; + } flags; + uint8_t raw; } faults; } ST_Efuse; diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c index b099c25b89..764c68ccfa 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c @@ -1,23 +1,24 @@ #include "io_efuse_TI.h" +#include "io_efuse/io_efuse_datatypes.h" #include "hw_gpio.h" #include #include -static void io_TI_efuse_setChannel(const Efuse *channel, const bool enabled); +static void io_TI_efuse_setChannel(const Efuse *channel, bool enabled); static bool io_TI_efuse_isChannelEnabled(const Efuse *channel); static float io_TI_efuse_getChannelCurrent(const Efuse *channel); -static void io_TI_efuse_Reset(const Efuse *efuse); -// static bool io_TI_efuse_pgood(const Efuse *efuse); - -const EfuseFunctions ti_efuse_functions = { - .set_channel = io_TI_efuse_setChannel, - .is_channel_enabled = io_TI_efuse_isChannelEnabled, - .get_channel_current = io_TI_efuse_getChannelCurrent, - .loadswitch_reset_set = NULL, - .reset_efuse = io_TI_efuse_Reset, -}; - -static void io_TI_efuse_setChannel(const Efuse *channel, const bool enabled) +static void io_TI_efuse_reset(const Efuse *efuse); +static bool io_TI_efuse_pgood(const Efuse *efuse); + +const EfuseFunctions ti_efuse_functions = { .set_channel = io_TI_efuse_setChannel, + .is_channel_enabled = io_TI_efuse_isChannelEnabled, + .get_channel_current = io_TI_efuse_getChannelCurrent, + .loadswitch_reset_set = NULL, + .reset_efuse = io_TI_efuse_reset, + .pgood = io_TI_efuse_pgood, + .efuse_ok = io_TI_efuse_pgood }; + +static void io_TI_efuse_setChannel(const Efuse *channel, bool enabled) { assert(channel->enable_gpio != NULL); hw_gpio_writePin(channel->enable_gpio, enabled); @@ -36,7 +37,7 @@ static float io_TI_efuse_getChannelCurrent(const Efuse *channel) return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; } -static void io_TI_efuse_Reset(const Efuse *efuse) +static void io_TI_efuse_reset(const Efuse *efuse) { assert(efuse->enable_gpio != NULL); @@ -45,8 +46,8 @@ static void io_TI_efuse_Reset(const Efuse *efuse) hw_gpio_writePin(efuse->enable_gpio, false); } -// static bool io_TI_efuse_pgood(const Efuse *efuse) -// { -// assert(efuse->pgood != NULL); -// return hw_gpio_readPin(efuse->pgood); -// } +static bool io_TI_efuse_pgood(const Efuse *efuse) +{ + assert(efuse->ti->pgood != NULL); + return hw_gpio_readPin(efuse->ti->pgood); +} diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h index 5d0f86597b..34955e4d86 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h @@ -4,7 +4,8 @@ #include #include "hw_gpio.h" #include "hw_adc.h" -#include "io_efuse/io_efuse_datatypes.h" + +typedef struct __EfuseFunctions EfuseFunctions; typedef struct __TI_Efuse { diff --git a/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h index e3ea3aa7cd..4165af7e75 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h @@ -1,27 +1,28 @@ #pragma once +#include #include "hw_gpio.h" #include "hw_adc.h" -#include "io_efuse_ST/io_efuse_ST.H" -#include "io_efuse_TI/io_efuse_TI.h" #define ADC_VOLTAGE_TO_CURRENT_A 1.720f -typedef struct __Efuse Efuse; -typedef struct __ST_Efuse ST_Efuse; -typedef struct __TI_Efuse TI_Efuse; +typedef struct __Efuse Efuse; +typedef struct __ST_Efuse ST_Efuse; +typedef struct __TI_Efuse TI_Efuse; +typedef struct __EfuseFunctions EfuseFunctions; -typedef struct +struct __EfuseFunctions { - void (*set_channel)(Efuse *channel, bool enabled); + void (*set_channel)(const Efuse *channel, bool enabled); bool (*is_channel_enabled)(const Efuse *channel); - bool (*get_channel_current)(const Efuse *channel); - void (*loadswitch_reset_set)(const Efuse *channel, const bool set); + float (*get_channel_current)(const Efuse *channel); + void (*loadswitch_reset_set)(const Efuse *channel, bool set); void (*reset_efuse)(const Efuse *channel); + bool (*pgood)(const Efuse *channel); + bool (*efuse_ok)(const Efuse *efuse); +}; -} EfuseFunctions; - -typedef struct __Efuse +struct __Efuse { const Gpio *enable_gpio; const AdcChannel *sns_adc_channel; @@ -31,5 +32,5 @@ typedef struct __Efuse TI_Efuse *ti; }; - EfuseFunctions *efuse_functions; -} Efuse; + const EfuseFunctions *efuse_functions; +}; From a928e00dbc1461f6d515559ede0eadf10de9be5b Mon Sep 17 00:00:00 2001 From: Aditya-Dhiman4 Date: Tue, 21 Oct 2025 00:07:53 -0700 Subject: [PATCH 05/12] baseline EFuse C++ Refactor --- firmware/shared/srcpp/io/efuse/io_efuse.hpp | 28 +++++++++++++ firmware/shared/srcpp/io/efuse/io_efuseST.cpp | 40 +++++++++++++++++++ firmware/shared/srcpp/io/efuse/io_efuseST.hpp | 37 +++++++++++++++++ firmware/shared/srcpp/io/efuse/io_efuseTI.cpp | 39 ++++++++++++++++++ firmware/shared/srcpp/io/efuse/io_efuseTI.hpp | 23 +++++++++++ 5 files changed, 167 insertions(+) create mode 100644 firmware/shared/srcpp/io/efuse/io_efuse.hpp create mode 100644 firmware/shared/srcpp/io/efuse/io_efuseST.cpp create mode 100644 firmware/shared/srcpp/io/efuse/io_efuseST.hpp create mode 100644 firmware/shared/srcpp/io/efuse/io_efuseTI.cpp create mode 100644 firmware/shared/srcpp/io/efuse/io_efuseTI.hpp diff --git a/firmware/shared/srcpp/io/efuse/io_efuse.hpp b/firmware/shared/srcpp/io/efuse/io_efuse.hpp new file mode 100644 index 0000000000..c0343cf6d7 --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuse.hpp @@ -0,0 +1,28 @@ +#pragma once +#include + +#include "hw_gpio.hpp" +#include "hw_adc.hpp" + +namespace io::efuse +{ + class Efuse + { + protected: + static constexpr float ADC_VOLTAGE_TO_CURRENT_A = 1.720f; + const hw::Gpio &enable_gpio; + const hw::Adc &sns_adc_channel; + + public: + Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel) + : enable_gpio(enable_gpio), sns_adc_channel(sns_adc_channel) {} + virtual ~Efuse() = default; + virtual void setChannel(bool enabled) = 0; + virtual const bool isChannelEnabled() = 0; + virtual const float getChannelCurrent() = 0; + virtual void resetSet(bool set) = 0; + virtual void reset() = 0; + virtual const bool pgood() = 0; + virtual const bool ok() = 0; + }; +} \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuseST.cpp b/firmware/shared/srcpp/io/efuse/io_efuseST.cpp new file mode 100644 index 0000000000..834b700d5a --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuseST.cpp @@ -0,0 +1,40 @@ +#include +#include "io_efuseST.hpp" +#include "hw_gpio.hpp" + +namespace io::efuse +{ + ST_Efuse::ST_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &stby_reset_gpio) + : Efuse(enable_gpio, sns_adc_channel), stby_reset_gpio(stby_reset_gpio) {} + + void ST_Efuse::setChannel(bool enabled) { + this->enable_gpio.writePin(enabled); + } + + const bool ST_Efuse::isChannelEnabled() { + return this->enable_gpio.readPin(); + } + + const float ST_Efuse::getChannelCurrent() { + return this->sns_adc_channel.getVoltage() * ADC_VOLTAGE_TO_CURRENT_A; + } + + void ST_Efuse::resetSet(bool set) { + this->stby_reset_gpio.writePin(set); + } + + void ST_Efuse::reset() { + this->stby_reset_gpio.writePin(false); + this->stby_reset_gpio.writePin(true); + this->stby_reset_gpio.writePin(false); + } + + // const bool ST_Efuse::pgood() { + + // } + + const bool ST_Efuse::ok() { + + } + +} \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuseST.hpp b/firmware/shared/srcpp/io/efuse/io_efuseST.hpp new file mode 100644 index 0000000000..c16fb4eb4e --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuseST.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include +#include "io_efuse.hpp" + +namespace io::efuse +{ + class ST_Efuse : public Efuse + { + private: + const hw::Gpio &stby_reset_gpio; + union + { + struct + { + uint8_t overload : 1; + uint8_t ovt_stp : 1; + uint8_t under_voltage : 1; + uint8_t short_to_vbat : 1; + uint8_t open_load_off_stat : 1; + uint8_t negative_output_voltage_clamp : 1; + uint8_t padding : 2; + } flags; + uint8_t raw; + } faults; + + public: + explicit ST_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &stby_reset_gpio); + void setChannel(bool enabled) override; + const bool isChannelEnabled() override; + const float getChannelCurrent() override; + void resetSet(bool set) override; + void reset() override; + const bool pgood() override; + const bool ok() override; + }; +} \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuseTI.cpp b/firmware/shared/srcpp/io/efuse/io_efuseTI.cpp new file mode 100644 index 0000000000..1fa3ef2d17 --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuseTI.cpp @@ -0,0 +1,39 @@ +#include +#include "io_efuseTI.hpp" +#include "hw_gpio.hpp" + +namespace io::efuse +{ + TI_Efuse::TI_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio& pgood) + : Efuse(enable_gpio, sns_adc_channel) , pgood_gpio(pgood) {} + + void TI_Efuse::setChannel(bool enabled) { + this->enable_gpio.writePin(enabled); + } + + const bool TI_Efuse::isChannelEnabled() { + return this->enable_gpio.readPin(); + } + + const float TI_Efuse::getChannelCurrent() { + return this->sns_adc_channel.getVoltage() * ADC_VOLTAGE_TO_CURRENT_A; + } + + // void TI_Efuse::resetSet(bool set) { + + // } + + void TI_Efuse::reset() { + this->enable_gpio.writePin(false); + this->enable_gpio.writePin(true); + this->enable_gpio.writePin(false); + } + + const bool TI_Efuse::pgood() { + return this->pgood_gpio.readPin(); + } + + const bool TI_Efuse::ok() { + return this->pgood(); + } +} \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuseTI.hpp b/firmware/shared/srcpp/io/efuse/io_efuseTI.hpp new file mode 100644 index 0000000000..e9ec903b17 --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuseTI.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include "io_efuse.hpp" + +namespace io::efuse +{ + class TI_Efuse : public Efuse + { + private: + const hw::Gpio& pgood_gpio; + + public: + explicit TI_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio& pgood); + void setChannel(bool enabled) override; + const bool isChannelEnabled() override; + const float getChannelCurrent() override; + void resetSet(bool set) override; + void reset() override; + const bool pgood() override; + const bool ok() override; + }; +} \ No newline at end of file From 2d2cdcc0e8bc9221f8c0af71b0d4371e3c857304 Mon Sep 17 00:00:00 2001 From: Aditya-Dhiman4 Date: Wed, 22 Oct 2025 22:44:13 -0700 Subject: [PATCH 06/12] Efuse C++ refactor mostly complete, just have ok function left and testing --- firmware/shared/srcpp/io/efuse/io_efuse.cpp | 24 ++++++++++++++ firmware/shared/srcpp/io/efuse/io_efuse.hpp | 8 ++--- firmware/shared/srcpp/io/efuse/io_efuseTI.cpp | 16 --------- firmware/shared/srcpp/io/efuse/io_efuseTI.hpp | 4 --- .../srcpp/io/efuse/io_efuse_ST_VND5.cpp | 28 ++++++++++++++++ .../srcpp/io/efuse/io_efuse_ST_VND5.hpp | 33 +++++++++++++++++++ 6 files changed, 88 insertions(+), 25 deletions(-) create mode 100644 firmware/shared/srcpp/io/efuse/io_efuse.cpp create mode 100644 firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp create mode 100644 firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp diff --git a/firmware/shared/srcpp/io/efuse/io_efuse.cpp b/firmware/shared/srcpp/io/efuse/io_efuse.cpp new file mode 100644 index 0000000000..8f16550578 --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuse.cpp @@ -0,0 +1,24 @@ +#include "io_efuse.hpp" +#include "hw_gpio.hpp" +#include "hw_adc.hpp" + +namespace io::efuse +{ + Efuse::Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel) + : enable_gpio(enable_gpio), sns_adc_channel(sns_adc_channel) {} + + void Efuse::setChannel(bool enabled) + { + this->enable_gpio.writePin(enabled); + } + + const bool Efuse::isChannelEnabled() + { + return this->enable_gpio.readPin(); + } + + const float Efuse::getChannelCurrent() + { + return this->sns_adc_channel.getVoltage() * ADC_VOLTAGE_TO_CURRENT_A; + } +} \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse.hpp b/firmware/shared/srcpp/io/efuse/io_efuse.hpp index c0343cf6d7..6a72e4b92e 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse.hpp @@ -17,12 +17,10 @@ namespace io::efuse Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel) : enable_gpio(enable_gpio), sns_adc_channel(sns_adc_channel) {} virtual ~Efuse() = default; - virtual void setChannel(bool enabled) = 0; - virtual const bool isChannelEnabled() = 0; - virtual const float getChannelCurrent() = 0; - virtual void resetSet(bool set) = 0; + void setChannel(bool enabled); + const bool isChannelEnabled(); + const float getChannelCurrent(); virtual void reset() = 0; - virtual const bool pgood() = 0; virtual const bool ok() = 0; }; } \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuseTI.cpp b/firmware/shared/srcpp/io/efuse/io_efuseTI.cpp index 1fa3ef2d17..60e5e9b9b4 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuseTI.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuseTI.cpp @@ -7,22 +7,6 @@ namespace io::efuse TI_Efuse::TI_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio& pgood) : Efuse(enable_gpio, sns_adc_channel) , pgood_gpio(pgood) {} - void TI_Efuse::setChannel(bool enabled) { - this->enable_gpio.writePin(enabled); - } - - const bool TI_Efuse::isChannelEnabled() { - return this->enable_gpio.readPin(); - } - - const float TI_Efuse::getChannelCurrent() { - return this->sns_adc_channel.getVoltage() * ADC_VOLTAGE_TO_CURRENT_A; - } - - // void TI_Efuse::resetSet(bool set) { - - // } - void TI_Efuse::reset() { this->enable_gpio.writePin(false); this->enable_gpio.writePin(true); diff --git a/firmware/shared/srcpp/io/efuse/io_efuseTI.hpp b/firmware/shared/srcpp/io/efuse/io_efuseTI.hpp index e9ec903b17..e24fe1bbae 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuseTI.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuseTI.hpp @@ -12,10 +12,6 @@ namespace io::efuse public: explicit TI_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio& pgood); - void setChannel(bool enabled) override; - const bool isChannelEnabled() override; - const float getChannelCurrent() override; - void resetSet(bool set) override; void reset() override; const bool pgood() override; const bool ok() override; diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp new file mode 100644 index 0000000000..1fbef67d51 --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp @@ -0,0 +1,28 @@ +#include "io_efuse_ST_VND5.hpp" +#include "hw_gpio.hpp" + +namespace io::efuse +{ + ST_VND5_Efuse::ST_VND5_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &stby_reset_gpio) + : Efuse(enable_gpio, sns_adc_channel), stby_reset_gpio(stby_reset_gpio) {} + + void ST_VND5_Efuse::reset() + { + this->stby_reset_gpio.writePin(false); + this->stby_reset_gpio.writePin(true); + this->stby_reset_gpio.writePin(false); + } + + void ST_VND5_Efuse::resetSet(const bool set) + { + this->stby_reset_gpio.writePin(set); + } + + const bool ST_VND5_Efuse::ok() + { + // TODO: implement this function + + return true; + } + +} \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp new file mode 100644 index 0000000000..284f79cad2 --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include "io_efuse.hpp" + +namespace io::efuse +{ + class ST_VND5_Efuse : public Efuse + { + private: + const hw::Gpio &stby_reset_gpio; + union + { + struct + { + uint8_t overload : 1; + uint8_t ovt_stp : 1; + uint8_t under_voltage : 1; + uint8_t short_to_vbat : 1; + uint8_t open_load_off_stat : 1; + uint8_t negative_output_voltage_clamp : 1; + uint8_t padding : 2; + } flags; + uint8_t raw; + } faults; + + public: + explicit ST_VND5_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &stby_reset_gpio); + void reset() override; + void resetSet(const bool set); + const bool ok() override; + }; +} \ No newline at end of file From 323442c24b7c7ce6a9f8eb855c96c952f8126721 Mon Sep 17 00:00:00 2001 From: Aditya-Dhiman4 Date: Sat, 25 Oct 2025 20:46:56 -0700 Subject: [PATCH 07/12] renamed efuses and implemented ok function --- firmware/shared/srcpp/io/efuse/io_efuse.hpp | 2 +- firmware/shared/srcpp/io/efuse/io_efuseST.cpp | 40 ----------------- firmware/shared/srcpp/io/efuse/io_efuseST.hpp | 37 ---------------- .../srcpp/io/efuse/io_efuse_ST_VND5.cpp | 44 ++++++++++++++++--- .../srcpp/io/efuse/io_efuse_ST_VND5.hpp | 4 +- .../{io_efuseTI.cpp => io_efuse_TI_TPS2.cpp} | 12 ++--- .../{io_efuseTI.hpp => io_efuse_TI_TPS2.hpp} | 8 ++-- 7 files changed, 52 insertions(+), 95 deletions(-) delete mode 100644 firmware/shared/srcpp/io/efuse/io_efuseST.cpp delete mode 100644 firmware/shared/srcpp/io/efuse/io_efuseST.hpp rename firmware/shared/srcpp/io/efuse/{io_efuseTI.cpp => io_efuse_TI_TPS2.cpp} (54%) rename firmware/shared/srcpp/io/efuse/{io_efuseTI.hpp => io_efuse_TI_TPS2.hpp} (51%) diff --git a/firmware/shared/srcpp/io/efuse/io_efuse.hpp b/firmware/shared/srcpp/io/efuse/io_efuse.hpp index 6a72e4b92e..1b3175410d 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse.hpp @@ -4,7 +4,7 @@ #include "hw_gpio.hpp" #include "hw_adc.hpp" -namespace io::efuse +namespace io { class Efuse { diff --git a/firmware/shared/srcpp/io/efuse/io_efuseST.cpp b/firmware/shared/srcpp/io/efuse/io_efuseST.cpp deleted file mode 100644 index 834b700d5a..0000000000 --- a/firmware/shared/srcpp/io/efuse/io_efuseST.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include "io_efuseST.hpp" -#include "hw_gpio.hpp" - -namespace io::efuse -{ - ST_Efuse::ST_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &stby_reset_gpio) - : Efuse(enable_gpio, sns_adc_channel), stby_reset_gpio(stby_reset_gpio) {} - - void ST_Efuse::setChannel(bool enabled) { - this->enable_gpio.writePin(enabled); - } - - const bool ST_Efuse::isChannelEnabled() { - return this->enable_gpio.readPin(); - } - - const float ST_Efuse::getChannelCurrent() { - return this->sns_adc_channel.getVoltage() * ADC_VOLTAGE_TO_CURRENT_A; - } - - void ST_Efuse::resetSet(bool set) { - this->stby_reset_gpio.writePin(set); - } - - void ST_Efuse::reset() { - this->stby_reset_gpio.writePin(false); - this->stby_reset_gpio.writePin(true); - this->stby_reset_gpio.writePin(false); - } - - // const bool ST_Efuse::pgood() { - - // } - - const bool ST_Efuse::ok() { - - } - -} \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuseST.hpp b/firmware/shared/srcpp/io/efuse/io_efuseST.hpp deleted file mode 100644 index c16fb4eb4e..0000000000 --- a/firmware/shared/srcpp/io/efuse/io_efuseST.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include "io_efuse.hpp" - -namespace io::efuse -{ - class ST_Efuse : public Efuse - { - private: - const hw::Gpio &stby_reset_gpio; - union - { - struct - { - uint8_t overload : 1; - uint8_t ovt_stp : 1; - uint8_t under_voltage : 1; - uint8_t short_to_vbat : 1; - uint8_t open_load_off_stat : 1; - uint8_t negative_output_voltage_clamp : 1; - uint8_t padding : 2; - } flags; - uint8_t raw; - } faults; - - public: - explicit ST_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &stby_reset_gpio); - void setChannel(bool enabled) override; - const bool isChannelEnabled() override; - const float getChannelCurrent() override; - void resetSet(bool set) override; - void reset() override; - const bool pgood() override; - const bool ok() override; - }; -} \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp index 1fbef67d51..bbcf00274d 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp @@ -1,10 +1,26 @@ +extern "C" +{ + #include "app_utils.h" +} + #include "io_efuse_ST_VND5.hpp" #include "hw_gpio.hpp" -namespace io::efuse +namespace io { - ST_VND5_Efuse::ST_VND5_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &stby_reset_gpio) - : Efuse(enable_gpio, sns_adc_channel), stby_reset_gpio(stby_reset_gpio) {} +static constexpr float NOMINAL_V = 3.0f; +// Vsenseh upper threshold +static constexpr float V_SENSE_H_H = 9.5f; +// Vsenseh lower threshold +static constexpr float V_SENSE_H_L = 7.5f; + +ST_VND5_Efuse::ST_VND5_Efuse( + const hw::Gpio &enable_gpio, + const hw::Adc &sns_adc_channel, + const hw::Gpio &stby_reset_gpio) + : Efuse(enable_gpio, sns_adc_channel), stby_reset_gpio(stby_reset_gpio) +{ +} void ST_VND5_Efuse::reset() { @@ -20,9 +36,27 @@ namespace io::efuse const bool ST_VND5_Efuse::ok() { - // TODO: implement this function + // TODO: WTF is output??? + const bool input = this->enable_gpio.readPin(); + const bool fault_reset_stby = this->stby_reset_gpio.readPin(); + const float voltage = this->sns_adc_channel.getVoltage() / ADC_VOLTAGE_TO_CURRENT_A; + + this->faults.flags.overload = (input && (voltage > NOMINAL_V)); + this->faults.flags.ovt_stg = (input && (IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage))); + this->faults.flags.under_voltage = (voltage <= 0.0f); + if (fault_reset_stby) + this->faults.flags.short_to_vbat = (!input && IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage)); + else + this->faults.flags.short_to_vbat = (input && (voltage < NOMINAL_V)); + + if (fault_reset_stby) + this->faults.flags.open_load_off_stat = (!input && IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage)); + else + this->faults.flags.open_load_off_stat = (input && voltage <= 0.0f); + + this->faults.flags.negative_output_voltage_clamp = (!input && voltage <= 0.0f); + return true; } - } \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp index 284f79cad2..289e1502e9 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp @@ -3,7 +3,7 @@ #include #include "io_efuse.hpp" -namespace io::efuse +namespace io { class ST_VND5_Efuse : public Efuse { @@ -14,7 +14,7 @@ namespace io::efuse struct { uint8_t overload : 1; - uint8_t ovt_stp : 1; + uint8_t ovt_stg : 1; uint8_t under_voltage : 1; uint8_t short_to_vbat : 1; uint8_t open_load_off_stat : 1; diff --git a/firmware/shared/srcpp/io/efuse/io_efuseTI.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.cpp similarity index 54% rename from firmware/shared/srcpp/io/efuse/io_efuseTI.cpp rename to firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.cpp index 60e5e9b9b4..32c28f1834 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuseTI.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.cpp @@ -1,23 +1,23 @@ #include -#include "io_efuseTI.hpp" +#include "io_efuse_TI_TPS2.hpp" #include "hw_gpio.hpp" -namespace io::efuse +namespace io { - TI_Efuse::TI_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio& pgood) + ST_TPS2_Efuse::ST_TPS2_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio& pgood) : Efuse(enable_gpio, sns_adc_channel) , pgood_gpio(pgood) {} - void TI_Efuse::reset() { + void ST_TPS2_Efuse::reset() { this->enable_gpio.writePin(false); this->enable_gpio.writePin(true); this->enable_gpio.writePin(false); } - const bool TI_Efuse::pgood() { + const bool ST_TPS2_Efuse::pgood() { return this->pgood_gpio.readPin(); } - const bool TI_Efuse::ok() { + const bool ST_TPS2_Efuse::ok() { return this->pgood(); } } \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuseTI.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.hpp similarity index 51% rename from firmware/shared/srcpp/io/efuse/io_efuseTI.hpp rename to firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.hpp index e24fe1bbae..6be1d6fb86 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuseTI.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.hpp @@ -3,17 +3,17 @@ #include #include "io_efuse.hpp" -namespace io::efuse +namespace io { - class TI_Efuse : public Efuse + class ST_TPS2_Efuse : public Efuse { private: const hw::Gpio& pgood_gpio; public: - explicit TI_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio& pgood); + explicit ST_TPS2_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio& pgood); void reset() override; - const bool pgood() override; + const bool pgood(); const bool ok() override; }; } \ No newline at end of file From 4eb67373c41b055bdda938e14754ecf98babe7ec Mon Sep 17 00:00:00 2001 From: Aditya-Dhiman4 Date: Sun, 23 Nov 2025 19:44:11 -0800 Subject: [PATCH 08/12] efuse fault handling overhaul --- firmware/quintuna/VC/CMakeLists.txt | 13 +- firmware/quintuna/VC/src/io/io_efuses.c | 54 ++++---- firmware/shared/src/app/app_ekf.h | 102 ++++++++++++++ .../src/io/io_efuse/io_efuse_ST/io_efuse_ST.c | 83 ------------ .../io_efuse_ST_VND5/io_efuse_ST_VND5.c | 127 ++++++++++++++++++ .../io_efuse_ST_VND5.h} | 6 +- .../src/io/io_efuse/io_efuse_TI/io_efuse_TI.c | 53 -------- .../io_efuse_TI_TPS25/io_efuse_TI_TPS25.c | 53 ++++++++ .../io_efuse_TI_TPS25.h} | 6 +- .../io_efuse_TI_TPS28/io_efuse_TI_TPS28.c | 123 +++++++++++++++++ .../io_efuse_TI_TPS28/io_efuse_TI_TPS28.h | 25 ++++ .../src/io/io_efuse/io_efuse_datatypes.h | 10 +- firmware/shared/srcpp/io/efuse/io_efuse.cpp | 32 ++--- firmware/shared/srcpp/io/efuse/io_efuse.hpp | 36 ++--- .../srcpp/io/efuse/io_efuse_ST_VND5.cpp | 78 +++++------ .../srcpp/io/efuse/io_efuse_ST_VND5.hpp | 51 +++---- .../srcpp/io/efuse/io_efuse_TI_TPS2.cpp | 23 ---- .../srcpp/io/efuse/io_efuse_TI_TPS2.hpp | 19 --- .../srcpp/io/efuse/io_efuse_TI_TPS25.cpp | 28 ++++ .../srcpp/io/efuse/io_efuse_TI_TPS25.hpp | 19 +++ 20 files changed, 628 insertions(+), 313 deletions(-) create mode 100644 firmware/shared/src/app/app_ekf.h delete mode 100644 firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c create mode 100644 firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c rename firmware/shared/src/io/io_efuse/{io_efuse_ST/io_efuse_ST.h => io_efuse_ST_VND5/io_efuse_ST_VND5.h} (86%) delete mode 100644 firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c create mode 100644 firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c rename firmware/shared/src/io/io_efuse/{io_efuse_TI/io_efuse_TI.h => io_efuse_TI_TPS25/io_efuse_TI_TPS25.h} (62%) create mode 100644 firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c create mode 100644 firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.h delete mode 100644 firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.cpp delete mode 100644 firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.hpp create mode 100644 firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp create mode 100644 firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp diff --git a/firmware/quintuna/VC/CMakeLists.txt b/firmware/quintuna/VC/CMakeLists.txt index be442f936a..0c8962e18c 100644 --- a/firmware/quintuna/VC/CMakeLists.txt +++ b/firmware/quintuna/VC/CMakeLists.txt @@ -29,13 +29,20 @@ list(APPEND IO_SRCS "${SHARED_IO_INCLUDE_DIR}/io_led.c" "${SHARED_IO_INCLUDE_DIR}/io_time.c" "${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse.c" - "${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_ST/io_efuse_ST.c" - "${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_TI/io_efuse_TI.c" + "${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c" + "${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c" "${SHARED_IO_INCLUDE_DIR}/io_potentiometer.c" "${SHARED_IO_INCLUDE_DIR}/io_bootHandler.c" "${SHARED_IO_INCLUDE_DIR}/io_imu.c" ) -set(IO_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src/io" "${CMAKE_CURRENT_SOURCE_DIR}/src/io/io_efuse" "${CMAKE_CURRENT_SOURCE_DIR}/src/io/io_efuse/io_efuse_TI" "${CMAKE_CURRENT_SOURCE_DIR}/src/io/io_efuse/io_efuse_ST" "${SHARED_IO_INCLUDE_DIR}" "${SHARED_IO_INCLUDE_QUINTUNA_DIR}") +set(IO_INCLUDE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}/src/io" + "${SHARED_IO_INCLUDE_DIR}" + "${SHARED_IO_INCLUDE_DIR}/io_efuse" + "${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_TI_TPS25" + "${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_ST_VND5" + "${SHARED_IO_INCLUDE_QUINTUNA_DIR}" +) file(GLOB_RECURSE HW_SRCS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/hw/*.c") list(APPEND HW_SRCS diff --git a/firmware/quintuna/VC/src/io/io_efuses.c b/firmware/quintuna/VC/src/io/io_efuses.c index a5ae182801..610f0e9e47 100644 --- a/firmware/quintuna/VC/src/io/io_efuses.c +++ b/firmware/quintuna/VC/src/io/io_efuses.c @@ -2,57 +2,57 @@ #include "hw_gpios.h" #include "hw_i2cs.h" #include "io_efuses.h" -#include "io_efuse/io_efuse_ST/io_efuse_ST.h" -#include "io_efuse/io_efuse_TI/io_efuse_TI.h" - -static ST_Efuse f_inv_st_efuse = { .stby_reset_gpio = &fr_stby_inv }; -static ST_Efuse rsm_st_efuse = { .stby_reset_gpio = &fr_stby_inv }; -static ST_Efuse bms_st_efuse = { .stby_reset_gpio = &fr_stby_front }; -static ST_Efuse r_inv_st_efuse = { .stby_reset_gpio = &fr_stby_front }; -static ST_Efuse dam_st_efuse = { .stby_reset_gpio = &fr_stby_rear }; -static ST_Efuse front_st_efuse = { .stby_reset_gpio = &fr_stby_rear }; -static TI_Efuse rl_pump_ti_efuse = { .pgood = &rl_pump_pgood }; -static ST_Efuse r_rad_fan_st_efuse = { .stby_reset_gpio = &fr_stby_rad }; +#include "io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.h" +#include "io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.h" + +static ST_VND5_Efuse f_inv_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_inv }; +static ST_VND5_Efuse rsm_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_inv }; +static ST_VND5_Efuse bms_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_front }; +static ST_VND5_Efuse r_inv_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_front }; +static ST_VND5_Efuse dam_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_rear }; +static ST_VND5_Efuse front_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_rear }; +static TI_TPS25_Efuse rl_pump_TI_TPS25_Efuse = { .pgood = &rl_pump_pgood }; +static ST_VND5_Efuse r_rad_fan_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_rad }; const Efuse f_inv_efuse = { .enable_gpio = &f_inv_en, .sns_adc_channel = &inv_f_pwr_i_sns, - .st = &f_inv_st_efuse, - .efuse_functions = &st_efuse_functions }; + .st_vnd5 = &f_inv_ST_VND5_Efuse, + .efuse_functions = &ST_VND5_Efuse_functions }; const Efuse rsm_efuse = { .enable_gpio = &rsm_en, .sns_adc_channel = &rsm_i_sns, - .st = &f_inv_st_efuse, - .efuse_functions = &st_efuse_functions }; + .st_vnd5 = &f_inv_ST_VND5_Efuse, + .efuse_functions = &ST_VND5_Efuse_functions }; const Efuse bms_efuse = { .enable_gpio = &bms_en, .sns_adc_channel = &bms_i_sns, - .st = &bms_st_efuse, - .efuse_functions = &st_efuse_functions }; + .st_vnd5 = &bms_ST_VND5_Efuse, + .efuse_functions = &ST_VND5_Efuse_functions }; const Efuse r_inv_efuse = { .enable_gpio = &r_inv_en, .sns_adc_channel = &inv_r_pwr_i_sns, - .st = &r_inv_st_efuse, - .efuse_functions = &st_efuse_functions }; + .st_vnd5 = &r_inv_ST_VND5_Efuse, + .efuse_functions = &ST_VND5_Efuse_functions }; const Efuse dam_efuse = { .enable_gpio = &dam_en, .sns_adc_channel = &dam_i_sns, - .st = &dam_st_efuse, - .efuse_functions = &st_efuse_functions }; + .st_vnd5 = &dam_ST_VND5_Efuse, + .efuse_functions = &ST_VND5_Efuse_functions }; const Efuse front_efuse = { .enable_gpio = &front_en, .sns_adc_channel = &front_i_sns, - .st = &front_st_efuse, - .efuse_functions = &st_efuse_functions }; + .st_vnd5 = &front_ST_VND5_Efuse, + .efuse_functions = &ST_VND5_Efuse_functions }; const Efuse rl_pump_efuse = { .enable_gpio = &rl_pump_en, .sns_adc_channel = &pump_rl_pwr_i_sns, - .ti = &rl_pump_ti_efuse, - .efuse_functions = &ti_efuse_functions }; + .ti_tps25 = &rl_pump_TI_TPS25_Efuse, + .efuse_functions = &TI_TPS25_Efuse_functions }; const Efuse r_rad_fan_efuse = { .enable_gpio = &rr_rad_fan_en, .sns_adc_channel = &r_rad_fan_i_sns, - .st = &r_rad_fan_st_efuse, - .efuse_functions = &ti_efuse_functions }; + .st_vnd5 = &r_rad_fan_ST_VND5_Efuse, + .efuse_functions = &TI_TPS25_Efuse_functions }; const Efuse *const efuse_channels[NUM_EFUSE_CHANNELS] = { [EFUSE_CHANNEL_F_INV] = &f_inv_efuse, [EFUSE_CHANNEL_RSM] = &rsm_efuse, diff --git a/firmware/shared/src/app/app_ekf.h b/firmware/shared/src/app/app_ekf.h new file mode 100644 index 0000000000..b87c007aee --- /dev/null +++ b/firmware/shared/src/app/app_ekf.h @@ -0,0 +1,102 @@ +#pragma once + +#include "app_math.h" + +/** + * General Extended Kalman Filter API + * + * How to use: + * + * 1) Include in your file like this along with the dimensions + * #define DIM x + * #include "app_ekf.h" + * + * 2) Define the functions in the function pointers + * + * 3) Define your measurement functions in your estimator api + * (They are not stored in the ekf struct which will allow multiple + * measurement functions and thus multiple sensors if required) + * + * Note: If you have more than 2 sensors for the update/measurement step, + * usually you will need the same amount of measurement functions. + * Thus, the user must swap the measurement functions in the ekf struct + * before calling the update step again with the new measurements + * Explain why velocity estimator is an exception + */ + +typedef struct +{ + // estimations + Matrix state_estimate; + Matrix covariance_estimate; + // internal variables + Matrix F_jacobian; + Matrix H_jacobian; + Matrix measurement_pred; + // user implementable functions functions + void (*state_transition)(Matrix *state_estimate, Matrix *prev_state, Matrix *control_input); + void (*state_jacobian)(Matrix *F_jacobian, Matrix *prev_state, Matrix *control_input); + void (*measurement_jacobian)(Matrix *H_jacobian, Matrix *prev_state); + void (*measurement_func)(Matrix *measurement_pred, Matrix *prev_state); +} EKF; + +static inline void predict(EKF *ekf, Matrix *prev_state, Matrix *control_input, Matrix *process_noise_cov) +{ + Matrix temp_cov = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM }; + Matrix F_transpose = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM }; + + // state prediction + ekf->state_transition(&ekf->state_estimate, prev_state, control_input); + ekf->state_jacobian(&ekf->F_jacobian, prev_state, control_input); + + // prediction covariance prediction + mult(&temp_cov, &ekf->F_jacobian, &ekf->covariance_estimate); + transpose(&F_transpose, &ekf->F_jacobian); + mult(&ekf->covariance_estimate, &temp_cov, &F_transpose); + add(&ekf->covariance_estimate, &ekf->covariance_estimate, process_noise_cov); +} + +/** + * Updates the prediction, gives the final, corrected state and covariance estimate + * with measured values given previous state and noise covariance + * + * measurement pred is obtained from your measurement function + */ +static inline void update(EKF *ekf, Matrix *measurement, Matrix *prev_state, Matrix *measurement_noise_cov) +{ + Matrix PH_transpose = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM }; + Matrix Ky = { .mat = (float[DIM * 1U]){ 0.0f }, .rows = DIM, .cols = 1 }; + Matrix H_transpose = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM }; + Matrix S = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM }; + Matrix S_inv = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM }; + Matrix K = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM }; + Matrix residual = { .mat = (float[DIM * 1U]){ 0.0f }, .rows = DIM, .cols = 1 }; + Matrix KH = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM }; + Matrix KHP = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM }; + + // measurement prediction + ekf->measurement_func(&ekf->measurement_pred, prev_state); + ekf->measurement_jacobian(&ekf->H_jacobian, prev_state); + + // measurement covariance prediction + transpose(&H_transpose, &ekf->H_jacobian); + mult(&PH_transpose, &ekf->covariance_estimate, &H_transpose); + mult(&S, &ekf->H_jacobian, &PH_transpose); + add(&S, &S, measurement_noise_cov); + + // kalman gain calculation + inverse2x2(&S_inv, &S); + mult(&K, &PH_transpose, &S_inv); + + // measurement residual calculation + sub(&residual, measurement, &ekf->measurement_pred); + + // state estimation + mult(&Ky, &K, &residual); + add(&ekf->state_estimate, prev_state, &Ky); + + // covariance estimation + mult(&KH, &K, &ekf->H_jacobian); + mult(&KHP, &KH, &ekf->covariance_estimate); + sub(&ekf->covariance_estimate, &ekf->covariance_estimate, &KHP); +} \ No newline at end of file diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c b/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c deleted file mode 100644 index 1228f1e285..0000000000 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c +++ /dev/null @@ -1,83 +0,0 @@ -#include "io_efuse_ST.h" -#include "io_efuse/io_efuse_datatypes.h" -#include "hw_gpio.h" -#include -#include - -/** - * ST Efuse Datasheet: - * https://octopart.com/datasheet/vnd5t100ajtr-e-stmicroelectronics-21218840 - */ - -static float NOMINAL_V = 3.0f; -static uint8_t ST_EFUSE_FAULT_FLAGS = 0x3F; - -static void io_efuse_ST_setChannel(const Efuse *channel, bool enabled); -static bool io_efuse_ST_isChannelEnabled(const Efuse *channel); -static float io_efuse_ST_getChannelCurrent(const Efuse *channel); -static void io_efuse_ST_reset_set(const Efuse *channel, bool set); -static void io_efuse_ST_reset(const Efuse *channel); -static bool io_efuse_ST_ok(const Efuse *efuse); - -const EfuseFunctions st_efuse_functions = { .set_channel = io_efuse_ST_setChannel, - .is_channel_enabled = io_efuse_ST_isChannelEnabled, - .get_channel_current = io_efuse_ST_getChannelCurrent, - .loadswitch_reset_set = io_efuse_ST_reset_set, - .reset_efuse = io_efuse_ST_reset, - .pgood = NULL, - .efuse_ok = io_efuse_ST_ok }; - -static void io_efuse_ST_setChannel(const Efuse *channel, bool enabled) -{ - assert(channel->enable_gpio != NULL); - hw_gpio_writePin(channel->enable_gpio, enabled); -} - -static bool io_efuse_ST_isChannelEnabled(const Efuse *channel) -{ - assert(channel->enable_gpio != NULL); - return hw_gpio_readPin(channel->enable_gpio); -} - -static float io_efuse_ST_getChannelCurrent(const Efuse *channel) -{ - const AdcChannel *current_sense = channel->sns_adc_channel; - assert(current_sense != NULL); - return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; -} - -static void io_efuse_ST_reset_set(const Efuse *channel, bool set) -{ - assert(channel->st->stby_reset_gpio != NULL); - hw_gpio_writePin(channel->st->stby_reset_gpio, set); -} - -static void io_efuse_ST_reset(const Efuse *channel) -{ - assert(channel->st->stby_reset_gpio != NULL); - hw_gpio_writePin(channel->st->stby_reset_gpio, false); - hw_gpio_writePin(channel->st->stby_reset_gpio, true); - hw_gpio_writePin(channel->st->stby_reset_gpio, false); -} - -static bool io_efuse_ST_ok(const Efuse *efuse) -{ - assert(efuse != NULL); - - float voltage = io_efuse_ST_getChannelCurrent(efuse) / ADC_VOLTAGE_TO_CURRENT_A; - bool channelEnabled = io_efuse_ST_isChannelEnabled(efuse); - - // Setting faults for st efuse - // TODO: these probably are not correct they must be fixed - efuse->st->faults.flags.under_voltage = (voltage <= 0.0f); - efuse->st->faults.flags.short_to_vbat = (voltage >= NOMINAL_V && channelEnabled); - efuse->st->faults.flags.overload = (voltage > NOMINAL_V && channelEnabled); - efuse->st->faults.flags.ovt_stp = (voltage >= NOMINAL_V && channelEnabled); - efuse->st->faults.flags.negative_output_voltage_clamp = (voltage <= 0.0f && !channelEnabled); - efuse->st->faults.flags.open_load_off_stat = (voltage >= NOMINAL_V); - - // check if any flag is set, then return the status - uint8_t flags = efuse->st->faults.raw & ST_EFUSE_FAULT_FLAGS; - - return !(flags > 0); -} diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c new file mode 100644 index 0000000000..a549a26ff0 --- /dev/null +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c @@ -0,0 +1,127 @@ +#include "app_utils.h" +#include "io_efuse_ST_VND5.h" +#include "io_efuse/io_efuse_datatypes.h" +#include "hw_gpio.h" +#include +#include + +/** + * ST_VND5 Efuse Datasheet: + * https://octopart.com/datasheet/vnd5t100ajtr-e-stmicroelectronics-21218840 + */ + +#define NOMINAL_V 3.0f +// Vsenseh lower threshold +#define V_SENSE_H_L 7.5f +// Vsenseh upper threshold +#define V_SENSE_H_H 9.5f + +#define V_THRES 0.1f + +#define ST_VND5_Efuse_FAULT_FLAGS 0x3F + +// {fault_reset_stby, channel_enabled} +#define L_L 0x00U +#define L_H 0x01U +#define H_L 0x02U +#define H_H 0x03U + +static void io_efuse_ST_setChannel(const Efuse *channel, bool enabled); +static bool io_efuse_ST_isChannelEnabled(const Efuse *channel); +static float io_efuse_ST_getChannelCurrent(const Efuse *channel); +static void io_efuse_ST_reset_set(const Efuse *channel, bool set); +static void io_efuse_ST_reset(const Efuse *channel); +static bool io_efuse_ST_ok(const Efuse *efuse); + +const EfuseFunctions ST_VND5_Efuse_functions = { .set_channel = io_efuse_ST_setChannel, + .is_channel_enabled = io_efuse_ST_isChannelEnabled, + .get_channel_current = io_efuse_ST_getChannelCurrent, + .loadswitch_reset_set = io_efuse_ST_reset_set, + .reset_efuse = io_efuse_ST_reset, + .pgood = NULL, + .efuse_ok = io_efuse_ST_ok }; + +static void io_efuse_ST_setChannel(const Efuse *channel, bool enabled) +{ + assert(channel->enable_gpio != NULL); + hw_gpio_writePin(channel->enable_gpio, enabled); +} + +static bool io_efuse_ST_isChannelEnabled(const Efuse *channel) +{ + assert(channel->enable_gpio != NULL); + return hw_gpio_readPin(channel->enable_gpio); +} + +static float io_efuse_ST_getChannelCurrent(const Efuse *channel) +{ + const AdcChannel *current_sense = channel->sns_adc_channel; + assert(current_sense != NULL); + return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; +} + +static void io_efuse_ST_reset_set(const Efuse *channel, bool set) +{ + assert(channel->st_vnd5->stby_reset_gpio != NULL); + hw_gpio_writePin(channel->st_vnd5->stby_reset_gpio, set); +} + +static void io_efuse_ST_reset(const Efuse *channel) +{ + assert(channel->st_vnd5->stby_reset_gpio != NULL); + hw_gpio_writePin(channel->st_vnd5->stby_reset_gpio, false); + hw_gpio_writePin(channel->st_vnd5->stby_reset_gpio, true); + hw_gpio_writePin(channel->st_vnd5->stby_reset_gpio, false); +} + +static bool io_efuse_ST_ok(const Efuse *efuse) +{ + assert(efuse != NULL); + + float voltage = io_efuse_ST_getChannelCurrent(efuse) / ADC_VOLTAGE_TO_CURRENT_A; + bool channelEnabled = io_efuse_ST_isChannelEnabled(efuse); + bool fault_reset_stby = hw_gpio_readPin(efuse->st_vnd5->stby_reset_gpio); + uint8_t fault_table_idx = 0x00U | ((uint8_t)((fault_reset_stby << 1) | (channelEnabled))); + + // Setting faults for st_vnd5 efuse + // TODO: these probably are not correct they must be fixed + if (fault_table_idx == L_L) + { + efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.ovt_stp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + } + else if (fault_table_idx == L_H) + { + efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + efuse->st_vnd5->faults.flags.ovt_stp = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + // efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = (voltage <= 0.0f); + } + else if (fault_table_idx == H_L) + { + efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.ovt_stp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.short_to_vbat = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + efuse->st_vnd5->faults.flags.open_load_off_stat = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + } + else if (fault_table_idx == H_H) + { + efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + efuse->st_vnd5->faults.flags.ovt_stp = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + // efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = (voltage <= 0.0f); + } + + efuse->st_vnd5->faults.flags.under_voltage = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + + // check if any flag is set, then return the status + uint8_t flags = efuse->st_vnd5->faults.raw & ST_VND5_Efuse_FAULT_FLAGS; + + return !(flags > 0); +} diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.h similarity index 86% rename from firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h rename to firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.h index 387239859f..cb55c4f83a 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.h @@ -7,7 +7,7 @@ typedef struct __EfuseFunctions EfuseFunctions; -typedef struct __ST_Efuse +typedef struct __ST_VND5_Efuse { const Gpio *stby_reset_gpio; @@ -26,6 +26,6 @@ typedef struct __ST_Efuse } flags; uint8_t raw; } faults; -} ST_Efuse; +} ST_VND5_Efuse; -extern const EfuseFunctions st_efuse_functions; +extern const EfuseFunctions ST_VND5_Efuse_functions; diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c b/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c deleted file mode 100644 index 764c68ccfa..0000000000 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "io_efuse_TI.h" -#include "io_efuse/io_efuse_datatypes.h" -#include "hw_gpio.h" -#include -#include - -static void io_TI_efuse_setChannel(const Efuse *channel, bool enabled); -static bool io_TI_efuse_isChannelEnabled(const Efuse *channel); -static float io_TI_efuse_getChannelCurrent(const Efuse *channel); -static void io_TI_efuse_reset(const Efuse *efuse); -static bool io_TI_efuse_pgood(const Efuse *efuse); - -const EfuseFunctions ti_efuse_functions = { .set_channel = io_TI_efuse_setChannel, - .is_channel_enabled = io_TI_efuse_isChannelEnabled, - .get_channel_current = io_TI_efuse_getChannelCurrent, - .loadswitch_reset_set = NULL, - .reset_efuse = io_TI_efuse_reset, - .pgood = io_TI_efuse_pgood, - .efuse_ok = io_TI_efuse_pgood }; - -static void io_TI_efuse_setChannel(const Efuse *channel, bool enabled) -{ - assert(channel->enable_gpio != NULL); - hw_gpio_writePin(channel->enable_gpio, enabled); -} - -static bool io_TI_efuse_isChannelEnabled(const Efuse *channel) -{ - assert(channel->enable_gpio != NULL); - return hw_gpio_readPin(channel->enable_gpio); -} - -static float io_TI_efuse_getChannelCurrent(const Efuse *channel) -{ - const AdcChannel *current_sense = channel->sns_adc_channel; - assert(current_sense != NULL); - return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; -} - -static void io_TI_efuse_reset(const Efuse *efuse) -{ - assert(efuse->enable_gpio != NULL); - - hw_gpio_writePin(efuse->enable_gpio, false); - hw_gpio_writePin(efuse->enable_gpio, true); - hw_gpio_writePin(efuse->enable_gpio, false); -} - -static bool io_TI_efuse_pgood(const Efuse *efuse) -{ - assert(efuse->ti->pgood != NULL); - return hw_gpio_readPin(efuse->ti->pgood); -} diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c new file mode 100644 index 0000000000..efe83c2b0a --- /dev/null +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c @@ -0,0 +1,53 @@ +#include "io_efuse_TI_TPS25.h" +#include "io_efuse/io_efuse_datatypes.h" +#include "hw_gpio.h" +#include +#include + +static void io_TI_TPS25_Efuse_setChannel(const Efuse *channel, bool enabled); +static bool io_TI_TPS25_Efuse_isChannelEnabled(const Efuse *channel); +static float io_TI_TPS25_Efuse_getChannelCurrent(const Efuse *channel); +static void io_TI_TPS25_Efuse_reset(const Efuse *efuse); +static bool io_TI_TPS25_Efuse_pgood(const Efuse *efuse); + +const EfuseFunctions TI_TPS25_Efuse_functions = { .set_channel = io_TI_TPS25_Efuse_setChannel, + .is_channel_enabled = io_TI_TPS25_Efuse_isChannelEnabled, + .get_channel_current = io_TI_TPS25_Efuse_getChannelCurrent, + .loadswitch_reset_set = NULL, + .reset_efuse = io_TI_TPS25_Efuse_reset, + .pgood = io_TI_TPS25_Efuse_pgood, + .efuse_ok = io_TI_TPS25_Efuse_pgood }; + +static void io_TI_TPS25_Efuse_setChannel(const Efuse *channel, bool enabled) +{ + assert(channel->enable_gpio != NULL); + hw_gpio_writePin(channel->enable_gpio, enabled); +} + +static bool io_TI_TPS25_Efuse_isChannelEnabled(const Efuse *channel) +{ + assert(channel->enable_gpio != NULL); + return hw_gpio_readPin(channel->enable_gpio); +} + +static float io_TI_TPS25_Efuse_getChannelCurrent(const Efuse *channel) +{ + const AdcChannel *current_sense = channel->sns_adc_channel; + assert(current_sense != NULL); + return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; +} + +static void io_TI_TPS25_Efuse_reset(const Efuse *efuse) +{ + assert(efuse->enable_gpio != NULL); + + hw_gpio_writePin(efuse->enable_gpio, false); + hw_gpio_writePin(efuse->enable_gpio, true); + hw_gpio_writePin(efuse->enable_gpio, false); +} + +static bool io_TI_TPS25_Efuse_pgood(const Efuse *efuse) +{ + assert(efuse->ti_tps25->pgood != NULL); + return hw_gpio_readPin(efuse->ti_tps25->pgood); +} diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.h similarity index 62% rename from firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h rename to firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.h index 34955e4d86..9dd10194d7 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI/io_efuse_TI.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.h @@ -7,9 +7,9 @@ typedef struct __EfuseFunctions EfuseFunctions; -typedef struct __TI_Efuse +typedef struct __TI_TPS25_Efuse { const Gpio *pgood; -} TI_Efuse; +} TI_TPS25_Efuse; -extern const EfuseFunctions ti_efuse_functions; +extern const EfuseFunctions TI_TPS25_Efuse_functions; diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c new file mode 100644 index 0000000000..92db7897ba --- /dev/null +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c @@ -0,0 +1,123 @@ +#include "app_utils.h" +#include "io_efuse_TI_TPS28.h" +#include "io_efuse/io_efuse_datatypes.h" +#include "hw_gpio.h" +#include +#include + +/** + * TI_TPS28 Efuse Datasheet: + * https://www.ti.com/lit/ds/symlink/tps281c30.pdf?ts=1763641186988&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTPS281C30 + */ + +/** + * The Current limit (I_LIM) is set attaching the ILIM pinto a pulldown resistor. + * + * The pulldown resistor must be between 10kOhm - 50kOhm + * The current limit ration K_CL is: + * 40 A*kOhm - 60 A*kOhm (Rev A or C) + * 80 A*kOhm - 120 A*kOhm (Rev B, D, or C) + */ + +#define R_PD 24.9f //kOhm +// TODO: is this actualy a linear interpolation?? +#define K_CL (((60.0f - 40.0f) / (50.0f - 10.0f)) * R_PD) // A*kOhm +#define I_LIM (K_CL / R_PD) + +// There are different V_SNSFH thresholds if DIAG_EN gpio is set to LOw (3.3V) or HIGH (5V) +#define V_SNSFH_MIN 3.5f +#define V_SNSFH 3.95f +#define V_SNSFH_MAX 4.4f + +static void io_TI_TPS28_Efuse_setChannel(const Efuse *channel, bool enabled); +static bool io_TI_TPS28_Efuse_isChannelEnabled(const Efuse *channel); +static float io_TI_TPS28_Efuse_getChannelCurrent(const Efuse *channel); +static void io_TI_TPS28_Efuse_reset(const Efuse *efuse); +static bool io_TI_TPS28_Efuse_pgood(const Efuse *efuse); + +const EfuseFunctions TI_TPS28_Efuse_functions = { .set_channel = io_TI_TPS28_Efuse_setChannel, + .is_channel_enabled = io_TI_TPS28_Efuse_isChannelEnabled, + .get_channel_current = io_TI_TPS28_Efuse_getChannelCurrent, + .loadswitch_reset_set = NULL, + .reset_efuse = io_TI_TPS28_Efuse_reset, + .pgood = NULL, + .efuse_ok = io_TI_TPS28_Efuse_ok }; + +static void io_TI_TPS28_Efuse_setChannel(const Efuse *channel, bool enabled) +{ + assert(channel->enable_gpio != NULL); + hw_gpio_writePin(channel->enable_gpio, enabled); +} + +static bool io_TI_TPS28_Efuse_isChannelEnabled(const Efuse *channel) +{ + assert(channel->enable_gpio != NULL); + return hw_gpio_readPin(channel->enable_gpio); +} + +static bool io_TI_TPS28_Efuse_isDiagEnabled(const Efuse *channel) +{ + assert(channel->ti_tps28->diag_en_gpio != NULL); + return hw_gpio_readPin(channel->ti_tps28->diag_en_gpio); +} + +static float io_TI_TPS28_Efuse_getChannelCurrent(const Efuse *channel) +{ + const AdcChannel *current_sense = channel->sns_adc_channel; + assert(current_sense != NULL); + return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; +} + +static void io_TI_TPS28_Efuse_reset(const Efuse *efuse) +{ + assert(efuse->enable_gpio != NULL); + + hw_gpio_writePin(efuse->enable_gpio, false); + hw_gpio_writePin(efuse->enable_gpio, true); + hw_gpio_writePin(efuse->enable_gpio, false); +} + +static bool io_TI_TPS28_Efuse_ok(const Efuse *efuse) +{ + assert(efuse != NULL); + + bool channel_enabled = io_TI_TPS28_Efuse_isChannelEnabled(efuse); + bool diag_enabled = hw_gpio_readPin(efuse->ti_tps28->diag_en_gpio); + float voltage = io_TI_TPS28_Efuse_getChannelCurrent(efuse) / ADC_VOLTAGE_TO_CURRENT_A; + + /** + * Note: Table 8.2 DIAG_EN Logic Table + * + * If DIAG_EN is low, FAULT will continue to indicate + * TSD (thermal_shdn) or ILIM (forgor what this is) + * + * Thus we only dont check for overcurrent if it's disabled + * + * TODO: but Table 8-3 contradicts this + */ + + + // if diagnostics are not enabled, only check TSD and ILIM + bool is_faulted = hw_gpio_readPin(efuse->ti_tps28->fault_gpio); + if (diag_enabled) + { + if (is_faulted) + { + // Determine specific faults + efuse->ti_tps28->faults.flags.overcurrent = + (channel_enabled && IS_IN_RANGE(V_SNSFH_MIN, V_SNSFH_MAX, voltage)); + efuse->ti_tps28->faults.flags.thermal_shdn = + (channel_enabled && IS_IN_RANGE(V_SNSFH_MIN, V_SNSFH_MAX, voltage)); + } + else + { + efuse->ti_tps28->faults.raw = 0x00U; + } + } + else + { + efuse->ti_tps28->faults.raw = 0x03; + } + + return !(efuse->ti_tps28->faults.raw > 0); +} diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.h b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.h new file mode 100644 index 0000000000..7fb38b7557 --- /dev/null +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.h @@ -0,0 +1,25 @@ +#pragma once + +#include "hw_gpio.h" + +typedef struct __EfuseFunctions EfuseFunctions; + +typedef struct __TI_TPS28_Efuse +{ + const Gpio *fault_gpio; + const Gpio *diag_en_gpio; + + /* Portable bit-fields: use 'unsigned' and name the subgroup */ + union + { + struct + { + uint8_t overcurrent : 1; + uint8_t thermal_shdn : 1; + uint8_t padding : 6; + } flags; + uint8_t raw; + } faults; +} TI_TPS28_Efuse; + +extern const EfuseFunctions TI_TPS28_EfuseFunctions; \ No newline at end of file diff --git a/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h index 4165af7e75..b893fc91ca 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h @@ -7,8 +7,9 @@ #define ADC_VOLTAGE_TO_CURRENT_A 1.720f typedef struct __Efuse Efuse; -typedef struct __ST_Efuse ST_Efuse; -typedef struct __TI_Efuse TI_Efuse; +typedef struct __ST_VND5_Efuse ST_VND5_Efuse; +typedef struct __TI_TPS25_Efuse TI_TPS25_Efuse; +typedef struct __TI_TPS28_Efuse TI_TPS28_Efuse; typedef struct __EfuseFunctions EfuseFunctions; struct __EfuseFunctions @@ -28,8 +29,9 @@ struct __Efuse const AdcChannel *sns_adc_channel; union { - ST_Efuse *st; - TI_Efuse *ti; + ST_VND5_Efuse *st_vnd5; + TI_TPS25_Efuse *ti_tps25; + TI_TPS28_Efuse *ti_tps28; }; const EfuseFunctions *efuse_functions; diff --git a/firmware/shared/srcpp/io/efuse/io_efuse.cpp b/firmware/shared/srcpp/io/efuse/io_efuse.cpp index 8f16550578..3422b00a42 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse.cpp @@ -4,21 +4,23 @@ namespace io::efuse { - Efuse::Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel) - : enable_gpio(enable_gpio), sns_adc_channel(sns_adc_channel) {} +Efuse::Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel) + : enable_gpio(enable_gpio), sns_adc_channel(sns_adc_channel) +{ +} - void Efuse::setChannel(bool enabled) - { - this->enable_gpio.writePin(enabled); - } +void Efuse::setChannel(bool enabled) +{ + this->enable_gpio.writePin(enabled); +} - const bool Efuse::isChannelEnabled() - { - return this->enable_gpio.readPin(); - } +const bool Efuse::isChannelEnabled() +{ + return this->enable_gpio.readPin(); +} - const float Efuse::getChannelCurrent() - { - return this->sns_adc_channel.getVoltage() * ADC_VOLTAGE_TO_CURRENT_A; - } -} \ No newline at end of file +const float Efuse::getChannelCurrent() +{ + return this->sns_adc_channel.getVoltage() * ADC_VOLTAGE_TO_CURRENT_A; +} +} // namespace io::efuse \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse.hpp b/firmware/shared/srcpp/io/efuse/io_efuse.hpp index 1b3175410d..72f48dd3f0 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse.hpp @@ -6,21 +6,23 @@ namespace io { - class Efuse - { - protected: - static constexpr float ADC_VOLTAGE_TO_CURRENT_A = 1.720f; - const hw::Gpio &enable_gpio; - const hw::Adc &sns_adc_channel; +class Efuse +{ + protected: + static constexpr float ADC_VOLTAGE_TO_CURRENT_A = 1.720f; + const hw::Gpio &enable_gpio; + const hw::Adc &sns_adc_channel; - public: - Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel) - : enable_gpio(enable_gpio), sns_adc_channel(sns_adc_channel) {} - virtual ~Efuse() = default; - void setChannel(bool enabled); - const bool isChannelEnabled(); - const float getChannelCurrent(); - virtual void reset() = 0; - virtual const bool ok() = 0; - }; -} \ No newline at end of file + public: + Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel) + : enable_gpio(enable_gpio), sns_adc_channel(sns_adc_channel) + { + } + virtual ~Efuse() = default; + void setChannel(bool enabled); + const bool isChannelEnabled(); + const float getChannelCurrent(); + virtual void reset() = 0; + virtual const bool ok() = 0; +}; +} // namespace io \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp index bbcf00274d..bb80d47ba0 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp @@ -1,6 +1,6 @@ extern "C" { - #include "app_utils.h" +#include "app_utils.h" } #include "io_efuse_ST_VND5.hpp" @@ -22,41 +22,41 @@ ST_VND5_Efuse::ST_VND5_Efuse( { } - void ST_VND5_Efuse::reset() - { - this->stby_reset_gpio.writePin(false); - this->stby_reset_gpio.writePin(true); - this->stby_reset_gpio.writePin(false); - } - - void ST_VND5_Efuse::resetSet(const bool set) - { - this->stby_reset_gpio.writePin(set); - } - - const bool ST_VND5_Efuse::ok() - { - // TODO: WTF is output??? - const bool input = this->enable_gpio.readPin(); - const bool fault_reset_stby = this->stby_reset_gpio.readPin(); - const float voltage = this->sns_adc_channel.getVoltage() / ADC_VOLTAGE_TO_CURRENT_A; - - this->faults.flags.overload = (input && (voltage > NOMINAL_V)); - this->faults.flags.ovt_stg = (input && (IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage))); - this->faults.flags.under_voltage = (voltage <= 0.0f); - - if (fault_reset_stby) - this->faults.flags.short_to_vbat = (!input && IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage)); - else - this->faults.flags.short_to_vbat = (input && (voltage < NOMINAL_V)); - - if (fault_reset_stby) - this->faults.flags.open_load_off_stat = (!input && IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage)); - else - this->faults.flags.open_load_off_stat = (input && voltage <= 0.0f); - - this->faults.flags.negative_output_voltage_clamp = (!input && voltage <= 0.0f); - - return true; - } -} \ No newline at end of file +void ST_VND5_Efuse::reset() +{ + this->stby_reset_gpio.writePin(false); + this->stby_reset_gpio.writePin(true); + this->stby_reset_gpio.writePin(false); +} + +void ST_VND5_Efuse::resetSet(const bool set) +{ + this->stby_reset_gpio.writePin(set); +} + +const bool ST_VND5_Efuse::ok() +{ + // TODO: WTF is output??? + const bool input = this->enable_gpio.readPin(); + const bool fault_reset_stby = this->stby_reset_gpio.readPin(); + const float voltage = this->sns_adc_channel.getVoltage() / ADC_VOLTAGE_TO_CURRENT_A; + + this->faults.flags.overload = (input && (voltage > NOMINAL_V)); + this->faults.flags.ovt_stg = (input && (IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage))); + this->faults.flags.under_voltage = (voltage <= 0.0f); + + if (fault_reset_stby) + this->faults.flags.short_to_vbat = (!input && IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage)); + else + this->faults.flags.short_to_vbat = (input && (voltage < NOMINAL_V)); + + if (fault_reset_stby) + this->faults.flags.open_load_off_stat = (!input && IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage)); + else + this->faults.flags.open_load_off_stat = (input && voltage <= 0.0f); + + this->faults.flags.negative_output_voltage_clamp = (!input && voltage <= 0.0f); + + return true; +} +} // namespace io \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp index 289e1502e9..7c9b360f0f 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp @@ -5,29 +5,32 @@ namespace io { - class ST_VND5_Efuse : public Efuse +class ST_VND5_Efuse : public Efuse +{ + private: + const hw::Gpio &stby_reset_gpio; + union { - private: - const hw::Gpio &stby_reset_gpio; - union - { - struct - { - uint8_t overload : 1; - uint8_t ovt_stg : 1; - uint8_t under_voltage : 1; - uint8_t short_to_vbat : 1; - uint8_t open_load_off_stat : 1; - uint8_t negative_output_voltage_clamp : 1; - uint8_t padding : 2; - } flags; - uint8_t raw; - } faults; + struct + { + uint8_t overload : 1; + uint8_t ovt_stg : 1; + uint8_t under_voltage : 1; + uint8_t short_to_vbat : 1; + uint8_t open_load_off_stat : 1; + uint8_t negative_output_voltage_clamp : 1; + uint8_t padding : 2; + } flags; + uint8_t raw; + } faults; - public: - explicit ST_VND5_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &stby_reset_gpio); - void reset() override; - void resetSet(const bool set); - const bool ok() override; - }; -} \ No newline at end of file + public: + explicit ST_VND5_Efuse( + const hw::Gpio &enable_gpio, + const hw::Adc &sns_adc_channel, + const hw::Gpio &stby_reset_gpio); + void reset() override; + void resetSet(const bool set); + const bool ok() override; +}; +} // namespace io \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.cpp deleted file mode 100644 index 32c28f1834..0000000000 --- a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include "io_efuse_TI_TPS2.hpp" -#include "hw_gpio.hpp" - -namespace io -{ - ST_TPS2_Efuse::ST_TPS2_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio& pgood) - : Efuse(enable_gpio, sns_adc_channel) , pgood_gpio(pgood) {} - - void ST_TPS2_Efuse::reset() { - this->enable_gpio.writePin(false); - this->enable_gpio.writePin(true); - this->enable_gpio.writePin(false); - } - - const bool ST_TPS2_Efuse::pgood() { - return this->pgood_gpio.readPin(); - } - - const bool ST_TPS2_Efuse::ok() { - return this->pgood(); - } -} \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.hpp deleted file mode 100644 index 6be1d6fb86..0000000000 --- a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS2.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include -#include "io_efuse.hpp" - -namespace io -{ - class ST_TPS2_Efuse : public Efuse - { - private: - const hw::Gpio& pgood_gpio; - - public: - explicit ST_TPS2_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio& pgood); - void reset() override; - const bool pgood(); - const bool ok() override; - }; -} \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp new file mode 100644 index 0000000000..a5b1754c0f --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp @@ -0,0 +1,28 @@ +#include +#include "io_efuse_TI_TPS25.hpp" +#include "hw_gpio.hpp" + +namespace io +{ +TI_TPS25_Efuse::TI_TPS25_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &pgood) + : Efuse(enable_gpio, sns_adc_channel), pgood_gpio(pgood) +{ +} + +void TI_TPS25_Efuse::reset() +{ + this->enable_gpio.writePin(false); + this->enable_gpio.writePin(true); + this->enable_gpio.writePin(false); +} + +const bool TI_TPS25_Efuse::pgood() +{ + return this->pgood_gpio.readPin(); +} + +const bool TI_TPS25_Efuse::ok() +{ + return this->pgood(); +} +} // namespace io diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp new file mode 100644 index 0000000000..d9c9a31a01 --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include +#include "io_efuse.hpp" + +namespace io +{ +class TI_TPS25_Efuse : public Efuse +{ + private: + const hw::Gpio &pgood_gpio; + + public: + explicit TI_TPS25_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &pgood); + void reset() override; + const bool pgood(); + const bool ok() override; +}; +} // namespace io From 7f7ebcdccbc6ca077a48d9256c0a84273f019f33 Mon Sep 17 00:00:00 2001 From: Aditya-Dhiman4 Date: Fri, 28 Nov 2025 00:21:36 -0800 Subject: [PATCH 09/12] C++ TPS28 Efuse, added final keyword cuz its cool and optimizations hopefuly --- .../io_efuse_ST_VND5/io_efuse_ST_VND5.c | 3 +- .../io_efuse_TI_TPS28/io_efuse_TI_TPS28.c | 2 +- .../srcpp/io/efuse/io_efuse_ST_VND5.cpp | 74 +++++++++++---- .../srcpp/io/efuse/io_efuse_ST_VND5.hpp | 10 +- .../srcpp/io/efuse/io_efuse_TI_TPS25.hpp | 6 +- .../srcpp/io/efuse/io_efuse_TI_TPS28.cpp | 91 +++++++++++++++++++ .../srcpp/io/efuse/io_efuse_TI_TPS28.hpp | 35 +++++++ 7 files changed, 191 insertions(+), 30 deletions(-) create mode 100644 firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp create mode 100644 firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c index a549a26ff0..7f05fea541 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c @@ -84,7 +84,7 @@ static bool io_efuse_ST_ok(const Efuse *efuse) uint8_t fault_table_idx = 0x00U | ((uint8_t)((fault_reset_stby << 1) | (channelEnabled))); // Setting faults for st_vnd5 efuse - // TODO: these probably are not correct they must be fixed + // TODO: Verify these if (fault_table_idx == L_L) { efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); @@ -123,5 +123,6 @@ static bool io_efuse_ST_ok(const Efuse *efuse) // check if any flag is set, then return the status uint8_t flags = efuse->st_vnd5->faults.raw & ST_VND5_Efuse_FAULT_FLAGS; + // TODO: Do we want to return a boolean or should we just return the faults union and add additional methods to check specific faults return !(flags > 0); } diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c index 92db7897ba..2c0e32c0cd 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c @@ -67,7 +67,7 @@ static float io_TI_TPS28_Efuse_getChannelCurrent(const Efuse *channel) assert(current_sense != NULL); return hw_adc_getVoltage(current_sense) * ADC_VOLTAGE_TO_CURRENT_A; } - +// TODO: verify reset function static void io_TI_TPS28_Efuse_reset(const Efuse *efuse) { assert(efuse->enable_gpio != NULL); diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp index bb80d47ba0..d74ea20f9d 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp @@ -13,12 +13,21 @@ static constexpr float NOMINAL_V = 3.0f; static constexpr float V_SENSE_H_H = 9.5f; // Vsenseh lower threshold static constexpr float V_SENSE_H_L = 7.5f; +static constexpr float V_THRES = 0.1f; + +static constexpr uint8_t ST_VND5_Efuse_FAULT_FLAGS = 0x3F; + +// {fault_reset_stby, channel_enabled} +static constexpr uint8_t L_L = 0x00U; +static constexpr uint8_t L_H = 0x01U; +static constexpr uint8_t H_L = 0x02U; +static constexpr uint8_t H_H = 0x03U; ST_VND5_Efuse::ST_VND5_Efuse( const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &stby_reset_gpio) - : Efuse(enable_gpio, sns_adc_channel), stby_reset_gpio(stby_reset_gpio) + : Efuse(enable_gpio, sns_adc_channel), stby_reset_gpio(stby_reset_gpio), faults{} { } @@ -34,29 +43,54 @@ void ST_VND5_Efuse::resetSet(const bool set) this->stby_reset_gpio.writePin(set); } +// TODO: Do we want to return a boolean or should we just return the faults union and add additional methods to check specific faults const bool ST_VND5_Efuse::ok() { - // TODO: WTF is output??? - const bool input = this->enable_gpio.readPin(); - const bool fault_reset_stby = this->stby_reset_gpio.readPin(); - const float voltage = this->sns_adc_channel.getVoltage() / ADC_VOLTAGE_TO_CURRENT_A; - - this->faults.flags.overload = (input && (voltage > NOMINAL_V)); - this->faults.flags.ovt_stg = (input && (IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage))); - this->faults.flags.under_voltage = (voltage <= 0.0f); + const float voltage = this->getChannelCurrent() / ADC_VOLTAGE_TO_CURRENT_A; + const bool channel_enabled = this->isChannelEnabled(); + const bool fault_reset_stby = this->stby_reset_gpio.readPin(); + const uint8_t fault_table_idx = + static_cast((static_cast(fault_reset_stby) << 1U) | + static_cast(channel_enabled)); - if (fault_reset_stby) - this->faults.flags.short_to_vbat = (!input && IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage)); - else - this->faults.flags.short_to_vbat = (input && (voltage < NOMINAL_V)); + // Setting faults for st_vnd5 efuse + // TODO: verify these + switch (fault_table_idx) + { + case L_L: + this->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + this->faults.flags.ovt_stp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + this->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + this->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + this->faults.flags.negative_output_voltage_clamp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + break; + case L_H: + this->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + this->faults.flags.ovt_stp = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + this->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + this->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + break; + case H_L: + this->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + this->faults.flags.ovt_stp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + this->faults.flags.short_to_vbat = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + this->faults.flags.open_load_off_stat = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + this->faults.flags.negative_output_voltage_clamp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + break; + case H_H: + this->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + this->faults.flags.ovt_stp = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + this->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + this->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + break; + default: + break; + } - if (fault_reset_stby) - this->faults.flags.open_load_off_stat = (!input && IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage)); - else - this->faults.flags.open_load_off_stat = (input && voltage <= 0.0f); + this->faults.flags.under_voltage = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - this->faults.flags.negative_output_voltage_clamp = (!input && voltage <= 0.0f); + const uint8_t flags = this->faults.raw & ST_VND5_Efuse_FAULT_FLAGS; - return true; + return !(flags > 0U); } -} // namespace io \ No newline at end of file +} // namespace io diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp index 7c9b360f0f..9f31247fc1 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp @@ -5,7 +5,7 @@ namespace io { -class ST_VND5_Efuse : public Efuse +class ST_VND5_Efuse final : public Efuse { private: const hw::Gpio &stby_reset_gpio; @@ -14,7 +14,7 @@ class ST_VND5_Efuse : public Efuse struct { uint8_t overload : 1; - uint8_t ovt_stg : 1; + uint8_t ovt_stp : 1; uint8_t under_voltage : 1; uint8_t short_to_vbat : 1; uint8_t open_load_off_stat : 1; @@ -29,8 +29,8 @@ class ST_VND5_Efuse : public Efuse const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &stby_reset_gpio); - void reset() override; + void reset() override final; void resetSet(const bool set); - const bool ok() override; + const bool ok() override final; }; -} // namespace io \ No newline at end of file +} // namespace io diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp index d9c9a31a01..73b8098a19 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp @@ -5,15 +5,15 @@ namespace io { -class TI_TPS25_Efuse : public Efuse +class TI_TPS25_Efuse final : public Efuse { private: const hw::Gpio &pgood_gpio; public: explicit TI_TPS25_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &pgood); - void reset() override; + void reset() override final; const bool pgood(); - const bool ok() override; + const bool ok() override final; }; } // namespace io diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp new file mode 100644 index 0000000000..9f0975deae --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp @@ -0,0 +1,91 @@ +extern "C" +{ +#include "app_utils.h" +} + +#include "io_efuse_TI_TPS28.hpp" +#include "hw_gpio.hpp" + +/** + * TI_TPS28 Efuse Datasheet: + * https://www.ti.com/lit/ds/symlink/tps281c30.pdf?ts=1763641186988&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTPS281C30 + */ + +/** + * The Current limit (I_LIM) is set attaching the ILIM pinto a pulldown resistor. + * + * The pulldown resistor must be between 10kOhm - 50kOhm + * The current limit ration K_CL is: + * 40 A*kOhm - 60 A*kOhm (Rev A or C) + * 80 A*kOhm - 120 A*kOhm (Rev B, D, or C) + */ + +namespace io +{ +static constexpr float R_PD = 24.9f; // kOhm +// TODO: is this actualy a linear interpolation?? +static constexpr float K_CL = (((60.0f - 40.0f) / (50.0f - 10.0f)) * R_PD); // A*kOhm +static constexpr float I_LIM = (K_CL / R_PD); + +// There are different V_SNSFH thresholds if DIAG_EN gpio is set to LOw (3.3V) or HIGH (5V) +static constexpr float V_SNSFH_MIN = 3.5f; +static constexpr float V_SNSFH = 3.95f; +static constexpr float V_SNSFH_MAX = 4.4f; + +TI_TPS28_Efuse::TI_TPS28_Efuse( + const hw::Gpio &enable_gpio, + const hw::Adc &sns_adc_channel, + const hw::Gpio &fault_gpio, + const hw::Gpio &diag_en_gpio) + : Efuse(enable_gpio, sns_adc_channel), fault_gpio(fault_gpio), diag_en_gpio(diag_en_gpio), faults{} +{ +} + +// TODO: verify reset function +void TI_TPS28_Efuse::reset() +{ + this->enable_gpio.writePin(false); + this->enable_gpio.writePin(true); + this->enable_gpio.writePin(false); +} + +const bool TI_TPS28_Efuse::ok() +{ + const bool channel_enabled = this->isChannelEnabled(); + const bool diag_enabled = this->diag_en_gpio.readPin(); + const float voltage = this->getChannelCurrent() / ADC_VOLTAGE_TO_CURRENT_A; + + /** + * Note: Table 8.2 DIAG_EN Logic Table + * + * If DIAG_EN is low, FAULT will continue to indicate + * TSD (thermal_shdn) or ILIM (forgor what this is) + * + * Thus we only dont check for overcurrent if it's disabled + * + * TODO: but Table 8-3 contradicts this + */ + + // if diagnostics are not enabled, only check TSD and ILIM + const bool is_faulted = this->fault_gpio.readPin(); + if (diag_enabled) + { + if (is_faulted) + { + this->faults.flags.overcurrent = (channel_enabled && IS_IN_RANGE(V_SNSFH_MIN, V_SNSFH_MAX, voltage)); + this->faults.flags.thermal_shdn = + (channel_enabled && IS_IN_RANGE(V_SNSFH_MIN, V_SNSFH_MAX, voltage)); + } + else + { + this->faults.raw = 0x00U; + } + } + else + { + this->faults.raw = 0x03U; + } + + return !(this->faults.raw > 0U); +} +} // namespace io diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp new file mode 100644 index 0000000000..3d53ffb37d --- /dev/null +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include "io_efuse.hpp" + +namespace io +{ +class TI_TPS28_Efuse final : public Efuse +{ + private: + const hw::Gpio &fault_gpio; + const hw::Gpio &diag_en_gpio; + + /* Portable bit-fields: use 'unsigned' and name the subgroup */ + union + { + struct + { + uint8_t overcurrent : 1; + uint8_t thermal_shdn : 1; + uint8_t padding : 6; + } flags; + uint8_t raw; + } faults; + + public: + explicit TI_TPS28_Efuse( + const hw::Gpio &enable_gpio, + const hw::Adc &sns_adc_channel, + const hw::Gpio &fault_gpio, + const hw::Gpio &diag_en_gpio); + void reset() override final; + const bool ok() override final; +}; +} // namespace io From 8a623c7603fa33f54b62e050a31c1c128a909b2b Mon Sep 17 00:00:00 2001 From: Aditya-Dhiman4 Date: Fri, 28 Nov 2025 00:23:15 -0800 Subject: [PATCH 10/12] le format --- .../io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c | 3 ++- .../io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c | 11 +++++------ firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp | 12 ++++++------ firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp | 7 +++---- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c index 7f05fea541..784b8f6718 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c @@ -123,6 +123,7 @@ static bool io_efuse_ST_ok(const Efuse *efuse) // check if any flag is set, then return the status uint8_t flags = efuse->st_vnd5->faults.raw & ST_VND5_Efuse_FAULT_FLAGS; - // TODO: Do we want to return a boolean or should we just return the faults union and add additional methods to check specific faults + // TODO: Do we want to return a boolean or should we just return the faults union and add additional methods to + // check specific faults return !(flags > 0); } diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c index 2c0e32c0cd..9af94730c1 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c @@ -11,15 +11,15 @@ */ /** - * The Current limit (I_LIM) is set attaching the ILIM pinto a pulldown resistor. - * + * The Current limit (I_LIM) is set attaching the ILIM pinto a pulldown resistor. + * * The pulldown resistor must be between 10kOhm - 50kOhm * The current limit ration K_CL is: * 40 A*kOhm - 60 A*kOhm (Rev A or C) * 80 A*kOhm - 120 A*kOhm (Rev B, D, or C) */ -#define R_PD 24.9f //kOhm +#define R_PD 24.9f // kOhm // TODO: is this actualy a linear interpolation?? #define K_CL (((60.0f - 40.0f) / (50.0f - 10.0f)) * R_PD) // A*kOhm #define I_LIM (K_CL / R_PD) @@ -83,7 +83,7 @@ static bool io_TI_TPS28_Efuse_ok(const Efuse *efuse) bool channel_enabled = io_TI_TPS28_Efuse_isChannelEnabled(efuse); bool diag_enabled = hw_gpio_readPin(efuse->ti_tps28->diag_en_gpio); - float voltage = io_TI_TPS28_Efuse_getChannelCurrent(efuse) / ADC_VOLTAGE_TO_CURRENT_A; + float voltage = io_TI_TPS28_Efuse_getChannelCurrent(efuse) / ADC_VOLTAGE_TO_CURRENT_A; /** * Note: Table 8.2 DIAG_EN Logic Table @@ -96,7 +96,6 @@ static bool io_TI_TPS28_Efuse_ok(const Efuse *efuse) * TODO: but Table 8-3 contradicts this */ - // if diagnostics are not enabled, only check TSD and ILIM bool is_faulted = hw_gpio_readPin(efuse->ti_tps28->fault_gpio); if (diag_enabled) @@ -104,7 +103,7 @@ static bool io_TI_TPS28_Efuse_ok(const Efuse *efuse) if (is_faulted) { // Determine specific faults - efuse->ti_tps28->faults.flags.overcurrent = + efuse->ti_tps28->faults.flags.overcurrent = (channel_enabled && IS_IN_RANGE(V_SNSFH_MIN, V_SNSFH_MAX, voltage)); efuse->ti_tps28->faults.flags.thermal_shdn = (channel_enabled && IS_IN_RANGE(V_SNSFH_MIN, V_SNSFH_MAX, voltage)); diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp index d74ea20f9d..f76c66c681 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp @@ -43,15 +43,15 @@ void ST_VND5_Efuse::resetSet(const bool set) this->stby_reset_gpio.writePin(set); } -// TODO: Do we want to return a boolean or should we just return the faults union and add additional methods to check specific faults +// TODO: Do we want to return a boolean or should we just return the faults union and add additional methods to check +// specific faults const bool ST_VND5_Efuse::ok() { - const float voltage = this->getChannelCurrent() / ADC_VOLTAGE_TO_CURRENT_A; - const bool channel_enabled = this->isChannelEnabled(); - const bool fault_reset_stby = this->stby_reset_gpio.readPin(); + const float voltage = this->getChannelCurrent() / ADC_VOLTAGE_TO_CURRENT_A; + const bool channel_enabled = this->isChannelEnabled(); + const bool fault_reset_stby = this->stby_reset_gpio.readPin(); const uint8_t fault_table_idx = - static_cast((static_cast(fault_reset_stby) << 1U) | - static_cast(channel_enabled)); + static_cast((static_cast(fault_reset_stby) << 1U) | static_cast(channel_enabled)); // Setting faults for st_vnd5 efuse // TODO: verify these diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp index 9f0975deae..5246ab8648 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp @@ -22,7 +22,7 @@ extern "C" namespace io { -static constexpr float R_PD = 24.9f; // kOhm +static constexpr float R_PD = 24.9f; // kOhm // TODO: is this actualy a linear interpolation?? static constexpr float K_CL = (((60.0f - 40.0f) / (50.0f - 10.0f)) * R_PD); // A*kOhm static constexpr float I_LIM = (K_CL / R_PD); @@ -72,9 +72,8 @@ const bool TI_TPS28_Efuse::ok() { if (is_faulted) { - this->faults.flags.overcurrent = (channel_enabled && IS_IN_RANGE(V_SNSFH_MIN, V_SNSFH_MAX, voltage)); - this->faults.flags.thermal_shdn = - (channel_enabled && IS_IN_RANGE(V_SNSFH_MIN, V_SNSFH_MAX, voltage)); + this->faults.flags.overcurrent = (channel_enabled && IS_IN_RANGE(V_SNSFH_MIN, V_SNSFH_MAX, voltage)); + this->faults.flags.thermal_shdn = (channel_enabled && IS_IN_RANGE(V_SNSFH_MIN, V_SNSFH_MAX, voltage)); } else { From 2cc1887b8ef5dd0e70b131e7af97f5ef46d71fe2 Mon Sep 17 00:00:00 2001 From: Aditya-Dhiman4 Date: Sun, 30 Nov 2025 23:09:21 -0800 Subject: [PATCH 11/12] many smol changes --- firmware/shared/src/io/io_efuse/io_efuse.c | 10 +++- firmware/shared/src/io/io_efuse/io_efuse.h | 7 +++ .../io_efuse_ST_VND5/io_efuse_ST_VND5.c | 48 ++++++++++--------- .../io_efuse_TI_TPS25/io_efuse_TI_TPS25.c | 9 +++- .../io_efuse_TI_TPS28/io_efuse_TI_TPS28.c | 25 +++++++--- .../src/io/io_efuse/io_efuse_datatypes.h | 5 +- firmware/shared/srcpp/hw/hw_adc.hpp | 2 +- firmware/shared/srcpp/io/efuse/io_efuse.cpp | 26 ---------- firmware/shared/srcpp/io/efuse/io_efuse.hpp | 21 +++++--- .../srcpp/io/efuse/io_efuse_ST_VND5.cpp | 10 +--- .../srcpp/io/efuse/io_efuse_ST_VND5.hpp | 12 +++-- .../srcpp/io/efuse/io_efuse_TI_TPS25.cpp | 9 +--- .../srcpp/io/efuse/io_efuse_TI_TPS25.hpp | 7 +-- .../srcpp/io/efuse/io_efuse_TI_TPS28.cpp | 11 +---- .../srcpp/io/efuse/io_efuse_TI_TPS28.hpp | 14 +++--- 15 files changed, 111 insertions(+), 105 deletions(-) delete mode 100644 firmware/shared/srcpp/io/efuse/io_efuse.cpp diff --git a/firmware/shared/src/io/io_efuse/io_efuse.c b/firmware/shared/src/io/io_efuse/io_efuse.c index 766d780930..e69d89addb 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse.c +++ b/firmware/shared/src/io/io_efuse/io_efuse.c @@ -48,5 +48,13 @@ bool io_efuse_pgood(const Efuse *channel) bool io_efuse_ok(const Efuse *efuse) { assert(efuse != NULL); - return efuse->efuse_functions->efuse_ok(efuse); + return IS_EXIT_OK(efuse->efuse_functions->efuse_ok(efuse)); +} + +void io_efuse_setDiagnostics(const Efuse *efuse, bool enabled) +{ + assert(efuse != NULL); + assert(efuse->efuse_functions->set_diagnostics != NULL); + + efuse->efuse_functions->set_diagnostics(efuse, enabled); } diff --git a/firmware/shared/src/io/io_efuse/io_efuse.h b/firmware/shared/src/io/io_efuse/io_efuse.h index f63903e879..e87da0eae7 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse.h +++ b/firmware/shared/src/io/io_efuse/io_efuse.h @@ -51,3 +51,10 @@ bool io_efuse_pgood(const Efuse *channel); * @return True if status is ok, False otherwise */ bool io_efuse_ok(const Efuse *efuse); + +/** + * Enable or disable the provided efuse diagnostics. + * @param efuse Channel to enable/disable + * @param enabled Enable if enabled is true, disable if false + */ +void io_efuse_setDiagnostics(const Efuse *efuse, bool enabled); \ No newline at end of file diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c index 784b8f6718..87ddddce82 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c @@ -1,16 +1,22 @@ +#include +#include + #include "app_utils.h" + #include "io_efuse_ST_VND5.h" #include "io_efuse/io_efuse_datatypes.h" + #include "hw_gpio.h" -#include -#include + +#include "util_errorCodes.h" /** * ST_VND5 Efuse Datasheet: * https://octopart.com/datasheet/vnd5t100ajtr-e-stmicroelectronics-21218840 */ -#define NOMINAL_V 3.0f +// TODO: Characterize this voltage +#define NOMINAL_V 3.3f // Vsenseh lower threshold #define V_SENSE_H_L 7.5f // Vsenseh upper threshold @@ -31,7 +37,7 @@ static bool io_efuse_ST_isChannelEnabled(const Efuse *channel); static float io_efuse_ST_getChannelCurrent(const Efuse *channel); static void io_efuse_ST_reset_set(const Efuse *channel, bool set); static void io_efuse_ST_reset(const Efuse *channel); -static bool io_efuse_ST_ok(const Efuse *efuse); +static ExitCode io_efuse_ST_ok(const Efuse *efuse); const EfuseFunctions ST_VND5_Efuse_functions = { .set_channel = io_efuse_ST_setChannel, .is_channel_enabled = io_efuse_ST_isChannelEnabled, @@ -39,7 +45,8 @@ const EfuseFunctions ST_VND5_Efuse_functions = { .set_channel = io_efus .loadswitch_reset_set = io_efuse_ST_reset_set, .reset_efuse = io_efuse_ST_reset, .pgood = NULL, - .efuse_ok = io_efuse_ST_ok }; + .efuse_ok = io_efuse_ST_ok, + .set_diagnostics = NULL }; static void io_efuse_ST_setChannel(const Efuse *channel, bool enabled) { @@ -74,7 +81,7 @@ static void io_efuse_ST_reset(const Efuse *channel) hw_gpio_writePin(channel->st_vnd5->stby_reset_gpio, false); } -static bool io_efuse_ST_ok(const Efuse *efuse) +static ExitCode io_efuse_ST_ok(const Efuse *efuse) { assert(efuse != NULL); @@ -84,46 +91,43 @@ static bool io_efuse_ST_ok(const Efuse *efuse) uint8_t fault_table_idx = 0x00U | ((uint8_t)((fault_reset_stby << 1) | (channelEnabled))); // Setting faults for st_vnd5 efuse - // TODO: Verify these - if (fault_table_idx == L_L) + switch (fault_table_idx) { + case L_L: efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); efuse->st_vnd5->faults.flags.ovt_stp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - } - else if (fault_table_idx == L_H) - { + break; + case L_H: efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); efuse->st_vnd5->faults.flags.ovt_stp = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); // efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = (voltage <= 0.0f); - } - else if (fault_table_idx == H_L) - { + break; + case H_L: efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); efuse->st_vnd5->faults.flags.ovt_stp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); efuse->st_vnd5->faults.flags.short_to_vbat = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); efuse->st_vnd5->faults.flags.open_load_off_stat = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - } - else if (fault_table_idx == H_H) - { + break; + case H_H: efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); efuse->st_vnd5->faults.flags.ovt_stp = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); // efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = (voltage <= 0.0f); + break; + default: + break; } + // This fault is the same for all conditions efuse->st_vnd5->faults.flags.under_voltage = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); // check if any flag is set, then return the status - uint8_t flags = efuse->st_vnd5->faults.raw & ST_VND5_Efuse_FAULT_FLAGS; - - // TODO: Do we want to return a boolean or should we just return the faults union and add additional methods to - // check specific faults - return !(flags > 0); + return ((efuse->st_vnd5->faults.raw & ST_VND5_Efuse_FAULT_FLAGS) > 0) ? EXIT_CODE_ERROR : EXIT_CODE_OK; } diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c index efe83c2b0a..d858af5ff4 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c @@ -9,6 +9,7 @@ static bool io_TI_TPS25_Efuse_isChannelEnabled(const Efuse *channel); static float io_TI_TPS25_Efuse_getChannelCurrent(const Efuse *channel); static void io_TI_TPS25_Efuse_reset(const Efuse *efuse); static bool io_TI_TPS25_Efuse_pgood(const Efuse *efuse); +static ExitCode io_TI_TPS25_Efuse_ok(const Efuse *efuse); const EfuseFunctions TI_TPS25_Efuse_functions = { .set_channel = io_TI_TPS25_Efuse_setChannel, .is_channel_enabled = io_TI_TPS25_Efuse_isChannelEnabled, @@ -16,7 +17,8 @@ const EfuseFunctions TI_TPS25_Efuse_functions = { .set_channel = io_TI_ .loadswitch_reset_set = NULL, .reset_efuse = io_TI_TPS25_Efuse_reset, .pgood = io_TI_TPS25_Efuse_pgood, - .efuse_ok = io_TI_TPS25_Efuse_pgood }; + .efuse_ok = io_TI_TPS25_Efuse_ok, + .set_diagnostics = NULL }; static void io_TI_TPS25_Efuse_setChannel(const Efuse *channel, bool enabled) { @@ -51,3 +53,8 @@ static bool io_TI_TPS25_Efuse_pgood(const Efuse *efuse) assert(efuse->ti_tps25->pgood != NULL); return hw_gpio_readPin(efuse->ti_tps25->pgood); } + +static ExitCode io_TI_TPS25_Efuse_ok(const Efuse *efuse) +{ + return io_TI_TPS25_Efuse_pgood(efuse) ? EXIT_CODE_OK : EXIT_CODE_OK; +} diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c index 9af94730c1..ccbb23b6eb 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c @@ -11,17 +11,17 @@ */ /** - * The Current limit (I_LIM) is set attaching the ILIM pinto a pulldown resistor. + * The Current limit (I_LIM) is set attaching the ILIM pin to a pulldown resistor. * * The pulldown resistor must be between 10kOhm - 50kOhm - * The current limit ration K_CL is: + * The current limit ratio K_CL is: * 40 A*kOhm - 60 A*kOhm (Rev A or C) * 80 A*kOhm - 120 A*kOhm (Rev B, D, or C) */ #define R_PD 24.9f // kOhm -// TODO: is this actualy a linear interpolation?? -#define K_CL (((60.0f - 40.0f) / (50.0f - 10.0f)) * R_PD) // A*kOhm +// TODO: is this actualy a linear interpolation and which revision are we?? +#define K_CL ((((60.0f - 40.0f) / (50.0f - 10.0f)) * R_PD) + 35.0f) // A*kOhm #define I_LIM (K_CL / R_PD) // There are different V_SNSFH thresholds if DIAG_EN gpio is set to LOw (3.3V) or HIGH (5V) @@ -34,6 +34,7 @@ static bool io_TI_TPS28_Efuse_isChannelEnabled(const Efuse *channel); static float io_TI_TPS28_Efuse_getChannelCurrent(const Efuse *channel); static void io_TI_TPS28_Efuse_reset(const Efuse *efuse); static bool io_TI_TPS28_Efuse_pgood(const Efuse *efuse); +static ExitCode io_TI_TPS28_Efuse_ok(const Efuse *efuse); const EfuseFunctions TI_TPS28_Efuse_functions = { .set_channel = io_TI_TPS28_Efuse_setChannel, .is_channel_enabled = io_TI_TPS28_Efuse_isChannelEnabled, @@ -41,7 +42,8 @@ const EfuseFunctions TI_TPS28_Efuse_functions = { .set_channel = io_TI_ .loadswitch_reset_set = NULL, .reset_efuse = io_TI_TPS28_Efuse_reset, .pgood = NULL, - .efuse_ok = io_TI_TPS28_Efuse_ok }; + .efuse_ok = io_TI_TPS28_Efuse_ok, + .set_diagnostics = io_TI_TPS28_Efuse_setDiagnostics }; static void io_TI_TPS28_Efuse_setChannel(const Efuse *channel, bool enabled) { @@ -61,6 +63,12 @@ static bool io_TI_TPS28_Efuse_isDiagEnabled(const Efuse *channel) return hw_gpio_readPin(channel->ti_tps28->diag_en_gpio); } +static bool io_TI_TPS28_Efuse_setDiagnostics(const Efuse *efuse, bool enabled) +{ + assert(efuse->ti_tps28->diag_en_gpio != NULL); + hw_gpio_writePin(efuse->ti_tps28->diag_en_gpio, enabled); +} + static float io_TI_TPS28_Efuse_getChannelCurrent(const Efuse *channel) { const AdcChannel *current_sense = channel->sns_adc_channel; @@ -77,7 +85,7 @@ static void io_TI_TPS28_Efuse_reset(const Efuse *efuse) hw_gpio_writePin(efuse->enable_gpio, false); } -static bool io_TI_TPS28_Efuse_ok(const Efuse *efuse) +static ExitCode io_TI_TPS28_Efuse_ok(const Efuse *efuse) { assert(efuse != NULL); @@ -115,8 +123,11 @@ static bool io_TI_TPS28_Efuse_ok(const Efuse *efuse) } else { + // TODO: is there a different way to check diagnostics when diag_enabled is low or is it the same way?? efuse->ti_tps28->faults.raw = 0x03; } - return !(efuse->ti_tps28->faults.raw > 0); + return (efuse->ti_tps28->faults.raw > 0) ? EXIT_CODE_OK : EXIT_CODE_ERROR; } + +static void io diff --git a/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h index b893fc91ca..8c3ef6caae 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h +++ b/firmware/shared/src/io/io_efuse/io_efuse_datatypes.h @@ -4,6 +4,8 @@ #include "hw_gpio.h" #include "hw_adc.h" +#include "util_errorCodes.h" + #define ADC_VOLTAGE_TO_CURRENT_A 1.720f typedef struct __Efuse Efuse; @@ -20,7 +22,8 @@ struct __EfuseFunctions void (*loadswitch_reset_set)(const Efuse *channel, bool set); void (*reset_efuse)(const Efuse *channel); bool (*pgood)(const Efuse *channel); - bool (*efuse_ok)(const Efuse *efuse); + ExitCode (*efuse_ok)(const Efuse *efuse); + bool (*set_diagnostics)(const Efuse *efuse, bool enabled); }; struct __Efuse diff --git a/firmware/shared/srcpp/hw/hw_adc.hpp b/firmware/shared/srcpp/hw/hw_adc.hpp index 2e10916999..8f3db48d60 100644 --- a/firmware/shared/srcpp/hw/hw_adc.hpp +++ b/firmware/shared/srcpp/hw/hw_adc.hpp @@ -1,6 +1,6 @@ #pragma once -#include "app_utils.hpp" +#include "util_utils.hpp" #include #ifdef TARGET_EMBEDDED diff --git a/firmware/shared/srcpp/io/efuse/io_efuse.cpp b/firmware/shared/srcpp/io/efuse/io_efuse.cpp deleted file mode 100644 index 3422b00a42..0000000000 --- a/firmware/shared/srcpp/io/efuse/io_efuse.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "io_efuse.hpp" -#include "hw_gpio.hpp" -#include "hw_adc.hpp" - -namespace io::efuse -{ -Efuse::Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel) - : enable_gpio(enable_gpio), sns_adc_channel(sns_adc_channel) -{ -} - -void Efuse::setChannel(bool enabled) -{ - this->enable_gpio.writePin(enabled); -} - -const bool Efuse::isChannelEnabled() -{ - return this->enable_gpio.readPin(); -} - -const float Efuse::getChannelCurrent() -{ - return this->sns_adc_channel.getVoltage() * ADC_VOLTAGE_TO_CURRENT_A; -} -} // namespace io::efuse \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse.hpp b/firmware/shared/srcpp/io/efuse/io_efuse.hpp index 72f48dd3f0..ab4c981e20 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse.hpp @@ -14,15 +14,24 @@ class Efuse const hw::Adc &sns_adc_channel; public: - Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel) - : enable_gpio(enable_gpio), sns_adc_channel(sns_adc_channel) + explicit consteval Efuse(const hw::Gpio &in_enable_gpio, const hw::Adc &in_sns_adc_channel) + : enable_gpio(in_enable_gpio), sns_adc_channel(in_sns_adc_channel) { } virtual ~Efuse() = default; - void setChannel(bool enabled); - const bool isChannelEnabled(); - const float getChannelCurrent(); + void setChannel(bool enabled) + { + enable_gpio.writePin(enabled); + } + bool isChannelEnabled() const + { + return this->enable_gpio.readPin(); + } + float getChannelCurrent() + { + return this->sns_adc_channel.getVoltage() * ADC_VOLTAGE_TO_CURRENT_A; + } virtual void reset() = 0; - virtual const bool ok() = 0; + virtual bool ok() = 0; }; } // namespace io \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp index f76c66c681..0e0afb5aaf 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.cpp @@ -23,14 +23,6 @@ static constexpr uint8_t L_H = 0x01U; static constexpr uint8_t H_L = 0x02U; static constexpr uint8_t H_H = 0x03U; -ST_VND5_Efuse::ST_VND5_Efuse( - const hw::Gpio &enable_gpio, - const hw::Adc &sns_adc_channel, - const hw::Gpio &stby_reset_gpio) - : Efuse(enable_gpio, sns_adc_channel), stby_reset_gpio(stby_reset_gpio), faults{} -{ -} - void ST_VND5_Efuse::reset() { this->stby_reset_gpio.writePin(false); @@ -45,7 +37,7 @@ void ST_VND5_Efuse::resetSet(const bool set) // TODO: Do we want to return a boolean or should we just return the faults union and add additional methods to check // specific faults -const bool ST_VND5_Efuse::ok() +bool ST_VND5_Efuse::ok() { const float voltage = this->getChannelCurrent() / ADC_VOLTAGE_TO_CURRENT_A; const bool channel_enabled = this->isChannelEnabled(); diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp index 9f31247fc1..5e38e1ab8e 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp @@ -25,12 +25,14 @@ class ST_VND5_Efuse final : public Efuse } faults; public: - explicit ST_VND5_Efuse( - const hw::Gpio &enable_gpio, - const hw::Adc &sns_adc_channel, - const hw::Gpio &stby_reset_gpio); + explicit consteval ST_VND5_Efuse( + const hw::Gpio &in_enable_gpio, + const hw::Adc &in_sns_adc_channel, + const hw::Gpio &in_stby_reset_gpio) + : Efuse(in_enable_gpio, in_sns_adc_channel), stby_reset_gpio(in_stby_reset_gpio) + {} void reset() override final; void resetSet(const bool set); - const bool ok() override final; + bool ok() override final; }; } // namespace io diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp index a5b1754c0f..8d86220b75 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp @@ -4,11 +4,6 @@ namespace io { -TI_TPS25_Efuse::TI_TPS25_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &pgood) - : Efuse(enable_gpio, sns_adc_channel), pgood_gpio(pgood) -{ -} - void TI_TPS25_Efuse::reset() { this->enable_gpio.writePin(false); @@ -16,12 +11,12 @@ void TI_TPS25_Efuse::reset() this->enable_gpio.writePin(false); } -const bool TI_TPS25_Efuse::pgood() +bool TI_TPS25_Efuse::pgood() const { return this->pgood_gpio.readPin(); } -const bool TI_TPS25_Efuse::ok() +bool TI_TPS25_Efuse::ok() { return this->pgood(); } diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp index 73b8098a19..3ead6f54b2 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp @@ -11,9 +11,10 @@ class TI_TPS25_Efuse final : public Efuse const hw::Gpio &pgood_gpio; public: - explicit TI_TPS25_Efuse(const hw::Gpio &enable_gpio, const hw::Adc &sns_adc_channel, const hw::Gpio &pgood); + explicit consteval TI_TPS25_Efuse(const hw::Gpio &in_enable_gpio, const hw::Adc &in_sns_adc_channel, const hw::Gpio &in_pgood) + : Efuse(in_enable_gpio, in_sns_adc_channel), pgood_gpio(in_pgood) {} void reset() override final; - const bool pgood(); - const bool ok() override final; + bool pgood() const; + bool ok() override final; }; } // namespace io diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp index 5246ab8648..92c9740c97 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.cpp @@ -32,15 +32,6 @@ static constexpr float V_SNSFH_MIN = 3.5f; static constexpr float V_SNSFH = 3.95f; static constexpr float V_SNSFH_MAX = 4.4f; -TI_TPS28_Efuse::TI_TPS28_Efuse( - const hw::Gpio &enable_gpio, - const hw::Adc &sns_adc_channel, - const hw::Gpio &fault_gpio, - const hw::Gpio &diag_en_gpio) - : Efuse(enable_gpio, sns_adc_channel), fault_gpio(fault_gpio), diag_en_gpio(diag_en_gpio), faults{} -{ -} - // TODO: verify reset function void TI_TPS28_Efuse::reset() { @@ -49,7 +40,7 @@ void TI_TPS28_Efuse::reset() this->enable_gpio.writePin(false); } -const bool TI_TPS28_Efuse::ok() +bool TI_TPS28_Efuse::ok() { const bool channel_enabled = this->isChannelEnabled(); const bool diag_enabled = this->diag_en_gpio.readPin(); diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp index 3d53ffb37d..25a103ca7e 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp @@ -24,12 +24,14 @@ class TI_TPS28_Efuse final : public Efuse } faults; public: - explicit TI_TPS28_Efuse( - const hw::Gpio &enable_gpio, - const hw::Adc &sns_adc_channel, - const hw::Gpio &fault_gpio, - const hw::Gpio &diag_en_gpio); + explicit consteval TI_TPS28_Efuse( + const hw::Gpio &in_enable_gpio, + const hw::Adc &in_sns_adc_channel, + const hw::Gpio &in_fault_gpio, + const hw::Gpio &in_diag_en_gpio) + : Efuse(in_enable_gpio, in_sns_adc_channel), fault_gpio(in_fault_gpio), diag_en_gpio(in_diag_en_gpio) + {} void reset() override final; - const bool ok() override final; + bool ok() override final; }; } // namespace io From a1311f3d8f9bdb98571ee91629e3b3c5f4e225c2 Mon Sep 17 00:00:00 2001 From: Aditya-Dhiman4 Date: Sun, 30 Nov 2025 23:09:57 -0800 Subject: [PATCH 12/12] format --- .../io_efuse_ST_VND5/io_efuse_ST_VND5.c | 74 +++++++++---------- .../io_efuse_TI_TPS25/io_efuse_TI_TPS25.c | 12 +-- .../io_efuse_TI_TPS28/io_efuse_TI_TPS28.c | 12 +-- firmware/shared/srcpp/io/efuse/io_efuse.hpp | 17 +---- .../srcpp/io/efuse/io_efuse_ST_VND5.hpp | 9 ++- .../srcpp/io/efuse/io_efuse_TI_TPS25.cpp | 2 +- .../srcpp/io/efuse/io_efuse_TI_TPS25.hpp | 11 ++- .../srcpp/io/efuse/io_efuse_TI_TPS28.hpp | 7 +- 8 files changed, 71 insertions(+), 73 deletions(-) diff --git a/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c index 87ddddce82..8dc580524a 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c @@ -32,12 +32,12 @@ #define H_L 0x02U #define H_H 0x03U -static void io_efuse_ST_setChannel(const Efuse *channel, bool enabled); -static bool io_efuse_ST_isChannelEnabled(const Efuse *channel); -static float io_efuse_ST_getChannelCurrent(const Efuse *channel); -static void io_efuse_ST_reset_set(const Efuse *channel, bool set); -static void io_efuse_ST_reset(const Efuse *channel); -static ExitCode io_efuse_ST_ok(const Efuse *efuse); +static void io_efuse_ST_setChannel(const Efuse *channel, bool enabled); +static bool io_efuse_ST_isChannelEnabled(const Efuse *channel); +static float io_efuse_ST_getChannelCurrent(const Efuse *channel); +static void io_efuse_ST_reset_set(const Efuse *channel, bool set); +static void io_efuse_ST_reset(const Efuse *channel); +static ExitCode io_efuse_ST_ok(const Efuse *efuse); const EfuseFunctions ST_VND5_Efuse_functions = { .set_channel = io_efuse_ST_setChannel, .is_channel_enabled = io_efuse_ST_isChannelEnabled, @@ -46,7 +46,7 @@ const EfuseFunctions ST_VND5_Efuse_functions = { .set_channel = io_efus .reset_efuse = io_efuse_ST_reset, .pgood = NULL, .efuse_ok = io_efuse_ST_ok, - .set_diagnostics = NULL }; + .set_diagnostics = NULL }; static void io_efuse_ST_setChannel(const Efuse *channel, bool enabled) { @@ -93,36 +93,36 @@ static ExitCode io_efuse_ST_ok(const Efuse *efuse) // Setting faults for st_vnd5 efuse switch (fault_table_idx) { - case L_L: - efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - efuse->st_vnd5->faults.flags.ovt_stp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - break; - case L_H: - efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); - efuse->st_vnd5->faults.flags.ovt_stp = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); - efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); - efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - // efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = (voltage <= 0.0f); - break; - case H_L: - efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - efuse->st_vnd5->faults.flags.ovt_stp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - efuse->st_vnd5->faults.flags.short_to_vbat = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); - efuse->st_vnd5->faults.flags.open_load_off_stat = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); - efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - break; - case H_H: - efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); - efuse->st_vnd5->faults.flags.ovt_stp = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); - efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); - efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); - // efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = (voltage <= 0.0f); - break; - default: - break; + case L_L: + efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.ovt_stp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + break; + case L_H: + efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + efuse->st_vnd5->faults.flags.ovt_stp = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + // efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = (voltage <= 0.0f); + break; + case H_L: + efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.ovt_stp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + efuse->st_vnd5->faults.flags.short_to_vbat = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + efuse->st_vnd5->faults.flags.open_load_off_stat = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + break; + case H_H: + efuse->st_vnd5->faults.flags.overload = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + efuse->st_vnd5->faults.flags.ovt_stp = IS_IN_RANGE(V_SENSE_H_L, V_SENSE_H_H, voltage); + efuse->st_vnd5->faults.flags.short_to_vbat = APPROX_EQUAL_FLOAT(voltage, NOMINAL_V, V_THRES); + efuse->st_vnd5->faults.flags.open_load_off_stat = APPROX_EQUAL_FLOAT(voltage, 0.0f, V_THRES); + // efuse->st_vnd5->faults.flags.negative_output_voltage_clamp = (voltage <= 0.0f); + break; + default: + break; } // This fault is the same for all conditions diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c index d858af5ff4..625a96bde6 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c @@ -4,11 +4,11 @@ #include #include -static void io_TI_TPS25_Efuse_setChannel(const Efuse *channel, bool enabled); -static bool io_TI_TPS25_Efuse_isChannelEnabled(const Efuse *channel); -static float io_TI_TPS25_Efuse_getChannelCurrent(const Efuse *channel); -static void io_TI_TPS25_Efuse_reset(const Efuse *efuse); -static bool io_TI_TPS25_Efuse_pgood(const Efuse *efuse); +static void io_TI_TPS25_Efuse_setChannel(const Efuse *channel, bool enabled); +static bool io_TI_TPS25_Efuse_isChannelEnabled(const Efuse *channel); +static float io_TI_TPS25_Efuse_getChannelCurrent(const Efuse *channel); +static void io_TI_TPS25_Efuse_reset(const Efuse *efuse); +static bool io_TI_TPS25_Efuse_pgood(const Efuse *efuse); static ExitCode io_TI_TPS25_Efuse_ok(const Efuse *efuse); const EfuseFunctions TI_TPS25_Efuse_functions = { .set_channel = io_TI_TPS25_Efuse_setChannel, @@ -18,7 +18,7 @@ const EfuseFunctions TI_TPS25_Efuse_functions = { .set_channel = io_TI_ .reset_efuse = io_TI_TPS25_Efuse_reset, .pgood = io_TI_TPS25_Efuse_pgood, .efuse_ok = io_TI_TPS25_Efuse_ok, - .set_diagnostics = NULL }; + .set_diagnostics = NULL }; static void io_TI_TPS25_Efuse_setChannel(const Efuse *channel, bool enabled) { diff --git a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c index ccbb23b6eb..7cd59df69c 100644 --- a/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c +++ b/firmware/shared/src/io/io_efuse/io_efuse_TI_TPS28/io_efuse_TI_TPS28.c @@ -29,11 +29,11 @@ #define V_SNSFH 3.95f #define V_SNSFH_MAX 4.4f -static void io_TI_TPS28_Efuse_setChannel(const Efuse *channel, bool enabled); -static bool io_TI_TPS28_Efuse_isChannelEnabled(const Efuse *channel); -static float io_TI_TPS28_Efuse_getChannelCurrent(const Efuse *channel); -static void io_TI_TPS28_Efuse_reset(const Efuse *efuse); -static bool io_TI_TPS28_Efuse_pgood(const Efuse *efuse); +static void io_TI_TPS28_Efuse_setChannel(const Efuse *channel, bool enabled); +static bool io_TI_TPS28_Efuse_isChannelEnabled(const Efuse *channel); +static float io_TI_TPS28_Efuse_getChannelCurrent(const Efuse *channel); +static void io_TI_TPS28_Efuse_reset(const Efuse *efuse); +static bool io_TI_TPS28_Efuse_pgood(const Efuse *efuse); static ExitCode io_TI_TPS28_Efuse_ok(const Efuse *efuse); const EfuseFunctions TI_TPS28_Efuse_functions = { .set_channel = io_TI_TPS28_Efuse_setChannel, @@ -43,7 +43,7 @@ const EfuseFunctions TI_TPS28_Efuse_functions = { .set_channel = io_TI_ .reset_efuse = io_TI_TPS28_Efuse_reset, .pgood = NULL, .efuse_ok = io_TI_TPS28_Efuse_ok, - .set_diagnostics = io_TI_TPS28_Efuse_setDiagnostics }; + .set_diagnostics = io_TI_TPS28_Efuse_setDiagnostics }; static void io_TI_TPS28_Efuse_setChannel(const Efuse *channel, bool enabled) { diff --git a/firmware/shared/srcpp/io/efuse/io_efuse.hpp b/firmware/shared/srcpp/io/efuse/io_efuse.hpp index ab4c981e20..9f840874a5 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse.hpp @@ -19,19 +19,10 @@ class Efuse { } virtual ~Efuse() = default; - void setChannel(bool enabled) - { - enable_gpio.writePin(enabled); - } - bool isChannelEnabled() const - { - return this->enable_gpio.readPin(); - } - float getChannelCurrent() - { - return this->sns_adc_channel.getVoltage() * ADC_VOLTAGE_TO_CURRENT_A; - } - virtual void reset() = 0; + void setChannel(bool enabled) { enable_gpio.writePin(enabled); } + bool isChannelEnabled() const { return this->enable_gpio.readPin(); } + float getChannelCurrent() { return this->sns_adc_channel.getVoltage() * ADC_VOLTAGE_TO_CURRENT_A; } + virtual void reset() = 0; virtual bool ok() = 0; }; } // namespace io \ No newline at end of file diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp index 5e38e1ab8e..22895fe82b 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_ST_VND5.hpp @@ -29,10 +29,11 @@ class ST_VND5_Efuse final : public Efuse const hw::Gpio &in_enable_gpio, const hw::Adc &in_sns_adc_channel, const hw::Gpio &in_stby_reset_gpio) - : Efuse(in_enable_gpio, in_sns_adc_channel), stby_reset_gpio(in_stby_reset_gpio) - {} - void reset() override final; - void resetSet(const bool set); + : Efuse(in_enable_gpio, in_sns_adc_channel), stby_reset_gpio(in_stby_reset_gpio) + { + } + void reset() override final; + void resetSet(const bool set); bool ok() override final; }; } // namespace io diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp index 8d86220b75..892b5d9bb0 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.cpp @@ -11,7 +11,7 @@ void TI_TPS25_Efuse::reset() this->enable_gpio.writePin(false); } -bool TI_TPS25_Efuse::pgood() const +bool TI_TPS25_Efuse::pgood() const { return this->pgood_gpio.readPin(); } diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp index 3ead6f54b2..a5e87db980 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS25.hpp @@ -11,9 +11,14 @@ class TI_TPS25_Efuse final : public Efuse const hw::Gpio &pgood_gpio; public: - explicit consteval TI_TPS25_Efuse(const hw::Gpio &in_enable_gpio, const hw::Adc &in_sns_adc_channel, const hw::Gpio &in_pgood) - : Efuse(in_enable_gpio, in_sns_adc_channel), pgood_gpio(in_pgood) {} - void reset() override final; + explicit consteval TI_TPS25_Efuse( + const hw::Gpio &in_enable_gpio, + const hw::Adc &in_sns_adc_channel, + const hw::Gpio &in_pgood) + : Efuse(in_enable_gpio, in_sns_adc_channel), pgood_gpio(in_pgood) + { + } + void reset() override final; bool pgood() const; bool ok() override final; }; diff --git a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp index 25a103ca7e..bc9e9fcb18 100644 --- a/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp +++ b/firmware/shared/srcpp/io/efuse/io_efuse_TI_TPS28.hpp @@ -29,9 +29,10 @@ class TI_TPS28_Efuse final : public Efuse const hw::Adc &in_sns_adc_channel, const hw::Gpio &in_fault_gpio, const hw::Gpio &in_diag_en_gpio) - : Efuse(in_enable_gpio, in_sns_adc_channel), fault_gpio(in_fault_gpio), diag_en_gpio(in_diag_en_gpio) - {} - void reset() override final; + : Efuse(in_enable_gpio, in_sns_adc_channel), fault_gpio(in_fault_gpio), diag_en_gpio(in_diag_en_gpio) + { + } + void reset() override final; bool ok() override final; }; } // namespace io