| /* |
| * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| #ifndef _HARDWARE_RESETS_H |
| #define _HARDWARE_RESETS_H |
| |
| #include "pico.h" |
| #include "hardware/structs/resets.h" |
| |
| /** \file hardware/resets.h |
| * \defgroup hardware_resets hardware_resets |
| * |
| * \brief Hardware Reset API |
| * |
| * The reset controller allows software control of the resets to all of the peripherals that are not |
| * critical to boot the processor in the RP-series microcontroller. |
| * |
| * \subsubsection reset_bitmask |
| * \addtogroup hardware_resets |
| * |
| * Multiple blocks are referred to using a bitmask as follows: |
| * |
| * Block to reset | Bit |
| * ---------------|---- |
| * USB | 24 |
| * UART 1 | 23 |
| * UART 0 | 22 |
| * Timer | 21 |
| * TB Manager | 20 |
| * SysInfo | 19 |
| * System Config | 18 |
| * SPI 1 | 17 |
| * SPI 0 | 16 |
| * RTC | 15 |
| * PWM | 14 |
| * PLL USB | 13 |
| * PLL System | 12 |
| * PIO 1 | 11 |
| * PIO 0 | 10 |
| * Pads - QSPI | 9 |
| * Pads - bank 0 | 8 |
| * JTAG | 7 |
| * IO Bank 1 | 6 |
| * IO Bank 0 | 5 |
| * I2C 1 | 4 |
| * I2C 0 | 3 |
| * DMA | 2 |
| * Bus Control | 1 |
| * ADC 0 | 0 |
| * |
| * \subsection reset_example Example |
| * \addtogroup hardware_resets |
| * \include hello_reset.c |
| */ |
| |
| // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_RESETS, Enable/disable assertions in the hardware_resets module, type=bool, default=0, group=hardware_adc |
| #ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_RESETS |
| #ifdef PARAM_ASSERTIONS_ENABLED_RESET // backwards compatibility with SDK < 2.0.0 |
| #define PARAM_ASSERTIONS_ENABLED_HARDWARE_RESETS PARAM_ASSERTIONS_ENABLED_RESET |
| #else |
| #define PARAM_ASSERTIONS_ENABLED_HARDWARE_RESETS 0 |
| #endif |
| #endif |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| static __force_inline void reset_block_reg_mask(io_rw_32 *reset, uint32_t mask) { |
| hw_set_bits(reset, mask); |
| } |
| |
| static __force_inline void unreset_block_reg_mask(io_rw_32 *reset, uint32_t mask) { |
| hw_clear_bits(reset, mask); |
| } |
| |
| static __force_inline void unreset_block_reg_mask_wait_blocking(io_rw_32 *reset, io_ro_32 *reset_done, uint32_t mask) { |
| hw_clear_bits(reset, mask); |
| while (~*reset_done & mask) |
| tight_loop_contents(); |
| } |
| |
| /// \tag::reset_funcs[] |
| |
| /*! \brief Reset the specified HW blocks |
| * \ingroup hardware_resets |
| * |
| * \param bits Bit pattern indicating blocks to reset. See \ref reset_bitmask |
| */ |
| static __force_inline void reset_block_mask(uint32_t bits) { |
| reset_block_reg_mask(&resets_hw->reset, bits); |
| } |
| |
| /*! \brief bring specified HW blocks out of reset |
| * \ingroup hardware_resets |
| * |
| * \param bits Bit pattern indicating blocks to unreset. See \ref reset_bitmask |
| */ |
| static __force_inline void unreset_block_mask(uint32_t bits) { |
| unreset_block_reg_mask(&resets_hw->reset, bits); |
| } |
| |
| /*! \brief Bring specified HW blocks out of reset and wait for completion |
| * \ingroup hardware_resets |
| * |
| * \param bits Bit pattern indicating blocks to unreset. See \ref reset_bitmask |
| */ |
| static __force_inline void unreset_block_mask_wait_blocking(uint32_t bits) { |
| unreset_block_reg_mask_wait_blocking(&resets_hw->reset, &resets_hw->reset_done, bits); |
| } |
| |
| /// \end::reset_funcs[] |
| |
| #ifndef HARDWARE_RESETS_ENABLE_SDK1XX_COMPATIBILITY |
| #define HARDWARE_RESETS_ENABLE_SDK1XX_COMPATIBILITY 1 |
| #endif |
| |
| #if HARDWARE_RESETS_ENABLE_SDK1XX_COMPATIBILITY |
| static __force_inline void reset_block(uint32_t bits) { |
| reset_block_mask(bits); |
| } |
| |
| static __force_inline void unreset_block(uint32_t bits) { |
| unreset_block_mask(bits); |
| } |
| |
| static __force_inline void unreset_block_wait(uint32_t bits) { |
| return unreset_block_mask_wait_blocking(bits); |
| } |
| #endif |
| |
| /*! \brief Reset the specified HW block |
| * \ingroup hardware_resets |
| * |
| * \param block_num the block number |
| */ |
| static inline void reset_block_num(uint32_t block_num) { |
| reset_block_reg_mask(&resets_hw->reset, 1u << block_num); |
| } |
| |
| /*! \brief bring specified HW block out of reset |
| * \ingroup hardware_resets |
| * |
| * \param block_num the block number |
| */ |
| static inline void unreset_block_num(uint block_num) { |
| invalid_params_if(HARDWARE_RESETS, block_num > NUM_RESETS); |
| unreset_block_reg_mask(&resets_hw->reset, 1u << block_num); |
| } |
| |
| /*! \brief Bring specified HW block out of reset and wait for completion |
| * \ingroup hardware_resets |
| * |
| * \param block_num the block number |
| */ |
| static inline void unreset_block_num_wait_blocking(uint block_num) { |
| invalid_params_if(HARDWARE_RESETS, block_num > NUM_RESETS); |
| unreset_block_reg_mask_wait_blocking(&resets_hw->reset, &resets_hw->reset_done, 1u << block_num); |
| } |
| |
| /*! \brief Reset the specified HW block, and then bring at back out of reset and wait for completion |
| * \ingroup hardware_resets |
| * |
| * \param block_num the block number |
| */ |
| static inline void reset_unreset_block_num_wait_blocking(uint block_num) { |
| invalid_params_if(HARDWARE_RESETS, block_num > NUM_RESETS); |
| reset_block_reg_mask(&resets_hw->reset, 1u << block_num); |
| unreset_block_reg_mask_wait_blocking(&resets_hw->reset, &resets_hw->reset_done, 1u << block_num); |
| } |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif |