openlcb / documents

The OpenLCB specification: standards, recommended practices and other documentation.
3 stars 7 forks source link

CAN bit timing #1

Closed balazsracz closed 1 year ago

balazsracz commented 7 years ago

We need to document the recommended / required bit timing information for CAN-bus. generally based on the cable length that we are trying to achieve we have a requirement on the prop segment length. Ensuring that standards compliant firmwares have sufficiently long prop segment length is important. Hence documenting it in the standard makes sense.

dpharris commented 7 years ago

Should that be in the S or TN?

On Thu, Jan 5, 2017 at 10:40 AM, Balazs Racz notifications@github.com wrote:

We need to document the recommended / required bit timing information for CAN-bus. generally based on the cable length that we are trying to achieve we have a requirement on the prop segment length. Ensuring that standards compliant firmwares have sufficiently long prop segment length is important. Hence documenting it in the standard makes sense.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/openlcb/documents/issues/1, or mute the thread https://github.com/notifications/unsubscribe-auth/AAg4SggalnADs31q2_qerBw9Or-gBNJDks5rPTkpgaJpZM4Lb_p1 .

balazsracz commented 7 years ago

In order to claim that devices will work in the presence of 1000' cable, the PROPSEG must be of a certain length. Therefore I think it needs to go to the S.​

balazsracz commented 7 years ago

We also need to have a provision on oscillator tolerance.

The oscillator tolerance also impacts the CAN bit timing.

References: http://www.mikrocontroller.net/attachment/114193/BOSCH_The_config_of_CAN_Bit_Timing_L-1.pdf http://www.analog.com/en/analog-dialogue/articles/configure-can-bit-timing.html

bakerstu commented 7 years ago

I'm going to drop a couple of references here:

http://www.nxp.com/assets/documents/data/en/application-notes/AN1798.pdf http://www.mikrocontroller.net/attachment/114193/BOSCH_The_config_of_CAN_Bit_Timing_L-1.pdf https://vector.com/portal/medien/cmc/application_notes/AN-AND-1-106_Basic_CAN_Bit_Timing.pdf

TQ = Time Quanta SJW = Sync Jump Width

There are 4 segments to a CAN bit (in order):

  1. SyncSeg (always 1 TQ)
  2. PropSeg (less than or equal to 8 TQ)
  3. PhaseSeg1 (less than or equal to 8 TQ)
  4. PhaseSeg2 (greater than or equal to PhaseSeg1)

(300m 5ns 2) + 400nsec = 3.4 usec <= PropSeg

