⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eeprom_i2c.c

📁 SHARP_ARM720T_LH79524/5软件开发包_支持TFT_LCD_NAND_FLASH_ETH_USB
💻 C
字号:
/***********************************************************************
 * $Workfile:   eeprom_i2c.c  $
 * $Revision:   1.2  $
 * $Author:   NambiarA  $
 * $Date:   Dec 30 2004 14:05:30  $
 *
 * Project: LH79524 EEPROM test
 *
 * Description: This file contains the basic eeprom tests where the
 *              I2C interface is a 7 bit Master.  These tests contain
 *              all code required to interface with an external EEPROM.
 *
 *              This test write/read/compare with exactly one sector of
 *              the EEPROM.  If there is a boot sector in the EEPROM,
 *              it will be destroyed.
 *
 *              This test assumes the presence of a terminal emulator
 *              connected to the first com port in order to display
 *              the results of the test.
 *
 * Local Includes:
 *
 * Revision History:
 * $Log::   $
 * 
 *    Rev 1.2   Dec 30 2004 14:05:30   NambiarA
 * Modified send_eeprom_address for Multimaster Mode operation
 * 
 *    Rev 1.1   Oct 14 2004 17:52:36   TilburyC
 * Fixed problem with reading eeprom at 400kbpS 
 *
 *    Rev 1.0   Oct 13 2004 16:58:52   TilburyC
 * Initial revision.
 *
 *
 ***********************************************************************
 *
 *  Copyright (c) 2004 Sharp Microelectronics of the Americas
 *
 *  All rights reserved
 *
 *  SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
 *  OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
 *  AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES,
 *  SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
 *
 *  SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY
 *  FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A
 *  SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
 *  FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
 *
 **********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include "sdk79524_board.h"
#include "lh79524_iocon.h"
#include "lh79524_gpio.h"
#include "lh79524_int_driver.h"
#include "eeprom_i2c.h"
#include "console.h"

#define I2C_EEPROM_ADDR 0xA0
static INT_32   dev_i2c;


/**********************************************************************
 *
 *  Function: init_i2c()
 *
 *  Purpose:
 *      Initialize the i2c interface for read and write using
 *      interrupts.
 *
 *  Processing:
 *      See comments below.
 *
 *  Parameters: None
 *
 *  Outputs:
 *      I2C configuration, VIC configuration, and IOCON regs.
 *
 *  Returns:
 *      0 upon success, otherwise retuns a non zero value that
 *      indicates an error has happened.
 *
 *  Notes:
 *      1.  This funciton must be called before any I2C function.
 *      2.  This function depends on having the VIC interface already
 *          open
 *
 *********************************************************************/
INT_32 init_i2c(void)
{
    PFV handler;

    /* open the I2C port with default parameters.  Sets it to 7
        bit master at the slow speed */
    if((dev_i2c = i2c_open(I2C_BASE, 0)) == 0)
        return _ERROR;

    i2c_ioctl(dev_i2c, I2C_IOCTL_GET_ISR, (INT_32)&handler);
    i2c_ioctl(dev_i2c, I2C_IOCTL_ENA_INTERRUPT, 0);

    /* instantiate the interrupt handler */
    create_irq_interrupt(VIC_I2C, VIC_VECT_1, handler);

    /* Configure IOCON pin multiplexing for I2C operation */
    /* clear the configuration bits in case the were being used for
        something else */
    IOCON->mux_ctl_4 &= IOCON_MUX_MASK(IOCON_RES4_PA7_CTCAP2B_CTCMP2B_SCL);
    IOCON->mux_ctl_4 &= IOCON_MUX_MASK(IOCON_RES4_PA6_CTCAP2A_CTCMP2A_SDA);
    /* set configuration the bits */
    IOCON->mux_ctl_4 |= IOCON_MUX4_SCL;
    IOCON->mux_ctl_4 |= IOCON_MUX4_SDA;

    /* clear the resistor control bits, setting them for floating
        behavior */
    IOCON->res_ctl_4 &= IOCON_MUX_MASK(IOCON_RES4_PA7_CTCAP2B_CTCMP2B_SCL);
    IOCON->res_ctl_4 &= IOCON_MUX_MASK(IOCON_RES4_PA6_CTCAP2A_CTCMP2A_SDA);

    return _NO_ERROR;
}


/**********************************************************************
 *
 *  Function: init_eeprom()
 *
 *  Purpose:
 *      Initialize the i2c interface for read and write using
 *      interrupts.  Then init the eeprom and get it ready for
 *      read and write operations.
 *
 *  Processing:
 *      See comments below.
 *
 *  Parameters:
 *      speed   - If speed is 0, then use low speed (100kbpS) otherwise,
 *                use the high speed (400kbpS).
 *
 *  Outputs:
 *      I2C configuration, VIC configuration, and IOCON regs.
 *
 *  Returns:
 *      0 upon success, otherwise retuns a non zero value that
 *      indicates an error has happened.
 *
 *  Notes:
 *      1.  This funciton must be called before any I2C function.
 *      2.  This function depends on having the VIC interface already
 *          open
 *
 *********************************************************************/
