3

I'm working on a sensor project which uses TelosB based on CC2420 and MSP430F1611 running TinyOS. And I want to timestamp each incoming packet, whose reception time is indicated by the SFD pin rising of CC2420. The SFD pin of CC2420 is connected to P4.1/TB1 of MSP430F1611 as seen from the schematic. One straightforward way is to buffer the timestamps: whenever an SFD rising edge is captured (e.g., by channel 1 of TimerB), store the captured timestamp in a queue. When each packet is read out from RXFIFO, a timestamp is dequeued and associated with it. This is actually what the default radio driver does in TinyOS. There are several problems with this approach.

(1) Before a captured timestamp is placed into the queue, another packet arrives and triggers an SFD rising edge, overwriting the previous timestamp. There is no timestamp for the corresponding packet. What's worse, it's unknown which remaining timestamp corresponds to which received packet. The mapping from the packet and timestamp is messed up.

(2) Some packets are dropped by CC2420 (e.g., fail to pass address recognition) and not placed into RXFIFO. Nevertheless, it still generates SFD rising edge. There is no packet for the corresponding timestamp. Again, the mapping is messy.

Can anyone please give me some hint on how to overcome these two issues and timestamp packets correctly, especially under heavy load? My requirement can be relaxed not to timestamp all packets correctly, but a fraction of them. Your help will be sincerely appreciated.

sinoTrinity
  • 201
  • 2
  • 6

1 Answers1

1

The method you described certainly seems like it won't suffer from the first problem you've described. Except in extreme circumstances or some kind of polling implementation. Are you not using an interrupt to place the time stamp into the queue? It would take maybe 15 cycles to complete the copy, how fast do packets come in?

// Timer B0 interrupt service routine
#pragma vector=TIMERB1_VECTOR
__interrupt void Timer_B (void)
{
 *Timestamp_RX_Write++ = TBR;   // Copy TBR value into timestamp buffer
 if(Timestamp_RX_Write >= Timestamp_RX_Buffer + Timestamp_Buffer_Size)
    Timestamp_RX_Write -= Timestamp_Buffer_Size;
}

This would be assuming you've created your FIFO like this:

unsigned int Timestamp_RX_Buffer[Timestamp_Buffer_Size];    // Timestamp buffer
volatile unsigned int *Timestamp_RX_Read = Timestamp_RX_Buffer;// Read pointer
volatile unsigned int *Timestamp_RX_Write = Timestamp_RX_Buffer;// Write pointer

For the second problem, just always pop the time stamps from the queue when you're servicing/verifying the packets, if the addressing fails then that time stamp is thrown away.

Timestamp = *Timestamp_RX_Read++;  // Load the time stamp value from the queue
if(Timestamp_RX_Read >= Timestamp_RX_Buffer + Timestamp_Buffer_Size)
   Timestamp_RX_Read -= Timestamp_Buffer_Size;

if(Packet_Address!=Correct_Address)
   return;

Now you'll obviously need to be checking for overflows in your counter, or at least keep a running index with RXed packets so you can order them correctly later. But that's going to depend on how you're using the time stamps, maybe all you need is the difference between two time stamps. I could give more help if you further describe your application.

Samuel
  • 11,891
  • 32
  • 51
  • Yes, I enqueue the timestamps in the SFD interrupt handler. Up to 3 packets can come per ms. Even it takes little time to enqueue a timestamp, the problem is that even interrupt may not be handled immediately, e.g., the previous packet is being read by the MCU in the packet reception interrupt handler, which can take 4 ms. During that period, multiple packets can arrive and case (1) occurs. – sinoTrinity Dec 02 '12 at 18:09
  • For case (2), the packet drop happens in the CC2420 radio, the MCU is not aware of any drop. Basically, my application is to timestamp a packet at the sender and receiver side so they can synchronize. Thanks very much for your response. – sinoTrinity Dec 02 '12 at 18:10