/*
 * Soubor:  sem-tam.c
 * Datum:   02.01.2012 23:47
 * Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
 * Licence: GNU/GPL 
 * Úloha:   Světlo se pohybuje doleva a doprava
 * Popis:   Tlačítka řídí rychlost.
 ****************************************************/
#include <at89x52.h>
#include <stdbool.h>

#include "delay12MHz.h"


/* **************************************************
 *               Hlavní program.
 ****************************************************/

#define VLEVO 0
#define VPRAVO 1
// tlačítko, které zvyšuje rychlost
#define TLPLUS (P1_0 == 0)
// tlačítko, které snižuje rychlost
#define TLMINUS (P1_1 == 0)
// tlačítko, které zastavuje a spouští
#define TLSTOP (P1_2 == 0)
// (jak dlouho musím držet tlačítko, aby reagovalo) x 10 ms 
#define DRZIM 10 


/** Funkce se stará o zobrazování a prohozazování směru
 *  pohybu světla 
 */
void zobrazuj(void)
{
    static bool smer = VPRAVO;
    static unsigned char svetlo = 0b10000000;

    /* sviť */
    P0 = ~svetlo;
    /* rotace */
    if (smer == VPRAVO) {
        svetlo = svetlo >> 1;
    } else if (smer == VLEVO) {
        svetlo = svetlo << 1;
    }
    /* prohození směru */
    if (svetlo == 128 || svetlo == 1) {
        smer = !smer;
    }
}

/** Funkce zobrazí na 7segmentu orientačí hodnotu rychlosti
 * (0 až 9)
 */

void zobrazuj7(unsigned char cas)
{
    /* pole uložené v paměti programu představuje čísla na displayi */
    __code char segment[] = { 
        0b11000000,           //0
        0b11111001,           // 1
        0b10100100,           // 2
        0b10110000,           // 3 
        0b10011001,           // 4
        0b10010010,           // 5
        0b10000010,           // 6
        0b11111000,           // 7
        0b10000000,           // 8
        0b10010000            // 9
    };
    P2 = segment[9 - (cas-1)/10 ];

}

/** Tato funkce se zpouští každých 10ms a kontroluje přidržení
 *  tlačítek.
 */
void kontrolujPlusMinus(unsigned char * cas)
{
    static unsigned char indikatorPlus = 0;
    static unsigned char indikatorMinus = 1;
    static bool drzimPlus = false;
    static bool drzimMinus = false;
    // tlačítko PLUS
    if (TLPLUS) {
        drzimPlus = true;
        indikatorPlus++;
    } else {
        drzimPlus = false;
        indikatorPlus = 0;
    }
    if (indikatorPlus > DRZIM) {
        (*cas) = (*cas) <= 2 ? 2 : (*cas) - 1;
        indikatorPlus = 0;
    }
    // tlačítko MINUS
    if (TLMINUS) {
        drzimMinus = true;
        indikatorMinus++;
    } else {
        drzimMinus = false;
        indikatorMinus = 0;
    }
    if (indikatorMinus > DRZIM) {
        (*cas) = (*cas) >= 100 ? 100 : (*cas) + 1;
        indikatorMinus = 0;
    }
}

void main(void)
{
    unsigned char cas = 50;
    unsigned char i;
    bool stop = false;
    bool stopPamet = false;
    for (;;) {
        if (!stop) {
            zobrazuj();
            zobrazuj7(cas);
            // realizuje zpoždění a zároveň kontroluje tlačítko
            for (i = 0; i < cas; i++) {
                delay_10m_x(1);
                kontrolujPlusMinus(&cas);
            }
        }
        // TLSTOP reaguje při uvolnění
        if (!TLSTOP && stopPamet) {
            stop = ! stop;
        } 
        stopPamet = TLSTOP;
    }
}

