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.

ED failed receiving data from AP

Other Parts Discussed in Thread: SIMPLICITI

Hello there,

The code in my project is based on  AP_as_Data_Hub example of SimpliciTI software. The network is composed of one AP and many EDs. The situation is that AP receiving data from every EDs works fine, but if I send data from AP to a specific ED, it fails.

Basically what I did in my software is as below.

ED side:

SMPL_Init(0);   SMPL_Link ($sLinkID1)

main loop start.

Collect data to "&msg" buffer.

SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, "" );

SMPL_SendOpt(sLinkID1, msg, sizeof(msg), SMPL_TXOPTION_ACKREQ);

SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);

keep running function SMPL_Receive(0, msg, &len); tens of times if nothing SMPL_SUCCESS is not returned.

SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);

Sleep for 1 minute

Go to loop start.

AP side:

SMPL_Init(sCB);

main loop start.

    if (sJoinSem && (sNumCurrentPeers < NUM_CONNECTIONS))
    {
      while (1)      // listen for a new connection
      {
        if (SMPL_SUCCESS == SMPL_LinkListen(&sLID[sNumCurrentPeers])) break;
      }
      sNumCurrentPeers++;
      BSP_ENTER_CRITICAL_SECTION(intState);
      if (sJoinSem)
      {
        sJoinSem--;
      }
      BSP_EXIT_CRITICAL_SECTION(intState);
    }
    if (sPeerFrameSem)    // Have we received a frame on one of the ED connections?
    {
      for (i=0; i<sNumCurrentPeers; ++i)    /// process all frames waiting
      {
        if (SMPL_Receive(sLID[i], msg, &len) == SMPL_SUCCESS)
        {
          ioctlRadioSiginfo_t sigInfo;
          sigInfo.lid = sLID[i];
          SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SIGINFO, (void *)&sigInfo);
          processMessage();

          set test data in $msg;
          SMPL_SendOpt(1, msg, sizeof(msg), SMPL_TXOPTION_ACKREQ); // Send data to ED

Go to main loop start.

As the result,  the return value of function SMPL_SendOpt() in AP side is SMPL_NO_ACK.

and SMPL_Receive() in ED side does receive any data from AP.

I appreciate very much if anybody can give me some suggestions. Thank you!

  • Wayne,

    sorry for the late reply. From your description, what I understand is that when the AP tried to send something to ED, the ED actually receives the message, but the SMPL_SendOpt() API call on the AP side returns SMPL_NO_ACK error.

    Is this right? Have you also tried to confirm this by using the SmartRF Packet Sniffer? http://processors.wiki.ti.com/index.php/SimpliciTI_-_Configuring_RF_Setting#SimpliciTI_Packet_Sniffing

    If yes, most probably that the delay function for waiting the ACK packet is too short. The simplest way to check for this is to increase the delay manually in MRFI_ReplyDelay() in mrfi_radio.c. Just multiply the delay value:

    void MRFI_ReplyDelay()
    {
      bspIState_t s;
      uint16_t    milliseconds = 2 * sReplyDelayScalar;
    
      BSP_ENTER_CRITICAL_SECTION(s);
      sReplyDelayContext = 1;
      BSP_EXIT_CRITICAL_SECTION(s);
    
      while (milliseconds)
      {
        Mrfi_DelayUsecSem( APP_USEC_VALUE );
        if (sKillSem)
        {
          break;
        }
        milliseconds--;
      }
    
      BSP_ENTER_CRITICAL_SECTION(s);
      sKillSem           = 0;
      sReplyDelayContext = 0;
      BSP_EXIT_CRITICAL_SECTION(s);
    }

    Let me know if this works for you.

  • Hi Leo

    Thank you for your reply.

    You are correct,  and it works now. 

    Before modified the control flow is as follows.

    ED                                                               AP

    SMPL_SendOpt()                                 SMPL_Receive()

    Wait for tens of miliseconds                  process received data (needed tens of miliseconds)

    Run SMPL_Receive() 3 times               SMPL_SendOpt() send data to the specified ED

    Go to sleep status

    In this case, it seems there was no enough time to response AP in ED side.

    Current flow is as below.

    ED                                                                     AP

    SMPL_SendOpt()                                       SMPL_Receive()

                                                                        process received data (needed tens of miliseconds)

    Run SMPL_Receive() until it receives       Keep running SMPL_SendOpt() to send data to ED many

    data from AP (max times is 0xffff).            times until AP got ACK from ED (max times is 6). 

    Go to sleep status

    And it works, although it is not efficient.

  • Re-edit the last response.

    Hi Leo

    Thank you for your reply.

    You are correct,  and it works now. 

    Before modified the control flow is as follows.

    ED  side

    1. SMPL_SendOpt()

    2. Wait for tens of miliseconds

    3. Run SMPL_Receive() 3 times

    4. Go to sleep status

    AP side

    1. SMPL_Receive()

    2.  process received data (needed tens of miliseconds)

    3. SMPL_SendOpt() send data to the specified ED

    In this case, it seems there was no enough time to response AP in ED side.

     

    Current flow is as below.

    ED side

    1. SMPL_SendOpt()

    2. Run SMPL_Receive() until it receives data from AP (max times is 0xffff).

    3. Go to sleep status

    AP side

    1. SMPL_Receive()

    2. process received data (needed tens of miliseconds)

    3. Keep running SMPL_SendOpt() to send data to ED many times until AP get ACK from ED (max times is 6). 

    And it works, although it is not efficient.

  • wayne,

    Wayne Yan said:

    ED side

    1. SMPL_SendOpt()

    2. Run SMPL_Receive() until it receives data from AP (max times is 0xffff).

    3. Go to sleep status

    I don't think it is really necessary and a good idea to wait forever for this. As I recommended above, you can just first try by using factor 2 to the delay variable:

    uint16_t    milliseconds = 2 * sReplyDelayScalar;

     

     

  • Hi Leo,

    I changed

    uint16_t    milliseconds = sReplyDelayScalar;

    to uint16_t milliseconds = 2 * sReplyDelayScalar;

    in MRFI_ReplyDelay() function.

    AP receives ACK in its first SMPL_SendOpt() try in this case, but ED still needs running SMPL_Receive() function many times for receiving data from AP.

  • Hi Yan,

    Please take a look over my code, I follow your instruction but ED still can not receive data from AP

    ED side:

    /* wake up radio. we need it to listen for others babbling. */
    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
    /* turn on RX. default is RX off. */
    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
    
    while(1) {
      /* Try sending message MISSES_IN_A_ROW times looking for ack */
      for (uint8_t misses = 0; misses < MISSES_IN_A_ROW; ++misses) {
        if (SMPL_SUCCESS == (rc = SMPL_SendOpt(sLinkID1, msg, sizeof(msg), SMPL_TXOPTION_ACKREQ))) {
          /* Message acked. We're done. Toggle LED 1 to indicate ack received. */
          toggleLED(1);
          UART0SendStr("Recv ACK\r\n");
          break;
        }
        
        if (SMPL_NO_ACK == rc) {
          /* Count ack failures. Could also fail becuase of CCA and
           * we don't want to scan in this case.
           */
          UART0SendStr("Missed ACK\r\n");
          noAck++;
        }
      }
      
      // loop until recv data from AP
      while(1) {
        uint8_t msg[2], len;
        if(SMPL_Receive(sLinkID1, msg, &len) == SMPL_SUCCESS) {
          UART0SendStr("Recv RF data\r\n");
          break;
        }
      }
    }

    Can you guess why?