@@ -44,6 +44,74 @@ float FEB_CAN_RMS_getTorqueFeedback(void)
4444 return RMS_MESSAGE .Torque_Feedback / 10.0f ;
4545}
4646
47+ /* Inverter Internal States (M170) accessors */
48+ bool FEB_CAN_RMS_StatesSeen (void )
49+ {
50+ return RMS_MESSAGE .states_rx_timestamp != 0 ;
51+ }
52+
53+ uint8_t FEB_CAN_RMS_getVsmState (void )
54+ {
55+ return RMS_MESSAGE .vsm_state ;
56+ }
57+
58+ uint8_t FEB_CAN_RMS_getInverterState (void )
59+ {
60+ return RMS_MESSAGE .inverter_state ;
61+ }
62+
63+ bool FEB_CAN_RMS_getEnableState (void )
64+ {
65+ return RMS_MESSAGE .enable_state != 0 ;
66+ }
67+
68+ bool FEB_CAN_RMS_getEnableLockout (void )
69+ {
70+ return RMS_MESSAGE .enable_lockout != 0 ;
71+ }
72+
73+ bool FEB_CAN_RMS_getCommandModeVsm (void )
74+ {
75+ return RMS_MESSAGE .command_mode != 0 ;
76+ }
77+
78+ uint8_t FEB_CAN_RMS_getEchoRollingCounter (void )
79+ {
80+ return RMS_MESSAGE .echo_rolling_counter ;
81+ }
82+
83+ /* Fault codes (M171) accessors */
84+ bool FEB_CAN_RMS_FaultsSeen (void )
85+ {
86+ return RMS_MESSAGE .faults_rx_timestamp != 0 ;
87+ }
88+
89+ bool FEB_CAN_RMS_HasActiveFault (void )
90+ {
91+ return (RMS_MESSAGE .post_fault_lo | RMS_MESSAGE .post_fault_hi | RMS_MESSAGE .run_fault_lo |
92+ RMS_MESSAGE .run_fault_hi ) != 0 ;
93+ }
94+
95+ uint16_t FEB_CAN_RMS_getPostFaultLo (void )
96+ {
97+ return RMS_MESSAGE .post_fault_lo ;
98+ }
99+
100+ uint16_t FEB_CAN_RMS_getPostFaultHi (void )
101+ {
102+ return RMS_MESSAGE .post_fault_hi ;
103+ }
104+
105+ uint16_t FEB_CAN_RMS_getRunFaultLo (void )
106+ {
107+ return RMS_MESSAGE .run_fault_lo ;
108+ }
109+
110+ uint16_t FEB_CAN_RMS_getRunFaultHi (void )
111+ {
112+ return RMS_MESSAGE .run_fault_hi ;
113+ }
114+
47115void FEB_CAN_RMS_Init (void )
48116{
49117 LOG_I (TAG_CAN , "Initializing RMS CAN communication" );
@@ -64,8 +132,15 @@ void FEB_CAN_RMS_Init(void)
64132 params .can_id = FEB_CAN_ID_RMS_MOTOR ;
65133 FEB_CAN_RX_Register (& params );
66134
67- LOG_I (TAG_CAN , "Registered RMS CAN callbacks (Voltage: 0x%03X, Motor: 0x%03X)" , (unsigned )FEB_CAN_ID_RMS_VOLTAGE ,
68- (unsigned )FEB_CAN_ID_RMS_MOTOR );
135+ params .can_id = FEB_CAN_ID_RMS_STATES ;
136+ FEB_CAN_RX_Register (& params );
137+
138+ params .can_id = FEB_CAN_ID_RMS_FAULTS ;
139+ FEB_CAN_RX_Register (& params );
140+
141+ LOG_I (TAG_CAN , "Registered RMS CAN callbacks (Voltage: 0x%03X, Motor: 0x%03X, States: 0x%03X, Faults: 0x%03X)" ,
142+ (unsigned )FEB_CAN_ID_RMS_VOLTAGE , (unsigned )FEB_CAN_ID_RMS_MOTOR , (unsigned )FEB_CAN_ID_RMS_STATES ,
143+ (unsigned )FEB_CAN_ID_RMS_FAULTS );
69144
70145 RMS_MESSAGE .HV_Bus_Voltage = 0 ;
71146 RMS_MESSAGE .Motor_Speed = 0 ;
@@ -74,6 +149,18 @@ void FEB_CAN_RMS_Init(void)
74149 RMS_MESSAGE .Torque_Feedback = 0 ;
75150 RMS_MESSAGE .DC_Bus_Voltage_V = 0.0f ;
76151 RMS_MESSAGE .last_rx_timestamp = 0 ;
152+ RMS_MESSAGE .vsm_state = 0 ;
153+ RMS_MESSAGE .inverter_state = 0 ;
154+ RMS_MESSAGE .enable_state = 0 ;
155+ RMS_MESSAGE .enable_lockout = 0 ;
156+ RMS_MESSAGE .command_mode = 0 ;
157+ RMS_MESSAGE .echo_rolling_counter = 0 ;
158+ RMS_MESSAGE .states_rx_timestamp = 0 ;
159+ RMS_MESSAGE .post_fault_lo = 0 ;
160+ RMS_MESSAGE .post_fault_hi = 0 ;
161+ RMS_MESSAGE .run_fault_lo = 0 ;
162+ RMS_MESSAGE .run_fault_hi = 0 ;
163+ RMS_MESSAGE .faults_rx_timestamp = 0 ;
77164
78165 LOG_I (TAG_CAN , "Sending RMS parameter safety commands" );
79166 for (int i = 0 ; i < 10 ; i ++ )
@@ -127,17 +214,42 @@ static void FEB_CAN_RMS_Callback(FEB_CAN_Instance_t instance, uint32_t can_id, F
127214
128215 if (can_id == FEB_CAN_ID_RMS_VOLTAGE )
129216 {
130- struct feb_can_m160_temperature_set_1_t m160 ;
131- feb_can_m160_temperature_set_1_unpack (& m160 , data , length );
132- RMS_MESSAGE .HV_Bus_Voltage = m160 .inv_module_a ;
133- RMS_MESSAGE .DC_Bus_Voltage_V = (m160 .inv_module_a - 50.0f ) / 10.0f ;
217+ /* M167 Voltage Info: INV_DC_Bus_Voltage is signed, scale 0.1 V, no offset. */
218+ struct feb_can_m167_voltage_info_t m167 ;
219+ feb_can_m167_voltage_info_unpack (& m167 , data , length );
220+ RMS_MESSAGE .HV_Bus_Voltage = m167 .inv_dc_bus_voltage ;
221+ RMS_MESSAGE .DC_Bus_Voltage_V = m167 .inv_dc_bus_voltage / 10.0f ;
134222 }
135223 else if (can_id == FEB_CAN_ID_RMS_MOTOR )
136224 {
137225 struct feb_can_m165_motor_position_info_t m165 ;
138226 feb_can_m165_motor_position_info_unpack (& m165 , data , length );
139227 RMS_MESSAGE .Motor_Speed = m165 .inv_motor_speed ;
140228 }
229+ else if (can_id == FEB_CAN_ID_RMS_STATES )
230+ {
231+ /* M170 Internal States: the "why won't it enable" frame. */
232+ struct feb_can_m170_internal_states_t m170 ;
233+ feb_can_m170_internal_states_unpack (& m170 , data , length );
234+ RMS_MESSAGE .vsm_state = m170 .inv_vsm_state ;
235+ RMS_MESSAGE .inverter_state = m170 .inv_inverter_state ;
236+ RMS_MESSAGE .enable_state = m170 .inv_inverter_enable_state ;
237+ RMS_MESSAGE .enable_lockout = m170 .inv_inverter_enable_lockout ;
238+ RMS_MESSAGE .command_mode = m170 .inv_inverter_command_mode ;
239+ RMS_MESSAGE .echo_rolling_counter = m170 .inv_rolling_counter ;
240+ RMS_MESSAGE .states_rx_timestamp = RMS_MESSAGE .last_rx_timestamp ;
241+ }
242+ else if (can_id == FEB_CAN_ID_RMS_FAULTS )
243+ {
244+ /* M171 Fault Codes: POST/Run fault bitfields (see PM100 manual). */
245+ struct feb_can_m171_fault_codes_t m171 ;
246+ feb_can_m171_fault_codes_unpack (& m171 , data , length );
247+ RMS_MESSAGE .post_fault_lo = m171 .inv_post_fault_lo ;
248+ RMS_MESSAGE .post_fault_hi = m171 .inv_post_fault_hi ;
249+ RMS_MESSAGE .run_fault_lo = m171 .inv_run_fault_lo ;
250+ RMS_MESSAGE .run_fault_hi = m171 .inv_run_fault_hi ;
251+ RMS_MESSAGE .faults_rx_timestamp = RMS_MESSAGE .last_rx_timestamp ;
252+ }
141253}
142254
143255/**
@@ -168,10 +280,17 @@ void FEB_CAN_RMS_Transmit_UpdateTorque(int16_t torque, uint8_t enabled)
168280
169281 RMS_MESSAGE .Torque_Command = torque ;
170282
283+ /* The RMS' CAN message-validity check requires a rolling counter that changes
284+ * every command frame; a counter stuck at 0 makes it reject every frame as
285+ * stale and refuse to enable. Increment 0..15 (field range) on every TX. */
286+ static uint8_t rolling_counter = 0 ;
287+
171288 struct feb_can_m192_command_message_t msg = {0 };
172289 msg .vcu_inv_torque_command = torque ;
173290 msg .vcu_inv_direction_command = 1u ;
174291 msg .vcu_inv_inverter_enable = enabled ;
292+ msg .vcu_inv_rolling_counter = rolling_counter ;
293+ rolling_counter = (uint8_t )((rolling_counter + 1u ) & 0x0Fu );
175294
176295 uint8_t data [FEB_CAN_M192_COMMAND_MESSAGE_LENGTH ];
177296 int packed = feb_can_m192_command_message_pack (data , & msg , sizeof (data ));
0 commit comments