STM32: I2S input not working when using DMA

DMA must be initialized before ADC peripheral, but generated code performs initialization in wrong order. It is well known minor flaw in default configuration of current STM32CubeIDE. Try to change

MX_GPIO_Init();
MX_I2S3_Init();
MX_DMA_Init(); // wrong order

to

MX_GPIO_Init();
MX_DMA_Init(); // right order
MX_I2S3_Init();

To make permanent changes,

  1. Open "Project Manager" (tab near Pinout / Clock Configuration)
  2. Project Manager → Advanced Settings → Generated Function Calls
  3. Use tiny arrow buttons near this list to move MX_DMA_Init() above MX_I2S3_Init()
  4. Save the project, generated code will have correct order

for my experience,

HAL_I2S_Receive_DMA() function is to configure the address (if you learn the LL API, you need manually set source/dest address and length of data: [LL_DMA_SetDataLength()])

So, you can move it before While(1) loop.

if you want to read/process the buffer "data", you can use dma interrupt callback function, in HAL API is : HAL_I2S_RxHalfCpltCallback(), HAL_I2S_RxCpltCallback()

===================================================================== update:

// init method and buff
...
xx_init()
volatile int16_t data[500] = {0};
int16_t data_shifted[500];
...
// 
HAL_I2S_Receive_DMA(&hi2s3, &data[0], 250);
while(1){
  if (FLAG_half){
    FLAG_half=0;
    // add your code: data shift [0:250]... 
  }
  if (FLAG_comp){
    FLAG_comp=0;
    // add your code: data shift [250:500]... 
  }


} // end while

} end main

HAL_I2S_RxHalfCpltCallback(){ 
  FLAG_half=1;
}
HAL_I2S_RxCpltCallback(){ 
  FLAG_comp=1;
}