Skip to content

Commit

Permalink
[SOFT-514] Improve MCI status broadcast (#433)
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
hewittmcg authored Sep 10, 2021
1 parent bb06c5f commit 50ed21f
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 48 deletions.
10 changes: 7 additions & 3 deletions codegen/can_messages.asciipb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions libraries/codegen-tooling/inc/can_pack.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
15 changes: 9 additions & 6 deletions libraries/codegen-tooling/inc/can_transmit.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, \
Expand Down
9 changes: 7 additions & 2 deletions libraries/codegen-tooling/inc/can_unpack.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
43 changes: 42 additions & 1 deletion projects/mci/inc/mci_broadcast.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions projects/mci/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
27 changes: 20 additions & 7 deletions projects/mci/src/mci_broadcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down
Loading

0 comments on commit 50ed21f

Please sign in to comment.