xref: /btstack/chipset/atwilc3000/btstack_chipset_atwilc3000.c (revision 2fca4dad957cd7b88f4657ed51e89c12615dda72)
1ccebdf93SMatthias Ringwald /*
2ccebdf93SMatthias Ringwald  * Copyright (C) 2017 BlueKitchen GmbH
3ccebdf93SMatthias Ringwald  *
4ccebdf93SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5ccebdf93SMatthias Ringwald  * modification, are permitted provided that the following conditions
6ccebdf93SMatthias Ringwald  * are met:
7ccebdf93SMatthias Ringwald  *
8ccebdf93SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9ccebdf93SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10ccebdf93SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11ccebdf93SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12ccebdf93SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13ccebdf93SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14ccebdf93SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15ccebdf93SMatthias Ringwald  *    from this software without specific prior written permission.
16ccebdf93SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17ccebdf93SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18ccebdf93SMatthias Ringwald  *    monetary gain.
19ccebdf93SMatthias Ringwald  *
20ccebdf93SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21ccebdf93SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22ccebdf93SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*2fca4dadSMilanka Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24*2fca4dadSMilanka Ringwald  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25ccebdf93SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26ccebdf93SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27ccebdf93SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28ccebdf93SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29ccebdf93SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30ccebdf93SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31ccebdf93SMatthias Ringwald  * SUCH DAMAGE.
32ccebdf93SMatthias Ringwald  *
33ccebdf93SMatthias Ringwald  * Please inquire about commercial licensing options at
34ccebdf93SMatthias Ringwald  * [email protected]
35ccebdf93SMatthias Ringwald  *
36ccebdf93SMatthias Ringwald  */
37ccebdf93SMatthias Ringwald 
387a4d61a3SMatthias Ringwald #define BTSTACK_FILE__ "btstack_chipset_atwilc3000.c"
397a4d61a3SMatthias Ringwald 
40ccebdf93SMatthias Ringwald /*
41ccebdf93SMatthias Ringwald  *  btstack_chipset_atwilc3000.c
42ccebdf93SMatthias Ringwald  *
43ccebdf93SMatthias Ringwald  *  Adapter to use atwilc3000-based chipsets with BTstack
44ccebdf93SMatthias Ringwald  *
45ccebdf93SMatthias Ringwald  */
46ccebdf93SMatthias Ringwald 
47ccebdf93SMatthias Ringwald #include "btstack_config.h"
48ccebdf93SMatthias Ringwald 
49ccebdf93SMatthias Ringwald #include <stddef.h>   /* NULL */
50ccebdf93SMatthias Ringwald #include <stdio.h>
51ccebdf93SMatthias Ringwald #include <string.h>   /* memcpy */
527a4d61a3SMatthias Ringwald 
537a4d61a3SMatthias Ringwald #include "btstack_chipset_atwilc3000.h"
547a4d61a3SMatthias Ringwald #include "btstack_debug.h"
55ccebdf93SMatthias Ringwald #include "hci.h"
56ccebdf93SMatthias Ringwald 
577a4d61a3SMatthias Ringwald // assert outgoing and incoming hci packet buffers can hold max hci command resp. event packet
587a4d61a3SMatthias Ringwald #if HCI_OUTGOING_PACKET_BUFFER_SIZE < (HCI_CMD_HEADER_SIZE + 255)
597a4d61a3SMatthias Ringwald #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."
607a4d61a3SMatthias Ringwald #endif
616ffe3f3eSMatthias Ringwald #if HCI_INCOMING_PACKET_BUFFER_SIZE < (HCI_EVENT_HEADER_SIZE + 255)
627a4d61a3SMatthias Ringwald #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."
637a4d61a3SMatthias Ringwald #endif
647a4d61a3SMatthias Ringwald 
65f14824f7SMatthias Ringwald // Address to load firmware
66ccebdf93SMatthias Ringwald #define IRAM_START 0x80000000
67f14824f7SMatthias Ringwald 
68f14824f7SMatthias Ringwald // Larger blocks (e.g. 8192) cause hang
69a1b34469SMatthias Ringwald #define FIRMWARE_CHUNK_SIZE 4096
70ccebdf93SMatthias Ringwald 
71f14824f7SMatthias Ringwald // works with 200 ms, so use 250 ms to stay on the safe side
72f14824f7SMatthias Ringwald #define ATWILC3000_RESET_TIME_MS 250
73f14824f7SMatthias Ringwald 
74f14824f7SMatthias Ringwald // HCI commands used for firmware upload
75ccebdf93SMatthias Ringwald static const uint8_t hci_reset_command[] = { 0x01, 0x03, 0x0c, 0x00 };
76ccebdf93SMatthias Ringwald static const uint8_t hci_read_local_version_information_command[] = { 0x01, 0x01, 0x10, 0x00 };
77ccebdf93SMatthias Ringwald static const uint8_t hci_vendor_specific_reset_command[] = { 0x01, 0x55, 0xfc, 0x00 };
78ccebdf93SMatthias Ringwald 
79ccebdf93SMatthias Ringwald // prototypes
80f14824f7SMatthias Ringwald static void atwilc3000_configure_uart(btstack_timer_source_t * ts);
81ccebdf93SMatthias Ringwald static void atwilc3000_done(void);
82c7d3427cSMatthias Ringwald static void atwilc3000_update_uart_params(void);
83f14824f7SMatthias Ringwald static void atwilc3000_vendor_specific_reset(void);
84c7d3427cSMatthias Ringwald static void atwilc3000_w4_baudrate_update(void);
85f14824f7SMatthias Ringwald static void atwilc3000_w4_command_complete_read_local_version_information(void);
86f14824f7SMatthias Ringwald static void atwilc3000_w4_command_complete_reset(void);
87f14824f7SMatthias Ringwald static void atwilc3000_wait_for_reset_completed(void);
88f14824f7SMatthias Ringwald static void atwilc3000_write_firmware(void);
89f14824f7SMatthias Ringwald static void atwilc3000_write_memory(void);
90ccebdf93SMatthias Ringwald 
91ccebdf93SMatthias Ringwald // globals
92ccebdf93SMatthias Ringwald static void (*download_complete)(int result);
9378a48aa8SMatthias Ringwald static const btstack_uart_t * the_uart_driver;
94f14824f7SMatthias Ringwald static btstack_timer_source_t reset_timer;
95ccebdf93SMatthias Ringwald 
96ccebdf93SMatthias Ringwald static int     download_count;
97ccebdf93SMatthias Ringwald static uint8_t event_buffer[15];
98a1b34469SMatthias Ringwald static uint8_t command_buffer[12];
99ccebdf93SMatthias Ringwald static const uint8_t * fw_data;
100ccebdf93SMatthias Ringwald static uint32_t        fw_size;
101ccebdf93SMatthias Ringwald static uint32_t        fw_offset;
102f14824f7SMatthias Ringwald 
103f14824f7SMatthias Ringwald // baudrate for firmware upload
104c7d3427cSMatthias Ringwald static uint32_t        fw_baudrate;
105ccebdf93SMatthias Ringwald 
106f14824f7SMatthias Ringwald // flow control requested
1076e0d5aedSMatthias Ringwald static int             fw_flowcontrol;
108f14824f7SMatthias Ringwald 
109f14824f7SMatthias Ringwald // flow control active
1106e0d5aedSMatthias Ringwald static int             atwilc3000_flowcontrol;
111a1b34469SMatthias Ringwald 
atwilc3000_set_baudrate_command(uint32_t baudrate,uint8_t * hci_cmd_buffer)1129df38542SMatthias Ringwald static void atwilc3000_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buffer){
1139df38542SMatthias Ringwald     hci_cmd_buffer[0] = 0x53;
1149df38542SMatthias Ringwald     hci_cmd_buffer[1] = 0xfc;
1159df38542SMatthias Ringwald     hci_cmd_buffer[2] = 5;
116f14824f7SMatthias Ringwald     little_endian_store_32(hci_cmd_buffer, 3, baudrate);
1176e0d5aedSMatthias Ringwald     hci_cmd_buffer[7] = atwilc3000_flowcontrol;    // use global state
1189df38542SMatthias Ringwald }
1199df38542SMatthias Ringwald 
atwilc3000_set_bd_addr_command(bd_addr_t addr,uint8_t * hci_cmd_buffer)1209df38542SMatthias Ringwald static void atwilc3000_set_bd_addr_command(bd_addr_t addr, uint8_t *hci_cmd_buffer){
1216ca9a99aSMatthias Ringwald     hci_cmd_buffer[0] = 0x54;
1229df38542SMatthias Ringwald     hci_cmd_buffer[1] = 0xFC;
1239df38542SMatthias Ringwald     hci_cmd_buffer[2] = 0x06;
1249df38542SMatthias Ringwald     reverse_bd_addr(addr, &hci_cmd_buffer[3]);
1259df38542SMatthias Ringwald }
1269df38542SMatthias Ringwald 
atwilc3000_send_command(const uint8_t * data,uint16_t len)127ccebdf93SMatthias Ringwald static void atwilc3000_send_command(const uint8_t * data, uint16_t len){
128ccebdf93SMatthias Ringwald     hci_dump_packet(HCI_COMMAND_DATA_PACKET, 0, (uint8_t *) &data[1], len - 1);
129ccebdf93SMatthias Ringwald     the_uart_driver->send_block(data, len);
130ccebdf93SMatthias Ringwald }
131ccebdf93SMatthias Ringwald 
atwilc3000_log_event(void)132ccebdf93SMatthias Ringwald static void atwilc3000_log_event(void){
133ccebdf93SMatthias Ringwald     int len = event_buffer[2] + 2;
134ccebdf93SMatthias Ringwald     hci_dump_packet(HCI_EVENT_PACKET, 1, &event_buffer[1], len);
135ccebdf93SMatthias Ringwald }
136ccebdf93SMatthias Ringwald 
atwilc3000_start(void)137ccebdf93SMatthias Ringwald static void atwilc3000_start(void){
138f14824f7SMatthias Ringwald     // default after power up
1396e0d5aedSMatthias Ringwald     atwilc3000_flowcontrol = 0;
140f14824f7SMatthias Ringwald 
141ccebdf93SMatthias Ringwald     // send HCI Reset
142ccebdf93SMatthias Ringwald     the_uart_driver->set_block_received(&atwilc3000_w4_command_complete_reset);
143ccebdf93SMatthias Ringwald     the_uart_driver->receive_block(&event_buffer[0], 7);
144ccebdf93SMatthias Ringwald     atwilc3000_send_command(&hci_reset_command[0], sizeof(hci_reset_command));
145ccebdf93SMatthias Ringwald }
146ccebdf93SMatthias Ringwald 
atwilc3000_w4_command_complete_reset(void)147ccebdf93SMatthias Ringwald static void atwilc3000_w4_command_complete_reset(void){
148ccebdf93SMatthias Ringwald     atwilc3000_log_event();
149ccebdf93SMatthias Ringwald     // send HCI Read Local Version Information
150ccebdf93SMatthias Ringwald     the_uart_driver->receive_block(&event_buffer[0], 15);
151ccebdf93SMatthias Ringwald     the_uart_driver->set_block_received(&atwilc3000_w4_command_complete_read_local_version_information);
152ccebdf93SMatthias Ringwald     atwilc3000_send_command(&hci_read_local_version_information_command[0], sizeof(hci_read_local_version_information_command));
153ccebdf93SMatthias Ringwald }
154ccebdf93SMatthias Ringwald 
atwilc3000_w4_command_complete_read_local_version_information(void)155ccebdf93SMatthias Ringwald static void atwilc3000_w4_command_complete_read_local_version_information(void){
156ccebdf93SMatthias Ringwald     atwilc3000_log_event();
157ccebdf93SMatthias Ringwald     uint8_t firmware_version = event_buffer[7];
158ccebdf93SMatthias Ringwald     if (firmware_version != 0xff){
159f14824f7SMatthias Ringwald         log_info("Firmware version 0x%02x already loaded, download complete", firmware_version);
160ccebdf93SMatthias Ringwald         download_complete(0);
161ccebdf93SMatthias Ringwald         return;
162ccebdf93SMatthias Ringwald     }
163ccebdf93SMatthias Ringwald     log_info("Running from ROM, start firmware download");
164c7d3427cSMatthias Ringwald     if (fw_baudrate){
165c7d3427cSMatthias Ringwald         atwilc3000_update_uart_params();
166c7d3427cSMatthias Ringwald     } else {
167ccebdf93SMatthias Ringwald         atwilc3000_write_memory();
168ccebdf93SMatthias Ringwald     }
169c7d3427cSMatthias Ringwald }
170c7d3427cSMatthias Ringwald 
atwilc3000_update_uart_params(void)171c7d3427cSMatthias Ringwald static void atwilc3000_update_uart_params(void){
172c7d3427cSMatthias Ringwald     command_buffer[0] = 1;
1739df38542SMatthias Ringwald     atwilc3000_set_baudrate_command(fw_baudrate, &command_buffer[1]);
174c7d3427cSMatthias Ringwald     the_uart_driver->receive_block(&event_buffer[0], 7);
175c7d3427cSMatthias Ringwald     the_uart_driver->set_block_received(&atwilc3000_w4_baudrate_update);
176c7d3427cSMatthias Ringwald     atwilc3000_send_command(&command_buffer[0], 9);
177c7d3427cSMatthias Ringwald }
178c7d3427cSMatthias Ringwald 
atwilc3000_w4_baudrate_update(void)179c7d3427cSMatthias Ringwald static void atwilc3000_w4_baudrate_update(void){
180c7d3427cSMatthias Ringwald     atwilc3000_log_event();
181c7d3427cSMatthias Ringwald     the_uart_driver->set_baudrate(fw_baudrate);
182c7d3427cSMatthias Ringwald     atwilc3000_write_memory();
183c7d3427cSMatthias Ringwald }
184c7d3427cSMatthias Ringwald 
atwilc3000_write_memory(void)185ccebdf93SMatthias Ringwald static void atwilc3000_write_memory(void){
186ccebdf93SMatthias Ringwald     atwilc3000_log_event();
187ccebdf93SMatthias Ringwald 
188ccebdf93SMatthias Ringwald     // done?
189ccebdf93SMatthias Ringwald     if (fw_offset >= fw_size){
190f14824f7SMatthias Ringwald         log_info("Firmware upload complete!!!");
191ccebdf93SMatthias Ringwald         atwilc3000_vendor_specific_reset();
192ccebdf93SMatthias Ringwald         return;
193ccebdf93SMatthias Ringwald     }
194a1b34469SMatthias Ringwald 
195ccebdf93SMatthias Ringwald     // bytes to write
1966e0d5aedSMatthias Ringwald     log_info("Write pos %u", (int) fw_offset);
197a1b34469SMatthias Ringwald     uint16_t bytes_to_write = btstack_min((fw_size - fw_offset), FIRMWARE_CHUNK_SIZE);
198ccebdf93SMatthias Ringwald     // setup write command
199ccebdf93SMatthias Ringwald     command_buffer[0] = 1;
200ccebdf93SMatthias Ringwald     command_buffer[1] = 0x52;
201ccebdf93SMatthias Ringwald     command_buffer[2] = 0xfc;
202ccebdf93SMatthias Ringwald     command_buffer[3] = 8; // NOTE: this is in violation of the Bluetooth Specification, but documented in the Atmel-NNNNN-ATWIL_Linux_Porting_Guide
203ccebdf93SMatthias Ringwald     little_endian_store_32(command_buffer, 4, IRAM_START + fw_offset);
204ccebdf93SMatthias Ringwald     little_endian_store_32(command_buffer, 8, bytes_to_write);
205ccebdf93SMatthias Ringwald 
206d119968eSMatthias Ringwald     // send write command - only log write command without the firmware blob
207d119968eSMatthias Ringwald     hci_dump_packet(HCI_COMMAND_DATA_PACKET, 0, (uint8_t *) &command_buffer[1], 12 - 1);
208a1b34469SMatthias Ringwald     the_uart_driver->set_block_sent(&atwilc3000_write_firmware);
209a1b34469SMatthias Ringwald     the_uart_driver->send_block(&command_buffer[0], 12);
210a1b34469SMatthias Ringwald }
211a1b34469SMatthias Ringwald 
atwilc3000_write_firmware(void)212a1b34469SMatthias Ringwald static void atwilc3000_write_firmware(void){
213a1b34469SMatthias Ringwald     the_uart_driver->set_block_received(&atwilc3000_write_memory);
214a1b34469SMatthias Ringwald     the_uart_driver->receive_block(&event_buffer[0], 7);
215a1b34469SMatthias Ringwald 
216a1b34469SMatthias Ringwald     uint16_t bytes_to_write = btstack_min((fw_size - fw_offset), FIRMWARE_CHUNK_SIZE);
217a1b34469SMatthias Ringwald 
218a1b34469SMatthias Ringwald     uint32_t offset = fw_offset;
219a1b34469SMatthias Ringwald     fw_offset += bytes_to_write;
220a1b34469SMatthias Ringwald 
221f14824f7SMatthias Ringwald     the_uart_driver->set_block_sent(NULL);
222a1b34469SMatthias Ringwald     the_uart_driver->send_block(&fw_data[offset], bytes_to_write);
223ccebdf93SMatthias Ringwald }
224ccebdf93SMatthias Ringwald 
atwilc3000_vendor_specific_reset(void)225ccebdf93SMatthias Ringwald static void atwilc3000_vendor_specific_reset(void){
226f14824f7SMatthias Ringwald     log_info("Trigger MCU reboot and wait ");
227ccebdf93SMatthias Ringwald     // send HCI Vendor Specific Reset
228f14824f7SMatthias Ringwald     the_uart_driver->set_block_sent(&atwilc3000_wait_for_reset_completed);
229ccebdf93SMatthias Ringwald     atwilc3000_send_command(&hci_vendor_specific_reset_command[0], sizeof(hci_vendor_specific_reset_command));
230ccebdf93SMatthias Ringwald }
231ccebdf93SMatthias Ringwald 
atwilc3000_wait_for_reset_completed(void)232f14824f7SMatthias Ringwald static void atwilc3000_wait_for_reset_completed(void){
233f14824f7SMatthias Ringwald     the_uart_driver->set_block_sent(NULL);
234f14824f7SMatthias Ringwald     btstack_run_loop_set_timer_handler(&reset_timer, &atwilc3000_configure_uart);
235f14824f7SMatthias Ringwald     btstack_run_loop_set_timer(&reset_timer, ATWILC3000_RESET_TIME_MS);
236f14824f7SMatthias Ringwald     btstack_run_loop_add_timer(&reset_timer);
237c7d3427cSMatthias Ringwald }
238f14824f7SMatthias Ringwald 
atwilc3000_configure_uart(btstack_timer_source_t * ts)239f14824f7SMatthias Ringwald static void atwilc3000_configure_uart(btstack_timer_source_t * ts){
240f14824f7SMatthias Ringwald     // reset baud rate if higher baud rate was requested before
241f14824f7SMatthias Ringwald     if (fw_baudrate){
242f14824f7SMatthias Ringwald         the_uart_driver->set_baudrate(HCI_DEFAULT_BAUDRATE);
243f14824f7SMatthias Ringwald     }
2446e0d5aedSMatthias Ringwald     // send baudrate command to enable flow control (if supported) and/or higher baud rate
2456e0d5aedSMatthias Ringwald     if ((fw_flowcontrol && the_uart_driver->set_flowcontrol) || (fw_baudrate != HCI_DEFAULT_BAUDRATE)){
2466e0d5aedSMatthias Ringwald         log_info("Send baudrate command (%u) to enable flow control", (int) fw_baudrate);
2476e0d5aedSMatthias Ringwald         atwilc3000_flowcontrol = fw_flowcontrol;
248f14824f7SMatthias Ringwald         command_buffer[0] = 1;
2496e0d5aedSMatthias Ringwald         atwilc3000_set_baudrate_command(fw_baudrate, &command_buffer[1]);
250f14824f7SMatthias Ringwald         the_uart_driver->set_block_received(&atwilc3000_done);
251f14824f7SMatthias Ringwald         the_uart_driver->receive_block(&event_buffer[0], 7);
252f14824f7SMatthias Ringwald         atwilc3000_send_command(&command_buffer[0], 9);
253f14824f7SMatthias Ringwald     } else {
254f14824f7SMatthias Ringwald         atwilc3000_done();
255f14824f7SMatthias Ringwald     }
256f14824f7SMatthias Ringwald }
257f14824f7SMatthias Ringwald 
atwilc3000_done(void)258f14824f7SMatthias Ringwald static void atwilc3000_done(void){
259f14824f7SMatthias Ringwald     atwilc3000_log_event();
260f14824f7SMatthias Ringwald     // enable our flow control
2616e0d5aedSMatthias Ringwald     if (atwilc3000_flowcontrol){
2626e0d5aedSMatthias Ringwald         the_uart_driver->set_flowcontrol(atwilc3000_flowcontrol);
263f14824f7SMatthias Ringwald     }
2646e0d5aedSMatthias Ringwald     if (fw_baudrate){
2656e0d5aedSMatthias Ringwald         the_uart_driver->set_baudrate(fw_baudrate);
2666e0d5aedSMatthias Ringwald     }
2676e0d5aedSMatthias Ringwald 
268f14824f7SMatthias Ringwald     // done
269ccebdf93SMatthias Ringwald     download_complete(0);
270ccebdf93SMatthias Ringwald }
271ccebdf93SMatthias Ringwald 
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))27278a48aa8SMatthias Ringwald 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)){
273ccebdf93SMatthias Ringwald 	the_uart_driver   = uart_driver;
274ccebdf93SMatthias Ringwald     download_complete = done;
275ccebdf93SMatthias Ringwald     fw_data = da_fw_data;
276ccebdf93SMatthias Ringwald     fw_size = da_fw_size;
277ccebdf93SMatthias Ringwald     fw_offset = 0;
278c7d3427cSMatthias Ringwald     fw_baudrate = baudrate;
2796e0d5aedSMatthias Ringwald     fw_flowcontrol = flowcontrol;
280ccebdf93SMatthias Ringwald 
281ccebdf93SMatthias Ringwald     int res = the_uart_driver->open();
282ccebdf93SMatthias Ringwald     if (res) {
283ccebdf93SMatthias Ringwald     	log_error("uart_block init failed %u", res);
284ccebdf93SMatthias Ringwald     	download_complete(res);
285f14824f7SMatthias Ringwald         return;
286ccebdf93SMatthias Ringwald     }
287ccebdf93SMatthias Ringwald 
288ccebdf93SMatthias Ringwald     download_count = 0;
289ccebdf93SMatthias Ringwald     atwilc3000_start();
290ccebdf93SMatthias Ringwald }
291ccebdf93SMatthias Ringwald 
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))29278a48aa8SMatthias Ringwald 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)){
29378a48aa8SMatthias Ringwald     btstack_chipset_atwilc3000_download_firmware_with_uart((const btstack_uart_t *) uart_driver, baudrate, flowcontrol, da_fw_data, da_fw_size, done);
29478a48aa8SMatthias Ringwald }
29578a48aa8SMatthias Ringwald 
296ccebdf93SMatthias Ringwald static const btstack_chipset_t btstack_chipset_atwilc3000 = {
297ccebdf93SMatthias Ringwald     "atwilc3000",
298ccebdf93SMatthias Ringwald     NULL, // chipset_init not used
299ccebdf93SMatthias Ringwald     NULL, // chipset_next_command not used
3009df38542SMatthias Ringwald     atwilc3000_set_baudrate_command,
3016ca9a99aSMatthias Ringwald     atwilc3000_set_bd_addr_command,
302ccebdf93SMatthias Ringwald };
303ccebdf93SMatthias Ringwald 
304ccebdf93SMatthias Ringwald // MARK: public API
btstack_chipset_atwilc3000_instance(void)305ccebdf93SMatthias Ringwald const btstack_chipset_t * btstack_chipset_atwilc3000_instance(void){
306ccebdf93SMatthias Ringwald     return &btstack_chipset_atwilc3000;
307ccebdf93SMatthias Ringwald }
308ccebdf93SMatthias Ringwald 
309