#include #include "FreeRTOS.h" #include "task.h" #include "nimble/nimble_port.h" #include "nimble_syscfg.h" #include "nimble/ble.h" #include "nimble/pan107x/nimble_glue_spark.h" #include "nimble/hci_common.h" #include "pan_ble_stack.h" #include "pan_svc_call.h" #include "comm_prf.h" #if CONFIG_PM && (CONFIG_LOW_SPEED_CLOCK_SRC == 2) #error "[Allert]LP 32K Clock in ACT32K mode cannot be enabled in low power mode.!!!" #endif #if (configUSE_TICKLESS_IDLE == 1) extern void UpdateTickAndSch(void); #endif static TaskHandle_t host_task_h; static uint8_t ll_enable = false; #define CONFIG_BT_CTLR_MAX_MST_CONN CONFIG_BT_MAX_NUM_OF_CENTRAL #define CONFIG_BT_CTLR_MAX_SLV_CONN CONFIG_BT_MAX_NUM_OF_PERIPHERAL #if NIMBLE_BLE_SM #define CONFIG_BT_CTLR_LL_ENC_TIME 200 #else #define CONFIG_BT_CTLR_LL_ENC_TIME 100 #endif #define CONFIG_BT_CTLR_MST_CONN_MARGN 6 #if CONFIG_LOW_SPEED_CLOCK_SRC == 0 #define BLE_SCA 1000 #else #define BLE_SCA 50 #endif #ifdef IP_107x #if CONFIG_SMP_OTA #define PAN_BLE_CTLR_BUFFER_ALLOC (4748) #elif CONFIG_BLE_MULTI_ROLE #define PAN_BLE_CTLR_BUFFER_ALLOC (6300) #elif ((CONFIG_BT_CTLR_MAX_MST_CONN > 1) || (CONFIG_BT_CTLR_MAX_SLV_CONN > 1)) #define PAN_BLE_CTLR_BUFFER_ALLOC (5500) #elif CONFIG_THROUGHPUT_TEST #define PAN_BLE_CTLR_BUFFER_ALLOC (5624) #else #define PAN_BLE_CTLR_BUFFER_ALLOC (4332) #endif #elif defined(IP_101x) #define PAN_BLE_CTLR_BUFFER_ALLOC (2500) #endif #define PAN_BLE_CTLR_BUFFER_SIZE (((PAN_BLE_CTLR_BUFFER_ALLOC) +3) & (~((uint32_t)0x03))) /*4 bytes aligned*/ static uint32_t mem_buffer[PAN_BLE_CTLR_BUFFER_SIZE / 4]; static uint32_t mem_pos = 0; #if CONFIG_CNTRL_MEM_POOL_PRINT static uint32_t mem_pool_usage = 0; #endif static void *mem_alloc(uint32_t size) { void *mem_ret = NULL; char *p_mem = (char *)mem_buffer; if (PAN_BLE_CTLR_BUFFER_SIZE - mem_pos >= size) { mem_ret = &p_mem[mem_pos]; mem_pos += size; } else { configASSERT(0); } #if CONFIG_CNTRL_MEM_POOL_PRINT mem_pool_usage += size; printf("BT controller memory pool used: %d bytes, remain bytes: %d, total:%d \n", mem_pool_usage, PAN_BLE_CTLR_BUFFER_SIZE - mem_pool_usage, PAN_BLE_CTLR_BUFFER_SIZE); #endif return mem_ret; } pan_ble_cfg ble_cfg = { .sleep_clock_source = CONFIG_LOW_SPEED_CLOCK_SRC, /* CONFIG_BT_CTLR_SLEEP_CLOCK_SOURCE,*/ .sleep_clock_accuracy = BLE_SCA, .max_num_of_states = 0, /*unused param*/ .tx_power = CONFIG_BT_CTLR_TX_POWER_DFT, .pf_mem_init = mem_alloc, #if (CONFIG_BT_CTLR_LINK_LAYER_DEBUG) .link_layer_debug = true, #else .link_layer_debug = false, #endif .agc_cfg_mode = 0, #if CONFIG_PM .pmEnable = true, #endif .mstMargin = CONFIG_BT_CTLR_MST_CONN_MARGN, .wlNum = 1, .rlNum = 1, .maxMst = CONFIG_BT_CTLR_MAX_MST_CONN, .maxSlv = CONFIG_BT_CTLR_MAX_SLV_CONN, // .maxAclLen = (MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE - 4), /*should adjust PAN_BLE_CTLR_BUFFER_ALLOC size*/ #ifdef IP_107x #if CONFIG_SMP_OTA .maxAclLen = CONFIG_BLE_ACL_RX_SIZE, .numRxBufs = 8, .numTxBufs = 8, .numMoreData = 5, #elif CONFIG_THROUGHPUT_TEST .maxAclLen = CONFIG_BLE_ACL_RX_SIZE, .numRxBufs = 8, .numTxBufs = 8, .numMoreData = 6, #elif CONFIG_BLE_MULTI_ROLE .maxAclLen = CONFIG_BLE_ACL_RX_SIZE, .numRxBufs = 16, .numTxBufs = 8, .numMoreData = 4, #else .maxAclLen = 27, .numRxBufs = 16, .numTxBufs = 16, .numMoreData = 4, #endif #elif defined(IP_101x) .maxAclLen = 80, .numRxBufs = 8, .numTxBufs = 16, .numMoreData = 6, #endif .llEncTime = CONFIG_BT_CTLR_LL_ENC_TIME, }; CONFIG_RAM_CODE int ll_semphr_cback(void) { NVIC_EnableIRQ(BLE_EVENT_PROC_IRQn); NVIC_SetPendingIRQ(BLE_EVENT_PROC_IRQn); return 0; } void ble_hs_thread_entry(void *parameter) { nimble_port_run(); } void hs_thread_init(void) { xTaskCreate(ble_hs_thread_entry, "host", MYNEWT_VAL(BLE_HOST_THREAD_STACK_SIZE), NULL, configMAX_PRIORITIES - os_priority_low, &host_task_h); } void vApplicationUserHook(void) { if(ll_enable){ pan_update_stimer(); } } int host_copydata(void *from, void *dst, uint16_t len) { struct os_mbuf *om = from; return os_mbuf_copydata(om, 0, OS_MBUF_PKTLEN(om), dst); } void ble_hci_evt_ll_to_host_cbk(uint8_t *p_evt, uint16_t evt_len) { void *buf; if (p_evt[2] == BLE_HCI_LE_SUBEV_ADV_RPT) { buf = ble_transport_alloc_evt(1); } else { buf = ble_transport_alloc_evt(0); } if (buf) { memcpy(buf, p_evt, evt_len); ble_transport_to_hs_evt(buf); } } void ble_hci_acl_ll_to_host_cbk(uint8_t *p_acl, uint16_t acl_len) { int ret; struct os_mbuf *om; om = ble_transport_alloc_acl_from_ll(); if (om) { ret = os_mbuf_append(om, p_acl, acl_len); if (ret) { os_mbuf_free_chain(om); } else { ble_transport_to_hs_acl(om); } } else{ APP_TRACK_ERR("Host transport alloc ACL buffer failed\n"); } } void ll_init(void) { printf("LL Spark Controller Version:%07x\n", pan_ble_get_version()->commit_id); pan_ll_register_hostcopy_cb(host_copydata); pan_ll_register_semphr_cback(ll_semphr_cback); pan_ble_hci_init(ble_hci_evt_ll_to_host_cbk, ble_hci_acl_ll_to_host_cbk); pan_ble_init(&ble_cfg); ll_enable = true; } int ble_transport_to_ll_acl_impl(struct os_mbuf *om) { int rc = 0; rc = pan_ble_hci_acl_nimble_handle((void *)om, OS_MBUF_PKTLEN(om)); os_mbuf_free_chain(om); return (rc != 0) ? BLE_ERR_MEM_CAPACITY : 0; } int ble_transport_to_ll_cmd_impl(void *buf) { int rc; struct ble_hci_cmd *cmd = buf; pan_ble_hci_cmd_handle(buf, sizeof(struct ble_hci_cmd) + cmd->length, 0, 0); ble_transport_free(cmd); return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; } void TRIM_IRQHandler(void) { printf("trim\n"); } CONFIG_RAM_CODE void BLE_EVENT_PROC_IRQ(void) { pan_ble_handle(); #if (configUSE_TICKLESS_IDLE == 1) UpdateTickAndSch(); #endif } CONFIG_RAM_CODE void LL_IRQHandler(void) { #ifdef PRF_BLE_DUAL_MODE if (panchip_prf_ble_handler()) { return; } #endif pan_ble_irq(); } uint32_t db_set_bd_address(uint8_t *bd_addr) { LL_SetBdAddr(bd_addr, 6); return 0; }