/*
  Main

  De software voor Gullinbursti, een pulsgenerator

  Pros 2007 - 2008
*/



#include "Main.h"

// We zouden voor een hogere frequentie kunnen kiezen, maar dan krijgen we te maken met jitter.
#define DDS_DEFAULT_FREQ 8333333.33
#define MAX_F (DDS_DEFAULT_FREQ / 65535.0)

// De werkelijke DDS-frequentie kan varieren tussen 10 en 20MHz, maar wij werken met de helft daarvan,
// omdat het DDS-signaal door 2 gedeeld wordt door een 74HC74. 5 ... 10MHz, dus
// De max frequentie die Madwizard kan voortbrengen bedraagt bijgevolg 2.5MHz ... 5MHz (Madwizard_maxcount = 1;)
// Minimum is 0.001Hz
// Zonder prescaler kan Madwizard zijn systeem-frequentie ten hoogste delen door 65535
// Hoe hoger dat deeltal, hoe groter de puls/pauze-verhouding kan zijn.

void set_freq(double freqdouble DDS_FREQ)
{
    double tmpprescaler_val;

    PORTA = 0xFF;                                               // Doolittle-adres = 7 = GAL blokkeren
    cbi(SHIFTPORTMW_RST);                                     // Madwizard uitschakelen
    DDS_deler = 1.0;
    if (freq == 0.0) {                                          // Stoppen?
        display_ALL();                                          // Toon de instellingen
        return;
    } else if (freq > 10000000.00) {                            // 10MHz is het maximum
        freq = 10000000.00;
        OutputFrequency = 10000000.00;
        DDS_frequency = freq;
        set_DDS(DDS_frequency);                                 // DDS-frequentie instellen
        PORTA = ADR3;                                           // Doolittle: DDS-clk / 2
        display_ALL();                                          // Toon de instellingen
        DDS_deler = 1.0;
        return;
    } else if (freq > 5000000.00) {                             // Meer dan 5MHz
        DDS_frequency = freq;
        set_DDS(DDS_frequency);                                 // DDS-frequentie instellen
        PORTA = ADR3;                                           // Doolittle: DDS-clk / 2
        display_ALL();                                          // Toon de instellingen
        DDS_deler = 1.0;
        return;
    } else if (freq > 2000000.00) {                             // Meer dan 2MHz; 
        // Madwizard kan deze frequenties niet aan, maar we kunnen Doolittle inzetten
        if (pulsbreedte < 30.0) {
            DDS_frequency = freq * 2.0;
            set_DDS(DDS_frequency);                             // DDS-frequentie instellen
            PORTA = ADR4;                                       // Doolittle: DDS-clk / 4
            DDS_deler = 2.0;
        } else if (pulsbreedte > 70.0) {
            DDS_frequency = freq * 2.0;
            set_DDS(DDS_frequency);                             // DDS-frequentie instellen
            PORTA = ADR5;                                       // Doolittle: DDS-clk / 4
            DDS_deler = 2.0;
        } else {
            DDS_frequency = freq;
            set_DDS(DDS_frequency);                             // DDS-frequentie instellen
            PORTA = ADR3;                                       // Doolittle: DDS-clk / 2
            DDS_deler = 1.0;
        }
        display_ALL();                                          // Toon de instellingen
        return;
    } else if (freq > MAX_F) {                                  // Voorbeeld: 12345
        Madwizard_prescaler = 1;                                // Geen prescaler nodig
        tmp = DDS_FREQ / freq;                                  // Madwizard_maxcount = 6250000 / 12345 = 506.277845281490482
        Madwizard_maxcount = (unsigned inttmp;                // Madwizard_maxcount = 506
        DDS_frequency = ((doubleMadwizard_maxcount) * freq;   // DDS_frequency = (12345 * 506) = 6246570
        DDS_deler = (doubleMadwizard_maxcount;
    } else {                                                    // Eerst prescaler berekenen: 8, 64, 256 of 1024
        prescaler_val = 1.0;
        if ((freq * 8.0) > MAX_F) {
            Madwizard_prescaler = 2;
            freq *= 8.0;                                        // freq aanpassen aan prescaler
            prescaler_val = 8.0;
        } else if ((freq * 64.0) > MAX_F) {
            Madwizard_prescaler = 3;
            freq *= 64.0;
            prescaler_val = 64.0;
        } else if ((freq * 256.0) > MAX_F) {                    // Max. 0.488Hz
            Madwizard_prescaler = 4;
            freq *= 256.0;
            prescaler_val = 256.0;
        } else if ((freq * 1024.0) > MAX_F) {                   // Max. 0.119Hz
            Madwizard_prescaler = 5;
            freq *= 1024.0;
            prescaler_val = 1024.0;
        } else {                                                // frequentie lager dan 0.119Hz, bv. 0.005
            Madwizard_prescaler = 5;
            prescaler_val = 1024.0;
            freq *= 1024.0;                                     // freq = 1.024 * 0.005 = 5.12
            Madwizard_maxcount = 65535;
            DDS_frequency = 65535.0 * freq;                     // 65535 * 5.12 = 335544.32
            DDS_deler = ((doubleMadwizard_maxcount) * prescaler_val;
            goto calc_done;
        }
        tmp = DDS_FREQ / freq;
        Madwizard_maxcount = (unsigned inttmp;
        DDS_frequency = ((doubleMadwizard_maxcount) * freq;
        DDS_deler = ((doubleMadwizard_maxcount) * prescaler_val;
    }
  calc_done:
    set_DDS(DDS_frequency);                                     // DDS-frequentie instellen
    delay_ms(20);                                               // Even wachten
    sbi(SHIFTPORTMW_RST);                                     // Madwizard terug inschakelen
    delay_ms(500);                                              // Even wachten
    shift2MW(PRESCMadwizard_prescaler);                       // Stel Madwizard's prescaler in
    shift2MW(PWM1);                                           // Pulsbreedte = klein, anders protesteert MW
    tmp = pulsbreedte;                                          // Vb. 2.4
    tmp *= (doubleMadwizard_maxcount;                         // Vb 2.4 * 888 = 2131.2
    tmp /= 100.0;                                               // 21.312
    Madwizard_ocr1b = (unsigned int) (tmp + 0.5);               // 21.812 -> 21
    if (Madwizard_ocr1b > (Madwizard_maxcount - 1)) {
        Madwizard_ocr1b = Madwizard_maxcount - 1;
    } else if (Madwizard_ocr1b < 1) {
        Madwizard_ocr1b = 1;
    }
    Madwizard_ocr1b--;
    shift2MW(MAXCNTMadwizard_maxcount - 1);                   // Stel Madwizard's ICR1 in
    shift2MW(PWMMadwizard_ocr1b);                             // Stel nu pas de juiste pulsbreedte in
    delay_ms(100);                                              // Even wachten tot Madwizard klaar is
    PORTA &= 0xF8;                                              // Doolittle-adres = 0 = Madwizard doorgeven
    display_ALL();                                              // Toon de instellingen
}


// We wijzigen enkel de DDS-frequentie
void change_freq(double freqdouble DDS_FREQ)
{
    double tmp;

    //PORTA = 0xFF; // Doolittle-adres = 7 = GAL blokkeren
    //cbi(SHIFTPORT, MW_RST);                                   // Madwizard uitschakelen
    if (freq == 0.0) {                                          // Stoppen?
        PORTA = 0xFF;                                           // Doolittle-adres = 7 = GAL blokkeren
        cbi(SHIFTPORTMW_RST);                                 // Madwizard uitschakelen
        display_ALL();                                          // Toon de instellingen
        return;
    } else if (freq > 10000000.00) {                            // 10MHz is het maximum
        freq = 10000000.00;
        OutputFrequency = 10000000.00;
        Madwizard_prescaler = 0;                                // Disable Madwizard's pwm-clk
        DDS_frequency = freq;
        set_DDS(DDS_frequency);                                 // DDS-frequentie instellen
        PORTA = 0x03;                                           // Doolittle: DDS-clk / 2
        display_ALL();                                          // Toon de instellingen
        return;
    } else if (freq > 2000000.00) {                             // Meer dan 2MHz; we hebben Madwizard niet nodig
        Madwizard_prescaler = 0;                                // Disable Madwizard's pwm-clk
        DDS_frequency = freq;
        set_DDS(DDS_frequency);                                 // DDS-frequentie instellen
        PORTA = 0x03;                                           // Doolittle: DDS-clk / 2
        display_ALL();                                          // Toon de instellingen
        return;
    } else if (freq > 1200.00) {                                // Voorbeeld: 12345
        tmp = DDS_FREQ / freq;                                  // Madwizard_maxcount = 6250000 / 12345 = 506.277845281490482
        Madwizard_maxcount = (unsigned inttmp;                // Madwizard_maxcount = 506
        DDS_frequency = ((doubleMadwizard_maxcount) * freq;   // DDS_frequency = (12345 * 506) = 6246570
    } else if (freq > 120.00) {                                 // Voorbeeld: 12345
        DDS_FREQ /= 2.0;                                        // 6250000 / 2 = 3125000
        tmp = DDS_FREQ / freq;                                  // Madwizard_maxcount = 6250000 / 12345 = 506.277845281490482
        DDS_frequency = ((doubleMadwizard_maxcount) * freq;   // DDS_frequency = (12345 * 506) = 6246570
    } else if (freq > 2.00) {                                   // Voorbeeld: 10
        DDS_FREQ /= 5.0;                                        // 6250000 / 2 = 1250000
        freq *= 64.0;                                           // freq = 640
        tmp = DDS_FREQ / freq;                                  // Madwizard_maxcount = 6250000 / 640 = 9765.625
        DDS_frequency = (double) (Madwizard_maxcount) * freq;   // DDS_frequency = (9765 * 640) = 6249600
    } else {                                                    // Voorbeeld: 0.2
        DDS_FREQ /= 10.0;                                       // 6250000 / 10 = 625000
        if (freq < 0.01) {
            freq = 0.01;                                        // 0.01Hz is het minimum
        }
        freq *= 1024.0;                                         // 0.2 * 1024 = 204.8
        tmp = DDS_FREQ / freq;                                  // 625000 / 204.8 = 3051.7578125
        DDS_frequency = (double) (Madwizard_maxcount) * freq;   // DDS_frequency = (3051 * 204.8) = 624844.8
    }
    set_DDS(DDS_frequency);                                     // DDS-frequentie instellen
    display_ALL();                                              // Toon de instellingen
}


void init(void)
{
    // PB1 ... PB4 zijn verbonden met Madwizard, die we als een schuifregister aansturen
    SHIFTDDR |= (_BV(MW_DATA) | _BV(MW_INT0) | _BV(MW_INT1) | _BV(MW_RST));
    SHIFTPORT |= (_BV(MW_DATA) | _BV(MW_INT0) | _BV(MW_INT1));  // Madwizard's INT0, INT1 en D hoog, RST laag

    // Het toetsenbord is verbonden met verschillende poorten
    DDRD = 0;
    PORTD = 0x68;                                               // Pull-up weerstanden v KB-input activeren
    cbi(DDRBPB5);
    sbi(PORTBPB5);
    DDRA = 0xFF;                                                // PA0 ... PA7 = uitgangen
    PORTA = _BV(PA3) | _BV(PA4) | _BV(PA5) | _BV(PA6);          // KB-uitgangen hoog

    DDS_word = 0x4CCCCCCC;                                      // DDS starten aan ±15MHz
    sbi(DDS_D_DDRDDS_D);                                      // DDS-pinnen = uitgang
    sbi(DDS_C_DDRDDS_CLK);
    sbi(DDS_E_DDRDDS_EN);
    sbi(DDS_E_PORTDDS_EN);                                    // FSYNC hoog maken
    pulsbreedte = 50.0;
    delay_ms(100);
    DDS_WRITE(DDS_STOP);                                        // set sleep, reset=1, clr=1
    FSEL = 0;                                                   // We starten met frequentie-register 0
    FREQ_WORD_WRITE(DDS_word);                                  // DDS-frequentie instellen
    DDS_WRITE(DDS_START);                                       // set sleep=0, reset=0, clr=0
    DDS_WRITE(SET_SYNC);

    uart_init();                                                // initialiseer RS232
    lcd_init(LCD_DISP_ON_CURSOR_BLINK);                         // initialiseer LCD
    lcd_puts(" Gullinbursti");
    lcd_puts_at(21Versie);
    sei();                                                      // enable global interrupt
    sbi(SHIFTPORTMW_RST);                                     // Laat Madwizard z'n gang gaan
    lcd_puts_at(31"  Initialising...");
    OutputFrequency = 0.00;                                     // Default-frequentie = 0Hz
    KB_mode = FREQ;
    sweepdelay = 1;
    delay_ms(500);
    set_freq(OutputFrequencyDDS_DEFAULT_FREQ);
    key_ptr = key_buffer;
    *key_ptr = 0;
    key_time = 500;                                             // Wachttijd bij UP- en DOWN-toetsen
    delay_ms(5000);
}


// Bij het sweepen laten we Madwizard buiten spel.

void sweep(double startdouble enddouble step)
{
    unsigned long STARTENDSTEP;

    cbi(SHIFTPORTMW_RST);                                     // Madwizard uitschakelen
    PORTA |= 0x03;                                              // Doolittle: DDS-clk / 2
    start *= 171.79869184;
    start += 0.5;
    START = (unsigned longstart;
    end *= 171.79869184;
    end += 0.5;
    END = (unsigned longend;
    if (step < 0.01) {
        step = 0.01;
    }
    step *= 171.79869184;
    step += 0.5;
    STEP = (unsigned longstep;
    FREQ_WORD_WRITE(START);

    if (START < END) {                                          // Oplopende frequentie
        while (START < END) {
            START += STEP;                                      // We nemen stappen van ±1Hz
            FREQ_WORD_WRITE(START);
        }
    } else {
        while (START > END) {
            START -= STEP;
            FREQ_WORD_WRITE(START);
        }
    }

    fwip();
}


void RS232menu(void)
{
    uart_sendstr_P("\nGullinbursti - RS232-menu:\n");
    uart_sendstr_P("--------------------------\n\n");
    uart_sendstr_P("f=(float)  uitgangs-frequentie instellen\n");
    uart_sendstr_P("d=(float)  DDS-frequentie instellen\n");
    uart_sendstr_P("w=(float)  DDS-frequentieword instellen\n");
    uart_sendstr_P("p=(float)  pulsbreedte instellen (in %)\n");
    uart_sendstr_P("m=(int)    ICR1 van Madwizard instellen\n");
    uart_sendstr_P("n=(int)    OCR1B van Madwizard instellen\n");
    uart_sendstr_P("c=(int)    tccr1b (prescaler) van Madwizard instellen\n");
    uart_sendstr_P("s1=(float) Startfrequentie voor sweep\n");
    uart_sendstr_P("s2=(float) Eindfrequentie voor sweep\n");
    uart_sendstr_P("sp=(int)   Pause tussen 2 stappen bij sweep\n");
    uart_sendstr_P("ss=(float) Frequentie-stappen bij sweep\n");
    uart_sendstr_P("sg=        Start sweep-functie\n\n");
}


void check_RS232(void)
{
    unsigned int Integer;
    double tmp;
    char *val;
    unsigned long LInt;

    if (strncmp(uart_outbuf"Who"3) == 0) {                  // Wie heb ik aan de lijn?
        uart_sendstr_P("Grotendikken\n");
        uart_sendstr(Versie);
        nl();
    } else if (uart_outbuf[1] == '=') {
        val = &(uart_outbuf[2]);
        switch (uart_outbuf[0]) {
        case 'f':
        case 'F':
            if ((*val > 47) && (*val < 58)) {                   // Stel de frequentie in
                ok();
                OutputFrequency = get_float(val);
                set_freq(OutputFrequencyDDS_DEFAULT_FREQ);
            } else {
                uart_sendstr_P("Frequentie = ");
                float2RS232(OutputFrequency);                   // of geef de ingestelde frequentie door
                nl();
            }
            break;
        case 'D':                                               // Stel de DDS-frequentie in
        case 'd':
            if ((*val > 47) && (*val < 58)) {                   // Er is een getal opgegeven
                ok();
                cbi(SHIFTPORTMW_RST);                         // Madwizard uitschakelen
                DDS_frequency = get_float(val);
                set_DDS(DDS_frequency);
                delay_ms(20);                                   // Even wachten
                sbi(SHIFTPORTMW_RST);                         // Madwizard terug inschakelen
                delay_ms(200);
                shift2MW(PRESCMadwizard_prescaler);           // Stel Madwizard's prescaler in
                shift2MW(PWM1);                               // Pulsbreedte = klein, anders protesteert MW
                shift2MW(MAXCNTMadwizard_maxcount - 1);       // Stel Madwizard's ICR1 in
                shift2MW(PWMMadwizard_ocr1b);                 // Stel nu pas de juiste pulsbreedte in
                display_ALL();
            } else {                                            // We geven de huidige instelling door
                uart_sendstr_P("DDS-frequentie = ");
                float2RS232(DDS_frequency);
                nl();
            }
            break;
        case 'W':                                               // Stel het frequency-word v/d DDS in
        case 'w':
            if ((*val > 47) && (*val < 58)) {                   // Er is een getal opgegeven
                ok();
                LInt = get_data(val);
                lcd_clrscr();
                lcd_puts_P("From: ");
                UL2LCD(DDS_word);
                lcd_puts_at(21"To:   ");
                UL2LCD(LInt);
                if (LInt < DDS_word) {                          // Frequentie stelselmatig verlagen
                    while (LInt < DDS_word) {
                        DDS_word -= 256UL;
                        FREQ_WORD_WRITE(DDS_word);
                    }
                } else {                                        // Frequentie stelselmatig verhogen
                    while (LInt > DDS_word) {
                        DDS_word += 256UL;
                        FREQ_WORD_WRITE(DDS_word);
                    }
                }
                display_ALL();
            } else {                                            // We geven het frequency-word v/d DDS door
                uart_sendstr_P("DDS-word = ");
                UL2RS232(DDS_word);
            }
            break;
        case 'P':
        case 'p':                                               // Stel de pulsbreedte in
            if ((*val > 47) && (*val < 58)) {
                pulsbreedte = get_float(val);
                if (pulsbreedte > 99.999) {
                    pulsbreedte = 99.999;
                } else if (pulsbreedte < 0.001) {
                    pulsbreedte = 0.001;
                }
                tmp = pulsbreedte;                              // Vb. 2.4
                tmp *= (doubleMadwizard_maxcount;             // Vb 2.4 * 888 = 2131.2
                tmp /= 100.0;                                   // 21.312
                Madwizard_ocr1b = (unsigned int) (tmp + 0.5);   // 21.812 -> 21
                if (Madwizard_ocr1b > (Madwizard_maxcount - 1)) {
                    Madwizard_ocr1b = Madwizard_maxcount - 1;
                } else if (Madwizard_ocr1b < 1) {
                    Madwizard_ocr1b = 1;
                }
                Madwizard_ocr1b--;
                shift2MW(PWMMadwizard_ocr1b);
                display_ALL();
                ok();
            } else {
                uart_sendstr_P("Pulsbreedte = ");
                float2RS232(pulsbreedte);
                nl();
            }
            break;
        case 'M':                                               // Stel Madwizard's PWM-maxcnt in
        case 'm':
            if ((*val > 47) && (*val < 58)) {                   // Gewenste maxcnt opgegeven
                Madwizard_maxcount = get_data(val);
                ok();
                shift2MW(MAXCNTMadwizard_maxcount);
                OutputFrequency = DDS_frequency / ((doubleMadwizard_maxcount * (doubleMadwizard_prescaler);
                display_ALL();
            } else {
                sprintf(txt_buffer"Madwizard_maxcount = %u\n"Madwizard_maxcount);
                uart_sendstr(txt_buffer);
            }
            break;
        case 'N':                                               // Stel Madwizard's PWM duty-cycle in
        case 'n':
            if ((*val > 47) && (*val < 58)) {
                Integer = get_data(val);
                ok();
                if (Integer > Madwizard_maxcount) {
                    Integer = Madwizard_maxcount - 1;
                } else if (Integer < 0) {
                    Integer = 1;
                }
                Madwizard_ocr1b = Integer;
                tmp = (doubleInteger *100.0;  // Percentage berekenen
                pulsbreedte = tmp / (doubleMadwizard_maxcount;
                display_ALL();
                shift2MW(PWMMadwizard_ocr1b);
            } else {
                sprintf(txt_buffer"Madwizard_ocr1b = %u\n"Madwizard_ocr1b);
                uart_sendstr(txt_buffer);
            }
            break;
        case 'C':                                               // Stel Madwizard's prescaler in
        case 'c':                                               // 1 ... 5
            if ((*val > 47) && (*val < 58)) {
                Integer = get_data(val);
                if ((Integer > 0) && (Integer < 6)) {
                    Madwizard_prescaler = Integer;
                    shift2MW(PRESCMadwizard_prescaler);
                    ok();
                } else {
                    uart_sendstr_P("Madwizard_prescaler out of range. Must be: 1 ... 5");
                }
            } else {
                sprintf(txt_buffer"Madwizard_prescaleraler = %u\n"Madwizard_prescaler);
                uart_sendstr(txt_buffer);
            }
            break;
        default:                                                // Onbekende opdracht
            RS232menu();
            break;
        }
    } else if ((uart_outbuf[0] == 's') && (uart_outbuf[2] == '=')) {    // Sweep-opdracht
        val = &(uart_outbuf[3]);                                // bv. "s1=12000"
        switch (uart_outbuf[1]) {
        case '1':                                               // Startfrequentie sweep
            if ((*val > 47) && (*val < 58)) {                   // Waarde opgegeven?
                sweep_start = get_float(val);
                ok();
            } else {                                            // Geen opgave
                uart_sendstr_P("Start sweep = ");
                float2RS232(sweep_start);                       // Dus geven we die zelf door
                nl();
            }
            break;
        case '2':                                               // Eindfrequentie sweep
            if ((*val > 47) && (*val < 58)) {                   // Waarde opgegeven?
                sweep_end = get_float(val);
                ok();
            } else {                                            // Geen opgave
                uart_sendstr_P("End sweep = ");
                float2RS232(sweep_end);                         // Dus geven we die zelf door
                nl();
            }
            break;
        case 'p':                                               // Pause
            if ((*val > 47) && (*val < 58)) {                   // Waarde opgegeven?
                pause_time = (unsigned int) (get_data(val));
                ok();
            } else {                                            // Geen opgave
                uart_sendstr_P("Sweep=pause = ");
                dec2RS232(pause_time);                          // Dus geven we die zelf door
                nl();
            }
            break;
        case 's':                                               // Sweep-step
            if ((*val > 47) && (*val < 58)) {                   // Waarde opgegeven?
                sweep_step = get_float(val);
                ok();
            } else {                                            // Geen opgave
                uart_sendstr_P("Sweep-step = ");
                float2RS232(sweep_step);                        // Dus geven we die zelf door
                nl();
            }
            break;
        case 'g':                                               // Go!
            ok();
            sweep(sweep_startsweep_endsweep_step);
            break;
        default:                                                // Toon alle sweep-gegevens
            uart_sendstr_P("\nStart sweep = ");
            float2RS232(sweep_start);
            uart_sendstr_P("\nEnd sweep = ");
            float2RS232(sweep_end);
            uart_sendstr_P("\nSweep=pause = ");
            dec2RS232(pause_time);
            uart_sendstr_P("\nSweep-step = ");
            float2RS232(sweep_step);
            nl();
            break;
        }
    } else {
        RS232menu();
    }
}


// Stel de frequentie in
void do_KB_freq(void)
{
    switch (Key) {
    case 'u':                                                   // Frequentie verhogen
        DDS_frequency++;                                        // We verhogen de frequentie v/d DDS met 1Hz
        set_DDS(DDS_frequency);
        OutputFrequency = DDS_frequency / DDS_deler;            // DDS-frequetie vertalen naar uitgangsfrequentie
        display_ALL();                                          // Toon de nieuwe instellingen
        delay_ms(key_time);
        if (key_time > 1) {
            key_time *= 10;
            key_time /= 15;
        }
        break;
    case 'd':                                                   // Frequentie verlagen
        DDS_frequency--;                                        // DDS-frequentie met 1 stap verlagen
        set_DDS(DDS_frequency);                                 // DDS-frequentie bijstellen
        OutputFrequency = DDS_frequency / DDS_deler;
        display_ALL();
        delay_ms(key_time);
        if (key_time > 1) {
            key_time *= 10;
            key_time /= 15;
        }
        break;
    case 'E':                                                   // Opgegeven frequentie instellen
        OutputFrequency = get_float(key_buffer);
        set_freq(OutputFrequencyDDS_DEFAULT_FREQ);
        key_ptr = key_buffer;
        *key_ptr = 0;
        key_time = 800;                                         // Default-wachttijd voor UP en DOWN resetten
        delay_ms(200);
        break;
    default:
        key_time = 800;                                         // Default-wachttijd voor UP en DOWN resetten
        break;
    }
}



// Stel de pulsbreedte in
void do_KB_puls(void)
{
    double tmp;

    switch (Key) {
    case 'u':                                                   // Pulsbreedte verhogen
        if (pulsbreedte < 98.9) {
            pulsbreedte += 1.0;
        }
        break;
    case 'd':
        if (pulsbreedte > 1.1) {
            pulsbreedte -= 1.0;
        }
        break;
    case 'E':                                                   // Opgegeven pulsbreedte instellen
        pulsbreedte = get_float(key_buffer);                    // De pulsbreedte wordt opgegeven in percent
        key_ptr = key_buffer;
        *key_ptr = 0;
        if (pulsbreedte > 99.999) {
            pulsbreedte = 99.999;
        } else if (pulsbreedte < 0.001) {
            pulsbreedte = 0.001;
        }
        break;
    default:
        break;
    }
    if (OutputFrequency > 5000000.0) {                          // Meer dan 5MHz?
        return;                                                 // Dan valt er geen pulsbreedte in te stellen
    } else if (OutputFrequency > 2000000.0) {                   // Meer dan 2MHz?
        if (pulsbreedte < 30.0) {
            DDS_frequency = OutputFrequency * 2.0;
            set_DDS(DDS_frequency);                             // DDS-frequentie instellen
            PORTA = ADR4;                                       // Doolittle: DDS-clk / 4
            DDS_deler = 2.0;
        } else if (pulsbreedte > 70.0) {
            DDS_frequency = OutputFrequency * 2.0;
            set_DDS(DDS_frequency);                             // DDS-frequentie instellen
            PORTA = ADR5;                                       // Doolittle: DDS-clk / 4
            DDS_deler = 2.0;
        } else {
            DDS_frequency = OutputFrequency;
            set_DDS(DDS_frequency);                             // DDS-frequentie instellen
            PORTA = ADR3;                                       // Doolittle: DDS-clk / 2
            DDS_deler = 1.0;
        }
    } else {
        tmp = pulsbreedte;                                      // Vb. 2.4
        tmp *= (doubleMadwizard_maxcount;                     // Vb 2.4 * 888 = 2131.2
        tmp /= 100.0;                                           // 21.312
        Madwizard_ocr1b = (unsigned int) (tmp + 0.5);           // 21.812 -> 21
        if (Madwizard_ocr1b > (Madwizard_maxcount - 1)) {
            Madwizard_ocr1b = Madwizard_maxcount - 1;
        } else if (Madwizard_ocr1b < 1) {
            Madwizard_ocr1b = 1;
        }
        Madwizard_ocr1b--;
        shift2MW(PWMMadwizard_ocr1b);
    }
    display_ALL();
    delay_ms(200);
}


void do_KB(void)
{
    if (Key < 10) {                                             // Een cijfer, bv. '5'
        *key_ptr = Key + '0';
        key_ptr++;
        *key_ptr = 0;
        lcd_putc(Key + '0');
        delay_ms(200);
    } else {
        switch (Key) {
        case 'M':                                               // De mode-toets?
            // De mode-toets behandelen we op een bijzondere wijze.
            // Als we in pulsbreedte-mode zitten, en de toets wordt kortstondig ingedrukt,
            // Gaan we terug naar frequentie-mode.
            // Pas als de toets langer ingedrukt wordt, komen we in de sweep-modes terecht.
            if (KB_mode == PULS) {
                if (time_KB() < 12) {                           // Toets kort ingedrukt?
                    KB_mode = FREQ;
                } else {
                    KB_mode++;
                    if (KB_mode > SWEEP) {
                        KB_mode = FREQ;
                    }
                }
            } else {
                KB_mode++;
                if (KB_mode > SWEEP) {
                    KB_mode = FREQ;
                }
            }
            display_ALL();
            delay_ms(200);
            break;
        case '.':                                               // dp
            *key_ptr = '.';
            key_ptr++;
            *key_ptr = 0;
            lcd_putc('.');
            delay_ms(200);
            break;
        case 'C':                                               // Clear 
            key_ptr = key_buffer;
            *key_ptr = 0;
            display_ALL();
            delay_ms(200);
            break;
        default:
            switch (KB_mode) {
            case FREQ:
                do_KB_freq();
                break;
            case PULS:
                do_KB_puls();
                break;
            case SW_START:                                      // De startfrequentie voor het sweepen
                if (Key == 'E') {
                    sweep_start = get_float(key_buffer);
                    key_ptr = key_buffer;
                    *key_ptr = 0;
                    KB_mode++;                                  // Stel meteen de volgende mode in
                    display_ALL();
                    delay_ms(200);
                }
                break;
            case SW_END:                                        // De eindfrequentie voor het sweepen
                if (Key == 'E') {
                    sweep_end = get_float(key_buffer);
                    key_ptr = key_buffer;
                    *key_ptr = 0;
                    KB_mode++;                                  // Stel meteen de volgende mode in
                    display_ALL();
                    delay_ms(200);
                }
                break;
            case SW_DELAY:                                      // De delay tussen 2 stappen bij het sweepen
                if (Key == 'E') {
                    pause_time = (unsigned int) (get_data(key_buffer));
                    key_ptr = key_buffer;
                    *key_ptr = 0;
                    KB_mode++;                                  // Stel meteen de volgende mode in
                    display_ALL();
                    delay_ms(200);
                }
                break;
            case SW_STEP:                                       // De grootte v/d stappen bij het sweepen
                if (Key == 'E') {
                    sweep_step = get_float(key_buffer);
                    key_ptr = key_buffer;
                    *key_ptr = 0;
                    KB_mode++;                                  // Stel meteen de volgende mode in
                    display_ALL();
                    delay_ms(200);
                }
                break;
            case SWEEP:                                 // Sweep!
                if (Key == 'E') {
                    sweep(sweep_startsweep_endsweep_step);
                }
                break;
            default:
                break;
            }
            delay_ms(20);
            break;
        }
    }
}


int main(void)
{
    init();

    while (1) {
        if (uart_rx_linecomplete != 0) {
            check_RS232();
            uart_rx_pos = 0;
            uart_rx_linecomplete = 0;
        } else if (check_KB() != 0xFF) {                        // Toetsenbord ingedrukt?
            do_KB();
        }
    }
}