Updated AFSK with print routine, use new delay line. AX25 receive tune to APRS.
This commit is contained in:
		
							parent
							
								
									888cf9d9fd
								
							
						
					
					
						commit
						cf93050e52
					
				
							
								
								
									
										44
									
								
								AFSK.cpp
								
								
								
								
							
							
						
						
									
										44
									
								
								AFSK.cpp
								
								
								
								
							| 
						 | 
					@ -194,26 +194,25 @@ bool AFSK::HDLCDecode::hdlcParse(bool bit, SimpleFIFO<uint8_t,HAMSHIELD_AFSK_RX_
 | 
				
			||||||
  return ret;
 | 
					  return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FASTRING_SIZE 4
 | 
					 | 
				
			||||||
#define FASTRING_MASK (FASTRING_SIZE-1)
 | 
					 | 
				
			||||||
template <typename T, int size>
 | 
					template <typename T, int size>
 | 
				
			||||||
class FastRing {
 | 
					class FastRing {
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  T ring[FASTRING_SIZE];
 | 
					  T ring[size];
 | 
				
			||||||
  uint8_t position;
 | 
					  uint8_t position;
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  FastRing(): position(0) {}
 | 
					  FastRing(): position(0) {}
 | 
				
			||||||
  inline void write(T value) {
 | 
					  inline void write(T value) {
 | 
				
			||||||
    ring[(position++) & FASTRING_MASK] = value;
 | 
					    ring[(position++) & (size-1)] = value;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  inline T read() const {
 | 
					  inline T read() const {
 | 
				
			||||||
    return ring[position & FASTRING_MASK];
 | 
					    return ring[position & (size-1)];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  inline T readn(uint8_t n) const {
 | 
					  inline T readn(uint8_t n) const {
 | 
				
			||||||
    return ring[(position + (~n+1)) & FASTRING_MASK];
 | 
					    return ring[(position + (~n+1)) & (size-1)];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
FastRing<uint8_t,4> delayLine;
 | 
					// Create a delay line that's half the length of the bit cycle (-90 degrees)
 | 
				
			||||||
 | 
					FastRing<uint8_t,(T_BIT/2)> delayLine;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Handle the A/D converter interrupt (hopefully quickly :)
 | 
					// Handle the A/D converter interrupt (hopefully quickly :)
 | 
				
			||||||
void AFSK::Decoder::process(int8_t curr_sample) {
 | 
					void AFSK::Decoder::process(int8_t curr_sample) {
 | 
				
			||||||
| 
						 | 
					@ -269,7 +268,6 @@ bool AFSK::Decoder::read() {
 | 
				
			||||||
  while(rx_fifo.count()) {
 | 
					  while(rx_fifo.count()) {
 | 
				
			||||||
    // Grab the character
 | 
					    // Grab the character
 | 
				
			||||||
    char c = rx_fifo.dequeue();
 | 
					    char c = rx_fifo.dequeue();
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    bool escaped = false;
 | 
					    bool escaped = false;
 | 
				
			||||||
    if(c == HDLC_ESCAPE) { // We received an escaped byte, mark it
 | 
					    if(c == HDLC_ESCAPE) { // We received an escaped byte, mark it
 | 
				
			||||||
      escaped = true;
 | 
					      escaped = true;
 | 
				
			||||||
| 
						 | 
					@ -312,10 +310,10 @@ bool AFSK::Decoder::read() {
 | 
				
			||||||
              if((currentPacket->getByte() & 0x1) == 0x1) { // Found a byte with LSB set
 | 
					              if((currentPacket->getByte() & 0x1) == 0x1) { // Found a byte with LSB set
 | 
				
			||||||
                // which marks the final address payload
 | 
					                // which marks the final address payload
 | 
				
			||||||
                // next two bytes should be the control/PID
 | 
					                // next two bytes should be the control/PID
 | 
				
			||||||
                if(currentPacket->getByte() == 0x03 && currentPacket->getByte() == 0xf0) {
 | 
					                //if(currentPacket->getByte() == 0x03 && currentPacket->getByte() == 0xf0) {
 | 
				
			||||||
                  filtered = true;
 | 
					                  filtered = true;
 | 
				
			||||||
                  break; // Found it
 | 
					                  break; // Found it
 | 
				
			||||||
                }
 | 
					                //}
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
| 
						 | 
					@ -520,12 +518,36 @@ size_t AFSK::Packet::appendCallsign(const char *callsign, uint8_t ssid, bool fin
 | 
				
			||||||
  appendFCS(ssidField);
 | 
					  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; i<len; i++) {
 | 
				
			||||||
 | 
					    s->write(*(dataPtr+i));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Determine what we want to do on this ADC tick.
 | 
					// Determine what we want to do on this ADC tick.
 | 
				
			||||||
void AFSK::timer() {
 | 
					void AFSK::timer() {
 | 
				
			||||||
  if(encoder.isSending())
 | 
					  if(encoder.isSending())
 | 
				
			||||||
    encoder.process();
 | 
					    encoder.process();
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    decoder.process(ADCH - 128);
 | 
					    decoder.process(((int8_t)(ADCH - 128)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AFSK::start(DDS *dds) {
 | 
					void AFSK::start(DDS *dds) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								AFSK.h
								
								
								
								
							
							
						
						
									
										2
									
								
								AFSK.h
								
								
								
								
							| 
						 | 
					@ -111,6 +111,8 @@ public:
 | 
				
			||||||
    inline bool crcOK() {
 | 
					    inline bool crcOK() {
 | 
				
			||||||
      return (fcs == 0xF0B8);
 | 
					      return (fcs == 0xF0B8);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    void print(Stream *s);
 | 
				
			||||||
  private:
 | 
					  private:
 | 
				
			||||||
#ifdef PACKET_PREALLOCATE
 | 
					#ifdef PACKET_PREALLOCATE
 | 
				
			||||||
    uint8_t dataPtr[128];
 | 
					    uint8_t dataPtr[128];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,29 +2,44 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <HamShield.h>
 | 
					#include <HamShield.h>
 | 
				
			||||||
#include <Wire.h>
 | 
					#include <Wire.h>
 | 
				
			||||||
 | 
					//#include <LiquidCrystal_I2C.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//LiquidCrystal_I2C lcd(0x27,16,2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HamShield radio;
 | 
					HamShield radio;
 | 
				
			||||||
DDS dds;
 | 
					DDS dds;
 | 
				
			||||||
 | 
					volatile uint8_t adcMax=0, adcMin=255;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setup() {
 | 
					void setup() {
 | 
				
			||||||
  Serial.begin(9600);
 | 
					  Serial.begin(9600);
 | 
				
			||||||
  Wire.begin();
 | 
					  Wire.begin();
 | 
				
			||||||
  pinMode(2, OUTPUT);
 | 
					  pinMode(2, OUTPUT);
 | 
				
			||||||
  pinMode(3, 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(F("Radio test connection"));
 | 
				
			||||||
  Serial.println(radio.testConnection(), DEC);
 | 
					  Serial.println(radio.testConnection(), DEC);
 | 
				
			||||||
  Serial.println(F("Initialize"));
 | 
					  Serial.println(F("Initialize"));
 | 
				
			||||||
  delay(100);
 | 
					  delay(100);
 | 
				
			||||||
  radio.initialize();
 | 
					  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"));
 | 
					  Serial.println(F("Frequency"));
 | 
				
			||||||
  delay(100);
 | 
					  delay(100);
 | 
				
			||||||
//  radio.setVHF();
 | 
					  Serial.print(F("Squelch(H/L): "));
 | 
				
			||||||
//  radio.setRfPower(0);
 | 
					  Serial.print(radio.getSQHiThresh());
 | 
				
			||||||
//  radio.setModeReceive();
 | 
					  Serial.print(F(" / "));
 | 
				
			||||||
  radio.setVolume1(0xFF);
 | 
					  Serial.println(radio.getSQLoThresh());
 | 
				
			||||||
  radio.setVolume2(0xFF);
 | 
					  radio.setModeReceive();
 | 
				
			||||||
  radio.frequency(145050);
 | 
					  Serial.print(F("RX? "));
 | 
				
			||||||
 | 
					  Serial.println(radio.getRX());
 | 
				
			||||||
  Serial.println(F("DDS Start"));
 | 
					  Serial.println(F("DDS Start"));
 | 
				
			||||||
  delay(100);
 | 
					  delay(100);
 | 
				
			||||||
  dds.start();
 | 
					  dds.start();
 | 
				
			||||||
| 
						 | 
					@ -35,26 +50,38 @@ void setup() {
 | 
				
			||||||
  pinMode(11, INPUT); // Bodge for now, as pin 3 is hotwired to pin 11
 | 
					  pinMode(11, INPUT); // Bodge for now, as pin 3 is hotwired to pin 11
 | 
				
			||||||
  delay(100);
 | 
					  delay(100);
 | 
				
			||||||
  dds.setAmplitude(255);
 | 
					  dds.setAmplitude(255);
 | 
				
			||||||
 | 
					  //lcd.backlight();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t last = 0;
 | 
					uint32_t last = 0;
 | 
				
			||||||
void loop() {
 | 
					void loop() {
 | 
				
			||||||
   if(radio.afsk.decoder.read() || radio.afsk.rxPacketCount()) {
 | 
					   if(radio.afsk.decoder.read() || radio.afsk.rxPacketCount()) {
 | 
				
			||||||
      // A true return means something was put onto the packet FIFO
 | 
					      // 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
 | 
					      // If we actually have data packets in the buffer, process them all now
 | 
				
			||||||
      while(radio.afsk.rxPacketCount()) {
 | 
					      while(radio.afsk.rxPacketCount()) {
 | 
				
			||||||
        AFSK::Packet *packet = radio.afsk.getRXPacket();
 | 
					        AFSK::Packet *packet = radio.afsk.getRXPacket();
 | 
				
			||||||
 | 
					        Serial.print(F("Packet: "));
 | 
				
			||||||
        if(packet) {
 | 
					        if(packet) {
 | 
				
			||||||
          for(unsigned short i = 0; i < packet->len; ++i)
 | 
					          packet->print(&Serial);
 | 
				
			||||||
            Serial.write((uint8_t)packet->getByte());
 | 
					 | 
				
			||||||
          AFSK::PacketBuffer::freePacket(packet);
 | 
					          AFSK::PacketBuffer::freePacket(packet);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      Serial.println("");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /*if(last < millis()) {
 | 
					/*    if(last < millis()) {
 | 
				
			||||||
      Serial.println(radio.readRSSI());
 | 
					      uint16_t buf;
 | 
				
			||||||
      last = millis()+1000;
 | 
					      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)
 | 
					  PORTD |= _BV(2); // Diagnostic pin (D2)
 | 
				
			||||||
  //dds.clockTick();
 | 
					  //dds.clockTick();
 | 
				
			||||||
  radio.afsk.timer();
 | 
					  radio.afsk.timer();
 | 
				
			||||||
 | 
					  if(ADCH>adcMax) {
 | 
				
			||||||
 | 
					    adcMax = ADCH;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(ADCH<adcMin) {
 | 
				
			||||||
 | 
					    adcMin = ADCH;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  PORTD &= ~(_BV(2)); // Pin D2 off again
 | 
					  PORTD &= ~(_BV(2)); // Pin D2 off again
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue