📄 lh7a400_lcd_evb_eeprom_driver.c
字号:
/**********************************************************************
* $Workfile: lh7a400_lcd_evb_eeprom_driver.c $
* $Revision: 1.2 $
* $Author: KovitzP $
* $Date: Nov 21 2001 11:38:28 $
*
* Project: LH7A400
*
* Description:
* This file contains a driver for the EEPROM device on the LCD
* board on LH7A400 evaluation board system.
* The EEPROM is a Microchip 93LC46B 64 x 16 EEPROM.
* Functions provided are:
* lcd_eeprom_driver_init()--Set up the SSP and direct the SSPFRM
* signal to the EEPROM chip select.
* You must call this before calling
* any other EEPROM driver functions
* lcd_eeprom_erase_word()--Erase (set to 0xFFFF) a single EEPROM
* word at the specified address
* lcd_eeprom_erase_all()--Erase (set to 0xFFFF) all EEPROM words
* lcd_eeprom_lock()--Prevent EEPROM write or erase commands from
* working.
* lcd_eeprom_unlock()--Allow EEPROM write or erase commands to work
* lcd_eeprom_read()--Return an EEPROM word from a specifed address
* lcd_eeprom_block_read()--Read a consecutive block of words from
* EEPROM starting at a specified address
* and return the number of words read.
* lcd_eeprom_write()--Write a single EEPROM word at a specifed
* EEPROM address
* lcd_eeprom_fill()--Fill the entire EEPROM with a specified data
* value
*
* Strategy:
* The EEPROM's data format is not quite compatible with the
* MICROWIRE mode on the LH7A400 SSP because the EEPROM command word
* is too long. We have to transmit 16-bit data during writes, and
* we have to read back 16-bit data during reads. We use the SPI mode
* with a 16-bit word length. We use SPH==1 so that SSPFRM will
* remain asserted for the multi-SSP word write commands, and the
* mult-SSP word read commands. See individual functions for
* details.
*
* References:
* SHARP_EVB_DISPLAY_BOARD_REV2.pdf
* 93LC46.pdf (Microchip 1K Microwire(R) EEPROM chip spec).
*
* Requires;
* ssp_driver.h -- serial communications driver
*
* Revision History:
* $Log: P:/PVCS6_6/archives/LH7A400 (Aruba)/SSP/lh7a400_lcd_evb_eeprom_driver.c-arc $
*
* Rev 1.2 Nov 21 2001 11:38:28 KovitzP
* Added function block comments and revised the
* lcd_eeprom_block_read() function to send only as many
* words as requried.
*
* Rev 1.1 Nov 14 2001 09:01:44 KovitzP
* Modified include hierarchy
*
* Rev 1.0 Nov 12 2001 13:32:10 KovitzP
* Initial revision.
*
*
* COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
* CAMAS, WA
*********************************************************************/
#include "lh7a400_lcd_evb_eeprom_driver.h"
/**********************************************************************
*
* Function: eeprom_busy_poll
*
* Purpose:
* Following a write or erase, wait for the EEPROM busy signal to
* go high.
*
* Processing:
* Following an erase or write command, the EEPROM will signal that
* the write or erase operation is complete by transitioning its
* data output from a 0 to a 1 provided that its chip select is
* desserted after the write command completes and reasserted 500 ns
* after the chip select has been deasserted. SSPFRM cannot be
* directly controlled as GPIO pin. This more complex algorithm
* results:
*
* Convert the timeout_in_milliseconds to units of the time it takes
* to send a single word.
* Wait for the last SSP transaction to complete.
* Flush the receive FIFO.
* Wait approximately 500 ns. This time is not really critical.
* It can be longer.
* Write a 0 to the transmit FIFO and then keep writing
* 0 to the transmit FIFO until the data read back from the
* EEPROM is not 0. This keeps the EEPROM's chip select
* asserted while we wait for the EEPROM data output to transition
* from 0 to 1.
*
*
* Parameters:
* timeout_in_milliseconds: approximate number of milliseconds before
* aborting the busy poll operation
*
* Outputs: None
*
* Returns:
* Return 0 if timed out. Otherwise, return 1.
*
* Notes:
*
**********************************************************************/
static INT_32 eeprom_busy_poll(INT_32 timeout_in_milliseconds)
{
int i, timeout_in_words;
timeout_in_words = (ssp_get_speed() *
timeout_in_milliseconds) /
(ssp_get_bits_per_word() *
1000);
/* wait for SSP to be not busy */
while (ssp_busy() )
;
/* flush the receive FIFO */
while (ssp_receive_fifo_not_empty() )
ssp_receive();
/*
assume 10 ns bus speed. Wait at least 500 ns before
checking if write is complete
*/
for (i = 0; i < 50; i++)
;
/* keep CS active by keeping data in the transmit buffer */
ssp_transmit(0);
do
{
ssp_transmit(0);
} while (timeout_in_words-- && ssp_receive() == 0);
/* wait for SSP to be not busy */
while (ssp_busy() )
;
/* flush the receive FIFO */
while (ssp_receive_fifo_not_empty() )
ssp_receive();
/* return success or timeout */
return timeout_in_words != 0;
}
/**********************************************************************
*
* Function: lcd_eeprom_driver_init
*
* Purpose:
* Set up the SSP and direct the SSPFRM signal to the EEPROM
* chip select
*
* Processing:
* Initialize SSP in SPI mode. Set the bits per word to EE_WORDSIZE,
* set the speed to EE_BPS. Turn loopback off, Set SPH so that
* SSPFRM will remain asserted so long as there is data in the
* SSP transmit FIFO. Set SPO so that data changes on the correct
* clock edge given the state of SPH. Switch the SSPFRM mux circuit
* on the CPU board so that SSPFRM will assert the EEPROM chip select
* Enable and flush the FIFOs.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
* must call this before calling any other EEPROM driver functions
*
**********************************************************************/
void lcd_eeprom_driver_init(void)
{
/* set up the SSP for SPI mode, 16-bit word access */
ssp_init_spi_mode();
ssp_set_bits_per_word(EE_WORDSIZE);
ssp_set_speed(EE_BPS);
ssp_loopback_off();
ssp_spi_set_sph(); /* allow for continuous mode transmission */
ssp_spi_set_spo(); /* correct the clock phase */
/* SSPFRM activates the LCD board's serial EEPROM's Chip Select */
lh7a400_evb_ssp_frame_eeprom();
/* enable the FIFOs */
ssp_enable_fifos();
ssp_flush_fifos();
}
/**********************************************************************
*
* Function: lcd_eeprom_erase_word
*
* Purpose:
* Erase (set to 0xFFFF) a single EEPROM word at the specified address
*
* Processing:
* Make sure the SSP is not in use.
* Flush the receive FIFO
* Write the erase word command to the transmit FIFO.
* Poll the EEPROM status until it is not busy anymore.
*
* Parameters:
* adr: The address of the word to erase (0-63)
* timeout_in_milliseconds: number of milliseconds to wait for erase
* operation to complete
*
* Outputs: None
*
* Returns:
* 0 if timed out.
* 1 if successful,
*
* Notes:
* This command will fail if the EEPROM is locked.
*
**********************************************************************/
INT_32 lcd_eeprom_erase_word(INT_32 adr,
INT_32 timeout_in_milliseconds)
{
/* wait for SSP to be not busy */
while (ssp_busy() )
;
/* flush the receive FIFO */
while (ssp_receive_fifo_not_empty() )
ssp_receive();
ssp_transmit(EE_ERASE(adr));
return eeprom_busy_poll(timeout_in_milliseconds);
}
/**********************************************************************
*
* Function: lcd_eeprom_erase_all
*
* Purpose:
* Erase (set to 0xFFFF) all EEPROM words
*
* Processing:
* Make sure the SSP is not in use.
* Flush the receive FIFO
* Write the erase all command to the transmit FIFO.
* Poll the EEPROM status until it is not busy anymore.
*
* Parameters:
* timeout_in_milliseconds: number of milliseconds to wait for erase
* operation to complete
*
* Outputs: None
*
* Returns:
* 0 if timed out.
* 1 if successful,
*
* Notes:
* This command will fail if the EEPROM is locked.
*
**********************************************************************/
INT_32 lcd_eeprom_erase_all(INT_32 timeout_in_milliseconds)
{
/* wait for SSP to be not busy */
while (ssp_busy() )
;
/* flush the receive FIFO */
while (ssp_receive_fifo_not_empty() )
ssp_receive();
ssp_transmit(EE_ERAL );
return eeprom_busy_poll(timeout_in_milliseconds);
}
/**********************************************************************
*
* Function: lcd_eeprom_lock
*
* Purpose:
* Prevent EEPROM write or erase commands from working.
*
* Processing:
* Wait for all pending SSP transmissions to complete. Transmit
* the lock command.
*
* Parameters: None
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -