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 roywI 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-dtcIf 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.-JayeshIf this response, or one provided by another user, answers your question, please verify the answer. Thank you!RenesasRulz Forum Moderatorhttps://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-controllerHowever, the version of the FSP is quite outdated in the above example so please refer to the latest FSP manual along with the example.-JayeshIf this response, or one provided by another user, answers your question, please verify the answer. Thank you!RenesasRulz Forum Moderatorhttps://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 royw. 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 Moderatorshttps://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.