mirror of https://github.com/ARMmbed/mbed-os.git
Upversion RPi Pico SDK (#176)
* Remove old pico SDK, import latest version using new importer script * Add new importer script, update CMakeLists * Merge changes from newer SDK into init assembly and linker script * Update pico hal code for new SDK version * Clean up linker script a bit, revert ram size * Fix accidental breakage of watchdog-reset test from warning fixing! Also better document USB setup procedure and disable reset as part of the test runner.pull/15494/head
parent
eb231be2cd
commit
20756f3bd7
|
@ -12,6 +12,7 @@ Additional, platform-specific setup is described below.
|
||||||
See also [Known issues](#known-issues).
|
See also [Known issues](#known-issues).
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
1. Install libusb0.dll somewhere on your PATH. The bitness of the DLL should match the bitness of your python interpreter. This DLL can be downloaded from the project [here](https://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/). Note that libusb1 does NOT work, it has to be libusb0! See the comments in host_tests/pyusb_basic.py for details.
|
||||||
1. Install a **generic USB driver** for two test devices.
|
1. Install a **generic USB driver** for two test devices.
|
||||||
1. Download `Zadig` application from [the Zadig website][LN-zadig].
|
1. Download `Zadig` application from [the Zadig website][LN-zadig].
|
||||||
1. Unplug the Mbed device.
|
1. Unplug the Mbed device.
|
||||||
|
|
|
@ -318,11 +318,12 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave);
|
||||||
*/
|
*/
|
||||||
int i2c_slave_receive(i2c_t *obj);
|
int i2c_slave_receive(i2c_t *obj);
|
||||||
|
|
||||||
/** Configure I2C as slave or master.
|
/**
|
||||||
|
* @brief Read specified number of bytes from an I2C master.
|
||||||
* @param obj The I2C object
|
* @param obj The I2C object
|
||||||
* @param data The buffer for receiving
|
* @param data The buffer for receiving
|
||||||
* @param length Number of bytes to read
|
* @param length Number of bytes to read
|
||||||
* @return non-zero if a value is available
|
* @return non-zero if a value is available, or zero on error
|
||||||
*/
|
*/
|
||||||
int i2c_slave_read(i2c_t *obj, char *data, int length);
|
int i2c_slave_read(i2c_t *obj, char *data, int length);
|
||||||
|
|
||||||
|
|
|
@ -255,7 +255,7 @@ void test_kick_reset()
|
||||||
for (int i = 3; i; i--) {
|
for (int i = 3; i; i--) {
|
||||||
// The reset is prevented as long as the watchdog is kicked
|
// The reset is prevented as long as the watchdog is kicked
|
||||||
// anytime before the timeout.
|
// anytime before the timeout.
|
||||||
wait_us(2 * std::chrono::duration_cast<std::chrono::microseconds>(TIMEOUT_MS - KICK_ADVANCE_MS).count());
|
wait_us(std::chrono::duration_cast<std::chrono::microseconds>(TIMEOUT_MS - KICK_ADVANCE_MS).count());
|
||||||
hal_watchdog_kick();
|
hal_watchdog_kick();
|
||||||
}
|
}
|
||||||
if (!send_reset_notification(¤t_case, 2 * TIMEOUT_MS + SERIAL_FLUSH_TIME_MS)) {
|
if (!send_reset_notification(¤t_case, 2 * TIMEOUT_MS + SERIAL_FLUSH_TIME_MS)) {
|
||||||
|
@ -269,7 +269,7 @@ void test_kick_reset()
|
||||||
// Watchdog reset should have occurred during a wait above.
|
// Watchdog reset should have occurred during a wait above.
|
||||||
|
|
||||||
hal_watchdog_kick();
|
hal_watchdog_kick();
|
||||||
wdg_kicking_ticker.attach_us(mbed::callback(hal_watchdog_kick), 20000); // For testsuite failure handling.
|
wdg_kicking_ticker.attach(mbed::callback(hal_watchdog_kick), 20ms); // For testsuite failure handling.
|
||||||
TEST_ASSERT_MESSAGE(0, "Watchdog did not reset the device as expected.");
|
TEST_ASSERT_MESSAGE(0, "Watchdog did not reset the device as expected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,113 @@
|
||||||
# Copyright (c) 2020-2021 ARM Limited. All rights reserved.
|
# Copyright (c) 2020-2021 ARM Limited. All rights reserved.
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
add_subdirectory(TARGET_RP2040 EXCLUDE_FROM_ALL)
|
|
||||||
|
|
||||||
add_library(mbed-raspberrypi INTERFACE)
|
add_library(mbed-raspberrypi INTERFACE)
|
||||||
|
|
||||||
|
# The Pico SDK relies on a couple of generated files in order to work.
|
||||||
|
# We generate those files here.
|
||||||
|
|
||||||
|
# Version header -- needs version information from CMake.
|
||||||
|
# Helpfully, that info lives in its own file, so we can just include it.
|
||||||
|
include(pico-sdk/pico_sdk_version.cmake)
|
||||||
|
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/pico-sdk-generated/pico)
|
||||||
|
configure_file(pico-sdk/src/common/pico_base/include/pico/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/pico-sdk-generated/pico/version.h)
|
||||||
|
|
||||||
|
# Autogen config header.
|
||||||
|
# The below settings discovered by analyzing the build system.
|
||||||
|
set(PICO_CONFIG_HEADER_FILES boards/pico.h)
|
||||||
|
|
||||||
|
# The following code copied from generate_config_header.cmake
|
||||||
|
macro(add_header_content_from_var VAR)
|
||||||
|
set(header_content "${header_content}\n\n// based on ${VAR}:\n")
|
||||||
|
foreach(var IN LISTS ${VAR})
|
||||||
|
set(header_content "${header_content}\n#include \"${var}\"")
|
||||||
|
endforeach()
|
||||||
|
endmacro()
|
||||||
|
set(header_content "// AUTOGENERATED FROM PICO_CONFIG_HEADER_FILES and then PICO_<PLATFORM>_CONFIG_HEADER_FILES\n// DO NOT EDIT!\n")
|
||||||
|
add_header_content_from_var(PICO_CONFIG_HEADER_FILES)
|
||||||
|
file(GENERATE
|
||||||
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pico-sdk-generated/pico/config_autogen.h
|
||||||
|
CONTENT "${header_content}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now, add includes and headers from the Pico SDK
|
||||||
target_include_directories(mbed-raspberrypi
|
target_include_directories(mbed-raspberrypi
|
||||||
INTERFACE
|
INTERFACE
|
||||||
.
|
.
|
||||||
|
pico-sdk/src/rp2_common/hardware_adc/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_gpio/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_resets/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_pwm/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_base/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_uart/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_spi/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_i2c/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_irq/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_flash/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_clocks/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_rtc/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_watchdog/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_timer/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_pll/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_sync/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_xosc/include
|
||||||
|
pico-sdk/src/rp2_common/pico_platform/include
|
||||||
|
pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/include/
|
||||||
|
pico-sdk/src/rp2_common/pico_bootrom/include
|
||||||
|
pico-sdk/src/rp2_common/hardware_claim/include
|
||||||
|
pico-sdk/src/common/pico_sync/include
|
||||||
|
pico-sdk/src/common/pico_time/include
|
||||||
|
pico-sdk/src/common/pico_base/include
|
||||||
|
pico-sdk/src/common/pico_binary_info/include
|
||||||
|
pico-sdk/src/common/pico_util/include
|
||||||
|
pico-sdk/src/boards/include
|
||||||
|
pico-sdk/src/generated
|
||||||
|
pico-sdk/src/rp2_common/cmsis/stub/CMSIS/Device/RaspberryPi/RP2040/Include
|
||||||
|
pico-sdk/src/rp2_common/cmsis/include
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/pico-sdk-generated/
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(mbed-raspberrypi
|
target_sources(mbed-raspberrypi
|
||||||
INTERFACE
|
INTERFACE
|
||||||
.
|
pico-sdk/src/rp2_common/hardware_flash/flash.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_uart/uart.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_spi/spi.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_i2c/i2c.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_gpio/gpio.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_xosc/xosc.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_irq/irq.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_irq/irq_handler_chain.S
|
||||||
|
pico-sdk/src/rp2_common/hardware_pll/pll.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_watchdog/watchdog.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_clocks/clocks.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_claim/claim.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_timer/timer.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_sync/sync.c
|
||||||
|
pico-sdk/src/rp2_common/hardware_rtc/rtc.c
|
||||||
|
pico-sdk/src/rp2_common/pico_bootrom/bootrom.c
|
||||||
|
pico-sdk/src/rp2_common/pico_platform/platform.c
|
||||||
|
pico-sdk/src/common/pico_time/time.c
|
||||||
|
pico-sdk/src/common/pico_sync/lock_core.c
|
||||||
|
pico-sdk/src/rp2_common/cmsis/stub/CMSIS/Device/RaspberryPi/RP2040/Source/system_RP2040.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(mbed-raspberrypi
|
||||||
|
INTERFACE
|
||||||
|
LIB_CMSIS_CORE # Enables renaming interrupt vectors to their CMSIS names
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(mbed-raspberrypi INTERFACE mbed-cmsis-cortex-m)
|
target_link_libraries(mbed-raspberrypi INTERFACE mbed-cmsis-cortex-m)
|
||||||
|
|
||||||
|
# Create RP2040 target (will have more sources added in subdir)
|
||||||
|
add_library(mbed-rp2040 INTERFACE)
|
||||||
|
target_include_directories(mbed-rp2040
|
||||||
|
INTERFACE
|
||||||
|
pico-sdk/src/rp2040/hardware_structs/include
|
||||||
|
pico-sdk/src/rp2040/hardware_regs/include
|
||||||
|
)
|
||||||
|
target_sources(mbed-rp2040
|
||||||
|
INTERFACE
|
||||||
|
pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c
|
||||||
|
)
|
||||||
|
|
||||||
|
add_subdirectory(TARGET_RP2040 EXCLUDE_FROM_ALL)
|
||||||
|
|
|
@ -3,42 +3,10 @@
|
||||||
|
|
||||||
add_subdirectory(TARGET_RASPBERRY_PI_PICO EXCLUDE_FROM_ALL)
|
add_subdirectory(TARGET_RASPBERRY_PI_PICO EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
set(LINKER_FILE TOOLCHAIN_GCC_ARM//memmap_default.ld)
|
set(LINKER_FILE TOOLCHAIN_GCC_ARM/memmap_default_mbed.ld)
|
||||||
|
|
||||||
add_library(mbed-rp2040 INTERFACE)
|
|
||||||
|
|
||||||
target_include_directories(mbed-rp2040
|
target_include_directories(mbed-rp2040
|
||||||
INTERFACE
|
INTERFACE
|
||||||
pico-sdk/rp2_common/hardware_adc/include
|
|
||||||
pico-sdk/rp2_common/hardware_gpio/include
|
|
||||||
pico-sdk/rp2_common/hardware_resets/include
|
|
||||||
pico-sdk/rp2_common/hardware_pwm/include
|
|
||||||
pico-sdk/rp2_common/hardware_base/include
|
|
||||||
pico-sdk/rp2_common/hardware_uart/include
|
|
||||||
pico-sdk/rp2_common/hardware_spi/include
|
|
||||||
pico-sdk/rp2_common/hardware_i2c/include
|
|
||||||
pico-sdk/rp2_common/hardware_irq/include
|
|
||||||
pico-sdk/rp2_common/hardware_flash/include
|
|
||||||
pico-sdk/rp2_common/hardware_clocks/include
|
|
||||||
pico-sdk/rp2_common/hardware_rtc/include
|
|
||||||
pico-sdk/rp2_common/hardware_watchdog/include
|
|
||||||
pico-sdk/rp2_common/hardware_timer/include
|
|
||||||
pico-sdk/rp2_common/hardware_pll/include
|
|
||||||
pico-sdk/rp2_common/hardware_sync/include
|
|
||||||
pico-sdk/rp2_common/hardware_xosc/include
|
|
||||||
pico-sdk/rp2_common/pico_platform/include
|
|
||||||
pico-sdk/rp2_common/pico_fix/rp2040_usb_device_enumeration/include/
|
|
||||||
pico-sdk/rp2_common/pico_bootrom/include
|
|
||||||
pico-sdk/rp2_common/hardware_claim/include
|
|
||||||
pico-sdk/rp2040/hardware_structs/include
|
|
||||||
pico-sdk/rp2040/hardware_regs/include
|
|
||||||
pico-sdk/common/pico_sync/include
|
|
||||||
pico-sdk/common/pico_time/include
|
|
||||||
pico-sdk/common/pico_base/include
|
|
||||||
pico-sdk/common/pico_binary_info/include
|
|
||||||
pico-sdk/common/pico_util/include
|
|
||||||
pico-sdk/boards/include
|
|
||||||
pico-sdk/generated
|
|
||||||
.
|
.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -59,27 +27,7 @@ target_sources(mbed-rp2040
|
||||||
us_ticker.c
|
us_ticker.c
|
||||||
USBPhy_RP2040.cpp
|
USBPhy_RP2040.cpp
|
||||||
watchdog_api.c
|
watchdog_api.c
|
||||||
pico-sdk/rp2_common/pico_standard_link/crt0.S
|
TOOLCHAIN_GCC_ARM/crt0_mbed.S
|
||||||
pico-sdk/rp2_common/hardware_flash/flash.c
|
|
||||||
pico-sdk/rp2_common/hardware_uart/uart.c
|
|
||||||
pico-sdk/rp2_common/hardware_spi/spi.c
|
|
||||||
pico-sdk/rp2_common/hardware_i2c/i2c.c
|
|
||||||
pico-sdk/rp2_common/hardware_gpio/gpio.c
|
|
||||||
pico-sdk/rp2_common/hardware_xosc/xosc.c
|
|
||||||
pico-sdk/rp2_common/hardware_irq/irq.c
|
|
||||||
pico-sdk/rp2_common/hardware_irq/irq_handler_chain.S
|
|
||||||
pico-sdk/rp2_common/hardware_pll/pll.c
|
|
||||||
pico-sdk/rp2_common/hardware_watchdog/watchdog.c
|
|
||||||
pico-sdk/rp2_common/hardware_clocks/clocks.c
|
|
||||||
pico-sdk/rp2_common/hardware_claim/claim.c
|
|
||||||
pico-sdk/rp2_common/hardware_timer/timer.c
|
|
||||||
pico-sdk/rp2_common/hardware_sync/sync.c
|
|
||||||
pico-sdk/rp2_common/hardware_rtc/rtc.c
|
|
||||||
pico-sdk/rp2_common/pico_bootrom/bootrom.c
|
|
||||||
pico-sdk/rp2_common/pico_platform/platform.c
|
|
||||||
pico-sdk/common/pico_time/time.c
|
|
||||||
pico-sdk/common/pico_sync/lock_core.c
|
|
||||||
pico-sdk/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
mbed_set_linker_script(mbed-rp2040 ${CMAKE_CURRENT_SOURCE_DIR}/${LINKER_FILE})
|
mbed_set_linker_script(mbed-rp2040 ${CMAKE_CURRENT_SOURCE_DIR}/${LINKER_FILE})
|
||||||
|
|
|
@ -10,7 +10,6 @@ target_include_directories(mbed-raspberry-pi-pico
|
||||||
|
|
||||||
target_sources(mbed-raspberry-pi-pico
|
target_sources(mbed-raspberry-pi-pico
|
||||||
INTERFACE
|
INTERFACE
|
||||||
board.c
|
|
||||||
bs2_default_padded_checksummed.S
|
bs2_default_padded_checksummed.S
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
#include "PinNames.h"
|
|
||||||
|
|
||||||
uint32_t SystemCoreClock = 125000000;
|
|
|
@ -4,8 +4,10 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "pico.h"
|
||||||
|
#include "pico/asm_helper.S"
|
||||||
|
|
||||||
#include "hardware/regs/m0plus.h"
|
#include "hardware/regs/m0plus.h"
|
||||||
#include "hardware/platform_defs.h"
|
|
||||||
#include "hardware/regs/addressmap.h"
|
#include "hardware/regs/addressmap.h"
|
||||||
#include "hardware/regs/sio.h"
|
#include "hardware/regs/sio.h"
|
||||||
#include "pico/binary_info/defs.h"
|
#include "pico/binary_info/defs.h"
|
||||||
|
@ -16,22 +18,21 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.syntax unified
|
pico_default_asm_setup
|
||||||
.cpu cortex-m0plus
|
|
||||||
.thumb
|
|
||||||
|
|
||||||
.section .vectors, "ax"
|
.section .vectors, "ax"
|
||||||
.align 2
|
.align 2
|
||||||
|
|
||||||
.global __vectors
|
.global __vectors, __VECTOR_TABLE
|
||||||
|
__VECTOR_TABLE:
|
||||||
__vectors:
|
__vectors:
|
||||||
.word __StackTop
|
.word __StackTop
|
||||||
.word _reset_handler
|
.word _reset_handler
|
||||||
.word isr_nmi
|
.word NMI_Handler
|
||||||
.word HardFault_Handler
|
.word HardFault_Handler
|
||||||
.word MemManage_Handler
|
.word isr_invalid // Reserved, should never fire
|
||||||
.word BusFault_Handler
|
.word isr_invalid // Reserved, should never fire
|
||||||
.word UsageFault_Handler
|
.word isr_invalid // Reserved, should never fire
|
||||||
.word isr_invalid // Reserved, should never fire
|
.word isr_invalid // Reserved, should never fire
|
||||||
.word isr_invalid // Reserved, should never fire
|
.word isr_invalid // Reserved, should never fire
|
||||||
.word isr_invalid // Reserved, should never fire
|
.word isr_invalid // Reserved, should never fire
|
||||||
|
@ -41,38 +42,43 @@ __vectors:
|
||||||
.word isr_invalid // Reserved, should never fire
|
.word isr_invalid // Reserved, should never fire
|
||||||
.word PendSV_Handler
|
.word PendSV_Handler
|
||||||
.word SysTick_Handler
|
.word SysTick_Handler
|
||||||
.word isr_irq0
|
.word TIMER_IRQ_0_Handler
|
||||||
.word isr_irq1
|
.word TIMER_IRQ_1_Handler
|
||||||
.word isr_irq2
|
.word TIMER_IRQ_2_Handler
|
||||||
.word isr_irq3
|
.word TIMER_IRQ_3_Handler
|
||||||
.word isr_irq4
|
.word PWM_IRQ_WRAP_Handler
|
||||||
.word isr_irq5
|
.word USBCTRL_IRQ_Handler
|
||||||
.word isr_irq6
|
.word XIP_IRQ_Handler
|
||||||
.word isr_irq7
|
.word PIO0_IRQ_0_Handler
|
||||||
.word isr_irq8
|
.word PIO0_IRQ_1_Handler
|
||||||
.word isr_irq9
|
.word PIO1_IRQ_0_Handler
|
||||||
.word isr_irq10
|
.word TIMER_IRQ_1_Handler0
|
||||||
.word isr_irq11
|
.word TIMER_IRQ_1_Handler1
|
||||||
.word isr_irq12
|
.word TIMER_IRQ_1_Handler2
|
||||||
.word isr_irq13
|
.word TIMER_IRQ_1_Handler3
|
||||||
.word isr_irq14
|
.word TIMER_IRQ_1_Handler4
|
||||||
.word isr_irq15
|
.word TIMER_IRQ_1_Handler5
|
||||||
.word isr_irq16
|
.word TIMER_IRQ_1_Handler6
|
||||||
.word isr_irq17
|
.word TIMER_IRQ_1_Handler7
|
||||||
.word isr_irq18
|
.word TIMER_IRQ_1_Handler8
|
||||||
.word isr_irq19
|
.word TIMER_IRQ_1_Handler9
|
||||||
.word isr_irq20
|
.word TIMER_IRQ_2_Handler0
|
||||||
.word isr_irq21
|
.word TIMER_IRQ_2_Handler1
|
||||||
.word isr_irq22
|
.word TIMER_IRQ_2_Handler2
|
||||||
.word isr_irq23
|
.word TIMER_IRQ_2_Handler3
|
||||||
.word isr_irq24
|
.word TIMER_IRQ_2_Handler4
|
||||||
.word isr_irq25
|
.word TIMER_IRQ_2_Handler5
|
||||||
.word isr_irq26
|
.word TIMER_IRQ_2_Handler6
|
||||||
.word isr_irq27
|
.word TIMER_IRQ_2_Handler7
|
||||||
.word isr_irq28
|
.word TIMER_IRQ_2_Handler8
|
||||||
.word isr_irq29
|
.word TIMER_IRQ_2_Handler9
|
||||||
.word isr_irq30
|
.word TIMER_IRQ_3_Handler0
|
||||||
.word isr_irq31
|
.word TIMER_IRQ_3_Handler1
|
||||||
|
|
||||||
|
// all default exception handlers do nothing, and we can check for them being set to our
|
||||||
|
// default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end
|
||||||
|
.global __default_isrs_start
|
||||||
|
__default_isrs_start:
|
||||||
|
|
||||||
// Declare a weak symbol for each ISR.
|
// Declare a weak symbol for each ISR.
|
||||||
// By default, they will fall through to the undefined IRQ handler below (breakpoint),
|
// By default, they will fall through to the undefined IRQ handler below (breakpoint),
|
||||||
|
@ -88,12 +94,15 @@ __vectors:
|
||||||
|
|
||||||
// these are separated out for clarity
|
// these are separated out for clarity
|
||||||
decl_isr_bkpt isr_invalid
|
decl_isr_bkpt isr_invalid
|
||||||
decl_isr_bkpt isr_nmi
|
decl_isr_bkpt NMI_Handler
|
||||||
decl_isr_bkpt HardFault_Handler
|
decl_isr_bkpt HardFault_Handler
|
||||||
decl_isr_bkpt SVC_Handler
|
decl_isr_bkpt SVC_Handler
|
||||||
decl_isr_bkpt PendSV_Handler
|
decl_isr_bkpt PendSV_Handler
|
||||||
decl_isr_bkpt SysTick_Handler
|
decl_isr_bkpt SysTick_Handler
|
||||||
|
|
||||||
|
.global __default_isrs_end
|
||||||
|
__default_isrs_end:
|
||||||
|
|
||||||
.macro decl_isr name
|
.macro decl_isr name
|
||||||
.weak \name
|
.weak \name
|
||||||
.type \name,%function
|
.type \name,%function
|
||||||
|
@ -101,44 +110,44 @@ decl_isr_bkpt SysTick_Handler
|
||||||
\name:
|
\name:
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
decl_isr isr_irq0
|
decl_isr TIMER_IRQ_0_Handler
|
||||||
decl_isr isr_irq1
|
decl_isr TIMER_IRQ_1_Handler
|
||||||
decl_isr isr_irq2
|
decl_isr TIMER_IRQ_2_Handler
|
||||||
decl_isr isr_irq3
|
decl_isr TIMER_IRQ_3_Handler
|
||||||
decl_isr isr_irq4
|
decl_isr PWM_IRQ_WRAP_Handler
|
||||||
decl_isr isr_irq5
|
decl_isr USBCTRL_IRQ_Handler
|
||||||
decl_isr isr_irq6
|
decl_isr XIP_IRQ_Handler
|
||||||
decl_isr isr_irq7
|
decl_isr PIO0_IRQ_0_Handler
|
||||||
decl_isr isr_irq8
|
decl_isr PIO0_IRQ_1_Handler
|
||||||
decl_isr isr_irq9
|
decl_isr PIO1_IRQ_0_Handler
|
||||||
decl_isr isr_irq10
|
decl_isr TIMER_IRQ_1_Handler0
|
||||||
decl_isr isr_irq11
|
decl_isr TIMER_IRQ_1_Handler1
|
||||||
decl_isr isr_irq12
|
decl_isr TIMER_IRQ_1_Handler2
|
||||||
decl_isr isr_irq13
|
decl_isr TIMER_IRQ_1_Handler3
|
||||||
decl_isr isr_irq14
|
decl_isr TIMER_IRQ_1_Handler4
|
||||||
decl_isr isr_irq15
|
decl_isr TIMER_IRQ_1_Handler5
|
||||||
decl_isr isr_irq16
|
decl_isr TIMER_IRQ_1_Handler6
|
||||||
decl_isr isr_irq17
|
decl_isr TIMER_IRQ_1_Handler7
|
||||||
decl_isr isr_irq18
|
decl_isr TIMER_IRQ_1_Handler8
|
||||||
decl_isr isr_irq19
|
decl_isr TIMER_IRQ_1_Handler9
|
||||||
decl_isr isr_irq20
|
decl_isr TIMER_IRQ_2_Handler0
|
||||||
decl_isr isr_irq21
|
decl_isr TIMER_IRQ_2_Handler1
|
||||||
decl_isr isr_irq22
|
decl_isr TIMER_IRQ_2_Handler2
|
||||||
decl_isr isr_irq23
|
decl_isr TIMER_IRQ_2_Handler3
|
||||||
decl_isr isr_irq24
|
decl_isr TIMER_IRQ_2_Handler4
|
||||||
decl_isr isr_irq25
|
decl_isr TIMER_IRQ_2_Handler5
|
||||||
decl_isr isr_irq26
|
decl_isr TIMER_IRQ_2_Handler6
|
||||||
decl_isr isr_irq27
|
decl_isr TIMER_IRQ_2_Handler7
|
||||||
decl_isr isr_irq28
|
decl_isr TIMER_IRQ_2_Handler8
|
||||||
decl_isr isr_irq29
|
decl_isr TIMER_IRQ_2_Handler9
|
||||||
decl_isr isr_irq30
|
decl_isr TIMER_IRQ_3_Handler0
|
||||||
decl_isr isr_irq31
|
decl_isr TIMER_IRQ_3_Handler1
|
||||||
|
|
||||||
// All unhandled USER IRQs fall through to here
|
// All unhandled USER IRQs fall through to here
|
||||||
.global __unhandled_user_irq
|
.global __unhandled_user_irq
|
||||||
.thumb_func
|
.thumb_func
|
||||||
__unhandled_user_irq:
|
__unhandled_user_irq:
|
||||||
bl __get_current_exception
|
mrs r0, ipsr
|
||||||
subs r0, #16
|
subs r0, #16
|
||||||
.global unhandled_user_irq_num_in_r0
|
.global unhandled_user_irq_num_in_r0
|
||||||
unhandled_user_irq_num_in_r0:
|
unhandled_user_irq_num_in_r0:
|
||||||
|
@ -216,6 +225,9 @@ _reset_handler:
|
||||||
cmp r0, #0
|
cmp r0, #0
|
||||||
bne hold_non_core0_in_bootrom
|
bne hold_non_core0_in_bootrom
|
||||||
|
|
||||||
|
// In a NO_FLASH binary, don't perform .data copy, since it's loaded
|
||||||
|
// in-place by the SRAM load. Still need to clear .bss
|
||||||
|
#if !PICO_NO_FLASH
|
||||||
adr r4, data_cpy_table
|
adr r4, data_cpy_table
|
||||||
|
|
||||||
// assume there is at least one entry
|
// assume there is at least one entry
|
||||||
|
@ -226,6 +238,7 @@ _reset_handler:
|
||||||
bl data_cpy
|
bl data_cpy
|
||||||
b 1b
|
b 1b
|
||||||
2:
|
2:
|
||||||
|
#endif
|
||||||
|
|
||||||
// Zero out the BSS
|
// Zero out the BSS
|
||||||
ldr r1, =__bss_start__
|
ldr r1, =__bss_start__
|
||||||
|
@ -241,22 +254,18 @@ bss_fill_test:
|
||||||
platform_entry: // symbol for stack traces
|
platform_entry: // symbol for stack traces
|
||||||
// Use 32-bit jumps, in case these symbols are moved out of branch range
|
// Use 32-bit jumps, in case these symbols are moved out of branch range
|
||||||
// (e.g. if main is in SRAM and crt0 in flash)
|
// (e.g. if main is in SRAM and crt0 in flash)
|
||||||
//ldr r1, =runtime_init
|
// Mbed OS: Changed this to call _start() instead of runtime_init() and main()
|
||||||
//blx r1
|
|
||||||
ldr r1, =_start
|
ldr r1, =_start
|
||||||
blx r1
|
blx r1
|
||||||
ldr r1, =exit
|
ldr r1, =exit
|
||||||
blx r1
|
blx r1
|
||||||
// exit should not return. If it does, hang the core.
|
// exit should not return. If it does, hang the core.
|
||||||
// (fall thru into our hang _exit impl
|
// (fall thru into our hang _exit impl
|
||||||
.weak _exit
|
|
||||||
.type _exit,%function
|
|
||||||
.thumb_func
|
|
||||||
_exit:
|
|
||||||
1: // separate label because _exit can be moved out of branch range
|
1: // separate label because _exit can be moved out of branch range
|
||||||
bkpt #0
|
bkpt #0
|
||||||
b 1b
|
b 1b
|
||||||
|
|
||||||
|
#if !PICO_NO_FLASH
|
||||||
data_cpy_loop:
|
data_cpy_loop:
|
||||||
ldm r1!, {r0}
|
ldm r1!, {r0}
|
||||||
stm r2!, {r0}
|
stm r2!, {r0}
|
||||||
|
@ -264,6 +273,10 @@ data_cpy:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
blo data_cpy_loop
|
blo data_cpy_loop
|
||||||
bx lr
|
bx lr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Note the data copy table is still included for NO_FLASH builds, even though
|
||||||
|
// we skip the copy, because it is listed in binary info
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
data_cpy_table:
|
data_cpy_table:
|
||||||
|
@ -306,10 +319,3 @@ hold_non_core0_in_bootrom:
|
||||||
ldr r0, = 'W' | ('V' << 8)
|
ldr r0, = 'W' | ('V' << 8)
|
||||||
bl rom_func_lookup
|
bl rom_func_lookup
|
||||||
bx r0
|
bx r0
|
||||||
|
|
||||||
.global __get_current_exception
|
|
||||||
.thumb_func
|
|
||||||
__get_current_exception:
|
|
||||||
mrs r0, ipsr
|
|
||||||
uxtb r0, r0
|
|
||||||
bx lr
|
|
|
@ -18,25 +18,27 @@
|
||||||
__HeapLimit
|
__HeapLimit
|
||||||
__StackLimit
|
__StackLimit
|
||||||
__StackTop
|
__StackTop
|
||||||
|
__StackBottom (== __StackLimit)
|
||||||
__stack (== StackTop)
|
__stack (== StackTop)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../cmsis_nvic.h"
|
||||||
|
|
||||||
#if !defined(MBED_CONF_TARGET_BOOT_STACK_SIZE)
|
#if !defined(MBED_CONF_TARGET_BOOT_STACK_SIZE)
|
||||||
/* This value is normally defined by the tools
|
/* This value is normally defined by the tools
|
||||||
to 0x1000 for bare metal and 0x400 for RTOS */
|
to 0x1000 for bare metal and 0x400 for RTOS */
|
||||||
#define MBED_CONF_TARGET_BOOT_STACK_SIZE 0x400
|
#define MBED_CONF_TARGET_BOOT_STACK_SIZE 0x400
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(PICO_FLASH_SIZE_BYTES)
|
|
||||||
/* This value is normally defined by the tools
|
|
||||||
to 0x1000 for bare metal and 0x400 for RTOS */
|
|
||||||
#define PICO_FLASH_SIZE_BYTES 2048k
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
FLASH(rx) : ORIGIN = 0x10000000, LENGTH = PICO_FLASH_SIZE_BYTES
|
FLASH(rx) : ORIGIN = MBED_ROM_START, LENGTH = MBED_ROM_SIZE
|
||||||
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
|
RAM(rwx) : ORIGIN = MBED_RAM_START, LENGTH = MBED_RAM_SIZE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scratch banks are commonly used for critical data and functions accessed only by one core (when only
|
||||||
|
* one core is accessing the RAM bank, there is no opportunity for stalls).
|
||||||
|
*/
|
||||||
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
|
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
|
||||||
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
|
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
|
||||||
}
|
}
|
||||||
|
@ -127,7 +129,7 @@ SECTIONS
|
||||||
/* End of .text-like segments */
|
/* End of .text-like segments */
|
||||||
__etext = .;
|
__etext = .;
|
||||||
|
|
||||||
.ram_vector_table (COPY): {
|
.ram_vector_table (NOLOAD): {
|
||||||
*(.ram_vector_table)
|
*(.ram_vector_table)
|
||||||
} > RAM
|
} > RAM
|
||||||
|
|
||||||
|
@ -177,7 +179,7 @@ SECTIONS
|
||||||
__data_end__ = .;
|
__data_end__ = .;
|
||||||
} > RAM AT> FLASH
|
} > RAM AT> FLASH
|
||||||
|
|
||||||
.uninitialized_data (COPY): {
|
.uninitialized_data (NOLOAD): {
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
*(.uninitialized_data*)
|
*(.uninitialized_data*)
|
||||||
} > RAM
|
} > RAM
|
||||||
|
@ -208,7 +210,7 @@ SECTIONS
|
||||||
__bss_end__ = .;
|
__bss_end__ = .;
|
||||||
} > RAM
|
} > RAM
|
||||||
|
|
||||||
.heap (COPY):
|
.heap (NOLOAD):
|
||||||
{
|
{
|
||||||
__end__ = .;
|
__end__ = .;
|
||||||
PROVIDE(end = .);
|
PROVIDE(end = .);
|
||||||
|
@ -217,35 +219,14 @@ SECTIONS
|
||||||
__HeapLimit = .;
|
__HeapLimit = .;
|
||||||
} > RAM
|
} > RAM
|
||||||
|
|
||||||
/* .stack*_dummy section doesn't contains any symbols. It is only
|
|
||||||
* used for linker to calculate size of stack sections, and assign
|
|
||||||
* values to stack symbols later
|
|
||||||
*
|
|
||||||
* stack1 section may be empty/missing if platform_launch_core1 is not used */
|
|
||||||
|
|
||||||
/* by default we put core 0 stack at the end of scratch Y, so that if core 1
|
|
||||||
* stack is not used then all of SCRATCH_X is free.
|
|
||||||
*/
|
|
||||||
.stack1_dummy (COPY):
|
|
||||||
{
|
|
||||||
*(.stack1*)
|
|
||||||
} > SCRATCH_X
|
|
||||||
|
|
||||||
.stack_dummy (COPY):
|
|
||||||
{
|
|
||||||
*(.stack*)
|
|
||||||
} > RAM
|
|
||||||
|
|
||||||
.flash_end : {
|
.flash_end : {
|
||||||
__flash_binary_end = .;
|
PROVIDE(__flash_binary_end = .);
|
||||||
} > FLASH
|
} > FLASH
|
||||||
|
|
||||||
/* stack limit is poorly named, but historically is maximum heap ptr */
|
/* stack limit is poorly named, but historically is maximum heap ptr */
|
||||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
__StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
|
||||||
__StackLimit = __StackTop - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
__StackLimit = __StackTop - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
||||||
__StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
|
__StackBottom = __StackLimit;
|
||||||
__StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
|
|
||||||
__StackBottom = __StackTop - SIZEOF(.stack_dummy);
|
|
||||||
PROVIDE(__stack = __StackTop);
|
PROVIDE(__stack = __StackTop);
|
||||||
|
|
||||||
/* Check if data + heap + stack exceeds RAM limit */
|
/* Check if data + heap + stack exceeds RAM limit */
|
|
@ -69,7 +69,7 @@ void USBPhyHw::init(USBPhyEvents *events)
|
||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
// Disable IRQ
|
// Disable IRQ
|
||||||
NVIC_DisableIRQ(USBCTRL_IRQn);
|
NVIC_DisableIRQ(USBCTRL_IRQ_IRQn);
|
||||||
|
|
||||||
// Reset usb controller
|
// Reset usb controller
|
||||||
reset_block(RESETS_RESET_USBCTRL_BITS);
|
reset_block(RESETS_RESET_USBCTRL_BITS);
|
||||||
|
@ -88,15 +88,15 @@ void USBPhyHw::init(USBPhyEvents *events)
|
||||||
usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS;
|
usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS;
|
||||||
|
|
||||||
// Enable IRQ
|
// Enable IRQ
|
||||||
NVIC_SetVector(USBCTRL_IRQn, (uint32_t)&_usbisr);
|
NVIC_SetVector(USBCTRL_IRQ_IRQn, (uint32_t)&_usbisr);
|
||||||
NVIC_EnableIRQ(USBCTRL_IRQn);
|
NVIC_EnableIRQ(USBCTRL_IRQ_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::deinit()
|
void USBPhyHw::deinit()
|
||||||
{
|
{
|
||||||
// Disconnect and disable interrupt
|
// Disconnect and disable interrupt
|
||||||
disconnect();
|
disconnect();
|
||||||
NVIC_DisableIRQ(USBCTRL_IRQn);
|
NVIC_DisableIRQ(USBCTRL_IRQ_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USBPhyHw::powered()
|
bool USBPhyHw::powered()
|
||||||
|
@ -412,8 +412,8 @@ again:
|
||||||
events->reset();
|
events->reset();
|
||||||
|
|
||||||
// Re-enable interrupt
|
// Re-enable interrupt
|
||||||
NVIC_ClearPendingIRQ(USBCTRL_IRQn);
|
NVIC_ClearPendingIRQ(USBCTRL_IRQ_IRQn);
|
||||||
NVIC_EnableIRQ(USBCTRL_IRQn);
|
NVIC_EnableIRQ(USBCTRL_IRQ_IRQn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,20 +503,20 @@ again:
|
||||||
// This is only for debug while developing the driver
|
// This is only for debug while developing the driver
|
||||||
if(usb_hw->ints & ~16)
|
if(usb_hw->ints & ~16)
|
||||||
{
|
{
|
||||||
volatile int ints = usb_hw->ints;
|
//volatile int ints = usb_hw->ints;
|
||||||
volatile int going = 1;
|
//volatile int going = 1;
|
||||||
goto again;
|
|
||||||
//while(ints && going);
|
//while(ints && going);
|
||||||
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Re-enable interrupt
|
// Re-enable interrupt
|
||||||
NVIC_ClearPendingIRQ(USBCTRL_IRQn);
|
NVIC_ClearPendingIRQ(USBCTRL_IRQ_IRQn);
|
||||||
NVIC_EnableIRQ(USBCTRL_IRQn);
|
NVIC_EnableIRQ(USBCTRL_IRQ_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBPhyHw::_usbisr(void)
|
void USBPhyHw::_usbisr(void)
|
||||||
{
|
{
|
||||||
NVIC_DisableIRQ(USBCTRL_IRQn);
|
NVIC_DisableIRQ(USBCTRL_IRQ_IRQn);
|
||||||
instance->events->start_process();
|
instance->events->start_process();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ void analogin_init(analogin_t *obj, PinName pin)
|
||||||
/* Lookup the corresponding ADC channel for a given pin. */
|
/* Lookup the corresponding ADC channel for a given pin. */
|
||||||
obj->channel = pinmap_find_function(pin, PinMap_ADC);
|
obj->channel = pinmap_find_function(pin, PinMap_ADC);
|
||||||
/* Make sure GPIO is high-impedance, no pullups etc. */
|
/* Make sure GPIO is high-impedance, no pullups etc. */
|
||||||
adc_gpio_init(pin);
|
adc_pico_sdk_gpio_init(pin);
|
||||||
/* Check if the ADC channel we just configured belongs to the
|
/* Check if the ADC channel we just configured belongs to the
|
||||||
* temperature sensor. If that's the case, enable the temperature
|
* temperature sensor. If that's the case, enable the temperature
|
||||||
* sensor.
|
* sensor.
|
||||||
|
|
|
@ -1,60 +1,8 @@
|
||||||
#ifndef __RP2040_H__
|
#ifndef __RP2040_H__
|
||||||
#define __RP2040_H__
|
#define __RP2040_H__
|
||||||
|
|
||||||
typedef enum IRQn
|
#include "RP2040.h"
|
||||||
{
|
#include "system_RP2040.h"
|
||||||
/* ToDo: use this Cortex interrupt numbers if your device is a CORTEX-M0 device */
|
|
||||||
NonMaskableInt_IRQn = -14, /*!< 2 Cortex-M0 Non Maskable Interrupt */
|
|
||||||
HardFault_IRQn = -13, /*!< 3 Cortex-M0 Hard Fault Interrupt */
|
|
||||||
SVCall_IRQn = -5, /*!< 11 Cortex-M0 SV Call Interrupt */
|
|
||||||
PendSV_IRQn = -2, /*!< 14 Cortex-M0 Pend SV Interrupt */
|
|
||||||
SysTick_IRQn = -1, /*!< 15 Cortex-M0 System Tick Interrupt */
|
|
||||||
|
|
||||||
/* ---------------------- RP2040 Specific Interrupt Numbers ------------------ */
|
|
||||||
TIMER_IRQ_0n = 0, /*!< */
|
|
||||||
TIMER_IRQ_1n = 1, /*!< */
|
|
||||||
TIMER_IRQ_2n = 2, /*!< */
|
|
||||||
TIMER_IRQ_3n = 3, /*!< */
|
|
||||||
PWM_IRQ_WRAPn = 4, /*!< */
|
|
||||||
USBCTRL_IRQn = 5, /*!< */
|
|
||||||
XIP_IRQn = 6, /*!< */
|
|
||||||
PIO0_IRQ_0n = 7, /*!< */
|
|
||||||
PIO0_IRQ_1n = 8, /*!< */
|
|
||||||
PIO1_IRQ_0n = 9, /*!< */
|
|
||||||
PIO1_IRQ_1n = 10, /*!< */
|
|
||||||
DMA_IRQ_0n = 11, /*!< */
|
|
||||||
DMA_IRQ_1n = 12, /*!< */
|
|
||||||
IO_IRQ_BANK0n = 13, /*!< */
|
|
||||||
IO_IRQ_QSPIn = 14, /*!< */
|
|
||||||
SIO_IRQ_PROC0n = 15, /*!< */
|
|
||||||
SIO_IRQ_PROC1n = 16, /*!< */
|
|
||||||
CLOCKS_IRQn = 17, /*!< */
|
|
||||||
SPI0_IRQn = 18, /*!< */
|
|
||||||
SPI1_IRQn = 19, /*!< */
|
|
||||||
UART0_IRQn = 20, /*!< */
|
|
||||||
UART1_IRQn = 21, /*!< */
|
|
||||||
ADC_IRQ_FIFOn = 22, /*!< */
|
|
||||||
I2C0_IRQn = 23, /*!< */
|
|
||||||
I2C1_IRQn = 24, /*!< */
|
|
||||||
RTC_IRQn = 25, /*!< */
|
|
||||||
} IRQn_Type;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ==========================================================================
|
|
||||||
* ----------- Processor and Core Peripheral Section ------------------------
|
|
||||||
* ==========================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Configuration of the Cortex-M0+ Processor and Core Peripherals */
|
|
||||||
#define __CM0PLUS_REV 0x0000 /* Core revision r0p0 */
|
|
||||||
#define __MPU_PRESENT 0 /* MPU present or not */
|
|
||||||
#define __VTOR_PRESENT 1 /* VTOR present or not */
|
|
||||||
#define __NVIC_PRIO_BITS 2 /* Number of Bits used for Priority Levels */
|
|
||||||
#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */
|
|
||||||
|
|
||||||
#include "core_cm0plus.h"
|
|
||||||
#include "cmsis_nvic.h"
|
#include "cmsis_nvic.h"
|
||||||
|
|
||||||
extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -28,7 +28,7 @@ void gpio_init(gpio_t *obj, PinName pin)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_gpio_init(obj->pin);
|
pico_sdk_gpio_init(obj->pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t gpio_convert_event(gpio_irq_event event)
|
static uint32_t gpio_convert_event(gpio_irq_event event)
|
||||||
|
|
|
@ -57,7 +57,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
|
||||||
//i2c_frequency(obj->dev, DEFAULT_I2C_BAUDRATE);
|
//i2c_frequency(obj->dev, DEFAULT_I2C_BAUDRATE);
|
||||||
|
|
||||||
/* Initialize the I2C module. */
|
/* Initialize the I2C module. */
|
||||||
_i2c_init(obj->dev, DEFAULT_I2C_BAUDRATE);
|
pico_sdk_i2c_init(obj->dev, DEFAULT_I2C_BAUDRATE);
|
||||||
|
|
||||||
/* Configure GPIO for I2C as alternate function. */
|
/* Configure GPIO for I2C as alternate function. */
|
||||||
gpio_set_function(sda, GPIO_FUNC_I2C);
|
gpio_set_function(sda, GPIO_FUNC_I2C);
|
||||||
|
@ -119,7 +119,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
|
||||||
void i2c_reset(i2c_t *obj)
|
void i2c_reset(i2c_t *obj)
|
||||||
{
|
{
|
||||||
i2c_deinit(obj->dev);
|
i2c_deinit(obj->dev);
|
||||||
_i2c_init(obj->dev, obj->baudrate);
|
pico_sdk_i2c_init(obj->dev, obj->baudrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
const PinMap *i2c_master_sda_pinmap()
|
const PinMap *i2c_master_sda_pinmap()
|
||||||
|
@ -144,7 +144,7 @@ const PinMap *i2c_slave_scl_pinmap()
|
||||||
|
|
||||||
int i2c_stop(i2c_t *obj)
|
int i2c_stop(i2c_t *obj)
|
||||||
{
|
{
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEVICE_I2CSLAVE
|
#if DEVICE_I2CSLAVE
|
||||||
|
@ -193,11 +193,28 @@ int i2c_slave_receive(i2c_t *obj)
|
||||||
*/
|
*/
|
||||||
int i2c_slave_read(i2c_t *obj, char *data, int length)
|
int i2c_slave_read(i2c_t *obj, char *data, int length)
|
||||||
{
|
{
|
||||||
size_t read_len = i2c_read_raw_blocking(obj->dev, (uint8_t *)data, length);
|
int bytes_read = 0;
|
||||||
|
for (size_t i = 0; i < (size_t)length; ++i) {
|
||||||
|
while (!i2c_get_read_available(obj->dev)) {
|
||||||
|
tight_loop_contents();
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_PRINTF("i2c_slave read %d bytes\r\n", read_len);
|
*data = obj->dev->hw->data_cmd;
|
||||||
|
bytes_read++;
|
||||||
|
|
||||||
return read_len;
|
// Check stop condition
|
||||||
|
bool stop = (obj->dev->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_STOP_DET_BITS) != 0;
|
||||||
|
if (stop && !i2c_get_read_available(obj->dev)) {
|
||||||
|
// Clear stop (by reading the register)
|
||||||
|
int clear_stop = obj->dev->hw->clr_stop_det;
|
||||||
|
(void)clear_stop;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Configure I2C as slave or master.
|
/** Configure I2C as slave or master.
|
||||||
|
@ -212,8 +229,9 @@ int i2c_slave_write(i2c_t *obj, const char *data, int length)
|
||||||
|
|
||||||
i2c_write_raw_blocking(obj->dev, (const uint8_t *)data, (size_t)length);
|
i2c_write_raw_blocking(obj->dev, (const uint8_t *)data, (size_t)length);
|
||||||
|
|
||||||
//Clear interrupt
|
// Clear interrupt (by reading the register)
|
||||||
int clear_read_req = i2c_get_hw(obj->dev)->clr_rd_req;
|
int clear_read_req = i2c_get_hw(obj->dev)->clr_rd_req;
|
||||||
|
(void)clear_read_req;
|
||||||
DEBUG_PRINTF("clear_read_req: %d\n", clear_read_req);
|
DEBUG_PRINTF("clear_read_req: %d\n", clear_read_req);
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
|
|
|
@ -43,6 +43,7 @@ void mbed_sdk_init()
|
||||||
// After calling preinit we have enough runtime to do the exciting maths
|
// After calling preinit we have enough runtime to do the exciting maths
|
||||||
// in clocks_init
|
// in clocks_init
|
||||||
clocks_init();
|
clocks_init();
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
|
||||||
// Peripheral clocks should now all be running
|
// Peripheral clocks should now all be running
|
||||||
unreset_block_wait(RESETS_RESET_BITS);
|
unreset_block_wait(RESETS_RESET_BITS);
|
||||||
|
@ -72,9 +73,7 @@ void mbed_sdk_init()
|
||||||
mbed_sdk_inited = 1;
|
mbed_sdk_inited = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note we put at most 4 pieces of binary info in the reset section because that's how much spare space we had
|
// Add a basic "binary info" note which says that this is an Mbed OS program
|
||||||
// (picked the most common ones)... if there is a link failure because of .reset section overflow then move
|
|
||||||
// more out.
|
|
||||||
#define reset_section_attr __attribute__((section(".reset")))
|
#define reset_section_attr __attribute__((section(".reset")))
|
||||||
bi_decl_with_attr(bi_program_name("Mbed OS CE Program"), reset_section_attr)
|
bi_decl_with_attr(bi_program_name("Mbed OS CE Program"), reset_section_attr)
|
||||||
|
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
cmake_policy(SET CMP0079 NEW) # allow inserting of dependencies into our INTERFACE libraries
|
|
||||||
set(PICO_PLATFORM_CMAKE_FILE "" CACHE INTERNAL "")
|
|
||||||
set(PICO_DOXYGEN_PATHS "" CACHE INTERNAL "") # generated each time
|
|
||||||
|
|
||||||
if (NOT PICO_PLATFORM_CMAKE_FILE)
|
|
||||||
set(PICO_PLATFORM_CMAKE_FILE ${CMAKE_CURRENT_LIST_DIR}/${PICO_PLATFORM}.cmake CACHE INTERNAL "")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (NOT EXISTS "${PICO_PLATFORM_CMAKE_FILE}")
|
|
||||||
message(FATAL_ERROR "${PICO_PLATFORM_CMAKE_FILE} does not exist. \
|
|
||||||
Either specify a valid PICO_PLATFORM (or PICO_PLATFORM_CMAKE_FILE).")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/board_setup.cmake)
|
|
||||||
|
|
||||||
# todo add option to disable skip flag
|
|
||||||
function(pico_add_subdirectory subdir)
|
|
||||||
string(TOUPPER ${subdir} subdir_upper)
|
|
||||||
set(replace_flag SKIP_${subdir_upper})
|
|
||||||
if (NOT ${replace_flag})
|
|
||||||
add_subdirectory(${subdir})
|
|
||||||
else ()
|
|
||||||
message("Not including ${subdir} because ${replace_flag} defined.")
|
|
||||||
endif ()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(pico_wrap_function TARGET FUNCNAME)
|
|
||||||
target_link_options(${TARGET} INTERFACE "LINKER:--wrap=${FUNCNAME}")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(pico_add_map_output TARGET)
|
|
||||||
get_target_property(target_type ${TARGET} TYPE)
|
|
||||||
if ("EXECUTABLE" STREQUAL "${target_type}")
|
|
||||||
target_link_options(${TARGET} PRIVATE "LINKER:-Map=$<TARGET_PROPERTY:NAME>${CMAKE_EXECUTABLE_SUFFIX}.map")
|
|
||||||
else ()
|
|
||||||
target_link_options(${TARGET} INTERFACE "LINKER:-Map=$<TARGET_PROPERTY:NAME>${CMAKE_EXECUTABLE_SUFFIX}.map")
|
|
||||||
endif ()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
macro(pico_simple_hardware_target NAME)
|
|
||||||
pico_simple_hardware_headers_target(${NAME})
|
|
||||||
pico_simple_hardware_impl_target(${NAME})
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
macro(pico_simple_hardware_headers_target NAME)
|
|
||||||
if (NOT TARGET hardware_${NAME}_headers)
|
|
||||||
add_library(hardware_${NAME}_headers INTERFACE)
|
|
||||||
|
|
||||||
target_include_directories(hardware_${NAME}_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
||||||
target_link_libraries(hardware_${NAME}_headers INTERFACE pico_base_headers)
|
|
||||||
if (NOT PICO_NO_HARDWARE)
|
|
||||||
target_link_libraries(hardware_${NAME}_headers INTERFACE hardware_structs hardware_claim)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
macro(pico_simple_hardware_headers_only_target NAME)
|
|
||||||
if (NOT TARGET hardware_${NAME})
|
|
||||||
add_library(hardware_${NAME} INTERFACE)
|
|
||||||
|
|
||||||
target_include_directories(hardware_${NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
||||||
target_link_libraries(hardware_${NAME} INTERFACE pico_base_headers)
|
|
||||||
if (NOT PICO_NO_HARDWARE)
|
|
||||||
target_link_libraries(hardware_${NAME} INTERFACE hardware_structs)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
macro(pico_simple_hardware_impl_target NAME)
|
|
||||||
if (NOT TARGET hardware_${NAME})
|
|
||||||
add_library(hardware_${NAME} INTERFACE)
|
|
||||||
|
|
||||||
target_sources(hardware_${NAME} INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/${NAME}.c
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(hardware_${NAME} INTERFACE hardware_${NAME}_headers pico_platform)
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
function(pico_add_doxygen SOURCE_DIR)
|
|
||||||
set(PICO_DOXYGEN_PATHS "${PICO_DOXYGEN_PATHS} ${SOURCE_DIR}" CACHE INTERNAL "")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(pico_add_doxygen_exclude SOURCE_DIR)
|
|
||||||
set(PICO_DOXYGEN_EXCLUDE_PATHS "${PICO_DOXYGEN_EXCLUDE_PATHS} ${SOURCE_DIR}" CACHE INTERNAL "")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
include(${PICO_PLATFORM_CMAKE_FILE})
|
|
|
@ -1,31 +0,0 @@
|
||||||
# PICO_CMAKE_CONFIG: PICO_BOARD, The board name being built for. This is overridable from the user environment, type=string, default=rp2040, group=build
|
|
||||||
if (DEFINED ENV{PICO_BOARD})
|
|
||||||
set(PICO_BOARD $ENV{PICO_BOARD})
|
|
||||||
message("Using PICO_BOARD from environment ('${PICO_BOARD}')")
|
|
||||||
else()
|
|
||||||
if (NOT PICO_BOARD)
|
|
||||||
set(PICO_BOARD "pico")
|
|
||||||
pico_message("Defaulting PICO target board to ${PICO_BOARD} since not specified.")
|
|
||||||
else()
|
|
||||||
message("PICO target board is ${PICO_BOARD}.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
set(PICO_BOARD ${PICO_BOARD} CACHE STRING "PICO target board (e.g. pico)")
|
|
||||||
|
|
||||||
# PICO_CMAKE_CONFIG: PICO_BOARD_CMAKE_DIRS, Directories to look for <PICO_BOARD>.cmake in. This is overridable from the user environment, type=list, default="", group=build
|
|
||||||
if (DEFINED ENV{PICO_BOARD_CMAKE_DIRS})
|
|
||||||
set(PICO_BOARD_CMAKE_DIRS $ENV{PICO_BOARD_CMAKE_DIRS})
|
|
||||||
message("Using PICO_BOARD_CMAKE_DIRS from environment ('${PICO_BOARD_CMAKE_DIRS}')")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
list(APPEND PICO_BOARD_CMAKE_DIRS ${CMAKE_CURRENT_LIST_DIR}/boards)
|
|
||||||
|
|
||||||
pico_find_in_paths(PICO_BOARD_CMAKE_FILE PICO_BOARD_CMAKE_DIRS ${PICO_BOARD}.cmake)
|
|
||||||
if (EXISTS "${PICO_BOARD_CMAKE_FILE}")
|
|
||||||
message("Using CMake board configuration from ${PICO_BOARD_CMAKE_FILE}")
|
|
||||||
include(${PICO_BOARD_CMAKE_FILE} board_config)
|
|
||||||
else()
|
|
||||||
include(boards/generic_board.cmake)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
list(APPEND PICO_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR}/boards/include) # so boards/foo.h can be explicitly included
|
|
|
@ -1,23 +0,0 @@
|
||||||
# For boards without their own cmake file, simply include a header
|
|
||||||
|
|
||||||
# PICO_CMAKE_CONFIG: PICO_BOARD_HEADER_DIRS, Directories to look for <PICO_BOARD>.h in. This is overridable from the user environment, type=list, default="", group=build
|
|
||||||
if (DEFINED ENV{PICO_BOARD_HEADER_DIRS})
|
|
||||||
set(PICO_BOARD_HEADER_DIRS $ENV{PICO_BOARD_HEADER_DIRS})
|
|
||||||
message("Using PICO_BOARD_HEADER_DIRS from environment ('${PICO_BOARD_HEADER_DIRS}')")
|
|
||||||
endif()
|
|
||||||
set(PICO_BOARD_HEADER_DIRS ${PICO_BOARD_HEADER_DIRS} CACHE STRING "PICO board header directories")
|
|
||||||
|
|
||||||
list(APPEND PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR}/include/boards)
|
|
||||||
pico_find_in_paths(PICO_BOARD_HEADER_FILE PICO_BOARD_HEADER_DIRS ${PICO_BOARD}.h)
|
|
||||||
|
|
||||||
if (EXISTS ${PICO_BOARD_HEADER_FILE})
|
|
||||||
message("Using board configuration from ${PICO_BOARD_HEADER_FILE}")
|
|
||||||
list(APPEND PICO_CONFIG_HEADER_FILES ${PICO_BOARD_HEADER_FILE})
|
|
||||||
else()
|
|
||||||
set(msg "Unable to find definition of board '${PICO_BOARD}' (specified by PICO_BOARD):\n")
|
|
||||||
list(JOIN PICO_BOARD_HEADER_DIRS ", " DIRS)
|
|
||||||
string(CONCAT msg ${msg} " Looked for ${PICO_BOARD}.h in ${DIRS} (additional paths specified by PICO_BOARD_HEADER_DIRS)\n")
|
|
||||||
list(JOIN PICO_BOARD_CMAKE_DIRS ", " DIRS)
|
|
||||||
string(CONCAT msg ${msg} " Looked for ${PICO_BOARD}.cmake in ${DIRS} (additional paths specified by PICO_BOARD_CMAKE_DIRS)")
|
|
||||||
message(FATAL_ERROR ${msg})
|
|
||||||
endif()
|
|
|
@ -1,15 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -----------------------------------------------------
|
|
||||||
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
|
|
||||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
|
||||||
// -----------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef _BOARDS_NONE_H
|
|
||||||
#define _BOARDS_NONE_H
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,52 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -----------------------------------------------------
|
|
||||||
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
|
|
||||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
|
||||||
// -----------------------------------------------------
|
|
||||||
|
|
||||||
// This header may be included by other board headers as "boards/pico.h"
|
|
||||||
|
|
||||||
#ifndef _BOARDS_PICO_H
|
|
||||||
#define _BOARDS_PICO_H
|
|
||||||
|
|
||||||
#ifndef PICO_DEFAULT_UART
|
|
||||||
#define PICO_DEFAULT_UART 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_DEFAULT_UART_TX_PIN
|
|
||||||
#define PICO_DEFAULT_UART_TX_PIN 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_DEFAULT_UART_RX_PIN
|
|
||||||
#define PICO_DEFAULT_UART_RX_PIN 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_DEFAULT_LED_PIN
|
|
||||||
#define PICO_DEFAULT_LED_PIN 25
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_FLASH_SPI_CLKDIV
|
|
||||||
#define PICO_FLASH_SPI_CLKDIV 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_FLASH_SIZE_BYTES
|
|
||||||
#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads)
|
|
||||||
#define PICO_SMPS_MODE_PIN 23
|
|
||||||
|
|
||||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
|
||||||
#define PICO_FLOAT_SUPPORT_ROM_V1 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
|
||||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,104 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -----------------------------------------------------
|
|
||||||
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
|
|
||||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
|
||||||
// -----------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef _BOARDS_VGABOARD_H
|
|
||||||
#define _BOARDS_VGABOARD_H
|
|
||||||
|
|
||||||
#ifndef PICO_DEFAULT_UART
|
|
||||||
#define PICO_DEFAULT_UART 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_DEFAULT_UART_TX_PIN
|
|
||||||
#define PICO_DEFAULT_UART_TX_PIN 20
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_DEFAULT_UART_RX_PIN
|
|
||||||
#define PICO_DEFAULT_UART_RX_PIN 21
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_DEFAULT_LED_PIN
|
|
||||||
#define PICO_DEFAULT_LED_PIN 25 // same as Pico
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Audio pins. I2S BCK, LRCK are on the same pins as PWM L/R.
|
|
||||||
// - When outputting I2S, PWM sees BCK and LRCK, which should sound silent as
|
|
||||||
// they are constant duty cycle, and above the filter cutoff
|
|
||||||
// - When outputting PWM, I2S DIN should be low, so I2S should remain silent.
|
|
||||||
#define VGABOARD_I2S_DIN_PIN 26
|
|
||||||
#define VGABOARD_I2S_BCK_PIN 27
|
|
||||||
#define VGABOARD_I2S_LRCK_PIN 28
|
|
||||||
|
|
||||||
#define VGABOARD_PWM_L_PIN 28
|
|
||||||
#define VGABOARD_PWM_R_PIN 27
|
|
||||||
|
|
||||||
#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)
|
|
||||||
#define VGABOARD_SD_CLK_PIN 5
|
|
||||||
#define VGABOARD_SD_CMD_PIN 18
|
|
||||||
#define VGABOARD_SD_DAT0_PIN 19
|
|
||||||
|
|
||||||
// Note buttons are shared with VGA colour LSBs -- if using VGA, you can float
|
|
||||||
// the pin on VSYNC assertion and sample on VSYNC deassertion
|
|
||||||
#define VGABOARD_BUTTON_A_PIN 0
|
|
||||||
#define VGABOARD_BUTTON_B_PIN 6
|
|
||||||
#define VGABOARD_BUTTON_C_PIN 11
|
|
||||||
|
|
||||||
#ifndef PICO_SCANVIDEO_COLOR_PIN_BASE
|
|
||||||
#define PICO_SCANVIDEO_COLOR_PIN_BASE VGABOARD_VGA_COLOR_PIN_BASE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_SCANVIDEO_SYMC_PIN_BASE
|
|
||||||
#define PICO_SCANVIDEO_SYNC_PIN_BASE VGABOARD_VGA_SYNC_PIN_BASE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_SD_CLK_PIN
|
|
||||||
#define PICO_SD_CLK_PIN VGABOARD_SD_CLK_PIN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_SD_CMD_PIN
|
|
||||||
#define PICO_SD_CMD_PIN VGABOARD_SD_CMD_PIN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_SD_DAT0_PIN
|
|
||||||
#define PICO_SD_DAT0_PIN VGABOARD_SD_DAT0_PIN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PICO_AUDIO_I2S_DATA_PIN VGABOARD_I2S_DIN_PIN
|
|
||||||
#define PICO_AUDIO_I2S_CLOCK_PIN_BASE VGABOARD_I2S_BCK_PIN
|
|
||||||
|
|
||||||
#define PICO_AUDIO_PWM_L_PIN VGABOARD_PWM_L_PIN
|
|
||||||
#define PICO_AUDIO_PWM_R_PIN VGABOARD_PWM_R_PIN
|
|
||||||
|
|
||||||
#ifndef PICO_FLASH_SPI_CLKDIV
|
|
||||||
#define PICO_FLASH_SPI_CLKDIV 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_FLASH_SIZE_BYTES
|
|
||||||
#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads)
|
|
||||||
#define PICO_SMPS_MODE_PIN 23
|
|
||||||
|
|
||||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
|
||||||
#define PICO_FLOAT_SUPPORT_ROM_V1 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
|
||||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PICO_VGA_BOARD
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,16 +0,0 @@
|
||||||
pico_add_subdirectory(boot_picoboot)
|
|
||||||
pico_add_subdirectory(boot_uf2)
|
|
||||||
pico_add_subdirectory(pico_base)
|
|
||||||
|
|
||||||
# PICO_CMAKE_CONFIG: PICO_BARE_METAL, Flag to exclude anything except base headers from the build, type=bool, default=0, group=build
|
|
||||||
if (NOT PICO_BARE_METAL)
|
|
||||||
pico_add_subdirectory(pico_bit_ops)
|
|
||||||
pico_add_subdirectory(pico_binary_info)
|
|
||||||
pico_add_subdirectory(pico_divider)
|
|
||||||
pico_add_subdirectory(pico_sync)
|
|
||||||
pico_add_subdirectory(pico_time)
|
|
||||||
pico_add_subdirectory(pico_util)
|
|
||||||
pico_add_subdirectory(pico_stdlib)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
pico_add_doxygen(${CMAKE_CURRENT_LIST_DIR})
|
|
|
@ -1,3 +0,0 @@
|
||||||
This directory code that is common to all builds regardless of `PICO_PLATFORM`. It is a mix
|
|
||||||
of common header files, or high level functionality built entirely using `hardware_` or `pico_` libraries provided
|
|
||||||
by the actual target `PICO_PLATFORM``
|
|
|
@ -1,2 +0,0 @@
|
||||||
add_library(boot_picoboot_headers INTERFACE)
|
|
||||||
target_include_directories(boot_picoboot_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
|
@ -1,124 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _BOOT_PICOBOOT_H
|
|
||||||
#define _BOOT_PICOBOOT_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#ifndef NO_PICO_PLATFORM
|
|
||||||
#include "pico/platform.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \file picoboot.h
|
|
||||||
* \defgroup boot_picoboot boot_picoboot
|
|
||||||
*
|
|
||||||
* Header file for the PICOBOOT USB interface exposed by an RP2040 in BOOTSEL mode.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PICOBOOT_MAGIC 0x431fd10bu
|
|
||||||
|
|
||||||
// --------------------------------------------
|
|
||||||
// CONTROL REQUESTS FOR THE PICOBOOT INTERFACE
|
|
||||||
// --------------------------------------------
|
|
||||||
|
|
||||||
// size 0 OUT - unstall EPs and reset
|
|
||||||
#define PICOBOOT_IF_RESET 0x41
|
|
||||||
|
|
||||||
// size 16 IN - return the status of the last command
|
|
||||||
#define PICOBOOT_IF_CMD_STATUS 0x42
|
|
||||||
|
|
||||||
// --------------------------------------------------
|
|
||||||
// COMMAND REQUESTS SENT TO THE PICOBOOT OUT ENDPOINT
|
|
||||||
// --------------------------------------------------
|
|
||||||
//
|
|
||||||
// picoboot_cmd structure of size 32 is sent to OUT endpoint
|
|
||||||
// transfer_length bytes are transferred via IN/OUT
|
|
||||||
// device responds on success with 0 length ACK packet set via OUT/IN
|
|
||||||
// device may stall the transferring endpoint in case of error
|
|
||||||
|
|
||||||
enum picoboot_cmd_id {
|
|
||||||
PC_EXCLUSIVE_ACCESS = 0x1,
|
|
||||||
PC_REBOOT = 0x2,
|
|
||||||
PC_FLASH_ERASE = 0x3,
|
|
||||||
PC_READ = 0x84, // either RAM or FLASH
|
|
||||||
PC_WRITE = 5, // either RAM or FLASH (does no erase)
|
|
||||||
PC_EXIT_XIP = 0x6,
|
|
||||||
PC_ENTER_CMD_XIP = 0x7,
|
|
||||||
PC_EXEC = 0x8,
|
|
||||||
PC_VECTORIZE_FLASH = 0x9
|
|
||||||
};
|
|
||||||
|
|
||||||
enum picoboot_status {
|
|
||||||
PICOBOOT_OK = 0,
|
|
||||||
PICOBOOT_UNKNOWN_CMD = 1,
|
|
||||||
PICOBOOT_INVALID_CMD_LENGTH = 2,
|
|
||||||
PICOBOOT_INVALID_TRANSFER_LENGTH = 3,
|
|
||||||
PICOBOOT_INVALID_ADDRESS = 4,
|
|
||||||
PICOBOOT_BAD_ALIGNMENT = 5,
|
|
||||||
PICOBOOT_INTERLEAVED_WRITE = 6,
|
|
||||||
PICOBOOT_REBOOTING = 7,
|
|
||||||
PICOBOOT_UNKNOWN_ERROR = 8,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct __packed picoboot_reboot_cmd {
|
|
||||||
uint32_t dPC; // 0 means reset into bootrom
|
|
||||||
uint32_t dSP;
|
|
||||||
uint32_t dDelayMS;
|
|
||||||
};
|
|
||||||
|
|
||||||
// used for EXEC, VECTORIZE_FLASH
|
|
||||||
struct __packed picoboot_address_only_cmd {
|
|
||||||
uint32_t dAddr;
|
|
||||||
};
|
|
||||||
|
|
||||||
// used for READ, WRITE, FLASH_ERASE
|
|
||||||
struct __packed picoboot_range_cmd {
|
|
||||||
uint32_t dAddr;
|
|
||||||
uint32_t dSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum picoboot_exclusive_type {
|
|
||||||
NOT_EXCLUSIVE = 0,
|
|
||||||
EXCLUSIVE,
|
|
||||||
EXCLUSIVE_AND_EJECT
|
|
||||||
};
|
|
||||||
|
|
||||||
struct __packed picoboot_exclusive_cmd {
|
|
||||||
uint8_t bExclusive;
|
|
||||||
};
|
|
||||||
|
|
||||||
// little endian
|
|
||||||
struct __packed __aligned(4) picoboot_cmd {
|
|
||||||
uint32_t dMagic;
|
|
||||||
uint32_t dToken; // an identifier for this token to correlate with a status response
|
|
||||||
uint8_t bCmdId; // top bit set for IN
|
|
||||||
uint8_t bCmdSize; // bytes of actual data in the arg part of this structure
|
|
||||||
uint16_t _unused;
|
|
||||||
uint32_t dTransferLength; // length of IN/OUT transfer (or 0) if none
|
|
||||||
union {
|
|
||||||
uint8_t args[16];
|
|
||||||
struct picoboot_reboot_cmd reboot_cmd;
|
|
||||||
struct picoboot_range_cmd range_cmd;
|
|
||||||
struct picoboot_address_only_cmd address_only_cmd;
|
|
||||||
struct picoboot_exclusive_cmd exclusive_cmd;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(32 == sizeof(struct picoboot_cmd), "picoboot_cmd must be 32 bytes big");
|
|
||||||
|
|
||||||
struct __packed __aligned(4) picoboot_cmd_status {
|
|
||||||
uint32_t dToken;
|
|
||||||
uint32_t dStatusCode;
|
|
||||||
uint8_t bCmdId;
|
|
||||||
uint8_t bInProgress;
|
|
||||||
uint8_t _pad[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(16 == sizeof(struct picoboot_cmd_status), "picoboot_cmd_status must be 16 bytes big");
|
|
||||||
#endif
|
|
|
@ -1,2 +0,0 @@
|
||||||
add_library(boot_uf2_headers INTERFACE)
|
|
||||||
target_include_directories(boot_uf2_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _BOOT_UF2_H
|
|
||||||
#define _BOOT_UF2_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
/** \file uf2.h
|
|
||||||
* \defgroup boot_uf2 boot_uf2
|
|
||||||
*
|
|
||||||
* Header file for the UF2 format supported by an RP2040 in BOOTSEL mode.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define UF2_MAGIC_START0 0x0A324655u
|
|
||||||
#define UF2_MAGIC_START1 0x9E5D5157u
|
|
||||||
#define UF2_MAGIC_END 0x0AB16F30u
|
|
||||||
|
|
||||||
#define UF2_FLAG_NOT_MAIN_FLASH 0x00000001u
|
|
||||||
#define UF2_FLAG_FILE_CONTAINER 0x00001000u
|
|
||||||
#define UF2_FLAG_FAMILY_ID_PRESENT 0x00002000u
|
|
||||||
#define UF2_FLAG_MD5_PRESENT 0x00004000u
|
|
||||||
|
|
||||||
#define RP2040_FAMILY_ID 0xe48bff56
|
|
||||||
|
|
||||||
struct uf2_block {
|
|
||||||
// 32 byte header
|
|
||||||
uint32_t magic_start0;
|
|
||||||
uint32_t magic_start1;
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t target_addr;
|
|
||||||
uint32_t payload_size;
|
|
||||||
uint32_t block_no;
|
|
||||||
uint32_t num_blocks;
|
|
||||||
uint32_t file_size; // or familyID;
|
|
||||||
uint8_t data[476];
|
|
||||||
uint32_t magic_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(struct uf2_block) == 512, "uf2_block not sector sized");
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,40 +0,0 @@
|
||||||
if (NOT TARGET pico_base_headers)
|
|
||||||
# build the auto gen config headers
|
|
||||||
|
|
||||||
set(header_content "// AUTOGENERATED FROM PICO_CONFIG_HEADER_FILES and then PICO_<PLATFORM>_CONFIG_HEADER_FILES\n// DO NOT EDIT!\n")
|
|
||||||
string(TOUPPER ${PICO_PLATFORM} PICO_PLATFORM_UPPER)
|
|
||||||
|
|
||||||
macro(add_header_content_from_var VAR)
|
|
||||||
set(header_content "${header_content}\n\n// based on ${VAR}:\n")
|
|
||||||
foreach(var IN LISTS ${VAR})
|
|
||||||
set(header_content "${header_content}\n#include \"${var}\"")
|
|
||||||
endforeach()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# PICO_CMAKE_CONFIG: PICO_CONFIG_HEADER_FILES, List of extra header files to include from pico/config.h for all platforms, type=list, default="", group=pico_base
|
|
||||||
add_header_content_from_var(PICO_CONFIG_HEADER_FILES)
|
|
||||||
|
|
||||||
# PICO_CMAKE_CONFIG: PICO_CONFIG_RP2040_HEADER_FILES, List of extra header files to include from pico/config.h for rp2040 platform, type=list, default="", group=pico_base
|
|
||||||
# PICO_CMAKE_CONFIG: PICO_CONFIG_HOST_HEADER_FILES, List of extra header files to include from pico/config.h for host platform, type=list, default="", group=pico_base
|
|
||||||
add_header_content_from_var(PICO_${PICO_PLATFORM_UPPER}_CONFIG_HEADER_FILES)
|
|
||||||
|
|
||||||
file(GENERATE
|
|
||||||
OUTPUT ${CMAKE_BINARY_DIR}/generated/pico_base/pico/config_autogen.h
|
|
||||||
CONTENT "${header_content}"
|
|
||||||
)
|
|
||||||
|
|
||||||
configure_file( include/pico/version.h.in ${CMAKE_BINARY_DIR}/generated/pico_base/pico/version.h)
|
|
||||||
|
|
||||||
add_library(pico_base_headers INTERFACE)
|
|
||||||
target_include_directories(pico_base_headers INTERFACE include ${CMAKE_BINARY_DIR}/generated/pico_base)
|
|
||||||
|
|
||||||
foreach(DIR IN LISTS PICO_INCLUDE_DIRS)
|
|
||||||
target_include_directories(pico_base_headers INTERFACE ${DIR})
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# PICO_BUILD_DEFINE: PICO_BOARD, Name of board, type=string, default=CMake PICO_BOARD variable, group=pico_base
|
|
||||||
target_compile_definitions(pico_base_headers INTERFACE
|
|
||||||
PICO_BOARD="${PICO_BOARD}")
|
|
||||||
|
|
||||||
target_link_libraries(pico_base_headers INTERFACE pico_platform_headers)
|
|
||||||
endif()
|
|
|
@ -1,23 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PICO_H_
|
|
||||||
#define PICO_H_
|
|
||||||
|
|
||||||
/** \file pico.h
|
|
||||||
* \defgroup pico_base pico_base
|
|
||||||
*
|
|
||||||
* Core types and macros for the Raspberry Pi Pico SDK. This header is intended to be included by all source code
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pico/types.h"
|
|
||||||
#include "pico/version.h"
|
|
||||||
#include "pico/config.h"
|
|
||||||
#include "pico/platform.h"
|
|
||||||
#include "pico/assert.h"
|
|
||||||
#include "pico/error.h"
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PICO_CONFIG_H_
|
|
||||||
#define PICO_CONFIG_H_
|
|
||||||
|
|
||||||
// -----------------------------------------------------
|
|
||||||
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
|
|
||||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
|
||||||
// OR USE #ifndef __ASSEMBLER__ guards
|
|
||||||
// -------------
|
|
||||||
|
|
||||||
// PICO_CONFIG_HEADER_FILES and then PICO_SDK_<PLATFORM>_CONFIG_INCLUDE_FILES
|
|
||||||
// entries are dumped in order at build time into this generated header
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PICO_ERROR_H
|
|
||||||
#define _PICO_ERROR_H
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Common return codes from pico_sdk methods that return a status
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
PICO_OK = 0,
|
|
||||||
PICO_ERROR_NONE = 0,
|
|
||||||
PICO_ERROR_TIMEOUT = -1,
|
|
||||||
PICO_ERROR_GENERIC = -2,
|
|
||||||
PICO_ERROR_NO_DATA = -3,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,30 +0,0 @@
|
||||||
add_library(pico_binary_info_headers INTERFACE)
|
|
||||||
|
|
||||||
target_include_directories(pico_binary_info_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
||||||
|
|
||||||
add_library(pico_binary_info INTERFACE)
|
|
||||||
|
|
||||||
target_link_libraries(pico_binary_info INTERFACE pico_binary_info_headers)
|
|
||||||
|
|
||||||
function(pico_set_program_name TARGET name)
|
|
||||||
# PICO_BUILD_DEFINE: PICO_PROGRAM_NAME, value passed to pico_set_program_name, type=string, default=none, group=pico_binary_info
|
|
||||||
target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_NAME="${name}")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(pico_set_program_description TARGET description)
|
|
||||||
# since this is the command line, we will remove newlines
|
|
||||||
string(REPLACE "\n" " " description ${description})
|
|
||||||
string(REPLACE "\"" "\\\"" description ${description})
|
|
||||||
# PICO_BUILD_DEFINE: PICO_PROGRAM_DESCRIPTION, value passed to pico_set_program_description, type=string, default=none, group=pico_binary_info
|
|
||||||
target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_DESCRIPTION="${description}")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(pico_set_program_url TARGET url)
|
|
||||||
# PICO_BUILD_DEFINE: PICO_PROGRAM_URL, value passed to pico_set_program_url, type=string, default=none, group=pico_binary_info
|
|
||||||
target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_URL="${url}")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(pico_set_program_version TARGET version)
|
|
||||||
# PICO_BUILD_DEFINE: PICO_PROGRAM_VERSION_STRING, value passed to pico_set_program_version, type=string, default=none, group=pico_binary_info
|
|
||||||
target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_VERSION_STRING="${version}")
|
|
||||||
endfunction()
|
|
|
@ -1,5 +0,0 @@
|
||||||
if (NOT TARGET pico_bit_ops_headers)
|
|
||||||
add_library(pico_bit_ops_headers INTERFACE)
|
|
||||||
target_include_directories(pico_bit_ops_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
||||||
target_link_libraries(pico_bit_ops_headers INTERFACE pico_base_headers)
|
|
||||||
endif()
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PICO_BIT_OPS_H
|
|
||||||
#define _PICO_BIT_OPS_H
|
|
||||||
|
|
||||||
#include "pico.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \file bit_ops.h
|
|
||||||
* \defgroup pico_bit_ops pico_bit_ops
|
|
||||||
*
|
|
||||||
* Optimized bit manipulation functions.
|
|
||||||
* Additionally provides replacement implementations of the compiler built-ins __builtin_popcount, __builtin_clz
|
|
||||||
* and __bulitin_ctz
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \brief Reverse the bits in a 32 bit word
|
|
||||||
* \ingroup pico_bit_ops
|
|
||||||
*
|
|
||||||
* \param bits 32 bit input
|
|
||||||
* \return the 32 input bits reversed
|
|
||||||
*/
|
|
||||||
uint32_t __rev(uint32_t bits);
|
|
||||||
|
|
||||||
/*! \brief Reverse the bits in a 64 bit double word
|
|
||||||
* \ingroup pico_bit_ops
|
|
||||||
*
|
|
||||||
* \param bits 64 bit input
|
|
||||||
* \return the 64 input bits reversed
|
|
||||||
*/
|
|
||||||
uint64_t __revll(uint64_t bits);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,5 +0,0 @@
|
||||||
if (NOT TARGET pico_divider_headers)
|
|
||||||
add_library(pico_divider_headers INTERFACE)
|
|
||||||
target_include_directories(pico_divider_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
||||||
target_link_libraries(pico_divider_headers INTERFACE pico_base_headers)
|
|
||||||
endif()
|
|
|
@ -1,322 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PICO_DIVIDER_H_
|
|
||||||
#define _PICO_DIVIDER_H_
|
|
||||||
|
|
||||||
#include "pico.h"
|
|
||||||
#include "hardware/divider.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \defgroup pico_divider pico_divider
|
|
||||||
* Optimized 32 and 64 bit division functions accelerated by the RP2040 hardware divider.
|
|
||||||
* Additionally provides integration with the C `/` and `%` operators
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \file pico/divider.h
|
|
||||||
* \brief High level APIs including combined quotient and remainder functions for 32 and 64 bit accelerated by the hardware divider
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* These functions all call __aeabi_idiv0 or __aebi_ldiv0 on division by zero
|
|
||||||
* passing the largest applicably signed value
|
|
||||||
*
|
|
||||||
* Functions with unsafe in their name do not save/restore divider state, so are unsafe to call from interrupts. Unsafe functions are slightly faster.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two signed 32-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return quotient
|
|
||||||
*/
|
|
||||||
int32_t div_s32s32(int32_t a, int32_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two signed 32-bit values, with remainder
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \param [out] rem The remainder of dividend/divisor
|
|
||||||
* \return Quotient result of dividend/divisor
|
|
||||||
*/
|
|
||||||
static inline int32_t divmod_s32s32_rem(int32_t a, int32_t b, int32_t *rem) {
|
|
||||||
divmod_result_t r = hw_divider_divmod_s32(a, b);
|
|
||||||
*rem = to_remainder_s32(r);
|
|
||||||
return to_quotient_s32(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two signed 32-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return quotient in low word/r0, remainder in high word/r1
|
|
||||||
*/
|
|
||||||
divmod_result_t divmod_s32s32(int32_t a, int32_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two unsigned 32-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return Quotient
|
|
||||||
*/
|
|
||||||
uint32_t div_u32u32(uint32_t a, uint32_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two unsigned 32-bit values, with remainder
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \param [out] rem The remainder of dividend/divisor
|
|
||||||
* \return Quotient result of dividend/divisor
|
|
||||||
*/
|
|
||||||
static inline uint32_t divmod_u32u32_rem(uint32_t a, uint32_t b, uint32_t *rem) {
|
|
||||||
divmod_result_t r = hw_divider_divmod_u32(a, b);
|
|
||||||
*rem = to_remainder_u32(r);
|
|
||||||
return to_quotient_u32(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two unsigned 32-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return quotient in low word/r0, remainder in high word/r1
|
|
||||||
*/
|
|
||||||
divmod_result_t divmod_u32u32(uint32_t a, uint32_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two signed 64-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return Quotient
|
|
||||||
*/
|
|
||||||
int64_t div_s64s64(int64_t a, int64_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two signed 64-bit values, with remainder
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \param [out] rem The remainder of dividend/divisor
|
|
||||||
* \return Quotient result of dividend/divisor
|
|
||||||
*/
|
|
||||||
int64_t divmod_s64s64_rem(int64_t a, int64_t b, int64_t *rem);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two signed 64-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return quotient in result (r0,r1), remainder in regs (r2, r3)
|
|
||||||
*/
|
|
||||||
int64_t divmod_s64s64(int64_t a, int64_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two unsigned 64-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return Quotient
|
|
||||||
*/
|
|
||||||
uint64_t div_u64u64(uint64_t a, uint64_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two unsigned 64-bit values, with remainder
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \param [out] rem The remainder of dividend/divisor
|
|
||||||
* \return Quotient result of dividend/divisor
|
|
||||||
*/
|
|
||||||
uint64_t divmod_u64u64_rem(uint64_t a, uint64_t b, uint64_t *rem);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Integer divide of two signed 64-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return quotient in result (r0,r1), remainder in regs (r2, r3)
|
|
||||||
*/
|
|
||||||
uint64_t divmod_u64u64(uint64_t a, uint64_t b);
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
// these "unsafe" functions are slightly faster, but do not save the divider state,
|
|
||||||
// so are not generally safe to be called from interrupts
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two signed 32-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return quotient
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
int32_t div_s32s32_unsafe(int32_t a, int32_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two signed 32-bit values, with remainder
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \param [out] rem The remainder of dividend/divisor
|
|
||||||
* \return Quotient result of dividend/divisor
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
int32_t divmod_s32s32_rem_unsafe(int32_t a, int32_t b, int32_t *rem);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two unsigned 32-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return quotient in low word/r0, remainder in high word/r1
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
int64_t divmod_s32s32_unsafe(int32_t a, int32_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two unsigned 32-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return Quotient
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
uint32_t div_u32u32_unsafe(uint32_t a, uint32_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two unsigned 32-bit values, with remainder
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \param [out] rem The remainder of dividend/divisor
|
|
||||||
* \return Quotient result of dividend/divisor
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
uint32_t divmod_u32u32_rem_unsafe(uint32_t a, uint32_t b, uint32_t *rem);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two unsigned 32-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return quotient in low word/r0, remainder in high word/r1
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
uint64_t divmod_u32u32_unsafe(uint32_t a, uint32_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two signed 64-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return Quotient
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
int64_t div_s64s64_unsafe(int64_t a, int64_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two signed 64-bit values, with remainder
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \param [out] rem The remainder of dividend/divisor
|
|
||||||
* \return Quotient result of dividend/divisor
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
int64_t divmod_s64s64_rem_unsafe(int64_t a, int64_t b, int64_t *rem);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two signed 64-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return quotient in result (r0,r1), remainder in regs (r2, r3)
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
int64_t divmod_s64s64_unsafe(int64_t a, int64_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two unsigned 64-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return Quotient
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
uint64_t div_u64u64_unsafe(uint64_t a, uint64_t b);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two unsigned 64-bit values, with remainder
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \param [out] rem The remainder of dividend/divisor
|
|
||||||
* \return Quotient result of dividend/divisor
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
uint64_t divmod_u64u64_rem_unsafe(uint64_t a, uint64_t b, uint64_t *rem);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Unsafe integer divide of two signed 64-bit values
|
|
||||||
* \ingroup pico_divider
|
|
||||||
*
|
|
||||||
* \param a Dividend
|
|
||||||
* \param b Divisor
|
|
||||||
* \return quotient in result (r0,r1), remainder in regs (r2, r3)
|
|
||||||
*
|
|
||||||
* Do not use in interrupts
|
|
||||||
*/
|
|
||||||
uint64_t divmod_u64u64_unsafe(uint64_t a, uint64_t b);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
|
@ -1,11 +0,0 @@
|
||||||
if (NOT TARGET pico_stdlib_headers)
|
|
||||||
add_library(pico_stdlib_headers INTERFACE)
|
|
||||||
target_include_directories(pico_stdlib_headers INTERFACE include)
|
|
||||||
target_link_libraries(pico_stdlib_headers INTERFACE
|
|
||||||
hardware_gpio
|
|
||||||
hardware_uart
|
|
||||||
hardware_divider
|
|
||||||
pico_time
|
|
||||||
pico_util
|
|
||||||
)
|
|
||||||
endif()
|
|
|
@ -1,130 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PICO_STDLIB_H
|
|
||||||
#define _PICO_STDLIB_H
|
|
||||||
|
|
||||||
#include "pico.h"
|
|
||||||
#include "pico/stdio.h"
|
|
||||||
#include "pico/time.h"
|
|
||||||
#include "hardware/gpio.h"
|
|
||||||
#include "hardware/uart.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \file stdlib.h
|
|
||||||
* \defgroup pico_stdlib pico_stdlib
|
|
||||||
*
|
|
||||||
* Aggregation of a core subset of Raspberry Pi Pico SDK libraries used by most executables along with some additional
|
|
||||||
* utility methods. Including pico_stdlib gives you everything you need to get a basic program running
|
|
||||||
* which prints to stdout or flashes a LED
|
|
||||||
*
|
|
||||||
* This library aggregates:
|
|
||||||
* - @ref hardware_uart
|
|
||||||
* - @ref hardware_gpio
|
|
||||||
* - @ref pico_binary_info
|
|
||||||
* - @ref pico_runtime
|
|
||||||
* - @ref pico_platform
|
|
||||||
* - @ref pico_printf
|
|
||||||
* - @ref pico_stdio
|
|
||||||
* - @ref pico_standard_link
|
|
||||||
* - @ref pico_util
|
|
||||||
*
|
|
||||||
* There are some basic default values used by these functions that will default to
|
|
||||||
* usable values, however, they can be customised in a board definition header via
|
|
||||||
* config.h or similar
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Note PICO_STDIO_UART, PICO_STDIO_USB, PICO_STDIO_SEMIHOSTING are set by the
|
|
||||||
// respective INTERFACE libraries, so these defines are set if the library
|
|
||||||
// is included for the target executable
|
|
||||||
|
|
||||||
#if PICO_STDIO_UART
|
|
||||||
#include "pico/stdio_uart.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PICO_STDIO_USB
|
|
||||||
#include "pico/stdio_usb.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PICO_STDIO_SEMIHOSTING
|
|
||||||
#include "pico/stdio_semihosting.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \brief Set up the default UART and assign it to the default GPIO's
|
|
||||||
* \ingroup pico_stdlib
|
|
||||||
*
|
|
||||||
* By default this will use UART 0, with TX to pin GPIO 0,
|
|
||||||
* RX to pin GPIO 1, and the baudrate to 115200
|
|
||||||
*
|
|
||||||
* Calling this method also initializes stdin/stdout over UART if the
|
|
||||||
* @ref pico_stdio_uart library is linked.
|
|
||||||
*
|
|
||||||
* Defaults can be changed using configuration defines,
|
|
||||||
* PICO_DEFAULT_UART_INSTANCE,
|
|
||||||
* PICO_DEFAULT_UART_BAUD_RATE
|
|
||||||
* PICO_DEFAULT_UART_TX_PIN
|
|
||||||
* PICO_DEFAULT_UART_RX_PIN
|
|
||||||
*/
|
|
||||||
void setup_default_uart();
|
|
||||||
|
|
||||||
/*! \brief Initialise the system clock to 48MHz
|
|
||||||
* \ingroup pico_stdlib
|
|
||||||
*
|
|
||||||
* Set the system clock to 48MHz, and set the peripheral clock to match.
|
|
||||||
*/
|
|
||||||
void set_sys_clock_48mhz();
|
|
||||||
|
|
||||||
/*! \brief Initialise the system clock
|
|
||||||
* \ingroup pico_stdlib
|
|
||||||
*
|
|
||||||
* \param vco_freq The voltage controller oscillator frequency to be used by the SYS PLL
|
|
||||||
* \param post_div1 The first post divider for the SYS PLL
|
|
||||||
* \param post_div2 The second post divider for the SYS PLL.
|
|
||||||
*
|
|
||||||
* See the PLL documentation in the datasheet for details of driving the PLLs.
|
|
||||||
*/
|
|
||||||
void set_sys_clock_pll(uint32_t vco_freq, uint post_div1, uint post_div2);
|
|
||||||
|
|
||||||
/*! \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.
|
|
||||||
*/
|
|
||||||
bool check_sys_clock_khz(uint32_t freq_khz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out);
|
|
||||||
|
|
||||||
/*! \brief Attempt to set a system clock frequency in khz
|
|
||||||
* \ingroup pico_stdlib
|
|
||||||
*
|
|
||||||
* Note that not all clock frequencies are possible; it is preferred that you
|
|
||||||
* use src/rp2_common/hardware_clocks/scripts/vcocalc.py to calculate the parameters
|
|
||||||
* for use with set_sys_clock_pll
|
|
||||||
*
|
|
||||||
* \param freq_khz Requested frequency
|
|
||||||
* \param required if true then this function will assert if the frequency is not attainable.
|
|
||||||
* \return true if the clock was configured
|
|
||||||
*/
|
|
||||||
static inline bool set_sys_clock_khz(uint32_t freq_khz, bool required) {
|
|
||||||
uint vco, postdiv1, postdiv2;
|
|
||||||
if (check_sys_clock_khz(freq_khz, &vco, &postdiv1, &postdiv2)) {
|
|
||||||
set_sys_clock_pll(vco, postdiv1, postdiv2);
|
|
||||||
return true;
|
|
||||||
} else if (required) {
|
|
||||||
panic("System clock of %u kHz cannot be exactly achieved", freq_khz);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
|
@ -1,44 +0,0 @@
|
||||||
if (NOT TARGET pico_sync_headers)
|
|
||||||
add_library(pico_sync_headers INTERFACE)
|
|
||||||
target_include_directories(pico_sync_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
||||||
target_link_libraries(pico_sync_headers INTERFACE hardware_sync pico_time)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET pico_sync_core)
|
|
||||||
add_library(pico_sync_core INTERFACE)
|
|
||||||
target_sources(pico_sync_core INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/lock_core.c
|
|
||||||
)
|
|
||||||
target_link_libraries(pico_sync_core INTERFACE pico_sync_headers)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET pico_sync_sem)
|
|
||||||
add_library(pico_sync_sem INTERFACE)
|
|
||||||
target_sources(pico_sync_sem INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/sem.c
|
|
||||||
)
|
|
||||||
target_link_libraries(pico_sync_sem INTERFACE pico_sync_core pico_time)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET pico_sync_mutex)
|
|
||||||
add_library(pico_sync_mutex INTERFACE)
|
|
||||||
target_sources(pico_sync_mutex INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/mutex.c
|
|
||||||
)
|
|
||||||
target_link_libraries(pico_sync_mutex INTERFACE pico_sync_core pico_time)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET pico_sync_critical_section)
|
|
||||||
add_library(pico_sync_critical_section INTERFACE)
|
|
||||||
target_sources(pico_sync_critical_section INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/critical_section.c
|
|
||||||
)
|
|
||||||
target_link_libraries(pico_sync_critical_section INTERFACE pico_sync_core pico_time)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET pico_sync)
|
|
||||||
add_library(pico_sync INTERFACE)
|
|
||||||
target_link_libraries(pico_sync INTERFACE pico_sync_sem pico_sync_mutex pico_sync_critical_section pico_sync_core)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pico/critical_section.h"
|
|
||||||
|
|
||||||
#if !PICO_NO_HARDWARE
|
|
||||||
static_assert(sizeof(critical_section_t) == 8, "");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void critical_section_init(critical_section_t *critsec) {
|
|
||||||
critical_section_init_with_lock_num(critsec, spin_lock_claim_unused(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
void critical_section_init_with_lock_num(critical_section_t *critsec, uint lock_num) {
|
|
||||||
lock_init(&critsec->core, lock_num);
|
|
||||||
__mem_fence_release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void critical_section_deinit(critical_section_t *critsec) {
|
|
||||||
spin_lock_unclaim(spin_lock_get_num(critsec->core.spin_lock));
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PICO_LOCK_CORE_H
|
|
||||||
#define _PICO_LOCK_CORE_H
|
|
||||||
|
|
||||||
#include "pico.h"
|
|
||||||
#include "hardware/sync.h"
|
|
||||||
|
|
||||||
/** \file lock_core.h
|
|
||||||
* \ingroup pico_sync
|
|
||||||
*
|
|
||||||
* Base implementation for locking primitives protected by a spin lock
|
|
||||||
*/
|
|
||||||
typedef struct lock_core {
|
|
||||||
// spin lock protecting this lock's state
|
|
||||||
spin_lock_t *spin_lock;
|
|
||||||
|
|
||||||
// note any lock members in containing structures need not be volatile;
|
|
||||||
// they are protected by memory/compiler barriers when gaining and release spin locks
|
|
||||||
} lock_core_t;
|
|
||||||
|
|
||||||
void lock_init(lock_core_t *core, uint lock_num);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,135 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PLATFORM_MUTEX_H
|
|
||||||
#define _PLATFORM_MUTEX_H
|
|
||||||
|
|
||||||
#include "pico/lock_core.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \file mutex.h
|
|
||||||
* \defgroup mutex mutex
|
|
||||||
* \ingroup pico_sync
|
|
||||||
* \brief Mutex API for non IRQ mutual exclusion between cores
|
|
||||||
*
|
|
||||||
* Mutexes are application level locks usually used protecting data structures that might be used by
|
|
||||||
* multiple cores. Unlike critical sections, the mutex protected code is not necessarily
|
|
||||||
* required/expected to complete quickly, as no other sytemwide locks are held on account of a locked mutex.
|
|
||||||
*
|
|
||||||
* Because they are not re-entrant on the same core, blocking on a mutex should never be done in an IRQ
|
|
||||||
* handler. It is valid to call \ref mutex_try_enter from within an IRQ handler, if the operation
|
|
||||||
* that would be conducted under lock can be skipped if the mutex is locked (at least by the same core).
|
|
||||||
*
|
|
||||||
* See \ref critical_section.h for protecting access between multiple cores AND IRQ handlers
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct __packed_aligned mutex {
|
|
||||||
lock_core_t core;
|
|
||||||
int8_t owner; //! core number or -1 for unowned
|
|
||||||
} mutex_t;
|
|
||||||
|
|
||||||
/*! \brief Initialise a mutex structure
|
|
||||||
* \ingroup mutex
|
|
||||||
*
|
|
||||||
* \param mtx Pointer to mutex structure
|
|
||||||
*/
|
|
||||||
void mutex_init(mutex_t *mtx);
|
|
||||||
|
|
||||||
/*! \brief Take ownership of a mutex
|
|
||||||
* \ingroup mutex
|
|
||||||
*
|
|
||||||
* This function will block until the calling core can claim ownership of the mutex.
|
|
||||||
* On return the caller core owns the mutex
|
|
||||||
*
|
|
||||||
* \param mtx Pointer to mutex structure
|
|
||||||
*/
|
|
||||||
void mutex_enter_blocking(mutex_t *mtx);
|
|
||||||
|
|
||||||
/*! \brief Check to see if a mutex is available
|
|
||||||
* \ingroup mutex
|
|
||||||
*
|
|
||||||
* Will return true if the mutex is unowned, false otherwise
|
|
||||||
*
|
|
||||||
* \param mtx Pointer to mutex structure
|
|
||||||
* \param owner_out If mutex is owned, and this pointer is non-zero, it will be filled in with the core number of the current owner of the mutex
|
|
||||||
*/
|
|
||||||
bool mutex_try_enter(mutex_t *mtx, uint32_t *owner_out);
|
|
||||||
|
|
||||||
/*! \brief Wait for mutex with timeout
|
|
||||||
* \ingroup mutex
|
|
||||||
*
|
|
||||||
* Wait for up to the specific time to take ownership of the mutex. If the calling
|
|
||||||
* core can take ownership of the mutex before the timeout expires, then true will be returned
|
|
||||||
* and the calling core will own the mutex, otherwise false will be returned and the calling
|
|
||||||
* core will *NOT* own the mutex.
|
|
||||||
*
|
|
||||||
* \param mtx Pointer to mutex structure
|
|
||||||
* \param timeout_ms The timeout in milliseconds.
|
|
||||||
* \return true if mutex now owned, false if timeout occurred before mutex became available
|
|
||||||
*/
|
|
||||||
bool mutex_enter_timeout_ms(mutex_t *mtx, uint32_t timeout_ms);
|
|
||||||
|
|
||||||
/*! \brief Wait for mutex until a specific time
|
|
||||||
* \ingroup mutex
|
|
||||||
*
|
|
||||||
* Wait until the specific time to take ownership of the mutex. If the calling
|
|
||||||
* core can take ownership of the mutex before the timeout expires, then true will be returned
|
|
||||||
* and the calling core will own the mutex, otherwise false will be returned and the calling
|
|
||||||
* core will *NOT* own the mutex.
|
|
||||||
*
|
|
||||||
* \param mtx Pointer to mutex structure
|
|
||||||
* \param until The time after which to return if the core cannot take owner ship of the mutex
|
|
||||||
* \return true if mutex now owned, false if timeout occurred before mutex became available
|
|
||||||
*/
|
|
||||||
bool mutex_enter_block_until(mutex_t *mtx, absolute_time_t until);
|
|
||||||
|
|
||||||
/*! \brief Release ownership of a mutex
|
|
||||||
* \ingroup mutex
|
|
||||||
*
|
|
||||||
* \param mtx Pointer to mutex structure
|
|
||||||
*/
|
|
||||||
void mutex_exit(mutex_t *mtx);
|
|
||||||
|
|
||||||
/*! \brief Test for mutex initialised state
|
|
||||||
* \ingroup mutex
|
|
||||||
*
|
|
||||||
* \param mtx Pointer to mutex structure
|
|
||||||
* \return true if the mutex is initialised, false otherwise
|
|
||||||
*/
|
|
||||||
static inline bool mutex_is_initialzed(mutex_t *mtx) {
|
|
||||||
return mtx->core.spin_lock != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \brief Helper macro for static definition of mutexes
|
|
||||||
* \ingroup mutex
|
|
||||||
*
|
|
||||||
* A mutex defined as follows:
|
|
||||||
*
|
|
||||||
* ```c
|
|
||||||
* auto_init_mutex(my_mutex);
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Is equivalent to doing
|
|
||||||
*
|
|
||||||
* ```c
|
|
||||||
* static mutex_t my_mutex;
|
|
||||||
*
|
|
||||||
* void my_init_function() {
|
|
||||||
* mutex_init(&my_mutex);
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* But the initialization of the mutex is performed automatically during runtime initialization
|
|
||||||
*/
|
|
||||||
#define auto_init_mutex(name) static __attribute__((section(".mutex_array"))) mutex_t name
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pico/mutex.h"
|
|
||||||
#include "pico/time.h"
|
|
||||||
|
|
||||||
#if !PICO_NO_HARDWARE
|
|
||||||
static_assert(sizeof(mutex_t) == 8, "");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void mutex_init(mutex_t *mtx) {
|
|
||||||
lock_init(&mtx->core, next_striped_spin_lock_num());
|
|
||||||
mtx->owner = -1;
|
|
||||||
__mem_fence_release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __time_critical_func(mutex_enter_blocking)(mutex_t *mtx) {
|
|
||||||
assert(mtx->core.spin_lock);
|
|
||||||
bool block = true;
|
|
||||||
do {
|
|
||||||
uint32_t save = spin_lock_blocking(mtx->core.spin_lock);
|
|
||||||
if (mtx->owner < 0) {
|
|
||||||
mtx->owner = get_core_num();
|
|
||||||
block = false;
|
|
||||||
}
|
|
||||||
spin_unlock(mtx->core.spin_lock, save);
|
|
||||||
if (block) {
|
|
||||||
__wfe();
|
|
||||||
}
|
|
||||||
} while (block);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool __time_critical_func(mutex_try_enter)(mutex_t *mtx, uint32_t *owner_out) {
|
|
||||||
bool entered;
|
|
||||||
uint32_t save = spin_lock_blocking(mtx->core.spin_lock);
|
|
||||||
if (mtx->owner < 0) {
|
|
||||||
mtx->owner = get_core_num();
|
|
||||||
entered = true;
|
|
||||||
} else {
|
|
||||||
if (owner_out) *owner_out = mtx->owner;
|
|
||||||
entered = false;
|
|
||||||
}
|
|
||||||
spin_unlock(mtx->core.spin_lock, save);
|
|
||||||
return entered;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool __time_critical_func(mutex_enter_timeout_ms)(mutex_t *mtx, uint32_t timeout_ms) {
|
|
||||||
return mutex_enter_block_until(mtx, make_timeout_time_ms(timeout_ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool __time_critical_func(mutex_enter_block_until)(mutex_t *mtx, absolute_time_t until) {
|
|
||||||
assert(mtx->core.spin_lock);
|
|
||||||
bool block = true;
|
|
||||||
do {
|
|
||||||
uint32_t save = spin_lock_blocking(mtx->core.spin_lock);
|
|
||||||
if (mtx->owner < 0) {
|
|
||||||
mtx->owner = get_core_num();
|
|
||||||
block = false;
|
|
||||||
}
|
|
||||||
spin_unlock(mtx->core.spin_lock, save);
|
|
||||||
if (block) {
|
|
||||||
if (best_effort_wfe_or_timeout(until)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (block);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __time_critical_func(mutex_exit)(mutex_t *mtx) {
|
|
||||||
uint32_t save = spin_lock_blocking(mtx->core.spin_lock);
|
|
||||||
assert(mtx->owner >= 0);
|
|
||||||
mtx->owner = -1;
|
|
||||||
__sev();
|
|
||||||
spin_unlock(mtx->core.spin_lock, save);
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
if (NOT TARGET pico_time_headers)
|
|
||||||
add_library(pico_time_headers INTERFACE)
|
|
||||||
|
|
||||||
target_include_directories(pico_time_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
||||||
|
|
||||||
target_link_libraries(pico_time_headers INTERFACE hardware_timer)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET pico_time)
|
|
||||||
add_library(pico_time INTERFACE)
|
|
||||||
|
|
||||||
target_sources(pico_time INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/time.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/timeout_helper.c)
|
|
||||||
target_link_libraries(pico_time INTERFACE pico_time_headers pico_sync pico_util)
|
|
||||||
endif()
|
|
|
@ -1,15 +0,0 @@
|
||||||
if (NOT TARGET pico_util_headers)
|
|
||||||
add_library(pico_util_headers INTERFACE)
|
|
||||||
target_include_directories(pico_util_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
||||||
target_link_libraries(pico_util_headers INTERFACE pico_base_headers hardware_sync)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET pico_util)
|
|
||||||
add_library(pico_util INTERFACE)
|
|
||||||
target_sources(pico_util INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/datetime.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pheap.c
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/queue.c
|
|
||||||
)
|
|
||||||
target_link_libraries(pico_util INTERFACE pico_util_headers)
|
|
||||||
endif()
|
|
|
@ -1,155 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PICO_UTIL_PHEAP_H
|
|
||||||
#define _PICO_UTIL_PHEAP_H
|
|
||||||
|
|
||||||
#include "pico.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_PHEAP, Enable/disable assertions in the pheap module, type=bool, default=0, group=pico_util
|
|
||||||
#ifndef PARAM_ASSERTIONS_ENABLED_PHEAP
|
|
||||||
#define PARAM_ASSERTIONS_ENABLED_PHEAP 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file pheap.h
|
|
||||||
* \defgroup util_pheap pheap
|
|
||||||
* Pairing Heap Implementation
|
|
||||||
* \ingroup pico_util
|
|
||||||
*
|
|
||||||
* pheap defines a simple pairing heap. the implementation simply tracks array indexes, it is up to
|
|
||||||
* the user to provide storage for heap entries and a comparison function.
|
|
||||||
*
|
|
||||||
* NOTE: this class is not safe for concurrent usage. It should be externally protected. Furthermore
|
|
||||||
* if used concurrently, the caller needs to protect around their use of the returned id.
|
|
||||||
* for example, ph_remove_head returns the id of an element that is no longer in the heap.
|
|
||||||
*
|
|
||||||
* The user can still use this to look at the data in their companion array, however obviously further operations
|
|
||||||
* on the heap may cause them to overwrite that data as the id may be reused on subsequent operations
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
// PICO_CONFIG: PICO_PHEAP_MAX_ENTRIES, Maximum number of entries in the pheap, min=1, max=65534, default=255, group=pico_util
|
|
||||||
#ifndef PICO_PHEAP_MAX_ENTRIES
|
|
||||||
#define PICO_PHEAP_MAX_ENTRIES 255
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// public heap_node ids are numbered from 1 (0 means none)
|
|
||||||
#if PICO_PHEAP_MAX_ENTRIES < 256
|
|
||||||
typedef uint8_t pheap_node_id_t;
|
|
||||||
#elif PICO_PHEAP_MAX_ENTRIES < 65535
|
|
||||||
typedef uint16_t pheap_node_id_t;
|
|
||||||
#else
|
|
||||||
#error invalid PICO_PHEAP_MAX_ENTRIES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct pheap_node {
|
|
||||||
pheap_node_id_t child, sibling, parent;
|
|
||||||
} pheap_node_t;
|
|
||||||
|
|
||||||
// return true if a < b in natural order
|
|
||||||
typedef bool (*pheap_comparator)(void *user_data, pheap_node_id_t a, pheap_node_id_t b);
|
|
||||||
|
|
||||||
typedef struct pheap {
|
|
||||||
pheap_node_t *nodes;
|
|
||||||
pheap_comparator comparator;
|
|
||||||
void *user_data;
|
|
||||||
pheap_node_id_t max_nodes;
|
|
||||||
pheap_node_id_t root_id;
|
|
||||||
// we remove from head and add to tail to stop reusing the same ids
|
|
||||||
pheap_node_id_t free_head_id;
|
|
||||||
pheap_node_id_t free_tail_id;
|
|
||||||
} pheap_t;
|
|
||||||
|
|
||||||
pheap_t *ph_create(uint max_nodes, pheap_comparator comparator, void *user_data);
|
|
||||||
|
|
||||||
void ph_clear(pheap_t *heap);
|
|
||||||
|
|
||||||
void ph_destroy(pheap_t *heap);
|
|
||||||
|
|
||||||
static inline pheap_node_t *ph_get_node(pheap_t *heap, pheap_node_id_t id) {
|
|
||||||
assert(id && id <= heap->max_nodes);
|
|
||||||
return heap->nodes + id - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ph_add_child_node(pheap_t *heap, pheap_node_id_t parent_id, pheap_node_id_t child_id) {
|
|
||||||
pheap_node_t *n = ph_get_node(heap, parent_id);
|
|
||||||
assert(parent_id);
|
|
||||||
assert(child_id);
|
|
||||||
assert(parent_id != child_id);
|
|
||||||
pheap_node_t *c = ph_get_node(heap, child_id);
|
|
||||||
c->parent = parent_id;
|
|
||||||
if (!n->child) {
|
|
||||||
n->child = child_id;
|
|
||||||
} else {
|
|
||||||
c->sibling = n->child;
|
|
||||||
n->child = child_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static pheap_node_id_t ph_merge_nodes(pheap_t *heap, pheap_node_id_t a, pheap_node_id_t b) {
|
|
||||||
if (!a) return b;
|
|
||||||
if (!b) return a;
|
|
||||||
if (heap->comparator(heap->user_data, a, b)) {
|
|
||||||
ph_add_child_node(heap, a, b);
|
|
||||||
return a;
|
|
||||||
} else {
|
|
||||||
ph_add_child_node(heap, b, a);
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline pheap_node_id_t ph_new_node(pheap_t *heap) {
|
|
||||||
if (!heap->free_head_id) return 0;
|
|
||||||
pheap_node_id_t id = heap->free_head_id;
|
|
||||||
heap->free_head_id = ph_get_node(heap, id)->sibling;
|
|
||||||
if (!heap->free_head_id) heap->free_tail_id = 0;
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// note this will callback the comparator for the node
|
|
||||||
// returns the (new) root of the heap
|
|
||||||
static inline pheap_node_id_t ph_insert(pheap_t *heap, pheap_node_id_t id) {
|
|
||||||
assert(id);
|
|
||||||
pheap_node_t *hn = ph_get_node(heap, id);
|
|
||||||
hn->child = hn->sibling = hn->parent = 0;
|
|
||||||
heap->root_id = ph_merge_nodes(heap, heap->root_id, id);
|
|
||||||
return heap->root_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline pheap_node_id_t ph_peek_head(pheap_t *heap) {
|
|
||||||
return heap->root_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
pheap_node_id_t ph_remove_head_reserve(pheap_t *heap, bool reserve);
|
|
||||||
|
|
||||||
static inline pheap_node_id_t ph_remove_head(pheap_t *heap) {
|
|
||||||
return ph_remove_head_reserve(heap, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool ph_contains(pheap_t *heap, pheap_node_id_t id) {
|
|
||||||
return id == heap->root_id || ph_get_node(heap, id)->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ph_delete(pheap_t *heap, pheap_node_id_t id);
|
|
||||||
|
|
||||||
static inline void ph_add_to_free_list(pheap_t *heap, pheap_node_id_t id) {
|
|
||||||
assert(id && !ph_contains(heap, id));
|
|
||||||
if (heap->free_tail_id) {
|
|
||||||
ph_get_node(heap, heap->free_tail_id)->sibling = id;
|
|
||||||
}
|
|
||||||
heap->free_tail_id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ph_dump(pheap_t *heap, void (*dump_key)(pheap_node_id_t, void *), void *user_data);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "pico/util/queue.h"
|
|
||||||
|
|
||||||
void queue_init_with_spinlock(queue_t *q, uint element_size, uint element_count, uint spinlock_num) {
|
|
||||||
q->lock = spin_lock_instance(spinlock_num);
|
|
||||||
q->data = (uint8_t *)calloc(element_count + 1, element_size);
|
|
||||||
q->element_count = element_count;
|
|
||||||
q->element_size = element_size;
|
|
||||||
q->wptr = 0;
|
|
||||||
q->rptr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void queue_free(queue_t *q) {
|
|
||||||
free(q->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *element_ptr(queue_t *q, uint index) {
|
|
||||||
assert(index <= q->element_count);
|
|
||||||
return q->data + index * q->element_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t inc_index(queue_t *q, uint16_t index) {
|
|
||||||
if (++index > q->element_count) { // > because we have element_count + 1 elements
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool queue_try_add(queue_t *q, void *data) {
|
|
||||||
bool success = false;
|
|
||||||
uint32_t flags = spin_lock_blocking(q->lock);
|
|
||||||
if (queue_get_level_unsafe(q) != q->element_count) {
|
|
||||||
memcpy(element_ptr(q, q->wptr), data, q->element_size);
|
|
||||||
q->wptr = inc_index(q, q->wptr);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
spin_unlock(q->lock, flags);
|
|
||||||
if (success) __sev();
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool queue_try_remove(queue_t *q, void *data) {
|
|
||||||
bool success = false;
|
|
||||||
uint32_t flags = spin_lock_blocking(q->lock);
|
|
||||||
if (queue_get_level_unsafe(q) != 0) {
|
|
||||||
memcpy(data, element_ptr(q, q->rptr), q->element_size);
|
|
||||||
q->rptr = inc_index(q, q->rptr);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
spin_unlock(q->lock, flags);
|
|
||||||
if (success) __sev();
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool queue_try_peek(queue_t *q, void *data) {
|
|
||||||
bool success = false;
|
|
||||||
uint32_t flags = spin_lock_blocking(q->lock);
|
|
||||||
if (queue_get_level_unsafe(q) != 0) {
|
|
||||||
memcpy(data, element_ptr(q, q->rptr), q->element_size);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
spin_unlock(q->lock, flags);
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
void queue_add_blocking(queue_t *q, void *data) {
|
|
||||||
bool done;
|
|
||||||
do {
|
|
||||||
done = queue_try_add(q, data);
|
|
||||||
if (done) break;
|
|
||||||
__wfe();
|
|
||||||
} while (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void queue_remove_blocking(queue_t *q, void *data) {
|
|
||||||
bool done;
|
|
||||||
do {
|
|
||||||
done = queue_try_remove(q, data);
|
|
||||||
if (done) break;
|
|
||||||
__wfe();
|
|
||||||
} while (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void queue_peek_blocking(queue_t *q, void *data) {
|
|
||||||
bool done;
|
|
||||||
do {
|
|
||||||
done = queue_try_peek(q, data);
|
|
||||||
if (done) break;
|
|
||||||
__wfe();
|
|
||||||
} while (true);
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
// ---------------------------------------
|
|
||||||
// THIS FILE IS AUTOGENERATED; DO NOT EDIT
|
|
||||||
// ---------------------------------------
|
|
||||||
|
|
||||||
#ifndef _PICO_VERSION_H
|
|
||||||
#define _PICO_VERSION_H
|
|
||||||
|
|
||||||
#define PICO_SDK_VERSION_MAJOR 1
|
|
||||||
#define PICO_SDK_VERSION_MINOR 0
|
|
||||||
#define PICO_SDK_VERSION_REVISION 1
|
|
||||||
#define PICO_SDK_VERSION_STRING "1.0.1"
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,10 +0,0 @@
|
||||||
# For targeting the host for testing purposes
|
|
||||||
|
|
||||||
function(pico_add_extra_outputs TARGET)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
set(PICO_NO_HARDWARE "1" CACHE INTERNAL "")
|
|
||||||
set(PICO_ON_DEVICE "0" CACHE INTERNAL "")
|
|
||||||
|
|
||||||
add_subdirectory(common)
|
|
||||||
add_subdirectory(host)
|
|
|
@ -1,28 +0,0 @@
|
||||||
pico_add_subdirectory(hardware_divider)
|
|
||||||
pico_add_subdirectory(hardware_gpio)
|
|
||||||
pico_add_subdirectory(hardware_sync)
|
|
||||||
pico_add_subdirectory(hardware_timer)
|
|
||||||
pico_add_subdirectory(hardware_uart)
|
|
||||||
pico_add_subdirectory(pico_bit_ops)
|
|
||||||
pico_add_subdirectory(pico_divider)
|
|
||||||
pico_add_subdirectory(pico_multicore)
|
|
||||||
pico_add_subdirectory(pico_platform)
|
|
||||||
pico_add_subdirectory(pico_printf)
|
|
||||||
pico_add_subdirectory(pico_stdio)
|
|
||||||
pico_add_subdirectory(pico_stdlib)
|
|
||||||
|
|
||||||
pico_add_doxygen(${CMAKE_CURRENT_LIST_DIR})
|
|
||||||
|
|
||||||
macro(pico_set_float_implementation TARGET IMPL)
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
macro(pico_set_double_implementation TARGET IMPL)
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
macro(pico_set_boot_stage2 TARGET IMPL)
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
set(PICO_HOST_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "")
|
|
||||||
function(pico_define_boot_stage2 NAME)
|
|
||||||
add_executable(${NAME} ${PICO_HOST_DIR}/boot_stage2.c)
|
|
||||||
endfunction()
|
|
|
@ -1,14 +0,0 @@
|
||||||
This is a basic set of replacement library implementations sufficient to get simple applications
|
|
||||||
running on your computer (Raspberry Pi OS, Linux, macOS or Windows using Cygwin or Windows Subsystem for Linux).
|
|
||||||
It is selected by `PICO_PLATFORM=host` in your CMake build
|
|
||||||
|
|
||||||
This can be extremely useful for testing and debugging higher level application code, or porting code which is not yet small enough
|
|
||||||
to run on the RP2040 device itself.
|
|
||||||
|
|
||||||
This base level host library provides a minimal environment to compile programs, but is likely sufficient for programs
|
|
||||||
that don't access hardware directly.
|
|
||||||
|
|
||||||
It is possible however to inject additional SDK library implementations/simulations to provide
|
|
||||||
more complete functionality. For an example of this see the [pico-host-sdl](https://github.com/raspberrypi/pico-host-sdl)
|
|
||||||
which uses the SDL2 library to add additional library support for pico_multicore, timers/alarms in pico-time and
|
|
||||||
pico-audio/pico-scanvideo from [pico-extras](https://github.com/raspberrypi/pico-extras)
|
|
|
@ -1 +0,0 @@
|
||||||
// empty
|
|
|
@ -1 +0,0 @@
|
||||||
pico_simple_hardware_target(divider)
|
|
|
@ -1,9 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hardware/divider.h"
|
|
||||||
|
|
||||||
__thread uint64_t hw_divider_result_threadlocal;
|
|
|
@ -1,122 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _HARDWARE_DIVIDER_H
|
|
||||||
#define _HARDWARE_DIVIDER_H
|
|
||||||
|
|
||||||
#include "pico/types.h"
|
|
||||||
|
|
||||||
typedef uint64_t divmod_result_t;
|
|
||||||
|
|
||||||
static inline int __sign_of(int32_t v) {
|
|
||||||
return v > 0 ? 1 : (v < 0 ? -1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// divides unsigned values a by b... (a/b) returned in low 32 bits, (a%b) in high 32 bits... results undefined for b==0
|
|
||||||
static inline uint64_t hw_divider_divmod_u32(uint32_t a, uint32_t b) {
|
|
||||||
if (!b) return (((uint64_t)a)<<32u) | (uint32_t)(-1); // todo check this
|
|
||||||
return (((uint64_t)(a%b))<<32u) | (a/b);
|
|
||||||
}
|
|
||||||
|
|
||||||
// divides signed values a by b... (a/b) returned in low 32 bits, (a%b) in high 32 bits... results undefined for b==0
|
|
||||||
static inline uint64_t hw_divider_divmod_s32(int32_t a, int32_t b) {
|
|
||||||
if (!b) return (((uint64_t)a)<<32u) | (uint32_t)(-__sign_of(a));
|
|
||||||
return (((uint64_t)(a%b))<<32u) | (uint32_t)(a/b);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern __thread divmod_result_t hw_divider_result_threadlocal;
|
|
||||||
|
|
||||||
static inline void hw_divider_divmod_s32_start(int32_t a, int32_t b) {
|
|
||||||
hw_divider_result_threadlocal = hw_divider_divmod_s32(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void hw_divider_divmod_u32_start(uint32_t a, uint32_t b) {
|
|
||||||
hw_divider_result_threadlocal = hw_divider_divmod_u32(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline divmod_result_t hw_divider_result_wait() {
|
|
||||||
return hw_divider_result_threadlocal;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t hw_divider_result_nowait() {
|
|
||||||
return hw_divider_result_threadlocal;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static uint32_t to_quotient_u32(unsigned long long int r) {
|
|
||||||
return (uint32_t) r;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static int32_t to_quotient_s32(unsigned long long int r) {
|
|
||||||
return (int32_t)(uint32_t)r;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static uint32_t to_remainder_u32(unsigned long long int r) {
|
|
||||||
return (uint32_t)(r >> 32u);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static int32_t to_remainder_s32(unsigned long long int r) {
|
|
||||||
return (int32_t)(r >> 32u);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t hw_divider_u32_quotient_wait() {
|
|
||||||
return to_quotient_u32(hw_divider_result_wait());
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t hw_divider_u32_remainder_wait() {
|
|
||||||
return to_remainder_u32(hw_divider_result_wait());
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t hw_divider_s32_quotient_wait() {
|
|
||||||
return to_quotient_s32(hw_divider_result_wait());
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t hw_divider_s32_remainder_wait() {
|
|
||||||
return to_remainder_s32(hw_divider_result_wait());
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t hw_divider_u32_quotient(uint32_t a, uint32_t b) {
|
|
||||||
return b ? (a / b) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t hw_divider_u32_remainder(uint32_t a, uint32_t b) {
|
|
||||||
return b ? (a % b) : a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t hw_divider_s32_quotient(int32_t a, int32_t b) {
|
|
||||||
return b ? (a / b) : -__sign_of(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t hw_divider_s32_remainder(int32_t a, int32_t b) {
|
|
||||||
return b ? (a % b) : a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t hw_divider_u32_quotient_inlined(uint32_t a, uint32_t b) {
|
|
||||||
return hw_divider_u32_quotient(a,b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t hw_divider_u32_remainder_inlined(uint32_t a, uint32_t b) {
|
|
||||||
return hw_divider_u32_remainder(a,b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t hw_divider_s32_quotient_inlined(int32_t a, int32_t b) {
|
|
||||||
return hw_divider_s32_quotient(a,b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t hw_divider_s32_remainder_inlined(int32_t a, int32_t b) {
|
|
||||||
return hw_divider_s32_remainder(a,b);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef uint64_t hw_divider_state_t;
|
|
||||||
|
|
||||||
static inline void hw_divider_save_state(hw_divider_state_t *dest) {
|
|
||||||
*dest = hw_divider_result_threadlocal;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void hw_divider_restore_state(hw_divider_state_t *src) {
|
|
||||||
hw_divider_result_threadlocal = *src;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _HARDWARE_DIVIDER_H
|
|
|
@ -1 +0,0 @@
|
||||||
pico_simple_hardware_target(gpio)
|
|
|
@ -1,118 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hardware/gpio.h"
|
|
||||||
|
|
||||||
// todo weak or replace? probably weak
|
|
||||||
void gpio_set_function(uint gpio, enum gpio_function fn) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_pull_up(uint gpio) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_pull_down(uint gpio) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_disable_pulls(uint gpio) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_pulls(uint gpio, bool up, bool down) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_outover(uint gpio, uint value) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_inover(uint gpio, uint value) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_oeover(uint gpio, uint value) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_irq_enabled(uint gpio, uint32_t events, bool enable) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_acknowledge_irq(uint gpio, uint32_t events) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_init(uint gpio) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(gpio_get)
|
|
||||||
|
|
||||||
bool PICO_WEAK_FUNCTION_IMPL_NAME(gpio_get)(uint gpio) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t gpio_get_all() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_mask(uint32_t mask) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_clr_mask(uint32_t mask) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_xor_mask(uint32_t mask) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_put_masked(uint32_t mask, uint32_t value) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_put_all(uint32_t value) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_put(uint gpio, int value) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_dir_out_masked(uint32_t mask) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_dir_in_masked(uint32_t mask) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_dir_masked(uint32_t mask, uint32_t value) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_dir_all_bits(uint32_t value) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_dir(uint gpio, bool out) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_debug_pins_init() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_set_input_enabled(uint gpio, bool enable) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_init_mask(uint gpio_mask) {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,147 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _HARDWARE_GPIO_H_
|
|
||||||
#define _HARDWARE_GPIO_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pico.h"
|
|
||||||
|
|
||||||
enum gpio_function {
|
|
||||||
GPIO_FUNC_XIP = 0,
|
|
||||||
GPIO_FUNC_SPI = 1,
|
|
||||||
GPIO_FUNC_UART = 2,
|
|
||||||
GPIO_FUNC_I2C = 3,
|
|
||||||
GPIO_FUNC_PWM = 4,
|
|
||||||
GPIO_FUNC_SIO = 5,
|
|
||||||
GPIO_FUNC_PIO0 = 6,
|
|
||||||
GPIO_FUNC_PIO1 = 7,
|
|
||||||
GPIO_FUNC_GPCK = 8,
|
|
||||||
GPIO_FUNC_USB = 9,
|
|
||||||
GPIO_FUNC_NULL = 0xf,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define GPIO_OUT 1
|
|
||||||
#define GPIO_IN 0
|
|
||||||
|
|
||||||
#define NUM_BANK0_GPIOS 30
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Pad Controls + IO Muxing
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Declarations for gpio.c
|
|
||||||
|
|
||||||
void gpio_set_function(uint gpio, enum gpio_function fn);
|
|
||||||
|
|
||||||
enum gpio_function gpio_get_function(uint gpio);
|
|
||||||
|
|
||||||
void gpio_pull_up(uint gpio);
|
|
||||||
|
|
||||||
void gpio_pull_down(uint gpio);
|
|
||||||
|
|
||||||
void gpio_disable_pulls(uint gpio);
|
|
||||||
|
|
||||||
void gpio_set_pulls(uint gpio, bool up, bool down);
|
|
||||||
|
|
||||||
void gpio_set_outover(uint gpio, uint value);
|
|
||||||
|
|
||||||
void gpio_set_inover(uint gpio, uint value);
|
|
||||||
|
|
||||||
void gpio_set_oeover(uint gpio, uint value);
|
|
||||||
|
|
||||||
void gpio_set_input_enabled(uint gpio, bool enable);
|
|
||||||
|
|
||||||
// Configure a GPIO for direct input/output from software
|
|
||||||
void gpio_init(uint gpio);
|
|
||||||
|
|
||||||
void gpio_init_mask(uint gpio_mask);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Input
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Get the value of a single GPIO
|
|
||||||
bool gpio_get(uint gpio);
|
|
||||||
|
|
||||||
// Get raw value of all
|
|
||||||
uint32_t gpio_get_all();
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Output
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Drive high every GPIO appearing in mask
|
|
||||||
void gpio_set_mask(uint32_t mask);
|
|
||||||
|
|
||||||
void gpio_clr_mask(uint32_t mask);
|
|
||||||
|
|
||||||
// Toggle every GPIO appearing in mask
|
|
||||||
void gpio_xor_mask(uint32_t mask);
|
|
||||||
|
|
||||||
|
|
||||||
// For each 1 bit in "mask", drive that pin to the value given by
|
|
||||||
// corresponding bit in "value", leaving other pins unchanged.
|
|
||||||
// Since this uses the TOGL alias, it is concurrency-safe with e.g. an IRQ
|
|
||||||
// bashing different pins from the same core.
|
|
||||||
void gpio_put_masked(uint32_t mask, uint32_t value);
|
|
||||||
|
|
||||||
// Drive all pins simultaneously
|
|
||||||
void gpio_put_all(uint32_t value);
|
|
||||||
|
|
||||||
|
|
||||||
// Drive a single GPIO high/low
|
|
||||||
void gpio_put(uint gpio, int value);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Direction
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Switch all GPIOs in "mask" to output
|
|
||||||
void gpio_set_dir_out_masked(uint32_t mask);
|
|
||||||
|
|
||||||
// Switch all GPIOs in "mask" to input
|
|
||||||
void gpio_set_dir_in_masked(uint32_t mask);
|
|
||||||
|
|
||||||
// For each 1 bit in "mask", switch that pin to the direction given by
|
|
||||||
// corresponding bit in "value", leaving other pins unchanged.
|
|
||||||
// E.g. gpio_set_dir_masked(0x3, 0x2); -> set pin 0 to input, pin 1 to output,
|
|
||||||
// simultaneously.
|
|
||||||
void gpio_set_dir_masked(uint32_t mask, uint32_t value);
|
|
||||||
|
|
||||||
// Set direction of all pins simultaneously.
|
|
||||||
// For each bit in value,
|
|
||||||
// 1 = out
|
|
||||||
// 0 = in
|
|
||||||
void gpio_set_dir_all_bits(uint32_t value);
|
|
||||||
|
|
||||||
// Set a single GPIO to input/output.
|
|
||||||
// true = out
|
|
||||||
// 0 = in
|
|
||||||
void gpio_set_dir(uint gpio, bool out);
|
|
||||||
|
|
||||||
// debugging
|
|
||||||
#define PICO_DEBUG_PIN_BASE 19u
|
|
||||||
|
|
||||||
// note these two macros may only be used once per compilation unit
|
|
||||||
#define CU_REGISTER_DEBUG_PINS(p, ...)
|
|
||||||
#define CU_SELECT_DEBUG_PINS(x)
|
|
||||||
#define DEBUG_PINS_ENABLED(p) false
|
|
||||||
|
|
||||||
#define DEBUG_PINS_SET(p, v) ((void)0)
|
|
||||||
#define DEBUG_PINS_CLR(p, v) ((void)0)
|
|
||||||
#define DEBUG_PINS_XOR(p, v) ((void)0)
|
|
||||||
|
|
||||||
void gpio_debug_pins_init();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,12 +0,0 @@
|
||||||
pico_simple_hardware_headers_target(sync)
|
|
||||||
|
|
||||||
if (NOT TARGET hardware_sync)
|
|
||||||
add_library(hardware_sync INTERFACE)
|
|
||||||
|
|
||||||
target_sources(hardware_sync INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/sync_core0_only.c
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(hardware_sync INTERFACE hardware_sync_headers pico_platform)
|
|
||||||
endif()
|
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _HARDWARE_SYNC_H
|
|
||||||
#define _HARDWARE_SYNC_H
|
|
||||||
|
|
||||||
#include "pico.h"
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
|
|
||||||
#if (__STDC_VERSION__ >= 201112L)
|
|
||||||
#include <stdatomic.h>
|
|
||||||
#else
|
|
||||||
enum {
|
|
||||||
memory_order_acquire, memory_order_release
|
|
||||||
};
|
|
||||||
static inline void atomic_thread_fence(uint x) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_SPINLOCK_ID_TIMER
|
|
||||||
#define PICO_SPINLOCK_ID_TIMER 10
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_SPINLOCK_ID_STRIPED_FIRST
|
|
||||||
#define PICO_SPINLOCK_ID_STRIPED_FIRST 16
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_SPINLOCK_ID_STRIPED_LAST
|
|
||||||
#define PICO_SPINLOCK_ID_STRIPED_LAST 23
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct _spin_lock_t spin_lock_t;
|
|
||||||
|
|
||||||
inline static void __mem_fence_acquire() {
|
|
||||||
#ifndef __cplusplus
|
|
||||||
atomic_thread_fence(memory_order_acquire);
|
|
||||||
#else
|
|
||||||
std::atomic_thread_fence(std::memory_order_acquire);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static void __mem_fence_release() {
|
|
||||||
#ifndef __cplusplus
|
|
||||||
atomic_thread_fence(memory_order_release);
|
|
||||||
#else
|
|
||||||
std::atomic_thread_fence(std::memory_order_release);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void __sev();
|
|
||||||
|
|
||||||
void __wev();
|
|
||||||
|
|
||||||
void __wfi();
|
|
||||||
|
|
||||||
void __wfe();
|
|
||||||
|
|
||||||
uint32_t save_and_disable_interrupts();
|
|
||||||
|
|
||||||
void restore_interrupts(uint32_t status);
|
|
||||||
|
|
||||||
uint spin_lock_get_num(spin_lock_t *lock);
|
|
||||||
|
|
||||||
spin_lock_t *spin_lock_instance(uint lock_num);
|
|
||||||
|
|
||||||
void spin_lock_unsafe_blocking(spin_lock_t *lock);
|
|
||||||
|
|
||||||
void spin_unlock_unsafe(spin_lock_t *lock);
|
|
||||||
|
|
||||||
uint32_t spin_lock_blocking(spin_lock_t *lock);
|
|
||||||
|
|
||||||
bool is_spin_locked(const spin_lock_t *lock);
|
|
||||||
|
|
||||||
void spin_unlock(spin_lock_t *lock, uint32_t saved_irq);
|
|
||||||
|
|
||||||
uint get_core_num();
|
|
||||||
|
|
||||||
spin_lock_t *spin_lock_init(uint lock_num);
|
|
||||||
|
|
||||||
void clear_spin_locks(void);
|
|
||||||
|
|
||||||
uint next_striped_spin_lock_num();
|
|
||||||
|
|
||||||
void spin_lock_claim(uint lock_num);
|
|
||||||
void spin_lock_claim_mask(uint32_t lock_num_mask);
|
|
||||||
void spin_lock_unclaim(uint lock_num);
|
|
||||||
int spin_lock_claim_unused(bool required);
|
|
||||||
uint spin_lock_num(spin_lock_t *lock);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
|
@ -1,140 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hardware/sync.h"
|
|
||||||
#include "hardware/platform_defs.h"
|
|
||||||
|
|
||||||
// This is a dummy implementation that is single threaded
|
|
||||||
|
|
||||||
static struct _spin_lock_t {
|
|
||||||
bool locked;
|
|
||||||
} _spinlocks[NUM_SPIN_LOCKS];
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(save_and_disable_interrupts)
|
|
||||||
|
|
||||||
//static uint8_t striped_spin_lock_num;
|
|
||||||
|
|
||||||
uint32_t PICO_WEAK_FUNCTION_IMPL_NAME(save_and_disable_interrupts)() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(restore_interrupts)
|
|
||||||
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(restore_interrupts)(uint32_t status) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_lock_instance)
|
|
||||||
|
|
||||||
spin_lock_t *PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_instance)(uint lock_num) {
|
|
||||||
assert(lock_num < NUM_SPIN_LOCKS);
|
|
||||||
return &_spinlocks[lock_num];
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_lock_get_num)
|
|
||||||
|
|
||||||
uint PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_get_num)(spin_lock_t *lock) {
|
|
||||||
return lock - _spinlocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_lock_init)
|
|
||||||
|
|
||||||
spin_lock_t *PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_init)(uint lock_num) {
|
|
||||||
spin_lock_t *lock = spin_lock_instance(lock_num);
|
|
||||||
spin_unlock_unsafe(lock);
|
|
||||||
return lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_lock_unsafe_blocking)
|
|
||||||
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_unsafe_blocking)(spin_lock_t *lock) {
|
|
||||||
lock->locked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_lock_blocking)
|
|
||||||
|
|
||||||
uint32_t PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_blocking)(spin_lock_t *lock) {
|
|
||||||
spin_lock_unsafe_blocking(lock);
|
|
||||||
return 1; // todo wrong value
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(is_spin_locked)
|
|
||||||
|
|
||||||
bool PICO_WEAK_FUNCTION_IMPL_NAME(is_spin_locked)(const spin_lock_t *lock) {
|
|
||||||
return lock->locked;
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_unlock_unsafe)
|
|
||||||
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(spin_unlock_unsafe)(spin_lock_t *lock) {
|
|
||||||
lock->locked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_unlock)
|
|
||||||
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(spin_unlock)(spin_lock_t *lock, uint32_t saved_irq) {
|
|
||||||
spin_unlock_unsafe(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(__sev)
|
|
||||||
|
|
||||||
volatile bool event_fired;
|
|
||||||
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(__sev)() {
|
|
||||||
event_fired = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(__wfi)
|
|
||||||
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(__wfi)() {
|
|
||||||
panic("Can't wait on irq for host core0 only implementation");
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(__wfe)
|
|
||||||
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(__wfe)() {
|
|
||||||
while (!event_fired) tight_loop_contents();
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(get_core_num)
|
|
||||||
|
|
||||||
uint PICO_WEAK_FUNCTION_IMPL_NAME(get_core_num)() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(clear_spin_locks)
|
|
||||||
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(clear_spin_locks)(void) {
|
|
||||||
for (uint i = 0; i < NUM_SPIN_LOCKS; i++) {
|
|
||||||
spin_unlock_unsafe(spin_lock_instance(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(next_striped_spin_lock_num)
|
|
||||||
uint PICO_WEAK_FUNCTION_IMPL_NAME(next_striped_spin_lock_num)() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_lock_claim)
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_claim)(uint lock_num) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_lock_claim_mask)
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_claim_mask)(uint32_t mask) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_lock_unclaim)
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_unclaim)(uint lock_num) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_lock_claim_unused)
|
|
||||||
int PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_claim_unused)(bool required) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(spin_lock_num)
|
|
||||||
uint PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_num)(spin_lock_t *lock) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
pico_simple_hardware_target(timer)
|
|
||||||
|
|
||||||
target_compile_definitions(hardware_timer INTERFACE
|
|
||||||
PICO_HARDWARE_TIMER_RESOLUTION_US=1000 # to loosen tests a little
|
|
||||||
)
|
|
||||||
|
|
||||||
if (NOT DEFINED PICO_TIME_NO_ALARM_SUPPORT)
|
|
||||||
# we don't have alarm pools in the basic host support, though pico_host_sdl adds it
|
|
||||||
set(PICO_TIME_NO_ALARM_SUPPORT "1" CACHE INTERNAL "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (PICO_TIME_NO_ALARM_SUPPORT)
|
|
||||||
target_compile_definitions(hardware_timer INTERFACE
|
|
||||||
PICO_TIME_DEFAULT_ALARM_POOL_DISABLED=1
|
|
||||||
)
|
|
||||||
endif()
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _HARDWARE_TIMER_H
|
|
||||||
#define _HARDWARE_TIMER_H
|
|
||||||
|
|
||||||
#include "pico.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PARAM_ASSERTIONS_ENABLED_TIMER
|
|
||||||
#define PARAM_ASSERTIONS_ENABLED_TIMER 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void check_hardware_alarm_num_param(uint alarm_num) {
|
|
||||||
invalid_params_if(TIMER, alarm_num >= NUM_TIMERS);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t time_us_32();
|
|
||||||
uint64_t time_us_64();
|
|
||||||
void busy_wait_us_32(uint32_t delay_us);
|
|
||||||
void busy_wait_us(uint64_t delay_us);
|
|
||||||
void busy_wait_until(absolute_time_t t);
|
|
||||||
bool time_reached(absolute_time_t t);
|
|
||||||
typedef void (*hardware_alarm_callback_t)(uint alarm_num);
|
|
||||||
void hardware_alarm_claim(uint alarm_num);
|
|
||||||
void hardware_alarm_unclaim(uint alarm_num);
|
|
||||||
void hardware_alarm_set_callback(uint alarm_num, hardware_alarm_callback_t callback);
|
|
||||||
bool hardware_alarm_set_target(uint alarm_num, absolute_time_t t);
|
|
||||||
void hardware_alarm_cancel(uint alarm_num);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,104 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hardware/timer.h"
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// in our case not a busy wait
|
|
||||||
PICO_WEAK_FUNCTION_DEF(busy_wait_us)
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(busy_wait_us_32)(uint32_t delay_us) {
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
|
||||||
usleep(delay_us);
|
|
||||||
#else
|
|
||||||
assert(false);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
PICO_WEAK_FUNCTION_DEF(busy_wait_us)
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(busy_wait_us)(uint64_t delay_us) {
|
|
||||||
absolute_time_t t;
|
|
||||||
update_us_since_boot(&t, time_us_64() + delay_us);
|
|
||||||
busy_wait_until(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this may or may not wrap
|
|
||||||
PICO_WEAK_FUNCTION_DEF(time_us_64)
|
|
||||||
uint64_t PICO_WEAK_FUNCTION_IMPL_NAME(time_us_64)() {
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
|
||||||
// struct timeval tv;
|
|
||||||
// gettimeofday(&tv, NULL);
|
|
||||||
// return tv.tv_sec * (uint64_t) 1000000 + tv.tv_usec;
|
|
||||||
struct timespec ts;
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
||||||
return ts.tv_sec * (uint64_t) 1000000 + ts.tv_nsec / 1000;
|
|
||||||
#else
|
|
||||||
panic_unsupported();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(timer_us_32)
|
|
||||||
uint32_t PICO_WEAK_FUNCTION_IMPL_NAME(timer_us_32)() {
|
|
||||||
return (uint32_t) time_us_64();
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(time_reached)
|
|
||||||
bool PICO_WEAK_FUNCTION_IMPL_NAME(time_reached)(absolute_time_t t) {
|
|
||||||
uint64_t target = to_us_since_boot(t);
|
|
||||||
if (target > 0xffffffffu) return false;
|
|
||||||
return time_us_64() >= target;
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(busy_wait_until)
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(busy_wait_until)(absolute_time_t target) {
|
|
||||||
#if defined(__unix__)
|
|
||||||
struct timespec tspec;
|
|
||||||
tspec.tv_sec = to_us_since_boot(target) / 1000000;
|
|
||||||
tspec.tv_nsec = (to_us_since_boot(target) % 1000000) * 1000;
|
|
||||||
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &tspec, NULL);
|
|
||||||
#else
|
|
||||||
const int chunk = 1u<<30u;
|
|
||||||
uint64_t target_us = to_us_since_boot(target);
|
|
||||||
uint64_t time_us = time_us_64();
|
|
||||||
while (target_us - time_us >= chunk) {
|
|
||||||
busy_wait_us_32(chunk);
|
|
||||||
time_us = time_us_64();
|
|
||||||
}
|
|
||||||
if (target_us != time_us) {
|
|
||||||
busy_wait_us_32(target_us - chunk);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t claimed_alarms;
|
|
||||||
|
|
||||||
void hardware_alarm_claim(uint alarm_num) {
|
|
||||||
assert(!(claimed_alarms & (1u << alarm_num)));
|
|
||||||
claimed_alarms |= 1u <<alarm_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hardware_alarm_unclaim(uint alarm_num) {
|
|
||||||
assert(claimed_alarms & (1u << alarm_num));
|
|
||||||
claimed_alarms &= ~(1u <<alarm_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(hardware_alarm_set_callback)
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(hardware_alarm_set_callback)(uint alarm_num, hardware_alarm_callback_t callback) {
|
|
||||||
panic_unsupported();
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(hardware_alarm_set_target)
|
|
||||||
bool PICO_WEAK_FUNCTION_IMPL_NAME(hardware_alarm_set_target)(uint alarm_num, absolute_time_t target) {
|
|
||||||
panic_unsupported();
|
|
||||||
}
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(hardware_alarm_cancel)
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(hardware_alarm_cancel)(uint alarm_num) {
|
|
||||||
panic_unsupported();
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
pico_simple_hardware_target(uart)
|
|
|
@ -1,91 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _HARDWARE_UART_H
|
|
||||||
#define _HARDWARE_UART_H
|
|
||||||
|
|
||||||
#include "pico.h"
|
|
||||||
|
|
||||||
#ifndef PARAM_ASSERTIONS_ENABLED_UART
|
|
||||||
#define PARAM_ASSERTIONS_ENABLED_UART 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct uart_inst uart_inst_t;
|
|
||||||
|
|
||||||
extern uart_inst_t * const uart0;
|
|
||||||
extern uart_inst_t * const uart1;
|
|
||||||
#define uart_default uart0
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
UART_PARITY_NONE,
|
|
||||||
UART_PARITY_EVEN,
|
|
||||||
UART_PARITY_ODD
|
|
||||||
} uart_parity_t;
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Setup
|
|
||||||
|
|
||||||
// Put the UART into a known state, and enable it. Must be called before other
|
|
||||||
// functions.
|
|
||||||
uint uart_init(uart_inst_t *uart, uint baudrate);
|
|
||||||
|
|
||||||
// Disable the UART if it is no longer used. Must be reinitialised before
|
|
||||||
// being used again.
|
|
||||||
void uart_deinit(uart_inst_t *uart);
|
|
||||||
|
|
||||||
// Set baud rate as close as possible to requested, and return actual rate.
|
|
||||||
uint uart_set_baudrate(uart_inst_t *uart, uint baudrate);
|
|
||||||
|
|
||||||
// cts: enable flow control of TX by clear-to-send input
|
|
||||||
// rts: enable assertion of request-to-send output by RX flow control
|
|
||||||
void uart_set_hw_flow(uart_inst_t *uart, bool cts, bool rts);
|
|
||||||
|
|
||||||
// Configure how the UART serialises and deserialises data on the wire
|
|
||||||
void uart_set_format(uart_inst_t *uart, uint data_bits, uint stop_bits, uart_parity_t parity);
|
|
||||||
|
|
||||||
// Enable the UART's interrupt output. Need to install an interrupt handler first.
|
|
||||||
void uart_set_irq_enables(uart_inst_t *uart, bool rx_has_data, bool tx_needs_data);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Generic input/output
|
|
||||||
|
|
||||||
// If returns 0, no space is available in the UART to write more data.
|
|
||||||
// If returns nonzero, at least that many bytes can be written without blocking.
|
|
||||||
size_t uart_is_writable(uart_inst_t *uart);
|
|
||||||
|
|
||||||
// If returns 0, no data is available to be read from UART.
|
|
||||||
// If returns nonzero, at least that many bytes can be written without blocking.
|
|
||||||
size_t uart_is_readable(uart_inst_t *uart);
|
|
||||||
|
|
||||||
// Write len bytes directly from src to the UART
|
|
||||||
void uart_write_blocking(uart_inst_t *uart, const uint8_t *src, size_t len);
|
|
||||||
|
|
||||||
// Read len bytes directly from the UART to dst
|
|
||||||
void uart_read_blocking(uart_inst_t *uart, uint8_t *dst, size_t len);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// UART-specific operations and aliases
|
|
||||||
|
|
||||||
void uart_putc(uart_inst_t *uart, char c);
|
|
||||||
|
|
||||||
void uart_puts(uart_inst_t *uart, const char *s);
|
|
||||||
|
|
||||||
char uart_getc(uart_inst_t *uart);
|
|
||||||
|
|
||||||
// en: assert break condition (TX held low) if true. Clear break condition if false.
|
|
||||||
void uart_set_break(uart_inst_t *uart, bool en);
|
|
||||||
|
|
||||||
void uart_default_tx_wait_blocking();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,118 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "hardware/uart.h"
|
|
||||||
|
|
||||||
#if defined(__unix) || defined(__APPLE__)
|
|
||||||
#define _XOPEN_SOURCE 600 /* for ONLCR */
|
|
||||||
#define __BSD_VISIBLE 1 /* for ONLCR in *BSD */
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifndef FNONBLOCK
|
|
||||||
#define FNONBLOCK O_NONBLOCK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct termios _tty;
|
|
||||||
static tcflag_t _res_oflg = 0;
|
|
||||||
static tcflag_t _res_lflg = 0;
|
|
||||||
|
|
||||||
void _resetty(void) {
|
|
||||||
if (!isatty(STDIN_FILENO))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* reset tty: */
|
|
||||||
_tty.c_oflag = _res_oflg;
|
|
||||||
_tty.c_lflag = _res_lflg;
|
|
||||||
tcsetattr(STDIN_FILENO, TCSADRAIN, &_tty);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _inittty(void) {
|
|
||||||
if (!isatty(STDIN_FILENO))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* save tty: */
|
|
||||||
tcgetattr(STDIN_FILENO, &_tty);
|
|
||||||
_res_oflg = _tty.c_oflag;
|
|
||||||
_res_lflg = _tty.c_lflag;
|
|
||||||
|
|
||||||
/* set raw: */
|
|
||||||
_tty.c_lflag &= ~(ICANON | ICRNL);// | ISIG);
|
|
||||||
//_tty.c_oflag &= ~ONLCR;
|
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &_tty);
|
|
||||||
|
|
||||||
fcntl(STDIN_FILENO, F_SETFL, FNONBLOCK);
|
|
||||||
atexit(_resetty);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
void _inittty() {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool dummy;
|
|
||||||
} uart_hw_t;
|
|
||||||
|
|
||||||
uart_inst_t *const uart0;
|
|
||||||
uart_inst_t *const uart1;
|
|
||||||
|
|
||||||
static int _nextchar = EOF;
|
|
||||||
|
|
||||||
static bool _peekchar() {
|
|
||||||
if (_nextchar == EOF) {
|
|
||||||
_nextchar = getchar();
|
|
||||||
}
|
|
||||||
return _nextchar != EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint uart_init(uart_inst_t *uart, uint baud_rate) {
|
|
||||||
_inittty();
|
|
||||||
return baud_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t uart_is_writable(uart_inst_t *uart) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If returns 0, no data is available to be read from UART.
|
|
||||||
// If returns nonzero, at least that many bytes can be written without blocking.
|
|
||||||
size_t uart_is_readable(uart_inst_t *uart) {
|
|
||||||
return _peekchar() ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write len bytes directly from src to the UART
|
|
||||||
//void uart_write_blocking(uart_inst_t uart, const uint8_t *src, size_t len);
|
|
||||||
|
|
||||||
// Read len bytes directly from the UART to dst
|
|
||||||
//void uart_read_blocking(uart_inst_t uart, uint8_t *dst, size_t len);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// UART-specific operations and aliases
|
|
||||||
|
|
||||||
void uart_putc(uart_inst_t *uart, char c) {
|
|
||||||
putchar(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart_puts(uart_inst_t *uart, const char *s) {
|
|
||||||
puts(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
char uart_getc(uart_inst_t *uart) {
|
|
||||||
while (!_peekchar()) {
|
|
||||||
tight_loop_contents();
|
|
||||||
}
|
|
||||||
char rc = (char) _nextchar;
|
|
||||||
_nextchar = EOF;
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart_default_tx_wait_blocking() {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
add_library(pico_bit_ops INTERFACE)
|
|
||||||
|
|
||||||
target_sources(pico_bit_ops INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/bit_ops.c)
|
|
||||||
|
|
||||||
target_link_libraries(pico_bit_ops INTERFACE pico_bit_ops_headers)
|
|
||||||
|
|
||||||
macro(pico_set_bit_ops_implementation TARGET IMPL)
|
|
||||||
endmacro()
|
|
|
@ -1,22 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pico/bit_ops.h"
|
|
||||||
|
|
||||||
uint32_t __rev(uint32_t v) {
|
|
||||||
v = ((v & 0x55555555u) << 1u) | ((v >> 1u) & 0x55555555u);
|
|
||||||
v = ((v & 0x33333333u) << 2u) | ((v >> 2u) & 0x33333333u);
|
|
||||||
v = ((v & 0x0f0f0f0fu) << 4u) | ((v >> 4u) & 0x0f0f0f0fu);
|
|
||||||
return (v << 24u) | ((v & 0xff00u) << 8u) | ((v >> 8u) & 0xff00u) | (v >> 24u);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t __revll(uint64_t v) {
|
|
||||||
v = ((v & 0x5555555555555555u) << 1u) | ((v >> 1u) & 0x5555555555555555u);
|
|
||||||
v = ((v & 0x3333333333333333u) << 2u) | ((v >> 2u) & 0x3333333333333333u);
|
|
||||||
v = ((v & 0x0f0f0f0f0f0f0f0fu) << 4u) | ((v >> 4u) & 0x0f0f0f0f0f0f0f0fu);
|
|
||||||
v = ((v & 0x00ff00ff00ff00ffu) << 8u) | ((v >> 8u) & 0x00ff00ff00ff00ffu);
|
|
||||||
return (v << 48u) | ((v & 0xffff0000u) << 16u) | ((v >> 16u) & 0xffff0000u) | (v >> 48u);
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
add_library(pico_divider INTERFACE)
|
|
||||||
|
|
||||||
target_sources(pico_divider INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/divider.c)
|
|
||||||
|
|
||||||
target_link_libraries(pico_divider INTERFACE pico_divider_headers)
|
|
||||||
|
|
||||||
macro(pico_set_divider_implementation TARGET IMPL)
|
|
||||||
endmacro()
|
|
|
@ -1,114 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pico/divider.h"
|
|
||||||
|
|
||||||
// These functions save/restore divider state, so are safe to call from interrupts
|
|
||||||
int32_t div_s32s32(int32_t a, int32_t b) {
|
|
||||||
return hw_divider_s32_quotient(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
divmod_result_t divmod_s32s32(int32_t a, int32_t b) {
|
|
||||||
return hw_divider_divmod_s32(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t div_u32u32(uint32_t a, uint32_t b) {
|
|
||||||
return hw_divider_u32_quotient(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
divmod_result_t divmod_u32u32(uint32_t a, uint32_t b) {
|
|
||||||
return hw_divider_divmod_u32(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int __sign_of_64(int32_t v) {
|
|
||||||
return v > 0 ? 1 : (v < 0 ? -1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint64_t quotient;
|
|
||||||
uint64_t remainder;
|
|
||||||
} qr_u64;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int64_t quotient;
|
|
||||||
int64_t remainder;
|
|
||||||
} qr_s64;
|
|
||||||
|
|
||||||
// divides unsigned values a by b... (a/b) returned in low 32 bits, (a%b) in high 32 bits... results undefined for b==0
|
|
||||||
static inline qr_u64 udiv64(uint64_t a, uint64_t b) {
|
|
||||||
qr_u64 rc;
|
|
||||||
if (!b) {
|
|
||||||
rc.quotient = (uint64_t)-1; // todo check this
|
|
||||||
rc.remainder = a;
|
|
||||||
} else {
|
|
||||||
rc.quotient = a/b;
|
|
||||||
rc.remainder = a%b;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// divides signed values a by b... (a/b) returned in low 32 bits, (a%b) in high 32 bits... results undefined for b==0
|
|
||||||
static inline qr_s64 div64(int64_t a, int64_t b) {
|
|
||||||
qr_s64 rc;
|
|
||||||
if (!b) {
|
|
||||||
rc.quotient = (uint64_t)(-__sign_of_64(a));
|
|
||||||
rc.remainder = a;
|
|
||||||
} else {
|
|
||||||
rc.quotient = a/b;
|
|
||||||
rc.remainder = a%b;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t div_s64s64(int64_t a, int64_t b) {
|
|
||||||
qr_s64 qr = div64(a, b);
|
|
||||||
return qr.quotient;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t divmod_s64s64_rem(int64_t a, int64_t b, int64_t *rem) {
|
|
||||||
qr_s64 qr = div64(a, b);
|
|
||||||
*rem = qr.remainder;
|
|
||||||
return qr.quotient;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t divmod_s64s64(int64_t a, int64_t b) {
|
|
||||||
qr_s64 qr = div64(a, b);
|
|
||||||
return qr.quotient;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t div_u64u64(uint64_t a, uint64_t b) {
|
|
||||||
qr_u64 qr = udiv64(a, b);
|
|
||||||
return qr.quotient;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t divmod_u64u64_rem(uint64_t a, uint64_t b, uint64_t *rem) {
|
|
||||||
qr_u64 qr = udiv64(a, b);
|
|
||||||
*rem = qr.remainder;
|
|
||||||
return qr.quotient;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t divmod_u64u64(uint64_t a, uint64_t b) {
|
|
||||||
qr_u64 qr = udiv64(a, b);
|
|
||||||
return qr.quotient;
|
|
||||||
}
|
|
||||||
|
|
||||||
// these functions are slightly faster, but unsafe the divider state, so are not generally safe to be called from interrupts
|
|
||||||
|
|
||||||
int32_t div_s32s32_unsafe(int32_t a, int32_t b) { return div_s32s32(a,b); }
|
|
||||||
int32_t divmod_s32s32_rem_unsafe(int32_t a, int32_t b, int32_t *rem) { return divmod_s32s32_rem(a, b, rem); }
|
|
||||||
int64_t divmod_s32s32_unsafe(int32_t a, int32_t b) { return divmod_s32s32(a, b); }
|
|
||||||
|
|
||||||
uint32_t div_u32u32_unsafe(uint32_t a, uint32_t b) { return div_u32u32(a, b); }
|
|
||||||
uint32_t divmod_u32u32_rem_unsafe(uint32_t a, uint32_t b, uint32_t *rem) { return divmod_u32u32_rem(a, b, rem); }
|
|
||||||
uint64_t divmod_u32u32_unsafe(uint32_t a, uint32_t b) { return divmod_u32u32(a, b); }
|
|
||||||
|
|
||||||
int64_t div_s64s64_unsafe(int64_t a, int64_t b) { return div_s64s64(a, b); }
|
|
||||||
int64_t divmod_s64s64_rem_unsafe(int64_t a, int64_t b, int64_t *rem) { return divmod_s64s64_rem(a, b, rem); }
|
|
||||||
int64_t divmod_s64s64_unsafe(int64_t a, int64_t b) { return divmod_s64s64(a, b); }
|
|
||||||
|
|
||||||
uint64_t div_u64u64_unsafe(uint64_t a, uint64_t b) { return div_u64u64(a, b); }
|
|
||||||
uint64_t divmod_u64u64_rem_unsafe(uint64_t a, uint64_t b, uint64_t *rem) { return divmod_u64u64_rem(a, b, rem); }
|
|
||||||
uint64_t divmod_u64u64_unsafe(uint64_t a, uint64_t b) { return divmod_u64u64(a, b); }
|
|
|
@ -1,8 +0,0 @@
|
||||||
if (NOT TARGET pico_multicore)
|
|
||||||
add_library(pico_multicore INTERFACE)
|
|
||||||
|
|
||||||
target_include_directories(pico_multicore INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PICO_MULTICORE_H
|
|
||||||
#define _PICO_MULTICORE_H
|
|
||||||
|
|
||||||
#include "pico/types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void multicore_reset_core1();
|
|
||||||
void multicore_launch_core1(void (*entry)(void));
|
|
||||||
void multicore_launch_core1_with_stack(void (*entry)(void), uint32_t *stack_bottom, size_t stack_size_bytes);
|
|
||||||
void multicore_sleep_core1();
|
|
||||||
void multicore_launch_core1_raw(void (*entry)(void), uint32_t *sp, uint32_t vector_table);
|
|
||||||
|
|
||||||
bool multicore_fifo_rvalid();
|
|
||||||
bool multicore_fifo_wready();
|
|
||||||
void multicore_fifo_push(uint32_t data);
|
|
||||||
uint32_t multicore_fifo_pop_blocking();
|
|
||||||
void multicore_fifo_drain();
|
|
||||||
void multicore_fifo_clear_irq();
|
|
||||||
int32_t multicore_fifo_get_status();
|
|
||||||
|
|
||||||
// call this from the lockout victim thread
|
|
||||||
void multicore_lockout_victim_init();
|
|
||||||
|
|
||||||
// start locking out the other core (it will be
|
|
||||||
bool multicore_lockout_start_timeout_us(uint64_t timeout_us);
|
|
||||||
void multicore_lockout_start_blocking();
|
|
||||||
|
|
||||||
bool multicore_lockout_end_timeout_us(uint64_t timeout_us);
|
|
||||||
void multicore_lockout_end_blocking();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,25 +0,0 @@
|
||||||
if (NOT TARGET pico_platform_headers)
|
|
||||||
add_library(pico_platform_headers INTERFACE)
|
|
||||||
|
|
||||||
target_compile_definitions(pico_platform_headers INTERFACE
|
|
||||||
PICO_NO_HARDWARE=1
|
|
||||||
PICO_ON_DEVICE=0
|
|
||||||
PICO_BUILD=1
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(pico_platform_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET pico_platform)
|
|
||||||
add_library(pico_platform INTERFACE)
|
|
||||||
|
|
||||||
target_sources(pico_platform INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platform_base.c
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(pico_platform INTERFACE pico_platform_headers pico_bit_ops ${PICO_PLATFORM_EXTRA_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
function(pico_add_platform_library TARGET)
|
|
||||||
target_link_libraries(pico_platform INTERFACE ${TARGET})
|
|
||||||
endfunction()
|
|
|
@ -1,24 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _HARDWARE_PLATFORM_DEFS_H
|
|
||||||
#define _HARDWARE_PLATFORM_DEFS_H
|
|
||||||
|
|
||||||
#define NUM_CORES 2u
|
|
||||||
|
|
||||||
#define NUM_DMA_CHANNELS 12u
|
|
||||||
|
|
||||||
#define NUM_TIMERS 4u
|
|
||||||
|
|
||||||
#define NUM_IRQS 32u
|
|
||||||
|
|
||||||
#define NUM_SPIN_LOCKS 32u
|
|
||||||
|
|
||||||
#define XOSC_MHZ 12
|
|
||||||
|
|
||||||
#define NUM_SPIN_LOCKS 32u
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PICO_PLATFORM_H_
|
|
||||||
#define _PICO_PLATFORM_H_
|
|
||||||
|
|
||||||
#include "hardware/platform_defs.h"
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#ifdef __unix__
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define __not_in_flash(grup)
|
|
||||||
#define __not_in_flash_func(func) func
|
|
||||||
#define __no_inline_not_in_flash_func(func)
|
|
||||||
#define __in_flash(group)
|
|
||||||
#define __scratch_x(group)
|
|
||||||
#define __scratch_y(group)
|
|
||||||
|
|
||||||
#define __packed_aligned
|
|
||||||
#define __packed
|
|
||||||
|
|
||||||
#define __time_critical_func(x) x
|
|
||||||
#define __after_data(group)
|
|
||||||
|
|
||||||
//int running_on_fpga() { return false; }
|
|
||||||
extern void tight_loop_contents();
|
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
|
||||||
#ifndef __noreturn
|
|
||||||
#define __noreturn __attribute((noreturn))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __unused
|
|
||||||
#define __unused __attribute__((unused))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __noinline
|
|
||||||
#define __noinline __attribute__((noinline))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __aligned
|
|
||||||
#define __aligned(x) __attribute__((aligned(x)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PICO_WEAK_FUNCTION_DEF(x) _Pragma(__STRING(weak x))
|
|
||||||
#define PICO_WEAK_FUNCTION_IMPL_NAME(x) x
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifndef __noreturn
|
|
||||||
#define __noreturn __declspec(noreturn)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __unused
|
|
||||||
#define __unused
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __noinline
|
|
||||||
#define __noinline __declspec(noinline)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __aligned
|
|
||||||
#define __aligned(x) __declspec(align(x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __CONCAT
|
|
||||||
#define __CONCAT(x,y) x ## y
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __STRING
|
|
||||||
#define __STRING(x) #x
|
|
||||||
#endif()
|
|
||||||
|
|
||||||
#define __thread __declspec( thread )
|
|
||||||
|
|
||||||
#define PICO_WEAK_FUNCTION_DEF(x) __pragma(comment(linker, __STRING(/alternatename:_##x=_##x##__weak)));
|
|
||||||
#define PICO_WEAK_FUNCTION_IMPL_NAME(x) x ## __weak
|
|
||||||
|
|
||||||
static __noreturn void __builtin_unreachable() {
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <intrin.h>
|
|
||||||
#define __builtin_clz __lzcnt
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef count_of
|
|
||||||
#define count_of(a) (sizeof(a)/sizeof((a)[0]))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MAX
|
|
||||||
#define MAX(a, b) ((a)>(b)?(a):(b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MIN
|
|
||||||
#define MIN(a, b) ((b)>(a)?(a):(b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// abort in our case
|
|
||||||
void __noreturn __breakpoint();
|
|
||||||
|
|
||||||
void __noreturn panic_unsupported();
|
|
||||||
|
|
||||||
void __noreturn panic(const char *fmt, ...);
|
|
||||||
|
|
||||||
// arggggghhhh there is a weak function called sem_init used by SDL
|
|
||||||
#define sem_init sem_init_alternative
|
|
||||||
|
|
||||||
extern uint32_t host_safe_hw_ptr_impl(uintptr_t x);
|
|
||||||
// return a 32 bit handle for a raw ptr; DMA chaining for example embeds pointers in 32 bit values
|
|
||||||
// which of course does not work if we're running the code natively on a 64 bit platforms. Therefore
|
|
||||||
// we provide this macro which allows that code to provide a 64->32 bit mapping in host mode
|
|
||||||
#define host_safe_hw_ptr(x) host_safe_hw_ptr_impl((uintptr_t)(x))
|
|
||||||
void *decode_host_safe_hw_ptr(uint32_t ptr);
|
|
||||||
|
|
||||||
#define __fast_mul(a,b) ((a)*(b))
|
|
||||||
|
|
||||||
typedef unsigned int uint;
|
|
||||||
|
|
||||||
inline static int32_t __mul_instruction(int32_t a,int32_t b)
|
|
||||||
{
|
|
||||||
return a*b;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "pico.h"
|
|
||||||
|
|
||||||
PICO_WEAK_FUNCTION_DEF(tight_loop_contents)
|
|
||||||
|
|
||||||
void PICO_WEAK_FUNCTION_IMPL_NAME(tight_loop_contents)() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void __noreturn panic_unsupported() {
|
|
||||||
panic("not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
void hard_assertion_failure(void) {
|
|
||||||
panic("Hard assert");
|
|
||||||
}
|
|
||||||
|
|
||||||
void panic(const char *fmt, ...) {
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
puts("*** PANIC ***\n");
|
|
||||||
if (fmt) {
|
|
||||||
va_start(args, fmt);
|
|
||||||
vprintf(fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
puts("\n");
|
|
||||||
|
|
||||||
__breakpoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __breakpoint() {
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
__debugbreak();
|
|
||||||
#else
|
|
||||||
__builtin_trap();
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
if (NOT TARGET pico_printf)
|
|
||||||
add_library(pico_printf INTERFACE)
|
|
||||||
function(pico_set_printf_implementation)
|
|
||||||
endfunction()
|
|
||||||
endif()
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
if (NOT TARGET pico_stdio)
|
|
||||||
add_library(pico_stdio INTERFACE)
|
|
||||||
|
|
||||||
target_include_directories(pico_stdio INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
|
||||||
|
|
||||||
target_sources(pico_stdio INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/stdio.c
|
|
||||||
)
|
|
||||||
add_library(pico_stdio_usb INTERFACE)
|
|
||||||
add_library(pico_stdio_uart INTERFACE)
|
|
||||||
add_library(pico_stdio_semihosting INTERFACE)
|
|
||||||
|
|
||||||
function(pico_enable_stdio_uart)
|
|
||||||
endfunction()
|
|
||||||
function(pico_enable_stdio_usb)
|
|
||||||
endfunction()
|
|
||||||
function(pico_enable_stdio_semihosting)
|
|
||||||
endfunction()
|
|
||||||
endif()
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
#ifndef _PICO_STDIO_H
|
|
||||||
#define _PICO_STDIO_H
|
|
||||||
|
|
||||||
typedef struct stdio_driver stdio_driver_t;
|
|
||||||
|
|
||||||
#define STDIO_ERROR -1
|
|
||||||
#define STDIO_NO_INPUT -2
|
|
||||||
|
|
||||||
static inline void stdio_usb_init() {}
|
|
||||||
void stdio_uart_init();
|
|
||||||
static inline void stdio_init_all() { stdio_uart_init(); }
|
|
||||||
static inline void stdio_filter_driver(stdio_driver_t *);
|
|
||||||
static inline void stdio_set_translate_crlf(stdio_driver_t *driver, bool enabled) {}
|
|
||||||
int getchar_timeout_us(uint32_t timeout_us);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,23 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pico/stdlib.h"
|
|
||||||
#include "hardware/uart.h"
|
|
||||||
|
|
||||||
int getchar_timeout_us(uint32_t timeout_us) {
|
|
||||||
absolute_time_t t = make_timeout_time_us(timeout_us);
|
|
||||||
while (!uart_is_readable(uart_default)) {
|
|
||||||
if (absolute_time_diff_us(t, get_absolute_time()) > 0) {
|
|
||||||
return STDIO_NO_INPUT;
|
|
||||||
}
|
|
||||||
sleep_ms(1);
|
|
||||||
}
|
|
||||||
return uart_getc(uart_default);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stdio_uart_init() {
|
|
||||||
uart_init(uart_default, 0);
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
if (NOT TARGET pico_stdlib)
|
|
||||||
add_library(pico_stdlib INTERFACE)
|
|
||||||
|
|
||||||
target_sources(pico_stdlib INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/stdlib.c
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(pico_stdlib INTERFACE
|
|
||||||
pico_stdlib_headers
|
|
||||||
pico_platform
|
|
||||||
pico_time
|
|
||||||
pico_divider
|
|
||||||
pico_binary_info
|
|
||||||
pico_printf
|
|
||||||
pico_stdio
|
|
||||||
hardware_gpio
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pico/stdlib.h"
|
|
||||||
|
|
||||||
void setup_default_uart() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_sys_clock_48mhz() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool check_sys_clock_khz(uint32_t freq_khz, uint *vco_out, uint *postdiv1_out, uint *postdiv2_out) {
|
|
||||||
*vco_out = 1000000;
|
|
||||||
*postdiv1_out = 0;
|
|
||||||
*postdiv2_out = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_sys_clock_pll(__unused uint32_t vco_freq, __unused uint post_div1, __unused uint post_div2) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
# include everything needed to build against rp2040
|
|
||||||
|
|
||||||
include(rp2_common.cmake)
|
|
||||||
|
|
||||||
add_subdirectory(rp2040)
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
# Targets specific to B0 silicon
|
|
||||||
pico_add_subdirectory(hardware_regs)
|
|
||||||
pico_add_subdirectory(hardware_structs)
|
|
||||||
|
|
||||||
pico_add_doxygen(${CMAKE_CURRENT_LIST_DIR})
|
|
||||||
pico_add_doxygen_exclude(${CMAKE_CURRENT_LIST_DIR}/hardware_regs) # very very big
|
|
|
@ -1,7 +0,0 @@
|
||||||
This directory contains header files defining the RP2040 hardware. It is selected when
|
|
||||||
`PICO_PLATFORM=rp2040` (the default) is specified for the build
|
|
||||||
|
|
||||||
`hardware_regs` contains low level hardware register #defines autogenerated from the RP2040 chip definition itself.
|
|
||||||
|
|
||||||
`hardware_structs` contains C structures for accessing memory mapped registers
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
add_library(hardware_regs INTERFACE)
|
|
||||||
target_include_directories(hardware_regs INTERFACE include)
|
|
||||||
target_link_libraries(hardware_regs INTERFACE hardware_base)
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _HARDWARE_PLATFORM_DEFS_H
|
|
||||||
#define _HARDWARE_PLATFORM_DEFS_H
|
|
||||||
|
|
||||||
// This header is included from C and assembler - only define macros
|
|
||||||
|
|
||||||
#include "hardware/regs/addressmap.h"
|
|
||||||
|
|
||||||
#define NUM_CORES 2u
|
|
||||||
#define NUM_DMA_CHANNELS 12u
|
|
||||||
#define NUM_IRQS 32u
|
|
||||||
#define NUM_PIOS 2u
|
|
||||||
#define NUM_PIO_STATE_MACHINES 4u
|
|
||||||
#define NUM_PWM_SLICES 8u
|
|
||||||
#define NUM_SPIN_LOCKS 32u
|
|
||||||
#define NUM_UARTS 2u
|
|
||||||
#define NUM_BANK0_GPIOS 30u
|
|
||||||
|
|
||||||
#define PIO_INSTRUCTION_COUNT 32u
|
|
||||||
|
|
||||||
#define XOSC_MHZ 12u
|
|
||||||
|
|
||||||
// PICO_CONFIG: PICO_STACK_SIZE, Stack Size, min=0x100, default=0x800, advanced=true, group=pico_standard_link
|
|
||||||
#ifndef PICO_STACK_SIZE
|
|
||||||
#define PICO_STACK_SIZE 0x800u
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// PICO_CONFIG: PICO_HEAP_SIZE, Heap size to reserve, min=0x100, default=0x800, advanced=true, group=pico_standard_link
|
|
||||||
#ifndef PICO_HEAP_SIZE
|
|
||||||
#define PICO_HEAP_SIZE 0x800
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// PICO_CONFIG: PICO_NO_RAM_VECTOR_TABLE, Enable/disable the RAM vector table, type=bool, default=0, advanced=true, group=pico_runtime
|
|
||||||
#ifndef PICO_NO_RAM_VECTOR_TABLE
|
|
||||||
#define PICO_NO_RAM_VECTOR_TABLE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PICO_FLASH_SIZE_BYTES
|
|
||||||
#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
#ifndef _ADDRESSMAP_H_
|
|
||||||
#define _ADDRESSMAP_H_
|
|
||||||
|
|
||||||
// Register address offsets for atomic RMW aliases
|
|
||||||
#define REG_ALIAS_RW_BITS (0x0u << 12u)
|
|
||||||
#define REG_ALIAS_XOR_BITS (0x1u << 12u)
|
|
||||||
#define REG_ALIAS_SET_BITS (0x2u << 12u)
|
|
||||||
#define REG_ALIAS_CLR_BITS (0x3u << 12u)
|
|
||||||
|
|
||||||
#define ROM_BASE 0x00000000
|
|
||||||
#define XIP_BASE 0x10000000
|
|
||||||
#define XIP_MAIN_BASE 0x10000000
|
|
||||||
#define XIP_NOALLOC_BASE 0x11000000
|
|
||||||
#define XIP_NOCACHE_BASE 0x12000000
|
|
||||||
#define XIP_NOCACHE_NOALLOC_BASE 0x13000000
|
|
||||||
#define XIP_CTRL_BASE 0x14000000
|
|
||||||
#define XIP_SRAM_BASE 0x15000000
|
|
||||||
#define XIP_SRAM_END 0x15004000
|
|
||||||
#define XIP_SSI_BASE 0x18000000
|
|
||||||
#define SRAM_BASE 0x20000000
|
|
||||||
#define SRAM_STRIPED_BASE 0x20000000
|
|
||||||
#define SRAM_STRIPED_END 0x20040000
|
|
||||||
#define SRAM4_BASE 0x20040000
|
|
||||||
#define SRAM5_BASE 0x20041000
|
|
||||||
#define SRAM_END 0x20042000
|
|
||||||
#define SRAM0_BASE 0x21000000
|
|
||||||
#define SRAM1_BASE 0x21010000
|
|
||||||
#define SRAM2_BASE 0x21020000
|
|
||||||
#define SRAM3_BASE 0x21030000
|
|
||||||
#define SYSINFO_BASE 0x40000000
|
|
||||||
#define SYSCFG_BASE 0x40004000
|
|
||||||
#define CLOCKS_BASE 0x40008000
|
|
||||||
#define RESETS_BASE 0x4000c000
|
|
||||||
#define PSM_BASE 0x40010000
|
|
||||||
#define IO_BANK0_BASE 0x40014000
|
|
||||||
#define IO_QSPI_BASE 0x40018000
|
|
||||||
#define PADS_BANK0_BASE 0x4001c000
|
|
||||||
#define PADS_QSPI_BASE 0x40020000
|
|
||||||
#define XOSC_BASE 0x40024000
|
|
||||||
#define PLL_SYS_BASE 0x40028000
|
|
||||||
#define PLL_USB_BASE 0x4002c000
|
|
||||||
#define BUSCTRL_BASE 0x40030000
|
|
||||||
#define UART0_BASE 0x40034000
|
|
||||||
#define UART1_BASE 0x40038000
|
|
||||||
#define SPI0_BASE 0x4003c000
|
|
||||||
#define SPI1_BASE 0x40040000
|
|
||||||
#define I2C0_BASE 0x40044000
|
|
||||||
#define I2C1_BASE 0x40048000
|
|
||||||
#define ADC_BASE 0x4004c000
|
|
||||||
#define PWM_BASE 0x40050000
|
|
||||||
#define TIMER_BASE 0x40054000
|
|
||||||
#define WATCHDOG_BASE 0x40058000
|
|
||||||
#define RTC_BASE 0x4005c000
|
|
||||||
#define ROSC_BASE 0x40060000
|
|
||||||
#define VREG_AND_CHIP_RESET_BASE 0x40064000
|
|
||||||
#define TBMAN_BASE 0x4006c000
|
|
||||||
#define DMA_BASE 0x50000000
|
|
||||||
#define USBCTRL_DPRAM_BASE 0x50100000
|
|
||||||
#define USBCTRL_BASE 0x50100000
|
|
||||||
#define USBCTRL_REGS_BASE 0x50110000
|
|
||||||
#define PIO0_BASE 0x50200000
|
|
||||||
#define PIO1_BASE 0x50300000
|
|
||||||
#define XIP_AUX_BASE 0x50400000
|
|
||||||
#define SIO_BASE 0xd0000000
|
|
||||||
#define PPB_BASE 0xe0000000
|
|
||||||
|
|
||||||
#endif // _ADDRESSMAP_H_
|
|
|
@ -1,160 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
// =============================================================================
|
|
||||||
// Register block : BUSCTRL
|
|
||||||
// Version : 1
|
|
||||||
// Bus type : apb
|
|
||||||
// Description : Register block for busfabric control signals and performance
|
|
||||||
// counters
|
|
||||||
// =============================================================================
|
|
||||||
#ifndef HARDWARE_REGS_BUSCTRL_DEFINED
|
|
||||||
#define HARDWARE_REGS_BUSCTRL_DEFINED
|
|
||||||
// =============================================================================
|
|
||||||
// Register : BUSCTRL_BUS_PRIORITY
|
|
||||||
// Description : Set the priority of each master for bus arbitration.
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_OFFSET 0x00000000
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_BITS 0x00001111
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_RESET 0x00000000
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// Field : BUSCTRL_BUS_PRIORITY_DMA_W
|
|
||||||
// Description : 0 - low priority, 1 - high priority
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_DMA_W_RESET 0x0
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_DMA_W_BITS 0x00001000
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_DMA_W_MSB 12
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_DMA_W_LSB 12
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_DMA_W_ACCESS "RW"
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// Field : BUSCTRL_BUS_PRIORITY_DMA_R
|
|
||||||
// Description : 0 - low priority, 1 - high priority
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_DMA_R_RESET 0x0
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_DMA_R_BITS 0x00000100
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_DMA_R_MSB 8
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_DMA_R_LSB 8
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_DMA_R_ACCESS "RW"
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// Field : BUSCTRL_BUS_PRIORITY_PROC1
|
|
||||||
// Description : 0 - low priority, 1 - high priority
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_PROC1_RESET 0x0
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_PROC1_BITS 0x00000010
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_PROC1_MSB 4
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_PROC1_LSB 4
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_PROC1_ACCESS "RW"
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// Field : BUSCTRL_BUS_PRIORITY_PROC0
|
|
||||||
// Description : 0 - low priority, 1 - high priority
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_PROC0_RESET 0x0
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_PROC0_BITS 0x00000001
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_PROC0_MSB 0
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_PROC0_LSB 0
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_PROC0_ACCESS "RW"
|
|
||||||
// =============================================================================
|
|
||||||
// Register : BUSCTRL_BUS_PRIORITY_ACK
|
|
||||||
// Description : Bus priority acknowledge
|
|
||||||
// Goes to 1 once all arbiters have registered the new global
|
|
||||||
// priority levels.
|
|
||||||
// Arbiters update their local priority when servicing a new
|
|
||||||
// nonsequential access.
|
|
||||||
// In normal circumstances this will happen almost immediately.
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_ACK_OFFSET 0x00000004
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_ACK_BITS 0x00000001
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_ACK_RESET 0x00000000
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_ACK_MSB 0
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_ACK_LSB 0
|
|
||||||
#define BUSCTRL_BUS_PRIORITY_ACK_ACCESS "RO"
|
|
||||||
// =============================================================================
|
|
||||||
// Register : BUSCTRL_PERFCTR0
|
|
||||||
// Description : Bus fabric performance counter 0
|
|
||||||
// Busfabric saturating performance counter 0
|
|
||||||
// Count some event signal from the busfabric arbiters.
|
|
||||||
// Write any value to clear. Select an event to count using
|
|
||||||
// PERFSEL0
|
|
||||||
#define BUSCTRL_PERFCTR0_OFFSET 0x00000008
|
|
||||||
#define BUSCTRL_PERFCTR0_BITS 0x00ffffff
|
|
||||||
#define BUSCTRL_PERFCTR0_RESET 0x00000000
|
|
||||||
#define BUSCTRL_PERFCTR0_MSB 23
|
|
||||||
#define BUSCTRL_PERFCTR0_LSB 0
|
|
||||||
#define BUSCTRL_PERFCTR0_ACCESS "WC"
|
|
||||||
// =============================================================================
|
|
||||||
// Register : BUSCTRL_PERFSEL0
|
|
||||||
// Description : Bus fabric performance event select for PERFCTR0
|
|
||||||
// Select a performance event for PERFCTR0
|
|
||||||
#define BUSCTRL_PERFSEL0_OFFSET 0x0000000c
|
|
||||||
#define BUSCTRL_PERFSEL0_BITS 0x0000001f
|
|
||||||
#define BUSCTRL_PERFSEL0_RESET 0x0000001f
|
|
||||||
#define BUSCTRL_PERFSEL0_MSB 4
|
|
||||||
#define BUSCTRL_PERFSEL0_LSB 0
|
|
||||||
#define BUSCTRL_PERFSEL0_ACCESS "RW"
|
|
||||||
// =============================================================================
|
|
||||||
// Register : BUSCTRL_PERFCTR1
|
|
||||||
// Description : Bus fabric performance counter 1
|
|
||||||
// Busfabric saturating performance counter 1
|
|
||||||
// Count some event signal from the busfabric arbiters.
|
|
||||||
// Write any value to clear. Select an event to count using
|
|
||||||
// PERFSEL1
|
|
||||||
#define BUSCTRL_PERFCTR1_OFFSET 0x00000010
|
|
||||||
#define BUSCTRL_PERFCTR1_BITS 0x00ffffff
|
|
||||||
#define BUSCTRL_PERFCTR1_RESET 0x00000000
|
|
||||||
#define BUSCTRL_PERFCTR1_MSB 23
|
|
||||||
#define BUSCTRL_PERFCTR1_LSB 0
|
|
||||||
#define BUSCTRL_PERFCTR1_ACCESS "WC"
|
|
||||||
// =============================================================================
|
|
||||||
// Register : BUSCTRL_PERFSEL1
|
|
||||||
// Description : Bus fabric performance event select for PERFCTR1
|
|
||||||
// Select a performance event for PERFCTR1
|
|
||||||
#define BUSCTRL_PERFSEL1_OFFSET 0x00000014
|
|
||||||
#define BUSCTRL_PERFSEL1_BITS 0x0000001f
|
|
||||||
#define BUSCTRL_PERFSEL1_RESET 0x0000001f
|
|
||||||
#define BUSCTRL_PERFSEL1_MSB 4
|
|
||||||
#define BUSCTRL_PERFSEL1_LSB 0
|
|
||||||
#define BUSCTRL_PERFSEL1_ACCESS "RW"
|
|
||||||
// =============================================================================
|
|
||||||
// Register : BUSCTRL_PERFCTR2
|
|
||||||
// Description : Bus fabric performance counter 2
|
|
||||||
// Busfabric saturating performance counter 2
|
|
||||||
// Count some event signal from the busfabric arbiters.
|
|
||||||
// Write any value to clear. Select an event to count using
|
|
||||||
// PERFSEL2
|
|
||||||
#define BUSCTRL_PERFCTR2_OFFSET 0x00000018
|
|
||||||
#define BUSCTRL_PERFCTR2_BITS 0x00ffffff
|
|
||||||
#define BUSCTRL_PERFCTR2_RESET 0x00000000
|
|
||||||
#define BUSCTRL_PERFCTR2_MSB 23
|
|
||||||
#define BUSCTRL_PERFCTR2_LSB 0
|
|
||||||
#define BUSCTRL_PERFCTR2_ACCESS "WC"
|
|
||||||
// =============================================================================
|
|
||||||
// Register : BUSCTRL_PERFSEL2
|
|
||||||
// Description : Bus fabric performance event select for PERFCTR2
|
|
||||||
// Select a performance event for PERFCTR2
|
|
||||||
#define BUSCTRL_PERFSEL2_OFFSET 0x0000001c
|
|
||||||
#define BUSCTRL_PERFSEL2_BITS 0x0000001f
|
|
||||||
#define BUSCTRL_PERFSEL2_RESET 0x0000001f
|
|
||||||
#define BUSCTRL_PERFSEL2_MSB 4
|
|
||||||
#define BUSCTRL_PERFSEL2_LSB 0
|
|
||||||
#define BUSCTRL_PERFSEL2_ACCESS "RW"
|
|
||||||
// =============================================================================
|
|
||||||
// Register : BUSCTRL_PERFCTR3
|
|
||||||
// Description : Bus fabric performance counter 3
|
|
||||||
// Busfabric saturating performance counter 3
|
|
||||||
// Count some event signal from the busfabric arbiters.
|
|
||||||
// Write any value to clear. Select an event to count using
|
|
||||||
// PERFSEL3
|
|
||||||
#define BUSCTRL_PERFCTR3_OFFSET 0x00000020
|
|
||||||
#define BUSCTRL_PERFCTR3_BITS 0x00ffffff
|
|
||||||
#define BUSCTRL_PERFCTR3_RESET 0x00000000
|
|
||||||
#define BUSCTRL_PERFCTR3_MSB 23
|
|
||||||
#define BUSCTRL_PERFCTR3_LSB 0
|
|
||||||
#define BUSCTRL_PERFCTR3_ACCESS "WC"
|
|
||||||
// =============================================================================
|
|
||||||
// Register : BUSCTRL_PERFSEL3
|
|
||||||
// Description : Bus fabric performance event select for PERFCTR3
|
|
||||||
// Select a performance event for PERFCTR3
|
|
||||||
#define BUSCTRL_PERFSEL3_OFFSET 0x00000024
|
|
||||||
#define BUSCTRL_PERFSEL3_BITS 0x0000001f
|
|
||||||
#define BUSCTRL_PERFSEL3_RESET 0x0000001f
|
|
||||||
#define BUSCTRL_PERFSEL3_MSB 4
|
|
||||||
#define BUSCTRL_PERFSEL3_LSB 0
|
|
||||||
#define BUSCTRL_PERFSEL3_ACCESS "RW"
|
|
||||||
// =============================================================================
|
|
||||||
#endif // HARDWARE_REGS_BUSCTRL_DEFINED
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,63 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
#ifndef _INTCTRL_H_
|
|
||||||
#define _INTCTRL_H_
|
|
||||||
|
|
||||||
#define TIMER_IRQ_0 0
|
|
||||||
#define TIMER_IRQ_1 1
|
|
||||||
#define TIMER_IRQ_2 2
|
|
||||||
#define TIMER_IRQ_3 3
|
|
||||||
#define PWM_IRQ_WRAP 4
|
|
||||||
#define USBCTRL_IRQ 5
|
|
||||||
#define XIP_IRQ 6
|
|
||||||
#define PIO0_IRQ_0 7
|
|
||||||
#define PIO0_IRQ_1 8
|
|
||||||
#define PIO1_IRQ_0 9
|
|
||||||
#define PIO1_IRQ_1 10
|
|
||||||
#define DMA_IRQ_0 11
|
|
||||||
#define DMA_IRQ_1 12
|
|
||||||
#define IO_IRQ_BANK0 13
|
|
||||||
#define IO_IRQ_QSPI 14
|
|
||||||
#define SIO_IRQ_PROC0 15
|
|
||||||
#define SIO_IRQ_PROC1 16
|
|
||||||
#define CLOCKS_IRQ 17
|
|
||||||
#define SPI0_IRQ 18
|
|
||||||
#define SPI1_IRQ 19
|
|
||||||
#define UART0_IRQ 20
|
|
||||||
#define UART1_IRQ 21
|
|
||||||
#define ADC_IRQ_FIFO 22
|
|
||||||
#define I2C0_IRQ 23
|
|
||||||
#define I2C1_IRQ 24
|
|
||||||
#define RTC_IRQ 25
|
|
||||||
|
|
||||||
#define isr_timer_0 isr_irq0
|
|
||||||
#define isr_timer_1 isr_irq1
|
|
||||||
#define isr_timer_2 isr_irq2
|
|
||||||
#define isr_timer_3 isr_irq3
|
|
||||||
#define isr_pwm_wrap isr_irq4
|
|
||||||
#define isr_usbctrl isr_irq5
|
|
||||||
#define isr_xip isr_irq6
|
|
||||||
#define isr_pio0_0 isr_irq7
|
|
||||||
#define isr_pio0_1 isr_irq8
|
|
||||||
#define isr_pio1_0 isr_irq9
|
|
||||||
#define isr_pio1_1 isr_irq10
|
|
||||||
#define isr_dma_0 isr_irq11
|
|
||||||
#define isr_dma_1 isr_irq12
|
|
||||||
#define isr_io_bank0 isr_irq13
|
|
||||||
#define isr_io_qspi isr_irq14
|
|
||||||
#define isr_sio_proc0 isr_irq15
|
|
||||||
#define isr_sio_proc1 isr_irq16
|
|
||||||
#define isr_clocks isr_irq17
|
|
||||||
#define isr_spi0 isr_irq18
|
|
||||||
#define isr_spi1 isr_irq19
|
|
||||||
#define isr_uart0 isr_irq20
|
|
||||||
#define isr_uart1 isr_irq21
|
|
||||||
#define isr_adc_fifo isr_irq22
|
|
||||||
#define isr_i2c0 isr_irq23
|
|
||||||
#define isr_i2c1 isr_irq24
|
|
||||||
#define isr_rtc isr_irq25
|
|
||||||
|
|
||||||
#endif // _INTCTRL_H_
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +0,0 @@
|
||||||
add_library(hardware_structs INTERFACE)
|
|
||||||
target_include_directories(hardware_structs INTERFACE include)
|
|
||||||
target_link_libraries(hardware_structs INTERFACE hardware_regs)
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
#ifndef _HARDWARE_STRUCTS_ADC_H
|
|
||||||
#define _HARDWARE_STRUCTS_ADC_H
|
|
||||||
|
|
||||||
#include "hardware/address_mapped.h"
|
|
||||||
#include "hardware/regs/adc.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
io_rw_32 cs;
|
|
||||||
io_rw_32 result;
|
|
||||||
io_rw_32 fcs;
|
|
||||||
io_rw_32 fifo;
|
|
||||||
io_rw_32 div;
|
|
||||||
io_rw_32 intr;
|
|
||||||
io_rw_32 inte;
|
|
||||||
io_rw_32 intf;
|
|
||||||
io_rw_32 ints;
|
|
||||||
} adc_hw_t;
|
|
||||||
|
|
||||||
check_hw_layout(adc_hw_t, ints, ADC_INTS_OFFSET);
|
|
||||||
|
|
||||||
#define adc_hw ((adc_hw_t *const)ADC_BASE)
|
|
||||||
|
|
||||||
#endif
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue