How to add nonstandard baud rate to flexCAN(colink80 version)?

Status
Not open for further replies.

Black_Stork

Member
My last obstacle is to add new baud rate to library which is 83 333 baud. At line 155 there is this some kind of baud rate determination mechanism which i don't fully understand.
If i want to get 83 333 baud rate by division of 16M i need to devide it by 192.000768 ~192, but what next then? How do i calculate low end, high end bit timing, how do i determine correct values and add them to library?
(Teensy 3.2)

Code:
 /*
    now using a system that tries to automatically generate a viable baud setting.
    Bear these things in mind:
    - The master clock is 16Mhz
    - You can freely divide it by anything from 1 to 256
    - There is always a start bit (+1)
    - The rest (prop, seg1, seg2) are specified 1 less than their actual value (aka +1)
    - This gives the low end bit timing as 5 (1 + 1 + 2 + 1) and the high end 25 (1 + 8 + 8 + 8)
    A worked example: 16Mhz clock, divisor = 19+1, bit values add up to 16 = 16Mhz / 20 / 16 = 50k baud        
  */

  //have to find a divisor that ends up as close to the target baud as possible while keeping the end result between 5 and 25
  int divisor = 0; 
  int result = 16000000 / baud / (divisor + 1);
  int error = baud - (16000000 / (result * (divisor + 1))); 
  int bestDivisor = 0;
  int bestError = error;

  while (result > 5)
  {
        divisor++;
        result = 16000000 / baud / (divisor + 1);
        if (result <= 25)
        {
            error = baud - (16000000 / (result * (divisor + 1)));
            if (error < 0) error *= -1;
            //if this error is better than we've ever seen then use it - it's the best option
            if (error < bestError) 
            {
                bestError = error;
                bestDivisor = divisor;
            }
            //If this is equal to a previously good option then
            //switch to it but only if the bit time result was in the middle of the range
            //this biases the output to use the middle of the range all things being equal
            //Otherwise it might try to use a higher divisor and smaller values for prop, seg1, seg2
            //and that's not necessarily the best idea.
            if (error == bestError && result > 11 && result < 19)
            {
                bestError = error;
                bestDivisor = divisor;                
            }
        }        
  }
  
  divisor = bestDivisor;
  result = 16000000 / baud / (divisor + 1);
  
  if (result < 5 || result > 25 || bestError > 300) 
  {
      Serial.println("Abort in CAN begin. Couldn't find a suitable baud config!");
      return;
  }
 
I've been working on flexcan, looks like the error rate should be acceptable.

I placed the following into GNU BC

Code:
baud = 83.333; divisor = 0; result = 16000000 / baud / (divisor + 1); error = baud - (16000000 / (result * (divisor + 1))); error
and out pops the error, which should be acceptable.
Code:
.003

Basically, the code tries to minimize the error amount within CANBUS specs.
You *SHOULD* be ok with the defaults, and shouldn't need to alter the timings table.
 
Status
Not open for further replies.
Back
Top