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.

AM335X: GPIO debounce issue



Hi,

I'm trying to configure the BBB Gpio debounce feature. I set GPIO2.6 to be an output pin and GPIO2.7 to be an input pin with interrupt enabled at just rising edge. All pinmux settings for both pins are done. Now i connect these pins with a wire externally [these are pins 45 and 46 on header P8] . Now I toggle the pin GPIO2.6 in a nearly infinite while loop and print out a short message in the interrupt to keep track which interrupts are triggered. I see that interrupts are triggered for each toggle of the pin as expected(that is, for every rising edge). I have a global counter variable which tells me which while iteration each edge interrupt corresponds to. I can see that each and every number is printed sequentially; so each of the edges are detected and each triggers an interrupt. 

Now comes the weird part. I enable debounce clk in PRCM, enable corresponding bit gpio debounce register, and set the gpio debounce time to 0x01. Now the interrupts are farther apart, around 20 numbers are skipped with each interrupt. But I also see some distortion in the interrupts. Some unexpected interrupts are also missed, but this is rare. Now I increase debounce time to 0x02. The interrupts are proportionally farther apart, and I see a bit more distortion in the number sequence. At random points I just miss a lot of interrupts. As I keep increasing the debounce time, the distortion keeps increasing until around 0x08, when I rarely get interrupts at all. I get maybe 1 interrupt per 3 seconds (yes seconds), which is extremely small considering the input is toggling in a while loop with minimal delay. At higher numbers I barely get any interrupts.

I've tried this with other gpio pins (within GPIO2), other gpio modules(GPIO0 and GPIO1) and other BBB boards. I believe I'm configuring the debounce correctly since I'm getting nearly the expected outputs for debounce times 0x01 and 0x02. I've looked into the following related posts but I dont think they answer this problem.

http://e2e.ti.com/support/arm/sitara_arm/f/791/t/217327 

https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/507463

https://e2e.ti.com/support/microcontrollers/stellaris_arm/f/471/p/169343/618474#618474

https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/717/t/379739

Regards,

Vineeth

  • Hi,

    What software is this?
  • I'm trying to develop a GPIO driver for XINU OS. The code I'm developing is not in the link though. I can send it separately.

    Regards,

    Vineeth

  • I am sorry. This forum supports only the TI distributed Processor SDK: www.ti.com/.../PROCESSOR-SDK-AM335X It's free to download and you can look through the Linux sources there.
  • Hi, 

    Is it possible to guide me as to how to use the debounce feature on linux? I don't see a way to set the debounce. I can set the direction and values by writing to the correct file. But I don't see a file for debounce.

    Regards,

    Vineeth

  • Check your timing.

    I assume that your GPIO toggle frequency is higher than the debounce time.

  • Hi Vineeth,

    I will refer to the latest released TI kernel (v4.4.32). It uses omap2_set_gpio_debounce(). You can see its implementation in drivers/gpio/gpio-omap.c:
    /**
    * omap2_set_gpio_debounce - low level gpio debounce time
    * @bank: the gpio bank we're acting upon
    * @offset: the gpio number on this @bank
    * @debounce: debounce time to use
    *
    * OMAP's debounce time is in 31us steps
    * <debounce time> = (GPIO_DEBOUNCINGTIME[7:0].DEBOUNCETIME + 1) x 31
    * so we need to convert and round up to the closest unit.
    */
    static void omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
    unsigned debounce)
    {
    void __iomem *reg;
    u32 val;
    u32 l;
    bool enable = !!debounce;

    if (!bank->dbck_flag)
    return;

    if (enable) {
    debounce = DIV_ROUND_UP(debounce, 31) - 1;
    debounce &= OMAP4_GPIO_DEBOUNCINGTIME_MASK;
    }

    l = BIT(offset);

    clk_enable(bank->dbck);
    reg = bank->base + bank->regs->debounce;
    writel_relaxed(debounce, reg);

    reg = bank->base + bank->regs->debounce_en;
    val = readl_relaxed(reg);

    if (enable)
    val |= l;
    else
    val &= ~l;
    bank->dbck_enable_mask = val;

    writel_relaxed(val, reg);
    clk_disable(bank->dbck);
    /*
    * Enable debounce clock per module.
    * This call is mandatory because in omap_gpio_request() when
    * *_runtime_get_sync() is called, _gpio_dbck_enable() within
    * runtime callbck fails to turn on dbck because dbck_enable_mask
    * used within _gpio_dbck_enable() is still not initialized at
    * that point. Therefore we have to enable dbck here.
    */
    omap_gpio_dbck_enable(bank);
    if (bank->dbck_enable_mask) {
    bank->context.debounce = debounce;
    bank->context.debounce_en = val;
    }
    }

    Hope this helps.

    Best Regards,
    Yordan