Adafruit PyPortal
The Adafruit PyPortal board provides a fast colour display with a resistive touchscreen, a micro SD card socket, and a separate ESP32 coprocessor to provide support for Wi-Fi. It is based on an ATSAMD51 running at 120 MHz:

The Adafruit PyPortal incorporates a 3.2" 320x240 colour TFT display with a fast 8-bit parallel interface, and a resistive touch screen. It supports the uLisp graphics extensions to allow you to plot points, lines, shapes, and text to the display, including reading pixels from the display.
The lower-cost Adafruit PyPortal Pynt is identical, apart from having a 2.4" display and no temperature sensor, and should be fully compatible with its larger sibling.
Graphics extensions
For reference information about the graphics extensions see: Graphics extensions.
For some demo graphics programs see Graphics examples.
Installing uLisp from the Arduino IDE
Install the Adafruit SAMD core
- Add the following URL to the Additional Boards Manager URLs list in the Arduino IDE Preferences dialog box:
https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
- In the Arduino IDE search for the Adafruit SAMD Boards core in Boards Manager and install it.
I tested this with core version 1.7.16.
- You also need to install the following libraries from Library Manager: Adafruit GFX Library, Adafruit ILI9341, Adafruit TouchScreen, Adafruit BusIO, and WiFiNINA.
- Select Adafruit SAMD (...) Boards from the Board menu, and Adafruit PyPortal M4 (SAMD51) from the submenu.
You can leave all the other options at their defaults.
Upload uLisp
- Download Release 4.9 or later of the ARM version of uLisp from the Download uLisp page.
- Enable the uLisp graphics support by uncommenting the line:
#define gfxsupport
- If you want to use micro SD cards uncomment the line:
#define sdcardsupport
- Select the board's USB port from the Port menu
- Upload uLisp to the board.
Using uLisp
- You may need to select the board's USB port from the Port menu again.
- Select Serial Monitor from the Tools menu.
- Enter Lisp commands.
Putting the board into upload mode
If the upload fails you may need to put the board into upload mode first.
- Double-click the RESET button on the reverse of the board.
The STATUS light next to it should go green.
Features
LED
The PyPortal has a red LED on the back of the board which you can flash with the following program:
(defun blink (&optional x) (pinmode :led-builtin t) (digitalwrite :led-builtin x)
(delay 1000) (blink (not x)))
Run it by typing:
(blink)
Exit by entering ~.
There is also a NeoPixel on pin 2.
Digital inputs/outputs
Digital pins 4 (D4) and 5 (D5) are available together with VCC (5V) and GND on two three-pin JST connectors.
Analogue inputs
The PyPortal has 10 analogue inputs on pins 14 (A0) to 23 (A9).
Serial
The PyPortal has a serial port on pin numbers 1 (TX) and 0 (RX).
SPI
The PyPortal has one accessible SPI port on pin numbers 31 (MISO), 29 (MOSI), and 30 (SCK).
I2C
The PyPortal has one I2C port on pin numbers 22 (SDA) and 23 (SCL). It is accessible on the I2C Stemma connector.
Sound
The PyPortal include an audio amplifier connected to analogue output DAC0, which corresponds to Arduino pin 12.
The following function sound makes a simple frequency sweep effect:
(defun sound () (dotimes (y 96) (dotimes (x y) (analogwrite 14 (* 16 x)))))
You can disable the amplifier with:
(pinmode 50 :output)
(digitalwrite 50 0)
You can connect an 8 to 16Ω speaker to the 2-pin JST SPEAKER connector.
Light sensor
There's a light sensor above the Adafruit logo on the front panel which you can read with the following routine:
(defun light-sensor () (analogread 16))
It returns an integer between 0 (dark) and 1023 (bright).
Display backlight
You can change the display backlight with the following routine:
(defun backlight (n) (analogwrite 25 n))
It takes a number between 0 (off) and 255 (full). By default uLisp sets it to 128.
Temperature sensor
The PyPortal includes an ADT7410 temperature sensor on I2C address #x48.
(defun adt7410-temp ()
(with-i2c (str #x48)
(write-byte 0 str)
(restart-i2c str 2)
(let* ((hi (read-byte str))
(lo (read-byte str))
(tmp (logior (ash hi 5) (ash lo -3))))
(/ (- (logand tmp #x0FFF) (logand tmp #x1000)) 16))))
It returns the temperature in degrees Celsius; for example:
> (adt7410-temp) 21.625
SD Card
The Cardputer has an SD card socket that can be used to read from and write to SD cards from uLisp. If the SD card interface is enabled the (save-image) command saves the workspace to the SD card.
To return a list of the files on an SD card give the command directory:
> (directory)
("ULISP.IMG" "Cards.gif" "JapanCat.gif")
For details of using SD cards see SD card interface.
If you don't want to use SD cards, upload the firmware with the following line commented out:
// #define sdcardsupport
The (save-image) command will then use the flash memory to save the workspace.
Graphics
The PyPortal is supported by the full range of uLisp graphics extensions, including read-pixel; see Graphics extensions.

The above photograph shows a GIF image loaded from SD card using the GIF decode/encode extension.
Touchscreen
The PyPortal includes a resistive touchscreen that you can read with the touchscreen function. It returns with a list of the x and y coordinates of the touch, or nil if no touch is being registered. For example:
> (touchscreen)
(167 118)
For a simple application of the touchscreen see the Touchdraw graphics example:

Wi-Fi
The Adafruit PyPortal uses the Arduino WiFiNINA library to communicate with the ESP32 coprocessor, and the board will run all of the uLisp Wi-Fi examples; see Wi-Fi examples.
ARM assembler
uLisp includes an ARM assembler that allows you to generate machine-code functions, integrated with Lisp, written in ARM code. The assembler itself is written in Lisp to make it easy to extend it or add new instructions.
For an overview of the ARM assembler and details of how to install it see: ARM assembler overview 2.
For a summary of the instructions in the ARM assembler see: ARM assembler instructions.
For example programs see: ARM assembler examples.
