Skip to content

Commit 36c68b5

Browse files
committed
Add firmware loading support for CYW43.
Signed-off-by: iabdalkader <[email protected]>
1 parent 2b5cf3a commit 36c68b5

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

src/utility/HCIVirtualTransportZephyr.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,105 @@
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

2830
static K_FIFO_DEFINE(rx_queue);
2931
struct k_fifo* __rx_queue = &rx_queue;
3032
extern "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 *) &param)) {
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+
32122
HCIVirtualTransportZephyrClass::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

Comments
 (0)