/**************************************************************************** * Function: _EthAckPacket * * PreCondition: None * * Input: pPkt - buffer/packet to be acknowledged or NULL * pRemList - list to look for done packets and to remove the packets from * pAddList - list were to add the removed packets * ackFnc - function to be called for each acknowledged buffer in turn * fParam - function argument * * Output: ETH_RES_OK - success * ETH_RES_PACKET_QUEUED - there are packets queued * ETH_RES_NO_PACKET - no packets available in the queue * * Side Effects: None * * Overview: This function acknowledges a packet. * The supplied packet has to have been completed otherwise the call will fail. * When pPkt==NULL, all packets with EOWN==0 will be acknowledged. * * Note: None *****************************************************************************/ eEthRes _EthAckPacket(const void* pPkt, sEthDcptList* pRemList, sEthDcptList* pAddList, pEthBuffAck ackFnc, void* fParam) { sEthDNode *pEDcpt; sEthDNode *prev, *next; int nAcks; int pktFound; int buffIx; prev=next=0; nAcks=pktFound=0; for(pEDcpt=pRemList->head; pEDcpt!=0; pEDcpt=next) { if(pEDcpt->hwDcpt.hdr.SOP && (pPkt==0 || pEDcpt->hwDcpt.pEDBuff==(unsigned char*)KVA_TO_PA(pPkt))) { // found the beg of a packet pktFound=1; if(pEDcpt->hwDcpt.hdr.EOWN) { break; // hw not done with it } next=pEDcpt; buffIx=0; do { pEDcpt=next; next=pEDcpt->next; while(pEDcpt->hwDcpt.hdr.EOWN); // shouldn't happen SlAddTail(pAddList, pEDcpt); // ack this node if(ackFnc) { void* pBuff; pBuff=(pEDcpt->hwDcpt.hdr.kv0?PA_TO_KVA0((int)pEDcpt->hwDcpt.pEDBuff):PA_TO_KVA1((int)pEDcpt->hwDcpt.pEDBuff)); (*ackFnc)(pBuff, buffIx++, fParam); // call user's acknowledge } }while(!pEDcpt->hwDcpt.hdr.EOP); nAcks++; // reconstruct the removed list if(prev) { prev->next=next; // prev->next_ed shouldn't matter here! } else { pRemList->head=next; } if(pPkt) { // done, just one packet ack-ed break; // done } } else { prev=pEDcpt; next=pEDcpt->next; } } return nAcks?ETH_RES_OK:(pktFound?ETH_RES_PACKET_QUEUED:ETH_RES_NO_PACKET); }
/******************************************************************** * Function: WriteHexRecord2Flash() * * Precondition: * * Input: None. * * Output: * * Side Effects: No return from here. * * Overview: Writes Hex Records to Flash. * * * Note: None. ********************************************************************/ void WriteHexRecord2Flash(UINT8* HexRecord) { static T_HEX_RECORD HexRecordSt; UINT8 Checksum = 0; UINT8 i; UINT WrData; UINT RdData; void* ProgAddress; UINT result; HexRecordSt.RecDataLen = HexRecord[0]; HexRecordSt.RecType = HexRecord[3]; HexRecordSt.Data = &HexRecord[4]; // Hex Record checksum check. for(i = 0; i < HexRecordSt.RecDataLen + 5; i++) { Checksum += HexRecord[i]; } if(Checksum != 0) { //Error. Hex record Checksum mismatch. //Indicate Error by switching ON all LEDs. //Error(); // Do not proceed further. ErrorFunction(); } else { // Hex record checksum OK. switch(HexRecordSt.RecType) { case DATA_RECORD: //Record Type 00, data record. HexRecordSt.Address.byte.MB = 0; HexRecordSt.Address.byte.UB = 0; HexRecordSt.Address.byte.HB = HexRecord[1]; HexRecordSt.Address.byte.LB = HexRecord[2]; // Derive the address. HexRecordSt.Address.Val = HexRecordSt.Address.Val + HexRecordSt.ExtLinAddress.Val + HexRecordSt.ExtSegAddress.Val; while(HexRecordSt.RecDataLen) // Loop till all bytes are done. { // Convert the Physical address to Virtual address. ProgAddress = (void *)PA_TO_KVA0(HexRecordSt.Address.Val); // Make sure we are not writing boot area and device configuration bits. if(((ProgAddress >= (void *)APP_FLASH_BASE_ADDRESS) && (ProgAddress <= (void *)APP_FLASH_END_ADDRESS)) && ((ProgAddress < (void*)DEV_CONFIG_REG_BASE_ADDRESS) || (ProgAddress > (void*)DEV_CONFIG_REG_END_ADDRESS))) { if(HexRecordSt.RecDataLen < 4) { // Sometimes record data length will not be in multiples of 4. Appending 0xFF will make sure that.. // we don't write junk data in such cases. WrData = 0xFFFFFFFF; memcpy(&WrData, HexRecordSt.Data, HexRecordSt.RecDataLen); } else { memcpy(&WrData, HexRecordSt.Data, 4); } // Write the data into flash. result = NVMemWriteWord(ProgAddress, WrData); // Assert on error. This must be caught during debug phase. if(result != 0) { while(1); } } // Increment the address. HexRecordSt.Address.Val += 4; // Increment the data pointer. HexRecordSt.Data += 4; // Decrement data len. if(HexRecordSt.RecDataLen > 3) { HexRecordSt.RecDataLen -= 4; } else { HexRecordSt.RecDataLen = 0; } } break; case EXT_SEG_ADRS_RECORD: // Record Type 02, defines 4th to 19th bits of the data address. HexRecordSt.ExtSegAddress.byte.MB = 0; HexRecordSt.ExtSegAddress.byte.UB = HexRecordSt.Data[0]; HexRecordSt.ExtSegAddress.byte.HB = HexRecordSt.Data[1]; HexRecordSt.ExtSegAddress.byte.LB = 0; // Reset linear address. HexRecordSt.ExtLinAddress.Val = 0; break; case EXT_LIN_ADRS_RECORD: // Record Type 04, defines 16th to 31st bits of the data address. HexRecordSt.ExtLinAddress.byte.MB = HexRecordSt.Data[0]; HexRecordSt.ExtLinAddress.byte.UB = HexRecordSt.Data[1]; HexRecordSt.ExtLinAddress.byte.HB = 0; HexRecordSt.ExtLinAddress.byte.LB = 0; // Reset segment address. HexRecordSt.ExtSegAddress.Val = 0; break; case END_OF_FILE_RECORD: //Record Type 01, defines the end of file record. HexRecordSt.ExtSegAddress.Val = 0; HexRecordSt.ExtLinAddress.Val = 0; // Disable any interrupts here before jumping to the application. JumpToApp(); break; default: HexRecordSt.ExtSegAddress.Val = 0; HexRecordSt.ExtLinAddress.Val = 0; break; } } }
/**************************************************************************** * Verifies flash * * \param StartAddress: Pointer to program start address * \param ProgLen: Pointer to Program length in bytes * \param crc : Pointer to CRC * \return *****************************************************************************/ void CHexManager::VerifyFlash(unsigned int* StartAdress, unsigned int* ProgLen, unsigned short* crc) { unsigned short HexRecLen; char HexRec[255]; T_HEX_RECORD HexRecordSt; unsigned int VirtualFlashAdrs; unsigned int ProgAddress; // Virtual Flash Erase (Set all bytes to 0xFF) memset((void*)VirtualFlash, 0xFF, sizeof(VirtualFlash)); // Start decoding the hex file and write into virtual flash // Reset file pointer. fseek(HexFilePtr, 0, 0); // Reset max address and min address. HexRecordSt.MaxAddress = 0; HexRecordSt.MinAddress = 0xFFFFFFFF; while((HexRecLen = GetNextHexRecord(&HexRec[0], 255)) != 0) { HexRecordSt.RecDataLen = HexRec[0]; HexRecordSt.RecType = HexRec[3]; HexRecordSt.Data = (unsigned char*)&HexRec[4]; switch(HexRecordSt.RecType) { case DATA_RECORD: //Record Type 00, data record. HexRecordSt.Address = (((HexRec[1] << 8) & 0x0000FF00) | (HexRec[2] & 0x000000FF)) & (0x0000FFFF); HexRecordSt.Address = HexRecordSt.Address + HexRecordSt.ExtLinAddress + HexRecordSt.ExtSegAddress; ProgAddress = PA_TO_KVA0(HexRecordSt.Address); if(ProgAddress < BOOT_SECTOR_BEGIN) // Make sure we are not writing boot sector. { if(HexRecordSt.MaxAddress < (ProgAddress + HexRecordSt.RecDataLen)) { HexRecordSt.MaxAddress = ProgAddress + HexRecordSt.RecDataLen; } if(HexRecordSt.MinAddress > ProgAddress) { HexRecordSt.MinAddress = ProgAddress; } VirtualFlashAdrs = PA_TO_VFA(ProgAddress); // Program address to local virtual flash address memcpy((void *)&VirtualFlash[VirtualFlashAdrs], HexRecordSt.Data, HexRecordSt.RecDataLen); } break; case EXT_SEG_ADRS_RECORD: // Record Type 02, defines 4 to 19 of the data address. HexRecordSt.ExtSegAddress = ((HexRecordSt.Data[0] << 16) & 0x00FF0000) | ((HexRecordSt.Data[1] << 8) & 0x0000FF00); HexRecordSt.ExtLinAddress = 0; break; case EXT_LIN_ADRS_RECORD: HexRecordSt.ExtLinAddress = ((HexRecordSt.Data[0] << 24) & 0xFF000000) | ((HexRecordSt.Data[1] << 16) & 0x00FF0000); HexRecordSt.ExtSegAddress = 0; break; case END_OF_FILE_RECORD: //Record Type 01 default: HexRecordSt.ExtSegAddress = 0; HexRecordSt.ExtLinAddress = 0; break; } } HexRecordSt.MinAddress -= HexRecordSt.MinAddress % 4; HexRecordSt.MaxAddress += HexRecordSt.MaxAddress % 4; *ProgLen = HexRecordSt.MaxAddress - HexRecordSt.MinAddress; *StartAdress = HexRecordSt.MinAddress; VirtualFlashAdrs = PA_TO_VFA(HexRecordSt.MinAddress); *crc = CalculateCrc((char*)&VirtualFlash[VirtualFlashAdrs], *ProgLen); }