Building CalEPD with Espressif IDF - martinberlin/cale-idf GitHub Wiki

I wanted to make a Wiki page explaining how to download cale-idf repository and effectively make an epaper refresh. First there are some prior understanding of the IDF universe that need to get sorted and slowly we will get there together. But you will need to burn some of your time to learn this. If you are not willing to do so then stop reading here and head to cale-platformio that is an easy repository which will grab all you need using the platformio build system and you don't have to be aware of anything that happens in the background. Will just pull required libraries, download them in the .pio/libdeps folder and build it for you. Keep on reading only if you mind to understand how the IDF build system works otherwise this will be lost time for you.

First pre-requisite is to have ESP-IDF toolchain installed in your operative system. There is plenty of documentation on how to do it in Linux on Espressif official documentation and I also explained in detail how to do it on Windows.

And to start with it we should start with learning how the IDF build system works. Sorry about that if you wanted a quick start but using a toolchain has a learning curve and you cannot run if you didn't learn to walk. You need to dig some time on this just as everyone does when learning something new, and that means that for 2 or 3 days you will not flash anything, you will just try to understand concepts before starting hands on.

That is my way to do it, of course if you want to do it the cowboy way, you might right start flashing stuff without understanding how anything works and just go through IDF examples. That's another way to do it. And everyone has to choose what is the best since there are no perfect formulas. But the build system is a must. Because doing this you will be building Firmware that is basically a set of components with a C or C++ main file that is going to be used as start point to build the ESP32 program that runs in your microchip.

ESP-IDF is built on top of the FreeRTOS operating system that is a real-time OS for micro-controllers. It's interesting to have a 10 minutes read in their website and get a grasp of what are the OS basic things. More than that basically ESP-IDF is a toolchain that is CMake based and uses components in order to build your Firmware. The /components are usually in that folder and are similar to the libraries that you installed in Arduino-IDE with the difference that this ones are components only for your Firmware that are usually added to your project using git submodules that is a really fancy way to add libraries quasy automatically. Since adding submodules this way you are telling git, just go to this URL and download the repository in my components/NAME folder. Instead of duplicating the code here and there, you just reference an URL in your git repository, and then people cloning this repository with the --recursive option is going to download your Firmware code but also your components folder with linked REMOTE components!

The IDF build system page adds a nice example of how that sums up together to do a sample project that shows the current humidity in a Web-Server:

  • The ESP-IDF base libraries (libc, ROM bindings, etc)
  • The Wi-Fi drivers
  • A TCP/IP stack
  • The FreeRTOS operating system
  • A webserver
  • A driver for the humidity sensor
  • Main code tying it all together

Now I will copy the explained parts and dig further with some extra comments:

ESP-IDF makes these components explicit and configurable. To do that, when a project is compiled, the build system will look up all the components in the ESP-IDF directories, the project directories and (optionally) in additional custom component directories. Exactly that is the way it works: Let's say we have a main/CMakeFiles that says that the entry point of your project is main/webserver.c and the required components are humidity_sensor. OK then IDF will build that C file but also go into components/humidity_sensor and build that library so it can be all linked together in your firmware.

It then allows the user to configure the ESP-IDF project using a text-based menu system to customize each component. After the components in the project are configured, the build system will compile the project.

The IDF concept to do configuration is based on the Kconfig language, that is the same way that Linux kernel options are offered, so you can just call:

idf.py menuconfig

And this will scan your entry point src file plus component KConfig files and add this entries to a comprehensive menu, that you can navigate with the arrow keys and change values. This values will be written to an sdkconfig file that is full of defines which will be the base to configure your firmware and related components.

Back to our humidity sensor, let's say that in our main/ folder we have a KConfig file where you can enter your WiFi Credentials, and that in the humidity sensor there is an additional setting so the Firmware knows in what GPIOs is your I2C sensor connected. Then IDF will just go from the root up in the tree and display you the WiFi Configuration but also the I2C sensor settings reading the additional KConfig file in the components/humidity_sensor directory.

The point that I would like to dig into here is that building a Firmware with CMake is like going up into the tree. You tell in the root CMakeLists file:

idf_component_register(
    SRCS "demos/demo-touch.cpp"
    INCLUDE_DIRS ".")

