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

📄 eep24c08.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: 71M651x POWER METER - Serial EEPROM Routines. 
// 
//  AUTHOR:  RGV
//
//  HISTORY: See end of file
//**************************************************************************              
// File: eep24C08.c              
//**************************************************************************
// high speed polling eeprom API for an AT24C08
// This can use either iicdio.c a fast bit-banging interface, or
// iiceep.c, a slower, less power-hungry interface that uses the
// chip's on-board I2C hardware.  Both have the same interface, iic.h
// 
// Note that the PAGE_SIZE (see meter\api.h) of an AT24C08 is 16, 
// not the normal value used for the EEPROM of the TSC demo PCB.
//
// Also note that pins 1 & 2 of an AT24C08 are required to be NC.
//
#include "options.h"
#if EEPROM && I2C_POLLED
#include "stm.h"
#include "eeprom.h"
#include "iic.h" // polling IIC/I2C interface.

static uint16x_t page_size, 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)
    {
       page_size = spg;
       time_to_write = tWr;

       IICInit();  // initialize the IIC bus   
       IICStart();  // this is probably not right; no change on scope, but it works
       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

// delay loop
//#define DELAY 20
#ifdef DELAY
#pragma save
#pragma NOAREGS
static void delay(void) small reentrant
{
   uint_fast8_t cnt0, cnt1, cnt2;

   for (cnt0 = DELAY; cnt0 > 0; --cnt0)
   {
       for (cnt1 = 10; cnt1 > 0; --cnt1)
       {
           for (cnt2 = 100; cnt2 > 0; --cnt2)
           {
           }
        }
    }
}
#pragma restore
#endif

// 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 uint8_t xdata xdst;

    if (eeprom_state != _OK)
        return 1;

    // this is supposed to address up to two EEPROMs
    cmd = 0xA0 | (0xE & (dst >> 7)); // page write command
    xdst = (uint8_t)dst;
#ifdef DELAY
    delay(); // for debugging
#endif
    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, 1) || !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

#if EXTRAS
// Copy four (4) bytes to eeprom; 
enum EEPROM_RC data *memset_pr  (uint32_t dst, int32_t src)
{
    int32_t xdata xsrc = src;

    return (memcpy_prx (dst, (uint8x_t *) &xsrc, 4));
}
#endif

// 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
{
    uint8_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 (((uint16_t)lenInPage) > len)
            lenInPage = len;
        if(EPWritePage(dst, src, lenInPage))
            return &eeprom_state;
        src += (int)lenInPage;
        dst += (uint32_t)lenInPage;
        len -= (uint16_t)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, (uint16_t)len))
            return &eeprom_state;
    }
    eeprom_state = _OK; 
    return &eeprom_state;
}
#pragma restore

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

    if (eeprom_state != _OK)
        return 1;

    // this is supposed to address up to two EEPROMs
    cmd = 0xA0 | (0x0E & (dst >> 7)); // page write command
    xdst = (uint8_t)dst;
#ifdef DELAY
    delay(); // for debugging
#endif
    timeout_start ();
    IICStart();
    while(IICWrite(&cmd, 1) && timeout_ok()) // while the EEPROM is busy, wait
    {
        IICStop();  
        IICStart();
    }
    if(IICWrite((uint8x_t *)&xdst, 1) || !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
}
#pragma restore
#endif

#if CLI
// clear the ROM; 
#pragma save
#pragma NOAREGS
enum EEPROM_RC data *memclr_pr (void) small reentrant
{
    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;
}
#pragma restore
#endif

#if EXTRAS
// Read four (4) bytes; A return of nonzero is a failure.
enum EEPROM_RC data *memget_pr (int32x_t *dst, uint32_t src)
{
    return (memcpy_xpr((uint8x_t *) dst, src, 4));  
}
#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 uint8_t xdata xsrc;

    if (eeprom_state != _OK)
        return &eeprom_state;

    // should address up to two EEPROMs
    cmd = 0xA0 | (0x0E & (src >> 7)); // page write command
    xsrc = (uint8_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();
    }
    if(IICWrite((uint8x_t *)&xsrc, 1) || !timeout_ok()) // write the address
    {
        IICStop();
        eeprom_state = _ERR_NACK; 
        return &eeprom_state;
    }
    IICStop();

    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: eep24c08.c,v $
 *  Revision 1.10  2006/10/13 00:47:27  tvander
 *  Removed compile options for 6530, 6515;
 *  renamed 6511 and 6513 to trace11 and trace13;
 *  Binary verified unchanged from previous version.
 *
 *  Revision 1.9  2006/09/09 01:09:11  gmikef
 *  *** empty log message ***
 *
 *  Revision 1.8  2006/08/09 00:56:33  tvander
 *  *** empty log message ***
 *
 *  Revision 1.7  2006/06/29 00:55:47  tvander
 *  Marked NOAREGS on reentrant routines that needed it.
 *
 *  Revision 1.6  2006/06/15 16:36:54  tvander
 *  Fixed reentrancy on iiceep.c and eepromp.c
 *  Made parallel code changes to microwire eeprom drivers.
 *
 *  Revision 1.5  2006/06/12 20:40:50  tvander
 *  Fixed to compile correctly
 *
 *  Revision 1.4  2006/05/25 03:24:11  tvander
 *  Added timeouts to EEPROMs.  Tested all three.
 *  Newly ported calibration loader, compiles without error.
 *  RTC setting uses a software timer (less code, also frees tmr1)
 *
 *  Revision 1.3  2006/05/18 23:18:43  tvander
 *  16K and 32K
 *  First cut at new requirements.
 *  32K 6521 is grossly tested.
 *  All others have a clean compile with C51 8.02
 *
 *  Revision 1.2  2006/04/14 20:11:22  tvander
 *  Fixed, integrated with phased calibration
 *
 *  Revision 1.1  2006/03/14 04:40:34  tvander
 *  Debugged in 3.4 code for customer, ported to v. 4 code
 *
 *  Revision 1.1  2006/03/14 04:06:42  tvander
 *  *** empty log message ***
 *
 *  Revision 1.3  2005/03/22 00:56:00  tvander
 *  Rolled date
 *  Changed misc.c to disable interrupts in Ce_Int_Enable().
 *  Changed calls to memcpy_xp to never write outside the buffer.
 *  Changed the help files to be more accurate.
 *
 *  Revision 1.2  2005/02/17 18:32:25  tvander
 *  Added automatic check-in logging to all source code.
 *
 *  2004 DECEMBER 22;    First Version
 *
 *  Revision 1.1  2005/02/01 20:04:40  tvander
 *  Reorganization
 *
 *  Revision 1.2  2005/01/26 19:52:35  tvander
 *  Added update log
 *
 * 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 + -