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.

TMDS64EVM: LLD MCU-domain MCSPI peripheral in interrupt mode does not produce clock signal

Part Number: TMDS64EVM
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Hi,

I am trying to get the "MCU_SPI0"-MCSPI-peripheral instance working with the LLD driver API provided with my 09.02.00 industrial comms SDK. As a reference in getting the interrupt values right I used the included "mcspi_loopback_interrupt_lld" example.

EDIT: The issue below has been resolved by changing the used interrupt callback mechanism. Though my reply still has a follow-up issue.

The first problem I ran into was that the interrupt never finished. Once the "MCSPI_lld_readWriteIntr"-function was called, the interrupt fired, my entry point "ISR_MCU_MCSPI0" is entered, "MCSPI_lld_controllerIsr" is called through the "ISR_CALL_LEVEL_NONFLOAT_REENTRANT"-macro and is stuck there, processing an interrupt that is never cleared.

I figured out that the issue there was me registering interrupt ID '208' during initialization of my driver wrapper (as I have my SPI peripheral device wired on the MCU_SPI0 pins) But passed interrupt number: '204' as argument to 'ISR_CALL_LEVEL_NONFLOAT_REENTRANT'. I think this caused that issue, and corrected the interrupt-ID to 208 in both 'MCSPILLD_InitObject'-initialization and the ISR-macro-argument.

Now the R5 core hangs in "HwiP_data_abort_handler_c()" after calling the macro in the following snippet:

AM64x_MCSPI.hpp

class AM64x_MCSPI : public drivers::SPI {
...
  [[gnu::section(".text.hwi"), gnu::noinline, gnu::naked, gnu::target("arm"),
    gnu::aligned(4)]] static void
  ISR_MCU_MCSPI0();
...
};

AM64x_MCSPI.cpp:

std::uintptr_t R5FSS01_VIC_section_base_address = 0x2FFF0000;
volatile MCSPILLD_Handle MCSPI_handle_MCSPI0 = nullptr;

...

void drivers::AM64x_MCSPI::ISR_MCU_MCSPI0() {
  ISR_CALL_LEVEL_NONFLOAT_REENTRANT(
      MCSPI_lld_controllerIsr, 
      MCSPI_handle_MCU_MCSPI0,
      208u,
      (R5FSS01_VIC_section_base_address + 0x404U + (((208) >> 5) & 0xFU) * 0x20U),
      0x1U << ((208u) & 0x1FU),
      R5FSS01_VIC_section_base_address);
}

The handle is correctly changed from nullptr to a valid MCSPILLD_Handle on class construction. I noticed that the register-clear-mask is 5 bits. Should a different register/mask combination be used in combination with the MCU MCSPI instances? I was thinking that the 5 bits of the mask (0x1Fu) might only account for the 5 main domain MCSPI instances, and a different argument is needed to properly handle MCU instances?

As a work around I could change the communication mode to polling, yielding to FreeRTOS between completed transfers. But I would like to get interrupt-mode working to minimize processing time on SPI transfers.

Thanks,

Matthijs

  • Update: I worked around this specific issue by using the HwiP_Object and associated functions. Created as follows:

        HwiP_Params parameters{
            .intNum = init_handle.intrNum, // 208 for MCU_MCSPI0
            .callback = &MCSPI_lld_controllerIsr,
            .args = &instance_handle, // MCSPILLD_Object*
            .eventId = 0,
            .priority = init_handle.intrPriority, // 4
            .isFIQ = 0,
            .isPulse = 0,
        };
        result = HwiP_construct(&interrupt_handle, &parameters);

    This interrupt and callback does fire. The transfer status does not progress beyond the 'MCSPI_TRANSFER_STARTED'-state though. And is eventually cancelled.

    I also attached a logic analyzer to the MISO, MOSI, CS and CLK pins. The output is as follows:

    In the red, Chip Select is pulled active for a number of millseconds. This closely aligns with a 5th Data/Command pin that is controlled with a GPIO driver between SPI transfers. So I think at least the CS mechanism works. The clock is inactive though. And I can't see a clock setting beyond the frequency/bitrate in the LLD_MCSPI configuration structs. Is there a setting I am missing? Or should I change something in sysconfig?

  • Update: Fixed this issue by rewriting the driver to use the HLD interface. Dumbing down the setup code to hook into the sysconfig generated stuff. Now it works, but I don't know why; The used settings should be identical