From cf93050e52ebf61b7266e1e4940416c311015156 Mon Sep 17 00:00:00 2001 From: Stephen Olesen Date: Fri, 10 Jul 2015 11:58:37 -0600 Subject: [PATCH] Updated AFSK with print routine, use new delay line. AX25 receive tune to APRS. --- AFSK.cpp | 44 +++++++++++++++------ AFSK.h | 2 + examples/AX25Receive/AX25Receive.ino | 59 ++++++++++++++++++++++------ 3 files changed, 81 insertions(+), 24 deletions(-) diff --git a/AFSK.cpp b/AFSK.cpp index 4bf18b1..26ebbd2 100644 --- a/AFSK.cpp +++ b/AFSK.cpp @@ -194,26 +194,25 @@ bool AFSK::HDLCDecode::hdlcParse(bool bit, SimpleFIFO class FastRing { private: - T ring[FASTRING_SIZE]; + T ring[size]; uint8_t position; public: FastRing(): position(0) {} inline void write(T value) { - ring[(position++) & FASTRING_MASK] = value; + ring[(position++) & (size-1)] = value; } inline T read() const { - return ring[position & FASTRING_MASK]; + return ring[position & (size-1)]; } inline T readn(uint8_t n) const { - return ring[(position + (~n+1)) & FASTRING_MASK]; + return ring[(position + (~n+1)) & (size-1)]; } }; -FastRing delayLine; +// Create a delay line that's half the length of the bit cycle (-90 degrees) +FastRing delayLine; // Handle the A/D converter interrupt (hopefully quickly :) void AFSK::Decoder::process(int8_t curr_sample) { @@ -269,7 +268,6 @@ bool AFSK::Decoder::read() { while(rx_fifo.count()) { // Grab the character char c = rx_fifo.dequeue(); - bool escaped = false; if(c == HDLC_ESCAPE) { // We received an escaped byte, mark it escaped = true; @@ -312,10 +310,10 @@ bool AFSK::Decoder::read() { if((currentPacket->getByte() & 0x1) == 0x1) { // Found a byte with LSB set // which marks the final address payload // next two bytes should be the control/PID - if(currentPacket->getByte() == 0x03 && currentPacket->getByte() == 0xf0) { + //if(currentPacket->getByte() == 0x03 && currentPacket->getByte() == 0xf0) { filtered = true; break; // Found it - } + //} } } @@ -520,12 +518,36 @@ size_t AFSK::Packet::appendCallsign(const char *callsign, uint8_t ssid, bool fin appendFCS(ssidField); } +void AFSK::Packet::print(Stream *s) { + uint8_t i; + // Second 6 bytes are source callsign + for(i=7; i<13; i++) { + s->write(*(dataPtr+i)>>1); + } + // SSID + s->write('-'); + s->print((*(dataPtr+13) >> 1) & 0xF); + s->print(" -> "); + // First 6 bytes are destination callsign + for(i=0; i<6; i++) { + s->write(*(dataPtr+i)>>1); + } + // SSID + s->write('-'); + s->print((*(dataPtr+6) >> 1) & 0xF); + // Control/PID next two bytes + // Skip those, print payload + for(i = 15; iwrite(*(dataPtr+i)); + } +} + // Determine what we want to do on this ADC tick. void AFSK::timer() { if(encoder.isSending()) encoder.process(); else - decoder.process(ADCH - 128); + decoder.process(((int8_t)(ADCH - 128))); } void AFSK::start(DDS *dds) { diff --git a/AFSK.h b/AFSK.h index 1f8b860..68504e7 100644 --- a/AFSK.h +++ b/AFSK.h @@ -111,6 +111,8 @@ public: inline bool crcOK() { return (fcs == 0xF0B8); } + + void print(Stream *s); private: #ifdef PACKET_PREALLOCATE uint8_t dataPtr[128]; diff --git a/examples/AX25Receive/AX25Receive.ino b/examples/AX25Receive/AX25Receive.ino index 4f4efca..c16576d 100644 --- a/examples/AX25Receive/AX25Receive.ino +++ b/examples/AX25Receive/AX25Receive.ino @@ -2,29 +2,44 @@ #include #include +//#include + +//LiquidCrystal_I2C lcd(0x27,16,2); HamShield radio; DDS dds; +volatile uint8_t adcMax=0, adcMin=255; void setup() { Serial.begin(9600); Wire.begin(); pinMode(2, OUTPUT); pinMode(3, OUTPUT); - + /*lcd.init(); + lcd.setCursor(0,0); + lcd.print(F("RSSI:")); + lcd.setCursor(0,1); + lcd.print(F("ADC:"));*/ Serial.println(F("Radio test connection")); Serial.println(radio.testConnection(), DEC); Serial.println(F("Initialize")); delay(100); radio.initialize(); + radio.frequency(144390); + radio.setVHF(); + radio.setSQOff(); + I2Cdev::writeWord(A1846S_DEV_ADDR_SENLOW, 0x30, 0x06); + I2Cdev::writeWord(A1846S_DEV_ADDR_SENLOW, 0x30, 0x26); + I2Cdev::writeWord(A1846S_DEV_ADDR_SENLOW, 0x44, 0b11111111); Serial.println(F("Frequency")); delay(100); -// radio.setVHF(); -// radio.setRfPower(0); -// radio.setModeReceive(); - radio.setVolume1(0xFF); - radio.setVolume2(0xFF); - radio.frequency(145050); + Serial.print(F("Squelch(H/L): ")); + Serial.print(radio.getSQHiThresh()); + Serial.print(F(" / ")); + Serial.println(radio.getSQLoThresh()); + radio.setModeReceive(); + Serial.print(F("RX? ")); + Serial.println(radio.getRX()); Serial.println(F("DDS Start")); delay(100); dds.start(); @@ -35,26 +50,38 @@ void setup() { pinMode(11, INPUT); // Bodge for now, as pin 3 is hotwired to pin 11 delay(100); dds.setAmplitude(255); + //lcd.backlight(); } uint32_t last = 0; void loop() { if(radio.afsk.decoder.read() || radio.afsk.rxPacketCount()) { // A true return means something was put onto the packet FIFO - Serial.println("Packet"); // If we actually have data packets in the buffer, process them all now while(radio.afsk.rxPacketCount()) { AFSK::Packet *packet = radio.afsk.getRXPacket(); + Serial.print(F("Packet: ")); if(packet) { - for(unsigned short i = 0; i < packet->len; ++i) - Serial.write((uint8_t)packet->getByte()); + packet->print(&Serial); AFSK::PacketBuffer::freePacket(packet); } } + Serial.println(""); } - /*if(last < millis()) { - Serial.println(radio.readRSSI()); - last = millis()+1000; +/* if(last < millis()) { + uint16_t buf; + lcd.setCursor(6,0); + lcd.print(radio.readRSSI()); + lcd.print(F(" ")); + lcd.setCursor(6,1); + lcd.print(adcMax); + lcd.print(F(" / ")); + lcd.print(adcMin); + lcd.print(F(" ")); + lcd.setCursor(11,0); + lcd.print(radio.afsk.decoder.isReceiving()); + adcMin=255; adcMax=0; + last = millis()+100; }*/ } @@ -74,6 +101,12 @@ ISR(ADC_vect) { PORTD |= _BV(2); // Diagnostic pin (D2) //dds.clockTick(); radio.afsk.timer(); + if(ADCH>adcMax) { + adcMax = ADCH; + } + if(ADCH