Multiple SPIM sections using EasyDMA

My design is in alpha test and we just discovered that apparently SPIM allows only one module to be enabled at a time. When a second module (SPIM3, SPIM2) is enabled, the first turns off or the 2nd never turns on, depending on the relative priority of the two. Surely this can't be a restriction of the part, or there would be no reason to have multiple modules. Reducing the clock rates does not help. How can I run two (or more) SPIM modules simultaneously?

Parents
  • Post your dts overlay with the peripherial and pin configs. I can run multiple SPIM peripherials here - but its easy to make a mistake with the shared peripherials and the DTS checker won't catch all of them AFAIK.

  • I can't find any reference to "DTS checker" etc., so I must presume that's something in whatever IDE you're using. I'm using Segger. Below are snippets of my code that show what I'm doing with the SPIM. I have tried using different combinations of SPIM0 thru 3, and various clock frequencies. SPIM3, being highest priority, works best, but enabling any other SPIMx channel kills SPIM3.My code does not use any of the TWI, SPI, or SPIS channels that conflict with the SPIM channels.

    NRF_SPIM_Type *SPITable [Channels] = {NRF_SPIM3, NRF_SPIM2};
    NRF_SPIM_Type *SPI;

    SetPinCfg (PinNum [Ch], 0x00000303);
    SPI = SPITable [Ch];
       SPI -> TASKS_STOP = 1;
       SPI -> ENABLE = 0;
       SPI -> SHORTS = 1 << 17;
       SPI -> PSEL.SCK = (uint32_t) 0xFFFFFFFF; // disconnect Clk
       SPI -> PSEL.MOSI = PinNum [Ch];
       SPI -> PSEL.MISO = 0xFFFFFFFF; // Disconnect MISO
       SPI -> PSEL.CSN   = 0xFFFFFFFF;
       SPI -> FREQUENCY = SpiClkFreq [SpiClk [Ch]].Reg;
       SPI -> RXD.PTR = (uint32_t) &Dummy;
       SPI -> RXD.MAXCNT = sizeof Dummy;
       SPI -> RXD.LIST = 0;
       SPI -> TXD.PTR = (uint32_t) Buffer [Ch];
       SPI -> TXD.MAXCNT = NumBytes [Ch];
       SPI -> TXD.LIST = 0;
       SPI -> CONFIG = 0;
       SPI -> ENABLE = 7;
       SPI -> TASKS_START = 1;

  • SCK is a required hardware pin and although it can be set to disconnected the SPIM then does not work correctly, particularly with multiple SPIMs. The reason is likely to be the hardware clock path to the internal SPI peripheral as the SPI peripheral must cope with both internal (Master) and external (Slave) clock routes. I suspect the physical path was simply designed to be identical and therefore requires the SCK to be an output pin driving the internal clock line. Even if you got a single SPIM to work multiple SPIMs would share the same clock line and therefore misbehave.

    In case I am correct regarding your issue, simply set SCK to any spare or unused pin for each SPIM and test again.

    Edit: Tidied up and found an old link: spi-not-transferring-when-sck-pin-not-used

    "It's not  bug, it's a feature .."

  • I thought of that also. But why does it work fine with only one channel operating?

    Still, it's worth a try. I'll have a go at that. I have plenty of unused pins where I can dump SCLK.

  • Well, son-of-a-self-sealing-cylinder!! That appears to work! Quite strange that the channels will work without it if only one is enabled and not with two enabled, but I've got the proof. Now, to get back to some of the other issues with my code.

    Thank you very much for being so responsive. Sometimes it just takes somebody else to point out the "obvious". One of the drawbacks of being a one-man-shop!

  • Glad to be of help; also a one-man-shop :-)

    This may possibly be of help if wanting many SPIMs: spi-sharing-common-lines

  • Won't help here, OP is abusing MOSI as some kind of PWM signal generator and thus needs constant clocking of the peripherial(s).

    I recommend the PWM peripherials for most signal generating use cases.

Reply Children
No Data
Related