Sunday, December 28, 2014

Microcontroller Showdown, Revisited

Back in March I finished the microcontroller comparison of a few chips I was considering using. The 8051 based chips all fared poorly in BCD calculations, which is the main thing they would be used for in another calculator project. Some other 8051 fans pointed out that tests like mine test the compiler more than the chip and the SDCC compiler does a lot less optimizing than GCC. So, I decided to recode the BCD Add routine from the test in assembly. At the beginning I didn't consider this because I thought I would only ever write C for the 8051, but after writing assembly for the 6502, I was excited to try it for the 8051 too.

For this test I used the MCU 8051 IDE simulator. It is really impressive! Being able to see all the RAM and registers helped a lot. It is similar in some ways to what I hoped to accomplish with my 6502 Virtual Trainer. When I translated the original BCD Add function from C, I left out the parts used for subtraction, since they weren't used in the test. Also, some of the values that don't change inside loops are calculated once before the loop and stored for use later. This makes sense because a good C compiler would do this for you. All values are stored in the internal DATA, although this would be far too small for real calculations. The simulator can also work with SDCC, so I was able to simulate the function in C after commenting out the parts for subtraction.

The assembly took a simulated 440us to execute. The C version took between 1365 and 1732us depending on memory model and whether the BCD data was stored in DATA or XDATA. Curiously, storing it in XDATA was always faster. The medium memory model was faster than the large memory model. It seems then that hand-coding the routine in assembly is 3-4 times faster. To be fair, the routines for other architectures might also show a speed up if they were rewritten. Compared to the original numbers of the test, a 3x speedup would make the DS89C450 faster than the MSP430 for this routine. The difference might actually be a little bigger since this test used an upgraded version of SDCC that might optimize better. With that in mind, an 8051-based calculator with external bus (coded in assembly) would outperform an MSP430 with SPI SRAM. That is a bit of a surprise after the results of the first test.

The LPC1114 could also be sped up a little. In the original test the chip was configured to run at 50MHz. Because the flash runs at a maximum 20MHz, 3 wait states are required when executing from flash. However, 3 wait states is a little wasteful since 2.5 would be enough. Running the chip at 40MHz would only require 2 wait states, and would let the flash run at full speed. I'm not sure this would give a whole 16% speedup but I imagine it would offer a little bit of a boost.

Thursday, November 27, 2014

Progress report (sort of)

So I have not updated my blog in a while. Grad school is keeping me pretty busy. Most of what I do with electronics now is related to the local hackspace I joined. I was able to use some tools there to shorten the bolts for the case of my RPN Scientific Calculator and I also have access to a laser cutter and 3D printer that I eventually want to use to make keys for it. One of the members there and I decided to start on a project together. We have not made enough progress yet to post about but we did finish a schematic of what we plan to do. For this we have both EPROMs and EEPROMs. The EPROMs have a small window and can be erased with UV light, though the lamp we have does not seem to be working. They would also need a higher voltage source to write them and I want to make a voltage multiplier when time allows. If I can get that working, it might also help me with another project that needs -27 volts for LCD contrast.

Another neat thing I have experimented with at the hackerspace is the Spark Core. One of our members was able to get a hold of several of these for us. These tiny little boards let you connect a microcontroller to Wi-Fi pretty painlessly. This would work really well for a project idea I have that I have not started on yet. One thing I don't like is the Arduino-like environment used to program them with but I think I could get used to it since I would probably use my own microcontroller for everything but Wi-Fi. Another idea would be to simply use the CC3000 chip the board uses without the Spark Core board, though that may be too complicated to be worth it. It seems that the newer Spark Photon uses a different chip which could be easier to use by itself, though Spark Photons are not scheduled to ship until March.

One thing I have been working on on my own is a sombrero with LEDs. It was supposed to be part of a Halloween costume, but I did not finish it in time. Each color (red, green, and blue) is soldered as a 4x4 matrix that has its own shift register. It might have been possible to solder all 48 LEDS (16 each of red, green, and blue) as a 6x8 matrix and use one less shift register, but this way lets me keep each LED on three times longer. NeoPixels would have worked well for this project but just one of them costs almost as much as all of the LEDs. The board for controlling everything is finished. Now all the LEDs just need to be sewed to the sombrero and the firmware written to control their flashing. In order to save time I only soldered buttons to the board for controlling the patterns of the LEDs, but I do have some nice potentiometers I bought that I now have time to use instead. Reading their value with an MSP430 worked great on the first try and I displayed it on my one wire debug display.

Tuesday, September 30, 2014

One wire debug display

Lately I haven't had much time to work on hobby projects but I did manage to do a few things. Sometimes for debugging I use an LED if the UART pins are not free to output to a serial terminal. This works alright for simple things but gets complicated when I start outputting different patterns of flashes. Instead I decided to wire a small screen to a microcontroller so that I can bitbang out debug information with just one pin.

At the beginning, I considered using a WM-1611-62C LCD from Russian telephones that I have had for the last two years. It runs on 1.5v, so I haven't been in a hurry to do anything with it. The documentation for it shows Vdd supplied by 5v through a 4.7k resistor with two standard diodes between Vdd and Vss. Running from the 3.6v of the launchpad, the voltage between Vdd and Vss was well under 1.5v and the display was very dim. Adding another diode brought the voltage up and resulted in the clear display you see on the right. Poking at the pins revealed what some of them do and I was able to bitbang some characters to the screen. This was possible even at 3.6v through diodes since the inputs are open drain. Unfortunately, other than 0-9, only a few other specialized characters are possible. Displaying anything in hexidecimal would not be possible, so I scratched the idea of using it.

The next idea I had was to use a cell phone screen. In Kyrgyzstan I found some 1202 cell phone screens for about $2 and I tried soldering 0.10mm wires to one of them. At 700°F the iron was way too hot and even at 550°F I managed to destroy the tiny ribbon cable of the LCD. The next LCD I tried was from a Nokia 3510i but I managed to lift the pads off of that LCD. It seems that the temperature displayed by the soldering iron might be wrong. Even at 350°F the iron melts solder very quickly.

Another idea I had was to use some small green 7 segment displays I have lying around. With one MSP430 I could multiplex all four of them. Even at the 6mA that a single pin can supply, these displays were very dim. Maybe it has something to do with running green LEDs at 3.6v. Next I tried a red 7 segment display from an answering machine that was very bright even at 1mA, so I soldered everything to perfboard like you see on the left. The MSP430 on there waits for data to come in on the purple line and flashes a number out digit by digit. It is probably not practical for displaying 32 bit numbers in decimal but seems to work well enough for 8 and 16 bit numbers in hex. The headers on the right are for relaying incoming data to a PC over UART, even if the UART pins on the main microcontroller are in use.

Saturday, August 23, 2014

6502 Virtual Trainer: Calculator Program

After I got my new Hakko FX-888, the first thing I did was solder the trainer to perfboard. It took some time to get used to the new iron but the board turned out well:

The FT232 cable connects to a few header pins soldered to a piece of perfboard connected perpendicularly to the main board by more pins that are bent at an angle. They make header pins at an angle but I used the last of mine on the board I made for programming the Z16F. There was also room to add some sockets and pins that can be used to program the MSP430, as well as power and status LEDs.

After using the board for about a week I had a strange error where the chip jumped to address 8080 on reset instead of 8000 which is stored at the reset vector. After some investigating, it seems there was a short between the Vcc pin of the IO expander and the pin controlling A7 of the 6502's address bus. On the back side of the board there was clearly no bridge which had me stumped but it worked fine after scraping away some of the flux between the joints. The problem reappeared after a week or two but was fixed again by cleaning the space between the joints. In frustration I ordered a W65C02 thinking the chip might have been damaged due to some acidental bus contention that had happened during testing. It seems that the pinout is a little different from the W65C816 I am using but it will still be useful because I plan to use it for an improved version of the trainer.

With the software I have made a little progress as well. The PC software skips sending any uninitialized memory and with a few other tweaks can program the whole 64kB memory in less than 3 seconds, down from 6 seconds. The microcontroller firmware is also a little better. Compiling with the -o3 flag in GCC brings average cycles per second up to about 16,000 from 12,000. However, setting the update rate to 100ms from 200ms to make typing more comfortable brings it back to around 14,000.

To learn 6502 assembly I decided to make a little test calculator program. It has turned out to be a really good way to get to know the chip, even though it has taken a lot longer than I expected. Below is a screenshot.

On the left is a text window for the 4-function RPN stack. It has 10 levels and each element is 8 bytes of packed BCD. This is convenient because the 6502 has a BCD mode. On the right is a window to enter formulas which can be graphed, like the first three, or repeated like the Celsius and Fahrenheit conversions. Formulas and graph colors can be selected with the dip switches. The toggle switch at the bottom selects between the two text windows and an LED above each window shows which one is selected. All of this could be done with a keyboard interface but I wanted to show off some of the peripherals that can be used. There is also a timer peripheral ticking every 500ms that the program reads to draw a flashing cursor in whichever of the two input text windows is active. The last peripheral is a multiplication ROM that works when single stepping the processor but not when running from SRAM yet.

There are still several improvements to be made to the trainer but I am done working on it for the moment. My plan is to port the code I have to an STM32 which will be much faster and also be able to store all 64kB of the 6502 address space in its internal RAM.

Thursday, July 3, 2014

Quiz Buzzer

About a month ago a friend of mine called and asked if I could make a buzzer system for a quiz game for students. Unfortunately, I only had two days until the competition and I did not get it working in time. Hopefully, I can fix it and send it to them to be used at the next competition in a few months.

The plan was that each of ten students would have a button connected to a buzzer by a few meters of wire and the first to press the button after a question was asked would cause a sound and light to go off. The connectors are RCA style and the buttons are from an automotive store.

