1 /* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "hci_transport_em9304_spi.c" 39 40 #include "btstack_config.h" 41 #include "hci_transport_em9304_spi.h" 42 43 #include "hci_transport.h" 44 45 // EM9304 SPI Driver 46 static const btstack_em9304_spi_t * btstack_em9304_spi; 47 48 ///////////////////////// 49 // em9304 engine 50 #include "btstack_ring_buffer.h" 51 #include "btstack_debug.h" 52 #include "btstack_util.h" 53 #include "hci.h" 54 #include "hci_transport.h" 55 56 static void em9304_spi_engine_run(void); 57 58 #define STS_SLAVE_READY 0xc0 59 60 #define EM9304_SPI_HEADER_TX 0x42 61 #define EM9304_SPI_HEADER_RX 0x81 62 63 #define SPI_EM9304_BUFFER_SIZE 64 64 #define SPI_EM9304_RING_BUFFER_SIZE 128 65 66 // state 67 static volatile enum { 68 SPI_EM9304_OFF, 69 SPI_EM9304_READY_FOR_TX, 70 SPI_EM9304_READY_FOR_TX_AND_RX, 71 SPI_EM9304_RX_W4_READ_COMMAND_SENT, 72 SPI_EM9304_RX_READ_COMMAND_SENT, 73 SPI_EM9304_RX_W4_STS2_RECEIVED, 74 SPI_EM9304_RX_STS2_RECEIVED, 75 SPI_EM9304_RX_W4_DATA_RECEIVED, 76 SPI_EM9304_RX_DATA_RECEIVED, 77 SPI_EM9304_TX_W4_RDY, 78 SPI_EM9304_TX_W4_WRITE_COMMAND_SENT, 79 SPI_EM9304_TX_WRITE_COMMAND_SENT, 80 SPI_EM9304_TX_W4_STS2_RECEIVED, 81 SPI_EM9304_TX_STS2_RECEIVED, 82 SPI_EM9304_TX_W4_DATA_SENT, 83 SPI_EM9304_TX_DATA_SENT, 84 SPI_EM9304_DONE, 85 } em9304_spi_engine_state; 86 87 static uint16_t em9304_spi_engine_rx_request_len; 88 static uint16_t em9304_spi_engine_tx_request_len; 89 90 static btstack_ring_buffer_t em9304_spi_engine_rx_ring_buffer; 91 92 static uint8_t em9304_spi_engine_rx_ring_buffer_storage[SPI_EM9304_RING_BUFFER_SIZE]; 93 94 static const uint8_t * em9304_spi_engine_tx_data; 95 static uint16_t em9304_spi_engine_tx_size; 96 97 // handlers 98 static void (*em9304_spi_engine_rx_available_handler)(void); 99 static void (*em9304_spi_engine_tx_done_handler)(void); 100 101 // TODO: get rid of alignment requirement 102 union { 103 uint32_t words[1]; 104 uint8_t bytes[1]; 105 } sCommand; 106 107 union { 108 uint32_t words[1]; 109 uint8_t bytes[1]; 110 } sStas; 111 112 union { 113 uint32_t words[SPI_EM9304_BUFFER_SIZE/4]; 114 uint8_t bytes[SPI_EM9304_BUFFER_SIZE]; 115 } em9304_spi_engine_spi_buffer; 116 117 static void em9304_spi_engine_ready_callback(void){ 118 // TODO: collect states 119 em9304_spi_engine_run(); 120 } 121 122 static void em9304_spi_engine_transfer_done(void){ 123 switch (em9304_spi_engine_state){ 124 case SPI_EM9304_RX_W4_READ_COMMAND_SENT: 125 em9304_spi_engine_state = SPI_EM9304_RX_READ_COMMAND_SENT; 126 break; 127 case SPI_EM9304_RX_W4_STS2_RECEIVED: 128 em9304_spi_engine_state = SPI_EM9304_RX_STS2_RECEIVED; 129 break; 130 case SPI_EM9304_RX_W4_DATA_RECEIVED: 131 em9304_spi_engine_state = SPI_EM9304_RX_DATA_RECEIVED; 132 break; 133 case SPI_EM9304_TX_W4_WRITE_COMMAND_SENT: 134 em9304_spi_engine_state = SPI_EM9304_TX_WRITE_COMMAND_SENT; 135 break; 136 case SPI_EM9304_TX_W4_STS2_RECEIVED: 137 em9304_spi_engine_state = SPI_EM9304_TX_STS2_RECEIVED; 138 break; 139 case SPI_EM9304_TX_W4_DATA_SENT: 140 em9304_spi_engine_state = SPI_EM9304_TX_DATA_SENT; 141 break; 142 default: 143 return; 144 } 145 em9304_spi_engine_run(); 146 } 147 148 static void em9304_spi_engine_start_tx_transaction(void){ 149 // state = wait for RDY 150 em9304_spi_engine_state = SPI_EM9304_TX_W4_RDY; 151 152 // chip select 153 btstack_em9304_spi->set_chip_select(1); 154 155 // enable IRQ 156 btstack_em9304_spi->set_ready_callback(&em9304_spi_engine_ready_callback); 157 } 158 159 static void em9304_spi_engine_start_rx_transaction(void){ 160 // disable interrupt again 161 btstack_em9304_spi->set_ready_callback(NULL); 162 163 // enable chip select 164 btstack_em9304_spi->set_chip_select(1); 165 166 // send read command 167 em9304_spi_engine_state = SPI_EM9304_RX_W4_READ_COMMAND_SENT; 168 sCommand.bytes[0] = EM9304_SPI_HEADER_RX; 169 btstack_em9304_spi->transmit(sCommand.bytes, 1); 170 } 171 172 static inline int em9304_engine_space_in_rx_buffer(void){ 173 return btstack_ring_buffer_bytes_free(&em9304_spi_engine_rx_ring_buffer) >= SPI_EM9304_BUFFER_SIZE; 174 } 175 176 static void em9304_engine_receive_buffer_ready(void){ 177 // no data ready for receive or transmit, but space in rx ringbuffer -> enable READY IRQ 178 em9304_spi_engine_state = SPI_EM9304_READY_FOR_TX_AND_RX; 179 btstack_em9304_spi->set_ready_callback(&em9304_spi_engine_ready_callback); 180 // avoid dead lock, check READY again 181 if (btstack_em9304_spi->get_ready()){ 182 em9304_spi_engine_start_rx_transaction(); 183 } 184 } 185 186 static void em9304_engine_start_next_transaction(void){ 187 188 switch (em9304_spi_engine_state){ 189 case SPI_EM9304_READY_FOR_TX: 190 case SPI_EM9304_READY_FOR_TX_AND_RX: 191 case SPI_EM9304_DONE: 192 break; 193 default: 194 return; 195 } 196 197 if (btstack_em9304_spi->get_ready() && em9304_engine_space_in_rx_buffer()) { 198 em9304_spi_engine_start_rx_transaction(); 199 } else if (em9304_spi_engine_tx_size){ 200 em9304_spi_engine_start_tx_transaction(); 201 } else if (em9304_engine_space_in_rx_buffer()){ 202 em9304_engine_receive_buffer_ready(); 203 } 204 } 205 206 static void em9304_engine_action_done(void){ 207 // chip deselect & done 208 btstack_em9304_spi->set_chip_select(0); 209 em9304_spi_engine_state = SPI_EM9304_DONE; 210 } 211 212 static void em9304_spi_engine_run(void){ 213 uint16_t max_bytes_to_send; 214 switch (em9304_spi_engine_state){ 215 216 case SPI_EM9304_READY_FOR_TX_AND_RX: 217 // check if ready 218 if (!btstack_em9304_spi->get_ready()) break; 219 em9304_spi_engine_start_rx_transaction(); 220 break; 221 222 case SPI_EM9304_RX_READ_COMMAND_SENT: 223 em9304_spi_engine_state = SPI_EM9304_RX_W4_STS2_RECEIVED; 224 btstack_em9304_spi->receive(sStas.bytes, 1); 225 break; 226 227 case SPI_EM9304_RX_STS2_RECEIVED: 228 // check slave status 229 log_debug("RX: STS2 0x%02X", sStas.bytes[0]); 230 231 // read data 232 em9304_spi_engine_state = SPI_EM9304_RX_W4_DATA_RECEIVED; 233 em9304_spi_engine_rx_request_len = sStas.bytes[0]; 234 btstack_em9304_spi->receive(em9304_spi_engine_spi_buffer.bytes, em9304_spi_engine_rx_request_len); 235 break; 236 237 case SPI_EM9304_RX_DATA_RECEIVED: 238 // done 239 em9304_engine_action_done(); 240 241 // move data into ring buffer 242 btstack_ring_buffer_write(&em9304_spi_engine_rx_ring_buffer, em9304_spi_engine_spi_buffer.bytes, em9304_spi_engine_rx_request_len); 243 em9304_spi_engine_rx_request_len = 0; 244 245 // notify about new data available -- assume empty 246 (*em9304_spi_engine_rx_available_handler)(); 247 248 // next 249 em9304_engine_start_next_transaction(); 250 break; 251 252 case SPI_EM9304_TX_W4_RDY: 253 // check if ready 254 if (!btstack_em9304_spi->get_ready()) break; 255 256 // disable interrupt again 257 btstack_em9304_spi->set_ready_callback(NULL); 258 259 // send write command 260 em9304_spi_engine_state = SPI_EM9304_TX_W4_WRITE_COMMAND_SENT; 261 sCommand.bytes[0] = EM9304_SPI_HEADER_TX; 262 btstack_em9304_spi->transmit(sCommand.bytes, 1); 263 break; 264 265 case SPI_EM9304_TX_WRITE_COMMAND_SENT: 266 em9304_spi_engine_state = SPI_EM9304_TX_W4_STS2_RECEIVED; 267 btstack_em9304_spi->receive(sStas.bytes, 1); 268 break; 269 270 case SPI_EM9304_TX_STS2_RECEIVED: 271 // check slave status and em9304 rx buffer space 272 log_debug("TX: STS2 0x%02X", sStas.bytes[0]); 273 max_bytes_to_send = sStas.bytes[0]; 274 if (max_bytes_to_send == 0u){ 275 // done 276 em9304_engine_action_done(); 277 // next 278 em9304_engine_start_next_transaction(); 279 break; 280 } 281 282 // number bytes to send 283 em9304_spi_engine_tx_request_len = btstack_min(em9304_spi_engine_tx_size, max_bytes_to_send); 284 285 // send command 286 em9304_spi_engine_state = SPI_EM9304_TX_W4_DATA_SENT; 287 if ( (((uintptr_t) em9304_spi_engine_tx_data) & 0x03u) == 0u){ 288 // 4-byte aligned 289 btstack_em9304_spi->transmit( (uint8_t*) em9304_spi_engine_tx_data, em9304_spi_engine_tx_request_len); 290 } else { 291 // TODO: get rid of alignment requirement 292 // enforce alignment by copying to spi buffer first 293 (void)memcpy(em9304_spi_engine_spi_buffer.bytes, 294 em9304_spi_engine_tx_data, 295 em9304_spi_engine_tx_request_len); 296 btstack_em9304_spi->transmit( (uint8_t*) em9304_spi_engine_spi_buffer.bytes, em9304_spi_engine_tx_request_len); 297 } 298 break; 299 300 case SPI_EM9304_TX_DATA_SENT: 301 // done 302 em9304_engine_action_done(); 303 304 // chunk sent 305 em9304_spi_engine_tx_size -= em9304_spi_engine_tx_request_len; 306 em9304_spi_engine_tx_data += em9304_spi_engine_tx_request_len; 307 em9304_spi_engine_tx_request_len = 0; 308 309 // notify higher layer when complete 310 if (em9304_spi_engine_tx_size == 0u){ 311 (*em9304_spi_engine_tx_done_handler)(); 312 } 313 314 // next 315 em9304_engine_start_next_transaction(); 316 break; 317 318 default: 319 break; 320 } 321 } 322 323 static void em9304_spi_engine_init(void){ 324 btstack_em9304_spi->open(); 325 btstack_em9304_spi->set_transfer_done_callback(&em9304_spi_engine_transfer_done); 326 btstack_ring_buffer_init(&em9304_spi_engine_rx_ring_buffer, &em9304_spi_engine_rx_ring_buffer_storage[0], SPI_EM9304_RING_BUFFER_SIZE); 327 em9304_spi_engine_state = SPI_EM9304_DONE; 328 em9304_engine_start_next_transaction(); 329 } 330 331 static void em9304_spi_engine_close(void){ 332 em9304_spi_engine_state = SPI_EM9304_OFF; 333 btstack_em9304_spi->close(); 334 } 335 336 static void em9304_spi_engine_set_data_available( void (*the_block_handler)(void)){ 337 em9304_spi_engine_rx_available_handler = the_block_handler; 338 } 339 340 static void em9304_spi_engine_set_block_sent( void (*the_block_handler)(void)){ 341 em9304_spi_engine_tx_done_handler = the_block_handler; 342 } 343 344 static void em9304_spi_engine_send_block(const uint8_t *buffer, uint16_t length){ 345 em9304_spi_engine_tx_data = buffer; 346 em9304_spi_engine_tx_size = length; 347 em9304_engine_start_next_transaction(); 348 } 349 350 static uint16_t em9304_engine_num_bytes_available(void){ 351 return btstack_ring_buffer_bytes_available(&em9304_spi_engine_rx_ring_buffer); 352 } 353 354 static void em9304_engine_get_bytes(uint8_t * buffer, uint16_t num_bytes){ 355 uint32_t bytes_read; 356 btstack_ring_buffer_read(&em9304_spi_engine_rx_ring_buffer, buffer, num_bytes, &bytes_read); 357 } 358 359 ////////////////////////////////////////////////////////////////////////////// 360 361 // assert pre-buffer for packet type is available 362 #if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE == 0) 363 #error HCI_OUTGOING_PRE_BUFFER_SIZE not defined. Please update hci.h 364 #endif 365 366 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size); 367 368 typedef enum { 369 H4_W4_PACKET_TYPE, 370 H4_W4_EVENT_HEADER, 371 H4_W4_ACL_HEADER, 372 H4_W4_PAYLOAD, 373 } H4_STATE; 374 375 typedef enum { 376 TX_IDLE = 1, 377 TX_W4_PACKET_SENT, 378 } TX_STATE; 379 380 // write state 381 static TX_STATE tx_state; 382 383 static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = dummy_handler; 384 385 // packet reader state machine 386 static H4_STATE hci_transport_em9304_h4_state; 387 static uint16_t hci_transport_em9304_spi_bytes_to_read; 388 static uint16_t hci_transport_em9304_spi_read_pos; 389 390 // incoming packet buffer 391 static uint8_t hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + HCI_INCOMING_PACKET_BUFFER_SIZE + 1]; // packet type + max(acl header + acl payload, event header + event data) 392 static uint8_t * hci_packet = &hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE]; 393 394 static void hci_transport_em9304_spi_block_read(void); 395 396 static void hci_transport_em9304_spi_reset_statemachine(void){ 397 hci_transport_em9304_h4_state = H4_W4_PACKET_TYPE; 398 hci_transport_em9304_spi_read_pos = 0; 399 hci_transport_em9304_spi_bytes_to_read = 1; 400 } 401 402 static void hci_transport_em9304_spi_process_data(void){ 403 while (true){ 404 405 uint16_t bytes_available = em9304_engine_num_bytes_available(); 406 log_debug("transfer_rx_data: ring buffer has %u -> hci wants %u", bytes_available, hci_transport_em9304_spi_bytes_to_read); 407 408 if (!bytes_available) break; 409 if (!hci_transport_em9304_spi_bytes_to_read) break; 410 411 uint16_t bytes_to_copy = btstack_min(bytes_available, hci_transport_em9304_spi_bytes_to_read); 412 em9304_engine_get_bytes(&hci_packet[hci_transport_em9304_spi_read_pos], bytes_to_copy); 413 414 hci_transport_em9304_spi_read_pos += bytes_to_copy; 415 hci_transport_em9304_spi_bytes_to_read -= bytes_to_copy; 416 417 if (hci_transport_em9304_spi_bytes_to_read == 0u){ 418 hci_transport_em9304_spi_block_read(); 419 } 420 } 421 } 422 423 static void hci_transport_em9304_spi_packet_complete(void){ 424 packet_handler(hci_packet[0u], &hci_packet[1u], hci_transport_em9304_spi_read_pos-1u); 425 hci_transport_em9304_spi_reset_statemachine(); 426 } 427 428 static void hci_transport_em9304_spi_block_read(void){ 429 switch (hci_transport_em9304_h4_state) { 430 case H4_W4_PACKET_TYPE: 431 switch (hci_packet[0]){ 432 case HCI_EVENT_PACKET: 433 hci_transport_em9304_spi_bytes_to_read = HCI_EVENT_HEADER_SIZE; 434 hci_transport_em9304_h4_state = H4_W4_EVENT_HEADER; 435 break; 436 case HCI_ACL_DATA_PACKET: 437 hci_transport_em9304_spi_bytes_to_read = HCI_ACL_HEADER_SIZE; 438 hci_transport_em9304_h4_state = H4_W4_ACL_HEADER; 439 break; 440 default: 441 log_error("invalid packet type 0x%02x", hci_packet[0]); 442 hci_transport_em9304_spi_reset_statemachine(); 443 break; 444 } 445 break; 446 447 case H4_W4_EVENT_HEADER: 448 hci_transport_em9304_spi_bytes_to_read = hci_packet[2]; 449 // check Event length 450 if (hci_transport_em9304_spi_bytes_to_read > (HCI_INCOMING_PACKET_BUFFER_SIZE - HCI_EVENT_HEADER_SIZE)){ 451 log_error("invalid Event len %d - only space for %u", hci_transport_em9304_spi_bytes_to_read, HCI_INCOMING_PACKET_BUFFER_SIZE - HCI_EVENT_HEADER_SIZE); 452 hci_transport_em9304_spi_reset_statemachine(); 453 break; 454 } 455 if (hci_transport_em9304_spi_bytes_to_read == 0u){ 456 hci_transport_em9304_spi_packet_complete(); 457 break; 458 } 459 hci_transport_em9304_h4_state = H4_W4_PAYLOAD; 460 break; 461 462 case H4_W4_ACL_HEADER: 463 hci_transport_em9304_spi_bytes_to_read = little_endian_read_16( hci_packet, 3); 464 // check ACL length 465 if (hci_transport_em9304_spi_bytes_to_read > (HCI_INCOMING_PACKET_BUFFER_SIZE - HCI_ACL_HEADER_SIZE)){ 466 log_error("invalid ACL payload len %d - only space for %u", hci_transport_em9304_spi_bytes_to_read, HCI_INCOMING_PACKET_BUFFER_SIZE - HCI_ACL_HEADER_SIZE); 467 hci_transport_em9304_spi_reset_statemachine(); 468 break; 469 } 470 if (hci_transport_em9304_spi_bytes_to_read == 0u){ 471 hci_transport_em9304_spi_packet_complete(); 472 break; 473 } 474 hci_transport_em9304_h4_state = H4_W4_PAYLOAD; 475 break; 476 477 case H4_W4_PAYLOAD: 478 hci_transport_em9304_spi_packet_complete(); 479 break; 480 default: 481 break; 482 } 483 } 484 485 static void hci_transport_em9304_spi_block_sent(void){ 486 487 static const uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 488 489 switch (tx_state){ 490 case TX_W4_PACKET_SENT: 491 // packet fully sent, reset state 492 tx_state = TX_IDLE; 493 // notify upper stack that it can send again 494 packet_handler(HCI_EVENT_PACKET, (uint8_t *) &packet_sent_event[0], sizeof(packet_sent_event)); 495 break; 496 default: 497 break; 498 } 499 } 500 501 static int hci_transport_em9304_spi_can_send_now(uint8_t packet_type){ 502 UNUSED(packet_type); 503 return tx_state == TX_IDLE; 504 } 505 506 static int hci_transport_em9304_spi_send_packet(uint8_t packet_type, uint8_t * packet, int size){ 507 508 // store packet type before actual data and increase size 509 size++; 510 packet--; 511 *packet = packet_type; 512 513 // start sending 514 tx_state = TX_W4_PACKET_SENT; 515 em9304_spi_engine_send_block(packet, size); 516 return 0; 517 } 518 519 static void hci_transport_em9304_spi_init(const void * transport_config){ 520 UNUSED(transport_config); 521 } 522 523 static int hci_transport_em9304_spi_open(void){ 524 525 // setup UART driver 526 em9304_spi_engine_init(); 527 em9304_spi_engine_set_data_available(&hci_transport_em9304_spi_process_data); 528 em9304_spi_engine_set_block_sent(&hci_transport_em9304_spi_block_sent); 529 // setup H4 RX 530 hci_transport_em9304_spi_reset_statemachine(); 531 // setup H4 TX 532 tx_state = TX_IDLE; 533 return 0; 534 } 535 536 static int hci_transport_em9304_spi_close(void){ 537 em9304_spi_engine_close(); 538 return 0; 539 } 540 541 static void hci_transport_em9304_spi_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 542 packet_handler = handler; 543 } 544 545 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ 546 UNUSED(packet_type); 547 UNUSED(packet); 548 UNUSED(size); 549 } 550 551 // --- end of eHCILL implementation --------- 552 553 // configure and return h4 singleton 554 const hci_transport_t * hci_transport_em9304_spi_instance(const btstack_em9304_spi_t * em9304_spi_driver) { 555 556 static const hci_transport_t hci_transport_em9304_spi = { 557 /* const char * name; */ "H4", 558 /* void (*init) (const void *transport_config); */ &hci_transport_em9304_spi_init, 559 /* int (*open)(void); */ &hci_transport_em9304_spi_open, 560 /* int (*close)(void); */ &hci_transport_em9304_spi_close, 561 /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_em9304_spi_register_packet_handler, 562 /* int (*can_send_packet_now)(uint8_t packet_type); */ &hci_transport_em9304_spi_can_send_now, 563 /* int (*send_packet)(...); */ &hci_transport_em9304_spi_send_packet, 564 /* int (*set_baudrate)(uint32_t baudrate); */ NULL, 565 /* void (*reset_link)(void); */ NULL, 566 /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL, 567 }; 568 569 btstack_em9304_spi = em9304_spi_driver; 570 return &hci_transport_em9304_spi; 571 } 572