240 lines
7.4 KiB
C
240 lines
7.4 KiB
C
|
#include "app_config.h"
|
||
|
#include "app_task.h"
|
||
|
#include "app_btdm.h"
|
||
|
#include "app_audio.h"
|
||
|
#include "app_ble.h"
|
||
|
#include "app_bt.h"
|
||
|
#include "user_bt.h"
|
||
|
#include "fr_device_pmu_io.h"
|
||
|
|
||
|
#include "fr_device_pmu_io.h"
|
||
|
|
||
|
#include "co_list.h"
|
||
|
#include "controller.h"
|
||
|
#include "host.h"
|
||
|
#include "btdm_mem.h"
|
||
|
#include "fdb_app.h"
|
||
|
|
||
|
#define SCO_DATA_BUFFER_COUNT 4
|
||
|
|
||
|
typedef int32_t app_btdm_ret_t;
|
||
|
|
||
|
struct sco_data_t {
|
||
|
struct co_list_hdr hdr;
|
||
|
void *arg;
|
||
|
uint16_t length;
|
||
|
uint8_t data[];
|
||
|
};
|
||
|
uint8_t bt_addr[] = {0x12, 0x00, 0x12, 0x12, 0x12, 0x12};
|
||
|
uint8_t ble_public_addr[] = {0x13, 0x00, 0x88, 0x12, 0x12, 0x12};
|
||
|
uint8_t ble_static_addr[] = {0x13, 0x66, 0x88, 0x12, 0x12, 0xc2};
|
||
|
|
||
|
static uint8_t sco_data_buffering = 0;
|
||
|
static struct co_list sco_data_list;
|
||
|
|
||
|
static void encoded_sco_frame_cb(void *arg, uint8_t *data, uint16_t length)
|
||
|
{
|
||
|
static uint16_t seq = 0;
|
||
|
if (sco_data_buffering) {
|
||
|
struct sco_data_t *sco_data;
|
||
|
|
||
|
sco_data = (void *)btdm_malloc(sizeof(struct sco_data_t) + length);
|
||
|
sco_data->arg = arg;
|
||
|
sco_data->length = length;
|
||
|
memcpy((void *)&sco_data->data[0], data, length);
|
||
|
co_list_push_back(&sco_data_list, &sco_data->hdr);
|
||
|
|
||
|
sco_data_buffering--;
|
||
|
if (sco_data_buffering == 0) {
|
||
|
sco_data = (void *)co_list_pop_front(&sco_data_list);
|
||
|
while (sco_data) {
|
||
|
//fputc('D', NULL);
|
||
|
app_bt_send_sco_data(sco_data->arg, seq++, sco_data->data, sco_data->length);
|
||
|
btdm_free((void *)sco_data);
|
||
|
sco_data = (void *)co_list_pop_front(&sco_data_list);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
//fputc('D', NULL);
|
||
|
app_bt_send_sco_data(arg, seq++, data, length);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void btdm_callback(struct app_btdm_event_t *event)
|
||
|
{
|
||
|
switch(event->event) {
|
||
|
case APP_BTDM_EVT_A2DP_STREAM_STARTED:
|
||
|
if (event->param.a2dp_codec.codec_type == APP_BTDM_CODEC_SBC) {
|
||
|
app_audio_a2dp_sink_start(AUDIO_TYPE_SBC, event->param.a2dp_codec.sample_rate);
|
||
|
}
|
||
|
else if (event->param.a2dp_codec.codec_type == APP_BTDM_CODEC_AAC) {
|
||
|
app_audio_a2dp_sink_start(AUDIO_TYPE_AAC, event->param.a2dp_codec.sample_rate);
|
||
|
}
|
||
|
system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_A2DP_ONGOING);
|
||
|
break;
|
||
|
case APP_BTDM_EVT_A2DP_STREAM_STOPPED:
|
||
|
app_audio_a2dp_sink_stop();
|
||
|
system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_A2DP_ONGOING);
|
||
|
break;
|
||
|
case APP_BTDM_EVT_A2DP_STREAM_DATA:
|
||
|
app_audio_a2dp_sink_play(event->param.a2dp_data.buffer, event->param.a2dp_data.length);
|
||
|
break;
|
||
|
case APP_BTDM_EVT_SCO_CREATED:
|
||
|
sco_data_buffering = SCO_DATA_BUFFER_COUNT;
|
||
|
{
|
||
|
struct sco_data_t *sco_data;
|
||
|
sco_data = (void *)co_list_pop_front(&sco_data_list);
|
||
|
while (sco_data) {
|
||
|
btdm_free((void *)sco_data);
|
||
|
sco_data = (void *)co_list_pop_front(&sco_data_list);
|
||
|
}
|
||
|
}
|
||
|
if (event->param.sco_codec.codec_type == APP_BTDM_CODEC_mSBC) {
|
||
|
app_audio_sco_start(AUDIO_TYPE_MSBC, encoded_sco_frame_cb, event->param.sco_codec.hf_channel);
|
||
|
}
|
||
|
else {
|
||
|
app_audio_sco_start(AUDIO_TYPE_PCM, encoded_sco_frame_cb, event->param.sco_codec.hf_channel);
|
||
|
}
|
||
|
system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_SCO_ONGOING);
|
||
|
break;
|
||
|
case APP_BTDM_EVT_SCO_REMOVED:
|
||
|
app_audio_sco_stop();
|
||
|
system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_SCO_ONGOING);
|
||
|
break;
|
||
|
case APP_BTDM_EVT_SCO_DATA:
|
||
|
{
|
||
|
uint8_t audio_codec_type;
|
||
|
if (event->param.sco_data.codec_type == APP_BTDM_CODEC_mSBC) {
|
||
|
audio_codec_type = AUDIO_TYPE_MSBC;
|
||
|
}
|
||
|
else {
|
||
|
audio_codec_type = AUDIO_TYPE_PCM;
|
||
|
}
|
||
|
app_audio_sco_recv(event->param.sco_data.valid, audio_codec_type, event->param.sco_data.buffer, event->param.sco_data.length);
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void app_btdm_start(void)
|
||
|
{
|
||
|
app_ble_init();
|
||
|
#if BTDM_STACK_ENABLE_BT == 1
|
||
|
app_bt_init(btdm_callback);
|
||
|
user_bt_init();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void host_ready_cb(void)
|
||
|
{
|
||
|
struct app_task_event *event;
|
||
|
/* notify application BTDM stack is ready. */
|
||
|
event = app_task_event_alloc(APP_TASK_EVENT_HOST_INITED, 0, true);
|
||
|
app_task_event_post(event, false);
|
||
|
}
|
||
|
|
||
|
void app_btdm_init(void)
|
||
|
{
|
||
|
/*get bt addr*/
|
||
|
#if BT_ADDR_RANDOM_ENABLE | BLE_ADDR_RANDOM_ENABLE
|
||
|
uint8_t rand_num[4];
|
||
|
if(flashdb_get(FDB_KEY_USER_RANDOM_SEED, (void *)&rand_num[0], 4) != 0){
|
||
|
#if BT_ADDR_RANDOM_ENABLE
|
||
|
memcpy((void *)&bt_addr[0],rand_num,4);
|
||
|
#endif
|
||
|
#if BLE_ADDR_RANDOM_ENABLE
|
||
|
memcpy((void *)&ble_static_addr[0],rand_num,4);
|
||
|
#endif
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* prepare for BTDM stack */
|
||
|
#if CONTROLLER_CODE_LOAD_MODE == CONTROLLER_CODE_LOAD_MODE_XIP_RO
|
||
|
#if CONTROLLER_CODE_INC_SENSOR_HUB
|
||
|
extern uint8_t CONTROLLER_CODE_SPLIT_OTA_BASE;
|
||
|
uint32_t controller_code_base_addr = (uint32_t)&CONTROLLER_CODE_SPLIT_OTA_BASE;
|
||
|
#else
|
||
|
extern uint8_t CONTROLLER_CODE_OTA_BASE;
|
||
|
uint32_t controller_code_base_addr = (uint32_t)&CONTROLLER_CODE_OTA_BASE;
|
||
|
#endif
|
||
|
controller_start(BTDM_STACK_HCI_BAUDRATE, ble_public_addr, bt_addr, controller_code_base_addr);
|
||
|
#elif CONTROLLER_CODE_LOAD_MODE == CONTROLLER_CODE_LOAD_MODE_FIX_ADDRESS
|
||
|
controller_start(BTDM_STACK_HCI_BAUDRATE, ble_public_addr, bt_addr, CONTROLLER_CODE_FIX_ADDRESS | FLASH_DAC_BASE);
|
||
|
#else
|
||
|
#error "choose correct CONTROLLER_CODE_LOAD_MODE"
|
||
|
#endif
|
||
|
|
||
|
#if BTDM_STACK_ENABLE_BT == 1
|
||
|
host_btdm_start(BTDM_STACK_HCI_BAUDRATE, HOST_TASK_STACK_SIZE, HOST_TASK_PRIORITY, ble_static_addr);
|
||
|
#else
|
||
|
host_ble_start(BTDM_STACK_HCI_BAUDRATE, HOST_TASK_STACK_SIZE, HOST_TASK_PRIORITY, ble_static_addr);
|
||
|
#endif
|
||
|
|
||
|
/* init MCU->BT pin, configure PMU_PIN_8 output BBG_EN signal */
|
||
|
ool_write(PMU_REG_DIAG_CTRL, 0x82);
|
||
|
ool_write(PMU_REG_PIN_IOMUX_H, 0x03);
|
||
|
/* disable PMU pin input as default setting */
|
||
|
ool_write16(PMU_REG_PIN_INPUT_EN, (PMU_IO_INTTERUPT_DEFAULT<<2) | 0x0002);
|
||
|
/* PP1 is connected to ARST of 1010, this pin is low in sleep mode */
|
||
|
ool_write16(PMU_REG_PIN_PULL_EN, 0x3ffd);
|
||
|
ool_write16(PMU_REG_PIN_PULL_SEL, 0x3fff);
|
||
|
|
||
|
/* init BT->MCU pin, system should not enter sleep mode when this pin is low level */
|
||
|
system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_TYPE_HCI_RX);
|
||
|
pmu_gpio_int_init(PMU_PIN_9, PMU_GPIO_PULL_UP, 0);
|
||
|
pmu_enable_isr(PMU_GPIO_PMU_INT_MSK_BIT);
|
||
|
NVIC_SetPriority(PMU_IRQn, 4);
|
||
|
NVIC_EnableIRQ(PMU_IRQn);
|
||
|
}
|
||
|
|
||
|
app_btdm_ret_t app_btdm_ble_adv_start(uint16_t dur)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
app_btdm_ret_t app_btdm_ble_adv_stop(void)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
app_btdm_ret_t app_btdm_ble_disconnect(void)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
app_btdm_ret_t app_btdm_bt_access_mode_set(uint8_t mode)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
app_btdm_ret_t app_btdm_bt_scan_start(uint16_t dur)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
app_btdm_ret_t app_btdm_bt_scan_stop(void)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
app_btdm_ret_t app_btdm_bt_connect(uint8_t *peer_addr)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
app_btdm_ret_t app_btdm_bt_disconnect(void)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
app_btdm_ret_t app_btdm_bt_profile_enable(uint16_t profiles)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
const uint8_t *app_get_bt_addr(void)
|
||
|
{
|
||
|
return bt_addr;
|
||
|
}
|