Updated doc. Cleanup.

This commit is contained in:
Mark Qvist 2014-04-09 23:33:15 +02:00
parent 65820627ec
commit 5452a7f662
6 changed files with 74 additions and 67 deletions

View File

@ -6,8 +6,7 @@
#include "config.h" // This stores basic configuration
#include "hardware.h" // Hardware functions are nice to have too :)
#include <drv/timer.h> // Timer driver from BertOS
//FIXME: is this needed ? #include <cfg/module.h>
#include <drv/timer.h> // Timer driver from BertOS
#include <cpu/power.h> // Power management from BertOS
#include <cpu/pgm.h> // Access to PROGMEM from BertOS
@ -79,16 +78,30 @@ INLINE uint8_t sinSample(uint16_t i) {
// bits in a stream and returns true if they differ.
#define TRANSITION_FOUND(bits) BITS_DIFFER((bits), (bits) >> 1)
// We use this macro to check if the signal transitioned
// from one bit (tone) to another. This is used in the phase
// synchronisation. We look at the last four bits in the
// stream of demodulated bits and if they differ in sets of
// two bits, we assume a signal transition occured. We look
// at pairs of bits to eliminate false positives where a
// single erroneously demodulated bit will trigger an
// incorrect phase syncronisation.
#define DUAL_XOR(bits1, bits2) ((((bits1)^(bits2)) & 0x03) == 0x03)
#define SIGNAL_TRANSITIONED(bits) DUAL_XOR((bits), (bits) >> 2)
// Phase sync constants
#define PHASE_BITS 8
#define PHASE_INC 1 // FIXME: originally 1
#define PHASE_MAX (SAMPLESPERBIT * PHASE_BITS)
#define PHASE_THRESHOLD (PHASE_MAX / 4) // FIXME: originally /2
#define PHASE_BITS 8 // How much to increment phase counter each sample
#define PHASE_INC 1 // Nudge by an eigth of a sample each adjustment
#define PHASE_MAX (SAMPLESPERBIT * PHASE_BITS) // Resolution of our phase counter = 64
#define PHASE_THRESHOLD (PHASE_MAX / 4) // Target transition point of our phase window
// Modulation constants
#define MARK_FREQ 1200
#define MARK_FREQ 1200 // The tone frequency signifying a binary one
#define SPACE_FREQ 2200 // The tone frequency signifying a binary zero
// We calculate the amount we need to increment the index
// in our sine table for each sample of the two tones
#define MARK_INC (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)MARK_FREQ, CONFIG_AFSK_DAC_SAMPLERATE))
#define SPACE_FREQ 2200
#define SPACE_INC (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)SPACE_FREQ, CONFIG_AFSK_DAC_SAMPLERATE))
// HDLC flag bytes
@ -111,7 +124,6 @@ STATIC_ASSERT(!(CONFIG_AFSK_DAC_SAMPLERATE % BITRATE));
// Link Layer Control and Demodulation //
//////////////////////////////////////////////////////
static int adjustCount; // FIXME: Debug
// hdlcParse /////////////////////////////////////////
// This function looks at the raw bits demodulated from
// the physical medium and tries to parse actual data
@ -158,7 +170,6 @@ static bool hdlcParse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo) {
// false and stopping the here.
ret = false;
hdlc->receiving = false;
kprintf("RX overrun 1!"); // FIXME: remove these
LED_RX_OFF();
}
@ -169,8 +180,6 @@ static bool hdlcParse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo) {
// of the received bytes.
hdlc->currentByte = 0;
hdlc->bitIndex = 0;
//if (adjustCount > 25) kprintf("[AC%d]", adjustCount); // this slows down stuff and makes it work. wtf?!
adjustCount = 0;
return ret;
}
@ -242,7 +251,6 @@ static bool hdlcParse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo) {
// If it is, abort and return false
hdlc->receiving = false;
LED_RX_OFF();
kprintf("RX overrun 3!");
ret = false;
}
}
@ -255,7 +263,6 @@ static bool hdlcParse(Hdlc *hdlc, bool bit, FIFOBuffer *fifo) {
// If it is, well, you know by now!
hdlc->receiving = false;
LED_RX_OFF();
kprintf("RX overrun 4!");
ret = false;
}
@ -339,8 +346,7 @@ void afsk_adc_isr(Afsk *afsk, int8_t currentSample) {
// 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)) {
adjustCount++;
if (SIGNAL_TRANSITIONED(afsk->sampledBits)) {
if (afsk->currentPhase < PHASE_THRESHOLD) {
afsk->currentPhase += PHASE_INC;
} else {
@ -363,27 +369,29 @@ void afsk_adc_isr(Afsk *afsk, int8_t currentSample) {
afsk->actualBits <<= 1;
// We determine the actual bit value by reading
// the last 3 sampled bits. If there is two or
// the last 5 sampled bits. If there is three or
// more 1's, we will assume that the transmitter
// sent us a one, otherwise we assume a zero
// FIXME: Increasing this to 5 bit determine
uint8_t bits = afsk->sampledBits & 0x07;
if (bits == 0x07 || // 111
bits == 0x06 || // 110
bits == 0x05 || // 101
bits == 0x03 // 011
) {
afsk->actualBits |= 1;
}
// uint8_t bits = afsk->sampledBits & 0x0f;
// uint8_t c = 0;
// c += bits & BV(1);
// c += bits & BV(2);
// c += bits & BV(3);
// c += bits & BV(4);
// c += bits & BV(5);
// if (c >= 3) afsk->actualBits |= 1;
uint8_t bits = afsk->sampledBits & 0x0f;
uint8_t c = 0;
c += bits & BV(1);
c += bits & BV(2);
c += bits & BV(3);
c += bits & BV(4);
c += bits & BV(5);
if (c >= 3) afsk->actualBits |= 1;
//// Alternative using only three bits //////////
// uint8_t bits = afsk->sampledBits & 0x07;
// if (bits == 0x07 || // 111
// bits == 0x06 || // 110
// bits == 0x05 || // 101
// bits == 0x03 // 011
// ) {
// afsk->actualBits |= 1;
// }
/////////////////////////////////////////////////
// Now we can pass the actual bit to the HDLC parser.
// We are using NRZ coding, so if 2 consecutive bits
@ -420,14 +428,17 @@ void afsk_adc_isr(Afsk *afsk, int8_t currentSample) {
#define BIT_STUFF_LEN 5
// A macro for switching what tone is being
// synthesized by the DAC.
// synthesized by the DAC. We basically just
// change how quickly we go through the sine
// table each time we send out a sample. This
// is done by changing the phaseInc variable
#define SWITCH_TONE(inc) (((inc) == MARK_INC) ? SPACE_INC : MARK_INC)
// This function starts the transmission
static void afsk_txStart(Afsk *afsk) {
if (!afsk->sending) {
// Initialize the phase increment to
// that of the mark frequency
// that of the mark frequency (zero)
afsk->phaseInc = MARK_INC;
// Reset the phase accumulator to 0
afsk->phaseAcc = 0;

View File

@ -11,7 +11,7 @@
#define CONFIG_AFSK_RXTIMEOUT 0 // How long a read operation from the modem
// will wait for data before timing out.
#define CONFIG_AFSK_PREAMBLE_LEN 350UL // The length of the packet preamble in milliseconds
#define CONFIG_AFSK_PREAMBLE_LEN 450UL // The length of the packet preamble in milliseconds
#define CONFIG_AFSK_TRAILER_LEN 100UL // The length of the packet tail in milliseconds
#endif

View File

@ -17,6 +17,10 @@ static Afsk *modem;
// And now for the actual hardware functions //
//////////////////////////////////////////////////////
// M1 correction = 9500
// M2 correction = 40000
#define FREQUENCY_CORRECTION 0
// This function initializes the ADC and configures
// it the way we need.
void hw_afsk_adcInit(int ch, Afsk *_modem)
@ -28,15 +32,19 @@ void hw_afsk_adcInit(int ch, Afsk *_modem)
// a pin that can't be used for analog input
ASSERT(ch <= 5);
// We need to do some configuration on the Timer/Counter Control
// Register 1, aka Timer1
// We need a timer to control how often our sampling functions
// should run. To do this we will need to change some registers.
// First we do some configuration on the Timer/Counter Control
// Register 1, aka Timer1.
//
// The following bits are set:
// CS11: ClockSource 11, sets the prescaler to 8, ie 2MHz
// WGM13 and WGM12 together enables Timer Mode 12, which
// CS10: ClockSource 10, sets no prescaler on the clock,
// meaning it will run at the same speed as the CPU, ie 16MHz
// WGM13 and WGM12 together enables "Timer Mode 12", which
// is Clear Timer on Compare, compare set to TOP, and the
// source for the TOP value is ICR1 (Input Capture Register1).
TCCR1A = 0;
TCCR1B = BV(CS11) | BV(WGM13) | BV(WGM12);
TCCR1B = BV(CS10) | BV(WGM13) | BV(WGM12);
// Then we set the ICR1 register to what count value we want to
// reset (and thus trigger the interrupt) at.
@ -47,7 +55,8 @@ void hw_afsk_adcInit(int ch, Afsk *_modem)
// (CPUClock / Prescaler) / desired frequency - 1
// So that's what well put in this register to set up our
// 9.6KHz sampling rate.
ICR1 = ((CPU_FREQ / 8) / 9600) - 1;
ICR1 = (((CPU_FREQ+FREQUENCY_CORRECTION)) / 9600) - 1;
kprintf("ICR1=%d",ICR1);
// Set reference to AVCC (5V), select pin
// Set the ADMUX register. The first part (BV(REFS0)) sets

View File

@ -29,7 +29,8 @@ static Serial ser; // Declare a serial interface struct
#define TEST_TX false // Whether we should send test packets
// periodically, plus what to send:
#define TEST_PACKET "Test MP1 AFSK Packet. Test123"
#define TEST_PACKET "Test MP1 AFSK Packet. Test123."
#define TEST_TX_INTERVAL 10000L
static uint8_t serialBuffer[MP1_MAX_FRAME_LENGTH]; // This is a buffer for incoming serial data
@ -47,8 +48,8 @@ static bool sertx = false; // Flag signifying whether it's time to send da
// so we can process each packet as they are decoded.
// Right now it just prints the packet to the serial port.
static void mp1Callback(struct MP1Packet *packet) {
//kfile_printf(&ser.fd, "%.*s\r\n", packet->dataLength, packet->data);
kprintf("%.*s\n", packet->dataLength, packet->data);
kfile_printf(&ser.fd, "%.*s\n", packet->dataLength, packet->data);
//kprintf("%.*s\n", packet->dataLength, packet->data);
}
// Simple initialization function.
@ -57,8 +58,7 @@ static void init(void)
// Enable interrupts
IRQ_ENABLE;
// Initialize BertOS debug bridge
kdbg_init();
kprintf("Init\n");
// kdbg_init();
// Initialize hardware timers
timer_init();
@ -103,7 +103,6 @@ int main(void)
// and the byte is not a "transmit" (newline) character,
// we should store it for transmission.
if ((serialLen < MP1_MAX_FRAME_LENGTH) && (sbyte != 138)) {
//kprintf("Byte: %d\n", sbyte); // FIXME: delete
// Put the read byte into the buffer;
serialBuffer[serialLen] = sbyte;
// Increment the read length counter
@ -127,7 +126,7 @@ int main(void)
}
// Periodically send test data if we should do so
if (TEST_TX && timer_clock() - start > ms_to_ticks(5000L)) {
if (TEST_TX && timer_clock() - start > ms_to_ticks(TEST_TX_INTERVAL)) {
// Reset the timer counter;
start = timer_clock();
// And send a test packet!

View File

@ -3,9 +3,6 @@
#include <string.h>
#include <drv/ser.h>
static int okC; // FIXME: remove
static int erC;
static void mp1Decode(MP1 *mp1) {
// This decode function is basic and bare minimum.
// It does nothing more than extract the data
@ -42,17 +39,13 @@ void mp1Poll(MP1 *mp1) {
// frame length, which means the flag signifies
// the end of the packet. Pass control to the
// decoder.
// kprintf("Got checksum: %d.\n", mp1->buffer[mp1->packetLength-1]);
if ((mp1->checksum_in & 0xff) == 0x00) {
//kprintf("Correct checksum. Found %d.\n", mp1->buffer[mp1->packetLength-1]);
kprintf("[OK%d] ", okC++);
mp1Decode(mp1);
} else {
// Checksum was incorrect
kprintf("[ER%d] ", erC++);
mp1Decode(mp1);
//kprintf("Incorrect checksum. Found %d, ", mp1->buffer[mp1->packetLength]);
//kprintf("should be %d\n", mp1->checksum_in);
// Checksum was incorrect, we don't do anything,
// but you can enable the decode anyway, if you
// need it for testing or debugging
// mp1Decode(mp1);
}
}
// If the above is not the case, this must be the
@ -60,7 +53,6 @@ void mp1Poll(MP1 *mp1) {
mp1->reading = true;
mp1->packetLength = 0;
mp1->checksum_in = MP1_CHECKSUM_INIT;
//kprintf("Checksum init with %d\n", mp1->checksum_in);
// We have indicated that we are reading,
// and reset the length counter. Now we'll
@ -91,7 +83,6 @@ void mp1Poll(MP1 *mp1) {
// still less than our max length, put the incoming
// byte in the buffer.
if (!mp1->escape) mp1->checksum_in = mp1->checksum_in ^ byte;
//kprintf("Checksum is now %d\n", mp1->checksum_in);
mp1->buffer[mp1->packetLength++] = byte;
} else {
// If not, we have a problem: The buffer has overrun
@ -130,7 +121,6 @@ void mp1Send(MP1 *mp1, const void *_buffer, size_t length) {
// Initialize checksum
mp1->checksum_out = MP1_CHECKSUM_INIT;
//kprintf("Checksum init with %d\n", mp1->checksum_out);
// Transmit the HDLC_FLAG to signify start of TX
kfile_putc(HDLC_FLAG, mp1->modem);
@ -140,12 +130,10 @@ void mp1Send(MP1 *mp1, const void *_buffer, size_t length) {
// output function
while (length--) {
mp1->checksum_out = mp1->checksum_out ^ *buffer;
//kprintf("Checksum is now %d\n", mp1->checksum_out);
mp1Putbyte(mp1, *buffer++);
}
// Write checksum to end of packet
kprintf("Sending packet with checksum %d\n", mp1->checksum_out);
mp1Putbyte(mp1, mp1->checksum_out);
// Transmit a HDLC_FLAG to signify end of TX

View File

@ -1,2 +1,2 @@
#define VERS_BUILD 480
#define VERS_BUILD 529
#define VERS_HOST "vixen"