Enable Micro-SD Card on PyGamer


In case someone else has a PyGamer that suffers from serial port overruns, the following patch against uLisp ARM Version 4.1 points load-image, save-image, and with-sd-card, to the PyGamer’s Micro-SD card interface when sdcardsupport is enabled.

--- ulisp4PyGamer.ino.41	2022-01-29 13:21:01.036120575 +0000
+++ ulisp4PyGamer.ino	2022-01-30 14:04:58.825125057 +0000
@@ -88,7 +88,11 @@
   #define DATAFLASH
   #define FLASHSIZE 2048000               /* 2 MBytes */
   #define CODESIZE 256                    /* Bytes */
+#if defined(ARDUINO_PYGAMER_M4) && defined(sdcardsupport)
+  #define SDCARD_SS_PIN 4
   #define SDCARD_SS_PIN 10
   #define STACKDIFF 400
   #define CPU_ATSAMD51

I use the above on my system with the following load library function, based on uLisp - SD card interface, to load Lisp programs from the SD card.

"(defun load (filename)"
"  (with-sd-card "
"   (s filename)"
"   (loop"
"    (let ((f (read s)))"
"      (print f)"
"      (if (not f) "
"	  (return)"
"	(eval f))))))"


Thanks for sharing this.

In case someone else has a PyGamer that suffers from serial port overruns

What do you mean by “serial port overruns”? Perhaps that can be fixed.


To be honest, I was quite happy to come up with a simple way to get around the following problem and I thought others might benefit.

With the following configuration:

// Lisp Library
const char LispLibrary[] PROGMEM = "";

// Compile options

// #define resetautorun
#define printfreespace
// #define printgcs
#define sdcardsupport
#define gfxsupport
// #define lisplibrary
#define assemblerlist
// #define lineeditor
// #define vt100

If I copy/paste the following lines into a terminal window:

(defvar maxx 160)

(defvar maxy 128)


    (x 100)
  (fill-circle (random maxx) (random maxy) (random 50) (random 65536)))

(defvar red #xf800)

(defvar blue #x1f)

I get the following output:

(defvar maxx 160)

20512> (defvar maxy 128)

20508> (fill-screen)

20508> (dotimes    (x 100)  (fill-circle (random maxx) (random maxy) (random 50) (random 65536)))


Nothing after the dotimes expression is evaluated - the output seems to silently discarded - neither red nor blue is defined.

A few more details in case they are relevant: my main system is running Debian 10 on x86_64 and the above example fails in the same way using minicom, putty and a plink connection inside emacs.

Perhaps this behaviour is a known limitation of the interpreter and I’ve missed where this is documented - if so, my apologies.


The Arduino cores don’t support handshaking on Serial, so it’s the responsibility of the receiver to process each byte before the next one arrives. In uLisp I’ve ensured that function and variable definitions are processed quickly enough to ensure there aren’t any problems, and I can copy a large Lisp source file, such as:


and paste it into the Serial Monitor in a single operation without errors.

However, in your example you’ve included some statements that take a significant time to execute; for example:


(dotimes (x 100)
  (fill-circle (random maxx) (random maxy) (random 50) (random 65536)))

This is why the following two statements get missed when you read them in via Serial.

The solution is to avoid doing any actual execution when reading in the source by packaging up the code you want to execute into a defun:

(defun go ()

  (dotimes (x 100)
    (fill-circle (random maxx) (random maxy) (random 50) (random 65536))))

Then call (go) as the last thing you read in.


Ah - that makes sense - thanks very much! Somehow I got it stuck in my head that the PyGamer has similar issues to the Adafruit CLUE, which I gather are of a different nature(?).