Ansteuern der I/O

VoCore

Nachdem ich den VoCore erfolgreich in Betrieb genommen habe, bestand die nächste Aufgabe darin die vorhanden GPIO-Pins nutzen zu können.
Hierfür habe ich mir eine kleine C-Bibliothek geschrieben, die die grundlegenden Funktionen der GPIO-Pins abdeckt.

Bevor damit begonnen werden konnte eine GPIO-Lib zu schreiben ist eine ausfürliche Studie des Datenblattes erforderlich.
Die Beschreibung und das Block Diagram von S. 18 sind dabei besonders hilfreich:

VoCore_GPIO(1)

Wie man beiden entnehmen kann, sind die GPIOs über einen separaten BUs angeschlossen, den Pbus bzw. Palmbus.
Dies wird noch mal deutlich, wenn man sich den Device Tree des Chips anschaut.
Auf S. 56 des Datenblattes beginnt dann die Sektion über die GPIO des Chips.
Die erste Information die benötigt wird, ist die Basisadresse des GPIO-Controllers. Laut Datenblatt ist die Basis die Adresse 0x1000600.
Abzüglich der Adresse des Palmbuses ist die Adresse des GPIO-Controllers also 0x600.
Bei den Adressen der GPIO-Register ist zu beachten, dass sich die Adressen immer auf den GPIO-Controller beziehen, sprich ein Offset von 0x0000 bedeutet.

Für den Zugriff auf die Register lege ich mir, wie beim Raspberry Pi, ein entsprechendes Struct an, welches sämtliche Informationen über die Hardware beinhaltet:

Um jetzt auf die Adressen zugrifen zu können, muss der entsprechende Speicherbereich maskiert werden:

Jetzt darf man allerdings nicht den Fehler machen und versuchen den Speicherbereich 0x1000600, sprich die Adresse des Palmbuses und des GPIO-Controllers zu maskieren. Dies führt nämlich zu einem Segmentation fault-Fehler beim Zugriff auf die Adresse!

Der richtige Weg ist den Bus zu maskieren und die maskierte Basisadresse, die unter Peripherie->Addr gespeichert ist, mit einem Offset von 0x600 für den GPIO-Controller zu versehen.

In einer entsprechenden Initialisierungsfunktion für die GPIOs wird das Mapping des Speicherbereiches vollzogen:

Der Rest des Programmes ist weniger kompliziert. Um jetzt auf ein Register zugreifen zu wollen, wie z.B. dem Toggle-Register für die Pins 0-22 muss ich nur folgendes schreiben:

Da hier mit Zeigern, sprich mit Adressen, gearbeitet wird, muss der Wert im Datenblatt noch durch 4 geteilt werden.
Mit diesen zwei Codezeilen würde nun der GPIO 22 getoggled werden.

Am Ende der Seite findet ihr eine fertige GPIO-Bibliothek von mir, die (bis auf die Interrupts) alle Basisfunktionen der GPIO abdeckt.
Dazu gibt es ein Makefile und ein kleines Beispielprogramm namens main.c.
Vor der eigenen Anwendung müsst ihr den Pfad des Cross-Compilers an euer Linuxsystem anpassen:

Zudem müsst ihr, falls ihr ein anderes Hauptprogramm als main.c verwenden wollt, den Namen austauschen:

Die Bibliothek veinhaltet folgende Funktionen:

  • int GPIO_Init()
    Initialisiert die GPIO.
    Bei einem Rückgabewert von -1 ist ein Fehler aufgetreten.
  • int Set_Dir(int Pin, char Direction)
    Setzt die Richtung eines GPIO. Ein „I“ steht für Eingang und ein „O“ für Ausgang.
    Bei einem Rückgabewert von -1 ist ein Fehler aufgetreten.
  • int Toggle_IO(int Pin)
    Toggled den entsprechenden GPIO.
    Bei einem Rückgabewert von -1 ist ein Fehler aufgetreten.
  • int Set_IO(int Pin)
    Setzt den entsprechenden GPIO auf einen High-Pegel.
    Bei einem Rückgabewert von -1 ist ein Fehler aufgetreten.
  • int Clear_IO(int Pin)
    Setzt den entsprechenden GPIO auf einen Low-Pegel.
    Bei einem Rückgabewert von -1 ist ein Fehler aufgetreten.
  • int Read_IO(int Pin)
    Liest den Status eines GPIO aus und gibt diesen zurück.
    Bei einem Rückgabewert von -1 ist ein Fehler aufgetreten.
  • int Set_Pol(int Pin, int Pol)
    Vertauscht die Polarität eines GPIO. Bei Pol = 0 tritt keine Änderung auf, bei Pol = 1 wird der Pin invertiert.
    Die Clear-Funktion setzt anschließend den Pin und die Set-Funktion löscht ihn wieder.
    Bei einem Rückgabewert von -1 ist ein Fehler aufgetreten.

 

Dokumentation:

 

-> Zurück zu VoCore

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload CAPTCHA.