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.

CC2543: trouble setting the receiver up in always on mode

Part Number: CC2543

I have a similar application to this thread but I'm having a hard time getting it to work

https://e2e.ti.com/support/wireless_connectivity/low_power_rf_tools/f/155/t/334040?tisearch=e2e-sitesearch&keymatch=constant%20receive%20cc2543

I started from the PER example and have modified it to run in basic fixed length mode.  I have 4 transmitters that send are synchronized such that a new message is generated every 250us in a round robin fashion... which means the receiver has to receive a new message every 250us (4 times a msec)

I have attempted to turn leave the synthesizer on, set the frequency control register directly and turned repeat on but I seem to be missing something because the setup seems to receive 1 or nothing depending on what the setup is.  Note i can set PRF.TASK_CONF.REPEAT = 0 and I can receive packets but the reception is sporadic and can't seem to keep up.

Here is my modified PER receive code, and a few specific questions... but also curious if you see any errors in the code below

  1. should i let the receiver start up once with PRF.CHAN.SYNTH = 0 to allow the synth to calibrate once?  This would require me to set PRF.CHAN.SYNTH = 1 after the first TX_DONE?
  2. does halRfStartRx() need to be called each time around the loop or just once at the start?


void remoteRxMode(void)
{ // Variables for RSSI, packet sequence, statistics, etc... uint32 packetSeq = 0, idx = 0; int8 rssi[8] = {0,0,0,0,0,0,0,0}, rssi_new = 0; int16 rssi_sum = 0,rssi_avg = 0; uint32 okPackets = 0, crcPackets = 0, lostPackets = 0, tmp, testTime; static uint8 pktData[50]; static uint8 pktLen; static uint8 res; static bool configSynth = true; // Clear and update LCD display. halLcdClear(); halLcdWriteLine(1, c2xd(text_Remote_Mode)); // Setup the radio with the received configuration. halRfDisableRadio(FORCE); halRfInit(); halRfConfig( modulation, RX, sync_word_len, PKT_CONF_MODE_BASIC_FIXLEN ); //halRfSetCrc(CRC_16_CCITT); halRfSetSyncWord( sync_word, 0); halRfSetRxAddress(0, ADDR_CONF_RX_BASIC_SW1, 0xAA, (packet_length)); //halRfSetFrequency(frequency); /* setup the packet handling */ PRF.FIFO_CONF.AUTOFLUSH_CRC = 0; // Do Not Flush packets with CRC error PRF.FIFO_CONF.RX_STATUS_CONF = 1; // add the status to the end of the packet reception /* for the synthesizer to stay on and ensure that the frequency is set properly */ PRF.CHAN.SYNTH_ON = 1; // leave the synthesizer on after task ends PRF.CHAN.FREQ = 127; FREQCTRL = frequency-2379; /* setup restarting the task */ //PRF.TASK_CONF.START_CONF = 0; // Start immediately after command. //PRF.TASK_CONF.REPEAT_CONF = 1; // Start immediately after command. //PRF.TASK_CONF.REPEAT = 1; // repeat the task when done /* Set timeout value (total test time + 1 second in margin) to end test when done. */ // testTime = (10*(packets)) + 1000; // halTimer2SetRadioTimeout(testTime, SINGLE); // halTimer2Start(0); // Start timer 2 (asynchronous). halRfEnableRadio(); // Enable RF interrupt. halRfEnableInterrupt(RFIRQF1_TASKDONE); // Enable global interrupt. halIntOn(); while(1 /*okPackets < packets*/) { // Start receiver. halRfStartRx(); // Wait for TASKDONE and halt CPU (PM0) until task is completed. while (!(rfirqf1 & RFIRQF1_TASKDONE)); // Check if task ended correctly if(PRF.ENDCAUSE == TASK_ENDOK) { // Check if packet was received. if(rfirqf1 & RFIRQF1_RXOK) { // Check if packet length is as expected. pktLen = RFD; if (packet_length == pktLen) { ... } halRfCommand(CMD_RXFIFO_RESET); } else if (rfirqf1 & RFIRQF1_RXNOK) { halRfCommand(CMD_RXFIFO_RESET); crcPackets++; } else { // Write end cause error code to screen. } } // Check if test time has expired or last packet is received. if (PRF.ENDCAUSE == TASK_RXTIMEOUT) { lostPackets++; } // Clear the global RFIRQF1 shadow variable (RF Interrupt flags). rfirqf1 = 0; // Set to a undefined value in enum type end cause. PRF.ENDCAUSE = TASK_UNDEF; } /* Disable interrupts enabled in this function, clear timer 2 and return. */ // Disable global interrupt. halIntOff(); // Reset Timer2. halTimer2Reset(); // Disable RF interrupt. halRfDisableInterrupt(RFIRQF1_TASKDONE); }

  • Hello Ryan,
    Which data rate are you using?

    You need to manually program IF frequency when you you leave the SYNTH running. Also If you enable the SYNTH for long periods where there is significant temperature change, you might lose synth lock and you will need to restart the radio to recalibrate the SYNTH. Note that the SYNTH should not be allowed to run for a long time after a task has ended, as this causes excessive power consumption. The synth can be stopped by sending a CMD_SHUTDOWN command.

    Please refer to the users guide section 23.5 Frequency and Channel Programming:

    "In Rx, the system operates on a low intermediate frequency (IF) of 1 MHz for data rates up to 1 Mbps, and on a zero IF for 2 Mbps. In Tx, the system supports operating on low IF or zero IF. The IF to be used for Tx can be programmed in the register MDMTEST1.TX_TONE. The receiver may operate on a positive of negative IF when the data rate is 1 Mbps and lower; this is controlled with MDMTEST1.RX_IF."

    Make sure the radio will start immediately after command issued:
    PRF.TASK_CONF.START_CONF = 0; // Start immediately after command.

    You can also start by running the receiver in debug mode. Set breakpoint at:
    // Check if packet was received.
    if(rfirqf1 & RFIRQF1_RXOK)
    Then observe the value of rfirqf1/PRF.ENDCAUSE.
  • Eirik,

    Thanks for that information.  I am using the 2Mbps 500kHz mode.

    I believe I'm not even getting to the point of being able to turn the synthesizer recal off.  I can leave the synthesizer on and I have found that whenever I set PRF.TASK_CONF.REPEAT = 1 it never receives a packet.  

    It is a little unclear to me that if I use the task repeat feature, will i get a RFIRQ1_TASKDONE interrupt, or will I just get RFIRQF1_RXOK interrupts?  My assumption was that I would still be leveraging the task feature had would want to check the following:

    // Wait for TASKDONE and halt CPU (PM0) until task is completed.
    while (!(rfirqf1 & RFIRQF1_TASKDONE));
    
    // Check if task ended correctly
    if(PRF.ENDCAUSE == TASK_ENDOK) 
    {      
      // Check if packet was received.
      if(rfirqf1 & RFIRQF1_RXOK) 
      {
        ...

    In the meantime, I will try to manually set the IF and frequencies again to see if that fixes it.

    Can you also comment when i should configure the task to do repeat? 

    Do i set it up without repeat and syth cal on for the first time and then reconfigure it after the task is enabled to repeat and turn the cal off?  

    If repeat is being used, do I need to call halRfStartRx() every loop? or is just once at the start sufficient?

    I can send you my code if there is a secure way to do that (it runs on the smartRF boards?

    Thanks,

    Ryan

     

  • Hello Ryan,
    This is explained in the users guide, section 23.9.2.3.3 Continuation and Ending of Receive Tasks. You can disable REPEAT and the synth will still run. Then you need to call halRfStartRx() every time the task ends. Although the RFIRQF1_TASKDONE implementation is the most robust, there are other ways to solve it ass well as you can enable/disable different RF interrupts with:
    // Enable RF interrupt.
    halRfEnableInterrupt(RFIRQF1_TASKDONE);

    I know the Radio chapter in the users guide can be a bit brutal, but I advice you to read through it with a big mug of coffee by your side. Chapter "23.9.2 Radio Tasks" is key to know the flow of the radio module.
  • Hi Eirik,

    I'm working with Ryan.

    Is it correct that we should pend on RFIRQF1_RXOK rather than RFIRQF1_TASKDONE when using REPEAT=1? After reading the "Radio Tasks" section, it seems we won't get a TASKDONE interrupt when enabling REPEAT since the receive state repeats forever until commanded otherwise.

    -Nick
  • Hello Nick,

    Yes that is possible. But you need to set/enable the RFIRQF1_RXOK interrupt flag.

    Please note that in TX the TXDONE interrupt will occur before the packet is sent over the air. So you must take care if you don't wait for the TASK_DONE interrupt for certain implementations. Excerpt from user guide:

    "A TXDONE interrupt to the MCU is raised when the packet has been completely read out of the Tx FIFO by
    the LLE. Note that due to modulator delay, CRC transmission and ramp-down, this will happen before the
    packet transmission is finished. The next action is as given in Section 23.9.2.4.3."

  • Hi Eirik,

    A couple other follow-up questions:
    1) We've seen better performance with SYNTH_ON and REPEAT enabled to shorten the turnaround time from packets as much as possible. There was a comment that leaving SYNTH_ON for a long time period can degrade performance. It was stated that SYNTH needs to periodically be recalibrated for temperature change. Is that true in a normal indoor environment? Or only in extreme conditions? Our plan would be to run this for maybe an hour indoors without recalibrating the SYNTH. Can you quantify how that might degrade performance?

    2) The datasheet discusses a tone in front of the preamble to match some transmitters. Is that tone generated at the receiver end, or needs to be sent by the transmitter? As far as I know, our transmitter is not putting a tone in front of the preamble, but we are still enabling the START_TONE setting. It's not clear to me from the datasheet where that tone comes from and how START_TONE should be set.

    Thanks,
    Nick
  • 1) This will depend on how fast temperature changes you may see, but in typical systems, you can have many seconds or even some minutes between recalibration. We don’t have any quantitative number for how long and under what conditions the VCO will stay in lock (stable). The general rule of thumb is to periodically recalibrate and you must to some field testing to figure out at what interval.

    2) You can disable the tone (which is transmitted) and simply use preamble bytes instead. For more details please refer to chapter "23.9.2.2 Tone in Front of Packet" in the user guide.

  • Commenting back for any future CC2543 users:

    Over the period of 1-2 hours indoors at normal room temperature, the performance doesn't change too much without a recalibration. We haven't taken many longer duration measurements.

    We're seeing the START_TONE setting not matter much, even though in our case there is no tone being transmitted. Performance is roughly equal whether the receiver has START_TONE enabled or not.