2014-07-07 28 views
6

Występuje przerwanie generowane co 10ms na GPIO_39 w pandaboard OMAP4. Zarejestrowałem do tego kod obsługi w kodzie sterownika Linuksa, ale program obsługi nie jest wywoływany, ponieważ przerwanie nie zostało wykryte.Jak wykrywać przerwanie na linii GPIO we wbudowanym systemie Linux?

Upewniłem się na poziomie sprzętowym (przez sondowanie pinezki gpio), czy rzeczywiście jest generowane przerwanie. To tylko, że oprogramowanie nie jest w stanie go wykryć.

Mam następujące w moim kodzie sterownika.

#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 należący do GPIO2 bankowego oraz odpowiadająca jej liczba przerwań jest 32. Ale wartość zwracana gpio_to_irq() jest 199. Jest to kolejny powód do niepokoju.

Proszę dać mi znać, jeśli coś jest nie tak w kodzie lub jeśli coś przeoczyłem.

+1

Twój kod najczęściej wygląda OK. Myślę, że twój pierwszy iowrite jest prawdopodobnie w najlepszym razie niepotrzebny, co ma robić? Czy sprawdziłeś ustawienia multipleksu pin i sprawdziłeś, czy możesz odczytać sygnał przerwania jako wartość (na przykład z interfejsem użytkownika). – slobobaby

+0

Pierwszy iowrite to część pinezki. –

+0

Jeśli używasz interfejsu przestrzeni użytkownika, czy poprawnie odczytujesz poziom sygnału zewnętrznego? – slobobaby

Odpowiedz

1

Utwórz pin GPIO tak, aby wykrywał zbocze opadające.

Na poziomie modułu gpio należy włączyć FALLING_DETECT gpio.