Hello,
I have a simple question about using the DMAC sending data to a SPI Master. I have the DMAC configured to perform 600 transfers of 32 bits on a manual software start in block transfer mode. The SPI is very quickly getting overwhelmed and throwing the overflow error SPSR.OVRF. I can only imagine that I have configured the DMAC incorrectly such that it is not watching the status of the SPI buffer and overwriting it many times before it is being transferred into the Tx buffer. Any ideas on how to solve this?
void configure_DMA(){
R_SYSTEM->MSTPCRA_b.MSTPA22 = 0; //breathe life into DMA and DTC modules
//SPI Data Tx DMA
R_DMAC0->DMSAR_b.DMSAR = MEMORY_BANK_0; // define source address -> first transmit bank
R_DMAC0->DMDAR_b.DMDAR = 0x40072004; // define destination address
R_DMAC0->DMTMD_b.DCTG = 0x0; // set transfer request source as software request
R_DMAC0->DMTMD_b.DTS = 0x1; // define source as block area
R_DMAC0->DMTMD_b.MD = 0x2; // define mode as block transfer mode
// R_DMAC0->DMINT_b.RPTIE = 1; // trigger an interrupt on each repeat size end
R_DMAC0->DMINT_b.DTIE = 1; // trigger interrupt on transfer end
R_DMAC0->DMAMD_b.DM = 0x0; // set destination address as fixed
R_DMAC0->DMAMD_b.SM = 0x2; // set source address as incrementing
R_DMAC0->DMREQ_b.CLRS = 0; // start bit is not cleared after DMA transfer completes
R_DMAC0->DMTMD_b.SZ = 0x3; // set transfer size to 32 bits
R_DMAC0->DMCRA_b.DMCRAH = 602; // set the number of repeats to n (n blocks of 32 bits to be transferred)
R_DMAC0->DMAMD_b.SARA = 0x0C; // define max repeat space: should be > (n * 32 bits = n * 4 bytes) : current 4KB
//when all DMACs configures, enable DMAC operations, then start configured DMACs
R_DMA->DMAST_b.DMST = 1;
R_DMAC0->DMCNT_b.DTE = 1; // enable DMAC0
// R_DMAC0->DMREQ_b.SWREQ = 1; // use this to generate software start request
}
void configure_SPI(){
//breathe life into the SPI_0 port
R_MSTP->MSTPCRB_b.MSTPB19 = 0; // SPI0
SPI0->SPCR_b.SPMS = 0; // 4 wire SPI
SPI0->SSLP_b.SSL0P = 0; // select active low CS.0 signal
SPI0->SPPCR_b.MOIFE = 1; // fixed MOSI idle value
SPI0->SPPCR_b.MOIFV = 1; // set MOSI idle level to low
SPI0->SPBR = 1; // bit rate register
SPI0->SPDCR_b.SPLW = 1; // enable access to full word
SPI0->SPDCR_b.SPFC = 0x0; // set to 4 frames
//define SPI command register
uint8_t CPHA = 1; // data change on rising edge, sample on falling edge
uint8_t CPOL = 1; // set clock low when idle
// uint8_t BRDV = 3; // base bit rate / 8: ~3.7MHz
uint8_t BRDV = 0; // base bit rate with no div: ~30MHz
uint8_t SPB = 0x3; // set spi data length to 32 bits
uint16_t* my_SPI0_SPCMD0 = (uint16_t*) 0x40072010;
my_SPI0_SPCMD0[0] = (uint16_t) (((SPB & 0xF) << 8) | ((BRDV & 0x3) << 2) | ((CPOL & 1) << 1) | (CPHA & 1));
SPI0->SPCR_b.MSTR = 1; // select master mode
SPI0->SPCR_b.SPE = 1; // enable the SPI
}