This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC1310 RAT Timer issue after several hours

Other Parts Discussed in Thread: CC1310

Hi all,

I've a very strange problem with CC1310, I'm using the latest RTOS 2.21, compiled with no code optimization, the problem is the following:

My device remains in Task.sleep for 9,5 seconds, after this I start a Radio RX with callback using endtrigger ABS_TIME with a value of 500 ms (calculed by macro ms to radio tick), and I pend for a semaphore into main. This semaphore will released by the callback on Event_Last_Command raised.

Before and after Radio RX operation, I print out on serial port an information, by my serial monitor I can see the time, and all works correctly, I mean that between the two serial print, I can see a difference of 500ms, all right.

The target of this code is to check , during the 500ms window, if someone is transmitting packets, if so the code goes on, if not, the loop restart (the device return to wait for 9,5 seconds etc etc...)

After several hours of job, where my device found packets, do others jobs etc, it stops to work, in the sense that it can't found packets, without a apparent reason.

Checking serial logs, I noticed that the interval between the two serial prints It is not more than 500 ms but varies continuously with smaller values like 60 ms, 200 ms, 484 ms, 17 ms etc, so the RX window became to small to RX packets, it is as if the RAT timer go crazy.

If I power off and on the device, all return to work properly. I'm using ABS_TIME on end trigger, setting RF_GetCurrentTime + ms_to_radio_tick(500ms) as value.

I set always this same value. The IC revision is the 2.0

