1 /* 2 * Copyright (C) 2017 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__ "btstack_chipset_atwilc3000.c" 39 40 /* 41 * btstack_chipset_atwilc3000.c 42 * 43 * Adapter to use atwilc3000-based chipsets with BTstack 44 * 45 */ 46 47 #include "btstack_config.h" 48 49 #include <stddef.h> /* NULL */ 50 #include <stdio.h> 51 #include <string.h> /* memcpy */ 52 53 #include "btstack_chipset_atwilc3000.h" 54 #include "btstack_debug.h" 55 #include "hci.h" 56 57 // assert outgoing and incoming hci packet buffers can hold max hci command resp. event packet 58 #if HCI_OUTGOING_PACKET_BUFFER_SIZE < (HCI_CMD_HEADER_SIZE + 255) 59 #error "HCI_OUTGOING_PACKET_BUFFER_SIZE to small. Outgoing HCI packet buffer to small for largest HCI Command packet. Please set HCI_ACL_PAYLOAD_SIZE to 258 or higher." 60 #endif 61 #if HCI_INCOMING_PACKET_BUFFER_SIZE < (HCI_EVENT_HEADER_SIZE + 255) 62 #error "HCI_INCOMING_PACKET_BUFFER_SIZE to small. Incoming HCI packet buffer to small for largest HCI Event packet. Please set HCI_ACL_PAYLOAD_SIZE to 257 or higher." 63 #endif 64 65 // Address to load firmware 66 #define IRAM_START 0x80000000 67 68 // Larger blocks (e.g. 8192) cause hang 69 #define FIRMWARE_CHUNK_SIZE 4096 70 71 // works with 200 ms, so use 250 ms to stay on the safe side 72 #define ATWILC3000_RESET_TIME_MS 250 73 74 // HCI commands used for firmware upload 75 static const uint8_t hci_reset_command[] = { 0x01, 0x03, 0x0c, 0x00 }; 76 static const uint8_t hci_read_local_version_information_command[] = { 0x01, 0x01, 0x10, 0x00 }; 77 static const uint8_t hci_vendor_specific_reset_command[] = { 0x01, 0x55, 0xfc, 0x00 }; 78 79 // prototypes 80 static void atwilc3000_configure_uart(btstack_timer_source_t * ts); 81 static void atwilc3000_done(void); 82 static void atwilc3000_update_uart_params(void); 83 static void atwilc3000_vendor_specific_reset(void); 84 static void atwilc3000_w4_baudrate_update(void); 85 static void atwilc3000_w4_command_complete_read_local_version_information(void); 86 static void atwilc3000_w4_command_complete_reset(void); 87 static void atwilc3000_wait_for_reset_completed(void); 88 static void atwilc3000_write_firmware(void); 89 static void atwilc3000_write_memory(void); 90 91 // globals 92 static void (*download_complete)(int result); 93 static const btstack_uart_t * the_uart_driver; 94 static btstack_timer_source_t reset_timer; 95 96 static int download_count; 97 static uint8_t event_buffer[15]; 98 static uint8_t command_buffer[12]; 99 static const uint8_t * fw_data; 100 static uint32_t fw_size; 101 static uint32_t fw_offset; 102 103 // baudrate for firmware upload 104 static uint32_t fw_baudrate; 105 106 // flow control requested 107 static int fw_flowcontrol; 108 109 // flow control active 110 static int atwilc3000_flowcontrol; 111 112 static void atwilc3000_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buffer){ 113 hci_cmd_buffer[0] = 0x53; 114 hci_cmd_buffer[1] = 0xfc; 115 hci_cmd_buffer[2] = 5; 116 little_endian_store_32(hci_cmd_buffer, 3, baudrate); 117 hci_cmd_buffer[7] = atwilc3000_flowcontrol; // use global state 118 } 119 120 static void atwilc3000_set_bd_addr_command(bd_addr_t addr, uint8_t *hci_cmd_buffer){ 121 hci_cmd_buffer[0] = 0x54; 122 hci_cmd_buffer[1] = 0xFC; 123 hci_cmd_buffer[2] = 0x06; 124 reverse_bd_addr(addr, &hci_cmd_buffer[3]); 125 } 126 127 static void atwilc3000_send_command(const uint8_t * data, uint16_t len){ 128 hci_dump_packet(HCI_COMMAND_DATA_PACKET, 0, (uint8_t *) &data[1], len - 1); 129 the_uart_driver->send_block(data, len); 130 } 131 132 static void atwilc3000_log_event(void){ 133 int len = event_buffer[2] + 2; 134 hci_dump_packet(HCI_EVENT_PACKET, 1, &event_buffer[1], len); 135 } 136 137 static void atwilc3000_start(void){ 138 // default after power up 139 atwilc3000_flowcontrol = 0; 140 141 // send HCI Reset 142 the_uart_driver->set_block_received(&atwilc3000_w4_command_complete_reset); 143 the_uart_driver->receive_block(&event_buffer[0], 7); 144 atwilc3000_send_command(&hci_reset_command[0], sizeof(hci_reset_command)); 145 } 146 147 static void atwilc3000_w4_command_complete_reset(void){ 148 atwilc3000_log_event(); 149 // send HCI Read Local Version Information 150 the_uart_driver->receive_block(&event_buffer[0], 15); 151 the_uart_driver->set_block_received(&atwilc3000_w4_command_complete_read_local_version_information); 152 atwilc3000_send_command(&hci_read_local_version_information_command[0], sizeof(hci_read_local_version_information_command)); 153 } 154 155 static void atwilc3000_w4_command_complete_read_local_version_information(void){ 156 atwilc3000_log_event(); 157 uint8_t firmware_version = event_buffer[7]; 158 if (firmware_version != 0xff){ 159 log_info("Firmware version 0x%02x already loaded, download complete", firmware_version); 160 download_complete(0); 161 return; 162 } 163 log_info("Running from ROM, start firmware download"); 164 if (fw_baudrate){ 165 atwilc3000_update_uart_params(); 166 } else { 167 atwilc3000_write_memory(); 168 } 169 } 170 171 static void atwilc3000_update_uart_params(void){ 172 command_buffer[0] = 1; 173 atwilc3000_set_baudrate_command(fw_baudrate, &command_buffer[1]); 174 the_uart_driver->receive_block(&event_buffer[0], 7); 175 the_uart_driver->set_block_received(&atwilc3000_w4_baudrate_update); 176 atwilc3000_send_command(&command_buffer[0], 9); 177 } 178 179 static void atwilc3000_w4_baudrate_update(void){ 180 atwilc3000_log_event(); 181 the_uart_driver->set_baudrate(fw_baudrate); 182 atwilc3000_write_memory(); 183 } 184 185 static void atwilc3000_write_memory(void){ 186 atwilc3000_log_event(); 187 188 // done? 189 if (fw_offset >= fw_size){ 190 log_info("Firmware upload complete!!!"); 191 atwilc3000_vendor_specific_reset(); 192 return; 193 } 194 195 // bytes to write 196 log_info("Write pos %u", (int) fw_offset); 197 uint16_t bytes_to_write = btstack_min((fw_size - fw_offset), FIRMWARE_CHUNK_SIZE); 198 // setup write command 199 command_buffer[0] = 1; 200 command_buffer[1] = 0x52; 201 command_buffer[2] = 0xfc; 202 command_buffer[3] = 8; // NOTE: this is in violation of the Bluetooth Specification, but documented in the Atmel-NNNNN-ATWIL_Linux_Porting_Guide 203 little_endian_store_32(command_buffer, 4, IRAM_START + fw_offset); 204 little_endian_store_32(command_buffer, 8, bytes_to_write); 205 206 // send write command - only log write command without the firmware blob 207 hci_dump_packet(HCI_COMMAND_DATA_PACKET, 0, (uint8_t *) &command_buffer[1], 12 - 1); 208 the_uart_driver->set_block_sent(&atwilc3000_write_firmware); 209 the_uart_driver->send_block(&command_buffer[0], 12); 210 } 211 212 static void atwilc3000_write_firmware(void){ 213 the_uart_driver->set_block_received(&atwilc3000_write_memory); 214 the_uart_driver->receive_block(&event_buffer[0], 7); 215 216 uint16_t bytes_to_write = btstack_min((fw_size - fw_offset), FIRMWARE_CHUNK_SIZE); 217 218 uint32_t offset = fw_offset; 219 fw_offset += bytes_to_write; 220 221 the_uart_driver->set_block_sent(NULL); 222 the_uart_driver->send_block(&fw_data[offset], bytes_to_write); 223 } 224 225 static void atwilc3000_vendor_specific_reset(void){ 226 log_info("Trigger MCU reboot and wait "); 227 // send HCI Vendor Specific Reset 228 the_uart_driver->set_block_sent(&atwilc3000_wait_for_reset_completed); 229 atwilc3000_send_command(&hci_vendor_specific_reset_command[0], sizeof(hci_vendor_specific_reset_command)); 230 } 231 232 static void atwilc3000_wait_for_reset_completed(void){ 233 the_uart_driver->set_block_sent(NULL); 234 btstack_run_loop_set_timer_handler(&reset_timer, &atwilc3000_configure_uart); 235 btstack_run_loop_set_timer(&reset_timer, ATWILC3000_RESET_TIME_MS); 236 btstack_run_loop_add_timer(&reset_timer); 237 } 238 239 static void atwilc3000_configure_uart(btstack_timer_source_t * ts){ 240 // reset baud rate if higher baud rate was requested before 241 if (fw_baudrate){ 242 the_uart_driver->set_baudrate(HCI_DEFAULT_BAUDRATE); 243 } 244 // send baudrate command to enable flow control (if supported) and/or higher baud rate 245 if ((fw_flowcontrol && the_uart_driver->set_flowcontrol) || (fw_baudrate != HCI_DEFAULT_BAUDRATE)){ 246 log_info("Send baudrate command (%u) to enable flow control", (int) fw_baudrate); 247 atwilc3000_flowcontrol = fw_flowcontrol; 248 command_buffer[0] = 1; 249 atwilc3000_set_baudrate_command(fw_baudrate, &command_buffer[1]); 250 the_uart_driver->set_block_received(&atwilc3000_done); 251 the_uart_driver->receive_block(&event_buffer[0], 7); 252 atwilc3000_send_command(&command_buffer[0], 9); 253 } else { 254 atwilc3000_done(); 255 } 256 } 257 258 static void atwilc3000_done(void){ 259 atwilc3000_log_event(); 260 // enable our flow control 261 if (atwilc3000_flowcontrol){ 262 the_uart_driver->set_flowcontrol(atwilc3000_flowcontrol); 263 } 264 if (fw_baudrate){ 265 the_uart_driver->set_baudrate(fw_baudrate); 266 } 267 268 // done 269 download_complete(0); 270 } 271 272 void btstack_chipset_atwilc3000_download_firmware_with_uart(const btstack_uart_t * uart_driver, uint32_t baudrate, int flowcontrol, const uint8_t * da_fw_data, uint32_t da_fw_size, void (*done)(int result)){ 273 the_uart_driver = uart_driver; 274 download_complete = done; 275 fw_data = da_fw_data; 276 fw_size = da_fw_size; 277 fw_offset = 0; 278 fw_baudrate = baudrate; 279 fw_flowcontrol = flowcontrol; 280 281 int res = the_uart_driver->open(); 282 if (res) { 283 log_error("uart_block init failed %u", res); 284 download_complete(res); 285 return; 286 } 287 288 download_count = 0; 289 atwilc3000_start(); 290 } 291 292 void btstack_chipset_atwilc3000_download_firmware(const btstack_uart_block_t * uart_driver, uint32_t baudrate, int flowcontrol, const uint8_t * da_fw_data, uint32_t da_fw_size, void (*done)(int result)){ 293 btstack_chipset_atwilc3000_download_firmware_with_uart((const btstack_uart_t *) uart_driver, baudrate, flowcontrol, da_fw_data, da_fw_size, done); 294 } 295 296 static const btstack_chipset_t btstack_chipset_atwilc3000 = { 297 "atwilc3000", 298 NULL, // chipset_init not used 299 NULL, // chipset_next_command not used 300 atwilc3000_set_baudrate_command, 301 atwilc3000_set_bd_addr_command, 302 }; 303 304 // MARK: public API 305 const btstack_chipset_t * btstack_chipset_atwilc3000_instance(void){ 306 return &btstack_chipset_atwilc3000; 307 } 308 309