Blue Pill Emulation

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 02/28/2024 at 23:440 Comments

Another key part of ensuring that replacing the TI-57's TMC1500 "brain" is possible is to ensure that the MCU has enough throughput to emulate it. My initial assumption was that a 64MHz 32-bit ARM MCU should be more than up to the task of emulating a nearly 50-year-old PMOS chip. In this, I was supremely confident.

What's better than being supremely confident, you might ask? Actually knowing, that's what!

I had already started down the path of understanding Paul Novaes' excellent "RCL-57" emulation code - firstly by reducing it down to the "engine" (emulation core) and porting that to run under windows using Pelles C.  That yielded a tremendous amount of education, aided by a multitude of printf() statements! Next step was to take the basic emulation core and migrate it to Keil ARM MDK and target the STM32F103 MCU on a Blue Pill board. After a bit of text editor jackhammering, the code compiled into a tidy 7KB (including the TI-57 ROM image). I was hesitant to make any changes to ti57.c, state57.c, etc. but in the end I had to do this, anyhow, to make the ARM C compiler happy. This was a bit unexpected, because my experiments on a windows C compiler didn't require any changes. Par for the course with embedded software...

The result was a 32-bit ARM M3 microcontroller at 64MHz executing ti57_next() in an infinite loop, with one pin toggling state after each instruction (the white trace in the figure below) and another pin indicating with a brief pulse when a DISPlay instruction occurs (the orange trace).

On this target at 64MHz sysclk, each TMC1500 instruction takes around 5us - some more, some less. Recall that the TI-57 instruction rate is 5KHz, or 200us. So this particular MCU running at full speed is about 40x the throughput of the original. This can be put to use in one of two ways: 1. MCU clock reduction to save battery life, or 2. massive speedup versus the original.

After more discussion with Paul, he suggested that 4x speedup vs original results in a pretty comfortable experience - so 50us per executed TMC1500 instruction. Playing with the MCU clock rate PLL multiplier and the systick timer, I determined that 24 MHz sysclk works pretty nicely - that's a 3X PLL multiplier (minimum is 2x). Most TMC1500 instructions take about 14us in this case. It's easy to put the MCU into sleep mode after each instruction executes, and then use the systick timer as wakeup. The end result is that one instruction gets executed every 50us, and average MCU current should end up right around 4mA.  Running the MCU at 64MHz sysclk and 50us systick increases the average current to 6.5mA, and of course still the same apparent 4x speedup (that's determined by systick interval).  I might consider an option at poweron (maybe hold-down a specific key during poweron) to run the sysclk at the maximum of 64MHz and run without waiting on systick - 'wide open throttle mode' - if that's somehow useful or interesting.  We'll see...

To keep the overall "UI timing" of the TI-57, I chose to retain the 6.4ms display cycle timing. This preserves the flashing display rate (after an error, for example) and the PAUSE interval. So when the MCU is running actual TI-57 "calculations" it is running 4x the original, but when it is running DISPlay instructions (and keyboard scanning) it is running at the same timing as the original.