cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 - I2S sending & receiving

manuel
Associate II
Posted on May 23, 2013 at 12:06

Hi togehter,

I've some questions about the I2S interface of the STM32F405 microcontroller. I hope someone could help me I'm in a bit of a crisis here now. First to my hardware setup: I've the microcontroller, an audiocodec, a microphjone and a speaker. The microcontroller is connected to the codec via I2S. The speaker and themicrophoneis connected to the codec. The codec is working fine; in fact sending data to the speaker is already working. My Problem is now, I'm not able to receive any data from the microphone.I checked the input data (Pin I2S3ext_SD) with anoscilloscope. On the pin data is present so the codec works fine. If I configure the I2S in receive mode, I always read zeros, no matter what data is on the I2S3ext_SD I am also notsurewhether I use the FullDuplexConfig right. What do I have to set in

I2S_InitStructure.I2S_ModeD)

if I use FullDuplex? I only get receiving Interrupts if I set it to MasterRx. Is that right?

Now to my code: GPIO configuration:

GPIO_InitTypeDef GPIO_InitStructure;
// Enable peripheral clocks
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE); // TODO: fix, enable alternate function clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
/* configure alternative functions */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_SPI3); // I2S3_WS
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_SPI3); // I2S3_MCK
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SPI3); // I2S3_CK
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_SPI3); // I2S3_ext_SD
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SPI3); // I2S3_SD
// Configure pins as alternate function
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // TODO: fix
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
GPIO_Init(GPIOC, &GPIO_InitStructure);

Interrupt: configuration:

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

I2S3 configuration:

// I2S3 peripheral configuration
SPI_I2S_DeInit(SPI3); // ERRATA: deinitialize i2s3 aka. spi3
I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b; // 16bextended
I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_8k;
I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;
I2S_Init(SPI3, &I2S_InitStructure);
I2S_FullDuplexConfig(I2S3ext, &I2S_InitStructure);
/* Enable the I2S3 TxE interrupt */
SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE);
/* Enable the Rx buffer not empty interrupt */
//SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_RXNE, ENABLE);
/* Enable the I2S3 */
I2S_Cmd(SPI3, ENABLE);

IRQ Handler:

extern ''C'' void I2S3_IRQHANDLER(void) { 
static uint32_t i = 2;
static uint16_t div = 1;
// Sending data
if(SPI_GetITStatus(SPI3, SPI_I2S_IT_TXE) != RESET) {
if(i < 
BUFFER_SIZE
) {
if(i % 2) {
SPI_I2S_SendData(SPI3,0x0000); // no right channel cause speaker is mono
} else {
// Send square wave
if((i/8) % 2) { 
SPI_I2S_SendData(SPI3, 0x7FFF);
} else {
SPI_I2S_SendData(SPI3, 0x0000);
}
}
i++;
} else {
SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, DISABLE);
i
= 
2
; 
}

// Receiving data
} else if(SPI_GetITStatus(SPI3, SPI_I2S_IT_RXNE) == SET) {
static uint16_t 
bufferSize
= 
0
;
RAM_Buf[bufferSize++] = SPI3->DR;//SPI_I2S_ReceiveData(SPI3);
if(bufferSize >= BUFFER_SIZE) {
g_pMain->m_i2s.SetSemaphore();
SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_RXNE, DISABLE);
}
}
return;
}

So this is my code so far. If I debug and check the data of the RAM_Buf in the receiving part of the ISR, the whole array is zero. I'm relatively new to the STM microcontrollers, so it' probably just a little mistakte you guys can find shortly. Hope you can help me. Thanks & best regards, Manuel #dma-i2s-spi-interrupts
1 REPLY 1
Posted on May 23, 2013 at 12:46

I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;
Really? You can't hear any output then. Please always post your actual code, consistent with the description.
 
 You'll also need
 
 I2S_Cmd(SPI3ext, ENABLE);
 
 
 for the I2S3Ext to work.
 
 [EDIT]
 You have to see I2S3Ext as a completely separate module, which has internally connected clocks to I2S3. Thus, to check its status, you have to read it's own I2S3Ext->SR register. To enable DMA for it, you have to enable it in I2S3Ext->CR2. And, of course, I2S3 and I2S3Ext have separate inputs to the DMA controller.
 I would say the same of the interrupt, but, turns out, there's no interrupt vector for I2SxExt. It might mean two things: either the two modules' interrupt lines are ORed, or the I2SxExt simply can't throw an interrupt. I can't find hints in the datasheet which one is true. OTOH, it does not matter much as it's quite unusual to feed the I2S through interrupt, and DMA works as expected. 
 [/EDIT]
 JW