mirror of
https://github.com/markqvist/OpenModem.git
synced 2024-12-29 01:16:17 -05:00
More commenting
This commit is contained in:
parent
a6bad60233
commit
fd4e7fb4bc
90
Modem/afsk.c
90
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;
|
||||
|
@ -1,2 +1,2 @@
|
||||
#define VERS_BUILD 382
|
||||
#define VERS_BUILD 383
|
||||
#define VERS_HOST "vixen"
|
||||
|
Loading…
Reference in New Issue
Block a user