1
0
mirror of https://github.com/bluekitchen/btstack.git synced 2025-03-25 16:43:28 +00:00

hfp: send BCM command to enable WBS, configure PCM for 8 vs. 16 kHz

hfp: use transparent 16-bit as voice setting for BCM WBS

fix

fix
This commit is contained in:
Matthias Ringwald 2021-01-05 14:15:46 +01:00
parent 067ecc364d
commit 689d4323e4
6 changed files with 85 additions and 4 deletions

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
CC256x: With ENABLE_CC256X_ASSISTED_HFP, HFP enables WBS codec on demand and configures PCM/I2S interface for 8kH/16kHz
BCM: With ENABLE_BCM_PCM_WBS, HFP enables WBS codec on demand and configures PCM/I2S interface for 8kH/16kHz
SDP Client RFCOMM: add `sdp_client_query_rfcomm_channel_and_name_for_service_class_uuid`
HFP AG/HSP AG: avoid connecting to remote service with same role

@ -97,6 +97,7 @@ ENABLE_CROSS_TRANSPORT_KEY_DERIVATION | Enable Cross-Transport Key Derivation (C
ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE | Enable L2CAP Enhanced Retransmission Mode. Mandatory for AVRCP Browsing
ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL | Enable HCI Controller to Host Flow Control, see below
ENABLE_ATT_DELAYED_RESPONSE | Enable support for delayed ATT operations, see [GATT Server](profiles/#sec:GATTServerProfile)
ENABLE_BCM_PCM_WBS | Enable support for Wide-Band Speech codec in BCM controller, requires ENABLE_SCO_OVER_PCM
ENABLE_CC256X_ASSISTED_HFP | Enable support for Assisted HFP mode in CC256x Controller, requires ENABLE_SCO_OVER_PCM
ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND | Enable workaround for bug in CC256x Flow Control during baud rate change, see chipset docs.
ENABLE_CYPRESS_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND | Enable workaround for bug in CYW2070x Flow Control during baud rate change, similar to CC256x.

@ -63,6 +63,10 @@
#error "Assisted HFP is only possible over PCM/I2S. Please add define: ENABLE_SCO_OVER_PCM"
#endif
#if defined(ENABLE_BCM_PCM_WBS) && !defined(ENABLE_SCO_OVER_PCM)
#error "WBS for PCM is only possible over PCM/I2S. Please add define: ENABLE_SCO_OVER_PCM"
#endif
#define HFP_HF_FEATURES_SIZE 10
#define HFP_AG_FEATURES_SIZE 12
@ -701,6 +705,9 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
}
#ifdef ENABLE_CC256X_ASSISTED_HFP
hfp_cc256x_prepare_for_sco(hfp_connection);
#endif
#ifdef ENABLE_BCM_PCM_WBS
hfp_bcm_prepare_for_sco(hfp_connection);
#endif
log_info("hf accept sco %u\n", hfp_connection->hf_accept_sco);
sco_establishment_active = hfp_connection;
@ -793,7 +800,9 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
#ifdef ENABLE_CC256X_ASSISTED_HFP
hfp_connection->cc256x_send_wbs_disassociate = true;
#endif
#ifdef ENABLE_BCM_PCM_WBS
hfp_connection->bcm_send_disable_wbs = true;
#endif
hfp_connection->sco_handle = HCI_CON_HANDLE_INVALID;
hfp_connection->release_audio_connection = 0;
hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
@ -1607,7 +1616,11 @@ void hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection){
sco_establishment_active = hfp_connection;
uint16_t sco_voice_setting = hci_get_sco_voice_setting();
if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
sco_voice_setting = 0x0043; // Transparent data
#ifdef ENABLE_BCM_PCM_WBS
sco_voice_setting = 0x0063; // Transparent data, 16-bit for BCM controllers
#else
sco_voice_setting = 0x0043; // Transparent data, 8-bit otherwise
#endif
}
// get packet types - bits 6-9 are 'don't allow'
uint16_t packet_types = hfp_link_settings[setting].packet_types ^ 0x03c0;
@ -1650,6 +1663,20 @@ void hfp_cc256x_write_codec_config(hfp_connection_t * hfp_connection){
}
#endif
#ifdef ENABLE_BCM_PCM_WBS
void hfp_bcm_prepare_for_sco(hfp_connection_t * hfp_connection){
hfp_connection->bcm_send_write_i2spcm_interface_param = true;
if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
hfp_connection->bcm_send_enable_wbs = true;
}
}
void hfp_bcm_write_i2spcm_interface_param(hfp_connection_t * hfp_connection){
uint8_t sample_rate = (hfp_connection->negotiated_codec == HFP_CODEC_MSBC) ? 1 : 0;
// i2s enable, master, 8/16 kHz, 2048 kHz
hci_send_cmd(&hci_bcm_write_i2spcm_interface_param, 1, 1, sample_rate, 4);
}
#endif
void hfp_set_hf_callback(btstack_packet_handler_t callback){
hfp_hf_callback = callback;
}

