Skip to main content
DYann.1
Senior II
January 8, 2024
Question

SAI with blocking mode

  • January 8, 2024
  • 13 replies
  • 5883 views

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

13 replies

DYann.1
DYann.1Author
Senior II
January 22, 2024

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 II
January 22, 2024

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;
}

 

DYann.1
DYann.1Author
Senior II
January 22, 2024

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 II
January 22, 2024

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.

DYann.1
DYann.1Author
Senior II
January 24, 2024

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 ?