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.

AM335x McSPI Receive Only mode needs a dummy transmit

McSPI is working with EDMA and the performance is good. I’m using SPI1, single channel  (CH0) and master mode with TRM mode = “Transmit and Receive”. Being a typical engineer, I wanted to optimize things further. In my application, I only need to do a “Transmit Only” followed by a “Receive Only”. “Transmit Only” works fine but “Receive Only” never starts. BUT if I manually write to the TX0 register after enabling the SPI channel, the “Receive Only” completes. This makes no sense.  

My application sets the MCSPI_MODULCTRL register to all 0 except SINGLE=1. Below is the “Transmit Only” sequence:

  1. Disable SPI channel (set EN=0 in MCSPI_CH0CTRL)

  2. Set MCSPI_CH0 CONF register FORCE=1 (asserts chip select)

  3. Initialize EDMA TX ParamSet. Enable EDMA TX SPI channel for event trigger.

  4. Set MCSPI_XFERLEVEL register to WCNT=length, AFL=0, AEL=0

  5. Set MCSPI_CH0 CONF register with CLKG=0, FFER=1, FFEW=1,TCS=0, SBPOL=0, SBE=0, SPIENSLV=0, TURBO=1,IS=0,DPE1=0,DPE0=1, DMAR=0, DMAW=1,TRM=2 (Transmit only),WL=7,EPOL=1,CLKD=1,POL=0,PHA=0

  6. Enable SPI channel (set EN=1 in MCSPI_CH0CTRL)

  7. Wait for transmit to complete.

    Transmit completes correctly. I see the bytes sent on the scope, WCNT got set to 0 in the MCSPI_XFERLEVEL register and the EDMA ISR indicates completion. The “Receive Only” sequence immediately follows:

  1. Disable SPI channel (set EN=0 in MCSPI_CH0CTRL). MCSPI_CH0 CONF “FORCE” remains set from above.

  2. Initialize EDMA RX ParamSet. Enable EDMA RX SPI channel for event trigger.

  3. Set MCSPI_XFERLEVEL register to WCNT=length, AFL=0, AEL=0

  4. Set MCSPI_CH0 CONF register with CLKG=0, FFER=1, FFEW=1,TCS=0, SBPOL=0, SBE=0, SPIENSLV=0, TURBO=1,IS=0,DPE1=0,DPE0=1, DMAR=1, DMAW=0,TRM=1 (receive only),WL=7,EPOL=1,CLKD=1,POL=0,PHA=0

  5. Enable SPI channel (set EN=1 in MCSPI_CH0CTRL)

  6. Wait for receive to complete – it never does. No activity on scope and WCNT doesn’t change.

  7. Write to MCSPI_TX0. I see activity on the scope then WCNT=0 and the RX EDMA ISR indicate completion.

  • This behavior is explained in the AM335x Technical Reference Manual under section “24.3.2.5 Master Receive-Only Mode” Rule 2 so it’s working properly. I noticed the minimum number of bytes we can read in this mode is 2 (Master Transmit and Receive mode with DMA can read a single byte). So for a 1 byte transfer, we disable DMAR then write a dummy byte to MCSPI_TX0 then poll the RXS flag in MCSPI_CH0STAT then read the byte from MCSPI_RX0.

    Another odd behavior is we sometimes have to write MSCPI_XFERLEVEL twice. The first write is ignored.

    When using DMA, we poll for completion by looking at the EOW flag in the MSCPI_IRQSTATUS register and the EDMA3CC_S_IPRH register for that channel. Master read/write must always complete so there’s no need to check for timeout.
  • Thanks for sharing your solution on the forum.