forked from espressif/arduino-esp32
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathesp32-hal-periman.c
241 lines (227 loc) · 8.46 KB
/
esp32-hal-periman.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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/*
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp32-hal-log.h"
#include "esp32-hal-periman.h"
#include "esp_bit_defs.h"
typedef struct ATTR_PACKED {
peripheral_bus_type_t type;
const char *extra_type;
void *bus;
int8_t bus_num;
int8_t bus_channel;
} peripheral_pin_item_t;
static peripheral_bus_deinit_cb_t deinit_functions[ESP32_BUS_TYPE_MAX];
static peripheral_pin_item_t pins[SOC_GPIO_PIN_COUNT];
#define GPIO_NOT_VALID(p) ((p >= SOC_GPIO_PIN_COUNT) || ((SOC_GPIO_VALID_GPIO_MASK & (1ULL << p)) == 0))
const char *perimanGetTypeName(peripheral_bus_type_t type) {
switch (type) {
case ESP32_BUS_TYPE_INIT: return "INIT";
case ESP32_BUS_TYPE_GPIO: return "GPIO";
case ESP32_BUS_TYPE_UART_RX: return "UART_RX";
case ESP32_BUS_TYPE_UART_TX: return "UART_TX";
case ESP32_BUS_TYPE_UART_CTS: return "UART_CTS";
case ESP32_BUS_TYPE_UART_RTS: return "UART_RTS";
#if SOC_SDM_SUPPORTED
case ESP32_BUS_TYPE_SIGMADELTA: return "SIGMADELTA";
#endif
#if SOC_ADC_SUPPORTED
case ESP32_BUS_TYPE_ADC_ONESHOT: return "ADC_ONESHOT";
case ESP32_BUS_TYPE_ADC_CONT: return "ADC_CONT";
#endif
#if SOC_DAC_SUPPORTED
case ESP32_BUS_TYPE_DAC_ONESHOT: return "DAC_ONESHOT";
case ESP32_BUS_TYPE_DAC_CONT: return "DAC_CONT";
case ESP32_BUS_TYPE_DAC_COSINE: return "DAC_COSINE";
#endif
#if SOC_LEDC_SUPPORTED
case ESP32_BUS_TYPE_LEDC: return "LEDC";
#endif
#if SOC_RMT_SUPPORTED
case ESP32_BUS_TYPE_RMT_TX: return "RMT_TX";
case ESP32_BUS_TYPE_RMT_RX: return "RMT_RX";
#endif
#if SOC_I2S_SUPPORTED
case ESP32_BUS_TYPE_I2S_STD_MCLK: return "I2S_STD_MCLK";
case ESP32_BUS_TYPE_I2S_STD_BCLK: return "I2S_STD_BCLK";
case ESP32_BUS_TYPE_I2S_STD_WS: return "I2S_STD_WS";
case ESP32_BUS_TYPE_I2S_STD_DOUT: return "I2S_STD_DOUT";
case ESP32_BUS_TYPE_I2S_STD_DIN: return "I2S_STD_DIN";
case ESP32_BUS_TYPE_I2S_TDM_MCLK: return "I2S_TDM_MCLK";
case ESP32_BUS_TYPE_I2S_TDM_BCLK: return "I2S_TDM_BCLK";
case ESP32_BUS_TYPE_I2S_TDM_WS: return "I2S_TDM_WS";
case ESP32_BUS_TYPE_I2S_TDM_DOUT: return "I2S_TDM_DOUT";
case ESP32_BUS_TYPE_I2S_TDM_DIN: return "I2S_TDM_DIN";
case ESP32_BUS_TYPE_I2S_PDM_TX_CLK: return "I2S_PDM_TX_CLK";
case ESP32_BUS_TYPE_I2S_PDM_TX_DOUT0: return "I2S_PDM_TX_DOUT0";
case ESP32_BUS_TYPE_I2S_PDM_TX_DOUT1: return "I2S_PDM_TX_DOUT1";
case ESP32_BUS_TYPE_I2S_PDM_RX_CLK: return "I2S_PDM_RX_CLK";
case ESP32_BUS_TYPE_I2S_PDM_RX_DIN0: return "I2S_PDM_RX_DIN0";
case ESP32_BUS_TYPE_I2S_PDM_RX_DIN1: return "I2S_PDM_RX_DIN1";
case ESP32_BUS_TYPE_I2S_PDM_RX_DIN2: return "I2S_PDM_RX_DIN2";
case ESP32_BUS_TYPE_I2S_PDM_RX_DIN3: return "I2S_PDM_RX_DIN3";
#endif
#if SOC_I2C_SUPPORTED
case ESP32_BUS_TYPE_I2C_MASTER_SDA: return "I2C_MASTER_SDA";
case ESP32_BUS_TYPE_I2C_MASTER_SCL: return "I2C_MASTER_SCL";
case ESP32_BUS_TYPE_I2C_SLAVE_SDA: return "I2C_SLAVE_SDA";
case ESP32_BUS_TYPE_I2C_SLAVE_SCL: return "I2C_SLAVE_SCL";
#endif
#if SOC_GPSPI_SUPPORTED
case ESP32_BUS_TYPE_SPI_MASTER_SCK: return "SPI_MASTER_SCK";
case ESP32_BUS_TYPE_SPI_MASTER_MISO: return "SPI_MASTER_MISO";
case ESP32_BUS_TYPE_SPI_MASTER_MOSI: return "SPI_MASTER_MOSI";
case ESP32_BUS_TYPE_SPI_MASTER_SS: return "SPI_MASTER_SS";
#endif
#if SOC_SDMMC_HOST_SUPPORTED
case ESP32_BUS_TYPE_SDMMC_CLK: return "SDMMC_CLK";
case ESP32_BUS_TYPE_SDMMC_CMD: return "SDMMC_CMD";
case ESP32_BUS_TYPE_SDMMC_D0: return "SDMMC_D0";
case ESP32_BUS_TYPE_SDMMC_D1: return "SDMMC_D1";
case ESP32_BUS_TYPE_SDMMC_D2: return "SDMMC_D2";
case ESP32_BUS_TYPE_SDMMC_D3: return "SDMMC_D3";
#endif
#if SOC_TOUCH_SENSOR_SUPPORTED
case ESP32_BUS_TYPE_TOUCH: return "TOUCH";
#endif
#if SOC_USB_SERIAL_JTAG_SUPPORTED || SOC_USB_OTG_SUPPORTED
case ESP32_BUS_TYPE_USB_DM: return "USB_DM";
case ESP32_BUS_TYPE_USB_DP: return "USB_DP";
#endif
#if SOC_GPSPI_SUPPORTED
case ESP32_BUS_TYPE_ETHERNET_SPI: return "ETHERNET_SPI";
#endif
#if CONFIG_ETH_USE_ESP32_EMAC
case ESP32_BUS_TYPE_ETHERNET_RMII: return "ETHERNET_RMII";
case ESP32_BUS_TYPE_ETHERNET_CLK: return "ETHERNET_CLK";
case ESP32_BUS_TYPE_ETHERNET_MCD: return "ETHERNET_MCD";
case ESP32_BUS_TYPE_ETHERNET_MDIO: return "ETHERNET_MDIO";
case ESP32_BUS_TYPE_ETHERNET_PWR: return "ETHERNET_PWR";
#endif
#if CONFIG_LWIP_PPP_SUPPORT
case ESP32_BUS_TYPE_PPP_TX: return "PPP_MODEM_TX";
case ESP32_BUS_TYPE_PPP_RX: return "PPP_MODEM_RX";
case ESP32_BUS_TYPE_PPP_RTS: return "PPP_MODEM_RTS";
case ESP32_BUS_TYPE_PPP_CTS: return "PPP_MODEM_CTS";
#endif
default: return "UNKNOWN";
}
}
bool perimanSetPinBus(uint8_t pin, peripheral_bus_type_t type, void *bus, int8_t bus_num, int8_t bus_channel) {
peripheral_bus_type_t otype = ESP32_BUS_TYPE_INIT;
void *obus = NULL;
if (GPIO_NOT_VALID(pin)) {
log_e("Invalid pin: %u", pin);
return false;
}
if (type >= ESP32_BUS_TYPE_MAX) {
log_e("Invalid type: %s (%u) when setting pin %u", perimanGetTypeName(type), (unsigned int)type, pin);
return false;
}
if (type > ESP32_BUS_TYPE_GPIO && bus == NULL) {
log_e("Bus is NULL for pin %u with type %s (%u)", pin, perimanGetTypeName(type), (unsigned int)type);
return false;
}
if (type == ESP32_BUS_TYPE_INIT && bus != NULL) {
log_e("Can't set a Bus to INIT Type (pin %u)", pin);
return false;
}
otype = pins[pin].type;
obus = pins[pin].bus;
if (type == otype && bus == obus) {
if (type != ESP32_BUS_TYPE_INIT) {
log_i("Pin %u already has type %s (%u) with bus %p", pin, perimanGetTypeName(type), (unsigned int)type, bus);
}
return true;
}
if (obus != NULL) {
if (deinit_functions[otype] == NULL) {
log_e("No deinit function for type %s (%u) (pin %u)", perimanGetTypeName(otype), (unsigned int)otype, pin);
return false;
}
if (!deinit_functions[otype](obus)) {
log_e("Deinit function for previous bus type %s (%u) failed (pin %u)", perimanGetTypeName(otype), (unsigned int)otype, pin);
return false;
}
}
pins[pin].type = type;
pins[pin].bus = bus;
pins[pin].bus_num = bus_num;
pins[pin].bus_channel = bus_channel;
pins[pin].extra_type = NULL;
log_v("Pin %u successfully set to type %s (%u) with bus %p", pin, perimanGetTypeName(type), (unsigned int)type, bus);
return true;
}
bool perimanSetPinBusExtraType(uint8_t pin, const char *extra_type) {
if (GPIO_NOT_VALID(pin)) {
log_e("Invalid pin: %u", pin);
return false;
}
if (pins[pin].type == ESP32_BUS_TYPE_INIT) {
log_e("Can't set extra type for Bus INIT Type (pin %u)", pin);
return false;
}
pins[pin].extra_type = extra_type;
log_v("Successfully set extra_type %s for pin %u", extra_type, pin);
return true;
}
void *perimanGetPinBus(uint8_t pin, peripheral_bus_type_t type) {
if (GPIO_NOT_VALID(pin)) {
log_e("Invalid pin: %u", pin);
return NULL;
}
if (type >= ESP32_BUS_TYPE_MAX || type == ESP32_BUS_TYPE_INIT) {
log_e("Invalid type %s (%u) for pin %u", perimanGetTypeName(type), (unsigned int)type, pin);
return NULL;
}
if (pins[pin].type == type) {
return pins[pin].bus;
}
return NULL;
}
peripheral_bus_type_t perimanGetPinBusType(uint8_t pin) {
if (GPIO_NOT_VALID(pin)) {
log_e("Invalid pin: %u", pin);
return ESP32_BUS_TYPE_MAX;
}
return pins[pin].type;
}
const char *perimanGetPinBusExtraType(uint8_t pin) {
if (GPIO_NOT_VALID(pin)) {
log_e("Invalid pin: %u", pin);
return NULL;
}
return pins[pin].extra_type;
}
int8_t perimanGetPinBusNum(uint8_t pin) {
if (GPIO_NOT_VALID(pin)) {
log_e("Invalid pin: %u", pin);
return -1;
}
return pins[pin].bus_num;
}
int8_t perimanGetPinBusChannel(uint8_t pin) {
if (GPIO_NOT_VALID(pin)) {
log_e("Invalid pin: %u", pin);
return -1;
}
return pins[pin].bus_channel;
}
bool perimanSetBusDeinit(peripheral_bus_type_t type, peripheral_bus_deinit_cb_t cb) {
if (type >= ESP32_BUS_TYPE_MAX || type == ESP32_BUS_TYPE_INIT) {
log_e("Invalid type: %s (%u)", perimanGetTypeName(type), (unsigned int)type);
return false;
}
if (cb == NULL) {
log_e("Callback is NULL when setting deinit function for type %s (%u)", perimanGetTypeName(type), (unsigned int)type);
return false;
}
deinit_functions[type] = cb;
log_v("Deinit function for type %s (%u) successfully set to %p", perimanGetTypeName(type), (unsigned int)type, cb);
return true;
}
bool perimanPinIsValid(uint8_t pin) {
return !(GPIO_NOT_VALID(pin));
}