Close
0%
0%

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.

Public Chat
Similar projects worth following
Use a modern MCU to faithfully emulate the TMC1501 inside the TI-57. The emulation will be faithful by executing the original TI-57 ROM code. With nearly 50 years of advancements since the TI-57, we can do some upgrades as well; run faster, longer battery life, EEPROM-based program storage, and better power-save mode.

rcl57mcu

This project came about because I stumbled across a TI-57 calculator with a "bad brain". The TMC1501 calculator-on-a-chip was faulty. This, in turn, led me to read more about this particular calculator and how the CPU inside functions.

Fortunately, I am 'standing on the shoulders of giants' here - three people that have been of great help to me are Joerg Woerner, Jeff Parsons and Paul Novaes. All humored me by answering my emails and helping me understand how the hardware works.

Joerg's DATAMATH pages are found here, and in particular contain a great summary of the TMC1501 IC that is the calculator-on-a-chip used in the TI-57. 

http://www.datamath.org/Chips/TMC1500.htm

@Jeff Parsons TI-57 pages are found here, and extremely helpful is his collection of original Texas Instruments patents filed around the introduction of this calculator:

https://www.pcjs.org/machines/ti/ti57/patents/

Both Jeff and Paul have created TI-57 emulators. Paul's is an iOS app, and Jeff's is browser-based. Both emulate the TMC1501 CPU innards, which in turn execute the original TI-57 ROM code. So it is a faithful 'emulation' of the calculator. 

Paul @n3times was kind enough to put his iOS app code up on GitHub:

https://github.com/n3times/rcl57

The 'guts' of the TMC1500 emulation are all contained within the 'engine' folder, and written in very generic and portable C. I learned an awful lot from studying this code.

The Quest

I began to hatch a scheme - could I put a modern microcontroller (MCU) to the task of emulating the 1970's TMC1501? Could this hardware emulator be then installed into my defunct TI-57 to make it live again, perhaps even better than before?

Adobe Portable Document Format - 24.40 kB - 03/12/2024 at 19:49

Preview
Download

Adobe Portable Document Format - 85.88 kB - 03/12/2024 at 19:49

Preview
Download

rcl57_mcu_top_assy.pdf

Topside assembly drawing for rcl57mcu PCB

Adobe Portable Document Format - 34.05 kB - 03/12/2024 at 19:48

Preview
Download

rcl57_mcu_bot_assy.pdf

Bottomside assembly drawing for rcl57mcu PCB

Adobe Portable Document Format - 32.28 kB - 03/12/2024 at 19:48

Preview
Download

rcl57_mcu_schematic.pdf

Schematic of the ARM CM3 MCU based retrofit for TI-57

Adobe Portable Document Format - 184.54 kB - 02/28/2024 at 23:50

