Using the register function on the ESP32


A new feature in Version 4.1 of uLisp is that you can access the ESP32 registers directly with the register command. Here’s an example:

Simple GPIO output

On the ESP32 there are 34 GPIO pins: 0-19, 21-23, 25-27, and 32-39. A GPIO Matrix allows you to route any pin to a specified signal within the processor. However, for simple GPIO input and output there are direct ways of accessing or controlling the pins, which is what the following example uses (see ESP32 Technical Reference Manual):

Setting a bit in the GPIO_OUT register will write to the corresponding GPIO pad, where its address is given by:

(defvar gpio-out #x3FF44004)

To configure a pin for simple GPIO output you need to set the GPIO Matrix GPIO_FUNCx_OUT_SEL register to the special peripheral index value #x100. The following function gpio-func-out-sel returns the correct address for this register for pin n, where n is 0 to 39:

(defun gpio-func-out-sel (n) (+ #x3FF44530 (* 4 n)))

You also need to set the appropriate bit in the GPIO_ENABLE register, given by:

(defvar gpio-enable #x3FF44020)

For example, the Adafruit ESP32 Feather has an LED connected to GPIO pin 13. The following program configures this pin and then flashes the LED:

(defun flash ()
  (register (gpio-func-out-sel 13) #x100) ; simple output
  (register gpio-enable (ash 1 13)) ; enable output
   (register gpio-out (logxor (register gpio-out) (ash 1 13)))
   (delay 1000)))

You can do a similar thing on the ESP32-S2.