Initial Release

This commit is contained in:
graham sanderson
2021-01-20 10:44:27 -06:00
commit 26653ea81e
404 changed files with 135614 additions and 0 deletions

28
src/host/CMakeLists.txt Normal file
View File

@ -0,0 +1,28 @@
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()

14
src/host/README.md Normal file
View File

@ -0,0 +1,14 @@
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
src/host/boot_stage2.c Normal file
View File

@ -0,0 +1 @@
// empty

View File

@ -0,0 +1 @@
pico_simple_hardware_target(divider)

View File

@ -0,0 +1,9 @@
/*
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "hardware/divider.h"
__thread uint64_t hw_divider_result_threadlocal;

View File

@ -0,0 +1,122 @@
/*
* 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

View File

@ -0,0 +1 @@
pico_simple_hardware_target(gpio)

View File

@ -0,0 +1,118 @@
/*
* 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) {
}

View File

@ -0,0 +1,147 @@
/*
* 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 N_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

View File

@ -0,0 +1,12 @@
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()

View File

@ -0,0 +1,106 @@
/*
* 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

View File

@ -0,0 +1,140 @@
/*
* 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;
}

View File

@ -0,0 +1,16 @@
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()

View File

@ -0,0 +1,42 @@
/*
* 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

View File

@ -0,0 +1,104 @@
/*
* 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();
}

View File

@ -0,0 +1 @@
pico_simple_hardware_target(uart)

View File

@ -0,0 +1,91 @@
/*
* 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

View File

@ -0,0 +1,118 @@
/*
* 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() {
}

View File

@ -0,0 +1,9 @@
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()

View File

@ -0,0 +1,22 @@
/*
* 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);
}

View File

@ -0,0 +1,9 @@
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()

View File

@ -0,0 +1,114 @@
/*
* 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); }

View File

@ -0,0 +1,8 @@
if (NOT TARGET pico_multicore)
add_library(pico_multicore INTERFACE)
target_include_directories(pico_multicore INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
endif()

View File

@ -0,0 +1,44 @@
/*
* 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

View File

@ -0,0 +1,25 @@
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()

View File

@ -0,0 +1,24 @@
/*
* 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

View File

@ -0,0 +1,137 @@
/*
* 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

View File

@ -0,0 +1,46 @@
/*
* 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
}

View File

@ -0,0 +1,6 @@
if (NOT TARGET pico_printf)
add_library(pico_printf INTERFACE)
function(pico_set_printf_implementation)
endfunction()
endif()

View File

@ -0,0 +1,20 @@
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()

View File

@ -0,0 +1,21 @@
/*
* 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

View File

@ -0,0 +1,23 @@
/*
* 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);
}

View File

@ -0,0 +1,19 @@
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()

View File

@ -0,0 +1,27 @@
/*
* 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) {
}