/*************************************************************************
 *
 * nastaveni syntezy s SAA1057
 *
 * (c) Ales Povalac, alpov@alpov.net, http://www.alpov.net/
 *
 *************************************************************************/


#include <avr/io.h>
#include <util/delay.h>

#define CLB     _BV(PD4)
#define DLEN    _BV(PD5)
#define DATA    _BV(PD6)

#define BTN     _BV(PD2)

#define DATA_WORD_A     0
#define DATA_WORD_B     _BV(15)
#define FM              _BV(14)
#define REFH            _BV(13)
#define CP3             _BV(12)
#define CP2             _BV(11)
#define CP1             _BV(10)
#define CP0             _BV(9)
#define SB2             _BV(8)
#define SLA             _BV(7)
#define PDM1            _BV(6)
#define PDM0            _BV(5)
#define BRM             _BV(4)
#define T3              _BV(3)
#define T2              _BV(2)
#define T1              _BV(1)
#define T0              _BV(0)

#define TUNING_WORD(x)  (x / 12500)

void delay(void)
{
    _delay_us(10);
}


void wait4key(void)
{
    while ((PIND & BTN)) {}
    _delay_ms(50);
    while (!(PIND & BTN)) {}
    _delay_ms(50);
}


void send_saa1057(unsigned int data)
{
    PORTD |= DLEN;
    delay();
    PORTD |= CLB;
    delay();
    PORTD &= ~CLB;
    delay();
    for (int i = 0; i < 16; i++) {
        if (data & 0x8000)
            PORTD |= DATA;
        else
            PORTD &= ~DATA;
        data <<= 1;
        delay();
        PORTD |= CLB;
        delay();
        PORTD &= ~CLB;
        delay();
    }
    PORTD &= ~DATA;
    delay();
    PORTD &= ~DLEN;
    delay();
    PORTD |= CLB;
    delay();
    PORTD &= ~CLB;
    delay();
    _delay_ms(50);
}


int main(void)
{
    DDRD |= CLB | DLEN | DATA;
    PORTD |= CLB | BTN;
    _delay_ms(10);
    for (int i = 0; i < 10; i++) {
        PORTD &= ~CLB;
        delay();
        PORTD |= CLB;
        delay();
    }
    _delay_ms(10);

    send_saa1057(DATA_WORD_B | FM | REFH);

    while (1) {
        send_saa1057(DATA_WORD_A | TUNING_WORD(155775000)); // 166.475 - 10.7 MHz
        wait4key();
        send_saa1057(DATA_WORD_A | TUNING_WORD(134775000)); // 145.475 - 10.7 MHz, radioamateri
        wait4key();
        send_saa1057(DATA_WORD_A | TUNING_WORD(130000000)); // 130.000 MHz, testovaci
        wait4key();
    }
}
