/*
 * AX.25 SIMPLE BEACON
 * ARDUINO DUE + AD9850 DDS
 * v0.03
 */

#include <DueTimer.h>

#define  CLK   6
#define  FQ    7
#define  DATA  8
#define  RST   9
long oFreq = 21390300; //Hz

byte pktBuf[300];
volatile bool trReady;

//dds
void shortPulse (char PIN)
{
        digitalWrite(PIN, 1);
        digitalWrite(PIN, 0);
}

void setFreq(double freq)
{
        //--calculate
        int32_t d_Phase = freq * pow(2, 32) / 125000000;
        //--send first 32bit
        for (int i=0; i<32; i++, d_Phase>>=1)
        {
                if(d_Phase & 1 == 1)
                {
                        digitalWrite(DATA, HIGH); //--data
                }
                else
                {
                        digitalWrite(DATA, LOW); //--data
                }
                shortPulse(CLK);
        }
        //--send rest 8bit
        digitalWrite(DATA, LOW); //--data
        for (int i=0; i<8; i++)
        {
                shortPulse(CLK);
        }
        //--finish
        shortPulse(FQ);
}

void setup() {
        //DDS
        pinMode(CLK, OUTPUT);
        pinMode(FQ, OUTPUT);
        pinMode(DATA, OUTPUT);
        pinMode(RST, OUTPUT);
        //--dds reset
        shortPulse(RST);
        shortPulse(CLK);
        //--change mode
        shortPulse(FQ);
        //--kHz2Hz
        //oFreq = oFreq * 1000;
        
        Timer1.attachInterrupt(timer1_interrupt).start(3333); //833@1200baud 3333@300baud
        
        //buf clear
        for(int i = 0; i < 300; i++)
        {
                pktBuf[i] = 0x00;
        }
        
        //packet
        for(int i = 0; i < 20; i++) //0-19
        {
                pktBuf[i] = 0x7E; //flag
        }
        
        //pre-shifted
        pktBuf[20] = 0xA2; //Q
        pktBuf[21] = 0xA6; //S
        pktBuf[22] = 0xA8; //T
        pktBuf[23] = 0x40; //sp
        pktBuf[24] = 0x40; //sp
        pktBuf[25] = 0x40; //sp
        pktBuf[26] = 0xE0; //-0
        
        //pre-shifted
        pktBuf[27] = 0x94; //J
        pktBuf[28] = 0x92; //I
        pktBuf[29] = 0x66; //3
        pktBuf[30] = 0x84; //B
        pktBuf[31] = 0x9C; //N
        pktBuf[32] = 0x84; //B
        pktBuf[33] = 0x61; //-0
        
        pktBuf[34] = 0x03; //C
        pktBuf[35] = 0xF0; //PID
        
        pktBuf[36] = 0x42; //B
        pktBuf[37] = 0x45; //E
        pktBuf[38] = 0x41; //A
        pktBuf[39] = 0x43; //C
        pktBuf[40] = 0x4F; //O
        pktBuf[41] = 0x4E; //N
        pktBuf[42] = 0x0D; //cr
        
        //pre-calculated
        pktBuf[43] = 0x55; //FCS
        pktBuf[44] = 0x40; //FCS
        
        pktBuf[45] = 0x7E; //flag
        pktBuf[46] = 0x7E;
        pktBuf[47] = 0x7E;
        pktBuf[48] = 0x7E;
        pktBuf[49] = 0x7E;
        
        trReady = true;
}

void timer1_interrupt(void)
{
        static int  bitPos;
        static int  bytePos;
        static bool masked;
        static bool toggle;

        if(trReady)
        {
                if(bitPos == 0)
                {
                        masked = pktBuf[bytePos] & B00000001;
                }
                else if(bitPos == 1)
                {
                        masked = pktBuf[bytePos] & B00000010;
                }
                else if(bitPos == 2)
                {
                        masked = pktBuf[bytePos] & B00000100;
                }
                else if(bitPos == 3)
                {
                        masked = pktBuf[bytePos] & B00001000;
                }
                else if(bitPos == 4)
                {
                        masked = pktBuf[bytePos] & B00010000;
                }
                else if(bitPos == 5)
                {
                        masked = pktBuf[bytePos] & B00100000;
                }
                else if(bitPos == 6)
                {
                        masked = pktBuf[bytePos] & B01000000;
                }
                else if(bitPos == 7)
                {
                        masked = pktBuf[bytePos] & B10000000;
                }
                
                if(masked == false) //0>>FLIP
                {
                        toggle = toggle ^ 1;
                        if(toggle)
                        {
                                setFreq(oFreq + 200);
                        }
                        else
                        {
                                setFreq(oFreq);
                        }
                }
                
                bitPos++;
                if(bitPos == 8)
                {
                        bitPos = 0;
                        bytePos++;
                        if(bytePos == 50)
                        {
                                bytePos = 0;
                                setFreq(2); //mute
                                trReady = false;
                        }
                }
        }
}

void loop() {
        if(trReady == false)
        {
                for(int i = 0; i < 10; i++) //interval
                {
                        delay(1000);
                }
                setFreq(oFreq);
                trReady = true;
        }
        delay(5);
}