Sunday, July 12, 2015

New Project: Programmable RPN Calculator

One of the projects I started on for my Summer Hackathon is a new version of my RPN calculator. This version uses an LPC1114 instead of the two MSP430s the last version used. Hopefully this version will be much smaller and faster. Even though I'm not yet at a good stopping place I wanted to make a post about it so that the last post is not overly long.

Porting the code from the MSP430 was not too difficult. The only real trouble was moving some of the memory registers from the external RAM to the internal RAM of the LPC1114. This really increases calculation speed since it eliminates the bottleneck of accessing external memory. On the MSP430 version I used a preprocessor function to identify and replace any array access to the external RAM with functions calls. This worked well since all of the registers were stored externally but caused a few headaches on the new version since internally stored registers need to be handled differently. One idea I had was to use 32 bit pointers, which wouldn't cause the performance hit they do on a 16-bit system, to somehow encode not only the memory address, but also the memory bank and whether an address is stored externally or internally. It also seems like it would make more sense to allocate memory buffers on a stack as they are needed, rather than hardcoding them in memory. This got me thinking about how other systems handle this problem and I decided to add a way to do that to my 6502 project with a CPLD.

Along the way I also noticed a few areas where I could improve my code. For some reason I got in the habit of reusing generic counter variables like x or i in an effort to save memory. This just makes everything harder to read and does not save any memory since GCC optimizes how variables are used anyway. BCD numbers should also be stored with the smallest places first since that way extending the number by a decimal place only involves incrementing the length field rather than moving every byte of the number one space. In retrospect 255 decimal places is probably way too much for such a simple calculator. This didn't make much difference when I had lots of external RAM but is inconvenient now that I am trying to fit as many registers as I can into the LPC1114's memory.

To read and write the external RAM I'm using the chip's SPI peripheral. It turned out to be somewhat difficult to configure since several of the steps to get it to work have to be done in a certain order. Debugging this was a lot easier with a logic analyzer. After I had it working and got the memory registers straightened out, I was a little surprised to see that calculating sine was slower than on the MSP430. This was a shock since it was so much faster in my microcontroller comparison. I tried raising the SPI peripheral speed to 24MHz, even though the max speed of the RAM is 20MHz, but it was still slower. My next step is to try and measure the clock speed of the SPI with the logic analyzer to make sure it really is going that fast. After I got sine to work, I uncommented other parts of the program in parts to see how much would fit in the flash. Compiling with GCC's -O3 option for speed optimization quickly overflowed the flash but all of it fit in less than 20kB with -Os. One of my gripes with GCC is that it doesn't tell you by how much the firmware is too large, so you have no clue how much you would need to shave off for it to fit.

Initializing and toggling the pins of the LPC1114 is a bit more complicated than on the MSP430 since different pins have different configuration bits and the pins themselves are not mapped into memory in order. I had a look at the HAL library and it seems to use quite a bit of code for what I want to accomplish so I wrote a simple class for handling pins. Luckily I can use C++ since I am just compiling with GCC, unlike with OpenSTM32 where I was stuck with plain C. One neat thing someone showed me was how to use operator overloading so that something like "Pin=1;" does the same as "Pin.high();"

Since I have so much space left over in the flash, I started adding a keystroke programming function. This was one of the neat things I have always liked about earlier calculators. I am nearly done with the editor on the screen for it, which I'm working on with the PC version of the program since it is much faster to test. The next time I do a project like this I will put the PC and embedded version in the same file and enable them with include statements instead of copying the changed sections of the PC version. So far I am only adding the ability to repeat keys and not loop or branch since I want to finish this and at least one other project in time for Makevention in August. When I have more time I hope to add that functionality.

Monday, July 6, 2015

2015 Hackaday Prize

Hackaday recently started a competition for projects that feature parts made by Atmel, Freescale, Microchip, or Texas Instruments. 50 prizes are being awarded for each group, so I entered my RPN Scientific Calculator into the TI competition. The winners were announced today and my project was one of the 50. My prize was a Bluefruit LE Sniffer, which I was able to order from the Hackaday store for free. I'm not sure what I will use it for yet since I don't have a smart phone. My project page for the calculator is here.

Saturday, June 27, 2015

Improved 6502 Virtual Trainer

