Esempio n. 1
0
/******************************************************************************
 * @fn          halTimer32kMcuSleepTicks
 *
 * @brief       This function uses Timer B to sleep for a specfied number of
 *              ACLK ticks, that is less than 2^15 tics(1s).
 *              Assumes that the only interrupt source is
 *              generated by Timer B.
 *
 *              NOTE: When called, this function will assign NO ISR to the
 *              TIMERB0_VECTOR interrupt(NULL pointer). When interrupt triggers
 *              it will just wake up the MCU. Conflicts are possible if not
 *              used carefully since other parts of a program might use the
 *              TIMER B.
 *
 * input parameters
 *
 * @param       ticks  - Number of ACLK(32768Hz) ticks that the MCU will sleep
 *
 * output parameters
 *
 * @return      void
 */
void halTimer32kMcuSleepTicks(uint16 ticks)
{
  halTimer32kIntConnect(NULL);
  halTimer32kInit(ticks);
  halTimer32kIntEnable();
  __low_power_mode_3();
  halTimer32kAbort();
}
/******************************************************************************
 * @fn          perCC1120CC1190RxTxISR
 *
 * @brief       ISR that's called when sync signal goes low. 
 *              In RX State: Filters incoming data. The global rxData pointer
 *              always points to this functions static rxData_tmp(struct of
 *              same kind). The validnes of rxData fields is indicated by the
 *              the global flag packetSemaphore.
 *              In TX State: Nothing is done except it facilitates power 
 *              consumption reduction when TX since the program doesn't need
 *              to wait until TX is done before re-enabling sync pin interrupt.
 *              cc1120cc1190RadioTxRx is also set to CC112X_STATE_IDLE to be consistent 
 *              with program.
 * 
 * input parameters
 *             
 * @param       none
 *
 * output parameters
 *
 * @return      void
 */
void perCC1120CC1190RxTxISR(void)
{
  uint8 rxBytes,rxLength,rssiIndex,lqiIndex;
  /* This variable stores the data locally. Access is given to per_test by 
   * assigning this instance to the global rxData pointer
   */
  static rxData_t rxData_tmp;
            
  rxData = &rxData_tmp;
  
  /* Checking if the chip is in RX state:  */
  if(cc1120cc1190RadioTxRx != CC112X_STATE_RX)
  {
    /* Transmission finished */
    if((perSettings.deviceMode == MASTER_DEVICE) && (perSettings.linkTopology == LINK_2_WAY) && (perSettings.masterSlaveLinked ==PER_DEVICE_LINKED))
    {
      /* Only applicable when master in 2-way test */
      cc1120cc1190RadioTxRx=CC112X_STATE_RX;
    }
    else
    {
      cc1120cc1190RadioTxRx  = CC112X_STATE_IDLE;
    }
    return;
  }
  
  packetSemaphore |= SYNC_FOUND;
  
  if(((perSettings.masterSlaveLinked == PER_DEVICE_LINKED)||(perSettings.masterSlaveLinked == PER_DEVICE_LINK_BYPASS)) && (perSettings.deviceMode == MASTER_DEVICE) && (perSettings.testRunning == PER_TRUE))
  {
  	if(perSettings.linkTopology == LINK_1_WAY)
  	{
  	  /* Read timer value and set the perSettings.packetRate valu(adjustment for temperature drift */
      halTimer32kSetIntFrequency(perSettings.packetRate);
      halTimer32kIntEnable();
    }
    else
    {
    	/* LINK_2_WAY */ 
    	
    	/* Timeout interrupt configuring is handled by the 2-way Per test */
      timer32kValue = halTimer32kReadTimerValue();
    	halTimer32kAbort();
    }
  }
    
  cc112xSpiReadReg(CC112X_NUM_RXBYTES,&rxBytes,1);
  /* Checking if the FIFO is empty */
  if(rxBytes == PER_FALSE)
  {
    /* The packet was removed by HW due to addr or length filtering -> Do nothing */
    /* Report that a sync was detected */ 
    rxData_tmp.rssi = perCC1120CC1190Read8BitRssi();
    return;
  }
  else
  {
    /* The RX FIFO is not empty, process contents */    
    cc112xSpiReadRxFifo(&rxLength, 1);  
    /* Check that the packet length just read + FCS(2B) + length byte match the RXBYTES */
    /* If these are not equal:
     * - RXFIFO overflow: Received packets not processed while beeing in RX. 
     */
    if(rxBytes != (rxLength+3))
    {
      /* This is a fault FIFO condition -> clean FIFO and register a sync detection */
      /* IDLE -> FLUSH RX FIFO -> RX */
      cc1120cc1190RxIdle();     
      perCC1120CC1190EnterRx(); 
      /* Report that a sync was detected */
      rxData_tmp.rssi = perCC1120CC1190Read8BitRssi();
      return;
    }
    else
    {
      /* We don't have a FIFO error condition -> get packet */
      
      /* Length Field */
      rxData_tmp.data[0] = rxLength;
      rssiIndex = rxLength+1;
      lqiIndex  = rssiIndex +1;
      
      /* Payload(ADDR + DATA + FCS) */
      cc112xSpiReadRxFifo(&rxData_tmp.data[1], lqiIndex);
      
      /* The whole packet has been read from the FIFO.
       * Check if the CRC is correct and that the packet length is as expected.
       * If not correct: report sync found and do not update RSSI or LQI.
       */
      if((!(rxData_tmp.data[lqiIndex] & CC112X_LQI_CRC_OK_BM)) || (perSettings.payloadLength != rxLength ))
      {
        rxData_tmp.rssi = perCC1120CC1190Read8BitRssi();
        return;
      }
      /* A complete error-free packet has arrived  */
      
      /* Measured data */
      rxData_tmp.length  = rxLength;
      rxData_tmp.lqi     = rxData_tmp.data[lqiIndex] & CC112X_LQI_EST_BM;
      rxData_tmp.addr    = rxData_tmp.data[1]; 
      
      /* Convert RSSI value from 2's complement to decimal value accounting for offset value */
      rxBytes = rxData_tmp.data[rssiIndex];        
      rxData_tmp.rssi = (int8)((int8)rxBytes) - cc1120cc1190RssiOffset;
      /* Signal a good packet is received */
      packetSemaphore |= PACKET_RECEIVED;
      return;
    } 
  }   
}