Teletype Oscilloscope (Telescope - build released)

Made this to help visualize interrupt activity on teletype.

Just a fun experiment.


Just another test. Output is audio rate sampled from Shapeshifter, sweeping a simple table.


One more and I’m done for the night.



this module has infinite potential


What sample rate were you able to coax out of the module?

I have to admit it would be a very useful addition under a hot key and with a bit of UI for ranges, triggers, etc. So long as it’s not too detrimental to the rest of the firmware.


I haven’t been following the development of teletype too closely but I keep seeing more and more graphics for it, especially all of @scanner_darkly’s grid applications. Will the next update include limited graphic capabilities? An oscilloscope feature, and the ability to make/use other people’s grid applications would be so cool!

Well, I requested 1000 Hz out of both the display refresh and the ADC sample (shorthand for as fast as possible), but I don’t know what I’m actually getting yet.

The lack of a real scope on my desk makes it hard to know. I’m going to look into the clock cycle counter and see what I can find.

wouah ! this is really nice ! so cute :slight_smile:

1 Like

Well, according to the CPU clock cycle count, this scope is actually running at 1000 Hz.


A windowed average reveals that some interrupts are being dropped on the screen refresh (avg 925 Hz), but that’s with both the adc poll and the screen refresh at 1ms.

Edit 2:

Probably going to put this on the shelf for now. I have developed some understanding into the limitations of the current timer setup and will keep this code around until I implement a better scheduler.


FYI, ~1000 Hz is only possible with a custom screen region array that only draws 2 columns each sample. (Edit: Actually, redrawing the whole screen on every single sample is the limiting factor. HSYNC build below hits 1000 Hz on a flat screen region)

Writing the whole screen throttles the operation to ~141 Hz.

1 Like

Here’s a build that operates at 1000 Hz sample rate dead-on (as far as I can tell). It’s configured more as an art generator than an oscilloscope as there is no sync and the fade doesn’t cost any computation. (121.2 KB)

Don’t expect it to work as a teletype… it won’t. Just plug your signal in to IN and play!


Edit: Here’s a version with horizontal sync so that the whole frame changes at once instead of sweeping live. It might reach 1000 sampes/sec, but drawing the value on screen eats a little performance, so I can’t tell. With the display on it reaches 980 or so. (121.1 KB)


Cool stuff!
Scope might take too much out of the CPI, but I wonder if there is a place for ‘sone’ kind of visualization of Teletype activity. Like an overview of what is being done by the midule at any given time. A map or signal flows,…

Actually, what I have learned is that the Teletype is not time-taxed, for the most part. I was able to maintain a 925 Hz scope with this script running:

L 1 1000: A I
M 25

I don’t know how substantial this is, but I’m going to start sewing profiling code into teletype so that I can develop a better understanding of CPU utilization.

… so that I can start pushing functionality to the limit :metal:


if you want to make a dedicated scope firmware, here’s a couple thoughts (just because i did test some stuff like this when putting together the screen driver, timers, and event queue in the first place)

  • firstly, maybe you are already doing this, but i’d rip out everything except a single TC interrupt. no event queue, no software timers. do everything in one ISR: blit screen, read ADC, update graphics memory.

  • i don’t remember if ADC and OLED are on separate SPI ports on TT; if they are i guess you could save some time by setting up asynchronous access. but it doesn’t seem worth the trouble since lion’s share of time will be waiting for the TX transaction to finish; the RX is really fast.

  • so, the actual SPI output is the bottleneck for refresh rate. bit clock is 40MHz and the whole screen is 4096 bytes, so thats 1220Hz i think? factor in the little delay between transactions and maybe that’s your 925Hz.

  • but! the OLED is set up with some smart tricks that we don’t use. i will probably never be able to stomach looking at this protocol again but here it is:

IIRC you should be able set up the screen pointer increment modes to do various kinds of scrolling, so you only blit one column or pixel at a time…


Amazing link. I think I’m up for rolling a new codebase for a dedicated oscilloscope mode. I’m getting in tune with the avr32 architecture (finally sat down and read the damned headers), so I’ve got a new toolbox. Combine that with the prospect of implementing a protocol, and it may be too tempting.

I was running 2 event queue timers for ease of integrating into TT firmware, but yeah there’s no reason this wouldn’t be a single ISR. Mmmmmm… hardware timers.

Table 19: Graphic acceleration command


Oh no, now I’m thinking of making a graphics scripting language.

Just to be a jerk, I’m going to use reverse polish notation, mwhahahahah!


Nope, they’re not.

I managed to make firmware that could run at up to 48000 Hz, although with sampling artifacts as a result of time contention for the SPI port. It required implementing a display driver that could poke individual cells. It reduced a 2-column update from 64 bytes to 0 - 19 bytes (as an oscilloscope column only has 1 pixel lit).

Interestingly, the variability of the data length required to update the display caused problems past the bandwidth limit. If you ever sync’d up the waveform to the display, it would quickly jump around as more samples were processed when there were no updates to the display.

I tried asynchronous access, but the SPI bandwidth was the limiting factor. Edit: Oooooh, you meant async read from the ADC. I think that’s beyond my reach at this point. I’m still fumbling around AVR32 IRQ levels and stuff.

I also tried using COPY to update two columns at a time, but it meant that the display divisor needed to be variable, and I didn’t have the numbers at hand to understand where my limits were. (Why are AVR32 docs sooooo baaaaaad?!?!?)

Learned a bunch in the process, but mostly that I can’t reduce the display code below 19 bytes per 2 col (1216 bytes per frame). Sooo… that means that the max sample rate is like 4000Hz.

Question: Why are 4 ADC channels polled on teletype? Aren’t there only 2 in use? (13.1 KB)

  • 4000 Hz sample rate
  • -32x to 32x zoom (not really, there’s a bug)
  • Knob at 12 o’clock is 1x zoom

Github repo here:

1 Like

because all the modules use the same ADC part (AD7923) and driver (from aleph codebase.) you’re right, there should be a flag per module saying which channels are actually needed