forked from m5stack/M5UnitUnified
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpin.cpp
More file actions
107 lines (95 loc) · 3.79 KB
/
Copy pathpin.cpp
File metadata and controls
107 lines (95 loc) · 3.79 KB
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
/*
* SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
*
* SPDX-License-Identifier: MIT
*/
/*!
@file pin.cpp
@brief PIN settings save/restore
@todo Will be transferred to M5HAL in the future
*/
#include "pin.hpp"
#include <M5Utility.hpp>
#include <cstddef>
#include <driver/i2c.h>
#include <soc/gpio_struct.h>
#include <soc/gpio_periph.h>
#include <soc/gpio_reg.h>
namespace m5 {
namespace unit {
namespace gpio {
pin_backup_t::pin_backup_t(int pin_num) : _pin_num{static_cast<gpio_num_t>(pin_num)}
{
if (pin_num >= 0) {
backup();
}
}
void pin_backup_t::backup(void)
{
#if !defined(CONFIG_IDF_TARGET_ESP32P4)
auto pin_num = (size_t)_pin_num;
if (pin_num < GPIO_NUM_MAX) {
_io_mux_gpio_reg = *reinterpret_cast<uint32_t*>(GPIO_PIN_MUX_REG[pin_num]);
_gpio_pin_reg = *reinterpret_cast<uint32_t*>(GPIO_PIN0_REG + (pin_num * 4));
_gpio_func_out_reg = *reinterpret_cast<uint32_t*>(GPIO_FUNC0_OUT_SEL_CFG_REG + (pin_num * 4));
#if defined(GPIO_ENABLE1_REG)
_gpio_enable = (bool)((*reinterpret_cast<uint32_t*>(((pin_num & 32) ? GPIO_ENABLE1_REG : GPIO_ENABLE_REG)) &
(1U << (pin_num & 31))) != 0);
#else
_gpio_enable = (bool)((*reinterpret_cast<uint32_t*>(GPIO_ENABLE_REG) & (1U << (pin_num & 31))) != 0);
#endif
_in_func_num = -1;
size_t func_num = ((_gpio_func_out_reg >> GPIO_FUNC0_OUT_SEL_S) & GPIO_FUNC0_OUT_SEL_V);
if (func_num < sizeof(GPIO.func_in_sel_cfg) / sizeof(GPIO.func_in_sel_cfg[0])) {
_gpio_func_in_reg = *reinterpret_cast<uint32_t*>(GPIO_FUNC0_IN_SEL_CFG_REG + (func_num * 4));
if (func_num == ((_gpio_func_in_reg >> GPIO_FUNC0_IN_SEL_S) & GPIO_FUNC0_IN_SEL_V)) {
_in_func_num = func_num;
M5_LIB_LOGV("backup pin:%d : func_num:%d", pin_num, _in_func_num);
}
}
}
#else
#pragma message "ESP32-P4 is not supported"
#endif
}
void pin_backup_t::restore(void)
{
#if !defined(CONFIG_IDF_TARGET_ESP32P4)
auto pin_num = (size_t)_pin_num;
if (pin_num < GPIO_NUM_MAX) {
if ((uint16_t)_in_func_num < 256) {
GPIO.func_in_sel_cfg[_in_func_num].val = _gpio_func_in_reg;
M5_LIB_LOGV("pin:%d in_func_num:%d", (int)pin_num, (int)_in_func_num);
}
M5_LIB_LOGV("restore pin:%d ", pin_num);
M5_LIB_LOGV("restore IO_MUX_GPIO0_REG :%08x -> %08x ",
*reinterpret_cast<uint32_t*>(GPIO_PIN_MUX_REG[pin_num]), _io_mux_gpio_reg);
M5_LIB_LOGV("restore GPIO_PIN0_REG :%08x -> %08x ",
*reinterpret_cast<uint32_t*>(GPIO_PIN0_REG + (pin_num * 4)), _gpio_pin_reg);
M5_LIB_LOGV("restore GPIO_FUNC0_OUT_SEL_CFG_REG:%08x -> %08x ",
*reinterpret_cast<uint32_t*>(GPIO_FUNC0_OUT_SEL_CFG_REG + (pin_num * 4)), _gpio_func_out_reg);
*reinterpret_cast<uint32_t*>(GPIO_PIN_MUX_REG[_pin_num]) = _io_mux_gpio_reg;
*reinterpret_cast<uint32_t*>(GPIO_PIN0_REG + (pin_num * 4)) = _gpio_pin_reg;
*reinterpret_cast<uint32_t*>(GPIO_FUNC0_OUT_SEL_CFG_REG + (pin_num * 4)) = _gpio_func_out_reg;
#if defined(GPIO_ENABLE1_REG)
auto gpio_enable_reg = reinterpret_cast<uint32_t*>(((pin_num & 32) ? GPIO_ENABLE1_REG : GPIO_ENABLE_REG));
#else
auto gpio_enable_reg = reinterpret_cast<uint32_t*>(GPIO_ENABLE_REG);
#endif
uint32_t pin_mask = 1 << (pin_num & 31);
uint32_t val = *gpio_enable_reg;
M5_LIB_LOGV("restore GPIO_ENABLE_REG:%08x", (int)*gpio_enable_reg);
if (_gpio_enable) {
val |= pin_mask;
} else {
val &= ~pin_mask;
}
*gpio_enable_reg = val;
}
#else
#pragma message "ESP32-P4 is not supported"
#endif
}
} // namespace gpio
} // namespace unit
} // namespace m5