mirror of
https://github.com/Klipper3d/klipper.git
synced 2025-07-24 23:24:01 -06:00
lib: Update lib/rp2040 to v2.0.0 SDK release
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
9f328cab95
commit
c75eb53c0c
139 changed files with 13359 additions and 8309 deletions
187
lib/pico-sdk/hardware/address_mapped.h
Normal file
187
lib/pico-sdk/hardware/address_mapped.h
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _HARDWARE_ADDRESS_MAPPED_H
|
||||
#define _HARDWARE_ADDRESS_MAPPED_H
|
||||
|
||||
//#include "pico.h"
|
||||
#define __force_inline inline
|
||||
#define static_assert(a,b)
|
||||
#define valid_params_if(a,b)
|
||||
#include "hardware/regs/addressmap.h"
|
||||
|
||||
/** \file address_mapped.h
|
||||
* \defgroup hardware_base hardware_base
|
||||
*
|
||||
* \brief Low-level types and (atomic) accessors for memory-mapped hardware registers
|
||||
*
|
||||
* `hardware_base` defines the low level types and access functions for memory mapped hardware registers. It is included
|
||||
* by default by all other hardware libraries.
|
||||
*
|
||||
* The following register access typedefs codify the access type (read/write) and the bus size (8/16/32) of the hardware register.
|
||||
* The register type names are formed by concatenating one from each of the 3 parts A, B, C
|
||||
|
||||
* A | B | C | Meaning
|
||||
* ------|---|---|--------
|
||||
* io_ | | | A Memory mapped IO register
|
||||
* |ro_| | read-only access
|
||||
* |rw_| | read-write access
|
||||
* |wo_| | write-only access (can't actually be enforced via C API)
|
||||
* | | 8| 8-bit wide access
|
||||
* | | 16| 16-bit wide access
|
||||
* | | 32| 32-bit wide access
|
||||
*
|
||||
* When dealing with these types, you will always use a pointer, i.e. `io_rw_32 *some_reg` is a pointer to a read/write
|
||||
* 32 bit register that you can write with `*some_reg = value`, or read with `value = *some_reg`.
|
||||
*
|
||||
* RP-series hardware is also aliased to provide atomic setting, clear or flipping of a subset of the bits within
|
||||
* a hardware register so that concurrent access by two cores is always consistent with one atomic operation
|
||||
* being performed first, followed by the second.
|
||||
*
|
||||
* See hw_set_bits(), hw_clear_bits() and hw_xor_bits() provide for atomic access via a pointer to a 32 bit register
|
||||
*
|
||||
* Additionally given a pointer to a structure representing a piece of hardware (e.g. `dma_hw_t *dma_hw` for the DMA controller), you can
|
||||
* get an alias to the entire structure such that writing any member (register) within the structure is equivalent
|
||||
* to an atomic operation via hw_set_alias(), hw_clear_alias() or hw_xor_alias()...
|
||||
*
|
||||
* For example `hw_set_alias(dma_hw)->inte1 = 0x80;` will set bit 7 of the INTE1 register of the DMA controller,
|
||||
* leaving the other bits unchanged.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define check_hw_layout(type, member, offset) static_assert(offsetof(type, member) == (offset), "hw offset mismatch")
|
||||
#define check_hw_size(type, size) static_assert(sizeof(type) == (size), "hw size mismatch")
|
||||
|
||||
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_ADDRESS_ALIAS, Enable/disable assertions in memory address aliasing macros, type=bool, default=0, group=hardware_base
|
||||
#ifndef PARAM_ASSERTIONS_ENABLED_ADDRESS_ALIAS
|
||||
#define PARAM_ASSERTIONS_ENABLED_ADDRESS_ALIAS 0
|
||||
#endif
|
||||
|
||||
typedef volatile uint64_t io_rw_64;
|
||||
typedef const volatile uint64_t io_ro_64;
|
||||
typedef volatile uint64_t io_wo_64;
|
||||
typedef volatile uint32_t io_rw_32;
|
||||
typedef const volatile uint32_t io_ro_32;
|
||||
typedef volatile uint32_t io_wo_32;
|
||||
typedef volatile uint16_t io_rw_16;
|
||||
typedef const volatile uint16_t io_ro_16;
|
||||
typedef volatile uint16_t io_wo_16;
|
||||
typedef volatile uint8_t io_rw_8;
|
||||
typedef const volatile uint8_t io_ro_8;
|
||||
typedef volatile uint8_t io_wo_8;
|
||||
|
||||
typedef volatile uint8_t *const ioptr;
|
||||
typedef ioptr const const_ioptr;
|
||||
|
||||
// A non-functional (empty) helper macro to help IDEs follow links from the autogenerated
|
||||
// hardware struct headers in hardware/structs/xxx.h to the raw register definitions
|
||||
// in hardware/regs/xxx.h. A preprocessor define such as TIMER_TIMEHW_OFFSET (a timer register offset)
|
||||
// is not generally clickable (in an IDE) if placed in a C comment, so _REG_(TIMER_TIMEHW_OFFSET) is
|
||||
// included outside of a comment instead
|
||||
#define _REG_(x)
|
||||
|
||||
// Helper method used by hw_alias macros to optionally check input validity
|
||||
#define hw_alias_check_addr(addr) ((uintptr_t)(addr))
|
||||
// can't use the following impl as it breaks existing static declarations using hw_alias, so would be a backwards incompatibility
|
||||
//static __force_inline uint32_t hw_alias_check_addr(volatile void *addr) {
|
||||
// uint32_t rc = (uintptr_t)addr;
|
||||
// invalid_params_if(ADDRESS_ALIAS, rc < 0x40000000); // catch likely non HW pointer types
|
||||
// return rc;
|
||||
//}
|
||||
|
||||
#if PICO_RP2040
|
||||
// Helper method used by xip_alias macros to optionally check input validity
|
||||
__force_inline static uint32_t xip_alias_check_addr(const void *addr) {
|
||||
uint32_t rc = (uintptr_t)addr;
|
||||
valid_params_if(ADDRESS_ALIAS, rc >= XIP_MAIN_BASE && rc < XIP_NOALLOC_BASE);
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
//static __force_inline uint32_t xip_alias_check_addr(const void *addr) {
|
||||
// uint32_t rc = (uintptr_t)addr;
|
||||
// valid_params_if(ADDRESS_ALIAS, rc >= XIP_BASE && rc < XIP_END);
|
||||
// return rc;
|
||||
//}
|
||||
#endif
|
||||
|
||||
// Untyped conversion alias pointer generation macros
|
||||
#define hw_set_alias_untyped(addr) ((void *)(REG_ALIAS_SET_BITS + hw_alias_check_addr(addr)))
|
||||
#define hw_clear_alias_untyped(addr) ((void *)(REG_ALIAS_CLR_BITS + hw_alias_check_addr(addr)))
|
||||
#define hw_xor_alias_untyped(addr) ((void *)(REG_ALIAS_XOR_BITS + hw_alias_check_addr(addr)))
|
||||
|
||||
#if PICO_RP2040
|
||||
#define xip_noalloc_alias_untyped(addr) ((void *)(XIP_NOALLOC_BASE | xip_alias_check_addr(addr)))
|
||||
#define xip_nocache_alias_untyped(addr) ((void *)(XIP_NOCACHE_BASE | xip_alias_check_addr(addr)))
|
||||
#define xip_nocache_noalloc_alias_untyped(addr) ((void *)(XIP_NOCACHE_NOALLOC_BASE | xip_alias_check_addr(addr)))
|
||||
#endif
|
||||
|
||||
// Typed conversion alias pointer generation macros
|
||||
#define hw_set_alias(p) ((typeof(p))hw_set_alias_untyped(p))
|
||||
#define hw_clear_alias(p) ((typeof(p))hw_clear_alias_untyped(p))
|
||||
#define hw_xor_alias(p) ((typeof(p))hw_xor_alias_untyped(p))
|
||||
#define xip_noalloc_alias(p) ((typeof(p))xip_noalloc_alias_untyped(p))
|
||||
#define xip_nocache_alias(p) ((typeof(p))xip_nocache_alias_untyped(p))
|
||||
#define xip_nocache_noalloc_alias(p) ((typeof(p))xip_nocache_noalloc_alias_untyped(p))
|
||||
|
||||
/*! \brief Atomically set the specified bits to 1 in a HW register
|
||||
* \ingroup hardware_base
|
||||
*
|
||||
* \param addr Address of writable register
|
||||
* \param mask Bit-mask specifying bits to set
|
||||
*/
|
||||
__force_inline static void hw_set_bits(io_rw_32 *addr, uint32_t mask) {
|
||||
*(io_rw_32 *) hw_set_alias_untyped((volatile void *) addr) = mask;
|
||||
}
|
||||
|
||||
/*! \brief Atomically clear the specified bits to 0 in a HW register
|
||||
* \ingroup hardware_base
|
||||
*
|
||||
* \param addr Address of writable register
|
||||
* \param mask Bit-mask specifying bits to clear
|
||||
*/
|
||||
__force_inline static void hw_clear_bits(io_rw_32 *addr, uint32_t mask) {
|
||||
*(io_rw_32 *) hw_clear_alias_untyped((volatile void *) addr) = mask;
|
||||
}
|
||||
|
||||
/*! \brief Atomically flip the specified bits in a HW register
|
||||
* \ingroup hardware_base
|
||||
*
|
||||
* \param addr Address of writable register
|
||||
* \param mask Bit-mask specifying bits to invert
|
||||
*/
|
||||
__force_inline static void hw_xor_bits(io_rw_32 *addr, uint32_t mask) {
|
||||
*(io_rw_32 *) hw_xor_alias_untyped((volatile void *) addr) = mask;
|
||||
}
|
||||
|
||||
/*! \brief Set new values for a sub-set of the bits in a HW register
|
||||
* \ingroup hardware_base
|
||||
*
|
||||
* Sets destination bits to values specified in \p values, if and only if corresponding bit in \p write_mask is set
|
||||
*
|
||||
* Note: this method allows safe concurrent modification of *different* bits of
|
||||
* a register, but multiple concurrent access to the same bits is still unsafe.
|
||||
*
|
||||
* \param addr Address of writable register
|
||||
* \param values Bits values
|
||||
* \param write_mask Mask of bits to change
|
||||
*/
|
||||
__force_inline static void hw_write_masked(io_rw_32 *addr, uint32_t values, uint32_t write_mask) {
|
||||
hw_xor_bits(addr, (*addr ^ values) & write_mask);
|
||||
}
|
||||
|
||||
#if !PICO_RP2040
|
||||
// include this here to avoid the check in every other hardware/structs header that needs it
|
||||
#include "hardware/structs/accessctrl.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue