📄 xnpm.nc
字号:
uint16_t wCapsuleNo; //code capsule number uint16_t wNofCapsules; //expected number of capsules uint16_t wNofLostCapsules; // uint8_t bCIDMissing; uint16_t wCIDMissing; uint16_t wCIDMissingPrevious; uint16_t wEEProgStart; //start location in EEFlash uint8_t btest; //true if test pattern is to be used uint16_t itest; //test pattern incrementer uint8_t bEEWriteEnabled; //EEFLASH is WRITE Enabled uint8_t bEEWriteContinuous; uint16_t EE_PageW; //current EEPROM page written uint16_t wEE_LineW; //current/final eprom line written uint16_t wEE_LineR; // uint16_t EE_LineEndR; //last EEROMline to read uint8_t cLineinPage; //line# within Page being read uint8_t bEELine1; //1st line of 2 being written uint8_t bEELineWritePending; uint8_t bEELineReadPending; uint8_t bEEPROMBusy; //0 if EPROM available for write uint16_t read_line; //line in eeprom read from uint16_t wLastEEPage; //nof lines to log(page is 256bytes=16lines=32samples) EEBUF_line_struct EELineBuf; //for readout uint8_t ELBuff[ELBUFF_SIZE]; uint8_t bELBuffAWE; //BufferA or B selected for write enable uint8_t bELBuffFull; bool DoneEveryCapsules; //------------------------ LOCAL FUNCTIONS ----------------------------------- void fNPXSysVarInit(); //init vars to default void fNPXStartDownload(TOS_MsgPtr msgptr); void fNPXS0RecBuild(); void fNPXSRECDownload(TOS_MsgPtr msgptr); //void fNPXBCastStartDownload(TOS_MsgPtr msgptr); uint8_t fNPXSRECParse(TOS_MsgPtr msgptr); void fNPXSRECStore(TOS_MsgPtr msgptr); uint8_t fNPXSRecDownloadDone(); void fNPXSRECUpdate(TOS_MsgPtr msgptr); uint8_t fNPXGetNextEmptySREC(uint16_t wCurrentCID); void fProcessMissingCapsule(uint16_t wlPID, uint16_t wlCIDMissing); void fReqMissingCapsule(uint16_t wlPID, uint16_t wlCIDMissing); void fDownloadComplete(uint16_t wlPID); void fNPXSendStatus(); //Sendstatus function void fNPXInSystemProgramExec(TOS_MsgPtr msgptr); void fNPXGetEEProgID(uint16_t wEEStart); void fNPXGetProgramID(TOS_MsgPtr msgptr); void fNPXSendPIDStatus(uint16_t wPID); /**************************************************************************** * Initialize the component. Initialize * ****************************************************************************/ command result_t StdControl.init() { fNPXSysVarInit(); //set vars to init call GenericCommCtl.init(); call EEPROMControl.init(); call Leds.init(); return SUCCESS; } /**************************************************************************** * Start the component.. * ****************************************************************************/ command result_t StdControl.start(){ call GenericCommCtl.start(); return SUCCESS; } /**************************************************************************** * Stop the component. Stop the clock * ****************************************************************************/ command result_t StdControl.stop() { return SUCCESS; } /**************************************************************************** * NPX__ISP: * task to writes GROUP_ID and TOS_ID into eeprom, then invoke bootloader ****************************************************************************/ task void NPX_ISP() { //setup parameters to pass //R20,R21 wProgId, R22:PageStart, R24,25:nwProgID uint16_t wPID; //uint8_t cTemp; uint8_t *pAddr; cli(); //turnoff interrupts // Store GROUPID and LOCAL ADDRESS into EEPROM // note:this function blocks &waits until EEPROM is available eeprom_write_byte ((uint8_t*)(AVREEPROM_GROUPID_ADDR), TOS_AM_GROUP); eeprom_write_byte ((uint8_t*)(AVREEPROM_LOCALID_ADDR), TOS_LOCAL_ADDRESS);//lsbyte eeprom_write_byte ((uint8_t *)AVREEPROM_LOCALID_ADDR+1, (TOS_LOCAL_ADDRESS>>8));//msbyte //The following should really only be done when ISP has loaded the program... pAddr = (uint8_t*)(&wProgramID); //the prog id eeprom_write_byte ((uint8_t*)(AVREEPROM_PID_ADDR), *pAddr++);//lsbyte eeprom_write_byte ((uint8_t*)(AVREEPROM_PID_ADDR+1), *pAddr);//msbyte while (!eeprom_is_ready()); //wait for eeprom to finish wPID = ~wProgramID; //inverted prog id __asm__ __volatile__ ("movw r20, %0" "\n\t"::"r" (wPID):"r20", "r21"); wPID = wEEProgStart; __asm__ __volatile__ ("movw r22, %0" "\n\t"::"r" (wPID):"r22", "r23"); wPID = wProgramID; //the prog id __asm__ __volatile__ ("movw r24, %0" "\n\t"::"r" (wPID):"r24", "r25"); //call bootloader - it may never return... __asm__ __volatile__ ("call 0x1F800" "\n\t"::); //bootloader at 0xFC00 // __asm__ __volatile__ ("clr r1" "\n\t"::); //if here reboot/reprog failed bCommandOK= CMD_STATE_BADCHECKSUM; //default we don't recognize it if(bAckMessage) fNPXSendStatus(); return; } /***************************************************************************** TOS TASK Write specified buffer out to EEPROM On completion, the CORRECT buffer FULL status will be cleared... Need a PENDING flag to keep trying until EEPROM ready or timeout bELBuffAWE [0,1] points to 1 of 2 256 byte buffers in EEPROM wEE_LineW Absolute line# as starting address for written data. Actually modulo 16 because only 16 lines (16bytes/line * 16lines = 1page) are used. But wEE_LineW as an absolute line# is used elsewhere in the TestBench ELBUFF_NOFLINES Number of Lines (16bytes) to write. ELBuff Data buffer. Must be 16*ELBUFF_NOFLINES bytes deep When reach end of a Page Buffer (256bytes) we switch buffers for writing And then EEWRITE_LINEDONE handler will flush out the previous buffer to EEPROM's internal ROM Notes" 1. hINSTANCE is a constant - should be variable set by StartEEPROM !!!!This is handled differently (correctly) in NESC !!!! *****************************************************************************/#define EEBufA 0 //Buffer IDs#define EEBufB 1 //Buffer IDs task void NPX_wEE_LineWrite() { uint8_t iRet; if( bEEWriteEnabled ) { if( !bEEPROMBusy){ //write the first of a 2line sequence bEELine1 = TRUE; // 1st line iRet = call EEPROMWrite.write(wEE_LineW, (uint8_t*)&ELBuff ); // ADD RETRY TIMEOUT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if(!iRet) //failed post NPX_wEE_LineWrite(); //keep trying bEEPROMBusy= TRUE; //Handle variable number of line per buffer wEE_LineW++; //track absolute line number cLineinPage++; //next line within page if( cLineinPage >= NOFLINESPERPAGE ) { //at page boundary bELBuffAWE = !bELBuffAWE; //toggle line buffer for writing lines bELBuffFull = TRUE; //tells LineDone handler to flush internal buffer cLineinPage = 0; //reset line counter } } else //try again post NPX_wEE_LineWrite(); } }//tos-task /***************************************************************************** NPX_STATEMACHINE Handles various states during SREC Download. -On each SREC capsule received () writes srec line if EEPROM not busy, otherwise loops until ready. -SYS_DL_FAIL Cleansup / releases EEPROM resource Send message to Host Goes into IDLE ******************************************************************************/ task void NPX_STATEMACHINE() { uint8_t cNextState; uint8_t bRePost; uint8_t bRet; uint16_t *wptr; cNextState = sSYSState; //default is no change bRePost = FALSE; //by default we do not repeat this statemachine task switch( sSYSState ) { case SYS_REQ_CIDMISSING: //get control back //if the requested PID does not match our current PID we ignore the request wptr = (uint16_t *)&(pNETTOSMsg->data[TS_PID]); if( *wptr != wProgramID ) { bCommandOK = CMD_STATE_BADSEQUENCE; cNextState = SYS_ACK; bRePost = TRUE; }else { cNextState = SYS_GET_CIDMISSING; //Release EEFLASH bRet = call EEPROMWrite.endWrite(); //EEWriteEndDone will invoke NPX statemachine if(bRet==FAIL) bRePost = TRUE; //endWrite will not signal enddone go directly to next state } break; case SYS_GET_CIDMISSING: sSYSMState = SYSM_UPDATE; fNPXGetNextEmptySREC(wCIDMissingPrevious);//this starts reading sequentially thru EEFLASH cNextState = sSYSState; break; case SYS_DL_START: cNextState = SYS_DL_START0; //this is a pseudo state waiting for APP to ack start dl request fNPXStartDownload(pNETTOSMsg); //prep & call app with DL request.Determines next state cNextState = sSYSState; //SYS state maybe changed by functioncall break; case SYS_DL_START1: //get system into clean known state cNextState = SYS_DL_START2; //Release EEFLASH unconditionally to get into clean state bRet = call EEPROMWrite.endWrite(); //EEWriteEndDone will invoke NPX statemachine if(bRet==FAIL) bRePost = TRUE; //no endWrite to signal enddone so go directly to START1 break; case SYS_DL_START2: // //Clear flags bEEWriteContinuous = FALSE; bEEWriteEnabled = FALSE; // eeprom writing enabled flag bEEPROMBusy = FALSE; //reset any pending eprom writes //lock down EEPROM resource bRet = call EEPROMWrite.startWrite(); //a function call - no event signal if( !bRet ) { //eeprom not available bCommandOK = CMD_STATE_BUSY; sSYSState = SYS_DL_FAIL; } else { bEEWriteContinuous = TRUE; //donot release EEFLASH after each srec write bEEWriteEnabled = TRUE; // eeprom writing enabled flag bEEPROMBusy = FALSE; //reset any pending eprom writes wEEProgStart = EE_PageW<<4;//the starting point in EEFlash wCapsuleNo = 0; //update current capsule# -Network capsule# starts at 1 //fNPXS0RecBuild(); //fNPXS0RecBuild sets up for EEFLASH write of S0 bCommandOK = CMD_STATE_DONE; sSYSMState = SYSM_DOWNLOAD; //Entered DOWNLOAD Major State cNextState = SYS_ACK; //we are ready to accept SREC Downloads } bRePost = TRUE; //goto next state break; case SYS_DL_SRECWRITE: //write SREC in DOWNLOAD Mode fNPXSRECStore(pNETTOSMsg); //storesrec cNextState = sSYSState; //whatever fNPXSRECStore did to sSYSState break; case SYS_UP_SRECWRITE: //write SREC in UPDATE Mode fNPXSRECUpdate(pNETTOSMsg); cNextState = sSYSState; //whatever fNPXSRECUpdate did to sSYSState break; case SYS_EEFLASH_WRITE:#ifdef PLATFORM_MICA2DOT call Leds.redOn();#endif call Leds.yellowOn(); if( bEELineWritePending ){ //waiting to post a task to EEWrite if( !bEEPROMBusy ){ post NPX_wEE_LineWrite();//write buffer out to EEPROM bEELineWritePending = FALSE; } else //EEPROM is busy bRePost = TRUE; //re-execute NPX_STATEMACHINE only if busy }//writepending else { //not pending cNextState = SYS_EEFLASH_WRITEDONE; //nothing to so so endit bRePost = TRUE; } break; case SYS_EEFLASH_WRITEDONE: cNextState = SYS_ACK; //where we go next if( !bEEWriteContinuous ) { //release the resource after each write if( bEEWriteEnabled ) call EEPROMWrite.endWrite(); //EEWriteEndDone will invoke next state else bRePost = TRUE; //chain to next state } else bRePost = TRUE; //chain to next state call Leds.yellowOff(); //diagnostic break; case SYS_DL_END: //release EEPROM resource cNextState = SYS_DL_END_SIGNAL; if( bEEWriteEnabled ) call EEPROMWrite.endWrite(); //EEWriteEndDone will invoke NPX statemachine else bRePost = TRUE; break; case SYS_DL_END_SIGNAL: //signal application that download process is finished -good bCommandOK = CMD_STATE_DONE; wCapsuleNo = 0; //reset current Capsule# signal Xnp.NPX_DOWNLOAD_DONE(wProgramID,TRUE, EE_PageW); cNextState = SYS_ACK; sSYSMState = SYSM_IDLE; bRePost = TRUE; //re-execute NPX_STATEMACHINE break; case SYS_DL_FAIL: //release EEPROM resource if required cNextState = SYS_DL_FAIL_SIGNAL; if( bEEWriteEnabled ) call EEPROMWrite.endWrite(); //EEWriteEndDone will invoke NPX statemachine else bRePost = TRUE; break; case SYS_DL_FAIL_SIGNAL: if(bAckMessage) fNPXSendStatus(); sSYSMState = SYSM_IDLE; wCapsuleNo = 0; //reset current Capsule# //Tell client download has finished - badly signal Xnp.NPX_DOWNLOAD_DONE(wProgramID,FALSE, EE_PageW); cNextState = SYS_ACK; // should wait for EEPROM flush buffer to fini? bRePost = TRUE; //re-execute NPX_STATEMACHINE break; case SYS_IDLE_RENTRY: //resume idle conditions cNextState = SYS_IDLE; bNXPMsgBusy = FALSE; //call Leds.greenOn(); break; case SYS_IDLE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -