1 /*
2  * Copyright (c) 2019 Leandro A. F. Pereira
3  * Copyright (c) 2020 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <soc/efuse_reg.h>
9 #include <soc/reset_reasons.h>
10 #include "esp_system.h"
11 #include "rtc.h"
12 
13 #include <zephyr/drivers/hwinfo.h>
14 #include <string.h>
15 
z_impl_hwinfo_get_device_id(uint8_t * buffer,size_t length)16 ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length)
17 {
18 #if defined(CONFIG_SOC_SERIES_ESP32C2)
19 	uint32_t rdata1 = sys_read32(EFUSE_RD_BLK2_DATA0_REG);
20 	uint32_t rdata2 = sys_read32(EFUSE_RD_BLK2_DATA1_REG);
21 #elif !defined(CONFIG_SOC_SERIES_ESP32)
22 	uint32_t rdata1 = sys_read32(EFUSE_RD_MAC_SPI_SYS_0_REG);
23 	uint32_t rdata2 = sys_read32(EFUSE_RD_MAC_SPI_SYS_1_REG);
24 #else
25 	uint32_t rdata1 = sys_read32(EFUSE_BLK0_RDATA1_REG);
26 	uint32_t rdata2 = sys_read32(EFUSE_BLK0_RDATA2_REG);
27 #endif
28 	uint8_t id[6];
29 
30 	/* The first word provides the lower 32 bits of the MAC
31 	 * address; the low 16 bits of the second word provide the
32 	 * upper 16 bytes of the MAC address.  The upper 16 bits are
33 	 * (apparently) a checksum, and reserved.  See ESP32 Technical
34 	 * Reference Manual V4.1 section 20.5.
35 	 */
36 	id[0] = (uint8_t)(rdata2 >> 8);
37 	id[1] = (uint8_t)(rdata2 >> 0);
38 	id[2] = (uint8_t)(rdata1 >> 24);
39 	id[3] = (uint8_t)(rdata1 >> 16);
40 	id[4] = (uint8_t)(rdata1 >> 8);
41 	id[5] = (uint8_t)(rdata1 >> 0);
42 
43 	if (length > sizeof(id)) {
44 		length = sizeof(id);
45 	}
46 	memcpy(buffer, id, length);
47 
48 	return length;
49 }
50 
z_impl_hwinfo_get_supported_reset_cause(uint32_t * supported)51 int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported)
52 {
53 	*supported = (RESET_POR
54 		      | RESET_PIN
55 		      | RESET_SOFTWARE
56 		      | RESET_WATCHDOG
57 		      | RESET_LOW_POWER_WAKE
58 		      | RESET_CPU_LOCKUP
59 		      | RESET_BROWNOUT);
60 
61 	return 0;
62 }
63 
z_impl_hwinfo_get_reset_cause(uint32_t * cause)64 int z_impl_hwinfo_get_reset_cause(uint32_t *cause)
65 {
66 	uint32_t reason = esp_reset_reason();
67 
68 	switch (reason) {
69 	case ESP_RST_POWERON:
70 		*cause = RESET_POR;
71 		break;
72 	case ESP_RST_EXT:
73 		*cause = RESET_PIN;
74 		break;
75 	case ESP_RST_SW:
76 		*cause = RESET_SOFTWARE;
77 		break;
78 	case ESP_RST_INT_WDT:
79 	case ESP_RST_TASK_WDT:
80 	case ESP_RST_WDT:
81 		*cause = RESET_WATCHDOG;
82 		break;
83 	case ESP_RST_DEEPSLEEP:
84 		*cause = RESET_LOW_POWER_WAKE;
85 		break;
86 	case ESP_RST_PANIC:
87 		*cause = RESET_CPU_LOCKUP;
88 	case ESP_RST_BROWNOUT:
89 		*cause = RESET_BROWNOUT;
90 		break;
91 	default:
92 		*cause = 0;
93 		break;
94 	}
95 
96 	return 0;
97 }
98