Wednesday, April 27, 2011

Project Papydoo - Part 2

This is a follow up to
Project Papydoo - Part 1

In Part 1 I've covered the hardware. Part 2 is about the firmware. There is also an introduction to the ZDS Studio II development environment, because its not as well known as the usual suspects (Atmel AVR, Microchip PIC, etc).

7. The Zilog ICD USB cable

Programming and debugging all recent Zilog MCUs is done with the same probe, or "smart cable". A serial RS-232, USB and Ethernet version is available. The USB version is bundled with most Zilog dev. boards, but can also be purchased separately from DigiKey or others for around $35. This probe does more than just in-circuit programming. It does full source-level in-circuit debugging (stop, trace, breakpoints, watches, registers content, etc.), all from 1 pin on the MCU.

The "native" connector on the ICD probe is a 2x3 pins ribbon cable header. Zilog has organized the pins layout so that its "reversal" proof, I guess.

Personally I don't like this connector. I've devised my own 3 pins .1" SIP connector with only the 3 signals: VCC, DBG and ground.

8. The Zilog Development Studio II IDE

Zilog freely provides a complete development environment suite called "Zilog Development Studio II" for the eZ8 (as well as other) family of Zilog microcontrollers. This is the complete, full-featured version. No demo, trial, or features limit. Its free and complete. Although some developers might find it lacking advanced features found in high-priced tool chains, everything is there for basic ANSI C or assembly development, programming and source-level debugging. For this project, I've used the recently released version 5.0.0. It features a more advanced source editor (with auto-completion, code block folding) and some other minor changes from the previous versions.

For people familiar with Microchip PIC, ZDS is like a less bloated version of Microchip MPLAB with an ANSI C compiler natively included. As far as I know, its mostly an MS Windows app., but heard some people running it inside Wine with Linux, and using the RS-232 ICD probe. See the Zilog forum for more details.

Doing projects in ZDS is very straightforward. You create a "New Project" from the file menu, answer a few questions about the MCU family used, memory size, C memory model, and then add source files to the project.

The full source code, released under a Creative Common license, is available for download at the end of this post.

The code is lightly documented and should make sense to most people familiar with C development on microcontrollers.

Their are a few minor things that I will explain in the following sections, for people unfamiliar with Zilog eZ8 MCUs.

9. eZ8 stop mode and C startup module

When the eZ8 enters stop mode (low power sleep), it stops executing code, turns off the oscillator and wait for an event to trigger a "wake-up", or recovery.

Recovery can come from a state change on an input pin, an external reset or the watchdog timer timing-out. The later is used to "wake-up" the eZ8 after about 1 second of sleep.

Unlike the Microchip PIC16F for instance, code execution doesn't resume where it left off, but at the reset vector. This causes problems with the default C startup module if you want to preserve states or variables content while in sleep. By default, the C startup code clears the RAM content (with zeros), and copy values from ROM for initialized variables. A custom version of the C startup module (startups.asm) was modified and included in the project's folder. This version doesn't clear the RAM on startup:

In the "main" function, a different code path is taken if the device is recovering from sleep, as oppose to a normal power-on reset.

10. "rom"? "near"? "far"?

The rest of the code is pretty straightforward stuff. It could easily be ported to PIC or AVR MCUs, apart from a few nuances in the C code: The "rom", "near" and "far" storage class modifier. The eZ8 is an Harvard architecture microprocessor: Code and data are stored in different address spaces. This poses problem with large arrays of constants (like character font table, menu text strings, ...). Zilog's ANSI C compiler allow the use of the "rom" storage class modifier for explicitly placing arrays in ROM, and generating the proper assembly code to access it:

char rom table[] = { [ ... large data set ...] } ;

The "near" storage class modifier is used in the code for compatibility purposes only, because some other members of the eZ8 family have more the 256 bytes of RAM and uses "far" pointers and the large memory model. In the small memory model, everything is "near".

Near pointers? Far pointers? This brings back memories from the days of x86 programming on MS-DOS :)

11. Bit Order Reversing

Being kind of lazy, I've used a character font table designed for a Nokia 5100 LCD mono display. The HT1632's frame buffer is almost identically structured, except the rows order are reversed: Row 0 is at the bottom of the display, versus the top for the Nokia LCD. This makes the font upside down when drawn in the frame buffer. Correcting the orientation implies reversing the bits order inside a byte: Bits 0 - 7 to bits 7 - 0. There are no efficient (and elegant) ways to do that in C, so I've used in-line assembly to call the BSWAP instruction who happens to do just that, in 1 instruction cycle.

12. Analog to digital converter (ADC)

The ADC of the Z8F083A is quite fast, at 2.8us per conversion. There is not much code that could get executed while waiting for the result. So when I initiate a conversion, I just wait for it to finish and get the result. The ADC is 10 bits and uses an internal 2.0 volt reference.

13. General Purpose Input / Output (GPIO)

The LED matrix operates at 5V, and the MCU operates at 3.3V.

