Sunday, November 4, 2018

New project: Tiny Calculator

My Pocket Calculator project has been on the back burner for a few months while I finish my master's thesis. In the mean time, I got interested in doing a much simpler project to make a very small calculator that will hopefully be about 2.5 inches long. This is the size of a 5x5 keypad and the small 128x32 LCD I want to use. Like my first first calculator, it will use a through hole MSP430. The first calculator needed two MSP430s to contain all the firmware, but I think I can fit everything on one chip for this project. It should also be possible to do what I want with the 512 bytes of internal RAM the chip has, so I won't need any external SRAM, and with 25 keys, I also won't need external shift registers. Other than the microcontroller and some capacitors, the only other thing on the board will be a CR2032 battery. The MSP430 needs 2.7v to run at 16MHz, so I plan to run at 8MHz in order to use the battery down to 2.4v. It might be possible to monitor the battery and run at 16MHz as long as the voltage is high enough, but I don't think I will need the extra speed like I did on the last calculator.

One of the main things that got me interested in this project was finding out that the MSP430 has a decimal add instruction that works on packed BCD words. This is really convenient and should be many times faster than doing BCD manually in C like I did for my first calculator. One possibility would be mixing C and assembly to take advantage of features like this, but I am going to try to do the whole thing in assembly to make it as small and fast as possible. Another speed up should come from switching to a 16 byte floating point format. This will let me calculate logarithms and trig functions to the same precision as my first calculator but fit everything in the 512 bytes of internal RAM. Eliminating the bottleneck of transferring data over SPI one bit at a time will probably be the main speed up. For multiplication, I want to try some of the algorithms I tested for the 6502, and for division, I will try out some based on Netwon's Method. For logarithms and trig functions, I'll probably use CORDIC routines again, but I want to see if Taylor polynomials will be much smaller, even if they are slower. With 25 keys, I can fit in just about everything from my first calculator. It should be able to do a little more than an HP-35. The main drawback compared to my first calculator will be less precision with large numbers and less stack space, although neither should be a problem, since there won't be a programmable mode. Also, I plan to keep track of exponents by the byte, rather than the nibble like a did on the first calculator. This will mean losing precision by a factor of 10 in some cases, but it will make aligning numbers during calculation much simpler.

For programming, I have switched from GCC to IAR Workbench. It has an IDE and simulator that lets me test my code without having to load it on a real chip, Unfortunately, the IDE itself is pretty atrocious. I'm mystified that they are charging money for the full version of this thing. It crashes frequently on my computer, which seems to be a common problem from what I have read on forums. The IDE tries to load the last project when it starts and if the project is corrupt, the IDE crashes again. The only solution is to delete your projects settings folder and good luck if you had anything important in there like the layout of the IDE windows. The interface itself is buggy as well. The registers window should help you debug your program, but the status register, for one, does not always update. I wasted a lot of time trying to figure out what was wrong with my code that prevented it from setting the carry bit as I expected before I realized that the IDE is just bugged. Clicking on the status register with the simulator paused can cause it to show a different (correct?) value.

So far, I have worked on BCD addition routines. Trying out alternate ways of doing the calculation and comparing the cycle counts is pretty fun. MSP430 assembly is really different from 6502 assembly, and it is nice to have so many registers to work with. One thing that takes some getting used to is not having index registers like the 6502 has. You have to add registers together manually instead. There is also no native INC or DEC instruction, so modifying a counter variable in a loop affects the carry bit. One alternative I have found is to use an auto-increment mode and copy a value into a free register like this: MOV @R4+,R15. This is necessary since only source arguments, not destination arguments, can auto-increment. The architecture has some really neat stuff that I've noticed working with it myself, rather than relying on a C compiler. The character generator, for example, saves a lot of space. The only really annoying thing is that word reads have to be word-aligned, so I can't add BCD words on odd addresses, which would be convenient when the exponent difference requires.

The main challenge of this project will probably be keeping the source code small enough to fit in the 16KB of flash the chip has. The code in C for the first calculator filled up the flash of one chip pretty fast and I had to move to two. One challenge will be including font data, since I am using a graphic LCD rather than a character LCD which would have font data built in. To keep track of how much space is left, I put everything in a spreadsheet. My plan is to write several versions of the routines to compare their size and speed. Below you can see the size and speed of some test numbers I chose. Some routines handle the adding differently depending on whether the difference in exponents is odd or even, so I took the average of the two. Already, I can see that some variants of my addition routine are slower and bigger than others, so I can eliminate them right away. Hopefully, this system will let me fit everything in and use faster routines if there is any extra space left.


No comments:

Post a Comment