2014-07-07 5 views
6

Es wird ein Interrupt alle 10ms auf GPIO_39 in pandaboard OMAP4 generiert. Ich habe einen Handler dafür im Linux-Treibercode registriert, aber der Handler wird nicht aufgerufen, da der Interrupt nicht erkannt wird.Wie erkennt man Interrupt auf einer GPIO-Leitung in Embedded Linux?

Ich habe auf der Hardware-Ebene (durch Sondierung der GPIO-Pin) sichergestellt, dass der Interrupt tatsächlich generiert wird. Es ist nur, dass die Software es nicht erkennen kann.

Ich habe folgendes in meinem Treibercode.

#define GPIO_NO  39 

    iowrite16(0x3, gpio_39_address + 2); /* Configured the pin 22 to be used as gpio. */ 

    ret = gpio_request(GPIO_NO, "Claiming GPIO"); 
    if(ret < 0) 
    { 
    printk(KERN_ALERT "%s: Claiming GPIO_%d failed\n", __func__, GPIO_NO); 
    return -1; 
    } 
    else 
    { 
    printk(KERN_INFO "%s: Claiming GPIO_%d successful\n", __func__, GPIO_NO); 
    } 

    ret = gpio_direction_input(GPIO_NO); 
    if(ret < 0) 
    { 
    printk(KERN_INFO "%s: Setting GPIO direction to input failed\n", __func__); 
    return -1; 
    } 
    else 
    { 
    printk(KERN_INFO "%s: Direction of GPIO_%d set to input\n", __func__, GPIO_NO); 
    } 

    GPIO_IRQ = gpio_to_irq(GPIO_NO); 

    if(GPIO_IRQ < 0) 
    { 
    printk(KERN_INFO "%s: Mapping GPIO_%d to IRQ failed\n", __func__, GPIO_NO); 
    return -1; 
    } 
    else 
    { 
    printk(KERN_INFO "%s: Mapping GPIO_%d to IRQ_%d successful\n", __func__, GPIO_NO, GPIO_IRQ); 
    } 

    if((request_irq(GPIO_IRQ, ten_ms_int, IRQF_TRIGGER_FALLING, DEVICE_NAME, NULL))) 
    { 
    printk(KERN_ALERT "%s: requeseting GPIO_IRQ %d failed\n", __func__, GPIO_IRQ); 
    return -1; 
    } 
    else 
    { 
    printk(KERN_INFO "%s: requesting GPIO_IRQ %d successful\n", __func__, GPIO_IRQ); 
    } 

irqreturn_t ten_ms_int(int irq, void *dev_id) 
{ 
    T_UINT32 l; 
    /* Enable spi channel */ 
    l = ioread32(spi_base + SPI_CHCONF0); 
    l |= SPI_CHCONF0_FORCE; 
    iowrite32(l, (spi_base + SPI_CHCONF0)); 

    l = ioread32(spi_base + SPI_CHCTRL0); 
    l |= SPI_CHCTRL_EN; 
    iowrite32(l, (spi_base + SPI_CHCTRL0)); 

    /* Enable dma channel 0 */ 
    l = ioread32(sdma_base + SDMA_CCR(CHANNEL0)); 
    l |= SDMA_CCR_ENABLE; 
    iowrite32(l, sdma_base + SDMA_CCR(CHANNEL0)); 

    /* Enable dma channel 1 */ 
    l = ioread32(sdma_base + SDMA_CCR(CHANNEL1)); 
    l |= SDMA_CCR_ENABLE; 
    iowrite32(l, sdma_base + SDMA_CCR(CHANNEL1)); 
    //printk(KERN_INFO "%s: 10ms interrupt detected %d\n", __func__, irq); /* I know that I've to remove this printk statement */ 
    return IRQ_HANDLED; 
} 

GPIO_39 gehört zur Bank GPIO2 und die entsprechende Interrupt-Nummer ist 32. Aber der Rückgabewert von gpio_to_irq() ist 199. Dies ist ein weiterer Grund zur Besorgnis.

Bitte lassen Sie mich wissen, wenn etwas im Code falsch ist oder wenn ich etwas verpasst habe.

+1

Ihr Code sieht meistens OK aus. Ich denke dein erster iowrite ist wahrscheinlich im besten Fall unnötig, was soll er tun? Haben Sie Ihre Pin-Multiplex-Einstellungen überprüft und verifiziert, dass Sie das Interrupt-Signal als Wert lesen können (z. B. mit der Userspace-Schnittstelle)? – slobobaby

+0

Der erste iowrite ist der Pin-Muxing-Teil. –

+0

Wenn Sie die Userspace-Schnittstelle verwenden, können Sie den externen Signalpegel richtig lesen? – slobobaby

Antwort

1

Stellen Sie den GPIO-Pin explizit auf fallende Flanke fest.

Auf der gpio-Modulebene muss FALLING_DETECT von gpio aktiviert werden.