2013-10-21 11:07 AM
I've DMA1 stream 3 channel 0 configured to handle the I2S2 data coming in from my UDA1380 codec and what I notice is that when configuring the Memory0BaseAddr to be the beginning of my circular buffer, the contents at the interrupt show the data being placed at the end of my buffer, moving toward the front[so in the case of four blocks, rather than placing the data at Block[0], I see the data being placed in Block[3], then decrementing to Block[2] the next interrupt]...I'm a little unclear as to what part of my code could be causing this...any insight would be much appreciated...
/* CODEC_I2S peripheral configuration */
SPI_I2S_DeInit(SPI2);
I2S_InitStructure.I2S_AudioFreq = AUDIO_FREQUENCY;
I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
I2S_InitStructure.I2S_CPOL = I2S_CPOL_High;
I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveRx;
I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
I2S_Init(SPI2, &I2S_InitStructure);
I2S_Cmd(SPI2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
DMA_Cmd(DMA1_Stream3, DISABLE);
DMA_DeInit(DMA1_Stream3);
DMA_InitStruct.DMA_Channel = DMA_Channel_0;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(SPI2->DR);
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&Uda1380AdcAudio.Uda1380AdcBlock;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStruct.DMA_BufferSize = DMA_TRANSFER_BLOCK_SIZE * 2;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
while( DMA_GetCmdStatus( DMA1_Stream3 ) == ENABLE );
DMA_Init( DMA1_Stream3, &DMA_InitStruct );
DMA_ITConfig( DMA1_Stream3, DMA_IT_TC, ENABLE );
DMA_Cmd( DMA1_Stream3, ENABLE );
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#dma #selective-cut-n-paste
2013-10-21 11:41 AM
Which interrupt, and where's the block definition?
The issue is not with the code presented. Have you filled the buffer with a known pattern and confirmed how the buffer fills, because it would be extremely odd of the DMA to fill backward. Are you sure you don't have an Endian issue with the formatting of the data? Or the configuration of the Codec?2013-10-21 01:45 PM
Here's my interrupt routine:
void DMA1_Stream3_IRQHandler(void)
{
static short unsigned int
i = 0;
if(DMA_GetFlagStatus(DMA1_Stream3, DMA_FLAG_TCIF3) != RESET)
{
while (DMA_GetCmdStatus(DMA1_Stream3) != DISABLE)
{}
DMA_ClearFlag(DMA1_Stream3, DMA_FLAG_TCIF3); // Clear the Interrupt flag
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&Uda1380AdcAudio.Uda1380AdcBlock[(SystemMaint.PcmInBufferingIndex + 1)% PCM_IN_BUFFER_BLOCKS];
DMA_Init(DMA1_Stream3, &DMA_InitStruct);//Configure the DMA Stream with the new parameters
DMA_Cmd(DMA1_Stream3, ENABLE);// Enable the I2S DMA Stream
SystemMaint.PcmInDataIndex = SystemMaint.PcmInBufferingIndex;
for(i = 0; i < AUDIO_BLOCK_SIZE; i++)
AudioTransmitBuffer.Buffer[SystemMaint.PcmInDataIndex].Block[i] = Uda1380AdcAudio.Uda1380AdcBlock[SystemMaint.PcmInBufferingIndex].AdcSample[i].RxLeft;
SystemMaint.PcmInBufferingIndex = (SystemMaint.PcmInBufferingIndex + 1)% PCM_IN_BUFFER_BLOCKS;
}
SystemMaint.DoTransmit = 1;
}
I've #pragma pack(1) before I define my structures that are as follows:
struct sUda1380AdcFrame
{
short int
RxLeft,
RxRight;
};
///////////////////////////////////////////////////////////////////////////////
struct sUda1380AdcSample
{
struct sUda1380AdcFrame
AdcSample[80];
};
///////////////////////////////////////////////////////////////////////////////
struct sUda1380AdcAudio
{
struct sUda1380AdcSample
Uda1380AdcBlock[5];
};
The data is coming from the codec to the STM32F4 and strangely enough I see after the first interrupt, data is placed at the last block[block 4 in this case]...if the dma configuration doesn't show any obvious goofs I'll continue debugging my code to see if I can't resolve the issue.
2013-10-21 04:01 PM
Two things you might check:
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&Uda1380AdcAudio.Uda1380AdcBlock[(SystemMaint.PcmInBufferingIndex + 1)% PCM_IN_BUFFER_BLOCKS];
Is your array packed? If not you may not be seeing the data where you expect it.
And second, at the TC interrupt dump your DMA registers to see what it just did, especially the configuration. You may have errant code clobbering the DMA regs.
Jack Peacock
2013-10-21 04:12 PM
DMA_TRANSFER_BLOCK_SIZE
is what? 400?