This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

L138在DSP/BOIS下GPIO中断INTSTATn全为0



你好,我用OMPL138在DSP/BOIS下使用GPIO硬件中断,使用的是GPIOB6中的GPIOB6_6和GPIOB6_14,两个引进都可以按配置的方式进中断函数,但是进中断后INTSTAT67寄存器的值为0,照理对应的标志位应该是1啊,我分不出是6引脚产生的中断还是14引脚产生的中断。

  • ARM那边有跑Linux,但是没用到这两个引脚的中断

  • 检查一下寄存器地址搞对了没有,不可能没值,不然中断怎么产生的。

  • 寄存器地址对了,测试了,ARM端LINUX系统不启动INTSTATn中就有对应引脚的值,启动Linux系统后,DSP端进中断INTSTATn中的值就全是0了

  • 我们这边有两块开发板,一块合众达的,一块瑞泰的,都是这样的。

  • 那就是linux把它改了呗,这跟板子没有什么关系。

    再说也不可能DSP一直不能改啊, Linux改完后,DSP再写也是可以的啊。

    你在CCS下手动改写寄存器,把寄存器的值截屏上来看看,说实话,我不相信不可改写。

  • 不是寄存器不能改,是在ARM端跑LIUNX系统时,DSP端进GPIO中断后,INTSTATn对应引脚的的标志没有,无法再DSP端区分中断是哪个引脚产生的。在ARM端不跑Linux系统时,DSP端GPIO中断的INTSTATn标志是正常的,通过CCS往INTSTATn中对应位写1会把对应标志清掉。ARM跑LINUX系统时DSP端的GPIO中断就不正常了,ARM端就跑一个系统,没有启动应用程序,也没用到GPIO中断。

  • 寄存器是可以写的,我DSP端已经进中断了,对应GPIO的中断使能寄存器,上升沿/下降沿触发等寄存器的配置都是对的。通过CCS仿真看过的。

    就是进中断后,INTSTATn中的值全为零,照理应该有对应引脚的GPIO中断标志,INTSTATn全为零,我就无法区分中断是哪个引脚产生的。

    ARM端不跑LINUX系统时,DSP端没这个问题,DSP端INTSTATn寄存器中对应位有值,ARM端就跑了个系统,无应用程序,无GPIO中断。

  • 这里无疑是Linux响应了GPIO的中断,把状态清掉了。

    建议: 研究一下Linux端GPIO代码,一定是注册了这个GPIO了。

    我暂时看到GPIO IRQ handler这里,你可以看到只要是使能了的GPIO,在handler里都把对应状态清掉了。你再去找一下,是在哪地方配置使能了吧。

    static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
    {
    void __iomem *isr_reg = NULL;
    u32 isr;
    unsigned int gpio_irq, gpio_index;
    struct gpio_bank *bank;
    u32 retrigger = 0;
    int unmasked = 0;
    struct irq_chip *chip = irq_desc_get_chip(desc);

    chained_irq_enter(chip, desc);

    bank = irq_get_handler_data(irq);
    isr_reg = bank->base + bank->regs->irqstatus;

    if (WARN_ON(!isr_reg))
    goto exit;

    while(1) {
    u32 isr_saved, level_mask = 0;
    u32 enabled;

    enabled = _get_gpio_irqbank_mask(bank);
    isr_saved = isr = __raw_readl(isr_reg) & enabled;

    if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
    isr &= 0x0000ffff;

    if (cpu_class_is_omap2()) {
    level_mask = bank->level_mask & enabled;
    }

    /* clear edge sensitive interrupts before handler(s) are
    called so that we don't miss any interrupt occurred while
    executing them */
    _disable_gpio_irqbank(bank, isr_saved & ~level_mask);
    _clear_gpio_irqbank(bank, isr_saved & ~level_mask);
    _enable_gpio_irqbank(bank, isr_saved & ~level_mask);

    /* if there is only edge sensitive GPIO pin interrupts
    configured, we could unmask GPIO bank interrupt immediately */
    if (!level_mask && !unmasked) {
    unmasked = 1;
    chained_irq_exit(chip, desc);
    }

    isr |= retrigger;
    retrigger = 0;
    if (!isr)
    break;

    gpio_irq = bank->virtual_irq_start;
    for (; isr != 0; isr >>= 1, gpio_irq++) {
    gpio_index = GPIO_INDEX(bank, irq_to_gpio(gpio_irq));

    if (!(isr & 1))
    continue;

    #ifdef CONFIG_ARCH_OMAP1
    /*
    * Some chips can't respond to both rising and falling
    * at the same time. If this irq was requested with
    * both flags, we need to flip the ICR data for the IRQ
    * to respond to the IRQ for the opposite direction.
    * This will be indicated in the bank toggle_mask.
    */
    if (bank->toggle_mask & (1 << gpio_index))
    _toggle_gpio_edge_triggering(bank, gpio_index);
    #endif

    generic_handle_irq(gpio_irq);
    }
    }