INT_32 init_eeprom(void)
{
    /* set up the i2c interface */
    if(init_i2c() != _NO_ERROR)
        return _ERROR;


    return _NO_ERROR;
}


/**********************************************************************
 *
 *  Function: read_eeprom_buffer()
 *
 *  Purpose:
 *      Read a buffer full of data from the EEPROM.
 *
 *  Processing:
 *      See comments below
 *
 *  Parameters:
 *      buffer  - location to put the data into
 *      buflen  - maximum number of bytes that can be written
 *                  into the buffer
 *  Outputs:
 *      none
 *
 *  Returns:
 *      The number of bytes actually read from the EEPROM.  If there
 *      was an error, then return a negative number.
 *
 *  Notes:
 *      none
 *
 *********************************************************************/
INT_32 read_eeprom_buffer(INT_32 addr, CHAR *buffer, INT_32 buflen)
{
    int idx;


    /* wait for the I2C bus to be idle */
    if(i2c_ioctl(dev_i2c, I2C_IOCTL_WAIT_IDLE, 0) == _ERROR)
    {
		while(1);    
    
        return -1;
    }

    /* send the address of the EEPROM with the write bit cleared */
    //if(i2c_write(dev_i2c, I2C_EEPROM_ADDR) != 1)
    if(send_eeprom_address() == _ERROR)
    {
		while(1);    
    
        return -1;
    }

    /* send the first word address (MSBs of address) */
    if(i2c_write(dev_i2c, (addr >> 8), 0) != 1)
    {
		while(1);    
    
        return -1;
    }

    /* send the second word address (LSBs of address) Set the Stop so
        the direction can be reversed */
    if(i2c_write(dev_i2c, (addr & 0xFF), I2C_RESTART) != 1)
    {
		while(1);    
        return -1;
    }

    /* send the address of the EEPROM with the read bit set */
    if(i2c_write(dev_i2c, I2C_EEPROM_ADDR | 0x01, I2C_READ) != 1)
    {
		while(1);    
        return -1;
    }

    /* read the entire buffer */
    for(idx = 0; idx < buflen - 1; idx++)
    {
        if(i2c_read(dev_i2c, (CHAR *)&buffer[idx], I2C_READ) != 1)
        {
			while(1);    
            return -1;
        }
    }

    /* set the stop state after the last byte */
    if(i2c_read(dev_i2c, (CHAR *)&buffer[idx++], I2C_READ|I2C_STOP) != 1)
    {
		while(1);    
        return -1;
    }

    return idx;
}


/**********************************************************************
 *
 *  Function: write_eeprom_buffer()
 *
 *  Purpose:
 *      Write a buffer full of data to the EEPROM.
 *
 *  Processing:
 *      See comments below
 *
 *  Parameters:
 *      buffer  - location to take the data from
 *      buflen  - number of bytes that are in the buffer.
 *
 *  Outputs:
 *      none
 *
 *  Returns:
 *      The number of bytes actually written to the EEPROM.  If there
 *      was an error, then return a negative number.
 *
 *  Notes:
 *      none
 *
 *********************************************************************/
INT_32 write_eeprom_buffer(INT_32 addr, CHAR *buffer, INT_32 buflen)
{
    INT_32 idx;

    /* wait for the I2C bus to be idle */
    if(i2c_ioctl(dev_i2c, I2C_IOCTL_WAIT_IDLE, 0) == _ERROR)
    {
		while(1);    
        return -1;
    }

    /* send the address of the EEPROM with the write bit cleared */
    if(send_eeprom_address() == _ERROR)
    {
		while(1);    
        return -1;
    }

    /* send the first word address (MSBs of address) */
    if(i2c_write(dev_i2c, (addr >> 8), 0) != 1)
    {
		while(1);    
        return -1;
    }

    /* send the second word address (LSBs of address) */
    if(i2c_write(dev_i2c, (addr & 0xFF), 0) != 1)
    {
		while(1);    
        return -1;
    }

    /* write the burst of bytes, one-at-a-time */
    for(idx = 0; idx < buflen-1; idx++)
    {
        if(i2c_write(dev_i2c, buffer[idx], 0) != 1)
        {
			while(1);    
            return -1;
        }
    }

    /* send the last byte to write with the stop bit set */
    if(i2c_write(dev_i2c, buffer[idx++], I2C_STOP) != 1)
    {
		while(1);    
        return -1;
    }

    return idx;
}

/**********************************************************************
 *
 *  Function: read_eeprom_byte()
 *
 *  Purpose:
 *      Read a byte of data from the EEPROM.
 *
 *  Processing:
 *      See comments below
 *
 *  Parameters:
 *      addr    - location in the eeprom to read from
 *      buffer  - location to put the data into
 *
 *  Outputs:
 *      none
 *
 *  Returns:
 *      1 upon success.  If there was an error, then return a
 *      negative number.
 *
 *  Notes:
 *      none
 *
 *********************************************************************/
