forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhwinfo_nrf.c
187 lines (166 loc) · 4.33 KB
/
hwinfo_nrf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
* Copyright (c) 2018 Alexander Wachter
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <soc.h>
#include <zephyr/drivers/hwinfo.h>
#include <string.h>
#include <zephyr/sys/byteorder.h>
#if !defined(CONFIG_SOC_SERIES_NRF54HX) && !defined(CONFIG_BOARD_QEMU_CORTEX_M0)
#include <helpers/nrfx_reset_reason.h>
#endif
#if defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) && defined(NRF_FICR_S)
#include <soc_secure.h>
#else
#include <hal/nrf_ficr.h>
#endif
struct nrf_uid {
uint32_t id[2];
};
ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length)
{
struct nrf_uid dev_id;
uint32_t buf[2];
#if NRF_FICR_HAS_DEVICE_ID || NRF_FICR_HAS_INFO_DEVICE_ID
/* DEVICEID is accessible, use this */
#if defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) && defined(NRF_FICR_S)
soc_secure_read_deviceid(buf);
#else
buf[0] = nrf_ficr_deviceid_get(NRF_FICR, 0);
buf[1] = nrf_ficr_deviceid_get(NRF_FICR, 1);
#endif
#elif NRF_FICR_HAS_DEVICE_ADDR || NRF_FICR_HAS_BLE_ADDR
/* DEVICEID is not accessible, use device/ble address instead.
* Assume that it is always accessible from the non-secure image.
*/
buf[0] = nrf_ficr_deviceaddr_get(NRF_FICR, 0);
buf[1] = nrf_ficr_deviceaddr_get(NRF_FICR, 1);
/* Assume that ER and IR are available whenever deviceaddr is.
* Use the LSBytes from ER and IR to complete the device id.
*/
buf[1] |= (nrf_ficr_er_get(NRF_FICR, 0) & 0xFF) << 16;
buf[1] |= (nrf_ficr_ir_get(NRF_FICR, 0) & 0xFF) << 24;
#else
#error "No suitable source for hwinfo device_id generation"
#endif
dev_id.id[0] = sys_cpu_to_be32(buf[1]);
dev_id.id[1] = sys_cpu_to_be32(buf[0]);
if (length > sizeof(dev_id.id)) {
length = sizeof(dev_id.id);
}
memcpy(buffer, dev_id.id, length);
return length;
}
#if !defined(CONFIG_SOC_SERIES_NRF54HX) && !defined(CONFIG_BOARD_QEMU_CORTEX_M0)
int z_impl_hwinfo_get_reset_cause(uint32_t *cause)
{
uint32_t flags = 0;
uint32_t reason = nrfx_reset_reason_get();
if (reason & NRFX_RESET_REASON_RESETPIN_MASK) {
flags |= RESET_PIN;
}
if (reason & NRFX_RESET_REASON_DOG_MASK) {
flags |= RESET_WATCHDOG;
}
if (reason & NRFX_RESET_REASON_LOCKUP_MASK) {
flags |= RESET_CPU_LOCKUP;
}
if (reason & NRFX_RESET_REASON_OFF_MASK) {
flags |= RESET_LOW_POWER_WAKE;
}
if (reason & NRFX_RESET_REASON_DIF_MASK) {
flags |= RESET_DEBUG;
}
if (reason & NRFX_RESET_REASON_SREQ_MASK) {
flags |= RESET_SOFTWARE;
}
#if NRFX_RESET_REASON_HAS_CTRLAP
if (reason & NRFX_RESET_REASON_CTRLAP_MASK) {
flags |= RESET_DEBUG;
}
#endif
#if NRFX_RESET_REASON_HAS_LPCOMP
if (reason & NRFX_RESET_REASON_LPCOMP_MASK) {
flags |= RESET_LOW_POWER_WAKE;
}
#endif
#if NRFX_RESET_REASON_HAS_NFC
if (reason & NRFX_RESET_REASON_NFC_MASK) {
flags |= RESET_LOW_POWER_WAKE;
}
#endif
#if NRFX_RESET_REASON_HAS_VBUS
if (reason & NRFX_RESET_REASON_VBUS_MASK) {
flags |= RESET_POR;
}
#endif
#if NRFX_RESET_REASON_HAS_CTRLAPSOFT
if (reason & NRFX_RESET_REASON_CTRLAPSOFT_MASK) {
flags |= RESET_DEBUG;
}
#endif
#if NRFX_RESET_REASON_HAS_CTRLAPHARD
if (reason & NRFX_RESET_REASON_CTRLAPHARD_MASK) {
flags |= RESET_DEBUG;
}
#endif
#if NRFX_RESET_REASON_HAS_CTRLAPPIN
if (reason & NRFX_RESET_REASON_CTRLAPPIN_MASK) {
flags |= RESET_DEBUG;
}
#endif
#if !NRF_POWER_HAS_RESETREAS
if (reason & NRFX_RESET_REASON_DOG1_MASK) {
flags |= RESET_WATCHDOG;
}
#endif
#if NRFX_RESET_REASON_HAS_GRTC
if (reason & NRFX_RESET_REASON_GRTC_MASK) {
flags |= RESET_CLOCK;
}
#endif
#if NRFX_RESET_REASON_HAS_NETWORK
if (reason & NRFX_RESET_REASON_LSREQ_MASK) {
flags |= RESET_SOFTWARE;
}
if (reason & NRFX_RESET_REASON_LLOCKUP_MASK) {
flags |= RESET_CPU_LOCKUP;
}
if (reason & NRFX_RESET_REASON_LDOG_MASK) {
flags |= RESET_WATCHDOG;
}
if (reason & NRFX_RESET_REASON_LCTRLAP_MASK) {
flags |= RESET_DEBUG;
}
#endif
#if defined(NRFX_RESET_REASON_TAMPC_MASK)
if (reason & NRFX_RESET_REASON_TAMPC_MASK) {
flags |= RESET_SECURITY;
}
#endif
#if defined(NRFX_RESET_REASON_SECTAMPER_MASK)
if (reason & NRFX_RESET_REASON_SECTAMPER_MASK) {
flags |= RESET_SECURITY;
}
#endif
*cause = flags;
return 0;
}
int z_impl_hwinfo_clear_reset_cause(void)
{
uint32_t reason = -1;
nrfx_reset_reason_clear(reason);
return 0;
}
int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported)
{
*supported = (RESET_PIN
| RESET_WATCHDOG
| RESET_SOFTWARE
| RESET_CPU_LOCKUP
| RESET_LOW_POWER_WAKE
| RESET_DEBUG);
return 0;
}
#endif