Gravis Interface Protocol

Posted by pulkomandy on Tue Nov 27 22:36:08 2012  •  Comments (0)  • 

Ever heard of the Gravis Gamepad Pro ? It's a gamepad using the old-fashioned PC gameport. It looks quite like the original Playstation controller and has a very solid build quality.

Those of you who know about the gameport limitations will quickly notice that there must be something non-standard about it: there are 10 buttons, while the gameport only allows 4. Even better, you can actually use 2 gamepads at the same time on a single port.

There are several modes accessible with a switch under the gamepad. These are 1-player, 2-player, and GrIP. In 1 player mode, you get 2 axis and 4 buttons. In 2 player mode, you get 2 axis and 2 buttons, and you can use 2 gamepads. In GrIP mode, each gamepad can use all 10 buttons, but this is not compatible with the games expecting a standard joystick.

I have some of these gamepads around, but my PC don't have a gamepad anymore. Since I'm not very happy with replacement hardware (I tried the Logitech Precision USB gamepad, but it doesn't look as nice and colourful), I'm thinking about building an adapter for these gamepads to plug them on an USB port. Of course, without opening and rewiring them. Not only this would void the long expired warranty, but I may still want to plug these gamepads to the system they were intended for (my 1995 Pentium 166 MMX).

There is some information on the internet about the protocol, but it's not easy to find. Heer is what I could get : a textfile with some info and the Linux driver for these joysticks. Since the textfile does not say everything the driver does, here are some notes that duplicate the text file and add the info from the driver.

First, the gameport pinout. It's a SUB-E 15 connector. The following pins are relevant:

  • 1,8,9,15: 5V power
  • 4,5,12: GND
  • 2,7,10,14: buttons 0,1,2,3
(the other pins are axis 0, 1, 2, 3, they are not used in GrIP mode).

When you use only one gamepad, buttons 0 and 1 are used as data lines. Button 0 is a 20kHz clock. On each rising edge of this, you can read the state of button 1. Frames are 24 bits long and holmd data as follows:

0 1      1     1      1    1
0 Select Start R2     Blue
0 L2     Green Yellow Red
0 L1     R1    Down   Up
0 Left   Right
The frame starts with a start bit, then 5 bits set high. Since the button data is split in 4-bit words with a 0 interleaved, there can't possibly be 5 set bits anywhere else, this makes it possible to detect the start of a frame.

Transmitting a full frame at 20KHz will take exactly 1.2ms. This is more than fast enough. It's likely that Gravis drivers on windows only polled the gameport only 20 or 25 times per second (or even less), and waited up to 2ms for a frame start. This was the only way for them, because these gameport buttons are not triggering interrupts.

When there are 2 joysticks connected, the second one uses buttons 2 and 3 exactly the same way. The Gamepad Pro has a pass through connector that swaps buttons 2 and 3 with 0 and 1 for the second device, like any Y-doubler joystick cable does.

My plan is to use a Stellaris Launchpad LM4F120 as an adapter. Why ? Because I have one and want to try playing with it. More interesting, this board has 4 SSI/SPI channels and they can be configured for up to 16 bit frames (where an AVR can only do 8 bits). Since our frames are actually 24 bits here, we'll have to cheat a bit. The plan is to use 2 12-bit frames. Another problem is since the bits come in in a continuous flow, there's a risk of getting out of sync. What I will try is configuring the SSI, reading 2 frames, and see if one of them starts with 0111110. If so, the system is in sync and should stay so forever. Else, wait for 1/20ms, reset the SSI and try again. This should shift by one bit until we get it right. If this approach fails, I'll have to revert to using GPIO and external interrupts. At 20kHz I think the Launchpad can handle it, even with 4 gamepads plugged in. Since the USB is handled in hardware I shouldn't run into as much problems as my amiga keyboard to USB adapter.

Discovering the STM32F3 Discovery

Posted by pulkomandy on Thu Sep 27 18:05:21 2012  •  Comments (3)  • 

So I just got this STM32F3 Discovery board. This is a development board from ST with a Cortex M4 chip, the mandatory leds and buttons, and some accelerometers and sensors.

The main problem is, as often, ST only offers code samples for commercial development environments. And I'm more of an open-source kind of guy. So let's setup some toolchain with free software.

First of all, get the files, this will be more convenient. This archive has the OpenOCD config file, the linker script, startup code, Makefile, and a stupid C code to show it all works (not even blinking a LED!).

Programming the board

That's the easy part. The STM32F3 Discovery has an embedded STLink/V2 interface. A nice thing about it is there are jumpers that allow to use the STLink part to program another device. However, there's a catch: the STLink can only be use to program STM32 and STM8 chips. It's not as flexible as other JTAG adapters.

Unfortunately, STM32F3 support is not part of OpenOCD sources yet. They have a patch set waiting, however:

Do not use OpenOCD 0.6.0 release packages, they don't have these patches in. You will need to get the sources from git and apply the patches above. Then, building OpenOCD is a rather straight-forward process (at least under Linux):

./bootstrap
./configure --enable-maintainer-mode --use-stlink
make
sudo make install
you need to enable access to the STLink hardware for openocd. Create the file /etc/udev/rules.d/99-stlink.rules and add :
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", MODE="0666"
Then test everything is allright. We use the config file for the STM32F4 since OpenOCD doesn't provide one yet for the STM32F3 discovery. They are close enough for this small test, but we'll need a more specific one later on.

Enter the following commands:

openocd -f /usr/local/share/openocd/scripts/board/stm32f4discovery.cfg &
telnet localhost 4444
reset init
reset run
When you enter 'reset init', the STLink should reset the CPU and the ledswill stop blinking. 'reset run' will make it run again and the led should resume blinking. If everything is ok, you're (almost) ready to debug!

Compiling

The Cortex M4 chip is some kind of ARM CPU, so you need an ARM toolchain. There are several to chose from: Linaro, Sourcery CodeBench Lite, a plain vanilla gcc, and so on. I used Sourcery Codebench, because I already have it installed. But it shouldn't matter anyway: we're not going to use their linker scripts or standard library at all. Just make sure you have some arm-none-eabi-gcc or similar compiler available in your PATH.

Linker script

To make it easier to use different toolchains, it's better to use our own linker script. I derived one from here.

The linker script tells the linker about several things. It defines the memory areas available in the chip, then tells where each section generated by the compiler must go. For example, all code sections are usually allocated in flash memory, while the variables are put in the RAM alongside the stack. Reset vectors usually need to be put at the start of the flash so the CPU knows what to do when booting.

Writing a linker script is not as hard as some toolchain-provided ones make it sound. If you only want to write plain C code, you can get away with something very simple. I plan to use C++ as well, but that doesn't add that much more stuff. I added comments to the linker script, so you should understand what's going on.

Startup code

An usual C program starts with a main() function. However, when working with microcontrollers, there are some things to do before you can reach it. These tasks are performed by the boot code, usually in a function named _start or something similar. This includes setting up some things required by the C language:

  • Setup some hardware so the C code can be used at all (on more complex devices this could include initializing SDRAM controllers or so, on CortexM3 there shouldn't be much to do)
  • A stack, so we can call functions, pass parameters and return (on Cortex M this is done by the CPU hardware as part of the reset handling)
  • Initialize all the global and static variables (so you thought that was done magically?)
  • For C++, call global constructors so the global objects (if any) are in a coherent state,
  • And finally call the main() function, eventually with the argc and argv parameters (but most of the time you don't need that)

Check everything is ok

With a fairly simple program it's easy to look at the final elf file using the

arm-none-eabi-objdump -d
command. This will dump a complete disassembly of the code, so you can check the reset vectors are at the right place as well as the startup code.

The code should start with _start, which will point first to the stack (somewhere in RAM), then to the reset vector which is stored right after it. See the startup.s file to see how that's made.

Debugging

We'll be using OpenOCD again. While we used the TCL interface to quickly try it out before, OpenOCD is really meant to be used together with gdb. This way, it's possible to debug your code on the chip just like youwould debug any unix application on your PC. How nice is that ?

So, let's load our executable now !

openocd -f /usr/local/share/openocd/scripts/board/stm32f3discovery.cfg &
telnet localhost 4444
reset halt

flash erase_sectors 0 0 127
flash write a.out 0x8000000

So, the first step is to reset the CPU and halt it to make sure it isn't runnning code from the flash while we're erasing it. Then, we erase the flash, bank 0, sectors 0 to 127 (that's the whole flash of this chip). Finally, we write our new code. Notice the 0x8000000 offset: while the code is executed from address 0, the flash must be written from address 0x8000000. This is related to the way the STM32 chip can boot. Depending on the state of the BOOT0 and BOOT1 pins, the address 0 will be mapped to eitehr the flash, the SRAM, or the system ROM holding ST bootloader. But writing can only occur at the "e;real"e; flash address.

Now that our program is flashed, let's attempt to debug it. Exit the openOCD telnet prompt, but leave OpenOCD runnning. Now connect to it with GDB:

arm-none-eabi-gdb
target remote localhost 3333
file a.out
stepi
break main
cont
step
First we connect to the OpenOCD server through the GDB port. Then, we load the file to get the debugging symbols from it. The first stepi command is to sync gdb with OpenOCD. From then on, we can set breakpoints, and run/debug the program as usual. Happy hacking!

Programming ARM chips with OpenOCD in Debian

Posted by pulkomandy on Sun Oct 9 14:31:43 2011  •  Comments (0)  • 

I bought an LPCXpresso board from NXP for toying around. Unfortunately, the JTAG interface built in this board can only be used with codeRed tools, and the free edition has a limit of 128k of flash memory. I want to use freely available tools, so I cut the board to remove the JTAG part and plugged in my Altera USB-blaster instead.

However, I quickly noticed that the version of OpenOCD built in Debian doesn't work well with it. Searching the web shows it's a bug in libftdi, and you have to use the closed-source libftd2xx instead. The installation works fairly well, just get libftd2xx from FTDI website, copy the so files in /usr/local/lib, then download and compile OpenOCD.

LibFTD2xx install

cd libftd2xx1.0.4
cp build/x86_64/libftd2xx.so.1.0.4 /usr/local/lib
pushd .
cd /usr/local/lib
ln -s libftd2xx.so.1.0.4 libftd2xx.so
popd
cp ftd2xx.h WinTypes.h /usr/local/include

OpenOCD 0.5.0 install

./configure --enable-usb_blaster_ftd2xx
make
# ... fix a warning as everything is built in -Wall mode ...
make
# there seem to be a bug with OpenOCD tools, where it forgets the -lftd2xx here. Do it ourselves :
gcc -std=gnu99 -g -O2 -Wall -Wstrict-prototypes -Wformat-security -Wshadow -Wextra -Wno-unused-parameter -Wbad-function-cast -Wcast-align -Wredundant-decls -Werror -o openocd main.o  ./.libs/libopenocd.a ../jimtcl/libjim.a -ldl -lftd2xx
sudo make install

Adaptateur souris AMIps2 pour Commodore Amiga et Atari ST

Posted by pulkomandy on Thu Nov 4 20:18:17 2010  •  Comments (1)  • 

AMIps2

Ce circuit de taille réduite permet de connecter de façon transparente une souris ps/2 à un ordinateur Amiga ou Atari ST. Il détecte automatiquement chacune de ces deux machines afin d'envoyer les signaux correspondants.

(merci à Arklif pour les photos)

Une version utilisable sur les ordinateurs Thomson TO est également disponible.

Une version du circuit spécialement adaptée pour recevoir une alimentation 5v externe est disponible. Elle permet d'utiliser une souris optique qui consomme trop d'électricité par rapport à ce que le port souris d'un amiga peut fournir.

Ce montage est adapté de celui disponible ici.

Informations techniques : le montage est réalisé autour d'un PIC 16f628 et comporte très peu de composants : 3 résistances et un condensateur.

Voici le schéma du circuit (résolution 300 dpi), et le projet piklab contenant le code source en assembleur.

Projet piklab Projet eagle

Prix : 20 euros, expédition comprise

ATTENTION : Problème de détection Atari/Amiga

certains utilisateurs sur Amiga 1200 et 4000 se sont apperçus que l'adaptateur se croyait sur Atari au démarrage de la machine. Cela est probablement du à de mauvaises valeurs de composants.

Il existe hereusement une solution simple pour forcer le mode Amiga : il suffit de couper une piste de l'adaptateur comme suit.

couper la piste entre la broche 6 du PIC et la resistance.

Dans ce cas, l'adaptateur fonctionnera toujours en mode Amiga et ne pourra pas être utilisé sur un Atari.

Des trucs AVR

Posted by pulkomandy on Mon Oct 18 22:36:51 2010  •  Comments (0)  • 

Je n'avais pas encore mis de news ici, mais les adaptateurs clavier amiga fonctionnent et sont en vente au prix de 20€. Contrairement à AmiPS/2, Amikey2USB est vendu avec un boîtier.

Comme les Atmel AVR marchent plutôt bien, j'en ai profité pour faire aussi une version ps/2 vers usb de l'adaptateur, ainsi qu'une carte pour gérer des boutons dans une borne d'arcade (encore en prototype pour l'instant).

En tout cas, je n'ai pas toujours le temps de maintenir ce site à jour, et j'utilise maintenant mon installation de Trac. Il y a donc d'autres façons de me surveiller...

  • La liste des projets. Pour l'instant tout ce qui est électronique est dans le projet avrstuff. Mais d'autres pourraient apparaitre.
  • Les flux RSS: ils sont également disponibles dans chaque projet de Trac, mais je trouve ça plus pratique d'avoir une page avec un apperçu complet.

D'autres projets sont en cours, mais je vous en dirai plus seulement une fois que ça commencera à fonctionner.

News en vrac

Posted by pulkomandy on Mon Feb 22 21:55:11 2010  •  Comments (0)  • 

Bon, il n'y a pas eu de mises à jour dans ce coin depuis un certain temps, donc en voilà quelques unes...

  • J'ai enfin fini de souder mon USBasp. Ce programmeur permet de graver des puces atmel AVR. Ça me changera un peu des PICs qui ont un assembleur assez illisibles et ne sont pas trop fait pour le C...
  • Ce programmeur va me permettre de travailler sur l'adaptateur permettant de brancher un clavier amiga (4000 ou 2000) sur une machine en USB. Mais j'ai fait quelques erreurs de gravure de la carte qu'il va falloir rattraper.
  • La version interne de l'AmiPS2 est maintenant officiellement disponible. Même prix que la version externe, légèrement plus petite, et avec deux trous de fixation pour l'accrocher ou vous voulez.
  • Prochaine étape : construire un programmeur de CPLD qui va me servir entre autres, pour le projet ReACID. Mais aussi par exemple pour fabriquer des UltraSatan ou d'autres machins un peu compliqués dans ce genre.

Cela dit, je suis assez pris par les projets scolaires, donc tout ça ne sera pas fini "la semaine prochaine". Plutôt pendant l'été. Les AMIps2 sont toujours disponibles (il en reste aussi quelques uns en version externe). Le reste arrivera petit à petit.

Lecteur de disquettes Floppy-1 pour Amstrad CPC et Amstrad Plus

Posted by pulkomandy on Mon Jul 6 14:06:19 2009  •  Comments (0)  • 

Floppy-1

photo du Floppy-1

Un lecteur de disquette pour les ordinateurs Amstrad CPC(+).

Vrai signal "ready", switchs de changement de face et de forçage en A, alimentation 5v externe.

3 versions avec des connecteurs différents : CPC Old, CPC Old Centronics, CPC Plus.

45 euros, expédition comprise

Adaptateur joystick 4joy pour Amiga

Posted by pulkomandy on Mon Jul 6 14:04:33 2009  •  Comments (0)  • 

4Joy

Cet adaptateur permet de connecter deux joysticks supplémentaires sur le port parallèle de votre Amiga.

Il est utilisable avec les jeux suivants :

  • Dynablaster
  • Gauntlet II (US Gold)
  • International Soccer (Microdeal)
  • Kick Off II (Anco)
  • Knock Out 2
  • Leatherneck (Microdeal)
  • Projectyle (Electronic Arts)
  • TV Sports Basketball (Cinemaware)

L'adaptateur coûte 15 euros, expédition incluse.

Afficheur a LEDs ledmeter pour tout ordinateur equipe d'un port parallele

Posted by pulkomandy on Mon Jul 6 14:01:55 2009  •  Comments (0)  • 

LEDMeter-2

ledmeter ledmeter ledmeter ledmeter ledmeter

Brochage du connecteur CON1:

  • 1: Data 4
  • 2: Masse
  • 3: Data 3
  • 4: Data 2
  • 5: Data 1
  • 6: Data 0

Le ledmeter est constitué de 32 DELs et se connecte sur le port parallèle de n'importe quel PC. Le circuit est plutôt simple puisqu'il s'agit simplement de démultiplexeurs (et d'une porte NON). Ceci permet une programmation également très simple: pour allumer une DEL, il suffit d'envoyer son numéro sur le port parallèle. En théorie, il est possible de cabler jusqu'à 2565 diodes sur un port parallèle. Cependant ma version n'en comporte que 32 pour des raisons de place disponible.

Une petite vidéo de démonstration est disponible ici.

Vous pouvez télécharger le projet eagle et le code source du programme pour linux.

Si vous voulez construire une version de ce ledmeter, si vous améliorez le programme, merci de partager vos idées et de m'envoyer des photos de vos créations.

ZenBox : 2 lignes, 1 telephone

Posted by pulkomandy on Fri Jun 27 23:12:37 2008  •  Comments (0)  • 

Zen PhoneBox

Il s'agit d'un boîtier permettant d'utiliser deux lignes teléphoniques (dans notre cas une ligne freebox et une ligne france téléom) avec un seul téléphone. Le circuit a été conçu par VieuxGeo, vous pouvez avoir pas mal d'infos sur son site: ICI