cancel
Showing results for 
Search instead for 
Did you mean: 

SAI with blocking mode

DYann.1
Senior

Hello,

I have this code

 

 

  // Initialiser le bloc A
  fresult= HAL_SAI_Init(&hsai_BlockA1);
  if (fresult != HAL_OK)
  	{
  	return HAL_ERROR;
  	}
  // Initialiser le bloc B
  fresult= HAL_SAI_Init(&hsai_BlockB1);
  if (fresult != HAL_OK)
	{
  	return HAL_ERROR;
	}

  // Transmission
  fresult = HAL_SAI_Transmit(&hsai_BlockB1, (uint8_t *)playbuf, (sizeof(playbuf))/4, 0xFF);
  if (fresult != HAL_OK)
  	{
  	return HAL_ERROR;
  	}
  // Reception
  fresult = HAL_SAI_Receive(&hsai_BlockA1, (uint8_t *)playbuf_RX, (sizeof(playbuf_RX))/4, 0xFF);
  if (fresult != HAL_OK)
  	{
  	return HAL_ERROR;
  	}

 

 

I am not receiving some of the data, do you know where I can find the documentation to implement SAI blocking mode? thanks in advance.

DYann1_0-1704728511248.png

In my reception array I have only a part of data, and yet my TX table is well initialized like this :

DYann1_1-1704728708060.png

28 REPLIES 28

My CPU clock is 16 MHz

Not, it probably does not.
Don't stop looking and thinking just because you found one number.
HSI = internal RC oscillator is the clock source.

Which then goes through the PLL, with PLLM as the first divider, as can be seen in the little pic you posted.

 

You really need to "go to school" and / or read  / watch lots of basic stuff, about the basics of programming in C, controllers, and probably electronics in general. 

I'm out for now, sorry.

In any case, thank you for your advice. It's a little late for me to go to school.

LCE
Principal

What I meant is to learn more basics, read and watch basic tutorials, ask colleagues, friends, whatever.

Right now you're kind of running through the dark, no offense meant, everybody has to start somewhere. And an STM32 is quite a big challenge for a beginner.

You've already helped me a lot and I thank you very much. I'll follow your advice. Only reading the datasheets or watching the tutorials is not a good method (I2S#SAI, not the same µP, not the same function prototypes....) I need examples and practice to realize that it's not as simple as that. But I've no choice, this SAI part has to work !

DYann.1
Senior

Hi,

After decreasing the size of the table to 128, and modify the DMA configuration for TX and RX like this :

  DYann1_0-1705935893913.png

In the Main I have something like this :

 

  while (1)
  {
    /* USER CODE END WHILE */
		 if( dataReadyFlag_1)
		 {
		   processData_1();
		 }
		 if( dataReadyFlag_2)
		 {
		   processData_2();
		 }
    /* USER CODE BEGIN 3 */
  }

 

And in the processData_1(); I fill half of the table and the same for the second half of the table.

 

void processData_1 ()
{	for (int32_t n=0; n<(BUFFER_SIZE/2); n++)
	{checkbuf_RX[n]=playbuf_RX[n];}
	dataReadyFlag_1=0;
}

 

For the processing time I am on time. With 110 MHz (time of a clock cycle). I'll have  

2x128x1/(110.10e -6) = 2.3µs x 4 (factor) = 9.3 µs which is less than 27µs. But I have only half of the data, looks like the other half is not working. I certainly forgot a few things but what ?

DYann1_1-1705936760291.png

And yet my TX table is correct

DYann1_2-1705936801954.png

For the scope I have (yellow : data. blue : FS)

DYann1_3-1705937329543.png

LCE
Principal

Show the function processData_2(), it should look something like this:

 

void processData_2()
{	for( int32_t n = (BUFFER_SIZE / 2); n < BUFFER_SIZE; n++ )
	{
		checkbuf_RX[n]=playbuf_RX[n];
	}
	dataReadyFlag_2 = 0;
}

 

I think it's the same

 

void processData_2 ()
{
	for (int32_t n=64; n<BUFFER_SIZE; n++)
	{
	 checkbuf_RX[n]=playbuf_RX[n];
	}
	dataReadyFlag_2=0;
}

And the callback :

void HAL_SAI_RxHalfCpltCallback (SAI_HandleTypeDef *hsai)
{
	dataReadyFlag_1=1;
}

void HAL_SAI_RxCpltCallback (SAI_HandleTypeDef *hsai)
 {
	dataReadyFlag_2=1;
 }

 

LCE
Principal

I think it's the same

Probably yes. Be more consistent, which means: don't use a number, and then a define - I mean the "64".
And for incrementing always use unsigned integers (uint32_t in this case).

To check that both flags are set: in processData_1() (better call it "half" or so than "1") set a GPIO high, in processData_2() (better call it "full" or so than "2") set the same GPIO low again. If both flags are set and reset again, the GPIO should toggle with a rate equal to sampling rate / buffer size. Check with scope.

Hi,

I'll come back with the curves.The result is not there but I have values.

yellow :FS / blue : led flashing

DYann1_0-1706089814662.png

My sample rate is 44.1 kHz (real : 35.7 kHz). So sampling rate/128 = 278 Hz (about), but I have 571 Hz (about twice as much). I'm Debug mode and maybe in Release mode that would change something ?