Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Auto reinitialize can bus speed on the fly #4

Open
Gcopper22 opened this issue Jul 19, 2022 · 19 comments
Open

Auto reinitialize can bus speed on the fly #4

Gcopper22 opened this issue Jul 19, 2022 · 19 comments

Comments

@Gcopper22
Copy link

Gcopper22 commented Jul 19, 2022

I have a standalone automotive ecu with obd2 can bus protocol and i can change the baud rate speeds on the fly.In the other hand i use an esp32 with built in can bus controller to read the PID (RPM,VSS...)When i change the can bus speed on the ecu , i have an option to reinitialize the can bus speed on eps32 so it can reconnect. I just cycle in every 1sec the acan.begin with the additional can bus speeds (128,250,500,1000) and pid request transmit. The problem is that it cannot reconnect to the bus although i get message "Configuration ESP32 OK!" . I think its stops transmitting the buffer. If i use acan 2515 with external controller (MCP 2515) the problem disappear and succeffully connected to the bus.The mc2515 was without interrupts using 2515.poll();

Maybe the transmit buffer is over the limit? Please can you help me?

@Gcopper22 Gcopper22 changed the title Auto initialise can bus protocolm,stuck problem Auto reinitialize can bus protocol on the fly Jul 20, 2022
@Gcopper22 Gcopper22 changed the title Auto reinitialize can bus protocol on the fly Auto reinitialize can bus speed on the fly Jul 20, 2022
@pierremolinaro
Copy link
Owner

pierremolinaro commented Jul 20, 2022 via email

@Gcopper22
Copy link
Author

Your sketch is not working when i change the can bus speed from ecu.

To be more specific :
i start the ECU BUS speed 125kbs as EPS32 CAN bus initialize (gBitRateIndex = 0=125000)
it run succefully :
00:29:06.850 -> Configure ESP32 CAN at 125000 bit/s
00:29:06.850 -> Bit Rate prescaler: 16
00:29:06.850 -> Time Segment 1: 13
00:29:06.850 -> Time Segment 2: 6
00:29:06.850 -> RJW: 4
00:29:06.850 -> Triple Sampling: yes
00:29:06.850 -> Actual bit rate: 125000 bit/s
00:29:06.850 -> Exact bit rate ? yes
00:29:06.850 -> Distance 0 ppm
00:29:06.850 -> Sample point: 65%
00:29:06.850 -> Configuration OK!
00:29:06.850 -> Sent 1
00:29:06.850 -> Received 1
00:29:06.850 -> Received 2
00:29:06.850 -> Received 3
00:29:06.850 -> Received 4
00:29:06.850 -> Received 5
00:29:06.850 -> Received 6
00:29:06.897 -> Received 7
........

When i change the ECU BUS speed @250kbs
Its stops and i get :

00:29:10.764 -> STATUS 0x60, RXERR 56, TXERR 128
00:29:10.764 -> Configure ESP32 CAN at 250000 bit/s
00:29:10.764 -> Bit Rate prescaler: 8
00:29:10.764 -> Time Segment 1: 13
00:29:10.764 -> Time Segment 2: 6
00:29:10.764 -> RJW: 4
00:29:10.764 -> Triple Sampling: no
00:29:10.764 -> Actual bit rate: 250000 bit/s
00:29:10.764 -> Exact bit rate ? yes
00:29:10.764 -> Distance 0 ppm
00:29:10.764 -> Sample point: 70%
00:29:10.764 -> Configuration OK!
00:29:10.764 -> Sent 1
00:29:10.764 -> Sent 2
00:29:10.764 -> Sent 3
00:29:10.764 -> Sent 4
00:29:10.764 -> Sent 5
00:29:10.764 -> Sent 6
00:29:10.764 -> Sent 7
00:29:10.764 -> Sent 8
00:29:10.764 -> Sent 9
00:29:10.764 -> Sent 10

AND STOPS..

Also after a lot of search i get CAN BUS STATUS 0x4 in my sketch ,what is this error? Is it possible to restart the Can bus? Or recover?

Thank you in andvace

@pierremolinaro
Copy link
Owner

pierremolinaro commented Jul 21, 2022 via email

@Gcopper22
Copy link
Author

Gcopper22 commented Jul 21, 2022

