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

📄 eepst24512.c

📁 TDK 6521 SOC 芯片 DEMO程序
💻 C
字号:
/***************************************************************************
 * This code and information is provided "as is" without warranty of any   *
 * kind, either expressed or implied, including but not limited to the     *
 * implied warranties of merchantability and/or fitness for a particular   *
 * purpose.                                                                *
 *                                                                         *
 * Copyright (C) 2006 Teridian Semiconductor Corp. All Rights Reserved.    *
 ***************************************************************************/
//**************************************************************************
//  DESCRIPTION: 71M65xx POWER METER - Serial EEPROM Routines. 
// 
//  AUTHOR:  RGV
//
//  HISTORY: See end of file
//**************************************************************************
// File: eepromp.c
//**************************************************************************
// High speed polling eeprom API for an ST24512
// This can use only iicdio.c, a fast bit-banging interface.
// Most I2C eeprom drivers can also use iiceep.c, a slower, 
// less power-hungry interface that uses the chip's on-board I2C hardware.
// However, the ST24512 requires an illegal bus transition state
// in its "random read" operation (See ST's data sheet, rev. 5, section
// 3.12.  It requires a "start" without a "stop".  Setting up this condition
// requires an illegal bus transition.)  Conforming I2C hardware cannot 
// perform this operation.
//
#include "options.h"
#if EEPROM && I2C_POLLED
#include "stm.h"
#include "eeprom.h"
#include "iic.h" // polling IIC/I2C interface.

static uint16x_t time_to_write;
static int16x_t timeout_cnt;
enum EEPROM_RC data eeprom_state;

// timeout routines;
#pragma save
#pragma NOAREGS
void timeout_start (void) small reentrant
{
    timeout_cnt = 10000;
}
#pragma restore

#pragma save
#pragma NOAREGS
uint8_t timeout_ok (void) small reentrant
{
    --timeout_cnt;
    if (timeout_cnt < 0)
    {
        eeprom_state = _ERR_NACK;
        timeout_cnt = 0;
        return 0;
    }
    return 1;
}
#pragma restore

// Initialize the EEPROM interface for polling access
#pragma save
#pragma NOAREGS
void EEProm_Config (uint8_t access, uint16_t spg, uint8_t tWr) small reentrant
{
    eeprom_state = _OK;
    if (access)
    {
       time_to_write = tWr;
   
       IICInit();  // initialize the IIC bus
   
       IICStart();

       IICStop();
    }
    else
    {
       EX_EEPROM  = FALSE;           // Disable EEPROM non-busy interrupt.
       #if TRACE10 || M6520
       DIO &= ~DIO_EEX;              // Disconnect from external EEPROM.
       #else
       #error unhandled device type
       #endif
    }    
}
#pragma restore

// Write EEPROM Data; returns 0 when OK
#pragma save
#pragma NOAREGS
static uint8_t EPWritePage(uint32_t dst, uint8x_t *pchOut, 
    uint16_t cnt) small reentrant
{
    static uint8_t xdata cmd;
    static uint16_t xdata xdst;

    if (eeprom_state != _OK)
        return 1;

    // should address up to eight EEPROMs
    cmd = 0xA0 | (0xE & (dst >> 15)); // page write command
    xdst = (uint16_t)dst;
    timeout_start(); // long, but not forever
    IICStart();
    // while the EEPROM is busy, wait
    while(IICWrite(&cmd, 1) && timeout_ok())
    {
        IICStop();  
        IICStart();
    }
    // write the address
    if(IICWrite((uint8x_t *)&xdst, 2) || !timeout_ok())
    {
        IICStop();
        eeprom_state = _ERR_NACK;
        return 1;
    }
    // write the rest of the page's data
    if(IICWrite(pchOut, cnt) || !timeout_ok())
    {
        IICStop();
        eeprom_state = _ERR_NACK;
        return 1;
    }
    IICStop();
    return 0; // no error
}
#pragma restore

// copy any number of bytes from xdata to eeprom; 
#pragma save
#pragma NOAREGS
enum EEPROM_RC data *memcpy_prx(uint32_t dst, 
    uint8x_t *src, int16_t len) small reentrant
{
    int16_t lenInPage;

    // figure the number of bytes to the end of the first page
    lenInPage = PAGE_SIZE - (dst & (PAGE_SIZE - 1));
    // if the number of bytes is zero, then the write
    // starts on a page boundary
    if (lenInPage != 0)
    {
        // if the write is less than one page, finish it
        if (lenInPage > len)
            lenInPage = len;
        if(EPWritePage(dst, src, lenInPage))
            return &eeprom_state;
        src += (int)lenInPage;
        dst += (uint32_t)lenInPage;
        len -= lenInPage;
    }
    // write pages as quickly as possible
    while (len > PAGE_SIZE)
    {
        // write pages
        if(EPWritePage(dst, src, PAGE_SIZE))
            return &eeprom_state;
        src += PAGE_SIZE;
        dst += PAGE_SIZE;
        len -= PAGE_SIZE;
    }
    // write the last partial page, if any
    if (0 != len)
    {
        // write the last few bytes
        if(EPWritePage(dst, src, len))
            return &eeprom_state;
    }
    eeprom_state = _OK; 
    return &eeprom_state;
}
#pragma restore

