2020#if defined(__ZEPHYR__)
2121
2222#include " HCIVirtualTransportZephyr.h"
23+ #include " HCI.h"
2324
2425#include < zephyr/bluetooth/buf.h>
2526#include < zephyr/bluetooth/hci.h>
2627#include < zephyr/bluetooth/hci_raw.h>
28+ #include < zephyr/drivers/uart.h>
2729
2830static K_FIFO_DEFINE (rx_queue);
2931struct k_fifo * __rx_queue = &rx_queue;
3032extern " C" int bt_h4_vnd_setup (const struct device *dev);
3133
34+ #if CONFIG_CYW4343W_MURATA_1DX
35+ // External firmware defines.
36+ extern const uint8_t brcm_patchram_buf[];
37+ extern const int brcm_patch_ram_length;
38+
39+ enum {
40+ HCI_VND_OP_FW_DOWNLOAD = 0xFC2E ,
41+ HCI_VND_OP_WRITE_RAM = 0xFC4C ,
42+ HCI_VND_OP_LAUNCH_RAM = 0xFC4E ,
43+ HCI_VND_OP_SET_BAUDRATE = 0xFC18 ,
44+ };
45+
46+ static int cyw4343_set_baudrate (const struct device *uart, uint32_t baudrate) {
47+ struct __attribute__ ((packed)) {
48+ uint16_t zero;
49+ uint32_t baud;
50+ } param = { 0 , baudrate };
51+
52+ struct uart_config uart_cfg;
53+ if (uart_config_get (uart, &uart_cfg)) {
54+ return -1 ;
55+ }
56+
57+ if (HCI.sendCommand (HCI_VND_OP_SET_BAUDRATE, sizeof (param), (void *) ¶m)) {
58+ return -1 ;
59+ }
60+
61+ uart_cfg.baudrate = baudrate;
62+ if (uart_configure (uart, &uart_cfg)) {
63+ return -1 ;
64+ }
65+
66+ uart_irq_rx_enable (uart);
67+ return 0 ;
68+ }
69+
70+ static int cyw4343_download_firmware (const struct device *uart) {
71+ #define MURATA_NODE DT_CHILD (DT_CHOSEN(zephyr_bt_hci), murata_1dx)
72+ uint32_t operational_speed = DT_PROP_OR(MURATA_NODE, hci_operation_speed, 115200 );
73+ uint32_t fw_download_speed = DT_PROP_OR (MURATA_NODE, fw_download_speed, 115200 );
74+
75+ // Reset controller
76+ if (HCI.sendCommand (0x0C03 , 0 , NULL )) {
77+ return -1 ;
78+ }
79+
80+ // Switch to fast baudrate
81+ if ((operational_speed != fw_download_speed) &&
82+ cyw4343_set_baudrate (uart, fw_download_speed)) {
83+ return -1 ;
84+ }
85+
86+ // Start firmware downloader.
87+ if (HCI.sendCommand (HCI_VND_OP_FW_DOWNLOAD, 0 , NULL )) {
88+ return -1 ;
89+ }
90+
91+ // Load the firmware image.
92+ for (size_t offset=0 ; offset < brcm_patch_ram_length;) {
93+ uint8_t length = brcm_patchram_buf[offset + 2 ];
94+ uint16_t opcode = (brcm_patchram_buf[offset + 0 ]) |
95+ (brcm_patchram_buf[offset + 1 ] << 8 );
96+
97+ // Opcode should be write RAM or launch RAM.
98+ if (opcode != HCI_VND_OP_WRITE_RAM && opcode != HCI_VND_OP_LAUNCH_RAM) {
99+ return -1 ;
100+ }
101+
102+ if (HCI.sendCommand (opcode, length, (void *) &brcm_patchram_buf[offset + 3 ])) {
103+ return -1 ;
104+ }
105+
106+ offset += length + 3 ;
107+ }
108+
109+ // Delay after firmware loading.
110+ delay (250 );
111+
112+ // Switch back to the default baudrate.
113+ if ((operational_speed != fw_download_speed) &&
114+ cyw4343_set_baudrate (uart, fw_download_speed)) {
115+ return -1 ;
116+ }
117+
118+ return 0 ;
119+ }
120+ #endif
121+
32122HCIVirtualTransportZephyrClass::HCIVirtualTransportZephyrClass () {
33123
34124}
@@ -49,6 +139,12 @@ int HCIVirtualTransportZephyrClass::begin() {
49139 if (bt_h4_vnd_setup (uart)) {
50140 return 0 ;
51141 }
142+
143+ #if CONFIG_CYW4343W_MURATA_1DX
144+ if (cyw4343_download_firmware (uart)) {
145+ return 0 ;
146+ }
147+ #endif /* CONFIG_CYW4343W_MURATA_1DX */
52148#endif /* CONFIG_BT_HCI_SETUP */
53149
54150 rxbuf.clear ();
0 commit comments