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.

CC2564: CC2564 and A3DP Source Demo

Part Number: CC2564

Hi,

My customer is developing a product using CC2564 and STM32.

They have a technical question that need to resolve as soon as possible:

We are using the A3DP Source Demo application, and it connects to a remote sink device and streams music as expected, so far so good.
Then when we want to pause the audio stream, we call Pause(NULL), if we keep the stream paused for 30sec or longer, when we start the stream again, then the audio heard at the remote sink is distorted.

If we keep the audio stream paused for a shorter period of time, say 10sec, then the audio heard at the remote sink is good.

Thanks,

Chuchen

  • Hello Chuchen,

    Please send us more details, The exact scenario and some FW logs
    so we can go over and see what could be the issue.

    BR,
    Chen Loewy
  • Hi,
    Thank you for your response, here are some details:
    We are using A3DPDemo_SRC application as the base, so in A3DPDemo_SRC.c when we receive 'etAUD_Stream_Open_Confirmation' event, we handle it as follows:
    case etAUD_Stream_Open_Confirmation:
    if (AUD_Event_Data->Event_Data.AUD_Stream_Open_Confirmation_Data->OpenStatus == AUD_STREAM_OPEN_CONFIRMATION_STATUS_SUCCESS)
    {
    // this opens the stream, and returns a successful result of zero.
    int result = OpenA3DPStream(AUD_Event_Data->Event_Data.AUD_Stream_Open_Confirmation_Data);

    /* Track this connection's BD_ADDR. */
    RemoteSinkBD_ADDR = AUD_Event_Data->Event_Data.AUD_Stream_Open_Confirmation_Data->BD_ADDR;

    A3DP_RemoteName();

    }


    then after a user action, we call Play(NULL) :

    static int Play(ParameterList_t *TempParam)
    {
    int ret_val;
    // calling this function always returns zero, which means TI sucessfully requested a change in the state of the stream.
    ret_val = AUD_Change_Stream_State(BluetoothStackID, RemoteSinkBD_ADDR, astSRC, astStreamStarted);

    if (ret_val)
    {
    DisplayFunctionError("AUD_Change_Stream_State-Play", ret_val);
    ret_val = FUNCTION_ERROR;
    }
    else
    {
    DisplayFunctionSuccess("AUD_Change_Stream_State-Play");
    }

    return (ret_val);
    }

    Then, when we receive confirmation of a successfully change of the stream state, we do the following:

    case etAUD_Stream_State_Change_Confirmation:
    if (AUD_Event_Data->Event_Data.AUD_Stream_State_Change_Confirmation_Data->StreamState == astStreamStarted)
    StartA3DPStream();
    else
    StopA3DPStream();


    A3DP_SendRegisterNotificationResponse(AVRCP_EVENT_PLAYBACK_STATUS_CHANGED, AVRCP_RESPONSE_CHANGED, AUD_Event_Data->Event_Data.AUD_Stream_State_Change_Confirmation_Data->StreamState, 0x00000001, A3DP_GetRemoteSinkBD_ADDR(), A3DP_GetTransactionID());

    break;


    where StartA3DPStream() is implemented as follows:
    static int StartA3DPStream(void)
    {
    int ret_val = 0;

    if (!A3DPPlaying)
    {
    //this call always returns zero
    ret_val = VS_A3DP_Start_Stream(BluetoothStackID, A3DPConnectionHandle);
    Display(("A3DP Start: %d\r\n", ret_val));

    if (ret_val == 0)
    {
    A3DPPlaying = TRUE;
    //there is no place in the a3dp source demo application where the stream state is set to 'ssPending', so this condition always
    // evaluates to true, and StreamState is set to 'ssStarted'
    if (StreamState != ssPending) {
    StreamState = ssStarted;
    Display(("A3DP Stream state set to ssStarted \r\n" ));
    }
    }
    else
    Display(("A3DP stayed FALSE, and StreamState did NOT change to ssStarted \r\n"));
    }
    else
    {
    ret_val = FUNCTION_ERROR;
    Display(("A3DP already started.\r\n"));
    }
    return (ret_val);
    }

    At this point, we are able to hear the audio stream on the connected headphone, so far so good.
    Now, on a user action, we want to pause the audio stream, so we call Pause(NULL), which calls AUD_Change_Stream_State(BluetoothStackID, RemoteSinkBD_ADDR, astSRC, astStreamStopped);

    and this call to change the audio stream state to stopped, always returns zero, which my understanding is that it means the call was successfully made....correct?

    then we receive the confirmation event : etAUD_Stream_State_Change_Confirmation, and this function is called : StopA3DPStream();
    where :
    static int StopA3DPStream(void)
    {
    int ret_val;

    if (A3DPPlaying)
    {
    //this call always returns zero
    ret_val = VS_A3DP_Stop_Stream(BluetoothStackID, A3DPConnectionHandle, STOP_STREAM_FLAG_FLUSH_DATA);

    A3DPPlaying = FALSE;

    if (StreamState != ssPending)
    StreamState = ssStopped;
    }
    else
    {
    ret_val = FUNCTION_ERROR;
    Display(("A3DP not started.\r\n"));
    }

    return (ret_val);
    }

    At this point the audio stream stops playing, if we keep the audio stream paused for less than 30sec, and then call Play(NULL) again, just as shown above, then audio re-starts normal.
    BUT, if we keep the audio stream paused for 30sec or more, then when calling Play(NULL), then the audio stream starts, but is distorted.
    I'll attach a print of the logs shortly, but I did not see anything obvious, since all the calls return success.

    Your insight is greatly appreciated.
    thank you,
    Elisa
  • attaching a file with some logs, I did not see any errors,  but we do hear audio distorted after the stream is changed back to ssStarted, after a 30sec pause.

    Your help is greatly appreciated.

    Cordially,

    Elisa

    Device, *
    * GetRemoteName, OpenSink, CloseSink, Play, *
    * Pause, Help *
    ******************************************************************
    A3DP_OpenConnection: Success
    5260: HEADSET_InitPaired
    A3DP_InsertLinkKey
    NVM Headset BD_ADDR: 0xB869C22BC6C9.
    NVM Headset LinkKey: 0xA41BC4A64167F93C0FA2BD0FFBF34064
    5274: HEADSET_ManualConnect
    5277: - Connect to JBL Reflect Mini BT [0x20000839]
    A3DP_StartConnection()
    Connect to BD_ADDR: 0xB869C22BC6C9.
    Auto-connecting to 0xB869C22BC6C9 via AUD...

    5950: HEADSET_InitPaired
    A3DP_InsertLinkKey
    NVM Headset BD_ADDR: 0xB869C22BC6C9.
    NVM Headset LinkKey: 0xA41BC4A64167F93C0FA2BD0FFBF34064
    5983: HEADSET_ManualConnect
    5989: - Connect to JBL Reflect Mini BT [0x20000839]
    A3DP_StartConnection()
    Connect to BD_ADDR: 0xB869C22BC6C9.


    atLinkKeyRequest: 0xB869C22BC6C9
    Found LinkKeyInfo (index=0):
    GAP_Authentication_Response success.
    BOOMS>
    atAuthenticationStatus: 0 for 0xB869C22BC6C9
    7728: HEADSET_Paired
    BOOMS>
    etEncryption_Change_Result for 0xB869C22BC6C9, Status: 0x00, Mode: Enabled.

    BOOMS>
    etAUD_Signalling_Channel_Open_Indication
    BD_ADDR: 0xB869C22BC6C9

    BOOMS>
    etAUD_Stream_Open_Confirmation
    Status: 0
    BD_ADDR: 0xB869C22BC6C9
    MediaMTU: 895
    A3DP Open: 0
    Initialize audio with Sample Freq: 48000
    Stream Format:
    Frequency: 48000
    Channels: 2
    Flags: 0
    AUD_Change_Stream_State-Play success.
    8081: - etAUD_Stream_Open_Confirmation
    8090: HEADSET_Connected
    BOOMS>
    etAUD_Stream_State_Change_Confirmation
    BD_ADDR: 0xB869C22BC6C9
    StreamState: Started
    A3DP Start: 0
    A3DP Stream state set to ssStarted
    Sending Register Notification of a Playback Status CHANGED


    etAUD_Remote_Control_Open_Indication
    BD_ADDR: 0xB869C22BC6C9
    AVRCP(Notification) command sent successfully.
    9203: - etAUD_Remote_Control_Open_Indication
    9213: HEADSET_Connected
    BOOMS>
    etAUD_Remote_Control_Command_Confirmation: 10
    RCCC Status: 0
    RCCC MSG Type: 19
    A3DP_ProcessRemoteControlCmdConfirmation: 19
    RCCC EVENT ID: 13
    RCCC VOLUME: 32
    A3DP_ProcessRemoteControlCmdConfirmation: AVRCP_RESPONSE_INTERIM
    9275: - etAUD_Remote_Control_Command_Confirmation

    etAUD_Remote_Control_Command_Indication
    MessageType: 8
    amtGetCapabilities: 3
    RemoteControl Capabilities response: 0

    BOOMS>
    etAUD_Remote_Control_Command_Indication
    MessageType: 19
    amtRegisterNotification- EventID: 1
    Playback Notification Registered
    RemoteControl Notification response: 0


    etAUD_Remote_Control_Command_Confirmation: 10
    RCCC Status: 0
    RCCC MSG Type: 22
    A3DP_ProcessRemoteControlCmdConfirmation: 22
    11404: - etAUD_Remote_Control_Command_Confirmation


    etAUD_Remote_Control_Command_Confirmation: 10
    RCCC Status: 0
    RCCC MSG Type: 22
    A3DP_ProcessRemoteControlCmdConfirmation: 22
    29923: - etAUD_Remote_Control_Command_Confirmation

    123816: - AVRCP_EVENT_PLAYBACK_STATUS_CHANGED

    123827: - Pause
    AUD_Change_Stream_State-Pause success.
    etAUD_Stream_State_Change_Confirmation
    BD_ADDR: 0xB869C22BC6C9
    StreamState: Suspended
    A3DP Stop: 0
    Sending Register Notification of a Playback Status CHANGED


    etAUD_Remote_Control_Command_Indication
    MessageType: 19
    amtRegisterNotification- EventID: 1
    Playback Notification Registered
    RemoteControl Notification response: 0


    185604: - AVRCP_EVENT_PLAYBACK_STATUS_CHANGED

    185615: - Play
    AUD_Change_Stream_State-Play success.
    etAUD_Stream_State_Change_Confirmation
    BD_ADDR: 0xB869C22BC6C9
    StreamState: Started
    A3DP Start: 0
    A3DP Stream state set to ssStarted
    Sending Register Notification of a Playback Status CHANGED


    etAUD_Remote_Control_Command_Indication
    MessageType: 19
    amtRegisterNotification- EventID: 1
    Playback Notification Registered
    RemoteControl Notification response: 0

  • Hello Elisa,

    Thanks for the information.

    I will loop in our BT expert of the upper protocol to help you with the UPS.

    Do you know how to take FW logs?
    If not please take a look at the following link: processors.wiki.ti.com/.../CC256x
    at the logs portion and tools.

    Once you add these logs i will be able to see what exactly does the FW receive and it will help us understand if your issue is UPS issue or FW issue.
    So our BT UPS expert will address this issue shortly and in the meanwhile if you can provide us with FW logs that would be great.

    BR,
    Chen Loewy
  • Unfortunately, our hardware does not have access to the TX_DBG pin at the moment.
    Is there anything else we could do?
  • Hi Elisa,

    The bad news is that without the FW log messages i'm mainly guessing here and can't really see what happens.
    I will consult with the upper stack expert and see what can we learn from the UPS and get back to you.

    BR,
    Chen Loewy
  • Which host are you using? You may also want to check, if longer pause is resulting in host entering into some low power states and on resumption it may be losing some context data?

    Thanks
  • Thank you, I appreciate your assistance, I am new to working with TI's CC2564, so I am trying to follow A3DP Source Demo.

    Is there a particular way,  we should be executing the function calls? maybe we are missing some other call I should be doing. A connection to the remote sink is already established, and changing the stream state to Started, and then calling VS_A3DP_Start_Stream(), seems to work fine, because we can hear our audio stream at the connected remote sink.

    So, in order to pause, we are following a similar sequence: 

    - Change the stream state to Pause,

    - Call VS_A3DP_Stop_Stream()

    That sequence does pause the audio, but for some reason, leaving the audio stream paused for 30sec or longer, seems to distort it.  May it be possible that the AUD library thinks/assumes that there would be no more audio streaming after 30sec?

    Is the application level supposed to close the audio path and re-starts after a pause that long?

  • Ah, I see, We are using STM32F411, it does enter sleep mode after but 20min of no audio streaming. I'll re-check, if there is any other similar scenario or condition.
  • For test purposes, please disable any low power modes/ Idle modes you may be using from your application/environment. This way you can eliminate any power related issues..
  • Hi 

    I can confirm that our hardware and application, does not have any low power or idle mode enable, and we are still observing the same behavior, after a 30sec stop/pause or longer, starting the audio stream produces distorted audio.

    I tried reconfiguring the stream after it was stopped (VS_A3DP_Stop_Stream()), I used VS_PCM_Codec_Config_Slave_I2S() and VS_A3DP_Codec_Configuration() to reconfigure it;  but no success.

    I noticed A3DPDemo has 3 states for the stream : Started, Pending and Stopped; but the AUDAPI.h has only two states : started and stopped. Is there any particular reason for this difference?

    I also noticed that the state Pending is never set in the application.

    I am using : VS_A3DP_Stop_Stream()  to stop the audio stream, Is that the right function use, I have been looking for one to pause or suspend, but could not find any. ?

    Any insight is greatly appreciated, We have had this problem for a long time, and we can not find a way to fix it.

    Thank you 

  • Hello,

    Reading through the A3DPDemo_SRC.c we found he following lines:

    if ((HCI_DriverInformation.DriverInformation.COMMDriverInformation.Protocol == cpHCILL) || (HCI_DriverInformation.DriverInformation.COMMDriverInformation.Protocol == cpHCILL_RTS_CTS)) {
    HCILLConfig.SleepCallbackFunction = HCI_Sleep_Callback;
    HCILLConfig.SleepCallbackParameter = 0;
    DriverReconfigureData.ReconfigureCommand = HCI_COMM_DRIVER_RECONFIGURE_DATA_COMMAND_CHANGE_HCILL_PARAMETERS;
    DriverReconfigureData.ReconfigureData = (void *)&HCILLConfig;
    /* Register the sleep mode callback. Note that if this */
    /* function returns greater than 0 then sleep is currently */
    /* enabled. */
    Result = HCI_Reconfigure_Driver((unsigned int)Result, FALSE, &DriverReconfigureData);
    if (Result > 0) {
    /* Flag that sleep mode is enabled. */
    Display(("\n\r ***** Sleep is allowed. ***** \r\n"));
    }
    } else {
    Error = -1;
    }

    So, we looked for the callback function, and added a display message:

    /* The following is the HCI Sleep Callback. This is registered with */
    /* the stack to note when the Host processor may enter into a sleep */
    /* mode. */
    void BTPSAPI HCI_Sleep_Callback(Boolean_t SleepAllowed, unsigned long CallbackParameter) {
    //xxx Monitor low power state
    Display(("\n\r Sleep Allowed : %d \n\r", SleepAllowed));
    Display(("\n\r CallbackParameter : %d \n\r", CallbackParameter));
    }

    And it turns out that we do receive this callback function after 30sec or more of no audio stream present, so it looks like TI is the one going to sleep.

    Now the question is, How can we disable this sleep mode?

    We have been looking at BluetopiaCoreAPI.pdf but I can't find how.

    Your input is appreciated, Thanks.