STM32H7 I2S HAL bugs
There seem to be some bugs in the H7 HAL library.
Firstly HAL_I2S_Receive_IT() causes a HardFault because, as far as I can see:
1) OVR flag is not cleared
2) in `HAL_I2S_IRQHandler()` there is an attempt to call ` hi2s->TxISR(hi2s);` when
TxISR is set to NULL.
void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
{ uint32_t itsource = hi2s->Instance->IER; uint32_t i2ssr = hi2s->Instance->SR; /* I2S in mode Receiver ------------------------------------------------*/ if(((i2ssr & I2S_FLAG_OVR) != I2S_FLAG_OVR) && ((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && ((itsource & I2S_IT_RXNE) != RESET)) { hi2s->RxISR(hi2s); // not called because OVR not cleared return; } /* I2S in mode Transmitter ---------------------------------------------*/ if(((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && ((itsource & I2S_IT_RXNE) != RESET)) { hi2s->TxISR(hi2s); // HardFaults when TxISR == NULL return; }Secondly in the polling function, HAL_I2S_Receive(), the destination data pointer is incremented 4x too fast.
In 32-bit and 24-bit data transfer mode, `hi2s->RxXferCount` is set to twice the Size, which is correct since Size is the number of half words to transfer.
Then, in the data transfer loop, the destination pointer is incremented like this:
hi2s->pRxBuffPtr += sizeof(uint32_t);
Since `hi2s->pRxBuffPtr` is of type `uint16_t*` this increments the pointer by 8 bytes with each half word transfer.
Note that the loop is still counting half-words, with `hi2s->RxXferCount--;`
So unless you've allocated an extra 4x buffer space then not only will you get the wrong results, you will also overflow badly and quite likely HardFault again.
I've not had any luck with HAL_I2S_Receive_DMA() so far (using RAM_D1), will report back when I've investigated some more.
This is using STM32CubeMX Version 4.26.0 and STM32Cube_FW_H7_V1.2.0 - latest versions.
#i2s #hal #stm32h7