Now using actual radio hardware in AFSK and SSTV. Tuned Tx settling timers.
This commit is contained in:
		
							parent
							
								
									208087693d
								
							
						
					
					
						commit
						8ebeabe496
					
				
							
								
								
									
										32
									
								
								AFSK.cpp
								
								
								
								
							
							
						
						
									
										32
									
								
								AFSK.cpp
								
								
								
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -194,21 +194,42 @@ bool AFSK::HDLCDecode::hdlcParse(bool bit, SimpleFIFO<uint8_t,HAMSHIELD_AFSK_RX_
 | 
			
		|||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define FASTRING_SIZE 4
 | 
			
		||||
#define FASTRING_MASK (FASTRING_SIZE-1)
 | 
			
		||||
template <typename T, int size>
 | 
			
		||||
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<uint8_t,4> 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);
 | 
			
		||||
  
 | 
			
		||||
  // If we found a 0/1 transition, adjust phases to track
 | 
			
		||||
  if(EDGE_FOUND(sampled_bits)) {
 | 
			
		||||
    if(curr_phase < PHASE_THRES)
 | 
			
		||||
| 
						 | 
				
			
			@ -503,6 +524,7 @@ size_t AFSK::Packet::appendCallsign(const char *callsign, uint8_t ssid, bool fin
 | 
			
		|||
void AFSK::timer() {
 | 
			
		||||
  if(encoder.isSending())
 | 
			
		||||
    encoder.process();
 | 
			
		||||
  else
 | 
			
		||||
    decoder.process(ADCH - 128);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
#define DDS_REFCLK_DEFAULT 9600
 | 
			
		||||
 | 
			
		||||
#include <HamShield.h>
 | 
			
		||||
#include <Wire.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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.txStart()) {
 | 
			
		||||
 | 
			
		||||
    if(radio.afsk.txReady()) {
 | 
			
		||||
      Serial.println(F("txReady"));
 | 
			
		||||
      radio.setModeTransmit();
 | 
			
		||||
      //delay(100);
 | 
			
		||||
      if(radio.afsk.txStart()) {
 | 
			
		||||
        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();
 | 
			
		||||
  if(++tcnt == 1) {
 | 
			
		||||
    if(radio.afsk.encoder.isSending()) {
 | 
			
		||||
      radio.afsk.timer();
 | 
			
		||||
  digitalWrite(2, LOW);
 | 
			
		||||
    }
 | 
			
		||||
    tcnt = 0;
 | 
			
		||||
  }
 | 
			
		||||
  PORTD &= ~(_BV(2)); // Pin D2 off again
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,9 @@
 | 
			
		|||
#define DDS_REFCLK_DEFAULT (34965/2)
 | 
			
		||||
 | 
			
		||||
#include <HamShield.h>
 | 
			
		||||
#include <Wire.h>
 | 
			
		||||
 | 
			
		||||
//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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue