Hallo,
folgende Ausgangssituation: Ich möchte von einem Linux-System
(Pandaboard) über die SPI-Schnittstelle Daten von einem AD-Wandler
(ADS1255 von Texas Instruments) lesen.
Der AD-Wandler hat einen DATA-READY Ausgang, der kurzzeitig high wird
wenn eine Wandlung fertig ist.
Nun möchte ich auf dem Pandaboard folgende Schritte durchführen:
- Interrupt an GPIO-Pin um DATA-READY Signal auszuwerten (bei steigender
Flanke)
- anschließend Daten auslesen mit spidev-Treiber (kommt später dran)
Der zugehörige GPIO-Pin ist unter /sys/class/gpio/gpioXX als input
konfiguriert. Unter edge habe ich "rising" eingetragen.
Wie kann ich in einem Linux-System einen Interrupt einrichten? Muss ich
dazu einen eigenen Treiber schreiben? Bzw. ist mein GPIO-Pin so
ausreichend konfiguriert?
Ich hoffe ich habe mich einigermaßen verständlich ausgedrückt.
Grüße
Ruben
ob es der einzige Weg ist, weiss ich nicht, aber es geht auf jeden Fall
sehr elegant mit einem Kernel-Modul. Hier kann man z.B. in der
init-Funktion GPIOs auf Interrupts mappen und dann einen entsprechenden
Callback hinterlegen:
(Beispiel stammt aus einem Treiber fuer einen Infrarot-Empfaenger, der
an einem GPIO haengt - allerdings handelt es sich um einen kleinen
Router, nicht um ein Pandaboard).
der Interrupt-Handler kann dann mit gpio_get_value den Pin lesen:
1
staticirqreturn_tirq_handler(inti,void*blah)
2
{
3
structtimevaltv;
4
intdcd;
5
longdeltv;
6
intdata;
7
staticintlast_dcd=-1;
8
9
while(1){
10
dcd=gpio_get_value(HIRC_GPIO);
11
12
if(dcd==last_dcd){
13
returnIRQ_HANDLED;
14
}
15
16
/* get current time */
17
do_gettimeofday(&tv);
18
19
deltv=tv.tv_sec-lasttv.tv_sec;
20
if(tv.tv_sec<lasttv.tv_sec||
21
(tv.tv_sec==lasttv.tv_sec&&
22
tv.tv_usec<lasttv.tv_usec)){
23
printk(KERN_WARNINGPFX"AIEEEE: your clock just jumped backwards\n");
24
printk(KERN_WARNINGPFX
25
"%d %d %lx %lx %lx %lx\n",
26
dcd,sense,
27
tv.tv_sec,lasttv.tv_sec,
28
tv.tv_usec,lasttv.tv_usec);
29
data=PULSE_MASK;
30
}elseif(deltv>15){
31
data=PULSE_MASK;/* really long time */
32
#if 0
33
printk (KERN_WARNING PFX "really long time: %ld\n", deltv);
Hallo,
ich habe den Vorschlag von Günter umgesetzt und das geht auch
grundsätzlich. Allerdings tritt der Interrupt nur einmal auf.
Meinem Verständnis nach muss ich im Interrupt-Handler den Interrupt
wieder frei schalten.
Hat da jemand einen Tipp für mich?
Vielen Dank im voraus.
Ruben
Hallo,
sowas habe ich versucht mit einem Linux FOX Board. Sollte dann ja auch
möglich sein damit.
Ein Tip zum DRDY Signal. Bei richtiger Behandlung, also wenn man die
Daten ausliest, müsste das DRDY Signal mit der ersten Clk-Flanke wieder
auf High gehen, also muss man den ISR auf negative Flanke stellen, dann
kann man im Wandlertakt( z.B. 1000Hz ADS1281) die 3 bzw 4 Bytes
auslesen. Klappt prima bei mir, leider nicht mit Linux.
Bernd
Hallo,
sorry das ich den alten Thread nochmal ausgrabe aber ich habe ein
ähnliches Problem: ich möchte einen GPIO als Interrupt nutzen und beim
eintreten des Interrupts eine Aktion auslösen.
Das Programmieren das Kernelmoduls ist kein Problem, ABER:
Weiß jemand ob es möglich ist aus dem Interrupt-Handler heraus ein
Aktion im Userspace aufzurufen, z.B. ein Programm starten?