/** @ingroup FLASH * フラッシュ書き込み * @param psFlash 書き込みたいデータ * @param sector 書き込みセクタ * @param offset 書き込みセクタ先頭からのオフセット * @return TRUE:書き込み成功 FALSE:失敗 */ bool_t bFlash_Write(tsFlash *psFlash, uint8 sector, uint32 offset) { bool_t bRet = FALSE; offset += (uint32)sector * FLASH_SECTOR_SIZE; // calculate the absolute address #ifdef USE_EEPROM psFlash->u32Magic = FLASH_MAGIC_NUMBER; psFlash->u8CRC = u8CCITT8((uint8*)&(psFlash->sData), sizeof(tsFlashApp)); if (EEP_6x_bWrite(0, sizeof(tsFlash), (uint8 *)psFlash)) { bRet = TRUE; } #else if (bAHI_FlashInit(FLASH_TYPE, NULL) == TRUE) { if (bAHI_FlashEraseSector(sector) == TRUE) { // erase a corresponding sector. psFlash->u32Magic = FLASH_MAGIC_NUMBER; psFlash->u8CRC = u8CCITT8((uint8*)&(psFlash->sData), sizeof(tsFlashApp)); if (bAHI_FullFlashProgram(offset, sizeof(tsFlash), (uint8 *)psFlash)) { bRet = TRUE; } } } #endif return bRet; }
uint8 startCodeUpdate(uint8* inMsg, uint8* outMsg) { bAHI_FlashInit(E_FL_CHIP_AUTO, NULL); //clear buffer in flash 32k for 5139 or 64k for 5148 codeUpdateLength=0; codeUpdateCrc=0; //send ack outMsg[0]=0x91; //todo store module type somewhere bAHI_FlashEraseSector(1); #ifdef JN5148 outMsg[1]=6; outMsg[2]='J'; outMsg[3]='N'; outMsg[4]='5'; outMsg[5]='1'; outMsg[6]='4'; outMsg[7]='8'; #else outMsg[1]=6; outMsg[2]='J'; outMsg[3]='N'; outMsg[4]='5'; outMsg[5]='1'; outMsg[6]='3'; outMsg[7]='9'; #endif return 8; }
/** @ingroup FLASH * フラッシュの読み込み * @param psFlash 読み込み格納データ * @param sector 読み出しセクタ * @param offset セクタ先頭からのオフセット * @return TRUE:読み出し成功 FALSE:失敗 */ bool_t bFlash_Read(tsFlash *psFlash, uint8 sector, uint32 offset) { bool_t bRet = FALSE; offset += (uint32)sector * FLASH_SECTOR_SIZE; // calculate the absolute address #ifdef USE_EEPROM if (EEP_6x_bRead(0, sizeof(tsFlash), (uint8 *)psFlash)) { bRet = TRUE; } #else if (bAHI_FlashInit(FLASH_TYPE, NULL) == TRUE) { if (bAHI_FullFlashRead(offset, sizeof(tsFlash), (uint8 *)psFlash)) { bRet = TRUE; } } #endif // validate content if (bRet && psFlash->u32Magic != FLASH_MAGIC_NUMBER) { bRet = FALSE; } if (bRet && psFlash->u8CRC != u8CCITT8((uint8*)&(psFlash->sData), sizeof(tsFlashApp))) { bRet = FALSE; } return bRet; }
PUBLIC void FlashErase() { vAHI_FlashPowerUp(); bAHI_FlashInit(E_FL_CHIP_AUTO, NULL); bAHI_FlashEraseSector(3); vAHI_FlashPowerDown(); }
PRIVATE void FlashInit(uint8* data) { uint8 i; if (m_FlashStartAddress == 0) { #ifdef JN5148 m_FlashStartAddress=1024*64*3; #else m_FlashStartAddress = 1024 * 32 * 3; #endif } for (i = 0; i < CONFIG_OBJECT_SIZE; i++) data[i] = 1; vAHI_FlashPowerUp(); bAHI_FlashInit(E_FL_CHIP_AUTO, NULL); }
PUBLIC void vFlashSettings_init(void *SettingsContent, uint8 SettingsLength){ // Проверить превышение массивом объема заданного буфера if(SettingsLength > APPROPRIATE_SETTINGS_LENGTH_IN_BYTES - SETTINGS_MARK_LENGTH_IN_BYTES - SETTINGS_CRC_LENGTH_IN_BYTES){ EHCall(FLASH_MOD_ID, FLASH_ERR_CODE_SETTINGS_CONTENT_OUT_OF_BUFFER); // Проверить наличие записываемых данных }else if(SettingsLength == 0){ EHCall(FLASH_MOD_ID, FLASH_ERR_CODE_SETTINGS_LENGTH_IS_ZERO); }else{ // Проинициализировать функции для внутренней Flash bAHI_FlashInit(E_FL_CHIP_INTERNAL, NULL); // Параметры массива CurrentSettingsContent = SettingsContent; CurrentSettingsLength = SettingsLength; } }
/** @ingroup FLASH * フラッシュセクター消去 * @return TRUE:書き込み成功 FALSE:失敗 */ bool_t bFlash_Erase(uint8 sector) { int i; bool_t bRet = FALSE; #ifdef USE_EEPROM // EEPROM の全領域をクリアする。セグメント単位で消去する uint8 au8buff[EEPROM_6X_SEGMENT_SIZE]; memset (au8buff, 0xFF, EEPROM_6X_SEGMENT_SIZE); bRet = TRUE; for (i = 0; i < EEPROM_6X_USER_SEGMENTS; i++) { bRet &= EEP_6x_bWrite(i * EEPROM_6X_SEGMENT_SIZE, EEPROM_6X_SEGMENT_SIZE, au8buff); } #else if (bAHI_FlashInit(FLASH_TYPE, NULL) == TRUE) { if (bAHI_FlashEraseSector(sector) == TRUE) { // erase a corresponding sector. bRet = TRUE; } } #endif return bRet; }
static void appcall(void *p) { static struct bl_appstate s = { IDLE, 0x00, 0x00, false }; clock_time_t time = clock_time(); msg_t *msg = uip_appdata, *smsg = uip_sappdata; if(uip_connected()) { s.state = IDLE; s.reset_req = false; s.write_addr = 0; s.write_len = 0; s.msg_len = 0; GDB2_PUTS(" conn "); } if(uip_closed() || uip_aborted() || uip_timedout()) { uip_close(); if(s.reset_req && uip_closed()) vAHI_SwReset(); /* at this point the system RESETS */ s.state = IDLE; GDB2_PUTS(" close\n"); } if(uip_acked()) { if (s.state==SENDING) { s.msg_len = 0; s.state = IDLE; }; GDB2_PUTS("bootloader: acked\n"); } if(uip_newdata()) { if (s.state == FLASHING) { bAHI_FullFlashProgram(s.write_addr, uip_datalen(), (uint8_t*) msg); s.write_addr += uip_datalen(); if(s.write_addr >= s.write_len) { GDB2_PUTS("bootloader: write done\n"); s.write_len = 0; s.state = SENDING; smsg->type = RSP_FLASH_PROG2; smsg->len = MSG_SIZEOF(smsg->asFlashWrite2Rsp); smsg->asFlashWrite2Rsp = OK; } } else if(s.state != SENDING) { s.msg_len += uip_datalen(); if(s.msg_len == msg->len) { GDB2_PUTS("bootloader: send\n"); s.msg_len = 0; s.state = SENDING; switch(msg->type) { case REQ_FLASH_ERASE: smsg->asFlashEraseRsp = bAHI_FlashEraseSector(0) ? OK : NOT_SUPPORTED; smsg->asFlashEraseRsp = bAHI_FlashEraseSector(1) ? OK|smsg->asFlashEraseRsp : NOT_SUPPORTED; smsg->asFlashEraseRsp = bAHI_FlashEraseSector(2) ? OK|smsg->asFlashEraseRsp : NOT_SUPPORTED; smsg->asFlashEraseRsp = bAHI_FlashEraseSector(3) ? OK|smsg->asFlashEraseRsp : NOT_SUPPORTED; smsg->asFlashEraseRsp = OK; smsg->type = RSP_FLASH_ERASE; smsg->len = MSG_SIZEOF(smsg->asFlashEraseRsp); break; case REQ_FLASH_PROGR: smsg->asProgramRsp = bAHI_FullFlashProgram(msg->asProgramReq.addr, msg->len-MSG_HDR_SIZE-sizeof(msg->asProgramReq.addr), msg->asProgramReq.data) ? OK : NOT_SUPPORTED; smsg->type = RSP_FLASH_PROGR; smsg->len = MSG_SIZEOF(smsg->asProgramRsp); break; case REQ_FLASH_READ: smsg->type = RSP_FLASH_READ; smsg->len = MIN(MSG_SIZEOF(smsg->asReadRsp), MSG_HDR_SIZE+(sizeof(smsg->asReadRsp)-sizeof(smsg->asReadRsp.data)) +msg->asReadReq.len); smsg->asReadRsp.status = bAHI_FullFlashRead(msg->asReadReq.addr, MIN(sizeof(smsg->asReadRsp.data), msg->asReadReq.len), smsg->asReadRsp.data) ? OK : NOT_SUPPORTED; break; case REQ_SECTOR_ERASE: smsg->asSelectRsp = OK; smsg->asSectorRsp = bAHI_FlashEraseSector(msg->asSectorReq) ? OK : NOT_SUPPORTED; smsg->type = RSP_SECTOR_ERASE; smsg->len = MSG_SIZEOF(smsg->asSectorRsp); break; case REQ_SR_WRITE: smsg->asSRRsp = NOT_SUPPORTED; smsg->type = RSP_SR_WRITE; smsg->len = MSG_SIZEOF(smsg->asSRRsp); break; case REQ_RAM_WRITE: memcpy((uint32_t*) smsg->asRamWriteReq.addr, smsg->asRamWriteReq.data, smsg->len-MSG_HDR_SIZE); smsg->asRamWriteRsp = OK; smsg->type = RSP_RAM_WRITE; smsg->len = MSG_SIZEOF(smsg->asRamWriteRsp); break; case REQ_RAM_READ: smsg->type = RSP_RAM_READ; smsg->len = MIN(MSG_SIZEOF(smsg->asRamReadRsp), MSG_HDR_SIZE+ (sizeof(smsg->asRamReadRsp)-sizeof(smsg->asRamReadRsp.data))+msg->asRamReadReq.len); memcpy(smsg->asRamReadRsp.data, (uint32_t*) msg->asRamReadReq.addr, MIN(sizeof(smsg->asRamReadRsp.data), msg->asRamReadReq.len)); break; case REQ_RUN: s.reset_req = true; smsg->asRunRsp = OK; smsg->type = RSP_RUN; smsg->len = MSG_SIZEOF(msg->asRunReq); break; case REQ_FLASH_ID: smsg->asFlashIdRsp.status = OK; smsg->asFlashIdRsp.manufacturer = smsg->asFlashIdRsp.device = 0x10; smsg->type = RSP_FLASH_ID; smsg->len = MSG_SIZEOF(smsg->asFlashIdRsp); break; case REQ_FLASH_SELECT: smsg->asSelectRsp = bAHI_FlashInit(msg->asSelectReq.flashtype, (tSPIflashFncTable*) msg->asSelectReq.addr) ? OK : NOT_SUPPORTED; smsg->type = RSP_FLASH_SELECT; smsg->len = MSG_SIZEOF(smsg->asSelectRsp); break; case REQ_FLASH_PROG2: GDB2_PUTS("bootloader: flashing started\n"); s.state = FLASHING; s.write_addr = 0x00000000; s.write_len = msg->asFlashWrite2.len; break; default: smsg->asSRRsp = NOT_SUPPORTED; smsg->type = RSP_SR_WRITE; smsg->len = MSG_SIZEOF(smsg->asSRRsp); } } } } if(uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll()) { if(s.state==SENDING) uip_send(smsg, smsg->len); } /* this is odd but needed to get tcp throughput rate in sync with flash * write rate, otherwise rtt is calculated as the rtt of small packets which * is too fast when writing to the flash has started, therefore limiting * the overall throughput of the bootloader protocol. */ time = clock_time() - time; if (time < CLOCK_SECOND/12) clock_delay(CLOCK_SECOND/12 - time); }