2424 *
2525 */
2626
27- #include <string.h>
28-
27+ #include "board.h"
2928#include "can_common.h"
3029#include "can_drv.h"
3130#include "host_frame.h"
3231#include "led.h"
3332#include "timer.h"
3433#include "usbd_gs_can.h"
3534
36- #define CAN_ERROR_WARNING_THRESHOLD 96
37- #define CAN_ERROR_PASSIVE_THRESHOLD 128
38- #define CAN_BUS_OFF_THRESHOLD 256
35+ #define CAN_ERROR_WARNING_THRESHOLD 96
36+ #define CAN_ERROR_PASSIVE_THRESHOLD 128
37+ #define CAN_BUS_OFF_THRESHOLD 256
38+
39+ #define CAN_BUS_OFF_RESTART_DELAY_MS 100
3940
4041#ifndef CONFIG_CANFD
4142const struct gs_device_bt_const_extended CAN_btconst_ext ;
@@ -69,20 +70,29 @@ bool can_check_filter_ok(const struct gs_device_filter *filter)
6970}
7071#endif
7172
73+ bool can_is_enabled (const struct can_channel * channel )
74+ {
75+ return channel -> state < GS_CAN_STATE_STOPPED ;
76+ }
77+
7278void can_enable (struct can_channel * channel , const uint32_t feature )
7379{
7480 channel -> feature = feature ;
7581
7682 led_set_mode (& channel -> leds , LED_MODE_NORMAL );
7783 channel -> state = GS_CAN_STATE_ERROR_ACTIVE ;
84+ board_phy_power_set (channel , true);
7885 can_drv_enable (channel );
7986}
8087
8188void can_disable (USBD_GS_CAN_HandleTypeDef * hcan , struct can_channel * channel )
8289{
8390 can_drv_disable (channel );
91+ board_phy_power_set (channel , false);
8492 usbd_gs_can_purge_from_host_list_by_channel (hcan , channel );
8593 usbd_gs_can_purge_to_host_list_by_channel (hcan , channel );
94+
95+ channel -> bus_off_restart = CAN_CHANNEL_BUS_OFF_RESTART_DISABLED ;
8696 channel -> state = GS_CAN_STATE_STOPPED ;
8797 led_set_mode (& channel -> leds , LED_MODE_OFF );
8898}
@@ -167,7 +177,7 @@ static void can_prepare_error_frame(const struct can_channel *channel,
167177 frame -> channel = can_channel_get_nr (channel );
168178 frame -> flags = 0 ;
169179 frame -> reserved = 0 ;
170- memset ( frame -> classic_can -> data , 0x0 , sizeof ( frame -> classic_can -> data )) ;
180+ * frame -> classic_can = ( struct classic_can ){ 0 } ;
171181
172182 frame -> classic_can_ts -> timestamp_us = timer_get ();
173183}
@@ -265,6 +275,14 @@ static bool can_bus_error_pending(const struct can_channel *channel, const uint3
265275 return can_drv_bus_error_pending (reg_status );
266276}
267277
278+ void can_schedule_bus_off_recovery (struct can_channel * channel , const uint32_t delay_ms )
279+ {
280+ channel -> bus_off_restart = HAL_GetTick () + delay_ms ;
281+
282+ if (channel -> bus_off_restart == CAN_CHANNEL_BUS_OFF_RESTART_DISABLED )
283+ channel -> bus_off_restart ++ ;
284+ }
285+
268286static void can_handle_state_change (USBD_GS_CAN_HandleTypeDef * hcan , struct can_channel * channel ,
269287 const uint32_t reg_status )
270288{
@@ -277,6 +295,7 @@ static void can_handle_state_change(USBD_GS_CAN_HandleTypeDef *hcan, struct can_
277295
278296 if (channel -> state == GS_CAN_STATE_BUS_OFF ) {
279297 frame -> can_id |= CAN_ERR_BUSOFF ;
298+ can_schedule_bus_off_recovery (channel , CAN_BUS_OFF_RESTART_DELAY_MS );
280299 } else {
281300 frame -> can_id |= CAN_ERR_CRTL | CAN_ERR_CNT ;
282301 can_drv_handle_state_change (channel , frame , reg_status );
@@ -288,7 +307,7 @@ static void can_handle_state_change(USBD_GS_CAN_HandleTypeDef *hcan, struct can_
288307
289308static bool can_state_change_pending (struct can_channel * channel , const uint32_t reg_status )
290309{
291- if (channel -> state >= GS_CAN_STATE_STOPPED )
310+ if (! can_is_enabled ( channel ) )
292311 return false;
293312
294313 const enum gs_can_state new_state = can_drv_get_state (reg_status );
@@ -300,6 +319,34 @@ static bool can_state_change_pending(struct can_channel *channel, const uint32_t
300319 return true;
301320}
302321
322+ static void can_handle_bus_off_recovery (USBD_GS_CAN_HandleTypeDef * hcan , struct can_channel * channel )
323+ {
324+ can_drv_handle_bus_off_recovery (channel );
325+
326+ channel -> bus_off_restart = CAN_CHANNEL_BUS_OFF_RESTART_DISABLED ;
327+
328+ struct gs_host_frame_object * frame_object = gs_host_frame_object_get_locked (hcan );
329+ if (!frame_object )
330+ return ;
331+
332+ struct gs_host_frame * frame = & frame_object -> frame ;
333+ can_prepare_error_frame (channel , frame );
334+
335+ frame -> can_id |= CAN_ERR_RESTARTED ;
336+
337+ list_add_tail_locked (& frame_object -> list , & hcan -> list_to_host );
338+ }
339+
340+ static bool can_bus_off_recovery_pending (const struct can_channel * channel )
341+ {
342+ if (channel -> bus_off_restart == CAN_CHANNEL_BUS_OFF_RESTART_DISABLED )
343+ return false;
344+
345+ const uint32_t now = HAL_GetTick ();
346+
347+ return time_after (now , channel -> bus_off_restart );
348+ }
349+
303350// If there are frames to receive, don't report any error frames. The
304351// best we can localize the errors to is "after the last successfully
305352// received frame", so wait until we get there. LEC will hold some error
@@ -316,5 +363,7 @@ void CAN_HandleError(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel)
316363 can_handle_state_change (hcan , channel , reg_status );
317364 } else if (can_bus_error_pending (channel , reg_status )) {
318365 can_handle_bus_error (hcan , channel , reg_status );
366+ } else if (can_bus_off_recovery_pending (channel )) {
367+ can_handle_bus_off_recovery (hcan , channel );
319368 }
320369}
0 commit comments