
/**
 ******************************************************************************
 *
 * @file        MG32_LCM_API.c
 * @brief       LCM display c Code. 
 *
 * @par         Project
 *              MG32
 * @version     V1.03
 * @date        2021/05/28
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2017 MegaWin Technology Co., Ltd.
 *              All rights reserved.
 *
 ******************************************************************************* 
 * @par Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 *******************************************************************************
 */


/* Includes ------------------------------------------------------------------*/
#include "MG32_LCM_API.h"
#include "MG32_TM_MID.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External vairables --------------------------------------------------------*/


/**
 *******************************************************************************
 * @brief       Initial H/W LCM 
 * @param[in]   None
 * @return		None
 *******************************************************************************
 */
void API_LCM_Init(void)
{
    TM_HandleTypeDef hTM;
    TM_ClockConfigTypeDef CKConfig;
    
    // Time Base Init (15ms)
    hTM.Instance = TM10;    
    hTM.Init.TM_CounterMode = TM_CASCADE_UP;
    hTM.Init.TM_Period = 720;
    hTM.Init.TM_Prescaler = 999;
    MID_TM_Base_Init(&hTM);
    
    // Config Clock 
    CKConfig.TM_ClockSource         = TM_INTERNAL_CLOCK;
    CKConfig.TM_InternalClockSource = TM_INTERNALCLOCK_PROC;
    CKConfig.TM_INTClockDivision    = TM_INTERNALCLOCK_DIVDER_DIV1;
#if defined ( __GNUC__ )
    CKConfig.TM_ExternalClockSource = 0;
#else
    CKConfig.TM_ExternalClockSource = NULL;
#endif
    MID_TM_ConfigClockSource(&hTM, &CKConfig);    
    
    // ------------------------------------------------------------------------
    /* Wait 15ms after Power-on */
    __DRV_TM_CLEAR_FLAG(&hTM, TM_FLAG_UPDATE_UP);
    MID_TM_Base_Start(&hTM);
    while(__DRV_TM_GET_FLAG(&hTM,TM_FLAG_UPDATE_UP) == 0);
    MID_TM_Base_Stop(&hTM);
    
    /* Function set (RS=0, RW=0, CMD=0x3C) */
    API_LCM_WriteCMD(FunctionSet);
    
    // ------------------------------------------------------------------------
    /* delay 4.1ms */
    hTM.Init.TM_Period = 984;
    hTM.Init.TM_Prescaler = 199;
    MID_TM_Base_Init(&hTM);
    
    __DRV_TM_CLEAR_FLAG(&hTM, TM_FLAG_UPDATE_UP);
    MID_TM_Base_Start(&hTM);
    while(__DRV_TM_GET_FLAG(&hTM,TM_FLAG_UPDATE_UP) == 0);
    MID_TM_Base_Stop(&hTM);
    
    /* Function set (RS=0, RW=0, CMD=0x3C) */
    API_LCM_WriteCMD(FunctionSet);
    
    // ------------------------------------------------------------------------
    /* delay 4.1ms */
    MID_TM_Base_Init(&hTM);
    
    __DRV_TM_CLEAR_FLAG(&hTM, TM_FLAG_UPDATE_UP);
    MID_TM_Base_Start(&hTM);
    while(__DRV_TM_GET_FLAG(&hTM,TM_FLAG_UPDATE_UP) == 0);
    MID_TM_Base_Stop(&hTM);
    
    /* Function set (RS=0, RW=0, CMD=0x3C) */
    API_LCM_WriteCMD(FunctionSet);
    
    // ------------------------------------------------------------------------
    /* delay 4.1ms */
    MID_TM_Base_Init(&hTM);
    
    __DRV_TM_CLEAR_FLAG(&hTM, TM_FLAG_UPDATE_UP);
    MID_TM_Base_Start(&hTM);
    while(__DRV_TM_GET_FLAG(&hTM,TM_FLAG_UPDATE_UP) == 0);
    MID_TM_Base_Stop(&hTM);
    
    /* Function set  (RS=0, RW=0, CMD=0x3C) */
    API_LCM_WriteCMD(FunctionSet);
    
    // ------------------------------------------------------------------------
    /* delay 4.1ms */
    MID_TM_Base_Init(&hTM);
    
    __DRV_TM_CLEAR_FLAG(&hTM, TM_FLAG_UPDATE_UP);
    MID_TM_Base_Start(&hTM);
    while(__DRV_TM_GET_FLAG(&hTM,TM_FLAG_UPDATE_UP) == 0);
    MID_TM_Base_Stop(&hTM);
    
    /* Function set  (RS=0, RW=0, CMD=0x3C) */
    API_LCM_WriteCMD(FunctionSet);
    
    // ------------------------------------------------------------------------
    /* delay 4.1ms */
    MID_TM_Base_Init(&hTM);
    
    __DRV_TM_CLEAR_FLAG(&hTM, TM_FLAG_UPDATE_UP);
    MID_TM_Base_Start(&hTM);
    while(__DRV_TM_GET_FLAG(&hTM,TM_FLAG_UPDATE_UP) == 0);
    MID_TM_Base_Stop(&hTM);
    
    /* Function set  (RS=0, RW=0, CMD=0x3F) */
    API_LCM_WriteCMD(FunctionSet);

    // ------------------------------------------------------------------------
    /* Display Off (RS=0, RW=0, CMD=0x08) */
    API_LCM_WriteCMD(DisplayOff);
    
    /* Display ON (RS=0, RW=0, CMD=0x0C) */
    API_LCM_WriteCMD(DispayON);
    
    /* Display Clear (RS=0, RW=0, CMD=0x01) */
    API_LCM_WriteCMD(DisplayClear);
    
    /* Entry Mode Set (RS=0, RW=0, CMD=0x06) */
    API_LCM_WriteCMD(EntryMode);
    
    /* return home (RS=0, RW=0, CMD=0x02) */
    API_LCM_WriteCMD(ReturnHome);

}


