Здравствуйте, уважаемые читатели!
Многие из вас наверняка читали сообщения на различных форумах и сайтах, что различные “отладочные” платы на ESP32 могут весьма “неохотно” переключаться в режим программирования по сигналу компьютера (автоматически), и что для решения проблемы бывает достаточно припаять “лишний” конденсатор к выводу EN микроконтроллера. Признаться, я довольно скептически относился к таким заявлениям, потому что “не видел” физических причин для таких заявлений. И тем не менее, оказалось, что причины эти – они как суслик, их не видно на первый взгляд, но они есть. Давайте разберемся, почему так получается.
Для чего обычно ставят резистор и конденсатор на выводе EN микроконтроллера
Наверное, все знают, что к выводу EN микроконтроллера, который “разрешает” его работу, почти всегда подключена RC-цепочка по схеме на рисунке ниже:
Причем это относится не только к ESP8266 / ESP32, но и к другим микроконтроллерам. Зачем она нужна?
А нужна она в первую очередь для того, чтобы “отложить” запуск процессора до момента, когда только что поданное на плату питание зарядило фильтрующие конденсаторы, а подключенная “периферия” нормально запустилась. При подаче питания конденсатор будет сравнительно медленно заряжаться через резистор, и на время своей зарядки “заблокирует” работу процессора.
Я попытался смоделировать это на цифровом осциллографе:
Верхний (зеленый) канал – это напряжение питания (3.3В), подаваемое через обычный USB-порт и хаб, который не очень “любит” большие токи. Поэтому переходные процессы получились так явно выражены (обведены красным). Нижний канал – сигнал на выводе EN микроконтроллера, и напряжение на этом выводе растет более плавно и медленно – и к тому моменту, когда оно достигнет “разрешающего” уровня, переходные процессы на шине питания в основном завершаться.
Это и есть основное предназначение такого конденсатора. И в этом своем предназначении он никак не влияет на режим программирования ESP32.
Что необходимо, чтобы перевести ESP32 в режим программирования
На ESP32 режимом работы заведует загрузчик первого уровня, который “сидит” в маленьком ПЗУ SoC и запускает с flash-памяти загрузчик второго этапа. Именно он и определяет текущий режим работы Soc с помощью так называемых strapping pins. Все strapping pins имеют внутренние защелки. При сбросе системы защелки сохраняют значения битов соответствующих strapping pins и сохраняют их до тех пор, пока чип не будет выключен или перезапущен. Состояния защелок strapping pins нельзя изменить после запуска. Это делает состояния strapping pins доступными в течение всей работы ESP32, и выводы освобождаются для использования в качестве обычных выводов ввода-вывода почти сразу после сброса (в течение ~1мс после начала работы процессора – подробности в datasheet-е).
Я уже довольно часто про них писал, но напомню еще раз, что для перевода ESP32 в режим загрузки двоичного дампа прошивки, необходимо подтянуть вывод GPIO0 к “земле” в момент запуска процессора. Это можно сделать с помощью кнопок, если они есть: одновременно нажать EN и GPIO0 (тем самым подтянув их к низкому уровню), затем отпустить EN, удерживая GPIO0, чтобы состояние GPIO0 сохранилось в защелке.
В принципе – ничто не мешает нажать GPIO0 раньше или позже EN, главное – отпустить его позже
Схема автоматического управления режимом программирования ESP32
На платах ESP32-DevKit и некоторых других, где присутствует USB-порт для программирования, имеется специальная схема для управления сигналами EN и GPIO0. Думаю, все её не раз уже видели:
Эта схема использует сигналы DTR и RTS, получаемые с USB-UART моста, для управления режимом работы и сбросом. Формирует эти сигналы утилита esptool.py, с помощью которой, собственно, и программируется микроконтроллер. Подробнее об этом я писал в предыдущей статье.
Если взглянуть на таблицу состояний схемы (справа от схемы), да и на саму схему – то можно увидеть, что она не удовлетворяет условиям, изложенным в предыдущей части – а именно исключается возможность одновременно установить низкий уровень на выводах EN и GPIO0, так как транзисторы взаимно блокируют друг друга. Сделано это, по заявлению espressif, для обеспечения совместимости с различными драйверами виртуальных com-портов – выбирают, так сказать, “меньшую из бед”. Это и есть тот самый суслик.
На скриншоте видно, что сигналы “приходят” на вход схемы одновременно, так как немного меняется уровень на верхнем графике. Но второй сигнал (сброса) его почти полностью блокирует. В момент, когда сигнал “сброса” пропадает – напряжение на выводе GPIO0 резко падает, но с пусть небольшой, но задержкой. И этой задержки может оказаться недостаточно, чтобы защелка GPIO0 обнаружила сигнал перевода в режим программирования.
И вот тут в дело опять вступает этот самый конденсатор, про который я упомянул выше. Если его емкость достаточно велика, то напряжение на EN будет опять таки расти медленнее, чем обычно, и этого оказывается вполне достаточно, чтобы к тому моменту второй (заблокированный) транзистор переключился и на GPIO0 уже был установлен необходимый уровень. Этот участок обведен сиреневой линией.
На скриншоте ниже я расширил этот участок для наглядности:
Здесь уже хорошо видно, что напряжение на GPIO0 падает с небольшой, но задержкой, после переключения EN. А напряжение на EN растет медленнее, и примерно к моменту запуска процессора на GPIO0 уже успевает установиться уверенный “0”. То есть данная схема изначально рассчитана на работу в комплекте с достаточно большим конденсатором на выводе EN.
Соответственно, если емкость данного конденсатора невелика – ни о какой значительной задержке речь идти уже не может! Процессор запустится и защелки защелкнут свое состояние раньше, чем переключится уровень на GPIO0. Это-то, скорее всего, и являлось проблемой на первых ревизиях плат с ESP32. А подпайка дополнительного конденсатора решала проблему. Что и требовалось доказать. Хорошо, что таких “бракованных” плат почти нет в продаже – мне не попадалось ни одной.
А на этом разрешите откланяться, с сами был Александр aka kotyara12.