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

📄 flashutils.c

📁 Zigbee2006入门(源代码+文档讲解+系统推荐)
💻 C
📖 第 1 页 / 共 2 页
字号:
#define ENABLE_BIT_DEFINITIONS 1
#include "zcomdef.h"
#include "FlashUtils.h"
#include <ioCC2430.h>
#include "OADSupport.h"
#include "OSAL_Memory.h"

#ifdef NV_IS_I2C
#include "i2cSupport.h"
#endif

#ifdef NV_IS_SPI
#include "serialize.h"
#endif

#define STATIC static


#define FERASE  0x01  // Page erase: erase=1
#define FWRITE  0x02  // Page write: write=1
#define FCONRD  0x10  // Continuous read: enable=1
#define FSWBSY  0x40  // Single write: busy=1
#define FBUSY   0x80  // Write/erase: busy=1
#define FWBUSY  0xC0  // Flash write: busy=1

/******************************************************************************
 ** ANY VARIABLES DECLARED 'STATIC' MUST BE USED _ONLY_ IN BOOT STARTUP CODE
 ** memory addresses assigned to static variables will not be valid when
 ** application code is running. they are valid only when the boot startup
 ** code is running.
*******************************************************************************/

/*********************************************************************
 * MACROS
 */
//Macro for erasing a given flash page
#define ERASE           0x01
#define FLASH_ERASE_PAGE(page) \
   do{                         \
      FADDRH = (page) << 1;    \
      FCTL = ERASE;            \
      asm("NOP");              \
      while(FCTL == 0x80);     \
   }while (0)

// DMA Sturcture
typedef struct
{
  uint8  SRC_HI;
  uint8  SRC_LO;
  uint8  DST_HI;
  uint8  DST_LO;
  uint8  VLEN;
  uint8  LEN;
  uint8  TRIG;
  uint8  INCMODE;
} DMA_t;

static DMA_t  __xdata FlashDMA;

extern __near_func  uint8  GetCodeByte(uint32 address);

// set up the mailbox in RAM
extern mbox_t mbox;


// LOCAL FUNCTIONS
STATIC  uint8  CheckCode(image_t, uint32, uint32);
STATIC  uint8  GetPreamble(image_t, uint32, preamble_t *);
STATIC  uint32 CRC32Value(uint16);
STATIC  uint8  imageCRC(image_t, uint32, uint32, preamble_t *);
STATIC  uint8  AccessStatus(action_t, sfield_t, void *);
STATIC  uint8  ReadFlash(image_t, uint32 page, uint8 __xdata *buf, uint16 len);
STATIC  uint8  WriteFlash(image_t, uint32 page, uint8 __xdata *buf, uint16 len);

__near_func void   flashErasePage(uint8, uint8 __xdata *);

// EXTERNAL FUNCTIONS
__near_func void  halFlashDmaTrigger(void);

static int8 (*rw_Xmem)(uint8, uint32, uint8 *, uint16);

void FlashInit()
{
#ifdef NV_IS_SPI
    // initialize SPI-dataflash interface
    DF_spiInit(&rw_Xmem);
#endif

#ifdef NV_IS_I2C
    // initialize I2C-dataflash interface
    DF_i2cInit(&rw_Xmem);
#endif

     // populate mailbox function pointers
    mbox.ReadFlash         = ReadFlash;
    mbox.WriteFlash        = WriteFlash;
    mbox.CheckCodeSanity   = CheckCode;
    mbox.GetPreamble       = GetPreamble;
    mbox.AccessZLOADStatus = AccessStatus;

    return;
}

void GetFlashRWFunc(int8 (**func)(uint8, uint32, uint8 *, uint16))
{
#ifdef NV_IS_SPI
    // initialize SPI-dataflash interface
    DF_spiInit(&rw_Xmem);
#endif

#ifdef NV_IS_I2C
    // initialize I2C-dataflash interface
    DF_i2cInit(&rw_Xmem);
#endif

  *func = rw_Xmem;
}

/************************************************************************************
 *   uint8 CheckCode
 *      Purpose: Do all code sanity checks. Currently, this is to check the magic
 *               and check the FCS.
 *
 *        This routine is avaliable to application code. It is re-entrant but not
 *        thread-safe.
 *
 *      Arguments:
 *        input:
 *          baseAddr: base address of image
 *          firstPageAddr: address of first page
 *        output:
 *          none.
 *      Returns:
 *        0: Code at spefied address is sane
 *        1: Code at spefied address is NOT sane
 ************************************************************************************/
