From c68a57aa34250533a428bc0a3714692085451582 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Mon, 8 Mar 2021 12:23:44 -0600 Subject: [PATCH 01/19] start 1.1.1 patch branch --- pico_sdk_version.cmake | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pico_sdk_version.cmake b/pico_sdk_version.cmake index 86ba043..9bea169 100644 --- a/pico_sdk_version.cmake +++ b/pico_sdk_version.cmake @@ -6,7 +6,15 @@ set(PICO_SDK_VERSION_MAJOR 1) set(PICO_SDK_VERSION_MINOR 1) # PICO_BUILD_DEFINE: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, pico_base # PICO_CONFIG: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, pico_base -set(PICO_SDK_VERSION_REVISION 0) +set(PICO_SDK_VERSION_REVISION 1) +# PICO_BUILD_DEFINE: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, pico_base +# PICO_CONFIG: PICO_SDK_VERSION_PRE_RELEASE_ID, SDK version revision, type=string, pico_base +set(PICO_SDK_VERSION_PRE_RELEASE_ID develop) + # PICO_BUILD_DEFINE: PICO_SDK_VERSION_STRING, SDK version, type=string, group=pico_base # PICO_CONFIG: PICO_SDK_VERSION_STRING, SDK version, type=string, group=pico_base set(PICO_SDK_VERSION_STRING "${PICO_SDK_VERSION_MAJOR}.${PICO_SDK_VERSION_MINOR}.${PICO_SDK_VERSION_REVISION}") + +if (PICO_SDK_VERSION_PRE_RELEASE_ID) + set(PICO_SDK_VERSION_STRING "${PICO_SDK_VERSION_STRING}-${PICO_SDK_VERSION_PRE_RELEASE_ID}") +endif() \ No newline at end of file From c4e35d914d628ff9d17abdb73566c75b664aa89c Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Mon, 8 Mar 2021 15:12:07 -0600 Subject: [PATCH 02/19] build: fix mismatched config descriptions --- pico_sdk_version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico_sdk_version.cmake b/pico_sdk_version.cmake index 9bea169..5cbdd8f 100644 --- a/pico_sdk_version.cmake +++ b/pico_sdk_version.cmake @@ -8,7 +8,7 @@ set(PICO_SDK_VERSION_MINOR 1) # PICO_CONFIG: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, pico_base set(PICO_SDK_VERSION_REVISION 1) # PICO_BUILD_DEFINE: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, pico_base -# PICO_CONFIG: PICO_SDK_VERSION_PRE_RELEASE_ID, SDK version revision, type=string, pico_base +# PICO_CONFIG: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, pico_base set(PICO_SDK_VERSION_PRE_RELEASE_ID develop) # PICO_BUILD_DEFINE: PICO_SDK_VERSION_STRING, SDK version, type=string, group=pico_base From d36b1ca8aec854f822c7df1619dd7c45d83b4127 Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Wed, 10 Mar 2021 12:04:04 -0600 Subject: [PATCH 03/19] hardware_timer: fix race condition whem a new timer being added becomes missed thus obviating the need for an IRQ but there is an IRQ already pending for another timer (#243) --- src/rp2_common/hardware_timer/timer.c | 27 ++++++++++++++-------- test/pico_time_test/pico_time_test.c | 32 ++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/rp2_common/hardware_timer/timer.c b/src/rp2_common/hardware_timer/timer.c index 7745484..23bea05 100644 --- a/src/rp2_common/hardware_timer/timer.c +++ b/src/rp2_common/hardware_timer/timer.c @@ -166,8 +166,9 @@ bool hardware_alarm_set_target(uint alarm_num, absolute_time_t target) { // 1) actually set the hardware timer spin_lock_t *lock = spin_lock_instance(PICO_SPINLOCK_ID_TIMER); uint32_t save = spin_lock_blocking(lock); - timer_hw->intr = 1u << alarm_num; + uint8_t old_timer_callbacks_pending = timer_callbacks_pending; timer_callbacks_pending |= (uint8_t)(1u << alarm_num); + timer_hw->intr = 1u << alarm_num; // clear any IRQ timer_hw->alarm[alarm_num] = (uint32_t) t; // Set the alarm. Writing time should arm it target_hi[alarm_num] = (uint32_t)(t >> 32u); @@ -178,18 +179,26 @@ bool hardware_alarm_set_target(uint alarm_num, absolute_time_t target) { assert(timer_hw->ints & 1u << alarm_num); } else { if (time_us_64() >= t) { - // ok well it is time now; the irq isn't being handled yet because of the spin lock - // however the other core might be in the IRQ handler itself about to do a callback - // we do the firing ourselves (and indicate to the IRQ handler if any that it shouldn't + // we are already at or past the right time; there is no point in us racing against the IRQ + // we are about to generate. note however that, if there was already a timer pending before, + // then we still let the IRQ fire, as whatever it was, is not handled by our setting missed=true here missed = true; - // disarm the timer - timer_hw->armed = 1u << alarm_num; - timer_hw->intr = 1u << alarm_num; // clear the IRQ too - // and set flag in case we're already in the IRQ handler waiting on the spinlock (on the other core) - timer_callbacks_pending &= (uint8_t)~(1u << alarm_num); + if (timer_callbacks_pending != old_timer_callbacks_pending) { + // disarm the timer + timer_hw->armed = 1u << alarm_num; + // clear the IRQ... + timer_hw->intr = 1u << alarm_num; + // ... including anything pending on the processor - perhaps unnecessary, but + // our timer flag says we aren't expecting anything. + irq_clear(harware_alarm_irq_number(alarm_num)); + // and clear our flag so that if the IRQ handler is already active (because it is on + // the other core) it will also skip doing anything + timer_callbacks_pending = old_timer_callbacks_pending; + } } } spin_unlock(lock, save); + // note at this point any pending timer IRQ can likely run } return missed; } diff --git a/test/pico_time_test/pico_time_test.c b/test/pico_time_test/pico_time_test.c index 1093dd6..2209fd5 100644 --- a/test/pico_time_test/pico_time_test.c +++ b/test/pico_time_test/pico_time_test.c @@ -64,12 +64,13 @@ static bool repeating_timer_callback(struct repeating_timer *t) { #define RESOLUTION_ALLOWANCE PICO_HARDWARE_TIMER_RESOLUTION_US #endif +int issue_195_test(void); + int main() { setup_default_uart(); alarm_pool_init_default(); PICOTEST_START(); - struct alarm_pool *pools[NUM_TIMERS]; for(uint i=0; i 0, "near the end of time should be before the end of time") PICOTEST_END_SECTION(); + if (issue_195_test()) { + return -1; + } + PICOTEST_END_TEST(); } +#define ISSUE_195_TIMER_DELAY 50 +volatile int issue_195_counter; +int64_t issue_195_callback(alarm_id_t id, void *user_data) { + issue_195_counter++; + return -ISSUE_195_TIMER_DELAY; +} + +int issue_195_test(void) { + PICOTEST_START_SECTION("Issue #195 race condition - without fix may hang on gcc 10.2.1 release builds"); + absolute_time_t t1 = get_absolute_time(); + int id = add_alarm_in_us(ISSUE_195_TIMER_DELAY, issue_195_callback, NULL, true); + for(uint i=0;i<5000;i++) { + sleep_us(100); + sleep_us(100); + uint delay = 9; // 9 seems to be the magic number (at least for reproducing on 10.2.1) + sleep_us(delay); + } + absolute_time_t t2 = get_absolute_time(); + cancel_alarm(id); + int expected_count = absolute_time_diff_us(t1, t2) / ISSUE_195_TIMER_DELAY; + printf("Timer fires approx_expected=%d actual=%d\n", expected_count, issue_195_counter); + PICOTEST_END_SECTION(); + return 0; +} + From fe3408b28662fb9f63179078ee809c00983a7dcd Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Wed, 17 Mar 2021 13:05:48 -0500 Subject: [PATCH 04/19] Small fixes (#260) * pico_stdio_usb: be more explicit about includes, fix warning (#257) * pico_base: NDEBUG backwards for absolute_time_t (#255) * pico_util: missing extern C in queue.h (#249) * build: remove -march which was masking -mcpu, now SVC available (#253) --- cmake/preload/toolchains/pico_arm_gcc.cmake | 5 +++-- src/common/pico_base/include/pico/types.h | 8 ++++---- src/common/pico_util/include/pico/util/queue.h | 9 ++++++++- src/rp2_common/pico_stdio_usb/reset_interface.c | 2 +- src/rp2_common/pico_stdio_usb/stdio_usb.c | 3 ++- test/kitchen_sink/kitchen_sink.c | 3 +++ 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/cmake/preload/toolchains/pico_arm_gcc.cmake b/cmake/preload/toolchains/pico_arm_gcc.cmake index 4fc0950..b0c2648 100644 --- a/cmake/preload/toolchains/pico_arm_gcc.cmake +++ b/cmake/preload/toolchains/pico_arm_gcc.cmake @@ -52,8 +52,9 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) option(PICO_DEOPTIMIZED_DEBUG "Build debug builds with -O0" 0) # todo move to platform/Generix-xxx -set(ARM_GCC_COMMON_FLAGS " -march=armv6-m -mcpu=cortex-m0plus -mthumb") -#set(ARM_GCC_COMMON_FLAGS " -mcpu=cortex-m0plus -mthumb") + +# on ARM -mcpu should not be mixed with -march +set(ARM_GCC_COMMON_FLAGS " -mcpu=cortex-m0plus -mthumb") foreach(LANG IN ITEMS C CXX ASM) set(CMAKE_${LANG}_FLAGS_INIT "${ARM_GCC_COMMON_FLAGS}") if (PICO_DEOPTIMIZED_DEBUG) diff --git a/src/common/pico_base/include/pico/types.h b/src/common/pico_base/include/pico/types.h index 51debf2..6b8e66f 100644 --- a/src/common/pico_base/include/pico/types.h +++ b/src/common/pico_base/include/pico/types.h @@ -25,7 +25,7 @@ typedef unsigned int uint; \see update_us_since_boot() \ingroup timestamp */ -#ifndef NDEBUG +#ifdef NDEBUG typedef uint64_t absolute_time_t; #else typedef struct { @@ -40,7 +40,7 @@ typedef struct { * \ingroup timestamp */ static inline uint64_t to_us_since_boot(absolute_time_t t) { -#ifndef NDEBUG +#ifdef NDEBUG return t; #else return t._private_us_since_boot; @@ -55,7 +55,7 @@ static inline uint64_t to_us_since_boot(absolute_time_t t) { * \ingroup timestamp */ static inline void update_us_since_boot(absolute_time_t *t, uint64_t us_since_boot) { -#ifndef NDEBUG +#ifdef NDEBUG *t = us_since_boot; #else assert(us_since_boot <= INT64_MAX); @@ -63,7 +63,7 @@ static inline void update_us_since_boot(absolute_time_t *t, uint64_t us_since_bo #endif } -#ifndef NDEBUG +#ifdef NDEBUG #define ABSOLUTE_TIME_INITIALIZED_VAR(name, value) name = value #else #define ABSOLUTE_TIME_INITIALIZED_VAR(name, value) name = {value} diff --git a/src/common/pico_util/include/pico/util/queue.h b/src/common/pico_util/include/pico/util/queue.h index 8281d8b..60a450a 100644 --- a/src/common/pico_util/include/pico/util/queue.h +++ b/src/common/pico_util/include/pico/util/queue.h @@ -18,6 +18,10 @@ * \ingroup pico_util */ +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { spin_lock_t *lock; uint8_t *data; @@ -69,7 +73,7 @@ void queue_free(queue_t *q); static inline uint queue_get_level_unsafe(queue_t *q) { int32_t rc = (int32_t)q->wptr - (int32_t)q->rptr; if (rc < 0) { - rc += + q->element_count + 1; + rc += q->element_count + 1; } return (uint)rc; } @@ -181,4 +185,7 @@ void queue_remove_blocking(queue_t *q, void *data); */ void queue_peek_blocking(queue_t *q, void *data); +#ifdef __cplusplus +} +#endif #endif diff --git a/src/rp2_common/pico_stdio_usb/reset_interface.c b/src/rp2_common/pico_stdio_usb/reset_interface.c index 2525486..1232857 100644 --- a/src/rp2_common/pico_stdio_usb/reset_interface.c +++ b/src/rp2_common/pico_stdio_usb/reset_interface.c @@ -60,7 +60,7 @@ static bool resetd_control_request_cb(uint8_t __unused rhport, tusb_control_requ #if PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT if (request->bRequest == RESET_REQUEST_FLASH) { - watchdog_reboot(0, SRAM_END, PICO_STDIO_USB_RESET_RESET_TO_FLASH_DELAY_MS); + watchdog_reboot(0, 0, PICO_STDIO_USB_RESET_RESET_TO_FLASH_DELAY_MS); return true; } #endif diff --git a/src/rp2_common/pico_stdio_usb/stdio_usb.c b/src/rp2_common/pico_stdio_usb/stdio_usb.c index c122b44..d86879f 100644 --- a/src/rp2_common/pico_stdio_usb/stdio_usb.c +++ b/src/rp2_common/pico_stdio_usb/stdio_usb.c @@ -10,12 +10,13 @@ #include "pico/time.h" #include "pico/stdio/driver.h" #include "pico/binary_info.h" +#include "pico/mutex.h" #include "hardware/irq.h" static_assert(PICO_STDIO_USB_LOW_PRIORITY_IRQ > RTC_IRQ, ""); // note RTC_IRQ is currently the last one static mutex_t stdio_usb_mutex; -static void low_priority_worker_irq() { +static void low_priority_worker_irq(void) { // if the mutex is already owned, then we are in user code // in this file which will do a tud_task itself, so we'll just do nothing // until the next tick; we won't starve diff --git a/test/kitchen_sink/kitchen_sink.c b/test/kitchen_sink/kitchen_sink.c index 7c19b1e..033df3d 100644 --- a/test/kitchen_sink/kitchen_sink.c +++ b/test/kitchen_sink/kitchen_sink.c @@ -83,6 +83,7 @@ int main(void) { dma_channel_configure(0, &config, &dma_to, &dma_from, 1, true); dma_channel_set_config(0, &config, false); + // note this loop expects to cause a breakpoint!! for (int i = 0; i < 20; i++) { puts("sleepy"); sleep_ms(1000); @@ -94,4 +95,6 @@ int main(void) { irq_remove_handler(DMA_IRQ_1, dma_handler_b); } } + // this should compile as we are Cortex M0+ + __asm volatile("SVC #3"); } From f6d32f87a1effd1e5ddac40eb8b12d58164888c3 Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Thu, 18 Mar 2021 19:41:40 +0000 Subject: [PATCH 05/19] Fix typo in sparkfun_micromod.h (#268) --- src/boards/include/boards/sparkfun_micromod.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boards/include/boards/sparkfun_micromod.h b/src/boards/include/boards/sparkfun_micromod.h index 52dcaeb..973a9e1 100644 --- a/src/boards/include/boards/sparkfun_micromod.h +++ b/src/boards/include/boards/sparkfun_micromod.h @@ -19,7 +19,7 @@ #ifndef PICO_DEFAULT_UART #define PICO_DEFAULT_UART 0 -#define +#endif #ifndef PICO_DEFAULT_UART_TX_PIN #define PICO_DEFAULT_UART_TX_PIN 0 From 304ab7dd92fedde6241daf2abaf22cf1af852bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Thu, 18 Mar 2021 20:02:21 +0000 Subject: [PATCH 06/19] Fix loading of PICO_TOOLCHAIN_PATH (#262) - Add double quotes because build option it's a string. - Remove comment as requested by @kilograham. - Resolves #258. --- cmake/pico_pre_load_toolchain.cmake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/pico_pre_load_toolchain.cmake b/cmake/pico_pre_load_toolchain.cmake index 9fc933d..6c01357 100644 --- a/cmake/pico_pre_load_toolchain.cmake +++ b/cmake/pico_pre_load_toolchain.cmake @@ -1,6 +1,5 @@ # PICO_CMAKE_CONFIG: PICO_TOOLCHAIN_PATH, Path to search for compiler, default=none (i.e. search system paths), group=build -# Set your compiler path here if it's not in the PATH environment variable. -set(PICO_TOOLCHAIN_PATH "" CACHE INTERNAL "") +set(PICO_TOOLCHAIN_PATH "${PICO_TOOLCHAIN_PATH}" CACHE INTERNAL "") # Set a default build type if none was specified set(default_build_type "Release") From f76567eb7f00f8c0bd459030b631128780fb454d Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Fri, 19 Mar 2021 14:11:42 +0000 Subject: [PATCH 07/19] Merge pico_sdk_version.cmake changes from develop branch into develop-1.1.1 branch --- pico_sdk_version.cmake | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pico_sdk_version.cmake b/pico_sdk_version.cmake index 5cbdd8f..9f2aa61 100644 --- a/pico_sdk_version.cmake +++ b/pico_sdk_version.cmake @@ -1,14 +1,14 @@ -# PICO_BUILD_DEFINE: PICO_SDK_VERSION_MAJOR, SDK major version number, type=int, pico_base -# PICO_CONFIG: PICO_SDK_VERSION_MAJOR, SDK major version number, type=int, pico_base +# PICO_BUILD_DEFINE: PICO_SDK_VERSION_MAJOR, SDK major version number, type=int, group=pico_base +# PICO_CONFIG: PICO_SDK_VERSION_MAJOR, SDK major version number, type=int, group=pico_base set(PICO_SDK_VERSION_MAJOR 1) -# PICO_BUILD_DEFINE: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, pico_base -# PICO_CONFIG: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, pico_base +# PICO_BUILD_DEFINE: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, group=pico_base +# PICO_CONFIG: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, group=pico_base set(PICO_SDK_VERSION_MINOR 1) -# PICO_BUILD_DEFINE: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, pico_base -# PICO_CONFIG: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, pico_base +# PICO_BUILD_DEFINE: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, group=pico_base +# PICO_CONFIG: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, group=pico_base set(PICO_SDK_VERSION_REVISION 1) -# PICO_BUILD_DEFINE: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, pico_base -# PICO_CONFIG: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, pico_base +# PICO_BUILD_DEFINE: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, group=pico_base +# PICO_CONFIG: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, group=pico_base set(PICO_SDK_VERSION_PRE_RELEASE_ID develop) # PICO_BUILD_DEFINE: PICO_SDK_VERSION_STRING, SDK version, type=string, group=pico_base @@ -17,4 +17,4 @@ set(PICO_SDK_VERSION_STRING "${PICO_SDK_VERSION_MAJOR}.${PICO_SDK_VERSION_MINOR} if (PICO_SDK_VERSION_PRE_RELEASE_ID) set(PICO_SDK_VERSION_STRING "${PICO_SDK_VERSION_STRING}-${PICO_SDK_VERSION_PRE_RELEASE_ID}") -endif() \ No newline at end of file +endif() From e9a521a9b1ecc66f4e90c3b40cd9625dea57583d Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 21 Mar 2021 13:23:24 -0500 Subject: [PATCH 08/19] rtc_get_datetime: read the rtc registers just once each In order for the returned value to accurately reflect a single moment in time, ensure the registers are read just once and in the datasheet order. Before this change, the RTC registers would each be read multiple times, leading (infrequently) to the returned fields not all reflecting the same moment in time. The rp2040 datasheet has what I believe is an incorrect example (embedding the source of this function); will the datasheet be updated if this function is fixed? This problem is only a speculative one; I did not actually observe it in the wild. --- src/rp2_common/hardware_rtc/rtc.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/rp2_common/hardware_rtc/rtc.c b/src/rp2_common/hardware_rtc/rtc.c index 813b5f1..5429acd 100644 --- a/src/rp2_common/hardware_rtc/rtc.c +++ b/src/rp2_common/hardware_rtc/rtc.c @@ -92,13 +92,16 @@ bool rtc_get_datetime(datetime_t *t) { } // Note: RTC_0 should be read before RTC_1 - t->dotw = (rtc_hw->rtc_0 & RTC_RTC_0_DOTW_BITS ) >> RTC_RTC_0_DOTW_LSB; - t->hour = (rtc_hw->rtc_0 & RTC_RTC_0_HOUR_BITS ) >> RTC_RTC_0_HOUR_LSB; - t->min = (rtc_hw->rtc_0 & RTC_RTC_0_MIN_BITS ) >> RTC_RTC_0_MIN_LSB; - t->sec = (rtc_hw->rtc_0 & RTC_RTC_0_SEC_BITS ) >> RTC_RTC_0_SEC_LSB; - t->year = (rtc_hw->rtc_1 & RTC_RTC_1_YEAR_BITS ) >> RTC_RTC_1_YEAR_LSB; - t->month = (rtc_hw->rtc_1 & RTC_RTC_1_MONTH_BITS) >> RTC_RTC_1_MONTH_LSB; - t->day = (rtc_hw->rtc_1 & RTC_RTC_1_DAY_BITS ) >> RTC_RTC_1_DAY_LSB; + uint32_t rtc_0 = rtc_hw->rtc_0; + uint32_t rtc_1 = rtc_hw->rtc_1; + + t->dotw = (rtc_0 & RTC_RTC_0_DOTW_BITS ) >> RTC_RTC_0_DOTW_LSB; + t->hour = (rtc_0 & RTC_RTC_0_HOUR_BITS ) >> RTC_RTC_0_HOUR_LSB; + t->min = (rtc_0 & RTC_RTC_0_MIN_BITS ) >> RTC_RTC_0_MIN_LSB; + t->sec = (rtc_0 & RTC_RTC_0_SEC_BITS ) >> RTC_RTC_0_SEC_LSB; + t->year = (rtc_1 & RTC_RTC_1_YEAR_BITS ) >> RTC_RTC_1_YEAR_LSB; + t->month = (rtc_1 & RTC_RTC_1_MONTH_BITS) >> RTC_RTC_1_MONTH_LSB; + t->day = (rtc_1 & RTC_RTC_1_DAY_BITS ) >> RTC_RTC_1_DAY_LSB; return true; } @@ -185,4 +188,4 @@ void rtc_disable_alarm(void) { while(rtc_hw->irq_setup_0 & RTC_IRQ_SETUP_0_MATCH_ACTIVE_BITS) { tight_loop_contents(); } -} \ No newline at end of file +} From 1d4588a565026ffa599e3221faad9df4c9122632 Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Wed, 24 Mar 2021 14:15:36 +0000 Subject: [PATCH 09/19] Board-header typos (#270) --- src/boards/include/boards/pimoroni_keybow2040.h | 2 +- src/boards/include/boards/vgaboard.h | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/boards/include/boards/pimoroni_keybow2040.h b/src/boards/include/boards/pimoroni_keybow2040.h index 46c5134..eeab409 100644 --- a/src/boards/include/boards/pimoroni_keybow2040.h +++ b/src/boards/include/boards/pimoroni_keybow2040.h @@ -107,7 +107,7 @@ #define KEYBOW2040_SW15_PIN 6 #endif -#ifndef KEYBOW2040_NUM_SWITCHES +#ifndef KEYBOW2040_NUM_SWITCHES_PINS #define KEYBOW2040_NUM_SWITCHES_PINS 16 #endif diff --git a/src/boards/include/boards/vgaboard.h b/src/boards/include/boards/vgaboard.h index b03eaa7..d9cb7ac 100644 --- a/src/boards/include/boards/vgaboard.h +++ b/src/boards/include/boards/vgaboard.h @@ -26,8 +26,8 @@ #define VGABOARD_VGA_COLOR_PIN_BASE 0 #define VGABOARD_VGA_SYNC_PIN_BASE 16 -// Note DAT2/3 are shared with UART TX/RX (pull jumpers off header to access -// UART pins and disconnect SD DAT2/3) +// Note DAT1/2 are shared with UART TX/RX (pull jumpers off header to access +// UART pins and disconnect SD DAT1/2) #define VGABOARD_SD_CLK_PIN 5 #define VGABOARD_SD_CMD_PIN 18 #define VGABOARD_SD_DAT0_PIN 19 @@ -57,10 +57,12 @@ #define PICO_SD_CMD_PIN VGABOARD_SD_CMD_PIN #define PICO_SD_DAT0_PIN VGABOARD_SD_DAT0_PIN +// 1 or 4 #ifndef PICO_SD_DAT_PIN_COUNT #define PICO_SD_DAT_PIN_COUNT 4 #endif +// 1 or -1 #define PICO_SD_DAT_PIN_INCREMENT 1 #define PICO_AUDIO_I2S_DATA_PIN VGABOARD_I2S_DIN_PIN From a47d6d6e14d4cd5d135606cf839c47340eaddfdc Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Wed, 24 Mar 2021 14:26:54 +0000 Subject: [PATCH 10/19] Allow heap end to be equal to stack limit (#266) --- src/rp2_common/pico_runtime/runtime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rp2_common/pico_runtime/runtime.c b/src/rp2_common/pico_runtime/runtime.c index 796284e..2340ba7 100644 --- a/src/rp2_common/pico_runtime/runtime.c +++ b/src/rp2_common/pico_runtime/runtime.c @@ -175,9 +175,9 @@ void *_sbrk(int incr) { prev_heap_end = heap_end; char *next_heap_end = heap_end + incr; - if (__builtin_expect(next_heap_end >= (&__StackLimit), false)) { + if (__builtin_expect(next_heap_end > (&__StackLimit), false)) { #if PICO_USE_OPTIMISTIC_SBRK - if (next_heap_end == &__StackLimit) { + if (heap_end == &__StackLimit) { // errno = ENOMEM; return (char *) -1; } From 0c941d9767572abcf757da91221f4737e3e39af0 Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Wed, 24 Mar 2021 14:32:38 +0000 Subject: [PATCH 11/19] Tweaks to PIO clkdiv-setting code (#254) - refactor to reduce duplication - add extra param-validation --- .../hardware_pio/include/hardware/pio.h | 88 ++++++++++--------- 1 file changed, 48 insertions(+), 40 deletions(-) diff --git a/src/rp2_common/hardware_pio/include/hardware/pio.h b/src/rp2_common/hardware_pio/include/hardware/pio.h index 2478495..36194b8 100644 --- a/src/rp2_common/hardware_pio/include/hardware/pio.h +++ b/src/rp2_common/hardware_pio/include/hardware/pio.h @@ -196,29 +196,6 @@ static inline void sm_config_set_sideset(pio_sm_config *c, uint bit_count, bool (bool_to_bit(pindirs) << PIO_SM0_EXECCTRL_SIDE_PINDIR_LSB); } -/*! \brief Set the state machine clock divider (from a floating point value) in a state machine configuration - * \ingroup sm_config - * - * The clock divider slows the state machine's execution by masking the - * system clock on some cycles, in a repeating pattern, so that the state - * machine does not advance. Effectively this produces a slower clock for the - * state machine to run from, which can be used to generate e.g. a particular - * UART baud rate. See the datasheet for further detail. - * - * \param c Pointer to the configuration structure to modify - * \param div The fractional divisor to be set. 1 for full speed. An integer clock divisor of n - * will cause the state machine to run 1 cycle in every n. - * Note that for small n, the jitter introduced by a fractional divider (e.g. 2.5) may be unacceptable - * although it will depend on the use case. - */ -static inline void sm_config_set_clkdiv(pio_sm_config *c, float div) { - uint div_int = (uint)div; - uint div_frac = (uint)((div - (float)div_int) * (1u << 8u)); - c->clkdiv = - (div_frac << PIO_SM0_CLKDIV_FRAC_LSB) | - (div_int << PIO_SM0_CLKDIV_INT_LSB); -} - /*! \brief Set the state machine clock divider (from integer and fractional parts - 16:8) in a state machine configuration * \ingroup sm_config * @@ -238,6 +215,38 @@ static inline void sm_config_set_clkdiv_int_frac(pio_sm_config *c, uint16_t div_ (((uint)div_int) << PIO_SM0_CLKDIV_INT_LSB); } +static inline void pio_calculate_clkdiv_from_float(float div, uint16_t *div_int, uint8_t *div_frac) { + valid_params_if(PIO, div >= 1 && div <= 65536); + *div_int = (uint16_t)div; + if (*div_int == 0) { + *div_frac = 0; + } else { + *div_frac = (uint8_t)((div - (float)*div_int) * (1u << 8u)); + } +} + +/*! \brief Set the state machine clock divider (from a floating point value) in a state machine configuration + * \ingroup sm_config + * + * The clock divider slows the state machine's execution by masking the + * system clock on some cycles, in a repeating pattern, so that the state + * machine does not advance. Effectively this produces a slower clock for the + * state machine to run from, which can be used to generate e.g. a particular + * UART baud rate. See the datasheet for further detail. + * + * \param c Pointer to the configuration structure to modify + * \param div The fractional divisor to be set. 1 for full speed. An integer clock divisor of n + * will cause the state machine to run 1 cycle in every n. + * Note that for small n, the jitter introduced by a fractional divider (e.g. 2.5) may be unacceptable + * although it will depend on the use case. + */ +static inline void sm_config_set_clkdiv(pio_sm_config *c, float div) { + uint16_t div_int; + uint8_t div_frac; + pio_calculate_clkdiv_from_float(div, &div_int, &div_frac); + sm_config_set_clkdiv_int_frac(c, div_int, div_frac); +} + /*! \brief Set the wrap addresses in a state machine configuration * \ingroup sm_config * @@ -978,23 +987,6 @@ static inline uint32_t pio_sm_get_blocking(PIO pio, uint sm) { */ void pio_sm_drain_tx_fifo(PIO pio, uint sm); -/*! \brief set the current clock divider for a state machine - * \ingroup hardware_pio - * - * \param pio The PIO instance; either \ref pio0 or \ref pio1 - * \param sm State machine index (0..3) - * \param div the floating point clock divider - */ -static inline void pio_sm_set_clkdiv(PIO pio, uint sm, float div) { - check_pio_param(pio); - check_sm_param(sm); - uint div_int = (uint16_t) div; - uint div_frac = (uint8_t) ((div - (float)div_int) * (1u << 8u)); - pio->sm[sm].clkdiv = - (div_frac << PIO_SM0_CLKDIV_FRAC_LSB) | - (div_int << PIO_SM0_CLKDIV_INT_LSB); -} - /*! \brief set the current clock divider for a state machine using a 16:8 fraction * \ingroup hardware_pio * @@ -1011,6 +1003,22 @@ static inline void pio_sm_set_clkdiv_int_frac(PIO pio, uint sm, uint16_t div_int (((uint)div_int) << PIO_SM0_CLKDIV_INT_LSB); } +/*! \brief set the current clock divider for a state machine + * \ingroup hardware_pio + * + * \param pio The PIO instance; either \ref pio0 or \ref pio1 + * \param sm State machine index (0..3) + * \param div the floating point clock divider + */ +static inline void pio_sm_set_clkdiv(PIO pio, uint sm, float div) { + check_pio_param(pio); + check_sm_param(sm); + uint16_t div_int; + uint8_t div_frac; + pio_calculate_clkdiv_from_float(div, &div_int, &div_frac); + pio_sm_set_clkdiv_int_frac(pio, sm, div_int, div_frac); +} + /*! \brief Clear a state machine's TX and RX FIFOs * \ingroup hardware_pio * From c1f164b9fdc6008afcc65295facafd3271a23e95 Mon Sep 17 00:00:00 2001 From: Tom Wasiluk Date: Wed, 24 Mar 2021 15:35:02 +0100 Subject: [PATCH 12/19] corrected clk_gpout3 to gpio pin 25 as per the rp2040 datasheet (#250) --- src/rp2_common/hardware_clocks/clocks.c | 2 +- src/rp2_common/hardware_clocks/include/hardware/clocks.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rp2_common/hardware_clocks/clocks.c b/src/rp2_common/hardware_clocks/clocks.c index 848e878..ac11680 100644 --- a/src/rp2_common/hardware_clocks/clocks.c +++ b/src/rp2_common/hardware_clocks/clocks.c @@ -322,7 +322,7 @@ void clock_gpio_init(uint gpio, uint src, uint div) { if (gpio == 21) gpclk = clk_gpout0; else if (gpio == 23) gpclk = clk_gpout1; else if (gpio == 24) gpclk = clk_gpout2; - else if (gpio == 26) gpclk = clk_gpout3; + else if (gpio == 25) gpclk = clk_gpout3; else { invalid_params_if(CLOCKS, true); } diff --git a/src/rp2_common/hardware_clocks/include/hardware/clocks.h b/src/rp2_common/hardware_clocks/include/hardware/clocks.h index 297dfa2..04d373d 100644 --- a/src/rp2_common/hardware_clocks/include/hardware/clocks.h +++ b/src/rp2_common/hardware_clocks/include/hardware/clocks.h @@ -170,7 +170,7 @@ void clocks_enable_resus(resus_callback_t resus_callback); /*! \brief Output an optionally divided clock to the specified gpio pin. * \ingroup hardware_clocks * - * \param gpio The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 26. These GPIOs are connected to the GPOUT0-3 clock generators. + * \param gpio The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators. * \param src The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator. * \param div The amount to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. */ From 85ac3d7cf867e81a3489a87584db4776292c4960 Mon Sep 17 00:00:00 2001 From: Andrew Scheller Date: Mon, 29 Mar 2021 17:37:50 +0100 Subject: [PATCH 13/19] I2C doxygen typos (#287) * I2C doxygen typos * another typo --- src/rp2_common/hardware_i2c/include/hardware/i2c.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rp2_common/hardware_i2c/include/hardware/i2c.h b/src/rp2_common/hardware_i2c/include/hardware/i2c.h index dd2cfbe..c049937 100644 --- a/src/rp2_common/hardware_i2c/include/hardware/i2c.h +++ b/src/rp2_common/hardware_i2c/include/hardware/i2c.h @@ -279,7 +279,7 @@ static inline size_t i2c_get_read_available(i2c_inst_t *i2c) { * \param src Data to send * \param len Number of bytes to send * - * Writes directly to the to I2C TX FIFO which us mainly useful for + * Writes directly to the I2C TX FIFO which is mainly useful for * slave-mode operation. */ static inline void i2c_write_raw_blocking(i2c_inst_t *i2c, const uint8_t *src, size_t len) { @@ -291,14 +291,14 @@ static inline void i2c_write_raw_blocking(i2c_inst_t *i2c, const uint8_t *src, s } } -/*! \brief Write direct to TX FIFO +/*! \brief Read direct from RX FIFO * \ingroup hardware_i2c * * \param i2c Either \ref i2c0 or \ref i2c1 * \param dst Buffer to accept data - * \param len Number of bytes to send + * \param len Number of bytes to read * - * Reads directly from the I2C RX FIFO which us mainly useful for + * Reads directly from the I2C RX FIFO which is mainly useful for * slave-mode operation. */ static inline void i2c_read_raw_blocking(i2c_inst_t *i2c, uint8_t *dst, size_t len) { From 859d1d27b8b6c67c291001da67de950f996b81af Mon Sep 17 00:00:00 2001 From: Liam Fraser Date: Tue, 30 Mar 2021 15:03:28 +0100 Subject: [PATCH 14/19] Don't advertise REMOTE_WAKEUP for USB stdio as it is is not currently implemented. Longer term need to implement REMOTE_WAKUP properly in TinyUSB. Similar fix needed in MicroPython to fix MicroPython issue #6866. The symptom is that USB serial will stop working if there is a delay of > 2 seconds ish between messages. We have seen this issue on Linux laptops with USB autosuspend enabled. (#289) --- src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c b/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c index c66df42..622a1fc 100644 --- a/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c +++ b/src/rp2_common/pico_stdio_usb/stdio_usb_descriptors.c @@ -88,7 +88,7 @@ static const tusb_desc_device_t usbd_desc_device = { static const uint8_t usbd_desc_cfg[USBD_DESC_LEN] = { TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_0, USBD_DESC_LEN, - TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA), + 0, USBD_MAX_POWER_MA), TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD, USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE), From 260128a725c53947b31a933bba1f0c1be8cc9f06 Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Thu, 1 Apr 2021 15:03:04 -0500 Subject: [PATCH 15/19] fixup elf2uf2 to allow blocked_ram (flash) binaries (#294) --- src/host/CMakeLists.txt | 7 +++++++ tools/elf2uf2/main.cpp | 17 ++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/host/CMakeLists.txt b/src/host/CMakeLists.txt index 5679005..13a73ad 100644 --- a/src/host/CMakeLists.txt +++ b/src/host/CMakeLists.txt @@ -14,12 +14,19 @@ pico_add_subdirectory(pico_stdlib) pico_add_doxygen(${CMAKE_CURRENT_LIST_DIR}) macro(pico_set_float_implementation TARGET IMPL) + # ignore endmacro() macro(pico_set_double_implementation TARGET IMPL) + # ignore +endmacro() + +macro(pico_set_binary_type TARGET IMPL) + # ignore endmacro() macro(pico_set_boot_stage2 TARGET IMPL) + # ignore endmacro() set(PICO_HOST_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "") diff --git a/tools/elf2uf2/main.cpp b/tools/elf2uf2/main.cpp index 07cd107..b66f082 100644 --- a/tools/elf2uf2/main.cpp +++ b/tools/elf2uf2/main.cpp @@ -59,16 +59,19 @@ struct address_range { typedef std::vector address_ranges; -#define MAIN_RAM_START 0x20000000u -#define MAIN_RAM_END 0x20042000u -#define FLASH_START 0x10000000u -#define FLASH_END 0x15000000u -#define XIP_SRAM_START 0x15000000u -#define XIP_SRAM_END 0x15004000u +#define MAIN_RAM_START 0x20000000u +#define MAIN_RAM_END 0x20042000u +#define FLASH_START 0x10000000u +#define FLASH_END 0x15000000u +#define XIP_SRAM_START 0x15000000u +#define XIP_SRAM_END 0x15004000u +#define MAIN_RAM_BANKED_START 0x21000000u +#define MAIN_RAM_BANKED_END 0x21040000u const address_ranges rp2040_address_ranges_flash { address_range(FLASH_START, FLASH_END, address_range::type::CONTENTS), - address_range(MAIN_RAM_START, MAIN_RAM_END, address_range::type::NO_CONTENTS) + address_range(MAIN_RAM_START, MAIN_RAM_END, address_range::type::NO_CONTENTS), + address_range(MAIN_RAM_BANKED_START, MAIN_RAM_BANKED_END, address_range::type::NO_CONTENTS) }; const address_ranges rp2040_address_ranges_ram { From 7f2f186bcc9a7723312bf9a1cce3303389a80e5b Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Thu, 1 Apr 2021 16:42:53 -0500 Subject: [PATCH 16/19] build: allow board config header to specify bootstage 2 without using custom per board cmake (#293) * build: allow compile time - and hence via board config header - choice of boot stage2 via a default compile_time_choice.S boot stage 2 which conditionally includes others adafruit_rp2040_feather: fix flash size/clkdiv * fixup GENERIC_03H #define names --- .../include/boards/adafruit_feather_rp2040.h | 8 +++- .../boards/adafruit_itsybitsy_rp2040.h | 3 ++ .../include/boards/adafruit_qtpy_rp2040.h | 3 ++ src/boards/include/boards/pico.h | 2 + .../include/boards/pimoroni_keybow2040.h | 2 + .../include/boards/pimoroni_picosystem.h | 2 + src/boards/include/boards/pimoroni_tiny2040.h | 2 + src/boards/include/boards/sparkfun_micromod.h | 2 + src/boards/include/boards/sparkfun_promicro.h | 2 + .../include/boards/sparkfun_thingplus.h | 3 ++ src/rp2_common/boot_stage2/CMakeLists.txt | 42 ++++++++++++++----- .../boot_stage2/compile_time_choice.S | 29 +++++++++++++ .../boot_stage2/include/boot_stage2/config.h | 38 +++++++++++++++++ .../pico_standard_link/CMakeLists.txt | 2 +- .../pico_standard_link/binary_info.c | 7 ++-- 15 files changed, 131 insertions(+), 16 deletions(-) create mode 100644 src/rp2_common/boot_stage2/compile_time_choice.S create mode 100644 src/rp2_common/boot_stage2/include/boot_stage2/config.h diff --git a/src/boards/include/boards/adafruit_feather_rp2040.h b/src/boards/include/boards/adafruit_feather_rp2040.h index 631c52d..a27f9a3 100644 --- a/src/boards/include/boards/adafruit_feather_rp2040.h +++ b/src/boards/include/boards/adafruit_feather_rp2040.h @@ -68,12 +68,16 @@ #endif //------------- FLASH -------------// + +// Use slower generic flash access +#define PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H 1 + #ifndef PICO_FLASH_SPI_CLKDIV -#define PICO_FLASH_SPI_CLKDIV 2 +#define PICO_FLASH_SPI_CLKDIV 4 #endif #ifndef PICO_FLASH_SIZE_BYTES -#define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) +#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024) #endif // All boards have B1 RP2040 diff --git a/src/boards/include/boards/adafruit_itsybitsy_rp2040.h b/src/boards/include/boards/adafruit_itsybitsy_rp2040.h index 55015c6..dd29d64 100644 --- a/src/boards/include/boards/adafruit_itsybitsy_rp2040.h +++ b/src/boards/include/boards/adafruit_itsybitsy_rp2040.h @@ -72,6 +72,9 @@ #endif //------------- FLASH -------------// + +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif diff --git a/src/boards/include/boards/adafruit_qtpy_rp2040.h b/src/boards/include/boards/adafruit_qtpy_rp2040.h index cfe68ab..570fb3d 100644 --- a/src/boards/include/boards/adafruit_qtpy_rp2040.h +++ b/src/boards/include/boards/adafruit_qtpy_rp2040.h @@ -71,6 +71,9 @@ #endif //------------- FLASH -------------// + +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif diff --git a/src/boards/include/boards/pico.h b/src/boards/include/boards/pico.h index cf45311..d681dc4 100644 --- a/src/boards/include/boards/pico.h +++ b/src/boards/include/boards/pico.h @@ -61,6 +61,8 @@ // --- FLASH --- +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif diff --git a/src/boards/include/boards/pimoroni_keybow2040.h b/src/boards/include/boards/pimoroni_keybow2040.h index eeab409..011212e 100644 --- a/src/boards/include/boards/pimoroni_keybow2040.h +++ b/src/boards/include/boards/pimoroni_keybow2040.h @@ -111,6 +111,8 @@ #define KEYBOW2040_NUM_SWITCHES_PINS 16 #endif +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif diff --git a/src/boards/include/boards/pimoroni_picosystem.h b/src/boards/include/boards/pimoroni_picosystem.h index c249469..72d4789 100644 --- a/src/boards/include/boards/pimoroni_picosystem.h +++ b/src/boards/include/boards/pimoroni_picosystem.h @@ -124,6 +124,8 @@ #define PICO_DEFAULT_LED_PIN_INVERTED 1 #endif +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif diff --git a/src/boards/include/boards/pimoroni_tiny2040.h b/src/boards/include/boards/pimoroni_tiny2040.h index 29194e4..6cf86b4 100644 --- a/src/boards/include/boards/pimoroni_tiny2040.h +++ b/src/boards/include/boards/pimoroni_tiny2040.h @@ -76,6 +76,8 @@ #define PICO_DEFAULT_LED_PIN_INVERTED 1 #endif +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif diff --git a/src/boards/include/boards/sparkfun_micromod.h b/src/boards/include/boards/sparkfun_micromod.h index 973a9e1..d082131 100644 --- a/src/boards/include/boards/sparkfun_micromod.h +++ b/src/boards/include/boards/sparkfun_micromod.h @@ -47,6 +47,8 @@ #endif // spi flash +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif diff --git a/src/boards/include/boards/sparkfun_promicro.h b/src/boards/include/boards/sparkfun_promicro.h index d63ab41..b042d6e 100644 --- a/src/boards/include/boards/sparkfun_promicro.h +++ b/src/boards/include/boards/sparkfun_promicro.h @@ -46,6 +46,8 @@ #define PICO_DEFAULT_I2C_SCL_PIN 17 #endif +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif diff --git a/src/boards/include/boards/sparkfun_thingplus.h b/src/boards/include/boards/sparkfun_thingplus.h index eac3aa4..d2a0d73 100644 --- a/src/boards/include/boards/sparkfun_thingplus.h +++ b/src/boards/include/boards/sparkfun_thingplus.h @@ -43,6 +43,9 @@ #endif // spi flash + +#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 + #ifndef PICO_FLASH_SPI_CLKDIV #define PICO_FLASH_SPI_CLKDIV 2 #endif diff --git a/src/rp2_common/boot_stage2/CMakeLists.txt b/src/rp2_common/boot_stage2/CMakeLists.txt index 4eda064..99adf40 100644 --- a/src/rp2_common/boot_stage2/CMakeLists.txt +++ b/src/rp2_common/boot_stage2/CMakeLists.txt @@ -1,17 +1,34 @@ -# PICO_CMAKE_CONFIG: PICO_DEFAULT_BOOT_STAGE2_FILE, Default stage2 file to use unless overridden by pico_set_boot_stage2 on the TARGET, type=bool, default=.../boot2_w25q080.S, group=build -if (NOT PICO_DEFAULT_BOOT_STAGE2_FILE) - set(PICO_DEFAULT_BOOT_STAGE2_FILE "${CMAKE_CURRENT_LIST_DIR}/boot2_w25q080.S") +# PICO_CMAKE_CONFIG: PICO_DEFAULT_BOOT_STAGE2_FILE, Default stage2 file to use unless overridden by pico_set_boot_stage2 on the TARGET; this setting is useful when explicitly setting the default build from a per board CMake file, group=build +# PICO_CMAKE_CONFIG: PICO_DEFAULT_BOOT_STAGE2, Simpler alternative to specifying PICO_DEFAULT_BOOT_STAGE2_FILE where the file is src/boards/{PICO_DEFAULT_BOOT_STAGE2_FILE}.S, default=compile_time_choice, group=build +if (DEFINED ENV{PICO_DEFAULT_BOOT_STAGE2_FILE}) + set(PICO_DEFAULT_BOOT_STAGE2_FILE $ENV{PICO_DEFAULT_BOOT_STAGE2_FILE}) + message("Using PICO_DEFAULT_BOOT_STAGE2_FILE from environment ('${PICO_DEFAULT_BOOT_STAGE2_FILE}')") endif() - set(PICO_DEFAULT_BOOT_STAGE2_FILE "${PICO_DEFAULT_BOOT_STAGE2_FILE}" CACHE STRING "boot_stage2 source file" FORCE) +set(PICO_BOOT_STAGE2_COMPILE_TIME_CHOICE_NAME compile_time_choice) # local var +if (NOT PICO_DEFAULT_BOOT_STAGE2_FILE) + if (DEFINED ENV{PICO_DEFAULT_BOOT_STAGE2}) + set(PICO_DEFAULT_BOOT_STAGE2 $ENV{PICO_DEFAULT_BOOT_STAGE2}) + message("Using PICO_DEFAULT_BOOT_STAGE2 from environment ('${PICO_DEFAULT_BOOT_STAGE2}')") + endif() + if (NOT DEFINED PICO_DEFAULT_BOOT_STAGE2) + set(PICO_DEFAULT_BOOT_STAGE2 ${PICO_BOOT_STAGE2_COMPILE_TIME_CHOICE_NAME}) + endif() + set(PICO_DEFAULT_BOOT_STAGE2 "${PICO_DEFAULT_BOOT_STAGE2}" CACHE STRING "boot_stage2 short name" FORCE) + set(PICO_DEFAULT_BOOT_STAGE2_FILE "${CMAKE_CURRENT_LIST_DIR}/${PICO_DEFAULT_BOOT_STAGE2}.S") +endif() + if (NOT EXISTS ${PICO_DEFAULT_BOOT_STAGE2_FILE}) - message(FATAL_ERROR "Specified boot_stage2 source '${PICO_BOOT_STAGE2_FILE}' does not exist.") + message(FATAL_ERROR "Specified boot_stage2 source '${PICO_DEFAULT_BOOT_STAGE2_FILE}' does not exist.") endif() # needed by function below set(PICO_BOOT_STAGE2_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "") +add_library(boot_stage2_headers INTERFACE) +target_include_directories(boot_stage2_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) + # by convention the first source file name without extension is used for the binary info name function(pico_define_boot_stage2 NAME SOURCES) add_executable(${NAME} @@ -29,7 +46,7 @@ function(pico_define_boot_stage2 NAME SOURCES) # boot2_helpers include dir target_include_directories(${NAME} PRIVATE ${PICO_BOOT_STAGE2_DIR}/asminclude) - target_link_libraries(${NAME} hardware_regs) + target_link_libraries(${NAME} hardware_regs boot_stage2_headers) target_link_options(${NAME} PRIVATE "LINKER:--script=${PICO_BOOT_STAGE2_DIR}/boot_stage2.ld") set_target_properties(${NAME} PROPERTIES LINK_DEPENDS ${PICO_BOOT_STAGE2_DIR}/boot_stage2.ld) @@ -49,17 +66,22 @@ function(pico_define_boot_stage2 NAME SOURCES) COMMAND ${Python3_EXECUTABLE} ${PICO_BOOT_STAGE2_DIR}/pad_checksum -s 0xffffffff ${ORIGINAL_BIN} ${PADDED_CHECKSUMMED_ASM} ) - add_library(${NAME}_library INTERFACE) add_dependencies(${NAME}_library ${NAME}_padded_checksummed_asm) # not strictly (or indeed actually) a link library, but this avoids dependency cycle target_link_libraries(${NAME}_library INTERFACE ${PADDED_CHECKSUMMED_ASM}) + target_link_libraries(${NAME}_library INTERFACE boot_stage2_headers) list(GET SOURCES 0 FIRST_SOURCE) - get_filename_component(BOOT2_BI_NAME ${FIRST_SOURCE} NAME_WE) + get_filename_component(BOOT_STAGE2_BI_NAME ${FIRST_SOURCE} NAME_WE) - target_compile_definitions(${NAME}_library INTERFACE - -DPICO_BOOT2_NAME="${BOOT2_BI_NAME}") + # we only set the PICO_BUILD_STAGE2_NAME if it isn't 'compile_time_choice' + if (NOT BOOT_STAGE2_BI_NAME STREQUAL PICO_BOOT_STAGE2_COMPILE_TIME_CHOICE_NAME) + target_compile_definitions(${NAME} INTERFACE + -DPICO_BUILD_BOOT_STAGE2_NAME="${BOOT_STAGE2_BI_NAME}") + target_compile_definitions(${NAME}_library INTERFACE + -DPICO_BUILD_BOOT_STAGE2_NAME="${BOOT_STAGE2_BI_NAME}") + endif() endfunction() macro(pico_set_boot_stage2 TARGET NAME) diff --git a/src/rp2_common/boot_stage2/compile_time_choice.S b/src/rp2_common/boot_stage2/compile_time_choice.S new file mode 100644 index 0000000..cacb9aa --- /dev/null +++ b/src/rp2_common/boot_stage2/compile_time_choice.S @@ -0,0 +1,29 @@ +// ---------------------------------------------------------------------------- +// Second stage boot code +// Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd. +// SPDX-License-Identifier: BSD-3-Clause +// ---------------------------------------------------------------------------- +// +// This implementation uses the PICO_BOOT_STAGE2_CHOOSE_ preprocessor defines to pick +// amongst a menu of known boot stage 2 implementations, allowing the board +// configuration header to be able to specify the boot stage 2 + +#include "boot_stage2/config.h" + +#ifdef PICO_BUILD_BOOT_STAGE2_NAME + // boot stage2 is configured by cmake, so use the name specified there + #error PICO_BUILD_BOOT_STAGE2_NAME should not be defined for compile_time_choice builds +#else + // boot stage2 is selected by board configu header, so we have to do some work + #if PICO_BOOT_STAGE2_CHOOSE_IS25LP080 + #include "boot2_is25lp080.S" + #elif PICO_BOOT_STAGE2_CHOOSE_W25Q080 + #include "boot2_w28q080.S" + #elif PICO_BOOT_STAGE2_CHOOSE_W25X10CL + #include "boot2_w25x10cl.S" + #elif PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H + #include "boot2_generic_03h.S" + #else + #error unknown boot stage2 choice + #endif +#endif diff --git a/src/rp2_common/boot_stage2/include/boot_stage2/config.h b/src/rp2_common/boot_stage2/include/boot_stage2/config.h new file mode 100644 index 0000000..f6fdb9f --- /dev/null +++ b/src/rp2_common/boot_stage2/include/boot_stage2/config.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _BOOT_STAGE2_CONFIG_H_ +#define _BOOT_STAGE2_CONFIG_H_ + +// NOTE THIS HEADER IS INCLUDED FROM ASSEMBLY + +// PICO_CONFIG: PICO_BUILD_BOOT_STAGE2_NAME, The name of the boot stage 2 if selected by the build, group=boot_stage2 +// PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_IS25LP080, Select boot2_is25lp080 as the boot stage 2 when no boot stage2 selection is made by the CMake build, type=bool, default=false, group=boot_stage2 +// PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_W25Q080, Select boot2_w28q080 as the boot stage 2 when no boot stage2 selection is made by the CMake build, type=bool, default=false, group=boot_stage2 +// PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_W25X10CL, Select boot2_is25lp080 as the boot stage 2 when no boot stage2 selection is made by the CMake build, type=bool, default=false, group=boot_stage2 +// PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H, Select boot2_generic_03h as the boot stage 2 when no boot stage2 selection is made by the CMake build, type=bool, default=true, group=boot_stage2 + +#ifdef PICO_BUILD_BOOT_STAGE2_NAME + // boot stage2 is configured by cmake, so use the name specified there + #define PICO_BOOT_STAGE2_NAME PICO_BUILD_BOOT_STAGE2_NAME +#else + // boot stage2 is selected by board configu header, so we have to do some work + // NOTE: this switch is mirrored in compile_time_choice.S + #if PICO_BOOT_STAGE2_CHOOSE_IS25LP080 + #define PICO_BOOT_STAGE2_NAME "boot2_is25lp080" + #elif PICO_BOOT_STAGE2_CHOOSE_W25Q080 + #define PICO_BOOT_STAGE2_NAME "boot2_w28q080" + #elif PICO_BOOT_STAGE2_CHOOSE_W25X10CL + #define PICO_BOOT_STAGE2_NAME "boot2_w25x10cl" + #elif PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H || !defined(PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H) + #undef PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H + #define PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H 1 + #define PICO_BOOT_STAGE2_NAME "boot2_generic_03h" + #else + #error no bootstage2 is defined by PICO_BOOT_STAGE2_CHOOSE_ macro + #endif +#endif +#endif \ No newline at end of file diff --git a/src/rp2_common/pico_standard_link/CMakeLists.txt b/src/rp2_common/pico_standard_link/CMakeLists.txt index 489594c..c58096d 100644 --- a/src/rp2_common/pico_standard_link/CMakeLists.txt +++ b/src/rp2_common/pico_standard_link/CMakeLists.txt @@ -14,7 +14,7 @@ if (NOT TARGET pico_standard_link) target_link_options(pico_standard_link INTERFACE "LINKER:-nostdlib") endif () - target_link_libraries(pico_standard_link INTERFACE hardware_regs pico_bootrom pico_binary_info pico_cxx_options) + target_link_libraries(pico_standard_link INTERFACE hardware_regs boot_stage2_headers pico_bootrom pico_binary_info pico_cxx_options) function(pico_add_link_depend TARGET dependency) get_target_property(target_type ${TARGET} TYPE) diff --git a/src/rp2_common/pico_standard_link/binary_info.c b/src/rp2_common/pico_standard_link/binary_info.c index ba5dad8..bde2027 100644 --- a/src/rp2_common/pico_standard_link/binary_info.c +++ b/src/rp2_common/pico_standard_link/binary_info.c @@ -6,6 +6,7 @@ #if !PICO_NO_BINARY_INFO && !PICO_NO_PROGRAM_INFO #include "pico/binary_info.h" +#include "boot_stage2/config.h" // Note we put at most 4 pieces of binary info in the reset section because that's how much spare space we had // (picked the most common ones)... if there is a link failure because of .reset section overflow then move @@ -66,9 +67,9 @@ bi_decl(bi_program_url(PICO_PROGRAM_URL)) #endif #endif -#if !PICO_NO_BI_BOOT2_NAME -#ifdef PICO_BOOT2_NAME -bi_decl(bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_BOOT2_NAME, PICO_BOOT2_NAME)) +#if !PICO_NO_BI_BOOT_STAGE2_NAME +#ifdef PICO_BOOT_STAGE2_NAME +bi_decl(bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_BOOT2_NAME, PICO_BOOT_STAGE2_NAME)) #endif #endif From 63d1baf263368edc19b4ec4e674f08310f0a2c85 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 1 Apr 2021 17:25:19 -0500 Subject: [PATCH 17/19] fix version to non develop --- pico_sdk_version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico_sdk_version.cmake b/pico_sdk_version.cmake index 9f2aa61..db48268 100644 --- a/pico_sdk_version.cmake +++ b/pico_sdk_version.cmake @@ -9,7 +9,7 @@ set(PICO_SDK_VERSION_MINOR 1) set(PICO_SDK_VERSION_REVISION 1) # PICO_BUILD_DEFINE: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, group=pico_base # PICO_CONFIG: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, group=pico_base -set(PICO_SDK_VERSION_PRE_RELEASE_ID develop) +#set(PICO_SDK_VERSION_PRE_RELEASE_ID develop) # PICO_BUILD_DEFINE: PICO_SDK_VERSION_STRING, SDK version, type=string, group=pico_base # PICO_CONFIG: PICO_SDK_VERSION_STRING, SDK version, type=string, group=pico_base From 707555f5bc542b156a10442d6de59008624aaca5 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 1 Apr 2021 17:27:33 -0500 Subject: [PATCH 18/19] revert version number to correct develop settings --- pico_sdk_version.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pico_sdk_version.cmake b/pico_sdk_version.cmake index db48268..5678595 100644 --- a/pico_sdk_version.cmake +++ b/pico_sdk_version.cmake @@ -3,13 +3,13 @@ set(PICO_SDK_VERSION_MAJOR 1) # PICO_BUILD_DEFINE: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, group=pico_base # PICO_CONFIG: PICO_SDK_VERSION_MINOR, SDK minor version number, type=int, group=pico_base -set(PICO_SDK_VERSION_MINOR 1) +set(PICO_SDK_VERSION_MINOR 2) # PICO_BUILD_DEFINE: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, group=pico_base # PICO_CONFIG: PICO_SDK_VERSION_REVISION, SDK version revision, type=int, group=pico_base -set(PICO_SDK_VERSION_REVISION 1) +set(PICO_SDK_VERSION_REVISION 0) # PICO_BUILD_DEFINE: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, group=pico_base # PICO_CONFIG: PICO_SDK_VERSION_PRE_RELEASE_ID, optional SDK pre-release version identifier, type=string, group=pico_base -#set(PICO_SDK_VERSION_PRE_RELEASE_ID develop) +set(PICO_SDK_VERSION_PRE_RELEASE_ID develop) # PICO_BUILD_DEFINE: PICO_SDK_VERSION_STRING, SDK version, type=string, group=pico_base # PICO_CONFIG: PICO_SDK_VERSION_STRING, SDK version, type=string, group=pico_base From 1089c1b83aad82d1a5b00e0d95b3b7b9df6fffc1 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Thu, 1 Apr 2021 17:31:01 -0500 Subject: [PATCH 19/19] remove whitespace --- pico_sdk_version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico_sdk_version.cmake b/pico_sdk_version.cmake index 5678595..1f9466c 100644 --- a/pico_sdk_version.cmake +++ b/pico_sdk_version.cmake @@ -17,4 +17,4 @@ set(PICO_SDK_VERSION_STRING "${PICO_SDK_VERSION_MAJOR}.${PICO_SDK_VERSION_MINOR} if (PICO_SDK_VERSION_PRE_RELEASE_ID) set(PICO_SDK_VERSION_STRING "${PICO_SDK_VERSION_STRING}-${PICO_SDK_VERSION_PRE_RELEASE_ID}") -endif() +endif() \ No newline at end of file