This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC110L Receiver code explanation for dummies

Other Parts Discussed in Thread: CC110L

Dear all,

Please, explain me some code tricks from СС110L receiver subrotine?

What exactly does this chunk?

cc11xLSpiReadReg(CC110L_RXBYTES,&rxBytesVerify,1);

do
{
rxBytes = rxBytesVerify;
cc11xLSpiReadReg(CC110L_RXBYTES,&rxBytesVerify,1);
}
while(rxBytes != rxBytesVerify);

Full code below:

/******************************************************************************
* @fn          runRX
*
* @brief       puts radio in RX and waits for packets. Update packet counter
*              and display for each packet received.
*                
* @param       none
*
* @return      none
*/
static void runRX(void)
{
  uint8 rxBuffer[64] = {0};
  uint8 rxBytes;
  uint8 rxBytesVerify;
  uint8 marcState;
  
  P2SEL &= ~0x40; // P2SEL bit 6 (GDO0) set to one as default. Set to zero (I/O)
  // connect ISR function to GPIO0, interrupt on falling edge
  trxIsrConnect(GPIO_0, FALLING_EDGE, &radioRxTxISR);
  
  // enable interrupt from GPIO_0
  trxEnableInt(GPIO_0);
  
  
  // set radio in RX
  trxSpiCmdStrobe(CC110L_SRX);
  
  // reset packet counter
  packetCounter = 0;
  
  
  
  // infinite loop
  while(1)
  {
    // wait for packet received interrupt 
    if(packetSemaphore == ISR_ACTION_REQUIRED)
    {
      cc11xLSpiReadReg(CC110L_RXBYTES,&rxBytesVerify,1);
      
      do
      {
        rxBytes = rxBytesVerify;
        cc11xLSpiReadReg(CC110L_RXBYTES,&rxBytesVerify,1);
      }
      while(rxBytes != rxBytesVerify);
      
      
      // Check that we have bytes in FIFO
      if(rxBytes != 0) {
        
        // Read MARCSTATE to check for RX FIFO error
        cc11xLSpiReadReg(CC110L_MARCSTATE, &marcState, 1);
        
        // Mask out MARCSTATE bits and check if we have a RX FIFO ERROR (0x11)
        if((marcState & 0x1F) == RXFIFO_OVERFLOW) {
          
          // Flush RX FIFO
          trxSpiCmdStrobe(CC110L_SFRX);
        } else {
          
          cc11xLSpiReadRxFifo(rxBuffer,(rxBytes));
          
          // check CRC ok (CRC_OK: bit7 in second status byte)
          if(rxBuffer[rxBytes-1] & 0x80)
          {
            // toggle led
            halLedToggle(LED1);
            // update packet counter
            packetCounter++;
          }
        }
      }
      // reset packet semaphore
      packetSemaphore = ISR_IDLE;
      
      // set radio back in RX
      trxSpiCmdStrobe(CC110L_SRX);
      
    }
  } 
}

/******************************************************************************
 * FUNCTIONS
 */  

#define PA_TABLE {0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}

// Deviation = 4.943848 
// Base frequency = 867.999573 
// Carrier frequency = 867.999573 
// Modulated = true 
// Modulation format = GFSK 
// Manchester enable = false 
// Sync word qualifier mode = 30/32 sync word bits detected 
// Preamble count = 4 
// Channel spacing = 199.813843 
// Carrier frequency = 867.999573 
// Data rate = 1.20056 
// RX filter BW = 60.267857 
// Data format = Normal mode 
// CRC enable = true 
// Device address = 0 
// Address config = No address check 
// CRC autoflush = false 
// PA ramping = false 
// TX power = 12 
static const registerSetting_t preferredSettings[] = {
  {CC110L_IOCFG0,       0x06},
  {CC110L_FIFOTHR,      0x47},
  {CC110L_PKTCTRL0,     0x05},
  {CC110L_FSCTRL1,      0x06},
  {CC110L_FREQ2,        0x20},
  {CC110L_FREQ1,        0x25},
  {CC110L_MDMCFG4,      0xF5},
  {CC110L_MDMCFG3,      0x75},
  {CC110L_MDMCFG2,      0x13},
  {CC110L_MDMCFG0,      0xE5},
  {CC110L_DEVIATN,      0x14},
  {CC110L_MCSM0,        0x18},
  {CC110L_FOCCFG,       0x16},
  {CC110L_RESERVED_0X20,0xFB},
  {CC110L_FSCAL3,       0xE9},
  {CC110L_FSCAL2,       0x2A},
  {CC110L_FSCAL1,       0x00},
  {CC110L_FSCAL0,       0x1F},
  {CC110L_TEST2,        0x81},
  {CC110L_TEST1,        0x35},
  {CC110L_TEST0,        0x09},
  {CC11xL_PA_TABLE0,    0xC0},
};
#ifdef  __cplusplus
}
#endif
/******************************************************************************

  • Hi Oleg,

    That particular piece of code is the workaround for errata #3 in the CC110L Errata Notes.

  • Thank you for explanation.

    I've read Errata and one point is still unclear for me:

    .............................................

    3.2.1 What Kinds of Register Fields Are Affected?
    This issue does not affect:
    ...
    Reading of any register whose value is known not to change at the time of the read operation
    (e.g. reading RXBYTES or RSSI after having received a packet)

    .............................................

    As I understood we read RXBYTES after falling edge of GDO (0x06). So it means packet has been recieved, yes?

    If NO, why we do not use the same workaround for MARCSTATE reading?

    (Read MARCSTATE to check for RX FIFO error - 2 lines down)

  • Hi Oleg

    You have understood the errata correctly and there is no need to implement the workaround from the errata as long as the packet is received.

    If RXOFF_MODE was set to something other than IDLE, it would have been necessary, but not with the register settings used here.

    Siri

  • Hi, Siri

    For case "RXOFF_MODE was set to something other than IDLE, it would have been necessary":

    should we use the same (ot another special) approach for this MARCSTATE read to get 100% right result at:

     // Read MARCSTATE to check for RX FIFO error
            cc11xLSpiReadReg(CC110L_MARCSTATE, &marcState, 1);

  • Hi Oleg

    The same workaround would be necessary for reading MARCSTATE if the radio is in a state where MARCSTATE could change. If RXOFF_MODE is for example RX it is fully possible for MARCSTATE to change to RXFIFO_OVERFLOW if the radio starts to receive another packet before the first one is read.

    BR

    Siri