INT_32 read_eeprom_byte(INT_32 addr, CHAR *buffer)
{
    /* wait for the I2C bus to be idle */
    if(i2c_ioctl(dev_i2c, I2C_IOCTL_WAIT_IDLE, 0) == _ERROR)
    {
		while(1);    
    
        return -1;
    }

    /* send the address of the EEPROM with the write bit cleared */
    if(send_eeprom_address() == _ERROR)
    {
		while(1);    
        return -1;
    }

    /* send the first word address (MSBs of address) */
    if(i2c_write(dev_i2c, (addr >> 8), 0) != 1)
    {
		while(1);    
        return -1;
    }

    /* send the second word address (LSBs of address) Set the Stop so
        the direction can be reversed */
    if(i2c_write(dev_i2c, (addr & 0xFF), I2C_RESTART) != 1)
    {
		while(1);    
        return -1;
    }

    /* send the address of the EEPROM with the read bit set */
    if(i2c_write(dev_i2c, I2C_EEPROM_ADDR | 0x01, I2C_READ) != 1)
    {
		while(1);    
        return -1;
    }

    if(i2c_read(dev_i2c, buffer, I2C_STOP|I2C_READ) != 1)
    {
		while(1);    
        return -1;
    }

    return 1;
}

/**********************************************************************
 *
 *  Function: write_eeprom_byte()
 *
 *  Purpose:
 *      Write a byte of data to the EEPROM.
 *
 *  Processing:
 *      See comments below
 *
 *  Parameters:
 *      addr    - location in the eeprom to write to
 *      buffer  - the data to write
 *
 *  Outputs:
 *      none
 *
 *  Returns:
 *      1 upon success.  If there was an error, then return a
 *      negative number.
 *
 *  Notes:
 *      none
 *
 *********************************************************************/
INT_32 write_eeprom_byte(INT_32 addr, CHAR buffer)
{
    /* wait for the I2C bus to be idle */
    if(i2c_ioctl(dev_i2c, I2C_IOCTL_WAIT_IDLE, 0) == _ERROR)
    {
		while(1);    
        return -1;
    }

    /* send the address of the EEPROM with the write bit cleared */
    if(send_eeprom_address() == _ERROR)
    {
		while(1);    
        return -1;
    }

    /* send the first word address (MSBs of address) */
    if(i2c_write(dev_i2c, (addr >> 8), 0) != 1)
    {
		while(1);    
        return -1;
    }

    /* send the second word address (LSBs of address) */
    if(i2c_write(dev_i2c, (addr & 0xFF), 0) != 1)
    {
		while(1);    
        return -1;
    }

    /* send the byte to write with the stop bit set */
    if(i2c_write(dev_i2c, buffer, I2C_STOP) != 1)
    {
		while(1);    
        return -1;
    }

    return 1;
}

/**********************************************************************
 *
 *  Function: send_eeprom_address()
 *
 *  Purpose:
 *      Send the eeprom address, waiting for the eeprom to not be
 *      busy.
 *
 *  Processing:
 *      Send a fake address to the eeprom.  If it is busy, then it
 *      will NACK the address.  That will be discovered by looking
 *      for a new TX_ABORT from the interface.  If the fake address
 *      is sent without recieving a TX_ABORT in response, then the
 *      real address is sent and processing continues.
 *
 *  Parameters:
 *      none
 *
 *  Outputs:
 *      none
 *
 *  Returns:
 *      _NO_ERROR if the EEPROM address was sent successfully.  If the
 *      address could not be sent, then return _ERROR.
 *
 *  Notes:
 *      If there is a catastrophic problem, this function will loop
 *      forever.
 *
 *********************************************************************/
INT_32 send_eeprom_address(void)
{
    UNS_32 old_aborts, new_aborts;

    do
    {
        /* find out the current number of TX aborts */
        i2c_ioctl(dev_i2c, I2C_IOCTL_GET_TXABORTS, (UNS_32)&old_aborts);

        /*it is quite possible that we might get an error
         so we check for aborts*/
        i2c_write(dev_i2c, I2C_EEPROM_ADDR, I2C_STOP);

        /* TX aborts are asserted after the interface is idle. */
        if(i2c_ioctl(dev_i2c, I2C_IOCTL_WAIT_IDLE, 0) == _NO_ERROR)
        {
            /* find if a new TX abort was asserted */
            i2c_ioctl(dev_i2c, I2C_IOCTL_GET_TXABORTS, (UNS_32)&new_aborts);
        }
        else
        {
            /* the isterface cannot go to idle state */
			while(1);    
            return _ERROR;
        }

    /* while there are new tx aborts being generated */
    } while(old_aborts != new_aborts);

    /* send the real address */
    if(i2c_write(dev_i2c, I2C_EEPROM_ADDR, 0) != 1)
    {
        /* the real address could not be written */
		while(1);    
        return _ERROR;
    }

    return _NO_ERROR;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -