Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/can_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ uint8_t gs_can_tx_state_to_frame(const enum gs_can_state state);
uint8_t gs_can_rx_state_to_frame(const enum gs_can_state state);
void can_lec_error_to_frame(struct gs_host_frame *frame, const uint8_t lec);

bool can_check_bus_off_recovery_ok(const struct can_channel *channel);
void can_schedule_bus_off_recovery(struct can_channel *channel, uint32_t delay_ms);

void CAN_SendFrame(USBD_GS_CAN_HandleTypeDef *hcan, can_data_t *channel);
Expand Down
10 changes: 10 additions & 0 deletions include/gs_usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@
* - struct gs_device_filter
*/
#define GS_CAN_FEATURE_FILTER (1<<16)
/* device support CAN bus off recovery
* - GS_USB_BREQ_BUS_OFF_RECOVERY
* - struct gs_device_bus_off_recovery
*/
#define GS_CAN_FEATURE_BUS_OFF_RECOVERY (1<<18)

#define GS_CAN_FLAG_OVERFLOW (1<<0)
#define GS_CAN_FLAG_FD (1<<1) /* is a CAN-FD frame */
Expand Down Expand Up @@ -196,6 +201,7 @@ enum gs_usb_breq {
__GS_USB_BREQ_ELM_PLACEHOLDER_29,
__GS_USB_BREQ_ELM_PLACEHOLDER_30,
__GS_USB_BREQ_ELM_PLACEHOLDER_31,
GS_USB_BREQ_BUS_OFF_RECOVERY = 32,
};

enum gs_can_mode {
Expand Down Expand Up @@ -319,6 +325,10 @@ struct gs_device_filter {
};
} __packed __aligned(4);

struct gs_device_bus_off_recovery {
u32 unused;
} __packed __aligned(4);

struct classic_can {
u8 data[8];
} __packed __aligned(4);
Expand Down
1 change: 1 addition & 0 deletions src/can/bxcan.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const struct gs_device_bt_const CAN_btconst = {
GS_CAN_FEATURE_GET_STATE |
(IS_ENABLED(CONFIG_CAN_FILTER) ?
GS_CAN_FEATURE_FILTER : 0) |
GS_CAN_FEATURE_BUS_OFF_RECOVERY |
0,
.fclk_can = CAN_CLOCK_SPEED,
.btc = {
Expand Down
11 changes: 10 additions & 1 deletion src/can_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,12 @@ static bool can_bus_error_pending(const struct can_channel *channel, const uint3
return can_drv_bus_error_pending(reg_status);
}

bool can_check_bus_off_recovery_ok(const struct can_channel *channel)
{
return channel->feature & GS_CAN_FEATURE_BUS_OFF_RECOVERY &&
channel->state == GS_CAN_STATE_BUS_OFF;
}

void can_schedule_bus_off_recovery(struct can_channel *channel, const uint32_t delay_ms)
{
channel->bus_off_restart = HAL_GetTick() + delay_ms;
Expand All @@ -295,7 +301,10 @@ static void can_handle_state_change(USBD_GS_CAN_HandleTypeDef *hcan, struct can_

if (channel->state == GS_CAN_STATE_BUS_OFF) {
frame->can_id |= CAN_ERR_BUSOFF;
can_schedule_bus_off_recovery(channel, CAN_BUS_OFF_RESTART_DELAY_MS);

/* host is not taking care of CAN bus of recovery */
if (!(channel->feature & GS_CAN_FEATURE_BUS_OFF_RECOVERY))
can_schedule_bus_off_recovery(channel, CAN_BUS_OFF_RESTART_DELAY_MS);
} else {
frame->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
can_drv_handle_state_change(channel, frame, reg_status);
Expand Down
11 changes: 11 additions & 0 deletions src/usbd_gs_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,9 @@ static uint8_t USBD_GS_CAN_Config_Request(USBD_HandleTypeDef *pdev, USBD_SetupRe
src = &CAN_filter_info;
len = sizeof(CAN_filter_info);
break;
case GS_USB_BREQ_BUS_OFF_RECOVERY:
len = 0;
break;
default:
goto out_fail;
}
Expand All @@ -469,6 +472,7 @@ static uint8_t USBD_GS_CAN_Config_Request(USBD_HandleTypeDef *pdev, USBD_SetupRe
case GS_USB_BREQ_DATA_BITTIMING:
case GS_USB_BREQ_SET_TERMINATION:
case GS_USB_BREQ_SET_FILTER:
case GS_USB_BREQ_BUS_OFF_RECOVERY:
if (req->wLength > sizeof(*ep0)) {
goto out_fail;
}
Expand Down Expand Up @@ -650,6 +654,13 @@ static uint8_t USBD_GS_CAN_EP0_RxReady(USBD_HandleTypeDef *pdev) {
can_set_filter(channel, filter);
break;
}
case GS_USB_BREQ_BUS_OFF_RECOVERY:
if (!can_is_enabled(channel) || !can_check_bus_off_recovery_ok(channel))
goto out_fail;

can_schedule_bus_off_recovery(channel, 0);
break;

default:
break;
}
Expand Down
Loading