#if CLI
// Clear EEPROM Data; returns 0 when OK
static bool EPClearPage(uint32_t dst)
{
    uint8_t xdata cmd;
    uint16_t xdata xdst;

    if (eeprom_state != _OK)
        return 1;

    // should address up to eight EEPROMs
    cmd = 0xA0 | (0xE & (dst >> 15)); // page write command
    xdst = (uint16_t)dst;
    timeout_start ();
    IICStart();
    while(IICWrite(&cmd, 1) && timeout_ok()) // while the EEPROM is busy, wait
    {
        IICStop();  
        IICStart();
    }
    if(IICWrite((uint8x_t *)&xdst, 2) || !timeout_ok()) // write the address
    {
        IICStop();
        eeprom_state = _ERR_NACK;
        return 1;
    }
    // write the rest of the page's data
    if(IICPad(PAGE_SIZE, 0xFF) || !timeout_ok())
    {
        IICStop();
        eeprom_state = _ERR_NACK;
        return 1;
    }
    IICStop();
    eeprom_state = _OK;
    return 0; // no error
}
#endif

#if CLI
// clear the ROM; 
enum EEPROM_RC data *memclr_pr (void)
{
    uint32_t len = EEPROM_SIZE;
    uint32_t dst = 0;

    // write pages as quickly as possible
    while (len > 0)
    {
        // write pages
        if(EPClearPage(dst))
            return &eeprom_state;
        dst += PAGE_SIZE;
        len -= PAGE_SIZE;
    }
    eeprom_state = _OK; 
    return &eeprom_state;
}
#endif

// read bytes; a return of nonzero is a fail.
#pragma save
#pragma NOAREGS
enum EEPROM_RC data *memcpy_xpr(
    uint8x_t *dst, 
    uint32_t src, 
    int16_t len
    ) small reentrant
{
    static uint8_t  xdata cmd;
    static uint16_t xdata xsrc;

    if (eeprom_state != _OK)
        return &eeprom_state;

    // should address up to eight EEPROMs
    cmd = 0xA0 | (0xE & (src >> 15)); // page read command
    xsrc = (uint16_t)src;

    // do dummy write to load address to chip
    timeout_start();
    IICStart();
    // while there's a write in progress, wait
    while(IICWrite(&cmd, 1) && timeout_ok())
    {
        // retry
        IICStop();
        IICStart();
    }
    // write the address
    if(IICWrite((uint8x_t *)&xsrc, 2) || !timeout_ok())
    {
        IICStop();
        eeprom_state = _ERR_NACK; 
        return &eeprom_state;
    }
    cmd |= 0xA1; // sequential read command, address bits preserved
    timeout_start();
    IICStart();
    while(IICWrite(&cmd, 1) && timeout_ok()) // while there's an error, wait
    {
        // retry
        IICStop();
        IICStart();
    }
    if (!timeout_ok())
    {
        IICStop();
        eeprom_state = _ERR_NACK; 
        return &eeprom_state;
    }
    IICRead(dst, (uint16_t)len); // read the rest of the page's data
    IICStop();

    eeprom_state = _OK; 
    return &eeprom_state;
}
#pragma restore

#if CAL_SAVE && NV_SELECT == NV_EEPROM
// returns 1 if it worked, 0 if it timed out or failed
#pragma save
#pragma NOAREGS
bool eeprom_ok (enum EEPROM_RC data *pstatus) small reentrant
{
    RESET_WD();
    return (_OK == *pstatus);
}
#pragma restore
#endif // extras

#endif // EEPROM
/***************************************************************************
 *  $Log: eepst24512.c,v $
 *  Revision 1.4  2006/10/13 00:47:28  tvander
 *  Removed compile options for 6530, 6515;
 *  renamed 6511 and 6513 to trace11 and trace13;
 *  Binary verified unchanged from previous version.
 *
 *  Revision 1.3  2006/09/09 01:09:27  gmikef
 *  *** empty log message ***
 *
 *  Revision 1.2  2006/08/09 00:56:34  tvander
 *  *** empty log message ***
 *
 *  Revision 1.1  2006/08/08 00:43:39  tvander
 *  Added debugged ST24512 EEPROM driver.
 *
 *
 * Copyright (C) 2006 Teridian Semiconductor Corp. All Rights Reserved.    *
 * this program is fully protected by the United States copyright          *
 * laws and is the property of Teridian Semiconductor Corporation.         *
 ***************************************************************************/

⌨️ 快捷键说明

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