Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Peter Harper <77111776+peterharperuk@users.noreply.github.com>
- Loading branch information
1 parent
0d207f4
commit c8ccefb
Showing
34 changed files
with
2,533 additions
and
44 deletions.
There are no files selected for viewing
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
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
Submodule cyw43-driver
updated
14 files
+ − | firmware/43439A0-7.95.49.00.combined | |
+ − | firmware/4343WA1-7.45.98.50.combined | |
+18 −7 | firmware/README.md | |
+517 −0 | firmware/cyw43_btfw_43439.h | |
+2,935 −0 | firmware/cyw43_btfw_4343A1.h | |
+18,775 −0 | firmware/w43439A0_7_95_49_00_combined.h | |
+32,581 −0 | firmware/w4343WA1_7_45_98_50_combined.h | |
+19,373 −0 | firmware/wb43439A0_7_95_49_00_combined.h | |
+37 −0 | src/cyw43.h | |
+43 −0 | src/cyw43_btbus.h | |
+21 −0 | src/cyw43_config.h | |
+69 −0 | src/cyw43_ctrl.c | |
+103 −32 | src/cyw43_ll.c | |
+15 −0 | src/cyw43_ll.h |
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
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
Large diffs are not rendered by default.
Oops, something went wrong.
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,144 @@ | ||
/* | ||
* Copyright (c) 2023 Raspberry Pi (Trading) Ltd. | ||
* | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
#include "pico/btstack_flash_bank.h" | ||
#include "hardware/flash.h" | ||
#include "hardware/sync.h" | ||
#include <string.h> | ||
|
||
// Check sizes | ||
static_assert(PICO_FLASH_BANK_TOTAL_SIZE % (FLASH_SECTOR_SIZE * 2) == 0, "PICO_FLASH_BANK_TOTAL_SIZE invalid"); | ||
static_assert(PICO_FLASH_BANK_TOTAL_SIZE <= PICO_FLASH_SIZE_BYTES, "PICO_FLASH_BANK_TOTAL_SIZE too big"); | ||
static_assert(PICO_FLASH_BANK_STORAGE_OFFSET + PICO_FLASH_BANK_TOTAL_SIZE <= PICO_FLASH_SIZE_BYTES, "PICO_FLASH_BANK_TOTAL_SIZE too big"); | ||
|
||
// Size of one bank | ||
#define PICO_FLASH_BANK_SIZE (PICO_FLASH_BANK_TOTAL_SIZE / 2) | ||
|
||
#if 0 | ||
#define DEBUG_PRINT(format,args...) printf(format, ## args) | ||
#else | ||
#define DEBUG_PRINT(...) | ||
#endif | ||
|
||
static uint32_t pico_flash_bank_get_size(void * context) { | ||
(void)(context); | ||
return PICO_FLASH_BANK_SIZE; | ||
} | ||
|
||
static uint32_t pico_flash_bank_get_alignment(void * context) { | ||
(void)(context); | ||
return 1; | ||
} | ||
|
||
static void pico_flash_bank_erase(void * context, int bank) { | ||
(void)(context); | ||
DEBUG_PRINT("erase: bank %d\n", bank); | ||
uint32_t status = save_and_disable_interrupts(); | ||
flash_range_erase(PICO_FLASH_BANK_STORAGE_OFFSET + (PICO_FLASH_BANK_SIZE * bank), PICO_FLASH_BANK_SIZE); | ||
restore_interrupts(status); | ||
} | ||
|
||
static void pico_flash_bank_read(void *context, int bank, uint32_t offset, uint8_t *buffer, uint32_t size) { | ||
(void)(context); | ||
DEBUG_PRINT("read: bank %d offset %u size %u\n", bank, offset, size); | ||
|
||
assert(bank <= 1); | ||
if (bank > 1) return; | ||
|
||
assert(offset < PICO_FLASH_BANK_SIZE); | ||
if (offset >= PICO_FLASH_BANK_SIZE) return; | ||
|
||
assert((offset + size) <= PICO_FLASH_BANK_SIZE); | ||
if ((offset + size) > PICO_FLASH_BANK_SIZE) return; | ||
|
||
// Flash is xip | ||
memcpy(buffer, (void *)(XIP_BASE + PICO_FLASH_BANK_STORAGE_OFFSET + (PICO_FLASH_BANK_SIZE * bank) + offset), size); | ||
} | ||
|
||
static void pico_flash_bank_write(void * context, int bank, uint32_t offset, const uint8_t *data, uint32_t size) { | ||
(void)(context); | ||
DEBUG_PRINT("write: bank %d offset %u size %u\n", bank, offset, size); | ||
|
||
assert(bank <= 1); | ||
if (bank > 1) return; | ||
|
||
assert(offset < PICO_FLASH_BANK_SIZE); | ||
if (offset >= PICO_FLASH_BANK_SIZE) return; | ||
|
||
assert((offset + size) <= PICO_FLASH_BANK_SIZE); | ||
if ((offset + size) > PICO_FLASH_BANK_SIZE) return; | ||
|
||
if (size == 0) return; | ||
|
||
// calc bank start position | ||
const uint32_t bank_start_pos = PICO_FLASH_BANK_STORAGE_OFFSET + (PICO_FLASH_BANK_SIZE * bank); | ||
|
||
// Calculate first and last page in the bank | ||
const uint32_t first_page = offset / FLASH_PAGE_SIZE; | ||
const uint32_t last_page = (offset + size + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE; | ||
|
||
// Now we only care about the offset in the first page | ||
offset %= FLASH_PAGE_SIZE; | ||
|
||
// Amount of data we've copied | ||
uint32_t data_pos = 0; | ||
uint32_t size_left = size; | ||
|
||
// Write all the pages required | ||
for(uint32_t page = first_page; page < last_page; page++) { | ||
uint8_t page_data[FLASH_PAGE_SIZE]; | ||
|
||
assert(data_pos < size && size_left <= size); | ||
|
||
// Copy data we're not going to overwrite in the first page | ||
if (page == first_page && offset > 0) { | ||
memcpy(page_data, | ||
(void *)(XIP_BASE + bank_start_pos + (page * FLASH_PAGE_SIZE)), | ||
offset); | ||
} | ||
|
||
// Copy the data we're not going to overwrite in the last page | ||
if (page == last_page - 1 && (offset + size_left) < FLASH_PAGE_SIZE) { | ||
memcpy(page_data + offset + size_left, | ||
(void *)(XIP_BASE + bank_start_pos + (page * FLASH_PAGE_SIZE) + offset + size_left), | ||
FLASH_PAGE_SIZE - offset - size_left); | ||
} | ||
|
||
// Now copy the new data into the page | ||
const uint32_t size_to_copy = MIN(size_left, FLASH_PAGE_SIZE - offset); | ||
memcpy(page_data + offset, data + data_pos, size_to_copy); | ||
|
||
data_pos += size_to_copy; | ||
size_left -= size_to_copy; | ||
|
||
// zero offset for the following pages | ||
offset = 0; | ||
|
||
// Now program the entire page | ||
uint32_t status = save_and_disable_interrupts(); | ||
flash_range_program(bank_start_pos + (page * FLASH_PAGE_SIZE), page_data, FLASH_PAGE_SIZE); | ||
restore_interrupts(status); | ||
} | ||
} | ||
|
||
static const hal_flash_bank_t pico_flash_bank_instance_obj = { | ||
/* uint32_t (*get_size)(..) */ &pico_flash_bank_get_size, | ||
/* uint32_t (*get_alignment)(..); */ &pico_flash_bank_get_alignment, | ||
/* void (*erase)(..); */ &pico_flash_bank_erase, | ||
/* void (*read)(..); */ &pico_flash_bank_read, | ||
/* void (*write)(..); */ &pico_flash_bank_write, | ||
}; | ||
|
||
const hal_flash_bank_t *pico_flash_bank_instance(void) { | ||
|
||
#ifndef NDEBUG | ||
// Check we're not overlapping the binary in flash | ||
extern char __flash_binary_end; | ||
assert((uintptr_t)&__flash_binary_end - XIP_BASE <= PICO_FLASH_BANK_STORAGE_OFFSET); | ||
#endif | ||
|
||
return &pico_flash_bank_instance_obj; | ||
} |
155 changes: 155 additions & 0 deletions
155
src/rp2_common/pico_btstack/btstack_run_loop_async_context.c
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,155 @@ | ||
/* | ||
* Copyright (c) 2023 Raspberry Pi (Trading) Ltd. | ||
* | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
#include "pico/btstack_run_loop_async_context.h" | ||
#include "hardware/sync.h" | ||
|
||
static async_context_t *btstack_async_context; | ||
static async_at_time_worker_t btstack_timeout_worker; | ||
static async_when_pending_worker_t btstack_processing_worker; | ||
static void btstack_timeout_reached(async_context_t *context, async_at_time_worker_t *worker); | ||
static void btstack_work_pending(async_context_t *context, async_when_pending_worker_t *worker); | ||
static volatile bool run_loop_exit; | ||
|
||
static void btstack_run_loop_async_context_init(void) { | ||
btstack_run_loop_base_init(); | ||
btstack_timeout_worker.do_work = btstack_timeout_reached; | ||
btstack_processing_worker.do_work = btstack_work_pending; | ||
async_context_add_when_pending_worker(btstack_async_context, &btstack_processing_worker); | ||
} | ||
|
||
static void btstack_run_loop_async_context_add_data_source(btstack_data_source_t * data_source) { | ||
async_context_acquire_lock_blocking(btstack_async_context); | ||
btstack_run_loop_base_add_data_source(data_source); | ||
async_context_release_lock(btstack_async_context); | ||
} | ||
|
||
static bool btstack_run_loop_async_context_remove_data_source(btstack_data_source_t * data_source) { | ||
async_context_acquire_lock_blocking(btstack_async_context); | ||
bool rc = btstack_run_loop_base_remove_data_source(data_source); | ||
async_context_release_lock(btstack_async_context); | ||
return rc; | ||
} | ||
|
||
static void btstack_run_loop_async_context_enable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks) { | ||
async_context_acquire_lock_blocking(btstack_async_context); | ||
btstack_run_loop_base_enable_data_source_callbacks(data_source, callbacks); | ||
async_context_release_lock(btstack_async_context); | ||
} | ||
|
||
static void btstack_run_loop_async_context_disable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks) { | ||
async_context_acquire_lock_blocking(btstack_async_context); | ||
btstack_run_loop_base_disable_data_source_callbacks(data_source, callbacks); | ||
async_context_release_lock(btstack_async_context); | ||
} | ||
|
||
static void btstack_run_loop_async_context_set_timer(btstack_timer_source_t *ts, uint32_t timeout_in_ms){ | ||
async_context_acquire_lock_blocking(btstack_async_context); | ||
ts->timeout = to_ms_since_boot(get_absolute_time()) + timeout_in_ms + 1; | ||
async_context_set_work_pending(btstack_async_context, &btstack_processing_worker); | ||
async_context_release_lock(btstack_async_context); | ||
} | ||
|
||
static void btstack_run_loop_async_context_add_timer(btstack_timer_source_t *timer) { | ||
async_context_acquire_lock_blocking(btstack_async_context); | ||
btstack_run_loop_base_add_timer(timer); | ||
async_context_set_work_pending(btstack_async_context, &btstack_processing_worker); | ||
async_context_release_lock(btstack_async_context); | ||
} | ||
|
||
static bool btstack_run_loop_async_context_remove_timer(btstack_timer_source_t *timer) { | ||
async_context_acquire_lock_blocking(btstack_async_context); | ||
bool rc = btstack_run_loop_base_remove_timer(timer); | ||
async_context_release_lock(btstack_async_context); | ||
return rc; | ||
} | ||
|
||
static void btstack_run_loop_async_context_dump_timer(void){ | ||
async_context_acquire_lock_blocking(btstack_async_context); | ||
btstack_run_loop_base_dump_timer(); | ||
async_context_release_lock(btstack_async_context); | ||
} | ||
|
||
static uint32_t btstack_run_loop_async_context_get_time_ms(void) | ||
{ | ||
return to_ms_since_boot(get_absolute_time()); | ||
} | ||
|
||
static void btstack_run_loop_async_context_execute(void) | ||
{ | ||
run_loop_exit = false; | ||
while (!run_loop_exit) { | ||
async_context_poll(btstack_async_context); | ||
async_context_wait_for_work_until(btstack_async_context, at_the_end_of_time); | ||
} | ||
} | ||
|
||
static void btstack_run_loop_async_context_trigger_exit(void) | ||
{ | ||
run_loop_exit = true; | ||
} | ||
|
||
static void btstack_run_loop_async_context_execute_on_main_thread(btstack_context_callback_registration_t *callback_registration) | ||
{ | ||
async_context_acquire_lock_blocking(btstack_async_context); | ||
btstack_run_loop_base_add_callback(callback_registration); | ||
async_context_set_work_pending(btstack_async_context, &btstack_processing_worker); | ||
async_context_release_lock(btstack_async_context); | ||
} | ||
|
||
static void btstack_run_loop_async_context_poll_data_sources_from_irq(void) | ||
{ | ||
async_context_set_work_pending(btstack_async_context, &btstack_processing_worker); | ||
} | ||
|
||
static const btstack_run_loop_t btstack_run_loop_async_context = { | ||
&btstack_run_loop_async_context_init, | ||
&btstack_run_loop_async_context_add_data_source, | ||
&btstack_run_loop_async_context_remove_data_source, | ||
&btstack_run_loop_async_context_enable_data_source_callbacks, | ||
&btstack_run_loop_async_context_disable_data_source_callbacks, | ||
&btstack_run_loop_async_context_set_timer, | ||
&btstack_run_loop_async_context_add_timer, | ||
&btstack_run_loop_async_context_remove_timer, | ||
&btstack_run_loop_async_context_execute, | ||
&btstack_run_loop_async_context_dump_timer, | ||
&btstack_run_loop_async_context_get_time_ms, | ||
&btstack_run_loop_async_context_poll_data_sources_from_irq, | ||
&btstack_run_loop_async_context_execute_on_main_thread, | ||
&btstack_run_loop_async_context_trigger_exit, | ||
}; | ||
|
||
const btstack_run_loop_t *btstack_run_loop_async_context_get_instance(async_context_t *async_context) | ||
{ | ||
assert(!btstack_async_context || btstack_async_context == async_context); | ||
btstack_async_context = async_context; | ||
return &btstack_run_loop_async_context; | ||
} | ||
|
||
static void btstack_timeout_reached(__unused async_context_t *context, __unused async_at_time_worker_t *worker) { | ||
// simply wakeup worker | ||
async_context_set_work_pending(btstack_async_context, &btstack_processing_worker); | ||
} | ||
|
||
static void btstack_work_pending(__unused async_context_t *context, __unused async_when_pending_worker_t *worker) { | ||
// poll data sources | ||
btstack_run_loop_base_poll_data_sources(); | ||
|
||
// execute callbacks | ||
btstack_run_loop_base_execute_callbacks(); | ||
|
||
uint32_t now = to_ms_since_boot(get_absolute_time()); | ||
|
||
// process timers | ||
btstack_run_loop_base_process_timers(now); | ||
now = to_ms_since_boot(get_absolute_time()); | ||
int ms = btstack_run_loop_base_get_time_until_timeout(now); | ||
if (ms == -1) { | ||
async_context_remove_at_time_worker(btstack_async_context, &btstack_timeout_worker); | ||
} else { | ||
async_context_add_at_time_worker_in_ms(btstack_async_context, &btstack_timeout_worker, ms); | ||
} | ||
} |
Oops, something went wrong.
c8ccefb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking forward to stable release ❤️