These lead to an A42 enclosure I was able to sample from Serpac. The enclosure felt really sturdy but the plastic was surprisingly easy to cut and work with with just a knife. I will definitely use them again when I need an enclosure. The circuit itself was fairly simple with just an MSP430 microcontroller, buzzer, two 595 shift registers, and two 165 shift registers. I did not get around to adding the LEDs, although the firmware does use the shift registers to turn on the correct light when someone buzzes in.

To control things I made a separate detachable board with a 16x2 LCD. It will be easier to transport if the cable is detachable and it will also let me add a longer cable if the judges doing the scoring need to sit farther away from the enclosure. Other than the LCD, the board has a 555 to generate negative voltage for the LCD contrast and another 595 shift register to run the LCD. It also has buttons to change the time given to answer and to reset the counter.

For the cable I used Cat-5 again and this may be part of the reason it does not work correctly. For the connector I wanted to make something that would only plug in one way so that people other than me could use it without fear of plugging it in backwards and shorting something. Each side has a pin that can only be connected one way.

A project like this would take me a week at least but I tried to finish in two days because my friends needed it. The night before I stayed up soldering until 7am and when I finally switched it on, the LCD came on as expected and the buzzer sounded when I pressed one of the contestants buttons, but it made a high pitched screeching noise when it was finished buzzing. When I turned it off and tried again the LCD wouldn't display anything and only worked some of the time when I tried it again, so we weren't able to use it in the competition after all.

Why did it fail? In retrospect, I have had problems with this particular LCD in the past. When I was working on my calculator project I noticed that the LCD would often not work when being driven directly by a microcontroller but worked fine when being driven from a shift register like in this project. I'm not sure why it worked before and not now but the fact that it was flaky before might be a clue to my problem. Also, maybe my assumption that it will always work at voltages less than 5v is not correct or maybe supplying negative voltage to the display somehow has consequences. On the other hand, I observed the same faulty behavior with the contrast left unconnected. Another source of problems could be the Cat-5 Ethernet cable I am using for wiring. Each pair is twisted together and running a separate signal through each side of the pair instead of grounding one side might be leading to signal corruption. Finally, the loud screeching of the piezo buzzer is something I will have to figure out as well. Hopefully, when I understand more about this it will help me straighten things out with my clock project also.

Going from nothing to a nearly complete project in only two days was a lot of work, but in the end there was not enough time to troubleshoot problems. When I move into my new apartment next month I will have time to figure everything out and then I can send the working system back to Kyrgyzstan for my friends to use.

Monday, June 30, 2014

Clock Modification

The unfinished clock without the arms
For Christmas 2012 I got a battery powered alarm clock. It felt pretty sturdy but only plays a beep when the alarm goes off and it does not have a backlight. There was plenty of room inside the case so I decided to add a microcontroller to play the unofficial national anthem of Kyrgyzstan Кыргыз Жери (Kyrgyz Jeri) instead of just the beep. Although I have been working on it on and off for the past few months I have not gotten the bugs worked out.

The mechanism inside the clock runs from one AA battery and has a small buzzer that looks like a piezo. The positive side of the battery is connected directly to the buzzer by a wire. The other side of the buzzer is connected to a chip under an epoxy blob that switches the buzzer on and off. The 1.5v of the AA battery is not enough to run the MSP430 I am using so I wired in two AAA batteries. The clock case has just enough room for the extra batteries and a small piece of protoboard for the microcontroller. I opened the mechanism to solder in some wires so that the microcontroller can monitor the line switching the buzzer and drive the buzzer directly instead. One of the small gears inside quickly melted from the heat given off by the soldering iron a few inches away. Luckily, all of the local clocks use a similar mechanism and I replaced the whole thing for about $1. The wires from the mechanism are connected to a switch so that the buzzer can either be run by the microcontroller or by the original clock in case the extra batteries die. Another feature the clock is missing is a light, so I wired in an RGB LED I bought a few years ago. It has a light so that it can be used as a backlight but it also flashes colors in time with the music when the alarm goes off.

At first I tried soldering components directly to a DIP socket but this was surprisingly difficult, so I added everything to a small piece of left of protoboard. The AAA batteries are too big to fit in the clock case side by side so I couldn't use a battery holder. Instead I soldered wires directly to the batteries. This will make them hard to change but hopefully the MSP430 will use very little power waiting for the alarm to go off. Once I got everything soldered, the microcontroller would play the music it should but it would not stop playing even when it was disconnected from the line switching the signal. This is a problem I still have not figured out but I'm sure it has something to do with fluctuating signals in the circuit.

There were a number of other strange problems as well. The P1IES register used to enable edge selects for interrupts on the MSP430 sometimes gives the wrong value when you read from it. It would be useful to read it in an interrupt to know which phase of the cycle the interrupt was last configured to fire for. There was also a problem working with 32-bit values. It seems that doing math with constants and assigning the result to an unsigned long does not automatically promote the constants involved to 32-bit values as well. When I got the wrong value, I tried it out on a PC and got the expected value, which was a little perplexing. It seems that constants default to the bit size of the processor, which seems silly from a portability point of view. To have the constants treated as longs, the L prefix has to be added. Another strange thing that happened was that the buzzer always made a high-pitched whining even when not being driven. The batteries for the microcontroller also drained alarmingly fast. It turns out that both of those problems are related to the buzzer being electromechanical instead of a piezo. These buzzers do not charge and stop current from flowing like a piezo. It seems they only have about 40 ohms of resistance and this is why the batteries drained so quickly.

There are still a lot of bugs to be worked out but I hope to make progress soon and finish this little project quickly.

Monday, June 23, 2014

6502 Virtual Trainer: Update

Lately I have been working on several different projects and I have made a lot of progress on the 6502 Virtual Trainer. The first step was connecting the PC interface to an MSP430 over UART. This was easy because I have done it in other projects. Microchip let me sample some MCP23S17 IO expanders and I was really excited to be able to try them out to read and write the pins of the 6502. Unfortunately, they were a little finicky to get going because the datasheet incorrectly lists the reset pin as an output instead of an input.  They do save a lot of space, though, because five shift registers would be needed to replace them. After that was solved, I was able to single-step the processor as I intended but only at about 90 cycles per second. For comparison's sake, with the processor doing nothing else, that is a little too slow to type comfortably. At the beginning I knew this would be slow but that is much slower than I expected. The bottleneck seems to be the USB<->serial layer since the program sends lots of small packets of data instead of small numbers of large packets. To speed this up, I send 10 bytes of op codes every packet. Then the MSP430 can use the data sent if it needs to read a byte that is near. It will have to request more data if a jump takes place or data is read from another location in memory but in general this improvement led to a speed up of about 150 cycles per second. This was still not as fast as I had hoped for so I decided to keep a copy of all of the memory on an SPI SRAM chip. For this I used a 23LC1024, also from Microchip, which holds 128k. Using an SPI SRAM might seem to make less sense than just hooking up a typical parallel SRAM but by letting the microcontroller control the memory I can hold extra information about the data such as which bytes have not been initialized and which should be ROM. This will let me break when reads and writes that would be illegal are performed. Even during testing this turned out to be useful as it is easy for a beginner to assembly to write something like LDX $FF instead of LDX #$FF. As a compromise the MSP430 runs the 6502 as fast as possible then pauses and updates the PC every 200ms or when 64 bytes of memory have been modified, whichever comes first. Another way to speed things up was to increase the COM port speed from the 230,400 bps max of the MSComm control I'm using with Visual Basic 6 to 1,000,000 bps. At 1,200,000 bps the MSP430 could not keep up running the 6502 and reading data. With these changes I can run the 6502 at about 12,000 cycles per second. This is still pretty slow but fast enough to play with for learning purposes. To test things I made a few programs including one that draws a faded red pattern like below:

Tuesday, May 13, 2014

RPN Scientific Calculator: Case

After a few months of work, the case for my calculator is finally finished. Back in January I made a post with a picture of the clad I soldered together for the case. My plan at the time was to stuff all of the internals of the calculator into the case over the course of a few days but it ended up taking much longer.

The first hurdle was figuring out how to attach the front and back plates to the case. In the end I settled on epoxy. The first one I tried was still oily after 24 hours and did not hold very well but a much cheaper one held extremely well and I used it to glue four bolts to either side of the case body. Oddly enough the epoxy turned the clad green pretty quickly. From there I made holes with a box cutter in the front and back pieces for the bolts. Cutting out the hole for the keypad and LCD in the front piece of clad with a box cutter and wire cutters was a real chore and I don't plan on working with clad ever again without something like a dremel. For spacers between the clad and components I used rubber erasers.

These are cheap and easy to work with. My only fear is that they may dry out and crack someday. At first I tried gluing one of the plastic battery holders to an eraser with epoxy but surprisingly the bond was very weak. Super glue worked very well, though, and I glued in more erasers to hold the LCD, PCB, and keypad in place. All of that added a noticeable amount of weight to everything. The front and back pieces also have erasers glued to them to help hold everything together.

There was not enough room to comfortably route the wires from the LCD and keypad to the PCB so I desoldered them and used Cat5 cable instead. The wires inside are much smaller and easier to work with. It is also possible to leave the individual wires inside the Cat5 cable to make routing neater and I did this for some of the keypad wires. After assembling everything it worked fairly well except the keypad buttons were hooked up upside down. This was easy to fix in software and I loaded the new version using the programming pins soldered to the PCB without having to take the PCB out of the case. There was another bug that caused the calculator to freeze after pressing escape. For some reason the program was going into sleep mode when I pressed escape. I must have added this during debugging but it does not make sense at this point.

The next step will be to add some sort of labels for the keys and then paint it if I decide to.

Saturday, May 10, 2014

New Project: 6502 Virtual Trainer

One project I have been interested in for a while is building a homebrew computer. Some of the projects I have followed like Veronica are really fascinating and I would like to do something similar. For my project I decided to use an M68000 but Mouser did not have any in DIP packages when I ordered from them last year so I settled on a W65C816S instead. This chip is compatible with the 6502 like Veronica uses but also has a 16-bit mode which is more powerful. Other homebrew computers like this one use that chip as well.

KIM-1 6502 trainer
Setting up RAM and ROM to work with the processor for a simple system is well-documented. My first idea was to hook up a microcontroller to the system once I had it running to monitor the bus and some of the control pins not usually used in simple systems. That way I could transfer information about the system to a PC over UART and even control the clock rate. Then I realized that it would be simpler to skip the RAM and ROM altogether and keep all of the memory on the PC. The microcontroller would relay data between the processor and the emulated memory and peripherals. This would not be a useful system by itself but it would let me learn a lot about how the processor works.

Simple systems like the KIM-1 were produced in the past along the same lines. These were called trainers and often had simple hardware that let people learn about how computers work. I decided to call my project a trainer also. My plan is to control the processor through an interface on the PC that will let me examine the memory as the program is running as well as set break points and single-step the processor. It will also show me the status of all the control pins and let me set the values of some of them. Peripherals like buttons, lights, and displays will all be virtual. Here are some of the ones I have working so far:

Wednesday, April 2, 2014

555 Entropy and Robotic Teddy Bears

Recently I have been keeping busy with a few electronics projects, although it doesn't look like either of them will turn into anything. The first would transmit text wirelessly from a PC to a microcontroller to be displayed on an LCD. For this I planned to hack toy walkie talkies. This is not an ideal way to transfer text but I thought it would be fun to try different ways of making them work to start understanding wireless communication. Unfortunately, in my whole town I could only find one set of walkie talkies and one of them turned out not to work. The data being sent would not be especially sensitive but I still did not want to send it as plain text. This got me wondering about encryption, which I also have no experience with. There are many algorithms but I would need one very easy to compute since the microcontrollers involved would not be very powerful but would have to decrypt and transfer quickly. One solution that intrigued me was using a one time pad. Each microcontroller would have the same list of random numbers that would simply be added or XOR'ed with the data to encrypt and decrypt it. One time pad schemes have the advantage of being truly unbreakable as long as the numbers used are random and never repeated. A bigger advantage for me is that the microcontrollers could simply fetch the numbers from an SD card without having to compute anything. To get truly random numbers, though, I would need a hardware random number generator. These are a common project for hobbysts but not always easy to build correctly. One method uses a transistor in reverse breakdown mode but I decided against this because it requires 15 volts or more. Apparently the transistor also changes with age (perhaps due to being continuously run in a way it was not designed to be) and the characteristics of the numbers generated change too. Another interesting way I found was to measure the output of a 555 timer with a microcontroller ADC as shown here. This made me wonder if I could just measure the length of 555 pulses compared to the oscillator in a microcontroller to use clock drift as an entropy source. I connected a 555 running at 480Hz to the hardware counter of an MSP430 running at 16MHz to measure how many clock cycles each 555 cycle took and dumped 1,000,000 samples out over UART.

Sunday, March 9, 2014

Microcontroller Showdown, Conclusion

The last chip in the comparison is the Z16F2810. When I started the tests I got a Loop overhead time of only 0.64, which made me think the chip might be very fast. When I moved on to the multiplication and division tests, though, some of them completed in only 0.89 seconds. After looking at the assembly generated during compilation I noticed that the arguments of division were only being copied to the register that holds the answer. It seems that even though all the variables were declared as volatile, the compiler decided to optimize the division out anyway. This made me think the compiler was simply ignoring the volatile keyword but the assembly generated when accessing volatiles is slightly different. Loops involving them take about 25% longer to run, so it does have an effect. The only way I could prevent it from optimizing out multiplies and divides while keeping optimizations was to declare the involved variables globally. The User Manual for the chip helped a lot when looking at this problem and I think it is really well done.

For arithmetic operations, the chip did very well. It was always faster than the MSP430 and almost as fast as the LPC1114 for most things. One place it did very well was division where it outperformed all the other chips by a large margin because it has a hardware divider. General GPIO is also pretty fast, although it does not have any special mechanism for speeding it up like the masks on the LPC1114 or the constant generator on the MSP430. BCD Add was about the same as the MSP430. BCD Multiply was faster than on the MSP430 but still much slower than on the LPC1114.

After running all the chips, here are my conclusions:
  • MSP430 Easy to use and reasonably fast. Good choice for small jobs and low-power projects. Held back by low clock speed (16MHz), small memory, and lack of hardware multiplier.
  • LPC1114 The fastest chip by far for everything but division and 8 bit math. Lots of RAM and Flash. Straightforward to use, although there is no real community. Very fast GPIO with masks. Top choice for calculations.
  • DS89C450 Fast for 8 bit math, although slow at shifting. Very fast GPIO since each GPIO pin is mapped to its own byte in memory. Extremely slow at BCD calculations. The only real advantage is the external memory bus.
  • AT89LP6440 Similar to the DS89C450 but lower clock speed and performance. 
  • Z16F2810 Good performance but inferior to the LPC1114 in everything but dividing. Debugger is very useful but the IDE itself is sometimes clunky. Enough RAM and very big Flash (128kB). PLCC package is inconvenient.
In the future I plan to do a few more projects that will need the extra horsepower for the LPC1114. For other smaller jobs I will stick with the MSP430.

Results are after the break.

Saturday, March 8, 2014

Z16F2810 Programmer

The last chip in the comparison of microcontrollers is the Z16F2810. It comes in PLCC and is the only part in the ZNEO line that isn't QFP only. In order to program the chip I soldered a PLCC socket to perfboard with headers for one of the GPIO ports and for an FTDI cable.

In the beginning I was excited about the PLCC socket but it turned out to be somewhat inconvenient to solder due to all the jumper wires needed to reach the inside row of pins. Next I connected the chip to the FTDI cable and tried to access it over UART as described in this Application Note about the bootloader. I had overlooked that the UART bootloader is not part of the ROM and has to be loaded over the one-wire interface normally used to program the chip. Until I realized this I removed the chip several times looking for faults in the circuit and managed to crack the socket with a screwdriver on the third removal. Zilog sells a specialized cable for programming their chips through the debug pin and I hoped to make something similar that would work over an FTDI cable. One forum post I found was really helpful. It showed what the cable looks like inside:

It seemed pretty unlikely that I could recreate this on my own. Later in the post someone mentioned that some of the Zilog documents show how to program the chip with a serial cable and only one diode. All I had to do was solder the diode and a 10k pull-up to the debug pin to make it work with the FTDI cable.

The next hurdle was the software. The picture above shows a USB SmartCable which will work with the ZNEO version of the ZDSII software Zilog offers for programming and debugging. The ZNEO version of ZDSII does not, however, work with the Serial SmartCable which the FTDI cable would replace. The Z8 Encore! version of ZDSII does support the cable. The same forum post explains that you can simply copy the file SerialSmartCable.xdt from the debugtools directory of the Z8 version to the debugtools directory of the ZNEO version. You will also need a copy of the file NxZNeoSerial.dll. Another website, also in German, explains that a copy of this file comes with Smart Flash Programmer 2.2.0.

The ZDSII IDE works well enough for writing code, although I still prefer to use Code::Blocks. The debugger is really handy. You can set break points and look at the disassembly compared to the C source as the program is running, as well as examine memory and registers. It is a little unwieldy, however, to go through the whole process of disconnecting, compiling, reconnecting, transferring, and restarting every time code is recompiled. In my opinion there should be a single button to recompile and run code. Another small gripe is that when code starts to run, the debugger automatically halts on the first instruction and jumps to that place in the source. Unfortunately, that is always start-up code, so every time you press Go it opens the start-up assembly file supplied with the compiler and waits for you to continue. This is just annoying since it has to be closed every time.

The IDE uses make with its own compiler. Running this compiler from the command line shows that there are many compiler options but the only one available in the IDE is "Limit Optimizations for Easier Debugging." There is no way from the IDE to specify arguments to optimize for speed or size specifically. You can, however, export a makefile from the IDE and run make on its own. Doing this I was able to edit the makefile to add the flags for speed and size optimizations but neither of them produced any difference. I copy the file generated by make to the output directory of an empty project that I keep open in the IDE. Because compiling is done outside of the IDE, I can upload the file to the chip without having to disconnect and reconnect.

Monday, March 3, 2014

Microcontroller Showdown, Part 4

The next chip to test is the AT89LP6440. This is a single-cycle 8052 compatible like the DS89C450. It can run from an internal oscillator at 8MHz or an external crystal up to 20MHz like I am using. According to the datasheet, total capacitance for the crystal should not exceed 20pF and the chip itself adds about 10pF of that. The smallest capacitors I can find are 22pF so I ran it without capacitors and it seems to work fine on a breadboard.

As you might imagine, the AT89LP6440 performs similarly to the DS89C450 at 20MHz. The times are not exactly the same, though, because both chips perform some instructions in less cycles than original 8051s. This is apparent, for example, in the multiply times where the AT89LP6440 can do 32 bit multiplication about 30% faster because it does multiplies in 2 cycles instead of the 4 cycles needed by the DS89C450 and standard 8051s. The AT89LP6440 also shifted about 5% faster in the tests, although it was a little slower at BCD calculations. Like the DS89C450, I don't think I will end up using this in a calculator but it may come in handy because it can run at 3 volts and has an external memory interface.

Results are after the break.

Sunday, March 2, 2014

MSP430-Based AT89LP6440 Programmer

