Skip to main content
leonardo
Associate III
January 2, 2019
Question

I2S DMA Complete transfer IRQ on circular mode

  • January 2, 2019
  • 9 replies
  • 2728 views

Hi, I'm using an audiocodec with a STM32F4011 through I2S interface. I configure I2S to transmit/receive in DMA mode and circular buffer. I need to get an ISR on HalfComplete and Complete transfer.

HAL_I2SEx_TxRxHalfCpltCallback is fired on half complete transfer, but HAL_I2SEx_TxRxCpltCallback is not.

Is there a way to get an IRQ on transfer complete?

Thank

This topic has been closed for replies.

9 replies

waclawek.jan
Super User
January 3, 2019

I don't see any reason why half-complete would work and transfer-complete wouldn't, except that the latter is not enabled (or some basic programming error).

Observe whether the related DMA_SxCR.TCIE/HTIE bits are set.

I don't Cube.

JW

leonardo
leonardoAuthor
Associate III
January 3, 2019

In full duplex, DMA enable CubeMX generate two ISR:

void DMA1_Stream3_IRQHandler(void)
{
 /* USER CODE BEGIN DMA1_Stream3_IRQn 0 */
 
 /* USER CODE END DMA1_Stream3_IRQn 0 */
 HAL_DMA_IRQHandler(&hdma_i2s2_ext_rx);
 /* USER CODE BEGIN DMA1_Stream3_IRQn 1 */
 
 /* USER CODE END DMA1_Stream3_IRQn 1 */
}
 
/**
 * @brief This function handles DMA1 stream4 global interrupt.
 */
void DMA1_Stream4_IRQHandler(void)
{
 /* USER CODE BEGIN DMA1_Stream4_IRQn 0 */
 
 /* USER CODE END DMA1_Stream4_IRQn 0 */
 HAL_DMA_IRQHandler(&hdma_spi2_tx);
 /* USER CODE BEGIN DMA1_Stream4_IRQn 1 */
 
 /* USER CODE END DMA1_Stream4_IRQn 1 */
}

hdma_i2s2_ext_rx->CR contain:

110000000000010110100011111

bit 3 and 4 are for TCIE and HTIE. Both have a 1

hdma_spi2_tx->CR contain:

10110101011111

again both bit's are in 1

both ISR are fired when I run my code.

Then I have two callbacks:

HAL_I2SEx_TxRxHalfCpltCallback

and

HAL_I2SEx_TxRxCpltCallback

The first one is fired but the second one not.

I'm working on circular mode.

There was some change on HAL code, becuse it works on previous versions... The calbbacks name change and Transfer complete does not work anymore

leonardo
leonardoAuthor
Associate III
January 3, 2019

Ok, I run step by step the HAL code and get here:

/**
 * @brief DMA I2S transmit receive process complete callback
 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
 * the configuration information for the specified DMA module.
 * @retval None
 */
static void I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma)
{
 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
 
 /* if DMA is not configured in DMA_CIRCULAR mode */
 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
 {
 if (hi2s->hdmarx == hdma)
 {
 /* Disable Rx DMA Request */
 if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) ||\
 ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
 {
 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_RXDMAEN);
 }
 else
 {
 CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
 }
 
 hi2s->RxXferCount = 0U;
 
 if (hi2s->TxXferCount == 0U)
 {
 hi2s->State = HAL_I2S_STATE_READY;
 
 HAL_I2SEx_TxRxCpltCallback(hi2s);
 }
 }
 
 if (hi2s->hdmatx == hdma)
 {
 /* Disable Tx DMA Request */
 if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) ||\
 ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
 {
 CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
 }
 else
 {
 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_TXDMAEN);
 }
 
 hi2s->TxXferCount = 0U;
 
 if (hi2s->RxXferCount == 0U)
 {
 hi2s->State = HAL_I2S_STATE_READY;
 
 HAL_I2SEx_TxRxCpltCallback(hi2s);
 }
 }
 }
}

And the first IF checks that DMA config is NOT in circular mode. So, IN circular mode, HAL_I2SEx_TxRxCpltCallback is never called.

In a previous version:

/**
 ******************************************************************************
 * @file stm32f4xx_hal_i2s_ex.c
 * @author MCD Application Team
 * @version V1.4.2
 * @date 10-November-2015
 * @brief I2S HAL module driver.
 * This file provides firmware functions to manage the following 
 * functionalities of I2S extension peripheral:
 * + Extension features Functions
 * 
 @verbatim

The ISR goes to:

void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
{
 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
 
 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
 {
 /* Disable Rx DMA Request */
 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
 defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F469xx) ||\
 defined(STM32F479xx)
 if(hi2s->Init.FullDuplexMode == I2S_FULLDUPLEXMODE_ENABLE)
 {
 /* Disable Tx DMA Request for the slave*/ 
 I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
 }
#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F401xx || STM32F411xx ||\
 STM32F469xx || STM32F479xx */
 hi2s->RxXferCount = 0;
 if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
 {
 if(hi2s->TxXferCount == 0)
 {
 hi2s->State = HAL_I2S_STATE_READY;
 }
 }
 else
 {
 hi2s->State = HAL_I2S_STATE_READY; 
 }
 }
 HAL_I2S_RxCpltCallback(hi2s); 
}

and as you can see HAL_I2S_RxCpltCallback is called outside of Circular mode check.

Is this a bug?

waclawek.jan
Super User
January 3, 2019

This is exactly why I don't use Cube.

JW

leonardo
leonardoAuthor
Associate III
January 3, 2019

BTW, do you use some other library?

waclawek.jan
Super User
January 3, 2019

No. In my opinion, handling hardware is simple enough, so that any "library" such as SPL/Cube only gets unnecessarily into way.

This view appears to be considered extreme here.

JW

leonardo
leonardoAuthor
Associate III
January 3, 2019

Could I expect some "oficial" help here or am I on my own with this problem?

Thank!

waclawek.jan
Super User
March 2, 2020