Willem Programmer with Linux

Hint: This is an historical article. Nowadays I would not recommend the Willem Programmer anymore. I replaced it after having many trouble with large EPROMs. My new Eprommer is a Batronix BX32P with works perfectly with Linux.

There is a hardware design called „Willem Programmer“ which is continuously developed further by several people. It seems that the company „KEE Electronics“ provides the software and some hardware versions today. The original design may come from the company Sivava which also sells a version of the programmer.

I bought a Willem 5.0E Programmer from some chinese source. This hardware looks different from e.g. the kee one.

There are versions with parallel connector and others with pure USB connector. The parallel versions are cheaper.

The programmer comes with a software for windows. Before buying, I checked the Internet and found that there is a reimplementation for Linux, called „geepro„.

Hardware preparation

My version of the programmer is controlled via parallel port and uses a USB cable for power connection. So it can only be used with a PC that has a parallel port. I added a cheap PCI-card with a parallel connector to my PC, so the hardware setup is simple.

Install geepro

Just download the software (Link here). It must be compiled from source. The installation consists of three steps (configure, buiild, install). See its README file. If the configure part lists libraries that are missing, use your packaging tool to add these (development versions of) libraries. On a clean OpenSuse 13.1, I had to install 3 additional libraries.
After successful build, I installed the software to /usr/local. The install step listed an error „No such file or directory: ‚/usr/local/lib/geepro/drivers/altera_byteblaster.driver‘ but repeating the install step several times succeeded 🙂

Use geepro to control willem programmer

There seems to be no documentation for using geepro.

After installation of geepro, you can start the software by typing „/usr/local/geepro“. It comes up with a user interface. Select „Willem 4.0“ as programmer, select the device (for me „parallel port parport0) and test the connection. A LED should flash on the programmer and the test should give a „connection ok“ dialogue box.


Then Select a chip. After selection, the required switches are listed as a picture on the user interface („Chip“ tab). Adjust all switches as requested and then insert the chip. Then, its content can be read or written („Buffer“ tab).
The content can also be manipulated in several ways.

There is also a „HW Test“ pad. I haven’t used it so far.

Atmel AVR Mikrocontroller mit OpenSuse: I2C, BeispielEEPROM-Ansteuerung

I2C (auch TWI=Two Wire Interface genannt) ist ein sehr hardware-naher De Facto-Standard, mit dem zwei oder mehrere Geräte oder auch Bausteine über einen gemeinsamen Bus miteinander kommunizieren können. Geräte können am Bus als Master oder als Slave teilnehmen. Über die Geräteadresse können mehrere Geräte unterschieden werden. Von verschiedenen Herstellern werden Chips angeboten, die das I2C Protokoll beherrschen. Die größeren AVRs bieten auch Unterstützung für dieses Protokoll.

Die Kommunikation erfolgt bei I2C über zwei Leitungen, SCL (serial clock) und SDA (serial data). Grob gesprochen wird pro Clock-Impuls ein Datenbit übertragen. Über diesem grundlegenden Protokoll sind bestimmte Abfolgen der übertragbaren Kommandos vorgeschrieben. Die Kommandos werden inhaltlich durch das jeweilige Gerät oder den jeweiligen Chip bestimmt. Die grundlegende Spezifikation von I2C ist unter http://www.nxp.com/acrobat/literature/9398/39340011.pdf zu finden.

Im folgenden sind die einfachen Kommandos des Busses kurz dargestellt: START, STOP, Bit-Übertragung, Acknowledgement. Komplexere Dinge bitte in der Spezifikation studieren.


START Condition: Beginn einer Übertragung
Während SCL high gehalten wird, wechselt SDA von high auf low

STOP Condition: Ende einer Übertragung. Während SCL high gehalten wird, wechselt SDA von low auf high

Übertragung eines einzelnen Bits.
Während einer positiven Taktflanke muss SDA stabil gehalten werden auf high oder auf low. Dies ist der übertragene Bit Wert

Acknowledge
Der Slave signalisiert dem Master dass er alle 8 Bits eines Bytes erhalten hat. Dazu gibt der Master die SDA Leitung frei (die unbelastet über den Pullup Widerstand auf high gehalten wird). Der Slave zieht seinerseits die Leitung auf low während der ganzen folgenden (neunten) positiven Taktflanke. Dies interpretiert der Master als Acnowledgement.

Praxis

Beispielhafte Chips sind die seriellen EEPROMs der Reihe 24Cxxx. Ich habe ein EEPROM 24C512 zum Experimentieren verwendet. Der Wert „xxx“ steht dabei für die Speichergröße in KBits (02…1024). Das 24C512 mit 512 KBit=64KByte kann mittels I2C gelesen und beschrieben werden. Das EEPROM kann benutzt werden, wenn die Größe des On-Chip EEPROMs des AVR nicht mehr ausreicht.

Das Protokoll kann in Software implementiert werden oder, wenn vorhanden,  kann die I2C Hardware eines Controllers verwendet werden.

Peter Fleury hat auch hierfür eine Bibliothek geschrieben, für den Hardware-Fall, bei der der AVR als I2C Master auftritt. Diese Bibliothek kann unter  http://homepage.hispeed.ch/peterfleury/i2cmaster.zip heruntergeladen werden. Als Beispiel ist der Zugriff auf ein 24C02 im ZIP File enthalten. Die kleineren EEPROMs kommen mit einer 8-Bit Adresse aus, für die größeren wie das 24C512 benötigt man eine 16-Bit-Adresse.


Pin-Belegung des 24C512.

Das 24C512 hat eine 2-Bit Adresse, so dass 4 solcher Bausteine am I2C-Bus unterschieden werden können. Die „Bausteinklasse“ 24Cxxx hat den festen Adressteil 1010xxxx (Binär) bzw. 0xAx. Die Chip-Adresse wird festgelegt, indem z.B. A0=A1=0 an GND gelegt wird. Dann kann man mit der I2C-Adresse 0xA0 diesen Chip ansprechen. Ein anderer, bei dem A0=1 und A1=0 gelegt wurde, ist mit 0xA1 anzusprechen. A0 und A1 sind 0, wenn sie nicht anders beschaltet werden. „WP“ heißt „Write Protect“, ein Hardware-Schreibschutz, der aktiv ist, wenn WP auf Vcc gelegt wird. Wird er offen gelassen oder auf GND gelegt, kann man das EEPROM auch beschreiben.


Simple Beschaltung des 24C512

Achtung: Auf dem Pollin Experimentierboard ist der WP-Anschluss leider fest auf Vcc gelegt, d.h. man kann ein normal eingestecktes EEPROM nicht beschreiben. Abhilfe schafft Einstecken mit abgebogenem WP-Pin.


24C512 auf dem Pollin Experimentierboard 2.0.  Da bei diesem Board der WP-Pin fest auf Vcc liegt,  muss man das EEPROM mit abgebogenem PIN einstecken, um es beschreiben zu können.

Im folgenden ist der beispielhafte Schreibzugriff dargestellt (der Code von Peter Fleury wurde im wesentlichen nur um die 2-Byte Adressierung erweitert):

#include "i2cmaster.h"

#define Dev24C512  0xA0      // device address of EEPROM 24C512, see datasheet

int main(void) {
     unsigned char val, ret;
     int addr;
 
     i2c_init(); // init I2C interface
 
     ret = i2c_start(Dev24C512+I2C_WRITE); // set device address and write mode
     if ( ret ) {
         /* failed to issue start condition, possibly no device found */
         printf("failed to issue start condition, possibly no device found.n");
         i2c_stop();
     } else {
         /* write 0x75 to eeprom address 0x05 (Byte Write) */
         /* issuing start condition ok, device accessible */
         addr=5;
         val=0x75;
         printf("writing %0x to address %0xn", val, addr ); 
         ret = i2c_write( (addr/256) ); // write hi address 
         if (ret!=0) 
             printf("error in writing value, ret=%0xn", ret );
         ret = i2c_write(  (addr%256) ); // write lo address 
         if (ret!=0) 
             printf("error in writing value, ret=%0xn", ret );
         ret = i2c_write(val); // ret=0 -> Ok, ret=1 -> no ACK 
         //printf("ret=%0xn", ret);
         if (ret!=0) 
             printf("error in writing value, ret=%0xn", ret );
         i2c_stop(); // set stop conditon = release bus
     }
}

Die ganzen dargestellten Prüfungen der Return-Werte sind nicht unbedingt nötig, aber bei der Fehlersuche hilfreich. Das Lesen geschieht wie folgt:

i2c_start_wait(Dev24C512+I2C_WRITE); // set device address and write mode
printf("reading value from address %0x: ", addr ); 
ret = i2c_write( (addr/256) ); // write hi address 
ret = i2c_write(  (addr%256) ); // write lo address 
i2c_rep_start(Dev24C512+I2C_READ); // set device address and read mode
ret = i2c_readNak(); // read one byte
printf("read value=%xn", ret );
i2c_stop();

Mit einem Logik Analysator wurde die Übertragung von Signalen betrachtet. Diese sind im folgenden dargestellt.

Ein AVR überträgt mit Hardware I2C Daten an das EEPROM.

Der Logikanalysator wurde auf asynchron, 200ns clock period gesetzt. Eine positive Taktflanke ist 8 Takte lang, also 1600ns=1,6µs. Die Übertragung eines ganzen Bytes dauert 21µs, so dass man auf eine Übertragungsrate von etwa 50KByte/s kommt. Der AVR kann noch deutlich schneller.


Das erste übertragene Byte, 1010.0000 = 0xa0

Das Byte hier dargestellt mit zusätzlichen Infos

ein weiteres übertragenes Byte, 0000.0101 = 0x05

Das Byte hier dargestellt mit zusätzlichen Infos