2024-08-05 01:46 PM - last edited on 2024-09-24 05:34 AM by Amel NASRI
I have set up a project in STM32CubeMX.
I have setup both I2S1 for Receiving and I2S2 for Transmiting with DMA.
After the normal initalization i start receiving from the DMA:
if (HAL_I2S_Transmit_DMA(&hi2s2, (uint16_t*)&output_buffer, 1) != HAL_OK)
{
Error_Handler();
}
And the setup of the I2S are as following:
void MX_I2S1_Init(void)
{
hi2s1.Instance = SPI1;
hi2s1.Init.Mode = I2S_MODE_MASTER_RX;
hi2s1.Init.Standard = I2S_STANDARD_PHILIPS;
hi2s1.Init.DataFormat = I2S_DATAFORMAT_32B;
hi2s1.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
hi2s1.Init.AudioFreq = I2S_AUDIOFREQ_48K;
hi2s1.Init.CPOL = I2S_CPOL_LOW;
hi2s1.Init.FirstBit = I2S_FIRSTBIT_MSB;
hi2s1.Init.WSInversion = I2S_WS_INVERSION_DISABLE;
hi2s1.Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_LEFT;
hi2s1.Init.MasterKeepIOState = I2S_MASTER_KEEP_IO_STATE_ENABLE;
if (HAL_I2S_Init(&hi2s1) != HAL_OK)
{
Error_Handler();
}
}
void MX_I2S2_Init(void)
{
hi2s2.Instance = SPI2;
hi2s2.Init.Mode = I2S_MODE_MASTER_TX;
hi2s2.Init.Standard = I2S_STANDARD_PHILIPS;
hi2s2.Init.DataFormat = I2S_DATAFORMAT_32B;
hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_48K;
hi2s2.Init.CPOL = I2S_CPOL_LOW;
hi2s2.Init.FirstBit = I2S_FIRSTBIT_MSB;
hi2s2.Init.WSInversion = I2S_WS_INVERSION_DISABLE;
hi2s2.Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_LEFT;
hi2s2.Init.MasterKeepIOState = I2S_MASTER_KEEP_IO_STATE_DISABLE;
if (HAL_I2S_Init(&hi2s2) != HAL_OK)
{
Error_Handler();
}
}
The HAL_I2S_RxCpltCallback doesn't do anything right now and the I2S2 is not started with the DMA.
I am only using the MCLK, BCLK, and LRCLK, and have conneted the peripherals ADC and DAC to these and their DIN and DOUT are connected, so if MCLK, BCLK, and LRCLK I should have a clean connection, but the audio is choppy. I can see when measuring MCLK, BCLK, and LRCLK, their frequency sporadically go up, cutting the correct transfer, to then go back. The stuttering happens a few times per second.
I have spent a lot of time trying to fix this, but i have no idea how to fix it.
Solved! Go to Solution.
2024-08-08 04:27 AM
So I have finally fixed the problem, my reluctancy to acknowledged using the HSI could be the problem has been my downfall.
I have tried adding 24.576 MHz to is2_ckin, and now everything is stable...
A lot of thanks to every one who has applied to the thread.
2024-08-05 04:35 PM
Verify where main uCPU clock is coming from. To have low jitter use crystal HSE. For nucleo boards ST-Link
2024-08-06 01:41 AM
So here are my newest measurements, LRCLK (BLUE) and BCLK (YELLOW). The problem isn't jitter, but that LRCLK changes more often than every 32 BCLK, but only a few times per second.
2024-08-06 01:45 AM
I am using the HSI, but as i have just added, it isn't jitter.
2024-08-06 07:47 AM
What is the dma mode? Is it possible that
HAL_I2S_Transmit_DMA
restarts happened?
Better to post all your code.
2024-08-06 09:07 AM
The DMA mode is circular, so i don't expect any restarts, here is the rest of the I2S.c:
void HAL_I2S_MspInit(I2S_HandleTypeDef* i2sHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(i2sHandle->Instance==SPI1)
{
/* I2S1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**I2S1 GPIO Configuration
PA5 ------> I2S1_CK
PA6 ------> I2S1_SDI
PC4 ------> I2S1_MCK
PA15(JTDI) ------> I2S1_WS
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* I2S1 DMA Init */
/* SPI1_RX Init */
hdma_spi1_rx.Instance = DMA1_Stream0;
hdma_spi1_rx.Init.Request = DMA_REQUEST_SPI1_RX;
hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_spi1_rx.Init.Mode = DMA_CIRCULAR;
hdma_spi1_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(i2sHandle,hdmarx,hdma_spi1_rx);
/* I2S1 interrupt Init */
HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
}
else if(i2sHandle->Instance==SPI2)
{
/* I2S2 clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I2S2 GPIO Configuration
PC1 ------> I2S2_SDO
PB10 ------> I2S2_CK
PB12 ------> I2S2_WS
PC6 ------> I2S2_MCK
*/
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* I2S2 DMA Init */
/* SPI2_TX Init */
hdma_spi2_tx.Instance = DMA1_Stream1;
hdma_spi2_tx.Init.Request = DMA_REQUEST_SPI2_TX;
hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_spi2_tx.Init.Mode = DMA_CIRCULAR;
hdma_spi2_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_spi2_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(i2sHandle,hdmatx,hdma_spi2_tx);
/* I2S2 interrupt Init */
HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI2_IRQn);
}
}
void HAL_I2S_MspDeInit(I2S_HandleTypeDef* i2sHandle)
{
if(i2sHandle->Instance==SPI1)
{
/* Peripheral clock disable */
__HAL_RCC_SPI1_CLK_DISABLE();
/**I2S1 GPIO Configuration
PA5 ------> I2S1_CK
PA6 ------> I2S1_SDI
PC4 ------> I2S1_MCK
PA15(JTDI) ------> I2S1_WS
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_15);
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_4);
/* I2S1 DMA DeInit */
HAL_DMA_DeInit(i2sHandle->hdmarx);
/* I2S1 interrupt Deinit */
HAL_NVIC_DisableIRQ(SPI1_IRQn);
}
else if(i2sHandle->Instance==SPI2)
{
/* Peripheral clock disable */
__HAL_RCC_SPI2_CLK_DISABLE();
/**I2S2 GPIO Configuration
PC1 ------> I2S2_SDO
PB10 ------> I2S2_CK
PB12 ------> I2S2_WS
PC6 ------> I2S2_MCK
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_1|GPIO_PIN_6);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_12);
/* I2S2 DMA DeInit */
HAL_DMA_DeInit(i2sHandle->hdmatx);
/* I2S2 interrupt Deinit */
HAL_NVIC_DisableIRQ(SPI2_IRQn);
}
}
2024-08-06 09:59 AM
if (HAL_I2S_Transmit_DMA(&hi2s2, (uint16_t*)&output_buffer, 1) != HAL_OK)
and
"The HAL_I2S_RxCpltCallback doesn't do anything right now and the I2S2 is not started with the DMA."
Do you mistype, and should be I2S1 is not started?
Anyway, I never tested I2S + dma transferring only one word, but I envision that uCPU would have hard time to figure out when to fire TransferComplete & TransferHalfComplete interrupts, since half of 1 is 0 in integers.
Try to increase size of data to be transferred.
What is the size of output_buffer?
What memory it's located?
Has DMA access to this memory?
2024-08-06 10:15 AM
Sorry wrote the wrong function, I2S2 is not started, the code running is initially is:
void Start_I2S1_Receive(void)
{
if (HAL_I2S_Receive_DMA(&hi2s1, (uint16_t*)&input_buffer, 1) != HAL_OK)
{
Error_Handler();
}
}
2024-08-06 10:16 AM
A follow up.
I have also tried setting up SAI, here all the clocks are correct, but I again experience stutter.
2024-08-06 10:17 AM
I have tried with a lot of different buffer sizes.