'Reverse CAN BTR value from register value of stm32
i'm trying to get the baud rate of a chip by reverse engineering it.
the register value for BTR is reading: 0x23000B
As per http://www.bittiming.can-wiki.info/ it seems that real values are "-1" in the register. So it seems that
SJW -> 0x0 -> becomes 1 TS2 -> 0x2 -> becomes 3 TS1 -> 0x3 -> becomes 4 preampl -> 0xB -> 11d -> becomes 12d
so if my decoding is correct (can't really find a reference of what the register should contain officially in any docs):
- The chip in question has a 48MHz clock
- So 48Mhz/(preampl) => 48MHz/12 => 4Mhz
- 4.000.000 / (SJW + TS1 + TS2) => 500kbps
does this make any sense? also if you can find reference to the register value in a pdf i would greatly appreciate that.
Besides the calculation i'm not sure about the 48Mhz clock.
Solution 1:[1]
A CAN bit is divided into time quanta (tq). The tq are clocked with your CAN prescaler clock which needs to be accurate enough (<1% inaccuracy). When setting up baudrate, you should strive to place the sample point close to 87.5% of the bit length, which comes from an industry standard (CANopen).
(In case you a reverse-engineering something, they did not necessarily follow industry standards though and the sample point could be anywhere...)
Ideally 87.5% sample point is achieved by having a total of 16 tq, 14 tq before the sample point and 2 tq behind it. The desired baudrate is then obtained by:
- 1 tq fixed sync segment (can't be configured)
- x tq propagation segment
- y tq phase segment 1 (before sample point)
- 2 tq phase segment 2 (after sample point)
Different CAN controllers might name propagation segment + phase segment 1 as a single "propagation segment". It doesn't matter, it's the number of tq between the sync segment and the sample point that matters. One ideal example would be:
1 tq sync + 13 tq prop seg/phase seg 1 + 2 tq phase seg 2.
For a CAN clock of 4MHz this would give a bit rate of 4*10^6 / 16 = 250kbps.
Note that some CAN controllers do indeed expect you to subtract 1 tq from each segment length when you write to the register.
SJW, (re)synchronization jump width doesn't play a part in the baudrate calculation. It is a setting which allows a receiving node some room to re-sync in case of inaccurate baudrates. A "hard sync" is performed at the sync segment (bit edge) and then a re-synch is performed at the sample point. SJW allows some inaccuracies to happen here. It is typically just set to 1 and that works fine for all common baudrates. If you go up to 1MHz, it is recommended to increase SJW some, to 2 or 3.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Lundin |
