/******************************************************************************
 * @fn          cc1101SpiReadReg
 *
 * @brief       Reads register(s). If len  = 1: one byte is read
 *                                 if len != 1: len bytes are read in burst
 *                                              mode
 * input parameters
 *
 * @param       addr   - address to read
 * @param       *pData - pointer to data array where read data is stored
 * @param       len    - numbers of bytes to read starting from addr
 *
 * output parameters
 *
 * @return      rfStatus_t
 */
rfStatus_t cc1101SpiReadReg(uint8 addr, uint8 *pData, uint8 len)
{
  uint8 rc;
  rc = trx8BitRegAccess((RADIO_BURST_ACCESS|RADIO_READ_ACCESS), addr, pData, len);
  return (rc);
}
/******************************************************************************   
 * @fn          trxDetectCC112xCrystal()                                     
 *                                                                                
 * @brief       This function estimates the crystal frequency if a CC112x 
 *              is detected.
 *              SPI init must be applied before this function   
 *              can be called.
 *
 * @param       none
 *          
 * @return      none
 */
static uint8 trxDetectCC112xCrystal()
{  
  // Write EXT CLOCK to IOCFG3 and IOCFG2
  uint8 writeBytes1[2] = {0x31, 0x31};
  trx8BitRegAccess(CC112X_WRITE_BURST, CC112X_IOCFG3, writeBytes1, 2);
  // set external clock divider to 32
  writeBytes1[0] = 0x00;
  trx16BitRegAccess(CC112X_WRITE_BURST,CC112X_EXT_MEM_ACCESS,CC112X_ECG_CFG,writeBytes1,1);
  
  //wait for crystal to be stable (CHIP_RDYn)
  while((trxSpiCmdStrobe(CC112X_SNOP)& 0xF0) != 0x00);
  
  //get system clock frequency
  uint32_t systemClockBak = bspSysClockSpeedGet();
  
  //set system clock frequency up to 25 MHz for accurate sampling
  bspSysClockSpeedSet(BSP_SYS_CLK_25MHZ);
  
  // initialize timerA to capture rising and falling edges on EXT CLOCK
  cc112xInitTimerA();
  
  // Setting up time out in case we hang wating for capture interrupt
  halTimer32kIntConnect(&timeOutISR);
  halTimer32kSetIntFrequency(1); // 1 sec timeout
  halTimer32kIntEnable();
  
  // wait for interrupt on timer capture or timeout
  while((!timerSemaphore) && (!timeoutSemaphore));
  
  // stop timeuot timer
  halTimer32kIntDisable();
  
  // stop timer
  disableTimerA();
 
  if(timerSemaphore)
  {
    // assuming 50% duty cycle. Period time = time between rising and
    // falling edge x 2
    capturePeriod = (captureTable[1]  - captureTable[0])*2;
  
    //check for negative number and set absolute value
    capturePeriod= (capturePeriod<0)?(0-capturePeriod):capturePeriod;
  
    // Claculate XOSC frequency in  MHz: 
    // system clock frequency / capturePeriod
    // times external clock divider (32)
    // times digital clock divider (2)
    floatingEstimate = (((25.0*32.0*2.0)/capturePeriod));
  
    //Round up/down estimated frequency and truncate to int
    xoscFreqEstimate = (uint8) (floatingEstimate + 0.5);
  }
  else
  {
    xoscFreqEstimate =  XOSC_FREQ_NONE;
  }
  
  //set system clock frequency back to standard
  bspSysClockSpeedSet(systemClockBak);
  
  //reset radio
  trxSpiCmdStrobe(CC112X_SRES);
  
  return xoscFreqEstimate;
}
/******************************************************************************
 * @fn          cc1101SpiReadRxFifo
 *
 * @brief       Reads RX FIFO values to pData array
 *
 * input parameters
 *
 * @param       *pData - pointer to data array where RX FIFO bytes are saved
 * @param       len    - number of bytes to read from the RX FIFO
 *
 * output parameters
 *
 * @return      rfStatus_t
 */
rfStatus_t cc1101SpiReadRxFifo(uint8 *pData, uint8 len)
{
  uint8 rc;
  rc = trx8BitRegAccess((RADIO_BURST_ACCESS|RADIO_READ_ACCESS),CC1101_FIFO, pData, len);
  return (rc);
}
/******************************************************************************   
 * @fn          trxDetectCC1101Crystal()                                    
 *                                                                                
 * @brief       This function estimates the crystal frequency if a NextGen 
 *              radio is detected.
 *              SPI init must be applied before this function   
 *              can be called.
 *
 * @param       none
 *          
 * @return      none
 */
static uint8 trxDetectCC1101Crystal()
{
  
 // Write CLOCK_XOSC/192 to GDO2
  uint8 writeByte = 0x3F;
  trx8BitRegAccess(CC1101_WRITE_BURST, CC1101_IOCFG2, &writeByte, 1);
  
  //Wait for crystal to be stable (CHIP_RDYn)
  while((trxSpiCmdStrobe(CC1101_SNOP)& 0xF0) != 0x00);
  
  //Get current system clock frequency
  uint32_t systemClockBak = bspSysClockSpeedGet();
  
  //set system clock frequency up to 25 MHz for accurate sampling
  bspSysClockSpeedSet(BSP_SYS_CLK_25MHZ);
  
  // initialize timerA to capture rising edges on CLOCK XOSC
  cc1101InitTimerA();
  
  // Setting up time out in case we hang wating for capture interrupt
  halTimer32kIntConnect(&timeOutISR);
  halTimer32kSetIntFrequency(1);  // 1 sec timeout
  halTimer32kIntEnable();
  
  // wait for interrupt on timer capture or timeout
  while((!timerSemaphore) && (!timeoutSemaphore));
  
  // stop timeuot timer
  halTimer32kIntDisable();
    
  // stop timer
  disableTimerA();
 
  if(timerSemaphore)
  {
     // assuming 50% duty cycle. Period time = time between rising and
    // falling edge x 2
    capturePeriod = (captureTable[1]  - captureTable[0])*2;
  
    //check for negative number and set absolute value
    capturePeriod= (capturePeriod<0)?(0-capturePeriod):capturePeriod;
  
    // Claculate XOSC frequency in  MHz:
    // system clock frequency / capturePeriod
    // times clock xosc divider (192)
    floatingEstimate = (((25.0*192.0)/capturePeriod));
  
    //Round up/down estimated frequency and truncate to int
    xoscFreqEstimate = (uint8) (floatingEstimate + 0.5);
  }
  else
  {
    xoscFreqEstimate =  XOSC_FREQ_NONE;
  }
  
  //set system clock frequency back to standard
  bspSysClockSpeedSet(systemClockBak);
    
  //reset radio
  trxSpiCmdStrobe(CC1101_SRES);
  
  return xoscFreqEstimate;
}