Oscillator tolerance is the lessor of:

  1. min(PhaseSeg1, PhaseSeg2) / (2 ((13 bit_time) - PhaseSeg2)
  2. SJW / (20 * bit_time)

Example:

sample point = 13/16 = 75% propagation = 7 * 500ns = 3.5 us > 3.4 usec

  1. 4 / (2 ((13 16) - 4)) = 0.9804%
  2. 3 / (20 * 16) = 0.9375%

Oscillator tolerance = min(calc 1, calc 2) = 0.9375%

This would suggest to me that an oscillator tolerance specification of 0.9% or better is reasonable, and that the CAN timing shall be setup in the CAN controller to support this.

bakerstu commented 7 years ago

Added CAN bit timing calculator spreadsheet:

https://github.com/openlcb/documents/blob/master/specs/drafts/CanBitTimingCalculator.ods

kiwi64ajs commented 7 years ago

Hi Guys,

On 6/01/2017, at 7:40 AM, Balazs Racz notifications@github.com wrote:

We need to document the recommended / required bit timing information for CAN-bus. generally based on the cable length that we are trying to achieve we have a requirement on the prop segment length. Ensuring that standards compliant firmwares have sufficiently long prop segment length is important. Hence documenting it in the standard makes sense.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/openlcb/documents/issues/1, or mute the thread https://github.com/notifications/unsubscribe-auth/AHuO7YjMwy93HYShrLUJcuDXFlIogAqyks5rPTkpgaJpZM4Lb_p1.

I’ve been experimenting with the Teensy 3.1 CAN controller and the FlexCAN libraries that support this chip and I’m seeing differences between the two libraries and I expect they have quite different CAN BitTimings such that one library works (early version) and the latest version doesn’t work wiht my RS-Io boards.

I need to educate myself a bit more about all this but it will obviously be a problem so we need to nail down in the OpenLCB CAN Spec if we are to achieve interoperability.

Has anyone got “the answer” for these values to operate well for OpenLCB?

Alex

bakerstu commented 7 years ago

Alex,

I've pushed a spreadsheet for calculating bit timings to the documentation repository.

https://github.com/openlcb/documents/blob/master/specs/drafts/CanBitTimingCalculator.ods

Thanks,

Stuart

On 5/9/17 12:57AM, Alex Shepherd wrote:

Hi Guys,

On 6/01/2017, at 7:40 AM, Balazs Racz notifications@github.com wrote:

We need to document the recommended / required bit timing information for CAN-bus. generally based on the cable length that we are trying to achieve we have a requirement on the prop segment length. Ensuring that standards compliant firmwares have sufficiently long prop segment length is important. Hence documenting it in the standard makes sense.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/openlcb/documents/issues/1, or mute the thread https://github.com/notifications/unsubscribe-auth/AHuO7YjMwy93HYShrLUJcuDXFlIogAqyks5rPTkpgaJpZM4Lb_p1.

I’ve been experimenting with the Teensy 3.1 CAN controller and the FlexCAN libraries that support this chip and I’m seeing differences between the two libraries and I expect they have quite different CAN BitTimings such that one library works (early version) and the latest version doesn’t work wiht my RS-Io boards.

I need to educate myself a bit more about all this but it will obviously be a problem so we need to nail down in the OpenLCB CAN Spec if we are to achieve interoperability.

Has anyone got “the answer” for these values to operate well for OpenLCB?

Alex

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/openlcb/documents/issues/1#issuecomment-300068691, or mute the thread https://github.com/notifications/unsubscribe-auth/ACLFjqnXokpZ-vY7lGikfYJNA0o1fRlAks5r4AA1gaJpZM4Lb_p1.

dpharris commented 7 years ago

I am working on this with Alex. Much is written about this! Stuart, thanks for the spreadsheet. There is a good Freescale paper that might help. Will keep you informed.

David

On May 9, 2017 04:47, "Stuart W Baker" notifications@github.com wrote:

Alex,

I've pushed a spreadsheet for calculating bit timings to the documentation repository. There is also a bug filed against this:

https://github.com/openlcb/documents/blob/master/specs/ drafts/CanBitTimingCalculator.ods

https://github.com/openlcb/documents/issues/1

Thanks,

Stuart

On 5/9/17 12:57AM, Alex Shepherd wrote:

Hi Guys,

On 6/01/2017, at 7:40 AM, Balazs Racz notifications@github.com wrote:

We need to document the recommended / required bit timing information for CAN-bus. generally based on the cable length that we are trying to achieve we have a requirement on the prop segment length. Ensuring that standards compliant firmwares have sufficiently long prop segment length is important. Hence documenting it in the standard makes sense.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/openlcb/documents/issues/1, or mute the thread https://github.com/notifications/unsubscribe-auth/ AHuO7YjMwy93HYShrLUJcuDXFlIogAqyks5rPTkpgaJpZM4Lb_p1.

I’ve been experimenting with the Teensy 3.1 CAN controller and the FlexCAN libraries that support this chip and I’m seeing differences between the two libraries and I expect they have quite different CAN BitTimings such that one library works (early version) and the latest version doesn’t work wiht my RS-Io boards.

I need to educate myself a bit more about all this but it will obviously be a problem so we need to nail down in the OpenLCB CAN Spec if we are to achieve interoperability.

Has anyone got “the answer” for these values to operate well for OpenLCB?

Alex

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/openlcb/documents/issues/1#issuecomment-300068691, or mute the thread https://github.com/notifications/unsubscribe-auth/ACLFjqnXokpZ- vY7lGikfYJNA0o1fRlAks5r4AA1gaJpZM4Lb_p1.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/openlcb/documents/issues/1#issuecomment-300139327, or mute the thread https://github.com/notifications/unsubscribe-auth/AAg4Sp8ih1CIBfHOpfE9T4Li1AZibZyYks5r4FI2gaJpZM4Lb_p1 .

bakerstu commented 7 years ago

My spreadsheet is based on the equations in the Freescale app note.

balazsracz commented 2 years ago

@kiwi64ajs Does your issue still appear? I'm wondering if this would be worth a deeper investigation. We could find that there might be a bug in one or the other CAN library implementation.

In the meantime I implemented a bit timing optimizer. Here are the possible combinations, sorted by reached oscillator tolerance:

0.98  :  ['len 310 m, prop 7 ps1 4 ps2 4 sjw 4, sample 75.0, o1 1.25 o2 0.98',
          'len 320 m, prop 9 ps1 5 ps2 5 sjw 4, sample 75.0, o1 1 o2 0.98']
0.938 :  ['len 310 m, prop 7 ps1 4 ps2 4 sjw 3, sample 75.0, o1 0.938 o2 0.98']
0.936 :  ['len 303 m, prop 9 ps1 5 ps2 6 sjw 4, sample 71.4, o1 0.952 o2 0.936']
0.933 :  ['len 303 m, prop 9 ps1 6 ps2 5 sjw 4, sample 76.2, o1 0.952 o2 0.933', 
          'len 341 m, prop 10 ps1 5 ps2 5 sjw 4, sample 76.2, o1 0.952 o2 0.933']
0.922 :  ['len 336 m, prop 8 ps1 4 ps2 4 sjw 4, sample 76.5, o1 1.18 o2 0.922']
0.904 :  ['len 329 m, prop 6 ps1 3 ps2 3 sjw 3, sample 76.9, o1 1.15 o2 0.904']
0.893 :  ['len 324 m, prop 10 ps1 5 ps2 6 sjw 4, sample 72.7, o1 0.909 o2 0.893']
0.89  :  ['len 324 m, prop 10 ps1 6 ps2 5 sjw 4, sample 77.3, o1 0.909 o2 0.89', 
          'len 360 m, prop 11 ps1 5 ps2 5 sjw 4, sample 77.3, o1 0.909 o2 0.89']
0.882 :  ['len 336 m, prop 8 ps1 4 ps2 4 sjw 3, sample 76.5, o1 0.882 o2 0.922']
0.873 :  ['len 316 m, prop 8 ps1 4 ps2 5 sjw 4, sample 72.2, o1 1.11 o2 0.873']

# Before colon: the oscillator tolerance in percent. This is to be interpreted
# as +- this percentage at both source and destination (independently).
#
# len = max cable length
# prop = number of TQ for propagation segment
# ps1 = number of TQ for phase segment 1
# ps2 = number of TQ for phase segment 2
# sjw = number of TQ for (re)-synchronization jump width
# sample = sample point within bit in %
# o1 = osc tolerance limit from one constraint
# o2 = osc tolerance limit from another constraint
#
# When there are two entries in this line, that means that two different
# configurations reach the same osc tolerance.
balazsracz commented 2 years ago

script code is here: https://github.com/bakerstu/openmrn/pull/606

kiwi64ajs commented 2 years ago

Wow, I'm struggling to switch back into this context as it was many years ago now huh..?

I seem to recall differences of CAN bit timing values in different devices and an absence of definitive CAN bit-timings in the specs as being a potential issue that needs to be explicitly defined in the spec - so I guess this is it huh?

As to my original Teensy 3.1 issue, I had assumed that to be caused more by library changes which may have included CAN bit timing, but I had assumed coding / framework changes were to blame and was going to wait for the issue to hopefully be resolved by others, but I've not checked since as I just used the RS-IO boards and code that was already working.

bakerstu commented 1 year ago

I've been looking at this today, and I believe the below results produced by Balazs' script have some invalid values in them. More specifically, according to the document references externally linked to this issue:

As a warning, some CAN controllers require SJW to be at least one less than PS2 to allow for processing time.

I have pushed an update to the spreadsheet calculator to be a bit easier to use. I've also added some conditional checks for catching errors that I missed in the previous version: https://github.com/openlcb/documents/tree/master/drafts/CanBitTimingCalculator.ods

0.98 : ['len 310 m, prop 7 ps1 4 ps2 4 sjw 4, sample 75.0, o1 1.25 o2 0.98', 'len 320 m, prop 9 ps1 5 ps2 5 sjw 4, sample 75.0, o1 1 o2 0.98'] 0.938 : ['len 310 m, prop 7 ps1 4 ps2 4 sjw 3, sample 75.0, o1 0.938 o2 0.98'] 0.936 : ['len 303 m, prop 9 ps1 5 ps2 6 sjw 4, sample 71.4, o1 0.952 o2 0.936'] 0.933 : ['len 303 m, prop 9 ps1 6 ps2 5 sjw 4, sample 76.2, o1 0.952 o2 0.933', 'len 341 m, prop 10 ps1 5 ps2 5 sjw 4, sample 76.2, o1 0.952 o2 0.933'] 0.922 : ['len 336 m, prop 8 ps1 4 ps2 4 sjw 4, sample 76.5, o1 1.18 o2 0.922'] 0.904 : ['len 329 m, prop 6 ps1 3 ps2 3 sjw 3, sample 76.9, o1 1.15 o2 0.904'] 0.893 : ['len 324 m, prop 10 ps1 5 ps2 6 sjw 4, sample 72.7, o1 0.909 o2 0.893'] 0.89 : ['len 324 m, prop 10 ps1 6 ps2 5 sjw 4, sample 77.3, o1 0.909 o2 0.89', 'len 360 m, prop 11 ps1 5 ps2 5 sjw 4, sample 77.3, o1 0.909 o2 0.89'] 0.882 : ['len 336 m, prop 8 ps1 4 ps2 4 sjw 3, sample 76.5, o1 0.882 o2 0.922'] 0.873 : ['len 316 m, prop 8 ps1 4 ps2 5 sjw 4, sample 72.2, o1 1.11 o2 0.873']

# Before colon: the oscillator tolerance in percent. This is to be interpreted # as +- this percentage at both source and destination (independently). # # len = max cable length # prop = number of TQ for propagation segment # ps1 = number of TQ for phase segment 1 # ps2 = number of TQ for phase segment 2 # sjw = number of TQ for (re)-synchronization jump width # sample = sample point within bit in % # o1 = osc tolerance limit from one constraint # o2 = osc tolerance limit from another constraint # # When there are two entries in this line, that means that two different # configurations reach the same osc tolerance.

dpharris commented 1 year ago

Thanks Stuart. That link fails as it points to blob.

Try https://github.com/openlcb/documents/tree/master/drafts/CanBitTimingCalculator.ods

David

On Sun, Nov 6, 2022 at 2:33 PM Stuart W Baker @.***> wrote:

I've been looking at this today, and I believe the below results produced by Balazs' script have some invalid values in them. More specifically, according to the document references externally linked to this issue:

  • Prop-Seg cannot be larger than 8
  • PhaseSeg1 must be less than or equal to PhaseSeg2, typically PS2 == PS1 or PS2 == PS1 + 1

As a warning, some CAN controllers require SJW to be at least one less than PS2 to allow for processing time.

I have pushed an update to the spreadsheet calculator to be a bit easier to use. I've also added some conditional checks for catching errors that I missed in the previous version: https://github.com/openlcb/documents/blob/master/specs/drafts/CanBitTimingCalculator.ods

0.98 : ['len 310 m, prop 7 ps1 4 ps2 4 sjw 4, sample 75.0, o1 1.25 o2 0.98', 'len 320 m, prop 9 ps1 5 ps2 5 sjw 4, sample 75.0, o1 1 o2 0.98'] 0.938 : ['len 310 m, prop 7 ps1 4 ps2 4 sjw 3, sample 75.0, o1 0.938 o2 0.98'] 0.936 : ['len 303 m, prop 9 ps1 5 ps2 6 sjw 4, sample 71.4, o1 0.952 o2 0.936'] 0.933 : ['len 303 m, prop 9 ps1 6 ps2 5 sjw 4, sample 76.2, o1 0.952 o2 0.933', 'len 341 m, prop 10 ps1 5 ps2 5 sjw 4, sample 76.2, o1 0.952 o2 0.933'] 0.922 : ['len 336 m, prop 8 ps1 4 ps2 4 sjw 4, sample 76.5, o1 1.18 o2 0.922'] 0.904 : ['len 329 m, prop 6 ps1 3 ps2 3 sjw 3, sample 76.9, o1 1.15 o2 0.904'] 0.893 : ['len 324 m, prop 10 ps1 5 ps2 6 sjw 4, sample 72.7, o1 0.909 o2 0.893'] 0.89 : ['len 324 m, prop 10 ps1 6 ps2 5 sjw 4, sample 77.3, o1 0.909 o2 0.89', 'len 360 m, prop 11 ps1 5 ps2 5 sjw 4, sample 77.3, o1 0.909 o2 0.89'] 0.882 : ['len 336 m, prop 8 ps1 4 ps2 4 sjw 3, sample 76.5, o1 0.882 o2 0.922'] 0.873 : ['len 316 m, prop 8 ps1 4 ps2 5 sjw 4, sample 72.2, o1 1.11 o2 0.873']

Before colon: the oscillator tolerance in percent. This is to be

interpreted

as +- this percentage at both source and destination (independently).

#

len = max cable length

prop = number of TQ for propagation segment

ps1 = number of TQ for phase segment 1

ps2 = number of TQ for phase segment 2

sjw = number of TQ for (re)-synchronization jump width

sample = sample point within bit in %

o1 = osc tolerance limit from one constraint

o2 = osc tolerance limit from another constraint

#

When there are two entries in this line, that means that two different

configurations reach the same osc tolerance.

— Reply to this email directly, view it on GitHub https://github.com/openlcb/documents/issues/1#issuecomment-1304911914, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEDQSQ5YXNRQU25KQQXKATWHAPZJANCNFSM4C3P7J2Q . You are receiving this because you commented.Message ID: @.***>

balazsracz commented 1 year ago

Note: in the list I posted about osc tolerances, the transmitter and receiver are already both factored in. In other words, the numbers seen above are after we divided the available tolerance by two. So 0.98 means that we could have one node being 0.98% too fast and another node 0.98% too slow and still able to communicate across 300 meters of cable.

balazsracz commented 1 year ago

Stuart is right in that not every entry in the bit timing charts can be programmed into every CAN controller. Different CAN controllers have different ways to specify the bit timing, and then they may have a variety of restrictions on the timing register content. For example some CAN controllers require separately setting PropSeg and they only have 3 bits (max 8); others take PropSeg + PS1 in one register and have 4 bits (max 16). Some CAN controllers say SJW < PS2, other say SJW <= PS2.

The table I generated is a superset of all possible bit timings. This means that you are guaranteed not to be able to find any bit timing that is better and not listed in the table. It is enough for you to consider the listings in the table, and verify which ones your specific CAN controller is compatible with. A simple rule of thumb would be to go from the top of the table and stop at the first entry that you find that can be programmed into the particular CAN controller. This procedure will give the best tolerance at 300m cable length.

If we want to optimize for something else than tolerance, then we might want to use the table in some other way.