Das Linux Kernel Modul cyport.o für die Cypress CY7C63000 - Familie
Die Mikrocontroller der CY7C63000 / CY7C63001 / Cy7C63100 / CY7C63101 - Familie zeichnen sich durch die folgenden Features aus:
- Conform mit der USB 1.5 Mbps Spezifikation, Version 1.1
- Unterstützt eine Device Adresse, mit zwei Endpunkten (ein Controller Endpunkt, 1 Daten Endpunkt)
- 8-bit RISC Micorocontroler
- Harvard Architektur
- nur ein 6 MHz Keramik Resonator als externer Frequenzgeber notwendig
- intern mit 12 MHz arbeitend
- USB optimierter Befehlssatz
- Interer Speicher:
- 128 byte RAM
- 2 kbyte EPROM (CY7C63000A, CY7C63100A)
- 4 kbyte EPROM (CY7C63001A, CY7C63101A)
- I/O Ports:
- Integrierter USB Transceiver
- Bis zu 16 Schmitt trigger gesteuerte I/O Ausgänge mit internem pull-up
- Bis zu 8 I/O Ausgänge, die LED's ansteuern können
- maskierbare Interrupts an allen Ports
- 8-bit frei-steuerbarer Timer
- Watch dog timer
- interner power-on reset
- Intant-On NOW [tm] für Suspend und periodische Wake-Up Modi
- Versorgungsspannung 4.0 - 5.25 VDC
- Operationstemperatur: 0 - 70°C
Durch seine kompakte Bauweise (SMD, wie auch 20 bzw 24 Pin DIL) ist er als kleiner, kostengünstiger Baustein für Anwendungen
im Bereich, der Peripherie (Maus, Joystick, 12 bzw. 16 Bit I/O-Controller, Messen und Regeln) geschaffen.
Zum Betrieb ist neben dem Controller selber nur der Keramik Resonator, sowie ein 1,5 kOhm Widerstand und eine USB-Portbuchse
vom Typ A oder B von notwendig. Der Controller selber kann mit dem Programm CYASM programmierbar und kann mit gängigen
Programmierern programmiert werden. Hier findet man den Bauplan eines solchen Programmierers (danke an roms!!!)
Über die Frima AK-Modul-Bus kann man in Deutschland bereits fertig programmierte Bauteile beziehen.
In Frankreich ist dies die Firma Elektor Magazins.
Da es zum dem Portbaustein USBPort der Firma AK-Modul-Bus keine Treiber unter Linux gab, habe ich selber geschrieben.
Als Vorlage diente hierbei der Treiber von Romain Liévin.
Mit dem von mir geschriebenen Linux Kernel Modul ist es möglich, die Portzustände der
einzelnen Ports P0.0 - P0.7, sowie P1.0 - P1.3 (CY7C6300X) bzw P1.0-P1.7(CY7C6310X) des USB-Controllers auszulesen und den Sinkstrom des Ports P1.3 einzustellen.
Das Modul cyport.o
Das erstellen des Moduls
Zum kompilieren sind die Kernel-Header bzw. Kernel-Quellen des verwendeten Kerles notwendig, sowie root-Rechte.
Man wechselt nach entpacken des Archives (tar -xvzf cyport-XX.tar.gz) in das Verzeichniss modul und ruft dort make und anschließend make install auf.
Sollte make erfolgreich kompiliert haben, kann man das Modul mit insmod ./cyport.o installieren und überprüfen, ob der Portbaustein erkannt wurde.
Nun kann man mit dem Portbaustein arbeiten.
Die API
Um die krüptischen Aufrufe des Treibers zu vereinfachen, habe ich eine API (Advanced Programming Interface) zu diesem Treiber entwickelt.
Die einzelnen Zustände eines Port werden dabei über Bool-Variablen in der structure Port dargestelt. Sie ist im Verzeichniss API zu finden
struct Port {
bool P0 :1;
bool P1 :1;
bool P2 :1;
bool P3 :1;
bool P4 :1;
bool P5 :1;
bool P6 :1;
bool P7 :1;
};
Es ist also notwendig, ein Array dieser Struktur zu erstellen (Beispiel: Port Port1; Port Port2;)
Über die folgenden Funktionen wird dann das Device selber gesteuert:
- void init (const unsigned short int &Device)
Mit dieser Funktion wird das Device initiert, nachdem es an den USB-Bus angeschlossen wurde.
Als Argument wird der Funktion die Gerätenummer übergeben. Im Fall des ersten Portbausteins die 0, beim zweiten die 1 usw.
- Port read_Port_Bits (const unsigned short int &Portnumber);
Diese Funktion ließt die aktuellen Portszustände aus und gibt sie als Portstrukture zurück.
Als Argument wird die Portnumer, im Fall P0.0 - P0.7, die 0, im Fall P1.0-P1.7 die 1 übergeben.
- void write_Port_Bits (const unsigned short int &Portnumber, const Port &Portdata);
Wenn man die Zustände, eines Ports ändern will, ändert man die Bools der entsprechenden Struktur und übergibt diese dann zusammen
mit der Portnumer (s. read_Port_Bits) dieser Funktion. Abschließend werden die Portzustände geändert.
- void set_all_low (void);
Möchte man gerne schnell alle Ports auf den Zustand low oder 0 setzen, ruft man diese Funktion auf
- void set_all_high (void);
Diese Funktion erreicht genau das Gegenteil.
- void set_sink_current (const unsigned short int &Rate);
Wie oben bereits erwähnt, kann man den Sinkstrom des Ports P1.3 zwischen 0 und 256 einstellen.
Dies ist die dazugehörige Funktion.
- void read_ROM (void);
Diese Funktion ließt einfach das ROM und gibts auf der Console aus
- void deinit (void);
Irgendwann sollte das Programm zu ende sein und damits keine Probleme mit offenen Handels gibt, bitte diese Funktion aufrufen.
Sie räumt dann enstrechend auf.
Ich (Marcus Maul) wünsche allen viel Spaß beim programmieren!!!
An dieser Stelle nochmals vielen Dank an den aPc, der mir bei der Programmierung tatkräftig durch Test und Hilfestellungen
zur Seite stand, sowie Martin Henne, Burkhard Kainka und Romain Liévin.
Ich selber bin Mitglied des
.
Special Thanks to Sourceforge for hosting this project!!!