yes the LoopBackMode is removed,
The Esp32 is not alone on the Bus.Is connected with standalone Engine ECU that I have the option to change the can bus speed as i told you.
Questions :
Is there any function to Stop the Driver?
Is there any function to Reset-Recover the Driver?
How can i decode the CAN BUS Status messages (the meanings) ?
I have CAN_STATUS 0x4 ,and in this situation i cant send or recieve any can bus message even if i start again the can bus (begin) thats why i'm asking for a recovery option

In IDF there is option to Recovering CAN BUS from Bus-off State (https://docs.espressif.com/projects/esp-idf/en/release-v3.3/api-reference/peripherals/can.html) :

esp_err_t can_initiate_recovery()
Start the bus recovery process.

Also there is option to Stop the CAN driver :
esp_err_tcan_stop()

Can you add this functions to your library?

@matt6626
Copy link

matt6626 commented Aug 9, 2022

Just wanted to add that I have run into the same issue with the tx buffer not being sent.

I haven't had time to create a min working example but the easiest trigger in my hardware setup (esp32 alone on canbus and esp32 with a single can logging device on canbus - loopback mode in both cases just sending out a random can packet onto the bus) has been to power cycle the 5V CAN for the can transceiver.

The ACAN_ESP32 driver is never able to recover after 5V CAN is re-enabled despite re-calling the can.begin() routine.

Only thing I noted was that attaching the CAN ISR in can.begin() fails when re-calling begin(). I briefly experimented with trying to de-initialize the can peripherals and free the can ISR without success despite getting rid of the failed isr attach call.

Calling esp_restart() is not sufficient to recover from the issue either. Calling a deepsleep of 0 duration does allow recovering from the issue.

If I get more time, I will investigate further.

Edit: The CAN interrupt handler stops being triggered entirely in the fault state.
void IRAM_ATTR ACAN_ESP32::isr(void *inUserArgument)

The primary registers appear to recover after cycling 5V CAN, however interrupt does not trigger anymore:

Initially Working:
mDriverisSending: 0
CAN_CMD (internalSendMessage): 10
internalSendMessageSentNow: 1
CAN Diagnostics:
CAN Driver Debug, TX_INTR_COUNT: 8
CAN MODE: 4
CAN_CMD: 0
CAN_STATUS: C
CAN_INTERRUPT: 0
CAN IER: 3
Sent: 8
Received: 8
CAN: STATUS 0X00C RXERR 0 TXERR 0

After 5V CAN power off:
mDriverisSending: 1
CAN_CMD (internalSendMessage): NO LONGER PRINTING
internalSendMessageSentNow: 0
CAN Diagnostics:
CAN Driver Debug, TX_INTR_COUNT: 35
CAN MODE: 5
CAN_CMD: 0
CAN_STATUS: D4
CAN_INTERRUPT: 0
CAN IER: 3
Sent: 43
Received: 35
CAN: STATUS 0X0D4 RXERR 0 TXERR 128

After 5V CAN power back on accompanied with can.begin():
mDriverisSending: 1
CAN_CMD (internalSendMessage): NO LONGER PRINTING
internalSendMessageSentNow: 0
CAN Diagnostics:
CAN Driver Debug, TX_INTR_COUNT: 35
CAN MODE: 4
CAN_CMD: 0
CAN_STATUS: C
CAN_INTERRUPT: 0
CAN IER: 3
Sent: 78
Received: 35
CAN: STATUS 0X00C RXERR 0 TXERR 0

All is pointing towards my earlier conclusion that the CAN ISR stops running, however, I'm not sure why.

@pierremolinaro
Copy link
Owner

pierremolinaro commented Aug 9, 2022 via email

@matt6626
Copy link

matt6626 commented Aug 9, 2022

I’ll give this a go in a day or two to confirm if this fixes the issue. Thanks for the fast turnaround.

@matt6626
Copy link

matt6626 commented Aug 10, 2022

Unfortunately the CAN ISR still doesn't trigger on latest commit after the can 5V is re-enabled and begin() is called. Uncommenting following made no difference:

if (mInterruptHandler != nullptr) {
esp_intr_disable (mInterruptHandler) ;
esp_intr_free (mInterruptHandler) ;
mInterruptHandler = nullptr ;
}

Only additional comment I can add is that no can packet is ever sent (ie. tx buffer never decreases) if any attempt to send a can packet is performed before 5VCAN is enabled (regardless of how many times begin() is called after this).

Update:
As long as there is no attempt being made to send can packets while 5V can is off, power cycling 5V can (with associated call to can.begin()) does not cause any issues and the can isr is called and sends can packets fine.

It is only when 5V can is turned off while still trying to send can packets that the issue occurs.

Update 2:
Just as a sanity check, I tried a different drop in replacement can transceiver to rule out any weird power off behaviour but this made no difference (to be expected).

I dug through the idf twai driver to see if they do much different, only difference I found so far was calling periph_module_reset before periph_module_enable but that didn't help.

Update 3:
I ported to the esp-idf TWAI/CAN driver and it recovers from the 5V can turning off and continues sending can packets.

@Gcopper22
Copy link
Author

@matt6626 can you please post an example with ported twai can driver that can recover and send packets as you said?

@matt6626
Copy link

matt6626 commented Aug 16, 2022

I've stripped out everything except hopefully the relevant min working can example (haven't checked whether it compiles). The main difference in the way I incorporated the idf-can was using no_ack mode instead of the loopback but I imagine principles are similar.

