/* 
 * File:   Cent.c
 * Author: andre
 *
 * Created on 21 maggio 2019, 19.10
 */

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <stdio.h>
#include <stdlib.h>
#include "Cent.h"
#include "ShaDe.h"   
#include "Clock.h"
#include "Lcd.h"

extern unsigned char ucDDRAMaddr;
extern unsigned int uiDDRAMsymb;
unsigned char ucIndex = 0, ucNopIndex = 0, ucStopIndex = 0, ucAlphabet = 0, ucNopAlphabet = 0, ucStopAlphabet = 0;
char *acMsg[] = {   "Mi me someja che",
                    "posa anca ndar. ",
                    "Ma ze un fia un ",
                    "carneval de fii."};

/*
 * 
 */
int main(int argc, char** argv) {
    AD1PCFG = 0xFF; //+++ All PORTB as digital.
    INTCON1bits.NSTDIS = 1;     //+++ Interrupt nesting is disabled.
    SetupClock();
    TRISB = 0x00;
    TRISA = 0x00;   
    
    /* The following code example will enable Timer1 interrupts, load the Timer1
    Period register and start Timer1.
    When a Timer1 period match interrupt occurs, the interrupt service
    routine must clear the Timer1 interrupt status flag in software.
    */
    T1CON = 0x00; //Stops the Timer1 and reset control reg.
    TMR1 = 0x00; //Clear contents of the timer register
    PR1 = 0xFFFF; //Load the Period register with the value 0xFFFF
    T1CONbits.TCKPS = 0x03;
    IPC0bits.T1IP = 0x04; //Setup Timer1 interrupt for desired priority level
    IFS0bits.T1IF = 0; //Clear the Timer1 interrupt status flag
    IEC0bits.T1IE = 1; //Enable Timer1 interrupts
    T1CONbits.TON = 0; //Start Timer1 with prescaler settings at 1:1 and clock source set to the internal instruction cycle
    
    /* The following code example will enable Timer3 interrupts, load the
    Timer3:Timer2 Period Register and start the 32-bit timer module
    consisting of Timer3 and Timer2.
    When a 32-bit period match interrupt occurs, the user must clear the
    Timer3 interrupt status flag in software.
    */
    T2CON = 0x00; //Stops any 16/32-bit Timer2 operation
    T3CON = 0x00; //Stops any 16-bit Timer3 operation
    TMR3 = 0x00; //Clear contents of the timer3 register
    TMR2 = 0x00; //Clear contents of the timer2 register
    PR3 = 0x00FF; //Load the Period register3 with the value 0xFFFF
    PR2 = 0xFFFF; //Load the Period register2 with the value 0xFFFF
    IPC2bits.T3IP = 0x03; //Setup Timer3 interrupt for desired priority level (this example assigns level 1 priority)
    IFS0bits.T3IF = 0; //Clear the Timer3 interrupt status flag
    IEC0bits.T3IE = 1; //Enable Timer3 interrupts
    T2CONbits.T32 = 1; //Enable 32-bit Timer operation
    T2CONbits.TON = 0; //Start 32-bit timer with prescaler settings at 1:1 and clock source set to the internal instruction cycle
         
    LCD_init();
    T1CONbits.TON = 1;     
    
    while (1)
    {
    }
    
    return (EXIT_SUCCESS);
}

//+++ Timer1 ISR.
void _ISR _T1Interrupt(void)
{
    /* Interrupt Service Routine code goes here */
    if (ucStopAlphabet == 0)
    {
        LCD_command(0x0080 + ucDDRAMaddr);    //+++ 
        ucDDRAMaddr++;
        if (ucDDRAMaddr == 0x10)
            ucDDRAMaddr = 0x40;
        if (ucDDRAMaddr == 0x50)
        {
            ucDDRAMaddr = 0x00;
            ucStopAlphabet = 1;
        }
        LCD_senddata(uiDDRAMsymb++);
        if (uiDDRAMsymb == 0x0080)
        {
            uiDDRAMsymb = 0x0020;
            ucAlphabet++;
        }            

        if (ucAlphabet == 2)
        {
            T1CON = 0x00; //Stops the Timer1 and reset control reg.
            T2CONbits.TON = 1; //Start 32-bit timer with prescaler settings at 1:1 and clock source set to the internal instruction cycle         
        }
    }
    else
    {
        ucNopAlphabet++;
        if (ucNopAlphabet == 20)
        {
            ucNopAlphabet = 0;
            ucStopAlphabet = 0;
        }
    }
    
    IFS0bits.T1IF = 0; //Reset Timer1 interrupt flag and Return from ISR
}

//+++ Timer3 ISR, 32 bit mode, timers 2&3.
void _ISR _T3Interrupt(void)
{
    /* Interrupt Service Routine code goes here */
    if (ucStopIndex == 0)
    {
        lcd_puts(acMsg[ucIndex++]);
        if (ucIndex == 2 || ucIndex == 4)
            ucStopIndex = 1;
        if (ucIndex == 4)
            ucIndex = 0;
    }
    else
    {
        ucNopIndex++;
        if (ucNopIndex == 5)
        {
            lcd_puts("                ");
            lcd_puts("                ");
            ucNopIndex = 0;
            ucStopIndex = 0;
        }
    } 
    
    IFS0bits.T3IF = 0; //Reset Timer3 interrupt flag and Return from ISR
}