0

Is it possible for arduino Due to act as DMA-SPI-slave device which can exchange SPI data (uint16_t TX[10] and RX[10]) in triggered slave mode?

I have a setup in which time period is very short (~500uS/cycle). so I need to exchange data with another Microcontroller (acting as 'Master') within the mensioned time limit. Some other tasks are also to be processed. This is why I have to go for DMA and fast data transfer without intervension of processor. All the codes available are to be used in Master mode of SPI. Not a single one is in SLAVE mode. I wrote a code but I cannot implement a transfer triggered by SPI hardware. Also how to implement data transfer complete Interrupt after all 10 datas(16bit) have been transferred and received? Here is my initialization code:

    void DMAslaveBegin()
{
    // Configure the pins for SPI in peripheral mode
    PIO_Configure(
        g_APinDescription[PIN_SPI_MOSI].pPort,
        g_APinDescription[PIN_SPI_MOSI].ulPinType,
        g_APinDescription[PIN_SPI_MOSI].ulPin,
        g_APinDescription[PIN_SPI_MOSI].ulPinConfiguration);
    PIO_Configure(
        g_APinDescription[PIN_SPI_MISO].pPort,
        g_APinDescription[PIN_SPI_MISO].ulPinType,
        g_APinDescription[PIN_SPI_MISO].ulPin,
        g_APinDescription[PIN_SPI_MISO].ulPinConfiguration);
    PIO_Configure(
        g_APinDescription[PIN_SPI_SCK].pPort,
        g_APinDescription[PIN_SPI_SCK].ulPinType,
        g_APinDescription[PIN_SPI_SCK].ulPin,
        g_APinDescription[PIN_SPI_SCK].ulPinConfiguration);
    PIO_Configure(
        g_APinDescription[PIN_SPI_SS0].pPort,
        g_APinDescription[PIN_SPI_SS0].ulPinType,
        g_APinDescription[PIN_SPI_SS0].ulPin,
        g_APinDescription[PIN_SPI_SS0].ulPinConfiguration); 
    //pmc_enable_periph_clk(ID_SPI0);
#if USE_SAM3X_DMAC
    pmc_enable_periph_clk(ID_DMAC);
    DMAC_Disable();
    DMAC->DMAC_GCFG = DMAC_GCFG_ARB_CFG_FIXED;  //Fixed priority arbiter
    DMAC_Enable();

#if USE_SAM3X_BUS_MATRIX_FIX    // not active here
    MATRIX->MATRIX_WPMR = 0x4d415400;
    MATRIX->MATRIX_MCFG[1] = 1;         //Single Access
    MATRIX->MATRIX_MCFG[2] = 1;         //Single Access
    MATRIX->MATRIX_SCFG[0] = 0x01000010;
    MATRIX->MATRIX_SCFG[1] = 0x01000010;
    MATRIX->MATRIX_SCFG[7] = 0x01000010;

#endif  // USE_SAM3X_BUS_MATRIX_FIX
#endif  // USE_SAM3X_DMAC
    //  initialize SPI controller - Slave mode
    SPI.begin(_pin);
    SPI_Disable(SPI0);
    REG_SPI0_CR = SPI_CR_SWRST;     // reset SPI
    REG_SPI0_CR = SPI_CR_SPIEN;     // enable SPI
    REG_SPI0_MR = 0x10;              // DLYBCS=0, PCS=0, MODFDIS=1, PS=0, MSTR=0(slave)
    REG_SPI0_CSR = 0x80;            // DLYBCT=0, DLYBS=0, SCBR=0, 16 bit transfer, Mode 0/1
    REG_SPI0_IDR = ~SPI_IDR_RDRF;
    REG_SPI0_IER = SPI_IDR_RDRF;
    NVIC_EnableIRQ(SPI0_IRQn);
    SPI_Enable(SPI0);
}

Is this a valid condition for DMA? How can I utilize SPI ISR handler like system in DMA for my code so that the complete transaction (simultaneous Transmit & Receive) becomes fully automatic without processor utilization?

7
  • It is more than likely possible. However, we lowly Arduino users probably aren't knowledgeable enough about Atmel's SDK and the workings of the Due's MCU to give you the best answer. Your best source of information would probably be a dedicated Atmel ARM MCU forum. One that deals on a more professional level than Arduino.
    – Majenko
    Sep 12 '19 at 18:52
  • Thanks. I'll post. but, does DMA callbacks on SPI interrupt?
    – souravg009
    Sep 12 '19 at 19:54
  • What does the datasheet / SDK API manual say?
    – Majenko
    Sep 12 '19 at 19:56
  • PDC can employ Handler, but I couldn't find DMA Handler for SPI slave mode. The datasheet DMAC section is also messy.
    – souravg009
    Sep 12 '19 at 20:10
  • 1
    Your point of view might be right about "DMA really cares about what "mode" SPI is running in".@Majenko. We are using SPI RX and TX Buffers as Source and Destination respectively. So, the SPI hardware is handling all data transfer and Interrupts; after this, DMA takes over for interaction with memory. The DMA and SPI both have a seperate clock and need to be activated seperately. This is the proof that two modules are seperate. Also, DMA is acting on behalf of processor, so it needs to be in master mode. Then, how we can enable and access "Chained buffer transmit complete" interrupt?
    – souravg009
    Sep 13 '19 at 5:52
0

I think I have discovered a solution while searching: https://github.com/avrxml/asf/blob/master/sam/drivers/spi/spi_dmac_slave_example/spi_dmac_slave_example.c

It is an example for atmel's sam3X8EK. But the MCU cores are same. Though the code serves different purpose, we can manage to mold it in the direction we need. Only thing remained to do is to push an array through it. Fellows, what do you think?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.