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.

GPIO interrupts broken on AM335x/387x/389x BSP A8_2.30

Other Parts Discussed in Thread: AM3359, SYSCONFIG

Looks like the GPIO interrupt is indeed broken. For sure in the AM33x and most probably also in AM387x and AM389x.

I corrected the obvious problem in the intr.c file in \COMMON_ti_v1\AM33X\OAL\INTR\intr.c where the "else if" tests were short circuiting because the software interrupts were moved to higher irq numbers than the GPIO.

The setup calls now at least do not fail but I am still not getting the interrupts to fire.

Is this a known problem? does anyone see a fix in our future?

  • We have recently updated the interrupt handler to address this issue. The code was "short circuiting" the handling of the gpio interrupts as mentioned. Here is the unified code diff for the change:

    ---<edited>/PLATFORM/COMMON/SRC/SOC/COMMON_TI_V1/AM33X/OAL/INTR/intr.c
    +++<edited>/PLATFORM/COMMON/SRC/SOC/COMMON_TI_V1/AM33X/OAL/INTR/intr.c
    @@ -308,5 +308,5 @@
         UINT32 irq, i;
     
    -    OALMSG(/*OAL_INTR&&OAL_VERBOSE*/1, (L"+OALIntrEnableIrqs(%d, 0x%08x)\r\n", count, pIrqs ));
    +    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OALIntrEnableIrqs(%d, 0x%08x)\r\n", count, pIrqs ));
     
         for (i = 0; i < count; i++){
    @@ -372,5 +372,5 @@
         UINT32 irq, i;
     
    -    OALMSG(/*OAL_INTR&&OAL_VERBOSE*/1, (L"+OALIntrDisableIrqs(%d, 0x%08x)\r\n", count, pIrqs ));
    +    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OALIntrDisableIrqs(%d, 0x%08x)\r\n", count, pIrqs ));
     
         for (i = 0; i < count; i++) {
    @@ -508,8 +508,7 @@
                     g_IrqCnt[irq]++;
     
    -    //if (irq != 69) OALMSG(/*OAL_INTR*/ 1, (L"OEMInterruptHandler(Irq %d)\r\n", irq));
    +    OALMSG(OAL_INTR, (L"OEMInterruptHandler(Irq %d)\r\n", irq));
     
         if (irq == IRQ_GPIO0A){
    -            OALMSG(/*OAL_INTR*/ 1, (L"²"));
             // mask status with irq enabled GPIO's to make sure
             // only interrupts which generated a new interrupt is 

    This will allow a gpio pin interrupt that has a sysintr registered to its IRQ
    to fire the associated event. This is assuming that the irq<->sysintr
    and event mapping have been made, and that the pin/pad have
    been multiplexed and configured to allow inputs on the gpio pin.
  • I'll give it a try.

    Could you attach the complete intr.c file?

  • Dear David,

    I have created a zip file with the modified files.

    0042.changeset_TRUNK.zip

  • Hi, boy, Now I have same issue with you about AM3359 WINCE7 GPIO IRQ.

    could you please help me ?

    below is my code:

    EnableDeviceClocks(AM_DEVICE_GPIO0, TRUE );     

    PHYSICAL_ADDRESS PortAddress = {AM33X_GPIO0_REGS_PA, 0}; 

    pGPIORegs = (AM3XX_GPIO_REGS *)MmMapIoSpace(PortAddress, sizeof(AM3XX_GPIO_REGS), FALSE);

        pGPIORegs->SYSCONFIG |= (1<<1);

        pGPIORegs->OE |= (1<<4); 

    pGPIORegs->IRQSTATUS_SET_0  |= (1<<4); 

    pGPIORegs->IRQSTATUS_SET_1  |= (1<<4);

      pGPIORegs->RISINGDETECT &= ~(1<<4);

      pGPIORegs->FALLINGDETECT |= (1<<4);

      pGPIORegs->LEVELDETECT0  |= (1<<4);

      pGPIORegs->LEVELDETECT1 &= ~(1<<4);

    pGPIORegs->OE &= ~(1<<5);

      pGPIORegs->DATAOUT |= (1<<5); 

    Sleep(100); 

    pGPIORegs->DATAOUT &= ~(1<<5); 

    Sleep(100);

      pGPIORegs->DATAOUT |= (1<<5);

        SX8650_Init();

    //    s_TouchDevice.nPenIRQ = GetIrqByDevice(AM_DEVICE_ADC_TSC, NULL); 

    s_TouchDevice.nPenIRQ = IRQ_GPIO_4;//BSPGetGpioIrq(GPIO_4);

        // run intr thread and configure interrupt 

    if (!KernelIoControl(             IOCTL_HAL_REQUEST_SYSINTR,             &s_TouchDevice.nPenIRQ,             sizeof(s_TouchDevice.nPenIRQ),             &s_TouchDevice.dwSysIntr,             sizeof(s_TouchDevice.dwSysIntr),             NULL             ) ) 

    {         RETAILMSG(1, (TEXT("ERROR: TOUCH: Failed to request the touch sysintr.\r\n")));     

    s_TouchDevice.dwSysIntr = (DWORD)SYSINTR_UNDEFINED;     

    goto cleanup;     }

      RETAILMSG(1, (TEXT(" TOUCH: touch sysintr:%d.\r\n"), s_TouchDevice.dwSysIntr));

  • Still got the issue on my BeagleBone with the BSP code provided by David Vescovi (based on TI WEC7 BSP)3630.am33x_gpio_reg.h5086.intr.c.

    Did someone manage to get interrupts fired on GPIOs ?

    Here is my code and I don't understand why the interrupts do not fire (although I can see the signal latching on the scope):

    dwGPIO_handle = GPIOOpen();
    GPIOSetMode(dwGPIO_handle, (DWORD)GPIO1_17, GPIO_DIR_INPUT | GPIO_INT_HIGH_LOW );
    bSuccess = ( (GPIO_DIR_INPUT | GPIO_INT_HIGH_LOW) == GPIOGetMode(dwGPIO_handle, (DWORD)GPIO1_17));
    
    if(bSuccess)
    {
    dwIRq=GPIOGetSystemIrq(dwGPIO_handle, (DWORD)GPIO1_17);
    if(dwIRq)
            {
                dwI2C_SysIntr =     (DWORD) SYSINTR_UNDEFINED;
                // Create an event to wait on
                hI2C_Event = CreateEvent(NULL, FALSE, FALSE, NULL);
                if (hI2C_Event!= NULL)
                {
                    // Get the SYSINTR that corresponds to dwIrq (non GPIO Irqs correspond to the bit numbers of the PXA27x Interrupt resisters)
                    if (!KernelIoControl(
                            IOCTL_HAL_REQUEST_SYSINTR,
                            &dwIRq,
                            sizeof(dwIRq),
                            &dwI2C_SysIntr,
                            sizeof(dwI2C_SysIntr),
                            NULL
                            ) )
                    {
                        RETAILMSG(ZONE_ERROR, (TEXT("ERROR: Failed to request the input interrupt gpio's sysintr.\r\n")));
                    }
                    else
                    {
                        if (GPIOInterruptInitialize(dwGPIO_handle, (DWORD)GPIO1_17, &dwI2C_SysIntr, hI2C_Event))
                        {
                            GPIOInterruptDone(dwGPIO_handle, (DWORD)GPIO1_17, dwI2C_SysIntr);
                        }
                        else
                        {
                            RETAILMSG(ZONE_ERROR, (TEXT("ERROR: Failed to initialize the interrupt line.\r\n")));
                        }
                    }
                }
    }


    And then, when I wait on the created event, the interrupt never occurs when my signal latches.

    I also tried without calling GPIOGetSystemIrq and KernerlIoControl + IOCTL_HAL_REQUEST_SYSINTR as these are already handled in GPIOInterruptInitialize but the result is the same.

    Any advice would be greatly appreciated !!

  • I thought only bank zero (GPIO0_0-GPIO0_31) are interrupt enabled ...but I could be wrong.

  • Thanks for your reply David.

    I tried with banks 0, 1 and 3 : same result.

    What surprises me is that I can see the GPIO registers set properly, DATAIN changes according to the pin signal value and IRQSTATUS_RAW_0 is changing on falling edges but SYSINTR is never called... (On the screenshot below, I am working with GPIO0_27 instead of GPIO1_17)



    What am I missing here ?