// TODO 17.01
#include "Microchip_Logo.h"
#include "Alphabet_Fonts.h" 


// TODO 17.02
#define LCM_WIDTH 128
#define LCM_HEIGHT 64
#define FONT_WIDTH  7
#define FONT_HEIGHT 8
uint8_t LogoX, LogoY;
unsigned char LCM_Blank[1024];
char Alphabet[95] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@#$%^&()[]{}_\\|;:,.`'\"<>+-*/=? ";

const uint8_t LCM_InitCMD[] = {
    0xAE, 0xD5, 0x80, 0xA8, 0x3F, 0xD3, 0x00, 0x40, 0x8D, 0x14, 0x20, 0x02, 0xA1,
    0xC8, 0xDA, 0x12, 0x81, 0xCF, 0xD9, 0xF1, 0xDB, 0x40, 0xA4, 0xA6, 0xAF
};

void LCM_SetCursor( uint8_t x, uint8_t y )
{
    uint8_t OUT[3] = { 0x0F & x, 0x10 + (x >> 4), 0xB0 + y };
    SSD1306_RS_PIN_Clear();
    SERCOM4_SPI_Write(( void* )OUT, 3);
}

void LCM_DrawBitmap( uint8_t sx, uint8_t sy, uint8_t width, uint8_t height, const unsigned char *byte )
{
    for( int y = 0; y < (height/8); y++ )
    {
        LCM_SetCursor(sx, sy + y);
        SSD1306_RS_PIN_Set();
        SERCOM4_SPI_Write(( void* )byte, (width - sx));
        byte += width;
    }
}

void LCM_DrawFont( uint8_t sx, uint8_t row, char ch )
{
    int chIdx = 0;

    while( ch != Alphabet[chIdx] ) { chIdx++; }	
    LCM_SetCursor(sx, row);
    SSD1306_RS_PIN_Set();
    SERCOM4_SPI_Write( ( void* )(Alphabet_Fonts+(chIdx*FONT_WIDTH)), FONT_WIDTH );
}

void LCM_DrawString( uint8_t sx, uint8_t row, char *str )
{
    for( int x=0 ; x<strlen(str); x++ )
    {
        LCM_DrawFont( sx+(x*FONT_WIDTH), row, str[x] );
    }
}


// TODO 17.03
    SYSTICK_TimerStart();
    SSD1306_CS_PIN_Clear();
    SSD1306_RS_PIN_Clear();
    SERCOM4_SPI_Write(( void* )LCM_InitCMD, sizeof (LCM_InitCMD));
    memset(LCM_Blank, 0, 1024);
    LCM_DrawBitmap(0, 0, LCM_WIDTH, LCM_HEIGHT, LCM_Blank);
    LogoX = 127;
    LogoY = 0;
    for( i = 0; i < 128; i += 2 )
    {
        LCM_DrawBitmap(LogoX - i, LogoY, LCM_WIDTH, LCM_HEIGHT, Microchip_Logo);
        SYSTICK_DelayMs((i * i) / 400);
    }
    SYSTICK_DelayMs(1000);
    memset(LCM_Blank, 0, 1024);
    LCM_DrawBitmap(0, 0, LCM_WIDTH, LCM_HEIGHT, LCM_Blank);
    sprintf( (char *)USARTRTxBuffer, "SysClock %ld.%-ldMHz", SYSTICK_TimerFrequencyGet()/1000000, (SYSTICK_TimerFrequencyGet()%1000000)/1000 );
    LCM_DrawString( 0, 0, (char *)USARTRTxBuffer );			
    sprintf( (char *)USARTRTxBuffer, "TC3 period %ldms", TC3_Timer16bitPeriodGet()*1000/TC3_TimerFrequencyGet() );
    LCM_DrawString( 0, 1, (char *)USARTRTxBuffer );			
    sprintf( (char *)USARTRTxBuffer, "TC4 period %ldms", TC4_Timer16bitPeriodGet()*1000/TC4_TimerFrequencyGet() );
    LCM_DrawString( 0, 2, (char *)USARTRTxBuffer );			
    sprintf( (char *)USARTRTxBuffer, "Received Data :" );
    LCM_DrawString( 0, 7, (char *)USARTRTxBuffer );


// TODO 17.04
            sprintf( (char *)USARTRTxBuffer, "Hello World!!");
            LCM_DrawString( 0, 3, (char *)USARTRTxBuffer );


// TODO 17.05
            sprintf( (char *)USARTRTxBuffer, "PWM Duty : %3d%%", Duty);
            LCM_DrawString( 0, 4, (char *)USARTRTxBuffer );


// TODO 17.06
            sprintf( (char *)USARTRTxBuffer, "Received Data : %1c", USART5_ReceiveData[0] );
            LCM_DrawString( 0, 7, (char *)USARTRTxBuffer );


// TODO 17.07
            sprintf( (char *)USARTRTxBuffer, "VR1  : %4d", ADC_Result[0]);
            LCM_DrawString( 0, 5, (char *)USARTRTxBuffer );
            sprintf( (char *)USARTRTxBuffer, "Temp : %4d", ADC_Result[1]);
            LCM_DrawString( 0, 6, (char *)USARTRTxBuffer );
