Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

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

  1. #1

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

    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;
      }

  2. #2
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    590
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •