void WriteBufferHandler(uint8_t numBytes, uint8_t inputBuffer[]){ //takes data from the loghandler and writes it to the flash memory uint16_u outInt16; for(uint16_t i = 0; i < numBytes; i++){ writeBuffer[writeBufferIndex] = inputBuffer[i]; writeBufferIndex++; if (writeBufferIndex == 0){ outInt16.val = currentRecordNumber; FlashWritePage(currentPageAddress,writeBuffer); loggingState = COMPLETE_PAGE; writeBuffer[0] = WRITE_STARTED; writeBuffer[1] = outInt16.buffer[0]; writeBuffer[2] = outInt16.buffer[1]; writeBufferIndex = 3; loggingReady = false; } } }
void WriteBufferRemainder(){ //any data remaining in the output buffer is written uint16_u outInt16; outInt16.val = currentRecordNumber; if (writeBufferIndex == 0){ currentPageAddress -= 1; FlashWriteByte(currentPageAddress,0,WRITE_COMPLETE_REC_END); loggingState = UPDATE_FIRST_PAGE; return; } writeBuffer[0] = WRITE_STARTED_REC_END; writeBuffer[1] = outInt16.buffer[0]; writeBuffer[2] = outInt16.buffer[1]; for(uint16_t i = writeBufferIndex; i < 256; i++){ writeBuffer[i] = 0xFF; } writeBufferIndex = 0; FlashWritePage(currentPageAddress,writeBuffer); loggingState = COMPLETE_LAST_PAGE; }
/******************************************************************** 函数功能:往FLASH中写一个扇区(FLASH_SECTOR_SIZE字节)。 入口参数:Addr: 字节地址;pBuf:保存数据的缓冲区;Remain:预计接下来还需要写多少扇区 返 回:写入的状态。0:成功。非0:失败。 备 注:当Remain不为0时,当前页以及该块内剩余部分将不会回写! 如果数据传输结束,应该将Remain置0,将数据写回。 ********************************************************************/ uint32 FlashWriteOneSector(uint32 Addr, uint8 * pBuf, uint32 Remain) { uint32 i; uint32 SwapPageAddr; FlashClrCe(); //选中芯片 if(Addr>FLASH_MAX_SECTOR_ADDR)return 1; //如果地址超出范围,则返回失败代码1,越界 Addr=FlashAddrRemap(Addr); //重新影射地址 if((Addr&(~(FLASH_PAGE_SIZE-1)))!=(FlashCurrentWriteSectorAddr&(~(FLASH_PAGE_SIZE-1)))) //如果跨page { if(FlashNeedWriteBack) //如果前面写了数据,则需要将当前读出的page写回 { if(FlashWritePage()&0x01) //写入失败 { Addr=FlashDealBadBlock(Addr-FLASH_PAGE_SIZE,3)+FLASH_PAGE_SIZE; //坏块处理 } } if((Addr&(~(FLASH_BLOCK_SIZE-1)))!=(FlashCurrentWriteSectorAddr&(~(FLASH_BLOCK_SIZE-1)))) //如果跨block,则需要擦除新的块, { //在擦除之前,要先将原来的块复制到交换区,并且将该块前面部分数据写回 //该函数除了将整块数据复制到交换区以外,并且还将擦除掉原来的块,然后将前面部分复制回原来的块 Addr=FlashCopyBlockToSwap(Addr); } //从交换区中读出对应的一页 FlashWriteCommand(0x00); FlashWriteAddr4Byte(FlashGetCurrentSwapBlock()+(Addr&(FLASH_BLOCK_SIZE-1))); FlashWriteCommand(0x35); FlashWait(); //随机写 FlashWriteCommand(0x85); FlashWriteAddr4Byte(Addr); //写4字节地址 FlashSetPortAsOut(); //总线设置为输出口 for(i=0;i<FLASH_SECTOR_SIZE;i++) { FlashWriteByte(pBuf[i]); } FlashSetPortAsIn(); //总线设置为输入口 FlashNeedWriteBack=1; //需要写回 } else //没有超过一页地址,则直接写数据 { //随机写 FlashWriteCommand(0x85); FlashWriteAddr2Byte(Addr); FlashSetPortAsOut(); //总线设置为输出口 for(i=0;i<FLASH_SECTOR_SIZE;i++) { FlashWriteByte(pBuf[i]); } FlashSetPortAsIn(); //总线设置为输入口 FlashNeedWriteBack=1; //需要写回 } FlashCurrentWriteSectorAddr=Addr; //保存本次地址 if(Remain==0) //剩余扇区数为0,不会再写了,需要写回 { if(FlashNeedWriteBack) //如果前面写了数据,则需要将当前读出的page写回 { if(FlashWritePage()&0x01) //写入失败 { Addr=FlashDealBadBlock(Addr,3); //坏块处理 } } //计算剩余页数 Remain=(((Addr+FLASH_BLOCK_SIZE)&(~(FLASH_BLOCK_SIZE-1)))-(Addr&(~(FLASH_PAGE_SIZE-1))))/FLASH_PAGE_SIZE-1; //计算在交换块中的起始页地址 SwapPageAddr=FlashGetCurrentSwapBlock()+(Addr&(FLASH_BLOCK_SIZE-1)); for(i=0;i<Remain;i++) //将该块内保存在交换块中剩余部分页的数据复制回该块 { Addr+=FLASH_PAGE_SIZE; //从下一页开始写 SwapPageAddr+=FLASH_PAGE_SIZE; if(0x01==(FlashCopyPage(SwapPageAddr,Addr)&0x01)) //如果复制失败 { Addr=FlashDealBadBlock(Addr,2); //处理坏块 } } FlashNeedWriteBack=0; //清除需要写回标志 FlashCurrentWriteSectorAddr=-1; } FlashSetCe(); //释放FLASH芯片 return 0; }
/******************************************************************** 函数功能:保存坏块表到FLASH的特定位置。 入口参数:无。 返 回:无。 备 注:无。 ********************************************************************/ void FlashSaveBadBlockTable(void) { uint32 i,j,k,Sum; for(i=0;i<FLASH_BLOCKS_TABLE;i++) //标志为准备擦除 { FlashWriteCommand(0x80); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*(i+1) - FLASH_PAGE_SIZE); FlashSetPortAsOut(); //总线设置为输出口 FlashWriteByte(0x00); //将第一字节设置为0,表示准备擦除 //剩余字节写0xFF for(j=1;j<FLASH_PAGE_SIZE;j++) { FlashWriteByte(0xFF); } FlashWritePage(); //写页 } for(i=0;i<FLASH_BLOCKS_TABLE;i++) //将坏块表写入这三块 { FlashEraseBlock(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i); //擦除一块 FlashWriteCommand(0x80); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i); //写入第一块的开始位置 FlashSetPortAsOut(); //总线设置为输出口 FlashWriteByte(0x00); //将第1字节设置为0 FlashWriteByte(0x55); //将第2字节设置为0x55 FlashWriteByte(0xAA); //将第3字节设置为0xAA FlashWriteByte(0xFF); //将第4字节设置为0xFF Sum=0x1FE; //接着写坏块数量,并统计校验和 FlashWriteByte((FlashBadBlocksCount>>24)&0xFF); Sum+=(FlashBadBlocksCount>>24)&0xFF; FlashWriteByte((FlashBadBlocksCount>>16)&0xFF); Sum+=(FlashBadBlocksCount>>16)&0xFF; FlashWriteByte((FlashBadBlocksCount>>8)&0xFF); Sum+=(FlashBadBlocksCount>>8)&0xFF; FlashWriteByte((FlashBadBlocksCount)&0xFF); Sum+=(FlashBadBlocksCount)&0xFF; j=8; //写了8字节 //保存坏块表 for(k=0;k<sizeof(FlashBadBlockTable[0][0])*FLASH_BAD_BLOCKS_REMAP*2;k++) { if(0==(j&(FLASH_PAGE_SIZE-1))) //如果超过了页,则需要重新写新页 { FlashWritePage(); //写页 FlashWriteCommand(0x80); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i + j); FlashSetPortAsOut(); //总线设置为输出口 } Sum+=((uint8 *)FlashBadBlockTable)[k]; //求校验和 FlashWriteByte(((uint8 *)FlashBadBlockTable)[k]); //写一字节 j++; } //保存重影射区的状态表 for(k=0;k<sizeof(FlashRemapBlockStatus[0])*FLASH_BAD_BLOCKS_REMAP;k++) { if(0==(j&(FLASH_PAGE_SIZE-1))) //如果超过了页,则需要重新写新页 { FlashWritePage(); //写页 FlashWriteCommand(0x80); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i + j); FlashSetPortAsOut(); //总线设置为输出口 } Sum+=((uint8 *)FlashRemapBlockStatus)[k]; //求校验和 FlashWriteByte(((uint8 *)FlashRemapBlockStatus)[k]); //写一字节 j++; } for(;0!=(j&(FLASH_PAGE_SIZE-1));j++) //将剩余部分写入0xFF { FlashWriteByte(0xFF); } FlashWritePage(); //写页 //已完成写状态及校验和写入到该块的倒数第二页 FlashWriteCommand(0x80); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*(i+1) - 2*FLASH_PAGE_SIZE); FlashSetPortAsOut(); //总线设置为输出口 FlashWriteByte(0x00); //将第一字节设置为0,表示已经写入 //将校验和取反加1,这样累加结果就为0 Sum=(~Sum)+1; //写校验和 FlashWriteByte((Sum>>24)&0xFF); FlashWriteByte((Sum>>16)&0xFF); FlashWriteByte((Sum>>8)&0xFF); FlashWriteByte((Sum)&0xFF); //剩余字节写0xFF for(j=5;j<FLASH_PAGE_SIZE;j++) { FlashWriteByte(0xFF); } FlashWritePage(); //写页 } }
void HttpcHandleContent(USHORT sLen, PCHAR pBuf) { UCHAR iVal; USHORT sLeftLen, sLen2; if (_sHttpcRespCode != 200) { goto SkipContent; } if (_iHttpcTask == HTTPC_TASK_GET_PROV || _iHttpcTask == HTTPC_TASK_GET_CFG || _iHttpcTask == HTTPC_TASK_CFG_AUTH) { sLen2 = sLen; if (_bHttpcEncrypt) { TaskRC4Calc(pBuf, pBuf, sLen2); } while (sLen2 --) { iVal = *pBuf ++; if (iVal == 0x0d || iVal == 0x0a) { if (_iHttpcTask == HTTPC_TASK_GET_PROV) { HandleProvParam(); } else { HttpcHandleSettings(); } } else if (iVal != (UCHAR)'"') { HttpcSaveRecv(iVal); } } goto SkipContent; } if (_iHttpcTask == HTTPC_TASK_GET_SW) { if (_iHttpcUpdatePage == SYSTEM_INVALID_PAGE) goto SkipContent; sLeftLen = FILE_FULL_PAGE_SIZE - _sHttpcPostLen; if (sLen < sLeftLen || !sLeftLen) { BufWrite(pBuf, sLen); BufForward(sLen); _sHttpcPostLen += sLen; } else { BufWrite(pBuf, sLeftLen); BufForward(sLeftLen); _sHttpcPostLen = 0; TaskUIHandler(UI_UPDATE_PROGRESS, (USHORT)_iHttpcCurPage); if (FlashWritePage(_iHttpcCurPage)) { _iHttpcUpdatePage = SYSTEM_INVALID_PAGE; goto SkipContent; } _iHttpcCurPage ++; if ((_iHttpcCurPage - _iHttpcUpdatePage) >= SYSTEM_PROGRAM_PAGE_NUM) { TaskSystemHandler(SYS_UPDATE_FLAG, _iHttpcCurPage); _iHttpcTask = HTTPC_TASK_REBOOT; } else { sLen2 = (USHORT)(sLen - sLeftLen); BufSeek(0); BufWrite((PCHAR)(pBuf + sLeftLen), sLen2); BufForward(sLen2); _sHttpcPostLen = sLen2; } } } SkipContent: if (_lHttpcContentLen > (ULONG)sLen) { _lHttpcContentLen -= (ULONG)sLen; } else { _lHttpcContentLen = 0; HttpcNextTask(); } }
void HttpcNextTask() { if (_iHttpcTask == HTTPC_TASK_GET_PROV) { if (_sHttpcRespCode == 200) { HandleProvParam(); _iHttpcTask = HTTPC_TASK_GET_CFG; } else if (_sHttpcRespCode == 503) { _sHttpcTimer = 10; _iHttpcTask = HTTPC_TASK_PROV_FAIL; } else { _sHttpcTimer = 0; _iHttpcTask = HTTPC_TASK_PROV_FAIL; } } else if (_iHttpcTask == HTTPC_TASK_GET_CFG || _iHttpcTask == HTTPC_TASK_CFG_AUTH) { if (_sHttpcRespCode == 401) { if (_iHttpcTask == HTTPC_TASK_GET_CFG) { _iHttpcRetry = 0; _iHttpcTask = HTTPC_TASK_CFG_AUTH; } } else { if (_sHttpcRespCode == 200) { HttpcHandleSettings(); TaskSystemHandler(SYS_MODIFY_PAGE, SYSTEM_SETTINGS_PAGE); FlashWritePage(SYSTEM_SETTINGS_PAGE); if (HttpcCheckCfg()) { _iHttpcTask = HttpcCheckSW() ? HTTPC_TASK_GET_SW : HTTPC_TASK_POST_CFGOK; } else { _iHttpcTask = HTTPC_TASK_POST_CFGFAIL; } } else { _sHttpcTimer = 20; _iHttpcTask = HTTPC_TASK_POST_CFGFAIL; } _iHttpcRetry = 0; if (_pHttpcRecvAuth) { free(_pHttpcRecvAuth); _pHttpcRecvAuth = NULL; } } } else if (_iHttpcTask == HTTPC_TASK_GET_SW) { _iHttpcTask = HTTPC_TASK_POST_SWFAIL; _iHttpcRetry = 0; } else if (_iHttpcTask == HTTPC_TASK_REBOOT) { _iHttpcTask = HTTPC_TASK_POST_SWOK; } else if (_iHttpcTask == HTTPC_TASK_POST_SWOK) { _iHttpcTask = HTTPC_TASK_REBOOT; } else if (_iHttpcTask == HTTPC_TASK_POST_SWFAIL || _iHttpcTask == HTTPC_TASK_POST_CFGOK) { _iHttpcTask = HTTPC_TASK_NONE; } else if (_iHttpcTask == HTTPC_TASK_POST_CFGFAIL) { _iHttpcTask = HTTPC_TASK_PROV_FAIL; } _iHttpcState = HCS_MESSAGE_END; _bHttpcEncrypt = FALSE; }