185edca797
The STM32WB, STM32WB and STM32WBA families devices include a EUI64 ID (called "IEEE 64-bit unique device ID register" in the reference manual that is distinct from the standard device ID. Add support for reading it, noting that it is stored in little endian format in the registers. On other families the weak implementation takes over and returns -ENOSYS. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
195 lines
4.3 KiB
C
195 lines
4.3 KiB
C
/*
|
|
* Copyright (c) 2018 Alexander Wachter
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <soc.h>
|
|
#include <stm32_ll_utils.h>
|
|
#include <stm32_ll_rcc.h>
|
|
#if defined(CONFIG_SOC_SERIES_STM32H5X)
|
|
#include <stm32_ll_icache.h>
|
|
#endif /* CONFIG_SOC_SERIES_STM32H5X */
|
|
#include <stm32_ll_pwr.h>
|
|
#include <zephyr/drivers/hwinfo.h>
|
|
#include <string.h>
|
|
#include <zephyr/sys/byteorder.h>
|
|
|
|
struct stm32_uid {
|
|
uint32_t id[3];
|
|
};
|
|
|
|
ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length)
|
|
{
|
|
struct stm32_uid dev_id;
|
|
|
|
#if defined(CONFIG_SOC_SERIES_STM32H5X)
|
|
LL_ICACHE_Disable();
|
|
#endif /* CONFIG_SOC_SERIES_STM32H5X */
|
|
|
|
dev_id.id[0] = sys_cpu_to_be32(LL_GetUID_Word2());
|
|
dev_id.id[1] = sys_cpu_to_be32(LL_GetUID_Word1());
|
|
dev_id.id[2] = sys_cpu_to_be32(LL_GetUID_Word0());
|
|
|
|
#if defined(CONFIG_SOC_SERIES_STM32H5X)
|
|
LL_ICACHE_Enable();
|
|
#endif /* CONFIG_SOC_SERIES_STM32H5X */
|
|
|
|
if (length > sizeof(dev_id.id)) {
|
|
length = sizeof(dev_id.id);
|
|
}
|
|
|
|
memcpy(buffer, dev_id.id, length);
|
|
|
|
return length;
|
|
}
|
|
|
|
#if defined(CONFIG_SOC_SERIES_STM32WBAX) || \
|
|
defined(CONFIG_SOC_SERIES_STM32WBX) || \
|
|
defined(CONFIG_SOC_SERIES_STM32WLX)
|
|
struct stm32_eui64 {
|
|
uint32_t id[2];
|
|
};
|
|
|
|
int z_impl_hwinfo_get_device_eui64(uint8_t *buffer)
|
|
{
|
|
struct stm32_eui64 dev_eui64;
|
|
|
|
dev_eui64.id[0] = sys_cpu_to_be32(READ_REG(*((uint32_t *)UID64_BASE + 1U)));
|
|
dev_eui64.id[1] = sys_cpu_to_be32(READ_REG(*((uint32_t *)UID64_BASE)));
|
|
|
|
memcpy(buffer, dev_eui64.id, sizeof(dev_eui64));
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
int z_impl_hwinfo_get_reset_cause(uint32_t *cause)
|
|
{
|
|
uint32_t flags = 0;
|
|
|
|
#if defined(RCC_FLAG_SFTRST)
|
|
if (LL_RCC_IsActiveFlag_SFTRST()) {
|
|
flags |= RESET_SOFTWARE;
|
|
}
|
|
#endif
|
|
#if defined(RCC_FLAG_PINRST)
|
|
if (LL_RCC_IsActiveFlag_PINRST()) {
|
|
flags |= RESET_PIN;
|
|
}
|
|
#endif
|
|
#if defined(RCC_FLAG_IWDGRST)
|
|
if (LL_RCC_IsActiveFlag_IWDGRST()) {
|
|
flags |= RESET_WATCHDOG;
|
|
}
|
|
#endif
|
|
#if defined(RCC_RSR_IWDG1RSTF)
|
|
if (LL_RCC_IsActiveFlag_IWDG1RST()) {
|
|
flags |= RESET_WATCHDOG;
|
|
}
|
|
#endif
|
|
#if defined(RCC_RSR_IWDG2RSTF)
|
|
if (LL_RCC_IsActiveFlag_IWDG2RST()) {
|
|
flags |= RESET_WATCHDOG;
|
|
}
|
|
#endif
|
|
#if defined(RCC_FLAG_WWDGRST)
|
|
if (LL_RCC_IsActiveFlag_WWDGRST()) {
|
|
flags |= RESET_WATCHDOG;
|
|
}
|
|
#endif
|
|
#if defined(RCC_RSR_WWDG1RSTF)
|
|
if (LL_RCC_IsActiveFlag_WWDG1RST()) {
|
|
flags |= RESET_WATCHDOG;
|
|
}
|
|
#endif
|
|
#if defined(RCC_RSR_WWDG2RSTF)
|
|
if (LL_RCC_IsActiveFlag_WWDG2RST()) {
|
|
flags |= RESET_WATCHDOG;
|
|
}
|
|
#endif
|
|
#if defined(RCC_FLAG_FWRST)
|
|
if (LL_RCC_IsActiveFlag_FWRST()) {
|
|
flags |= RESET_SECURITY;
|
|
}
|
|
#endif
|
|
#if defined(RCC_FLAG_BORRST)
|
|
if (LL_RCC_IsActiveFlag_BORRST()) {
|
|
flags |= RESET_BROWNOUT;
|
|
}
|
|
#endif
|
|
#if defined(RCC_FLAG_PWRRST)
|
|
if (LL_RCC_IsActiveFlag_PWRRST()) {
|
|
flags |= RESET_POR;
|
|
}
|
|
#endif
|
|
#if defined(RCC_FLAG_PORRST)
|
|
if (LL_RCC_IsActiveFlag_PORRST()) {
|
|
flags |= RESET_POR;
|
|
}
|
|
#endif
|
|
#if defined(RCC_FLAG_LPWRRST)
|
|
if (LL_RCC_IsActiveFlag_LPWRRST()) {
|
|
flags |= RESET_LOW_POWER_WAKE;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CORE_CM4)
|
|
if (LL_PWR_CPU2_IsActiveFlag_SB()) {
|
|
flags |= RESET_LOW_POWER_WAKE;
|
|
}
|
|
#elif defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CORE_CM7)
|
|
if (LL_PWR_CPU_IsActiveFlag_SB()) {
|
|
flags |= RESET_LOW_POWER_WAKE;
|
|
}
|
|
#elif defined(CONFIG_SOC_SERIES_STM32MP1X)
|
|
if (LL_PWR_MCU_IsActiveFlag_SB()) {
|
|
flags |= RESET_LOW_POWER_WAKE;
|
|
}
|
|
#elif defined(CONFIG_SOC_SERIES_STM32WLX) || defined(CONFIG_SOC_SERIES_STM32WBX)
|
|
if (LL_PWR_IsActiveFlag_C1SB()) {
|
|
flags |= RESET_LOW_POWER_WAKE;
|
|
}
|
|
#elif defined(PWR_FLAG_SB)
|
|
if (LL_PWR_IsActiveFlag_SB()) {
|
|
flags |= RESET_LOW_POWER_WAKE;
|
|
}
|
|
#endif /* PWR_FLAG_SB */
|
|
|
|
*cause = flags;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int z_impl_hwinfo_clear_reset_cause(void)
|
|
{
|
|
LL_RCC_ClearResetFlags();
|
|
|
|
#if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CORE_CM4)
|
|
LL_PWR_ClearFlag_CPU2();
|
|
#elif defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CORE_CM7)
|
|
LL_PWR_ClearFlag_CPU();
|
|
#elif defined(CONFIG_SOC_SERIES_STM32MP1X)
|
|
LL_PWR_ClearFlag_MCU();
|
|
#elif defined(CONFIG_SOC_SERIES_STM32WLX) || defined(CONFIG_SOC_SERIES_STM32WBX)
|
|
LL_PWR_ClearFlag_C1STOP_C1STB();
|
|
#elif defined(PWR_FLAG_SB)
|
|
LL_PWR_ClearFlag_SB();
|
|
#endif /* PWR_FLAG_SB */
|
|
|
|
return 0;
|
|
}
|
|
|
|
int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported)
|
|
{
|
|
*supported = (RESET_PIN
|
|
| RESET_WATCHDOG
|
|
| RESET_SOFTWARE
|
|
| RESET_SECURITY
|
|
| RESET_LOW_POWER_WAKE
|
|
| RESET_POR
|
|
| RESET_BROWNOUT);
|
|
|
|
return 0;
|
|
}
|