CAN bus Transmit Error Counter (TEC) and the Receive Error Counter. How to read? - Page 1
Forum section: electronics / projects

author: tru3533
author_rank: Regular Contributor
timestamp: July 07, 2022, 03:31:19 pm
content: Looking at the CAN documentation with examples from Espressifhttps://docs.espressif.com/projects/esp-idf/en/release-v3.3/api-reference/peripherals/can.htmlTrying to read the Transmit Error Counter (TEC) and the Receive Error CounterThe CAN2.0B specification implements fault confinement by requiring every CAN node to maintain two internal error counters known as theTransmit Error Counter (TEC) and the Receive Error Counter (REC). The two error counters are used to determine a CAN node’s error state, and the counters are incremented and decremented following a set of rules (see CAN2.0B specification).I can't figure out how to do that, what am I missing?

author: H.O
author_rank: Frequent Contributor
timestamp: July 07, 2022, 05:58:06 pm
content: I generally suck at C so this is likely going to make me look like a fool but looking at the API documentation you linked to, about 4/5 towards the end there's a description of thecan_status_info_tstruct. Two of its members are the two error counters.So perhaps something like:Code:tec = can_status_info_t.tx_error_counterrec = can_status_info_t.rx_error_counterIf that's not correct I'm sure someone will let us both know in a hurry...

author: tru3533
author_rank: Regular Contributor
timestamp: July 08, 2022, 12:47:41 am
content: Totally agree it should be something like that, but I'm in the same club, so no luck so far.

author: paul@yahrprobert.com
author_rank: Regular Contributor
timestamp: July 08, 2022, 03:04:30 am
content: at the hardware level you would use your processor to read the CAN controller's registers that contain those counters. On my MCP2515 units the TEC is register 6-1, REC is 6-2, at addresses 0x1c and 0x1d.

author: tru3533
author_rank: Regular Contributor
timestamp: July 08, 2022, 03:55:20 am
content: Thanks Paul. I'm using the API from Espressif so no external CAN controller like the MCP2515 just a standard CAN transceiver MAX3051ESA+T

author: H.O
author_rank: Frequent Contributor
timestamp: July 08, 2022, 04:55:33 am
content: They seem to call it it TWAI (two wire automotive interface) instead of CAN. Here's theAPI descriptionlooking like the same CAN API with simply the name changed...I don't knowApart from what I wrote earlier I'm afraid I don't have much else to offer for the API but if you're able to access uC registers directly (what paul is suggesting) then looking at the TWAI section of theESP32 reference manualtells us the names (and addresses) of the two error counters:Code:TWAI_RX_ERR_CNT_REG Receive Error Counter Register 0x3FF6B038 RO | R/WTWAI_TX_ERR_CNT_REG Transmit Error Counter Register 0x3FF6B03C RO | R/WThey say it's compatible with the SAJ1000 CAN controller so take a look at that datasheet as well.

author: tru3533
author_rank: Regular Contributor
timestamp: July 08, 2022, 02:54:31 pm
content: Hmm. This looks even more complicated. No idea how to do this.Ideal would be to use the struct can_status_info_t

author: paul@yahrprobert.com
author_rank: Regular Contributor
timestamp: July 08, 2022, 03:09:10 pm
content: I followed your link and looked up a technical reference manual for one of the chips that has a CAN(TWAI) interface, and found the section on TWAI register summary. There you find TWAI_RX_ERR_CNT_REG at address 0x0038. TX is at 0x003c.Maybe there is a way to see these values through the API as well.

author: paul@yahrprobert.com
author_rank: Regular Contributor
timestamp: July 08, 2022, 03:39:34 pm
content: OK, I looked further in your link, and if you look down at "API Reference" you'll see a link to the C header file can.h. It shows that the function can_get_status_info returns a status_info structure which has your rx and tx error counts in it.

author: tru3533
author_rank: Regular Contributor
timestamp: July 08, 2022, 04:07:14 pm
content: Yes, I can see that, its looks like this, but how to read the counter?Code:/*** @brief Structure to store status information of CAN driver*/typedef struct {can_state_t state; /**< Current state of CAN controller (Stopped/Running/Bus-Off/Recovery) */uint32_t msgs_to_tx; /**< Number of messages queued for transmission or awaiting transmission completion */uint32_t msgs_to_rx; /**< Number of messages in RX queue waiting to be read */uint32_t tx_error_counter; /**< Current value of Transmit Error Counter */uint32_t rx_error_counter; /**< Current value of Receive Error Counter */uint32_t tx_failed_count; /**< Number of messages that failed transmissions */uint32_t rx_missed_count; /**< Number of messages that were lost due to a full RX queue */uint32_t arb_lost_count; /**< Number of instances arbitration was lost */uint32_t bus_error_count; /**< Number of instances a bus error has occurred */} can_status_info_t;

author: paul@yahrprobert.com
author_rank: Regular Contributor
timestamp: July 08, 2022, 06:10:28 pm
content: OK, you have to declare an empty can_status_info struct, pass the address of that to can_get_status_info, and the function will fill it in:Code:#include "driver/can.h"..can_status_info_t can_status;....can_get_status_info(&can_status);printf("tx error count=%d",can_status.tx_error_counter);Some of the other examples show how this works - basic C stuff

author: tru3533
author_rank: Regular Contributor
timestamp: July 08, 2022, 08:11:12 pm
content: Thank you so much Paul. Problem solved