A Python script for programming Zilog MCUs – Z8F2480


Zilog may be a rather obscure MCU manufacturer nowadays, but for the ones who uses its MCUs, the script described here and published on GitHub may be useful.

This is a Python script developed to program Zilog MCUs through the COM port (RS232 or emulated with an USB-UART converter). It was specifically developed in order to be able program Z8F2480 MCUs through a COM port.


The Z8F2480 is a 8-bit MCU with a nice set of features, including 24 kB Flash, internal oscillator (dispensing the use of crystal oscillators), SPI, I2C, ADC, an on-chip low power OpAmp and two integrated analog comparators.

For some unknown (and to me uncomprehensible) reason, Zilog decided to drop out support for the Serial Smart Cable in its Z8F2480/1680/0880 MCU line. In order to use them, the first option was to buy the rather expensive USB Smart Cable. An anachronism nowadays, in a world full of manufacturer-subsized development kits and tools.

So, I decided to find another way. The OCD (On-Chip Debugger) commands used during programming and debug are detailed described in the datasheet. Also, an application note by Zilog put some more light on how to develop a programmer. All the information available pointed out that it was possible to program the MCUs through a COM port. After spending some time, scratching my head a lot to develop and debug, the script was complete.

OCD interface

The hardware needed is a Serial Smart Cable or a DIY equivalent, which can be easily assembled. As it is stated on the datasheets, the minimum hardware is only composed of  a RS232 transceiver (or an USB-UART transceiver), a diode and a pull-up resistor.


The script is divided in four parts:

  • programmer.py – the main application code.
  • intelhex2bin.py – converts a hex file to binary data.
  • crc_calc.py – calculates the CRC based on the algorithm used by Zilog (CCITT algorithm, input reflected, output reflected and output XOR’ed with 0xFFFF).
  • zilog_ocd.py – library of functions implementing OCD commands.

The main application input arguments are:

  • Firmware to be downloaded, as a hex file
  • COM port
  • MCU

For example, in order to program a Z8F2480 with firmware.hex through the COM1, the input arguments are:

python programmer.py firmware.hex COM1 Z8F2480

The execution sequence is:

  • Convert hex file to binary data
  • Open COM port
  • Enter debug mode: at this point, with the programmer attached to the MCU, the user is required to reset the MCU, either by pressing a reset button or power cycling the target board.
  • Read OCD revision
  • Check if MCU is in debug mode
  • Set Flash Programming Frequency registers
  • Mass erase Flash
  • Download code to Flash
  • Read Flash CRC and compare it with source CRC
  • If CRC is different, the all the Flash memory data is read back to the computer (Warning: this operation takes several minutes)

Zilog programmer

The project is published on my GitHub.


  • Firmware in an Intel Hex file format – the ZDS must be configured to generate Intel Hex32 files (Project -> Settings -> Linker -> Output -> Executable formats).
  • Hardware – Serial Smart Cable or equivalent.
  • Python 3

Future improvements

This code is useful to me, but may be improved in some ways.

First, I have had problems reading Flash memory data back to the computer. Although the OCD command specifies that up to 65535 bytes may be read at once, in reality I was able to reliably read only 2 bytes at a time. So, the Flash read back operation is very slow and may take several minutes. After some hours spent debugging and not being able to correct this, I decided to look for alternatives and perform a CRC check to validate the memory integrity. The Flash read back is still executed, but only if the CRC check returns an error.

Second, it is being used only with Z8F2480 and Z8F082A MCUs. If you wish to use it with other Zilog MCUs, the could should be modified. The mods needed are easy: only change get_mcu_flash_size() and get_mcu_clock() functions to comply with the new MCU specifications.

Another interesting feature to add is a graphical interface, maybe built with the Qt framework.


Microphone preamp with phantom power


Some years ago, I’ve had the need to build a microphone preamp. I was planning to buy a condenser microphone (Behringer C3), but had no way connect it to my PC soundcard.

At that time, I didn’t have a soundcard with balanced inputs and phantom power. So, I decided to exercise my electronics knowledge and build a microphone preamp from scratch, with these characteristics:

  • Balanced input
  • Ability to supply 48V to the mic through phantom power
  • Unbalanced output
  • Mains powered (127/220 V)
  • Use readily available components (for me, at that moment)

For those who aren’t familiar with phantom power, Wikipedia provides some useful explanation.

The design is divided in two blocks: the power supply and the preamp itself.

Power supply


For the power supply, I’ve decided to use a transformer with 12V secondary, as in my case it was readily available. Its design was based on a project available at Elliott Sound Products, with some modifications.

To provide 48V to the mic, it is needed to elevate the secondary voltage somehow. It is done by a voltage quadrupler/rectifier, followed by a linear regulator. The quadrupler/rectifier is able to provide approximately 60V DC to the linear regulator. This topology allows the use of inexpensive and easily available 12V transformers.

The linear regulator is based on a BD139 medium power NPN transistor and a 1N4749 Zener diode (with a Zener voltage of 24V). The trimpot must be adjusted until the output is at 48V.

48V is required for the mic, but to power the preamplifier, two Zener regulators were inserted, to provide 24V (positive supply to the opamps) and 12V (reference voltage to the amplifier).

Overall power dissipation at the linear stage is relatively low, and I haven’t seen the need to fit the BD139 transitor with a heatsink. As the preamp is not meant to be battery powered, low power consumption and high efficiency weren’t as important as simplicity and low noise operation.



The preamplifier itself is a differential amplifier followed by a inverting amplifier with adjustable gain. The opamp may be a NE5532 (as I used) or any other audio opamp. 1N4148 diodes are used as protection against ESD and wrong polarity.

For best performance, the resistors that comprise the differential amplifier should be of low tolerance, but I’ve built mine with 10% tolerance carbon resistors and hadn’t problems with noise.

Output level is adjusted through the potentiometer, which sets the inverting amplifier gain. It is recommended to use a audio taper (logarithmic) pot.


At the mic input, a female XLR connector is used, and care should be taken to wire it properly, or the microphone can be damaged. The diagram below represents the frontal view of the XLR connector. Some connectors have numbers identifying each pin.

XLR pinouts.svg

  • Pin 1 – Ground (cable shield);
  • Pin 2 – Positive polarity terminal (aka “hot”);
  • Pin 3 – Negative polarity terminal (aka “cold”);

Source: Wikipedia.

With the unit properly mounted and powered, the voltages between pin 2/pin 3 and pin 1 should be approximately 48 V each one.

A 1/4″ or 1/8″ mono jack may be used as output connector. The output can be directly connected to a amplifier, a mixer or a soundcard.


The design can be optimized in many ways, but considering the compromise between simplicity and performance, this preamplifier has worked very well for me.

This project was designed to be used with balanced microphones with phantom power, or any compatible equipment. Its use with guitars, dynamic mics or any uncompatible instrument/equipment may cause damage.