Forum: Mikrocontroller und Digitale Elektronik External Interrupt bei ATSAMD51


von Neves (Gast)


Lesenswert?

Hi,

ich versuche gerade erfolglos, bei einem ATSAMD51 einen externen 
Interrupt abzufragen (genau IRQ0 für PB05 und PB06). Das erzeugt mir 
ATMEL Start als Initialisierungscode:

    void EXTERNAL_IRQ_0_init(void)
    {
       hri_gclk_write_PCHCTRL_reg(GCLK, EIC_GCLK_ID, CONF_GCLK_EIC_SRC | 
(1 << GCLK_PCHCTRL_CHEN_Pos));
       hri_mclk_set_APBAMASK_EIC_bit(MCLK);
       // Set pin direction to input
       gpio_set_pin_direction(CLKY, GPIO_DIRECTION_IN);
       gpio_set_pin_pull_mode(CLKY,
                         // <y> Pull configuration
                         // <id> pad_pull_config
                         // <GPIO_PULL_OFF"> Off
                         // <GPIO_PULL_UP"> Pull-up
                         // <GPIO_PULL_DOWN"> Pull-down
                         GPIO_PULL_OFF);
       gpio_set_pin_function(CLKY, PINMUX_PA05A_EIC_EXTINT5);
       // Set pin direction to input
       gpio_set_pin_direction(SYNCY, GPIO_DIRECTION_IN);
       gpio_set_pin_pull_mode(SYNCY,
                         // <y> Pull configuration
                         // <id> pad_pull_config
                         // <GPIO_PULL_OFF"> Off
                         // <GPIO_PULL_UP"> Pull-up
                         // <GPIO_PULL_DOWN"> Pull-down
                         GPIO_PULL_OFF);
       gpio_set_pin_function(SYNCY, PINMUX_PA06A_EIC_EXTINT6);
       ext_irq_init();
    }

Meine ISRs sehen so aus (gleichnamige Funktionen innerhalb des 
ATMEL-Start-Codes habe ich entfernt):

    void EIC_5_Handler(void)
    {
       if(EIC->INTFLAG.reg & (1<<5))
       {
          EIC->INTFLAG.reg=(1<<5);
       }
       else
       {
          /* spurious interrupt?, clear all interrupt flags */
          EIC->INTFLAG.reg = EIC->INTFLAG.reg;        /* clear all EIC 
interrupt flags */
       }
    }

    void EIC_6_Handler(void)
    {
       if(EIC->INTFLAG.reg & (1<<6))
       {
          EIC->INTFLAG.reg = (1<<6);
       }
       else
       {
          /* spurious interrupt?, clear all interrupt flags */
          EIC->INTFLAG.reg = EIC->INTFLAG.reg;        /* clear all EIC 
interrupt flags */
       }
    }

Mein Problem: keine der ISRs wird jemals angesprungen, noch nicht mal 
ein einziges mal. Ein Hardwaresignal ist vorhanden, in ATMEL Start habe 
ich dne EIC mit einem 120 Mhz-Clock verbunden, die beiden Interrupts 5 
und 6 sind enabled und es ist Fallende/Beide Flanken für diese 
eingetragen.

Was könnte da noch fehlen?

Danke!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Weiß nicht, was die da unter der Haube zusammen zaubern. Ist der 
Interrupt im NVIC freigegeben worden?

von Neves (Gast)


Lesenswert?

Also es wird innerhalb des Start-Codes zumindest das hier aufgerufen:

    hri_eic_set_CTRLA_ENABLE_bit(EIC);
    NVIC_DisableIRQ(EIC_5_IRQn);
    NVIC_ClearPendingIRQ(EIC_5_IRQn);
    NVIC_EnableIRQ(EIC_5_IRQn);
    NVIC_DisableIRQ(EIC_6_IRQn);
    NVIC_ClearPendingIRQ(EIC_6_IRQn);
    NVIC_EnableIRQ(EIC_6_IRQn);

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Das sieht plausibel aus.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Das hier steht bei uns in SAMR21-Code drin (SAMD21 + AT86RF233):
1
        PM->APBAMASK.reg |= PM_APBAMASK_EIC;
2
        GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_EIC | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);
3
        EIC->CTRL.bit.ENABLE = 0;
4
        while (EIC->STATUS.bit.SYNCBUSY);
5
        EIC->CONFIG[0].bit.SENSE0 = EIC_CONFIG_SENSE0_HIGH_Val;
6
        EIC->INTENSET.bit.EXTINT0 = 1;
7
        EIC->CTRL.bit.ENABLE = 1;
8
        while (EIC->STATUS.bit.SYNCBUSY);
9
10
        NVIC_EnableIRQ(EIC_IRQn);

Ich müsste jetzt auch im Datenblatt nachlesen gehen, was das alles genau 
macht …

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.