Merge the data bit detection and data byte assembly into the same loop

Original code loops through the analogue array m[] detecting data bits
and putting them into the bits[] array. It then loops through all the
bits[] creating the msg[] byte array. It then loops through the analogue
array m[] again calculating the signal strength.

Change this so that everything is done in one loop so we can go straight
from analogue samples to bytes, calculating the signal strength on the
fly.

Also use the results of the signal strength calculation to populate the
message records mm.signalLevel variable.
This commit is contained in:
Malcolm Robb 2013-04-10 11:33:18 +01:00
parent d85939c4f5
commit e59142b9dc

View file

@ -945,7 +945,6 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
/* Work on our local copy */ /* Work on our local copy */
memcpy(mm->msg,msg,MODES_LONG_MSG_BYTES); memcpy(mm->msg,msg,MODES_LONG_MSG_BYTES);
mm->signalLevel = 0xA5;
msg = mm->msg; msg = mm->msg;
/* Get the message type ASAP as other operations depend on this */ /* Get the message type ASAP as other operations depend on this */
@ -1312,8 +1311,7 @@ void applyPhaseCorrection(uint16_t *pPayload) {
* size 'mlen' bytes. Every detected Mode S message is convert it into a * size 'mlen' bytes. Every detected Mode S message is convert it into a
* stream of bits and passed to the function to display it. */ * stream of bits and passed to the function to display it. */
void detectModeS(uint16_t *m, uint32_t mlen) { void detectModeS(uint16_t *m, uint32_t mlen) {
unsigned char bits[MODES_LONG_MSG_BITS]; unsigned char msg[MODES_LONG_MSG_BYTES], *pMsg;
unsigned char msg[MODES_LONG_MSG_BYTES];
uint16_t aux[MODES_LONG_MSG_SAMPLES]; uint16_t aux[MODES_LONG_MSG_SAMPLES];
uint32_t j; uint32_t j;
int use_correction = 0; int use_correction = 0;
@ -1345,7 +1343,8 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
int low, high, delta, i, errors; int low, high, delta, i, errors;
int good_message = 0; int good_message = 0;
uint16_t *pPreamble, *pPayload, *pPtr; uint16_t *pPreamble, *pPayload, *pPtr;
int msglen; uint8_t theByte;
int msglen, sigStrength;
pPreamble = &m[j]; pPreamble = &m[j];
pPayload = &m[j+MODES_PREAMBLE_SAMPLES]; pPayload = &m[j+MODES_PREAMBLE_SAMPLES];
@ -1414,8 +1413,12 @@ good_preamble:
/* Decode all the next 112 bits, regardless of the actual message /* Decode all the next 112 bits, regardless of the actual message
* size. We'll check the actual message type later. */ * size. We'll check the actual message type later. */
pMsg = &msg[0];
pPtr = pPayload; pPtr = pPayload;
theByte = 0;
errors = 0; errors = 0;
sigStrength = 0;
msglen = MODES_LONG_MSG_BITS;
for (i = 0; i < MODES_LONG_MSG_BITS; i++) { for (i = 0; i < MODES_LONG_MSG_BITS; i++) {
low = *pPtr++; low = *pPtr++;
high = *pPtr++; high = *pPtr++;
@ -1423,49 +1426,36 @@ good_preamble:
if (delta < 0) delta = -delta; if (delta < 0) delta = -delta;
if (i > 0 && delta < 256) { if (i > 0 && delta < 256) {
bits[i] = bits[i-1]; if (theByte & 2)
{theByte |= 1;}
} else if (low == high) { } else if (low == high) {
/* Checking if two adiacent samples have the same magnitude /* Checking if two adiacent samples have the same magnitude
* is an effective way to detect if it's just random noise * is an effective way to detect if it's just random noise
* that was detected as a valid preamble. */ * that was detected as a valid preamble. */
bits[i] = 2; /* error */ theByte |= 2; /* error */
if (i < MODES_SHORT_MSG_SAMPLES) errors++; if (i < MODES_SHORT_MSG_BITS) errors++;
} else if (low > high) { } else if (low > high) {
bits[i] = 1; theByte |= 1;
} else {
/* (low < high) for exclusion */
bits[i] = 0;
}
} }
/* Pack bits into bytes */ if (i < msglen) {
for (i = 0; i < MODES_LONG_MSG_BITS; i += 8) { sigStrength += delta;
msg[i/8] =
bits[i]<<7 |
bits[i+1]<<6 |
bits[i+2]<<5 |
bits[i+3]<<4 |
bits[i+4]<<3 |
bits[i+5]<<2 |
bits[i+6]<<1 |
bits[i+7];
} }
msglen = modesMessageLenByType(msg[0] >> 3) / 8; if (i == 4) {
msglen = modesMessageLenByType(theByte);
/* Last check, high and low bits are different enough in magnitude } else if ((i & 7) == 7) {
* to mark this as real message and not just noise? */ *pMsg++ = theByte;
delta = 0; }
pPtr = pPayload; theByte = theByte << 1;
for (i = 0; i < msglen*8; i ++, pPtr += 2) {
delta += abs(pPtr[0] - pPtr[1]);
} }
delta /= msglen*4;
/* Filter for an average delta of three is small enough to let almost /* Filter for an average delta of three is small enough to let almost
* every kind of message to pass, but high enough to filter some * every kind of message to pass, but high enough to filter some
* random noise. */ * random noise. */
if (delta < 10*255) { sigStrength /= msglen;
if (sigStrength < (5*255)) {
use_correction = 0; use_correction = 0;
continue; continue;
} }
@ -1478,6 +1468,7 @@ good_preamble:
/* Decode the received message and update statistics */ /* Decode the received message and update statistics */
mm.timestampMsg = Modes.timestampBlk + (j*6); mm.timestampMsg = Modes.timestampBlk + (j*6);
mm.signalLevel = min(((sigStrength+0x7F) >> 8), 255);
decodeModesMessage(&mm,msg); decodeModesMessage(&mm,msg);
/* Update statistics. */ /* Update statistics. */
@ -1513,7 +1504,7 @@ good_preamble:
/* Skip this message if we are sure it's fine. */ /* Skip this message if we are sure it's fine. */
if (mm.crcok) { if (mm.crcok) {
j += (MODES_PREAMBLE_US+(msglen*8))*2; j += (MODES_PREAMBLE_US+msglen)*2;
good_message = 1; good_message = 1;
if (use_correction) if (use_correction)
mm.phase_corrected = 1; mm.phase_corrected = 1;
@ -2170,6 +2161,7 @@ int decodeHexMessage(struct client *c) {
msg[j/2] = (high<<4) | low; msg[j/2] = (high<<4) | low;
} }
mm.timestampMsg = -1; mm.timestampMsg = -1;
mm.signalLevel = -1;
decodeModesMessage(&mm,msg); decodeModesMessage(&mm,msg);
useModesMessage(&mm); useModesMessage(&mm);
return 0; return 0;