# Other additional defines maybe
# This is just to avoid that BitBank2 components include Arduino.h
idf_build_set_property(COMPILE_OPTIONS "-D __LINUX__" APPEND) 

Then IDF will know at this point that he has to compile the main/demos/demo-touch.cpp file as an entry point but also if you have the components/ directory with a bunch of components will go there first and try to build the components with the settings you previously configured or had as default set in the sdkconfig for this components.

To get it better: This is my main file. But then goes though the tree branches and builds the dependencies.

This at the beginning can be quite daunting and I found myself for many hours debugging things because I didn't understand correctly what was going on. But at some point after spending this initial time that no one has for free, it will settle down on you, and at this point you will understand the basics of how the build system works and how to build your own Firmware.

There is no magic pot. At some point, building any Firmware, you will get errors and you will have to find your own solutions to overcome them. Then after many weeks of learning, and of course just like everyone, learning from the community and using ESP32 gitter or any other channels you will be able to master the right steps to get things running.

The practice makes the master.

Pulling this repository and build one demo Firmware

Considering that you already have ESP-IDF installed (min. version 4.2) then you can already download this codebase and related components. All in one line using git (Linux) or Git bash / Powershell (Windows)

git clone --recursive https://github.com/martinberlin/cale-idf.git

The --recursive will tell git: "If there are any linked submodules, then pull them recursively" You don't have to use git if you don't like it. It's also possible to download a ZIP but then you need to go to the component folder and do the same with the linked components too. As you can see learning basic git commands will save you lot's of time and it's not that complicated if you will mostly pull code.

Opening this in VSCODE or any IDE you will see a directory structure similar than this one:

vcode view

As you can see there is a CMakeLists in the root that basically you don't need to touch, which just says there is a minimum CMake version required, and has the name that the binary will have when it will be generated in the build directory. Not important for us now, so let's focus in the next CMakeLists the one that is in the main/ directory. We could also configure a different directory than main but when nothing is configured, main will be the default entry-point where CMake will look for the next CMakeLists file:

idf_component_register(
   SRCS "demos/demo-epaper.cpp"
)

This file is a bit messy since it contains a commented list of many different demos that I collected in last two years. But that's not important since you can just reduce it to that 3 lines. This just tells IDF build process:

Build as main source the file demos/demo-epaper.cpp

Now on the hardware side, let's imagine we have a GDEY027T91 2.7" epaper display, and we've the 8 pins SPI + power and ground, wired to our ESP32 with a standard pinup. You can find in the folder: config-examples some common configurations for different MCUs including ESP32, ESP32S3 and versions with and without PSRAM. Then we can open one of this files, search for "MOSI", and wire things up in our breadboard. To make it easier, we can just copy this sdkconfig example to our root folder/sdkconfig. Or we just run:

idf.py menuconfig

menuconfig

There select Display configuration and you can configure manually the SPI configuration.

At this point we have then the epaper wired to the ESP32 and a known GPIO configuration. Then we will proceed to edit demos/demo-epaper.cpp and make sure it is using the right class for this epaper:

#include "goodisplay/gdey027T91.h"
EpdSpi io;
Gdey027T91 display(io);

This classes you can also find navigating this Wiki since I created a page per display model adding a small example of how to set it up. You can also open components/CalEPD that is the name of the component and navigate models in order to find the right class. Now after making sure we have the right class and the physical GPIO configuration matches our menuconfig one, then we can build it:

idf.py build

And if all goes fine we can connect the ESP32 to USB and flash it in our Micro-controller:

idf.py flash monitor

monitor will open the serial monitor after flashing the Firmware which is very convenient to spot errors. For example you might have selected a GPIO that is not output capable, then SPI driver will through a red warning in your console. This can happen or there can be some wrong configuration if the epaper does not refresh. Do not give up!

No one get's the things working in the first time. There is always some picky thing here and there, you need time to get it right, so just check wiring again. Measure with the amperemeter that in fact the EPD display, is getting 3.3V, connecting that pin and GND. If it's not powered for sure won't work, if MOSI or CLK are wrongly connected, or swapped it won't also work at all. # All the hardware part needs to be properly connected. The rest is software configuration and selecting the right class, which in turn, sends the right SPI commands.

Best luck in your future builds!