Forum: Mikrocontroller und Digitale Elektronik Frage zu Konfiguration eines Pin-Interrups auf dem AT91 unter ecos


von Christian L. (chl)


Lesenswert?

Hallo,

Ich brauche unter Ecos einen Interrupt der auf die steigende Flanke an 
einem Pin reagiert.

Meine Konfigration sieht momentan folgendermaßen aus:
1
//=========ECOS PIN IRQ DATA======================================================================================
2
3
struct fs20pin_irqConfig_t
4
{
5
    cyg_vector_t   int_vector;       //  number of irq (eg 5 for SPI)
6
    cyg_priority_t irq_priority;     //  AIC Priority Level
7
    cyg_uint32     irq_mode;         //  AIC Interrupt Source Type
8
    cyg_uint32     irq_initData;     //  additional irq data
9
    cyg_uint32     irq_data;         //  passed data to the IRQ
10
};
11
12
//  Create and initialise the interrupt data:
13
static struct fs20pin_irqConfig_t fs20pin_irqConfig =
14
{
15
    //  regular SPI interrupt
16
    AT91C_ID_PIOA,                 //  int_vector
17
    7,                             //  irq_priority
18
    AT91C_AIC_PRIOR_LOWEST         //  irq_mode
19
};
20
21
//  Create a structures for eCos internal interrupt specific data:
22
static cyg_interrupt fs20pin_ecosIrq;
23
static cyg_handle_t  irq_fs20pin_handle;
24
25
cyg_uint32 at91_fs20pin_ISR( cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
26
void at91_fs20pin_DSR( cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
27
28
//=========ECOS TC IRQ DATA=======================================================================================
29
30
void Setup_Pin_Interrupt(void){   
31
32
    AT91F_PIO_CfgInput( AT91C_BASE_PIOA, RX_PIN );
33
    //AT91F_PIO_CfgPullup( AT91C_BASE_PIOA, RX_PIN );
34
35
    //SETUP interrupt
36
    cyg_drv_interrupt_create( fs20pin_irqConfig.int_vector,         //  number of the interrupt (0-31)
37
                              fs20pin_irqConfig.irq_priority,
38
                              (cyg_addrword_t) &fs20pin_irqConfig,  //  data used by the ISR & DSR
39
                              at91_fs20pin_ISR,
40
                              at91_fs20pin_DSR,
41
                              &irq_fs20pin_handle,                  //  irq handle
42
                              &fs20pin_ecosIrq);                    //  ecos internal struct
43
44
    //Interrupt konfigurieren
45
    //Interupt loest bei steigender Flanke am Pin aus, so kann mit dem Timer eine Periodendauer gemssen werden.
46
    cyg_interrupt_configure(
47
        fs20pin_irqConfig.int_vector,   //Interrupt-Nummer
48
        false,                          //reagiere auf Flanke, nicht Level
49
        true);                          //reagiere auf steigend, nicht fallend
50
51
52
    //  Fill eCos interrupt vector tables
53
    cyg_drv_interrupt_attach( irq_fs20pin_handle);
54
    cyg_drv_interrupt_unmask( fs20pin_irqConfig.int_vector);
55
56
    AT91F_PIO_InterruptEnable ( AT91C_BASE_PIOA, RX_PIN );
57
   
58
59
}
60
cyg_uint32 at91_fs20pin_ISR( cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data ){
61
62
    //aktuellen Interrupt sperren
63
    cyg_interrupt_mask(fs20pin_irqConfig.int_vector);
64
65
    AT91F_PIO_InterruptDisable ( AT91C_BASE_PIOA, RX_PIN );
66
    
67
    //aktuellen Interrupt bestaetigen
68
    cyg_interrupt_acknowledge(fs20pin_irqConfig.int_vector);
69
70
    if(AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, RX_PIN)){
71
    
72
        xPrintf("Inputset\n");
73
        AT91F_PIO_GetInterruptStatus(AT91C_BASE_PIOA); // Statusregister lesen => Clear Interrupt
74
        
75
        //xPrintf("Interuptabfrage %d\n",AT91F_PIO_IsInterruptSet( AT91C_BASE_PIOA, RX_PIN ));
76
    }
77
    else {
78
        xPrintf("Input not set\n");
79
        cyg_interrupt_unmask(fs20pin_irqConfig.int_vector);
80
        return (CYG_ISR_HANDLED);
81
    }
82
83
    //AT91F_PIO_InterruptEnable ( AT91C_BASE_PIOA, RX_PIN );
84
85
    
86
    cyg_drv_interrupt_unmask(AT91C_ID_PIOA);
87
    return (CYG_ISR_HANDLED);
88
}

Der Interrupt wird aber bei jedem Flankenwechsel ausgelöst und nicht nur 
bei der steigenden Flanke, was mich zu dem etwas unschönen Workaround 
veranlasst hat.
Lieber wäre es mir den Interrupt nur zu bekommen, wenn von Low auf High 
gewechselt wird.

Vielleicht kann mir jemand weiter helfen.
Danke

von Christian L. (chl)


Lesenswert?

Hat niemand einen Tipp? :(

von gerhard (Gast)


Lesenswert?

hallo,
du kannst beim at91sam7 nur die Leitungen IRQ0/IRQ1/FIQ auf 
flanken-triggerung einstellen. bei allen anderen i/o-leitungen wird bei 
jeder flanke der interrupt getriggert.

gruss
gerhard

von Christian L. (chl)


Lesenswert?

Hey Danke, dann werde ich wohl bei meiner Methode bleiben müssen.

von Christian L. (chl)


Lesenswert?

gerhard schrieb:
> du kannst beim at91sam7 nur die Leitungen IRQ0/IRQ1/FIQ auf
> flanken-triggerung einstellen.

Hallo nochmal

Ich versuche gerde diesen IRQ0 Interrupt unter Ecos zu verwenden.
Aber ich bekomme ihn nicht ausgelöst.

Ich verwende den Code wie oben habe aber die Konfiguration des 
Interrupts angepasst.
1
AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,AT91C_PA30_IRQ0);
2
3
static struct RX_PIN_irqConfig_t RX_PIN_irqConfig =
4
{
5
    //  regular SPI interrupt
6
    AT91C_ID_IRQ0,                 //  int_vector
7
    7,                             //  irq_priority
8
    AT91C_AIC_PRIOR_LOWEST         //  irq_mode
9
};

Desweiteren verwende ich die folgenden Funktionen
1
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_IRQ0)
2
AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_IRQ0)
3
AT91F_AIC_ClearIt (AT91C_BASE_AIC, AT91C_ID_IRQ0)

anstatt der PioInterruptEnable etc

Ich war der Meinung dass sich der IRQ genauso konfigurieren ließe wie 
der PIO-Interrupt. Vielleicht könnte mir jemand weiterhelfen.

Danke

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.