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

nRF8001 Data Credit System Details

I wrote my own ACI interfacing code, so I have questions about some details of the data credit system that most devs may be insulated from by the Nordic SDK.

Section 25 of the nRF8001 Product Specification (page 133, Revision 1.2) lists 5 "data commands": SetLocalData, SendData, SendDataAck, RequestData, and SendDataNack. But of these, only SendData and SendDataNack list a DataCreditEvent as a possible return packet in their "Returned events" sections. Presumably, the remaining 3 "data commands" that cannot return data credits should NOT have credits charged against them on transmission. Is that correct?

I'm a bit suspicious of the accuracy of the documentation. In particular, it seems strange that SendDataNack would consume a credit while SendDataAck does not. And RequestData presumably involves a radio transmission as well; does it not consume a data credit?

Alone among the data commands, SetLocalData returns a regular CommandResponseEvent. And if I understand its function correctly, it cannot trigger any radio communication. Is it fair to say that SetLocalData is really just a regular command and should in no way be treated as a "data command"? That is, not only should it not be charged a data credit, but it should also block all other non-data commands until the CommandResponseEvent is received?

  • Hi Garth,

    You are correct that the documentation is appears in-correct with respect to RequestData.

    There are 3 pieces in the documentation that refer to the DataCredits being returned after a RequestData , SendDataAck, SendDataNack

    1. Table 28.ACI commands and events affecting command buffer memory credits
    2. The section 25.x that lists the returned Events for the Command
    3. Table 34. Data commands format overview

    The Table 28 lists the RequestData as "RequestData Uses ONE available credit" which is conflicting with the other two entries. I suspect that you are correct and the RequestData does use 1 credit, this however needs to be verified.

    The returned events for the "SendDataAck" is marked as "None" which is in conflict with the other two entries. This is incorrect. The "SendDataAck" does use 1 credit as stated in the other two entries.

    SetLocalData: This is works as a ordinary ACI command as it does not use a DataCredit and returns a Command Response event, however it is used for Broadcast pipes (advertising) and Set pipes so that is the likely reason it is grouped under data commands. You are correct that it does not block any of the other commands.

    Others:

    You must also note that most of the commands do not block other commands, a few commands like OpenRemotePipe, CloseRemotePipe, RequestData which must be used only after Service Discovery of the peer is finished, they also block each other until they are completed. See the documentation of the commands for details.

    SendData on the ACK pipe on local GATT Server will also block another SendData being sent on all ACK pipes on the local GATT Server until the ACK is received. SendData on the ACK pipe on remote - using the GATT client will also block another SendData being sent on all ACK pipes on the remote using GATT Client until the ACK is received.

  • In addition if a send data commands or request data fails with a PipeError, the credit used for the send data/request data needs to be recovered. case ACI_EVT_PIPE_ERROR: //See the appendix in the nRF8001 Product Specication for details on the error codes Serial.print(F("ACI Evt Pipe Error: Pipe #:")); Serial.print(aci_evt->params.pipe_error.pipe_number, DEC); Serial.print(F(" Pipe Error Code: 0x")); Serial.println(aci_evt->params.pipe_error.error_code, HEX);

        //Increment the credit available as the data packet was not sent.
        //The pipe error also represents the Attribute protocol Error Response sent from the peer and that should not be counted 
        //for the credit.
        if (ACI_STATUS_ERROR_PEER_ATT_ERROR != aci_evt->params.pipe_error.error_code)
        {
          aci_state.data_credit_available++;
        }
        break;
    
  • Thank you for this detailed and thoughtful response, and best wishes for a happy new year. This is very helpful.

    I think this points me toward all the information I needed, but just for the sake of providing feedback on the documentation, it's surprising to me that you mention that "most...commands do not block other commands". I had been under the impression that there could only ever be one non-data command outstanding, for the reasons outlined below. (Mind you, I'm not arguing or nitpicking -- I'm just pointing out an additional area where the documentation might be potentially misleading.)

    The text of Section 19.x divides ACI packets into three groups: system commands, data commands, and events. And then in Section 21.1, "System command buffering", the product spec states explicitly that "Only one System Command can be outstanding at any moment in time before the application controller is allowed to send another one...The application controller must receive an event confirming the execution of the command before sending the next system command."

    It does make intuitive sense that some packets classified as system commands might be more lenient in their behavior, but the overall impression I had had from reading these sections was that any outgoing (controller-to-nRF8001) command that was not a data command should be sent only when no other commands were pending.

  • I agree that the documentation can be improved. I will add a task in the project to have a better way to communicate this and re-phrase some of the currently restrictive text.

  • I am looking into problems with my radio communication related to dropped command responses to setLocalData commands. And I found this thoughtful discussion. Like Garth, I am trying to understand exactly how the radio works so my code can be totally reliable. And while the documentation is very good considering, it doesn't answer all questions. I totally agree with Garth's point that the docs indicate system commands have to be single threaded. And it's not clear how setLocalData fits with that because it's listed as a Data command but doesn't use credits like the others. Tuning up some of these discussions in the reference manual to be clearer would be helpful. But, overall, thanks for the good documentation.

Related