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