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.

AM2434: mmc interrupt can't be set in PRU interrupt

Genius 13655 points
Part Number: AM2434
Other Parts Discussed in Thread: SYSCONFIG

Hello Champs,

In R5 code, customer enabled both PRU and MMC interrupts. The priority of PRU is higher than MMC's. In PRU ISR function, it communicates to MMC. The interrupt status bit in MMCSD1_NORMAL_INTR_STS(Normal Interrupt Status Register,0FA0 0030h)and MMCSD1_ERROR_INTR_STS(Error Interrupt Status Register,0FA0 0032h) registers are not set. 
Customer enabled all the interrupt. 

Why the mmc interrupt can't be set in PRU interrupt?




Thanks
Regards
Shine

  • Hi Shine,

    Whether the MMC generates interrupts to R5F/VIM should have nothing to do with whether the PRU also generates interrupts to R5F/VIM. This also has nothing to do with VIM, since you're saying the MMC peripheral itself isn't generating interrupts.

    Does the MMC generate interrupts (flags set in MMCSD1_NORMAL_INTR_STS or MMCSD1_ERROR_INTR_STS) if PRU interrupts (no PRU ISR is executed) are disabled?

    Regards,
    Frank

  • Hi Frank,

    Thanks for your great support.

    Customer is using TI's SDK, and the interrupts in it are handled by the HwiP_irq_handler_c() function. At the same time, the interrupts in MMCSD1_NORMAL_INTR_STS_EN and MMCSD1_ERROR_INTR_STS_EN are both enabled. After the PRU ISR process exits, it can enter the MMC ISR. The key is that in the PRU ISR, when the MMC communicates, you can see the MMCSD1_NORMAL_INTR_STS and MMCSD1_ERROR_INTR_STS interrupt flags are not set. Only when the PRU ISR exit, the  MMCSD1_NORMAL_INTR_STS and MMCSD1_ERROR_INTR_STS interrupt flags can be set.

    I want to know, how can I get the low priority interrupt status flag in the high priority interrupt ISR? ? ? Or, is it possible?

    Thanks
    Regards,
    Shine

  • Hi Shine,

    The priority of PRU is higher than MMC's

    I assume you're using IRQs and you're referring to the VIM PRU (ICSSG) vs MMC interrupt priority. Is this correct?

    The VIM priority for an interrupt has no effect on the interrupt status bits generated in a peripherial register (here MMC).

    Are you using No RTOS? According to the documentation, No RTOS support IRQ interrupt nesting: https://software-dl.ti.com/mcu-plus-sdk/esd/AM243X/08_05_00_24/exports/docs/api_guide_am243x/KERNEL_NORTOS_PAGE.html#autotoc_md490

    Is the PRU ISR interrupting the MMC ISR (since it's lower priority) after MMC ISR has cleared the MMC status registers? After exiting the PRU ISR, the MMC ISR would resume.

    Regards,
    Frank

  • Hi Frank,

    Thank you very much. 

    Below is the customer's reply.

    I assume you're using IRQs and you're referring to the VIM PRU (ICSSG) vs MMC interrupt priority. Is this correct?


    Yes, I disabled all interrupts in PRU ISR and then used the MMC. The MMC device can receive the data correctly, the interrupt flag should be set to 1 after transmitting data, but I checked the MMCSD1_NORMAL_INTR_STS and MMCSD1_ERROR_INTR_STS, they are not set to 1. 

    Thanks
    Regards
    Shine

  • Hi Shine,

    What is the behavior if you disable PRU interrupts entirely and perform the MMC processing you're currently experimenting with in PRU ISR inside the MMC ISR? Do you see the behavior you expect?

    What if you set the PRU & MMC ISRs to the same interrupt priority?

    Can you send me a toy example that shows the behavior so I can better you you with debug?

    Regards,
    Frank

  • Hi Frank,

    The PRU interrupt is completely disabled, and the MMC interrupt status is normal. After the MMC sends the data, the XFER_COMPLETE in MMCSD1_NORMAL_INTR_STS can be set to 1 which is exactly what he needs.

    BTW, customer is sorry that he doesn't have a suitable test code that can demonstrate this problem.

    Thanks
    Regards
    Shine

  • Hi Frank,

    Below is the customer's MMC SDIO configuration, it is not in PRU ISR. The status of XFER_COMPLETE is changing when MMC transmit/receive data. 

    {
    .ssBaseAddr = CSL_MMCSD1_SS_CFG_BASE,
    .ctrlBaseAddr = CSL_MMCSD1_CTL_CFG_BASE,
    .inputClkFreq = 200*1000000U,
    .outputClkFreq = 4*1000000U,
    .ClockEdge = SDIO_CLOCK_EDGE_FALLING,
    .enableDma = TRUE,
    .intrEnable = TRUE,
    .intrNum = 166U,
    .busWidth = SDIO_WIDTH_4BIT,
    .busVoltage = SDIO_VOLT_3_3V,
    .Callback = SDIO_IRQHandler,
    },

    MMCSD1_NORMAL_INTR_STS_ENA = 0xffff;
    MMCSD1_ERROR_INTR_STS_ENA = 0xffff;
    MMCSD1_NORMAL_INTR_SIG_ENA = 0xffff;
    MMCSD1_ERROR_INTR_SIG_ENA = 0xffff;

    static void SDIO_IRQHandler(void *arg)
    {

    const SDIO_Attrs *sdioAttrs = (const SDIO_Attrs *)arg;
    const CSL_mmc_ctlcfgRegs *pReg = (const CSL_mmc_ctlcfgRegs *)(sdioAttrs->ctrlBaseAddr);

    uint16_t regErr = 0U;
    uint16_t regNor = 0U;
    uint16_t respVal[8] = {0};

    regErr = CSL_REG16_RD(&pReg->ERROR_INTR_STS);
    regNor = CSL_REG16_RD(&pReg->NORMAL_INTR_STS);

    if(regNor & CSL_MMC_CTLCFG_NORMAL_INTR_STS_CMD_COMPLETE_MASK)
    {
    flgResp=1;
    }

    if(regNor & CSL_MMC_CTLCFG_NORMAL_INTR_STS_BUF_RD_READY_MASK)
    {
    flgResp=2;
    }

    CSL_REG16_WR(&pReg->ERROR_INTR_STS, 0xffff);
    CSL_REG16_WR(&pReg->NORMAL_INTR_STS, 0xffff);

    }

    static uint16_t SDIO_StateCode()
    {

    const CSL_mmc_ctlcfgRegs *pReg = (const CSL_mmc_ctlcfgRegs *)(gSdioAttrs->ctrlBaseAddr);

    uint16_t regErr;
    uint16_t regNor;
    uint16_t resCode = 0;

    regErr = CSL_REG16_RD(&pReg->ERROR_INTR_STS);
    regNor = CSL_REG16_RD(&pReg->NORMAL_INTR_STS);

    if(regNor & CSL_MMC_CTLCFG_NORMAL_INTR_STS_CMD_COMPLETE_MASK)
    {
    resCode=1;
    }

    if(regNor & CSL_MMC_CTLCFG_NORMAL_INTR_STS_BUF_RD_READY_MASK)
    {
    resCode=2;
    }
    /*
    CSL_REG16_WR(&pReg->ERROR_INTR_STS, 0xffff);
    CSL_REG16_WR(&pReg->NORMAL_INTR_STS, 0xffff);
    */
    return resCode;

    }



    Thanks
    Regards
    Shine

  • Hi Shine,

    I looked at the SDK 08.05 MMCSD driver. I'm not an expert in this driver, but from what I can determine, interrupt mode isn't supported.

    • Sysconfig has no "interrupt enable" switch. Generated code sets gMmcsdAttrs[0].intrEnable to FALSE.
    • Inside the driver (<SDK>\source\drivers\mmcsd\v0\mmcsd_v0.c:MMCSD_open(), MMCSD_isr() is registered if attrs->intrEnable is TRUE.
    • MMCSD_isr() is an empty function.

    Also, looking at the SDK release notes, I see the comment "Interrupt mode not tested" for the MMCSD R5F driver: https://software-dl.ti.com/mcu-plus-sdk/esd/AM243X/08_05_00_24/exports/docs/api_guide_am243x/RELEASE_NOTES_08_05_00_PAGE.html

    I'm looping in an MMCSD driver expert for further comment in case I'm mistaken.

    What SDK software is the customer using for MMCSD transfers? How is the customer enabling and registering interrupts for the MMCSD software?

    I want to make sure I understand what the customer is trying to do. Can you please confirm my summary below is correct?

    Summary:

    • Software executing on R5F.
    • Using MMCSD1.
      • Using MMCSD1_EMMCSDSS_INTR_0 input on VIM, routed to IRQ.
      • Interrupt enabled.
    • Using ICCSGn,PRUm.
      • Using one of PRU_ICSSG0_PR1_HOST_INTR_PEND_0-7 interrupt inputs on VIM, routed to IRQ.
      • Interrupt enabled.
    • PRU interrupt is set as higher priority than MMCSD interrupt.
    • Inside PRU ISR:
      • MMCSD is used for read and/or write.
      • Customer expects MMCSD1_NORMAL_INTR_STS bits to be updated while inside PRU ISR after MMCSD read/write is complete. These status register bits aren't updating as expected inside the PRU ISR.
      • Customer needs MMCSD1_NORMAL_INTR_STS bits to update inside PRU ISR for proper operation of code.
    • Customer disabled MMCSD interrupts, observes same behavior in PRU ISR. This seems to indicate interrupt nesting isn't causing the issue.
    • If PRU interrupts are disabled, MMCSD behaves normally. MMCSD1_NORMAL_INTR_STS bits are set correctly after read/write completes.

    How is the customer determining the MMCSD1_NORMAL_INTR_STS bits aren't set inside the PRU ISR?

    Inside the PRU ISR, what are the values of these registers:

    • MMCSD1_NORMAL_INTR_SIG_ENA
    • MMCSD1_NORMAL_INTR_STS_ENA

    What is the value of these registers if the MMCSD read/write is invoked outside the PRU ISR?

    Does the customer see the same behavior if another interrupt is used intead of PRU, e.g. DMTimer?

    Regards,
    Frank

  • Hi Frank,

    What SDK software is the customer using for MMCSD transfers?

    SDK 8.5.0.24

    How is the customer enabling and registering interrupts for the MMCSD software?

    HwiP_Params hwiPrms;
    if((sdioAttrs->intrEnable == TRUE) && (sdioAttrs->Callback != NULL))
    {
    HwiP_Params_init(&hwiPrms);
    hwiPrms.intNum = sdioAttrs->intrNum;
    hwiPrms.callback = sdioAttrs->Callback;
    hwiPrms.args = (void *)sdioAttrs;
    hwiPrms.priority = 0x03;
    status = HwiP_construct(NULL, &hwiPrms);
    }

    How is the customer determining the MMCSD1_NORMAL_INTR_STS bits aren't set inside the PRU ISR?

    After MMC sent data, customer read the MMCSD1_NORMAL_INTR_STS to see if  XFER_COMPLETE is set to 1.


    What is the value of these registers if the MMCSD read/write is invoked outside the PRU ISR?


    Thanks
    Regards
    Shine

  • Hi Shine,

    I understand the customer is using their own SDIO driver. Is that correct?

    Can you please confirm my above summary is correct?

    Thanks for sharing MMCSD1_NORMAL_INTR_SIG_ENA / MMCSD1_NORMAL_INTR_STS_ENA outside the PRU ISR. From your snapshot, I understand:

    • MMCSD1_NORMAL_INTR_SIG_ENA = 0x7FFF
    • MMCSD1_NORMAL_INTR_STS_ENA = 0x7FFF

    What are the values of these registers inside the PRU ISR?

    Does the customer see the same behavior if another interrupt is used instead of PRU, e.g. DMTimer? This should be a simple experiment for them.

    I can't think of a reason MMCSD status register updates would be masked (or not update) inside an ISR (PRU or otherwise). I don't think this has anything to do with PRU host interrupts, R5F VIM, or the SDK IRQ handler.

    I'm reassigning this thread to a colleague with more expertise on MMCSD.

    Regards,
    Frank

  • Hi Frank,

    Thank you very much.

    Below is customer's reply.

    Summary:

    • Software executing on R5F. Yes
    • Using MMCSD1.
      • Using MMCSD1_EMMCSDSS_INTR_0 input on VIM, routed to IRQ. Yes
      • Interrupt enabled. Yes
    • Using ICCSGn,PRUm.
      • Using one of PRU_ICSSG0_PR1_HOST_INTR_PEND_0-7 interrupt inputs on VIM, routed to IRQ.

    PRU_ICSSG1_PR1_HOST_INTR_PEND_1,PRU_ICSSG1_PR1_HOST_INTR_PEND_2,PRU_ICSSG1_PR1_HOST_INTR_PEND_3,PRU_ICSSG1_PR1_HOST_INTR_PEND_4

      • Interrupt enabled. Yes
    • PRU interrupt is set as higher priority than MMCSD interrupt.

    Yes,PRU=1,MMCSD=15。If changing MMCSD priority to other value, e.g. 4, the result is the same. 

    • Inside PRU ISR:
      • MMCSD is used for read and/or write. yes
      • Customer expects MMCSD1_NORMAL_INTR_STS bits to be updated while inside PRU ISR after MMCSD read/write is complete. These status register bits aren't updating as expected inside the PRU ISR. yes
      • Customer needs MMCSD1_NORMAL_INTR_STS bits to update inside PRU ISR for proper operation of code. yes
    • Customer disabled MMCSD interrupts, observes same behavior in PRU ISR. This seems to indicate interrupt nesting isn't causing the issue.

    MMCSD1_NORMAL_INTR_STS. XFER_COMPLETE can't set to 1

    • If PRU interrupts are disabled, MMCSD behaves normally. MMCSD1_NORMAL_INTR_STS bits are set correctly after read/write completes. yes

    What are the values of these registers inside the PRU ISR?

    Does the customer see the same behavior if another interrupt is used instead of PRU, e.g. DMTimer? 

    Yes, DMTimer can run correctly.



    Thanks
    Regards,
    Shine

  • Hi ,

    To analyze the problem more in depth, can the customer share the project where the problem is replicated ? This will save us some time in recreating the project. Customer can choose to remove all their proprietary SW and replicate the issue on a vanilla software from SDK code base.

    This will really speed-up the debug by a few days.

    Thanks and Regards,
    Aakash

  • Hi Shine,

    Thanks for the response.

    From your snapshot, I understand MMCSD1_NORMAL_INTR_SIG_ENA/MMCSD1_NORMAL_INTR_STS_ENA have these settings inside the PRU ISR:

    • MMCSD1_NORMAL_INTR_SIG_ENA = 0x7FFF
    • MMCSD1_NORMAL_INTR_STS_ENA = 0x7FFF

    These look normal.

    Yes, DMTimer can run correctly.

    To be clear, when you take the DMTimer ISR, you're able to use your MMCSD software inside the ISR and the MMCSD behaves correctly? I assume you've set the DMTimer interrupt priority to the same as the PRU ISR (when it's built into the code)? This suggests there is some issue with PRU interrupts.

    I agree with Aakash and I'm again requesting an example demonstrating this behavior. I understand the customer has written custom MMCSD driver software. Also, it would be difficult for us to recreate this using SDK MMCSD APIs since they don't currently support interrupt mode (Aakash, please confirm).

    Regards,
    Frank

  • Hi ,

    For starters, if we could get hands on an example that works with PRU and DMTimer that would be good start for us as well. We might need more information on how the MMCSD changes are required, but this will enable us to support better.

    Best Regards,
    Aakash

  • Hi Aakash & Frank,

    Thanks for your great support.

    OK. I've contacted customer to see if he would like to provide us a test project. 

    I'll post it here as soon as I get it. 

    Thanks
    Regards,
    Shine