Over the last few days I have made a lot of progress on this project. The main hurdle was getting a USB Virtual Com Port example running with the toolchain. The code from the first 6502 Virtual Trainer, which used an MSP430, was pretty easy to port to the STM32. After I got single-stepping to work, as I mentioned in my last post, I worked on the mode that stores the entire address space on the chip. It was a little surprising at first that it only ran at about 23,000hz. This is not much faster than the 14,000hz I was running at with the MSP430 version. My initial suspicion was that the transfers between the chip and PC to keep their respective copies of the address space synced were taking too much time. Timing the transfers showed that the chip usually spent over 90% of its time executing code, however. The biggest speed up came by manipulating the GPIO registers directly, rather than relying on the cumbersome HAL functions. Another thing I tried was changing the baud rate, although I couldn't find where it was initialized in the code. Eventually I found out that the Virtual Com Port doesn't rely on any sort of baud rate setting. A few other small improvements got the speed up to 350,000hz or so. When I found out how to turn on GCC optimizations in the System Workbench IDE, the speed got up to over 770,000hz. That's 0.77MHz! It's not quite the 1MHz I had hoped for but it is over 50 times faster than the first version.
My original plan was to leave the IDE unchanged so that it would be compatible with both the old
MSP430 board and the new STM32 version, but I had to change a few things. For one, I was only transferring two bytes of data to count how many clock cycles had been executed since the last update, so I had to add a third one since the new board runs so much faster. The old version synced with the IDE when at least 64 bytes of data needed to be transferred. This is the most I could store in the MSP430's internal RAM. The new limit is 200, which wastes less time syncing when lots of data is transferred. A few thousand bytes would probably be even better, but the IDE wasn't able to keep up. This could probably be fixed but 200 is fine for now.
Another thing that changed was losing support for breaking on uninitialized reads. This was a very handy feature on the first version because it could catch many different kinds of errors. That version used a 65C816 in 6502 mode and separating read cycles from internal operation cycles (when the processor is not reading despite the RWB pin being high) was easy monitoring the VPA and VDA pins. There is no easy way to do this on the 65C02 I am using now without storing information on the microcontroller about the status of the bus for every cycle of every opcode in every addressing mode. Hopefully I can live without this feature now that I have a little more experience with 6502 assembly. To test the new version I used the same small RPN graphing calculator program I wrote for the first version. It works great but drawing to the screen, even with the GDI library, is still a bit of a bottleneck.
Now that I am finished with this project I can start on programming the calculator I hope to build for the Makevention in August.

Thursday, June 25, 2015

Summer Hackathon: Update

During the past few weeks I have had a lot of time to work on the projects I planned for my Summer Hackathon. So far I haven't made as much progress as I hoped, mostly because two of them took a lot more time to get going than I expected. Here is my what I have done so far on the ones I have worked on.

EEPROM Computer
Basing a computer architecture on precomputed lookup tables seemed like a an interesting idea when I started working on an assembler program for a 4-bit EEPROM-based computer. On IRC I explained what I was intending and the creator of the CADET computer showed me what he had accomplished. It is more or less the same thing I wanted to build, so I decided to stop work on this project for the time being. After discussing the idea with a friend at our hackerspace, I decided that it would only be worth continuing this project if I expanded it to a 16 or 32-bit architecture.

Brainfuck Microcontroller
For this project I have only hooked up four 74ALS193 counters since the last update. These will be the address counters for the program memory. My plan is to build the computer in small parts on a breadboard and transfer them to protoboard when I finish each piece. Rather than lay everything out on a a large board, I started soldering 8x12cm boards that will stack with double row headers. This way I will have plenty of pins to transfer signals between boards. I also plan to put LEDs on the topmost board to show signals like the address, jump buffer, op code, data pointer, and control signals.

A guy at our hackerspace was having trouble getting his ESP8266 going, so I set mine up to figure
out how to do it. Luckily for me, mine worked fairly well on the first try. The 03 variant I bought last year looked especially good since it is a little smaller than the others I looked at, and has several GPIOs, which I will need for one of the projects I have planned. One inconvenient thing is the 2mm pitch of the pins, which is slightly smaller than the 2.54mm, or 0.1'', pitch of a breadboard, but I soldered a small adapter. The firmware behavior is a little different than what some of the tutorials say to expect, but I was able to get a list of wireless networks at my house and connect to the WiFi at our hackerspace.
The LED of my friend's ESP8266 only lit dimly on my breadboard, as the voltage dropped down as low as 2.3v when run through the 3.3v LM1117 regulator I was running my repurposed 5v supply through. We haven't been able to figure out why this happens yet. For my chip the voltage also sank to about 3v, but it was still enough to keep the chip working. The supply itself seems to be good, as it delivers 5.18v, so I think the problem is with the regulator. When I tested the supply without the regulator on a breadboard with the 74ALS193 counters for the Brainfuck microcontroller, one side of the breadboard was down to 4.8v while the supply was still at 5.18v. Moving the jumper wires on the power rails around brought everything back to 5.18v

Wireless Breadboard
This project was especially exciting to me because it can be used to debug several of the other projects. To begin with I cut one of my 8x12cm protoboards in half and soldered single-row female headers to them, so a breadboard with male headers soldered on could be plugged into it. Unfortunately, I miscalculated the width of the breadboard and soldered the female headers on too wide apart. My local shop has been out of headers lately, so I tried to desolder the headers and broke a row of them in half in the process. So far I would consider this project a failure.

This is an essential part of the 6502-based calculator I am hoping to build soon. Unfortunately, it has been my main source of headaches over the past few weeks. First of all, I tried to program the chip with an MSP430 generating JTAG signals from an svf file but this failed. After some searching, I found out that the JTAG standard is not really "standard" at all, and chips from different manufacturers handle the standard differently. Next, I tried generating a pcf file from the svf file, because it contains the actual states of every pin on every clock cycle. Although this worked and I could program the chip, the programming steps were ridiculously complicated. After using Atmel's WinCUPL program (which itself is rather unpleasant to use) to generate a JEDEC file, I convert it to an svf file with the Atmel ISP program. The problem with this is that the program offers a couple of nonsense error messages and just crashes if the FTDI cable I use to communicate with the MSP430 is still plugged in when I start the program or click the button to generate the svf file. Next, I have to switch to a virtual machine to generate the pcf file, since Atmel's SVF2PCF utility is 16-bit only.
After generating this, I have to replug my FTDI cable into USB and start a program I wrote myself to stream the PCF bytes to the MSP430. In an effort to streamline the process, I tried using Altera's SVF2PCF utility to generate the pcf file, since it is 32-bit, but unbelievably it leaves out all delay statements necessary for programming. When I tried transferring this file, the CPLD stopped responding and is now essentially bricked. For some incomprehensible reason the pins necessary for programming can be reassigned to other purposes, rendering the chip unprogrammable. At $14 apiece, this was an expensive error to make.
When my troubles with this chip started, I ordered a Byteblaster JTAG programmer, as the Atmel datasheets list this as a possibility for programming the chip. When it arrived, I quickly found out that the USB Byteblaster I had ordered has nothing at all to do with the Byteblaster cable that Atmel ISP can use. The open source driver I tried for the programmer caused my Windows 7 computer to crash with the blue sreen. Next, I ordered a USB to parallel converter cable, since the schematic for the Byteblaster is just a 74HC244 chip connected to the parallel port. So far I have not tried programming with this chip and may go back to programming with the pcf files generated by Atmel's 16-bit SVF2PCF utility.

Improved 6502 Virtual Trainer
In my post about GCC for the STM32F429 I explained how difficult it had been to get a GCC toolchain running. While I did get the toolchain to work in the end, I was unable to make any of the USB-to-serial examples work. This is very attractive for this project because I could use the chip as a Virtual Com Port and wouldn't need an FT232 chip or USB-to-serial cable. Many examples used the STM32CubeMx program from ST to generate the base code. None of the generated projects, however, can be opened with Eclipse, This is especially disappointing considering that the page for the utility lists GCC as a supported toolchain (although it is not actually in the list of toolchains in the project generator!) and provides an Eclipse plugin form of the utility. As I stated before, developing for STM32 with free tools has been a real pain! I tried the OpenSTM32 IDE, which is based on Eclipse and the libopencm3 library. This was able to compile a USB project generated by STM32CubeMx, but not without a good bit of fiddling with the files generated.
Next I soldered a small board for the 6502 that fits on the STM32 board. The pins of each port are not grouped together on the chip or on the headers on the board, but 8 of the 16 pins of port A are grouped together so I connected the 6502 data bus to them. Pins PA1 and PA2 only rose to 0.6v when driven high, which seems to be due to them being connected to some of the peripherals on the board. I connected PB1 and PB2 in those pins' place, so reading or writing the data bus means combining data from two different ports, but it does work. So far I have the chip working in single-cycle mode with the same software I made for the first trainer. My plan is to leave this software unchanged so it will work with either board.

Our hackerspace is sponsoring a convention for makers in August and I would like to show some of my calculator projects there, so for the next two months I plan to focus mostly on the Improved 6502 Trainer and ATF1508 CPLD. These will both be necessary for the next calculator I want to build.

Wednesday, May 13, 2015

Summer Hackathon

Over the past year, I have not had as much time as I would have liked to devote to my electronics projects because I have been so busy with school. Hopefully I will be able to catch up this summer. My goal is to finish some projects I have already started on and start on some others I have been planning for a long time.

