arduino-CAN
arduino-CAN copied to clipboard
CAN running at half speed
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 ?)
MCP or internal ESP32 can controler?
If MCP, does the frequency of the quartz on the board match the parameters in the code?
Sorry I left that information out, I am using the ESP32's internal CAN controller
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 Thank you for pointing me to the registers, I will have a good look at this and revert back.
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, 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 @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 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 Sounds great! :) I created pull request #71 but you can also clone from here: https://github.com/mister0wl/arduino-CAN
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 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, 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
@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
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
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...