Level translation to 5V is done by configuring output pins in "open-drain" mode, with external pull-up resistors to 5V.

The pushbutton input pin has an internal pull-up resistor enabled.

14. Source Code

The source code can be downloaded here

Monday, April 18, 2011

Project Papydoo - Part 1

Papydoo is is a project I've built recently.


Normally, Papydoo is asleep. The enclosure sits on top of a vibration sensor. Papydoo is waken up by a sufficiently strong vibration. Two eyes are then displayed on the LED matrix, wandering randomly around. After a few seconds with no vibration detected, the eyes close and Papydoo goes back to sleep. Also once in a while (odds: 1/5), a parade of "Space Invaders" is displayed, which bounces up with vibrations. There is a button at the back to manually switch through different modes: Eyes, Space Invaders, Vibration bar graph and batteries voltage. The project runs from 4 AA batteries and draws around 150uA when sleeping, and around 150mA when awake.

1. Vibration Sensor

The vibration sensor is piezoelectric. I've salvaged a crystal element from a 75W plastic "horn" type tweeter (pictured above). These tweeters can be found for around $5-$10 at electronic parts stores. I've cut out the paper cone glued to one side of the crystal, leaving only a flat disc around 1" in diameter, with two braid wires coming out. This disc then became one of the pad underneath the box. I've put 2 rubber pad on each side at the back, and the crystal at the centre on the front, where most of the weight of the display is.

The trick is to "sandwitch" the piezo crystal between the enclosure and the sitting surface. Any vibration is transmitted through the crystal and mechanical pressure is transformed into voltage.

2. LED Matrix Display

The front display is a red LED 32 columns by 8 rows matrix. The module was bought from SureElectronics on Ebay for around $11 shipped (!). Its based on a Holtek HT1632 which contains a frame buffer and does all the multiplexing work. Communication is done in a serial, SPI like fashion. The module works at 5V. A rectangle was cut out from the front of the wood enclosure to fit the display. The balsa wood is quite thin, so simple scoring and cutting with a utility knife did the trick.

3. The Microcontroller
The Zilog Z8F083A is an 8 bits microcontroller:

Main features:
- 8K flash ROM
- 256 bytes RAM
- 20MHz internal oscillator
- Fast 2.8us 10 bits ADC
- 20DIP package available
- 2 uA sleep current with watchdog timer running.
- 2.7-3.6V operation, with 5V tolerant I/O
- Single pin in-circuit debugging (ICD) and programming

The Zilog eZ8 series MCUs are almost completely absent from the DIY / hacker / maker scene. I've been working with Zilog eZ8 microcontrollers in "work" related projects and already had the in-circuit debugger / programmer USB cable, a few eZ8 ICs and an extensive C codebase done over the years for it. I've worked with Microchip PIC also, but didn't have any suitable candidates on hand (PIC18F?). I did have a few PIC16F819, but didn't want to "bend over backward" trying to carefully "craft" the code in a 2K ROM MCU. I've also had a few Parallax Propellers, but it would have been overkill, and the Prop doesn't have any sleep / power-down mode nor 5V tolerant I/O. Too bad.

The Zilog ANSI C compiler and IDE (Zilog Developpement Studio II) are freely available to use and download on Zilog's website ( The toolchain is very simple to use and would deserve to be better known. More about the code in part 2.

4 - Circuit

This project operates from 4 AA batteries and is "on" all the time. So very low current draw (in the uA range) is essential for multi-months battery life.

When sleeping, 3.3V is generated through an ultra-low power MCP1700 LDO voltage regulator (1.6uA quiescent typ.). The MCU draws almost no current in sleep mode (about 2uA). The bulk is drawn by the MCP601 op-amp (150uA measured) always running and interfacing the piezo sensor to the MCU's ADC. Specialized op-amps exist with much lower current draw, but all I had was MCP601 "jelly beans" op amps, and 150uA was acceptable for this project.

The analog block is a non-inverting voltage gain / half wave rectifier / peak detector with bleed. All in one unit:

The watchdog timer wakes the MCU every 1 second. During this brief wake-up, the MCU turns on the on-chip ADC, performs a conversion and goes back to sleep if a determined voltage threshold is not reached. This sequence lasts about 170us, every 1 second. If the threshold is reached, full wake-up follows. The 5V supply is turned-on (through an IRF7343 MOSFET pair) and the display matrix is initialized.

5. Circuit board

The circuit was first put together on a breadboard and when everything was working as desired, a permanent version was done using a generic PCB with copper traces like this one:

This PCB is very common and can even be found at Radio-Shack. The IRF7343 dual MOSFET chip is an 8 pins SOIC SMT package and required to have "leads" soldered to it. An SOIC to DIP adapter could also be used for the less adventurous:

Here is a finished version of the board, assembled in the box with a battery holder:

A ribbon cable connects the led matrix to the main board. Separate power wires were used for the 5V supply:

There is a pushbutton at the back for manually switching the display mode:

6. Full Schematic