Using an FTDI cable to program the AT89LP6440 like I mentioned in my last post turned out to be more difficult than I expected. Configuring the FT232 chip is a real pain because the reset command in the API does not seem to actually reset any of the chip settings to default. After trying some more tweaking I noticed that the uploading itself inexplicably hangs sometimes on longer files. I was not able to finish the next step of the microcontroller comparison. According to another page, FTDI states that "using bitbanging for SPI or I2C is not recommended with the FT232RL part."

The next step was to use an MSP430 to take data in over UART and relay it over SPI to the AT89LP6440. The UART interface of the DS89C450 works really well so I copied this. The MSP430 gives a prompt over UART that can be used to erase the chip, load or verify firmware, and set flags. The challenge of the project was coordinating interrupts and ring buffers for the hardware UART and SPI peripherals so that no data is missed. At 9600 baud it worked reliably but at higher speeds there were checksum errors because sometimes the previous UART byte was not read before the next one came in. This seems to happen at the end of a line of hex when the MSP430 has to send a lot of data out over SPI to prepare the chip for writing. The solution was to send an XOFF character back to the terminal, which stops it from sending any more data bytes until an XON character is sent. Like this I can program at 57.6k and after a few dozen tries I have not had any errors writing to the chip or verifying the firmware. The MSP430 is also connected to the reset line of the AT89LP6440 so that I can put the chip in run mode without having to press any buttons on the breadboard.

The source for the programmer can be found here: AT89 Programmer.

Sunday, February 9, 2014

AT89LP6440 Flashing

For the Microcontroller Comparison I have been trying to get the AT89LP6440 to work. When I sampled the chip I thought it could be programmed over serial with an FTDI cable like the DS89C450, but it turns out that it needs a parallel port. There are adapters and programmers that will simulate a parallel port over USB but I don't want to buy one for a chip that I might not use much in the future.

As a workaround I used the FTDI cable to bitbang the SPI interface. This was tricky because I had to write a whole new loading program instead of relying on the program Atmel supplies. Thankfully, they provide very good documentation of the ISP specification. Bits are sampled on MISO on the falling edge of the clock and MOSI is sampled on the rising edge. My first version of the program worked well but could only upload about 100 bytes of firmware per second. Part of this is due to reading MISO every clock cycle, which is not always necessary. By splitting reading and writing into different functions and sending pin states in groups instead of individually, flashing is much faster. There is a bug, though, that randomly gives a wrong byte when I try to read from the chip to verify the firmware. The wrong byte is always at a different address and sometimes the verification completes, so I know the AT89LP6440 has been programmed properly. I wasted about a week trying to tweak the program and saw that the D2XX drivers supplied by FTDI are unreliable and pretty buggy (at least when used under Windows 7 for bitbanging). This particular problem could be with the chip but several of the other D2XX functions I tried didn't work very well either. The same problem happens with both synchronous and asynchronous modes. There is an open source library called libFTDI but I didn't get very far with it because installing the driver for it would mean losing the virtual COM port you get with the FTDI driver. The next step would be to program the chip using another microcontroller connected to the PC over UART but I don't want to waste any more time on this chip since I am unlikely to use it for anything after the microcontroller comparison.

You can download the program here: AT89Loader. Flashing seems to work with no problems but verification occasionally fails.

Monday, February 3, 2014

DS89C450 High-Baud Flashing

As I mentioned in my last post, I have been using the DS89C450 lately to do some tests. It has a serial program loader in ROM used to program the chip over UART. The baud rate of programming is dependent on the crystal speed. Some crystals, even fast ones, only work with low standard baud rates and some don't work at any of the standard rates. To understand why, we should look at what baud rates the loader accepts. The User's Guide gives an equation for this:

Baud rate = Crystal Frequency / (192 * (256 - Timer Reload))

The loader tries these values for Timer Reload:  FF, FE, FD, FC, FB, FA, F8, F6, F5, F4, F3, F0, EC, EA, E8, E6, E0, DD, D8, D4, D0, CC, C0, BA, B0, A8, A0, 98, 80, 60, 40. The resulting baud rate must match the baud rate used by the programming computer to within 3%. Using this equation we can see that some common crystals such as 12 and 20MHz only fall within the 3% limit for a few of the slower standard baud rates.

This limit can be overcome, however, by using a non-standard baud rate. Neither the MTK program supplied by Maxim nor Hyperterminal can use non-standard baud rates, but some terminal emulators like uCon can. The above equation can be used to calculate the ideal value. In my case, a 20MHz crystal with a Timer Reload of FF gives a baud rate of 104,166. At this speed I could connect to the chip but not program it without errors. Using the next value of FE for Timer Reload gives 52,083 and at this speed I could connect and program the chip successfully. This is big a improvement over the previous maximum baud of only 4,800!

Another great function of uCon is scripting. Scripts can be saved and assigned to a button. The following script lets me erase the DS89C450 and upload new firmware with just one button click (I usually compile programs to "temp.hex" to make scripting easier):

