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.

MSP432P401R: eUSCI - transferring greater than 8-bit word width in SPI mode

Part Number: MSP432P401R

MSP432 Team,

A customer needs to perform 16, 24, and 32-bit word transfers in SPI mode with the eUSCI.  That is, they need UCxSTE to go inactive between word transfers.  However, the eUSCI only allows data width of 7 or 8 bits.  I have confirmed using an EVM that the UCxSTE bit will remain active between transfers if you keep UCxTXBUF filled without the TX shift register getting empty (this needs to be documented).  So, the CPU could be used to perform a multi-byte transfer using interrupts from the eUSCI.  If the CPU is used, an alternative is to use a GPIO in place of UCxSTE signal as well.  Then the CPU has full manual control of the STE signal.

But, I don't think the DMA can be efficiently used here.  I think all you could do is setup the DMA to transfer the number of bytes needed in a single word (e.g., 16, 24, or 32 bit word).  After that, you need a pause so that the eUSCI stops transmitting and the UCxSTE signal goes inactive.  The CPU could then re-start the DMA for the next word.

Am I missing the trick here?  Is there any way to get the DMA to handle a buffer of multiple 16, 24, or 32-bit words to the eUSCI without the need for CPU intervention?  Specifically, the UCxSTE signal must go inactive between words.

Thank you,

David

  • David,
    I think you have described the DMA accurately. The only trick would be to use the scatter-gather feature and create a task list(s) that would support the transfer, assuming the transfer size and function is always the same.

    Is the multiple number of words being sent always the same and relatively small (<50)? The thought is that some of the tasks would handle the GPIO while others would load the eUSCI buffer. You could have the GPIO tasks be triggered automatically while the eUSCI tasks are triggered from the peripheral.

    Conceptually, it might look like this for the 24-bit example:

    DMA_ControlTable spi_24_Seq[TX_TASKS] =
    {
    /* Task1, Dummy read RX buffer to clear IFG */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
    UDMA_DST_INC_NONE, &dummyRX,
    UDMA_ARB_1, (UDMA_MODE_MEM_SCATTER_GATHER)),
    /* Task2, Clear Chip select P6.2 */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &outputLow,
    UDMA_DST_INC_NONE, &P6->OUT,
    UDMA_ARB_1, (UDMA_MODE_MEM_SCATTER_GATHER)),
    /* Task3, load TX buffer to initiate SPI */
    DMA_TaskStructEntry(2, UDMA_SIZE_8,
    UDMA_SRC_INC_8, &txBuffer[0],
    UDMA_DST_INC_NONE, &EUSCI_B1_SPI->TXBUF,
    UDMA_ARB_2, (UDMA_MODE_PER_SCATTER_GATHER)),
    /* Task4, Dummy read RX buffer to clear IFG, wait for RXIFG trigger */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
    UDMA_DST_INC_NONE, &dummyRX,
    UDMA_ARB_1, (UDMA_MODE_MEM_SCATTER_GATHER)),
    /* Task 5, load TX buffer to initiate SPI */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &txBuffer[2],
    UDMA_DST_INC_NONE, &EUSCI_B1_SPI->TXBUF,
    UDMA_ARB_1, (UDMA_MODE_PER_SCATTER_GATHER)),
    /*
    * Task 6, Dummy read RX buffer to clear IFG
    * This delay ensures that the chip select happens after the last byte is transmitted
    */
    DMA_TaskStructEntry(2, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
    UDMA_DST_INC_NONE, &dummyRX,
    UDMA_ARB_2, (UDMA_MODE_MEM_SCATTER_GATHER)),
    /* Task 7, set GPIO, chip select */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &DAC_CS,
    UDMA_DST_INC_NONE, &P6->OUT,
    UDMA_ARB_4, UDMA_MODE_MEM_SCATTER_GATHER)
    // copy (repeat) tasks 2-7 ‘n’ times


    // for the last one it would need to look like this

    /*
    * Task 6, Dummy read RX buffer to clear IFG
    * This delay ensures that the chip select happens after the last byte is transmitted
    */
    DMA_TaskStructEntry(2, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
    UDMA_DST_INC_NONE, &dummyRX,
    UDMA_ARB_2, (UDMA_MODE_MEM_SCATTER_GATHER)),
    /* Task 7, set GPIO, chip select */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &DAC_CS,
    UDMA_DST_INC_NONE, &P6->OUT,
    UDMA_ARB_4, UDMA_MODE_BASIC)


    };

    Chris
  • > I have confirmed using an EVM that the UCxSTE bit will remain active between transfers if you keep UCxTXBUF filled without the TX shift register getting empty (this needs to be documented).

    Is this the behavior of UCSTEM(=1)? That would seem to contradict SLAU356G Fig 23-4 (and only sometimes).
  • Bruce McKenney47378 said:

    Is this the behavior of UCSTEM(=1)? That would seem to contradict SLAU356G Fig 23-4 (and only sometimes).

    Yes, UCSTEM=1.  I think Figure 23-4 is for a single byte transfer only.
    - David

**Attention** This is a public forum