acan_esp32_example.zip

@matthew-mower
Copy link

matthew-mower commented Sep 12, 2022

I seem to be having this same issue. My setup has rare failures where receiving CAN just stops working on my board so I'm forced to reset the CAN peripheral, but if I try begin() and end()ing it fails to ever send more CAN messages. (The rare failures are definitely not simply being in CAN Bus Off mode as I've verified that I'm handling that. My best guess is I'm hitting some errata condition but I haven't looked into it very far)

As a workaround I'm currently resetting the device by putting it into deep sleep and reinitializing everything, which works but is pretty tricky to get glitch free.

@AndreaInverardi
Copy link

The ACAN library works successfully with a CANbed board v1 (AT328U4 + MCP2515) and it can recover from BUS-OFF state. This one (acan-esp32), i confirm it can't recover from BUS-OFF state, and the receive ISR is not recover. Hope it can be fixed.

@matthew-mower
Copy link

matthew-mower commented Sep 23, 2022

The ACAN library works successfully with a CANbed board v1 (AT328U4 + MCP2515) and it can recover from BUS-OFF state. This one (acan-esp32), i confirm it can't recover from BUS-OFF state, and the receive ISR is not recover. Hope it can be fixed.

I was able to get my board to recover from BUS-OFF by occasionally running the code below:

bool CAN_check()
{
	if (MODULE_CAN->SR.B.BS == 1 && MODULE_CAN->MOD.B.RM == 1)
	{
		MODULE_CAN->MOD.B.RM = 0;// leave reset
		return true;
	}
	return false;
}

Note it uses the register definitions in the file here: https://github.com/ThomasBarth/ESP32-CAN-Driver/blob/master/components/can/include/can_regdef.h

I'm sure it can be ported easily over to not require that but I haven't bothered and just copied the file into my lib.

@pierremolinaro
Copy link
Owner

pierremolinaro commented Sep 24, 2022 via email

@pierremolinaro
Copy link
Owner

pierremolinaro commented Oct 11, 2022 via email

@Gcopper22
Copy link
Author

I'm trying compile examples using version 1.1.0 and unfortunately the didn't complete.I use 1.0.6 core and i dont know how i can include twai driver.Also when i update to core version 2.0.4 i have error "freertos/FreeRTOS.h: No such file or directory.

Please is it possible to use your library with core 1.0.6 and how it will be done? Can someone help me.I want to use the recoveryFromBusOff method in 1.0.6 arduino core.

Thank you advance

@pierremolinaro
Copy link
Owner

pierremolinaro commented Oct 28, 2022 via email

@Gcopper22
Copy link
Author

Ok, i successfully run busrecover, so i have another problem : Its stop receiving messages when i have a heavy load in the can bus network and trying to saving to EEPROM.
So is there any example to use CAN driver’s ISR (Interrupt Service Routine) for the receiving and maybe also for the transmitting messages?

@ronzelver
Copy link

So is there any example to use CAN driver’s ISR (Interrupt Service Routine) for the receiving and maybe also for the transmitting messages?

I would also like to see an interrupt driven / callback handler for receiving CAN messages.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants