I have cc2538em on SmartRF06eb and am experimenting with measuring TIme Of Flight using the basicrf setup included in the per_test (firmware foundation) for the cc2538.
Basically, I am measuring the time taken (using systick) for a transmit pkt to be sent and it's associated Ack pkt to be received.
It appears that the best place for this is in basic_rf.c within basicRfSendPacket() as follows:
/**************************************************************************//** * @brief Send packet * * @param destAddr Destination short address * @param pPayload Pointer to payload buffer. This buffer must be * allocated by higher layer. * @param length Length of payload * txState File scope variable that keeps tx state info * mpdu File scope variable. Buffer for the frame to send * * @return Returns SUCCESS or FAILED ******************************************************************************/ uint8 basicRfSendPacket(uint16 destAddr, uint8* pPayload, uint8 length) { uint8 mpduLength; uint8 status; // Turn on receiver if its not on if(!txState.receiveOn) { halRfReceiveOn(); } // Check packet length length = MIN(length, BASIC_RF_MAX_PAYLOAD_SIZE); // Wait until the transceiver is idle halRfWaitTransceiverReady(); // Turn off RX frame done interrupt to avoid interference on the SPI interface halRfDisableRxInterrupt(); mpduLength = basicRfBuildMpdu(destAddr, pPayload, length); #ifdef SECURITY_CCM halRfWriteTxBufSecure(txMpdu, mpduLength, length, BASIC_RF_LEN_AUTH, BASIC_RF_SECURITY_M); txState.frameCounter++; // Increment frame counter field #else halRfWriteTxBuf(txMpdu, mpduLength); #endif // Turn on RX frame done interrupt for ACK reception halRfEnableRxInterrupt(); SysTickIntEnable(); // // Get count before sending ranging packet // rangeA = SysTickValueGet(); // Send frame with CCA. return FAILED if not successful if(halRfTransmit() != SUCCESS) { status = FAILED; } // Wait for the acknowledge to be received, if any if (pConfig->ackRequest) { txState.ackReceived = FALSE; // // We'll enter RX automatically, so just wait until we can be sure that the ack reception should have finished //#ifdef __ICCARM__ // // // The timeout consists of a 12-symbol turnaround time, the ack packet duration, and a small margin // // TODO: Improve solution! // SysCtrlDelay((uint32)((SysCtrlClockGet() / 1000000) * BASIC_RF_ACK_WAIT)); //#else // halMcuWaitUs(BASIC_RF_ACK_WAIT); //#endif while(!txState.ackReceived) { } // // Get count after sending ranging packet // rangeB = SysTickValueGet(); // // Disable SysTick Interrupts // SysTickIntDisable(); // If an acknowledgment has been received (by RxFrmDoneIsr), the ackReceived flag should be set status = txState.ackReceived ? SUCCESS : FAILED; } else { status = SUCCESS; } // Turn off the receiver if it should not continue to be enabled if (!txState.receiveOn) { halRfReceiveOff(); } if(status == SUCCESS) { txState.txSeqNumber++; } #ifdef SECURITY_CCM halRfIncNonceTx(); // Increment nonce value #endif return status; }
In green you can see I am experimenting with an event driven Receive Packet instead of just waiting for a predefined timeframe. I will need to set a timeout for this in the future.
In red is the timing code. There is also a sysTick ISR registered for SysTickIntRegister in main() so that I can count the sysTick periods between sysTickIntEnable() and sysTickIntDisable().
The problem is, I am effectively getting a constant time period between rangeA and rangeB of +128k which occasionally fluctuates to +160k.
I'm guessing this is not the actual tx->rx measurement time, but some artificial time window ???
Can anybody point me in the correct direction?
Regards