Выводы GPIO11 - GPIO17 по умолчанию предназначены для подключения внешней памяти программ SPI flash:
Вывод корпуса |
Имя |
GPIO |
Описание |
18 |
VDD_SPI |
GPIO11 |
Выход. Напряжение питания внешней микросхемы SPI flash. |
19 |
FLASH_HOLD# |
GPIO12 |
Выход. Приостанавливает функционирование FLASH, даже если она выбрана сигналом CS#. |
20 |
FLASH_WP# |
GPIO13 |
Выход. Лог. 0 запрещает запись в SPI flash. |
21 |
FLASH_CS# |
GPIO14 |
Выход. Сигнал выборки SPI flash. |
22 |
FLASH_SCK |
GPIO15 |
Выход. Сигнал тактирования SPI flash. |
23 |
FLASH_SDI |
GPIO16 |
Вход. Сигнал данных SPI flash. |
24 |
FLASH_SDO |
GPIO17 |
Выход. Сигнал данных SPI flash. |
В официальной документации написано, что использовать эти выводы под другие функции не рекомендуется, однако это явно не запрещается [1]. Встает вопрос - можно ли эти выводы использовать в программе для других функций, например как обычные цифровые порты для ввода и вывода, GPIO?
Среди библиотечных функций ESP-IDF SDK есть макросы, которые позволяют определить возможности выводов: GPIO_IS_VALID_GPIO, GPIO_IS_VALID_OUTPUT_GPIO, GPIO_IS_VALID_DIGITAL_IO_PAD, GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO. Можно написать код, который будет проверять возможности этих выводов:
void CheckValidGPIO (void)
{
ESP_LOGW("GPIO_IS_VALID_GPIO", "");
for(uint8_t pinNum = 11; pinNum<18; pinNum++)
printf("GPIO%u %u\n", pinNum, GPIO_IS_VALID_GPIO(pinNum));
ESP_LOGW("GPIO_IS_VALID_OUTPUT_GPIO", "");
for(uint8_t pinNum = 11; pinNum<18; pinNum++)
printf("GPIO%u %u\n", pinNum, GPIO_IS_VALID_OUTPUT_GPIO(pinNum));
// ESP_LOGW("GPIO_IS_VALID_DIGITAL_IO_PAD", "");
// for(uint8_t pinNum = 11; pinNum<18; pinNum++)
// printf("GPIO%u %u\n", pinNum, GPIO_IS_VALID_DIGITAL_IO_PAD(pinNum));
ESP_LOGW("GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO", "");
for(uint8_t pinNum = 11; pinNum<18; pinNum++)
printf("GPIO%u %u\n", pinNum, GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(pinNum));
}
После запуска эта функция выведет положительный результат, что якобы использовать эти выводы можно. Выведенная 1 означает, что эти выводы можно использовать для функционала GPIO:
W (623) GPIO_IS_VALID_GPIO:
GPIO11 1
GPIO12 1
GPIO13 1
GPIO14 1
GPIO15 1
GPIO16 1
GPIO17 1
W (623) GPIO_IS_VALID_OUTPUT_GPIO:
GPIO11 1
GPIO12 1
GPIO13 1
GPIO14 1
GPIO15 1
GPIO16 1
GPIO17 1
W (623) GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO:
GPIO11 1
GPIO12 1
GPIO13 1
GPIO14 1
GPIO15 1
GPIO16 1
GPIO17 1
Но к сожалению, не все так радужно, как хотелось бы. Даже если память flash размещена внутри чипа (а такие варианты чипов ESP32-C3 существуют), все равно в момент загрузки на этих выводах можно наблюдать на этих выводах активность.
Какие выводы из этого можно сделать? Сигналы подключения SPI flash можно использовать как GPIO, но с соблюдением некоторых условий:
1. Если весь код размещается только в IRAM (это можно обеспечить только для небольших по объему программ), и если в момент включения выводы SPI flash ничем не заблокированы.
2. Вывод FLASH_WP# можно относительно свободно использовать, если не подразумевается доступ к SPI Flash на запись. Лог. 0 на этом выводе всего лишь блокирует возможность записи содержимого SPI Flash. Обычный логический уровень на нем единица, и сигнал на нем не меняется в процессе перепрошивки и работы программы.
3. Для использования GPIO11 (VDD_SPI) необходимо воспользоваться перепрограммированием фьюзов eFUSE [3].
[Ссылки]
1. ESP32-C3: GPIO и RTC GPIO. 2. ESP32-C3: справочник по выводам. 3. ESP32-C3: управление выводом VDD_SPI как ножкой порта GPIO11. |