More commenting

This commit is contained in:
Mark Qvist 2014-04-06 22:24:16 +02:00
parent a6bad60233
commit fd4e7fb4bc
2 changed files with 75 additions and 17 deletions

View File

@ -282,16 +282,48 @@ void afsk_adc_isr(Afsk *afsk, int8_t currentSample) {
afsk->iirY[0] = afsk->iirY[1]; afsk->iirY[0] = afsk->iirY[1];
afsk->iirY[1] = afsk->iirX[0] + afsk->iirX[1] + (afsk->iirY[0] >> 1); afsk->iirY[1] = afsk->iirX[0] + afsk->iirX[1] + (afsk->iirY[0] >> 1);
// Put the sampled bit in a delay-line // We put the sampled bit in a delay-line:
afsk->sampledBits <<= 1; // Bitshift everything 1 left // 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; afsk->sampledBits |= (afsk->iirY[1] > 0) ? 1 : 0;
// Put the current raw sample in the delay FIFO // Put the current raw sample in the delay FIFO
fifo_push(&afsk->delayFifo, currentSample); fifo_push(&afsk->delayFifo, currentSample);
// If there is a signal transition, recalibrate // We need to check whether there is a signal transition.
// sampling phase // 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 (TRANSITION_FOUND(afsk->sampledBits)) {
if (afsk->currentPhase < PHASE_THRESHOLD) { if (afsk->currentPhase < PHASE_THRESHOLD) {
afsk->currentPhase += PHASE_INC; afsk->currentPhase += PHASE_INC;
@ -299,18 +331,25 @@ void afsk_adc_isr(Afsk *afsk, int8_t currentSample) {
afsk->currentPhase -= PHASE_INC; afsk->currentPhase -= PHASE_INC;
} }
} }
// We incroment our phase counter
afsk->currentPhase += PHASE_BITS; 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 (afsk->currentPhase >= PHASE_MAX) {
// If we have, wrap around our phase
// counter by modulus
afsk->currentPhase %= PHASE_MAX; 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; afsk->actualBits <<= 1;
// Determine the actual bit value by reading the last // We determine the actual bit value by reading
// 3 sampled bits. If there is two ore more 1's, the // the last 3 sampled bits. If there is two or
// actual bit is a 1, otherwise a 0. // more 1's, we will assume that the transmitter
// sent us a one, otherwise we assume a zero
uint8_t bits = afsk->sampledBits & 0x07; uint8_t bits = afsk->sampledBits & 0x07;
if (bits == 0x07 || // 111 if (bits == 0x07 || // 111
bits == 0x06 || // 110 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. // 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. // 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 // We also check the return of the Link Control parser
// to check if an error occured. // to check if an error occured.
if (!hdlcParse(&afsk->hdlc, !TRANSITION_FOUND(afsk->actualBits), &afsk->rxFifo)) { 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 // 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 #define BIT_STUFF_LEN 5
// A macro for switching what tone is being // A macro for switching what tone is being
@ -528,11 +580,14 @@ void afsk_init(Afsk *afsk, int _adcPin) {
// Allocate memory for struct // Allocate memory for struct
memset(afsk, 0, sizeof(*afsk)); memset(afsk, 0, sizeof(*afsk));
// Configure pins // Configure ADC pin
afsk->adcPin = _adcPin; afsk->adcPin = _adcPin;
// Initialise phase increment to that
// of the mark frequency
afsk->phaseInc = MARK_INC; afsk->phaseInc = MARK_INC;
// Init FIFO buffers // Initialize FIFO buffers
fifo_init(&afsk->delayFifo, (uint8_t *)afsk->delayBuf, sizeof(afsk->delayBuf)); fifo_init(&afsk->delayFifo, (uint8_t *)afsk->delayBuf, sizeof(afsk->delayBuf));
fifo_init(&afsk->rxFifo, afsk->rxBuf, sizeof(afsk->rxBuf)); fifo_init(&afsk->rxFifo, afsk->rxBuf, sizeof(afsk->rxBuf));
fifo_init(&afsk->txFifo, afsk->txBuf, sizeof(afsk->txBuf)); 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); fifo_push(&afsk->delayFifo, 0);
} }
// Init DAC & ADC // Initialize hardware
AFSK_ADC_INIT(_adcPin, afsk); AFSK_ADC_INIT(_adcPin, afsk);
AFSK_DAC_INIT(); AFSK_DAC_INIT();
LED_TX_INIT(); LED_TX_INIT();
LED_RX_INIT(); LED_RX_INIT();
// And register the modem file-pointer
// functions for reading from and
// writing to it.
DB(afsk->fd._type = KFT_AFSK); DB(afsk->fd._type = KFT_AFSK);
afsk->fd.write = afsk_write; afsk->fd.write = afsk_write;
afsk->fd.read = afsk_read; afsk->fd.read = afsk_read;

View File

@ -1,2 +1,2 @@
#define VERS_BUILD 382 #define VERS_BUILD 383
#define VERS_HOST "vixen" #define VERS_HOST "vixen"