Created Wednesday 29 November 2023
To set right length for I2S DMA transfers, we need to know several parameters:
- Data Width of DMA configuration (Byte, Half Word or Word)
- I2S data configuration (16 or 24/32-bit data)
- Array type (uint8_t, uint16_t or uint32_t)
E.g., assume that DMA data width is set to Word, I2S data type is set to 24/32-bit, and array type is uint32_t:
#define ARRAY_SIZE 10 uint32_t i2sBuffer[ARRAY_SIZE]={0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888, 0x99999999,0xAAAAAAAA}; // let's test it: HAL_I2S_Receive_DMA(&hi2s1, (uint16_t *)&i2sBuffer[0], 4); // this will fill 8 elements of i2sBuffer array (all except 0x99999999 and 0xAAAAAAAA) // thus, we can't pass ARRAY_SIZE (10), because it will write 20 elements HAL_I2S_Receive_DMA(&hi2s1, (uint16_t *)&i2sBuffer[0], ARRAY_SIZE/2); // because dma data width is Word (32-bit), but this function assumes 16-bit data.
HAL_I2S_Receive_DMA will multiply ARRAY_SIZE by 2, and will receive 10 32-bit elements
now, if DMA Data Width is set to Half Word, this will be correct:
HAL_I2S_Receive_DMA(&hi2s1, (uint16_t *)&i2sBuffer[0], ARRAY_SIZE);
HAL_I2S_Receive_DMA will multiply ARRAY_SIZE by 2, and will receive 20 16-bit elements (which is 10 32-bit elements)
Second case is correct solution, because I2S data register (SPI_DR) is a 16-bit register (half word).