forked from georgerobotics/cyw43-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor the driver to call wifi_fw_funcs to get functions to load firmware data. If CYW43_DECOMPRESS_FIRMWARE is true it will load gzip compressed firmware using uzlib. The driver calls cyw43_wifi_firmware_details to get details of the firmware. Fixes georgerobotics#4
- Loading branch information
1 parent
7d3291d
commit b38220b
Showing
6 changed files
with
621 additions
and
111 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/* | ||
* This file is part of the cyw43-driver | ||
* | ||
* Copyright (C) 2019-2022 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 WIFI_FIRMWARE_H | ||
#define WIFI_FIRMWARE_H | ||
|
||
#if CYW43_DECOMPRESS_FIRMWARE | ||
#include "cyw43_decompress_firmware.h" | ||
#endif | ||
|
||
/*! | ||
* \brief Structure to store wifi firmware details | ||
*/ | ||
//!\{ | ||
typedef struct cyw43_wifi_firmware_details { | ||
size_t raw_size; ///< size in bytes of the firmware binary | ||
const uint8_t *raw_data; ///< pointer to the firmware binary | ||
size_t fw_size; ///< Size of the firmware in bytes | ||
size_t clm_size; ///< Size of the clm in bytes | ||
const uint8_t *fw_addr; ///< Pointer to the firmware in the binary | ||
const uint8_t *clm_addr; ///< Pointer to the clm in the binary | ||
size_t wifi_nvram_len; ///< Size of nvram data | ||
const uint8_t *wifi_nvram_data; ///< Pointer to nvram data | ||
} cyw43_wifi_firmware_details_t; | ||
//!\} | ||
|
||
/*! | ||
* \brief Structure to hold function pointers for loading firmware | ||
*/ | ||
//!\{ | ||
typedef struct cyw43_wifi_firmware_funcs { | ||
int (*start)(const cyw43_wifi_firmware_details_t *fw_details); ///< start firmware loading | ||
const uint8_t* (*get_fw_source)(const uint8_t *addr, size_t sz_in, uint8_t *buffer, size_t buffer_len); ///< get fw data | ||
const uint8_t* (*get_nvram_source)(const uint8_t *addr, size_t sz_in, uint8_t *buffer, size_t buffer_len); ///< get nvram data | ||
int (*get_clm)(uint8_t *dst, const uint8_t *src, uint32_t len); ///< get clm data | ||
void (*end)(void); ///< end firmware loading | ||
} cyw43_wifi_firmware_funcs_t; | ||
//!\} | ||
|
||
/*! | ||
* \brief get firmware data from flash | ||
* | ||
* Loads firmware data from flash and returns a pointer to it | ||
* | ||
* \param addr Address of firmware data required | ||
* \param sz_in Amount of firmware data required in bytes | ||
* \param buffer Temporary buffer that can be used to load and return firmware data | ||
* \param buffer_len Length of temporary buffer in bytes | ||
* \return Requested firmware data | ||
*/ | ||
const uint8_t *wifi_firmware_get_source_storage(const uint8_t *addr, size_t sz_in, uint8_t *buffer, size_t buffer_len); | ||
|
||
/*! | ||
* \brief get firmware data embedded in the elf file binary | ||
* | ||
* Loads firmware data from the elf file and returns a pointer to it | ||
* | ||
* \param addr Address of firmware data required | ||
* \param sz_in Amount of firmware data required in bytes | ||
* \param buffer Temporary buffer that can be used to load and return firmware data | ||
* \param buffer_len Length of temporary buffer in bytes | ||
* \return Requested firmware data | ||
*/ | ||
const uint8_t *wifi_firmware_get_source_embedded(const uint8_t *addr, size_t sz_in, uint8_t *buffer, size_t buffer_len); | ||
|
||
/*! | ||
* \brief get clm data embedded in the elf file binary | ||
* | ||
* Loads clm data from the elf file binary and returns a pointer to it | ||
* | ||
* \param dst Destination of clm data | ||
* \param src Source address of the clm data | ||
* \param len Amount of data required in bytes | ||
* \return >=0 on success or <0 on error | ||
*/ | ||
int wifi_firmware_get_clm_embedded(uint8_t *dst, const uint8_t *src, uint32_t len); | ||
|
||
#if CYW43_DECOMPRESS_FIRMWARE | ||
/*! | ||
* \brief Start firmware decompression process | ||
* | ||
* Prepares and allocates resources needed to decompress firmware | ||
* | ||
* \param fw_details Details of the firmware | ||
* \see cyw43_wifi_firmware_details_t | ||
* \return >=0 on success or <0 on error | ||
*/ | ||
int wifi_firmware_start_decompress(const cyw43_wifi_firmware_details_t* fw_details); | ||
|
||
/*! | ||
* \brief get and decompress firmware data embedded in the elf file binary | ||
* | ||
* Loads firmware data from the elf file, decompressed it and returns a pointer to it | ||
* | ||
* \param addr Address of firmware data required | ||
* \param sz_in Amount of firmware data required in bytes | ||
* \param buffer Temporary buffer that can be used to load and return firmware data | ||
* \param buffer_len Length of temporary buffer in bytes | ||
* \return Requested firmware data | ||
*/ | ||
const uint8_t *wifi_firmware_get_source_decompress(const uint8_t *addr, size_t sz_in, uint8_t *buffer, size_t buffer_len); | ||
|
||
/*! | ||
* \brief get and decompress clm data embedded in the elf file binary | ||
* | ||
* Loads clm data from flash, decompresses it and returns a pointer to it | ||
* | ||
* \param dst Destination of clm data | ||
* \param src Source address of the clm data | ||
* \param len Amount of data required in bytes | ||
* \return >=0 on success or <0 on error | ||
*/ | ||
int wifi_firmware_get_clm_decompress(uint8_t *dst, const uint8_t *src, uint32_t len); | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* This file is part of the cyw43-driver | ||
* | ||
* Copyright (C) 2019-2022 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 WIFI_FIRMWARE_43439_H | ||
#define WIFI_FIRMWARE_43439_H | ||
|
||
#include CYW43_WIFI_NVRAM_INCLUDE_FILE | ||
#include "wifi_firmware.h" | ||
|
||
#if CYW43_USE_SPI | ||
#define CYW43_FW_LEN (224190) // 43439A0.bin | ||
#define CYW43_CLM_LEN (984) // 43439_raspberrypi_picow_v5_220624.clm_blob | ||
|
||
extern const uint8_t fw_43439A0_7_95_49_00_combined_start[]; | ||
extern const uint8_t fw_43439A0_7_95_49_00_combined_end[]; | ||
#define CYW43_FIRMWARE_START fw_43439A0_7_95_49_00_combined_start | ||
#define CYW43_FIRMWARE_END fw_43439A0_7_95_49_00_combined_end | ||
|
||
#elif !CYW43_USE_SPI | ||
#define CYW43_FW_LEN (383110) // 7.45.98.50 | ||
extern const uint8_t fw_4343WA1_7_45_98_50_start[]; | ||
extern const uint8_t fw_4343WA1_7_45_98_50_end[]; | ||
#define CYW43_CLM_LEN (7222) | ||
#define CYW43_FIRMWARE_START fw_4343WA1_7_45_98_50_start | ||
#define CYW43_FIRMWARE_END fw_4343WA1_7_45_98_50_end | ||
#endif | ||
|
||
/*! | ||
* \brief Get the firmware binary details | ||
* | ||
* This method returns the details of the firmware binary | ||
* | ||
* \param fw_details Structure to be filled with firmware details | ||
* \see cyw43_wifi_firmware_details_t | ||
*/ | ||
static inline void cyw43_wifi_firmware_details(cyw43_wifi_firmware_details_t *fw_details) { | ||
fw_details->raw_size = CYW43_FIRMWARE_END - CYW43_FIRMWARE_START; | ||
fw_details->raw_data = CYW43_FIRMWARE_START; | ||
fw_details->fw_size = CYW43_FW_LEN; | ||
fw_details->clm_size = CYW43_CLM_LEN, | ||
fw_details->fw_addr = CYW43_FIRMWARE_START; | ||
fw_details->clm_addr = CYW43_FIRMWARE_START + ((CYW43_FW_LEN + 511) & ~511); | ||
fw_details->wifi_nvram_len = (sizeof(wifi_nvram_4343) + 63) & ~63; | ||
fw_details->wifi_nvram_data = wifi_nvram_4343; | ||
} | ||
|
||
/*! | ||
* \brief Get the functions used to load firmware | ||
* | ||
* This method returns pointers to functions that load firmware | ||
* | ||
* \return structure that contains functions that load firmware | ||
* \see cyw43_wifi_firmware_funcs_t | ||
*/ | ||
static inline const cyw43_wifi_firmware_funcs_t *wifi_fw_funcs(void) { | ||
static const cyw43_wifi_firmware_funcs_t funcs = { | ||
#if CYW43_DECOMPRESS_FIRMWARE | ||
.start = wifi_firmware_start_decompress, | ||
.get_fw_source = wifi_firmware_get_source_decompress, | ||
.get_nvram_source = wifi_firmware_get_source_embedded, // not compressed | ||
.get_clm = wifi_firmware_get_clm_decompress, | ||
.end = cyw43_decompress_firmware_end, | ||
#else | ||
.start = NULL, | ||
.get_fw_source = wifi_firmware_get_source_embedded, | ||
.get_nvram_source = wifi_firmware_get_source_embedded, | ||
.get_clm = wifi_firmware_get_clm_embedded, | ||
.end = NULL, | ||
#endif | ||
}; | ||
return &funcs; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* This file is part of the cyw43-driver | ||
* | ||
* Copyright (C) 2019-2022 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. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#include "pico/stdlib.h" | ||
#include "uzlib.h" | ||
|
||
#define DICT_SIZE 32767 | ||
typedef struct uzlib_data { | ||
uint8_t dict[DICT_SIZE]; // todo: use smaller dictionary? | ||
struct uzlib_uncomp state; | ||
size_t amount_left; | ||
} uzlib_data_t; | ||
static uzlib_data_t *uzlib; | ||
|
||
#define CYW43_DECOMPRESS_ERR_NO_MEM -1 | ||
#define CYW43_DECOMPRESS_ERR_BAD_HEADER -2 | ||
#define CYW43_DECOMPRESS_ERR_NO_MORE -3 | ||
#define CYW43_DECOMPRESS_ERR_DECOMPRESS -4 | ||
|
||
size_t cyw43_decompress_firmware_start(const uint8_t *raw_data, size_t raw_size) | ||
{ | ||
uzlib_init(); | ||
|
||
uzlib = malloc(sizeof(*uzlib)); | ||
assert(uzlib); | ||
if (!uzlib) { | ||
return CYW43_DECOMPRESS_ERR_NO_MEM; | ||
} | ||
|
||
uzlib->amount_left = raw_data[raw_size - 1]; | ||
uzlib->amount_left = 256 * uzlib->amount_left + raw_data[raw_size - 2]; | ||
uzlib->amount_left = 256 * uzlib->amount_left + raw_data[raw_size - 3]; | ||
uzlib->amount_left = 256 * uzlib->amount_left + raw_data[raw_size - 4]; | ||
|
||
uzlib_uncompress_init(&uzlib->state, uzlib->dict, sizeof(uzlib->dict)); | ||
|
||
uzlib->state.source = raw_data; | ||
uzlib->state.source_limit = raw_data + raw_size - 4; | ||
uzlib->state.source_read_cb = NULL; | ||
|
||
int res = uzlib_gzip_parse_header(&uzlib->state); | ||
assert(res == TINF_OK); | ||
if (res != TINF_OK) { | ||
return CYW43_DECOMPRESS_ERR_BAD_HEADER; | ||
} | ||
|
||
return uzlib->amount_left; | ||
} | ||
|
||
int cyw43_decompress_firmware_next(uint8_t *buffer, size_t len) | ||
{ | ||
assert(uzlib->amount_left > 0); | ||
if (uzlib->amount_left <= 0) { | ||
return CYW43_DECOMPRESS_ERR_NO_MORE; | ||
} | ||
const size_t chunk_len = uzlib->amount_left < len ? uzlib->amount_left : len; | ||
uzlib->state.dest = buffer; | ||
uzlib->state.dest_limit = uzlib->state.dest + chunk_len; | ||
int res = uzlib_uncompress_chksum(&uzlib->state); | ||
assert(res == TINF_OK); | ||
if (res != TINF_OK) { | ||
return CYW43_DECOMPRESS_ERR_DECOMPRESS; | ||
} | ||
uzlib->amount_left -= chunk_len; | ||
return chunk_len; | ||
} | ||
|
||
void cyw43_decompress_firmware_end(void) | ||
{ | ||
if (uzlib) { | ||
free(uzlib); | ||
uzlib = NULL; | ||
} | ||
} |
Oops, something went wrong.