Skip to content

Commit

Permalink
src: Add changes for SPI Bluetooth support.
Browse files Browse the repository at this point in the history
See CYW43_ENABLE_BLUETOOTH.
New firmware added that supports Wifi and BT.
Firmware now stored as binary data in header files.
  • Loading branch information
peterharperuk committed Feb 6, 2023
1 parent 683f77e commit 931b0ce
Show file tree
Hide file tree
Showing 11 changed files with 38,952 additions and 28 deletions.
Binary file removed firmware/43439A0-7.95.49.00.combined
Binary file not shown.
22 changes: 15 additions & 7 deletions firmware/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,26 @@ CYW43xx WiFi SoC firmware
This directory contains firmware patch blobs that need to be downloaded on to the
CYW43xx SoC in order for it to function correctly.

The firmware is padded to 512 bytes and then the CLM appended to that, to create the
combined binary file.
The Wifi firmware and CLM data is padded to 512 bytes. Then the Wifi firmware, CLM data and BT firmware are all appended together,
to create the combined binary file.

For example:

$ cp 43439A0.bin 43439A0_padded.bin
$ dd if=/dev/zero of=43439A0_padded.bin bs=1 count=1 seek=$(( ($(stat -c %s 43439A0.bin) / 512) * 512 + 512 - 1))
$ cat 43439A0_padded.bin 43439A0.clm_blob > 43439A0-7.95.49.00.combined

Note that the number of dots in the filename is significant, due to the way symbols
are renamed by the linker when it is included in a compiled application.
This binary is then converted to a header file, e.g. xxd -i 43439A0-7.95.49.00.combined
The macros `CYW43_WIFI_FW_LEN`, `CYW43_CLM_LEN` specify the unpadded size of the original firmware binaries in bytes.

When updating this firmware, check and update the values of `CYW43_FW_LEN` and
`CYW43_CLM_LEN`. These should be the original, unpadded size of the two binaries
in bytes. The array size should be the size of the combined file.
The BT firmware binary is stored as a static array in clw43_btfw_43439.h and has the following format.

1 byte: number of characters in version string including null terminator
n bytes: zero terminated version string
1 byte: number of records following

Each record has the following format...
1 byte: data count
2 bytes: address
1 byte: address type
n bytes: data
517 changes: 517 additions & 0 deletions firmware/cyw43_btfw_43439.h

Large diffs are not rendered by default.

18,775 changes: 18,775 additions & 0 deletions firmware/w43439A0_7_95_49_00_combined.h

Large diffs are not rendered by default.

19,373 changes: 19,373 additions & 0 deletions firmware/wb43439A0_7_95_49_00_combined.h

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions src/cyw43.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ typedef struct _cyw43_t {

// mac from otp (or from cyw43_hal_generate_laa_mac if not set)
uint8_t mac[6];

#if CYW43_ENABLE_BLUETOOTH
bool bt_loaded;
#endif
} cyw43_t;

