|
发表于 2014-12-26 13:29:28
|
显示全部楼层
- /***********************************************************
- * 函数库说明:Bootloader底层操作函数库 *
- * 版本: v1.00beta *
- * 作者: 王卓然 *
- * 创建日期: 2008年8月31日 *
- * -------------------------------------------------------- *
- * [支 持 库] *
- * 支持库名称: *
- * 需要版本: *
- * 声明库说明: *
- * -------------------------------------------------------- *
- * [版本更新] *
- * 修改: *
- * 修改日期: *
- * 版本: *
- * -------------------------------------------------------- *
- * [版本历史] *
- * -------------------------------------------------------- *
- * [使用说明] *
- ***********************************************************/
- /********************
- * 头 文 件 配 置 区 *
- ********************/
- # include "RD_MacroAndConst.h"
- # include "BL_Config.h"
- # include "PF_Config.h"
- /********************
- * 系 统 宏 定 义 *
- ********************/
- /*------------------*
- * 常 数 宏 定 义 *
- *------------------*/
- #ifndef SIGRD
- # define SIGRD 5
- #endif
- # define SPM_ENBALE_RWW (BIT(RWWSRE)|BIT(SPMEN))
- # define SPM_PAGE_WRITE (BIT(PGWRT)|BIT(SPMEN))
- # define SPM_PAGE_ERASE (BIT(PGERS)|BIT(SPMEN))
- # define SPM_FUSE_AND_LOCK_BITS (BIT(BLBSET)|BIT(SPMEN))
- # define SPM_WRITE_BUFFER BIT(SPMEN)
- # define SPM_READ_SIGNATURE (BIT(SIGRD)|BIT(SPMEN))
- #ifndef FLASH_PAGE_SIZE
- # error No define FLASH_PAGE_SIZE
- #endif
- #ifndef SPMCSR
- # define SPMCSR SPMCR
- #endif
- #ifndef EEPE
- # define EEPE EEWE
- #endif
- /*------------------*
- * 动 作 宏 定 义 *
- *------------------*/
- /********************
- * 模块结构体定义区 *
- ********************/
- /********************
- * 函 数 声 明 区 *
- ********************/
- #if BL_USE_PAGE_VERIFY == ENABLE
- BOOL Bootloader_Flash_Page_Verify
- (
- BYTE *pchDataBuffer,
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT32 dwAddress
- #else
- UINT16 wAddress
- #endif
- );
- #endif
- #if BL_USE_LOAD_PAGE == ENABLE
- #if defined(BOOTLOADER_USE_CRC16)
- UINT16 Bootloader_Load_Page_Buffer
- #elif defined(BOOTLOADER_USE_XOR)
- UINT8 Bootloader_Load_Page_Buffer
- #else
- void Bootloader_Load_Page_Buffer
- #endif
- (
- BYTE chDataBuffer[FLASH_PAGE_SIZE],
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT32 dwAddress
- #else
- UINT16 wAddress
- #endif
- );
- #endif
- BOOL Bootloader_Write_Page
- (
- void *pData,
- UINT16 wLength,
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT32 dwAddress
- #else
- UINT16 wAddress
- #endif
- );
- void Bootloader_Put_INT_Vector_Into_APPS(void);
- void Bootloader_Put_INT_Vector_Into_BLS(void);
- #if BL_USE_READ_FUSE_AND_LOCK_BITS == ENABLE
- UINT8 Bootloader_Read_Fuse(UINT16 wIndex);
- #endif
- #if BL_USE_READ_FUSE_AND_LOCK_BITS == ENABLE
- UINT8 Bootloader_Read_Signature(UINT16 wIndex);
- #endif
- #if BL_USE_WRITE_LOCK_BITS == ENABLE
- void Bootloader_Write_Lock_Bits(UINT8 chLockBits);
- #endif
- #if defined(BOOTLOADER_USE_CRC16) || (BL_CRC16_SERVICE_SUPPORT == ENABLE)
- UINT16 CRC16_Check(UINT16 *pwCRCValue,BYTE chData);
- #endif
- #if BL_USE_CHIP_ERASE == ENABLE
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- void Bootloader_Chip_Erase(UINT32 dwMaxAddress);
- #else
- void Bootloader_Chip_Erase(UINT16 wMaxAddress);
- #endif
- #endif
- /********************
- * 模块函数声明区 *
- ********************/
- static void Do_Boot_Loader_Action(UINT8 chFunction);
- static BOOL Fill_Page_Buffer
- (
- BYTE chDataBuffer[FLASH_PAGE_SIZE],
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT32 dwAddress
- #else
- UINT16 wAddress
- #endif
- );
-
- /********************
- * 模块变量声明区 *
- ********************/
- /********************
- * 全局变量声明区 *
- ********************/
- #if defined(BOOTLOADER_USE_CRC16) || (BL_CRC16_SERVICE_SUPPORT == ENABLE)
- /***********************************************************
- * 函数说明: CRC16单数据处理函数 *
- * 输入: 保存CRC校验值的地址,新的数据 *
- * 输出: CRC交验 *
- * 调用函数: 无 *
- ***********************************************************/
- UINT16 CRC16_Check(UINT16 *pwCRCValue,BYTE chData)
- {
- UINT16 wCRC = (*pwCRCValue);
-
- chData ^= (UINT8)((UINT16)wCRC & 0x00FF);
- chData ^= chData << 4;
- (*pwCRCValue) = ((((uint16)chData << 8) | (wCRC >> 8)) ^ (uint8)(chData >> 4)
- ^ ((uint16)chData << 3));
-
- return (*pwCRCValue);
- }
- #endif
- /***********************************************************
- * 函数说明: 等待SPM指令执行结束函数 *
- * 输入: 需要执行的功能 *
- * 输出: 无 *
- * 调用函数: 无 *
- ***********************************************************/
- static void Do_Boot_Loader_Action(UINT8 chFunction)
- {
- /* 等待上次操作结束 */
- while(SPMCSR & BIT(SPMEN))
- {
- asm("wdr");
- }
-
- SAFE_CODE_PERFORMANCE
- (
- while(EECR & BIT(EEWE))
- {
- asm("wdr");
- }
- SPMCSR = chFunction;
- asm("spm");
- )
- }
- #if BL_USE_CHIP_ERASE == ENABLE
- /***********************************************************
- * 函数说明: 片擦除函数 *
- * 输入: 擦除时不能越过的地址 *
- * 输出: 无 *
- * 调用函数: Do_Boot_Loader_Action *
- ***********************************************************/
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- void Bootloader_Chip_Erase(UINT32 dwMaxAddress)
- #else
- void Bootloader_Chip_Erase(UINT16 wMaxAddress)
- #endif
- {
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT32 dwAddress;
- UINT8 TRAMPZ = RAMPZ;
- for (
- dwAddress = 0;
- dwAddress < dwMaxAddress;
- dwAddress += FLASH_PAGE_SIZE
- )
- {
- UINT16 wAddress = dwAddress;
- RAMPZ = dwAddress>>16;
- asm("movw r30,%wAddress");
- Do_Boot_Loader_Action(SPM_PAGE_ERASE);
- Do_Boot_Loader_Action(SPM_ENBALE_RWW);
- WDR();
- }
- RAMPZ = TRAMPZ;
-
- #else
- UINT16 wAddress;
- for (
- wAddress = 0;
- wAddress < wMaxAddress;
- wAddress += FLASH_PAGE_SIZE
- )
- {
- /* 将地址保存到Z寄存器 */
- asm("movw r30,%wAddress");
- WDR();
- Do_Boot_Loader_Action(SPM_PAGE_ERASE);
- Do_Boot_Loader_Action(SPM_ENBALE_RWW);
- }
- #endif
- }
- #endif
- #if BL_USE_LOAD_PAGE == ENABLE
- /*-----------------------------------------------------------------------------*
- * Function Description: *
- * Load a specified page to a page buffer. *
- * Parameters: *
- * chDataBuffer the page buffer. *
- * dwAddress/wAddress the target page address. *
- * Return *
- * CRC16 / XOR / None *
- *----------------------------------------------------------------------------*/
- #if defined(BOOTLOADER_USE_CRC16)
- UINT16 Bootloader_Load_Page_Buffer
- #elif defined(BOOTLOADER_USE_XOR)
- UINT8 Bootloader_Load_Page_Buffer
- #else
- void Bootloader_Load_Page_Buffer
- #endif
- (
- UINT8 chDataBuffer[FLASH_PAGE_SIZE],
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT32 dwAddress
- #else
- UINT16 wAddress
- #endif
- )
- {
- UINT16 wCounter = FLASH_PAGE_SIZE;
- #if defined(BOOTLOADER_USE_CRC16)
- UINT16 wTempCRC = CRC_INIT;
- UINT8 chData;
- #elif defined(BOOTLOADER_USE_XOR)
- UINT8 chXOR = 0;
- #endif
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT8 TRAMPZ = RAMPZ;
- #endif
-
- #if !defined(BOOTLOADER_USE_CRC16) && !defined(BOOTLOADER_USE_XOR)
- if (chDataBuffer == NULL)
- {
- //! in none checking model, a null buffer means nothing.
- return ;
- }
- #endif
-
- //! Enable RWW write
- while(SPMCSR & BIT(RWWSB))
- {
- Do_Boot_Loader_Action(SPM_ENBALE_RWW);
- }
- asm("push r30");
- asm("push r31");
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- RAMPZ = dwAddress >> 16;
- #endif
- //! load address to z register
- asm("movw r30,r18");
- //! load buffer address to x register
- asm("movw r26,r16");
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
-
- if (chDataBuffer != NULL)
- {
- #ifdef BOOTLOADER_USE_XOR
- //! Initialize the xor checking result register
- asm("ldi r1,0");
- #endif
- if (RAMPZ)
- {
- while(wCounter--)
- {
- WDR();
- //! load value from flash (addressed by z register)
- asm("elpm r0,z+");
- //! save the value to sram (address by x register)
- asm("st x+,r0");
- //! do checking function if necessary
- #if defined(BOOTLOADER_USE_CRC16)
- //! use chData as a temporary variable
- asm("mov %chData,r0");
- //! calculate the crc16 value
- CRC(wTempCRC,chData);
- #elif defined (BOOTLOADER_USE_XOR)
- //! xor
- asm("eor r1,r0");
- #endif
- }
- }
- else
- {
- while(wCounter--)
- {
- WDR();
- //! load value from flash (addressed by z register)
- asm("lpm r0,z+");
- //! save the value to sram (address by x register)
- asm("st x+,r0");
- //! do checking function if necessary
- #if defined(BOOTLOADER_USE_CRC16)
- //! use chData as a temporary variable
- asm("mov %chData,r0");
- //! calculate the crc16 value
- CRC(wTempCRC,chData);
- #elif defined (BOOTLOADER_USE_XOR)
- //! xor
- asm("eor r1,r0");
- #endif
- }
- }
- #ifdef BOOTLOADER_USE_XOR
- //! save the xor checking result to variable chXOR
- asm("mov %chXOR,r1");
- #endif
- }
- else
- {
- //! do checking function if necessary
- #if defined(BOOTLOADER_USE_CRC16)
- if (RAMPZ)
- {
- while(wCounter--)
- {
- WDR();
- //! load value from flash (addressed by z register)
- asm("elpm r0,z+");
- //! use chData as a temporary variable
- asm("mov %chData,r0");
- //! calculate the crc16 value
- CRC(wTempCRC,chData);
- }
- }
- else
- {
- while(wCounter--)
- {
- WDR();
- //! load value from flash (addressed by z register)
- asm("lpm r0,z+");
- //! use chData as a temporary variable
- asm("mov %chData,r0");
- //! calculate the crc16 value
- CRC(wTempCRC,chData);
- }
- }
- #elif defined (BOOTLOADER_USE_XOR)
- //! Initialize the xor checking result register
- if (RAMPZ)
- {
- asm("ldi r1,0");
- while(wCounter--)
- {
- WDR();
- //! load a byte from flash to r0 (addressed by z register)
- asm("elpm r0,z+");
- //! xor
- asm("eor r1,r0");
- }
- //! save the xor checking result to variable chXOR
- asm("mov %chXOR,r1");
- }
- else
- {
- asm("ldi r1,0");
- while(wCounter--)
- {
- WDR();
- //! load a byte from flash to r0 (addressed by z register)
- asm("lpm r0,z+");
- //! xor
- asm("eor r1,r0");
- }
- //! save the xor checking result to variable chXOR
- asm("mov %chXOR,r1");
- }
- #endif
- }
- RAMPZ = TRAMPZ;
-
- #else
- if (chDataBuffer != NULL)
- {
- #ifdef BOOTLOADER_USE_XOR
- //! Initialize the xor checking result register
- asm("ldi r1,0");
- #endif
- while(wCounter--)
- {
- WDR();
- //! load value from flash (addressed by z register)
- asm("lpm r0,z+");
- //! save the value to sram (address by x register)
- asm("st x+,r0");
- //! do checking function if necessary
- #if defined(BOOTLOADER_USE_CRC16)
- //! use chData as a temporary variable
- asm("mov %chData,r0");
- //! calculate the crc16 value
- CRC(wTempCRC,chData);
- #elif defined (BOOTLOADER_USE_XOR)
- //! xor
- asm("eor r1,r0");
- #endif
- }
- #ifdef BOOTLOADER_USE_XOR
- //! save the xor checking result to variable chXOR
- asm("mov %chXOR,r1");
- #endif
- }
- else
- {
- //! do checking function if necessary
- #if defined(BOOTLOADER_USE_CRC16)
- while(wCounter--)
- {
- WDR();
- //! load value from flash (addressed by z register)
- asm("lpm r0,z+");
- //! use chData as a temporary variable
- asm("mov %chData,r0");
- //! calculate the crc16 value
- CRC(wTempCRC,chData);
- }
- #elif defined (BOOTLOADER_USE_XOR)
- //! Initialize the xor checking result register
- asm("ldi r1,0");
- while(wCounter--)
- {
- WDR();
- //! load a byte from flash to r0 (addressed by z register)
- asm("lpm r0,z+");
- //! xor
- asm("eor r1,r0");
- }
- //! save the xor checking result to variable chXOR
- asm("mov %chXOR,r1");
- #endif
- }
- #endif
- asm("pop r31");
- asm("pop r30");
-
- #if defined(BOOTLOADER_USE_CRC16)
- return wTempCRC;
- #elif defined(OOTLOADER_USE_XOR)
- return chXOR;
- #endif
- }
- #endif
- //#pragma abs_address: BL_VECTOR_FREE_TEXT_ADDRESS
- /***********************************************************
- * 函数说明: 向页缓冲区写入数据函数 *
- * 输入: 缓冲区指针,要写入的地址 *
- * 输出: 写入是否成功 *
- * 调用函数: 无 *
- ***********************************************************/
- static BOOL Fill_Page_Buffer
- (
- BYTE chDataBuffer[FLASH_PAGE_SIZE],
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT32 dwAddress
- #else
- UINT16 wAddress
- #endif
- )
- {
- UINT8 chCounter = (FLASH_PAGE_SIZE>>1);
-
- if (chDataBuffer == NULL)
- {
- return FALSE;
- }
-
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- dwAddress &= ~((UINT32)(FLASH_PAGE_SIZE - 1));
- #else
- wAddress &= ~((UINT16)(FLASH_PAGE_SIZE - 1));
- #endif
- //! load zero value to z register
- asm("ldi r30,0");
- //! load the page buffer address to x register
- asm("movw r26,r16");
- while(chCounter--)
- {
- WDR();
- //! load half word(2bytes) from sram to R0 register (addressed by x register)
- asm("ld r0,x+");
- asm("ld r1,x+");
- //! save the half word to flash page buffer
- Do_Boot_Loader_Action(SPM_WRITE_BUFFER);
- //! increase the flash page buffer writing pointer.
- asm("adiw r30,2");
- }
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- RAMPZ = dwAddress >> 16;
- #endif
- //! save a address to z register
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- {
- UINT8 A = ((UINT8 *)&dwAddress)[0];
- UINT8 B = ((UINT8 *)&dwAddress)[1];
- asm("mov r30,%A");
- asm("mov r31,%B");
- }
- #else
- asm("movw r30,r18");
- #endif
- return TRUE;
- }
- //#pragma end_abs_address
- #if BL_USE_PAGE_VERIFY == ENABLE
- /***********************************************************
- * 函数说明: 页面校验函数 *
- * 输入: 源页面缓冲区,目标地址 *
- * 输出: 校验是否成功 *
- * 调用函数: 无 *
- ***********************************************************/
- BOOL Bootloader_Flash_Page_Verify
- (
- BYTE *pchDataBuffer,
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT32 dwAddress
- #else
- UINT16 wAddress
- #endif
- )
- {
- UINT16 wCounter = FLASH_PAGE_SIZE;
- UINT8 chDataA;
- UINT8 chDataB;
-
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT8 TRAMPZ = RAMPZ;
- #endif
- if (pchDataBuffer == NULL)
- {
- //! have nothing to do with...
- return FALSE;
- }
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- RAMPZ = dwAddress >> 16;
- #endif
- //! load the address to z register
- asm("movw r30,r18");
- //! load the buffer address to x register
- asm("movw r26,r16");
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- if (RAMPZ)
- {
- while(wCounter--)
- {
- //! load a byte from flash (addressed by z register)
- asm("elpm r0,z+");
- //! employ a temporary variable chDataA
- asm("mov %chDataA,r0");
- //! load a byte from sram (addressed by x register)
- asm("ld r0,x+");
- //! employ a temporary variable chDataB
- asm("mov %chDataB,r0");
- //! checking...
- if (chDataA != chDataB)
- {
- RAMPZ = TRAMPZ;
- return FALSE;
- }
- WDR();
- }
- }
- else
- {
- while(wCounter--)
- {
- //! load a byte from flash (addressed by z register)
- asm("lpm r0,z+");
- //! employ a temporary variable chDataA
- asm("mov %chDataA,r0");
- //! load a byte from sram (addressed by x register)
- asm("ld r0,x+");
- //! employ a temporary variable chDataB
- asm("mov %chDataB,r0");
- //! checking...
- if (chDataA != chDataB)
- {
- RAMPZ = TRAMPZ;
- return FALSE;
- }
- WDR();
- }
- }
- RAMPZ = TRAMPZ;
- #else
- while(wCounter--)
- {
- //! load a byte from flash (addressed by z register)
- asm("lpm r0,z+");
- //! employ a temporary variable chDataA
- asm("mov %chDataA,r0");
- //! load a byte from sram (addressed by x register)
- asm("ld r0,x+");
- //! employ a temporary variable chDataB
- asm("mov %chDataB,r0");
- //! checking...
- if (chDataA != chDataB)
- {
- return FALSE;
- }
- }
- #endif
- return TRUE;
- }
- #endif
- /***********************************************************
- * 函数说明: 写入页面函数 *
- * 输入: 缓冲区地址,目标地址 *
- * 输出: 操作是否成功 *
- * 调用函数: *
- ***********************************************************/
- BOOL Bootloader_Write_Page
- (
- void *pData,
- UINT16 wLength,
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT32 dwAddress
- #else
- UINT16 wAddress
- #endif
- )
- {
- BYTE *pchData = pData;
- BYTE *pchBuffer = NULL;
- #if BL_USE_LOAD_PAGE != ENABLE
- UINT16 wCounter;
- #endif
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT8 TRAMPZ = RAMPZ;
- #endif
- if (pData == NULL)
- {
- return FALSE;
- }
-
- asm("wdr");
-
- #if BL_CANCEL_AUTO_FORMAT_ADDRESS == ENABLE
- //! do not snap the input flash address to page address
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- if ((dwAddress & (FLASH_PAGE_SIZE - 1)) != 0)
- #else
- if ((wAddress & (FLASH_PAGE_SIZE - 1)) != 0)
- #endif
- {
- UINT8 chBuffer[FLASH_PAGE_SIZE];
-
- //! get to know how many bytes are there before a normal page accessing.
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- UINT8 chTempCounter = FLASH_PAGE_SIZE - (dwAddress & (FLASH_PAGE_SIZE - 1));
- #else
- UINT8 chTempCounter = FLASH_PAGE_SIZE - (wAddress & (FLASH_PAGE_SIZE - 1));
- #endif
- if (wLength < chTempCounter)
- {
- chTempCounter = wLength;
- }
- wLength -= chTempCounter;
-
- #if BL_USE_LOAD_PAGE == ENABLE
- Bootloader_Load_Page_Buffer
- (
- chBuffer,
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- dwAddress & (~((UINT32)FLASH_PAGE_SIZE - 1))
- #else
- wAddress & (~((UINT16)FLASH_PAGE_SIZE - 1))
- #endif
- );
- #else
- for (wCounter = 0;wCounter < UBOUND(chBuffer);wCounter++)
- {
- chBuffer[wCounter] = 0xFF;
- }
- #endif
- //! copy the data
- //! need to read the page before writing
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- pchBuffer = chBuffer + (dwAddress & (FLASH_PAGE_SIZE - 1));
- #else
- pchBuffer = chBuffer + (wAddress & (FLASH_PAGE_SIZE - 1));
- #endif
- while(chTempCounter--)
- {
- *pchBuffer = *pchData;
- pchBuffer++;
- pchData++;
- }
-
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- SAFE_CODE_PERFORMANCE
- (
- Fill_Page_Buffer(chBuffer,dwAddress);
- Do_Boot_Loader_Action(SPM_PAGE_ERASE);
- Do_Boot_Loader_Action(SPM_PAGE_WRITE);
- Do_Boot_Loader_Action(SPM_ENBALE_RWW);
- )
- RAMPZ = TRAMPZ;
- #else
- SAFE_CODE_PERFORMANCE
- (
- Fill_Page_Buffer(chBuffer,wAddress);
- Do_Boot_Loader_Action(SPM_PAGE_ERASE);
- Do_Boot_Loader_Action(SPM_PAGE_WRITE);
- Do_Boot_Loader_Action(SPM_ENBALE_RWW);
- )
-
- #endif
-
-
- WDR();
- #if BL_USE_PAGE_VERIFY == ENABLE
- //! verify the page
- if (
- !Bootloader_Flash_Page_Verify
- (
- chBuffer,
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- dwAddress & (~((UINT32)FLASH_PAGE_SIZE - 1))
- #else
- wAddress & (~((UINT16)FLASH_PAGE_SIZE - 1))
- #endif
- )
- )
- {
- //! failed in verifying...
- return FALSE;
- }
- #endif
-
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- dwAddress += FLASH_PAGE_SIZE;
- dwAddress &= (~((UINT32)FLASH_PAGE_SIZE - 1));
- #else
- wAddress += FLASH_PAGE_SIZE;
- wAddress &= (~((UINT16)FLASH_PAGE_SIZE - 1));
- #endif
-
- }
- #endif
- //! normal page writing access
- while(wLength > FLASH_PAGE_SIZE)
- {
- //! do a page write sequence...
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- SAFE_CODE_PERFORMANCE
- (
- Fill_Page_Buffer(pchData,dwAddress);
- Do_Boot_Loader_Action(SPM_PAGE_ERASE);
- Do_Boot_Loader_Action(SPM_PAGE_WRITE);
- Do_Boot_Loader_Action(SPM_ENBALE_RWW);
- )
- RAMPZ = TRAMPZ;
- #else
- SAFE_CODE_PERFORMANCE
- (
- Fill_Page_Buffer(pchData,wAddress);
- Do_Boot_Loader_Action(SPM_PAGE_ERASE);
- Do_Boot_Loader_Action(SPM_PAGE_WRITE);
- Do_Boot_Loader_Action(SPM_ENBALE_RWW);
- )
- #endif
-
- #if BL_USE_PAGE_VERIFY == ENABLE
- //! verify the page
- if (
- !Bootloader_Flash_Page_Verify
- (
- pchData,
- #if BL_CANCEL_AUTO_FORMAT_ADDRESS == ENABLE
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- dwAddress
- #else
- wAddress
- #endif
- #else
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- dwAddress & (~((uint32_t)FLASH_PAGE_SIZE - 1))
- #else
- wAddress & (~((uint16_t)FLASH_PAGE_SIZE - 1))
- #endif
- #endif
- )
- )
- {
- //! failed in verifying
- return FALSE;
- }
- #endif
- pchData += FLASH_PAGE_SIZE;
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- dwAddress += FLASH_PAGE_SIZE;
- #else
- wAddress += FLASH_PAGE_SIZE;
- #endif
- wLength -= FLASH_PAGE_SIZE;
- }
-
- if (wLength)
- {
- #if BL_USE_LOAD_PAGE == ENABLE
- UINT8 chBuffer[FLASH_PAGE_SIZE];
- #else
- UINT8 chBuffer[FLASH_PAGE_SIZE];
- #endif
- if (wLength < FLASH_PAGE_SIZE)
- {
- //! need to read the page before writing
- pchBuffer = chBuffer;
-
- #if BL_USE_LOAD_PAGE == ENABLE
- Bootloader_Load_Page_Buffer
- (
- chBuffer,
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- dwAddress
- #else
- wAddress
- #endif
- );
- #else
- for (wCounter = 0;wCounter < UBOUND(chBuffer);wCounter++)
- {
- chBuffer[wCounter] = 0xFF;
- }
- #endif
-
- //! copy the data
- while(wLength--)
- {
- *pchBuffer = *pchData;
- pchBuffer++;
- pchData++;
- }
- pchBuffer = chBuffer;
- }
- else
- {
- pchBuffer = pchData;
- }
-
- //! bootloader sequence
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- SAFE_CODE_PERFORMANCE
- (
- Fill_Page_Buffer(pchBuffer,dwAddress);
- Do_Boot_Loader_Action(SPM_PAGE_ERASE);
- Do_Boot_Loader_Action(SPM_PAGE_WRITE);
- Do_Boot_Loader_Action(SPM_ENBALE_RWW);
- )
- RAMPZ = TRAMPZ;
- #else
- SAFE_CODE_PERFORMANCE
- (
- Fill_Page_Buffer(pchBuffer,wAddress);
- Do_Boot_Loader_Action(SPM_PAGE_ERASE);
- Do_Boot_Loader_Action(SPM_PAGE_WRITE);
- Do_Boot_Loader_Action(SPM_ENBALE_RWW);
- )
- #endif
- #if BL_USE_PAGE_VERIFY == ENABLE
- //! verify the page
- if (
- !Bootloader_Flash_Page_Verify
- (
- pchBuffer,
- #if BL_CANCEL_AUTO_FORMAT_ADDRESS == ENABLE
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- dwAddress
- #else
- wAddress
- #endif
- #else
- #if BL_USE_EXTEND_ADDRESS_SPACE == ENABLE
- dwAddress & (~((uint32_t)FLASH_PAGE_SIZE - 1))
- #else
- wAddress & (~((uint16_t)FLASH_PAGE_SIZE - 1))
- #endif
- #endif
- )
- )
- {
- //! failed in verifying
- return FALSE;
- }
- #endif
- }
- return TRUE;
- }
- /***********************************************************
- * 函数说明: 将中断向量表放置到Bootloader Section *
- * 输入: 无 *
- * 输出: 无 *
- * 调用函数: 无 *
- ***********************************************************/
- void Bootloader_Put_INT_Vector_Into_BLS(void)
- {
- #if defined(ATMega32) || defined(ATMega16)
- GICR |= BIT(IVCE);
- GICR = (GICR & (~BIT(IVCE))) | BIT(IVSEL);
- #else
- MCUCR |= BIT(IVCE);
- MCUCR = (MCUCR & (~BIT(IVCE))) | BIT(IVSEL);
- #endif
- }
- /***********************************************************
- * 函数说明: 将中断向量表放置到Application Section *
- * 输入: 无 *
- * 输出: 无 *
- * 调用函数: 无 *
- ***********************************************************/
- void Bootloader_Put_INT_Vector_Into_APPS(void)
- {
- #if defined(ATMega32) || defined(ATMega16)
- GICR |= BIT(IVCE);
- GICR = GICR & (~(BIT(IVCE) | BIT(IVSEL)));
- #else
- MCUCR |= BIT(IVCE);
- MCUCR = MCUCR & (~(BIT(IVCE) | BIT(IVSEL)));
- #endif
- }
- #if BL_USE_WRITE_LOCK_BITS == ENABLE
- /***********************************************************
- * 函数说明: 写Lockbits指令 *
- * 输入: 要写入Lockbits的内容 *
- * 输出: 无 *
- * 调用函数: Do_Boot_Loader_Action() *
- ***********************************************************/
- void Bootloader_Write_Lock_Bits(UINT8 chLockBits)
- {
- // 读取LockBits到r0
- asm("mov r0,r16");
- //向Z指针写入0x0001,以保持兼容性
- asm("ldi r30,0x01");
- asm("ldi r31,0x00");
-
- Do_Boot_Loader_Action(SPM_FUSE_AND_LOCK_BITS);
- }
- #endif
- #if BL_USE_READ_SIGNATURE == ENABLE
- /***********************************************************
- * 函数说明: 读取芯片Signature *
- * 输入: Signature地址 *
- * 输出: 读取到的字节 *
- * 调用函数: 无 *
- ***********************************************************/
- UINT8 Bootloader_Read_Signature(UINT16 wIndex)
- {
- UINT8 chData;
-
- //将地址保存到Z指针
- asm("movw r30,r16");
-
- /* 等待上次操作结束 */
- while(SPMCSR & BIT(SPMEN))
- {
- asm("wdr");
- }
-
- SAFE_CODE_PERFORMANCE
- (
- while(EECR & BIT(EEWE))
- {
- asm("wdr");
- }
- SPMCSR = SPM_READ_SIGNATURE;
- asm("lpm %chData,z");
- )
-
- return chData;
- }
- #endif
- #if BL_USE_READ_FUSE_AND_LOCK_BITS == ENABLE
- /***********************************************************
- * 函数说明: Fuse和Lock Bits读取函数 *
- * 输入: Fuse和Lock Bits的地址 *
- * 输出: 读取到的字节 *
- * 调用函数: 无 *
- ***********************************************************/
- UINT8 Bootloader_Read_Fuse(UINT16 wIndex)
- {
- UINT8 chData;
-
- //将地址保存到Z指针
- asm("movw r30,r16");
-
- /* 等待上次操作结束 */
- while(SPMCSR & BIT(SPMEN))
- {
- asm("wdr");
- }
-
- SAFE_CODE_PERFORMANCE
- (
- while(EECR & BIT(EEWE))
- {
- asm("wdr");
- }
- SPMCSR = SPM_FUSE_AND_LOCK_BITS;
- asm("lpm %chData,z");
- )
-
- return chData;
- }
- #endif
复制代码 |
|