@ -648,7 +648,11 @@ typedef struct hfp_connection {
bool cc256x_send_wbs_associate;
bool cc256x_send_wbs_disassociate;
#endif
#ifdef ENABLE_BCM_PCM_WBS
bool bcm_send_enable_wbs;
bool bcm_send_disable_wbs;
bool bcm_send_write_i2spcm_interface_param;
#endif
} hfp_connection_t;
// UTILS_START : TODO move to utils
@ -711,6 +715,10 @@ const char * hfp_enhanced_call_mpty2str(uint16_t index);
void hfp_cc256x_prepare_for_sco(hfp_connection_t * hfp_connection);
void hfp_cc256x_write_codec_config(hfp_connection_t * hfp_connection);
#endif
#ifdef ENABLE_BCM_PCM_WBS
void hfp_bcm_prepare_for_sco(hfp_connection_t * hfp_connection);
void hfp_bcm_write_i2spcm_interface_param (hfp_connection_t * hfp_connection);
#endif
/**
* @brief Set packet types for SCO connections

@ -1737,6 +1737,26 @@ static void hfp_ag_run_for_context(hfp_connection_t *hfp_connection){
return;
}
#endif
#ifdef ENABLE_BCM_PCM_WBS
// Enable WBS
if (hfp_connection->bcm_send_enable_wbs){
hfp_connection->bcm_send_enable_wbs = false;
hci_send_cmd(&hci_bcm_enable_wbs, 1, 2);
return;
}
// Write I2S/PCM params
if (hfp_connection->bcm_send_write_i2spcm_interface_param){
hfp_connection->bcm_send_write_i2spcm_interface_param = false;
hfp_bcm_write_i2spcm_interface_param(hfp_connection);
return;
}
// Disable WBS
if (hfp_connection->bcm_send_disable_wbs){
hfp_connection->bcm_send_disable_wbs = false;
hci_send_cmd(&hci_bcm_enable_wbs, 0, 2);
return;
}
#endif
if (!rfcomm_can_send_packet_now(hfp_connection->rfcomm_cid)) {
log_info("hfp_ag_run_for_context: request can send for 0x%02x", hfp_connection->rfcomm_cid);

@ -567,6 +567,26 @@ static void hfp_hf_run_for_context(hfp_connection_t * hfp_connection){
return;
}
#endif
#ifdef ENABLE_BCM_PCM_WBS
// Enable WBS
if (hfp_connection->bcm_send_enable_wbs){
hfp_connection->bcm_send_enable_wbs = false;
hci_send_cmd(&hci_bcm_enable_wbs, 1, 2);
return;
}
// Write I2S/PCM params
if (hfp_connection->bcm_send_write_i2spcm_interface_param){
hfp_connection->bcm_send_write_i2spcm_interface_param = false;
hfp_bcm_write_i2spcm_interface_param(hfp_connection);
return;
}
// Disable WBS
if (hfp_connection->bcm_send_disable_wbs){
hfp_connection->bcm_send_disable_wbs = false;
hci_send_cmd(&hci_bcm_enable_wbs, 0, 2);
return;
}
#endif
if (hfp_connection->hf_accept_sco){
@ -599,7 +619,11 @@ static void hfp_hf_run_for_context(hfp_connection_t * hfp_connection){
// mSBC only allows for transparent data
uint16_t sco_voice_setting = hci_get_sco_voice_setting();
if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
sco_voice_setting = 0x0043; // Transparent data
#ifdef ENABLE_BCM_PCM_WBS
sco_voice_setting = 0x0063; // Transparent data, 16-bit for BCM controllers
#else
sco_voice_setting = 0x0043; // Transparent data, 8-bit otherwise
#endif
}
// filter packet types