Here is a list of what I will be working on. Even though I probably won't have time to finish them all, these are my goals for the summer.

EEPROM Computer
As part of another project, I got interested in using an EEPROM lookup table to do four bit additions and ended up with this test setup. A 32 KB EEPROM can hold 64 tables, which is enough to implement all the op codes for a full CPU. Hopefully this will greatly reduce the amount of logic involved. All that should be needed are some counters, buffers, and a multiplexer.
So far I have finished most of a simulation in Atanua and started on a symbolic assembler. After I finish the assembler and have the simulation running, I will move everything to perfboard and program the op codes and source code into real EEPROMs.

8-bit Homebrew Computer
This project is something I have been thinking about for a long time. I won't say exactly how I plan to do it yet but looking on the internet I haven't found anything similar. It won't be possible to simulate this project in Atanua, so I plan to build it directly on a breadboard. The same assembler from the EEPROM Computer should be able to be changed to work for this also. I'm not sure yet whether it will be worth it to make a PC simulator for this project.

Brainfuck Micrcontroller
After I finished the simulation for this project, I did not do much more work on it. The simulated version is four bits and will have to be expanded to eight in the final hardware. The software for the project is very simple, as all it does is convert Brainfuck commands into simple op codes. 

Juggalo Robot
My brother and I started work on converting a remote control car into a robot. It will have a baby doll on top with moving arms and a rotating head. He decided to paint the doll's face and make the robot juggalo themed. He got motor drivers working with an Arduino for servos in the arms and a stepper for the head. My work so far has been to reroute motor control signals on the car from the motors to a microcontroller. That way another microcontroller in the remote control can send motor control signals over the radio, which the microcontroller in the car will intercept and interpret. Then it can activate the motors, servos, or stepper according to the signal sent by the remote. The hardware is mostly finished. All that's left is the software, which should be pretty simple. 

Last year we had a fun night doing projects with some SparkCores at our hackerspace and I decided to get a hold of an ESP8266. At $4 it was much cheaper than a SparkCore, even if it is not as easy to program. Unfortunately, I have not had time to even hook it up and try anything with it. One of my plans is to install it in a calculator for an idea I have been thinking about for a long time. One of the challenges will be getting it to connect correctly to WiFi at my university or local cafes. Another idea is to use it to program MSP430s or EEPROMs from my Chromebook, since it can't program them directly over USB.

Wireless Breadboard
This is a project I put a lot of thought into before I found out that it has already been done. My plan is to use IO expanders to control every row of a breadboard with a microcontroller. For rows that should be connected wirelessly, the microcontroller will read and relay signals to the appropriate row. This will be comparatively slow because the microcontroller will be bitbanging both the input and output of the IO expanders. Another project I saw used an FPGA, which would be much faster, but using IO expanders will hopefully be an acceptable solution, even if it is much slower.
All the connections between rows will be set on the PC, which is hopefully more convenient than plugging in wires. The main advantage will be monitoring the rows and displaying data in an easy to read way on the PC. This should really speed up debugging. Also, output signals can be controlled from the PC, so programming EEPROMs or other chips should be easy.

For my next 6502 project I want to use a CPLD for the address decoding. The ATF1508 is one of the few ones left in production that runs at 5 volts. It can be programmed over JTAG, so I started soldering a programmer that will use an MPS430. The chip comes in PLCC. so soldering the adapter will be a little inconvenient. My plan is to add LEDs and dip switches so I can test my designs after programming.

BASIC Interpreter
A couple of projects I would like to do eventually will need to run a BASIC interpreter. One of them is the wireless breadboard mentioned above. It would be better for new functionality, like device programming, to be done with some kind of script. That way, new scripts can be transfered to the chip at run time, instead of having to reflash the chip every time.

LCD Programming
Some of the upcoming projects will need an output of some kind. A four inch LCD should work well for the ones that a 20x4 character LCD isn't enough for. Hopefully I can get one kind of LCD going that will work for several of the projects. Another option is a 5.5 inch LCD I got a few years ago. It is much larger but requires -27 volts for contrast. This is not easy to generate, but if I can get it going, I will hopefully be able to buy several more pretty cheaply. It would work well with homebrew projects if I can get it working without a microcontroller. The STM32M429 board I have been working with also has an LCD that I would like to get going.