Preview
Download

  • DMA be Damned!

    tomcircuit3 天前 0 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!

  • Keyboard Woes

    tomcircuit04/16/2024 at 00:37 0 comments

    At this point the display is working quite nicely - segment drivers are driving, current sinks are sinking, LED’s are emitting. Joy. 

    Tests with the keyboard, however, have been less successful. That slowly delaying segment driver output, and what I can only assume is a leakage path across the FETs, results in a very ugly multi-voltage waveform. No issue for the LED displays - LED's are current, not voltage, controlled beasties, so they light up when the should and stay dark otherwise. But, this leakage path voltage is a big problem for the keyboard column inputs - when a key is pressed, it is typically registering in several rows. All because the row (segment) voltages are interacting with one another; they are not ‘crisp’ CMOS levels

    I spent several hours thinking about how to tame the segment voltages. An initially promising solution was adding N MOSFETs to make CMOS P-P segment drivers. Challenging from a PCB area standpoint because it would double the number of MOSFETs but ultimately not a solution for the D and DP segments, because they are shared with the current sinks for D1 and D12. Driving either of these “segments” low whilst another segment is high would illuminate that segment on D1 and D12, very brightly.  

    I thought about how the TI engineers must have solved this. I concluded that this melange of voltages is only a problem for reading keys. The beautiful display was confirmation of this. So, rather than trying to tame the segment voltages, I shifted my focus entirely towards reading the keyboard columns. A “simple fix” would be to make the VIH threshold much higher than the garbage on the un-driven segment outputs. Easy to do in a custom IC, but not possible with a standard MCU. Reading the column voltages with an ADC, however, is the next best thing.

    I experimented with the ADC but quickly discovered that the STM32F103 MCU doesn’t allow the GPIO internal pulldowns to be enabled when a pin is configured as an Analog Input. So I added some leaded resistor pulldowns on my test setup. Voila! My random selection of 1.8K and 5.1K pulldown resistors dissipated all the nasty voltages on 6 of the 8 segment lines when a keyswitch in those rows is closed - there's a nice, crisp 3.3V pulse for the 700us active segment interval.

    When the columns are switched to the shared lines (D+D12 and DP+D1) the voltages are still ugly - this is unavoidable because of the shared digit cathode and segment anode arrangement on those two digits. The "high" level (green box, peak around 3.3V) is the segment driver row being read through a key column. The "medium" level (blue box, peaks around 1.7V) are the segment drivers for the other rows being read via the shared segment-digit path into the key column input. For these two rows (segments D and DP, rows 7 & 8 on the keypad) even with the addition of column input pulldown resistors, I will have to use the ADC to manually threshold the signal to something above, say, 2.5V. (Note: I suppose that I could add a series diode to the segment D and DP outputs to reduce this residual voltage to something below the MCU VIH threshold, but that means even more parts on the PCB...) 

    Unfortunately, this means a new PCB, to add pulldowns on the K1-K5 inputs…  I can prototype with the pulldown resistors tacked to the bottom of the TI PCB but I'm not super-happy with that as a long-term solution.

  • When 700us isn't 700us...

    tomcircuit04/01/2024 at 17:42 0 comments

    I've assembled four of the rcl57 PCB.  Three actually function.  The fourth wouldn't connect via SWD to get flashed. Even after replacing and reworking the VQFN36 MCU I was not able to get it to work. So, I have three boards right now, one of which I have setup for test/debug.

    With the PCB populated, I can now see the effects of the few off-MCU hardware resources of the rcl57 circuit. One thing I really wanted to look into was the effect using the open-drain Pch MOSFET drivers for segment anode drivers. On the one hand, they can source a lot of current - more than 60mA or so maximum that will ever be needed. On the other hand, with just the PCB and no attached LED digits, I was able to observe that the PMOS segment driver outputs were high longer than the 700us low-going gate pulse. For example, in this screenshot, the segment output registers as "high" to my Saleae logic analyzer for about 1.1ms (top trace):

    Looking into the analog domain (lower trace), it's easy to guess what is happening: the segment output is slowly discharging into the input of the logic analyzer (high Z input). 

    When an LED is present between a segment output and a digit sink, the digital pulse width (top trace) is right in line with the gate pulse width - the voltage rapidly falls below 1.6V

    Looking at the analog voltage in this case (lower trace) it's clear what is going on - the LED discharges the drain output until the LED no longer conducts, at which point the residual charge simply leaks away. Therefore, when a segment is to be illuminated in at least one of the twelve digit positions, the segment voltage will discharge quickly through the LED(s). That's good news, and really means that nothing special needs to be done to discharge the segment outputs; the LEDs themselves will take care of this problem for us. 

    What about 'dark segment intervals' - segment intervals in which no LED in any of the digit positions is illuminated? Well, we're back to a slowly decaying >1ms pulse; there's no low impedance discharge path for segment drive output. This is a problem because the subsequent segment will get enabled after 800us and there will be about 300us of 'overlap' with two segments active at the same time:

    Why could this 'overlap' be a problem?  Well, if a dark segment interval is followed by a non-dark segment interval, the residual charge on the 'dark' segment output will dump through the digits that are subsequently enabled. That could end up looking like "sparkle" in the display. Sure, it would be a brief flash, but here's an interesting post on stackexchange that claims that around 150ns of "on" time could be visible.

    Ok, well, then why drive inactive segments at all? Why I am paying so much attention to the logic analyzer's "digital interpretation" of the decaying voltage on the segment driver outputs?  The answers to both of these questions are related, and all revolve around the fact that the segment driver outputs are also used for reading the keypad. If the segment isn't driven at all, then the corresponding row of the keyboard cannot be read. If the slowly decaying voltage were to take too long to decay, it could end up being "high enough" when subsequent segment keyboard reads take place - so keys from more than one row could potentially be read simultaneously, leading to strange behavior. The logic analyzer digital interpretation of the voltage indication an idea of what the STM32F103 GPIO pin would read.

    Ok, so for segment intervals in which there is no display activity, we need only to read the keyboard. So far, my plan to achieve this is the following:  as the display update function (hw_display_update) loops though the 8 segment intervals, if no digits are to be activated during this segment interval, the segment output is driven for only 100us, rather than 700us. At the end of the 100us, the keyboard row lines are read, and then the segment output is disabled...

    Read more »

  • Power Supply and Lid

    tomcircuit03/13/2024 at 15:02 0 comments

    Rcl57mcu wants a 3.5-5V supply. So, even if I could resurrect the dead BP-7 NiCd pack/lid, it won’t work for this upgrade. I will instead recycle the tried-and-true USB charged 3.7V LiPo supply that I’ve used for HP Classic, HP-28S, and TI-58/59 supply upgrades. I will 3D print a new case lid that holds the LiPo and a small PCB with the charging circuitry. So, another PCB is needed, but it certainly doesn’t merit a 4-layer board. I created a separate KiCad project with the PSU and a “debug breakout board” on a common 2-layer PCB. The latter is to make it easy to program/debug the rcl57mcu through its 2mm pitch header pins. These pair nicely onto a single board with perforations in between. Adding this 2-layer PCB to my 4-layer PCB order only cost an additional $5 and avoided  shipping charges had it been ordered separately. 

    I had it in mind that the TI-57 with rcl57mcu could be operated while charging. That’s why I put a diode between VBAT and the source terminal of the PMOS LED Anode drivers - with the MCU driving the gate at 3.3V, the source voltage should be able to be as much as 1.7V higher, or about 5V, and still keep the PMOS drivers in cutoff. The LiPo charge voltage is about 4.2V, so no problem here. Physically, however, I don’t see a nice way to attacg a USB plug, so I will just put the USB receptacle on the inside of the lid - meaning the lid has to be open to charge. I guess one could still operate the calculator with an open back and dangling wires… My experience is that these classic LED calculators running from LiPo cells don’t need to be charged very often at all. 

    Maybe I will look into a wireless charging solution at some point - the lid area seems large enough to easily pull this off…

  • Driving the Display

    tomcircuit03/02/2024 at 15:43 0 comments

    The TI-57 has a multiplexed 12-digit common cathode LED display. The corresponding 8 segments of all 12 digits are connected together; sort of. It turns out that TI economized on IC package pins by ”doubling up” the decimal point segment anode with the digit 1 cathode, and the “d” segment anode with the digit 12 cathode. This means it’s impossible to display a decimal point on the rightmost digit, and a “d” segment (the bottommost segment) on the leftmost digit. Each segment line is also connected to one row of keyboard switches. Each column of keyboard switches is common and connected to an MCU GPIO input. 

    Due to the “segment scanning” approach that TI chose to use, each segment driver must be able to source up to 12 digit’s worth of anode current - up to 60mA. This is too much for one MCU GPIO to supply, so I chose to use a P-channel MOSFET to drive each anode line; the MCU needs to drive the gate of the P-MOS low to source current to that anode line. At the same time, the cathode for the digit(s) that require that particular segment to be illuminated must be driven low to cause current to flow. Because any digit has at most one segment illuminated at a time, the “on” current per digit is 5mA. An MCU GPIO and series resistor could carry this current, but it’s easier to use a Constant Current LED driver to do this. I chose the Texas Instruments TLC5929 for this job. It’s essentially a shift register with 16 constant current sink outputs that are turned on or off via the serial control word. This device is particularly well-suited because it allows analog current adjustment via the serial word. It also features a Power Save mode that reduces the quiescent current to tens of uA when all outputs are off. These are both notable features of this device, and what drove me to choose it. The only downside of this device is that it requires a 17-bit serial control word, but the MCU SPI peripheral only supports 8 or 16 bit word lengths - so the serial interface must be “bit-banged”.

    During a display cycle, the MCU must process the display content segment by segment. The MCU must shift the correct digit enable outputs into the TLC5929 and enable the segment output by driving it low. Then pause for 800us to allow the LEDs to illuminate and be visible. At the end of this 800us period, the MCU samples the Keyboard Column inputs - if any keys in the keyboard row connected to that segment line are pressed, the corresponding keyboard column inputs will read as high. This 800us sequence is repeated for each of the segments - an entire display cycle lasts 6.4ms. The TI-57 ROM includes DISPlay instructions at the necessary intervals to generate a flicker-free display. The MCU can be put into a low power Sleep Mode for most of each segment’s 800us interval, keeping current drain to a minimum. Furthermore, the Power Save feature of the TLC5929 automatically reduces the current draw of that device anytime all of the digit output sinks are off. 

  • Blue Pill Emulation

    tomcircuit02/28/2024 at 23:44 0 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. 

  • I didn't choose the MCU ... it chose me!

    tomcircuit02/28/2024 at 22:51 0 comments

    I like the STM32 ARM cortex MCU family. They are well documented, readily available, and cheap 'breakout boards' for them abound. The MCU retrofit must fit nicely in the space of a 28-pin 0.6" pitch DIP, so package size is key.  The STM32F103 is an ARM Cortex M3 MCU that can run at up to 64MHz from its internal 8MHz oscillator. It's available in a 5x5mm QFN36 package. It's also the same part (well, from the same family) as the MCU on the ubiquitous "Blue Pill" boards. So, there's a cheap evaluation platform available.

    There are not so many other choices in small-yet-still-hobby-solderable-package MCU, so I really wanted to make the QFN36 device work. 

    Of course, with 36 pins, that makes GPIO a bit scarce. I need 8 segment anode driver enables, 12 digit cathode sink pins, and 5 keyboard sense lines. That's about 3 too many. Also, making space for the 12 digit cathode ballast resistors (to achieve 5mA segment current) was clearly going to be tough. LED digit drivers with serial interfaces abound, and nice ones provide constant current sink outputs, eliminating the dozen ballast resistors. Well, ok, the driver has one resistor to set the current for the outputs, but that's a great convenience! I found a number of 16-output LED driver chips that use a simple serial interface. I opted for speed over pincount, and favored the simple serial "shift register like" interface over I2C. That means that the 12 digit cathode sinks can be controlled by just 3 GPIO pins - a net savings of 9 GPIO.

    The other approach would be to use a 3-to-8 decoder, such as an 74HC138. This would allow the 8 segment lines to be controlled by only 3 GPIO. But, that doesn't eliminate the ballast resistors and only yields a net savings of 5 GPIO.

    The STM32F103TBU6 has 128KB of onchip FLASH, which turns out to be far more than required. It also has SPI and UART and timers and all sort of other goodies that I probably won't need. 

    So, we have a winner based upon package size, availability, and onchip goodies.

  • Flashback : Measurements

    tomcircuit02/28/2024 at 22:11 4 comments

    I carefully opened a TI-55 donor unit and inserted a 27ohm resistor in series with one of the digit cathodes. I captured the display sequence on my trusty LeCroy oscilloscope and dumped to the built-in thermal printer - TI-55 LED timing and Vfwd measurement

    There are several important observations that can be made from this plot:

    • The LED is scanned by segment rather than by digit. That is, all of the "a" segment anodes are sourced, but only the digit common cathodes in the digit positions that have this segment illuminated are sunk. This means that the TMC1500 has only to 'scan' 8 segments (a-g, dp) rather than the more intuitive approach of scanning 12 digits. This is covered in TI patent Number 4,014,012 so was not a surprise to me.
    • During a display cycle, each segment anode is energized for 800us, and the overall display cycle duration is 6.4ms. TI patent Number 4,125,901 describes how, during a display cycle, the CPU cycle interval is increased by a factor of 32, so that the LED display is visible.  This implies that the normal CPU cycle interval is 6.4ms / 32 = 200us.
    • The voltage across the 27 ohm series resistor I fitted to one digit's common cathode, when energized, is 130mV. Therefore, the segment current is 5mA.  If all 12 digits have the same segment active, the segment driver must source 5mA * 12 = 60mA.  This is a bit much for a single MCU GPIO output pin, so PNP BJT or P-MOS will be required for each segment line.  On the other hand, each digit has only one segment active at any one time, so the most current the digit drivers must sink is 5mA.

    Thank you, TI-55.  That didn't hurt a bit now, did it?

  • Flashback : Prework

    tomcircuit02/28/2024 at 22:07 0 comments

    The more I read about the TI-57, the more I wanted to fix mine.  Of course, these are easily found on a-large-well-known-online-auction-site for modest prices - typically $40 or less. Like most hobby projects, my goals were entirely devoid of practicality.  Vive les fous!

    The heart of the TI-57 is a calculator-on-a-chip executed in 4-phase PMOS. If you've not yet gone down this rabbithole, I strongly recommend a read through Ken Shirriff's excellent coverage of this subject.  So, this means multiple supply rails and oddball voltages (at least, oddball in this day and age) are required. The IC designers at TI built the substrate bias voltage generator into the TMC1500 family, vastly simplifying things by allowing operation from a single -9V rail.  Of course, we can call -9V "ground" and that makes the TI-57 ground "+9V". It's why when you power one of these calculators from a 9V battery, you need to connect the battery's POSITIVE terminal to the BLACK wire, and NEAGATIVE terminal to the RED wire. Um...thanks, TI.

    Much of how the TMC1500 works can be learned from studying the incredibly detailed and completely helpful US Patents that TI applied for prior to the production of the TI-57.  Jeff Parsons has collected the most important ones here, and it is well worth studying them - if not only as standout examples of well-written patents!  Because my goal was to replace the TMC1500 IC with a microcontroller and some discrete components, I had some questions about the "rest" of the calculator - mostly the 12-digit LED display. Digging around online in 1970's eta TI optoelectronic databooks was marginally helpful, but nothing beats an actual measurement of the LED in action to gather some critical items:

    • LED segment ON time
    • LED segment forward current 
    • LED segment voltage drop

    The TI-57 has a lot in common with a cheaper model, the TI-55. It's the same TMC1500 family process, with a different keyboard layout and ROM content.  These are even cheaper to obtain, so I picked a couple up for experimental purposes.

View all 9 project logs

Enjoy this project?

Share

Discussions

Bharbour wrote 03/13/2024 at 17:32 point

This looks good!

  Are you sure? yes | no

tomcircuit wrote 03/15/2024 at 11:59 point

thank you! The VQFN-36 on the small board is buffing up my reflow solder skills. Next time I do a board this small I will put perforated “wings” on it to make it easier to work with during assembly. I can’t imagine how difficult your DIY LED displays must have been to assemble!! 

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates