w.pasman Elite Veteran Location: Netherlands
| I forgot to post this, but here is the improved version of the annotated propro code. I think I have all comments in place but I did not check everything over again, so maybe there's still some inconsistency in my comments. In my head it's clear now so I go further
//---------------------------------------------------------------------------
// The SmartPropo project is concerned with reading out the
// transmitter via the trainer port to a computer.
[Edited, some stupid remark was left here..]
// ProcessPulse is called for every high-low and low-high flank in the samples
// width is the length to the previous flank (#samples) and input is
// FALSE if the transition is low2high and TRUE if the transition is high2low.
// sampling rate is always 44.1kHz or T=22.6757us.
#ifdef FUTABA_PCM
static void __fastcall ProcessPulse(int width, BOOL input)
{
static int sync = 0;
static unsigned int bit = 0; // last received bit since sync.
// should be equal to input variable I think.
static unsigned int bitcount = 0;
static unsigned int bitstream = 0;
static int data[32]; // 6bit packets received. Don't know why this isn't just byte but int.
static int datacount = 0;
width = (int)floor(width / PW_FUTABA + 0.5);
if (sync == 0 && width == 18) { // more than 18 pulsewidths (408us) is sync
sync = 1;
bit = 0;
bitstream = 0;
bitcount = 0;
datacount = 0;
return;
// NOTE apparently we can trigger both on 408us LOW as 408us HIGH pulse
// but the sync will fail on the second half.
}
if (!sync) return;
// now if width>1 we received more than 1 bit.
// add equal bits to right of the the bitstream
// bitcount keeps track of #bits in bitstream
bitstream = (bitstream << width) | (bit >> (32 - width));
bit ^= 0xFFFFFFFF;
// weird, they are flipping all bits, but they also shift them.
// this goes right (all 1's or all 0's at the rightmost bits
// because they shift always >=22 bits to the right, clearing
// enough bits in the top end to stay out of trouble next round.
bitcount += width;
// I first thought they were preventing buffer overflow here but it seems something else. // apparently they are checking the first 6 bits of the header.
if (sync == 1)
{
if (bitcount >= 6)
{
bitcount -= 6;
if (((bitstream >> bitcount) & 0x3F) == 0x03) {
// first 6 bits are 000011 then odd frame
sync = 2;
datacount = 0; // odd frames put data at head of data block
} else if (((bitstream >> bitcount) & 0x3F) == 0x00) {
// first 6 bits are 000000 then even frame
sync = 2;
datacount = 16; //even frames put data halfway the datablock.
bitcount -= 2; // AND we drop two bits ???
} else {
sync = 0;
}
}
return;
}
// we passed the header, and we're now in sync mode 2
// if we have 10 bits we have received a new symbol.
// This is a 6B10B block code as they call it,
// which means every 10 bits encode a 6 bit value.
// Why this is useful is still to be figured out.
if (bitcount >= 10)
{
bitcount -= 10;
// look up the corresponding symbol from the table and store it in data array.
if ((data[datacount++] = futaba_symbol[(bitstream >> bitcount) & 0x3FF]) < 0)
{
// only 2^6 out of the 2^10 symbols are valid.
// If we get here we received an illegal symbol and cancel processing.
sync = 0;
return;
}
}
// check if we can calculate some channel positions.
// To do that we join parts of two 6-bit values to make a 10 bit number.
// FredericG found more accurate contents for the data array
// Every 24bits data contains 2bits of auxilialy data,
// 4bits of difference data, 10bits ofposition data,
//and 8 bits of error correcting data.
// NOTE that they ignore the differnce data here, they only use the
// absolute bits. and they also ignore the error checking.
// Therefore they wait two frames, as each frame has only one half of the
// absolute data.
switch (datacount) {
case 3: if ((data[0] >> 4) != 0) Position[2] = (data[1] << 4) | (data[2] >> 2); break;
case 7: Position[3] = (data[5] << 4) | (data[6] >> 2); break;
case 11: if ((data[0] >> 4) != 0) Position[4] = (data[9] << 4) | (data[10] >> 2); break;
case 15: sync = 0;
case 19: Position[1] = (data[17] << 4) | (data[18] >> 2); break;
case 23: if ((data[16] >> 4) != 1) Position[0] = (data[21] << 4) | (data[22] >> 2); break;
case 27: Position[5] = (data[25] << 4) | (data[26] >> 2); break;
case 31: break;
case 32: sync = 0;
}
}
|