Cardputer uLisp Machine

16th November 2024

This article describes how to create a handheld Lisp computer from an M5Stack Cardputer Kit:

Cardputer.jpg 

The Cardputer uLisp Machine, a handheld Lisp computer with a self-contained keyboard and display.

The M5Stack Cardputer is a card-sized portable computer based on the ESP32-S3, available for about £30/$30. It has a 240x135 colour TFT display that gives a scrolling display of up to 16 lines of 40 characters, an integrated 56-key keyboard, and an SD card socket. It's available direct from M5Stack [1], or from The Pi-Hut in the UK [2].

Introduction

The M5Stack Cardputer is based on an ESP32-S3 dual-core LX7 microprocessor, with 2.4 GHz Wi-Fi, Bluetooth 5 (LE), and 8M bytes of flash.

The display is a 1.14 inch ST7789V2 SPI Interface IPS LCD with a resolution of 240 x 135. The display uses the Arduino GFX library, and the firmware provides software scrolling.

The keyboard has 56 keys, providing a full ASCII character set. However, it's very tiny; small fingers are recommended.

The Cardputer is contained in a fairly rugged case, and includes a 120 mAh rechargeable battery on the main board and a 1400 mAh LiPo cell in the backpack. These can be charged from the USB port.

Note: Although the StampS3 module is a separate module in the Cardputer I recommend you don't attempt to remove it, as it is attached to the display internally, and you can easily damage the connector.

Factory firmware

The M5Stack Cardputer is supplied with several built-in applications. Installing uLisp will delete these applications, but you can reinstall them from the M5 Cardputer User Demo repository on GitHub: M5Cardputer-UserDemo.

Installing the Cardputer uLisp firmware

Install the M5Stack core

  • Add the following M5Stack URL to the Additional Boards Manager URLs list in the Arduino IDE Preferences dialog box:
https://static-cdn.m5stack.com/resource/arduino/package_m5stack_index.json
  • In the Arduino IDE search for the M5Stack core in Boards Manager and install it. I used version 2.1.2.
  • In the Arduino IDE search for the M5Cardputer library in Library Manager and install it. I used version 1.0.2.

It will prompt to install some dependencies. Click Install all to agree.

  • Select M5Stack Arduino from the Board menu, and M5Cardputer from the submenu.
  • Check that the subsequent options are set as follows:

USB CDC On Boot: "Enabled"
Flash Size: "8MB (64Mb)"
Partition Scheme: "8MB with spiffs (3MB APP/1.5MB SPIFFS)"

You can leave the other options at their defaults.

Install uLisp

  • Download the Cardputer uLisp firmware from https://github.com/technoblogy/ulisp-cardputer.
  • Connect the computer's USB port to the Cardputer and select the port from the Tools menu Port submenu.
  • Choose Upload from the Sketch menu to upload uLisp.

You should then see the uLisp prompt on the Cardputer display, and be able to enter Lisp programs at the keyboard. You can also enter Lisp programs from the Arduino IDE Serial Monitor.

Larger font

A larger font option gives 9 lines of 30 characters per line:

CardputerLargerfont.jpg 

The uLisp Cardputer with the larger font option selected.

To choose the larger font option uncomment the option:

#define largerfont 

before uploading uLisp.

Cardputer uLisp Machine – Specification

Here's the full specification:

Size: 84 x 54 x 19.7 mm (2.7" x 3.9"); Weight: 93 g.

Display: 40 characters x 16 lines (or 30 characters x 9 lines with a larger font option).

Keyboard: Integrated 56-key keyboard providing upper and lower-case characters, digits, and symbols required by uLisp.

Memory available: 23750 Lisp objects.

Flash: 1.5M bytes of flash are reserved for use to save the Lisp workspace using save-image if the SD card interface is not used.

Processor: ESP32-S3

Clock speed: 240 MHz.

Language

uLisp, a subset of Common Lisp, with approximately 200 Lisp functions and special forms.

It also provides keywords, such as :input and :output, as a convenient way of entering Arduino constants.

