SLAAEL4 September   2025

 

  1.   1
  2. 1Description
  3. 2Required Peripherals
  4. 3Design Steps
  5. 4Design Considerations
  6. 5Software Flow Chart
  7. 6Required I2C Packet
  8. 7Application Code
  9. 8Additional Resources
  10. 9E2E

Application Code

The code example updates the stored GPIO state any time a pin observes a rising or falling edge. The IRQ_OUT pin is only pulled low when an input pin observes a rising or falling edge, and is pulled high once the controller requests a read. The TX FIFO is filled upon receiving an I2C Start and is flushed upon an I2C Stop:

//I2C INT
void I2C_INST_IRQHandler(void)
{
    switch (DL_I2C_getPendingInterrupt(I2C_INST)) {
        case DL_I2C_IIDX_TARGET_START: 
            /* Fill TX FIFO with current pin state */
            DL_I2C_fillTargetTXFIFO(I2C_INST, &gGpioState, 1);
            break;
        case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER: 
            /* Store received data in buffer */
            while (DL_I2C_isTargetRXFIFOEmpty(I2C_INST) != true) {
                receivePacket(DL_I2C_receiveTargetData(I2C_INST)); 
            }
            break;
        case DL_I2C_IIDX_TARGET_TX_DONE: 
            /* Pull interrupt pin high when Controller reads from IO Expander */
            DL_GPIO_setPins(GPIO_GRP_0_PORT, GPIO_GRP_0_IRQ_OUT_PIN);
            break;
        case DL_I2C_IIDX_TARGET_STOP: 
            /* Flush TX FIFO */
            DL_I2C_flushTargetTXFIFO(I2C_INST);
            break;
        default:
            break; 
    }
}

void GPIOA_IRQHandler(void)
{ 
    /* Store the current pin state */
    gGpioState = (DL_GPIO_readPinStatus(GPIO_GRP_0_PIN_7_PIN) << 7) |
                 (DL_GPIO_readPinStatus(GPIO_GRP_0_PIN_6_PIN) << 6) | 
                 (DL_GPIO_readPinStatus(GPIO_GRP_0_PIN_5_PIN) << 5) | 
                 (DL_GPIO_readPinStatus(GPIO_GRP_0_PIN_4_PIN) << 4) | 
                 (DL_GPIO_readPinStatus(GPIO_GRP_0_PIN_3_PIN) << 3) | 
                 (DL_GPIO_readPinStatus(GPIO_GRP_0_PIN_2_PIN) << 2) | 
                 (DL_GPIO_readPinStatus(GPIO_GRP_0_PIN_1_PIN) << 1) | 
                 (DL_GPIO_readPinStatus(GPIO_GRP_0_PIN_0_PIN)); 

    /* Loop through all pins */
    for (int i = 0; i < 8; i++) { 
        /* Check if the current pin state changed */
        if (((gGpioState >> i) & 0x1) != ((gLastGpioState >> i) & 0x1)) { 
            /* If the pin is an Input */
            if (((gGpioDirection >> i) & 0x1) == 0) { 
                /* Pull interrupt pin LOW when an input pin state changes */
                DL_GPIO_clearPins(GPIO_GRP_0_PORT, GPIO_GRP_0_IRQ_OUT_PIN); 
            } 
        } 
    }
    gLastGpioState = gGpioState;
}

The controller IRQ_IN interrupt is triggered upon a detected falling edge, where a read to the IO expander is requested:

void GPIOA_IRQHandler(void)
{ 
    /* Set LED HIGH */
    DL_GPIO_clearPins(GROUP0_PORT, GROUP0_LED_PIN); 

    /* Request a read from the IO Expander */
    gRxLen = I2C_RX_PACKET_SIZE;
    gRxCount = 0; 

    /* Wait until the I2C bus is idle */
    while (!(DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)); 

    /* Start a read operation */
    gI2cControllerStatus = I2C_STATUS_RX_STARTED;
    DL_I2C_startControllerTransfer(I2C_INST, I2C_IO_EXPANDER_ADDRESS,
                                    DL_I2C_CONTROLLER_DIRECTION_RX, gRxLen); 
    /* Enable RX FIFO trigger interrupt */
    DL_I2C_enableInterrupt(I2C_INST, DL_I2C_INTERRUPT_CONTROLLER_RXFIFO_TRIGGER);
}