As part of my testing of the latest version of uLisp on the RP2040-based boards I wrote an assembler routine to control the NeoPixel LED provided on the Adafruit Feather RP2040 and Adafruit QT-Py RP2040 boards. In case anyone’s interested, here’s what I did.
First install the ARM assembler by copying the source from ARM assembler in Lisp and pasting it into the Serial Monitor.
Define a variable led to specify the NeoPixel pin; on the Adafruit Feather this is:
(defvar led 16)
On the Adafruit QT-Py this is:
(defvar led 12)
Make this pin an output with:
(pinmode led :output)
On the Adafruit QT-Py the NeoPixel is powered by pin 11, so you need to make this an output too, and make it high, with:
(pinmode 11 :output)
(digitalwrite 11 :high)
The machine-code routine uses a macro pulse4 to generate the instructions for the correct pulse delays:
(defun pulse4 (n)
(list
($str 'r3 '(r4))
($mov 'r5 n)
($sub 'r5 1)
($bne (- *pc* 2))))
Finally, here’s the assembler code for the NeoPixel driver routine:
(defcode neopixel (a)
($push '(lr r5 r4))
($ldr 'r4 port-xor)
($mov 'r1 1)
($lsl 'r3 'r1 led)
($lsl 'r1 23)
nextbit
($tst 'r0 'r1) ; test if bit is 1
($bne one)
zero
(pulse4 12)
(pulse4 26)
($b next)
one
(pulse4 25)
(pulse4 14)
next
($lsr 'r1 1)
($bne nextbit)
($pop '(r4 r5 pc))
port-xor
($word #xd000001c))
After defining the assembler routine you should be able to light up the NeoPixel in any colour with the command:
(neopixel #xggrrbb)
where #xggrrbb is a hexadecimal number specifying the green, red, and blue intensities. So, for example, the following call makes it orange:
(neopixel #x070f00)
For more details about controlling NeoPixels see: ARM NeoPixel driver using assembler.