VGA Investigation Continues with Teensy

After deciding the Arduino VGAX library was not going to serve my needs, I started researching other ways to generate a VGA signal. What became clear pretty quickly was that a standard Arduino isn’t fast enough to meet timing requirements without additional hardware support. So solutions that work entirely in software will be roughly as limited as VGAX, and those that work for higher resolutions require auxiliary hardware.

Given that fact, I started looking at VGA signal generation by a faster line of microcontrollers: the Teensy line. I have on hand a Teensy LC and a Teensy 4, and I found this thread on Teensy forums announcing a library for generating VGA signal strictly in software, no auxiliary hardware. Browsing through the Github repository of this uVGA library, it looked quite promising. However, the primary target platform is the Teensy 3. I bracket it above and below with a Teensy 4 and a Teensy LC. Would one of them be able to run this code?

An attempt to compile an uVGA example for the Teensy LC failed:

In file included from /home/roger/Arduino/libraries/uVGA/examples/HelloWorldColour/HelloWorldColour.ino:3:0:
/home/roger/Arduino/libraries/uVGA/uVGA.h:297:16: error: 'TCD_t' in 'class DMABaseClass' does not name a type
DMABaseClass::TCD_t *edma_TCD; // address of eDMA TCD registers

My best guess is that the Teensy LC lacks the direct memory access (DMA) capability uVGA requires. I’ve already been foiled once on the reduced hardware capability on a Teensy LC, so this was no surprise. DMA is critical for shuttling memory back and forth without bogging down the CPU for timing-critical tasks (like VGA signal generation) so this requirement is unlikely to be lifted.

However, since my goal is only to generate a signal outputting a single color to the entire screen, I don’t really need to shuttle data from a video frame buffer for display. If I’m willing to dig into the uVGA code, I can probably find a way to bypass the commands moving memory and accomplish my very specific goal.

Before I start doing work, though, I should see what happens when I try compiling the same uVGA example for the Teensy 4:

In file included from /home/roger/Arduino/libraries/uVGA/examples/HelloWorldColour/HelloWorldColour.ino:8:0:
/home/roger/Arduino/libraries/uVGA/uVGA_valid_settings.h:59:17: note: #pragma message: No resolution defined for this CPU frequency. Known CPU frequency: 240Mhz, 192MHz, 180Mhz, 168Mhz, 144Mhz, 96Mhz, 72Mhz, 48Mhz

It looks like the uVGA library has some hard-coded dependencies on a Teensy CPU’s frequency, and it doesn’t know what to do with the high speed of a Teensy 4. I expect that speed will open up new capabilities, but someone has to teach uVGA about a Teensy 4 before that could happen. If I’m willing to dig into uVGA code, this would be a more productive and forward-looking way to go and a positive contribution to the open source community.

But before I can realistically contemplate that project, I’ll need to become a lot more knowledgeable about VGA timing requirements.

First Experiment in Teensy Audio Foiled By CPU Instruction Set

The original line of Arduino boards are know for a lot of very flexible features that made them the champion of entry into physical computing. “Large storage space” is not one of those features, as the ATmega328P has only 32KB of flash. Plenty for blinking little LEDs and a great many other projects, severely limiting for anything that requires nontrivial amount of data.

One such class of projects is playing back digital audio samples. Simple sounds like tones, beeps, and bloops take little data, but recorded digital audio consumes a great many bytes. I was introduced to the Mozzi Arduino sound synthesis library via exposure to Emily’s projects. While the emphasis is on synthesis, it does have provision to handle sampled audio. However, due to the small flash storage, even with compression it could only handle short sounds.

Looking around for an upgrade, I remembered I have a Teensy LC OSH Park edition I had purchased alongside an OSH Park order years ago and thought it was worth an audio playback experiment. The CPU is much faster and it has almost double the flash storage. Exploring the Arduino-compatibility layer called Teensyduino, I see it offers a full analog audio API, complete with a graphical tool to help compose the tree of audio input/processing/output nodes. I was very impressed!

I decided to start small with just two nodes: sound is to be generated by playing from sampled audio data in memory, and sent to built-in DAC. Pressing “Export” generated the following boilerplate code:

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioPlayMemory playMem1; //xy=262,658
AudioOutputAnalog dac1; //xy=436,657
AudioConnection patchCord1(playMem1, dac1);
// GUItool: end automatically generated code

void setup() {
// put your setup code here, to run once:

}

void loop() {
// put your main code here, to run repeatedly:

}

Sadly, this code did not compile. Instead, I encountered this error:

/tmp/ccLBGUGU.s: Assembler messages:
/tmp/ccLBGUGU.s:291: Error: selected processor does not support `smull r0,ip,r3,r5' in Thumb mode
/tmp/ccLBGUGU.s:292: Error: shifts in CMP/MOV instructions are only supported in unified syntax -- `mov ip,ip,asl r6'
/tmp/ccLBGUGU.s:293: Error: unshifted register required -- `orr r0,ip,r0,lsr r7'

A web search on this error message indicated this is because the chip on Teensy LC does not support the instructions described in the error message, I’d need a Teensy 3 or 4. To test this hypothesis, I changed the compiler to target Teensy 3 instead of LC and hit “Verify” again. This time, it was successful. But I don’t have a Teensy 3 on hand, so I can’t actually run that code.

Given this limitation I’ll have to find some other project for my Teensy LC. In the meantime, I’ll drop back to the tried and true Arduino for my Mozzi exercise.