Riccardo

  • Hi all,

    some news about the problem: I added more printout on serial, including the difference between RAT Timer after and before the RX operation, obtained by RF_GetCurrentTime() function. When all work, the printout give me a value of 500000 us, while when the problem starts, the returned values vary continuously. The impression is that the radio ends RX operation before the given time without a reason, i printout the event value returned inside the callback, and its value is always 2, working right or not (2 is the value for Event_LastCommand by RF_Event enum).
    Now I would try to put the radio end trigger to TRIG_NEVER, and use the Task.sleep to wait the 500ms and cancel the RX operation using the RF_cancel command to kill the current RX operation , in this way I'll use the main core timer to wait the 500ms and not the radio timer and I'll hope to resolve the problem. It may be occurring a radio operation issue after several hours of job or any pending command? How can I verify the status of the radio when the problem appeare ?

    Riccardo
  • Hi Riccardo,

    thanks for the detailed error report. There is nothing wrong in your description, so it might be a bug. After command completion, there are two possibilities to check:

    • The return value of RF_runCmd()
    • The status field of the command itself

    The return value of RF_runCmd() is an event mask where RF_EventCmdDone, RF_EventLastCmdDone should be set if the command ended. If you abort the command, then you will see RF_EventCmdAborted  as well.

    CMD_PROP_RX can have several status codes, defined in <driverlib/rf_prop_mailbox.h>. The expected status after completion would be PROP_DONE_OK.

    Could you also please show the code where you set up the end trigger and the configuration of the whole RX command? There might be the possibility that you forgot to configure:

    RF_cmdPropRx.pktConf.bRepeatOk = 1;
    RF_cmdPropRx.pktConf.bRepeatNok = 1;

    Thanks

  • Hi Richard,
    RF_cmdPropRx.pktConf.bRepeatOk and RF_cmdPropRx.pktConf.bRepeatNok are set to 1 correctly in that for hours all work right. When all work, during the 500ms window I can get more than one packet without problem, instead during the problem I can't receive nothing.
    I'm running radio RX using RF_postCmd, not RF_runCmd, and it return me valid command handle (> -1). Where are defined the possible status values for the RX_Prop.status variable ?
    It could be very usefull to know the status of the radio operation (this thing is not present into the vary examples). Actually I'm trying to use the task.sleep function to execute the wait window, and the RF_postCmd with a end trigger set to TRIG_NEVER, after the wait window, i'll terminate the radio RX by RF_cancel() and RF_pending(), but I think that the original solution with end trigger ABS_TIME and semaphore released by callback is more elegant.

    p.s. sometimes, the problem appear after 6 days, sometimes after 12 hour....very difficulty to debug (thanks to the serial interface, it will never die:) )

    Riccardo
  • Hi,

    the status codes are defined in <driverlib/rf_prop_mailbox.h>

    #define PROP_DONE_OK            0x3400  ///< Operation ended normally
    #define PROP_DONE_RXTIMEOUT     0x3401  ///< Operation stopped after end trigger while waiting for sync
    #define PROP_DONE_BREAK         0x3402  ///< Rx stopped due to timeout in the middle of a packet
    #define PROP_DONE_ENDED         0x3403  ///< Operation stopped after end trigger during reception
    #define PROP_DONE_STOPPED       0x3404  ///< Operation stopped after stop command
    #define PROP_DONE_ABORT         0x3405  ///< Operation aborted by abort command
    #define PROP_DONE_RXERR         0x3406  ///< Operation ended after receiving packet with CRC error
    #define PROP_DONE_IDLE          0x3407  ///< Carrier sense operation ended because of idle channel
    #define PROP_DONE_BUSY          0x3408  ///< Carrier sense operation ended because of busy channel
    #define PROP_DONE_IDLETIMEOUT   0x3409  ///< Carrier sense operation ended because of timeout with csConf.timeoutRes = 1
    #define PROP_DONE_BUSYTIMEOUT   0x340A  ///< Carrier sense operation ended because of timeout with csConf.timeoutRes = 0
    
    ///@}
    /// \name Operation finished with error
    ///@{
    #define PROP_ERROR_PAR          0x3800  ///< Illegal parameter
    #define PROP_ERROR_RXBUF        0x3801  ///< No available Rx buffer at the start of a packet
    #define PROP_ERROR_RXFULL       0x3802  ///< Out of Rx buffer during reception in a partial read buffer
    #define PROP_ERROR_NO_SETUP     0x3803  ///< Radio was not set up in proprietary mode
    #define PROP_ERROR_NO_FS        0x3804  ///< Synth was not programmed when running Rx or Tx
    #define PROP_ERROR_RXOVF        0x3805  ///< Rx overflow observed during operation
    #define PROP_ERROR_TXUNF        0x3806  ///< Tx underflow observed during operation

    We have to investigate on that. But to solve your problem: Why aren't you using a relative end trigger?

  • Hi Richard,

    I used ABS_TIME 'cause I saw it inside TI examples, however, into the docs folder file:///C:/ti/tirtos_cc13xx_cc26xx_2_21_00_06/products/tidrivers_cc13xx_cc26xx_2_21_00_04/docs/doxygen/html/_r_f_8h.html#a2b0ee444fcb74917df94eefea804ecbb, notes about RF_postCmd() report this:

    • Only some of the trigger modes are supported
      • TRIG_NOW, TRIG_ABSTIME

    Is this information wrong ?

    I'd like to use Relative Trigger, more elegant and simple respect do RF_GetCurrentTime() + time_to_wait_radio_ticks, but I'm afraid to use RAT Timer....

  • Hi all,

    some update about the issue: I tryed to bypass rat timer using task_sleep function and the problem is the same, I understand the critical point is that for some reason, the radio terminates the rx operation in wrong way , now I'm printing out the rx_prop status value and I'll can see what happen. I'm using the 2.21 rtos with an old smartrf settings file cause my IC revision is 2.0, is this correct?

    How can I check if the radio has multiple commands pending in its queue? I would not the problem can be an overflow into the radio command queue,  though I always cancel the active command before post a new one, the queue should has at the max one posted command at time.

  • Hi Riccardo,

    I find it difficult to follow your descriptions. In a previous message you asked about end triggers. RF operation commands can only have TRIG_ABSTIME and TRIG_NOW as start triggers, but they can use relative triggers as end triggers, because the start time is a time that the end trigger can relate to.

    Is the error now that your RX command ends in an unexpected way? Then please post the following information:

    1. What settings are you using for the RX command (the whole command)
    2. How do you execute the commands? Please provide some code snippets.

    Regarding your latest post:

    • There is interface to look into the RF driver queue. You would have to include the RF driver source file into your project and modify it, but I have serious doubts that this would help you.
    • Why do you think that there is an overflow in the RF command queue? Please again, post some code.
    • How old is the RF settings file? When was it created and with which SmartRF Studio version? Could you post your overrides section and which patches you use?

    In order to find errors and request help:

    • Reduce the complexity in the application code and isolate the failing code section. Very often, this helps to locate the error in the own code. I can tell based on experience that 99% of errors that I observe, were in my own code. 
    • If you want somebody else to look into it, create a minimal example project that shows the faulty behavior. Make it as simple as possible.
  • Hi Richard,

    I will try to be as clear as possible, by explaining how my project and code works:

    my project is composed by end device equipped with one CC1310, and a gateway equipped with two CC1310 plus a Raspberry. The End Device connects to the gateway to send events like push button, and receive commands like led turn on/off, and the latter transmit and receive data using the ethernet interface to a management platform.

    The End Devices code is designed to stay as long as possible in low power mode. Instead the gateway's radios are always on:the first one transmits every 300 ms advertisment packets that contain information about the gateway (I call it Hello Radio), and the second one deals to exchange messages with the End Devices (I call it Mess Radio), the two gateway's radio work on different RF channels, so, the flow chart of a End Device is the following:

    State Unlocked

    1) Stand by for 9.5 seconds

    2) Awake, set RF channel to Hello Radio, put in RX for 0.5 seconds, listening for Hello Packets from gateway.

    3) If find some Hello Packet, acquire information and try to connect to the gateway (Set RF channel to Mess Radio, send a request to the Mess Radio)

    4) if Mess radio reply OK to the request, the connection is gone right and the End Device enter in Locked State, if Mess radio reply NOK, the End Device return to point 1.

    State Locked

    1) Stand by for 2 seconds

    2) Awake, send a message to the Mess Radio to request if is there any packet for it, and stay in RX for 15 ms.

    3) If there is packet for it, do something, if not, return to point 1 (if there is not any packet, the Mess radio doesn't reply nothing to the End Device).

    4) Every 8 requests, the End Devices ping the gateway to check its presence, if for 4 times the gateway does not reply, the End Device return to Unlocked State.

    This is how the project works, the problem raise on the End Device, after several hour of normal job, it can't receive nothing (in Locked, return into Unlocked State).

    Now, the previous version of code was developed using the End Trigger of the Radio (TRIG_ABSTIME): after posted the RX command to the radio, the main loop stopped on a semaphore that was released inside the RX callback when a RF_EventLastCmdDone happened (after the End Time expired).

    Thinking the problem was on the radio timer (RAT), I rewrite the code using task_sleep function instead the End Trigger, so the code flow is this: set the radio in RX mode with End Trigger set to TRIG_NEVER, task_sleep for the required time, cancel the RX radio operation using RF_cancel() command.

    The code works for hours but at certain time, the problem appear again. As you suggest me, now I'm printing out the value of the RF_RX_Prop.status, 'cause it seams the RX Radio operation terminates for some reason different from RF_PROP_OK (Now I'm waiting the problem appear to read the status value).

    Below I attach you some code snippets, the Radio function and a piece of the main loop I wrote, keep in consideration that

    1) the RX functions, respect to the driver lib function, implements retries on errors, and return codes based on the outcome 

    2) the Cancel function as above

    3) The Tx function as above, it implements a LBT developed by me (before the official TI examples appeared on the 2.21 RTOS release).

    • rxRadioAlwaysOn (used to put the radio in RX mode forever, I use the rxCancel function to stop it)
    • rxRadioCancel() (Used to terminate a previous rxRadioAlwaysOn)
    • rxRadioPacket(RF_Callback callback, uint32_t time) (Used to set Radio in RX mode for a specific time)
    • txRadioPacket(uint8_t * dest, uint8_t * source, uint16_t messID, uint8_t * payload, uint8_t payloadLen) (Used to transmit a packet)

    char rxRadioAlwaysOn(RF_Callback callback)
    {
    
    	uint8_t retry,cancel_res;
    
    	if (radioCmdHandle != RADIO_CMD_HANDLE_INVALID) // Controlla se c'è un comando appeso in esecuzione
    	{
    	    retry = 10;
    	    cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
    	    while (cancel_res != RF_StatSuccess && retry--)
    	    {
    	    	Task_sleep(300); // 3 ms in caso di handle non valido
    	    	cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
    	    }
    	    if (cancel_res != RF_StatSuccess) return 1; // Errore
    
    	    if (!(RF_pendCmd(rfHandle, radioCmdHandle, (RF_EventLastCmdDone | RF_EventCmdError |
    	   			RF_EventCmdAborted | RF_EventCmdCancelled | RF_EventCmdStopped)) & RF_EventLastCmdDone)) return 2; // Errore
    	}
    
    	retry = 10;
    	RF_cmdPropRx.status = 0x0000;
    	radioCmdHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, callback,RF_EventRxEntryDone);
    	while(radioCmdHandle == RADIO_CMD_HANDLE_INVALID && retry--)
    	{
        	Task_sleep(300); // 3 ms in caso di handle non valido
    		radioCmdHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, callback,RF_EventRxEntryDone);
    	}
    	if (radioCmdHandle == RADIO_CMD_HANDLE_INVALID)	return 3; // Errore
    	else return 0; // Operazione riuscita
    
    }
    
    char rxRadioCancel()
    {
    
    	uint8_t retry,cancel_res;
    
    	if (radioCmdHandle != RADIO_CMD_HANDLE_INVALID)
    	{
    	    retry = 10;
    	    cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
    	    while (cancel_res != RF_StatSuccess && --retry)
    	    {
    	    	Task_sleep(300); // 3 ms in caso di handle non valido
    	    	cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
    	    }
    	    if (cancel_res != RF_StatSuccess) return 1; // Errore
    
    	    if (RF_pendCmd(rfHandle, radioCmdHandle, (RF_EventLastCmdDone | RF_EventCmdError |
    	   			RF_EventCmdAborted | RF_EventCmdCancelled | RF_EventCmdStopped)) & RF_EventLastCmdDone)
    	    {
    	    	radioCmdHandle = RADIO_CMD_HANDLE_INVALID;
    	    	return 0; // Operazione riuscita
    	    }
    	    else return 2; // Errore
    	}
    	else return 3;
    
    }
    
    
    char rxRadioPacket(RF_Callback callback, uint32_t time)
    {
    
    	uint8_t retry,cancel_res;
    
    	if (radioCmdHandle != RADIO_CMD_HANDLE_INVALID) // Controlla se c'è un comando appeso in esecuzione
    	{
    	    retry = 10;
    	    cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
    	    while (cancel_res != RF_StatSuccess && retry--)
    	    {
    	    	Task_sleep(300); // 3 ms in caso di handle non valido
    	    	cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
    	    }
    	    if (cancel_res != RF_StatSuccess) return 1; // Errore
    
    	    if (!(RF_pendCmd(rfHandle, radioCmdHandle, (RF_EventLastCmdDone | RF_EventCmdError |
    	   			RF_EventCmdAborted | RF_EventCmdCancelled | RF_EventCmdStopped)) & RF_EventLastCmdDone)) return 2; // Errore
    	}
    
    	retry = 10;
    	RF_cmdPropRx.status = 0x0000;
    	radioCmdHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, callback,RF_EventRxEntryDone);
    	while(radioCmdHandle == RADIO_CMD_HANDLE_INVALID && retry--)
    	{
        	Task_sleep(300); // 3 ms in caso di handle non valido
    		radioCmdHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, callback,RF_EventRxEntryDone);
    	}
    	if (radioCmdHandle == RADIO_CMD_HANDLE_INVALID)	return 3; // Errore
    
    	Task_sleep(time); // Attende time
    
    	#ifdef SERIAL_DEBUG
    		sprintf(echoPrompt,"rRP - s:%x\r\n",RF_cmdPropRx.status);
    		UART_write(uart, echoPrompt, strlen(echoPrompt));
    	#endif
    
        retry = 10; // Disattiva la ricezione
        cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
        while (cancel_res != RF_StatSuccess && retry--)
        {
        	Task_sleep(300); // 3 ms in caso di handle non valido
        	cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
        }
        if (cancel_res != RF_StatSuccess) return 4; // Errore
    
       	if (RF_pendCmd(rfHandle, radioCmdHandle, (RF_EventLastCmdDone | RF_EventCmdError |
       			RF_EventCmdAborted | RF_EventCmdCancelled | RF_EventCmdStopped)) & RF_EventLastCmdDone)
       	{
    		radioCmdHandle = RADIO_CMD_HANDLE_INVALID;
       		return 0; // operazione riuscita
       	}
       	else	return 5; // Errore
    
    }
    
    char txRadioPacket(uint8_t * dest, uint8_t * source, uint16_t messID, uint8_t * payload, uint8_t payloadLen)
    {
    
    	uint8_t retryTx,i,x,retry,cancel_res;
    
    	if (radioCmdHandle != RADIO_CMD_HANDLE_INVALID) // Controlla se c'è un comando appeso in esecuzione
    	{
    	    retry = 10;
    	    cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
    	    while (cancel_res != RF_StatSuccess && retry--)
    	    {
    	    	Task_sleep(300); // 3 ms in caso di handle non valido
    	    	cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
    	    }
    	    if (cancel_res != RF_StatSuccess) return 1; // Errore
    
    	    if (!(RF_pendCmd(rfHandle, radioCmdHandle, (RF_EventLastCmdDone | RF_EventCmdError |
    	   			RF_EventCmdAborted | RF_EventCmdCancelled | RF_EventCmdStopped)) & RF_EventLastCmdDone)) return 2; // Errore
    	}
    
    	memcpy(&radioTxBuffer[RADIO_PACKET_DEST_ADDR_POS],dest,8);
    	memcpy(&radioTxBuffer[RADIO_PACKET_SOURCE_ADDR_POS],source,8);
    	radioTxBuffer[RADIO_PACKET_MESS_ID_POS] = messID >> 8;
    	radioTxBuffer[RADIO_PACKET_MESS_ID_POS+1] = messID;
    	radioTxBuffer[RADIO_PACKET_MESS_OPT_POS] = 0;
    	memcpy(&radioTxBuffer[RADIO_PACKET_MESS_DATA_POS],payload,payloadLen);
    
    	retryTx = RADIO_TX_RETRY;
    	while (retryTx--)
    	{
    		// Attiva radio in RX per effettuare il Listen Before Talk
    		retry = 10;
    		RF_cmdPropRx.status = 0x0000;
    		radioCmdHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, NULL,0);
    		while(radioCmdHandle == RADIO_CMD_HANDLE_INVALID && retry--)
    		{
    	    	Task_sleep(300); // 3 ms in caso di handle non valido
    			radioCmdHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, NULL,0);
    		}
    		if (radioCmdHandle == RADIO_CMD_HANDLE_INVALID) return 3;
    
    		Task_sleep(100); // Attende 1 ms per stabilizzare la radio in RX
    
    		i = 0;
    		for (x=0;x<10;x++) // Effettua 10 campioni RSSI, se tutti sono liberi, assegna il canale
    			if (RF_getRssi(rfHandle) >= RSSI_THRESHOLD) i++;
    
    	    retry = 10; // Disattiva la ricezione radio
    	    cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
    	    while (cancel_res != RF_StatSuccess && retry--)
    	    {
    	    	Task_sleep(300); // 3 ms in caso di handle non valido
    	    	cancel_res = RF_cancelCmd(rfHandle, radioCmdHandle, 0);
    	    }
    	    if (cancel_res != RF_StatSuccess) return 4;
    
    	   	if (!(RF_pendCmd(rfHandle, radioCmdHandle, (RF_EventLastCmdDone | RF_EventCmdError |
    	   			RF_EventCmdAborted | RF_EventCmdCancelled | RF_EventCmdStopped)) & RF_EventLastCmdDone)) return 5;
    
    		if (i)
    		{
    			delayValue = 5000 + (GetRandom() & 0x3FF);
    			Task_sleep(delayValue);// Se canale occupato aggiunge 50 ms + random (max 1023) di offset senza trasmettere
    		}
    		else
    		{
    			radioCmdHandle = RADIO_CMD_HANDLE_INVALID;
    			RF_cmdPropTx.pPkt = radioTxBuffer;
    			RF_cmdPropTx.pktLen = RADIO_PACKET_MESS_DATA_POS + payloadLen;
    			if (RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0) & RF_EventLastCmdDone) return 0; // Altrimenti trasmette
    		}
    	}
    	return 6;
    }
    

    The main loop code:

    void mainTaskFxn(UArg arg0, UArg arg1)
    {
    	static RF_Params rfParams;
        static Semaphore_Params semParams;
        static Clock_Params clkParams;
        static uint8_t * myAddressLoc = (uint8_t *)PRIMARY_IEEE_ADDR_LOCATION;
        reset_ctl = (uint32_t *)RSTCTL_LOCATION;
        static uint64_t tick_diff;
        char tx_res,rx_res;
    
        strcpy(echoPrompt,"######################################\r\n");
        UART_write(uart, echoPrompt, strlen(echoPrompt));
        UART_write(uart, echoPrompt, strlen(echoPrompt));
        UART_write(uart, echoPrompt, strlen(echoPrompt));
        strcpy(echoPrompt,"=============== eButton ==============\r\n");
        UART_write(uart, echoPrompt, strlen(echoPrompt));
        sprintf(echoPrompt,"ResetCTL:%x - ",*reset_ctl);
        UART_write(uart, echoPrompt, strlen(echoPrompt));
    
        if		((*reset_ctl & 0xF) == 0x2)	strcpy(echoPrompt,"Reset Pin\r\n");
        else if	((*reset_ctl & 0xF) == 0x4)	strcpy(echoPrompt,"VDDS Brown Out\r\n");
        else if	((*reset_ctl & 0xF) == 0x6)	strcpy(echoPrompt,"VDD  Brown Out\r\n");
        else if	((*reset_ctl & 0xF) == 0x8)	strcpy(echoPrompt,"VDDR Brown Out\r\n");
        else if	((*reset_ctl & 0xF) == 0xA)	strcpy(echoPrompt,"Clock loss detect\r\n");
        else if	((*reset_ctl & 0xF) == 0xC)	strcpy(echoPrompt,"Software Reset via SYSRESET\r\n");
        else if	((*reset_ctl & 0xF) == 0xE)	strcpy(echoPrompt,"Software Reset via PRCM warm reset request\r\n");
        else								strcpy(echoPrompt,"Power On Reset\r\n");
    
        UART_write(uart, echoPrompt, strlen(echoPrompt));
    
        Power_setDependency(PowerCC26XX_PERIPH_TRNG);
        TRNGEnable();
    	while (!(TRNGStatusGet() & TRNG_NUMBER_READY));
        randomIndex = TRNGNumberGet(TRNG_LOW_WORD) & 0x1F;
        TRNGDisable();
        Power_releaseDependency(PowerCC26XX_PERIPH_TRNG);
    
        sprintf(echoPrompt,"Random Index:%d\r\n",randomIndex);
        UART_write(uart, echoPrompt, strlen(echoPrompt));
    
        strcpy(echoPrompt,"######################################\r\n");
        UART_write(uart, echoPrompt, strlen(echoPrompt));
        UART_write(uart, echoPrompt, strlen(echoPrompt));
        UART_write(uart, echoPrompt, strlen(echoPrompt));
    
        strcpy(echoPrompt,"\r\n");
        UART_write(uart, echoPrompt, strlen(echoPrompt));
    
    
        	// Inizializzazione Variabili Generiche //
        deviceState = DEVICE_WAIT_FOR_SCAN;
        gatewayScanRSSI = -128;
        for (i=0;i<8;i++) myAddress[i] = myAddressLoc[8 - 1 - i];
        messIDTrs = MESS_ID_TX_MIN;
        messIDRcv = 0;
        led1LastMessID = 0xFFFF;
    	led2LastMessID = 0xFFFF;
    	led1LastpacketSendReply = PACKET_REPLY_VALUE_NONE;
    	led2LastpacketSendReply = PACKET_REPLY_VALUE_NONE;
        advCh = 0;
        messCh = 0;
        buttonValue = BUTTON_NOT_PRESSED;
        batteryLevel = 0;
    
        	// Inizializzazione MAIN //
    	Semaphore_Params_init(&semParams);
        semParams.mode = Semaphore_Mode_BINARY;
       	Semaphore_construct(&mainSemStruct, 0, &semParams);
        mainSemHandle = Semaphore_handle(&mainSemStruct);
    
        Semaphore_Params_init(&semParams);
        semParams.mode = Semaphore_Mode_BINARY;
       	Semaphore_construct(&eventsSemStruct, 0, &semParams);
        eventsSemHandle = Semaphore_handle(&eventsSemStruct);
    
        Clock_Params_init(&clkParams);
        clkParams.period = DEVICE_WAIT_FOR_READY_TO_RX_tick;
        clkParams.startFlag = FALSE;
        Clock_construct(&clkReadyToRxStruct, (Clock_FuncPtr)clkReadyToRxFxn,
        		DEVICE_WAIT_FOR_READY_TO_RX_tick, &clkParams);
        clkReadyToRxHandle = Clock_handle(&clkReadyToRxStruct);
    
        Clock_Params_init(&clkParams);
        clkParams.period = DEVICE_READ_BATTERY_tick;
        clkParams.startFlag = TRUE;
        Clock_construct(&clkReadBatteryStruct, (Clock_FuncPtr)clkReadBatteryFxn,
        		DEVICE_READ_BATTERY_tick, &clkParams);
        clkReadBatteryHandle = Clock_handle(&clkReadBatteryStruct);
    
    	Task_sleep(DEVICE_FIRST_BATTERY_READ_tick);
    	batteryLevel = GetBattery();
    	// Inizializzazione RADIO //
    	RF_Params_init(&rfParams);
    	rfParams.nInactivityTimeout = ms_To_RadioTime(1);
    	rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
    	setPower(6);
    	setFrequency(ADV_CH_Table[0]);
    
    	// Impostazioni Comando RX
    	RFQueue_defineQueue(&radioRxQueue, rxDataEntryBuffer, sizeof(rxDataEntryBuffer), NUM_DATA_ENTRIES, MAX_LENGTH + NUM_APPENDED_BYTES);
    
    	RF_cmdPropRx.commandNo = 0x3802;
    	RF_cmdPropRx.status = 0x0000;
    	RF_cmdPropRx.pNextOp = 0;
    	RF_cmdPropRx.startTime = 0;
    	RF_cmdPropRx.startTrigger.triggerType = 0;
    	RF_cmdPropRx.startTrigger.bEnaCmd = 0;
    	RF_cmdPropRx.startTrigger.triggerNo = 0;
    	RF_cmdPropRx.startTrigger.pastTrig = 0;
    	RF_cmdPropRx.condition.rule = 1;
    	RF_cmdPropRx.condition.nSkip = 0;
    	RF_cmdPropRx.pktConf.bFsOff = 0;
    	RF_cmdPropRx.pktConf.bRepeatOk = 1;
    	RF_cmdPropRx.pktConf.bRepeatNok = 1;
    	RF_cmdPropRx.pktConf.bUseCrc = 1;
    
    	RF_cmdPropRx.pktConf.bVarLen = 1;
    	RF_cmdPropRx.pktConf.bChkAddress = 0;
    	RF_cmdPropRx.pktConf.endType = 0;
    	RF_cmdPropRx.pktConf.filterOp = 0;
    	RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;
    	RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
    	RF_cmdPropRx.rxConf.bIncludeHdr = 1;
    	RF_cmdPropRx.rxConf.bIncludeCrc = 0;
    	RF_cmdPropRx.rxConf.bAppendRssi = 1;
    	RF_cmdPropRx.rxConf.bAppendTimestamp = 0;
    	RF_cmdPropRx.rxConf.bAppendStatus = 1;
    	RF_cmdPropRx.syncWord = 0x930b51de;
    	RF_cmdPropRx.maxPktLen = RADIO_RX_BUFFER_SIZE;
    	RF_cmdPropRx.endTrigger.triggerType = TRIG_NEVER;
    	RF_cmdPropRx.endTrigger.bEnaCmd = 0;
    	RF_cmdPropRx.endTrigger.triggerNo = 0;
    	RF_cmdPropRx.endTrigger.pastTrig = 0;
    	RF_cmdPropRx.endTime = 0;
    	RF_cmdPropRx.pQueue = &radioRxQueue;
    	RF_cmdPropRx.pOutput = 0;
    
    	radioCmdHandle = RADIO_CMD_HANDLE_INVALID;
    
    	while(1)
    	{
    		switch (deviceState)
    		{
    			case DEVICE_WAIT_FOR_SCAN:	delayValue = DEVICE_WAIT_FOR_SCAN_TIME_tick + (GetRandom() & 0xFFFF);
    										Clock_stop(clkReadyToRxHandle);
    										Task_sleep(delayValue); // random (max 65535)
    										deviceState = DEVICE_SCANNING;
    										break;
    			case DEVICE_SCANNING:	gatewayScanRSSI = -120;
    									memset(gatewayAddress,0x00,8);
    									messCh = 0;
    									setFrequency(ADV_CH_Table[advCh]);
    									tick_diff = Clock_getTicks();
    									rx_res = rxRadioPacket(&radioRxScanCallbackFnx,DEVICE_SCAN_TIME_tick);
    									tick_diff = Clock_getTicks() - tick_diff;
    									if (messCh)
    									{
    										setFrequency(Mess_CH_Table[messCh - 1]);
    										deviceState = DEVICE_TRY_JOIN;
    									}
    									else
    									{
    										advCh++;
    										if (advCh == 3) advCh = 0;
    										deviceState = DEVICE_WAIT_FOR_SCAN;
    									}
    									break;
    
    			case DEVICE_TRY_JOIN:	gatewayJoinAllow = RADIO_PACKET_MESS_JOIN_REPLY_NO;
    									payload[0] = RADIO_PACKET_MESS_JOIN_REQUEST;
    									payload[1] = DEVICE_MODEL_ID;
    									payload[2] = DEVICE_POWER_MODE;
    									payload[3] = batteryLevel;
    									messIDTrs++;
    									if (messIDTrs == MESS_ID_TX_MAX) messIDTrs = MESS_ID_TX_MIN;
    									messIDWaiting = messIDTrs;
    									tx_res = txRadioPacket(gatewayAddress,myAddress,messIDTrs,payload,4);
    									rx_res = rxRadioPacket(&radioRxTryJoinCallbackFnx,DEVICE_TRY_JOIN_TIME_tick);
    									if (gatewayJoinAllow == RADIO_PACKET_MESS_JOIN_REPLY_OK)
    									{
    										gatewayReplyRequestCounter = 0;
    										gatewayReplyRequestFlag = 0;
    										gatewayInactivityCounter = 0;
    										events = 0;
    										Semaphore_pend(eventsSemHandle,0); // Forza reset semaforo
    										Clock_start(clkReadyToRxHandle);
    										deviceState = DEVICE_JOINED;
    									}
    									else
    									{
    										deviceState = DEVICE_WAIT_FOR_SCAN;
    									}
    									break;
    
    			case DEVICE_JOINED:		Semaphore_pend(eventsSemHandle,BIOS_WAIT_FOREVER);
    									while(events)
    									{
    										// ====================================== //
    										// ========= Evento READY_TO_RX ========= //
    										// ====================================== //
    										if (events & EVENTS_READY_TO_RX)
    										{
    											events &= ~EVENTS_READY_TO_RX;
    											ReplySendTxDataIndex = 0;
    											gatewayReplyRequestCounter++;
    											if (gatewayReplyRequestCounter == GATEWAY_REPLY_REQUEST_COUNTER)
    											{
    												payload[0] = RADIO_PACKET_MESS_READY_TO_RX_REPLY_REQUEST;
    												gatewayReplyRequestCounter = 0;
    												gatewayReplyRequestFlag = 1;
    											}
    											else
    											{
    												payload[0] = RADIO_PACKET_MESS_READY_TO_RX;
    											}
    											messIDTrs++;
    											if (messIDTrs == MESS_ID_TX_MAX) messIDTrs = MESS_ID_TX_MIN;
    											messIDWaiting = messIDTrs;
    											tx_res = txRadioPacket(gatewayAddress,myAddress,messIDTrs,payload,1);
    											round_trip = Clock_getTicks();
    											round_trip_flag = 0;
    											longReceiveWindowFlag = 0;
    											rx_res = rxRadioAlwaysOn(&radioRxReceivingWindowCallbackFnx);
    											Task_sleep(DEVICE_RECEIVING_SHORT_TIME_tick);
    
    											while (longReceiveWindowFlag)
    											{
    												longReceiveWindowFlag = 0;
    												round_trip = Clock_getTicks();
    												round_trip_flag = 0;
    												Task_sleep(DEVICE_RECEIVING_LONG_TIME_tick);
    											}
    											rx_res = rxRadioCancel();
    											// ===== Invia pacchetti ack se presenti ===== //
    											if (ReplySendTxDataIndex)
    												for (y=0;y<ReplySendTxDataIndex;y++)
    												{
    													payload[0] = RADIO_PACKET_MESS_REPLY;
    													payload[1] = ReplySendTxBuffer[y].ReplyValue;
    													tx_res = txRadioPacket(gatewayAddress,myAddress,ReplySendTxBuffer[y].messID,payload,2);
    													delayValue = 2000 + (GetRandom() & 0x3FF);
    													Task_sleep(delayValue);// Attende 20 ms + random (max 1023) tra una tx e l'altra
    												}
    
    											// ======== Controllo attività Gateway ======= //
    											if (gatewayReplyRequestFlag)
    											{
    												gatewayReplyRequestFlag = 0;
    												if (gatewayInactivityCounter == GATEWAY_INACTIVITY_COUNTER)
    												{
    													deviceState = DEVICE_WAIT_FOR_SCAN;
    												}
    												gatewayInactivityCounter++;
    											}
    										}
    									}
    									break;
    		}
    	}
    }

    • The Clock_start(clkReadyToRxHandle) function, after the join (connect) to the gateway is gone right, enable the "every 2 seconds" awake when in Locked State (DEVICE_JOINED switch state).
    • radioCmdHandle variable is global
    
    

    I attach as files the smartrf files:

    
    //*********************************************************************************
    // These settings have been generated for use with TI-RTOS and cc13xxware
    //
    // Generated by SmartRF Studio version 2.3.0
    // Tested with TI-RTOS version tirtos_simplelink_2_15_xx_xx
    //
    //*********************************************************************************
    
    
    //*********************************************************************************
    // Parameter summary
    // Address: aa-bb
    // Frequency: 868.00000 MHz
    // Data Format: Serial mode disable
    // Deviation: 25.000 kHz
    // Packet Length Config: Variable
    // Max Packet Length: 128
    // Packet Length: 30
    // RX Filter BW: 98 kHz
    // Symbol Rate: 50.00000 kBaud
    // Sync Word Length: 32 Bits
    // TX Power: 14 dBm (requires define CCFG_FORCE_VDDR_HH = 1 in ccfg.c, see CC13xx/CC26xx Technical Reference Manual)
    // Whitening: No whitening
    
    #include <driverlib/rf_mailbox.h>
    #include <driverlib/rf_common_cmd.h>
    #include <driverlib/rf_prop_cmd.h>
    #include <ti/drivers/rf/RF.h>
    #include <rf_patches/rf_patch_cpe_genfsk.h>
    #include "smartrf_settings.h"
    
    
    // TI-RTOS RF Mode Object
    RF_Mode RF_prop =
    {
        .rfMode = RF_MODE_PROPRIETARY_SUB_1,
        .cpePatchFxn = &rf_patch_cpe_genfsk,
        .mcePatchFxn = 0,
        .rfePatchFxn = 0,
    };
    
    // Overrides for CMD_PROP_RADIO_DIV_SETUP
    uint32_t pOverrides[] =
    {
        // override_synth_prop_863_970_div5.xml
        HW_REG_OVERRIDE(0x4038,0x003A),
        HW_REG_OVERRIDE(0x4020,0x7F00),
        HW_REG_OVERRIDE(0x4064,0x0040),
        (uint32_t)0x000684A3,
        (uint32_t)0xC0040141,
        (uint32_t)0x0533B107,
        (uint32_t)0x0A480583,
        (uint32_t)0x7AB80603,
        ADI_REG_OVERRIDE(1,4,0x9F),
        ADI_HALFREG_OVERRIDE(1,7,0x4,0x4),
        (uint32_t)0x02010403,
        (uint32_t)0x00108463,
        (uint32_t)0x04B00243,
        // override_phy_gfsk_rx_rssi.xml
        HW_REG_OVERRIDE(0x6084,0x35F1),
        (uint32_t)0x00038883,
        (uint32_t)0x00FB88A3,
        // override_phy_agc_reflevel_0x1a.xml
        HW_REG_OVERRIDE(0x6088,0x001A),
        // override_phy_rx_aaf_bw_0xd.xml
        ADI_HALFREG_OVERRIDE(0,61,0xF,0xD),
        (uint32_t)0xFFFFFFFF,
    };
    
    
    // CMD_PROP_RADIO_DIV_SETUP
    rfc_CMD_PROP_RADIO_DIV_SETUP_t RF_cmdPropRadioDivSetup =
    {
        .commandNo = 0x3807,
        .status = 0x0000,
        .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .modulation.modType = 0x1,
        .modulation.deviation = 0x64,
        .symbolRate.preScale = 0xf,
        .symbolRate.rateWord = 0x8000,
        .rxBw = 0x24,
        .preamConf.nPreamBytes = 0x4,
        .preamConf.preamMode = 0x0,
        .formatConf.nSwBits = 0x20,
        .formatConf.bBitReversal = 0x0,
        .formatConf.bMsbFirst = 0x1,
        .formatConf.fecMode = 0x0,
        .formatConf.whitenMode = 0x0,
        .config.frontEndMode = 0x0,
        .config.biasMode = 0x1,
        .config.bNoFsPowerUp = 0x0,
        .txPower = 0x1cc7,
        .pRegOverride = pOverrides,
        .centerFreq = 0x0364,
        .intFreq = 0x8000,
        .loDivider = 0x05,
    };
    
    
    // CMD_FS
    rfc_CMD_FS_t RF_cmdFs =
    {
        .commandNo = 0x0803,
        .status = 0x0000,
        .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .frequency = 0x0364,
        .fractFreq = 0x0000,
        .synthConf.bTxMode = 0x0,
        .synthConf.refFreq = 0x0,
        .__dummy0 = 0x00,
        .midPrecal = 0x00,
        .ktPrecal = 0x00,
        .tdcPrecal = 0x0000,
    };
    
    // CMD_PROP_TX
    rfc_CMD_PROP_TX_t RF_cmdPropTx =
    {
        .commandNo = 0x3801,
        .status = 0x0000,
        .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .pktConf.bFsOff = 0x0,
        .pktConf.bUseCrc = 0x1,
        .pktConf.bVarLen = 0x1,
        .pktLen = 0x1e, // SET APPLICATION PAYLOAD LENGTH
        .syncWord = 0x930b51de,
        .pPkt = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
    };
    
    // CMD_PROP_RX
    rfc_CMD_PROP_RX_t RF_cmdPropRx =
    {
        .commandNo = 0x3802,
        .status = 0x0000,
        .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .pktConf.bFsOff = 0x0,
        .pktConf.bRepeatOk = 0x0,
        .pktConf.bRepeatNok = 0x0,
        .pktConf.bUseCrc = 0x1,
        .pktConf.bVarLen = 0x1,
        .pktConf.bChkAddress = 0x0,
        .pktConf.endType = 0x0,
        .pktConf.filterOp = 0x0,
        .rxConf.bAutoFlushIgnored = 0x0,
        .rxConf.bAutoFlushCrcErr = 0x0,
        .rxConf.bIncludeHdr = 0x1,
        .rxConf.bIncludeCrc = 0x0,
        .rxConf.bAppendRssi = 0x0,
        .rxConf.bAppendTimestamp = 0x0,
        .rxConf.bAppendStatus = 0x1,
        .syncWord = 0x930b51de,
        .maxPktLen = 0x7d, // MAKE SURE DATA ENTRY IS LARGE ENOUGH
        .address0 = 0xaa,
        .address1 = 0xbb,
        .endTrigger.triggerType = 0x1,
        .endTrigger.bEnaCmd = 0x0,
        .endTrigger.triggerNo = 0x0,
        .endTrigger.pastTrig = 0x0,
        .endTime = 0x00000000,
        .pQueue = 0, // INSERT APPLICABLE POINTER: (dataQueue_t*)&xxx
        .pOutput = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
    };
    

    2402.smartrf_settings.h

    Thanks!

    Riccardo

  • Hi Riccardo,

    thanks for taking the time to explain your application. It's much clearer now. You code doesn't use the radio timer for command triggering so I doubt that there is an issue related to that.

    You say that the application locks after many hours. Are you able to attach the debugger in the moment your application hangs and could you observe where it hangs? You can start the application in the CCS debugger and then click Run -> Disconnect Target. Leave the application run. When it blocks, re-attach with Run -> Connect target. 

    Instead of re-trying RF_postCmd() or RF_cancelCmd(), you could use asserts or for testing, just go into an infinite loop. If RF_postCmd() or RF_cancelCmd() fail, then you would have a serious error in the application. This could make it easier to spot the failing code section.

    If you want have more exact timing, please read about relative end triggers and alternative triggers for radio operation commands.

  • Hi Richard,

    I'm at the fourth day and all run correctly....switching from RAT managed version of the code to the task_sleep managed version (the last one I attached in the previous post) I made heavy code edit, so I would not like that I have solved the problem without realizing it. However, I prefer using RAT designed code so I have to identify the problem.

    A very interesting thing you told me is the fact that an error code on RF_postCmd() or RF_cancelCmd() is a serious problem, this means that these functions have to return always an OK code ? And if not, how have I manage the error code ? There are a lot of error codes. 

    Easy Link lib simply return a generic error if the operation is different from OK status, but is not described as manage an error, is it possible to send a sort of reset to the radio if an error happens?

    In my case, I suspected could be a problem on the radioCommandHandle that I used to keep track of the last radio operation, in the past code (RAT version), I used the RF_LastEventCommand to set radioCommandHandle to -1, but I think this is correct cause when the Radio terminates an operation, raise always this IRQ (I don't use chain operation for the moment), is this correct ?

    I need two clarification if you can give me:

    1)  If I set the flag inside the RF_RX_Prop struct to complete the packet RX in the case of a end trigger happend,  the  RF_LastEventCommand IRQ is set at the end trigger operation or after the packet rx completation ?

    2) Is there a way to posticipate an end trigger time after the RX command is started and is running? When I send the RX command to the Radio, I need to keep RX on for 500 ms, I could get this by setting End Trigger with TRIG_REL_START, but if I receive a specific packet, I need to posticipate the End Trigger time during the RX operation running, is this possible ?

    Thanks!

    Riccardo

  • Hello Riccardo,

    A very interesting thing you told me is the fact that an error code on RF_postCmd() or RF_cancelCmd() is a serious problem, this means that these functions have to return always an OK code ? And if not, how have I manage the error code ? There are a lot of error codes. 

    RF_postCmd() only returns an error if the RF driver runs out of command containers. It provides 8 containers, so up to 8 commands can be stored in the command queue. In your application, you run only one command at a time so if the RF driver runs out of containers, then your application has a serious problem and you should not try to recover from that, but investigate and fix the error.

    The same thing applies to RF_cancelCmd(), if it fails then the command handle is invalid or there is a serious problem somewhere in the driver or the RF core. Don't try to recover, but investigate what could cause this problem.

    In my case, I suspected could be a problem on the radioCommandHandle that I used to keep track of the last radio operation, in the past code (RAT version), I used the RF_LastEventCommand to set radioCommandHandle to -1, but I think this is correct cause when the Radio terminates an operation, raise always this IRQ (I don't use chain operation for the moment), is this correct ?

    Yes, RF_EventLastCmdDone is always raised, no matter how the command ended.

    1)  If I set the flag inside the RF_RX_Prop struct to complete the packet RX in the case of a end trigger happend,  the  RF_LastEventCommand IRQ is set at the end trigger operation or after the packet rx completation ?

    The RF_EventLastCmdDone is raised after the command has completed. It is the last event that can happen. Packet reception is always finished at that time.

    2) Is there a way to posticipate an end trigger time after the RX command is started and is running? When I send the RX command to the Radio, I need to keep RX on for 500 ms, I could get this by setting End Trigger with TRIG_REL_START, but if I receive a specific packet, I need to posticipate the End Trigger time during the RX operation running, is this possible ?

    You can configure the RX command to behave in two ways when the end trigger is fired:

    1. to complete an ongoing packet reception
    2. to abort packet reception immediately 

    This is done with the following flag:

    // 0: Packet is received to the end if end trigger happens after sync is obtained 
    // 1: Packet reception is stopped if end trigger happens rxCommand.pktConf.endType = 0x0;

    Hope that helps.

  • Hi Richard,

    I'll try to be more clear:

    Every 2 seconds my End Device awakes, transmits a packet to the gateway and switch in RX mode for 15 ms waiting for an incoming (if available) from the gateway, after this 15 ms RX window, it return into standby. During the RX window I can receive different kinds of packet, and if I receive a packet with a specific value inside (where the gateway told me "ehi there are more packets for you, don't power off the RX but keep it on for more time") I need to extend the RX window for more milliseconds, remaing in RX without terminate and restart a new RX. Is this possible using only Radio commands ? Actually , to obtain this, I post a RX command with end trigger to TRIG_NEVER and I terminate it maually using RF_Cancel() command when I need.

    Thanks!

    Riccardo
  • During the RX window I can receive different kinds of packet, and if I receive a packet with a specific value inside (where the gateway told me "ehi there are more packets for you, don't power off the RX but keep it on for more time") I need to extend the RX window for more milliseconds, remaing in RX without terminate and restart a new RX. Is this possible using only Radio commands ? 

    There is the possibility to create the following command chain:

    You would configure CMD_PATTERN_CHECK to look for the status code of CMD_PROP_RX. Depending on pktConf.endType it ends either with PROP_DONE_BREAK or PROP_DONE_ENDED while receiving a packet.  For the meaning of the different status codes, have a look at the Technical Reference Manual section 23.7.5.4. The CMD_PATTERN_CHECK is explained in section 23.3.3.1.14.

    Actually , to obtain this, I post a RX command with end trigger to TRIG_NEVER and I terminate it maually using RF_Cancel() command when I need.

    This is also totally valid and even simpler than the above variant.

    Please try relative end triggers and if it works for you, consider tho mark this thread as being answered. Feel free to ask more questions if you still observe the error mentioned in your first post.

  • Hi Richard,

    I'll give you some update: after 11 days, all runs correctly!

    Rechecking the code, the only thing that I can see is that now I set always to 0 the RF_Rx_prop.status variable before I post the command to the Radio. I have read in the CC1310 Technical Reference datasheet that this variable must be set always to 0 before send the command (I have read this information after I have edit the code.....bad luck as usual...), could this be the solution / cause of the problem?

    Checking the examples, the status variable is set to 0 only in the RF_Rx_prop initialization but not every time there is a radio RX or TX operation.

    Thanks!

    Riccardo

  • Hi Riccardo,

    the designer of the RF core Command and Packet Engine and he told me that it is technically not necessary to set the command state to IDLE before posting the command. However, it is good practice to do so, if you want to debug your application.

  • Hi Richard,

    thanks for the information, however for the moment I'll leave the code with the retries loop in the case of errors, you told me that there must be no mistakes on the part of the radio and if there are, the cause must to be in code and must be resolved of course, but I have seen that errors also cover cases as radio busy etc, can these errors occur dynamically (and therefore must be managed)? during run time?  The only way to understand what happened, is to restore my old code and printout the status variable.

    Thanks!

    Riccardo