1faa6c1f6SMatthias Ringwald /* 2faa6c1f6SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3faa6c1f6SMatthias Ringwald * 4faa6c1f6SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5faa6c1f6SMatthias Ringwald * modification, are permitted provided that the following conditions 6faa6c1f6SMatthias Ringwald * are met: 7faa6c1f6SMatthias Ringwald * 8faa6c1f6SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9faa6c1f6SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10faa6c1f6SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11faa6c1f6SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12faa6c1f6SMatthias Ringwald * documentation and/or other materials provided with the distribution. 13faa6c1f6SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14faa6c1f6SMatthias Ringwald * contributors may be used to endorse or promote products derived 15faa6c1f6SMatthias Ringwald * from this software without specific prior written permission. 16faa6c1f6SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17faa6c1f6SMatthias Ringwald * personal benefit and not for any commercial purpose or for 18faa6c1f6SMatthias Ringwald * monetary gain. 19faa6c1f6SMatthias Ringwald * 20faa6c1f6SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21faa6c1f6SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22faa6c1f6SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23faa6c1f6SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24faa6c1f6SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25faa6c1f6SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26faa6c1f6SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27faa6c1f6SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28faa6c1f6SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29faa6c1f6SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30faa6c1f6SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31faa6c1f6SMatthias Ringwald * SUCH DAMAGE. 32faa6c1f6SMatthias Ringwald * 33faa6c1f6SMatthias Ringwald * Please inquire about commercial licensing options at 34faa6c1f6SMatthias Ringwald * [email protected] 35faa6c1f6SMatthias Ringwald * 36faa6c1f6SMatthias Ringwald */ 37faa6c1f6SMatthias Ringwald 38faa6c1f6SMatthias Ringwald /* 39fb55bd0aSMatthias Ringwald * btstack_chipset_csr.c 40faa6c1f6SMatthias Ringwald * 41faa6c1f6SMatthias Ringwald * Adapter to use CSR-based chipsets with BTstack 42*fc62ef06SMatthias Ringwald * SCO over HCI doesn't work over H4 connection and BTM805 module from Microchip Bluetooth Audio Developer Kit (CSR8811) 43faa6c1f6SMatthias Ringwald */ 44faa6c1f6SMatthias Ringwald 45fb55bd0aSMatthias Ringwald #include "btstack_chipset_csr.h" 46faa6c1f6SMatthias Ringwald 47faa6c1f6SMatthias Ringwald #include <stddef.h> /* NULL */ 48faa6c1f6SMatthias Ringwald #include <stdio.h> 49faa6c1f6SMatthias Ringwald #include <string.h> /* memcpy */ 50faa6c1f6SMatthias Ringwald 51faa6c1f6SMatthias Ringwald #include "btstack_control.h" 52faa6c1f6SMatthias Ringwald #include "btstack_debug.h" 53faa6c1f6SMatthias Ringwald #include "btstack_util.h" 54faa6c1f6SMatthias Ringwald #include "hci_transport.h" 55faa6c1f6SMatthias Ringwald 56faa6c1f6SMatthias Ringwald // minimal CSR init script to configure PSKEYs and activate them 57faa6c1f6SMatthias Ringwald static const uint8_t init_script[] = { 58*fc62ef06SMatthias Ringwald 59*fc62ef06SMatthias Ringwald // Set ANA_Freq to 26MHz 60faa6c1f6SMatthias Ringwald 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xfe, 0x01, 0x01, 0x00, 0x00, 0x00, 0x90, 0x65, 61*fc62ef06SMatthias Ringwald 62faa6c1f6SMatthias Ringwald // Set HCI_NOP_DISABLE 63faa6c1f6SMatthias Ringwald 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 64*fc62ef06SMatthias Ringwald 65*fc62ef06SMatthias Ringwald #ifdef HAVE_SCO_OVER_HCI 66*fc62ef06SMatthias Ringwald // Set HOSTIO_MAP_SCO_PCM to 0 67*fc62ef06SMatthias Ringwald 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xab, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 68*fc62ef06SMatthias Ringwald 69*fc62ef06SMatthias Ringwald // Set ENABLE_SCO_STREAMS to 0 70*fc62ef06SMatthias Ringwald 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x03, 0x70, 0x00, 0x00, 0xc9, 0x22, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 71*fc62ef06SMatthias Ringwald #endif 72*fc62ef06SMatthias Ringwald 73faa6c1f6SMatthias Ringwald // Set UART baudrate to 115200 74faa6c1f6SMatthias Ringwald 0x01, 0x00, 0xFC, 0x15, 0xc2, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x03, 0x70, 0x00, 0x00, 0xea, 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xc2, 75*fc62ef06SMatthias Ringwald 76faa6c1f6SMatthias Ringwald // WarmReset 77faa6c1f6SMatthias Ringwald 0x01, 0x00, 0xFC, 0x13, 0xc2, 0x02, 0x00, 0x09, 0x00, 0x03, 0x0e, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78faa6c1f6SMatthias Ringwald }; 79faa6c1f6SMatthias Ringwald static const uint16_t init_script_size = sizeof(init_script); 80faa6c1f6SMatthias Ringwald 81faa6c1f6SMatthias Ringwald // 82faa6c1f6SMatthias Ringwald static uint32_t init_script_offset = 0; 83faa6c1f6SMatthias Ringwald static hci_transport_config_uart_t * hci_transport_config_uart = NULL; 84faa6c1f6SMatthias Ringwald 85fb55bd0aSMatthias Ringwald static void chipset_init(const void * config){ 86faa6c1f6SMatthias Ringwald init_script_offset = 0; 87faa6c1f6SMatthias Ringwald hci_transport_config_uart = NULL; 88faa6c1f6SMatthias Ringwald // check for hci_transport_config_uart_t 89faa6c1f6SMatthias Ringwald if (!config) return; 90faa6c1f6SMatthias Ringwald if (((hci_transport_config_t*)config)->type != HCI_TRANSPORT_CONFIG_UART) return; 91faa6c1f6SMatthias Ringwald hci_transport_config_uart = (hci_transport_config_uart_t*) config; 92faa6c1f6SMatthias Ringwald } 93faa6c1f6SMatthias Ringwald 94faa6c1f6SMatthias Ringwald static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buffer){ 95faa6c1f6SMatthias Ringwald } 96faa6c1f6SMatthias Ringwald 97faa6c1f6SMatthias Ringwald // set requested baud rate 98faa6c1f6SMatthias Ringwald static void update_init_script_command(uint8_t *hci_cmd_buffer){ 99faa6c1f6SMatthias Ringwald uint16_t varid = READ_BT_16(hci_cmd_buffer, 10); 100faa6c1f6SMatthias Ringwald if (varid != 0x7003) return; 101faa6c1f6SMatthias Ringwald uint16_t key = READ_BT_16(hci_cmd_buffer, 14); 102*fc62ef06SMatthias Ringwald log_info("csr: pskey 0x%04x", key); 103faa6c1f6SMatthias Ringwald if (key != 0x01ea) return; 104faa6c1f6SMatthias Ringwald 105faa6c1f6SMatthias Ringwald // check for baud rate 106faa6c1f6SMatthias Ringwald if (!hci_transport_config_uart) return; 107faa6c1f6SMatthias Ringwald uint32_t baudrate = hci_transport_config_uart->baudrate_main; 108faa6c1f6SMatthias Ringwald if (baudrate == 0){ 109faa6c1f6SMatthias Ringwald baudrate = hci_transport_config_uart->baudrate_init; 110faa6c1f6SMatthias Ringwald } 111faa6c1f6SMatthias Ringwald // uint32_t is stored as 2 x uint16_t with most important 16 bits first 112faa6c1f6SMatthias Ringwald bt_store_16(hci_cmd_buffer, 20, baudrate >> 16); 113faa6c1f6SMatthias Ringwald bt_store_16(hci_cmd_buffer, 22, baudrate & 0xffff); 114faa6c1f6SMatthias Ringwald } 115faa6c1f6SMatthias Ringwald 116faa6c1f6SMatthias Ringwald static btstack_chipset_result_t chipset_next_command(uint8_t * hci_cmd_buffer){ 117faa6c1f6SMatthias Ringwald 118faa6c1f6SMatthias Ringwald if (init_script_offset >= init_script_size) { 119faa6c1f6SMatthias Ringwald return BTSTACK_CHIPSET_DONE; 120faa6c1f6SMatthias Ringwald } 121faa6c1f6SMatthias Ringwald 122faa6c1f6SMatthias Ringwald // init script is stored with the HCI Command Packet Type 123faa6c1f6SMatthias Ringwald init_script_offset++; 124faa6c1f6SMatthias Ringwald // copy command header 125faa6c1f6SMatthias Ringwald memcpy(&hci_cmd_buffer[0], (uint8_t *) &init_script[init_script_offset], 3); 126faa6c1f6SMatthias Ringwald init_script_offset += 3; 127faa6c1f6SMatthias Ringwald int payload_len = hci_cmd_buffer[2]; 128faa6c1f6SMatthias Ringwald // copy command payload 129faa6c1f6SMatthias Ringwald memcpy(&hci_cmd_buffer[3], (uint8_t *) &init_script[init_script_offset], payload_len); 130faa6c1f6SMatthias Ringwald 131faa6c1f6SMatthias Ringwald // support for on-the-fly configuration updates 132faa6c1f6SMatthias Ringwald update_init_script_command(hci_cmd_buffer); 133faa6c1f6SMatthias Ringwald 134faa6c1f6SMatthias Ringwald init_script_offset += payload_len; 135faa6c1f6SMatthias Ringwald 136faa6c1f6SMatthias Ringwald // support for warm boot command 137faa6c1f6SMatthias Ringwald uint16_t varid = READ_BT_16(hci_cmd_buffer, 10); 138faa6c1f6SMatthias Ringwald if (varid == 0x4002){ 139faa6c1f6SMatthias Ringwald return BTSTACK_CHIPSET_WARMSTART_REQUIRED; 140faa6c1f6SMatthias Ringwald } 141faa6c1f6SMatthias Ringwald 142faa6c1f6SMatthias Ringwald return BTSTACK_CHIPSET_VALID_COMMAND; 143faa6c1f6SMatthias Ringwald } 144faa6c1f6SMatthias Ringwald 145faa6c1f6SMatthias Ringwald 146faa6c1f6SMatthias Ringwald static const btstack_chipset_t btstack_chipset_bcm = { 147faa6c1f6SMatthias Ringwald "BCM", 148faa6c1f6SMatthias Ringwald chipset_init, 149faa6c1f6SMatthias Ringwald chipset_next_command, 150faa6c1f6SMatthias Ringwald chipset_set_baudrate_command, 151faa6c1f6SMatthias Ringwald NULL, // chipset_set_bd_addr_command not supported or implemented 152faa6c1f6SMatthias Ringwald }; 153faa6c1f6SMatthias Ringwald 154faa6c1f6SMatthias Ringwald // MARK: public API 155faa6c1f6SMatthias Ringwald const btstack_chipset_t * btstack_chipset_csr_instance(void){ 156faa6c1f6SMatthias Ringwald return &btstack_chipset_bcm; 157faa6c1f6SMatthias Ringwald } 158