/**
  ******************************************************************************
  * @file demo_microsd.c
  * @brief This file contains all the functions for the MICROSD demo.
  * @author STMicroelectronics - MCD Application Team
  * @version V1.1.0
  * @date    09/14/2009
  ******************************************************************************
  *
  */

// Includes ------------------------------------------------------------------
#include "demo_microsd.h"

// Private typedef -----------------------------------------------------------
// Private define ------------------------------------------------------------
// Private macro -------------------------------------------------------------
#define countof(a) (sizeof(a) / sizeof(*(a)))
// Private variables ---------------------------------------------------------
#define BufferSize (countof(Tx_Buffer)-1)
// Private function prototypes -----------------------------------------------
// Private functions ---------------------------------------------------------

  // * @addtogroup Demo_Functions

void MICROSDDEMO_Reset(void)
{
    LEDS_OFF();
}

void MICROSDDEMO_Exec(void)
{
		JOYSTICK_ID_T Key;
		BUTTON_ID_T KeyB;
    uint8_t status,SD_ERROR;
    uint8_t Tx_Buffer[] = "DEMO MICROSD";
    uint8_t Rx_Buffer[BufferSize];
    uint8_t address =0;
    uint8_t i =0;
		
    // Initialize LCD
    LCD_Init();
		
		LCD_Clear();

    LCD_PrintString(LCD_LINE1, ENABLE, DISABLE, " Insert MicroSD ");
    LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, "Press KEY buttn");
		
		PlayTunePWM(16000, 200);
		KeyB = ReadButton();
      while (KeyB != B_PRESSED)
        {
            // Wait MicroSD card insertion or Joystick action to end 
            Key = ReadJoystick();
            if (Key == UP)
            {
                MenuUpdate(Key);
                return;
            }
				KeyB = ReadButton();
        }

    LCD_PrintString(LCD_LINE1, ENABLE, DISABLE, "  MicroSD card");
    LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, "Start Operations");
    LEDBICOLOR_ON();
    PlayMelody("4.da");
    WaitDelay(100);

    // Init MicroSD 
    LCD_Clear();
    LCD_ChipSelect(DISABLE);
    Init_SPIFullDuplex();
    status = MSD_Init();
    MSD_ChipSelect(DISABLE);
    Init_SPISimplex();
		// Initialize LCD
    LCD_Init();
    LCD_ChipSelect(ENABLE);
    LCD_Clear();
    LCD_PrintString(LCD_LINE1, ENABLE, DISABLE, "     Init");
    if (status == MSD_RESPONSE_NO_ERROR)
    {
        LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, "     PASS");
        LED2_ON();
        PlayNote(NOTE_RE, 4, 100);
    }
    else
    {
        LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, "     FAIL");
        PlayNote(NOTE_DO, 3, 200);
        MenuUpdate(UP);
        return;
    }
    // Clear LCD
    LCD_Clear();
    // Disable Chip select
    LCD_ChipSelect(DISABLE);
		
		// Write block into MicroSD 
    Init_SPIFullDuplex();
    MSD_ChipSelect(ENABLE);
    status = MSD_WriteBlock(Tx_Buffer, (uint32_t)0, BufferSize);
    MSD_ChipSelect(DISABLE);
    Init_SPISimplex();
		// Initialize LCD
    LCD_Init();
    LCD_ChipSelect(ENABLE);
    LCD_Clear();
    LCD_PrintString(LCD_LINE1, ENABLE, DISABLE, "  Write Block");
    if (status == MSD_RESPONSE_NO_ERROR)
    {
        LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, "     PASS");
        LED3_ON();
        PlayNote(NOTE_RE, 4, 100);
    }
    else
    {
        LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, "     FAIL");
        PlayNote(NOTE_DO, 3, 200);
        MenuUpdate(UP);
        return;
    }
    // Delay to display 
    WaitDelay(100);

    // Read block from MicroSD 
    LCD_Clear();
    LCD_ChipSelect(DISABLE);
    Init_SPIFullDuplex();
    MSD_ChipSelect(ENABLE);
    status = MSD_ReadBlock(Rx_Buffer, (uint32_t)0, BufferSize);
    MSD_ChipSelect(DISABLE);
    Init_SPISimplex();
		// Initialize LCD
    LCD_Init();
    LCD_ChipSelect(ENABLE);
    LCD_Clear();
    LCD_PrintString(LCD_LINE1, ENABLE, DISABLE, "  Read Block");
    if (status == MSD_RESPONSE_NO_ERROR)
    {
        LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, "     PASS");
        SD_ERROR = 0;
        i=0;
        while ((!SD_ERROR)&& (i < BufferSize))
        {
            if (Rx_Buffer[i] != Tx_Buffer[i])
            {
                SD_ERROR = 1;
            }
            else
            {
                i++;
            }
        }
        LED4_ON();
        PlayNote(NOTE_RE, 4, 100);
    }
    else
    {
        LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, "     FAIL");
        PlayNote(NOTE_DO, 3, 200);
        MenuUpdate(UP);
        return;
    }
    // Delay to display 
    WaitDelay(100);

    // Data verification 
    LCD_Clear();
		WaitDelay(100);
    LCD_PrintString(LCD_LINE1, ENABLE, DISABLE, "  DATA Check");
    if (SD_ERROR)
    {
        LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, "     FAIL");
    }
    else
    {
        LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, "     PASS");
    }
    // Delay to display 
    WaitDelay(200);

    // Navigate into read buffer 
    LCD_Clear();
		WaitDelay(100);
    LCD_PrintString(LCD_LINE1, ENABLE, DISABLE, " LEFT or RIGHT");
    LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, "  to see data");
    WaitDelay(200);

    address = 0;

    while (1)
    {
        Key = ReadJoystick();
        if ((Key == LEFT) || (Key == RIGHT))
        {
            if (Key == LEFT)
            {
               if (address == 0x00) 
							 {
							   address = BufferSize; 
						   }	
							 else 
							 {
							   address --;
					     }	
            }
            else
            {
							 if (address == BufferSize-1)
               { 							 
							    address = 0x00;
						   } 
							 else
               {
  							 address ++;
               }
			      }			 
			      LCD_ClearLine(LCD_LINE1);
            LCD_SetCursorPos(LCD_LINE1, 0);
            LCD_PrintString(LCD_LINE1, DISABLE, DISABLE, "Addr: 0x");
            LCD_PrintHex2((uint8_t)(address));
            LCD_PrintString(LCD_LINE1, ENABLE, ENABLE, "");
            LCD_ClearLine(LCD_LINE2);
            LCD_SetCursorPos(LCD_LINE2, 0);
            LCD_PrintString(LCD_LINE2, DISABLE, DISABLE, "Character: ");
						LCD_PrintChar(Rx_Buffer[address]);
            LCD_PrintString(LCD_LINE2, ENABLE, ENABLE, "");
        }
        if (Key == UP)
        {
            MenuUpdate(Key);
            return;
        }
    }
}

