void UpdateLEDs (void) /****************************************************************************/ { unsigned long tiStamp; tiStamp = hwclock (); # ifdef CONFIG_USE_TX_LED if (txLED < tiStamp) { LED_TX(LED_OFF); } # endif # ifdef CONFIG_USE_RX_LED if (rxLED < tiStamp) { LED_RX(LED_OFF); } # endif # ifdef CONFIG_USE_ERR_LED if (errLED < tiStamp) { LED_ERR(LED_OFF); } # endif # ifdef CONFIG_USE_CAL_LED if (calLED < tiStamp) { LED_CAL(LED_OFF); } # endif }
/** * NTRXTxEnd: * * NTRXTxEnd() finish transmission and reset internal state. * * Returns: none * */ void NTRXTxEnd (void) { MyByte8T maxArqCount; /* * get number of transmissions needed to last message */ NTRXGetRegister (NA_TxArqCnt, &ntrxArqCount); maxArqCount = NTRXGetTxARQmax(); if ((ntrxArqCount > maxArqCount) && (ntrxState == TxWAIT)) { rcwd++; txIrq &= ~(TxEND); ntrxState = TxIDLE; if (ntrxCal != 0) { # ifdef CONFIG_NTRX_AUTO_RECALIB tiRecal = hwclock() + calDelay; # endif NTRXAllCalibration (); rcwd = 0; # ifdef CONFIG_RECALIB_LED TRIGGER_LED3(); # endif /* CONFIG_RECALIB_LED */ } lState = RANGING_READY; # ifdef CONFIG_TRAFFIC_LED TRIGGER_LED2(); # endif /* CONFIG_TRAFFIC_LED */ }else{ txIrq &= ~(TxEND); ntrxState = TxIDLE; if (lState != RANGING_READY) { RangingCallback_Ack(ntrxArqCount); lState = RANGING_ANSWER1; } } }
usc_time_t usc_MD_clock() { #if defined(TC_2000) || defined(TC_2000_TCMP) #define TIMER_USED "tc2000 butterfly" struct { unsigned long hi; unsigned long low; } usclock; get64bitclock(&usclock); return((usc_time_t)usclock.low); #endif #if defined(IPSC860) #define TIMER_USED "ipsc" esize_t hwtime; unsigned long ustime; hwclock(&hwtime); hwtime.shigh = (hwtime.shigh & 0x7) << (sizeof(long)*8-3); hwtime.slow = ((hwtime.slow >> 3) & ~(0x7 << (sizeof(long)*8-3))) | hwtime.shigh; ustime = (unsigned long)hwtime.slow * 0.8; return( (usc_time_t) ustime); #endif #if defined(MEIKO_CS2) #define TIMER_USED "meiko cs2" /* making it look like a SUN temporarily (see *.h files also) - RMB */ /**** #include <sys/types.h> #include <elan/elanreg.h> #include <elan/elanctxt.h> struct elan_timeval t; unsigned int uS; elan_clock(elan_ctxt,&t); uS = t.tv_sec*1000000 + t.tv_nsec/1000; return uS; *****/ #endif #if defined(NCUBE) #define TIMER_USED "ncube" unsigned long ustime; double amicclk(); ustime = (unsigned long) amicclk(); /* printf("usc_MD_clock: returning %lu %u\n",ustime,ustime); */ return( (usc_time_t) ustime); #endif #if defined(FX2800) || defined(FX2800_SWITCH) #define TIMER_USED "Alliant fx2800" struct hrcval temptime; hrcstamp(&temptime); return ((usc_time_t) (temptime.hv_low * 10)); #endif #if defined(SUN) || defined(HP) || \ defined(SUN_SOLARIS) || defined(FREEBSD) || defined(LINUX) || \ defined(I86_SOLARIS) || defined(NETBSD) || \ defined(BALANCE) || \ defined(RS6000) || defined(IBM3090) || \ defined(NEXT) || defined(TITAN) || defined(TC1000) || \ defined(KSR) || \ defined(MEIKO_CS2) || \ defined(SGI) || defined(FX8) #define TIMER_USED "gettimeofday" unsigned long ustime; struct timeval tp; struct timezone tzp; #if defined(SUN_SOLARIS) && defined(USE_WIERDGETTIMEOFDAY) gettimeofday(&tp); #else gettimeofday(&tp,&tzp); #endif ustime = (unsigned long) tp.tv_sec; ustime = ustime % usc_MD_rollover_val; ustime = (ustime * 1000000) + (unsigned long) tp.tv_usec; return((usc_time_t) ustime); #endif #if defined(DEC5000) /* * hack by [email protected]: * * clock resolution is 3906 us * we can do about 120 calls in 3906 us == 32 us per call */ #define TIMER_USED "dec5000" unsigned long ustime; struct timeval tp; struct timezone tzp; static unsigned long last= 0; static unsigned long increment= 0; gettimeofday(&tp,&tzp); ustime = (unsigned long) tp.tv_sec; ustime = ustime % usc_MD_rollover_val; ustime = (ustime * 1000000) + (unsigned long) tp.tv_usec; if (last == ustime) { increment += 33L; } else { last = ustime; increment = 0; } return((usc_time_t) last + increment); #endif #ifndef TIMER_USED 'Error - no timer code used. Please file a bug report' #endif }
void PDCallback (void) /****************************************************************************/ { MyByte8T status; MyByte8T reg[2]; /* * use 1 led to indicate message reception on the devBoard * The led will stay on for a 50 ms. */ # ifdef CONFIG_TRAFFIC_LED TRIGGER_LED_RX (); # endif /* CONFIG_TRAFFIC_LED */ /* * read the crc2 status register */ NTRXSPIReadByte (NA_RxCrc2Stat_O, &status); rxIrq = 0; /* check if data is valid */ if ((status & (1 << NA_RxCrc2Stat_B)) != 0) { NTRXSetIndexReg (0); /* read source address */ NTRXSPIRead (NA_RamRxSrcAddr_O, upMsg.addr, 6); /* read length plus additionl bits */ NTRXSPIRead (NA_RamRxLength_O, reg, 2); rState = reg[1]>>5; /* read destination address */ # ifdef CONFIG_NTRX_SNIFFER NTRXSPIRead (NA_RamRxDstAddr_O, upMsg.rxAddr, 6); upMsg.count++; upMsg.extBits = rState; upMsg.frameType = (status & 0x0f); # endif upMsg.len = reg[0]; if (upMsg.len > PHY_PACKET_SIZE) { /* restart receiver */ if (phyPIB.rxState == PHY_RX_ON) { NTRXSPIWriteByte (NA_RxCmdStart_O, ntrxShadowReg[NA_RxCmdStart_O] | (1 << NA_RxCmdStart_B) | (0x03 << NA_RxBufferCmd_LSB)); } } else { if (buffSwapped == TRUE) { buffSwapped = FALSE; /* SWAP BUFFER for receive*/ ntrxShadowReg[NA_SwapBbBuffers_O] &= ~(1 << NA_SwapBbBuffers_B); NTRXSPIWriteByte (NA_SwapBbBuffers_O, ntrxShadowReg[NA_SwapBbBuffers_O]); NTRXSetIndexReg (3); } else { buffSwapped = TRUE; /* SWAP BUFFER for receive*/ ntrxShadowReg[NA_SwapBbBuffers_O] |= (1 << NA_SwapBbBuffers_B); NTRXSPIWriteByte (NA_SwapBbBuffers_O, ntrxShadowReg[NA_SwapBbBuffers_O]); NTRXSetIndexReg (2); } tiPhyRxTimeout_once = FALSE; tiPhyRxTimeout = hwclock() + phyPIB.phyRxTimeout; /* * restart receiver and than read rx buffer. This is ok because we use * buffer swapping. */ if (phyPIB.rxState == PHY_RX_ON) { NTRXSPIWriteByte (NA_RxCmdStart_O, ntrxShadowReg[NA_RxCmdStart_O] | (1 << NA_RxCmdStart_B) | (0x03 << NA_RxBufferCmd_LSB)); } NTRXSPIRead ((MyByte8T)(NA_RamRxBuffer_O & 0xFF), upMsg.data, upMsg.len); NTRXSetIndexReg (0); #ifdef CONFIG_NTRX_SNIFFER upMsg.value = 0xff; upMsg.prim = PD_DATA_INDICATION; SendMsgUp (&upMsg); #else /* * if address matching off, ignore rangingstates * this path is used for normal data reception * ranging is handled in the else path */ if (((ntrxShadowReg[NA_RxAddrMode_O] & (1<<NA_RxAddrMode_B)) == 0) || (lState == RANGING_READY && rState == RANGING_READY)) { upMsg.value = 0xff; upMsg.prim = PD_DATA_INDICATION; SendMsgUp (&upMsg); } else if((lState == RANGING_READY) && (rState == RANGING_START || rState == RANGING_FAST_START)) { memcpy(rDest, upMsg.addr, 6); RangingCallback_Rx(upMsg.data, upMsg.len); if(rState == RANGING_START) { lState = RANGING_ANSWER1; /* send ranging packet */ RangingMode(RANGING_ANSWER1, rDest); }else if (rState == RANGING_FAST_START) { lState = RANGING_FAST_ANSWER1; /* send ranging packet */ RangingMode(RANGING_FAST_ANSWER1, rDest); } } else if((memcmp(rDest, upMsg.addr, 6) == 0) && lState == RANGING_ANSWER1 && rState == RANGING_ANSWER1) { /* received ranging data to RangingCallback_Rx * (without protocol header stuff) */ RangingCallback_Rx(upMsg.data, upMsg.len); lState = RANGING_ANSWER2; } else if((memcmp(rDest, upMsg.addr, 6) == 0) && ((lState == RANGING_ANSWER2 && rState == RANGING_ANSWER2) || (lState == RANGING_FAST_ANSWER1 && rState == RANGING_FAST_ANSWER1))) { /* ranging was successfull, stop timeout */ NTRXStopBbTimer(); /* received ranging data to RangingCallback_Rx *(without protocol header stuff) */ RangingCallback_Rx(upMsg.data, upMsg.len); /* calculate the distance */ rangingPIB.distance = getDistance(); rangingPIB.rssi = getRSSI(); if (rangingPIB.distance < 0.0) rangingPIB.error = STAT_RANGING_VALUE_ERROR; upMsg.value = 0xff; memcpy(upMsg.data, (MyByte8T*) &rangingPIB, sizeof(RangingPIB)); upMsg.len = sizeof(RangingPIB); if (rState == RANGING_ANSWER2) upMsg.prim = PD_RANGING_INDICATION; else if (rState == RANGING_FAST_ANSWER1) upMsg.prim = PD_RANGING_FAST_INDICATION; /* set ready for new ranging */ lState = RANGING_READY; SendMsgUp (&upMsg); } # endif } }
void PDSap (MyMsgT *msg) /****************************************************************************/ { MyByte8T txLen[2]; static MyAddressT cacheAddr; /* * check the message length. If the message length is bigger than * the allowed buffer size the packet will be rejected. */ if (msg->len > PHY_PACKET_SIZE) { msg->prim = PD_DATA_CONFIRM; msg->status = PHY_BUSY_TX; SendMsgUp (msg); return; } switch(msg->prim) { case PD_DATA_REQUEST : /* transmitter still busy */ if (txSendMsg != NULL) { msg->prim = PD_DATA_CONFIRM; msg->status = PHY_BUSY_TX; SendMsgUp (msg); return; } /* * there is no break here !!! * This is intentional and not a mistake. */ case PD_RANGING_ANSWER1_EXECUTE : case PD_RANGING_ANSWER2_EXECUTE : case PD_RANGING_REQUEST_EXECUTE : case PD_RANGING_FAST_REQUEST_EXECUTE : case PD_RANGING_FAST_ANSWER1_EXECUTE : # ifdef CONFIG_NTRX_AUTO_RECALIB if (phyPIB.recalInterval != 0) { if( tiRecal < hwclock() ) { /* INFO: If the TRX sends a packet, calibration failes! * In this case rcwd is not reset, but tiRecal is. */ /* normal operation mode */ if (phyPIB.testmode == 0) { if (NTRXAllCalibration ()) { tiRecal = hwclock() + phyPIB.recalInterval; rcwd = 0; TRIGGER_LED_CAL(); } } } } # endif /* CONFIG_NTRX_AUTO_RECALIB */ /* check which buffer is free to transmit data */ if (buffSwapped ==TRUE) { /* write user data to transmit buffer in ntrx chip */ NTRXSetIndexReg (2); NTRXSPIWrite ((MyByte8T)(NA_RamTxBuffer_O & 0xff), msg->data, (MyByte8T)(msg->len & 0xff)); }else { /* write user data to transmit buffer in ntrx chip */ NTRXSetIndexReg (3); NTRXSPIWrite ((MyByte8T)(NA_RamTxBuffer_O & 0xff), msg->data, (MyByte8T)(msg->len & 0xff)); } NTRXSetIndexReg (0); /* copy the destination address to temp buffer */ if (memcmp (cacheAddr, msg->addr, 6) != 0) { memcpy (cacheAddr, msg->addr, 6); NTRXSPIWrite (NA_RamTxDstAddr_O, cacheAddr, 6); } /* merge the three bits into the temp buffer */ txLen[0] = msg->len; // txLen[1] = (len & 0x1F00) >> 8; txLen[1] = (lState & 0x01) ? 0x20 : 0; txLen[1] |= (lState & 0x02) ? 0x40 : 0; txLen[1] |= (lState & 0x04) ? 0x80 : 0; NTRXSPIWrite (NA_RamTxLength_O, txLen, 2); ntrxState = TxSEND; /* mark buffers as valid and start transmission */ NTRXSPIWriteByte (NA_TxBufferCmd_O, (1 << NA_TxCmdStart_B) | (0x03 << NA_TxBufferCmd_LSB)); TRIGGER_LED_TX(); txSendMsg = msg; break; case PD_RANGING_REQUEST : case PD_RANGING_FAST_REQUEST : /* transmitter still busy */ rangingPIB.distance = -1.0; rangingPIB.error = STAT_NO_ERROR; if (txSendMsg != NULL) { msg->prim = PD_RANGING_CONFIRM; msg->status = PHY_BUSY_TX; memcpy(msg->data, (MyByte8T*) &rangingPIB, sizeof(RangingPIB)); msg->len = sizeof(RangingPIB); SendMsgUp (msg); return; } if (lState != RANGING_READY) { txSendMsg = NULL; msg->prim = PD_RANGING_CONFIRM; msg->status = PHY_BUSY; memcpy(msg->data, (MyByte8T*) &rangingPIB, sizeof(RangingPIB)); msg->len = sizeof(RangingPIB); SendMsgUp (msg); return; } memcpy(rDest, msg->addr, 6); if (msg->prim == PD_RANGING_REQUEST) { lState = RANGING_START; RangingMode(RANGING_START, msg->addr); } else if (msg->prim == PD_RANGING_FAST_REQUEST) { lState = RANGING_FAST_START; RangingMode(RANGING_FAST_START, msg->addr); } break; default: break; } }
void PHYInit (void) /****************************************************************************/ { phyPIB.currentChannel = PHY_CHANNEL_MIN; phyPIB.txPower = 0x3f; phyPIB.pwrDownMode = 2; txSendMsg = NULL; phyPIB.recalInterval = CONFIG_NTRX_RECAL_DELAY; phyPIB.phyRxTimeout = CONFIG_NTRX_PHY_RX_TIMEOUT; tiPhyRxTimeout = hwclock() + phyPIB.phyRxTimeout; tiPhyRxTimeout_once = FALSE; phyPIB.arqMax = CONFIG_MAX_ARQ; phyPIB.testmode = 0; phyPIB.fec = FALSE; trxPollMode = TRUE; /* * Clear and reset all interrupt flags of the nanoLOC chip */ ntrxShadowReg[NA_TxIntsReset_O] = 0x3f; ntrxShadowReg[NA_RxIntsReset_O] = 0x7f; /* * enable tx and rx interrupts */ ntrxShadowReg[NA_RxIrqEnable_O] |= ((1 << NA_RxIrqEnable_B) | (1 << NA_TxIrqEnable_B)); NTRXResetSettings (); /* * enable CRC checks on received messages. This will cause corrupt frames to be droped * silently by the nanoLOC chip. The receiver is restarted automatically. */ if ((ntrxShadowReg[NA_RxCrc2Mode_O] & (1<< NA_RxCrc2Mode_B)) != 0) { ntrxShadowReg[NA_RxIntsEn_O] = (0x01 << NA_RxEnd_B); } else { ntrxShadowReg[NA_RxIntsEn_O] = ((0x01 << NA_RxEnd_B) | (0x01 << NA_RxOverflow_B)); } ntrxShadowReg[NA_TxIntsEn_O] = (1 << NA_TxEnd_B); NTRXSPIWrite (NA_RxIrqEnable_O, ntrxShadowReg + 0x0f, 6); /* * initialize layer global variables */ txIrqStatus = 0; rxIrqStatus = 0; txIrq = 0; rxIrq = 0; bbIrq = 0; lState = RANGING_READY; rState = RANGING_READY; ntrxShadowReg[NA_TxIntsReset_O] = 0; ntrxShadowReg[NA_RxIntsReset_O] = 0; /* * start the receiver of the TRX chip */ if (phyPIB.rxState == PHY_RX_ON) { NTRXSPIWriteByte (NA_RxCmdStart_O, ntrxShadowReg[NA_RxCmdStart_O] | (1 << NA_RxCmdStart_B) | (0x03 << NA_RxBufferCmd_LSB)); } ntrxState = TxIDLE; }