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

📄 flash.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) 2005 Teridian Semiconductor Corp. All Rights Reserved.    *
 ***************************************************************************/
//**************************************************************************
//  DESCRIPTION: 71M652x POWER METER - Flash Routines.
// 
//  AUTHOR:  MTF
//
//  HISTORY: See end of file.
//**************************************************************************
// File: FLASH.C
//
#include "options.h"
#if FLASH
#include "IRQ.H"

#include "library.h"
#include "flash.h"

/*** External functions used within this module ***/
// Compare FLASH.

/*** External variables used within this module ***/
// None.

/*** Public functions/variables declared within this module ***/
// see flash.h

/*** Private functions declared within this module ***/
// Erase FLASH before write to it.
static void memcpy_rxe (uint8r_t *dst, uint8x_t *src, uint16_t len) small reentrant;
// Just write to FLASH.
static void memcpy_rx_ (uint8r_t *dst, uint8x_t *src, uint16_t len) small reentrant;
#define memset_r(d, s) memcpy_rx_(d, s, 1)

static bool flash_write_ok (uint8r_t *dst, uint8x_t *src, uint16_t len) small reentrant;
static bool flash_bad_cmp (uint8r_t *rsrc, uint8x_t *xsrc, uint16_t len) small reentrant;
static bool flash_not_erased (uint8r_t *rsrc, uint16_t len) small reentrant;

/*** Private variables declared within this module ***/
// None.

//--------------------------------------//
//  FLASH API
#if FLASH || (CAL_SAVE && (NV_SELECT == NV_FLASH))
#pragma save
#pragma NOAREGS
bool memcpy_rx (uint8r_t *dst, uint8x_t *src, uint16_t len) small reentrant
{                   
    if (!flash_write_ok (dst, src, len))
       return (FALSE);

    memcpy_rxe (dst, src, len);         // Only erase if full page write.
    return (0 == memcmp_rx (dst, src, len));             
}                                       // Verify write.

//  Note: FPAGE contains page address in 7 MSbs (i.e. PAGE ADDR is 2 x PAGE).   
#define NEXT_PAGE  0x02
static void memcpy_rxe (uint8r_t *dst, uint8x_t *src, uint16_t len) small reentrant
{
    uint16_t  tlen;
    int8_t page;
    IRQ_DEFINES;

    page = (uint16_t) dst >> 8;              // Extract page number x 2.
                                     
    if ((uint16_t) dst & FPAGE_MASK)
    {                                   // Not starting at page boundary.
       tlen = min (FPAGE_SIZE - ((uint16_t) dst & FPAGE_MASK), len);

       if (flash_bad_cmp (dst, src, tlen))
       {                                // Need to erase page first.
          IRQ_DISABLE();                // ALL interrupt OFF.
          FPAGE = page;                 // Set Flash Page Erase Enable.
          ERASE = PAGE_ERASE_;          // Initiate page erase, MPU halted.
          IRQ_ENABLE();                 // Turn interrupts back ON.
       }          

       memcpy_rx_ (dst, src, tlen);     // Just write partial page.
       dst += tlen;
       src += tlen;
       len -= tlen;
    }                                   
                                        // Starting at page boundary.
    while (len)                         
    {
       if (len >= FPAGE_SIZE)
       {
          IRQ_DISABLE();                // ALL interrupt OFF.
          FPAGE = page;                 // Set Flash Page Erase Enable.
          ERASE = PAGE_ERASE_;          // Initiate page erase, MPU halted.
          IRQ_ENABLE();                 // Turn interrupts back ON.
       }

       memcpy_rx_ (dst, src, min (len, FPAGE_SIZE));   

       dst += FPAGE_SIZE;               // Update pointers.
       src += FPAGE_SIZE; 
       len -= min (len, FPAGE_SIZE);
       page += NEXT_PAGE;               // Next page.
    }
}

static void memcpy_rx_ (uint8r_t *Dst, uint8x_t *src, uint16_t len) small reentrant
{
    IRQ_DEFINES;
	uint8x_t *dst = (uint8x_t *) Dst;
 
    while (len--)
    {
       IRQ_DISABLE();                   // ALL interrupt OFF.
       FCTRL |= PWE_;                   // MOVX @DPTR,A writes single byte to FLASH.
       *dst = *src;
	   FCTRL = 0;						// Disable further writing to flash.
       IRQ_ENABLE();                    // Turn interrupts back ON.
       dst++;	src++;
    }
}

static bool flash_write_ok (uint8r_t *dst, uint8x_t *src, uint16_t len) small reentrant
{
    uint16_t  tlen;
    
    if ((uint16_t) dst & FPAGE_MASK)
    {                                   // Not starting at page boundary.
       tlen = min (FPAGE_SIZE - ((uint16_t) dst & FPAGE_MASK), len);
                                        // First, just check overlayed portion of first page. 
       if (flash_bad_cmp (dst, src, tlen))  
       {                                // May need to erase this page.
          if (flash_not_erased ((uint8r_t *) ((uint16_t) dst & ~FPAGE_MASK), (uint16_t) dst & FPAGE_MASK))
          {                             // Do not do write.
             return (FALSE);            // Needed to read/erase/modify/write.           
          }
       }

       dst += tlen;
       src += tlen;
       len -= tlen;
    }                                   
                                        // Next, check overlayed portion of last page.
    tlen = len & ~FPAGE_MASK;           // Compute distance to final page.

    if (flash_bad_cmp (dst + tlen, src + tlen, len - tlen))   
    {
       if (flash_not_erased (dst + len, FPAGE_SIZE - (((uint16_t) dst + len) & FPAGE_MASK)))
       {                                // Do not do write.
          return (FALSE);               // Needed to read/erase/modify/write.           
       }
    }

    return (TRUE);
}

static bool flash_bad_cmp (uint8r_t *rsrc, uint8x_t *xsrc, uint16_t len) small reentrant
{
    while (len--)
    {
       if ((*rsrc & *xsrc) != *xsrc) break;

       rsrc++;  xsrc++;  
    }

    return (len + 1);
}

static bool flash_not_erased (uint8r_t *src, uint16_t len) small reentrant
{
    while (len--)
    {
       if (0xFF != *src) break;

       src++;  
    }

    return (len + 1);
}

//  The standard 16-bit CRC polynomial specified in ISO/IEC 3309 is used.
//             16   12   5
//  Which is: x  + x  + x + 1
// 
#if EXTRAS
bool CRC_Calc (uint8r_t *ptr, uint16_t len, int8_t set) small reentrant
{
    IRQ_DEFINES;
    int8_t d, Ok;
    uint16_t CRC;
	static uint8_t xdata src;
	
    if (set)
       len -= 2;                        // Do not include CRC in calculation.        

    CRC = 0xFFFF;
    do
    {
       d = *ptr++ ^ (CRC & 0xFF);       // Compute combined value.
       d ^= d << 4;                           
       CRC  = (d << 3) ^ (d << 8) ^ (CRC >> 8) ^ (d >> 4);
    } while (--len);

    if (set)
    {                                   // Store complement of CRC.   
	   CRC ^= 0xFFFF;					// Complement CRC.
	   d = CRC & 0xFF;   	
	   src = d;	
	   memset_r (ptr, &src);	
       ptr++;
	   d = CRC >> 8;
	   src = d;	
	   memset_r (ptr, &src);	
	   Ok  = (CRC >> 8)   == (*(ptr + 1));
	   Ok &= (CRC & 0xFF) == (*(ptr    ));
	   return (Ok);	
    }
    else
	{
	   Ok = CRC == 0xF0B8;
       return (Ok);
	}
}
#endif
#pragma restore
#endif

#if (CLI && !CAL_SAVE) || (CAL_SAVE && NV_SELECT == NV_FLASH)
bool memcpy_rce (int32r_t *dst, int32x_t *src, uint8_t len)
{                                       // Never any overlapped data.
    uint8x_t *pDst;
    uint8x_t *pSrc;
    int8_t page;
    CE_XFER_DEFINES;
    
    pDst = (uint8x_t *) dst;
    pSrc = (uint8x_t *) src;    
    page = (uint16_t) dst >> 8;         // Extract page number x 2.
    IRQ_DISABLE();                      // Turn OFF all interrupts.
    FPAGE = page;                       // Set Flash Page Erase Enable.
    ERASE = PAGE_ERASE_;                // Initiate page erase, MPU halted.
    IRQ_ENABLE();                       // Restore interrupt state.

    do
    {
       BEGIN_CE_CRITICAL_SECTION;       // this actually disables interrupts
       CLK_STRETCH;                     // Change stretch to '6'
       FCTRL |= PWE_; *pDst = *pSrc;
	   FCTRL = 0;						// Disable further writing to flash.
       CLK_RELAX;                       // Back to default value
       pDst++;  pSrc++;
       FCTRL |= PWE_; *pDst = *pSrc; FCTRL = 0;	pDst++;  pSrc++;
       FCTRL |= PWE_; *pDst = *pSrc; FCTRL = 0;	pDst++;  pSrc++;
       FCTRL |= PWE_; *pDst = *pSrc; FCTRL = 0;	
       END_CE_CRITICAL_SECTION;
       pDst++;  pSrc++;
    } while (--len);

    return (TRUE);
}
#endif

#if M6520
#pragma save
#pragma NOAREGS
void fwcol_isr (void) small reentrant interrupt FWCOL_IV
{
    if (IE_FWCOL0)
        CLR_IE_FWCOL0();

    if (IE_FWCOL1)
        CLR_IE_FWCOL1();
}
#pragma restore
#endif

#endif // flash

/***************************************************************************
 * History:
 * $Log: flash.c,v $
 * Revision 1.25  2006/09/09 01:15:14  gmikef
 * *** empty log message ***
 *
 * Revision 1.24  2006/06/29 00:58:43  tvander
 * Added NOAREGs to reentrant code.
 *
 * Revision 1.23  2006/06/06 05:15:56  tvander
 * clean build
 *
 * Revision 1.22  2006/04/14 20:21:58  tvander
 * Integrated with phased calibration
 *
 * Revision 1.21  2006/04/12 00:30:40  tvander
 * Added code for phased calibration, 6513 compiled with equations 3 and 4.
 *
 * Revision 1.20  2006/03/08 00:10:53  tvander
 * Clean build
 *
 * Revision 1.19  2006/03/06 03:42:09  Michael T. Fischer
 * More 6530 prep.
 *
 * Revision 1.18  2006/03/03 11:31:15  Michael T. Fischer
 * Prep for 6530 LCD, etc.
 *
 * Revision 1.17  2006/01/16 20:11:31  tvander
 * Clean Keil build, all versions
 *
 * Revision 1.16  2006/01/10 04:11:35  gmikef
 * Added PDATA support for CE Outputs.
 *
 * Revision 1.15  2006/01/04 04:47:55  gmikef
 * Switched RMS and VA calculations to use floating point. (and Calibration).
 *
 * Revision 1.14  2005/12/23 01:28:22  tvander
 * Fixed compile errors
 *
 * Revision 1.12  2005/12/21 01:37:09  tvander
 * 6513
 *
 * Revision 1.11  2005/12/08 03:09:10  gmikef
 * Manually clear PWE (disable flash writes) after each write.
 *
 * Revision 1.10  2005/10/15 02:21:24  tvander
 * Improved critical sections to use the official macros.
 * Also improved the compilation flags.
 *
 * Revision 1.9  2005/10/12 23:00:07  tvander
 * Includes demonstratable mission mode, brownout, LCD and sleep modes
 *
 * Revision 1.8  2005/09/22 23:45:26  tvander
 * Clean build all models and unit tests, updated copyright to be fore Teridian
 *
 * Revision 1.7  2005/09/11 00:34:08  tvander
 * Clean compiles
 *
 * Revision 1.6  2005/09/01 04:25:28  gmikef
 * *** empty log message ***
 *
 * Revision 1.5  2005/08/31 05:58:03  gmikef
 * First version w/ LAPIE interface.
 *
 * Revision 1.4  2005/08/30 18:22:56  gmikef
 * *** empty log message ***
 *
 * Revision 1.3  2005/08/12 06:03:07  gmikef
 * Added MPU temperature compensation for GAIN_ADJ.
 * Added changes to support new CE 6521 code.
 *
 * Revision 1.2  2005/08/11 18:10:25  tvander
 * *** empty log message ***
 *
 * Revision 1.1  2005/08/10 02:07:05  gmikef
 * *** empty log message ***
 *
 * Revision 1.10  2005/07/15 01:20:06  gmikef
 * *** empty log message ***
 *
 * Copyright (C) 2005 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 + -