Showing posts with label Device programming. Show all posts
Showing posts with label Device programming. Show all posts

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 256KB 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 32KB 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.

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.

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):

SET PROMPT >
SEND "K"
SEND -n "L"
SET PROMPT G
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.