From c25f4ce480a31c4241d4d67cc2f774620bc04b12 Mon Sep 17 00:00:00 2001 From: Jeroen Hofstee Date: Wed, 31 Aug 2022 23:08:29 +0200 Subject: [PATCH] remove odd err-frames The gusb-interface can report completely weird error-frames, like being in error-ative (based on counters), and error-warning, and bus-off at the same time. To fix this: - only send state changes once. - don't send LEC / err counters in bus-off (invalid anyway). - don't send empty error frames. --- src/can.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/can.c b/src/can.c index b3cde8c..2570ef7 100644 --- a/src/can.c +++ b/src/can.c @@ -295,7 +295,7 @@ bool can_parse_error_status(uint32_t err, uint32_t last_err, can_data_t *hcan, s (void) hcan; frame->echo_id = 0xFFFFFFFF; - frame->can_id = CAN_ERR_FLAG | CAN_ERR_CRTL; + frame->can_id = CAN_ERR_FLAG; frame->can_dlc = CAN_ERR_DLC; frame->data[0] = CAN_ERR_LOSTARB_UNSPEC; frame->data[1] = CAN_ERR_CRTL_UNSPEC; @@ -307,18 +307,23 @@ bool can_parse_error_status(uint32_t err, uint32_t last_err, can_data_t *hcan, s frame->data[7] = 0; if (err & CAN_ESR_BOFF) { - frame->can_id |= CAN_ERR_BUSOFF; if (!(last_err & CAN_ESR_BOFF)) { /* We transitioned to bus-off. */ + frame->can_id |= CAN_ERR_BUSOFF; should_send = true; } - } else if (last_err & CAN_ESR_BOFF) { - /* We transitioned out of bus-off. */ - should_send = true; + // - tec (overflowed) / rec (looping, likely used for recessive counting) + // are not valid in the bus-off state. + // - The warning flags remains set, error passive will cleared. + // - LEC errors will be reported, while the device isn't even allowed to send. + // + // Hence only report bus-off, ignore everything else. + return should_send; } /* We transitioned from passive/bus-off to active, so report the edge. */ if (!status_is_active(last_err) && status_is_active(err)) { + frame->can_id |= CAN_ERR_CRTL; frame->data[1] |= CAN_ERR_CRTL_ACTIVE; should_send = true; } @@ -331,17 +336,17 @@ bool can_parse_error_status(uint32_t err, uint32_t last_err, can_data_t *hcan, s frame->data[7] = rx_error_cnt; if (err & CAN_ESR_EPVF) { - frame->data[1] |= CAN_ERR_CRTL_RX_PASSIVE | CAN_ERR_CRTL_TX_PASSIVE; if (!(last_err & CAN_ESR_EPVF)) { + frame->can_id |= CAN_ERR_CRTL; + frame->data[1] |= CAN_ERR_CRTL_RX_PASSIVE | CAN_ERR_CRTL_TX_PASSIVE; should_send = true; } - } else if (err & CAN_ESR_EWGF) { - frame->data[1] |= CAN_ERR_CRTL_RX_WARNING | CAN_ERR_CRTL_TX_WARNING; + } else if (err & CAN_ESR_EWGF) { if (!(last_err & CAN_ESR_EWGF)) { + frame->can_id |= CAN_ERR_CRTL; + frame->data[1] |= CAN_ERR_CRTL_RX_WARNING | CAN_ERR_CRTL_TX_WARNING; should_send = true; } - } else if (last_err & (CAN_ESR_EPVF | CAN_ESR_EWGF)) { - should_send = true; } uint8_t lec = (err>>4) & 0x07;