From 5e50be411f13164d4ba9060676df792eea2dd3c2 Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 2 Dec 2024 08:33:49 +0000 Subject: [PATCH] Update pico SDK to v2.1.0 with RP2350 support (#2918) --- .github/workflows/ci.yml | 4 +- .gitmodules | 2 +- .../Rp2040/Components/driver/hw_timer.cpp | 16 +- .../driver/include/driver/hw_timer.h | 13 +- .../Rp2040/Components/driver/os_timer.cpp | 8 +- Sming/Arch/Rp2040/Components/driver/uart.cpp | 10 +- Sming/Arch/Rp2040/Components/libc/src/heap.c | 16 -- .../Arch/Rp2040/Components/libc/src/heap.cpp | 58 ++++ .../libc/src/include/sys/pgmspace.h | 4 + .../Rp2040/Components/picotool/README.rst | 8 +- .../Rp2040/Components/picotool/component.mk | 45 ++- .../Arch/Rp2040/Components/picotool/picotool | 2 +- .../Rp2040/Components/picotool/picotool.patch | 28 ++ .../Rp2040/Components/rp2040/component.mk | 41 ++- .../Components/rp2040/cyw43-driver.patch | 256 ++++++++---------- Sming/Arch/Rp2040/Components/rp2040/pico-sdk | 2 +- .../Rp2040/Components/rp2040/pico-sdk.patch | 68 ++--- .../Components/rp2040/sdk/CMakeLists.txt | 20 +- .../Components/rp2040/sdk/pico_bit_ops.mk | 2 + .../Components/rp2040/sdk/pico_divider.mk | 2 + .../Components/rp2040/sdk/pico_float.mk | 6 +- .../Components/rp2040/sdk/pico_int64_ops.mk | 2 + .../Components/rp2040/sdk/pico_mem_ops.mk | 2 + Sming/Arch/Rp2040/Components/rp2040/src/clk.c | 39 +-- .../Rp2040/Components/rp2040/src/startup.cpp | 14 +- .../Rp2040/Components/rp2040/src/wifi.cpp | 21 ++ .../Rp2040/Components/sming-arch/component.mk | 1 + .../Rp2040/Components/spi_flash/flashmem.cpp | 37 ++- Sming/Arch/Rp2040/Components/uf2/component.mk | 34 +-- .../Rp2040/Components/uf2/uf2families.json | 184 ++++++++++++- Sming/Arch/Rp2040/Platform/RTC.cpp | 74 +++-- Sming/Arch/Rp2040/README.rst | 30 +- Sming/Arch/Rp2040/app.mk | 12 +- Sming/Arch/Rp2040/build.mk | 20 +- Sming/Arch/Rp2040/rp2350-pindefs.txt | 52 ++++ Sming/Arch/Rp2040/rp2350-soc.json | 62 +++++ Sming/Components/malloc_count/component.mk | 1 - .../Components/malloc_count/malloc_count.cpp | 2 +- Sming/Libraries/USB | 2 +- Tools/ci/scanlog.py | 5 +- samples/Basic_IFS/app/application.cpp | 2 +- samples/Basic_IFS/basic_ifs_Rp2040.hw | 2 +- 42 files changed, 828 insertions(+), 381 deletions(-) delete mode 100644 Sming/Arch/Rp2040/Components/libc/src/heap.c create mode 100644 Sming/Arch/Rp2040/Components/libc/src/heap.cpp create mode 100644 Sming/Arch/Rp2040/Components/picotool/picotool.patch create mode 100644 Sming/Arch/Rp2040/rp2350-pindefs.txt create mode 100644 Sming/Arch/Rp2040/rp2350-soc.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b33ec55ea..133dd9a13e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - variant: [esp8266, host, rp2040] + variant: [esp8266, host, rp2040, rp2350] toolchain: [gcc] include: - variant: esp8266 @@ -31,6 +31,8 @@ jobs: toolchain: gcc64 - variant: rp2040 arch: Rp2040 + - variant: rp2350 + arch: Rp2040 concurrency: group: ${{ github.workflow }}-${{ github.ref }}-${{ toJson(matrix) }} diff --git a/.gitmodules b/.gitmodules index cbd4b056cb..7a6bfa13a3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -122,7 +122,7 @@ [submodule "Rp2040.picotool"] path = Sming/Arch/Rp2040/Components/picotool/picotool - url = https://github.com/mikee47/picotool + url = https://github.com/raspberrypi/picotool ignore = dirty [submodule "Rp2040.Sdk"] diff --git a/Sming/Arch/Rp2040/Components/driver/hw_timer.cpp b/Sming/Arch/Rp2040/Components/driver/hw_timer.cpp index 0c8f44c741..03556d271e 100644 --- a/Sming/Arch/Rp2040/Components/driver/hw_timer.cpp +++ b/Sming/Arch/Rp2040/Components/driver/hw_timer.cpp @@ -18,7 +18,7 @@ namespace { void IRAM_ATTR timer1_isr() { - hw_clear_bits(&timer_hw->intr, BIT(0)); + hw_clear_bits(&timer_hw->intr, BIT(0)); auto& p = hw_timer_private; if(p.timer1_callback != nullptr) { p.timer1_callback(p.timer1_arg); @@ -33,20 +33,22 @@ void IRAM_ATTR timer1_isr() void IRAM_ATTR hw_timer1_attach_interrupt(hw_timer_source_type_t source_type, hw_timer_callback_t callback, void* arg) { (void)source_type; + auto irq_num = TIMER_ALARM_IRQ_NUM(HW_TIMER_NUM, 0); + irq_set_enabled(irq_num, false); auto& p = hw_timer_private; - irq_set_enabled(TIMER_IRQ_0, false); p.timer1_callback = callback; p.timer1_arg = arg; - irq_set_exclusive_handler(TIMER_IRQ_0, timer1_isr); + irq_set_exclusive_handler(irq_num, timer1_isr); hw_set_bits(&timer_hw->inte, BIT(0)); - irq_set_enabled(TIMER_IRQ_0, true); + irq_set_enabled(irq_num, true); } void hw_timer1_detach_interrupt() { hw_clear_bits(&timer_hw->inte, BIT(0)); - irq_set_enabled(TIMER_IRQ_0, false); - irq_remove_handler(TIMER_IRQ_0, timer1_isr); + auto irq_num = TIMER_ALARM_IRQ_NUM(HW_TIMER_NUM, 0); + irq_set_enabled(irq_num, false); + irq_remove_handler(irq_num, timer1_isr); } void IRAM_ATTR hw_timer1_enable(hw_timer_clkdiv_t div, hw_timer_intr_type_t intr_type, bool auto_load) @@ -59,5 +61,5 @@ void IRAM_ATTR hw_timer1_enable(hw_timer_clkdiv_t div, hw_timer_intr_type_t intr void hw_timer_init() { - // hardware_alarm_claim(0); + timer_hardware_alarm_claim(HW_TIMER_INST, 0); } diff --git a/Sming/Arch/Rp2040/Components/driver/include/driver/hw_timer.h b/Sming/Arch/Rp2040/Components/driver/include/driver/hw_timer.h index b94d5b4e34..101382027d 100644 --- a/Sming/Arch/Rp2040/Components/driver/include/driver/hw_timer.h +++ b/Sming/Arch/Rp2040/Components/driver/include/driver/hw_timer.h @@ -11,7 +11,7 @@ #pragma once #include -#include +#include #ifdef __cplusplus extern "C" { @@ -19,6 +19,9 @@ extern "C" { #define HW_TIMER_BASE_CLK 1000000U +#define HW_TIMER_NUM 0 +#define HW_TIMER_INST TIMER_INSTANCE(HW_TIMER_NUM) + /** * @defgroup hw_timer Hardware Timer Driver * @ingroup drivers @@ -36,7 +39,7 @@ extern "C" { */ __forceinline uint32_t IRAM_ATTR hw_timer_ticks() { - return timer_hw->timerawl; + return timer_time_us_32(HW_TIMER_INST); } /************************************* @@ -116,7 +119,7 @@ __forceinline void IRAM_ATTR hw_timer1_write(uint32_t ticks) { ticks <<= hw_timer_private.timer1_clkdiv; hw_timer_private.timer1_ticks = ticks; - timer_hw->alarm[0] = hw_timer_ticks() + ticks; + HW_TIMER_INST->alarm[0] = hw_timer_ticks() + ticks; } /** @@ -124,7 +127,7 @@ __forceinline void IRAM_ATTR hw_timer1_write(uint32_t ticks) */ __forceinline void IRAM_ATTR hw_timer1_disable() { - timer_hw->armed = BIT(0); + HW_TIMER_INST->armed = BIT(0); } /** @@ -133,7 +136,7 @@ __forceinline void IRAM_ATTR hw_timer1_disable() */ __forceinline uint32_t hw_timer1_read() { - int time = hw_timer_ticks() - timer_hw->alarm[0]; + int time = hw_timer_ticks() - HW_TIMER_INST->alarm[0]; return (time > 0) ? (time >> hw_timer_private.timer1_clkdiv) : 0; } diff --git a/Sming/Arch/Rp2040/Components/driver/os_timer.cpp b/Sming/Arch/Rp2040/Components/driver/os_timer.cpp index b524d56ceb..d43afb6cfd 100644 --- a/Sming/Arch/Rp2040/Components/driver/os_timer.cpp +++ b/Sming/Arch/Rp2040/Components/driver/os_timer.cpp @@ -75,16 +75,16 @@ void IRAM_ATTR timer_schedule() if(timer_list == nullptr) { debug_tmr("cancel"); // Cancel hardware timer - timer_hw->armed = BIT(1); + HW_TIMER_INST->armed = BIT(1); return; } constexpr int TIMER2_MIN_US{50}; auto now = hw_timer2_read(); if(int(timer_list->timer_expire - now) < TIMER2_MIN_US) { - timer_hw->alarm[1] = now + TIMER2_MIN_US; + HW_TIMER_INST->alarm[1] = now + TIMER2_MIN_US; } else { - timer_hw->alarm[1] = timer_list->timer_expire; + HW_TIMER_INST->alarm[1] = timer_list->timer_expire; } } @@ -95,7 +95,7 @@ os_timer_t* find_expired_timer() } // Using Timer2 hardware to schedule software timers - if(timer_hw->armed & BIT(1)) { + if(HW_TIMER_INST->armed & BIT(1)) { return nullptr; } diff --git a/Sming/Arch/Rp2040/Components/driver/uart.cpp b/Sming/Arch/Rp2040/Components/driver/uart.cpp index c277d41037..9d4867f742 100644 --- a/Sming/Arch/Rp2040/Components/driver/uart.cpp +++ b/Sming/Arch/Rp2040/Components/driver/uart.cpp @@ -13,6 +13,12 @@ #include #include +#ifdef ARCH_RP2040 +#define UART_FUNCSEL_NUM(gpio) GPIO_FUNC_UART +#else +#define UART_FUNCSEL_NUM(gpio) ((gpio) & 0x2 ? GPIO_FUNC_UART_AUX : GPIO_FUNC_UART) +#endif + namespace { using uart_dev_t = uart_hw_t; @@ -721,7 +727,7 @@ bool smg_uart_set_pins(smg_uart_t* uart, int tx_pin, int rx_pin) if(uart->tx_pin != UART_PIN_DEFAULT) { gpio_set_function(uart->tx_pin, GPIO_FUNC_NULL); } - gpio_set_function(tx_pin, GPIO_FUNC_UART); + gpio_set_function(tx_pin, UART_FUNCSEL_NUM(tx_pin)); uart->tx_pin = tx_pin; } @@ -729,7 +735,7 @@ bool smg_uart_set_pins(smg_uart_t* uart, int tx_pin, int rx_pin) if(uart->rx_pin != UART_PIN_DEFAULT) { gpio_set_function(uart->rx_pin, GPIO_FUNC_NULL); } - gpio_set_function(rx_pin, GPIO_FUNC_UART); + gpio_set_function(rx_pin, UART_FUNCSEL_NUM(rx_pin)); uart->rx_pin = rx_pin; } diff --git a/Sming/Arch/Rp2040/Components/libc/src/heap.c b/Sming/Arch/Rp2040/Components/libc/src/heap.c deleted file mode 100644 index de274e3b4e..0000000000 --- a/Sming/Arch/Rp2040/Components/libc/src/heap.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * heap.c - */ - -#include "include/heap.h" -#include - -uint32_t system_get_free_heap_size(void) -{ - // These are set by linker - extern char __end__; - extern char __StackLimit; - uint32_t maxHeap = (uint32_t)&__StackLimit - (uint32_t)&__end__; - struct mallinfo m = mallinfo(); - return maxHeap - m.uordblks; -} diff --git a/Sming/Arch/Rp2040/Components/libc/src/heap.cpp b/Sming/Arch/Rp2040/Components/libc/src/heap.cpp new file mode 100644 index 0000000000..1074e9d8ac --- /dev/null +++ b/Sming/Arch/Rp2040/Components/libc/src/heap.cpp @@ -0,0 +1,58 @@ +/* + * heap.c + */ + +#include "include/heap.h" +#include +#include +#include + +extern "C" uint32_t system_get_free_heap_size(void) +{ + // These are set by linker + extern char __end__; + extern char __StackLimit; + uint32_t maxHeap = (uint32_t)&__StackLimit - (uint32_t)&__end__; + struct mallinfo m = mallinfo(); + return maxHeap - m.uordblks; +} + +void* operator new(size_t size) +{ + return malloc(size); +} + +void* operator new(size_t size, const std::nothrow_t&) +{ + return malloc(size); +} + +void* operator new[](size_t size) +{ + return malloc(size); +} + +void* operator new[](size_t size, const std::nothrow_t&) +{ + return malloc(size); +} + +void operator delete(void* ptr) +{ + free(ptr); +} + +void operator delete[](void* ptr) +{ + free(ptr); +} + +void operator delete(void* ptr, size_t) +{ + free(ptr); +} + +void operator delete[](void* ptr, size_t) +{ + free(ptr); +} diff --git a/Sming/Arch/Rp2040/Components/libc/src/include/sys/pgmspace.h b/Sming/Arch/Rp2040/Components/libc/src/include/sys/pgmspace.h index a04deaa0c9..895eb8774d 100644 --- a/Sming/Arch/Rp2040/Components/libc/src/include/sys/pgmspace.h +++ b/Sming/Arch/Rp2040/Components/libc/src/include/sys/pgmspace.h @@ -21,7 +21,11 @@ extern "C" { /** * @brief Simple check to determine if a pointer refers to flash memory */ +#ifdef XIP_END +#define isFlashPtr(ptr) ((uint32_t)(ptr) >= XIP_BASE && (uint32_t)(ptr) < XIP_END) +#else #define isFlashPtr(ptr) ((uint32_t)(ptr) >= XIP_MAIN_BASE && (uint32_t)(ptr) < XIP_NOALLOC_BASE) +#endif #define PROGMEM STORE_ATTR ICACHE_RODATA_ATTR #define PROGMEM_PSTR PROGMEM diff --git a/Sming/Arch/Rp2040/Components/picotool/README.rst b/Sming/Arch/Rp2040/Components/picotool/README.rst index e887b5d13e..b16fb5ed6a 100644 --- a/Sming/Arch/Rp2040/Components/picotool/README.rst +++ b/Sming/Arch/Rp2040/Components/picotool/README.rst @@ -3,4 +3,10 @@ Picotool Picotool is a tool for inspecting RP2040 binaries, and interacting with RP2040 devices when they are in BOOTSEL mode. -Note for full documentation see https://rptl.io/pico-get-started Appendix B. +See https://rptl.io/pico-get-started Appendix B for an introduction to this tool. + +Sming builds picotool from source and uses it to read back flash memory with build targets such as ``make readpart``. + +The tool can be invoked directly like this:: + + make picotool CMD="info -a" diff --git a/Sming/Arch/Rp2040/Components/picotool/component.mk b/Sming/Arch/Rp2040/Components/picotool/component.mk index 9e2ea04f85..f7e18a3241 100644 --- a/Sming/Arch/Rp2040/Components/picotool/component.mk +++ b/Sming/Arch/Rp2040/Components/picotool/component.mk @@ -33,10 +33,49 @@ $(COMPONENT_RULE)$(PICOTOOL): $(Q) mkdir -p $(@D) $(Q) cd $(@D) && $(CMAKE) $(PICOTOOL_CMAKE_OPTIONS) $(PICOTOOL_SRC) && $(MAKE) +##@Flashing + +.PHONY: picotool +picotool: ##Pass options to picotool, e.g. `make picotool -- help` + $(Q) $(PICOTOOL) $(CMD) + +comma := , +XIP_BASE := 0x10000000 + +define CalcHex +$$(printf "0x%x" $$(( $1 ))) +endef + +define RangeStart +$(call CalcHex,$(XIP_BASE) + $(firstword $(subst $(comma), ,$1))) +endef + +define RangeEnd +$(call CalcHex,$(XIP_BASE) + $(firstword $(subst $(comma), ,$1)) + $(word 2,$(subst $(comma), ,$1))) +endef + +# Read flash memory into file +# $1 -> `Offset,Size` chunk +# $2 -> Output filename +define ReadFlash + $(info ReadFlash $1,$2) + $(Q) $(PICOTOOL) save -r $(call RangeStart,$1) $(call RangeEnd,$1) $2 -t bin +endef # Read flash manufacturer ID and determine actual size define ReadFlashID $(info ReadFlashID) - $(Q) $(PICOTOOL) info -a $(TARGET_BIN) - # $(PICOTOOL) help info - endef + $(Q) $(PICOTOOL) info -a +endef + +# Erase a region of Flash +# $1 -> Offset,Size +define EraseFlashRegion + $(info EraseFlashRegion $1) + $(Q) $(PICOTOOL) erase -r $(call RangeStart,$1) $(call RangeEnd,$1) +endef + +# Erase flash memory contents +define EraseFlash + $(Q) $(PICOTOOL) erase -a +endef diff --git a/Sming/Arch/Rp2040/Components/picotool/picotool b/Sming/Arch/Rp2040/Components/picotool/picotool index 5d6df39033..df21059f7c 160000 --- a/Sming/Arch/Rp2040/Components/picotool/picotool +++ b/Sming/Arch/Rp2040/Components/picotool/picotool @@ -1 +1 @@ -Subproject commit 5d6df39033c7166ea6e76cbde1ff0c0240a4bba4 +Subproject commit df21059f7ca6f1babc7f1f3b92122cacffc85951 diff --git a/Sming/Arch/Rp2040/Components/picotool/picotool.patch b/Sming/Arch/Rp2040/Components/picotool/picotool.patch new file mode 100644 index 0000000000..dbfcf4c51d --- /dev/null +++ b/Sming/Arch/Rp2040/Components/picotool/picotool.patch @@ -0,0 +1,28 @@ +diff --git a/lib/whereami/whereami.c b/lib/whereami/whereami.c +index d052e14..940736e 100644 +--- a/lib/whereami/whereami.c ++++ b/lib/whereami/whereami.c +@@ -60,8 +60,9 @@ extern "C" { + #if defined(_MSC_VER) + #pragma warning(push, 3) + #endif ++#undef _WIN32_WINNT ++#define _WIN32_WINNT _WIN32_WINNT_WINXP + #include +-#include + #if defined(_MSC_VER) + #pragma warning(pop) + #endif +diff --git a/picoboot_connection/picoboot_connection.c b/picoboot_connection/picoboot_connection.c +index 265608c..e487714 100644 +--- a/picoboot_connection/picoboot_connection.c ++++ b/picoboot_connection/picoboot_connection.c +@@ -9,6 +9,8 @@ + #include + #include + ++#define static_assert _Static_assert ++ + #include "picoboot_connection.h" + #include "boot/bootrom_constants.h" + #include "pico/stdio_usb/reset_interface.h" diff --git a/Sming/Arch/Rp2040/Components/rp2040/component.mk b/Sming/Arch/Rp2040/Components/rp2040/component.mk index 4c03455044..50fdec72b9 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/component.mk +++ b/Sming/Arch/Rp2040/Components/rp2040/component.mk @@ -6,10 +6,16 @@ else export PICO_SDK_PATH := $(COMPONENT_PATH)/pico-sdk endif +ifeq ($(SMING_SOC),rp2350) +PICO_VARIANT=pico2 +else +PICO_VARIANT=pico +endif + ifeq ($(DISABLE_WIFI),1) -export PICO_BOARD ?= pico +export PICO_BOARD ?= $(PICO_VARIANT) else -export PICO_BOARD ?= pico_w +export PICO_BOARD ?= $(PICO_VARIANT)_w COMPONENT_DEPENDS += uzlib endif @@ -35,29 +41,33 @@ ifeq ($(ENABLE_BOOTSEL),1) COMPONENT_CXXFLAGS += -DENABLE_BOOTSEL=1 endif +# Functions which are wrapped by the SDK WRAPPED_FUNCTIONS := $(foreach c,$(wildcard $(COMPONENT_PATH)/sdk/*.mk),$(eval include $c)) EXTRA_LDFLAGS := \ $(call Wrap,$(WRAPPED_FUNCTIONS)) \ + -Wl,--whole-archive -lpico -Wl,--no-whole-archive \ -T memmap_default.ld SDK_INTERFACES := \ boards \ - common/pico_base \ + common/pico_base_headers \ common/pico_binary_info \ - common/pico_bit_ops \ - common/pico_divider \ + common/pico_bit_ops_headers \ + common/pico_divider_headers \ common/pico_sync \ common/pico_time \ common/pico_util \ - rp2040/hardware_regs \ - rp2040/hardware_structs \ + $(RP_VARIANT)/hardware_regs \ + $(RP_VARIANT)/hardware_structs \ rp2_common/hardware_adc \ rp2_common/hardware_gpio \ - rp2_common/pico_platform \ + $(RP_VARIANT)/pico_platform \ + rp2_common/boot_bootrom_headers \ rp2_common/hardware_base \ + rp2_common/hardware_boot_lock \ rp2_common/hardware_sync \ rp2_common/hardware_divider \ rp2_common/hardware_timer \ @@ -73,17 +83,25 @@ SDK_INTERFACES := \ rp2_common/hardware_rtc \ rp2_common/hardware_pll \ rp2_common/hardware_spi \ + rp2_common/hardware_sync_spin_lock \ rp2_common/hardware_vreg \ rp2_common/hardware_watchdog \ rp2_common/hardware_xosc \ + rp2_common/pico_aon_timer \ rp2_common/pico_async_context \ rp2_common/pico_bootrom \ rp2_common/pico_double \ rp2_common/pico_int64_ops \ rp2_common/pico_float \ + rp2_common/pico_flash \ + rp2_common/pico_mem_ops \ rp2_common/pico_multicore \ + rp2_common/pico_platform_compiler \ + rp2_common/pico_platform_panic \ + rp2_common/pico_platform_sections \ rp2_common/pico_rand \ rp2_common/pico_runtime \ + rp2_common/pico_runtime_init \ rp2_common/pico_unique_id \ rp2_common/pico_cyw43_arch \ rp2_common/pico_cyw43_driver @@ -105,10 +123,10 @@ COMPONENT_INCDIRS += $(PICO_BASE_DIR) LIBDIRS += \ $(PICO_SDK_PATH)/src/rp2_common/pico_standard_link \ + $(PICO_SDK_PATH)/src/rp2_common/pico_crt0/$(RP_VARIANT) \ $(PICO_BUILD_DIR) EXTRA_LIBS += \ - pico \ m \ stdc++ \ gcc @@ -116,7 +134,8 @@ EXTRA_LIBS += \ RP2040_CMAKE_OPTIONS := \ -G Ninja \ -DCMAKE_MAKE_PROGRAM=$(NINJA) \ - -DCMAKE_BUILD_TYPE=$(if $(subst 1,,$(PICO_DEBUG)),RelWithDebInfo,Debug) + -DCMAKE_BUILD_TYPE=$(if $(subst 1,,$(PICO_DEBUG)),RelWithDebInfo,Debug) \ + -DPICO_VARIANT=$(RP_VARIANT) ifeq ($(ENABLE_CCACHE),1) RP2040_CMAKE_OPTIONS += \ @@ -126,7 +145,7 @@ endif COMPONENT_PREREQUISITES := $(PICO_CONFIG) -BOOTLOADER := $(PICO_BUILD_DIR)/pico-sdk/src/rp2_common/boot_stage2/bs2_default_padded_checksummed.S +BOOTLOADER := $(PICO_BUILD_DIR)/pico-sdk/src/$(RP_VARIANT)/boot_stage2/bs2_default_padded_checksummed.S DEBUG_VARS += CYW43_FIRMWARE CYW43_FIRMWARE := $(COMPONENT_BUILD_BASE)/cyw43-fw.gz diff --git a/Sming/Arch/Rp2040/Components/rp2040/cyw43-driver.patch b/Sming/Arch/Rp2040/Components/rp2040/cyw43-driver.patch index c7edc5b93e..ff93702411 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/cyw43-driver.patch +++ b/Sming/Arch/Rp2040/Components/rp2040/cyw43-driver.patch @@ -1,8 +1,8 @@ diff --git a/src/cyw43_ctrl.c b/src/cyw43_ctrl.c -index edec1f3..de03c73 100644 +index cc9973e..ab76673 100644 --- a/src/cyw43_ctrl.c +++ b/src/cyw43_ctrl.c -@@ -296,13 +296,17 @@ static const char *const cyw43_async_event_name_table[89] = { +@@ -288,13 +288,17 @@ static const char *const cyw43_async_event_name_table[89] = { [CYW43_EV_SET_SSID] = "SET_SSID", [CYW43_EV_JOIN] = "JOIN", [CYW43_EV_AUTH] = "AUTH", @@ -21,20 +21,10 @@ index edec1f3..de03c73 100644 [CYW43_EV_ASSOC_REQ_IE] = "ASSOC_REQ_IE", [CYW43_EV_ASSOC_RESP_IE] = "ASSOC_RESP_IE", diff --git a/src/cyw43_ll.c b/src/cyw43_ll.c -index 604335c..4aeb629 100644 +index 033eec2..11f08d5 100644 --- a/src/cyw43_ll.c +++ b/src/cyw43_ll.c -@@ -54,9 +54,6 @@ - #include "cyw43_sdio.h" - #endif - --#define CYW43_FLASH_BLOCK_SIZE (512) --uint32_t storage_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks); -- - struct pbuf; - uint16_t pbuf_copy_partial(const struct pbuf *p, void *dataptr, uint16_t len, uint16_t offset); - -@@ -68,10 +65,6 @@ extern bool enable_spi_packet_dumping; +@@ -65,11 +65,6 @@ extern bool enable_spi_packet_dumping; #define CYW43_RAM_SIZE (512 * 1024) @@ -42,160 +32,146 @@ index 604335c..4aeb629 100644 -#include CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE - -#define CYW43_CLM_ADDR (fw_data + ALIGN_UINT(CYW43_WIFI_FW_LEN, 512)) - #define VERIFY_FIRMWARE_DOWNLOAD (0) - +- #define ALIGN_UINT(val, align) (((val) + (align) - 1) & ~((align) - 1)) -@@ -357,58 +350,31 @@ static void cyw43_write_backplane(cyw43_int_t *self, uint32_t addr, size_t size, - cyw43_set_backplane_window(self, CHIPCOMMON_BASE_ADDRESS); + + // Configure the padding needed for data sent to cyw43_write_bytes(). +@@ -101,18 +96,6 @@ static inline void cyw43_put_le32(uint8_t *buf, uint32_t x) { + buf[3] = x >> 24; } --static int cyw43_download_resource(cyw43_int_t *self, uint32_t addr, size_t raw_len, int from_storage, uintptr_t source) { -- // round up len to simplify download -- size_t len = (raw_len + 255) & ~255; +-#if CYW43_RESOURCE_VERIFY_DOWNLOAD +-static void cyw43_xxd(size_t len, const uint8_t *buf) { +- for (size_t i = 0; i < len; ++i) { +- CYW43_PRINTF(" %02x", buf[i]); +- if (i % 32 == 31) { +- CYW43_PRINTF("\n"); +- } +- } +- CYW43_PRINTF("\n"); +-} +-#endif - -- CYW43_VDEBUG("writing %lu bytes to 0x%lx\n", (uint32_t)len, (uint32_t)addr); + /*******************************************************************************/ + // CYW43 constants and types + +@@ -409,10 +392,6 @@ static int cyw43_check_valid_chipset_firmware(cyw43_int_t *self, size_t len, uin + } + + static int cyw43_download_resource(cyw43_int_t *self, uint32_t addr, size_t len, uintptr_t source) { +- // The calls to cyw43_write_bytes() (and cyw43_read_bytes()) require data sizes that +- // are aligned to a certain amount. +- assert(CYW43_WRITE_BYTES_PAD(len) == len); - -- uint32_t block_size = CYW43_BUS_MAX_BLOCK_SIZE; -- if (from_storage) { -- // reused the spid_buf to copy the data (must be larger than 512 storage block size) -- block_size = sizeof(self->spid_buf); -- CYW43_DEBUG("data comes from external storage via buffer of size %u\n", (unsigned int)block_size); -+static uint32_t storage_get_chunksize() -+{ -+ const uint32_t chunkTag = 0x4b4e4843; // "CHNK" -+ struct chunk_t { -+ uint32_t tag; -+ uint32_t length; -+ }; -+ struct chunk_t chunk; -+ int res = cyw43_storage_read(&chunk, sizeof(chunk)); -+ if (res != sizeof(chunk)) { -+ CYW43_WARN("Bad chunk header %d\n", res); -+ return 0; - } -+ if (chunk.tag != chunkTag) { -+ CYW43_WARN("Bad chunk tag %08x\n", chunk.tag); -+ return 0; -+ } -+ CYW43_DEBUG("Chunk %u bytes\n", chunk.length); -+ return chunk.length; -+} + CYW43_VDEBUG("writing %u bytes to 0x%x\n", (uint32_t)len, (uint32_t)addr); + + uint32_t block_size = CYW43_BUS_MAX_BLOCK_SIZE; +@@ -431,12 +410,18 @@ static int cyw43_download_resource(cyw43_int_t *self, uint32_t addr, size_t len, + uint32_t dest_addr = addr + offset; + assert(((dest_addr & BACKPLANE_ADDR_MASK) + sz) <= (BACKPLANE_ADDR_MASK + 1)); + cyw43_set_backplane_window(self, dest_addr); +- const uint8_t *src = (const uint8_t *)source + offset; ++ const uint8_t *src; ++ if (source) { ++ src = (const uint8_t *)source + offset; ++ } else { ++ cyw43_storage_read(self->spid_buf, sz); ++ src = self->spid_buf; ++ } + dest_addr &= BACKPLANE_ADDR_MASK; + #if CYW43_USE_SPI + dest_addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + #endif +- int ret = cyw43_write_bytes(self, BACKPLANE_FUNCTION, dest_addr, sz, src); ++ int ret = cyw43_write_bytes(self, BACKPLANE_FUNCTION, dest_addr, CYW43_WRITE_BYTES_PAD(sz), src); + if (ret != 0) { + + return CYW43_FAIL_FAST_CHECK(ret); +@@ -449,42 +434,6 @@ static int cyw43_download_resource(cyw43_int_t *self, uint32_t addr, size_t len, + CYW43_VDEBUG("done dnload; dt = %u us; speed = %u kbytes/sec\n", (unsigned int)dt, (unsigned int)(len * 1000 / dt)); + #endif -- if (addr == 0) { -- // check that firmware is actually there +- #if CYW43_RESOURCE_VERIFY_DOWNLOAD - -- // get the last bit of the firmware -- const uint8_t *b; -- uint32_t fw_end; -- if (from_storage) { -- // get the last aligned-1024 bytes -- uint32_t last_bl = (raw_len - 1) / CYW43_FLASH_BLOCK_SIZE; -- storage_read_blocks(self->spid_buf, source + last_bl - 1, 2); -- fw_end = raw_len - (last_bl - 1) * CYW43_FLASH_BLOCK_SIZE; -- b = self->spid_buf; -- } else { -- // get the last 800 bytes -- fw_end = 800; -- b = (const uint8_t *)source + raw_len - fw_end; -- } +- // Verification of 380k takes about 40ms using a 512-byte transfer size +- const size_t verify_block_size = CYW43_BUS_MAX_BLOCK_SIZE; +- uint8_t buf[verify_block_size]; - -- // get length of trailer -- fw_end -= 16; // skip DVID trailer -- uint32_t trail_len = b[fw_end - 2] | b[fw_end - 1] << 8; -- int found = -1; -- if (trail_len < 500 && b[fw_end - 3] == '\0') { -- for (int i = 80; i < (int)trail_len; ++i) { -- if (strncmp((const char *)&b[fw_end - 3 - i], "Version: ", 9) == 0) { -- found = i; -- break; -- } -- } -- } +- #if CYW43_VERBOSE_DEBUG +- t_start = cyw43_hal_ticks_us(); +- #endif - -- if (found == -1) { -- CYW43_WARN("could not find valid firmware\n"); +- for (size_t offset = 0; offset < len; offset += verify_block_size) { +- size_t sz = verify_block_size; +- if (offset + sz > len) { +- sz = len - offset; +- } +- uint32_t dest_addr = addr + offset; +- assert(((dest_addr & BACKPLANE_ADDR_MASK) + sz) <= (BACKPLANE_ADDR_MASK + 1)); +- cyw43_set_backplane_window(self, dest_addr); +- cyw43_read_bytes(self, BACKPLANE_FUNCTION, dest_addr & BACKPLANE_ADDR_MASK, sz, buf); +- const uint8_t *src = (const uint8_t *)source + offset; +- if (memcmp(buf, src, sz) != 0) { +- CYW43_WARN("fail verify at address 0x%08x:\n", (unsigned int)dest_addr); +- cyw43_xxd(sz, src); +- cyw43_xxd(sz, buf); - return CYW43_FAIL_FAST_CHECK(-CYW43_EIO); - } -+static int cyw43_download_resource(cyw43_int_t *self, uint32_t addr, size_t len, int from_storage, uintptr_t source) { -+ CYW43_VDEBUG("writing %lu bytes to 0x%lx\n", (uint32_t)len, (uint32_t)addr); - -- // print wifi firmware version info -- CYW43_DEBUG("%s\n", &b[fw_end - 3 - found]); - } -+ const uint32_t block_size = CYW43_BUS_MAX_BLOCK_SIZE; - - #if VERIFY_FIRMWARE_DOWNLOAD - uint32_t t_start = cyw43_hal_ticks_us(); -@@ -426,7 +392,7 @@ static int cyw43_download_resource(cyw43_int_t *self, uint32_t addr, size_t raw_ - cyw43_set_backplane_window(self, dest_addr); - const uint8_t *src; - if (from_storage) { -- storage_read_blocks(self->spid_buf, source + offset / CYW43_FLASH_BLOCK_SIZE, block_size / CYW43_FLASH_BLOCK_SIZE); -+ cyw43_storage_read(self->spid_buf, sz); - src = self->spid_buf; - } else { - src = (const uint8_t *)source + offset; -@@ -443,6 +409,10 @@ static int cyw43_download_resource(cyw43_int_t *self, uint32_t addr, size_t raw_ - } +- +- #if CYW43_VERBOSE_DEBUG +- t_end = cyw43_hal_ticks_us(); +- dt = t_end - t_start; +- CYW43_VDEBUG("done verify; dt = %u us; speed = %u kbytes/sec\n", (unsigned int)dt, (unsigned int)(len * 1000 / dt)); +- #endif +- +- #endif // CYW43_RESOURCE_VERIFY_DOWNLOAD +- + return 0; + } - #if VERIFY_FIRMWARE_DOWNLOAD -+ if(from_storage) { -+ cyw43_storage_cleanup(); -+ storage_get_chunksize(); -+ } - uint32_t t_end = cyw43_hal_ticks_us(); - uint32_t dt = t_end - t_start; - CYW43_VDEBUG("done dnload; dt = %u us; speed = %u kbytes/sec\n", (unsigned int)dt, (unsigned int)(len * 1000 / dt)); -@@ -464,7 +434,7 @@ static int cyw43_download_resource(cyw43_int_t *self, uint32_t addr, size_t raw_ - cyw43_read_bytes(self, BACKPLANE_FUNCTION, dest_addr & BACKPLANE_ADDR_MASK, sz, buf); - const uint8_t *src; - if (from_storage) { -- storage_read_blocks(self->spid_buf, source + offset / CYW43_FLASH_BLOCK_SIZE, verify_block_size / CYW43_FLASH_BLOCK_SIZE); -+ cyw43_storage_read(self->spid_buf, verify_block_size); - src = self->spid_buf; - } else { - src = (const uint8_t *)source + offset; -@@ -1372,8 +1342,8 @@ void cyw43_ll_bus_sleep(cyw43_ll_t *self_in, bool can_sleep) { +@@ -1374,7 +1323,7 @@ void cyw43_ll_bus_sleep(cyw43_ll_t *self_in, bool can_sleep) { #define CLM_CHUNK_LEN 1024 + 512 #endif -static void cyw43_clm_load(cyw43_int_t *self, const uint8_t *clm_ptr, size_t clm_len) { -- // Reuse spid_buf but be careful to start at the right offset in it +static void cyw43_clm_load(cyw43_int_t *self, size_t clm_len) { -+ // Reuse spid_buf but be careful to start at the right offset in i + // Reuse spid_buf but be careful to start at the right offset in it uint8_t *buf = &self->spid_buf[SDPCM_HEADER_LEN + 16]; - const size_t clm_dload_chunk_len = CLM_CHUNK_LEN; -@@ -1398,7 +1368,7 @@ static void cyw43_clm_load(cyw43_int_t *self, const uint8_t *clm_ptr, size_t clm +@@ -1400,7 +1349,7 @@ static void cyw43_clm_load(cyw43_int_t *self, const uint8_t *clm_ptr, size_t clm *(uint32_t *)(buf + 12) = len; *(uint32_t *)(buf + 16) = 0; #pragma GCC diagnostic pop - memcpy(buf + 20, clm_ptr + off, len); + cyw43_storage_read(buf + 20, len); - CYW43_VDEBUG("clm data send %lu/%zu\n", off + len, clm_len); + CYW43_VDEBUG("clm data send %u/%u\n", off + len, clm_len); -@@ -1654,12 +1624,9 @@ alp_set: +@@ -1656,14 +1605,11 @@ alp_set: cyw43_write_backplane(self, SOCSRAM_BANKX_INDEX, 4, 0x3); cyw43_write_backplane(self, SOCSRAM_BANKX_PDA, 4, 0); -- // Take firmware from the address space -- cyw43_download_resource(self, 0x00000000, CYW43_WIFI_FW_LEN, 0, fw_data); -- /* - // Take firmware from storage block device -- cyw43_download_resource(self, 0x00000000, CYW43_WIFI_FW_LEN, 1, 0x100 + 0x1000); -- */ +- // Check that valid chipset firmware exists at the given source address. +- int ret = cyw43_check_valid_chipset_firmware(self, CYW43_WIFI_FW_LEN, fw_data); +- if (ret != 0) { +- return ret; +- } ++ // Take firmware from storage block device + cyw43_storage_init(); -+ cyw43_download_resource(self, 0x00000000, storage_get_chunksize(), 1, 0); - size_t wifi_nvram_len = ALIGN_UINT(sizeof(wifi_nvram_4343), 64); - const uint8_t *wifi_nvram_data = wifi_nvram_4343; -@@ -1776,9 +1743,11 @@ f2_ready: + // Download the main WiFi firmware blob to the 43xx device. +- ret = cyw43_download_resource(self, 0x00000000, CYW43_WRITE_BYTES_PAD(CYW43_WIFI_FW_LEN), fw_data); ++ int ret = cyw43_download_resource(self, 0x00000000, cyw43_storage_get_chunksize(), 0); + if (ret != 0) { + return ret; + } +@@ -1784,9 +1730,11 @@ f2_ready: // Load the CLM data; it sits just after main firmware CYW43_VDEBUG("cyw43_clm_load start\n"); - cyw43_clm_load(self, (const uint8_t *)CYW43_CLM_ADDR, CYW43_CLM_LEN); -+ cyw43_clm_load(self, storage_get_chunksize()); ++ cyw43_clm_load(self, cyw43_storage_get_chunksize()); CYW43_VDEBUG("cyw43_clm_load done\n"); + cyw43_storage_cleanup(); @@ -203,18 +179,23 @@ index 604335c..4aeb629 100644 cyw43_write_iovar_u32(self, "bus:txglom", 0, WWD_STA_INTERFACE); // tx glomming off cyw43_write_iovar_u32(self, "apsta", 1, WWD_STA_INTERFACE); // apsta on -@@ -1882,6 +1851,10 @@ int cyw43_ll_wifi_on(cyw43_ll_t *self_in, uint32_t country) { +@@ -1890,10 +1838,14 @@ int cyw43_ll_wifi_on(cyw43_ll_t *self_in, uint32_t country) { cyw43_delay_ms(50); #ifndef NDEBUG + // Get and print firmware version + memcpy(buf, "ver\x00", 4); + cyw43_do_ioctl(self, SDPCM_GET, WLC_GET_VAR, 128, buf, WWD_STA_INTERFACE); -+ CYW43_DEBUG("%s", buf); ++ CYW43_DEBUG("CYW43 ver %s", buf); // Get and print CLM version memcpy(buf, "clmver\x00", 7); cyw43_do_ioctl(self, SDPCM_GET, WLC_GET_VAR, 128, buf, WWD_STA_INTERFACE); -@@ -1911,8 +1884,8 @@ int cyw43_ll_wifi_on(cyw43_ll_t *self_in, uint32_t country) { +- CYW43_DEBUG("%s\n", buf); ++ CYW43_DEBUG("CYW43 clmver %s\n", buf); + #endif + + // Set antenna to chip antenna +@@ -1919,8 +1871,8 @@ int cyw43_ll_wifi_on(cyw43_ll_t *self_in, uint32_t country) { CLR_EV(buf, 19); // roam attempt occurred CLR_EV(buf, 20); // tx fail CLR_EV(buf, 40); // radio @@ -225,7 +206,7 @@ index 604335c..4aeb629 100644 #undef CLR_EV memcpy(buf, "bsscfg:event_msgs", 18); diff --git a/src/cyw43_ll.h b/src/cyw43_ll.h -index 2750238..c281093 100644 +index b5c1ead..6e4ea30 100644 --- a/src/cyw43_ll.h +++ b/src/cyw43_ll.h @@ -67,15 +67,19 @@ @@ -248,12 +229,13 @@ index 2750238..c281093 100644 #define CYW43_EV_CSA_COMPLETE_IND (80) #define CYW43_EV_ASSOC_REQ_IE (87) #define CYW43_EV_ASSOC_RESP_IE (88) -@@ -318,6 +322,11 @@ uint32_t cyw43_ll_read_backplane_reg(cyw43_ll_t *self_in, uint32_t addr); +@@ -316,6 +320,12 @@ uint32_t cyw43_ll_read_backplane_reg(cyw43_ll_t *self_in, uint32_t addr); int cyw43_ll_write_backplane_mem(cyw43_ll_t *self_in, uint32_t addr, uint32_t len, const uint8_t *buf); int cyw43_ll_read_backplane_mem(cyw43_ll_t *self_in, uint32_t addr, uint32_t len, uint8_t *buf); +// Sming framework methods for accessing partition storage +int cyw43_storage_init(); ++uint32_t cyw43_storage_get_chunksize(); +uint32_t cyw43_storage_read(void *dest, uint32_t length); +void cyw43_storage_cleanup(void); + diff --git a/Sming/Arch/Rp2040/Components/rp2040/pico-sdk b/Sming/Arch/Rp2040/Components/rp2040/pico-sdk index 263a6680aa..95ea6acad1 160000 --- a/Sming/Arch/Rp2040/Components/rp2040/pico-sdk +++ b/Sming/Arch/Rp2040/Components/rp2040/pico-sdk @@ -1 +1 @@ -Subproject commit 263a6680aaf590b3c48f55645f30d1b96d168832 +Subproject commit 95ea6acad131124694cda1c162c52cd30e0aece0 diff --git a/Sming/Arch/Rp2040/Components/rp2040/pico-sdk.patch b/Sming/Arch/Rp2040/Components/rp2040/pico-sdk.patch index f559e5fb88..c9373bb0ad 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/pico-sdk.patch +++ b/Sming/Arch/Rp2040/Components/rp2040/pico-sdk.patch @@ -1,58 +1,26 @@ -diff --git a/src/common/pico_util/queue.c b/src/common/pico_util/queue.c -index a5c8e18..c3b8a91 100644 ---- a/src/common/pico_util/queue.c -+++ b/src/common/pico_util/queue.c -@@ -41,7 +41,7 @@ static inline uint16_t inc_index(queue_t *q, uint16_t index) { - return index; - } +diff --git a/src/rp2_common/pico_crt0/rp2040/memmap_default.ld b/src/rp2_common/pico_crt0/rp2040/memmap_default.ld +index 5125401..6ba0d2f 100644 +--- a/src/rp2_common/pico_crt0/rp2040/memmap_default.ld ++++ b/src/rp2_common/pico_crt0/rp2040/memmap_default.ld +@@ -255,7 +255,7 @@ SECTIONS --static bool queue_add_internal(queue_t *q, const void *data, bool block) { -+static bool __not_in_flash_func(queue_add_internal)(queue_t *q, const void *data, bool block) { - do { - uint32_t save = spin_lock_blocking(q->core.spin_lock); - if (queue_get_level_unsafe(q) != q->element_count) { -@@ -94,7 +94,7 @@ static bool queue_peek_internal(queue_t *q, void *data, bool block) { - } while (true); - } - --bool queue_try_add(queue_t *q, const void *data) { -+bool __not_in_flash_func(queue_try_add)(queue_t *q, const void *data) { - return queue_add_internal(q, data, false); - } - -diff --git a/src/rp2_common/hardware_base/include/hardware/address_mapped.h b/src/rp2_common/hardware_base/include/hardware/address_mapped.h -index 8e92d8b..da5feac 100644 ---- a/src/rp2_common/hardware_base/include/hardware/address_mapped.h -+++ b/src/rp2_common/hardware_base/include/hardware/address_mapped.h -@@ -105,12 +105,12 @@ __force_inline static uint32_t xip_alias_check_addr(const void *addr) { - #define xip_nocache_noalloc_alias_untyped(addr) ((void *)(XIP_NOCACHE_NOALLOC_BASE | xip_alias_check_addr(addr))) - - // Typed conversion alias pointer generation macros --#define hw_set_alias(p) ((typeof(p))hw_set_alias_untyped(p)) --#define hw_clear_alias(p) ((typeof(p))hw_clear_alias_untyped(p)) --#define hw_xor_alias(p) ((typeof(p))hw_xor_alias_untyped(p)) --#define xip_noalloc_alias(p) ((typeof(p))xip_noalloc_alias_untyped(p)) --#define xip_nocache_alias(p) ((typeof(p))xip_nocache_alias_untyped(p)) --#define xip_nocache_noalloc_alias(p) ((typeof(p))xip_nocache_noalloc_alias_untyped(p)) -+#define hw_set_alias(p) ((__typeof__(p))hw_set_alias_untyped(p)) -+#define hw_clear_alias(p) ((__typeof__(p))hw_clear_alias_untyped(p)) -+#define hw_xor_alias(p) ((__typeof__(p))hw_xor_alias_untyped(p)) -+#define xip_noalloc_alias(p) ((__typeof__(p))xip_noalloc_alias_untyped(p)) -+#define xip_nocache_alias(p) ((__typeof__(p))xip_nocache_alias_untyped(p)) -+#define xip_nocache_noalloc_alias(p) ((__typeof__(p))xip_nocache_noalloc_alias_untyped(p)) + .flash_end : { + KEEP(*(.embedded_end_block*)) +- PROVIDE(__flash_binary_end = .); ++ __flash_binary_end = .; + } > FLASH - /*! \brief Atomically set the specified bits to 1 in a HW register - * \ingroup hardware_base -diff --git a/src/rp2_common/pico_standard_link/memmap_default.ld b/src/rp2_common/pico_standard_link/memmap_default.ld -index e85b327..cf826c6 100644 ---- a/src/rp2_common/pico_standard_link/memmap_default.ld -+++ b/src/rp2_common/pico_standard_link/memmap_default.ld -@@ -231,7 +231,7 @@ SECTIONS - } > SCRATCH_Y + /* stack limit is poorly named, but historically is maximum heap ptr */ +diff --git a/src/rp2_common/pico_crt0/rp2350/memmap_default.ld b/src/rp2_common/pico_crt0/rp2350/memmap_default.ld +index bce316d..05c1beb 100644 +--- a/src/rp2_common/pico_crt0/rp2350/memmap_default.ld ++++ b/src/rp2_common/pico_crt0/rp2350/memmap_default.ld +@@ -269,7 +269,7 @@ SECTIONS .flash_end : { + KEEP(*(.embedded_end_block*)) - PROVIDE(__flash_binary_end = .); + __flash_binary_end = .; - } > FLASH + } > FLASH =0xaa /* stack limit is poorly named, but historically is maximum heap ptr */ diff --git a/Sming/Arch/Rp2040/Components/rp2040/sdk/CMakeLists.txt b/Sming/Arch/Rp2040/Components/rp2040/sdk/CMakeLists.txt index 7081f49973..80bfa74b9e 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/sdk/CMakeLists.txt +++ b/Sming/Arch/Rp2040/Components/rp2040/sdk/CMakeLists.txt @@ -1,7 +1,12 @@ cmake_minimum_required(VERSION 3.12) -set(PICO_PLATFORM "rp2040") -set(PICO_COMPILER "pico_arm_gcc") +if (PICO_VARIANT STREQUAL "rp2350") + set(PICO_COMPILER "pico_arm_cortex_m33_gcc") + set(PICO_PLATFORM "rp2350-arm-s") +else() + set(PICO_COMPILER "pico_arm_cortex_m0plus_gcc") + set(PICO_PLATFORM "rp2040") +endif() set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 17) @@ -19,6 +24,8 @@ set(SKIP_PICO_STDIO_UART 1) set(SKIP_PICO_STDIO_USB 1) set(SKIP_TINYUSB 1) +set(PICO_NO_PICOTOOL 1) + # Initialize the SDK pico_sdk_init() @@ -31,6 +38,7 @@ target_compile_definitions(pico PUBLIC PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64 PICO_DIVIDER_IN_RAM=1 PICO_MEM_IN_RAM=1 + PICO_CXX_DISABLE_ALLOCATION_OVERRIDES=1 ) pico_set_program_name(pico "Sming") @@ -40,7 +48,7 @@ include_directories(BEFORE ${pico_lib_SOURCE_DIR}) target_link_libraries(pico hardware_adc - hardware_base + hardware_boot_lock hardware_claim hardware_clocks hardware_divider @@ -63,15 +71,21 @@ target_link_libraries(pico hardware_vreg hardware_watchdog hardware_xosc + pico_aon_timer pico_bit_ops pico_divider pico_double pico_fix + pico_flash pico_float pico_int64_ops pico_mem_ops pico_multicore + pico_platform_compiler + pico_platform_panic + pico_platform_sections pico_runtime + pico_runtime_init pico_standard_link pico_unique_id pico_audio_i2s diff --git a/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_bit_ops.mk b/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_bit_ops.mk index a0ec0d43df..b25898865e 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_bit_ops.mk +++ b/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_bit_ops.mk @@ -1,5 +1,6 @@ # pico_bit_ops +ifeq ($(SMING_SOC),rp2040) WRAPPED_FUNCTIONS += \ __clzsi2 \ __clzdi2 \ @@ -7,3 +8,4 @@ WRAPPED_FUNCTIONS += \ __ctzdi2 \ __popcountsi2 \ __popcountdi2 +endif diff --git a/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_divider.mk b/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_divider.mk index 8578a4ccf2..a8f3244744 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_divider.mk +++ b/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_divider.mk @@ -1,5 +1,6 @@ # pico_divider +ifeq ($(SMING_SOC),rp2040) WRAPPED_FUNCTIONS += \ __aeabi_idiv \ __aeabi_idivmod \ @@ -7,3 +8,4 @@ WRAPPED_FUNCTIONS += \ __aeabi_uidiv \ __aeabi_uidivmod \ __aeabi_uldivmod +endif diff --git a/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_float.mk b/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_float.mk index e45345f639..ef47c520ad 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_float.mk +++ b/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_float.mk @@ -1,5 +1,6 @@ # pico_float +ifeq ($(SMING_SOC),rp2040) WRAPPED_FUNCTIONS += \ __aeabi_fadd \ __aeabi_fdiv \ @@ -24,7 +25,10 @@ WRAPPED_FUNCTIONS += \ __aeabi_f2uiz \ __aeabi_f2ulz \ __aeabi_f2d \ - sqrtf \ + sqrtf +endif + +WRAPPED_FUNCTIONS += \ cosf \ sinf \ tanf \ diff --git a/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_int64_ops.mk b/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_int64_ops.mk index 83f39e1492..ce6c395606 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_int64_ops.mk +++ b/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_int64_ops.mk @@ -1,4 +1,6 @@ # pico_int64_ops +ifeq ($(SMING_SOC),rp2040) WRAPPED_FUNCTIONS += \ __aeabi_lmul +endif diff --git a/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_mem_ops.mk b/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_mem_ops.mk index 6244c18b5d..9815650161 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_mem_ops.mk +++ b/Sming/Arch/Rp2040/Components/rp2040/sdk/pico_mem_ops.mk @@ -1,5 +1,6 @@ # pico_mem_ops +ifeq ($(SMING_SOC),rp2040) WRAPPED_FUNCTIONS += \ memcpy \ memset \ @@ -9,3 +10,4 @@ WRAPPED_FUNCTIONS += \ __aeabi_memset4 \ __aeabi_memcpy8 \ __aeabi_memset8 +endif diff --git a/Sming/Arch/Rp2040/Components/rp2040/src/clk.c b/Sming/Arch/Rp2040/Components/rp2040/src/clk.c index 6abc297851..2724fd0393 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/src/clk.c +++ b/Sming/Arch/Rp2040/Components/rp2040/src/clk.c @@ -25,38 +25,6 @@ uint32_t IRAM_ATTR esp_get_ccount() return ((1 + ovf) << 24) - systick_hw->cvr; } -/*! \brief Check if a given system clock frequency is valid/attainable - * \ingroup pico_stdlib - * - * \param freq_khz Requested frequency - * \param vco_freq_out On success, the voltage controller oscillator frequeucny to be used by the SYS PLL - * \param post_div1_out On success, The first post divider for the SYS PLL - * \param post_div2_out On success, The second post divider for the SYS PLL. - * @return true if the frequency is possible and the output parameters have been written. - */ -static bool check_sys_clock_khz(uint32_t freq_khz, uint* vco_out, uint* postdiv1_out, uint* postdiv_out) -{ - uint crystal_freq_khz = clock_get_hz(clk_ref) / 1000; - for(uint fbdiv = 320; fbdiv >= 16; fbdiv--) { - uint vco = fbdiv * crystal_freq_khz; - if(vco < 400000 || vco > 1600000) { - continue; - } - for(uint postdiv1 = 7; postdiv1 >= 1; postdiv1--) { - for(uint postdiv2 = postdiv1; postdiv2 >= 1; postdiv2--) { - uint out = vco / (postdiv1 * postdiv2); - if(out == freq_khz && (vco % (postdiv1 * postdiv2)) == 0) { - *vco_out = vco * 1000; - *postdiv1_out = postdiv1; - *postdiv_out = postdiv2; - return true; - } - } - } - } - return false; -} - // Fix the peripheral clocks but allow system (CPU) to be varied independently using PLL void system_init_clocks() { @@ -85,10 +53,17 @@ void system_init_clocks() // Initialise systick for use by esp_get_ccount() exception_set_exclusive_handler(SYSTICK_EXCEPTION, systick_overflow_isr); +#ifdef SOC_RP2350 + systick_hw->csr = (1 << M33_SYST_CSR_CLKSOURCE_LSB) // Processor CLK source + | M33_SYST_CSR_TICKINT_BITS // Enable overflow ISR + | M33_SYST_CSR_ENABLE_BITS; // ENABLE + systick_hw->rvr = M33_SYST_RVR_BITS; // Reload value when counter hits 0 +#else systick_hw->csr = (1 << M0PLUS_SYST_CSR_CLKSOURCE_LSB) // Processor CLK source | M0PLUS_SYST_CSR_TICKINT_BITS // Enable overflow ISR | M0PLUS_SYST_CSR_ENABLE_BITS; // ENABLE systick_hw->rvr = M0PLUS_SYST_RVR_BITS; // Reload value when counter hits 0 +#endif } bool system_update_cpu_freq(uint8_t mhz) diff --git a/Sming/Arch/Rp2040/Components/rp2040/src/startup.cpp b/Sming/Arch/Rp2040/Components/rp2040/src/startup.cpp index ab6e329416..77d50b6e13 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/src/startup.cpp +++ b/Sming/Arch/Rp2040/Components/rp2040/src/startup.cpp @@ -57,8 +57,14 @@ bool __noinline IRAM_ATTR get_bootsel_button() // } - // Read input (low when BOOTSEL pressed) - bool button_state = !(sio_hw->gpio_hi_in & BIT(CS_PIN_INDEX)); + // The HI GPIO registers in SIO can observe and control the 6 QSPI pins. + // Note the button pulls the pin *low* when pressed. +#ifdef SOC_RP2040 +#define CS_BIT (1u << 1) +#else +#define CS_BIT SIO_GPIO_HI_IN_QSPI_CSN_BITS +#endif + bool button_state = !(sio_hw->gpio_hi_in & CS_BIT); // Re-enable chip select hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, @@ -88,15 +94,11 @@ void check_bootsel() } // namespace -extern void system_init_rtc(); - extern "C" int main(void) { extern void system_init_clocks(); system_init_clocks(); - system_init_rtc(); - system_soft_wdt_restart(); // Initialise hardware timers diff --git a/Sming/Arch/Rp2040/Components/rp2040/src/wifi.cpp b/Sming/Arch/Rp2040/Components/rp2040/src/wifi.cpp index d048995da7..1615997c0f 100644 --- a/Sming/Arch/Rp2040/Components/rp2040/src/wifi.cpp +++ b/Sming/Arch/Rp2040/Components/rp2040/src/wifi.cpp @@ -122,6 +122,27 @@ uint32_t cyw43_storage_read(void* dest, uint32_t length) return length; } +uint32_t cyw43_storage_get_chunksize() +{ + const uint32_t chunkTag = 0x4b4e4843; // "CHNK" + struct chunk_t { + uint32_t tag; + uint32_t length; + }; + struct chunk_t chunk; + int res = cyw43_storage_read(&chunk, sizeof(chunk)); + if(res != sizeof(chunk)) { + debug_e("[CYW43] Bad chunk header %d\n", res); + return 0; + } + if(chunk.tag != chunkTag) { + debug_e("[CYW43] Bad chunk tag %08x\n", chunk.tag); + return 0; + } + debug_d("[CYW43] Chunk %u bytes\n", chunk.length); + return chunk.length; +} + void cyw43_storage_cleanup() { decompressor.reset(); diff --git a/Sming/Arch/Rp2040/Components/sming-arch/component.mk b/Sming/Arch/Rp2040/Components/sming-arch/component.mk index 95761ca116..1395bfdfa5 100644 --- a/Sming/Arch/Rp2040/Components/sming-arch/component.mk +++ b/Sming/Arch/Rp2040/Components/sming-arch/component.mk @@ -12,6 +12,7 @@ COMPONENT_DEPENDS := \ libc \ rp2040 \ uf2 \ + picotool \ driver \ gdbstub \ spi_flash diff --git a/Sming/Arch/Rp2040/Components/spi_flash/flashmem.cpp b/Sming/Arch/Rp2040/Components/spi_flash/flashmem.cpp index 36917e6ffa..fe25a3566a 100644 --- a/Sming/Arch/Rp2040/Components/spi_flash/flashmem.cpp +++ b/Sming/Arch/Rp2040/Components/spi_flash/flashmem.cpp @@ -13,9 +13,15 @@ #include #include #include +#include + +#ifdef SOC_RP2350 +#include +#include +#else #include #include -#include +#endif #define FLASHCMD_READ_SFDP 0x5a #define FLASHCMD_READ_JEDEC_ID 0x9f @@ -305,11 +311,33 @@ bool flashmem_erase_sector(flash_sector_t sector_id) return true; } +/* + DOUT/DUAL, ///< Two bits per clock for Data, 1-bit for Command and Address + DIO, ///< Two bits per clock for Address and Data, 1-bit for Command + QOUT/QUAD, ///< Four bits per clock for Data, 1-bit for Command and Address + QIO, ///< Four bits per clock for Address and Data, 1-bit for Command +*/ SPIFlashInfo flashmem_get_info() { SPIFlashInfo info{}; info.size = flashmem_get_size_type(); +#ifdef SOC_RP2350 + uint32_t rfmt = qmi_hw->m[0].rfmt; + auto data_width = (rfmt & QMI_M0_RFMT_DATA_WIDTH_BITS) >> QMI_M0_RFMT_DATA_WIDTH_LSB; + auto addr_width = (rfmt & QMI_M0_RFMT_ADDR_WIDTH_BITS) >> QMI_M0_RFMT_ADDR_WIDTH_LSB; + + switch(data_width) { + case 2: + info.mode = (addr_width == QMI_M0_RFMT_ADDR_WIDTH_VALUE_D) ? MODE_DIO : MODE_DOUT; + break; + case 4: + info.mode = (addr_width == QMI_M0_RFMT_ADDR_WIDTH_VALUE_Q) ? MODE_QIO : MODE_QOUT; + break; + default: + info.mode = MODE_SLOW_READ; + } +#else // Flash mode uint32_t ctrlr0 = ssi_hw->ctrlr0; auto ssi_frame_format = (ctrlr0 & SSI_CTRLR0_SPI_FRF_BITS) >> SSI_CTRLR0_SPI_FRF_LSB; @@ -326,6 +354,7 @@ SPIFlashInfo flashmem_get_info() default: info.mode = MODE_SLOW_READ; } +#endif return info; } @@ -376,11 +405,7 @@ uint32_t spi_flash_get_id(void) flash_addr_t flashmem_get_address(const void* memptr) { - auto addr = uint32_t(memptr); - if(addr < XIP_BASE || addr >= XIP_NOALLOC_BASE) { - return 0; - } - return addr - XIP_BASE; + return isFlashPtr(memptr) ? (uint32_t(memptr) - XIP_BASE) : 0; } void flashmem_sfdp_read(uint32_t addr, void* buffer, size_t count) diff --git a/Sming/Arch/Rp2040/Components/uf2/component.mk b/Sming/Arch/Rp2040/Components/uf2/component.mk index a2f33922a9..21d4d52ec4 100644 --- a/Sming/Arch/Rp2040/Components/uf2/component.mk +++ b/Sming/Arch/Rp2040/Components/uf2/component.mk @@ -8,6 +8,11 @@ COMPONENT_DOCFILES := \ DEBUG_VARS += UF2CONV_PY UF2CONV_PY := $(COMPONENT_PATH)/uf2conv.py +ifeq ($(SMING_SOC),rp2350) +UF2_FAMILY := "rp2xxx_absolute" +else +UF2_FAMILY := "rp2040" +endif # Invoke uf2conv utility # $1 -> Parameters @@ -17,19 +22,12 @@ else Uf2Conv = $(PYTHON) $(UF2CONV_PY) $(if $V,--verbose) $1 endif - -# Read flash manufacturer ID and determine actual size -define ReadFlashID - $(info Reading Flash ID) - $(call Uf2Conv,--list --verbose) -endef - # Write file contents to Flash # $1 -> List of `Offset=File` chunks define WriteFlash $(if $1,\ $(info WriteFlash $1) \ - $(call Uf2Conv,--upload $1 --output $(OUT_BASE)/flash.uf2) + $(call Uf2Conv,--family $(UF2_FAMILY) --upload $1 --output $(OUT_BASE)/flash.uf2) ) endef @@ -41,23 +39,3 @@ define VerifyFlash $(info ** NOT IMPLEMENTED **) ) endef - -# Read flash memory into file -# $1 -> `Offset,Size` chunk -# $2 -> Output filename -define ReadFlash - $(info ReadFlash $1,$2) - $(info ** NOT IMPLEMENTED **) -endef - -# Erase a region of Flash -# $1 -> Offset,Size -define EraseFlashRegion - $(info EraseFlashRegion $1) - $(info ** NOT IMPLEMENTED **) -endef - -# Erase flash memory contents -define EraseFlash - $(info ** NOT IMPLEMENTED **) -endef diff --git a/Sming/Arch/Rp2040/Components/uf2/uf2families.json b/Sming/Arch/Rp2040/Components/uf2/uf2families.json index 42b5bbc2a2..26812b97b8 100644 --- a/Sming/Arch/Rp2040/Components/uf2/uf2families.json +++ b/Sming/Arch/Rp2040/Components/uf2/uf2families.json @@ -34,6 +34,11 @@ "short_name": "STM32WL", "description": "ST STM32WLxx" }, + { + "id": "0x22e0d6fc", + "short_name": "RTL8710B", + "description": "Realtek AmebaZ RTL8710B" + }, { "id": "0x2abc77ec", "short_name": "LPC55", @@ -49,6 +54,11 @@ "short_name": "GD32F350", "description": "GD32F350" }, + { + "id": "0x3379CFE2", + "short_name": "RTL8720D", + "description": "Realtek AmebaD RTL8720D" + }, { "id": "0x04240bdf", "short_name": "STM32L5", @@ -64,6 +74,11 @@ "short_name": "MIMXRT10XX", "description": "NXP i.MX RT10XX" }, + { + "id": "0x51e903a8", + "short_name": "XR809", + "description": "Xradiotech 809" + }, { "id": "0x53b80f00", "short_name": "STM32F7", @@ -77,7 +92,7 @@ { "id": "0x57755a57", "short_name": "STM32F4", - "description": "ST STM32F401" + "description": "ST STM32F4xx" }, { "id": "0x5a18069b", @@ -94,16 +109,31 @@ "short_name": "STM32F1", "description": "ST STM32F103" }, + { + "id": "0x621e937a", + "short_name": "NRF52833", + "description": "Nordic NRF52833" + }, { "id": "0x647824b6", "short_name": "STM32F0", "description": "ST STM32F0xx" }, + { + "id": "0x675a40b0", + "short_name": "BK7231U", + "description": "Beken 7231U/7231T" + }, { "id": "0x68ed2b88", "short_name": "SAMD21", "description": "Microchip (Atmel) SAMD21" }, + { + "id": "0x6a82cc42", + "short_name": "BK7251", + "description": "Beken 7251/7252" + }, { "id": "0x6b846188", "short_name": "STM32F3", @@ -114,6 +144,11 @@ "short_name": "STM32F407", "description": "ST STM32F407" }, + { + "id": "0x4e8f1c5d", + "short_name": "STM32H5", + "description": "ST STM32H5xx" + }, { "id": "0x6db66082", "short_name": "STM32H7", @@ -124,6 +159,11 @@ "short_name": "STM32WB", "description": "ST STM32WBxx" }, + { + "id": "0x7b3ef230", + "short_name": "BK7231N", + "description": "Beken 7231N" + }, { "id": "0x7eab61ed", "short_name": "ESP8266", @@ -139,11 +179,21 @@ "short_name": "STM32F407VG", "description": "ST STM32F407VG" }, + { + "id": "0x9fffd543", + "short_name": "RTL8710A", + "description": "Realtek Ameba1 RTL8710A" + }, { "id": "0xada52840", "short_name": "NRF52840", "description": "Nordic NRF52840" }, + { + "id": "0x820d9a5f", + "short_name": "NRF52820", + "description": "Nordic NRF52820_xxAA" + }, { "id": "0xbfdd4eee", "short_name": "ESP32S2", @@ -159,14 +209,144 @@ "short_name": "ESP32C3", "description": "ESP32-C3" }, + { + "id": "0x2b88d29c", + "short_name": "ESP32C2", + "description": "ESP32-C2" + }, + { + "id": "0x332726f6", + "short_name": "ESP32H2", + "description": "ESP32-H2" + }, + { + "id": "0x540ddf62", + "short_name": "ESP32C6", + "description": "ESP32-C6" + }, + { + "id": "0x3d308e94", + "short_name": "ESP32P4", + "description": "ESP32-P4" + }, + { + "id": "0xf71c0343", + "short_name": "ESP32C5", + "description": "ESP32-C5" + }, + { + "id": "0x77d850c4", + "short_name": "ESP32C61", + "description": "ESP32-C61" + }, + { + "id": "0xde1270b7", + "short_name": "BL602", + "description": "Boufallo 602" + }, + { + "id": "0xe08f7564", + "short_name": "RTL8720C", + "description": "Realtek AmebaZ2 RTL8720C" + }, { "id": "0xe48bff56", "short_name": "RP2040", "description": "Raspberry Pi RP2040" }, + { + "id": "0xe48bff57", + "short_name": "RP2XXX_ABSOLUTE", + "description": "Raspberry Pi Microcontrollers: Absolute (unpartitioned) download" + }, + { + "id": "0xe48bff58", + "short_name": "RP2XXX_DATA", + "description": "Raspberry Pi Microcontrollers: Data partition download" + }, + { + "id": "0xe48bff59", + "short_name": "RP2350_ARM_S", + "description": "Raspberry Pi RP2350, Secure Arm image" + }, + { + "id": "0xe48bff5a", + "short_name": "RP2350_RISCV", + "description": "Raspberry Pi RP2350, RISC-V image" + }, + { + "id": "0xe48bff5b", + "short_name": "RP2350_ARM_NS", + "description": "Raspberry Pi RP2350, Non-secure Arm image" + }, { "id": "0x00ff6919", "short_name": "STM32L4", "description": "ST STM32L4xx" + }, + { + "id": "0x9af03e33", + "short_name": "GD32VF103", + "description": "GigaDevice GD32VF103" + }, + { + "id": "0x4f6ace52", + "short_name": "CSK4", + "description": "LISTENAI CSK300x/400x" + }, + { + "id": "0x6e7348a8", + "short_name": "CSK6", + "description": "LISTENAI CSK60xx" + }, + { + "id": "0x11de784a", + "short_name": "M0SENSE", + "description": "M0SENSE BL702" + }, + { + "id": "0x4b684d71", + "short_name": "MaixPlay-U4", + "description": "Sipeed MaixPlay-U4(BL618)" + }, + { + "id": "0x9517422f", + "short_name": "RZA1LU", + "description": "Renesas RZ/A1LU (R7S7210xx)" + }, + { + "id": "0x2dc309c5", + "short_name": "STM32F411xE", + "description": "ST STM32F411xE" + }, + { + "id": "0x06d1097b", + "short_name": "STM32F411xC", + "description": "ST STM32F411xC" + }, + { + "id": "0x72721d4e", + "short_name": "NRF52832xxAA", + "description": "Nordic NRF52832xxAA" + }, + { + "id": "0x6f752678", + "short_name": "NRF52832xxAB", + "description": "Nordic NRF52832xxAB" + }, + { + "id": "0xa0c97b8e", + "short_name": "AT32F415", + "description": "ArteryTek AT32F415" + }, + { + "id": "0x699b62ec", + "short_name": "CH32V", + "description": "WCH CH32V2xx and CH32V3xx" + }, + { + "id": "0x7be8976d", + "short_name": "RA4M1", + "description": "Renesas RA4M1" } -] \ No newline at end of file +] diff --git a/Sming/Arch/Rp2040/Platform/RTC.cpp b/Sming/Arch/Rp2040/Platform/RTC.cpp index 07a317b173..07c14c7ed8 100644 --- a/Sming/Arch/Rp2040/Platform/RTC.cpp +++ b/Sming/Arch/Rp2040/Platform/RTC.cpp @@ -9,66 +9,62 @@ ****/ #include -#include -#include #include - -extern "C" int settimeofday(const struct timeval*, const struct timezone*); +#include RtcClass RTC; -#define NS_PER_SECOND 1000000000 +#define NS_PER_SECOND 1'000'000'000 +#define US_PER_SECOND 1'000'000 + +RtcClass::RtcClass() = default; -void system_init_rtc() +namespace { - rtc_init(); - datetime_t t{.year = 1970, .month = 1, .day = 1}; - rtc_set_datetime(&t); +int64_t epoch_sys_time_us; } -RtcClass::RtcClass() = default; - -uint64_t RtcClass::getRtcNanoseconds() +extern "C" int _gettimeofday(struct timeval* tv, void*) { - return uint64_t(getRtcSeconds()) * NS_PER_SECOND; + if(tv) { + auto us_since_epoch = epoch_sys_time_us + time_us_64(); + *tv = { + .tv_sec = time_t(us_since_epoch / US_PER_SECOND), + .tv_usec = suseconds_t(us_since_epoch % US_PER_SECOND), + }; + } + return 0; } -uint32_t RtcClass::getRtcSeconds() +extern "C" int settimeofday(const struct timeval* tv, const struct timezone*) { - datetime_t t; - if(!rtc_get_datetime(&t)) { - return 0; + if(tv) { + auto us_since_epoch = tv->tv_sec * US_PER_SECOND + tv->tv_usec; + epoch_sys_time_us = us_since_epoch - time_us_64(); } + return 0; +} - DateTime dt; - dt.setTime(t.sec, t.min, t.hour, t.day, t.month - 1, t.year); +uint64_t RtcClass::getRtcNanoseconds() +{ + return uint64_t(epoch_sys_time_us + time_us_64()) * 1000ULL; +} - return time_t(dt); +uint32_t RtcClass::getRtcSeconds() +{ + return (epoch_sys_time_us + time_us_64()) / US_PER_SECOND; } bool RtcClass::setRtcNanoseconds(uint64_t nanoseconds) { - return setRtcSeconds(nanoseconds / NS_PER_SECOND); + auto us_since_epoch = nanoseconds / 1000; + epoch_sys_time_us = us_since_epoch - get_absolute_time(); + return true; } bool RtcClass::setRtcSeconds(uint32_t seconds) { - struct timeval tv { - seconds - }; - settimeofday(&tv, nullptr); - - DateTime dt{seconds}; - - datetime_t t = { - .year = int16_t(dt.Year), - .month = int8_t(1 + dt.Month), - .day = int8_t(dt.Day), - .dotw = int8_t(dt.DayofWeek), - .hour = int8_t(dt.Hour), - .min = int8_t(dt.Minute), - .sec = int8_t(dt.Second), - }; - - return rtc_set_datetime(&t); + auto us_since_epoch = int64_t(seconds) * US_PER_SECOND; + epoch_sys_time_us = us_since_epoch - time_us_64(); + return true; } diff --git a/Sming/Arch/Rp2040/README.rst b/Sming/Arch/Rp2040/README.rst index 3897680c39..de9dfe5a19 100644 --- a/Sming/Arch/Rp2040/README.rst +++ b/Sming/Arch/Rp2040/README.rst @@ -3,11 +3,13 @@ Sming RP2040 Architecture .. highlight:: bash -Support building Sming for the `Raspberry Pi RP2040 SOC -`__. +Support building Sming for the `Raspberry Pi Pico-series Microcontrollers `__. +At time of writing this includes both RP2040 and RP2350 devices. -Testing so far has been limited to the Rasperry Pi Pico, but there are lots of other boards available. -Configure this using the :envvar:`PICO_BOARD` setting. The default is ``pico`` (or ``pico_w`` if networking is enabled). +Testing has been limited to the Rasperry Pi Pico development boards, but there are lots of others available. +Configure this using the :envvar:`PICO_BOARD` setting. +The default is ``pico`` (or ``pico_w`` if networking is enabled). +Support for the new ``pico2`` boards is provided using :envvar:`SMING_SOC=rp2350 `. You can find the `full list here `__. Special mention to the arduino-pico project https://github.com/earlephilhower/arduino-pico. @@ -41,7 +43,8 @@ The following features are tested and working: - USB supported using the :library:`USB` library, both host and device modes. - HardwareSPI via :library:`HardwareSPI` for fully asynchronous SPI communications (host mode only). -Not yet implemented: +Limited or no support is provided for the following items. +In many cases best use of the hardware is made using the Pico SDK API directly. PWM Hardware can drive up to 16 outputs and measure input frequency/duty cycle. @@ -51,13 +54,14 @@ I2C RTC Can wake from deep sleep but requires an external clock (e.g. 32kHz crystal) and appropriate API. (Setting and reading the time is implemented.) + Note that the RP2350 does not have an RTC. Sming uses the Always-On timer api to support both devices. Low-power modes Deep sleep / suspend / power-saving PIO (Programmable I/O) - A killer feature for the RP2040. + A killer feature for the RP2 series. Uses range from simple glue logic to I2S, etc. Crash/exception handling & serial debugging - RP2040 supports JTAG debugging but requires extra hardware. + RP2 devices support JTAG debugging but requires extra hardware. Serial debugging is often enough and easier to set up. Requires GDB stub plus implementing crash handler callbacks, etc. Multi-boot / OTA updates. @@ -66,8 +70,13 @@ Multi-boot / OTA updates. Adding RP2040 support to rBoot may work, however the Pico typically has only 2MByte flash which is quite restrictive. It is also necessary to compile images at different addresses as there is no windowed XIP (eXecute In Place) capability. See :library:`FlashIP` library for a basic method of OTA. + Note that the Pico2 boards have 4MByte flash and partition table support which requires integrating with Sming. Bluetooth - The SDK supports this but has not yet been integrated into Sming. + The SDK supports bluetooth for the CYW43439 BT/WiFi SoC which the Pico-W boards (and other) use. + This has not yet been integrated into Sming. +RISCV (RP2350) + Sming builds ARM code but these devices also support RISCV. + This will require an additional toolchain and compile options. Installation @@ -144,10 +153,7 @@ Once the file has finished sending the RP2040 reboots itself into normal operati The RP2040 can also be programmed via JTAG debugging but this requires additional hardware and setup. -.. note:: - - The RP2040 bootloader does not include support for reading flash memory via mass storage, - so commands such as ``make verifyflash`` won't work at present. +Commands such as ``make readmap`` use :component-rp2040:`picotool` and require the device to be in BOOT mode. Dual-core support diff --git a/Sming/Arch/Rp2040/app.mk b/Sming/Arch/Rp2040/app.mk index 97bd3ab590..e1c19d9882 100644 --- a/Sming/Arch/Rp2040/app.mk +++ b/Sming/Arch/Rp2040/app.mk @@ -8,9 +8,19 @@ LDFLAGS += \ -Wl,--build-id=none \ --specs=nosys.specs \ - -mcpu=cortex-m0plus \ -mthumb +ifeq ($(SMING_SOC),rp2350) +LDFLAGS += \ + -mcpu=cortex-m33 \ + -march=armv8-m.main+fp+dsp \ + -mfloat-abi=softfp +else +LDFLAGS += \ + -mcpu=cortex-m0plus \ + -march=armv6-m +endif + ifneq ($(COMPILER_VERSION_MAJOR),10) LDFLAGS += -Wl,--no-warn-rwx-segments endif diff --git a/Sming/Arch/Rp2040/build.mk b/Sming/Arch/Rp2040/build.mk index d3ccb6622f..08d421e887 100644 --- a/Sming/Arch/Rp2040/build.mk +++ b/Sming/Arch/Rp2040/build.mk @@ -7,11 +7,27 @@ CPPFLAGS += \ -DARCH_RP2040 \ -DARDUINO_ARCH_RP2040 \ - -march=armv6-m \ - -mcpu=cortex-m0plus \ + -DPICO_NO_HARDWARE=0 \ + -DPICO_ON_DEVICE=1 \ + -DPICO_32BIT=1 \ -mthumb \ -nostdlib +ifeq ($(SMING_SOC),rp2350) +RP_VARIANT = rp2350 +CPPFLAGS += \ + -mcpu=cortex-m33 \ + -march=armv8-m.main+fp+dsp \ + -mfloat-abi=softfp \ + -mcmse \ + -DPICO_RP2350 +else +RP_VARIANT = rp2040 +CPPFLAGS += \ + -mcpu=cortex-m0plus \ + -DPICO_RP2040 +endif + CXXFLAGS += \ -fno-threadsafe-statics \ -fno-use-cxa-atexit diff --git a/Sming/Arch/Rp2040/rp2350-pindefs.txt b/Sming/Arch/Rp2040/rp2350-pindefs.txt new file mode 100644 index 0000000000..e8940b933e --- /dev/null +++ b/Sming/Arch/Rp2040/rp2350-pindefs.txt @@ -0,0 +1,52 @@ +[io_mux] +gpio f0 f1 f2 f3 f4 ff5 ff6 ff7 ff8 f9 f10 f11 notes +0 - SPI0_RX UART0_TX I2C0_SDA PWM0_A SIO PIO0 PIO1 PIO2 XIP_CS1n USB_OVCUR_DET - +1 - SPI0_CSn UART0_RX I2C0_SCL PWM0_B SIO PIO0 PIO1 PIO2 TRACECLK USB_VBUS_DET - +2 - SPI0_SCK UART0_CTS I2C1_SDA PWM1_A SIO PIO0 PIO1 PIO2 TRACEDATA0 USB_VBUS_EN UART0_TX +3 - SPI0_TX UART0_RTS I2C1_SCL PWM1_B SIO PIO0 PIO1 PIO2 TRACEDATA1 USB_OVCUR_DET UART0_RX +4 - SPI0_RX UART1_TX I2C0_SDA PWM2_A SIO PIO0 PIO1 PIO2 TRACEDATA2 USB_VBUS_DET - +5 - SPI0_CSn UART1_RX I2C0_SCL PWM2_B SIO PIO0 PIO1 PIO2 TRACEDATA3 USB_VBUS_EN - +6 - SPI0_SCK UART1_CTS I2C1_SDA PWM3_A SIO PIO0 PIO1 PIO2 - USB_OVCUR_DET UART1_TX +7 - SPI0_TX UART1_RTS I2C1_SCL PWM3_B SIO PIO0 PIO1 PIO2 - USB_VBUS_DET UART1_RX +8 - SPI1_RX UART1_TX I2C0_SDA PWM4_A SIO PIO0 PIO1 PIO2 XIP_CS1n USB_VBUS_EN - +9 - SPI1_CSn UART1_RX I2C0_SCL PWM4_B SIO PIO0 PIO1 PIO2 - USB_OVCUR_DET - +10 - SPI1_SCK UART1_CTS I2C1_SDA PWM5_A SIO PIO0 PIO1 PIO2 - USB_VBUS_DET UART1_TX +11 - SPI1_TX UART1_RTS I2C1_SCL PWM5_B SIO PIO0 PIO1 PIO2 - USB_VBUS_EN UART1_RX +12 HSTX SPI1_RX UART0_TX I2C0_SDA PWM6_A SIO PIO0 PIO1 PIO2 CLOCK_GPIN0 USB_OVCUR_DET - +13 HSTX SPI1_CSn UART0_RX I2C0_SCL PWM6_B SIO PIO0 PIO1 PIO2 CLOCK_GPOUT0 USB_VBUS_DET - +14 HSTX SPI1_SCK UART0_CTS I2C1_SDA PWM7_A SIO PIO0 PIO1 PIO2 CLOCK_GPIN1 USB_VBUS_EN UART0_TX +15 HSTX SPI1_TX UART0_RTS I2C1_SCL PWM7_B SIO PIO0 PIO1 PIO2 CLOCK_GPOUT1 USB_OVCUR_DET UART0_RX +16 HSTX SPI0_RX UART0_TX I2C0_SDA PWM0_A SIO PIO0 PIO1 PIO2 - USB_VBUS_DET - +17 HSTX SPI0_CSn UART0_RX I2C0_SCL PWM0_B SIO PIO0 PIO1 PIO2 - USB_VBUS_EN - +18 HSTX SPI0_SCK UART0_CTS I2C1_SDA PWM1_A SIO PIO0 PIO1 PIO2 - USB_OVCUR_DET UART0_TX +19 HSTX SPI0_TX UART0_RTS I2C1_SCL PWM1_B SIO PIO0 PIO1 PIO2 XIP_CS1n USB_VBUS_DET UART0_RX +20 - SPI0_RX UART1_TX I2C0_SDA PWM2_A SIO PIO0 PIO1 PIO2 CLOCK_GPIN0 USB_VBUS_EN - +21 - SPI0_CSn UART1_RX I2C0_SCL PWM2_B SIO PIO0 PIO1 PIO2 CLOCK_GPOUT0 USB_OVCUR_DET - +22 - SPI0_SCK UART1_CTS I2C1_SDA PWM3_A SIO PIO0 PIO1 PIO2 CLOCK_GPIN1 USB_VBUS_DET UART1_TX +23 - SPI0_TX UART1_RTS I2C1_SCL PWM3_B SIO PIO0 PIO1 PIO2 CLOCK_GPOUT1 USB_VBUS_EN UART1_RX +24 - SPI1_RX UART1_TX I2C0_SDA PWM4_A SIO PIO0 PIO1 PIO2 CLOCK_GPOUT2 USB_OVCUR_DET - +25 - SPI1_CSn UART1_RX I2C0_SCL PWM4_B SIO PIO0 PIO1 PIO2 CLOCK_GPOUT3 USB_VBUS_DET - +26 - SPI1_SCK UART1_CTS I2C1_SDA PWM5_A SIO PIO0 PIO1 PIO2 - USB_VBUS_EN UART1_TX +27 - SPI1_TX UART1_RTS I2C1_SCL PWM5_B SIO PIO0 PIO1 PIO2 - USB_OVCUR_DET UART1_RX +28 - SPI1_RX UART0_TX I2C0_SDA PWM6_A SIO PIO0 PIO1 PIO2 - USB_VBUS_DET - +29 - SPI1_CSn UART0_RX I2C0_SCL PWM6_B SIO PIO0 PIO1 PIO2 - USB_VBUS_EN - + +# IOs 30 through 47 are QFN-80 only +30 - SPI1_SCK UART0_CTS I2C1_SDA PWM7_A SIO PIO0 PIO1 PIO2 - USB_OVCUR_DET UART0_TX +31 - SPI1_TX UART0_RTS I2C1_SCL PWM7_B SIO PIO0 PIO1 PIO2 - USB_VBUS_DET UART0_RX +32 - SPI0_RX UART0_TX I2C0_SDA PWM8_A SIO PIO0 PIO1 PIO2 - USB_VBUS_EN - +33 - SPI0_CSn UART0_RX I2C0_SCL PWM8_B SIO PIO0 PIO1 PIO2 - USB_OVCUR_DET - +34 - SPI0_SCK UART0_CTS I2C1_SDA PWM9_A SIO PIO0 PIO1 PIO2 - USB_VBUS_DET UART0_TX +35 - SPI0_TX UART0_RTS I2C1_SCL PWM9_B SIO PIO0 PIO1 PIO2 - USB_VBUS_EN UART0_RX +36 - SPI0_RX UART1_TX I2C0_SDA PWM10_A SIO PIO0 PIO1 PIO2 - USB_OVCUR_DET - +37 - SPI0_CSn UART1_RX I2C0_SCL PWM10_B SIO PIO0 PIO1 PIO2 - USB_VBUS_DET - +38 - SPI0_SCK UART1_CTS I2C1_SDA PWM11_A SIO PIO0 PIO1 PIO2 - USB_VBUS_EN UART1_TX +39 - SPI0_TX UART1_RTS I2C1_SCL PWM11_B SIO PIO0 PIO1 PIO2 - USB_OVCUR_DET UART1_RX +40 - SPI1_RX UART1_TX I2C0_SDA PWM8_A SIO PIO0 PIO1 PIO2 - USB_VBUS_DET - +41 - SPI1_CSn UART1_RX I2C0_SCL PWM8_B SIO PIO0 PIO1 PIO2 - USB_VBUS_EN - +42 - SPI1_SCK UART1_CTS I2C1_SDA PWM9_A SIO PIO0 PIO1 PIO2 - USB_OVCUR_DET UART1_TX +43 - SPI1_TX UART1_RTS I2C1_SCL PWM9_B SIO PIO0 PIO1 PIO2 - USB_VBUS_DET UART1_RX +44 - SPI1_RX UART0_TX I2C0_SDA PWM10_A SIO PIO0 PIO1 PIO2 - USB_VBUS_EN - +45 - SPI1_CSn UART0_RX I2C0_SCL PWM10_B SIO PIO0 PIO1 PIO2 - USB_OVCUR_DET - +46 - SPI1_SCK UART0_CTS I2C1_SDA PWM11_A SIO PIO0 PIO1 PIO2 - USB_VBUS_DET UART0_TX +47 - SPI1_TX UART0_RTS I2C1_SCL PWM11_B SIO PIO0 PIO1 PIO2 XIP_CS1n USB_VBUS_EN UART0_RX diff --git a/Sming/Arch/Rp2040/rp2350-soc.json b/Sming/Arch/Rp2040/rp2350-soc.json new file mode 100644 index 0000000000..bbd9c6cfe8 --- /dev/null +++ b/Sming/Arch/Rp2040/rp2350-soc.json @@ -0,0 +1,62 @@ +{ + "variant": "rp2350", + "name": "RP2350", + "peripherals": { + "CLOCK": { + "sigmask": "{name}.+" + }, + "SPI[0-1]": { + "sigmask": "{name}.+" + }, + "UART0": { + "sigmask": "{name}.+", + "default": { + "TXD": [ + "UART0_TX", + 0 + ], + "RXD": [ + "UART0_RX", + 1 + ] + } + }, + "UART1": { + "sigmask": "{name}.+", + "default": { + "TXD": [ + "UART1_TX", + 4 + ], + "RXD": [ + "UART1_RX", + 5 + ] + } + }, + "I2C[0-1]": { + "sigmask": "{name}.+" + }, + "PIO[0-2]": { + "sigmask": "{name}.+" + }, + "PWM[0-9]": { + "sigmask": "{name}.+" + }, + "SIO": { + "sigmask": "{name}.+" + }, + "USB": { + "sigmask": "{name}.+" + }, + "HSTX": { + "sigmask": "{name}" + }, + "XIP": { + "sigmask": "{name}.+" + }, + "TRACE": { + "sigmask": "{name}.+" + } + } +} \ No newline at end of file diff --git a/Sming/Components/malloc_count/component.mk b/Sming/Components/malloc_count/component.mk index 5579848cd1..abc46923f8 100644 --- a/Sming/Components/malloc_count/component.mk +++ b/Sming/Components/malloc_count/component.mk @@ -21,7 +21,6 @@ MC_WRAP_FUNCS := \ strdup ifeq ($(SMING_ARCH),Esp8266) MC_WRAP_FUNCS += \ - realloc \ pvPortMalloc \ pvPortCalloc \ pvPortRealloc \ diff --git a/Sming/Components/malloc_count/malloc_count.cpp b/Sming/Components/malloc_count/malloc_count.cpp index d886933dee..5f50e85b0a 100644 --- a/Sming/Components/malloc_count/malloc_count.cpp +++ b/Sming/Components/malloc_count/malloc_count.cpp @@ -378,7 +378,7 @@ extern "C" void* WRAP(pvPortZalloc)(size_t) __attribute__((alias("mc_zalloc"))); extern "C" void* WRAP(pvPortZallocIram)(size_t) __attribute__((alias("mc_zalloc"))); extern "C" void WRAP(vPortFree)(void*) __attribute__((alias("mc_free"))); -#else +#elif !defined(ARCH_RP2040) void* operator new(size_t size) { diff --git a/Sming/Libraries/USB b/Sming/Libraries/USB index df65917eb6..0717652a30 160000 --- a/Sming/Libraries/USB +++ b/Sming/Libraries/USB @@ -1 +1 @@ -Subproject commit df65917eb6b796dbf1137f93ac0190d777403a7c +Subproject commit 0717652a3095a3091d5bb56ed683474b2d72f0bf diff --git a/Tools/ci/scanlog.py b/Tools/ci/scanlog.py index 73821602b8..bdd196320a 100644 --- a/Tools/ci/scanlog.py +++ b/Tools/ci/scanlog.py @@ -327,7 +327,6 @@ def get_args(cmd: str): def print_diff(log1: Log, log2: Log): for job1 in log1.jobs: - job_printed = False try: job2 = next(job for job in log2.jobs if job.name == job1.name) except StopIteration: @@ -364,9 +363,7 @@ def print_diff(log1: Log, log2: Log): data[name] = f'{v2-v1:+}' diff_table.append(data) - if not job_printed: - print(f'{job1.name}:') - job_printed = True + print(f'{job1.name}: {target}') print_table(diff_table) if table2.rows: diff --git a/samples/Basic_IFS/app/application.cpp b/samples/Basic_IFS/app/application.cpp index 7f8b01064f..8602249330 100644 --- a/samples/Basic_IFS/app/application.cpp +++ b/samples/Basic_IFS/app/application.cpp @@ -284,7 +284,7 @@ bool initFileSystem() for(auto part : unit.partitions()) { Serial << part << endl; } - auto part = *unit.partitions().begin(); + auto part = Storage::findDefaultPartition(Storage::Partition::SubType::Data::fat); auto fatfs = IFS::createFatFilesystem(part); if(fatfs && fatfs->mount() == FS_OK) { getFileSystem()->setVolume(3, fatfs); diff --git a/samples/Basic_IFS/basic_ifs_Rp2040.hw b/samples/Basic_IFS/basic_ifs_Rp2040.hw index 004bc45534..53b0f9bde0 100644 --- a/samples/Basic_IFS/basic_ifs_Rp2040.hw +++ b/samples/Basic_IFS/basic_ifs_Rp2040.hw @@ -8,7 +8,7 @@ ], "partitions": { "rom0": { - "size": "320K" + "size": "428K" }, "lfs1": { "size": "932K",