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