Skip to main content
Explorer
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

    This topic has been closed for replies.

    13 replies

    DYann.1Author
    Explorer
    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

    Graduate 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.1Author
    Explorer
    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;
     }

     

    Graduate 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.1Author
    Explorer
    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 ?