/******************************************************************************
 *                   WIRELESS COMMUNICATION SYSTEM DEVELOPMENT
 *
 *             (C) 2002 Texas Instruments France. All rights reserved
 *
 *                          Author : Philippe MARTINEZ
 *
 *
 *  Important Note
 *  --------------
 *
 *  This S/W is a preliminary version. It contains information on a product 
 *  under development and is issued for evaluation purposes only. Features 
 *  characteristics, data and other information are subject to change.
 *
 *  The S/W is furnished under Non Disclosure Agreement and may be used or
 *  copied only in accordance with the terms of the agreement. It is an offence
 *  to copy the software in any way except as specifically set out in the 
 *  agreement. No part of this document may be reproduced or transmitted in any
 *  form or by any means, electronic or mechanical, including photocopying and
 *  recording, for any purpose without the express written permission of Texas
 *  Instruments Inc.
 *
 ******************************************************************************
 *
 *  FILE NAME: lcd_if.c
 *
 *
 *  PURPOSE:  LCD Interface driver compiled in 16-bits mode (thumb mode)
 *
 *
 *  FILE REFERENCES:
 *
 *  Name                  IO      Description
 *  -------------         --      ---------------------------------------------
 *  
 *
 *
 *  EXTERNAL VARIABLES:
 *
 *  Source:
 *
 *  Name                  Type              IO   Description
 *  -------------         ---------------   --   ------------------------------
 *
 *
 *
 *  EXTERNAL REFERENCES:
 *
 *  Name                Description
 *  ------------------  -------------------------------------------------------
 *
 *
 *
 *  ABNORMAL TERMINATION CONDITIONS, ERROR AND WARNING MESSAGES:
 *  
 *
 *
 *  ASSUMPTION, CONSTRAINTS, RESTRICTIONS:
 *  
 *
 *
 *  NOTES:
 *  
 *
 *
 *  REQUIREMENTS/FUNCTIONAL SPECIFICATION REFERENCES:
 *
 *
 *
 *
 *  DEVELOPMENT HISTORY:
 *
 *  Date         Name(s)           Version  Description
 *  -----------  --------------    -------  -------------------------------------
 *  30-Oct-2002  Philippe MARTINEZ  0.0.1    First implementation
 *
 *  ALGORITHM: 
 *
 *
 *****************************************************************************/

