?? rsm_upd.c
字號:
#include "user_init.h"
#include "rsm_upd.h"
/// ****** New resume info write / read functions ******
#ifdef SUPPORT_SPI_FLASH//added by wangyong for compile warning 2007-1-16 03:01下午
extern int SPI_Resume_Read();
extern int SPI_Resume_Write();
#endif
//#define RSM_UPDATE_DBG
//#define RESUME_INFO_DBG
#include "flash.h"
#define UNUSED_VALUE 0xFF
#define FIRST_LEN 4 //ted.chang 2006 1117, 2
#ifdef SUPPORT_SPI_FLASH
//static int find_start_addr(int low, int high)
int find_start_addr(int low, int high)
{
int hi, lo; //, mid;
BYTE tmp1[4];
lo = low;
hi = high-3;
while (lo<=hi)
{
SPI_Resume_Read(hi, tmp1, 4);
if(tmp1[3]!=0xFF || tmp1[2]!=0xFF || tmp1[1]!=0xFF || tmp1[0]!=0xFF)
{
break;
}
hi-=4;
}
if (hi<lo)
return lo;
else
return (hi+4);
}
//swpong 2006 0404
// Function : Resume_Info_Write_Update
// Description : re-direct writing address to free-section address
// Input : iStartAddr -> the Start Address of pBuf1 where pBuf2 starts
// *pBuf1 -> buffer of full record, used in the first time and after sector full.
// iBuf1Len -> length of pBuf1
// *pBuf2 -> buffer for updated data
// iBuf2Len -> length of pBuf2
// Output : >=0 -> sucess
// <0 -> fail
// Note : call write-funcion to write index array,
// and write buffer data to destination
enum {H_MODFF=0, H_LEN, H_OFFSET_HI, H_OFFSET_LO, HEAD_SIZE};
#define W_ARRAY_SIZE 8
#define W_ALIGN 4
#define MODFF_IDX 0
int Resume_Info_Write_Update(UINT32 iStartAddr, BYTE *pBuf1, UINT32 iBuf1Len, BYTE *pBuf2, UINT32 iBuf2Len)
{
#ifdef RESUME_INFO_DBG
printf_w("---Resume_Info_Write_Update---\n");
#endif
if(((flash_info>>16) != 0x1111) && (flash_info!=0))
{
SPI_APP_upgrade_init();
}
int iRes =0;
BYTE FirstMark[FIRST_LEN];
UINT32 i, j, size;
BYTE w_array[W_ARRAY_SIZE];
BYTE w_head[HEAD_SIZE];
UINT32 ExtraInfoSize, total_len, current_start;
BYTE *p;
#ifdef RESUME_INFO_DBG
printf_w("Resume info write Update\n");
FlashDelay(10000);
#endif
SPI_Resume_Read(rsm_flash_start_addr, FirstMark, FIRST_LEN);
if (FirstMark[0] == rsm_flash_erasing_keyword) //the first time written, write full structure.
{
FirstMark[0] = (iBuf1Len+FIRST_LEN)>>8;
FirstMark[1] = (iBuf1Len+FIRST_LEN)&0xff;
FirstMark[2] = 0x00;
FirstMark[3] = 0x00;
SPI_Resume_Write(rsm_flash_start_addr, FirstMark, FIRST_LEN);
SPI_Resume_Write(rsm_flash_start_addr+FIRST_LEN,pBuf1,iBuf1Len);
spi_api_resume_start_address = rsm_flash_start_addr+FIRST_LEN + iBuf1Len;//tw add.20070416
#ifdef RESUME_INFO_DBG
printf_w("Write initial %x, %x, %d\n", FirstMark[0], FirstMark[1], iBuf1Len);
#endif
}
else //for difference history
{
SPI_Resume_Read(rsm_flash_start_addr, FirstMark, FIRST_LEN);
//====ted.chang 2007 07.24 for block resume, only for 4 ~ 64k resume
if(FirstMark[0]==0xFF)
{
SPI_Resume_Write(rsm_flash_start_addr+FIRST_LEN+iStartAddr,pBuf2,iBuf2Len);
}
else
//====
{
current_start = spi_api_resume_start_address;//tw add.20070416
////tw mark.20070416
//current_start = find_start_addr(rsm_flash_start_addr + ((FirstMark[0]<<8)|(FirstMark[1])),
// rsm_flash_start_addr + rsm_flash_sec_size-1);
if (!current_start)
{
iRes = -1;
printf_w ("**SPI find start addr error***\n");
}
else
{
if(iBuf2Len % 7 == 0)
ExtraInfoSize = HEAD_SIZE + (iBuf2Len)/(W_ARRAY_SIZE-1);
else
ExtraInfoSize = HEAD_SIZE + (iBuf2Len)/(W_ARRAY_SIZE-1) + 1;
total_len = iBuf2Len + ExtraInfoSize;
UINT32 realwrite;
realwrite = ((total_len-1)&0xFFFFFFFC) +4;
#ifdef RSM_UPDATE_DBG
printf_w("Write at 0x%x, len = %d, extra = %d\n", current_start, total_len, ExtraInfoSize);
#endif
//====ted.chang 2007 07.24 for block resume, only for 4 ~ 64k resume
//if ((current_start + total_len) >= (rsm_flash_start_addr+rsm_flash_sec_size))
if ((current_start + realwrite) >= (rsm_flash_start_addr+0x1000))
//====
{
//====ted.chang 2007 07.24 for block resume, only for 4 ~ 64k resume
if((rsm_flash_start_addr & 0xf000)!=0xf000)
{
rsm_flash_start_addr = rsm_flash_start_addr + 0x1000;
printf_w("Recreate new 4k block ... \n");
FirstMark[0] = (iBuf1Len+FIRST_LEN)>>8;
FirstMark[1] = (iBuf1Len+FIRST_LEN)&0xff;
FirstMark[2] = 0x00;
FirstMark[3] = 0x00;
SPI_Resume_Write(rsm_flash_start_addr, FirstMark, FIRST_LEN);//tw mark.20070416
iRes = SPI_Resume_Write(rsm_flash_start_addr+FIRST_LEN,pBuf1,iBuf1Len);//tw mark.20070416
spi_api_resume_start_address = rsm_flash_start_addr+FIRST_LEN + iBuf1Len;//tw add.20070416
if(((flash_info>>16) != 0x1111) && (flash_info!=0))//tw add.20070416
{
SPI_APP_flash_init();
}
return iRes; //tw mark.20070416
}
else
//====
{
printf_w("Sector full, erasing ... \n");
//====ted.chang 2007 07.24 for block resume, only for 4 ~ 64k resume
rsm_flash_start_addr = rsm_flash_start_addr + 0x1000 - rsm_flash_sec_size;
//====
//sector full, erase and update all.
SPI_api_sec_erase(rsm_flash_sec_type, rsm_flash_start_addr);
FirstMark[0] = (iBuf1Len+FIRST_LEN)>>8;
FirstMark[1] = (iBuf1Len+FIRST_LEN)&0xff;
FirstMark[2] = 0x00;
FirstMark[3] = 0x00;
SPI_Resume_Write(rsm_flash_start_addr, FirstMark, FIRST_LEN);//tw mark.20070416
iRes = SPI_Resume_Write(rsm_flash_start_addr+FIRST_LEN,pBuf1,iBuf1Len);//tw mark.20070416
spi_api_resume_start_address = rsm_flash_start_addr+FIRST_LEN + iBuf1Len;//rsm_flash_start_addr;tw add.20070416
//return 0;//tw mark.20070416
if(((flash_info>>16) != 0x1111) && (flash_info!=0))//tw add.20070416
{
SPI_APP_flash_init();
}
return iRes;
}
}
else //Update history
{
//swpong 2006 0505 w_head[H_MODFF] = 0;
w_head[H_MODFF] = (rsm_flash_erasing_keyword&0x80)^0x80;
if (total_len == rsm_flash_erasing_keyword) //swpong 2006 0505, 0xff)
{
w_head[H_MODFF] |= (1<<H_LEN);
w_head[H_LEN] = 0;
}
else
w_head[H_LEN] = total_len&0xff;
if ((iStartAddr&0xff) == rsm_flash_erasing_keyword) //swpong 2006 0505, 0xff)
{
w_head[H_MODFF] |= (1<<H_OFFSET_LO);
w_head[H_OFFSET_LO] = 0;
}
else
w_head[H_OFFSET_LO] = iStartAddr&0xff;
if ((iStartAddr>>8) == rsm_flash_erasing_keyword) //swpong 2006 0505, 0xff)
{
w_head[H_MODFF] |= (1<<H_OFFSET_HI);
w_head[H_OFFSET_HI] = 0;
}
else
w_head[H_OFFSET_HI] = (iStartAddr>>8)&0xff;
#ifdef RSM_UPDATE_DBG
printf_w("Write cur = %d HEAD(%x,%x,%x,%x)\n",current_start, w_head[H_MODFF], w_head[H_OFFSET_HI], w_head[H_OFFSET_LO], w_head[H_LEN]);
#endif
SPI_Resume_Write(current_start, w_head, HEAD_SIZE);
current_start += HEAD_SIZE;
#ifdef RSM_UPDATE_DBG
printf_w("Write offset = 0x%x, len = %d\n", w_head[H_OFFSET_LO]|((w_head[H_OFFSET_HI])<<8), w_head[H_LEN]);
#endif
size = iBuf2Len;
j = 0;
p = pBuf2;
while (size)
{
if (j==0)
//swpong2006 0505 w_array[MODFF_IDX] = 0;
w_array[MODFF_IDX] = (rsm_flash_erasing_keyword&0x80)^0x80;
if (*p == 0xff)
{
w_array[MODFF_IDX] |= (1<<j);
w_array[j+1] = 0;
}
else
w_array[j+1] = *p;
j++;
j%=(W_ARRAY_SIZE - 1);
if (j==0)
{
#ifdef RSM_UPDATE_DBG
printf_w("WriteTo:0x%x, left : %d\n", current_start, size);
#endif
SPI_Resume_Write(current_start, w_array, W_ARRAY_SIZE);
current_start += W_ARRAY_SIZE;
}
size--;
p++;
}
if (j)
{
for (i=j+1;i<W_ARRAY_SIZE;i++)
w_array[i] = 0x00;
//ted.chang 2007.07.25 for unfinished writing
if (j<=(W_ALIGN-1))// for size less then or equal to 3
//====
{
SPI_Resume_Write(current_start, w_array, W_ALIGN);
current_start += W_ALIGN;
}
else//for size larger then 3 and less then or equal to 7
{
SPI_Resume_Write(current_start, w_array, W_ARRAY_SIZE);
current_start += W_ARRAY_SIZE;
}
}
#ifdef RSM_UPDATE_DBG
printf_w ("Write next start = 0x%x\n", current_start);
#endif
}
}
spi_api_resume_start_address = current_start;//tw add.20070416
}
}
if(((flash_info>>16) != 0x1111) && (flash_info!=0))
{
SPI_APP_flash_init();
}
return iRes;
}
//
// Function : Resume_Info_Read_Update
// Description : re-direct reading address to current-section address
// Input :
// *pBuf1 -> buffer for recording data
// iLen -> buffer length
// Output : >=0 -> sucess
// <0 -> fail
// Note :
int Resume_Info_Read_Update(BYTE *pBuf1, UINT32 iLen)
{
#ifdef RESUME_INFO_DBG
printf_w("---Resume_Info_Read---\n");
#endif
int current_addr = 0, end_addr, len;
unsigned int cnt = 0, get_cnt;
UINT32 offset, j;
BYTE *p;
BYTE FirstMark[FIRST_LEN];
BYTE w_array[W_ARRAY_SIZE];
BYTE w_head[HEAD_SIZE];
if(((flash_info>>16) != 0x1111) && (flash_info!=0))//tw open.20070416
{
SPI_APP_upgrade_init();
}
#ifdef RSM_UPDATE_DBG
printf_w("Resume info read Update\n");
#endif
// for skip first mark and jump to append data start address if exist
SPI_Resume_Read(rsm_flash_start_addr, FirstMark, FIRST_LEN);
SPI_Resume_Read(rsm_flash_start_addr+FIRST_LEN, pBuf1, iLen);
current_addr = rsm_flash_start_addr + ((FirstMark[0]<<8)|(FirstMark[1]));
if (FirstMark[0] == rsm_flash_erasing_keyword)
{
#ifdef RSM_UPDATE_DBG
printf_w("FirstMark[0] == rsm_flash_erasing\n");
#endif
end_addr = current_addr; //swpong 2006 0503
}
else{ //swpong 2006 0503
//end_addr = find_start_addr(current_addr, rsm_flash_start_addr + rsm_flash_sec_size-1);//tw mark.20070416
end_addr = spi_api_resume_start_address;//tw add.20070416
}
#ifdef RSM_UPDATE_DBG
printf_w("Resume Update get curr = 0x%x, end = 0x%x\n", current_addr, end_addr);
#endif
//p = pBuf1;
while (current_addr < end_addr)
{
SPI_Resume_Read(current_addr, w_head, HEAD_SIZE);
#ifdef RSM_UPDATE_DBG
printf_w("Read cur = %x HEAD(%x,%x,%x,%x)\n",current_addr, w_head[H_MODFF], w_head[H_OFFSET_HI], w_head[H_OFFSET_LO], w_head[H_LEN]);
#endif
//ted.chang 2007.07.25 for unfinished writing
if((w_head[0]==0xFF) || (w_head[1]==0xFF)||(w_head[2]==0xFF)||(w_head[3]==0xFF)){
if((w_head[0]==0xFF) && (w_head[1]==0xFF)&&(w_head[2]==0xFF)&&(w_head[3]==0xFF))
break;
else{
current_addr += HEAD_SIZE;
continue;
}
}
//====
if (w_head[H_MODFF]&(1<<H_LEN))
w_head[H_LEN] = rsm_flash_erasing_keyword; //swpong 2006 0505, 0xff;
if (w_head[H_MODFF]&(1<<H_OFFSET_LO))
w_head[H_OFFSET_LO] = rsm_flash_erasing_keyword; //swpong 2006 0505, 0xff;
if (w_head[H_MODFF]&(1<<H_OFFSET_HI))
w_head[H_OFFSET_HI] = rsm_flash_erasing_keyword; //swpong 2006 0505, 0xff;
offset = (((UINT32)w_head[H_OFFSET_HI])<<8) | (w_head[H_OFFSET_LO]);
len = (w_head[H_LEN]&0xff) - HEAD_SIZE;
if((offset >iLen) || (len <0)){
if(((flash_info>>16) != 0x1111) && (flash_info!=0))//tw add.20070416
{
SPI_APP_flash_init();
}
return 1;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -