Part Number:CC1310
Tool/software:TI-RTOS
Hello,
We have designed custom devices for digital signal transfer. Transmitter device sends input values every 50ms and receiver process the data and outputs the transmitter signal values. Devices use address filter for not mixturing any data. If one transmitter sends the data to the receiver, everything works well.
But, 2 transmitters send the data packet at the same time, receivers confuse. Receivers cannot process the data and it behaves unstable.
For clear declaration;
TransmitterDevice-1=ON - address filter=0x04, ReceiverDevice-1=ON - address filter=0x04, TransmitterDevice-2=OFF - address filter=0x05, ReceiverDevice-2=OFF - address filter=0x05 >>> WORKS NORMALLY
TransmitterDevice-1=ON - address filter=0x04, ReceiverDevice-1=ON - address filter=0x04, TransmitterDevice-2=OFF - address filter=0x05, ReceiverDevice-2=ON - address filter=0x05 >>> WORKS NORMALLY
TransmitterDevice-1=OFF - address filter=0x04, ReceiverDevice-1=OFF - address filter=0x04, TransmitterDevice-2=ON - address filter=0x05, ReceiverDevice-2=ON - address filter=0x05 >>> WORKS NORMALLY
TransmitterDevice-1=OFF - address filter=0x04, ReceiverDevice-1=ON - address filter=0x04, TransmitterDevice-2=ON - address filter=0x05, ReceiverDevice-2=ON - address filter=0x05 >>> WORKS NORMALLY
TransmitterDevice-1=ON - address filter=0x04, ReceiverDevice-1=ON - address filter=0x04, TransmitterDevice-2=ON - address filter=0x05, ReceiverDevice-2=ON - address filter=0x05 >>> UNSTABLE, NOT WORKING, RECEIVER LEDS CUT OFF
In unstable condition (2 devices powered on at the same time and their transmit times are equal), I power off one transmitter and power on back it again, it works (time difference between transmitters).
TRANSMITTER PROGRAM:
/* * ======== rfEasyLinkTx.c ======== */ /* XDCtools Header files */ #include <stdlib.h> #include <xdc/std.h> #include <xdc/runtime/System.h> #include <xdc/runtime/Error.h> /* BIOS Header files */ #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #include <ti/sysbios/knl/Semaphore.h> #include <ti/sysbios/knl/Clock.h> /* TI-RTOS Header files */ #include <ti/drivers/PIN.h> /* Board Header files */ #include "Board.h" /* EasyLink API Header files */ #include "easylink/EasyLink.h" /* Undefine to not use async mode */ #define RFEASYLINKTX_ASYNC #define RFEASYLINKTX_TASK_STACK_SIZE 1024 #define RFEASYLINKTX_TASK_PRIORITY 2 #define RFEASYLINKTX_BURST_SIZE 10 #define RFEASYLINKTXPAYLOAD_LENGTH 30 Task_Struct txTask; /* not static so you can see in ROV */ static Task_Params txTaskParams; static uint8_t txTaskStack[RFEASYLINKTX_TASK_STACK_SIZE]; #define STATUS1 IOID_1 #define STATUS2 IOID_2 #define DIN8 IOID_8 #define DIN7 IOID_9 #define DIN6 IOID_10 #define DIN5 IOID_11 #define DIN4 IOID_12 #define DIN3 IOID_13 #define DIN2 IOID_14 #define DIN1 IOID_15 /* Pin driver handle */ static PIN_Handle pinHandle; static PIN_State pinState; /* * Application LED pin configuration table: * - All LEDs board LEDs are off. */ PIN_Config pinTable[] = { STATUS1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, STATUS2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, DIN1 | PIN_INPUT_EN | PIN_PULLUP, DIN2 | PIN_INPUT_EN | PIN_PULLUP, DIN3 | PIN_INPUT_EN | PIN_PULLUP, DIN4 | PIN_INPUT_EN | PIN_PULLUP, DIN5 | PIN_INPUT_EN | PIN_PULLUP, DIN6 | PIN_INPUT_EN | PIN_PULLUP, DIN7 | PIN_INPUT_EN | PIN_PULLUP, DIN8 | PIN_INPUT_EN | PIN_PULLUP, PIN_TERMINATE }; static uint16_t seqNumber; #ifdef RFEASYLINKTX_ASYNC static Semaphore_Handle txDoneSem; #endif //RFEASYLINKTX_ASYNC #ifdef RFEASYLINKTX_ASYNC void txDoneCb(EasyLink_Status status) { if (PIN_getOutputValue(STATUS2)==0) { PIN_setOutputValue(pinHandle, STATUS2, 1); //PIN_setOutputValue(ledPinHandle, STATUS2, 0); }else{ PIN_setOutputValue(pinHandle, STATUS2, 0); //PIN_setOutputValue(ledPinHandle, STATUS2, 1); } Semaphore_post(txDoneSem); } #endif //RFEASYLINKTX_ASYNC static void rfEasyLinkTxFnx(UArg arg0, UArg arg1) { uint8_t txBurstSize = 0; #ifdef RFEASYLINKTX_ASYNC /* Create a semaphore for Async */ Semaphore_Params params; Error_Block eb; /* Init params */ Semaphore_Params_init(¶ms); Error_init(&eb); /* Create semaphore instance */ txDoneSem = Semaphore_create(0, ¶ms, &eb); #endif //TX_ASYNC EasyLink_init(EasyLink_Phy_Custom); EasyLink_setFrequency(424700000); //433mhz operation //EasyLink_setFrequency(868000000); /* * If you wish to use a frequency other than the default, use * the following API: * EasyLink_setFrequency(868000000); */ /* Set output power to 12dBm */ EasyLink_setRfPwr(14); while(1) { EasyLink_TxPacket txPacket = { {0}, 0, 0, {0} }; //txPacket.payload[0] = (uint8_t)(seqNumber >> 8); //txPacket.payload[1] = (uint8_t)(seqNumber++); txPacket.len = RFEASYLINKTXPAYLOAD_LENGTH; txPacket.dstAddr[0] = 0x04; //1 uint8_t i, sendPacketTrigger = 0; if (PIN_getInputValue(DIN1)==0) { txPacket.payload[0] = 0x01; } else{ txPacket.payload[0] = 0x00; } if (PIN_getInputValue(DIN2)==0) { txPacket.payload[1] = 0x01; } else{ txPacket.payload[1] = 0x00; } if (PIN_getInputValue(DIN3)==0) { txPacket.payload[2] = 0x01; } else{ txPacket.payload[2] = 0x00; } if (PIN_getInputValue(DIN4)==0) { txPacket.payload[3] = 0x01; } else{ txPacket.payload[3] = 0x00; } if (PIN_getInputValue(DIN5)==0) { txPacket.payload[4] = 0x01; } else{ txPacket.payload[4] = 0x00; } if (PIN_getInputValue(DIN6)==0) { txPacket.payload[5] = 0x01; } else{ txPacket.payload[5] = 0x00; } if (PIN_getInputValue(DIN7)==0) { txPacket.payload[6] = 0x01; } else{ txPacket.payload[6] = 0x00; } if (PIN_getInputValue(DIN8)==0) { txPacket.payload[7] = 0x01; } else{ txPacket.payload[7] = 0x00; } if (PIN_getOutputValue(STATUS1)==0) { PIN_setOutputValue(pinHandle, STATUS1, 1); //PIN_setOutputValue(ledPinHandle, STATUS2, 0); }else{ PIN_setOutputValue(pinHandle, STATUS1, 0); //PIN_setOutputValue(ledPinHandle, STATUS2, 1); } txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(80); EasyLink_transmitAsync(&txPacket, txDoneCb); // Wait 300ms for Tx to complete if(Semaphore_pend(txDoneSem, (300000 / Clock_tickPeriod)) == FALSE) { // TX timed out, abort if(EasyLink_abort() == EasyLink_Status_Success) { Semaphore_pend(txDoneSem, BIOS_WAIT_FOREVER); } } } } void txTask_init(PIN_Handle inPinHandle) { pinHandle = inPinHandle; Task_Params_init(&txTaskParams); txTaskParams.stackSize = RFEASYLINKTX_TASK_STACK_SIZE; txTaskParams.priority = RFEASYLINKTX_TASK_PRIORITY; txTaskParams.stack = &txTaskStack; txTaskParams.arg0 = (UInt)1000000; Task_construct(&txTask, rfEasyLinkTxFnx, &txTaskParams, NULL); } /* * ======== main ======== */ int main(void) { /* Call driver init functions. */ Board_initGeneral(); /* Open LED pins */ pinHandle = PIN_open(&pinState, pinTable); if(!pinHandle) { System_abort("Error initializing board LED pins\n"); } /* Clear LED pins */ PIN_setOutputValue(pinHandle, STATUS1, 0); PIN_setOutputValue(pinHandle, STATUS2, 0); txTask_init(pinHandle); /* Start BIOS */ BIOS_start(); return (0); }
RECEIVER PROGRAM:
/* * ======== rfEasyLinkRx.c ======== */ /* XDCtools Header files */ #include <xdc/std.h> #include <xdc/runtime/System.h> #include <xdc/runtime/Error.h> /* BIOS Header files */ #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #include <ti/sysbios/knl/Semaphore.h> #include <ti/sysbios/knl/Clock.h> /* TI-RTOS Header files */ #include <ti/drivers/PIN.h> /* Board Header files */ #include "Board.h" /* EasyLink API Header files */ #include "easylink/EasyLink.h" /***** Defines *****/ /* Undefine to remove address filter and async mode */ #define RFEASYLINKRX_ASYNC #define RFEASYLINKRX_ADDR_FILTER #define RFEASYLINKEX_TASK_STACK_SIZE 1024 #define RFEASYLINKEX_TASK_PRIORITY 2 #define STATUS1 IOID_1 #define STATUS2 IOID_2 #define DOUT1 IOID_8 #define DOUT2 IOID_9 #define DOUT3 IOID_10 #define DOUT4 IOID_11 #define DOUT5 IOID_12 #define DOUT6 IOID_13 #define DOUT7 IOID_14 #define DOUT8 IOID_15 /* Pin driver handle */ static PIN_Handle ledPinHandle; static PIN_State ledPinState; /* * Application LED pin configuration table: * - All LEDs board LEDs are off. */ PIN_Config pinTable[] = { //Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, //Board_PIN_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, STATUS1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, STATUS2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, DOUT1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX, DOUT2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX, DOUT3 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX, DOUT4 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX, DOUT5 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX, DOUT6 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX, DOUT7 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX, DOUT8 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX, PIN_TERMINATE }; /***** Variable declarations *****/ static Task_Params rxTaskParams; Task_Struct rxTask; /* not static so you can see in ROV */ static uint8_t rxTaskStack[RFEASYLINKEX_TASK_STACK_SIZE]; /* The RX Output struct contains statistics about the RX operation of the radio */ PIN_Handle pinHandle; #ifdef RFEASYLINKRX_ASYNC static Semaphore_Handle rxDoneSem; #endif /***** Function definitions *****/ #ifdef RFEASYLINKRX_ASYNC void rxDoneCb(EasyLink_RxPacket * rxPacket, EasyLink_Status status) { if(status == EasyLink_Status_Success && rxPacket->payload[0]==0x01) { PIN_setOutputValue(ledPinHandle, DOUT1, 0); } else{ PIN_setOutputValue(ledPinHandle, DOUT1, 1); } if(status == EasyLink_Status_Success && rxPacket->payload[1]==0x01) { PIN_setOutputValue(ledPinHandle, DOUT2, 0); } else{ PIN_setOutputValue(ledPinHandle, DOUT2, 1); } if(status == EasyLink_Status_Success && rxPacket->payload[2]==0x01) { PIN_setOutputValue(ledPinHandle, DOUT3, 0); } else{ PIN_setOutputValue(ledPinHandle, DOUT3, 1); } if(status == EasyLink_Status_Success && rxPacket->payload[3]==0x01) { PIN_setOutputValue(ledPinHandle, DOUT4, 0); } else{ PIN_setOutputValue(ledPinHandle, DOUT4, 1); } if(status == EasyLink_Status_Success && rxPacket->payload[4]==0x01) { PIN_setOutputValue(ledPinHandle, DOUT5, 0); } else{ PIN_setOutputValue(ledPinHandle, DOUT5, 1); } if(status == EasyLink_Status_Success && rxPacket->payload[5]==0x01) { PIN_setOutputValue(ledPinHandle, DOUT6, 0); } else{ PIN_setOutputValue(ledPinHandle, DOUT6, 1); } if(status == EasyLink_Status_Success && rxPacket->payload[6]==0x01) { PIN_setOutputValue(ledPinHandle, DOUT7, 0); } else{ PIN_setOutputValue(ledPinHandle, DOUT7, 1); } if(status == EasyLink_Status_Success && rxPacket->payload[7]==0x01) { PIN_setOutputValue(ledPinHandle, DOUT8, 0); } else{ PIN_setOutputValue(ledPinHandle, DOUT8, 1); } if(status == EasyLink_Status_Success){ PIN_setOutputValue(pinHandle, STATUS2,!PIN_getOutputValue(STATUS2)); }else{ PIN_setOutputValue(pinHandle, STATUS2, 0); } Semaphore_post(rxDoneSem); } #endif static void rfEasyLinkRxFnx(UArg arg0, UArg arg1) { #ifndef RFEASYLINKRX_ASYNC EasyLink_RxPacket rxPacket = {0}; #endif #ifdef RFEASYLINKRX_ASYNC /* Create a semaphore for Async*/ Semaphore_Params params; Error_Block eb; /* Init params */ Semaphore_Params_init(¶ms); Error_init(&eb); /* Create semaphore instance */ rxDoneSem = Semaphore_create(0, ¶ms, &eb); #endif //RFEASYLINKRX_ASYNC EasyLink_init(EasyLink_Phy_Custom); //EasyLink_init(EasyLink_Phy_5kbpsSlLr); EasyLink_setFrequency(424700000); //433mhz operation //EasyLink_setFrequency(868000000); /* * If you wish to use a frequency other than the default, use * the following API: * EasyLink_setFrequency(868000000); */ //#ifdef RFEASYLINKRX_ADDR_FILTER uint8_t addrFilter = 0x05; EasyLink_enableRxAddrFilter(&addrFilter, 1, 1); //#endif //RFEASYLINKRX_ADDR_FILTER while(1) { #ifdef RFEASYLINKRX_ASYNC EasyLink_Status result = EasyLink_receiveAsync(rxDoneCb, 0); /* Wait 300ms for Rx */ if(Semaphore_pend(rxDoneSem, (900000 / Clock_tickPeriod)) == FALSE) { /* RX timed out abort */ if(EasyLink_abort() == EasyLink_Status_Success) { /* Wait for the abort */ Semaphore_pend(rxDoneSem, BIOS_WAIT_FOREVER); } } //if (result == EasyLink_Status_Success){ if (PIN_getOutputValue(STATUS1)==0) { PIN_setOutputValue(ledPinHandle, STATUS1, 1); //PIN_setOutputValue(ledPinHandle, STATUS2, 0); }else{ PIN_setOutputValue(ledPinHandle, STATUS1, 0); //PIN_setOutputValue(ledPinHandle, STATUS2, 1); } //} //PIN_setOutputValue(pinHandle, STATUS2,!PIN_getOutputValue(STATUS2)); #else rxPacket.absTime = 0; EasyLink_Status result = EasyLink_receive(&rxPacket); if (result == EasyLink_Status_Success) { /* Toggle LED2 to indicate RX */ PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2)); } else { /* Toggle LED1 and LED2 to indicate error */ PIN_setOutputValue(pinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1)); PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2)); } #endif //RX_ASYNC } } void rxTask_init(PIN_Handle ledPinHandle) { pinHandle = ledPinHandle; Task_Params_init(&rxTaskParams); rxTaskParams.stackSize = RFEASYLINKEX_TASK_STACK_SIZE; rxTaskParams.priority = RFEASYLINKEX_TASK_PRIORITY; rxTaskParams.stack = &rxTaskStack; rxTaskParams.arg0 = (UInt)1000000; Task_construct(&rxTask, rfEasyLinkRxFnx, &rxTaskParams, NULL); } /* * ======== main ======== */ int main(void) { /* Call driver init functions */ Board_initGeneral(); /* Open LED pins */ ledPinHandle = PIN_open(&ledPinState, pinTable); if(!ledPinHandle) { System_abort("Error initializing board LED pins\n"); } /* Clear LED pins */ PIN_setOutputValue(ledPinHandle, STATUS1, 0); PIN_setOutputValue(ledPinHandle, STATUS2, 0); rxTask_init(ledPinHandle); /* Start BIOS */ BIOS_start(); return (0); }
Looking forward for your advices.
Best regards,
Onur