/**
 *******************************************************************************
 * @brief       Initializes the TM TMe base Unit according to the specified 
 *              parameters in the TM_HandleTypeDef and create the associated handle.
 * @param[in]   hTM : pointer to a TM_HandleTypeDef
 * @return		MID_StatusTypeDef
 * @note 
 * @par         Example
 * @code
    TM_HandleTypeDef hTM;
 
    MID_TM_PWM_Init(&TM_Handle);
 * @endcode
 *******************************************************************************
 */
void API_LCM_Display(uint8_t LCMAddr, uint8_t *String)
{
    // set LCM display address
    API_LCM_WriteCMD(LCMAddrCmd | LCMAddr);
    
    // show string by LCM
    while(*String != 0x00)
    {
        // display a character
        API_LCM_WriteData(*String);
        String ++;
    }
    
        
}


/**
 *******************************************************************************
 * @brief       Clear LCM monitor
 * @param[in]   None
 * @return		None
 *******************************************************************************
 */
void API_LCM_Clear(void)
{
    /* Display Clear  */
    API_LCM_WriteCMD(DisplayClear);
}

/**
 *******************************************************************************
 * @brief       Write LCM command.
 * @param[in]   CMD : LCM command
 * @return		None
 *******************************************************************************
 */
void API_LCM_WriteCMD(uint8_t CMD)
{
    volatile uint16_t i;
    
    // config LCM for Register with Write state
    API_LCM_RW = WriteCommand;
    __NOP(); __NOP(); 
    API_LCM_RS = RegisterSelect;
    
    // set command to LCM-Bus
    API_LCM_WRITE_TO_BUS(CMD);
    
    for(i=0;i<1000;i++);
    API_LCM_EN = ActiveEN; 
    for(i=0;i<1000;i++);
    API_LCM_EN = DeactiveEN; 
    for(i=0;i<1000;i++);
    
}

/**
 *******************************************************************************
 * @brief       Write LCM data.
 * @param[in]   Data : LCM Data
 * @return		None
 *******************************************************************************
 */
void API_LCM_WriteData(uint8_t Data)
{
    volatile uint16_t i;
    
    // config LCM for data with Write state
    API_LCM_RW = WriteCommand;
    __NOP(); __NOP(); 
    API_LCM_RS = DataSelect;
    
    // set data to LCM-Bus
    API_LCM_WRITE_TO_BUS(Data);
    
    for(i=0;i<1000;i++);
    API_LCM_EN = ActiveEN; 
    for(i=0;i<1000;i++);
    API_LCM_EN = DeactiveEN; 
    for(i=0;i<1000;i++);
}

