Hi robtillaart,
I wondered why a long devision (int32) is needed. I tried to find a solution with int (int16) only. And came up with this precise solution (focus is on rxintra):
// 8MHZ
int baudrate = (int)speed;
int j=-39 | baudrate;
int m=2* (-baudrate & 2*j | baudrate);
int a=((2*m) & m ) | baudrate;
int rxintra=(-15240-3*a-j)/a-1;
It's precise in a sense that it resembles all table data with 0 difference. (But it's not "linear" in your sense. Instead I call it "weird".)
To make your proof simple I wrote this scetch:
#include "WProgram.h"
//
// Lookup table
//
typedef struct _DELAY_TABLE
{
long baud;
unsigned short rx_delay_centering;
unsigned short rx_delay_intrabit;
unsigned short rx_delay_stopbit;
unsigned short tx_delay;
} DELAY_TABLE;
// 8 Mhz table
static const DELAY_TABLE table[] PROGMEM =
{
// baud rxcenter rxintra rxstop tx
{ 115200, 1, 5, 5, 3, },
{ 57600, 1, 15, 15, 13, },
{ 38400, 2, 25, 26, 23, },
{ 31250, 7, 32, 33, 29, },
{ 28800, 11, 35, 35, 32, },
{ 19200, 20, 55, 55, 52, },
{ 14400, 30, 75, 75, 72, },
{ 9600, 50, 114, 114, 112, },
{ 4800, 110, 233, 233, 230, },
{ 2400, 229, 472, 472, 469, },
{ 1200, 467, 948, 948, 945, },
{ 300, 1895, 3805, 3805, 3802, },
};
int SoftwareSerial_rxintraA(long speed)
{
for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i)
{
long baud = pgm_read_dword(&table[i].baud);
if (baud == speed)
{
return pgm_read_word(&table[i].rx_delay_intrabit);
}
}
return -1;
}
int SoftwareSerial_rxintraB(long speed)
{
long baudrate = speed;
// 8MHZ
int rxintra = 8000000L/(7 * baudrate) - 4;
return rxintra;
}
int SoftwareSerial_rxintraC(long speed)
{
// 8MHZ
int baudrate = (int)speed;
int j=-39 | baudrate;
int m=2* (-baudrate & 2*j | baudrate);
int a=((2*m) & m ) | baudrate;
int rxintra=(-15240-3*a-j)/a-1;
return rxintra;
}
void setup() {
Serial.begin(9600);
Serial.println("baud\tA\tB\tC");
for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i)
{
long baud = pgm_read_dword(&table[i].baud);
Serial.print(baud); Serial.print("\t");
Serial.print(SoftwareSerial_rxintraA(baud)); Serial.print("\t");
Serial.print(SoftwareSerial_rxintraB(baud)); Serial.print("\t");
Serial.print(SoftwareSerial_rxintraC(baud)); Serial.print("\t");
Serial.println();
}
}
void loop() {
}