Improved 6502 Trainer
The 6502 Virtual Trainer was nearly finished when I stopped working on it months ago. It works really well, except that the max speed is just under 0.02 MHz. Now that I have my STM32 board running, I hope to port the code for the project from the MSP430. It ran the BCD multiply routine from the microcontroller comparison about 15 times faster, although that's probably not a good indicator of how much faster it would be for this project. There are a few changes to how UART works that might speed things up also. Another speedup will come from driving the GPIOs directly, instead of through IO expanders. Hopefully all of this together will give me the 50x speedup I need to hit 1MHz. At first I intend to make a board that will plug into the STM32 board directly and possibly use a UART cable for communication. When I figure out how to design PCBs I will make a standalone board with an STM32F429 and an FT232.

Improved RPN Calculator
For one of my friends I would like to remake my original RPN Scientific Calculator. This time I will use an LPC1114, which will allow me to copy numbers to the chip's memory before calculating. This should greatly increase calculation time because the external memory won't have to be accessed during any calculations. This will also make the firmware smaller. It should easily fit into the 32 KB the chip has, so two microcontrollers won't be necessary. Also, I would like to use a 23LC1024 SPI SRAM this time instead of parallel RAM. Altogether, the circuit should be very small.

Tuesday, May 12, 2015

GCC for STM32F429

About a year ago I bought a Discover kit from ST. This one has an STM32F429, which is an ARM M4 running at 168MHz with 256 KB of RAM and 2MB of Flash. This seemed like the beefiest microcontroller I would need for a long time. It also has a 2.4" LCD and an external 64 Mbit SDRAM. At only $24 it seemed like a really good deal.

Last year when I had some free time, I tried to get a blinky program running for the board without much luck. The example I found had a makefile but I could not get make to work with it. For one, it could not find the rm utility to delete files. Since then I have found out that utilities like these can be installed on Windows also.

Next, I tried getting GCC working with Eclipse. For all other microcontrollers I use Code::Blocks, but the tutorials I found used Eclipse. One tutorial had no less than 25 steps to get it working, which is absolutely ridiculous if all you want to do is blink an LED. Good for the author of the blog for being so extensive but I wish ST offered an easy way to get GCC working just to get started. Another option many websites pointed to was Sourcery CodeBench. There is a free version for five different processors but the ARM version is no longer free. Next, I tried OpenSTM32. This is the Eclipse IDE prepackaged with GCC and everything needed to compile. It installed fine but when I tried to update it, the installation failed. Using the old version, I tried to generate a new project using the Standard Peripheral firmware, which for some reason is not included in OpenSTM32. The download for that also failed. Next up was Keil. It seems to work well but I do not like being limited to only 32 KB of firmware. App note 230 from Keil shows how to get it working with the STM32F4 Discovery board, which is similar to the board I have. The app note shows how to use the Pack Installer in version 5.10 of the MDK software to download a blinky program or another blinky program based on an RTOS with threads. Unfortunately, the blinky program the entire app note is based on is completely missing from the packages in version 5.14 of MDK. There doesn't seem to be any way to install a simple example without the added complications of an RTOS, which is certainly overkill for blinking LEDs.

What I settled on in the end was a set of GNU ARM Eclipse Plug-ins. There is only one thing to install in Eclipse and the plug-ins generate everything from a wizard. The included blinky program is set to work with the STM32F4 Discovery board, but it compiled and ran fine after I changed the LED pin defines. To upload I used ST-LINK, which is also quirky in that it does not actually use the file you select in the Program window. Instead it uses the last file that was "loaded," so if you select a file then recompile, it will not actually use the new version. This is annoying and took a while to figure out. After I was sure I had things working right, I set Eclipse to upload with ST-LINK automatically after each compile.

To test the new setup, I ran the BCD multiply test from the microcontroller comparison. Since I'm on vacation and don't have all my other stuff, I timed it with a stopwatch and got about 24 seconds. This is five times faster than the LPC1114, which is pretty good. Next, I would like to design an improved version of the 6502 Virtual Trainer with this chip.

Monday, May 4, 2015

4x4 Full-Adder EEPROM Lookup Table

My first use for the EEPROM programmer I have been working on is a lookup table. This will be for another project I have not started on yet. Before I plan much more for that, I wanted to make sure my idea would work. This project will need to add and subtract 8 bit numbers and a lookup table is one way to do that. The 8k EEPROMs I'm using have 13 address lines which allow four pairs of bits to be added with a carry bit. When I first started I fed the carry output of each pair into the carry input of the next pair. This wasted outputs and inputs. It probably would have taken a long time for the carries to propagate also. Now, it only needs nine inputs and the remaining four could be used to select functions other than adding. The data in the EEPROM was simple to generate with a small script that calculates all possible input combinations.