ESP32 – jak opravit chybu v návrhu rozhraní na SD kartu (a troška nářků na ESP32)

Jak mi postupně roste velikost kódu pro EasyTherm do ESP8266, tak jsem usoudil, že je na čase se poohlédnout po lepší variantě. Protože jsem chtěl udržet kódovou základnu EasyThermu pokud možno stejnou pro všechny platformy z důvodu snadnějšího vývoje, padla volba na ESP32, se kterým jsem už jednu konstrukci navrhoval…

Stanovené požadavky na zařízení byly jasné:

  • Funkce jako řídící elektronika pro systém EasyTherm s lepším výkonem, než stávající jednotka s ESP8266
  • Doplnění o malý OLED displej, nebo TFT, připojený přes SPI rozhraní
  • Možnost ukládat data na externí úložiště

a pár dalších, méně podstatných změn a vylepšení. Z mé starší konstrukce jsem měl ověřené zapojení rozhraní na SD kartu pomocí SPI, ale nelíbil se mi dosažený výkon a proto jsem se rozhodl navrhnout zapojení přes rozhraní SD MMC. Po kratším studiu dostupné dokumentace jsem nakreslil schéma zapojení, navrhl PCB a nechal ho vyrobit (jako obvykle) v Seeed Studiu. Manželka mi vzorek PCB osadila a tak jsem se mohl pustit do oživování. Vše fungovalo „na první dobrou“, bohužel až na rozhraní na SD kartu, které se mi nepodařilo rozhýbat ani ve 4 bitovém, ani v 1 bitovém režimu. Nezbylo tedy nic jiného, než se ponořit do hlubin internetu a zjistit, kde jsem udělal chybu. Nakonec se ukázalo, že problémem je to, že jsem špatně navrhl (respektive zcela vypustil) pull-up odpory na některé signály. Budiž mi omluvou, že dokumentace je celkem roztříštěná a obsahuje spoustu matoucích informací. Výrobci modulů s ESP32 tomu také nahrávají – jako příklad uvedu situaci u pinu GPIO12:

Tento vývod je tzv. bootstraping pin, takže jeho hodnota je testovaná při spouštění modulu a určuje, jaké napětí se použije pro programování Flash paměti. Default hodnota pro programovací napětí 3V3 je L, ale pokud připojím na stejný pin rozhraní na SD kartu, tak je sem připojený signál D2, který vyžaduje pull-up rezistor a klidovou hodnotu H. Řešením by mohlo být vypálení vnitřních pojistek ESP32, které umožní trvalé nastavení programovacího napětí pro paměť Flash na 3.3V a také odpojí GPIO12 z jeho bootstraping funkce. Otevřeně řečeno nechápu, proč modul Wroom-32 není distribuovaný s touto konfigurací, protože paměť Flash je osazená pod kovovým krytem a v dokumentaci k Wroom-32 se píše, že GPIO12 musí být při startu v L. Těžko předpokládat, že někdo sám odstraní stínící kryt a vymění SPI flash za nějakou, která vyžaduje programovací napětí 1.8V. Aby ale ani to nebylo jednoduché, tak existují dva popisy, jak vnitřní pojistky nastavit – https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card a https://www.esp32.com/viewtopic.php?f=2&t=849&sid=136e5660600bf4f167e174933bfc2f74&start=10 . Vzhledem k tomu, že nastavení pojistek je možné jen jednou a je nevratné, jsem se do experimentu zatím nepustil a zkusil jsem to jinak. U většiny GPIO je možné separátně aktivovat vnitřní pull-upy. U některých je – vzhledem k chybě v HW – nutné pro správnou funkci použít oblast RTC, ale zdá se, že v SDK již došlo k aplikaci SW opravy. Napadlo mě tedy, aktivovat před inicializací SD MMC periferie odpovídající pull-upy v kódu. Před inicializací standardního ovladače z knihovny SD_MMC jsem napsal sekvenci, která přes funkce SDK aktivuje vnitřní pull-upy u odpovídajících pinů:

… po aplikaci této „záplaty“ se 4 bitové rozhraní na SD kartu rozběhlo. Nepovažuji to za konečné a zcela správné řešení – to bude až opravené schéma pro revizi B a správně nastavené efuses v ESP32, nicméně pro účely testování a ladění je naprosto dostačující.

