arduino-CAN icon indicating copy to clipboard operation
arduino-CAN copied to clipboard

CAN running at half speed

Open NeliusNDL opened this issue 3 years ago • 16 comments

For some reason around about the time I switched to an RTOS system I have to call CAN.begin(1000E3) to get it to work at 500kbs. Does anyone have any idea why ? Where could the clock speeds have been incorrectly defined (and what clock ?)

NeliusNDL avatar Feb 11 '21 12:02 NeliusNDL

MCP or internal ESP32 can controler?

Petros144 avatar Feb 17 '21 02:02 Petros144

If MCP, does the frequency of the quartz on the board match the parameters in the code?

timurrrr avatar Feb 17 '21 05:02 timurrrr

Sorry I left that information out, I am using the ESP32's internal CAN controller

NeliusNDL avatar Feb 17 '21 05:02 NeliusNDL

switch (baudRate) { case (long)1000E3: modifyRegister(REG_BTR1, 0x0f, 0x04); modifyRegister(REG_BTR0, 0x3f, 4); break;

case (long)500E3:
  modifyRegister(REG_BTR1, 0x0f, 0x0c);
  modifyRegister(REG_BTR0, 0x3f, 4);
  break;

case (long)250E3:
  modifyRegister(REG_BTR1, 0x0f, 0x0c);
  modifyRegister(REG_BTR0, 0x3f, 9);
  break;

case (long)200E3:
  modifyRegister(REG_BTR1, 0x0f, 0x0c);
  modifyRegister(REG_BTR0, 0x3f, 12);
  break;

case (long)125E3:
  modifyRegister(REG_BTR1, 0x0f, 0x0c);
  modifyRegister(REG_BTR0, 0x3f, 19);
  break;

case (long)100E3:
  modifyRegister(REG_BTR1, 0x0f, 0x0c);
  modifyRegister(REG_BTR0, 0x3f, 24);
  break;

case (long)80E3:
  modifyRegister(REG_BTR1, 0x0f, 0x0c);
  modifyRegister(REG_BTR0, 0x3f, 30);
  break;

case (long)50E3:
  modifyRegister(REG_BTR1, 0x0f, 0x0c);
  modifyRegister(REG_BTR0, 0x3f, 49);
  break;

/* Due to limitations in ESP32 hardware and/or RTOS software, baudrate can't be lower than 50kbps. See https://esp32.com/viewtopic.php?t=2142 */

maybe check theese registers in the ESP32 refrence manual. TWAI Bus.

I dont have any issuses what so ever. (arduino IDE)

Petros144 avatar Feb 19 '21 16:02 Petros144

@Petros144 Thank you for pointing me to the registers, I will have a good look at this and revert back.

NeliusNDL avatar Feb 26 '21 16:02 NeliusNDL

I added :

modifyRegister(REG_IER, 0x10, 0);  
 //brp_div will prescale BRP by 2. Only available on ESP32 Revision 2 or later. Reserved otherwise 

To ESP32SJA1000.cpp at line 126
Aparently there is a "feature" in some versions of the ESP to be able to lower the baudrate by a factor of two. And this disables it

kp911 avatar Mar 01 '21 12:03 kp911

@kp911, how about adding it at line 72 or 133 instead, then it will be disabled for all baud rates ? In my .cpp file line 126 is in the "case (long)10E3:"

But I think I am missing something else here. 1- It seems to me that modifyRegister(REG_IER, 0x10, 0); is making changes to "Interrupt Enable Register" 2- IER 0x10 = IER.4 = "Wake-Up Interrupt Enable" and is not related to prescaler

NeliusNDL avatar Apr 14 '21 10:04 NeliusNDL

@NeliusNDL @sandeepmistry This discussion just gave me an idea. Two years ago I found that ESP32 is not able to communicate in low bandwidth (under 50kbps) due to the clock frequency and the baud rate prescaler is limited in 6 bits. Following the thread about the hardware limitation (https://esp32.com/viewtopic.php?t=2142) just recently I read that in Rev2 or up versions of the chip they changed the meaning of bit 4 in IER, from "Wake-up interrupt" to "divide BRP by 2". That explains why the CAN ran in half speed (for some reason bit 4 was set) in newer ESP32.

I modified the code again in order to support this change. However, I don't have a v2+ chip at hand and it would take quite a few weeks to order. So if someone could kindly test my code I'd create a PR that makes either slower bandwidth possible and finally support CANOpen standard with ESP32, too; or workaround this "bug" or "new feature" in ESP32 chip for once and all.

I'll create the PR soon. Please test it if your time permits. I tested all speeds from 1000kbps until 50kbps with my v1 chip, in real life scenario, I connected my ESP + VP230 to an Android Nano + MCP2515 (+TJA1050), I can't go lower of course due to the limitations in my chip. Thanks.

mister0wl avatar Apr 14 '21 20:04 mister0wl

@mister0wl I will gladly test. I have old and new versions of the ESP32, please send me a link to your modified code or post it here (or PM me)

NeliusNDL avatar Apr 16 '21 09:04 NeliusNDL

@NeliusNDL Sounds great! :) I created pull request #71 but you can also clone from here: https://github.com/mister0wl/arduino-CAN

mister0wl avatar Apr 16 '21 21:04 mister0wl

Hey @NeliusNDL , did you find the time to test the code with v2 chip? I could've been ordered one for myself in the meantime but it seems Chinese merchants don't know what they sell as they could not give me the info if their chip is v2 or not. sigh So you're our hope. ;-)

mister0wl avatar May 31 '21 14:05 mister0wl

@mister0wl I did do some tests. All working very well. In addition I have made some more changes. CAN bus testing and finalization is on my to-do list for mid to end june. Will post my results here when all done with a copy of my changes

NeliusNDL avatar May 31 '21 14:05 NeliusNDL

Hi, the fix from mister0wl is not working because the IER register is written with 0xFF at the end of the function ;-( Therefor I changed ESP32SJA1000.cpp a little. Now the IER register is written at the end as 0xEF if the chip version >=2 was detected and the baud rate is >= 50K. The change was tested with chip revision 1 and 3 at 250K baud.

Hardi

arduino-CAN_adapted_to_chip_revision_2.zip

Hardi-St avatar Jul 10 '22 18:07 Hardi-St

@mister0wl I did do some tests. All working very well. In addition I have made some more changes. CAN bus testing and finalization is on my to-do list for mid to end june. Will post my results here when all done with a copy of my changes

Hi, what baudrates did you try? Do you happen to have the BTR0 and BTR1 values for 33.33kbps? Thanks

zalexzperez avatar Jul 19 '23 20:07 zalexzperez

Hi, I don't remember which baud rates I've tested. To calculate the BTR registers, you could use a tool from the net. Search for "sja1000 baud rate calculator" I'm using the tool from Peak because I also use their hardware. Hardi

Hardi-St avatar Jul 20 '23 07:07 Hardi-St

To calculate the BTR registers, you could use a tool from the net. Search for "sja1000 baud rate calculator"

In ESP32SJA1000.cpp, there's modifyRegister(REG_BTR1, mask, value) modifyRegister(REG_BTR1, mask, value)

I suppose the calculated BTR0 and BTR1 values go on the 'value' field, as the mask field is always the same for all baudrates. However, BTR1 value on all predefined baudrates is also always the same value (0x0c) except with 1Mhz and 20kbps.

For instance, using this calculator and parameters 80Mhz, 33.33kbps, I get BTR0= 138 and BTR1= 28.

Using

modifyRegister(REG_BTR1, 0x0f, 0x0c);
modifyRegister(REG_BTR0, 0x3f, 138);

or

modifyRegister(REG_BTR1, 0x0f, 28);
modifyRegister(REG_BTR0, 0x3f, 138);

I'm measuring a 112kbps signal. Kvaser calculator values give me around 16ish kbps, which is around half the desired baudrate.

I asked somewhere else, and some person provided me with the 4 timing bit parameters to connect to 33.33kbps GMLAN and they were these: {.brp = 120, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false}

Using the TWAI driver I did measure a 33.33kbps signal. I need to translate those values to BTR0 and BTR1 values.

After some trial and error I found these register values, using the default modifyRegister(REG_BTR1, 0x0f, 0x0c): (REG_BTR0, 0x3f, 36): 33.7kHz (REG_BTR0, 0x3f, 100): 33.44kHz

Using chatgpt and providing it the 4 parameteres + 80MHz input clock frequency: BTR0= 0x3e, BTR1 = 0x77. I placed them on the mask field, and played with BTR0's value until I got a 33.33kbps signal:

modifyRegister(REG_BTR1, 0x77, 0x0c); modifyRegister(REG_BTR0, 0x3e, 166);

Still need to try in my car...

zalexzperez avatar Jul 21 '23 19:07 zalexzperez