extern cyw43_t cyw43_state;
Expand Down Expand Up @@ -619,6 +623,34 @@ static inline uint32_t cyw43_pm_value(uint8_t pm_mode, uint16_t pm2_sleep_ret_ms
*/
#define CYW43_PERFORMANCE_PM cyw43_pm_value(CYW43_PM2_POWERSAVE_MODE, 20, 1, 1, 1)

#if CYW43_ENABLE_BLUETOOTH
/*!
* \brief Initialise bluetooth
*
* \return true on success
*/
int cyw43_bluetooth_hci_init(void);

/*!
* \brief Read bt hci data
*
* \param buf Buffer to be filled with hci data
* \param max_size The maximum size of the buffer
* \param len Returns the length of the data in the buffer including an initial 4 byte header. The last byte of the header is the packet type
* \return zero on success
*/
int cyw43_bluetooth_hci_read(uint8_t *buf, uint32_t max_size, uint32_t *len);

/*!
* \brief Write data for bt hci
*
* \param buf Data to write
* \param len Size of data to send. Must include a 4 byte header. The last byte of the header should be the packet type
* \return zero on success
*/
int cyw43_bluetooth_hci_write(uint8_t *buf, size_t len);
#endif

//!\} // cyw43_driver doxygen group

#endif // CYW43_INCLUDED_CYW43_H
43 changes: 43 additions & 0 deletions src/cyw43_btbus.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* This file is part of the cyw43-driver
*
* Copyright (C) 2019-2023 George Robotics Pty Ltd
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Any redistribution, use, or modification in source or binary form is done
* solely for personal benefit and not for any commercial purpose or for
* monetary gain.
*
* THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE LICENSOR OR COPYRIGHT OWNER BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software is also available for use with certain devices under different
* terms, as set out in the top level LICENSE file. For commercial licensing
* options please email contact@georgerobotics.com.au.
*/

#ifndef CYW43_INCLUDED_CYW43_BTBUS_H
#define CYW43_INCLUDED_CYW43_BTBUS_H

#include "cyw43_ll.h"

int cyw43_btbus_init(cyw43_ll_t *self);
int cyw43_btbus_read(uint8_t *buf, uint32_t max_buf_size, uint32_t *size);
int cyw43_btbus_write(uint8_t *buf, uint32_t size);

#endif
17 changes: 17 additions & 0 deletions src/cyw43_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,23 @@

// Firmware configuration.

// Whether Bluetooth support is enabled.
#ifndef CYW43_ENABLE_BLUETOOTH
#define CYW43_ENABLE_BLUETOOTH (0)
#endif

// This include should define:
// - CYW43_WIFI_FW_LEN
// - CYW43_CLM_LEN
// - const uintptr_t fw_data
#ifndef CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE
#if CYW43_ENABLE_BLUETOOTH
#define CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE "firmware/wb43439A0_7_95_49_00_combined.h"
#else
#define CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE "firmware/w43439A0_7_95_49_00_combined.h"
#endif
#endif

// This include should define a wifi_nvram_4343[] variable.
#ifndef CYW43_WIFI_NVRAM_INCLUDE_FILE
#define CYW43_WIFI_NVRAM_INCLUDE_FILE "firmware/wifi_nvram_43439.h"
Expand Down
73 changes: 73 additions & 0 deletions src/cyw43_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
#include "cyw43_sdio.h"
#endif

#if CYW43_ENABLE_BLUETOOTH
#include "cyw43_btbus.h"
#endif

#ifdef CYW43_PIN_WL_HOST_WAKE
#define USE_SDIOIT (0)
#else
Expand All @@ -65,6 +69,10 @@ cyw43_t cyw43_state;
void (*cyw43_poll)(void);
uint32_t cyw43_sleep;

#if CYW43_ENABLE_BLUETOOTH
void cyw43_hci_process_func(void);
#endif

#ifndef CYW43_POST_POLL_HOOK
#define CYW43_POST_POLL_HOOK
#endif
Expand Down Expand Up @@ -109,6 +117,10 @@ void cyw43_init(cyw43_t *self) {

cyw43_poll = NULL;
self->initted = true;

#if CYW43_ENABLE_BLUETOOTH
self->bt_loaded = false;
#endif
}

void cyw43_deinit(cyw43_t *self) {
Expand All @@ -134,6 +146,10 @@ void cyw43_deinit(cyw43_t *self) {
cyw43_ll_deinit(&self->cyw43_ll);
cyw43_init(self);

#if CYW43_ENABLE_BLUETOOTH
self->bt_loaded = false;
#endif

CYW43_THREAD_EXIT;
}

Expand Down Expand Up @@ -215,6 +231,13 @@ STATIC void cyw43_poll_func(void) {
CYW43_STAT_INC(CYW43_RUN_COUNT);

cyw43_t *self = &cyw43_state;

#if CYW43_ENABLE_BLUETOOTH
if (self->bt_loaded && cyw43_ll_bt_has_work(&self->cyw43_ll)) {
cyw43_hci_process_func();
}
#endif

if (cyw43_ll_has_work(&self->cyw43_ll)) {
cyw43_ll_process_packets(&self->cyw43_ll);
}
Expand Down Expand Up @@ -722,3 +745,53 @@ int cyw43_gpio_get(cyw43_t *self, int gpio, bool *val) {
}

#endif

#if CYW43_ENABLE_BLUETOOTH
STATIC int cyw43_ensure_bt_up(cyw43_t *self) {
CYW43_THREAD_ENTER;
int ret = cyw43_ensure_up(self);
if (ret == 0 && !self->bt_loaded) {
ret = cyw43_btbus_init(&self->cyw43_ll); // todo: Passing cyw43_ll is a bit naff
if (ret == 0) {
self->bt_loaded = true;
}
}
CYW43_THREAD_EXIT;
return ret;
}

// Just load firmware
int cyw43_bluetooth_hci_init(void) {
return cyw43_ensure_bt_up(&cyw43_state);
}

// Read data
int cyw43_bluetooth_hci_read(uint8_t *buf, uint32_t max_size, uint32_t *len) {
cyw43_t *self = &cyw43_state;
int ret = cyw43_ensure_bt_up(self);
if (ret) {
return ret;
}
ret = cyw43_btbus_read(buf, max_size, len);
if (ret) {
CYW43_PRINTF("cyw43_bluetooth_hci_read: failed to read from shared bus\n");
return ret;
}
return 0;
}

// Write data, buffer needs to include space for a 4 byte header and include this in len
int cyw43_bluetooth_hci_write(uint8_t *buf, size_t len) {
cyw43_t *self = &cyw43_state;
int ret = cyw43_ensure_bt_up(self);
if (ret) {
return ret;
}
ret = cyw43_btbus_write(buf, len);
if (ret) {
CYW43_PRINTF("cyw43_bluetooth_hci_write: failed to write to shared bus\n");
return ret;
}
return 0;
}
#endif
Loading

0 comments on commit 931b0ce

Please sign in to comment.