SEND -n "L"
FSEND "temp.hex"

Sunday, February 2, 2014

Microcontroller Showdown, Part 3

The next chip I compared was the DS89C450 from Maxim. This is a single-cycle 8051 with clock speeds up to 33MHz. The other single-cycle 8051 I wanted to test is the AT89LP6440 but I wasn't able to program it with an FTDI cable. It expects an SPI interface based on a parallel port and I do not know how to get it working with the FTDI cable.

At first I had a lot of trouble getting the DS89C450 running with the flashing software supplied by Maxim. It just would not connect no matter what crystal or capacitor combination I tried. After a little digging I found out that the baud rate depends on the crystal and that 4800 is the max for 12 and 20MHz crystals. Unfortunately, the flashing software only supports 1200 and 9600 or higher bauds. At 1200 baud I was finally able to connect successfully but the chip returned an error when I tried to load firmware. After more digging it seems the problem is caused by using an FTDI cable instead of a real serial port. I can't really hold this against the manufacturer, though, since the chip and software are over 10 years old at this point. Next I tried connecting over Hyperterminal at 4800 baud and this worked great. The interface for communicating with the chip is actually kind of slick. It gives you a prompt you can type commands into and responds back to your input. Loading firmware at 4800 baud, however, was a real pain. If I decide to seriously use this chip, I will definitely track down a crystal that lets me connect at 57600 baud.

The results of the tests are after the break. I ran them with a 20MHz crystal and scaled the results for what they would probably be with a 33MHz crystal. For compiling I used SDCC. This compiler is new to me but it seems pretty simple to use. In place of -O3 I used --opt-code-speed and for -Os I used --opt-code-size. There wasn't really a difference in the results though. As you can see, it adds 8 bit numbers even faster than the LPC1114, 16 bit numbers about as fast as the MSP430, and 32 bit numbers almost twice as fast. It is also much faster at multiplying than the MSP430, which was a surprise to me. Out of curiosity I looked at the 8051 instruction set and was quite surprised to learn that it has 4-cycle multiplication of 8 bit values. The rest of the instruction set and architecture seems very straightforward and I imagine it would be fun to write assembly code for this chip. Division and shifting are pretty slow. GPIO, however, is very fast. Each pin is mapped to its own byte in memory. This seems like a simple feature and I wish more chips had it. With this the chip can bit bang almost as fast as the LPC1114 can with masks. The real test of the chip, though, is BCD calculations and in this it was pretty disappointing, running 2-3 times slower than the MSP430. For these tests all the data was stored in the on-chip external RAM (xdata). This is slower to access but it was necessary to store it here since the internal RAM holds less than 100 bytes. I also tried storing it in the idata section available in 8052 compatible chips like this but that was even slower. It looks like I won't be using this chip for any calculator designs but I will keep it in case I do a project that needs an external memory interface or memory mapped peripherals.

Friday, January 31, 2014

RPN Scientific Calculator: Hardware

In the last two months I have made a lot of progress with my calculator. The software is now finished. As well as cleaning up a few bugs I also added a battery meter to the settings page. There was enough memory on the external RAM for two separate stacks with 200 levels each. All of the code is now on a GitHub page:

For the hardware I soldered everything on to perfboard. It didn't power up the first time I plugged it in but after fixing one power connection everything started up and worked fine. Here is a picture:

For the power supply I am using 4xAA batteries with an LM1117 adjustable regulator. My local shop didn't have the resistors I needed to get 3.6v from the regulator so it is running closer to 3.5v. On the left side you can see female headers for the keyboard outputs to be plugged into and on the lower left a repurposed DIP socket for the LCD and keyboard inputs to be plugged into. The red, white, and blue wires were the smallest single strand gauge one store had and worked fairly well. When I ran out of that I switched to an even smaller gauge (the brown wires) I got form another store and it was even more convenient. It works so much better than breadboard wire and I definitely plan to use it again. If you look closely you will see two pins for power so that the whole board can be powered from the LaunchPad if needed. Each MSP430 also has its own set of programming pins so that they can be programmed in circuit. One strange thing I noticed on this project is that solder will sometimes spill through the holes and onto the other side of the board. This may be because the smaller gauge wire lets the solder through more easily. One problem I had while testing the connections were two adjacent socket pins that seemed to be bridged, even after desoldering everything around them. After removing the socket itself, I saw that a drop of solder had flowed to the other side of the board and shorted the two legs in the space between the board and the socket.

Here is everything connected and running:

 Here is a circuit schematic of the whole system:

For the case I soldered together some clad which I was able to get really cheaply. It feels pretty solid. It needs a coat of paint and I need to adjust the holes in the faceplate for the keyboard and screen. Here is what it looks like so far:

As was my goal, I submitted the project to the Project of the Month Competition at Thankfully it was extended an extra month so I had some time to finish most of what I wanted to finish. Voting starts tomorrow!