/*******************************************************************************
 * @fn          perCC1120CC1190Read8BitRssi
 *    
 * @brief       Reads MSB RSSI value from register, converts the dBm value to
 *              decimal and adjusts it according to RSSI offset
 *
 * input parameters
 *
 * @param       none
 *
 * output parameters
 *
 * @return      decimal RSSI value corrected for RSSI offset
 */ 
int8 perCC1120CC1190Read8BitRssi(void)
{
  uint8 rssi2compl,rssiValid;
  int16 rssiConverted;
  
  cc112xSpiReadReg(CC112X_RSSI0, &rssiValid,1);
  if(rssiValid & 0x01)
  {
    /* Read RSSI from MSB register */
    cc112xSpiReadReg(CC112X_RSSI1, &rssi2compl,1);
    rssiConverted = (int8)((int8)rssi2compl) - cc1120cc1190RssiOffset;
    return rssiConverted;
  }
  /* keep last value since new value is not valid */
  return rxData->rssi;
}
/*******************************************************************************
*   @fn         packetReceivedISR
*
*   @brief      Function running every time a packet has been received
*
*   @param      none
*
*   @return     none
*/
static void packetReceivedISR(void) {
    cc112xSpiReadRxFifo(pBufferIndex, bytesLeft);
    
    packetReceived = TRUE;

    cc112xSpiReadReg(CC112X_RSSI1,&rssi_readout,1);
    
    // Convert to decimal value from 2's complement rssi_readout.
    rssi = (int16)((int8)rssi_readout) - cc112xRssiOffset;
    
    // Clear ISR flag
    ioPinIntClear(IO_PIN_PORT_1, GPIO3);
}
/******************************************************************************
* @fn          perCC1120CC1190SetOutputPower
*
* @brief       Configures the output power of CC112x according to the provided
*              index:
*              0 =  xx dBm
*              1 =  26 dBm

*              NOTE: for PG2.0 pa_shape_en and pa_power_ramp has swapped 
*                    position
*
*
*
* input parameters
*
* @param       index - index to table <=> wanted output level
*                  
* output parameters
*
* @return      void
*/
void perCC1120CC1190SetOutputPower(uint8 index)
{
  uint8 level; 
  
  /* Reading the PA_CFG2 value to account for pa_shape_en */
  cc112xSpiReadReg(CC112X_PA_CFG2,&level,1);
  /* Saving pa_shape_en */
  level &= 0x40;
  /* Oring in the PA power ramp value */
  level |= paPowerRamp[index];
  /* Updating PA_CFG2 register with its' new value */
  cc112xSpiWriteReg(CC112X_PA_CFG2,&level,1);
  return;
}
/*******************************************************************************
*   @fn         syncReceivedISR
*
*   @brief      Function running every time a sync word has been received
*
*   @param      none
*
*   @return     none
*/
static void syncReceivedISR(void) {

    uint8 numRxBytes;
    uint8 writeByte;

    // After the sync word is received one needs to wait for the two
    // length bytes to be put in the RX FIFO
    do {
        cc112xSpiReadReg(CC112X_NUM_RXBYTES, &numRxBytes, 1);
    } while (numRxBytes < 2);

    // Read the length byte and store it in the packetLength variable
    cc112xSpiReadRxFifo(rxBuffer, 2);
    pBufferIndex += 2;
    packetLength =  (uint16)(((uint16)(rxBuffer[0] << 8)) | rxBuffer[1]);

    // Make sure that the packet length is in the correct range, update
    // variables and enable interrupt on falling edge of GPIO3 (PKT_SYNC_RXTX)
    if ((packetLength > MAX_VARIABLE_LENGTH) 
        && (packetLength <= PACKET_LENGTH)) {
        bytesLeft = packetLength + 2;
        fixedPacketLength = bytesLeft  % (MAX_VARIABLE_LENGTH + 1);
        writeByte = fixedPacketLength;
        cc112xSpiWriteReg(CC112X_PKT_LEN, &writeByte, 1);

        // Clear interrupt flag and enable GPIO3
        ioPinIntClear(IO_PIN_PORT_1, GPIO3);
        ioPinIntEnable(IO_PIN_PORT_1, GPIO3);

    } else { // Exit RX and flush RX FIFO due to length byte being out of range
        trxSpiCmdStrobe(CC112X_SIDLE);
        trxSpiCmdStrobe(CC112X_SFRX);
        state = RX_START;
    }
  
    // Clear ISR flag
    ioPinIntClear(IO_PIN_PORT_1, GPIO2);
}
Esempio n. 5
0
void cc112x_event_handler_test(void)
{
	uint8_t part_num = 0;
	
	cc112x_init();
	GPIO_ResetBits(GPIO_PORT_CC112X_RESET, GPIO_PIN_CC112X_RESET);
	delay1ms(1);
	GPIO_SetBits(GPIO_PORT_CC112X_RESET, GPIO_PIN_CC112X_RESET);

	/* Power Up Reset */
	rf_PowerUpReset();

	registerConfig();
#ifdef CC112x_DEBUG
	    printf("[CC112X] registerConfiging OK...\r\n"); 
#endif

	cc112xSpiReadReg(CC112X_PARTNUMBER, &part_num, 1);
#ifdef CC112x_DEBUG
	   printf("[CC112X] cc112xSpiReadReg,part_num = 0x%02x\r\n",part_num);   
#endif

}
/******************************************************************************
 * @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;
    } 
  }   
}     
/*******************************************************************************
* @fn          manualCalibration
*
* @brief       Perform manual calibration according to the errata note
* @param       none
*
* @return      none
*/
static void manualCalibration(void) {
  uint8 original_fs_cal2;
  uint8 calResults_for_vcdac_start_high[3];
  uint8 calResults_for_vcdac_start_mid[3];
  uint8 marcstate;
  uint8 writeByte;

  // 1) Set VCO cap-array to 0 (FS_VCO2 = 0x00)
  writeByte = 0x00;
  cc112xSpiWriteReg(CC112X_FS_VCO2, &writeByte, 1);

  // 2) Start with high VCDAC (original VCDAC_START + 2):
  cc112xSpiReadReg(CC112X_FS_CAL2, &original_fs_cal2, 1);
  writeByte = original_fs_cal2 + VCDAC_START_OFFSET;
  cc112xSpiWriteReg(CC112X_FS_CAL2, &writeByte, 1);

  // 3) Calibrate and wait for calibration to be done (radio back in IDLE state)
  trxSpiCmdStrobe(CC112X_SCAL);
  do {
    cc112xSpiReadReg(CC112X_MARCSTATE, &marcstate, 1);
  } while (marcstate != 0x41);

  // 4) Read FS_VCO2, FS_VCO4 and FS_CHP register obtained with high VCDAC_START value
  cc112xSpiReadReg(CC112X_FS_VCO2, &calResults_for_vcdac_start_high[FS_VCO2_INDEX], 1);
  cc112xSpiReadReg(CC112X_FS_VCO4, &calResults_for_vcdac_start_high[FS_VCO4_INDEX], 1);
  cc112xSpiReadReg(CC112X_FS_CHP, &calResults_for_vcdac_start_high[FS_CHP_INDEX], 1);

  // 5) Set VCO cap-array to 0 (FS_VCO2 = 0x00)
  writeByte = 0x00;
  cc112xSpiWriteReg(CC112X_FS_VCO2, &writeByte, 1);

  // 6) Continue with mid VCDAC (original VCDAC_START):
  writeByte = original_fs_cal2;
  cc112xSpiWriteReg(CC112X_FS_CAL2, &writeByte, 1);

  // 7) Calibrate and wait for calibration to be done (radio back in IDLE state)
  trxSpiCmdStrobe(CC112X_SCAL);
  do {
    cc112xSpiReadReg(CC112X_MARCSTATE, &marcstate, 1);
  } while (marcstate != 0x41);

  // 8) Read FS_VCO2, FS_VCO4 and FS_CHP register obtained with mid VCDAC_START value
  cc112xSpiReadReg(CC112X_FS_VCO2, &calResults_for_vcdac_start_mid[FS_VCO2_INDEX], 1);
  cc112xSpiReadReg(CC112X_FS_VCO4, &calResults_for_vcdac_start_mid[FS_VCO4_INDEX], 1);
  cc112xSpiReadReg(CC112X_FS_CHP, &calResults_for_vcdac_start_mid[FS_CHP_INDEX], 1);

  // 9) Write back highest FS_VCO2 and corresponding FS_VCO and FS_CHP result
  if (calResults_for_vcdac_start_high[FS_VCO2_INDEX] > calResults_for_vcdac_start_mid[FS_VCO2_INDEX]) {
    writeByte = calResults_for_vcdac_start_high[FS_VCO2_INDEX];
    cc112xSpiWriteReg(CC112X_FS_VCO2, &writeByte, 1);
    writeByte = calResults_for_vcdac_start_high[FS_VCO4_INDEX];
    cc112xSpiWriteReg(CC112X_FS_VCO4, &writeByte, 1);
    writeByte = calResults_for_vcdac_start_high[FS_CHP_INDEX];
    cc112xSpiWriteReg(CC112X_FS_CHP, &writeByte, 1);
  }
  else {
    writeByte = calResults_for_vcdac_start_mid[FS_VCO2_INDEX];
    cc112xSpiWriteReg(CC112X_FS_VCO2, &writeByte, 1);
    writeByte = calResults_for_vcdac_start_mid[FS_VCO4_INDEX];
    cc112xSpiWriteReg(CC112X_FS_VCO4, &writeByte, 1);
    writeByte = calResults_for_vcdac_start_mid[FS_CHP_INDEX];
    cc112xSpiWriteReg(CC112X_FS_CHP, &writeByte, 1);
  }
}
Esempio n. 8
0
/***********************************************************************
  * @brief  Deal with the event handler for cc112x.
  * @param  p_event_data
  * @param  event_size
  * @retval None
************************************************************************/
void cc112x_event_handler(void * p_event_data, uint16_t event_size)
{
    cc112x_event_t * p_cc112x_event_temp = p_event_data;
	uint8_t part_num = 0;
	uint8_t i,readByte;
    
    switch(p_cc112x_event_temp->eCC112x_event)
    {
        case CC112X_INIT_EVENT:
			#ifdef CC112x_DEBUG
			    printf("[CC112X] CC112X_INIT_EVENT...\r\n");   
			#endif

			cc112x_init();
			GPIO_ResetBits(GPIO_PORT_CC112X_RESET, GPIO_PIN_CC112X_RESET);
			delay1ms(1);
			GPIO_SetBits(GPIO_PORT_CC112X_RESET, GPIO_PIN_CC112X_RESET);

			// Power Up Reset 
			rf_PowerUpReset();
			registerConfig();
			
			#ifdef CC112x_DEBUG
			    printf("[CC112X] registerConfiging OK...\r\n"); 
				cc112xSpiReadReg(CC112X_PARTNUMBER, &part_num, 1);
				printf("[CC112X] cc112xSpiReadReg,part_num = 0x%02x\r\n",part_num);   
			#endif
			
			SPI_DeInit(APP_CC112X_SPI);
			GPIO_DeInit(GPIO_PORT_CC112X_SPI_NSS);
            break;
            
        case CC112X_TRANSMIT_EVENT:
			#ifdef CC112x_DEBUG
			    printf("[CC112X] CC112X_TRANSMIT_EVENT...\r\n");   
			#endif

			trxRfSpiInterfaceInit();

			#ifdef CC112x_DEBUG	
				printf("[CC112X] cc112xSpiReadReg,part_num = 0x%02x\r\n",part_num);	 
				for(i = 0;i < (sizeof(preferredSettings)/sizeof(registerSetting_t)); i++) 
				{
					cc112xSpiReadReg(preferredSettings[i].addr, &readByte, 1);
					printf("[CC112X] i = %d : 0x%02x \r\n",i,readByte); 
				}
			#endif
			
			SPI_DeInit(APP_CC112X_SPI);
			GPIO_DeInit(GPIO_PORT_CC112X_SPI_NSS);
            break;
            
        case CC112X_RECEIVE_EVENT:
			trxRfSpiInterfaceInit();

			#ifdef CC112x_DEBUG	
				cc112xSpiReadReg(CC112X_PARTNUMBER, &part_num, 1);
				printf("[CC112X] cc112xSpiReadReg,part_num = 0x%02x\r\n",part_num);	 
				for(i = 0;i < (sizeof(preferredSettings)/sizeof(registerSetting_t)); i++) 
				{
					cc112xSpiReadReg(preferredSettings[i].addr, &readByte, 1);
					printf("[CC112X] i = %d : 0x%02x \r\n",i,readByte); 
				}
			#endif
			
			SPI_DeInit(APP_CC112X_SPI);
			GPIO_DeInit(GPIO_PORT_CC112X_SPI_NSS);
            break;
            
        default:
            break;
    }
}