1 /*
2  * Copyright (c) 2018 Alexander Wachter
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <soc.h>
8 #include <stm32_ll_utils.h>
9 #include <stm32_ll_rcc.h>
10 #if defined(CONFIG_SOC_SERIES_STM32H5X)
11 #include <stm32_ll_icache.h>
12 #endif /* CONFIG_SOC_SERIES_STM32H5X */
13 #include <stm32_ll_pwr.h>
14 #include <zephyr/drivers/hwinfo.h>
15 #include <string.h>
16 #include <zephyr/sys/byteorder.h>
17 
18 struct stm32_uid {
19 	uint32_t id[3];
20 };
21 
z_impl_hwinfo_get_device_id(uint8_t * buffer,size_t length)22 ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length)
23 {
24 	struct stm32_uid dev_id;
25 
26 #if defined(CONFIG_SOC_SERIES_STM32H5X)
27 	LL_ICACHE_Disable();
28 #endif /* CONFIG_SOC_SERIES_STM32H5X */
29 
30 	dev_id.id[0] = sys_cpu_to_be32(LL_GetUID_Word2());
31 	dev_id.id[1] = sys_cpu_to_be32(LL_GetUID_Word1());
32 	dev_id.id[2] = sys_cpu_to_be32(LL_GetUID_Word0());
33 
34 #if defined(CONFIG_SOC_SERIES_STM32H5X)
35 	LL_ICACHE_Enable();
36 #endif /* CONFIG_SOC_SERIES_STM32H5X */
37 
38 	if (length > sizeof(dev_id.id)) {
39 		length = sizeof(dev_id.id);
40 	}
41 
42 	memcpy(buffer, dev_id.id, length);
43 
44 	return length;
45 }
46 
z_impl_hwinfo_get_reset_cause(uint32_t * cause)47 int z_impl_hwinfo_get_reset_cause(uint32_t *cause)
48 {
49 	uint32_t flags = 0;
50 
51 #if defined(RCC_FLAG_SFTRST)
52 	if (LL_RCC_IsActiveFlag_SFTRST()) {
53 		flags |= RESET_SOFTWARE;
54 	}
55 #endif
56 #if defined(RCC_FLAG_PINRST)
57 	if (LL_RCC_IsActiveFlag_PINRST()) {
58 		flags |= RESET_PIN;
59 	}
60 #endif
61 #if defined(RCC_FLAG_IWDGRST)
62 	if (LL_RCC_IsActiveFlag_IWDGRST()) {
63 		flags |= RESET_WATCHDOG;
64 	}
65 #endif
66 #if defined(RCC_RSR_IWDG1RSTF)
67 	if (LL_RCC_IsActiveFlag_IWDG1RST()) {
68 		flags |= RESET_WATCHDOG;
69 	}
70 #endif
71 #if defined(RCC_RSR_IWDG2RSTF)
72 	if (LL_RCC_IsActiveFlag_IWDG2RST()) {
73 		flags |= RESET_WATCHDOG;
74 	}
75 #endif
76 #if defined(RCC_FLAG_WWDGRST)
77 	if (LL_RCC_IsActiveFlag_WWDGRST()) {
78 		flags |= RESET_WATCHDOG;
79 	}
80 #endif
81 #if defined(RCC_RSR_WWDG1RSTF)
82 	if (LL_RCC_IsActiveFlag_WWDG1RST()) {
83 		flags |= RESET_WATCHDOG;
84 	}
85 #endif
86 #if defined(RCC_RSR_WWDG2RSTF)
87 	if (LL_RCC_IsActiveFlag_WWDG2RST()) {
88 		flags |= RESET_WATCHDOG;
89 	}
90 #endif
91 #if defined(RCC_FLAG_FWRST)
92 	if (LL_RCC_IsActiveFlag_FWRST()) {
93 		flags |= RESET_SECURITY;
94 	}
95 #endif
96 #if defined(RCC_FLAG_BORRST)
97 	if (LL_RCC_IsActiveFlag_BORRST()) {
98 		flags |= RESET_BROWNOUT;
99 	}
100 #endif
101 #if defined(RCC_FLAG_PWRRST)
102 	if (LL_RCC_IsActiveFlag_PWRRST()) {
103 		flags |= RESET_POR;
104 	}
105 #endif
106 #if defined(RCC_FLAG_PORRST)
107 	if (LL_RCC_IsActiveFlag_PORRST()) {
108 		flags |= RESET_POR;
109 	}
110 #endif
111 #if defined(RCC_FLAG_LPWRRST)
112 	if (LL_RCC_IsActiveFlag_LPWRRST()) {
113 		flags |= RESET_LOW_POWER_WAKE;
114 	}
115 #endif
116 
117 #if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CORE_CM4)
118 	if (LL_PWR_CPU2_IsActiveFlag_SB()) {
119 		flags |= RESET_LOW_POWER_WAKE;
120 	}
121 #elif defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CORE_CM7)
122 	if (LL_PWR_CPU_IsActiveFlag_SB()) {
123 		flags |= RESET_LOW_POWER_WAKE;
124 	}
125 #elif defined(CONFIG_SOC_SERIES_STM32MP1X)
126 	if (LL_PWR_MCU_IsActiveFlag_SB()) {
127 		flags |= RESET_LOW_POWER_WAKE;
128 	}
129 #elif defined(CONFIG_SOC_SERIES_STM32WLX) || defined(CONFIG_SOC_SERIES_STM32WBX)
130 	if (LL_PWR_IsActiveFlag_C1SB()) {
131 		flags |= RESET_LOW_POWER_WAKE;
132 	}
133 #elif defined(PWR_FLAG_SB)
134 	if (LL_PWR_IsActiveFlag_SB()) {
135 		flags |= RESET_LOW_POWER_WAKE;
136 	}
137 #endif /* PWR_FLAG_SB */
138 
139 	*cause = flags;
140 
141 	return 0;
142 }
143 
z_impl_hwinfo_clear_reset_cause(void)144 int z_impl_hwinfo_clear_reset_cause(void)
145 {
146 	LL_RCC_ClearResetFlags();
147 
148 #if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CORE_CM4)
149 	LL_PWR_ClearFlag_CPU2();
150 #elif defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CORE_CM7)
151 	LL_PWR_ClearFlag_CPU();
152 #elif defined(CONFIG_SOC_SERIES_STM32MP1X)
153 	LL_PWR_ClearFlag_MCU();
154 #elif defined(CONFIG_SOC_SERIES_STM32WLX) || defined(CONFIG_SOC_SERIES_STM32WBX)
155 	LL_PWR_ClearFlag_C1STOP_C1STB();
156 #elif defined(PWR_FLAG_SB)
157 	LL_PWR_ClearFlag_SB();
158 #endif /* PWR_FLAG_SB */
159 
160 	return 0;
161 }
162 
z_impl_hwinfo_get_supported_reset_cause(uint32_t * supported)163 int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported)
164 {
165 	*supported = (RESET_PIN
166 		      | RESET_WATCHDOG
167 		      | RESET_SOFTWARE
168 		      | RESET_SECURITY
169 		      | RESET_LOW_POWER_WAKE
170 		      | RESET_POR
171 		      | RESET_BROWNOUT);
172 
173 	return 0;
174 }
175