From 50ed21fe0117b44388b0f3ea378d2f7f160774de Mon Sep 17 00:00:00 2001 From: Hewitt McGaughey Date: Thu, 9 Sep 2021 21:34:24 -0400 Subject: [PATCH] [SOFT-514] Improve MCI status broadcast (#433) This improves the MCI status broadcast so it sends more useful info. In short, SYSTEM_CAN_MESSAGE_MOTOR_STATUS now sends each WaveSculptor's status/limit flags, as well as any board overtemperatures and overtemperatures from the WaveSculptor's temperature messages (to be added in SOFT-534). --- codegen/can_messages.asciipb | 10 +- libraries/codegen-tooling/inc/can_pack.h | 11 +- libraries/codegen-tooling/inc/can_transmit.h | 15 +-- libraries/codegen-tooling/inc/can_unpack.h | 9 +- projects/mci/inc/mci_broadcast.h | 43 +++++++- projects/mci/rules.mk | 1 + projects/mci/src/mci_broadcast.c | 27 +++-- projects/mci/test/test_mci_broadcast.c | 103 ++++++++++++++----- 8 files changed, 171 insertions(+), 48 deletions(-) diff --git a/codegen/can_messages.asciipb b/codegen/can_messages.asciipb index 65a4d988d..2a0ad16c0 100644 --- a/codegen/can_messages.asciipb +++ b/codegen/can_messages.asciipb @@ -341,9 +341,13 @@ msg { target: "TELEMETRY" msg_name: "motor status" can_data { - u32 { - field_name_1: "motor_status_l" - field_name_2: "motor_status_r" + u8 { + field_name_1: "mc_limit_flags_l" + field_name_2: "mc_limit_flags_r" + field_name_3: "mc_error_flags_l" + field_name_4: "mc_error_flags_r" + field_name_5: "board_fan_faults" + field_name_6: "mc_overtemp" } } } diff --git a/libraries/codegen-tooling/inc/can_pack.h b/libraries/codegen-tooling/inc/can_pack.h index ab1918085..79ccb352c 100644 --- a/libraries/codegen-tooling/inc/can_pack.h +++ b/libraries/codegen-tooling/inc/can_pack.h @@ -127,10 +127,13 @@ SYSTEM_CAN_MESSAGE_MOTOR_VELOCITY, 4, (vehicle_velocity_left_u16), \ (vehicle_velocity_right_u16), CAN_PACK_IMPL_EMPTY, CAN_PACK_IMPL_EMPTY) -#define CAN_PACK_MOTOR_STATUS(msg_ptr, motor_status_l_u32, motor_status_r_u32) \ - can_pack_impl_u32((msg_ptr), SYSTEM_CAN_DEVICE_MOTOR_CONTROLLER, \ - SYSTEM_CAN_MESSAGE_MOTOR_STATUS, 8, (motor_status_l_u32), \ - (motor_status_r_u32)) +#define CAN_PACK_MOTOR_STATUS(msg_ptr, mc_limit_flags_l_u8, mc_limit_flags_r_u8, \ + mc_error_flags_l_u8, mc_error_flags_r_u8, board_fan_faults_u8, \ + mc_overtemp_u8) \ + can_pack_impl_u8((msg_ptr), SYSTEM_CAN_DEVICE_MOTOR_CONTROLLER, SYSTEM_CAN_MESSAGE_MOTOR_STATUS, \ + 6, (mc_limit_flags_l_u8), (mc_limit_flags_r_u8), (mc_error_flags_l_u8), \ + (mc_error_flags_r_u8), (board_fan_faults_u8), (mc_overtemp_u8), \ + CAN_PACK_IMPL_EMPTY, CAN_PACK_IMPL_EMPTY) #define CAN_PACK_MOTOR_SINK_TEMPS(msg_ptr, motor_temp_l_u16, sink_temp_l_u16, motor_temp_r_u16, \ sink_temp_r_u16) \ diff --git a/libraries/codegen-tooling/inc/can_transmit.h b/libraries/codegen-tooling/inc/can_transmit.h index c8770d9f3..8baeb44b0 100644 --- a/libraries/codegen-tooling/inc/can_transmit.h +++ b/libraries/codegen-tooling/inc/can_transmit.h @@ -209,12 +209,15 @@ status; \ }) -#define CAN_TRANSMIT_MOTOR_STATUS(motor_status_l_u32, motor_status_r_u32) \ - ({ \ - CanMessage msg = { 0 }; \ - CAN_PACK_MOTOR_STATUS(&msg, (motor_status_l_u32), (motor_status_r_u32)); \ - StatusCode status = can_transmit(&msg, NULL); \ - status; \ +#define CAN_TRANSMIT_MOTOR_STATUS(mc_limit_flags_l_u8, mc_limit_flags_r_u8, mc_error_flags_l_u8, \ + mc_error_flags_r_u8, board_fan_faults_u8, mc_overtemp_u8) \ + ({ \ + CanMessage msg = { 0 }; \ + CAN_PACK_MOTOR_STATUS(&msg, (mc_limit_flags_l_u8), (mc_limit_flags_r_u8), \ + (mc_error_flags_l_u8), (mc_error_flags_r_u8), (board_fan_faults_u8), \ + (mc_overtemp_u8)); \ + StatusCode status = can_transmit(&msg, NULL); \ + status; \ }) #define CAN_TRANSMIT_MOTOR_SINK_TEMPS(motor_temp_l_u16, sink_temp_l_u16, motor_temp_r_u16, \ diff --git a/libraries/codegen-tooling/inc/can_unpack.h b/libraries/codegen-tooling/inc/can_unpack.h index 093c4c0a4..ada31b2d7 100644 --- a/libraries/codegen-tooling/inc/can_unpack.h +++ b/libraries/codegen-tooling/inc/can_unpack.h @@ -99,8 +99,13 @@ (vehicle_velocity_right_u16_ptr), CAN_UNPACK_IMPL_EMPTY, \ CAN_UNPACK_IMPL_EMPTY) -#define CAN_UNPACK_MOTOR_STATUS(msg_ptr, motor_status_l_u32_ptr, motor_status_r_u32_ptr) \ - can_unpack_impl_u32((msg_ptr), 8, (motor_status_l_u32_ptr), (motor_status_r_u32_ptr)) +#define CAN_UNPACK_MOTOR_STATUS(msg_ptr, mc_limit_flags_l_u8_ptr, mc_limit_flags_r_u8_ptr, \ + mc_error_flags_l_u8_ptr, mc_error_flags_r_u8_ptr, \ + board_fan_faults_u8_ptr, mc_overtemp_u8_ptr) \ + can_unpack_impl_u8((msg_ptr), 6, (mc_limit_flags_l_u8_ptr), (mc_limit_flags_r_u8_ptr), \ + (mc_error_flags_l_u8_ptr), (mc_error_flags_r_u8_ptr), \ + (board_fan_faults_u8_ptr), (mc_overtemp_u8_ptr), CAN_UNPACK_IMPL_EMPTY, \ + CAN_UNPACK_IMPL_EMPTY) #define CAN_UNPACK_MOTOR_SINK_TEMPS(msg_ptr, motor_temp_l_u16_ptr, sink_temp_l_u16_ptr, \ motor_temp_r_u16_ptr, sink_temp_r_u16_ptr) \ diff --git a/projects/mci/inc/mci_broadcast.h b/projects/mci/inc/mci_broadcast.h index 51957f8c9..a03717fdb 100644 --- a/projects/mci/inc/mci_broadcast.h +++ b/projects/mci/inc/mci_broadcast.h @@ -32,10 +32,51 @@ typedef enum { #define LEFT_MOTOR_CONTROLLER_BASE_ADDR 0x400 #define RIGHT_MOTOR_CONTROLLER_BASE_ADDR 0x200 +// Limit flags -- see WS22 user manual for more info +typedef enum { + MCI_LIMIT_OUTPUT_VOLTAGE = 0, + MCI_LIMIT_MOTOR_CURRENT, + MCI_LIMIT_VELOCITY, + MCI_LIMIT_BUS_CURRENT, + MCI_LIMIT_VOLTAGE_UPPER, + MCI_LIMIT_VOLTAGE_LOWER, + MCI_LIMIT_TEMPERATURE, + NUM_MCI_LIMITS, +} MciLimit; +static_assert(NUM_MCI_LIMITS <= sizeof(uint8_t) * 8, "MciLimit is too large to store in a uint8_t"); + +// Error flags -- see WS22 user manual for more info +typedef enum { + MCI_ERROR_RESERVED0 = 0, // First bit reserved + MCI_ERROR_SW_OVERCURRENT, + MCI_ERROR_BUS_OVERVOLTAGE, + MCI_ERROR_BAD_POSITION, + MCI_ERROR_WATCHDOG, + MCI_ERROR_CONFIG_READ, + MCI_ERROR_UVLO, + MCI_ERROR_OVERSPEED, + NUM_MCI_ERRORS, +} MciError; +static_assert(NUM_MCI_ERRORS <= sizeof(uint8_t) * 8, "MciError is too large to store in a uint8_t"); + +// To mask out reserved bits +#define MCI_LIMIT_MASK ((1 << NUM_MCI_LIMITS) - 1) +#define MCI_ERROR_MASK ((1 << NUM_MCI_ERRORS) - 1) + +// Stores status info for broadcasting +typedef struct { + uint8_t mc_limit_bitset[NUM_MOTOR_CONTROLLERS]; // from each WS + uint8_t mc_error_bitset[NUM_MOTOR_CONTROLLERS]; // from each WS + uint8_t board_fault_bitset; // from mci_fan_control + uint8_t mc_overtemp_bitset; // from temp messages +} MciStatusMessage; +static_assert(sizeof(MciStatusMessage) <= sizeof(uint64_t), + "MciStatusMessage is too large to store in a uint64_t"); + typedef struct MotorControllerMeasurements { WaveSculptorBusMeasurement bus_measurements[NUM_MOTOR_CONTROLLERS]; float vehicle_velocity[NUM_MOTOR_CONTROLLERS]; - uint32_t status[NUM_MOTOR_CONTROLLERS]; + MciStatusMessage status; WaveSculptorSinkMotorTempMeasurement sink_motor_measurements[NUM_MOTOR_CONTROLLERS]; WaveSculptorDspTempMeasurement dsp_measurements[NUM_MOTOR_CONTROLLERS]; } MotorControllerMeasurements; diff --git a/projects/mci/rules.mk b/projects/mci/rules.mk index a38c36db3..cdca5aeb6 100644 --- a/projects/mci/rules.mk +++ b/projects/mci/rules.mk @@ -15,4 +15,5 @@ $(T)_test_drive_fsm_MOCKS := get_precharge_state $(T)_test_cruise_rx_MOCKS := get_precharge_state $(T)_test_mci_output_MOCKS := mcp2515_tx drive_fsm_get_drive_state $(T)_test_mci_fan_control_MOCKS := gpio_get_state gpio_set_state +$(T)_test_mci_broadcast_MOCKS := mci_fan_get_fault_bitset endif diff --git a/projects/mci/src/mci_broadcast.c b/projects/mci/src/mci_broadcast.c index 924cdb4a3..2829b140d 100644 --- a/projects/mci/src/mci_broadcast.c +++ b/projects/mci/src/mci_broadcast.c @@ -10,6 +10,7 @@ #include "controller_board_pins.h" #include "cruise_rx.h" #include "log.h" +#include "mci_fan_control.h" #include "motor_can.h" #include "motor_controller.h" #include "soft_timer.h" @@ -54,9 +55,12 @@ static void prv_broadcast_bus_measurement(MotorControllerBroadcastStorage *stora // Status static void prv_broadcast_status(MotorControllerBroadcastStorage *storage) { - uint32_t *measurements = storage->measurements.status; - CAN_TRANSMIT_MOTOR_STATUS(measurements[LEFT_MOTOR_CONTROLLER], - measurements[RIGHT_MOTOR_CONTROLLER]); + MciStatusMessage message = storage->measurements.status; + CAN_TRANSMIT_MOTOR_STATUS(message.mc_limit_bitset[LEFT_MOTOR_CONTROLLER], + message.mc_limit_bitset[RIGHT_MOTOR_CONTROLLER], + message.mc_error_bitset[LEFT_MOTOR_CONTROLLER], + message.mc_error_bitset[RIGHT_MOTOR_CONTROLLER], + message.board_fault_bitset, message.mc_overtemp_bitset); } // Motor and heat sink temperatures @@ -83,13 +87,22 @@ static void prv_handle_status_rx(const GenericCanMsg *msg, void *context) { WaveSculptorCanId can_id = { .raw = msg->id }; WaveSculptorCanData can_data = { .raw = msg->data }; - // Cast out upper 32 bits so we can broadcast both status in one CAN message - uint32_t status = (uint32_t)(can_data.raw); - for (size_t motor_id = 0; motor_id < NUM_MOTOR_CONTROLLERS; motor_id++) { if (can_id.device_id == storage->ids[motor_id]) { bool disabled = critical_section_start(); - storage->measurements.status[motor_id] = status; + // Update status message with error/limit flags + storage->measurements.status.mc_error_bitset[motor_id] = + can_data.status_info.error_flags.raw & MCI_ERROR_MASK; + storage->measurements.status.mc_limit_bitset[motor_id] = + can_data.status_info.limit_flags.raw & MCI_LIMIT_MASK; + + // Technically we only need to update these bitsets prior to broadcasting the status, but it + // makes testing easier to update all status bitsets at the same time + storage->measurements.status.board_fault_bitset = mci_fan_get_fault_bitset(); + + // TODO(SOFT-534): updatee this with the actual value + storage->measurements.status.mc_overtemp_bitset = 0; + storage->status_rx_bitset |= 1 << motor_id; critical_section_end(disabled); break; diff --git a/projects/mci/test/test_mci_broadcast.c b/projects/mci/test/test_mci_broadcast.c index 407629e21..7f134b0fe 100644 --- a/projects/mci/test/test_mci_broadcast.c +++ b/projects/mci/test/test_mci_broadcast.c @@ -70,7 +70,7 @@ typedef struct TestWaveSculptorSinkMotorTempMeasurement { typedef struct TestMotorControllerMeasurements { TestWaveSculptorBusMeasurement bus_measurements[NUM_MOTOR_CONTROLLERS]; uint16_t vehicle_velocity[NUM_MOTOR_CONTROLLERS]; - uint32_t status[NUM_MOTOR_CONTROLLERS]; + MciStatusMessage status; TestWaveSculptorSinkMotorTempMeasurement sink_motor_measurements[NUM_MOTOR_CONTROLLERS]; uint32_t dsp_measurements[NUM_MOTOR_CONTROLLERS]; } TestMotorControllerMeasurements; @@ -105,6 +105,12 @@ static MotorCanFrameId s_frame_id_map[] = { R_MTR_MSG_ID(WAVESCULPTOR_MEASUREMENT_ID_DSP_BOARD_TEMPERATURE), }; +// To allow for setting fan fault bitset +static uint8_t s_test_fan_fault_bitset = 0; +uint8_t TEST_MOCK(mci_fan_get_fault_bitset)(void) { + return s_test_fan_fault_bitset; +} + static StatusCode prv_handle_velocity(const CanMessage *msg, void *context, CanAckStatus *ack_reply) { uint16_t left_velocity, right_velocity; @@ -128,11 +134,14 @@ static StatusCode prv_handle_bus_measurement(const CanMessage *msg, void *contex } static StatusCode prv_handle_status(const CanMessage *msg, void *context, CanAckStatus *ack_reply) { - uint32_t status_left, status_right; - CAN_UNPACK_MOTOR_STATUS(msg, &status_left, &status_right); + MciStatusMessage message; + CAN_UNPACK_MOTOR_STATUS(msg, &message.mc_limit_bitset[LEFT_MOTOR_CONTROLLER], + &message.mc_limit_bitset[RIGHT_MOTOR_CONTROLLER], + &message.mc_error_bitset[LEFT_MOTOR_CONTROLLER], + &message.mc_error_bitset[RIGHT_MOTOR_CONTROLLER], + &message.board_fault_bitset, &message.mc_overtemp_bitset); s_received_status = true; - s_test_measurements.status[LEFT_MOTOR_CONTROLLER] = status_left; - s_test_measurements.status[RIGHT_MOTOR_CONTROLLER] = status_right; + memcpy(&s_test_measurements.status, &message, sizeof(message)); return STATUS_CODE_OK; } @@ -174,7 +183,16 @@ static void prv_send_measurements(MotorController controller, TestMciMessage mes can_data.bus_measurement.bus_current_a = measurements->bus_measurements[controller].bus_current_a; } else if (message_type == TEST_MCI_STATUS_MESSAGE) { - can_data.raw = measurements->status[controller]; + // Populate status message flags we care about + WaveSculptorCanData ws_data = { 0 }; + ws_data.status_info.error_flags.raw = measurements->status.mc_error_bitset[controller]; + ws_data.status_info.limit_flags.raw = measurements->status.mc_limit_bitset[controller]; + + // Will get updated on status message broadcast + s_test_fan_fault_bitset = measurements->status.board_fault_bitset; + // TODO(SOFT-534): update the overtemp bitset if needed + + can_data.raw = ws_data.raw; } else if (message_type == TEST_MCI_SINK_MOTOR_TEMP_MESSAGE) { can_data.sink_motor_temp_measurement.heatsink_temp_c = measurements->sink_motor_measurements[controller].heatsink_temp_c; @@ -250,8 +268,14 @@ static void prv_assert_eq_expected_storage_vel(MotorControllerMeasurements expec // Status static void prv_assert_eq_expected_storage_status(MotorControllerMeasurements expected_measurements, MotorController controller) { - TEST_ASSERT_EQUAL((uint16_t)expected_measurements.status[controller], - (uint16_t)s_broadcast_storage.measurements.status[controller]); + TEST_ASSERT_EQUAL(expected_measurements.status.mc_limit_bitset[controller] & MCI_LIMIT_MASK, + s_broadcast_storage.measurements.status.mc_limit_bitset[controller]); + TEST_ASSERT_EQUAL(expected_measurements.status.mc_error_bitset[controller] & MCI_ERROR_MASK, + s_broadcast_storage.measurements.status.mc_error_bitset[controller]); + TEST_ASSERT_EQUAL(expected_measurements.status.board_fault_bitset, + s_broadcast_storage.measurements.status.board_fault_bitset); + TEST_ASSERT_EQUAL(expected_measurements.status.mc_overtemp_bitset, + s_broadcast_storage.measurements.status.mc_overtemp_bitset); } // Sink temperature @@ -341,8 +365,13 @@ void test_left_all_right_all(void) { }, .status = { - [LEFT_MOTOR_CONTROLLER] = 0xDEADBEEF, - [RIGHT_MOTOR_CONTROLLER] = 0xDEADBEEF, + // Note that, due to the reserved bit 0, error bitsets can't have their MSB high + .mc_limit_bitset[LEFT_MOTOR_CONTROLLER] = 0x11, + .mc_limit_bitset[RIGHT_MOTOR_CONTROLLER] = 0x13, + .mc_error_bitset[LEFT_MOTOR_CONTROLLER] = 0x32, + .mc_error_bitset[RIGHT_MOTOR_CONTROLLER] = 0x5F, + .board_fault_bitset = 0xCA, + .mc_overtemp_bitset = 0x00, // currently always 0 }, .sink_motor_measurements = { @@ -405,6 +434,7 @@ void test_left_all_right_all(void) { s_test_measurements.bus_measurements[motor_id].bus_current_a); TEST_ASSERT_EQUAL((uint16_t)(expected_measurements.vehicle_velocity[motor_id] * 100), s_test_measurements.vehicle_velocity[motor_id]); + prv_assert_eq_expected_storage_status(expected_measurements, motor_id); TEST_ASSERT_EQUAL(expected_measurements.sink_motor_measurements[motor_id].heatsink_temp_c, s_test_measurements.sink_motor_measurements[motor_id].heatsink_temp_c); TEST_ASSERT_EQUAL(expected_measurements.sink_motor_measurements[motor_id].motor_temp_c, @@ -442,8 +472,13 @@ void test_left_all_right_none(void) { }, .status = { - [LEFT_MOTOR_CONTROLLER] = 0xDEADBEEF, - [RIGHT_MOTOR_CONTROLLER] = 0xDEADBEEF, + // Note that, due to the reserved bit 0, error bitsets can't have their MSB high + .mc_limit_bitset[LEFT_MOTOR_CONTROLLER] = 0x11, + .mc_limit_bitset[RIGHT_MOTOR_CONTROLLER] = 0x13, + .mc_error_bitset[LEFT_MOTOR_CONTROLLER] = 0x32, + .mc_error_bitset[RIGHT_MOTOR_CONTROLLER] = 0x5F, + .board_fault_bitset = 0xCA, + .mc_overtemp_bitset = 0x00, // currently always 0 }, .sink_motor_measurements = { @@ -530,8 +565,13 @@ void test_left_all_right_status(void) { .status = { - [LEFT_MOTOR_CONTROLLER] = 0xDEADBEEF, - [RIGHT_MOTOR_CONTROLLER] = 0xDEADBEEF, + // Note that, due to the reserved bit 0, error bitsets can't have their MSB high + .mc_limit_bitset[LEFT_MOTOR_CONTROLLER] = 0x11, + .mc_limit_bitset[RIGHT_MOTOR_CONTROLLER] = 0x13, + .mc_error_bitset[LEFT_MOTOR_CONTROLLER] = 0x32, + .mc_error_bitset[RIGHT_MOTOR_CONTROLLER] = 0x5F, + .board_fault_bitset = 0xCA, + .mc_overtemp_bitset = 0x00, // currently always 0 }, .sink_motor_measurements = { @@ -580,7 +620,7 @@ void test_left_all_right_status(void) { TEST_ASSERT_FALSE(s_received_dsp_temp); TEST_ASSERT_TRUE(s_received_status); for (size_t motor_id = 0; motor_id < NUM_MOTOR_CONTROLLERS; motor_id++) { - TEST_ASSERT_EQUAL(expected_measurements.status[motor_id], s_test_measurements.status[motor_id]); + prv_assert_eq_expected_storage_status(expected_measurements, motor_id); } } @@ -614,8 +654,13 @@ void test_left_all_right_status_bus(void) { .status = { - [LEFT_MOTOR_CONTROLLER] = 0xDEADBEEF, - [RIGHT_MOTOR_CONTROLLER] = 0xDEADBEEF, + // Note that, due to the reserved bit 0, error bitsets can't have their MSB high + .mc_limit_bitset[LEFT_MOTOR_CONTROLLER] = 0x11, + .mc_limit_bitset[RIGHT_MOTOR_CONTROLLER] = 0x13, + .mc_error_bitset[LEFT_MOTOR_CONTROLLER] = 0x32, + .mc_error_bitset[RIGHT_MOTOR_CONTROLLER] = 0x5F, + .board_fault_bitset = 0xCA, + .mc_overtemp_bitset = 0x00, // currently always 0 }, .sink_motor_measurements = { @@ -666,7 +711,7 @@ void test_left_all_right_status_bus(void) { TEST_ASSERT_TRUE(s_received_bus_measurement); TEST_ASSERT_TRUE(s_received_status); for (size_t motor_id = 0; motor_id < NUM_MOTOR_CONTROLLERS; motor_id++) { - TEST_ASSERT_EQUAL(expected_measurements.status[motor_id], s_test_measurements.status[motor_id]); + prv_assert_eq_expected_storage_status(expected_measurements, motor_id); TEST_ASSERT_EQUAL((uint16_t)expected_measurements.bus_measurements[motor_id].bus_voltage_v, s_test_measurements.bus_measurements[motor_id].bus_voltage_v); TEST_ASSERT_EQUAL((uint16_t)expected_measurements.bus_measurements[motor_id].bus_current_a, @@ -700,8 +745,13 @@ void test_3x_left_all_right_all(void) { }, .status = { - [LEFT_MOTOR_CONTROLLER] = 0xDEADBEEF, - [RIGHT_MOTOR_CONTROLLER] = 0xDEADBEEF, + // Note that, due to the reserved bit 0, error bitsets can't have their MSB high + .mc_limit_bitset[LEFT_MOTOR_CONTROLLER] = 0x11, + .mc_limit_bitset[RIGHT_MOTOR_CONTROLLER] = 0x13, + .mc_error_bitset[LEFT_MOTOR_CONTROLLER] = 0x32, + .mc_error_bitset[RIGHT_MOTOR_CONTROLLER] = 0x5F, + .board_fault_bitset = 0xCA, + .mc_overtemp_bitset = 0x00, // currently always 0 }, .sink_motor_measurements = { @@ -766,8 +816,7 @@ void test_3x_left_all_right_all(void) { s_test_measurements.bus_measurements[motor_id].bus_current_a); TEST_ASSERT_EQUAL((uint16_t)(expected_measurements.vehicle_velocity[motor_id] * 100), s_test_measurements.vehicle_velocity[motor_id]); - TEST_ASSERT_EQUAL(expected_measurements.status[motor_id], - s_test_measurements.status[motor_id]); + prv_assert_eq_expected_storage_status(expected_measurements, motor_id); TEST_ASSERT_EQUAL(expected_measurements.sink_motor_measurements[motor_id].heatsink_temp_c, s_test_measurements.sink_motor_measurements[motor_id].heatsink_temp_c); TEST_ASSERT_EQUAL(expected_measurements.sink_motor_measurements[motor_id].motor_temp_c, @@ -810,8 +859,12 @@ void test_message_id_filter(void) { }, .status = { - [LEFT_MOTOR_CONTROLLER] = 0xDEADBEEF, - [RIGHT_MOTOR_CONTROLLER] = 0xDEADBEEF, + .mc_limit_bitset[LEFT_MOTOR_CONTROLLER] = 0xDE, + .mc_limit_bitset[RIGHT_MOTOR_CONTROLLER] = 0xAD, + .mc_error_bitset[LEFT_MOTOR_CONTROLLER] = 0xBE, + .mc_error_bitset[RIGHT_MOTOR_CONTROLLER] = 0xEF, + .board_fault_bitset = 0xCA, + .mc_overtemp_bitset = 0x00, // currently always 0 }, .sink_motor_measurements = { @@ -924,7 +977,7 @@ void test_message_id_filter(void) { s_test_measurements.bus_measurements[motor_id].bus_current_a); TEST_ASSERT_EQUAL((uint16_t)(expected_measurements.vehicle_velocity[motor_id] * 100), s_test_measurements.vehicle_velocity[motor_id]); - TEST_ASSERT_EQUAL(expected_measurements.status[motor_id], s_test_measurements.status[motor_id]); + prv_assert_eq_expected_storage_status(expected_measurements, motor_id); TEST_ASSERT_EQUAL(expected_measurements.sink_motor_measurements[motor_id].heatsink_temp_c, s_test_measurements.sink_motor_measurements[motor_id].heatsink_temp_c); TEST_ASSERT_EQUAL(expected_measurements.sink_motor_measurements[motor_id].motor_temp_c,