но это ии))) а верить ему можно аккуратно…
Согласно официальной документации, у ESP32-S3 действительно 45 физических GPIO (0-21 и 26-48) . Пин 22 физически не существует, что делает проверка pin < 54 на первый взгляд странной.
Однако gpio_matrix_out работает не напрямую с ножками кристалла, а с GPIO Matrix — сложным коммутатором, который позволяет назначить любой внутренний сигнал (UART, I2C, PWM) на любой вывод .
🗺️ «Теневые» пины: что находится по адресам 22-53?
В регистровом пространстве GPIO Matrix зарезервированы слоты для всех 54 возможных каналов ввода-вывода. Слоты с 22 по 53 делятся на три типа:
Слоты 22, 23, 24, 25 (Физически отсутствуют): Если вы попытаетесь использовать их, сигнал уйдет «в никуда», не вызвав ошибки или сбоя. Физически вы просто не увидите его на ножке, потому что ножки нет.
Слоты 26-48 (Реальные пины): Здесь все стандартно — физические выводы кристалла.
Слоты 49-53 (Спецфункции): Это самое интересное. Эти номера зарезервированы для управления специальными функциями чипа, которые не выведены на внешние пины, но управляются через ту же систему матрицы. Например:
Внутренний тактовый сигнал (CLK_OUT): Сигнал с номера 49 (как вариант) может тактировать внутренние модули.
USB- Serial/JTAG: Номера могут использоваться для перенаправления отладочных сигналов внутрь контроллера USB.
⚙️ Как работает GPIO Matrix (Главный ключ к пониманию)
Главная фишка ESP32 — GPIO Matrix (или просто "IO MUX") . Это виртуальный коммутатор, который отвязывает периферию от конкретных пинов. Вы говорите процессору: "Хочу вывести сигнал UART на пин 10".
Матрица ищет слот №10 и соединяет его с нужной функцией. Матрица спроектирована так, чтобы иметь фиксированный размер памяти (54 слота), потому что переделывать архитектуру под каждую новую модель чипа (где разное количество пинов) дорого и сложно . Производителю просто оставить 54 слота "на вырост" или для внутренних нужд.
💎 Вывод
Код в ROM работает идеально. Он просто кладет данные в ячейку памяти по адресу ADDRESS + pin * 4.
Если вы укажете pin = 23 (которого нет), регистр запишется, сигнал уйдет в матрицу, но так как физического контакта снаружи нет — вы просто ничего не увидите на ножке.
Это позволяет использовать единый драйвер для всех моделей ESP32-S3, независимо от того, 45 пинов у чипа в корпусе или 54 в условной футуристической версии.
| 26, 32 |
CS и CLK для PSRAM возможно… |
|
|
| 49 |
Внутренний тактовый сигнал (CLK_OUT) |
Сигнал для отладки тактирования |
| 50 |
USB Serial/JTAG (вход) |
Можно перенаправить UART внутрь USB-контроллера |
На платах с ESP32-S3-WROOM-2 или маркировкой R8/R16V используется Octal PSRAM . Тогда заняты 6 пинов:
Пины Назначение
26, 27, 28, 29, 30, 31, 32 SPI1 (внутренняя шина для flash/PSRAM)
33, 34, 35, 36, 37 Octal PSRAM (старшие линии данных и DQS)
⚠️ Важно: Если у вас плата с 8 MB PSRAM (ESP32-S3-WROOM-1 N8R8 или N16R8/N16R16V), то пины 35, 36, 37 заняты и не доступны для внешнего использования .
Как определить:
N8R2 или N4R2 — Quad PSRAM (только пины 26, 32 заняты)
N8R8, N16R8, N16R16V — Octal PSRAM (пины 26-37 сильно ограничены)
#include <Arduino.h>
#include <rom/gpio.h>
// Таблица статусов пинов
const char* pinStatus[54] = {0};
void analyzeAllPins() {
Serial.println("\n=== АНАЛИЗ ВСЕХ 54 СЛОТОВ GPIO MATRIX ===\n");
for(int pin = 0; pin < 54; pin++) {
bool existsInMatrix = true; // Все 54 существуют в матрице
bool hasPhysicalPin = false;
bool isSpecial = false;
String note = "";
// Физические пины (0-21 и 26-48)
if((pin >= 0 && pin <= 21) || (pin >= 26 && pin <= 48)) {
hasPhysicalPin = true;
if(pin >= 26 && pin <= 32) note = " (может быть занят PSRAM)";
if(pin >= 43 && pin <= 44) note = " (UART0 консоль)";
if(pin >= 45 && pin <= 46) note = " (Strapping пины)";
}
// "Дырки" - нет физического пина
if(pin >= 22 && pin <= 25) {
hasPhysicalPin = false;
note = " ❌ ФИЗИЧЕСКИ ОТСУТСТВУЕТ!";
}
// Специальные слоты (49-53)
if(pin >= 49 && pin <= 53) {
hasPhysicalPin = false;
switch(pin) {
case 49: note = " (Внутренний CLK_OUT)"; break;
case 50: note = " (USB-JTAG/Serial)"; break;
case 51: note = " (Внутренний сигнал)"; break;
case 52: note = " (Внутренний сигнал)"; break;
case 53: note = " (Внутренний сигнал)"; break;
}
}
// Вывод статуса
Serial.printf("Слот %3d: В матрице=ДА | Физический=%s | %s\n",
pin,
hasPhysicalPin ? "ДА " : "НЕТ",
hasPhysicalPin ? (String("OK") + note).c_str() : note.c_str()
);
}
Serial.println("\n=== ИТОГО ===");
Serial.println("Слоты 0-53: 54 слота (все есть в GPIO Matrix)");
Serial.println("Физические пины: 0-21 и 26-48 (всего 45 пинов)");
Serial.println("Пустые слоты: 22-25 (4 слота - физически отсутствуют)");
Serial.println("Спец-слоты: 49-53 (5 слотов - внутренние функции)");
}
void testMatrixWrite(int pin) {
Serial.printf("\n--- Тест записи в слот %d ---\n", pin);
// Пытаемся записать сигнал (любой, например 0x38 - FSPI CLK)
gpio_matrix_out(pin, 0x38, false, false);
// Читаем что записалось
uint32_t regAddr = GPIO_FUNC0_OUT_SEL_CFG_REG + (pin * 4);
uint32_t regValue = READ_PERI_REG(regAddr);
Serial.printf("Регистр 0x%08X = 0x%08X\n", regAddr, regValue);
if(regValue != 0) {
Serial.printf("✅ Слот %d: запись успешна (сигнал уйдет в матрицу)\n", pin);
if(pin >= 22 && pin <= 25) {
Serial.printf("⚠️ Но физического пина нет - сигнал пропадет!\n");
} else if(pin >= 49) {
Serial.printf("🔧 Специальный слот - сигнал уйдет внутрь чипа\n");
}
}
}
void setup() {
Serial.begin(115200);
delay(1000);
// 1. Анализ всех слотов
analyzeAllPins();
// 2. Тест записи в разные типы слотов
testMatrixWrite(10); // обычный физический пин
testMatrixWrite(23); // пустой слот (нет пина)
testMatrixWrite(50); // специальный слот
Serial.println("\n=== ВЫВОД ===");
Serial.println("Все 54 слота (0-53) существуют в GPIO Matrix");
Serial.println("Физических пинов только 45 (0-21 и 26-48)");
Serial.println("Слоты 22-25: есть в матрице, но нет ножек");
Serial.println("Слоты 49-53: зарезервированы для внутренних функций");
}
void loop() {}
там еще и от платы зависит…
и отдельно продублирую
gpio_matrix_out() работает не с физическими ножками, а с виртуальными слотами GPIO Matrix — таблицей маршрутизации сигналов внутри чипа. Эта таблица имеет фиксированный размер 54 слота (0–53) по архитектурным причинам, независимо от того, сколько из них реально выведено на корпус. ESP32-S3 наследует GPIO Matrix от более старых чипов (ESP32, ESP32-S2). У ESP32 было больше пинов, плюс закладывали запас “на будущее”. Проще оставить старый размер матрицы, чем переписывать драйверы и рисковать несовместимостью.