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.

CC2652R: A Method for Evaluating Channel Quality in BLE Communications

Part Number: CC2652R

Is it possible to retrieve the following metrics from a user application using the “SimpleLink CC13xx/26xx BLE5-Stack” SDK?

  • RSSI
  • PER
  • Number of packet retransmissions
  • SNR (Signal-to-Noise Ratio) or SNIR (Signal-to-Interference-plus-Noise Ratio)
  • Throughput

 

I am using the Launchpad CC26X2R hardware.

 

 

Thank you in advance.

  • Hi !

    For most of these, you can use HCI commands directly to get the information you need.

    For the RSSI, you HCI_ReadRssiCmd function.
    For the PER you can use the HCI_EXT_PacketErrorRateCmd function.
    For the retransmissions, HCI_EXT_GetTxStatisticsCmd returns the number of packets retransmissions and total number of packets among other information.

    For the throughput, there is no exact way to get it but you can estimate it. You can use HCI_EXT_GetTxStatisticsCmd to see the number of packets sent at an instant T and HCI_LE_ReadMaxDataLenCmd to read the max size of packets transmitted. If you call HCI_EXT_GetTxStatisticsCmd two times with a delay, you can measure the number of packets sent during this delay, multiply by the maximum length and divide by the delay to get your throughput.

    Finally, there is no way as far as I know to get the SNR/SNIR values.

    Kind regards,
    Lea

  • Hi !

    Thank you for your response.

    Can the commands you provided be used to retrieve data on a per-channel basis?

    For example, the PER for Channel 0.

    Also, I’m having a bit of trouble understanding how throughput is calculated.

    Is it correct to count the number of packets successfully transmitted during a given time period and divide that by the duration of that period?

    If that’s correct, I don’t understand why we need to retrieve the maximum packet size...

    Kind regards,

  • Hi ! 

    Yes there is ! You can use the HCI_EXT_PERbyChanCmd command instead to get the PER for a specific channel.

    For the throughput, we used to have an example for CC26XX in the F2 SDK. What the example did was set up a peripheral to send a bunch of notifications as fast as it could. The central would then measure the amounts of bits received, add it to a counter and start a 1000ms timer. After the timer was up, it would simple print the amount of bits and it counted for a second, which gives a result in bits/s.

    You can find the example here : https://github.com/TexasInstruments-Sandbox/ble_examples/tree/ble_examples-2.2/src/examples

    My advice is to do the same thing but on the latest SDK : send a bunch of packets from a peripheral, read their length on the central, and measure the throughput that way. The reason I advised to use HCI_LE_ReadMaxDataLenCmd was to get the packet length, but that's not really necessary.

    Kind regards,
    Lea

  • Hi !

    Thank you for your reply.

    So there is such a command! I apologize for not researching it thoroughly enough.
    I checked the link you provided, but could you please explain how to use this command?

    - Is the PER for each channel stored in the member array of the “perByChan” argument? For example, is Channel 0 stored at index 0 of the array?

    - When I issue this command, can I retrieve the PER for each channel as of that moment?

    - Or does it retrieve the PER since the command was issued?

    Thank you also for the information on throughput. I’ll take a look at the example you provided.

    Kind regards,

  • Hi !

    You're correct, the PER for each channel is stored in the "perByChan" argument with channel N stored at index N of the array. This HCI command takes a pointer to a perByChan_t object as a parameter. The command will fill out the object with the PER values for each channels, and the data becomes valid to read when you receive the hciEvt_VSCmdComplete_t event with cmdOpcode HCI_EXT_PER_BY_CHAN. The memory region pointed by perByChan argument needs to exist for the entire duration of the command, therefore it cannot be allocated on the stack of the calling function.

    When you issue the command, it will give you the data that was accumulated by the controller. The documentation says that since the counters are 16 bits, the counters can store at least 8 minutes of data when using the smallest connection interval possible, and more time when using a larger connection interval.

    Do note that the PERbyChan command gives only the total number of packets and the total number of CRC errors per channels, while using the PacketErrorRate command also give you the number of events and the number of missed events.

    Kind regards,
    Lea

  • Hi !

    Thank you for your response.That really helps.  

    I have a few questions.  

    1. You mentioned that “therefore it cannot be allocated on the stack of the calling function.” Does this mean that variables of type `perByChan_t` used as arguments are acceptable if they are module variables or global variables?  

    2. Just to confirm, when you say “it will give you the data that was accumulated by the controller,” does this refer to data accumulated from the time the connection is established until the command is issued?  

    3. Assuming we use the shortest connection interval and save 8 minutes of data, what happens after that?

    - Can subsequent data not be retrieved? Or is it not updated?

    - Is it cleared and new data begins accumulating?

    4. You mentioned that data can be read after an event occurs. Is it possible for a user to clear the values that can be read from the controller?
    For example,  
      Send command → Read value via event → Clear value → Send command...
    Is it possible to use it in this way?


    I am asking these questions because I am considering whether it would be possible for the user to evaluate the communication quality of each channel and update the channel map accordingly.

    Kind regards,

  • Hi !

    1. Yes, the 2 options you have should be either global variables or allocated on the heap through dynamic memory allocations (malloc)

    2 & 3. I was a little bit wrong about how the counters work, here is what happens. For each connection object, there is a field called perByChan_t pointer field called "perInfoByChan", set to NULL upon creation of the connection. When sending the HCI_EXT_PERbyChanCmd command, the only thing that is done is that this field now points to the object you have given as a parameter. Then, when a BLE event happens such as sending a packet or receiving a CRC error, if the perInfoByChan pointer is not null, it will update the counters in the object. This means that the counters only start from when you are calling the function. After 8 minutes, the counters can overflow if you are using the shortest connection interval, and they will wrap around back to 0 since they are unsigned integers, giving incoherent data.

    4. Since the counters are being increased by the BLE stack, and stored on your side through malloc or a global variable, you can actuallt read and clear them whenever you want, even from an interrupt routine.

    Therefore, what you can do is call PERbyChanCmd at the start of your software, read the values every X seconds to take your channel map update decision accordingly, and reset all values to 0 every 8 minutes.

    Kind regards,
    Lea

  • Hi,

    Thank you for your response.

    I understand that “This means that the counters only start from when you are calling the function.”

    I also understand the concept of the counter.

    Based on your previous responses,

    I understand that calling `free` on memory allocated with `malloc` clears the counter (ends the count).

    Is that correct?

    Kind regards,

  • Hi !

    If the only thing you do is free the memory allocated, you will get a segmentation fault in your software, because the controller will still try to write to the memory address you previously allocated.

    What you need to do is to first call the HCI_EXT_PERbyChanCmd function with NULL as the parameter "perByChan", and then free the memory. This is because according to the documentation of HCI_EXT_PERbyChanCmd : "If perByChan is NULL, counter accumulation will be discontinued".

    Kind regards,
    Lea

  • Hi,

    Thank you for your response.

    I understand that I need to set the value to NULL before freeing the memory.


    I understand that PER can be retrieved for each channel, but what about the other commands?

    • HCI_ReadRssiCmd
    • HCI_EXT_GetTxStatisticsCmd

    Kind regards,

  • Hi !

    There is no channel-specific equivalent for these functions.
    Note that HCI_EXT_GetTxStatisticsCmd give the same info as HCI_EXT_PERbyChanCmd, but also gives data on the control packets and the number of retransmissions.

    Kind regards,
    Lea

  • Hi !

    Thank you for your response.

    I understand completely.

    Kind regards,