Platform updates (#611)
* Platform updates - Add PICO_RP2040=1 to rp2040 builds - Add new PICO_RP2040_B0/1/2_SUPPORTED macros and retailer chip specific code to use - Add doxygen to platform.h - Make pico.h includable from assembly (because header order is important and tricky) - split out platform_asm.h - Switch to using PICO_RP2040_B0_SUPPORTED in board headers
This commit is contained in:
parent
723dfd04ff
commit
e850214938
@ -86,12 +86,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -89,12 +89,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -88,12 +88,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -66,12 +66,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -77,12 +77,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -84,12 +84,8 @@
|
||||
#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -77,12 +77,8 @@
|
||||
// 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
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -174,12 +174,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -147,12 +147,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -72,12 +72,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -85,12 +85,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -85,12 +85,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -156,12 +156,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -130,12 +130,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -120,12 +120,8 @@
|
||||
#endif
|
||||
|
||||
// All boards have B1 RP2040
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -79,12 +79,8 @@
|
||||
|
||||
// All boards have B1 RP2040
|
||||
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -79,12 +79,8 @@
|
||||
|
||||
// All boards have B1 RP2040
|
||||
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -85,12 +85,8 @@
|
||||
|
||||
// All boards have B1 RP2040
|
||||
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 0
|
||||
#endif
|
||||
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 0
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -11,6 +11,9 @@
|
||||
* \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
|
||||
* as it includes configuration headers and overrides in the correct order
|
||||
*
|
||||
* This header may be included by assembly code
|
||||
*/
|
||||
|
||||
#include "pico/types.h"
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define PICO_CONFIG_H_
|
||||
|
||||
// -----------------------------------------------------
|
||||
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
|
||||
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLY CODE SO
|
||||
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||
// OR USE #ifndef __ASSEMBLER__ guards
|
||||
// -------------
|
||||
|
@ -7,6 +7,8 @@
|
||||
#ifndef _PICO_ERROR_H
|
||||
#define _PICO_ERROR_H
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/*!
|
||||
* Common return codes from pico_sdk methods that return a status
|
||||
*/
|
||||
@ -18,4 +20,6 @@ enum {
|
||||
PICO_ERROR_NO_DATA = -3,
|
||||
};
|
||||
|
||||
#endif // !__ASSEMBLER__
|
||||
|
||||
#endif
|
@ -7,6 +7,8 @@
|
||||
#ifndef _PICO_TYPES_H
|
||||
#define _PICO_TYPES_H
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include "pico/assert.h"
|
||||
|
||||
#include <stdint.h>
|
||||
@ -89,3 +91,4 @@ typedef struct {
|
||||
#define bool_to_bit(x) ((uint)!!(x))
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -20,7 +20,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define __not_in_flash(grup)
|
||||
#define __not_in_flash(group)
|
||||
#define __not_in_flash_func(func) func
|
||||
#define __no_inline_not_in_flash_func(func)
|
||||
#define __in_flash(group)
|
||||
|
@ -7,7 +7,7 @@
|
||||
#ifndef _HARDWARE_PLATFORM_DEFS_H
|
||||
#define _HARDWARE_PLATFORM_DEFS_H
|
||||
|
||||
// This header is included from C and assembler - only define macros
|
||||
// This header is included from C and assembler - intended mostly for #defines; guard other stuff with #ifdef __ASSEMBLER__
|
||||
|
||||
#ifndef _u
|
||||
#ifdef __ASSEMBLER__
|
||||
@ -38,20 +38,5 @@
|
||||
|
||||
#define XOSC_MHZ _u(12)
|
||||
|
||||
// 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 _u(0x800)
|
||||
#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 _u(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
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -37,7 +37,7 @@ function(pico_add_extra_outputs TARGET)
|
||||
add_custom_command(TARGET ${TARGET}_symlinked POST_BUILD
|
||||
COMMAND rm -f "${PICO_SYMLINK_ELF_AS_FILENAME}"
|
||||
COMMAND ln -s -r $<TARGET_FILE:${TARGET}> "${PICO_SYMLINK_ELF_AS_FILENAME}"
|
||||
COMMENT "Symlinking from ${PICO_SYMLINK_ELF_AS_FILENAME} to $<TARGET_FILE:${TARGET}>"
|
||||
COMMENT "Symlinking from ${PICO_SYMLINK_ELF_AS_FILENAME} to ${TARGET}"
|
||||
)
|
||||
endif ()
|
||||
# PICO_CMAKE_CONFIG: PICO_NO_UF2, Disable UF2 output, type=bool, default=0, group=build
|
||||
|
@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "hardware/platform_defs.h"
|
||||
#include "pico.h"
|
||||
#include "hardware/irq.h"
|
||||
|
||||
#if !PICO_DISABLE_SHARED_IRQ_HANDLERS
|
||||
|
@ -9,6 +9,8 @@
|
||||
.thumb
|
||||
|
||||
#include "pico/asm_helper.S"
|
||||
#include "pico/bootrom.h"
|
||||
|
||||
__pre_init __aeabi_bits_init, 00010
|
||||
|
||||
.macro bits_section name
|
||||
@ -24,10 +26,10 @@ __pre_init __aeabi_bits_init, 00010
|
||||
.equ BITS_FUNC_COUNT, 4
|
||||
.align 4
|
||||
aeabi_bits_funcs:
|
||||
.word rom_table_code('P','3') // popcount32
|
||||
.word rom_table_code('L','3') // clz32
|
||||
.word rom_table_code('T','3') // ctz32
|
||||
.word rom_table_code('R','3') // reverse32
|
||||
.word ROM_FUNC_POPCOUNT32
|
||||
.word ROM_FUNC_CLZ32
|
||||
.word ROM_FUNC_CTZ32
|
||||
.word ROM_FUNC_REVERSE32
|
||||
aeabi_bits_funcs_end:
|
||||
|
||||
.section .text
|
||||
|
@ -12,8 +12,60 @@
|
||||
/** \file bootrom.h
|
||||
* \defgroup pico_bootrom pico_bootrom
|
||||
* Access to functions and data in the RP2040 bootrom
|
||||
*
|
||||
* This header may be included by assembly code
|
||||
*/
|
||||
|
||||
// ROM FUNCTIONS
|
||||
|
||||
#define ROM_FUNC_POPCOUNT32 ROM_TABLE_CODE('P', '3')
|
||||
#define ROM_FUNC_REVERSE32 ROM_TABLE_CODE('R', '3')
|
||||
#define ROM_FUNC_CLZ32 ROM_TABLE_CODE('L', '3')
|
||||
#define ROM_FUNC_CTZ32 ROM_TABLE_CODE('T', '3')
|
||||
#define ROM_FUNC_MEMSET ROM_TABLE_CODE('M', 'S')
|
||||
#define ROM_FUNC_MEMSET4 ROM_TABLE_CODE('S', '4')
|
||||
#define ROM_FUNC_MEMCPY ROM_TABLE_CODE('M', 'C')
|
||||
#define ROM_FUNC_MEMCPY44 ROM_TABLE_CODE('C', '4')
|
||||
#define ROM_FUNC_RESET_USB_BOOT ROM_TABLE_CODE('U', 'B')
|
||||
#define ROM_FUNC_CONNECT_INTERNAL_FLASH ROM_TABLE_CODE('I', 'F')
|
||||
#define ROM_FUNC_FLASH_EXIT_XIP ROM_TABLE_CODE('E', 'X')
|
||||
#define ROM_FUNC_FLASH_RANGE_ERASE ROM_TABLE_CODE('R', 'E')
|
||||
#define ROM_FUNC_FLASH_RANGE_PROGRAM ROM_TABLE_CODE('R', 'P')
|
||||
#define ROM_FUNC_FLASH_FLUSH_CACHE ROM_TABLE_CODE('F', 'C')
|
||||
#define ROM_FUNC_FLASH_ENTER_CMD_XIP ROM_TABLE_CODE('C', 'X')
|
||||
|
||||
/*! \brief Return a bootrom lookup code based on two ASCII characters
|
||||
* \ingroup pico_bootrom
|
||||
*
|
||||
* These codes are uses to lookup data or function addresses in the bootrom
|
||||
*
|
||||
* \param c1 the first character
|
||||
* \param c2 the second character
|
||||
* \return the 'code' to use in rom_func_lookup() or rom_data_lookup()
|
||||
*/
|
||||
#define ROM_TABLE_CODE(c1, c2) ((c1) | ((c2) << 8))
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
// ROM FUNCTION SIGNATURES
|
||||
|
||||
typedef uint32_t (*rom_popcount32_fn)(uint32_t);
|
||||
typedef uint32_t (*rom_reverse32_fn)(uint32_t);
|
||||
typedef uint32_t (*rom_clz32_fn)(uint32_t);
|
||||
typedef uint32_t (*rom_ctz32_fn)(uint32_t);
|
||||
typedef uint8_t *(*rom_memset_fn)(uint8_t *, uint8_t, uint32_t);
|
||||
typedef uint32_t *(*rom_memset4_fn)(uint32_t *, uint8_t, uint32_t);
|
||||
typedef uint32_t *(*rom_memcpy_fn)(uint8_t *, const uint8_t *, uint32_t);
|
||||
typedef uint32_t *(*rom_memcpy44_fn)(uint32_t *, const uint32_t *, uint32_t);
|
||||
typedef void __attribute__((noreturn)) (*rom_reset_usb_boot_fn)(uint32_t, uint32_t);
|
||||
typedef rom_reset_usb_boot_fn reset_usb_boot_fn; // kept for backwards compatibility
|
||||
typedef void (*rom_connect_internal_flash_fn)(void);
|
||||
typedef void (*rom_flash_exit_xip_fn)(void);
|
||||
typedef void (*rom_flash_range_erase_fn)(uint32_t, size_t, uint32_t, uint8_t);
|
||||
typedef void (*rom_flash_range_program_fn)(uint32_t, const uint8_t*, size_t);
|
||||
typedef void (*rom_flash_flush_cache_fn)(void);
|
||||
typedef void (*rom_flash_enter_cmd_xip_fn)(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -28,10 +80,9 @@ extern "C" {
|
||||
* \return the 'code' to use in rom_func_lookup() or rom_data_lookup()
|
||||
*/
|
||||
static inline uint32_t rom_table_code(uint8_t c1, uint8_t c2) {
|
||||
return (((uint)c2) << 8u) | (uint)c1;
|
||||
return ROM_TABLE_CODE((uint32_t) c1, (uint32_t) c2);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Lookup a bootrom function by code
|
||||
* \ingroup pico_bootrom
|
||||
@ -61,54 +112,6 @@ void *rom_data_lookup(uint32_t code);
|
||||
*/
|
||||
bool rom_funcs_lookup(uint32_t *table, unsigned int count);
|
||||
|
||||
// The following is a list of bootrom functions available via rom_func_lookup and their signature
|
||||
|
||||
typedef uint32_t (*rom_popcount32_fn)(uint32_t);
|
||||
#define ROM_FUNC_POPCOUNT32 rom_table_code('P', '3')
|
||||
|
||||
typedef uint32_t (*rom_reverse32_fn)(uint32_t);
|
||||
#define ROM_FUNC_REVERSE32 rom_table_code('R', '3')
|
||||
|
||||
typedef uint32_t (*rom_clz32_fn)(uint32_t);
|
||||
#define ROM_FUNC_CLZ32 rom_table_code('L', '3')
|
||||
|
||||
typedef uint32_t (*rom_ctz32_fn)(uint32_t);
|
||||
#define ROM_FUNC_CTZ32 rom_table_code('T', '3')
|
||||
|
||||
typedef uint8_t *(*rom_memset_fn)(uint8_t *, uint8_t, uint32_t);
|
||||
#define ROM_FUNC_MEMSET rom_table_code('M', 'S')
|
||||
|
||||
typedef uint32_t *(*rom_memset4_fn)(uint32_t *, uint8_t, uint32_t);
|
||||
#define ROM_FUNC_MEMSET4 rom_table_code('S', '4')
|
||||
|
||||
typedef uint32_t *(*rom_memcpy_fn)(uint8_t *, const uint8_t *, uint32_t);
|
||||
#define ROM_FUNC_MEMCPY rom_table_code('M', 'C')
|
||||
|
||||
typedef uint32_t *(*rom_memcpy44_fn)(uint32_t *, const uint32_t *, uint32_t);
|
||||
#define ROM_FUNC_MEMCPY44 rom_table_code('C', '4')
|
||||
|
||||
typedef void __attribute__((noreturn)) (*rom_reset_usb_boot_fn)(uint32_t, uint32_t);
|
||||
typedef rom_reset_usb_boot_fn reset_usb_boot_fn; // kept for backwards compatibility
|
||||
#define ROM_FUNC_RESET_USB_BOOT rom_table_code('U', 'B')
|
||||
|
||||
typedef void (*rom_connect_internal_flash_fn)(void);
|
||||
#define ROM_FUNC_CONNECT_INTERNAL_FLASH rom_table_code('I', 'F')
|
||||
|
||||
typedef void (*rom_flash_exit_xip_fn)(void);
|
||||
#define ROM_FUNC_FLASH_EXIT_XIP rom_table_code('E', 'X')
|
||||
|
||||
typedef void (*rom_flash_range_erase_fn)(uint32_t, size_t, uint32_t, uint8_t);
|
||||
#define ROM_FUNC_FLASH_RANGE_ERASE rom_table_code('R', 'E')
|
||||
|
||||
typedef void (*rom_flash_range_program_fn)(uint32_t, const uint8_t*, size_t);
|
||||
#define ROM_FUNC_FLASH_RANGE_PROGRAM rom_table_code('R', 'P')
|
||||
|
||||
typedef void (*rom_flash_flush_cache_fn)(void);
|
||||
#define ROM_FUNC_FLASH_FLUSH_CACHE rom_table_code('F', 'C')
|
||||
|
||||
typedef void (*rom_flash_enter_cmd_xip_fn)(void);
|
||||
#define ROM_FUNC_FLASH_ENTER_CMD_XIP rom_table_code('C', 'X')
|
||||
|
||||
// Bootrom function: rom_table_lookup
|
||||
// Returns the 32 bit pointer into the ROM if found or NULL otherwise.
|
||||
typedef void *(*rom_table_lookup_fn)(uint16_t *table, uint32_t code);
|
||||
@ -155,4 +158,5 @@ static inline void __attribute__((noreturn)) reset_usb_boot(uint32_t usb_activit
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !__ASSEMBLER__
|
||||
#endif
|
||||
|
@ -43,8 +43,7 @@ static const uint32_t magic_token[] = {
|
||||
|
||||
static uint32_t __uninitialized_ram(magic_location)[count_of(magic_token)];
|
||||
|
||||
/*! \brief Check for double reset and enter BOOTSEL mode if detected
|
||||
* \ingroup pico_bootsel_via_double_reset
|
||||
/* Check for double reset and enter BOOTSEL mode if detected
|
||||
*
|
||||
* This function is registered to run automatically before main(). The
|
||||
* algorithm is:
|
||||
|
@ -83,7 +83,7 @@ __check_nan_d2:
|
||||
|
||||
.macro table_tail_call SF_TABLE_OFFSET
|
||||
push {r3, r4}
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
#ifndef NDEBUG
|
||||
movs r3, #0
|
||||
mov ip, r3
|
||||
@ -99,12 +99,12 @@ __check_nan_d2:
|
||||
push {r3, r4}
|
||||
ldr r3, =sd_table
|
||||
ldr r3, [r3, #\SF_TABLE_OFFSET]
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
mov ip, pc
|
||||
#endif
|
||||
str r3, [sp, #4]
|
||||
pop {r3, pc}
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
.byte \SF_TABLE_OFFSET, 0xdf
|
||||
.word \shim
|
||||
#endif
|
||||
@ -733,7 +733,7 @@ sincos_shim_bootstrap:
|
||||
push {r2, r3, r4}
|
||||
movs r3, #0x13
|
||||
ldrb r3, [r3]
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
cmp r3, #1
|
||||
bne 1f
|
||||
ldr r3, =dsincos_shim
|
||||
|
@ -12,7 +12,7 @@
|
||||
// IT IS ***NOT*** SAFE TO CALL THESE FUNCTION POINTERS FROM ARBITRARY CODE
|
||||
uint32_t sd_table[SF_TABLE_V2_SIZE / 2];
|
||||
|
||||
#if !PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if !(PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED)
|
||||
static __attribute__((noreturn)) void missing_double_func_shim(void) {
|
||||
panic("missing double function");
|
||||
}
|
||||
@ -23,7 +23,7 @@ void __attribute__((weak)) *sf_clz_func;
|
||||
|
||||
void __aeabi_double_init(void) {
|
||||
int rom_version = rp2040_rom_version();
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
if (rom_version == 1) {
|
||||
|
||||
// this is a little tricky.. we only want to pull in a shim if the corresponding function
|
||||
|
@ -63,7 +63,7 @@ regular_func double_table_shim_on_use_helper
|
||||
str r0, [sp, #12]
|
||||
pop {r0-r2, pc}
|
||||
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
// Note that the V1 ROM has no double support, so this is basically the identical
|
||||
// library, and shim inter-function calls do not bother to redirect back thru the
|
||||
// wrapper functions
|
||||
|
@ -22,6 +22,9 @@ static void hw_enumeration_fix_force_ls_j(void);
|
||||
static void hw_enumeration_fix_finish(void);
|
||||
|
||||
void rp2040_usb_device_enumeration_fix(void) {
|
||||
#if PICO_RP2040_B0_SUPPORTED || PICO_RP2040_B1_SUPPORTED
|
||||
// Actually check for B0/B1 h/w
|
||||
if (rp2040_chip_version() == 1) {
|
||||
// After coming out of reset, the hardware expects 800us of LS_J (linestate J) time
|
||||
// before it will move to the connected state. However on a hub that broadcasts packets
|
||||
// for other devices this isn't the case. The plan here is to wait for the end of the bus
|
||||
@ -33,6 +36,8 @@ void rp2040_usb_device_enumeration_fix(void) {
|
||||
// Wait SE0 phase will call force ls_j phase which will call finish phase
|
||||
hw_enumeration_fix_wait_se0();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint8_t hw_line_state(void) {
|
||||
return (usb_hw->sie_status & USB_SIE_STATUS_LINE_STATE_BITS) >> USB_SIE_STATUS_LINE_STATE_LSB;
|
||||
|
@ -80,7 +80,7 @@ __check_nan_f2:
|
||||
#endif
|
||||
|
||||
.macro table_tail_call SF_TABLE_OFFSET
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
#ifndef NDEBUG
|
||||
movs r3, #0
|
||||
mov ip, r3
|
||||
@ -94,11 +94,11 @@ __check_nan_f2:
|
||||
.macro shimmable_table_tail_call SF_TABLE_OFFSET shim
|
||||
ldr r3, =sf_table
|
||||
ldr r3, [r3, #\SF_TABLE_OFFSET]
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
mov ip, pc
|
||||
#endif
|
||||
bx r3
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
.byte \SF_TABLE_OFFSET, 0xdf
|
||||
.word \shim
|
||||
#endif
|
||||
@ -584,13 +584,13 @@ wrapper_func __aeabi_f2d
|
||||
|
||||
float_wrapper_section srqtf
|
||||
wrapper_func_f1 sqrtf
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
// check for negative
|
||||
asrs r1, r0, #23
|
||||
bmi 1f
|
||||
#endif
|
||||
table_tail_call SF_TABLE_FSQRT
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
1:
|
||||
mvns r0, r1
|
||||
cmp r0, #255
|
||||
|
@ -13,7 +13,7 @@
|
||||
uint32_t sf_table[SF_TABLE_V2_SIZE / 2];
|
||||
void __attribute__((weak)) *sf_clz_func;
|
||||
|
||||
#if !PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#if !(PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED)
|
||||
static __attribute__((noreturn)) void missing_float_func_shim(void) {
|
||||
panic("");
|
||||
}
|
||||
@ -22,7 +22,7 @@ static __attribute__((noreturn)) void missing_float_func_shim(void) {
|
||||
void __aeabi_float_init(void) {
|
||||
int rom_version = rp2040_rom_version();
|
||||
void *rom_table = rom_data_lookup(rom_table_code('S', 'F'));
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
if (rom_version == 1) {
|
||||
memcpy(&sf_table, rom_table, SF_TABLE_V1_SIZE);
|
||||
extern void float_table_shim_on_use_helper(void);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "pico/asm_helper.S"
|
||||
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
.syntax unified
|
||||
.cpu cortex-m0plus
|
||||
.thumb
|
||||
|
@ -9,6 +9,7 @@
|
||||
.thumb
|
||||
|
||||
#include "pico/asm_helper.S"
|
||||
#include "pico/bootrom.h"
|
||||
|
||||
__pre_init __aeabi_mem_init, 00001
|
||||
|
||||
@ -34,10 +35,10 @@ __pre_init __aeabi_mem_init, 00001
|
||||
|
||||
.align 2
|
||||
aeabi_mem_funcs:
|
||||
.word rom_table_code('M','S')
|
||||
.word rom_table_code('M','C')
|
||||
.word rom_table_code('S','4')
|
||||
.word rom_table_code('C','4')
|
||||
.word ROM_FUNC_MEMSET
|
||||
.word ROM_FUNC_MEMCPY
|
||||
.word ROM_FUNC_MEMSET4
|
||||
.word ROM_FUNC_MEMCPY44
|
||||
aeabi_mem_funcs_end:
|
||||
|
||||
.section .text
|
||||
|
@ -4,13 +4,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "hardware/platform_defs.h"
|
||||
#include "pico/config.h"
|
||||
|
||||
#define WRAPPER_FUNC_NAME(x) __wrap_##x
|
||||
#define SECTION_NAME(x) .text.##x
|
||||
#define RAM_SECTION_NAME(x) .time_critical.##x
|
||||
#define rom_table_code(c1, c2) ((c1) | ((c2) << 8))
|
||||
#include "pico.h"
|
||||
|
||||
// do not put align in here as it is used mid function sometimes
|
||||
.macro regular_func x
|
||||
|
@ -7,91 +7,304 @@
|
||||
#ifndef _PICO_PLATFORM_H_
|
||||
#define _PICO_PLATFORM_H_
|
||||
|
||||
/** \file platform.h
|
||||
* \defgroup pico_platform pico_platform
|
||||
*
|
||||
* Macros and definitions (and functions when included by non assembly code) for the RP2 family device / architecture
|
||||
* to provide a common abstraction over low level compiler / platform specifics.
|
||||
*
|
||||
* This header may be included by assembly code
|
||||
*/
|
||||
|
||||
#include "hardware/platform_defs.h"
|
||||
|
||||
// Marker for builds targeting the RP2040
|
||||
#define PICO_RP2040 1
|
||||
|
||||
// PICO_CONFIG: PICO_STACK_SIZE, Stack Size, min=0x100, default=0x800, advanced=true, group=pico_platform
|
||||
#ifndef PICO_STACK_SIZE
|
||||
#define PICO_STACK_SIZE _u(0x800)
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_HEAP_SIZE, Heap size to reserve, min=0x100, default=0x800, advanced=true, group=pico_platform
|
||||
#ifndef PICO_HEAP_SIZE
|
||||
#define PICO_HEAP_SIZE _u(0x800)
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_NO_RAM_VECTOR_TABLE, Enable/disable the RAM vector table, type=bool, default=0, advanced=true, group=pico_platform
|
||||
#ifndef PICO_NO_RAM_VECTOR_TABLE
|
||||
#define PICO_NO_RAM_VECTOR_TABLE 0
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_RP2040_B0_SUPPORTED, Whether to include any specific software support for RP2040 B0 revision, type=bool, default=1, advanced=true, group=pico_platform
|
||||
#ifndef PICO_RP2040_B0_SUPPORTED
|
||||
#define PICO_RP2040_B0_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_FLOAT_SUPPORT_ROM_V1, Include float support code for RP2040 B0 when that chip revision is supported , type=bool, default=1, advanced=true, group=pico_platform
|
||||
#ifndef PICO_FLOAT_SUPPORT_ROM_V1
|
||||
#define PICO_FLOAT_SUPPORT_ROM_V1 1
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_DOUBLE_SUPPORT_ROM_V1, Include double support code for RP2040 B0 when that chip revision is supported , type=bool, default=1, advanced=true, group=pico_platform
|
||||
#ifndef PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#define PICO_DOUBLE_SUPPORT_ROM_V1 1
|
||||
#endif
|
||||
|
||||
|
||||
// PICO_CONFIG: PICO_RP2040_B1_SUPPORTED, Whether to include any specific software support for RP2040 B1 revision, type=bool, default=1, advanced=true, group=pico_platform
|
||||
#ifndef PICO_RP2040_B1_SUPPORTED
|
||||
#define PICO_RP2040_B1_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_RP2040_B2_SUPPORTED, Whether to include any specific software support for RP2040 B2 revision, type=bool, default=1, advanced=true, group=pico_platform
|
||||
#ifndef PICO_RP2040_B2_SUPPORTED
|
||||
#define PICO_RP2040_B2_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
// --- remainder of file is not included by assembly code ---
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include "pico/types.h"
|
||||
#include "hardware/platform_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \file platform.h
|
||||
* \defgroup pico_platform pico_platform
|
||||
* Compiler definitions for the selected PICO_PLATFORM
|
||||
/*! \brief Marker for an interrupt handler
|
||||
* \ingroup pico_platform
|
||||
* For example an IRQ handler function called my_interrupt_handler:
|
||||
*
|
||||
* void __isr my_interrupt_handler(void) {
|
||||
*/
|
||||
|
||||
#define __isr
|
||||
|
||||
// Section naming macros
|
||||
/*! \brief Section attribute macro for placement in RAM after the `.data` section
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* For example a 400 element `uint32_t` array placed after the .data section
|
||||
*
|
||||
* uint32_t __after_data("my_group_name") a_big_array[400];
|
||||
*
|
||||
* The section attribute is `.after_data.<group>`
|
||||
*
|
||||
* \param group a string suffix to use in the section name to distinguish groups that can be linker
|
||||
* garbage-collected independently
|
||||
*/
|
||||
#define __after_data(group) __attribute__((section(".after_data." group)))
|
||||
|
||||
/*! \brief Section attribute macro for placement not in flash (i.e in RAM)
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* For example a 3 element `uint32_t` array placed in RAM (even though it is `static const`)
|
||||
*
|
||||
* static const uint32_t __not_in_flash("my_group_name") an_array[3];
|
||||
*
|
||||
* The section attribute is `.time_critical.<group>`
|
||||
*
|
||||
* \param group a string suffix to use in the section name to distinguish groups that can be linker
|
||||
* garbage-collected independently
|
||||
*/
|
||||
#define __not_in_flash(group) __attribute__((section(".time_critical." group)))
|
||||
|
||||
/*! \brief Section attribute macro for placement in the SRAM bank 4 (known as "scratch X")
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* Scratch X is 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)
|
||||
*
|
||||
* For example a `uint32_t` variable placed in "scratch X"
|
||||
*
|
||||
* uint32_t __scratch_x("my_group_name") foo = 23;
|
||||
*
|
||||
* The section attribute is `.scratch_x.<group>`
|
||||
*
|
||||
* \param group a string suffix to use in the section name to distinguish groups that can be linker
|
||||
* garbage-collected independently
|
||||
*/
|
||||
#define __scratch_x(group) __attribute__((section(".scratch_x." group)))
|
||||
|
||||
/*! \brief Section attribute macro for placement in the SRAM bank 5 (known as "scratch Y")
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* Scratch Y is 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)
|
||||
*
|
||||
* For example a `uint32_t` variable placed in "scratch Y"
|
||||
*
|
||||
* uint32_t __scratch_y("my_group_name") foo = 23;
|
||||
*
|
||||
* The section attribute is `.scratch_y.<group>`
|
||||
*
|
||||
* \param group a string suffix to use in the section name to distinguish groups that can be linker
|
||||
* garbage-collected independently
|
||||
*/
|
||||
#define __scratch_y(group) __attribute__((section(".scratch_y." group)))
|
||||
|
||||
/*! \brief Section attribute macro for data that is to be left uninitialized
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* Data marked this way will retain its value across a reset (normally uninitialized data - in the .bss
|
||||
* section) is initialized to zero during runtime initialization
|
||||
*
|
||||
* For example a `uint32_t` foo that will retain its value if the program is restarted by reset.
|
||||
*
|
||||
* uint32_t __uninitialized_ram("my_group_name") foo;
|
||||
*
|
||||
* The section attribute is `.uninitialized_ram.<group>`
|
||||
*
|
||||
* \param group a string suffix to use in the section name to distinguish groups that can be linker
|
||||
* garbage-collected independently
|
||||
*/
|
||||
#define __uninitialized_ram(group) __attribute__((section(".uninitialized_ram." #group))) group
|
||||
// For use with PICO_COPY_TO_RAM:
|
||||
|
||||
/*! \brief Section attribute macro for placement in flash even in a COPY_TO_RAM binary
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* For example a `uint32_t` variable explicitly placed in flash (it will hard fault if you attempt to write it!)
|
||||
*
|
||||
* uint32_t __in_flash("my_group_name") foo = 23;
|
||||
*
|
||||
* The section attribute is `.flashdata.<group>`
|
||||
*
|
||||
* \param group a string suffix to use in the section name to distinguish groups that can be linker
|
||||
* garbage-collected independently
|
||||
*/
|
||||
#define __in_flash(group) __attribute__((section(".flashdata" group)))
|
||||
|
||||
/**
|
||||
/*! \brief Indicates a function should not be stored in flash
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* Decorates a function name, such that the function will execute from RAM (assuming it is not inlined
|
||||
* into a flash function by the compiler)
|
||||
*
|
||||
* For example a function called my_func taking an int parameter:
|
||||
*
|
||||
* void __not_in_flash_func(my_func)(int some_arg) {
|
||||
*
|
||||
* The function is placed in the `.time_critical.<func_name>` linker section
|
||||
*
|
||||
* \see __no_inline_not_in_flash_func
|
||||
*/
|
||||
#define __not_in_flash_func(func_name) __not_in_flash(__STRING(func_name)) func_name
|
||||
/**
|
||||
* Historical synonym for __not_in_flash_func()
|
||||
|
||||
/*! \brief Indicates a function is time/latency critical and should not run from flash
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* Decorates a function name, such that the function will execute from RAM (assuming it is not inlined
|
||||
* into a flash function by the compiler) to avoid possible flash latency. Currently this macro is identical
|
||||
* in implementation to `__not_in_flash_func`, however the semantics are distinct and a `__time_critical_func`
|
||||
* may in the future be treated more specially to reduce the overhead when calling such function from a flash
|
||||
* function.
|
||||
*
|
||||
* For example a function called my_func taking an int parameter:
|
||||
*
|
||||
* void __time_critical(my_func)(int some_arg) {
|
||||
*
|
||||
* The function is placed in the `.time_critical.<func_name>` linker section
|
||||
*
|
||||
* \see __not_in_flash_func
|
||||
*/
|
||||
#define __time_critical_func(func_name) __not_in_flash_func(func_name)
|
||||
|
||||
/**
|
||||
/*! \brief Indicate a function should not be stored in flash and should not be inlined
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* Decorates a function name, such that the function will execute from RAM, explicitly marking it as
|
||||
* noinline to prevent it being inlined into a flash function by the compiler
|
||||
*
|
||||
* For example a function called my_func taking an int parameter:
|
||||
*
|
||||
* void __no_inline_not_in_flash_func(my_func)(int some_arg) {
|
||||
*
|
||||
* The function is placed in the `.time_critical.<func_name>` linker section
|
||||
*/
|
||||
#define __no_inline_not_in_flash_func(func_name) __noinline __not_in_flash_func(func_name)
|
||||
|
||||
#define __packed_aligned __packed __aligned(4)
|
||||
|
||||
/*! \brief Attribute to force inlining of a function regardless of optimization level
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* For example my_function here will always be inlined:
|
||||
*
|
||||
* int __force_inline my_function(int x) {
|
||||
*
|
||||
*/
|
||||
#if defined(__GNUC__) && __GNUC__ <= 7
|
||||
#define __force_inline inline __always_inline
|
||||
#else
|
||||
#define __force_inline __always_inline
|
||||
#endif
|
||||
|
||||
/*! \brief Macro to determine the number of elements in an array
|
||||
* \ingroup pico_platform
|
||||
*/
|
||||
#ifndef count_of
|
||||
#define count_of(a) (sizeof(a)/sizeof((a)[0]))
|
||||
#endif
|
||||
|
||||
/*! \brief Macro to return the maximum of two comparable values
|
||||
* \ingroup pico_platform
|
||||
*/
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a)>(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
/*! \brief Macro to return the minimum of two comparable values
|
||||
* \ingroup pico_platform
|
||||
*/
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((b)>(a)?(a):(b))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Execute a breakpoint instruction
|
||||
/*! \brief Execute a breakpoint instruction
|
||||
* \ingroup pico_platform
|
||||
*/
|
||||
static inline void __breakpoint(void) {
|
||||
__asm__("bkpt #0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the compiler does not move memory access across this method call
|
||||
/*! \brief Ensure that the compiler does not move memory access across this method call
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* For example in the following code:
|
||||
*
|
||||
* *some_memory_location = var_a;
|
||||
* __compiler_memory_barrier();
|
||||
* uint32_t var_b = *some_other_memory_location
|
||||
*
|
||||
* The compiler will not move the load from `some_other_memory_location` above the memory barrier (which it otherwise
|
||||
* might - even above the memory store!)
|
||||
*/
|
||||
__force_inline static void __compiler_memory_barrier(void) {
|
||||
__asm__ volatile ("" : : : "memory");
|
||||
}
|
||||
|
||||
// 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
|
||||
/*! \brief Macro for converting memory addresses to 32 bit addresses suitable for DMA
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* This is just a cast to `uintptr_t` on the RP2040, however you may want to use this when developing code
|
||||
* that also runs in "host" mode. If the host mode is 64 bit and you are embedding data pointers
|
||||
* in other data (e.g. DMA chaining), then there is a need in "host" mode to convert a 64 bit native
|
||||
* pointer to a 32 bit value for storage, which can be done using this macro.
|
||||
*/
|
||||
#define host_safe_hw_ptr(x) ((uintptr_t)(x))
|
||||
#define native_safe_hw_ptr(x) host_safe_hw_ptr(x)
|
||||
|
||||
/**
|
||||
* Panic (see panic()) with the message "Unsupported".
|
||||
|
||||
/*! \brief Panics with the message "Unsupported"
|
||||
* \ingroup pico_platform
|
||||
* \see panic
|
||||
*/
|
||||
void __attribute__((noreturn)) panic_unsupported(void);
|
||||
|
||||
/**
|
||||
* Panic with a message. An attempt is made to output the message to all registered STDOUT drivers
|
||||
/*! \brief Displays a panic message and halts execution
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* An attempt is made to output the message to all registered STDOUT drivers
|
||||
* after which this method executes a BKPT instruction.
|
||||
*
|
||||
* @param fmt format string (printf-like)
|
||||
@ -110,36 +323,34 @@ static inline bool running_on_fpga(void) {return false;}
|
||||
bool running_on_fpga(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @return the RP2040 chip revision number
|
||||
/*! \brief Returns the RP2040 chip revision number
|
||||
* \ingroup pico_platform
|
||||
* @return the RP2040 chip revision number (1 for B0/B1, 2 for B2)
|
||||
*/
|
||||
uint8_t rp2040_chip_version(void);
|
||||
|
||||
/**
|
||||
* @return the RP2040 rom version number
|
||||
/*! \brief Returns the RP2040 rom version number
|
||||
* \ingroup pico_platform
|
||||
* @return the RP2040 rom version number (1 for RP2040-B0, 2 for RP2040-B1, 3 for RP2040-B2)
|
||||
*/
|
||||
static inline uint8_t rp2040_rom_version(void) {
|
||||
return *(uint8_t*)0x13;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty function intended to be called by any tight hardware polling loop. using this ubiquitously
|
||||
/*! \brief No-op function for the body of tight loops
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* Np-op function intended to be called by any tight hardware polling loop. Using this ubiquitously
|
||||
* makes it much easier to find tight loops, but also in the future \#ifdef-ed support for lockup
|
||||
* debugging might be added
|
||||
*/
|
||||
static inline void tight_loop_contents(void) {}
|
||||
static __force_inline void tight_loop_contents(void) {}
|
||||
|
||||
/**
|
||||
* Helper macro for making chain DMA code portable to PICO_PLATFORM=host. The problem here is
|
||||
* that embedded pointers in the data are only 32 bit, which is a problem if the host
|
||||
* system is 64 bit. This macro is zero cost on the actual device, but in host mode
|
||||
* it provides a 64->32 bit mapping
|
||||
*/
|
||||
#define native_safe_hw_ptr(x) ((uintptr_t)(x))
|
||||
|
||||
/**
|
||||
* Multiplies a by b using multiply instruction using the ARM mul instruction regardless of values;
|
||||
* i.e. this is a 1 cycle operation.
|
||||
/*! \brief Multiply two integers using an assembly `MUL` instruction
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* This multiplies a by b using multiply instruction using the ARM mul instruction regardless of values (the compiler
|
||||
* might otherwise choose to perform shifts/adds), i.e. this is a 1 cycle operation.
|
||||
*
|
||||
* \param a the first operand
|
||||
* \param b the second operand
|
||||
@ -150,10 +361,14 @@ __force_inline static int32_t __mul_instruction(int32_t a, int32_t b) {
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Efficiently Multiplies value a by possibly constant value b.
|
||||
/*! \brief multiply two integer values using the fastest method possible
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* Efficiently multiplies value a by possibly constant value b.
|
||||
*
|
||||
* If b is known to be constant and not zero or a power of 2, then a mul instruction is used rather than gcc's default
|
||||
* which is often a slow combination of shifts and adds
|
||||
* which is often a slow combination of shifts and adds. If b is a power of 2 then a single shift is of course preferable
|
||||
* and will be used
|
||||
*
|
||||
* \param a the first operand
|
||||
* \param b the second operand
|
||||
@ -163,18 +378,34 @@ __force_inline static int32_t __mul_instruction(int32_t a, int32_t b) {
|
||||
(__builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)), \
|
||||
(a)*(b))
|
||||
|
||||
#define WRAPPER_FUNC(x) __wrap_ ## x
|
||||
#define REAL_FUNC(x) __real_ ## x
|
||||
|
||||
/*! \brief Utility macro to assert two types are equivalent.
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* This macro can be useful in other macros along with `typeof` to assert that two parameters are of equivalent type
|
||||
* (or that a single parameter is of an expected type)
|
||||
*/
|
||||
#define __check_type_compatible(type_a, type_b) static_assert(__builtin_types_compatible_p(type_a, type_b), __STRING(type_a) " is not compatible with " __STRING(type_b));
|
||||
|
||||
/**
|
||||
* Get the current exception level on this core
|
||||
/*! \brief Get the current exception level on this core
|
||||
* \ingroup pico_platform
|
||||
*
|
||||
* \return the exception number if the CPU is handling an exception, or 0 otherwise
|
||||
*/
|
||||
uint __get_current_exception(void);
|
||||
|
||||
#define WRAPPER_FUNC(x) __wrap_ ## x
|
||||
#define REAL_FUNC(x) __real_ ## x
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else // __ASSEMBLER__
|
||||
|
||||
#define WRAPPER_FUNC_NAME(x) __wrap_##x
|
||||
#define SECTION_NAME(x) .text.##x
|
||||
#define RAM_SECTION_NAME(x) .time_critical.##x
|
||||
|
||||
#endif // !__ASSEMBLER__
|
||||
|
||||
#endif
|
||||
|
@ -32,10 +32,6 @@
|
||||
#include "pico/bootrom.h"
|
||||
#endif
|
||||
|
||||
#ifndef PICO_NO_RAM_VECTOR_TABLE
|
||||
#define PICO_NO_RAM_VECTOR_TABLE 0
|
||||
#endif
|
||||
|
||||
extern char __StackLimit; /* Set by linker. */
|
||||
|
||||
uint32_t __attribute__((section(".ram_vector_table"))) ram_vector_table[48];
|
||||
|
@ -4,12 +4,11 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "pico.h"
|
||||
#include "hardware/regs/m0plus.h"
|
||||
#include "hardware/platform_defs.h"
|
||||
#include "hardware/regs/addressmap.h"
|
||||
#include "hardware/regs/sio.h"
|
||||
#include "pico/binary_info/defs.h"
|
||||
#include "pico/config.h"
|
||||
|
||||
#ifdef NDEBUG
|
||||
#ifndef COLLAPSE_IRQS
|
||||
|
Loading…
Reference in New Issue
Block a user