STATIC  uint8 CheckCode(image_t itype, uint32 baseAddr, uint32 firstPageAddress)
{
    uint8      rc;
    preamble_t preamble;

    // get preamble
    mbox.GetPreamble(itype, firstPageAddress, &preamble);

    // check for magic
    if ((preamble.pre_Magic[0] != PREAMBLE_MAGIC1) || (preamble.pre_Magic[1] != PREAMBLE_MAGIC2))  {
        return 1;
    }

    // only thing left to check for is CRC
    rc = imageCRC(itype, baseAddr, firstPageAddress, &preamble);

    return rc;
}

/************************************************************************************
 *   uint8 imageCRC
 *      Purpose: compute image CRC. Taken as an amalgam from various sources. There
 *      are a number of slightly varying implementations. It was hard to find test
 *      data for this specific implementation. The test used is the very weak test
 *      in which the ASCII string "123456789" is checked.
 *
 *      In this space it is calculating the CRC on downloaded image only. The
 *      application will never request the CRC calculated on the active image.
 *
 *      Note: the routine that follows this one also supports the CRC calculation.
 *
 *      Arguments:
 *        input:
 *          baseAddr: base address of image
 *          firstPageOffset: offset from baseAddr of actual first page of image
 *          premable: pointer to preamble info
 *        output:
 *          none
 *      Returns:
 *        0: CRC calculation matches the CRC in image
 *        1: CRC calculation does NOT match the CRC in image
 ************************************************************************************/
#define  DFBUFSIZE  32
STATIC  uint8 imageCRC(image_t itype, uint32 baseAddr, uint32 firstPageAddress, preamble_t *preamble)
{
    uint8  ch, scnt, dfIdx, dfSize;
    uint32 imgCRC, imglen, ulCRC, ulTemp1, ulTemp2, lastAddress, baseOrig;
#ifdef CC2430_BOOT_CODE
    uint8 cptr[DFBUFSIZE];
#else
    uint8 *cptr;
#endif

    imglen = preamble->pre_Length;

    // figure out wrap address in case image wraps within download area
    // the number is too big if the image doesn't wrap but that won't
    // matter becuase the loop(s) below will terminate since the image
    // length count is reached. this value matters only if the image
    // stored actually wraps.
    lastAddress = (baseAddr + imglen - 1) | ((itype == IMAGE_DL) ? (DF_PAGESIZE-1) : (CHIP_PAGESIZE-1));
    baseOrig    = baseAddr;
    baseAddr    = firstPageAddress;

    // start with all bits on. common practice to guard against initial sequence of
    // 0's (even though we don't have this case)
    ulCRC  = 0xFFFFFFFF;
    imgCRC = 0;
    scnt   = 0;

    dfIdx = 0;
    if (IMAGE_DL == itype)  {
      dfIdx = dfSize = DFBUFSIZE;
#ifndef CC2430_BOOT_CODE
      if (!(cptr = osal_mem_alloc(DFBUFSIZE)))  {
      // Plan B if the malloc fails...
        dfIdx = dfSize = 1;
        cptr           = &ch;
      }
#endif
    }

    // the same logic is used to both calculate the checksum and to retrieve stored
    // CRC. this is because the method below already deals with wrapping so we
    // might as well use the same logic to get the CRC. Otherwise the wrapping
    // logic has to be repeated: though unlikely, the CRC _could_ span the wrap.
    do  {
        for (; baseAddr <= lastAddress && imglen; baseAddr++, imglen--)  {
            // next byte...
          if (IMAGE_ACTIVE == itype)  {
            ch = GetCodeByte(baseAddr);
          }
          else  {
            if (dfIdx >= dfSize)  {
              rw_Xmem(XMEM_READ, baseAddr, cptr, dfSize);
              dfIdx = 0;
            }
            ch = cptr[dfIdx++];
          }
          if (imglen > FCS_LENGTH)  {
              ulTemp1 = (ulCRC >> 8) & 0x00FFFFFFL;
              ulTemp2 = CRC32Value(((uint16)ulCRC ^ ch) & 0xFF);
              ulCRC   = ulTemp1 ^ ulTemp2;
          }
          else  {
              // we've reached the stored CRC. create the actual
              // value by shifting in the bytes.
              imgCRC = imgCRC | (uint32)ch<<scnt;
              scnt  += 8;
          }
        }
        baseAddr = baseOrig;
    } while (imglen);

#ifndef CC2430_BOOT_CODE
    if (dfSize > 1)  {
      osal_mem_free(cptr);
    }
#endif

    // XOR with all bits on. this is a common practice
    ulCRC ^= 0xFFFFFFFF;

    // match?
    if (ulCRC != imgCRC)  {
        // "Close, but no match and the board goes back" (remember that?)
        return 1;
    }

    return 0;

⌨️ 快捷键说明

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