Hi All,
I'm working simultaneously communication between two devices using CC1120.
There are two devices which one of the device is in TX and another device is in RX phase and those are woken up for every minute
by RTC interrupt in the main function.
After these devices start to work, TX device always work but RX side is stuck at end of the receive function in uncertain period of the time that this stuck time is changing such as 5 minutes,7 hours and more.
Also all interrupts stop until we restart the device in this case. When we checked the received and transmitted packet lenght, we don't see any fault and everythings seems okay.
TX device is sending 10 bytes and RX side is getting 12 bytes( 10 Data + 2 Status)
Is there any way how to solve this return trouble?
Also i'm sharing the rx function as below and attached.
void waitBeacon(void){
uint8 rxBuffer[RX_PKTLEN] = {0}; // RX_PKTLEN = 100;
uint8 rxBytes;
uint8 marcStatus;
uint8 control;
bool rx_process_status;
uint8 rxFirstByte;
uint8 rxLastByte;
uint8 txFirstByte;
uint8 txLastByte;
rx_process_status = false;
control = 1;
volatile uint32 count = 0;
// Setting register to receive
rx_client_registers();
waitTrakingProcess=0; //0
writeTP(waitTrakingProcess,0);
// Set fundamentals register and interrupy
setFundamentals();
waitTrakingProcess=1; //1
writeTP(waitTrakingProcess,1);
// Set radio in RX
trxSpiCmdStrobe(CC112X_SRX);
Delay10msx(5);
rx_process_status = waitRXStatus();
if(rx_process_status)
TEST_LED_ON;
waitTrakingProcess=2; //2
writeTP(waitTrakingProcess,2);
cc112xSpiReadReg(CC112X_RXFIRST, &rxFirstByte, 1);
cc112xSpiReadReg(CC112X_RXLAST, &rxLastByte, 1);
writeByteRange(rxFirstByte,rxLastByte,3);
cc112xSpiReadReg(CC112X_TXFIRST, &txFirstByte, 1);
cc112xSpiReadReg(CC112X_TXLAST, &txLastByte, 1);
writeByteRange(txFirstByte,txLastByte,4);
// Loop untill any meaningful is received or completed timeout
while(control){
if(count > 300000){
control = 0;
}
// Wait for packet received interrupt
if((packetSemaphore == ISR_ACTION_REQUIRED) && (rx_process_status == true) ){
// Read number of bytes in rx fifo
cc112xSpiReadReg(CC112X_NUM_RXBYTES, &rxBytes, 1);
waitTrakingProcess=3; //3
writeTP(rxBytes,3);
// Check that we have bytes in fifo
if(rxBytes != 0){
// Read marcstate to check for RX FIFO error
cc112xSpiReadReg(CC112X_MARCSTATE, &marcStatus, 1);
// Mask out marcstate bits and check if we have a RX FIFO error
if((marcStatus & 0x1F) == RX_FIFO_ERROR){
// Flush RX Fifo
trxSpiCmdStrobe(CC112X_SFRX);
Delay10msx(5);
control = 0;
waitTrakingProcess=4; //4
writeTP(waitTrakingProcess,4);
}
else{
// Read n bytes from rx fifo
cc112xSpiReadRxFifo(rxBuffer, rxBytes);
waitTrakingProcess=5; //5
writeTP(waitTrakingProcess,5);
// Check CRC ok (CRC_OK: bit7 in second status byte).This assumes status bytes are appended in RX_FIFO (PKT_CFG1.APPEND_STATUS = 1.) If CRC is disabled the CRC_OK field will read 1
if(rxBuffer[rxBytes-1] & 0x80){
// Launch and Root Type bytes is checked by this section
if( (rxBuffer[1] == LAUNCH) && (rxBuffer[2] == ROOT_TYPE) &&(rxBuffer[3] == 0x12) ){
Network.BeaconWasTaken = 1;
control = 0;
waitTrakingProcess=6;
writeTP(waitTrakingProcess,6);
}
}
}
}
packetSemaphore = ISR_IDLE;
}
count ++;
}
enterRxSleep();
// Put radio to sleep and exit application
//trxSpiCmdStrobe(CC112X_SPWD);
//Delay10msx(5);
waitTrakingProcess = 11; //9
writeTP(waitTrakingProcess,4);
if(Network.InDataProgress){
Network.InDataProgress = 0;
trxSpiCmdStrobe(CC112X_SFRX);
Delay10msx(5);
}
//***************** THIS FUNCTION IS STUCK HERE AND DOESN'T COME BACK WHERE IT CAME FROM *************************//
//***************** We are seeing 11 value on lcd of process part ****************************//
return;
}
#include "io430fr6972.h"
#include "pins_6972.h"
#include <in430.h>
#include "lcd_funcs.h"
#include "mcu_spi_rf.h"
#include "cc1120_spi.h"
#include "stdlib.h"
#include "gpio_int_rf.h"
#include "register_config.h"
#include "delays.h"
#include "1120_rxtx.h"
#include "ext_vars.h"
#include "string_funcs.h"
#include "defines.h"
#include "G1206_COG_LCD.h"
#include "string.h"
#include "uart.h"
#include "chip_detect.h"
#include "math.h"
static uint8 packetSemaphore;
/*******************************************************************************
* @fn initRfSpi
*
* @brief Radio - Spi aray�z�n� kur
*
* @param none
*
* @return none
*/
void initRfSpi(void) {
trxRfSpiInterfaceInit();
/* Enable global interrupt */
_BIS_SR(GIE);
}
/*******************************************************************************
* @fn registerConfig
*
* @brief Transmitter&Receiver'da ortak olan register ayarlar�
*
* @param none
*
* @return none
*/
void registerConfig(void) {
uint8 writeByte;
/* Reset radio */
trxSpiCmdStrobe(CC112X_SRES);
/* Write registers to radio */
for(uint16 i = 0;
i < (sizeof(preferredSettings)/sizeof(registerSetting_t)); i++) {
writeByte = preferredSettings[i].data;
cc112xSpiWriteReg(preferredSettings[i].addr, &writeByte, 1);
}
}
/*******************************************************************************
* @fn radioTxRXISR
*
* @brief ISR for packet handling in TX and RX. Sets packet semaphore
* and clears ISR flag
*
* @param none
*
* @return none
*/
void radioRxTxISR(uint8 gpioPin) {
// Set packet semaphore
packetSemaphore = ISR_ACTION_REQUIRED;
// Clear ISR flag
ioPinIntClear(gpioPin);
}
static void accessRxIdle(void)
{
/* Disable pin interrupt */
ioPinIntDisable(GPIOPIN2);
/* Strobe IDLE */
trxSpiCmdStrobe(CC112X_SIDLE);
/* Wait until chip is in IDLE */
while(trxSpiCmdStrobe(CC112X_SNOP) & 0xF0);
trxSpiCmdStrobe(CC112X_SFRX);
/* Clear pin interrupt flag */
ioPinIntClear(GPIOPIN2);
return;
}
void enterRxSleep(void)
{
accessRxIdle();
Delay10msx(50);
trxSpiCmdStrobe(CC112X_SPWD);
Delay10msx(50);
/* Only important to differ between RX/TX and IDLE */
return;
}
/*******************************************************************************
* @fn manualCalibration
*
* @brief radio calibration
*
* @param none
*
* @return none
*/
#define VCDAC_START_OFFSET 2
#define FS_VCO2_INDEX 0
#define FS_VCO4_INDEX 1
#define FS_CHP_INDEX 2
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);
}
}
//----------------------------------------------------------------------------------
// uint8 Read8BitRssi(void)
//
// DESCRIPTION:
// Measure signal quality
//
// ARGUMENTS:
// None
//----------------------------------------------------------------------------------
uint8 Read8BitRssi(void){
uint8 rssi2compl,rssiValid;
uint8 rssiOffset = 102;
int8 rssiConverted;
//Read RSSI_VALID from RSSI0
cc112xSpiReadReg(CC112X_RSSI0, &rssiValid, 1);
// Check if the RSSI_VALID flag is set
if(rssiValid & 0x01){
// Read RSSI from MSB register
cc112xSpiReadReg(CC112X_RSSI1, &rssi2compl, 1);
rssiConverted = (int8)rssi2compl - rssiOffset;
return rssiConverted;
}
// return 0 since new value is not valid
return 0;
}
/* ------------------------------------------------------------------------------------------------
* Init Radio
* ------------------------------------------------------------------------------------------------
*/
void initRadio(void){
/* Spi communication is built */
initRfSpi();
/* Default registers are adjusted for starting*/
registerConfig();
}
void setFundamentals(void)
{
// Connect ISR function to GPIO0, interrupt on falling edge //P4.4 GPIO2
ioPinIntRegister(&radioRxTxISR,GPIOPIN2);
// Interrupt on falling edge
ioPinIntTypeSet(IO_PIN_FALLING_EDGE,GPIOPIN2);
// Clear ISR flag
//ioPinIntClear(GPIOPIN2);
// Enable interrupt form GPIO
ioPinIntEnable(GPIOPIN2);
// Calibrate radio according to errata
manualCalibration();
}
bool waitRXStatus(void){
uint8 temp;
temp = 0x00;
temp = cc112xGetTxStatus();
if((temp >> 4) & 1)
return true;
else
return false;
}
/*******************************************************************************
* @fn rx_registers
*
* @brief Receiver register. Ref: 1120 User Guide
*
* @param none
*
* @return none
*/
static void rx_client_registers(void) {
uint8 writeByte;
registerConfig();
//RX Gain
writeByte = 0x04; cc112xSpiWriteReg(CC112X_CHAN_BW, &writeByte, 1); //RX filter bandwidth 200kHz
writeByte = 0x11; cc112xSpiWriteReg(CC112X_AGC_CFG3, &writeByte, 1); //adjust min gain
writeByte = 0x20; cc112xSpiWriteReg(CC112X_AGC_CFG2, &writeByte, 1); //0x20-->max gain 0xA0-->previous gain
writeByte = 0x19; cc112xSpiWriteReg(CC112X_AGC_REF, &writeByte, 1); //0x19
//TX Power
writeByte = 0x7F; cc112xSpiWriteReg(CC112X_PA_CFG2, &writeByte, 1);
writeByte = 0x56; cc112xSpiWriteReg(CC112X_PA_CFG1, &writeByte, 1);
writeByte = 0x7C; cc112xSpiWriteReg(CC112X_PA_CFG0, &writeByte, 1);
// LBT
writeByte = 0x10; cc112xSpiWriteReg(CC112X_PKT_CFG2, &writeByte, 1); //Indicates clear channel when RSSI is below threshold and ETSI LBT requirements are met
}
/*******************************************************************************
* @fn tx_registers
*
* @brief Transmitter register. Ref: 1120 User Guide
*
* @param none
*
* @return none
*/
static void tx_registers(void) {
uint8 writeByte;
registerConfig();
//RX Gain
writeByte = 0x04; cc112xSpiWriteReg(CC112X_CHAN_BW, &writeByte, 1);
writeByte = 0x11; cc112xSpiWriteReg(CC112X_AGC_CFG3, &writeByte, 1);
writeByte = 0x20; cc112xSpiWriteReg(CC112X_AGC_CFG2, &writeByte, 1);
writeByte = 0x19; cc112xSpiWriteReg(CC112X_AGC_REF, &writeByte, 1);
//TX Power
writeByte = 0x7F; cc112xSpiWriteReg(CC112X_PA_CFG2, &writeByte, 1);
writeByte = 0x56; cc112xSpiWriteReg(CC112X_PA_CFG1, &writeByte, 1);
writeByte = 0x7C; cc112xSpiWriteReg(CC112X_PA_CFG0, &writeByte, 1);
}
//----------------------------------------------------------------------------------
// static void createBeacon(uint8 *tempBuffer)
//
// DESCRIPTION:
// Creating launched packet the to start the netwok installation
//
// ARGUMENTS:
// uint8 *tempBuffer - Pointer to the beacon packet byte table
//----------------------------------------------------------------------------------
static void createBeacon(uint8 *tempBuffer){
tempBuffer[0] = BEACON_PKTLEN; // 9
tempBuffer[1] = LAUNCH; // 'N'
tempBuffer[2] = ROOT_TYPE; // 'R'
tempBuffer[3] = 0x12;
// Fill with random bytes rest of the buffer
for(uint8 i=4; i<(BEACON_PKTLEN+1); i++){
tempBuffer[i] = 0x00;
}
}
//----------------------------------------------------------------------------------
// void sendBeacon(void)
//
// DESCRIPTION:
// Send beacon info to client
//
// ARGUMENTS:
// None
//----------------------------------------------------------------------------------
void sendBeacon(void){
// Buffer was defined
uint8 txBuffer[BEACON_PKTLEN+1] = {0};
volatile uint8 count = 0;
uint8 txFirstByte;
uint8 txLastByte;
lcdClr();
write5x7_const(10,4,"Send Beacon");
//Delay10msx(20);
do{
count ++;
// Transceiver is set for transmit
tx_registers();
// Set fundamentals register and interrupy
setFundamentals();
// Launched Beacon Is Created
createBeacon(txBuffer);
cc112xSpiReadReg(CC112X_TXFIRST, &txFirstByte, 1);
cc112xSpiReadReg(CC112X_TXLAST, &txLastByte, 1);
writeByteRange(txFirstByte,txLastByte,3);
// Write packet to tx fifo
cc112xSpiWriteTxFifo(txBuffer,sizeof(txBuffer));
// Strobe TX to send packet
trxSpiCmdStrobe(CC112X_STX);
writeTP(sizeof(txBuffer),2);
// Wait for interrupt that packet has been sent.
// (Assumes the GPIO connected to the radioRxTxISR function is set
// to GPIOx_CFG = 0x06)
while(!packetSemaphore) {
uint8 readByte;
//Read datarate from registers
cc112xSpiReadReg(CC112X_MARCSTATE, &readByte, 1);
if(readByte);
};
// Clear semaphore flag
packetSemaphore = ISR_IDLE;
}while(count < 1);
// Put radio to sleep and exit application
trxSpiCmdStrobe(CC112X_SPWD);
Delay10msx(5);
}
//----------------------------------------------------------------------------------
// uint8 waitBeacon(void)
//
// DESCRIPTION:
// Waiting beacon to start conversation with own root.
//
// ARGUMENTS:
// None
//----------------------------------------------------------------------------------
void waitBeacon(void){
uint8 rxBuffer[RX_PKTLEN] = {0}; // RX_PKTLEN = 100;
uint8 rxBytes;
uint8 marcStatus;
uint8 control;
bool rx_process_status;
uint8 rxFirstByte;
uint8 rxLastByte;
uint8 txFirstByte;
uint8 txLastByte;
rx_process_status = false;
control = 1;
volatile uint32 count = 0;
// Setting register to receive
rx_client_registers();
waitTrakingProcess=0; //0
writeTP(waitTrakingProcess,0);
// Set fundamentals register and interrupy
setFundamentals();
waitTrakingProcess=1; //1
writeTP(waitTrakingProcess,1);
// Set radio in RX
trxSpiCmdStrobe(CC112X_SRX);
Delay10msx(5);
rx_process_status = waitRXStatus();
if(rx_process_status)
TEST_LED_ON;
waitTrakingProcess=2; //2
writeTP(waitTrakingProcess,2);
cc112xSpiReadReg(CC112X_RXFIRST, &rxFirstByte, 1);
cc112xSpiReadReg(CC112X_RXLAST, &rxLastByte, 1);
writeByteRange(rxFirstByte,rxLastByte,3);
cc112xSpiReadReg(CC112X_TXFIRST, &txFirstByte, 1);
cc112xSpiReadReg(CC112X_TXLAST, &txLastByte, 1);
writeByteRange(txFirstByte,txLastByte,4);
// Loop untill any meaningful is received or completed timeout
while(control){
if(count > 300000){
control = 0;
}
// Wait for packet received interrupt
if((packetSemaphore == ISR_ACTION_REQUIRED) && (rx_process_status == true) ){
// Read number of bytes in rx fifo
cc112xSpiReadReg(CC112X_NUM_RXBYTES, &rxBytes, 1);
waitTrakingProcess=3; //3
writeTP(rxBytes,3);
// Check that we have bytes in fifo
if(rxBytes != 0){
// Read marcstate to check for RX FIFO error
cc112xSpiReadReg(CC112X_MARCSTATE, &marcStatus, 1);
// Mask out marcstate bits and check if we have a RX FIFO error
if((marcStatus & 0x1F) == RX_FIFO_ERROR){
// Flush RX Fifo
trxSpiCmdStrobe(CC112X_SFRX);
Delay10msx(5);
control = 0;
waitTrakingProcess=4; //4
writeTP(waitTrakingProcess,4);
}
else{
// Read n bytes from rx fifo
cc112xSpiReadRxFifo(rxBuffer, rxBytes);
waitTrakingProcess=5; //5
writeTP(waitTrakingProcess,5);
// Check CRC ok (CRC_OK: bit7 in second status byte).This assumes status bytes are appended in RX_FIFO (PKT_CFG1.APPEND_STATUS = 1.) If CRC is disabled the CRC_OK field will read 1
if(rxBuffer[rxBytes-1] & 0x80){
// Launch and Root Type bytes is checked by this section
if( (rxBuffer[1] == LAUNCH) && (rxBuffer[2] == ROOT_TYPE) &&(rxBuffer[3] == 0x12) ){
Network.BeaconWasTaken = 1;
control = 0;
waitTrakingProcess=6;
writeTP(waitTrakingProcess,6);
}
}
}
}
packetSemaphore = ISR_IDLE;
}
count ++;
}
enterRxSleep();
// Put radio to sleep and exit application
//trxSpiCmdStrobe(CC112X_SPWD);
//Delay10msx(5);
waitTrakingProcess = 11; //9
writeTP(waitTrakingProcess,4);
if(Network.InDataProgress){
Network.InDataProgress = 0;
trxSpiCmdStrobe(CC112X_SFRX);
Delay10msx(5);
}
//***************** THIS FUNCTION IS STUCK HERE AND DOESN'T COME BACK WHERE IT CAME FROM *************************//
//***************** We are seeing 11 value on lcd of process part ****************************//
return;
}
uint8 networkConfig() {
uint8 maincontrol = 1;
enableRF();
initRadio();
if(Network.NextProcess == TXPROCESS)
Delay1s();
while(maincontrol){
if(Network.DeviceType == ACCESS_POINT){
if(processPart == 0){
sendBeacon();
rfTxCount++;
goto endOfProcess;
}
}
else if(Network.DeviceType == CLIENT){
if(processPart == 0){
waitBeacon();
if(Network.BeaconWasTaken){
rfRxCount++;
Network.BeaconWasTaken = 0;
}
goto endOfProcess;
}
}
endOfProcess:
waitTrakingProcess = 12; //9
writeTP(waitTrakingProcess,5);
maincontrol = 0;
}
disableRF();
return 0x02;
}