DMA be Damned!

A project log for TI-57 Programmable Calculator Hardware Retrofit

A modern MCU-based hardware replacement for the venerable TMC1501 used in the Texas Instruments TI-57 LED calculator.

tomcircuittomcircuit 04/24/2024 at 02:170 Comments

With moderately “stiff” resistor pulldowns on the five K1-K5 keyboard column inputs, it’s possible to read them using the STM32F103’s ADC. Of course, that’s not as easy as one might think. 

The STM32 family has a very nice 12bit ADC subsystem, providing lots of input channels, ability to autonomously scan across them, in an arbitrary order, all in the background while the CPU chugs away. My initial thought was to configure the ADC to convert analog channels 0 through 4, which correspond to pins PA0-PA4, which in turn are connected to the K1-K5 keypad columns. In theory this can be done so that a software trigger starts the sequence, and either polling or interrupt at end of conversion. 

Unfortunately, there is only a single ADC result register. So, after each channel is converted the results must be moved from the DR register to elsewhere in memory. The preferred way to do this, according to ST, is to use the DMA controller to do this, to be sure there is no possibility of data overrun and losing a conversion result. 

I couldn’t get it to work. Even with a lot of experimenting. Most examples were using HAL library, whereas I am using Standard Peripheral Library. I just couldn’t get DMA based ADC to work  

The ADC has a neat feature to allow up to four conversions to be “injected” into the queue. These injected conversions take priority over the ‘normal’ channel sequence, and more importantly each injected conversion has its own, dedicated, result register. So, I can convert one “regular” channel and then request four “injected” conversions. After all conversions are complete, I can unload the results from the one regular result register and the four injected result registers. 

It works like a charm, and no DMA required. I might revisit DMA at some point, but this is a perfectly workable solution. If anyone has an SPL example of DMA based single scanned ADC conversion, please share with me!