1*277e512cSDirk Helbig /* 2*277e512cSDirk Helbig * Copyright (c) 2016 Nordic Semiconductor ASA 3*277e512cSDirk Helbig * Copyright (c) 2015-2016 Intel Corporation 4*277e512cSDirk Helbig * 5*277e512cSDirk Helbig * SPDX-License-Identifier: Apache-2.0 6*277e512cSDirk Helbig */ 7*277e512cSDirk Helbig 8*277e512cSDirk Helbig #include <errno.h> 9*277e512cSDirk Helbig #include <stddef.h> 10*277e512cSDirk Helbig #include <stdio.h> 11*277e512cSDirk Helbig #include <string.h> 12*277e512cSDirk Helbig 13*277e512cSDirk Helbig #include <zephyr/kernel.h> 14*277e512cSDirk Helbig #include <zephyr/bluetooth/bluetooth.h> 15*277e512cSDirk Helbig #include <zephyr/bluetooth/l2cap.h> 16*277e512cSDirk Helbig #include <zephyr/bluetooth/hci.h> 17*277e512cSDirk Helbig #include <zephyr/bluetooth/buf.h> 18*277e512cSDirk Helbig #include <zephyr/bluetooth/hci_raw.h> 19*277e512cSDirk Helbig 20*277e512cSDirk Helbig // Nordic NDK 21*277e512cSDirk Helbig #include "nrf.h" 22*277e512cSDirk Helbig 23*277e512cSDirk Helbig // BTstack 24*277e512cSDirk Helbig #include "btstack_debug.h" 25*277e512cSDirk Helbig #include "btstack_event.h" 26*277e512cSDirk Helbig #include "btstack_memory.h" 27*277e512cSDirk Helbig #include "btstack_run_loop_zephyr.h" 28*277e512cSDirk Helbig #include "hci.h" 29*277e512cSDirk Helbig #include "hci_dump.h" 30*277e512cSDirk Helbig #include "hci_dump_embedded_stdout.h" 31*277e512cSDirk Helbig #include "hci_transport.h" 32*277e512cSDirk Helbig 33*277e512cSDirk Helbig #include "btstack_tlv.h" 34*277e512cSDirk Helbig #include "btstack_tlv_none.h" 35*277e512cSDirk Helbig #include "ble/le_device_db_tlv.h" 36*277e512cSDirk Helbig 37*277e512cSDirk Helbig static K_FIFO_DEFINE(tx_queue); 38*277e512cSDirk Helbig static K_FIFO_DEFINE(rx_queue); 39*277e512cSDirk Helbig 40*277e512cSDirk Helbig // 41*277e512cSDirk Helbig // hci_transport_zephyr.c 42*277e512cSDirk Helbig // 43*277e512cSDirk Helbig 44*277e512cSDirk Helbig static void (*transport_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); 45*277e512cSDirk Helbig 46*277e512cSDirk Helbig /** 47*277e512cSDirk Helbig * init transport 48*277e512cSDirk Helbig * @param transport_config 49*277e512cSDirk Helbig */ 50*277e512cSDirk Helbig static void transport_init(const void *transport_config){ 51*277e512cSDirk Helbig /* startup Controller */ 52*277e512cSDirk Helbig bt_enable_raw(&rx_queue); 53*277e512cSDirk Helbig } 54*277e512cSDirk Helbig 55*277e512cSDirk Helbig /** 56*277e512cSDirk Helbig * open transport connection 57*277e512cSDirk Helbig */ 58*277e512cSDirk Helbig static int transport_open(void){ 59*277e512cSDirk Helbig return 0; 60*277e512cSDirk Helbig } 61*277e512cSDirk Helbig 62*277e512cSDirk Helbig /** 63*277e512cSDirk Helbig * close transport connection 64*277e512cSDirk Helbig */ 65*277e512cSDirk Helbig static int transport_close(void){ 66*277e512cSDirk Helbig return 0; 67*277e512cSDirk Helbig } 68*277e512cSDirk Helbig 69*277e512cSDirk Helbig /** 70*277e512cSDirk Helbig * register packet handler for HCI packets: ACL, SCO, and Events 71*277e512cSDirk Helbig */ 72*277e512cSDirk Helbig static void transport_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 73*277e512cSDirk Helbig transport_packet_handler = handler; 74*277e512cSDirk Helbig } 75*277e512cSDirk Helbig 76*277e512cSDirk Helbig static void send_hardware_error(uint8_t error_code){ 77*277e512cSDirk Helbig // hci_outgoing_event[0] = HCI_EVENT_HARDWARE_ERROR; 78*277e512cSDirk Helbig // hci_outgoing_event[1] = 1; 79*277e512cSDirk Helbig // hci_outgoing_event[2] = error_code; 80*277e512cSDirk Helbig // hci_outgoing_event_ready = 1; 81*277e512cSDirk Helbig } 82*277e512cSDirk Helbig 83*277e512cSDirk Helbig static int transport_send_packet(uint8_t packet_type, uint8_t *packet, int size){ 84*277e512cSDirk Helbig struct net_buf *buf; 85*277e512cSDirk Helbig switch (packet_type){ 86*277e512cSDirk Helbig case HCI_COMMAND_DATA_PACKET: 87*277e512cSDirk Helbig buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, packet, size); 88*277e512cSDirk Helbig if (!buf) { 89*277e512cSDirk Helbig log_error("No available command buffers!\n"); 90*277e512cSDirk Helbig break; 91*277e512cSDirk Helbig } 92*277e512cSDirk Helbig 93*277e512cSDirk Helbig memcpy(net_buf_add(buf, size), packet, size); 94*277e512cSDirk Helbig bt_send(buf); 95*277e512cSDirk Helbig break; 96*277e512cSDirk Helbig case HCI_ACL_DATA_PACKET: 97*277e512cSDirk Helbig buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_NO_WAIT, packet, size); 98*277e512cSDirk Helbig if (!buf) { 99*277e512cSDirk Helbig log_error("No available ACL buffers!\n"); 100*277e512cSDirk Helbig break; 101*277e512cSDirk Helbig } 102*277e512cSDirk Helbig 103*277e512cSDirk Helbig memcpy(net_buf_add(buf, size), packet, size); 104*277e512cSDirk Helbig bt_send(buf); 105*277e512cSDirk Helbig break; 106*277e512cSDirk Helbig default: 107*277e512cSDirk Helbig send_hardware_error(0x01); // invalid HCI packet 108*277e512cSDirk Helbig break; 109*277e512cSDirk Helbig } 110*277e512cSDirk Helbig 111*277e512cSDirk Helbig return 0; 112*277e512cSDirk Helbig } 113*277e512cSDirk Helbig 114*277e512cSDirk Helbig static const hci_transport_t transport = { 115*277e512cSDirk Helbig /* const char * name; */ "nRF5-Zephyr", 116*277e512cSDirk Helbig /* void (*init) (const void *transport_config); */ &transport_init, 117*277e512cSDirk Helbig /* int (*open)(void); */ &transport_open, 118*277e512cSDirk Helbig /* int (*close)(void); */ &transport_close, 119*277e512cSDirk Helbig /* void (*register_packet_handler)(void (*handler)(...); */ &transport_register_packet_handler, 120*277e512cSDirk Helbig /* int (*can_send_packet_now)(uint8_t packet_type); */ NULL, 121*277e512cSDirk Helbig /* int (*send_packet)(...); */ &transport_send_packet, 122*277e512cSDirk Helbig /* int (*set_baudrate)(uint32_t baudrate); */ NULL, 123*277e512cSDirk Helbig /* void (*reset_link)(void); */ NULL, 124*277e512cSDirk Helbig }; 125*277e512cSDirk Helbig 126*277e512cSDirk Helbig static const hci_transport_t * transport_get_instance(void){ 127*277e512cSDirk Helbig return &transport; 128*277e512cSDirk Helbig } 129*277e512cSDirk Helbig 130*277e512cSDirk Helbig static void transport_deliver_controller_packet(struct net_buf * buf){ 131*277e512cSDirk Helbig uint16_t size = buf->len; 132*277e512cSDirk Helbig uint8_t * packet = buf->data; 133*277e512cSDirk Helbig switch (bt_buf_get_type(buf)) { 134*277e512cSDirk Helbig case BT_BUF_ACL_IN: 135*277e512cSDirk Helbig transport_packet_handler(HCI_ACL_DATA_PACKET, packet, size); 136*277e512cSDirk Helbig break; 137*277e512cSDirk Helbig case BT_BUF_EVT: 138*277e512cSDirk Helbig transport_packet_handler(HCI_EVENT_PACKET, packet, size); 139*277e512cSDirk Helbig break; 140*277e512cSDirk Helbig default: 141*277e512cSDirk Helbig log_error("Unknown type %u\n", bt_buf_get_type(buf)); 142*277e512cSDirk Helbig break; 143*277e512cSDirk Helbig } 144*277e512cSDirk Helbig net_buf_unref(buf); 145*277e512cSDirk Helbig } 146*277e512cSDirk Helbig 147*277e512cSDirk Helbig // btstack_run_loop_zephry.c 148*277e512cSDirk Helbig 149*277e512cSDirk Helbig // the run loop 150*277e512cSDirk Helbig //static btstack_linked_list_t timers; 151*277e512cSDirk Helbig 152*277e512cSDirk Helbig // TODO: handle 32 bit ms time overrun 153*277e512cSDirk Helbig static uint32_t btstack_run_loop_zephyr_get_time_ms(void){ 154*277e512cSDirk Helbig return k_uptime_get_32(); 155*277e512cSDirk Helbig } 156*277e512cSDirk Helbig 157*277e512cSDirk Helbig static void btstack_run_loop_zephyr_set_timer(btstack_timer_source_t *ts, uint32_t timeout_in_ms){ 158*277e512cSDirk Helbig ts->timeout = k_uptime_get_32() + 1 + timeout_in_ms; 159*277e512cSDirk Helbig } 160*277e512cSDirk Helbig 161*277e512cSDirk Helbig /** 162*277e512cSDirk Helbig * Execute run_loop 163*277e512cSDirk Helbig */ 164*277e512cSDirk Helbig static void btstack_run_loop_zephyr_execute(void) { 165*277e512cSDirk Helbig while (1) { 166*277e512cSDirk Helbig // process timers 167*277e512cSDirk Helbig uint32_t now = k_uptime_get_32(); 168*277e512cSDirk Helbig btstack_run_loop_base_process_timers(now); 169*277e512cSDirk Helbig 170*277e512cSDirk Helbig // get time until next timer expires 171*277e512cSDirk Helbig k_timeout_t timeout; 172*277e512cSDirk Helbig timeout.ticks = btstack_run_loop_base_get_time_until_timeout(now); 173*277e512cSDirk Helbig if (timeout.ticks < 0){ 174*277e512cSDirk Helbig timeout.ticks = K_TICKS_FOREVER; 175*277e512cSDirk Helbig } 176*277e512cSDirk Helbig 177*277e512cSDirk Helbig // process RX fifo only 178*277e512cSDirk Helbig struct net_buf *buf = net_buf_get(&rx_queue, timeout); 179*277e512cSDirk Helbig if (buf){ 180*277e512cSDirk Helbig transport_deliver_controller_packet(buf); 181*277e512cSDirk Helbig } 182*277e512cSDirk Helbig } 183*277e512cSDirk Helbig } 184*277e512cSDirk Helbig 185*277e512cSDirk Helbig static void btstack_run_loop_zephyr_btstack_run_loop_init(void){ 186*277e512cSDirk Helbig btstack_run_loop_base_init(); 187*277e512cSDirk Helbig } 188*277e512cSDirk Helbig 189*277e512cSDirk Helbig static const btstack_run_loop_t btstack_run_loop_zephyr = { 190*277e512cSDirk Helbig &btstack_run_loop_zephyr_btstack_run_loop_init, 191*277e512cSDirk Helbig NULL, 192*277e512cSDirk Helbig NULL, 193*277e512cSDirk Helbig NULL, 194*277e512cSDirk Helbig NULL, 195*277e512cSDirk Helbig &btstack_run_loop_zephyr_set_timer, 196*277e512cSDirk Helbig &btstack_run_loop_base_add_timer, 197*277e512cSDirk Helbig &btstack_run_loop_base_remove_timer, 198*277e512cSDirk Helbig &btstack_run_loop_zephyr_execute, 199*277e512cSDirk Helbig &btstack_run_loop_base_dump_timer, 200*277e512cSDirk Helbig &btstack_run_loop_zephyr_get_time_ms, 201*277e512cSDirk Helbig }; 202*277e512cSDirk Helbig /** 203*277e512cSDirk Helbig * @brief Provide btstack_run_loop_posix instance for use with btstack_run_loop_init 204*277e512cSDirk Helbig */ 205*277e512cSDirk Helbig const btstack_run_loop_t * btstack_run_loop_zephyr_get_instance(void){ 206*277e512cSDirk Helbig return &btstack_run_loop_zephyr; 207*277e512cSDirk Helbig } 208*277e512cSDirk Helbig 209*277e512cSDirk Helbig static btstack_packet_callback_registration_t hci_event_callback_registration; 210*277e512cSDirk Helbig 211*277e512cSDirk Helbig static bd_addr_t static_address; 212*277e512cSDirk Helbig 213*277e512cSDirk Helbig static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 214*277e512cSDirk Helbig if (packet_type != HCI_EVENT_PACKET) return; 215*277e512cSDirk Helbig if (hci_event_packet_get_type(packet) != BTSTACK_EVENT_STATE) return; 216*277e512cSDirk Helbig if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; 217*277e512cSDirk Helbig printf("BTstack up and running as %s.\n", bd_addr_to_str(static_address)); 218*277e512cSDirk Helbig } 219*277e512cSDirk Helbig 220*277e512cSDirk Helbig int btstack_main(void); 221*277e512cSDirk Helbig 222*277e512cSDirk Helbig #if defined(CONFIG_BT_CTLR_ASSERT_HANDLER) 223*277e512cSDirk Helbig void bt_ctlr_assert_handle(char *file, uint32_t line) 224*277e512cSDirk Helbig { 225*277e512cSDirk Helbig printf("CONFIG_BT_CTLR_ASSERT_HANDLER: file %s, line %u\n", file, line); 226*277e512cSDirk Helbig while (1) { 227*277e512cSDirk Helbig } 228*277e512cSDirk Helbig } 229*277e512cSDirk Helbig #endif /* CONFIG_BT_CTLR_ASSERT_HANDLER */ 230*277e512cSDirk Helbig 231*277e512cSDirk Helbig void main(void) 232*277e512cSDirk Helbig { 233*277e512cSDirk Helbig // configure console UART by replacing CONFIG_UART_NRF5_BAUD_RATE with 115200 in uart_console.c 234*277e512cSDirk Helbig 235*277e512cSDirk Helbig printf("BTstack booting up..\n"); 236*277e512cSDirk Helbig 237*277e512cSDirk Helbig // start with BTstack init - especially configure HCI Transport 238*277e512cSDirk Helbig btstack_memory_init(); 239*277e512cSDirk Helbig btstack_run_loop_init(btstack_run_loop_zephyr_get_instance()); 240*277e512cSDirk Helbig 241*277e512cSDirk Helbig // enable full log output while porting 242*277e512cSDirk Helbig hci_dump_init(hci_dump_embedded_stdout_get_instance()); 243*277e512cSDirk Helbig 244*277e512cSDirk Helbig const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_none_init_instance(); 245*277e512cSDirk Helbig // setup global tlv 246*277e512cSDirk Helbig btstack_tlv_set_instance(btstack_tlv_impl, NULL); 247*277e512cSDirk Helbig 248*277e512cSDirk Helbig // setup LE Device DB using TLV 249*277e512cSDirk Helbig le_device_db_tlv_configure(btstack_tlv_impl, NULL); 250*277e512cSDirk Helbig 251*277e512cSDirk Helbig // init HCI 252*277e512cSDirk Helbig hci_init(transport_get_instance(), NULL); 253*277e512cSDirk Helbig 254*277e512cSDirk Helbig // nRF5 chipsets don't have an official public address 255*277e512cSDirk Helbig // Instead, a Static Random Address is assigned during manufacturing 256*277e512cSDirk Helbig // let's use it as well 257*277e512cSDirk Helbig big_endian_store_16(static_address, 0, NRF_FICR->DEVICEADDR[1] | 0xc000); 258*277e512cSDirk Helbig big_endian_store_32(static_address, 2, NRF_FICR->DEVICEADDR[0]); 259*277e512cSDirk Helbig gap_random_address_set(static_address); 260*277e512cSDirk Helbig 261*277e512cSDirk Helbig // inform about BTstack state 262*277e512cSDirk Helbig hci_event_callback_registration.callback = &packet_handler; 263*277e512cSDirk Helbig hci_add_event_handler(&hci_event_callback_registration); 264*277e512cSDirk Helbig 265*277e512cSDirk Helbig // hand over to btstack embedded code 266*277e512cSDirk Helbig btstack_main(); 267*277e512cSDirk Helbig 268*277e512cSDirk Helbig // go 269*277e512cSDirk Helbig btstack_run_loop_execute(); 270*277e512cSDirk Helbig 271*277e512cSDirk Helbig while (1){}; 272*277e512cSDirk Helbig } 273