RA4M1 , SPI with DMA

Hi,

I search a small example for SPI Master and DMA transfer.

So that I can receive e.g. 15 bytes with DMA and get a transfer end interrupt/callback when it is finished.

Thanks in advanced !

  • Hello 

    I couldn't find the implementation of SPI with DMA as of now, but you might want to check out the following thread which mentions a comparison between DMAC and DTC: 
    https://renesasrulz.com/mcu-mpu/ra/f/forum/19850/ra-dmac-and-dtc

    If that seems like DTC can be relevant to your application, please check out the following thread and example:

    https://renesasrulz.com/mcu-mpu/ra/f/forum/19608/spi-dtc (For stack configuration)
    RA4M1 SPI using DTC Example

    Kindly let me know if that's helpful or not, in the meantime I'll keep looking for more relevant resources.

    -Jayesh
    If this response, or one provided by another user, answers your question, please verify the answer. Thank you!
    RenesasRulz Forum Moderator
    https://renesasrulz.com/
    https://academy.renesas.com/
    https://en-support.renesas.com/knowledgeBase/

  • Thank you ,

    I think DMA is for me the better solution, because I need a very fast firmware. The ADC convert  the signals periodly and than I have only some µs for reading and calculating values.

    I will try it with DTC, but DMA is my favorite ...

  • I'm still looking for more relevant resources but I just found an implementation of UART with DMAC on RA4M1 attached as a zip in the following thread. Again, not exactly what you asked for but mentioning it here as it could serve as a reference for implementing DMAC with SPI.

    renesasrulz.com/.../dma-access-using-sci-uart-in-ra4m1-series-controller

    However, the version of the FSP is quite outdated in the above example so please refer to the latest FSP manual along with the example.

    -Jayesh
    If this response, or one provided by another user, answers your question, please verify the answer. Thank you!
    RenesasRulz Forum Moderator
    https://renesasrulz.com/
    https://academy.renesas.com/
    https://en-support.renesas.com/knowledgeBase/


  • Have you an example for SPI Master with DMA / DTC ?

  • FSP4.0 supports DTC and DMAC transfer interface in the driver

     Add the r_spi driver to your project

    Add the DMAC transfer driver to the stack:

  • Hello . As mentioned by Richard, the latest release of FSP added support for SPI with DMAC. 

    And if you are looking for SPI with DTC, the example code named "r_sci_spi" uses DTC by default. Please check that out here:

    https://github.com/renesas/ra-fsp-examples/tree/master/example_projects/ek_ra4m1/sci_spi/sci_spi_ek_ra4m1_ep

    -Jayesh

    If this response, or one provided by another user, answers your question, please verify the answer. Thank you!
    Renesas Engineering Community Moderators
    https://community.renesas.com/
    https://academy.renesas.com/
    en-support.renesas.com/.../

  • Now I use the 4.0 and there is DMAC supported. But I don't get a SPI DMA transmission to work. here my HAL_ENTRY :

    void hal_entry(void)
    {

    unsigned char txByte[] = {0,1,2,3,4,5,6,7,8,9};
    unsigned char rxByte[] = {0,1,2,3,4,5,6,7,8,9};

    /* Initialize SPI driver */
    g_spi_master.p_api->open (&g_spi_master_ctrl, &g_spi_master_cfg);
    /* Initialize SPI TX DMAC driver */
    g_transferSPI0_tx_cfg.p_info->p_dest = (void*)&R_SPI0->SPDR ;
    g_transferSPI0_tx_cfg.p_info->p_src = (void*)&txByte ;
    g_transferSPI0_tx_cfg.p_info->length = 10;
    /* Initialize SPI RX DMAC driver */
    g_transferSPI0_rx_cfg.p_info->p_dest = (void*)&rxByte ;
    g_transferSPI0_rx_cfg.p_info->p_src = (void*)&R_SPI0->SPDR ;

    g_transferSPI0_tx.p_api->open(&g_transferSPI0_tx_ctrl , &g_transferSPI0_tx_cfg);
    g_transferSPI0_rx.p_api->open(&g_transferSPI0_rx_ctrl , &g_transferSPI0_rx_cfg);

    g_transferSPI0_tx.p_api->enable(&g_transferSPI0_tx_ctrl);
    g_transferSPI0_tx.p_api->softwareStart(&g_transferSPI0_tx_ctrl,TRANSFER_START_MODE_SINGLE);

    while(1) {

    }

    }

    and here my settings :

    I can't see a SPI transfer on the Pins on my board. How I start the transmission with DMAC for e.g. 10 bytes ?

    What is wrong or missing ?

    Thanks in advanced

  • now I tested it at low level programming without FSP .

    void hal_entry(void)
    {
        unsigned char txByte[] = {0,1,2,3,4,5,6,7,8,9};
        unsigned char rxByte[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
    
    	// Init SPI Master Mode
    	R_SPI0->SPCR_b.SPE = 0x00;		// Disable SPI function
    
    	R_SPI0->SSLP_b.SSL0P = 0;
    	R_SPI0->SSLP_b.SSL1P = 0;
    	R_SPI0->SSLP_b.SSL2P = 0;
    	R_SPI0->SSLP_b.SSL3P = 0;
    	R_SPI0->SSLP_b.SSL4P = 0;
    	R_SPI0->SSLP_b.SSL5P = 0;
    	R_SPI0->SSLP_b.SSL6P = 0;
    	R_SPI0->SSLP_b.SSL7P = 0;
    
    	R_SPI0->SPPCR = 0;
    
    	R_SPI0->SPBR =	0x17;
    
    	R_SPI0->SPDCR = 0x00;			// Read SPDR from receive buffer + Halfword
    
    	R_SPI0->SPCKD = 0x00;			// RSPCK Delay = 1 RSPCK -> 1 SPI Clock Pause nachdem CS auf low gezogen wurde
    
    	R_SPI0->SSLND = 0x00;			// SLNDL Delay = 1 RSPCK -> 1 SPI Clock Pause bevor CS wieder auf high gezogen wird
    
    	R_SPI0->SPND = 0x00;			// Next-Access Delay -> 1 RSPCK + 2 PCLKA
    
    	R_SPI0->SPCR2_b.SPPE 	= 0x00;					// No Parity
    	R_SPI0->SPCR2_b.SPOE 	= 0x00;					// Select even parity for use in transmission and reception
    	R_SPI0->SPCR2_b.SPIIE 	= 0x00;					// Idle interrupt requests disabled
    	R_SPI0->SPCR2_b.PTE 	= 0x00;					// Self-diagnosis function of the parity circuit disabled
    	R_SPI0->SPCR2_b.SCKASE 	= 0x00;					// RSPCK auto-stop function disabled
    	R_SPI0->SPCR2_b.SPTDDL 	= 0x00;					//
    
    	R_SPI0->SPCMD_b->CPHA 	= 0x01;					// Select data change on leading edge, data sampling on trailing edge.
    	R_SPI0->SPCMD_b->CPOL 	= 0x00;					// Set RSPCK low when idle
    	R_SPI0->SPCMD_b->BRDV	= 0x00;					// Base bit rate
    	R_SPI0->SPCMD_b->SSLA 	= 0x00;					// Set SSL0 als CS
    	R_SPI0->SPCMD_b->SPB  	= 0x0f;					// 16 Bits Data length
    	R_SPI0->SPCMD_b->LSBF 	= 0x00;					// MSB first
    	R_SPI0->SPCMD_b->SPNDEN = 0x01;					// A next-access delay equal to the setting of the SPI Next-Access Delay Register (SPND).
    	R_SPI0->SPCMD_b->SLNDEN = 0x01;					// An SSL negation delay equal to the setting of the SPI Slave Select Negation Delay Register (SSLND).
    	R_SPI0->SPCMD_b->SCKDEN = 0x01;					// An RSPCK delay equal to the setting of the SPI Clock Delay Register (SPCKD)
    
    	// Set TX DMAC
    	R_DMAC0->DMSAR			= (uint32_t)&txByte;			// Source address
    	R_DMAC0->DMDAR			= (uint32_t)&R_SPI0->SPDR_HA;	// destination address
    	R_DMAC0->DMCRA_b.DMCRAL = 10;					// Transfer count
    	R_DMAC0->DMCRA_b.DMCRAH = 10;					// Transfer count
    	R_DMAC0->DMCRB 			= 0;					// DMA Block Transfer Count
    	R_DMAC0->DMTMD_b.DCTG	= 0;					// Transfer Request : Software
    	R_DMAC0->DMTMD_b.SZ		= 1;					// Transfer Data Size : 16 Bits
    	R_DMAC0->DMTMD_b.DTS	= 1;					// Repeat Area : Source
    	R_DMAC0->DMTMD_b.MD		= 1;					// Transfer Mode : Repeat
    
    	R_DMAC0->DMINT_b.DARIE	= 0;					// Destination Address Extended Repeat Area Overflow Interrupt disable
    	R_DMAC0->DMINT_b.SARIE	= 0;					// Source Address Extended Repeat Area Overflow Interrupt disable
    	R_DMAC0->DMINT_b.RPTIE	= 0;					// Repeat Size End Interrupt disable
    	R_DMAC0->DMINT_b.ESIE	= 0;					// Transfer Escape End Interrupt disable
    	R_DMAC0->DMINT_b.DTIE	= 0;					// Transfer End Interrupt disable
    
    	R_DMAC0->DMAMD_b.DARA	= 0;					// Destination Address Extended Repeat Area : not specified
    	R_DMAC0->DMAMD_b.DM		= 0;					// Destination address fixed
    	R_DMAC0->DMAMD_b.SARA	= 0;					// Source Address Extended Repeat Area : not specified
    	R_DMAC0->DMAMD_b.SM		= 2;					// Source address is incremented
    	R_DMAC0->DMAMD_b.DADR	= 0;
    	R_DMAC0->DMAMD_b.SADR	= 0;
    
    	R_DMAC0->DMOFR			= 0;					// DMA Offset Register
    
    	R_DMAC0->DMCNT_b.DTE	= 1;					// DMA transfer enable
    
    	// Set RX DMAC
    	R_DMAC1->DMDAR			= (uint32_t)&rxByte;			// Source address
    	R_DMAC1->DMSAR			= (uint32_t)&R_SPI0->SPDR_HA;	// destination address
    	R_DMAC1->DMCRA_b.DMCRAL = 1;					// Transfer count
    	R_DMAC1->DMCRA_b.DMCRAH = 1;					// Transfer count
    	R_DMAC1->DMCRB 			= 0;					// DMA Block Transfer Count
    	R_DMAC1->DMTMD_b.DCTG	= 0;					// Transfer Request : Software
    	R_DMAC1->DMTMD_b.SZ		= 1;					// Transfer Data Size : 16 Bits
    	R_DMAC1->DMTMD_b.DTS	= 0;					// Repeat Area : Destination
    	R_DMAC1->DMTMD_b.MD		= 1;					// Transfer Mode : Repeat
    
    	R_DMAC1->DMINT_b.DARIE	= 0;					// Destination Address Extended Repeat Area Overflow Interrupt disable
    	R_DMAC1->DMINT_b.SARIE	= 0;					// Source Address Extended Repeat Area Overflow Interrupt disable
    	R_DMAC1->DMINT_b.RPTIE	= 0;					// Repeat Size End Interrupt disable
    	R_DMAC1->DMINT_b.ESIE	= 0;					// Transfer Escape End Interrupt disable
    	R_DMAC1->DMINT_b.DTIE	= 0;					// Transfer End Interrupt disable
    
    	R_DMAC1->DMAMD_b.DARA	= 0;					// Destination Address Extended Repeat Area : not specified
    	R_DMAC1->DMAMD_b.DM		= 2;					// Destination address is incremented
    	R_DMAC1->DMAMD_b.SARA	= 0;					// Source Address Extended Repeat Area : not specified
    	R_DMAC1->DMAMD_b.SM		= 0;					// Source address fixed
    	R_DMAC1->DMAMD_b.DADR	= 0;
    	R_DMAC1->DMAMD_b.SADR	= 0;
    
    	R_DMAC1->DMOFR			= 0;					// DMA Offset Register
    
    	R_DMAC1->DMCNT_b.DTE	= 1;					// DMA transfer enable
    
    	// Set SPI
    
    	R_SPI0->SPCR_b.MSTR 	= 0x01;					// Select Master mode
    	R_SPI0->SPCR_b.SPMS 	= 0x00;					// Select SPI operation (4-wire method)
    	R_SPI0->SPCR_b.TXMD 	= 0x00;					// Select full-duplex synchronous serial communications
    	R_SPI0->SPCR_b.MODFEN 	= 0x00;					// Disable the detection of mode fault error
    	R_SPI0->SPCR_b.SPEIE 	= 0x00;					// Disable SPI error interrupt requests
    	R_SPI0->SPCR_b.SPTIE 	= 0x00;					// Disable transmit buffer empty interrupt requests
    	R_SPI0->SPCR_b.SPRIE 	= 0x00;					// Disable SPI receive buffer full interrupt requests
    
    	R_SPI0->SPCR_b.SPE 		= 0x01;					// Enable SPI function
    
    	// Start DMA
    	R_DMA->DMAST_b.DMST		= 1;					// DMAC start enabled
    	R_DMAC0->DMREQ_b.CLRS 	= 0;					// SWREQ bit is cleared after DMA transfer is started by software
    	R_DMAC0->DMREQ_b.SWREQ 	= 1;					// DMA transfer is requested
    	
    	while(1) {
    	
    	}

    The Pin configuration is maked with FSP.

    On my Oszi I see a transmission from 16 bits and the CS (SSLP0) pin is handshaked.

    But why only 16 Bits ? I will transfer 10 bytes ...

  • You need to link DMA transfer to an activation source.

    R_ICU->DELSR[0] = ELC_EVENT_SPI0_TXI;    // SPI0_SPTI

    R_ICU->DELSR[1] = ELC_EVENT_SPI0_RXI;  // SPI0_SPRI

  • I inserted this lines, but nothing is changed. Only 16 bits are transferred when I start the DMA.