For a full definition see uLisp Language Reference.

Types supported: list, symbol, integer, floating-point, character, string, stream, and array.

An integer is a sequence of digits, optionally prefixed with "+" or "-". Integers can be between -32768 and 32767. You can enter numbers in hexadecimal, octal, or binary with the notations #x2A, #o52, or #b101010, all of which represent 42.

The floating-point numbers have full 32-bit precision.

User-defined symbol names can have arbitrary names. Any sequence that isn't an integer can be used as a symbol; so, for example, 12a is a valid symbol.

There is one namespace for functions and variables; in other words, you cannot use the same name for a function and a variable.

uLisp includes a mark and sweep garbage collector. Garbage collection takes about 1 ms.

Entering programs

You can enter commands and programs by typing them at the keyboard, and pressing ↩. A keyboard buffer is provided that buffers a full screen of text, and you can use the ⌫ key to delete characters and correct typing mistakes. The editor includes parenthesis matching which automatically highlights matching brackets in green as you type in a program. This makes it much easier to enter a program correctly, and is especially helpful in telling you how many closing brackets to type at the end of defining a function.

Keyboard

To get upper-case letters, or the blue symbols above the digits and some other keys, hold down the Aa shift key while typing a key.

Escape

To escape from a running program press the G0 button to the right of the On/Off switch on the back panel.

Copying the last line

Press the tab key to echo the previous line typed after the uLisp prompt, allowing you to edit it.

Connecting to a computer

You can also connect the Cardputer to a computer via a USB cable. You can then use the Serial Monitor in the Arduino IDE to enter and edit programs as described in Using uLisp.

Sound

You can play notes through the internal speaker using the uLisp note function. For example, the following function plays a scale of C (the pin number is ignored):

(defun scale () 
  (mapc 
   (lambda (n) (note 0 n 4) (delay 500))
   '(0 2 4 5 7 9 11 12))
  (note))

The beep character beeps the speaker:

(write-byte 7)

SD Card

The Cardputer has an SD card socket that can be used to read from and write to SD cards from uLisp, and to save an image of the Lisp workspace. To return a list of the files on an SD card give the command directory:

> (directory)
("T1.bmp" "A1" "F2" "T2" "PIC.BMP" "ULISP.IMG" "Greeting.txt" "PIC2.BMP" "X1")

For details of using SD cards see SD card interface.

If you don't want to use the SD card, upload the firmware with the following line commented out with:

// #define sdcardsupport

The (save-image) command will then use the flash memory to save the workspace.

Graphics

You can draw graphics with the full range of graphics extensions; for example:

(defun damped ()
  (cls)
  (dotimes (x 240)
    (let ((y (round (+ 80 (/ (* 40 (sin (/ x 3.1416))) (exp (/ x 36)))))))
      (draw-pixel x y 2016)))
  (loop))

which produces the graph of damped harmonic oscillation shown in the photograph at the start of this page. See Graphics extensions for details.

Disabling output to the Cardputer display

The terminal control codes 14 (Shift Out) and 15 (Shift In) allow you to turn off or on output to the Cardputer display. This is useful if you are displaying graphics on the display, and don't want it overwritten by the text output.

So to turn off output to the display:

(write-byte 14)

To turn it back on:

(write-byte 15)

Limitations

As discussed on the page ESP32-S2, ESP-S3, and ESP-C3 boards, there is an outstanding issue with the ESP32-S3 built-in USB support that makes it hang up if you try to enter a program of more than a few lines from the Serial Monitor on a Mac computer.

Resources

The Cardputer uLisp Machine firmware on GitHub: https://github.com/technoblogy/ulisp-cardputer

The M5Stack Cardputer documentation: Cardputer.

Acknowledgements

This firmware builds on the work done by @hasn0life in initially porting uLisp to the Cardputer.


  1. ^ M5Stack Cardputer Kit on M5Stack.
  2. ^ M5Stack Cardputer Kit on The Pi Hut.