/****************************************************************************** * @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; } } }