diff --git a/AFSK.cpp b/AFSK.cpp index b56363e..49ed68c 100644 --- a/AFSK.cpp +++ b/AFSK.cpp @@ -50,29 +50,29 @@ void AFSK::Encoder::process() { lastTxEnd = millis(); return; } - lastTx = millis(); - currentBytePos = 0; - } + lastTx = millis(); + currentBytePos = 0; + } - // We ran out of actual data, provide an HDLC frame (idle) - if(currentBytePos++ == packet->len) { - pBuf.freePacket(packet); - packet = pBuf.getPacket(); // Get the next, if any - currentBytePos = 0; - currentByte = HDLC_FRAME; - hdlc = true; - } else { - // Grab the next byte - currentByte = packet->getByte(); //[currentBytePos++]; - if(currentByte == HDLC_ESCAPE) { - currentByte = packet->getByte(); //[currentBytePos++]; + // We ran out of actual data, provide an HDLC frame (idle) + if(currentBytePos++ == packet->len) { + pBuf.freePacket(packet); + packet = pBuf.getPacket(); // Get the next, if any + currentBytePos = 0; + currentByte = HDLC_FRAME; hdlc = true; } else { - hdlc = false; + // Grab the next byte + currentByte = packet->getByte(); //[currentBytePos++]; + if(currentByte == HDLC_ESCAPE) { + currentByte = packet->getByte(); //[currentBytePos++]; + hdlc = true; + } else { + hdlc = false; + } } } } - } // Pickup the last bit currentBit = currentByte & 0x1; @@ -121,7 +121,7 @@ bool AFSK::Encoder::start() { lastZero = 0; bitPosition = 0; bitClock = 0; - preamble = 23; // 6.7ms each, 23 = 153ms + preamble = 0b11000; // 6.7ms each, 23 = 153ms done = false; hdlc = true; packet = 0x0; // No initial packet, find in the ISR @@ -143,7 +143,7 @@ void AFSK::Encoder::stop() { AFSK::Decoder::Decoder() { // Initialize the sampler delay line (phase shift) for(unsigned char i = 0; i < SAMPLEPERBIT/2; i++) - delay_fifo.enqueue(0); + delay_fifo.enqueue(0); } bool AFSK::HDLCDecode::hdlcParse(bool bit, SimpleFIFO *fifo) { @@ -193,21 +193,42 @@ bool AFSK::HDLCDecode::hdlcParse(bool bit, SimpleFIFO +class FastRing { +private: + T ring[FASTRING_SIZE]; + uint8_t position; +public: + FastRing(): position(0) {} + inline void write(T value) { + ring[(position++) & FASTRING_MASK] = value; + } + inline T read() const { + return ring[position & FASTRING_MASK]; + } + inline T readn(uint8_t n) const { + return ring[(position + (~n+1)) & FASTRING_MASK]; + } +}; +FastRing delayLine; + // Handle the A/D converter interrupt (hopefully quickly :) void AFSK::Decoder::process(int8_t curr_sample) { // Run the same through the phase multiplier and butterworth filter iir_x[0] = iir_x[1]; - iir_x[1] = ((int8_t)delay_fifo.dequeue() * curr_sample) >> 2; + iir_x[1] = ((int8_t)delayLine.read() * curr_sample) >> 2; iir_y[0] = iir_y[1]; iir_y[1] = iir_x[0] + iir_x[1] + (iir_y[0] >> 1) + (iir_y[0]>>3) + (iir_y[0]>>5); + // Place this ADC sample into the delay line + delayLine.write(curr_sample); + // Shift the bit into place based on the output of the discriminator sampled_bits <<= 1; - sampled_bits |= (iir_y[1] > 0) ? 1 : 0; - - // Place this ADC sample into the delay line - delay_fifo.enqueue(curr_sample); + sampled_bits |= (iir_y[1] > 0) ? 1 : 0; // If we found a 0/1 transition, adjust phases to track if(EDGE_FOUND(sampled_bits)) { @@ -503,7 +524,8 @@ size_t AFSK::Packet::appendCallsign(const char *callsign, uint8_t ssid, bool fin void AFSK::timer() { if(encoder.isSending()) encoder.process(); - decoder.process(ADCH - 128); + else + decoder.process(ADCH - 128); } void AFSK::start(DDS *dds) { diff --git a/examples/AFSK-Send/AFSK-Send.ino b/examples/AFSK-Send/AFSK-Send.ino index 104d39c..063c0cb 100644 --- a/examples/AFSK-Send/AFSK-Send.ino +++ b/examples/AFSK-Send/AFSK-Send.ino @@ -1,3 +1,5 @@ +#define DDS_REFCLK_DEFAULT 9600 + #include #include @@ -6,25 +8,29 @@ DDS dds; void setup() { Serial.begin(9600); - // put your setup code here, to run once: + Wire.begin(); pinMode(2, OUTPUT); - pinMode(10, OUTPUT); pinMode(3, OUTPUT); - pinMode(11, OUTPUT); - digitalWrite(2, LOW); - digitalWrite(10, LOW); Serial.println(F("Radio test connection")); - radio.testConnection(); + Serial.println(radio.testConnection(), DEC); Serial.println(F("Initialize")); + delay(100); radio.initialize(); Serial.println(F("Frequency")); - radio.frequency(446000); + delay(100); + radio.setVHF(); + radio.frequency(145050); + radio.setRfPower(0); Serial.println(F("DDS Start")); + delay(100); dds.start(); Serial.println(F("AFSK start")); + delay(100); radio.afsk.start(&dds); Serial.println(F("Starting...")); + pinMode(11, INPUT); // Bodge for now, as pin 3 is hotwired to pin 11 + delay(100); } void loop() { @@ -35,26 +41,34 @@ void loop() { packet->appendCallsign("VA6GA",15,true); packet->appendFCS(0x03); packet->appendFCS(0xf0); - packet->print("Hello "); + packet->print(F("Hello ")); packet->println(millis()); packet->finish(); bool ret = radio.afsk.putTXPacket(packet); - if(radio.afsk.txReady()) + + if(radio.afsk.txReady()) { + Serial.println(F("txReady")); + radio.setModeTransmit(); + //delay(100); if(radio.afsk.txStart()) { - radio.setModeTransmit(); + Serial.println(F("txStart")); + } else { + radio.setModeReceive(); } + } // Wait 2 seconds before we send our beacon again. Serial.println("tick"); // Wait up to 2.5 seconds to finish sending, and stop transmitter. // TODO: This is hackery. for(int i = 0; i < 500; i++) { - if(!radio.afsk.encoder.isSending()) + if(radio.afsk.encoder.isDone()) break; delay(50); } + Serial.println("Done sending"); radio.setModeReceive(); - delay(2000); + delay(30000); } /*ISR(TIMER2_OVF_vect) { @@ -68,10 +82,16 @@ void loop() { } }*/ ISR(ADC_vect) { + static uint8_t tcnt = 0; TIFR1 = _BV(ICF1); // Clear the timer flag - digitalWrite(2, HIGH); + PORTD |= _BV(2); // Diagnostic pin (D2) dds.clockTick(); - radio.afsk.timer(); - digitalWrite(2, LOW); + if(++tcnt == 1) { + if(radio.afsk.encoder.isSending()) { + radio.afsk.timer(); + } + tcnt = 0; + } + PORTD &= ~(_BV(2)); // Pin D2 off again } diff --git a/examples/SSTV-M1-Static/SSTV-M1-Static.ino b/examples/SSTV-M1-Static/SSTV-M1-Static.ino index 4a7e9e6..a86b757 100644 --- a/examples/SSTV-M1-Static/SSTV-M1-Static.ino +++ b/examples/SSTV-M1-Static/SSTV-M1-Static.ino @@ -2,8 +2,9 @@ #define DDS_REFCLK_DEFAULT (34965/2) #include +#include -//HamShield radio; +HamShield radio; DDS dds; // Defined at the end of the sketch extern const uint16_t image[256*20] PROGMEM; @@ -15,8 +16,21 @@ ddsAccumulator_t freqTable[3]; void setup() { Serial.begin(9600); + Wire.begin(); + // Query the HamShield for status information + Serial.print("Radio status: "); + int result = 0; + result = radio.testConnection(); + Serial.println(result,DEC); + + // Tell the HamShield to start up + radio.initialize(); + radio.setRfPower(0); + radio.setVHF(); + radio.setFrequency(145500); pinMode(2, OUTPUT); pinMode(3, OUTPUT); + pinMode(11, INPUT); // HiZ // put your setup code here, to run once: //dds.setReferenceClock(34965/4); dds.start(); @@ -71,7 +85,8 @@ void loadScanline(uint8_t s, int y) { void loop() { // Load the first scanline loadScanline(0, 0); - + radio.setModeTransmit(); + delay(500); // VIS dds.playWait(1900,300); dds.playWait(1200,10); @@ -110,6 +125,7 @@ void loop() { } } dds.off(); + radio.setModeReceive(); delay(10000); return; }