1 /* 2 * Copyright (c) 2022 Yonatan Schachter 3 * Copyright (c) 2024 Andrew Featherstone 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #include <string.h> 9 #include <zephyr/drivers/hwinfo.h> 10 #include <hardware/flash.h> 11 #if defined(CONFIG_SOC_SERIES_RP2040) 12 #include <hardware/structs/vreg_and_chip_reset.h> 13 #else 14 #include <hardware/structs/powman.h> 15 #endif 16 17 #define FLASH_RUID_DATA_BYTES 8 18 19 #if defined(CONFIG_SOC_SERIES_RP2040) 20 #define HAD_RUN_BIT BIT(VREG_AND_CHIP_RESET_CHIP_RESET_HAD_RUN_LSB) 21 #define HAD_PSM_RESTART_BIT BIT(VREG_AND_CHIP_RESET_CHIP_RESET_HAD_PSM_RESTART_LSB) 22 #define HAD_POR_BIT BIT(VREG_AND_CHIP_RESET_CHIP_RESET_HAD_POR_LSB) 23 #else 24 #define HAD_RUN_BIT BIT(POWMAN_CHIP_RESET_HAD_RUN_LOW_LSB) 25 #define HAD_PSM_RESTART_BIT BIT(POWMAN_CHIP_RESET_HAD_DP_RESET_REQ_LSB) 26 #define HAD_POR_BIT BIT(POWMAN_CHIP_RESET_HAD_POR_LSB) 27 #endif 28 z_impl_hwinfo_get_device_id(uint8_t * buffer,size_t length)29ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) 30 { 31 uint8_t id[FLASH_RUID_DATA_BYTES]; 32 uint32_t key; 33 34 /* 35 * flash_get_unique_id temporarily disables XIP to query the 36 * flash for its ID. If the CPU is interrupted while XIP is 37 * disabled, it will halt. Therefore, interrupts must be disabled 38 * before fetching the ID. 39 */ 40 key = irq_lock(); 41 flash_get_unique_id(id); 42 irq_unlock(key); 43 44 if (length > sizeof(id)) { 45 length = sizeof(id); 46 } 47 memcpy(buffer, id, length); 48 49 return length; 50 } 51 z_impl_hwinfo_get_reset_cause(uint32_t * cause)52int z_impl_hwinfo_get_reset_cause(uint32_t *cause) 53 { 54 uint32_t flags = 0; 55 #if defined(CONFIG_SOC_SERIES_RP2040) 56 uint32_t reset_register = vreg_and_chip_reset_hw->chip_reset; 57 #else 58 uint32_t reset_register = powman_hw->chip_reset; 59 #endif 60 61 if (reset_register & HAD_POR_BIT) { 62 flags |= RESET_POR; 63 } 64 65 if (reset_register & HAD_RUN_BIT) { 66 flags |= RESET_PIN; 67 } 68 69 if (reset_register & HAD_PSM_RESTART_BIT) { 70 flags |= RESET_DEBUG; 71 } 72 #if defined(CONFIG_SOC_SERIES_RP2350) 73 if (reset_register & POWMAN_CHIP_RESET_HAD_BOR_BITS) { 74 flags |= RESET_BROWNOUT; 75 } 76 77 if (reset_register & (POWMAN_CHIP_RESET_HAD_WATCHDOG_RESET_RSM_BITS | 78 POWMAN_CHIP_RESET_HAD_WATCHDOG_RESET_SWCORE_BITS | 79 POWMAN_CHIP_RESET_HAD_WATCHDOG_RESET_POWMAN_BITS | 80 POWMAN_CHIP_RESET_HAD_WATCHDOG_RESET_POWMAN_ASYNC_BITS)) { 81 flags |= RESET_WATCHDOG; 82 } 83 #endif 84 85 *cause = flags; 86 return 0; 87 } 88 z_impl_hwinfo_clear_reset_cause(void)89int z_impl_hwinfo_clear_reset_cause(void) 90 { 91 /* The reset register can't be modified, nothing to do. */ 92 93 return -ENOSYS; 94 } 95 z_impl_hwinfo_get_supported_reset_cause(uint32_t * supported)96int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported) 97 { 98 *supported = RESET_PIN | RESET_DEBUG | RESET_POR; 99 #if defined(CONFIG_SOC_SERIES_RP2350) 100 *supported |= RESET_BROWNOUT | RESET_WATCHDOG; 101 #endif 102 103 return 0; 104 } 105