view src/cs/drivers/drv_app/r2d/lcds/E_Sample/lcd_if.c @ 303:f76436d19a7a default tip

!GPRS config: fix long-standing AT+COPS chance hanging bug There has been a long-standing bug in FreeCalypso going back years: sometimes in the AT command bring-up sequence of an ACI-only MS, the AT+COPS command would produce only a power scan followed by cessation of protocol stack activity (only L1 ADC traces), instead of the expected network search sequence. This behaviour was seen in different FC firmware versions going back to Citrine, and seemed to follow some law of chance, not reliably repeatable. This bug has been tracked down and found to be specific to !GPRS configuration, stemming from our TCS2/TCS3 hybrid and reconstruction of !GPRS support that was bitrotten in TCS3.2/LoCosto version. ACI module psa_mms.c, needed only for !GPRS, was missing in the TCS3 version and had to be pulled from TCS2 - but as it turns out, there is a new field in the MMR_REG_REQ primitive that needs to be set correctly, and that psa_mms.c module is the place where this initialization needed to be added.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 08 Jun 2023 08:23:37 +0000
parents 4e78acac3d88
children
line wrap: on
line source

/******************************************************************************
 *                   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);

   }