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 MATTHIAS 24 * RINGWALD 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_h4.c" 39 40 /* 41 * hci_h4_transport.c 42 * 43 * HCI Transport API implementation for H4 protocol over POSIX with optional support for eHCILL 44 * 45 * Created by Matthias Ringwald on 4/29/09. 46 */ 47 48 #include <inttypes.h> 49 50 #include "btstack_config.h" 51 52 #include "btstack_debug.h" 53 #include "hci.h" 54 #include "hci_transport.h" 55 #include "bluetooth_company_id.h" 56 #include "btstack_uart_block.h" 57 58 #define ENABLE_LOG_EHCILL 59 60 #ifdef ENABLE_EHCILL 61 62 // eHCILL commands 63 enum EHCILL_MESSAGES { 64 EHCILL_GO_TO_SLEEP_IND = 0x030, 65 EHCILL_GO_TO_SLEEP_ACK = 0x031, 66 EHCILL_WAKE_UP_IND = 0x032, 67 EHCILL_WAKE_UP_ACK = 0x033, 68 EHCILL_WAKEUP_SIGNAL = 0x034, 69 }; 70 71 static int hci_transport_h4_ehcill_outgoing_packet_ready(void); 72 static void hci_transport_h4_echill_send_wakeup_ind(void); 73 static void hci_transport_h4_ehcill_handle_command(uint8_t action); 74 static void hci_transport_h4_ehcill_handle_ehcill_command_sent(void); 75 static void hci_transport_h4_ehcill_handle_packet_sent(void); 76 static void hci_transport_h4_ehcill_open(void); 77 static void hci_transport_h4_ehcill_reset_statemachine(void); 78 static void hci_transport_h4_ehcill_send_ehcill_command(void); 79 static void hci_transport_h4_ehcill_sleep_ack_timer_setup(void); 80 static void hci_transport_h4_ehcill_trigger_wakeup(void); 81 82 typedef enum { 83 EHCILL_STATE_W2_SEND_SLEEP_ACK, 84 EHCILL_STATE_SLEEP, 85 EHCILL_STATE_W4_WAKEUP_IND_OR_ACK, 86 EHCILL_STATE_AWAKE 87 } EHCILL_STATE; 88 89 // eHCILL state machine 90 static EHCILL_STATE ehcill_state; 91 static uint8_t ehcill_command_to_send; 92 93 static btstack_uart_sleep_mode_t btstack_uart_sleep_mode; 94 95 // work around for eHCILL problem 96 static btstack_timer_source_t ehcill_sleep_ack_timer; 97 98 #endif 99 100 101 // assert pre-buffer for packet type is available 102 #if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE == 0) 103 #error HCI_OUTGOING_PRE_BUFFER_SIZE not defined. Please update hci.h 104 #endif 105 106 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size); 107 108 typedef enum { 109 H4_W4_PACKET_TYPE, 110 H4_W4_EVENT_HEADER, 111 H4_W4_ACL_HEADER, 112 H4_W4_SCO_HEADER, 113 H4_W4_PAYLOAD, 114 } H4_STATE; 115 116 typedef enum { 117 TX_IDLE = 1, 118 TX_W4_PACKET_SENT, 119 #ifdef ENABLE_EHCILL 120 TX_W4_WAKEUP, 121 TX_W2_EHCILL_SEND, 122 TX_W4_EHCILL_SENT, 123 #endif 124 } TX_STATE; 125 126 // UART Driver + Config 127 static const btstack_uart_block_t * btstack_uart; 128 static btstack_uart_config_t uart_config; 129 130 // write state 131 static TX_STATE tx_state; 132 static uint8_t * tx_data; 133 static uint16_t tx_len; // 0 == no outgoing packet 134 135 static uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 136 137 static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = dummy_handler; 138 139 // packet reader state machine 140 static H4_STATE h4_state; 141 static int bytes_to_read; 142 static int read_pos; 143 144 // incoming packet buffer 145 static uint8_t hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + 1 + HCI_PACKET_BUFFER_SIZE]; // packet type + max(acl header + acl payload, event header + event data) 146 static uint8_t * hci_packet = &hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE]; 147 148 #ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND 149 static const uint8_t local_version_event_prefix[] = { 0x04, 0x0e, 0x0c, 0x01, 0x01, 0x10}; 150 static const uint8_t baud_rate_command_prefix[] = { 0x01, 0x36, 0xff, 0x04}; 151 static enum { 152 CC256X_WORKAROUND_IDLE, 153 CC256X_WORKAROUND_CHIPSET_DETECTED, 154 CC256X_WORKAROUND_BAUDRATE_COMMAND_SENT, 155 CC256X_WORKAROUND_DONE 156 } cc256x_workaround_state; 157 #endif 158 159 static int hci_transport_h4_set_baudrate(uint32_t baudrate){ 160 log_info("hci_transport_h4_set_baudrate %"PRIu32, baudrate); 161 return btstack_uart->set_baudrate(baudrate); 162 } 163 164 static void hci_transport_h4_reset_statemachine(void){ 165 h4_state = H4_W4_PACKET_TYPE; 166 read_pos = 0; 167 bytes_to_read = 1; 168 } 169 170 static void hci_transport_h4_trigger_next_read(void){ 171 // log_info("hci_transport_h4_trigger_next_read: %u bytes", bytes_to_read); 172 btstack_uart->receive_block(&hci_packet[read_pos], bytes_to_read); 173 } 174 175 static void hci_transport_h4_block_read(void){ 176 177 read_pos += bytes_to_read; 178 179 switch (h4_state) { 180 case H4_W4_PACKET_TYPE: 181 switch (hci_packet[0]){ 182 case HCI_EVENT_PACKET: 183 bytes_to_read = HCI_EVENT_HEADER_SIZE; 184 h4_state = H4_W4_EVENT_HEADER; 185 break; 186 case HCI_ACL_DATA_PACKET: 187 bytes_to_read = HCI_ACL_HEADER_SIZE; 188 h4_state = H4_W4_ACL_HEADER; 189 break; 190 case HCI_SCO_DATA_PACKET: 191 bytes_to_read = HCI_SCO_HEADER_SIZE; 192 h4_state = H4_W4_SCO_HEADER; 193 break; 194 #ifdef ENABLE_EHCILL 195 case EHCILL_GO_TO_SLEEP_IND: 196 case EHCILL_GO_TO_SLEEP_ACK: 197 case EHCILL_WAKE_UP_IND: 198 case EHCILL_WAKE_UP_ACK: 199 hci_transport_h4_ehcill_handle_command(hci_packet[0]); 200 hci_transport_h4_reset_statemachine(); 201 break; 202 #endif 203 default: 204 log_error("hci_transport_h4: invalid packet type 0x%02x", hci_packet[0]); 205 hci_transport_h4_reset_statemachine(); 206 break; 207 } 208 break; 209 210 case H4_W4_EVENT_HEADER: 211 bytes_to_read = hci_packet[2]; 212 h4_state = H4_W4_PAYLOAD; 213 break; 214 215 case H4_W4_ACL_HEADER: 216 bytes_to_read = little_endian_read_16( hci_packet, 3); 217 // check ACL length 218 if (HCI_ACL_HEADER_SIZE + bytes_to_read > HCI_PACKET_BUFFER_SIZE){ 219 log_error("hci_transport_h4: invalid ACL payload len %d - only space for %u", bytes_to_read, HCI_PACKET_BUFFER_SIZE - HCI_ACL_HEADER_SIZE); 220 hci_transport_h4_reset_statemachine(); 221 break; 222 } 223 h4_state = H4_W4_PAYLOAD; 224 break; 225 226 case H4_W4_SCO_HEADER: 227 bytes_to_read = hci_packet[3]; 228 h4_state = H4_W4_PAYLOAD; 229 break; 230 231 case H4_W4_PAYLOAD: 232 #ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND 233 if (cc256x_workaround_state == CC256X_WORKAROUND_IDLE 234 && memcmp(hci_packet, local_version_event_prefix, sizeof(local_version_event_prefix)) == 0){ 235 if (little_endian_read_16(hci_packet, 11) == BLUETOOTH_COMPANY_ID_TEXAS_INSTRUMENTS_INC){ 236 // detect TI CC256x controller based on manufacturer 237 log_info("Detected CC256x controller"); 238 cc256x_workaround_state = CC256X_WORKAROUND_CHIPSET_DETECTED; 239 } else { 240 // work around not needed 241 log_info("Bluetooth controller not by TI"); 242 cc256x_workaround_state = CC256X_WORKAROUND_DONE; 243 } 244 } 245 #endif 246 packet_handler(hci_packet[0], &hci_packet[1], read_pos-1); 247 hci_transport_h4_reset_statemachine(); 248 break; 249 default: 250 break; 251 } 252 253 #ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND 254 if (cc256x_workaround_state == CC256X_WORKAROUND_BAUDRATE_COMMAND_SENT){ 255 cc256x_workaround_state = CC256X_WORKAROUND_IDLE; 256 // avoid flowcontrol problem by reading expected hci command complete event of 7 bytes in a single block read 257 h4_state = H4_W4_PAYLOAD; 258 bytes_to_read = 7; 259 } 260 #endif 261 262 hci_transport_h4_trigger_next_read(); 263 } 264 265 static void hci_transport_h4_block_sent(void){ 266 switch (tx_state){ 267 case TX_W4_PACKET_SENT: 268 // packet fully sent, reset state 269 tx_len = 0; 270 tx_state = TX_IDLE; 271 272 #ifdef ENABLE_EHCILL 273 // notify eHCILL engine 274 hci_transport_h4_ehcill_handle_packet_sent(); 275 #endif 276 // notify upper stack that it can send again 277 packet_handler(HCI_EVENT_PACKET, &packet_sent_event[0], sizeof(packet_sent_event)); 278 break; 279 280 #ifdef ENABLE_EHCILL 281 case TX_W4_EHCILL_SENT: 282 case TX_W4_WAKEUP: 283 hci_transport_h4_ehcill_handle_ehcill_command_sent(); 284 break; 285 #endif 286 287 default: 288 break; 289 } 290 } 291 292 static int hci_transport_h4_can_send_now(uint8_t packet_type){ 293 return tx_state == TX_IDLE; 294 } 295 296 static int hci_transport_h4_send_packet(uint8_t packet_type, uint8_t * packet, int size){ 297 298 // store packet type before actual data and increase size 299 size++; 300 packet--; 301 *packet = packet_type; 302 303 #ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND 304 if ((cc256x_workaround_state == CC256X_WORKAROUND_CHIPSET_DETECTED) 305 && (memcmp(packet, baud_rate_command_prefix, sizeof(baud_rate_command_prefix)) == 0)) { 306 log_info("CC256x baud rate command detected, expect command complete event next"); 307 cc256x_workaround_state = CC256X_WORKAROUND_BAUDRATE_COMMAND_SENT; 308 } 309 #endif 310 311 // store request 312 tx_len = size; 313 tx_data = packet; 314 315 #ifdef ENABLE_EHCILL 316 switch (ehcill_state){ 317 case EHCILL_STATE_SLEEP: 318 hci_transport_h4_ehcill_trigger_wakeup(); 319 return 0; 320 case EHCILL_STATE_W2_SEND_SLEEP_ACK: 321 log_info("eHILL: send next packet, state EHCILL_STATE_W2_SEND_SLEEP_ACK"); 322 return 0; 323 default: 324 break; 325 } 326 #endif 327 328 // start sending 329 tx_state = TX_W4_PACKET_SENT; 330 btstack_uart->send_block(packet, size); 331 return 0; 332 } 333 334 static void hci_transport_h4_init(const void * transport_config){ 335 // check for hci_transport_config_uart_t 336 if (!transport_config) { 337 log_error("hci_transport_h4: no config!"); 338 return; 339 } 340 if (((hci_transport_config_t*)transport_config)->type != HCI_TRANSPORT_CONFIG_UART) { 341 log_error("hci_transport_h4: config not of type != HCI_TRANSPORT_CONFIG_UART!"); 342 return; 343 } 344 345 // extract UART config from transport config 346 hci_transport_config_uart_t * hci_transport_config_uart = (hci_transport_config_uart_t*) transport_config; 347 uart_config.baudrate = hci_transport_config_uart->baudrate_init; 348 uart_config.flowcontrol = hci_transport_config_uart->flowcontrol; 349 uart_config.device_name = hci_transport_config_uart->device_name; 350 351 // setup UART driver 352 btstack_uart->init(&uart_config); 353 btstack_uart->set_block_received(&hci_transport_h4_block_read); 354 btstack_uart->set_block_sent(&hci_transport_h4_block_sent); 355 } 356 357 static int hci_transport_h4_open(void){ 358 int res = btstack_uart->open(); 359 if (res){ 360 return res; 361 } 362 hci_transport_h4_reset_statemachine(); 363 hci_transport_h4_trigger_next_read(); 364 365 tx_state = TX_IDLE; 366 367 #ifdef ENABLE_EHCILL 368 hci_transport_h4_ehcill_open(); 369 #endif 370 return 0; 371 } 372 373 static int hci_transport_h4_close(void){ 374 return btstack_uart->close(); 375 } 376 377 static void hci_transport_h4_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 378 packet_handler = handler; 379 } 380 381 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ 382 } 383 384 // 385 // --- main part of eHCILL implementation --- 386 // 387 388 #ifdef ENABLE_EHCILL 389 390 static void hci_transport_h4_ehcill_emit_sleep_state(int sleep_active){ 391 static int last_state = 0; 392 if (sleep_active == last_state) return; 393 last_state = sleep_active; 394 395 log_info("hci_transport_h4_ehcill_emit_sleep_state: %u", sleep_active); 396 uint8_t event[3]; 397 event[0] = HCI_EVENT_TRANSPORT_SLEEP_MODE; 398 event[1] = sizeof(event) - 2; 399 event[2] = sleep_active; 400 packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); 401 } 402 403 static void hci_transport_h4_ehcill_wakeup_handler(void){ 404 #ifdef ENABLE_LOG_EHCILL 405 log_info("eHCILL: UART wakeup received"); 406 #endif 407 hci_transport_h4_ehcill_handle_command(EHCILL_WAKEUP_SIGNAL); 408 } 409 410 static void hci_transport_h4_ehcill_open(void){ 411 hci_transport_h4_ehcill_reset_statemachine(); 412 413 // find best sleep mode to use: wake on CTS, wake on RX, none 414 btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_OFF; 415 int supported_sleep_modes = 0; 416 if (btstack_uart->get_supported_sleep_modes){ 417 supported_sleep_modes = btstack_uart->get_supported_sleep_modes(); 418 } 419 if (supported_sleep_modes & BTSTACK_UART_SLEEP_MASK_RTS_HIGH_WAKE_ON_CTS_PULSE){ 420 log_info("eHCILL: using wake on CTS"); 421 btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_RTS_HIGH_WAKE_ON_CTS_PULSE; 422 } else if (supported_sleep_modes & BTSTACK_UART_SLEEP_MASK_RTS_LOW_WAKE_ON_RX_EDGE){ 423 log_info("eHCILL: using wake on RX"); 424 btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_RTS_LOW_WAKE_ON_RX_EDGE; 425 } else { 426 log_info("eHCILL: UART driver does not provide compatible sleep mode"); 427 } 428 if (btstack_uart->set_wakeup_handler){ 429 btstack_uart->set_wakeup_handler(&hci_transport_h4_ehcill_wakeup_handler); 430 } 431 } 432 433 static void hci_transport_h4_echill_send_wakeup_ind(void){ 434 #ifdef ENABLE_LOG_EHCILL 435 log_info("eHCILL: send WAKEUP_IND"); 436 #endif 437 // update state 438 tx_state = TX_W4_WAKEUP; 439 ehcill_state = EHCILL_STATE_W4_WAKEUP_IND_OR_ACK; 440 ehcill_command_to_send = EHCILL_WAKE_UP_IND; 441 btstack_uart->send_block(&ehcill_command_to_send, 1); 442 } 443 444 static int hci_transport_h4_ehcill_outgoing_packet_ready(void){ 445 return tx_len != 0; 446 } 447 448 static void hci_transport_h4_ehcill_reset_statemachine(void){ 449 ehcill_state = EHCILL_STATE_AWAKE; 450 } 451 452 static void hci_transport_h4_ehcill_send_ehcill_command(void){ 453 #ifdef ENABLE_LOG_EHCILL 454 log_info("eHCILL: send command %02x", ehcill_command_to_send); 455 #endif 456 tx_state = TX_W4_EHCILL_SENT; 457 if (ehcill_command_to_send == EHCILL_GO_TO_SLEEP_ACK){ 458 ehcill_state = EHCILL_STATE_SLEEP; 459 } 460 btstack_uart->send_block(&ehcill_command_to_send, 1); 461 } 462 463 static void hci_transport_h4_ehcill_sleep_ack_timer_handler(btstack_timer_source_t * timer){ 464 UNUSED(timer); 465 #ifdef ENABLE_LOG_EHCILL 466 log_info("eHCILL: timer triggered"); 467 #endif 468 hci_transport_h4_ehcill_send_ehcill_command(); 469 } 470 471 static void hci_transport_h4_ehcill_sleep_ack_timer_setup(void){ 472 // setup timer 473 #ifdef ENABLE_LOG_EHCILL 474 log_info("eHCILL: set timer for sending command %02x", ehcill_command_to_send); 475 #endif 476 btstack_run_loop_set_timer_handler(&ehcill_sleep_ack_timer, &hci_transport_h4_ehcill_sleep_ack_timer_handler); 477 btstack_run_loop_set_timer(&ehcill_sleep_ack_timer, 50); 478 btstack_run_loop_add_timer(&ehcill_sleep_ack_timer); 479 } 480 481 static void hci_transport_h4_ehcill_trigger_wakeup(void){ 482 switch (tx_state){ 483 case TX_W2_EHCILL_SEND: 484 case TX_W4_EHCILL_SENT: 485 // wake up / sleep ack in progress, nothing to do now 486 return; 487 case TX_IDLE: 488 default: 489 // all clear, prepare for wakeup 490 break; 491 } 492 // UART needed again 493 hci_transport_h4_ehcill_emit_sleep_state(0); 494 if (btstack_uart_sleep_mode){ 495 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 496 } 497 hci_transport_h4_echill_send_wakeup_ind(); 498 } 499 500 static void hci_transport_h4_ehcill_schedule_ehcill_command(uint8_t command){ 501 #ifdef ENABLE_LOG_EHCILL 502 log_info("eHCILL: schedule eHCILL command %02x", command); 503 #endif 504 ehcill_command_to_send = command; 505 switch (tx_state){ 506 case TX_IDLE: 507 if (ehcill_command_to_send == EHCILL_WAKE_UP_ACK){ 508 // send right away 509 hci_transport_h4_ehcill_send_ehcill_command(); 510 } else { 511 // change state so BTstack cannot send and setup timer 512 tx_state = TX_W2_EHCILL_SEND; 513 hci_transport_h4_ehcill_sleep_ack_timer_setup(); 514 } 515 break; 516 default: 517 break; 518 } 519 } 520 521 static void hci_transport_h4_ehcill_handle_command(uint8_t action){ 522 // log_info("hci_transport_h4_ehcill_handle: %x, state %u, defer_rx %u", action, ehcill_state, ehcill_defer_rx_size); 523 switch(ehcill_state){ 524 case EHCILL_STATE_AWAKE: 525 switch(action){ 526 case EHCILL_GO_TO_SLEEP_IND: 527 ehcill_state = EHCILL_STATE_W2_SEND_SLEEP_ACK; 528 #ifdef ENABLE_LOG_EHCILL 529 log_info("eHCILL: Received GO_TO_SLEEP_IND RX"); 530 #endif 531 hci_transport_h4_ehcill_schedule_ehcill_command(EHCILL_GO_TO_SLEEP_ACK); 532 break; 533 default: 534 break; 535 } 536 break; 537 538 case EHCILL_STATE_W2_SEND_SLEEP_ACK: 539 switch(action){ 540 case EHCILL_WAKE_UP_IND: 541 ehcill_state = EHCILL_STATE_AWAKE; 542 hci_transport_h4_ehcill_emit_sleep_state(0); 543 if (btstack_uart_sleep_mode){ 544 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 545 } 546 #ifdef ENABLE_LOG_EHCILL 547 log_info("eHCILL: Received WAKE_UP_IND RX"); 548 #endif 549 hci_transport_h4_ehcill_schedule_ehcill_command(EHCILL_WAKE_UP_ACK); 550 break; 551 552 default: 553 break; 554 } 555 break; 556 557 case EHCILL_STATE_SLEEP: 558 switch(action){ 559 case EHCILL_WAKEUP_SIGNAL: 560 hci_transport_h4_ehcill_emit_sleep_state(0); 561 if (btstack_uart_sleep_mode){ 562 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 563 } 564 break; 565 case EHCILL_WAKE_UP_IND: 566 ehcill_state = EHCILL_STATE_AWAKE; 567 hci_transport_h4_ehcill_emit_sleep_state(0); 568 if (btstack_uart_sleep_mode){ 569 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 570 } 571 #ifdef ENABLE_LOG_EHCILL 572 log_info("eHCILL: Received WAKE_UP_IND RX"); 573 #endif 574 hci_transport_h4_ehcill_schedule_ehcill_command(EHCILL_WAKE_UP_ACK); 575 break; 576 577 default: 578 break; 579 } 580 break; 581 582 case EHCILL_STATE_W4_WAKEUP_IND_OR_ACK: 583 switch(action){ 584 case EHCILL_WAKE_UP_IND: 585 case EHCILL_WAKE_UP_ACK: 586 #ifdef ENABLE_LOG_EHCILL 587 log_info("eHCILL: Received WAKE_UP (%02x)", action); 588 #endif 589 tx_state = TX_W4_PACKET_SENT; 590 ehcill_state = EHCILL_STATE_AWAKE; 591 btstack_uart->send_block(tx_data, tx_len); 592 break; 593 default: 594 break; 595 } 596 break; 597 } 598 } 599 600 static void hci_transport_h4_ehcill_handle_packet_sent(void){ 601 #ifdef ENABLE_LOG_EHCILL 602 log_info("eHCILL: handle packet sent, command to send %02x", ehcill_command_to_send); 603 #endif 604 // now, send pending ehcill command if neccessary 605 switch (ehcill_command_to_send){ 606 case EHCILL_GO_TO_SLEEP_ACK: 607 hci_transport_h4_ehcill_sleep_ack_timer_setup(); 608 break; 609 case EHCILL_WAKE_UP_IND: 610 hci_transport_h4_ehcill_send_ehcill_command(); 611 break; 612 default: 613 break; 614 } 615 } 616 617 static void hci_transport_h4_ehcill_handle_ehcill_command_sent(void){ 618 tx_state = TX_IDLE; 619 int command = ehcill_command_to_send; 620 ehcill_command_to_send = 0; 621 622 #ifdef ENABLE_LOG_EHCILL 623 log_info("eHCILL: handle eHCILL sent, command was %02x", command); 624 #endif 625 626 if (command == EHCILL_GO_TO_SLEEP_ACK) { 627 #ifdef ENABLE_LOG_EHCILL 628 log_info("eHCILL: GO_TO_SLEEP_ACK sent, enter sleep mode"); 629 #endif 630 // UART not needed after EHCILL_GO_TO_SLEEP_ACK was sent 631 if (btstack_uart_sleep_mode != BTSTACK_UART_SLEEP_OFF){ 632 btstack_uart->set_sleep(btstack_uart_sleep_mode); 633 } 634 hci_transport_h4_ehcill_emit_sleep_state(1); 635 } 636 // already packet ready? then start wakeup 637 if (hci_transport_h4_ehcill_outgoing_packet_ready()){ 638 hci_transport_h4_ehcill_emit_sleep_state(0); 639 if (btstack_uart_sleep_mode != BTSTACK_UART_SLEEP_OFF){ 640 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 641 } 642 if (command != EHCILL_WAKE_UP_IND){ 643 hci_transport_h4_echill_send_wakeup_ind(); 644 } 645 } 646 } 647 648 #endif 649 // --- end of eHCILL implementation --------- 650 651 static const hci_transport_t hci_transport_h4 = { 652 /* const char * name; */ "H4", 653 /* void (*init) (const void *transport_config); */ &hci_transport_h4_init, 654 /* int (*open)(void); */ &hci_transport_h4_open, 655 /* int (*close)(void); */ &hci_transport_h4_close, 656 /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_h4_register_packet_handler, 657 /* int (*can_send_packet_now)(uint8_t packet_type); */ &hci_transport_h4_can_send_now, 658 /* int (*send_packet)(...); */ &hci_transport_h4_send_packet, 659 /* int (*set_baudrate)(uint32_t baudrate); */ &hci_transport_h4_set_baudrate, 660 /* void (*reset_link)(void); */ NULL, 661 /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL, 662 }; 663 664 // configure and return h4 singleton 665 const hci_transport_t * hci_transport_h4_instance(const btstack_uart_block_t * uart_driver) { 666 btstack_uart = uart_driver; 667 return &hci_transport_h4; 668 } 669