📄 xnpm.nc
字号:
*************************************************************************/ void fNPXStartDownload(TOS_MsgPtr msgptr) { uint16_t *wptr; //TOS_MsgPtr *wptr; // CSS: ^-- Whoever changed wptr from uint16_t* to TOS_MsgPtr* is dumb and // should learn not to poke at and commit code when they don't understand // and obviously must know they don't understand pointers. Both // wProgramID and wNofCapsules were garbage. To that person: each time // you do that again, I kill you. wptr = (uint16_t*)(&(msgptr->data[TS_PID])); wProgramID = *wptr++; wNofCapsules= *wptr; //Initialize EEPROM writing wEE_LineW = EE_LINE_START; //reset eprom write count EE_PageW = EE_PAGE_START; //reset eprom page wCIDMissingPrevious = 1; wCIDMissing = 1; bCIDMissing = FALSE; bCommandOK = CMD_STATE_BUSY; //assume we are busy //Ask client to stop/suspend main application etc // -16 capsules per EEPage signal Xnp.NPX_DOWNLOAD_REQ(wProgramID,EE_PageW, wNofCapsules<<4); //now wait for client to respond. If doesnt should have a timeout and goto idle? return; }//fNPXStartDownload /****************************************************************************** NPX_DOWNLOAD_ACK: Acknowledge from Client to proceed/cancel Netprogramming pending download request ******************************************************************************/ command result_t Xnp.NPX_DOWNLOAD_ACK(uint8_t cAck ) { //uint8_t bRet; if( (sSYSState != SYS_DL_START ) ){ //bogus call from app! sSYSState = SYS_IDLE; bCommandOK = CMD_STATE_WRONGSTATE; return(FALSE); } if( !cAck ) { //Client is not allowing download bCommandOK = CMD_STATE_BUSY; sSYSState = SYS_ACK; }else { //Check status of Battery and return OK/Bad status //Reset/init all states and start bCommandOK = CMD_STATE_BUSY; //still processing the start request sSYSState = SYS_DL_START1; }//ack is OK post NPX_STATEMACHINE();//get going return(FALSE); } /****************************************************************************** fNPXS0RecBuild: Write an S0 record and go... ******************************************************************************/ void fNPXS0RecBuild(){ wEEProgStart = EE_PageW<<4;//the starting point in EEFlash wCapsuleNo = 0; //update current capsule# -Network capsule# starts at 1 wPIDinFLASH = wProgramID; //Write a pseudo S0 record w/ ProgramID into Flash ELBuff[POS_PID] = (uint8_t) wProgramID; //lsbyte of ProgID ELBuff[POS_PID+1] = (uint8_t)(wProgramID>>8); //ms of address ELBuff[POS_CID] = 0; //capsule number is 0 ELBuff[POS_CID+1] = 0; ELBuff[POS_STYPE] = SREC_S0; //srec9 only has 2byte address ELBuff[POS_SNOFB] = 3; //progid plus crc ELBuff[POS_S0_PID] = (uint8_t)wProgramID; //lsbyte of ProgID ELBuff[POS_S0_PID+1] = (uint8_t)(wProgramID>>8); //ms of address ELBuff[POS_S0_CRC] = 0xAA; //progid plus crc wEE_LineW = wEEProgStart; //2 lines per srec -1st line is S0 bEELineWritePending = TRUE; //main state machine handles posting task and busy retries sSYSState = SYS_EEFLASH_WRITE; post NPX_STATEMACHINE();//store srec to eeprom bCommandOK = CMD_STATE_DONE; return; }//fnpx_downloadgo //======================= LOCAL FUNCTIONS ================================== /******************************************************************************************** fNPXGetProgramID Compare current applications ProgramID with caller If request TS_MSGDATA parameter is TRUE , acknowledge if PIDs match If request TS_MSGDATA parameter is FALSE , acknowledge if PIDs do NOT match *******************************************************************************************/ void fNPXGetProgramID(TOS_MsgPtr msgptr){ //Get programID from ATMEL EEPROM and compare with Network Requested PROGID uint8_t bPIDMatch; uint8_t bIFMatch; uint16_t wlPID; uint16_t *wptr; uint16_t wTemp; bIFMatch = msgptr->data[TS_MSGDATA]; wptr = (uint16_t*)(&(msgptr->data[TS_PID])); wTemp = *wptr; wlPID = eeprom_read_word ((uint16_t *)AVREEPROM_PID_ADDR); bPIDMatch = (wTemp== wlPID); bCommandOK = CMD_STATE_DONE; if( bBCASTMsg ) {//only respond according to flag if( (bIFMatch && bPIDMatch) | (!bIFMatch && !bPIDMatch)) //re match fNPXSendPIDStatus(wlPID); }//broadcast else fNPXSendPIDStatus(wlPID); } /************************************************************************* fNPXSRECStore Got a code capsule containing 1 srec from radio [0]:commandid [1.2]:program id [3:4]:nofcapsules (srecords) space that is used only during boot-download. *************************************************************************/ void fNPXSRECStore(TOS_MsgPtr msgptr) { //uint8_t bRet; //uint8_t j; unsigned short wTemp; //uint8_t cLen; uint8_t cSRecType; uint8_t bSRecValid; //uint8_t bFini = FALSE; uint16_t *wptr; if( sSYSMState != SYSM_DOWNLOAD ) { bCommandOK = CMD_STATE_WRONGSTATE; // sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; //back to statemachine } wptr = (uint16_t *)&(msgptr->data[TS_PID]); wTemp = *wptr; if( wTemp != wProgramID ) { //not the same ProgramID so ignore bCommandOK = CMD_STATE_BADSEQUENCE; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; //back to statemachine } //Get and check capsule # wptr = (uint16_t *)&(msgptr->data[TS_CAPSULEID]); wTemp = *wptr; if( wTemp != wCapsuleNo+1 ) { //missed a capsule? if(!bCIDMissing ) {//first one missed? bCIDMissing = TRUE; wCIDMissing = wCapsuleNo+1; wCIDMissingPrevious = wCIDMissing; } wNofLostCapsules = wTemp-wCapsuleNo-1; }//here if wrong capsule # but we continue on... wCapsuleNo = wTemp; //update current capsule# cSRecType = msgptr->data[TS_TYPE]; bSRecValid = fNPXSRECParse( msgptr ); //parse the srec if(!bSRecValid) { bCommandOK = CMD_STATE_BADSTYPE; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; //back to statemachine }//!srecvalid //if srec parsed then save to external flash -Capsule starts at 1 wEE_LineW = wEEProgStart + (wCapsuleNo<<1); //2 lines per srec bCommandOK = CMD_STATE_DONE; bEELineWritePending = TRUE; //main state machine handles posting task and busy retries sSYSState = SYS_EEFLASH_WRITE; post NPX_STATEMACHINE();//store srec to eepromn return; } //fnpx_srecstore /************************************************************************* fNPXSRECUpdate Got an update code capsule containing 1 srec from radio Replaces a missing or bad srec in EEFLASH Verifies correct PID Verifies a valid srec Enables EEFLASH Write write Release EEFLASH Copies into a local buffer for passing to EEFLASH driver. The source buffer (TOSMsg) is not available after function returns because TOS reuses it. NOTES *************************************************************************/ void fNPXSRECUpdate(TOS_MsgPtr msgptr) { uint8_t bRet; //uint8_t j; unsigned short wTemp; //uint8_t cLen; uint8_t cSRecType; uint8_t bSRecValid; //uint8_t bFini = FALSE; uint16_t *wptr; if( sSYSMState != SYSM_UPDATE ) { bCommandOK = CMD_STATE_WRONGSTATE; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; } wptr = (uint16_t *)&(msgptr->data[TS_PID]); wTemp = *wptr; if( wTemp != wProgramID ) { //not the same ProgramID downloading bCommandOK = CMD_STATE_BADSEQUENCE; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; } //Get and check capsule # wptr = (uint16_t *)&(msgptr->data[TS_CAPSULEID]); wCapsuleNo = *wptr; //update current capsule# cSRecType = msgptr->data[TS_TYPE]; bSRecValid = fNPXSRECParse( msgptr ); //parse the srec if(!bSRecValid) { bCommandOK = CMD_STATE_BADSTYPE; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; }//!srecvalid //if srec parsed then save to external flash -Capsule starts at 1 wEE_LineW = wEEProgStart + (wCapsuleNo<<1); //2 lines per srec bCommandOK = CMD_STATE_DONE; bEELineWritePending = TRUE; //main state machine handles posting task and busy retries if( !bEEWriteEnabled ) { //here if doing random SREC writes so must Writeenable the EEFLASH bRet = call EEPROMWrite.startWrite(); if( !bRet ) { //eeprom not available bCommandOK = CMD_STATE_BUSY; sSYSState = SYS_ACK; post NPX_STATEMACHINE();//exec new state return; } }//!beeLocked bEEWriteEnabled = 1; // eeprom writing enabled flag bEEWriteContinuous = FALSE; //MUST release EEFLASH WriteEnable to do future reads on EEFLASH sSYSState = SYS_EEFLASH_WRITE; post NPX_STATEMACHINE();//store srec to eepromn return; } //fnpx_srecupdate /************************************************************************* fNPXSRecDownloadDone End of broadcast srec download. Network will interrogate motes for missing packets cleanup regardless of state - this function can also be used to abort *************************************************************************/ uint8_t fNPXSRecDownloadDone() { sSYSState = SYS_DL_END;//we are finished....flush eeprom buffer sSYSMState = SYSM_IDLE; post NPX_STATEMACHINE();//fetch srec from eeprom flash return(1); }//fNPXSrecDownloadDone /************************************************************************* fNPXGetEEProgID Read the ProgramID currently in the External EEFLASH *************************************************************************/ void fNPXGetEEProgID(uint16_t wEEStart) { wEE_LineR = wEEStart; sSYSState = SYS_ISP_REQ; bEELineReadPending = TRUE; //main state machine handles posting task and busy retries post NPX_STATEMACHINE();//fetch srec from eeprom flash return; } /************************************************************************* fNPXGetNextEmptySREC Starte/Resume Scan thru EEPROM from specified point and starts search for next missing srec. NOTES 1.Need terminator (S9 record) indicating end of program 2. Actual work is done in READ_DONE 3. Must have released FLASH from writing *************************************************************************/ uint8_t fNPXGetNextEmptySREC(uint16_t wCurrentCID) { // VAR(wEEProgStart2) = wEEProgStart+2; call Leds.greenOff(); //diagnostic wCapsuleNo = wCurrentCID; //where we are... wEE_LineR = wEEProgStart+ (wCurrentCID<<1); //2 lines per srec -1st line is S0 sSYSState = SYS_GETNEXTCID; bEELineReadPending = TRUE; //main state machine handles posting task and busy retries post NPX_STATEMACHINE();//fetch srec from eeprom flash return(TRUE); } /************************************************************************* EEPROM_READ_DONE EEPROM read record completed. Handle per current state *************************************************************************/ event result_t EEPROMRead.readDone(uint8_t *pEEB, result_t result){ uint16_t* pW; uint16_t wCID,wPID; bEELineReadPending = FALSE; //main state machine handles posting task and busy retries call Leds.redOff(); //diagnostic=LED on during read now off switch (sSYSState) {#ifdef new1 case SYS_GET_EEPID: //read EEFLASH program ID and store pW = &pEEB[POS_PID]; wPIDinFLASH = pW; break;#endif case SYS_ISP_REQ1: //check the EEFLASH programid matches the ISP requested PID pW = (uint16_t*)(&pEEB[POS_PID]); if( *pW == wProgramID ) { //this matches so invoke ISP bCommandOK = CMD_STATE_DONE; post NPX_ISP(); }else { //programids do not match - donot invoke ISP bCommandOK = CMD_STATE_BADSEQUENCE; } sSYSMState = SYSM_IDLE; //reset state because SYS_ACK does not sSYSState = SYS_ACK; //we are finished-turnoff led post NPX_STATEMACHINE();//fetch srec from eeprom flash break; case SYS_GETNEXTCID: //searching for bad/missing srecs //check correct ProgramID and expected Capsule ID pW = (uint16_t*)(&pEEB[POS_CID]); wCID = *pW; //type cast pW = (uint16_t*)(&pEEB[POS_PID]); wPID = *pW; if( (wPID != wProgramID ) | (wCID != wCapsuleNo) ) { //something is wrong fProcessMissingCapsule(wPID, wCapsuleNo); } else //ProgramID and CapsuleID are correct {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -