Port Input

Funktion


Ein PortIn-Modul umfasst bis zu 18 Eingänge, die ein Interruptsignal bei steigender oder fallender Flanke am Eingang erzeugen können. Die Eingänge eines Moduls können einzeln programmiert werden, indem das jeweils korrespondierende Bit des entsprechenden Steuerregisters verändert wird.

Register


OffsetRegisterFunktionZugriff
0PIN_IN_DATDatenread
1PIN_IN_IEInterrupt Freigabe für jedes Bitread/write
2PIN_IN_EDGSELAuswahl der aktiven Flanke für jedes Bitread/write
3PIN_IN_IR_STATUSInterrupt Status für jedes Bitread


Das Datenregister PIN_IN_DAT enthält die Daten der Pins des Port-In-Moduls. Bei einem Reset werden alle Bits mit Null initilaisiert. Auf das Register kann nur lesend zugegriffen werden.

Im Steuerregister PIN_IN_IE können für die einzelnen Pins des Port IN-Moduls Interrupts aktiviert werden. Bei einem Reset werden alle Bits mit Null initialisiert. Auf das Register kann lesend und schreibend zugegriffen werden.

Im Steuerregister PIN_IN_EDGSEL kann für die Pins des Port In-Moduls ausgewählt werden, ob sie auf steigende oder fallende Flanken einen Interrupt generieren sollen. Bei einem Reset werden alle Bits mit Null (= fallende Flanke) initialisiert. Auf das Register kann lesend und schreibend zugegriffen werden.

Im Statusregister PIN_IN_IR_STATUS wird für die einzelnen Pins des Port In-Moduls der Zustand des Interruptsignals angezeigt. Bei einem Reset werden alle Bits mit Null initialisiert. Auf das Register kann nur lesend zugegriffen werden. Die Bits des Registers werden erst bei einem Lesen eines der anderen 3 Register gelöscht. Damit können auch sehr kurze Impulse erkannt werden. Die gesetzten Bits des Registers lösen nur dann Interrupt aus, wenn auch das Bit an der gleichen Position im PIN_IN_IE Register gesetzt ist.

port_in.h

#ifndef __PORT_IN_H
#define __PORT_IN_H

#ifndef __PORT_IN_F_H

#define PORT_INBIT_0    (1<<0)
#define PORT_INBIT_1    (1<<1)
#define PORT_INBIT_2    (1<<2)
#define PORT_INBIT_3    (1<<3)
#define PORT_INBIT_4    (1<<4)
#define PORT_INBIT_5    (1<<5)
#define PORT_INBIT_6    (1<<6)
#define PORT_INBIT_7    (1<<7)
#define PORT_INBIT_8    (1<<8)
#define PORT_INBIT_9    (1<<9)
#define PORT_INBIT_10   (1<<10)
#define PORT_INBIT_11   (1<<11)
#define PORT_INBIT_12   (1<<12)
#define PORT_INBIT_13   (1<<13)
#define PORT_INBIT_14   (1<<14)
#define PORT_INBIT_15   (1<<15)
#define PORT_INBIT_16   (1<<16)
#define PORT_INBIT_17   (1<<17)

#endif

typedef struct port_in {
        volatile unsigned int data;     // (r)   (r = reset-interrupt)
        volatile unsigned int ie;       // (r/w) (r = reset-interrupt)
        volatile unsigned int edgsel;   // (r/w) (r = reset-interrupt)
        volatile unsigned int ir_stat;  // (r)
} port_in_regs_t;

#endif


Konfiguration und Instanziierung


Bei der Instanziierung eines IO-Moduls gibt es zwei Parameter, die man einstellen muss: BASE_ADR und PORT_WIDTH. BASE_ADR gibt den Offset der Adresse des Moduls zur Basisadresse der Peripherieregister an. Der Wert besteht aus den oberen sieben Bit der zehn Bit-Adresse eines Moduls (die unteren drei Bit werden nur modulintern benutzt). PORT_WIDTH bezeichnet die Breite des jeweiligen Ports, sie kann von 1 Bit bis 18 Bit eingestellt werden.

Die Interruptleitungen des Moduls müssen an die gewünschten Eingänge des Interruptkontrollers angeschlossen werden und die IO-Pins an die Ein- und Ausgänge des Top Level Moduls. Diese müssen dann noch den Pins des FPGA zugeordnet werden (z.B. in der .ucf-Datei des ISE-Projekts).


SpartanMC