#include "r2d/lcds/e_sample/lcd_if.h"
#include "memif/mem.h"


  /****************************************************************************
   *                         GLOBAL VARIABLES 
   ***************************************************************************/

   /* internal structure instance */

   T_LCD_IF_INTERNAL d_lcd_if_internal;

  /****************************************************************************
   *                         INTERNAL FUNCTION PROTOTYPE 
   ***************************************************************************/
 
   void f_lcd_if_set_cs_and_data_type( E_LCD_IF_CS d_cs, 
                                              E_LCD_IF_DATA_TYPE d_type, 
                                              E_LCD_IF_DATA_ACCESS d_access );
                                              
   static E_LCD_IF_CALLBACK_RET f_lcd_if_dummy_callback( void );



  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_init
   *
   *    Initialize the internal initialization structure.
   *
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  d_cs  		 E_LCD_IF_CS            I   LCD Controller Chip select
   *  p_init         T_LCD_IF_INIT*         I   Pointer on the external initialization 
   *                                            structure
   * RETURN VALUE: None
   *
   *****************************************************************************/

  void f_lcd_if_init( E_LCD_IF_CS   d_cs, T_LCD_IF_INIT *p_init ) 
  {

    /* reset internal state to IDLE */

    d_lcd_if_internal.d_interrupt_state = C_LCD_IF_IDLE;

    /* What is the chip select value ? */

    if( d_cs == C_LCD_IF_CS_NOT_SELECTED )
	{
	  /* not a valid CS */
	  return;
	} // End if

	/* update current struct pointer */

	//d_lcd_if_internal.p_current_struct = &d_lcd_if_internal.d_cs_struct[d_cs];
  
    /* Copy the LCD manager init structure to the internal structure */
	/* and initialize the internal structure */

	d_lcd_if_internal.d_cs_struct[d_cs].d_mode               = p_init->d_mode;
	d_lcd_if_internal.d_cs_struct[d_cs].b_flip_bytes         = p_init->b_flip_bytes;
	d_lcd_if_internal.d_cs_struct[d_cs].d_isll               = p_init->d_isll;
	d_lcd_if_internal.d_cs_struct[d_cs].d_tx.d_clock_divider = p_init->d_tx_init.d_clock_divider;
        d_lcd_if_internal.d_cs_struct[d_cs].d_tx.p_callback      = f_lcd_if_dummy_callback;
	d_lcd_if_internal.d_cs_struct[d_cs].d_tx.p_buffer        = (SYS_UWORD16*) NULL;
	d_lcd_if_internal.d_cs_struct[d_cs].d_tx.d_buffer_size   = 0;
	d_lcd_if_internal.d_cs_struct[d_cs].d_rx.d_clock_divider = p_init->d_rx_init.d_clock_divider;
	d_lcd_if_internal.d_cs_struct[d_cs].d_rx.d_dummy_cycles  = p_init->d_rx_init.d_dummy_cycles;

	/* compose the CNTL_REG and LCD_CNTL_REG bit fields */

	d_lcd_if_internal.d_cs_struct[d_cs].d_cntl_reg = 
	 (C_LCD_IF_CNTL_REG_SOFT_NRST_INIT                         << C_LCD_IF_CNTL_REG_SOFT_NRST_POS)            |
	 (C_LCD_IF_CNTL_REG_CLOCK13_EN_INIT                        << C_LCD_IF_CNTL_REG_CLOCK13_EN_POS)           |
	 (d_lcd_if_internal.d_cs_struct[d_cs].d_tx.d_clock_divider << C_LCD_IF_CNTL_REG_TX_CLOCK_DIV_POS)         |
	 (d_lcd_if_internal.d_cs_struct[d_cs].d_rx.d_clock_divider << C_LCD_IF_CNTL_REG_RX_CLOCK_DIV_POS)         |
	 (C_LCD_IF_CNTL_REG_FIFO_EMPTY_IT_EN_INIT                  << C_LCD_IF_CNTL_REG_FIFO_EMPTY_IT_EN_POS)     |
	 (C_LCD_IF_CNTL_REG_LCD_READ_EVENT_IT_EN_INIT              << C_LCD_IF_CNTL_REG_LCD_READ_EVENT_IT_EN_POS) |
	 (C_LCD_IF_CNTL_REG_DMA_EN_INIT                            << C_LCD_IF_CNTL_REG_DMA_EN_POS)               |
	 (d_lcd_if_internal.d_cs_struct[d_cs].d_mode               << C_LCD_IF_CNTL_REG_MODE_POS)                 |
	 (d_lcd_if_internal.d_cs_struct[d_cs].b_flip_bytes         << C_LCD_IF_CNTL_REG_FLIP_BYTES_POS)           |
	 (C_LCD_IF_CNTL_REG_SUSPEND_EN_INIT                        << C_LCD_IF_CNTL_REG_SUSPEND_EN_POS)           |
	 (C_LCD_IF_CNTL_REG_MIN_FRAME_SIZE_INIT                    << C_LCD_IF_CNTL_REG_MIN_FRAME_SIZE_POS)       |
	 (d_lcd_if_internal.d_cs_struct[d_cs].d_rx.d_dummy_cycles  << C_LCD_IF_CNTL_REG_N_DUMMY_POS);

	d_lcd_if_internal.d_cs_struct[d_cs].d_lcd_cntl_reg = 
	 (d_cs                                                     << C_LCD_IF_LCD_CNTL_REG_LCD_NCS0_POS)         |
	 (C_LCD_IF_LCD_CNTL_REG_LCD_RS_INIT                        << C_LCD_IF_LCD_CNTL_REG_LCD_RS_POS)           |
	 (C_LCD_IF_LCD_CNTL_REG_LCD_START_READ_INIT                << C_LCD_IF_LCD_CNTL_REG_LCD_START_READ_POS)   |
	 (C_LCD_IF_LCD_CNTL_REG_LCD_NRESET_INIT                    << C_LCD_IF_LCD_CNTL_REG_LCD_NRESET_POS)       |
	 (~d_cs                                                    << C_LCD_IF_LCD_CNTL_REG_LCD_NCS1_POS);

    /* Force Switch to Chip select */

    d_lcd_if_internal.d_current_cs = C_LCD_IF_CS_NOT_SELECTED;

    /* Switch to chip select */
    /* Set data type and access to instruction (arbitrary) and write */

    f_lcd_if_set_cs_and_data_type( d_cs, C_LCD_IF_INSTRUCTION, C_LCD_IF_WRITE );
  
  } /* f_lcd_if_init */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_reset
   *
   *    Reset the LCD Interface Hardware.
   *
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  None 
   *                                            
   * RETURN VALUE: None
   *
   *****************************************************************************/

  void f_lcd_if_reset( void )
  {
     /* Reset CNTL_REG:SOFT_NRST bit */

    (*(volatile SYS_UWORD16*) C_LCD_IF_CNTL_REG) &= ~(C_LCD_IF_CNTL_REG_SOFT_NRST_MASK);

     /* loop to wait for CNTL_REG:SOFT_NRST bit return back to 1 */

     F_LCD_IF_WAIT_LCD_IF_RESET;

  } /* f_lcd_if_reset */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_get_version
   *
   *    Return the LCD Interface driver version.
   *
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  None 
   *                                            
   * RETURN VALUE: SYS_UWORD16 : Version number.
   *
   *****************************************************************************/

  SYS_UWORD16 f_lcd_if_get_version( void )
  {
    return ((SYS_UWORD16) C_LCD_IF_DRIVER_VERSION);
  } /* f_lcd_if_get_version */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_reset_lcd_controller
   *
   *    Resets the LCD Controller hardware.
   *
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  d_cs  	     E_LCD_IF_CS            I   LCD Controller Chip select 
   *  d_reset        E_LCD_IF_RESET         I   ON => reset state
   *                                        
   * RETURN VALUE: None
   *
   *****************************************************************************/

  void f_lcd_if_reset_lcd_controller( E_LCD_IF_CS     d_cs,
                                      E_LCD_IF_RESET d_reset )
  {
    /* Switch to chip select */
    /* Set data type and access to instruction (arbitrary) and write */

    f_lcd_if_set_cs_and_data_type( d_cs, C_LCD_IF_INSTRUCTION, C_LCD_IF_WRITE );

   /* Apply the LCD Controller reset on the LCD Interface line (LCD_CNTL_REG:LCD_nRESET bit) */
    if( d_reset == C_LCD_IF_OFF)
    {
      (*(volatile SYS_UWORD16*) C_LCD_IF_LCD_CNTL_REG) |= (d_reset << C_LCD_IF_LCD_CNTL_REG_LCD_NRESET_POS);
    }
    else
    {
      (*(volatile SYS_UWORD16*) C_LCD_IF_LCD_CNTL_REG) &= ~(d_reset << C_LCD_IF_LCD_CNTL_REG_LCD_NRESET_POS);      
    } // End if
    
  } /* f_lcd_if_reset_lcd_controller */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_clock
   *
   *    Enable/disable the LCD Interface 13 MHx clock in.
   *
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  d_clock_switch E_LCD_IF_CLOCK         I   CLOCK_ON/CLOCK_OFF state
   *                                        
   * RETURN VALUE: None
   *
   *****************************************************************************/

  void f_lcd_if_clock( E_LCD_IF_CLOCK d_clock_switch )
  {
    /* write argument into CNTL_REG:CLOCK13_EN bit */
    
    if( d_clock_switch == C_LCD_IF_CLOCK_ON )
    {
      (*(volatile SYS_UWORD16*) C_LCD_IF_CNTL_REG) |= (d_clock_switch << C_LCD_IF_CNTL_REG_CLOCK13_EN_POS);
    }
    else
    {
      (*(volatile SYS_UWORD16*) C_LCD_IF_CNTL_REG) &= ~(d_clock_switch << C_LCD_IF_CNTL_REG_CLOCK13_EN_POS);    
    } // End if

  } /* f_lcd_if_clock */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_poll_write
   *
   *    LCD Controller write procedure in polling mode.
   *
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  d_cs  		 E_LCD_IF_CS            I   LCD Controller Chip select 
   *  p_data         SYS_UWORD16*           I   pointer on data buffer
   *  d_size         SYS_UWORD32            I   data buffe size
   *  d_type         E_LCD_IF_DATA_TYPE     I   Instruction / Data type selector
   *                                        
   * RETURN VALUE: None
   *
   *****************************************************************************/

  void f_lcd_if_poll_write( E_LCD_IF_CS        d_cs,
                            SYS_UWORD16        *p_data,
                            SYS_UWORD32        d_size,
                            E_LCD_IF_DATA_TYPE d_type )
  {

    SYS_UWORD32    d_nb_words_to_copy = d_size;
    SYS_UWORD32    d_nb_words_in_loop = 0;
    SYS_UWORD16    *p_buffer          = p_data;
    SYS_UWORD8     d_data_type        = 0;
    SYS_UWORD8     i                  = 0;

    /* Switch to chip select */
    /* Set data type and access */

    f_lcd_if_set_cs_and_data_type( d_cs, d_type, C_LCD_IF_WRITE );
        
    /* infinite loop : exit loop when no words to copy and Tx FIFO empty */

    while( C_LCD_IF_INFINITE_LOOP )
	{

      /*  Wait for the LCD Interface Tx FIFO is empty LCD_IF_STS_REG:FIFO_EMPTY_STATUS_BIT */

      F_LCD_IF_WAIT_TX_FIFO_EMPTY;

   	  /* Check if all data have been copied */

      if( d_nb_words_to_copy == 0 )
	  {
	    return;
	  } // End if

      /* Copy up to C_LCD_IF_TX_FIFO_SIZE words into the TX FIFO. */

	  if( d_nb_words_to_copy >= C_LCD_IF_TX_FIFO_SIZE)
	  {
	    d_nb_words_in_loop = C_LCD_IF_TX_FIFO_SIZE; 
      }
	  else
	  {
	    d_nb_words_in_loop = d_nb_words_to_copy; 
	  } // End if

      for( i=0; i<d_nb_words_in_loop ;i++ )
	  {
	    F_LCD_IF_WRITE_IN_FIFO( p_buffer[i] );
      } // End for

      /* update d_nb_words_to copy and p_buffer */
      d_nb_words_to_copy -=  d_nb_words_in_loop;
	  p_buffer           +=  d_nb_words_in_loop;

	} // End while
    
  } /* f_lcd_if_poll_write */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_poll_read
   *
   *    LCD Controller read procedure in polling mode.
   *
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  d_cs  		 E_LCD_IF_CS            I   LCD Controller Chip select 
   *  d_type         E_LCD_IF_DATA_TYPE     I   Instruction / Data type selector
   *                                        
   * RETURN VALUE: SYS_UWORD16 : read data word
   *
   *****************************************************************************/

  SYS_UWORD16 f_lcd_if_poll_read( E_LCD_IF_CS        d_cs,
                                  E_LCD_IF_DATA_TYPE d_type )
  {

    SYS_UWORD8  d_data_type = 0;

    /* Switch to chip select */
    /* Set data type and access */

    f_lcd_if_set_cs_and_data_type( d_cs, d_type, C_LCD_IF_READ );
   
   /* Wait for data received from the LCD Controller hardware */

   F_LCD_IF_WAIT_READ_STATUS;

   /* retrieve data read */

   return (*(volatile SYS_UWORD16*) C_LCD_IF_RD_REG);
   
  } /* f_lcd_if_poll_read */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_it_write
   *
   *    LCD Controller write procedure in interrupt mode.
   *	Direct access to the data buffer
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  d_cs  		 E_LCD_IF_CS            I   LCD Controller Chip select 
   *  p_buffer       SYS_UWORD16            I   Pointer to the data buffer
   *  d_size         SYS_UWORD32            I   Data buffer size
   *  d_type         E_LCD_IF_DATA_TYPE     I   Instruction / Data type selector
   *  pf_callback_sts T_LCD_IF_CALLBACK     I   Status callback function pointer.
   *                                        
   * RETURN VALUE: E_LCD_IF_RET function status.
   *
   *****************************************************************************/

  E_LCD_IF_RET f_lcd_if_it_write( E_LCD_IF_CS        d_cs,
                                  SYS_UWORD16        *p_buffer,
                                  SYS_UWORD32        d_size,
                                  E_LCD_IF_DATA_TYPE d_type,
                                  T_LCD_IF_CALLBACK  pf_callback_sts )
  {

    SYS_UWORD8 d_data_type = 0;

    /* Check the callback function argument */

    if( pf_callback_sts == (T_LCD_IF_CALLBACK) NULL )
	  return( C_LCD_IF_RET_ERR );

    /* Switch to chip select */
    /* Set data type and access */

    f_lcd_if_set_cs_and_data_type( d_cs, d_type, C_LCD_IF_WRITE );

    /* save buffer references and install status callback function */

    d_lcd_if_internal.d_cs_struct[d_cs].d_tx.p_callback      = pf_callback_sts;
    d_lcd_if_internal.d_cs_struct[d_cs].d_tx.p_buffer        = p_buffer;
    d_lcd_if_internal.d_cs_struct[d_cs].d_tx.d_buffer_size   = d_size;

    /* set d_interrupt_state to C_LCD_IF_IT_BUFF */
	 
    d_lcd_if_internal.d_interrupt_state = C_LCD_IF_IT_BUFF; 

    /* Enable LCD Interface TX FIFO Empty interrupt */
    
    F_LCD_IF_ENABLE_TX_FIFO_EMPTY_IT;

    return( C_LCD_IF_RET_OK );
       
  } /* f_lcd_if_it_write */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_it_write_cust
   *
   *    LCD Controller write procedure in interrupt mode.
   *	LCD Controller Tx FIFO copy done by transmit callback function.
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  d_cs  		 E_LCD_IF_CS            I   LCD Controller Chip select 
   *  d_type         E_LCD_IF_DATA_TYPE     I   Instruction / Data type selector
   *  pf_callback_tx T_LCD_IF_CALLBACK     I   Transmit callback function pointer.
   *                                        
   * RETURN VALUE: E_LCD_IF_RET function status.
   *
   *****************************************************************************/

  E_LCD_IF_RET f_lcd_if_it_write_cust( E_LCD_IF_CS        d_cs,
                                       E_LCD_IF_DATA_TYPE d_type,
                                       T_LCD_IF_CALLBACK  pf_callback_tx )
  {
	 
	 SYS_UWORD8 d_data_type = 0;

    /* Check the callback function argument */

    if( pf_callback_tx == (T_LCD_IF_CALLBACK) NULL )
	  return( C_LCD_IF_RET_ERR );
	 
    /* Switch to chip select */
    /* Set data type and access */

    f_lcd_if_set_cs_and_data_type( d_cs, d_type, C_LCD_IF_WRITE );

    /* install transmit callback function */

    d_lcd_if_internal.d_cs_struct[d_cs].d_tx.p_callback      = pf_callback_tx;

    /* set d_interrupt_state to C_LCD_IF_IT_CUST */
	 
    d_lcd_if_internal.d_interrupt_state = C_LCD_IF_IT_CUST; 

    /* Enable LCD Interface TX FIFO Empty interrupt */
    
    F_LCD_IF_ENABLE_TX_FIFO_EMPTY_IT;
    
    return( C_LCD_IF_RET_OK );

  } /* f_lcd_if_it_write_cust */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_dma_enable
   *
   *    LCD Controller write procedure start in DMA mode.
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  d_cs  		 E_LCD_IF_CS            I   LCD Controller Chip select 
   *  d_min_frame_sz E_LCD_IF_FRAME_SZ      I   LCD Interface Minimum frame size
   *  d_type         E_LCD_IF_DATA_TYPE     I   Instruction / Data type selector
   *                                        
   * RETURN VALUE: None.
   *
   *****************************************************************************/

  void f_lcd_if_dma_enable( E_LCD_IF_CS        d_cs,
                            E_LCD_IF_FRAME_SZ  d_min_frame_sz,
                            E_LCD_IF_DATA_TYPE d_type )
  {

    SYS_UWORD8 d_data_type = 0;

    /* Switch to chip select */
    /* Set data type and access */

    f_lcd_if_set_cs_and_data_type( d_cs, d_type, C_LCD_IF_WRITE );

    /* enables DMA capabilities */

    F_LCD_IF_ENABLE_DMA;
    
  } /* f_lcd_if_dma_enable */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_dma_disable
   *
   *    LCD Controller write procedure stop in DMA mode.
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  d_cs  		 E_LCD_IF_CS            I   LCD Controller Chip select 
   *  pf_callback_sts T_LCD_IF_CALLBACK     I   Status Callback function pointer
   *                                        
   * RETURN VALUE: E_LCD_IF_RET function status.
   *
   *****************************************************************************/


  E_LCD_IF_RET f_lcd_if_dma_disable( E_LCD_IF_CS         d_cs,             
                                     T_LCD_IF_CALLBACK   pf_callback_sts )
  {

    /* Check the callback function argument */

    if( pf_callback_sts == (T_LCD_IF_CALLBACK) NULL )
	  return( C_LCD_IF_RET_ERR );

    /* disable DMA capabilities */

    F_LCD_IF_DISABLE_DMA;

    /* install status callback function */

    d_lcd_if_internal.d_cs_struct[d_cs].d_tx.p_callback      = pf_callback_sts;

    /* set d_interrupt_state to C_LCD_IF_IT_CUST */
	 
    d_lcd_if_internal.d_interrupt_state = C_LCD_IF_IT_CUST; 

    /* Enable LCD Interface TX FIFO Empty interrupt */
    
    F_LCD_IF_ENABLE_TX_FIFO_EMPTY_IT;

    return( C_LCD_IF_RET_OK );

  } /* f_lcd_if_dma_disable */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_set_cs_and_data_type
   *
   *    Updates CNTL_REG and LCD_CNTL_REG to change LCD Controller addressing.
   *    Updates LCD_CNTL_REG to set data type and read or write access
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  d_cs  	     E_LCD_IF_CS            I   LCD Controller Chip select 
   *  d_type  	     E_LCD_IF_DATA_TYPE     I   data type 
   *  d_access       E_LCD_IF_DATA_ACCESS   I   Data access   
   *                                            
   * RETURN VALUE: None
   *
   *****************************************************************************/

  void f_lcd_if_set_cs_and_data_type( E_LCD_IF_CS d_cs, E_LCD_IF_DATA_TYPE d_type, E_LCD_IF_DATA_ACCESS d_access )
  {

    SYS_UWORD8 d_data_type;    

    /* if the argument equals the current chip select, nothing to do */

    if( d_lcd_if_internal.d_current_cs != d_cs )
	{
      /* What is the chip select value ? */

      if( d_cs == C_LCD_IF_CS_NOT_SELECTED )
	  {
	    /* not a valid CS */
	    return;
	  } // End if

	  /* update current struct pointer */

	  //d_lcd_if_internal.p_current_struct = &d_lcd_if_internal.d_cs_struct[d_cs];
  

	  /* Update CNTL_REG register and LCD_CNTL_REG to the new chip select */
	  /* The CNTL_REG:CLOCK_EN bit is set to Clock enable */

	  (*(volatile SYS_UWORD16*) C_LCD_IF_CNTL_REG)     = d_lcd_if_internal.d_cs_struct[d_cs].d_cntl_reg;
	  (*(volatile SYS_UWORD16*) C_LCD_IF_LCD_CNTL_REG) = d_lcd_if_internal.d_cs_struct[d_cs].d_lcd_cntl_reg;
      
      /* update d_current_cs */

      d_lcd_if_internal.d_current_cs = d_cs;

	} // End if

    /* Sets LCD_CNTL_REG:LCD_RS to type defined in argument and start read */

    if( d_type == C_LCD_IF_INSTRUCTION )
    {
      d_data_type = (SYS_UWORD8) d_lcd_if_internal.d_cs_struct[d_cs].d_isll; 
    }
    else
    {
      d_data_type = (SYS_UWORD8) ~d_lcd_if_internal.d_cs_struct[d_cs].d_isll;
    } // End if

    if( d_data_type == 0 )
    {
      (*(volatile SYS_UWORD16*) C_LCD_IF_LCD_CNTL_REG) &= ~( 0x01 << C_LCD_IF_LCD_CNTL_REG_LCD_RS_POS );
    }
    else
    {
      (*(volatile SYS_UWORD16*) C_LCD_IF_LCD_CNTL_REG) |= ( 0x01 << C_LCD_IF_LCD_CNTL_REG_LCD_RS_POS );
    } // End if

    // Set access type
    
    if( d_access == C_LCD_IF_READ )
    {
      (*(volatile SYS_UWORD16*) C_LCD_IF_LCD_CNTL_REG) |= 
                  (C_LCD_IF_LCD_CNTL_REG_LCD_START_READ_EN << C_LCD_IF_LCD_CNTL_REG_LCD_START_READ_POS);
    }
    else
    {
      (*(volatile SYS_UWORD16*) C_LCD_IF_LCD_CNTL_REG) &= 
                  ~(C_LCD_IF_LCD_CNTL_REG_LCD_START_READ_EN << C_LCD_IF_LCD_CNTL_REG_LCD_START_READ_POS);
    } // End if

  } /* f_lcd_if_set_cs_and_data_type */

  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_dummy_callback
   *
   *    Dummy callback function for Internal structure initialization.
   *
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  None. 
   *                                            
   * RETURN VALUE: E_LCD_IF_CALLBACK_RET
   *
   *****************************************************************************/

   static E_LCD_IF_CALLBACK_RET f_lcd_if_dummy_callback( void )
   {
     /* EMPTY DUMMY FUNCTION */
     
   } /* f_lcd_if_dummy_callback */





  /******************************************************************************
   *
   *  FUNCTION NAME: f_lcd_if_initialization
   *
   *
   *
   *  ARGUMENT LIST:
   *
   *  Argument       Type                   IO  Description
   *  ------------   -------------------    --  ---------------------------------
   *  None. 
   *                                            
   * RETURN VALUE: 
   *
   *****************************************************************************/

   void f_lcd_if_initialization( void )
   {
      T_LCD_IF_INIT init_struct_ptr;
      volatile SYS_UWORD8 i;

      init_struct_ptr.d_mode = C_LCD_IF_8086_MODE;
      init_struct_ptr.b_flip_bytes = C_LCD_IF_LSB_FIRST;
      init_struct_ptr.d_isll = C_LCD_IF_LOW;
      init_struct_ptr.d_tx_init.d_clock_divider = C_LCD_IF_DIV8;
      init_struct_ptr.d_rx_init.d_clock_divider = C_LCD_IF_DIV8;
      init_struct_ptr.d_rx_init.d_dummy_cycles = C_LCD_IF_0_CYCLE;
      

      f_lcd_if_reset();
      f_lcd_if_clock(C_LCD_IF_CLOCK_ON);
      f_lcd_if_init(C_LCD_IF_CS0, &(init_struct_ptr) );
      f_lcd_if_reset_lcd_controller(C_LCD_IF_CS0, C_LCD_IF_ON);
      for(i=0;i<10;i++);
      f_lcd_if_reset_lcd_controller(C_LCD_IF_CS0, C_LCD_IF_OFF);

   } 