I am trying to get a basic loopback dma ping pong audio test to work with the ADSP-BF706 EZ-KIT-MINI. This supposed to be a 2d array to emulate a ping pong approach. I have everything working, but there seems to be a pop or glitch at the beginning or end of each block when being transmitted. I can't figure out what it is, but it seems like something is out of sync. Does my initialization code and interrupts look good? I have shown the relevant code below:
int32_t TX_buffer[BUFFER_SIZE*2];
int32_t RX_buffer[BUFFER_SIZE*2];
int32_t audio_buffer[BUFFER_SIZE];
volatile char RX_shift=0;
volatile char TX_shift=0;
void sport_init(void)
{
// SPORT0_A initialization
*pREG_SPORT0_CTL_A = ENUM_SPORT_CTL_TX
|ENUM_SPORT_CTL_CLK_RISE_EDGE
|ENUM_SPORT_CTL_I2S_MODE
|23<<4;
*pREG_SPORT0_DIV_A = (64<<BITP_SPORT_DIV_FSDIV)
|(1<<BITP_SPORT_DIV_CLKDIV);
// SPORT0_B initialization
*pREG_SPORT0_CTL2_A = ENUM_SPORT_CTL2_CLK_MUX_EN
|ENUM_SPORT_CTL2_FS_MUX_EN;
*pREG_SPORT0_CTL_B =
ENUM_SPORT_CTL_CLK_RISE_EDGE
|ENUM_SPORT_CTL_I2S_MODE
|23<<4;
*pREG_SPORT0_DIV_B = (64<<BITP_SPORT_DIV_FSDIV)
|(1<<BITP_SPORT_DIV_CLKDIV);
}
void dma_init(void)
{
//DMA0 initialization
*pREG_DMA0_CFG = ENUM_DMA_CFG_XCNT_INT
|ENUM_DMA_CFG_AUTO
|ENUM_DMA_CFG_ADDR2D
|ENUM_DMA_CFG_PSIZE04
|ENUM_DMA_CFG_MSIZE04;
*pREG_DMA0_ADDRSTART = TX_buffer;
*pREG_DMA0_XCNT = BUFFER_SIZE;
*pREG_DMA0_YCNT = 2;
*pREG_DMA0_XMOD = 4;
*pREG_DMA0_YMOD = 4;
// DMA1 initialization
*pREG_DMA1_CFG = ENUM_DMA_CFG_XCNT_INT
|ENUM_DMA_CFG_WRITE
|ENUM_DMA_CFG_AUTO
|ENUM_DMA_CFG_ADDR2D
|ENUM_DMA_CFG_PSIZE04
|ENUM_DMA_CFG_MSIZE04;
*pREG_DMA1_ADDRSTART = RX_buffer;
*pREG_DMA1_XCNT = BUFFER_SIZE;
*pREG_DMA1_YCNT = 2;
*pREG_DMA1_XMOD = 4;
*pREG_DMA1_YMOD = 4;
}
void DMA_RX_interrupt_handler(uint32_t iid, void *handlerArg)
{
if (*pREG_DMA1_STAT & ENUM_DMA_STAT_IRQDONE)
*pREG_DMA1_STAT = ENUM_DMA_STAT_IRQDONE;
for (int i = 0; i < BUFFER_SIZE; i++)
{
audio_buffer[i] = RX_buffer[i + RX_shift * BUFFER_SIZE];
}
RX_shift ^= 1;
}
void DMA_TX_interrupt_handler(uint32_t iid, void *handlerArg)
{
if (*pREG_DMA0_STAT & ENUM_DMA_STAT_IRQDONE)
*pREG_DMA0_STAT = ENUM_DMA_STAT_IRQDONE;
for (int i = 0; i < BUFFER_SIZE; i++)
{
TX_buffer[i + TX_shift * BUFFER_SIZE] = audio_buffer[i];
}
TX_shift ^= 1;
}
void main(void)
{
//INIT CLOCK AND EVERYTHING ELSE
*pREG_SEC0_GCTL = ENUM_SEC_GCTL_EN; // Enable the System Event Controller (SEC)
*pREG_SEC0_CCTL0 = ENUM_SEC_CCTL_EN; // Enable SEC Core Interface (SCI)
adi_int_InstallHandler(INTR_SPORT0_B_DMA, DMA_RX_interrupt_handler, 0, true);
adi_int_InstallHandler(INTR_SPORT0_A_DMA, DMA_TX_interrupt_handler, 0, true);
dma_init();
sport_init();
*pREG_DMA0_CFG |= ENUM_DMA_CFG_EN;
*pREG_DMA1_CFG |= ENUM_DMA_CFG_EN;
*pREG_SPORT0_CTL_B |= 1;
*pREG_SPORT0_CTL_A |= 1;
while (1) idle();
}