Monday, March 7, 2011

Multiple access, collision avoidance

Avoiding packet collisions is one of the main worries when designing wireless systems. The radio-frequency space is usually crowded since ISM bands are very popular nowadays. On the other hand, implementing collision-avoidance systems depends on the features provided by each RF IC most of the times. Fortunately, CC11xx interfaces do include a listen-before-talk mechanism called Clear Channel Assessment (CCA). From the CC1101 datasheet:

“The Clear Channel Assessment (CCA) is used to indicate if the current channel is free or busy”

Any of the CC1101 GDO pins can be configure to show the current CCA state. Even better, the CC1101 includes a feature that forces it to complete transmissions only if the channel is clear. The following piece of code, taken from the CC1101 library currently being developed, shows the final function responsible of transmitting packets between panStamps:
 * sendData
 * 
 * Send data packet via RF
 * 
 * 'packet'    Packet to be transmitted
 *
 *  Return:
 *    True if the transmission succeeds
 *    False otherwise
 */
boolean CC1101::sendData(CCPACKET packet)
{
  // Enter RX state
  cmdStrobe(CC1101_SRX);

  // Check that the RX state has been entered
  while (readStatusReg(CC1101_MARCSTATE) != 0x0D)
    delay(1);
  delayMicroseconds(500);
  
  // Set data length at the first position of the TX FIFO
  writeReg(CC1101_TXFIFO,  packet.length);
  // Write data into the TX FIFO
  writeBurstReg(CC1101_TXFIFO, packet.data, packet.length);

  // CCA enabled: will enter TX state only if the channel is clear
  cmdStrobe(CC1101_STX);
  
  // Check that TX state is being entered (state = RXTX_SETTLING)
  if(readStatusReg(CC1101_MARCSTATE) != 0x15)
    return false;

  // Wait for the sync word to be transmitted
  wait_GDO0_high();
  // Wait until the end of the packet transmission
  wait_GDO0_low();

  // Flush TX FIFO
  cmdStrobe(CC1101_SFTX);
  
  // Enter back into RX state
  setRxState();
  
  //cCheck that the TX FIFO is empty
  if((readStatusReg(CC1101_TXBYTES) & 0x7F) == 0)
    return true;

  return false;
}

CC1101::sendData(CCPACKET packet) can be cyclically called until the transmission is actually completed. Each transmission will be started only if the channel is free.

No comments:

Post a Comment