diff options
author | Peter Harper <peter.harper@raspberrypi.com> | 2024-05-23 10:57:14 +0100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2024-10-15 12:07:59 +1100 |
commit | d2c85c74dabc33a4574422d8970d2b25bcc22b7a (patch) | |
tree | d8daaae1343e5e75628531c84bccbfeea861ef4e | |
parent | 27aeade832665c434b0150c6fd32a455e6865eef (diff) |
rp2: Integrate RP2350 and use aon_timer instead of rtc API.
This commit separates various build settings and include files that are
specific to RP2040 and RP2350, and uses the aon_timer interface instead of
rtc, to work across both MCU variants.
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Phil Howard <phil@gadgetoid.com>
-rw-r--r-- | ports/rp2/CMakeLists.txt | 49 | ||||
-rw-r--r-- | ports/rp2/boards/RPI_PICO/mpconfigboard.cmake | 1 | ||||
-rw-r--r-- | ports/rp2/fatfs_port.c | 11 | ||||
-rw-r--r-- | ports/rp2/machine_rtc.c | 69 | ||||
-rw-r--r-- | ports/rp2/main.c | 25 | ||||
-rw-r--r-- | ports/rp2/mbedtls/mbedtls_port.c | 8 | ||||
-rw-r--r-- | ports/rp2/modmachine.c | 1 | ||||
-rw-r--r-- | ports/rp2/modtime.c | 30 | ||||
-rw-r--r-- | ports/rp2/mphalport.c | 24 | ||||
-rw-r--r-- | ports/rp2/mpnetworkport.c | 7 | ||||
-rw-r--r-- | ports/rp2/pendsv.c | 7 |
11 files changed, 142 insertions, 90 deletions
diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index 54b7e84bc..6f6618154 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -191,19 +191,26 @@ set(PICO_SDK_COMPONENTS hardware_pll hardware_pwm hardware_regs - hardware_rtc + hardware_resets hardware_spi hardware_structs hardware_sync + hardware_sync_spin_lock hardware_timer hardware_uart hardware_watchdog hardware_xosc + pico_aon_timer pico_base_headers pico_binary_info pico_bootrom pico_multicore pico_platform + pico_platform_compiler + pico_platform_panic + pico_platform_sections + pico_runtime + pico_runtime_init pico_stdio pico_stdlib pico_sync @@ -224,14 +231,24 @@ pico_add_library(pico_float_micropython) # pico_float_micropython: add pico-sdk float and our libm source files. target_sources(pico_float_micropython INTERFACE - ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_aeabi.S - ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_init_rom.c - ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_v1_rom_shim.S ${MICROPY_SOURCE_LIB_LIBM} ${MICROPY_SOURCE_LIB_LIBM_SQRT_SW} ${MICROPY_PORT_DIR}/libm_extra.c ) +if(PICO_RP2040) + target_sources(pico_float_micropython INTERFACE + ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_aeabi_rp2040.S + ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_init_rom_rp2040.c + ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_v1_rom_shim_rp2040.S + ) +elseif(PICO_RP2350) + target_sources(pico_float_micropython INTERFACE + ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_aeabi_dcp.S + ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_conv_m33.S + ) +endif() + # pico_float_micropython: wrap low-level floating-point ops, to call the pico-sdk versions. pico_wrap_function(pico_float_micropython __aeabi_fdiv) pico_wrap_function(pico_float_micropython __aeabi_fmul) @@ -253,7 +270,9 @@ pico_wrap_function(pico_float_micropython __aeabi_ul2f) pico_wrap_function(pico_float_micropython __aeabi_f2iz) pico_wrap_function(pico_float_micropython __aeabi_f2lz) pico_wrap_function(pico_float_micropython __aeabi_f2uiz) -pico_wrap_function(pico_float_micropython __aeabi_f2ulz) +if(PICO_RP2040) + pico_wrap_function(pico_float_micropython __aeabi_f2ulz) +endif() pico_wrap_function(pico_float_micropython __aeabi_f2d) if (MICROPY_PY_LWIP) @@ -507,9 +526,18 @@ target_compile_definitions(${MICROPY_TARGET} PRIVATE PICO_NO_PROGRAM_VERSION_STRING=1 # do it ourselves in main.c MICROPY_BUILD_TYPE="${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION} ${CMAKE_BUILD_TYPE}" PICO_NO_BI_STDIO_UART=1 # we call it UART REPL - PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 ) +if(PICO_RP2040) + target_compile_definitions(${MICROPY_TARGET} PRIVATE + PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 + ) +elseif(PICO_RP2350) + target_compile_definitions(${MICROPY_TARGET} PRIVATE + PICO_EMBED_XIP_SETUP=1 # to put flash into continuous read mode + ) +endif() + target_link_libraries(${MICROPY_TARGET} ${PICO_SDK_COMPONENTS} ) @@ -525,7 +553,11 @@ endif() # a linker script modification) until we explicitly add macro calls around the function # defs to move them into RAM. if (PICO_ON_DEVICE AND NOT PICO_NO_FLASH AND NOT PICO_COPY_TO_RAM) - pico_set_linker_script(${MICROPY_TARGET} ${CMAKE_CURRENT_LIST_DIR}/memmap_mp_${PICO_PLATFORM}.ld) + if(PICO_RP2040) + pico_set_linker_script(${MICROPY_TARGET} ${CMAKE_CURRENT_LIST_DIR}/memmap_mp_rp2040.ld) + elseif(PICO_RP2350) + pico_set_linker_script(${MICROPY_TARGET} ${CMAKE_CURRENT_LIST_DIR}/memmap_mp_rp2350.ld) + endif() endif() pico_add_extra_outputs(${MICROPY_TARGET}) @@ -544,6 +576,9 @@ foreach(comp ${PICO_SDK_COMPONENTS}) micropy_gather_target_properties(${comp}_headers) endforeach() +set(MICROPY_CPP_FLAGS_EXTRA ${PICO_COMMON_LANG_FLAGS}) +separate_arguments(MICROPY_CPP_FLAGS_EXTRA) + # Include the main MicroPython cmake rules. include(${MICROPY_DIR}/py/mkrules.cmake) diff --git a/ports/rp2/boards/RPI_PICO/mpconfigboard.cmake b/ports/rp2/boards/RPI_PICO/mpconfigboard.cmake index 13269e81e..386bd3328 100644 --- a/ports/rp2/boards/RPI_PICO/mpconfigboard.cmake +++ b/ports/rp2/boards/RPI_PICO/mpconfigboard.cmake @@ -1,2 +1,3 @@ # cmake file for Raspberry Pi Pico set(PICO_BOARD "pico") +set(PICO_PLATFORM "rp2040") diff --git a/ports/rp2/fatfs_port.c b/ports/rp2/fatfs_port.c index 9706b6fe7..1ce505dd6 100644 --- a/ports/rp2/fatfs_port.c +++ b/ports/rp2/fatfs_port.c @@ -25,10 +25,13 @@ */ #include "lib/oofatfs/ff.h" -#include "hardware/rtc.h" +#include "pico/aon_timer.h" +#include "shared/timeutils/timeutils.h" MP_WEAK DWORD get_fattime(void) { - datetime_t t; - rtc_get_datetime(&t); - return ((t.year - 1980) << 25) | ((t.month) << 21) | ((t.day) << 16) | ((t.hour) << 11) | ((t.min) << 5) | (t.sec / 2); + struct timespec ts; + timeutils_struct_time_t tm; + aon_timer_get_time(&ts); + timeutils_seconds_since_epoch_to_struct_time(ts.tv_sec, &tm); + return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) | ((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) | ((tm.tm_min) << 5) | (tm.tm_sec / 2); } diff --git a/ports/rp2/machine_rtc.c b/ports/rp2/machine_rtc.c index ce224be71..0d8fdef30 100644 --- a/ports/rp2/machine_rtc.c +++ b/ports/rp2/machine_rtc.c @@ -30,6 +30,8 @@ #include <time.h> #include <sys/time.h> +#include "pico/aon_timer.h" + #include "py/nlr.h" #include "py/obj.h" #include "py/runtime.h" @@ -37,8 +39,6 @@ #include "py/mperrno.h" #include "extmod/modmachine.h" #include "shared/timeutils/timeutils.h" -#include "hardware/rtc.h" -#include "pico/util/datetime.h" typedef struct _machine_rtc_obj_t { mp_obj_base_t base; @@ -50,14 +50,12 @@ static const machine_rtc_obj_t machine_rtc_obj = {{&machine_rtc_type}}; static mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { // check arguments mp_arg_check_num(n_args, n_kw, 0, 0, false); - bool r = rtc_running(); + bool r = aon_timer_is_running(); if (!r) { - // This shouldn't happen as rtc_init() is already called in main so - // it's here just in case - rtc_init(); - datetime_t t = { .month = 1, .day = 1 }; - rtc_set_datetime(&t); + // This shouldn't happen. it's here just in case + struct timespec ts = { 0, 0 }; + aon_timer_start(&ts); mp_hal_time_ns_set_from_rtc(); } // return constant object @@ -66,47 +64,36 @@ static mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, s static mp_obj_t machine_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) { if (n_args == 1) { - bool ret; - datetime_t t; - - ret = rtc_get_datetime(&t); - if (!ret) { - mp_raise_OSError(MP_EIO); - } - + struct timespec ts; + timeutils_struct_time_t tm; + aon_timer_get_time(&ts); + timeutils_seconds_since_epoch_to_struct_time(ts.tv_sec, &tm); mp_obj_t tuple[8] = { - mp_obj_new_int(t.year), - mp_obj_new_int(t.month), - mp_obj_new_int(t.day), - mp_obj_new_int(t.dotw), - mp_obj_new_int(t.hour), - mp_obj_new_int(t.min), - mp_obj_new_int(t.sec), - mp_obj_new_int(0) + mp_obj_new_int(tm.tm_year), + mp_obj_new_int(tm.tm_mon), + mp_obj_new_int(tm.tm_mday), + mp_obj_new_int(tm.tm_wday), + mp_obj_new_int(tm.tm_hour), + mp_obj_new_int(tm.tm_min), + mp_obj_new_int(tm.tm_sec), + mp_obj_new_int(0), }; - return mp_obj_new_tuple(8, tuple); } else { mp_obj_t *items; - mp_obj_get_array_fixed_n(args[1], 8, &items); - - datetime_t t = { - .year = mp_obj_get_int(items[0]), - .month = mp_obj_get_int(items[1]), - .day = mp_obj_get_int(items[2]), - .hour = mp_obj_get_int(items[4]), - .min = mp_obj_get_int(items[5]), - .sec = mp_obj_get_int(items[6]), + timeutils_struct_time_t tm = { + .tm_year = mp_obj_get_int(items[0]), + .tm_mon = mp_obj_get_int(items[1]), + .tm_mday = mp_obj_get_int(items[2]), + .tm_hour = mp_obj_get_int(items[4]), + .tm_min = mp_obj_get_int(items[5]), + .tm_sec = mp_obj_get_int(items[6]), }; - // Deliberately ignore the weekday argument and compute the proper value - t.dotw = timeutils_calc_weekday(t.year, t.month, t.day); - - if (!rtc_set_datetime(&t)) { - mp_raise_OSError(MP_EINVAL); - } + struct timespec ts = { 0, 0 }; + ts.tv_sec = timeutils_seconds_since_epoch(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); + aon_timer_set_time(&ts); mp_hal_time_ns_set_from_rtc(); - } return mp_const_none; } diff --git a/ports/rp2/main.c b/ports/rp2/main.c index 7fb4a6486..012e26f48 100644 --- a/ports/rp2/main.c +++ b/ports/rp2/main.c @@ -47,11 +47,9 @@ #include "genhdr/mpversion.h" #include "mp_usbd.h" -#include "RP2040.h" // cmsis, for PendSV_IRQn and SCB/SCB_SCR_SEVONPEND_Msk #include "pico/stdlib.h" #include "pico/binary_info.h" #include "pico/unique_id.h" -#include "hardware/rtc.h" #include "hardware/structs/rosc.h" #if MICROPY_PY_LWIP #include "lwip/init.h" @@ -60,6 +58,15 @@ #if MICROPY_PY_NETWORK_CYW43 #include "lib/cyw43-driver/src/cyw43.h" #endif +#if PICO_RP2040 +#include "RP2040.h" // cmsis, for PendSV_IRQn and SCB/SCB_SCR_SEVONPEND_Msk +#elif PICO_RP2350 +#include "RP2350.h" // cmsis, for PendSV_IRQn and SCB/SCB_SCR_SEVONPEND_Msk +#else +#error Unknown processor +#endif +#include "pico/aon_timer.h" +#include "shared/timeutils/timeutils.h" extern uint8_t __StackTop, __StackBottom; extern uint8_t __GcHeapStart, __GcHeapEnd; @@ -106,17 +113,9 @@ int main(int argc, char **argv) { #endif // Start and initialise the RTC - datetime_t t = { - .year = 2021, - .month = 1, - .day = 1, - .dotw = 4, // 0 is Monday, so 4 is Friday - .hour = 0, - .min = 0, - .sec = 0, - }; - rtc_init(); - rtc_set_datetime(&t); + struct timespec ts = { 0, 0 }; + ts.tv_sec = timeutils_seconds_since_epoch(2021, 1, 1, 0, 0, 0); + aon_timer_start(&ts); mp_hal_time_ns_set_from_rtc(); // Initialise stack extents and GC heap. diff --git a/ports/rp2/mbedtls/mbedtls_port.c b/ports/rp2/mbedtls/mbedtls_port.c index 9b1e0d20e..521d815d2 100644 --- a/ports/rp2/mbedtls/mbedtls_port.c +++ b/ports/rp2/mbedtls/mbedtls_port.c @@ -29,9 +29,9 @@ #include "mbedtls_config_port.h" -#include "hardware/rtc.h" #include "shared/timeutils/timeutils.h" #include "mbedtls/platform_time.h" +#include "pico/aon_timer.h" extern uint8_t rosc_random_u8(size_t cycles); @@ -44,9 +44,9 @@ int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t } time_t rp2_rtctime_seconds(time_t *timer) { - datetime_t t; - rtc_get_datetime(&t); - return timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.min, t.sec); + struct timespec ts; + aon_timer_get_time(&ts); + return ts.tv_sec; } mbedtls_ms_time_t mbedtls_ms_time(void) { diff --git a/ports/rp2/modmachine.c b/ports/rp2/modmachine.c index 0acae2549..798078faf 100644 --- a/ports/rp2/modmachine.c +++ b/ports/rp2/modmachine.c @@ -41,6 +41,7 @@ #include "pico/bootrom.h" #include "pico/stdlib.h" #include "pico/unique_id.h" +#include "pico/runtime_init.h" #if MICROPY_PY_NETWORK_CYW43 #include "lib/cyw43-driver/src/cyw43.h" #endif diff --git a/ports/rp2/modtime.c b/ports/rp2/modtime.c index 21e5cb459..7d6dd8fd9 100644 --- a/ports/rp2/modtime.c +++ b/ports/rp2/modtime.c @@ -26,28 +26,30 @@ #include "py/obj.h" #include "shared/timeutils/timeutils.h" -#include "hardware/rtc.h" +#include "pico/aon_timer.h" // Return the localtime as an 8-tuple. static mp_obj_t mp_time_localtime_get(void) { - datetime_t t; - rtc_get_datetime(&t); + struct timespec ts; + aon_timer_get_time(&ts); + timeutils_struct_time_t tm; + timeutils_seconds_since_epoch_to_struct_time(ts.tv_sec, &tm); mp_obj_t tuple[8] = { - mp_obj_new_int(t.year), - mp_obj_new_int(t.month), - mp_obj_new_int(t.day), - mp_obj_new_int(t.hour), - mp_obj_new_int(t.min), - mp_obj_new_int(t.sec), - mp_obj_new_int(t.dotw), - mp_obj_new_int(timeutils_year_day(t.year, t.month, t.day)), + mp_obj_new_int(tm.tm_year), + mp_obj_new_int(tm.tm_mon), + mp_obj_new_int(tm.tm_mday), + mp_obj_new_int(tm.tm_hour), + mp_obj_new_int(tm.tm_min), + mp_obj_new_int(tm.tm_sec), + mp_obj_new_int(tm.tm_wday), + mp_obj_new_int(tm.tm_yday), }; return mp_obj_new_tuple(8, tuple); } // Return the number of seconds since the Epoch. static mp_obj_t mp_time_time_get(void) { - datetime_t t; - rtc_get_datetime(&t); - return mp_obj_new_int_from_ull(timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.min, t.sec)); + struct timespec ts; + aon_timer_get_time(&ts); + return mp_obj_new_int_from_ull(ts.tv_sec); } diff --git a/ports/rp2/mphalport.c b/ports/rp2/mphalport.c index aa5415d6c..3fcc011b6 100644 --- a/ports/rp2/mphalport.c +++ b/ports/rp2/mphalport.c @@ -37,16 +37,18 @@ #include "tusb.h" #include "uart.h" #include "hardware/irq.h" -#include "hardware/rtc.h" #include "pico/unique_id.h" +#include "pico/aon_timer.h" #if MICROPY_PY_NETWORK_CYW43 #include "lib/cyw43-driver/src/cyw43.h" #endif +#if PICO_RP2040 // This needs to be added to the result of time_us_64() to get the number of // microseconds since the Epoch. static uint64_t time_us_64_offset_from_epoch; +#endif #if MICROPY_HW_ENABLE_UART_REPL || MICROPY_HW_USB_CDC @@ -145,27 +147,35 @@ void mp_hal_delay_ms(mp_uint_t ms) { } void mp_hal_time_ns_set_from_rtc(void) { + #if PICO_RP2040 // Outstanding RTC register writes need at least two RTC clock cycles to // update. (See RP2040 datasheet section 4.8.4 "Reference clock"). mp_hal_delay_us(44); // Sample RTC and time_us_64() as close together as possible, so the offset // calculated for the latter can be as accurate as possible. - datetime_t t; - rtc_get_datetime(&t); + struct timespec ts; + aon_timer_get_time(&ts); uint64_t us = time_us_64(); - // Calculate the difference between the RTC Epoch seconds and time_us_64(). - uint64_t s = timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.min, t.sec); - time_us_64_offset_from_epoch = (uint64_t)s * 1000000ULL - us; + // Calculate the difference between the RTC Epoch and time_us_64(). + time_us_64_offset_from_epoch = ((uint64_t)ts.tv_sec * 1000000ULL) + ((uint64_t)ts.tv_nsec / 1000ULL) - us; + #endif } uint64_t mp_hal_time_ns(void) { - // The RTC only has seconds resolution, so instead use time_us_64() to get a more + #if PICO_RP2040 + // The RTC probably has limited resolution, so instead use time_us_64() to get a more // precise measure of Epoch time. Both these "clocks" are clocked from the same // source so they remain synchronised, and only differ by a fixed offset (calculated // in mp_hal_time_ns_set_from_rtc). return (time_us_64_offset_from_epoch + time_us_64()) * 1000ULL; + #else + // aon timer has ms resolution + struct timespec ts; + aon_timer_get_time(&ts); + return ((uint64_t)ts.tv_sec * 1000000000ULL) + (uint64_t)ts.tv_nsec; + #endif } // Generate a random locally administered MAC address (LAA) diff --git a/ports/rp2/mpnetworkport.c b/ports/rp2/mpnetworkport.c index e58adb3ba..fcc60b3fe 100644 --- a/ports/rp2/mpnetworkport.c +++ b/ports/rp2/mpnetworkport.c @@ -43,7 +43,14 @@ static soft_timer_entry_t mp_network_soft_timer; #include "lib/cyw43-driver/src/cyw43.h" #include "lib/cyw43-driver/src/cyw43_stats.h" #include "hardware/irq.h" + +#if PICO_RP2040 #include "RP2040.h" // cmsis, for NVIC_SetPriority and PendSV_IRQn +#elif PICO_RP2350 +#include "RP2350.h" // cmsis, for NVIC_SetPriority and PendSV_IRQn +#else +#error Unknown processor +#endif #define CYW43_IRQ_LEVEL GPIO_IRQ_LEVEL_HIGH #define CYW43_SHARED_IRQ_HANDLER_PRIORITY PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY diff --git a/ports/rp2/pendsv.c b/ports/rp2/pendsv.c index 6cfe624c3..2f06871b3 100644 --- a/ports/rp2/pendsv.c +++ b/ports/rp2/pendsv.c @@ -28,7 +28,14 @@ #include "py/mpconfig.h" #include "mutex_extra.h" #include "pendsv.h" + +#if PICO_RP2040 #include "RP2040.h" +#elif PICO_RP2350 +#include "RP2350.h" +#else +#error Unknown chip +#endif #if MICROPY_PY_NETWORK_CYW43 #include "lib/cyw43-driver/src/cyw43_stats.h" |