Hello all,
We need to have slave SPI in compatibility mode and DMA transfer.
We have a master one emitting at 1.25MHz. Without DMA, the code is working fine.
You will find our code included.
#include "HL_spi.h"
#include "HL_sys_dma.h"
#include "sys_common.h"
g_dmaCTRL g_dmaCTRLPKT; /* DMA control packet configuration stack */
void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize, uint32 fsize);
void main(void)
{
uint32_t Count=0;
uint16_t RX_Data_Slave[52] = { 0 };
dmaBASE_t *DMA_REG = dmaREG;
spiBASE_t * SPI_REG3 = spiREG3;
spiDAT1_t dataconfig1_t;
dataconfig1_t.CS_HOLD = FALSE;
dataconfig1_t.WDEL = TRUE;
dataconfig1_t.DFSEL = SPI_FMT_0;
dataconfig1_t.CSNR = 0xFD;
spiInit(); // Initialize SPI3 (SLAVE)
gioInit();
spiREG3->DAT1 = ((uint32)SPI_FMT_0 << 24U) |(0XFD << 16U) |(0x04000000U);
// - enabling dma module : this brings DMA out of reset
dmaEnable();
// - assigning dma request: channel-0 with request line - 14 (SPI3 Receive DMA Request)
dmaReqAssign(0,14);
// - configuring DMA control packets
dmaConfigCtrlPacket((uint32)(&spiREG3->BUF) ,(uint32)(&RX_Data_Slave),26,1);
// - setting DMA control packets
dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT);
// - setting the DMA channel to trigger on h/w request */
dmaSetChEnable(DMA_CH0, DMA_HW);
spiREG3->INT0 = 0x00010000;// DMA_REQ_Enable
// On first received data, a DMA_Req will be
// send to DMA
while(1)
{
while(DMA_REG->BTCFLAG!=0x00000001) // Wait for Block Transfer Complete
{
Count++;
}
Count=0; // Reset Count
DMA_REG->BTCFLAG=0x00000001; // Clear BTC Flag
// Because Channel 0 is configured with AutoInit
// DMA is ready to receive the next Block.
spiREG3->DAT1 = ((uint32)SPI_FMT_0 << 24U) | (0XFD << 16U) | (0x04000000U);
}
}
void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize, uint32 fsize)
{
g_dmaCTRLPKT.SADD = sadd+2; /* source address */
g_dmaCTRLPKT.DADD = dadd; /* destination address */
g_dmaCTRLPKT.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT.FRCNT = fsize; /* frame count */
g_dmaCTRLPKT.ELCNT = dsize; /* element count */
g_dmaCTRLPKT.ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT.ELSOFFSET = 0; /* element source offset */
g_dmaCTRLPKT.FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT.FRSOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT.PORTASGN = 4; /* port b */
g_dmaCTRLPKT.RDSIZE = ACCESS_16_BIT; /* read size */
g_dmaCTRLPKT.WRSIZE = ACCESS_16_BIT; /* write size */
g_dmaCTRLPKT.TTYPE = FRAME_TRANSFER ; /* transfer type */
g_dmaCTRLPKT.ADDMODERD = ADDR_FIXED; /* address mode read */
g_dmaCTRLPKT.ADDMODEWR = ADDR_INC1; /* address mode write */
g_dmaCTRLPKT.AUTOINIT = AUTOINIT_ON; /* autoinit */
}
We have made some tests:
1) With element count equal to 26 and frame count equal to 1, we got 26 time the same value in the reception buffer
2) With element count equal to 1 and frame count equal to 26, the DMA doesn't finish (BTCFLAG never equal to zero).
We cannot understand this behavior.
Is someone can explain this strange phenomena?
Thanks a lot
Alain