No a nyní k těm nářkům na ESP32 – při vývoji EasyThermu jsem před několika měsíci přešel na platformu Platformio/ATOM. Bylo to pragmatické rozhodnutí ze dvou důvodů:

  • přístup projektu v Platformio mi umožňuje mít pohromadě celý projekt včetně knihoven, které nemusím nijak upravovat (jako jsem musel pro Arduino IDE, pokud jsem chtěl mít vše pohromadě).
  • Platformio mi umožňuje mít v projektu můj modifikovaný linker script, který používám kvůli rozdělení paměti Flash na 2M pro kód a 2M pro SPIFFS. Jde sice vyrobit i pro Arduino IDE, ale znamená to ruční modifikaci souboru baords.txt a přikopírování linker scriptu do odpovídajícího adresáře

jak se ale nakonec ukázalo, tak toto jsou jediné dvě výhody oproti Arduino IDE. Jinak je prakticky vše spíše ve prospěch originálního Arduina. Platformio IDE je tvořené editorem Atom, který rozhodně není z nejsvižnějších, IDE postrádá funkce, které jsem používal zcela (archivace projektu, rozdělení oblasti paměti, upload SPIFFS pro ESP32), nebo je nahrazuje ruční editací souborů (výběr zařízení pro OTA). Pro ESP8266 se s tím dá žít celkem klidně, ale pro ESP32 je to podstatně horší. Uvedu příklad:

Jedna část rozšíření EasyThermu v ESP32 je řízení Bluetooth termostatických hlavic z Lídlu.

Spojení s hlavicemi mám ověřené na jednom z vývojových modulů s ESP32, ale ve chvíli, kdy jsem přidal BLE knihovny do projektu EasyTherm začaly problémy – rozdělení paměti flash v ESP32 je totiž navrženo tak, že pro OTA je k dispozici 2x1MB a zbytek je vyhrazený pro SPIFFS. Potíž je v tom, že BLE knihovny zabírají cca 800kB kódu, takže po slinkování projektu jsem se dostal na velikost kolem 1.5MB, což se už do standardního rozdělení nevejde. Existují sice postupy, jak rozdělení změnit (https://github.com/espressif/arduino-esp32/issues/339 , https://github.com/espressif/arduino-esp32/issues/703 , https://github.com/espressif/arduino-esp32/issues/703 , https://github.com/beegee-tokyo/arduino-esp32/wiki/Change-partition-size ), ale drtivá většina z nich popisuje změnu pro Arduino IDE a v případě popisu pro Platformio se opět jedná o editaci, ale tentokrát souborů, které jsou ručně modifikované v adresářích Platformia (vzpomínáte na druhý důvod, který jsem uvedl pro přechod k Platformio?…).

Musím tedy říct, že stav vývojových nástrojů, knihoven (SDK) a dokumentace k ESP32 dá zabrat i poměrně ostříleným uživatelům.

4 thoughts on “ESP32 – jak opravit chybu v návrhu rozhraní na SD kartu (a troška nářků na ESP32)”

  1. Můžete, prosím,
    uvést nějaký odkaz/popis kódy příkazů pro Lídl hlavice?
    Mám jich doma 6 kusů (s BT) a jejich „řízení“ přes „Andorid aplikaci“ se mi vůbc nelíbí…

    1. Dobrý den,
      hlavice komunikují pomocí GATT. Kód, který bych chtěl uveřejnit ale zatím nemám, nicméně můžete se podívat zde https://github.com/im-0/cometblue , popřípadě čerpat inspiraci z https://github.com/xavriley/Arduino-EQ3-Motion-Aware-Radiator-Thermostat , https://github.com/rytilahti/python-eq3bt . Další informace se pak dají najít přes Google pomocí dotazu „Comet blue GATT“. V ESP32 je ale trošku potíž s rannou fází implementace BLE, takže na stole mi to sice funguje, ale pro produkci je to ještě příliš křehké…
      Pavel Brychta

  2. Zrovna dneska jsem si pro zajímavost modifikoval Arduino IDE pro esp8266 2M/2M. Našel jsem na GitHub přesný popis a PSPadem to byla hračka. Zatím to na svoje hraní ani nepotřebuji, ale chtěl jsem si to vyzkoušet. Před časem jsem si myslel, že ani OTA nepoužiji, ale tento názor jsem už změnil.
    Pavel Janko

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *