1 /*
2  * Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "pico.h"
8 #include "cyw43.h"
9 #include "hci_transport.h"
10 #include "hci.h"
11 #include "pico/btstack_hci_transport_cyw43.h"
12 #include "pico/btstack_chipset_cyw43.h"
13 
14 // assert outgoing pre-buffer for cyw43 header is available
15 #if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE < 4)
16 #error HCI_OUTGOING_PRE_BUFFER_SIZE not defined or smaller than 4. Please update btstack_config.h
17 #endif
18 
19 // assert outgoing packet fragments are word aligned
20 #if !defined(HCI_ACL_CHUNK_SIZE_ALIGNMENT) || ((HCI_ACL_CHUNK_SIZE_ALIGNMENT & 3) != 0)
21 #error HCI_ACL_CHUNK_SIZE_ALIGNMENT not defined or not a multiply of 4. Please update btstack_config.h
22 #endif
23 
24 #define BT_DEBUG_ENABLED 0
25 #if BT_DEBUG_ENABLED
26 #define BT_DEBUG(...) CYW43_PRINTF(__VA_ARGS__)
27 #else
28 #define BT_DEBUG(...) (void)0
29 #endif
30 
31 // Callback when we have data
32 static void (*hci_transport_cyw43_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = NULL;
33 
34 // Incoming packet buffer - cyw43 packet header (incl packet type) + incoming pre buffer + max(acl header + acl payload, event header + event data)
35 __attribute__((aligned(4)))
36 static uint8_t hci_packet_with_pre_buffer[4 + HCI_INCOMING_PRE_BUFFER_SIZE + HCI_INCOMING_PACKET_BUFFER_SIZE ];
37 
38 static btstack_data_source_t transport_data_source;
39 static bool hci_transport_ready;
40 
41 // Forward declaration
42 static void hci_transport_cyw43_process(void);
43 
hci_transport_data_source_process(btstack_data_source_t * ds,btstack_data_source_callback_type_t callback_type)44 static void hci_transport_data_source_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
45     assert(callback_type == DATA_SOURCE_CALLBACK_POLL);
46     assert(ds == &transport_data_source);
47     (void)callback_type;
48     (void)ds;
49     hci_transport_cyw43_process();
50 }
51 
hci_transport_cyw43_init(const void * transport_config)52 static void hci_transport_cyw43_init(const void *transport_config) {
53     UNUSED(transport_config);
54 }
55 
hci_transport_cyw43_open(void)56 static int hci_transport_cyw43_open(void) {
57     int err = cyw43_bluetooth_hci_init();
58     if (err != 0) {
59         CYW43_PRINTF("Failed to open cyw43 hci controller: %d\n", err);
60         return err;
61     }
62 
63     // OTP should be set in which case BT gets an address of wifi mac + 1
64     // If OTP is not set for some reason BT gets set to 43:43:A2:12:1F:AC.
65     // So for safety, set the bluetooth device address here.
66     bd_addr_t addr;
67     cyw43_hal_get_mac(0, (uint8_t*)&addr);
68     addr[BD_ADDR_LEN - 1]++;
69     hci_set_chipset(btstack_chipset_cyw43_instance());
70     hci_set_bd_addr(addr);
71 
72     btstack_run_loop_set_data_source_handler(&transport_data_source, &hci_transport_data_source_process);
73     btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_POLL);
74     btstack_run_loop_add_data_source(&transport_data_source);
75     hci_transport_ready = true;
76 
77     return 0;
78 }
79 
hci_transport_cyw43_close(void)80 static int hci_transport_cyw43_close(void) {
81     btstack_run_loop_disable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_POLL);
82     btstack_run_loop_remove_data_source(&transport_data_source);
83     hci_transport_ready = false;
84 
85     return 0;
86 }
87 
hci_transport_cyw43_register_packet_handler(void (* handler)(uint8_t packet_type,uint8_t * packet,uint16_t size))88 static void hci_transport_cyw43_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)) {
89     hci_transport_cyw43_packet_handler = handler;
90 }
91 
hci_transport_cyw43_can_send_now(uint8_t packet_type)92 static int hci_transport_cyw43_can_send_now(uint8_t packet_type) {
93     UNUSED(packet_type);
94     return true;
95 }
96 
hci_transport_cyw43_send_packet(uint8_t packet_type,uint8_t * packet,int size)97 static int hci_transport_cyw43_send_packet(uint8_t packet_type, uint8_t *packet, int size) {
98     // store packet type before actual data and increase size
99     // This relies on HCI_OUTGOING_PRE_BUFFER_SIZE being set
100     uint8_t *buffer = &packet[-4];
101     uint32_t buffer_size = size + 4;
102     buffer[3] = packet_type;
103 
104     CYW43_THREAD_ENTER
105     int err = cyw43_bluetooth_hci_write(buffer, buffer_size);
106 
107     if (err != 0) {
108         CYW43_PRINTF("Failed to send cyw43 hci packet: %d\n", err);
109         assert(false);
110     } else {
111         BT_DEBUG("bt sent %lu\n", buffer_size);
112         static uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0};
113         hci_transport_cyw43_packet_handler(HCI_EVENT_PACKET, &packet_sent_event[0], sizeof(packet_sent_event));
114     }
115     CYW43_THREAD_EXIT
116     return err;
117 }
118 
119 // configure and return hci transport singleton
120 static const hci_transport_t hci_transport_cyw43 = {
121         /* const char * name; */                                        "CYW43",
122         /* void   (*init) (const void *transport_config); */            &hci_transport_cyw43_init,
123         /* int    (*open)(void); */                                     &hci_transport_cyw43_open,
124         /* int    (*close)(void); */                                    &hci_transport_cyw43_close,
125         /* void   (*register_packet_handler)(void (*handler)(...); */   &hci_transport_cyw43_register_packet_handler,
126         /* int    (*can_send_packet_now)(uint8_t packet_type); */       &hci_transport_cyw43_can_send_now,
127         /* int    (*send_packet)(...); */                               &hci_transport_cyw43_send_packet,
128         /* int    (*set_baudrate)(uint32_t baudrate); */                NULL,
129         /* void   (*reset_link)(void); */                               NULL,
130         /* void   (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL,
131 };
132 
hci_transport_cyw43_instance(void)133 const hci_transport_t *hci_transport_cyw43_instance(void) {
134     return &hci_transport_cyw43;
135 }
136 
137 // Called to perform bt work from a data source
hci_transport_cyw43_process(void)138 static void hci_transport_cyw43_process(void) {
139     CYW43_THREAD_LOCK_CHECK
140     uint32_t len = 0;
141     bool has_work;
142 #ifdef PICO_BTSTACK_CYW43_MAX_HCI_PROCESS_LOOP_COUNT
143     uint32_t loop_count = 0;
144 #endif
145     do {
146         int err = cyw43_bluetooth_hci_read(hci_packet_with_pre_buffer, sizeof(hci_packet_with_pre_buffer), &len);
147         BT_DEBUG("bt in len=%lu err=%d\n", len, err);
148         if (err == 0 && len > 0) {
149             hci_transport_cyw43_packet_handler(hci_packet_with_pre_buffer[3], hci_packet_with_pre_buffer + 4, len - 4);
150             has_work = true;
151         } else {
152             has_work = false;
153         }
154 // PICO_CONFIG: PICO_BTSTACK_CYW43_MAX_HCI_PROCESS_LOOP_COUNT, limit the max number of iterations of the hci processing loop, type=int, advanced=true, group=pico_btstack
155 #ifdef PICO_BTSTACK_CYW43_MAX_HCI_PROCESS_LOOP_COUNT
156         if (++loop_count >= PICO_BTSTACK_CYW43_MAX_HCI_PROCESS_LOOP_COUNT) {
157             break;
158         }
159 #endif
160     } while (has_work);
161 }
162 
163 // This is called from cyw43_poll_func.
cyw43_bluetooth_hci_process(void)164 void cyw43_bluetooth_hci_process(void) {
165     if (hci_transport_ready) {
166         btstack_run_loop_poll_data_sources_from_irq();
167     }
168 }
169