Принимать через I2S удается в режиме программного поллинга
Код
while(1){
while( (SPI3->SR & SPI_I2S_FLAG_RXNE) == 0 );
SPDiffRxBuffer[TimeRXPointer][0] = (long)SPI3->DR;
if( ++TimeRXPointer >= SPDIFF_BUF_LEN ) TimeRXPointer = 0;
}
while( (SPI3->SR & SPI_I2S_FLAG_RXNE) == 0 );
SPDiffRxBuffer[TimeRXPointer][0] = (long)SPI3->DR;
if( ++TimeRXPointer >= SPDIFF_BUF_LEN ) TimeRXPointer = 0;
}
Т.е. сам I2S приемник работает
Пытаюсь добавить код что бы сделать прием через DMA
CODE
static void I2S_DMA_Init( void )
{
DMA_InitTypeDef DMA_InitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_DeInit( DMA1_Stream2 );
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
DMA_InitStruct.DMA_Channel = DMA_Channel_2;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(SPI3->DR);
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)SPDiffRxBuffer;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStruct.DMA_BufferSize = SPDIFF_BUF_LEN * 4;
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_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
while( DMA_GetCmdStatus( DMA1_Stream2 ) == ENABLE );
DMA_Init( DMA1_Stream2, &DMA_InitStruct );
DMA_ITConfig( DMA1_Stream2, DMA_IT_TC, ENABLE );
DMA_Cmd( DMA1_Stream2, ENABLE );
SPI_I2S_DMACmd( SPI3, SPI_I2S_DMAReq_Rx, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
{
DMA_InitTypeDef DMA_InitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_DeInit( DMA1_Stream2 );
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
DMA_InitStruct.DMA_Channel = DMA_Channel_2;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(SPI3->DR);
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)SPDiffRxBuffer;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStruct.DMA_BufferSize = SPDIFF_BUF_LEN * 4;
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_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
while( DMA_GetCmdStatus( DMA1_Stream2 ) == ENABLE );
DMA_Init( DMA1_Stream2, &DMA_InitStruct );
DMA_ITConfig( DMA1_Stream2, DMA_IT_TC, ENABLE );
DMA_Cmd( DMA1_Stream2, ENABLE );
SPI_I2S_DMACmd( SPI3, SPI_I2S_DMAReq_Rx, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
и
Код
void DMA1_Stream2_IRQHandler( void )
{
LEDOn( LED1 );
LEDOff( LED1 );
}
{
LEDOn( LED1 );
LEDOff( LED1 );
}
Прерывание не вызывается, буфер не заполняется. При этом флаг RXNE поднимается и можно опять же работать с опросом.
Пробовал работать через DMA1 Channel3 Stream0 - результат такой же, отрицательный.
Пробовал без прерывания, буфер все равно не заполняется.
Что я делаю не правильно?
Можно принимать и через прерывание от I2S, но это неудобно, поскольку контроллер принимает только 16 бит и выходит 4 прерывания на семпл. Очень хочется задействовать Fifo в DMA для сбора по два 32 битных слова и передачей полного семпла за раз.