From fd4e7fb4bce8700086422428448b2038bc714463 Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Sun, 6 Apr 2014 22:24:16 +0200 Subject: [PATCH] More commenting --- Modem/afsk.c | 90 ++++++++++++++++++++++++++++++++++++++++++---------- buildrev.h | 2 +- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/Modem/afsk.c b/Modem/afsk.c index b68bdc0..8681e5e 100644 --- a/Modem/afsk.c +++ b/Modem/afsk.c @@ -282,16 +282,48 @@ void afsk_adc_isr(Afsk *afsk, int8_t currentSample) { afsk->iirY[0] = afsk->iirY[1]; afsk->iirY[1] = afsk->iirX[0] + afsk->iirX[1] + (afsk->iirY[0] >> 1); - // Put the sampled bit in a delay-line - afsk->sampledBits <<= 1; // Bitshift everything 1 left + // We put the sampled bit in a delay-line: + // First we bitshift everything 1 left + afsk->sampledBits <<= 1; + // And then add the sampled bit to our delay line afsk->sampledBits |= (afsk->iirY[1] > 0) ? 1 : 0; // Put the current raw sample in the delay FIFO fifo_push(&afsk->delayFifo, currentSample); - // If there is a signal transition, recalibrate - // sampling phase - + // We need to check whether there is a signal transition. + // If there is, we can recalibrate the phase of our + // sampler to stay in sync with the transmitter. A bit of + // explanation is required to understand how this works. + // Since we have PHASE_MAX/PHASE_BITS = 8 samples per bit, + // we employ a phase counter (currentPhase), that increments + // by PHASE_BITS everytime a sample is captured. When this + // counter reaches PHASE_MAX, it wraps around by modulus + // PHASE_MAX. We then look at the last three samples we + // captured and determine if the bit was a one or a zero. + // + // This gives us a "window" looking into the stream of + // samples coming from the ADC. Sort of like this: + // + // Past Future + // 0000000011111111000000001111111100000000 + // |________| + // || + // Window + // + // Every time we detect a signal transition, we adjust + // where this window is positioned little. How much we + // adjust it is defined by PHASE_INC. If our current phase + // phase counter value is less than half of PHASE_MAX (ie, + // the window size) when a signal transition is detected, + // add PHASE_INC to our phase counter, effectively moving + // the window a little bit backward (to the left in the + // illustration), inversely, if the phase counter is greater + // than half of PHASE_MAX, we move it forward a little. + // This way, our "window" is constantly seeking to position + // it's center at the bit transitions. Thus, we synchronise + // our timing to the transmitter, even if it's timing is + // a little off compared to our own. if (TRANSITION_FOUND(afsk->sampledBits)) { if (afsk->currentPhase < PHASE_THRESHOLD) { afsk->currentPhase += PHASE_INC; @@ -299,18 +331,25 @@ void afsk_adc_isr(Afsk *afsk, int8_t currentSample) { afsk->currentPhase -= PHASE_INC; } } + + // We incroment our phase counter afsk->currentPhase += PHASE_BITS; - // Look at the raw samples to determine the transmitted bit + // Check if we have reached the end of + // our sampling window. if (afsk->currentPhase >= PHASE_MAX) { + // If we have, wrap around our phase + // counter by modulus afsk->currentPhase %= PHASE_MAX; - // Bitshift to make room for next bit + // Bitshift to make room for the next + // bit in our stream of demodulated bits afsk->actualBits <<= 1; - // Determine the actual bit value by reading the last - // 3 sampled bits. If there is two ore more 1's, the - // actual bit is a 1, otherwise a 0. + // We determine the actual bit value by reading + // the last 3 sampled bits. If there is two or + // more 1's, we will assume that the transmitter + // sent us a one, otherwise we assume a zero uint8_t bits = afsk->sampledBits & 0x07; if (bits == 0x07 || // 111 bits == 0x06 || // 110 @@ -321,9 +360,22 @@ void afsk_adc_isr(Afsk *afsk, int8_t currentSample) { } // Now we can pass the actual bit to the HDLC parser. - // We are using NRZI coding, so if 2 consecutive bits + // We are using NRZ coding, so if 2 consecutive bits // have the same value, we have a 1, otherwise a 0. - // We use the EDGE_FOUND function to determine this. + // We use the TRANSITION_FOUND function to determine this. + // + // This is smart in combination with bit stuffing, + // since it ensures a transmitter will never send more + // than five consecutive 1's. When sending consecutive + // ones, the signal stays at the same level, and if + // this happens for longer periods of time, we would + // not be able to synchronize our phase to the transmitter + // and would start experiencing "bit slip". + // + // By combining bit-stuffing with NRZ coding, we ensure + // that the signal will regularly make transitions + // that we can use to synchronize our phase. + // // We also check the return of the Link Control parser // to check if an error occured. if (!hdlcParse(&afsk->hdlc, !TRANSITION_FOUND(afsk->actualBits), &afsk->rxFifo)) { @@ -337,7 +389,7 @@ void afsk_adc_isr(Afsk *afsk, int8_t currentSample) { ////////////////////////////////////////////////////// // Defines how many consecutive ones we send -// before we need "stuff" in a zero +// before we need to "stuff" in a zero #define BIT_STUFF_LEN 5 // A macro for switching what tone is being @@ -528,11 +580,14 @@ void afsk_init(Afsk *afsk, int _adcPin) { // Allocate memory for struct memset(afsk, 0, sizeof(*afsk)); - // Configure pins + // Configure ADC pin afsk->adcPin = _adcPin; + + // Initialise phase increment to that + // of the mark frequency afsk->phaseInc = MARK_INC; - // Init FIFO buffers + // Initialize FIFO buffers fifo_init(&afsk->delayFifo, (uint8_t *)afsk->delayBuf, sizeof(afsk->delayBuf)); fifo_init(&afsk->rxFifo, afsk->rxBuf, sizeof(afsk->rxBuf)); fifo_init(&afsk->txFifo, afsk->txBuf, sizeof(afsk->txBuf)); @@ -542,12 +597,15 @@ void afsk_init(Afsk *afsk, int _adcPin) { fifo_push(&afsk->delayFifo, 0); } - // Init DAC & ADC + // Initialize hardware AFSK_ADC_INIT(_adcPin, afsk); AFSK_DAC_INIT(); LED_TX_INIT(); LED_RX_INIT(); + // And register the modem file-pointer + // functions for reading from and + // writing to it. DB(afsk->fd._type = KFT_AFSK); afsk->fd.write = afsk_write; afsk->fd.read = afsk_read; diff --git a/buildrev.h b/buildrev.h index a383596..1251492 100644 --- a/buildrev.h +++ b/buildrev.h @@ -1,2 +1,2 @@ -#define VERS_BUILD 382 +#define VERS_BUILD 383 #define VERS_HOST "vixen"