2019-01-02 03:44 PM
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
2019-01-03 12:43 AM
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
2019-01-03 02:23 PM
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
2019-01-03 02:48 PM
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?
2019-01-03 02:51 PM
This is exactly why I don't use Cube.
JW
2019-01-03 03:13 PM
Could I expect some "oficial" help here or am I on my own with this problem?
Thank!
2019-01-03 03:14 PM
BTW, do you use some other library?
2019-01-03 03:47 PM
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
2019-01-03 04:54 PM
in the begining I used to use CMSIS register definitions and write values directly to them using user manual. But there is not much suport in HAL and there is musch less support on the using direct register access...
2020-03-02 03:35 PM