This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRF 52 (PCA10040) GZLL Host Rx Issue

Hi guys. I'm currently stumped by a most peculiar issue.

Im using two PCA10040 boards (20 cm apart) to send a data stream via the GZLL protocol: DEVICE button pressed -> DEVICE sends two bytes (uint16_t) that pretty much tell the HOST how many bytes make up a complete message, then the DEVICE sends the actual payload, in 32 bytes increments.

this is are the releant typedefs:

typedef enum
{
PAYLOAD_STATUS_STANDBY,         // waiting to send/ receive


PAYLOAD_STATUS_HEADER_SENT,     // a header has been sent
PAYLOAD_STATUS_SENDING_DATA,    // a header has been received, we are now sending the actual payload

PAYLOAD_STATUS_RECEIVING_DATA,  // a header has been received, we are now receiving the payload

} CORE_PAYLOAD_STATUS_typedef;

typedef struct
{
    union
    {
    uint16_t Uint;                      // the payload length
    uint8_t Bytes[2];
    } Header;                           // this basically converts two bytes to an uint16_t
uint8_t Buffer[1024];                   // this is actual payload
uint16_t Offset;                        // used to append data to the Buffer, at the correct position
CORE_PAYLOAD_STATUS_typedef Status;
} CORE_PAYLOAD_typedef;

i have the same project for both host and device, which is pretty much a copy paste of the project provided in the sdk (v17 i think) - the only difference being a #define HOST which handles Gzll's init.

Now, the problem:

If I send 512 bytes or less, the whole process works flawlessly.

However, if i try and send 1022 or 980, for example, it fails. Miserably.

// THIS IS THE ROUTINE USED TO SEND THE HEADER. IT WORKS

static void SendData                      (uint8_t* data, uint16_t size)
{
  private.TxPayload.Header.Uint = size;
  memcpy(private.TxPayload.Buffer, data, size);
  NRF_LOG_INFO("WIRELESS SENDING %u HEADER", private.TxPayload.Header.Uint);
  bool result = nrf_gzll_add_packet_to_tx_fifo(0, private.TxPayload.Header.Bytes, 2);
  ErrorHandler(result, "ERROR SENDING HEADER");

  private.TxPayload.Status = PAYLOAD_STATUS_HEADER_SENT;
}

after I use the above, I wait for the nrf_gzll_device_tx_success callback.

// HANDLE THE DATA SENDING

    // A HEADER HAS BEEN RECEIVED BY THE HOST
    if(private.TxPayload.Status == PAYLOAD_STATUS_HEADER_SENT)
    {
      // SWITCH STATUS TO DATA SENDING
      private.TxPayload.Status = PAYLOAD_STATUS_SENDING_DATA;
      NRF_LOG_INFO("WIRELESS HEADER SENT");
    }

    if(private.TxPayload.Status == PAYLOAD_STATUS_SENDING_DATA)
    {
      // SELECT THE FIRST 32 OR THE REMAINING BYTES FROM THE PAYLOAD
      uint32_t bytesToSend = MIN(32, private.TxPayload.Header.Uint - private.TxPayload.Offset);

      // SEND THE DATA TO THE FIFO
      while(nrf_gzll_add_packet_to_tx_fifo(0, private.TxPayload.Buffer + private.TxPayload.Offset, bytesToSend) != true)
      {
        NRF_LOG_INFO("NU S A PUTUT COAE");
      }
      
      // INCREASE THE STEP
      private.TxPayload.Offset += bytesToSend;
      //NRF_LOG_INFO("FRAME - OFFSET SIZE %u", private.TxPayload.Offset);

      
      // IF ALL THE BYTES HAVE BEEN SENT, SWITCH TO STANDBY
      if(private.TxPayload.Offset == private.TxPayload.MessageLength.Uint)
      {
        private.TxPayload.Status = PAYLOAD_STATUS_STANDBY;
        private.TxPayload.Offset = 0;
        NRF_LOG_INFO("SENT A MESSAGE");
      }
    }

 This works as well, I always receive the correct number of callbacks. However, on the host side, the MCU hangs on nrf_gzll_host_rx_data_ready:

    uint32_t data_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
    nrf_gzll_error_code_t errorCode;
    // THIS ALWAYS FIRES
    if(private.RxPayload.Status == PAYLOAD_STATUS_STANDBY)
    {
      nrf_gzll_fetch_packet_from_rx_fifo(pipe, m_data_payload, &data_payload_length);
      memcpy(private.RxPayload.Header.Bytes, m_data_payload, data_payload_length);
      private.RxPayload.Status = PAYLOAD_STATUS_RECEIVING_DATA;
      NRF_LOG_INFO("HEADER SIZE RECEIVED: %u", private.RxPayload.Header.Uint);
    }

    // THIS HANGS
    while(nrf_gzll_fetch_packet_from_rx_fifo(pipe, m_data_payload, &data_payload_length) != false)
    {
          NRF_LOG_INFO("1");
      if(private.RxPayload.Status == PAYLOAD_STATUS_RECEIVING_DATA)
      {
        memcpy(private.RxPayload.Buffer + private.RxPayload.Offset, m_data_payload, data_payload_length);
        private.RxPayload.Offset += data_payload_length;
        NRF_LOG_INFO("REC %lu", private.RxPayload.Offset);
        if(private.RxPayload.Offset == private.RxPayload.Header.Uint)
        {
          private.RxPayload.Status = PAYLOAD_STATUS_STANDBY;
          private.RxPayload.Offset = 0;
          RaiseNewDataAvailableEvent(private.RxPayload.Buffer, private.RxPayload.MessageLength.Uint);
        }
      }
    }
          NRF_LOG_INFO("2");

Now, if I send 512 bytes, it works perfectly. However, if I try and send 1022:

<info> app: HEADER SIZE RECEIVED: 1024
<info> app: 2
<info> app: 1
<info> app: REC 32
<info> app: 2
<info> app: 1
<info> app: REC 64
<info> app: 2
<info> app: 1
<info> app: REC 96
<info> app: 2
<info> app: 1
<info> app: REC 128
<info> app: 2
<info> app: 1
<info> app: REC 160
<info> app: 2
<info> app: 1
<info> app: REC 192
<info> app: 2
<info> app: 1
<info> app: REC 224
<info> app: 2
<info> app: 1
<info> app: REC 256
<info> app: 2
<info> app: 1
<info> app: REC 288
<info> app: 2
<info> app: 1
<info> app: REC 320
<info> app: 2
<info> app: 1
<info> app: REC 352
<info> app: 2
<info> app: 2
<info> app: 2
<info> app: 2
<info> app: 2
<info> app: 2
<info> app: 2
<info> app: 2
<info> app: 2
<info> app: 2
<info> app: 2
<info> app: 2
<info> app: 2

this is the output.

I am going crazy. I've stayed up till 4 am. I cant for the life of me figure it out.

BTW: stack heap & size are 8096.

Parents Reply Children
No Data
Related