static void h4_block_received(void){ read_pos += bytes_to_read; // act switch (h4_state) { case H4_W4_PACKET_TYPE: switch (hci_packet[0]) { case HCI_ACL_DATA_PACKET: h4_state = H4_W4_ACL_HEADER; bytes_to_read = HCI_ACL_HEADER_SIZE; break; case HCI_EVENT_PACKET: h4_state = H4_W4_EVENT_HEADER; bytes_to_read = HCI_EVENT_HEADER_SIZE; break; default: log_error("h4_process: invalid packet type 0x%02x", hci_packet[0]); read_pos = 0; h4_state = H4_W4_PACKET_TYPE; bytes_to_read = 1; break; } break; case H4_W4_EVENT_HEADER: bytes_to_read = hci_packet[2]; if (bytes_to_read == 0) { h4_state = H4_PACKET_RECEIVED; break; } h4_state = H4_W4_PAYLOAD; break; case H4_W4_ACL_HEADER: bytes_to_read = READ_BT_16( hci_packet, 3); if (bytes_to_read == 0) { h4_state = H4_PACKET_RECEIVED; break; } h4_state = H4_W4_PAYLOAD; break; case H4_W4_PAYLOAD: h4_state = H4_PACKET_RECEIVED; bytes_to_read = 0; // trigger run loop embedded_trigger(); break; default: bytes_to_read = 0; break; } // read next block if (bytes_to_read) { hal_uart_dma_receive_block(&hci_packet[read_pos], bytes_to_read); } }
static void ehcill_sleep_ack_timer_setup(void){ // setup timer ehcill_sleep_ack_timer.process = &ehcill_sleep_ack_timer_handler; run_loop_set_timer(&ehcill_sleep_ack_timer, 50); run_loop_add_timer(&ehcill_sleep_ack_timer); embedded_trigger(); }
// potentially called from ISR context static void h4_block_sent(void){ int command; switch (tx_state){ case TX_W4_PACKET_SENT: // packet fully sent, reset state tx_len = 0; // now, send pending ehcill command if neccessary switch (ehcill_command_to_send){ case EHCILL_GO_TO_SLEEP_ACK: ehcill_sleep_ack_timer_setup(); tx_send_packet_sent = 1; break; case EHCILL_WAKE_UP_IND: tx_state = TX_W4_EHCILL_SENT; // gpio_clear(GPIOB, GPIO_DEBUG_1); hal_uart_dma_send_block(&ehcill_command_to_send, 1); tx_send_packet_sent = 1; break; default: // trigger run loop tx_state = TX_DONE; tx_send_packet_sent = 1; embedded_trigger(); break; } break; case TX_W4_EHCILL_SENT: tx_state = TX_DONE; command = ehcill_command_to_send; ehcill_command_to_send = 0; if (command == EHCILL_GO_TO_SLEEP_ACK) { // UART not needed after EHCILL_GO_TO_SLEEP_ACK was sent hal_uart_dma_set_sleep(1); } if (h4_outgoing_packet_ready()){ // already packet ready? then start wakeup hal_uart_dma_set_sleep(0); ehcill_reactivate_rx(); echill_send_wakeup_ind(); } // trigger run loop embedded_trigger(); break; default: break; } }
static void h4_block_sent(void){ switch (tx_state){ case TX_W4_HEADER_SENT: tx_state = TX_W4_PACKET_SENT; // h4 packet type + actual packet hal_uart_dma_send_block(tx_data, tx_len); break; case TX_W4_PACKET_SENT: tx_state = TX_DONE; // trigger run loop embedded_trigger(); break; default: break; } }
// potentially called from ISR context static void h4_block_received(void){ read_pos += bytes_to_read; // act switch (h4_state) { case H4_W4_PACKET_TYPE: switch (hci_packet[0]) { case HCI_ACL_DATA_PACKET: h4_state = H4_W4_ACL_HEADER; bytes_to_read = HCI_ACL_HEADER_SIZE; break; case HCI_EVENT_PACKET: h4_state = H4_W4_EVENT_HEADER; bytes_to_read = HCI_EVENT_HEADER_SIZE; break; case EHCILL_GO_TO_SLEEP_IND: case EHCILL_GO_TO_SLEEP_ACK: case EHCILL_WAKE_UP_IND: case EHCILL_WAKE_UP_ACK: ehcill_handle(hci_packet[0]); h4_rx_init_sm(); return; default: log_error("h4_process: invalid packet type 0x%02x", hci_packet[0]); h4_rx_init_sm(); return; } break; case H4_W4_EVENT_HEADER: bytes_to_read = hci_packet[2]; // check ACL length if (HCI_ACL_HEADER_SIZE + bytes_to_read > HCI_PACKET_BUFFER_SIZE){ log_error("h4_process: invalid ACL payload len %u - only space for %u", bytes_to_read, HCI_PACKET_BUFFER_SIZE - HCI_ACL_HEADER_SIZE); h4_rx_init_sm(); return; } if (bytes_to_read) { h4_state = H4_W4_PAYLOAD; break; } h4_state = H4_PACKET_RECEIVED; break; case H4_W4_ACL_HEADER: bytes_to_read = READ_BT_16( hci_packet, 3); if (bytes_to_read) { h4_state = H4_W4_PAYLOAD; break; } h4_state = H4_PACKET_RECEIVED; break; case H4_W4_PAYLOAD: h4_state = H4_PACKET_RECEIVED; bytes_to_read = 0; // trigger run loop - necessary for use in low power modes embedded_trigger(); break; default: bytes_to_read = 0; break; } // read next block if (bytes_to_read) { ehcill_uart_dma_receive_block(&hci_packet[read_pos], bytes_to_read); } // gpio_clear(GPIOB, GPIO_DEBUG_0); }