cancel
Showing results for 
Search instead for 
Did you mean: 

DMA HALFWORD and SAI_DATASIZE_24;

benyBoy
Associate II
Posted on June 29, 2018 at 07:30

Hi, I'm trying to use SAI_DATASIZE_24; with the Audio_playback_and_record application demo for the STM32f769i_Discovery.

The demo uses DMA to copy data from the SAIx to the recorder buffer in 16bit.

I tried changing the data size in the DMA to WORD from HALFWORD but the just get a hard fault !

#define AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_WORD  // was HALFWORD 16bit ? now 32bit ?

#define AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_WORD  //  was HALFWORD 16bit ? now 32bit ?

is there anything else I must do to enable 32bit DMA transfer ?

I can't change this from 0xFFFF // 16bit  to 32bit since

#define DMA_MAX_SZE    0xFFFFFFFF

as you can see in the SAI_Handle_Structure_definition its a max of uint16_t transfer size?

uint16_t XferSize; /*!< SAI transfer size */

/** @defgroup SAI_Handle_Structure_definition SAI Handle Structure definition

* @brief SAI handle Structure definition

* @{

*/

typedef struct __SAI_HandleTypeDef

{

SAI_Block_TypeDef *Instance; /*!< SAI Blockx registers base address */

SAI_InitTypeDef Init; /*!< SAI communication parameters */

SAI_FrameInitTypeDef FrameInit; /*!< SAI Frame configuration parameters */

SAI_SlotInitTypeDef SlotInit; /*!< SAI Slot configuration parameters */

uint8_t *pBuffPtr; /*!< Pointer to SAI transfer Buffer */

uint16_t XferSize; /*!< SAI transfer size */

uint16_t XferCount; /*!< SAI transfer counter */

DMA_HandleTypeDef *hdmatx; /*!< SAI Tx DMA handle parameters */

DMA_HandleTypeDef *hdmarx; /*!< SAI Rx DMA handle parameters */

SAIcallback mutecallback; /*!< SAI mute callback */

void (*InterruptServiceRoutine)(struct __SAI_HandleTypeDef *hsai); /* function pointer for IRQ handler */

HAL_LockTypeDef Lock; /*!< SAI locking object */

__IO HAL_SAI_StateTypeDef State; /*!< SAI communication state */

__IO uint32_t ErrorCode; /*!< SAI Error code */

}SAI_HandleTypeDef;

the application recorder code was setup for 24bit 8 channels and works in TDM8 16bit.

So , should I hack the SAI HAL to work with 32 bit ?

Or does it not matter how the data is sent over DMA ?

There is also this

#define AUDIODATA_SIZE   2 /* 16-bits audio data size */

should I just change this to;

#define AUDIODATA_SIZE   4  /* 32-bits audio data size */ 

or

#define AUDIODATA_SIZE   3  /* 24-bits audio data size */ 

the data is sent out over DMA with ... 

/* Update the Media layer and enable it for play */

HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE));

4 REPLIES 4
GGiul
Associate

Hi benyBoy,

I´m trying to make a similar thing. I want to use SAI_DATASIZE_24 on the STM32f746g discovery board with the Audioplayback.c from BSP example.The idea is to use the wm8994 codec which came with the board. This audio codec works with 24 bits data size in the ADC and DAC. I'm already manage to rec from the INPUT_DEVICE_INPUT_LINE_1 and playback through the headphone with the SAI_SLOTACTIVE_0 and SAI_SLOTACTIVE_2. Its the only way i found to do it because i cant disable TDM in AIF1 so the Timeslot 0 and 1 are stereo.

I want to know if you could do it and how, i dont have a lot of experience using DMA. I worked with the stm32f407 before and used HAL_I2S_Transmit_IT to transfer 24 bit setereo data to the codec cs43L22.

Please any help is well received.

Regards,

Gonzalo Giulio.

Hi Gonzalo ,

I now tried setting SAI DMA to WORD which is 32 bits.

SAI_DATASIZE_32

I change pcm_buff to 32bit although I'm not quite sure why this is unsigned !

uint32_t pcm_buff[AUDIO_IN_PCM_BUFFER_SIZE];

 struct value pcm_buff is in main.h

typedef struct {
 
 uint16_t pcm_buff[AUDIO_IN_PCM_BUFFER_SIZE];  
 
 uint32_t pcm_ptr;
 
 WR_BUFFER_StateTypeDef wr_state;
 
 uint32_t offset;  
 
 uint32_t fptr;
 
}AUDIO_IN_BufferTypeDef;

the player reads uint8_t bytes from file and sets FS in the SAI from header in the file.

#define AUDIODATA_SIZE 4 // 3 bytes for 24bit but I need to send 32bit for SAI DMA so its 4

my issue now is this line,

// max DMA size made of 8bit char =  16bit 65535 change to 32bit ?
#define DMA_MAX_SZE    0xFFFFFFFF //
#define DMA_MAX(x)  (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE)

HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE));

HAL_SAI_Transmit_DMA expects the size as uint16_t but I am trying to define max size as 32bit ( or in your case 24bit )

I'll try cast the size to uint16_t like this but I don't think its right.

HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, (uint16_t) DMA_MAX(Size / AUDIODATA_SIZE));

I need to understand what the DMA_MAX is doing. If it was a mask for 16bit then maybe I can just do it another way for 32bit.

The idea is that if I can get 32bit working , then I can just ignore the last byte to get 24bit samples from the SAI.

The DMA is copying the 32bits but I just have to figure out the last part.

I'll write the answer here when it works. I think i'm nearly there.

I'm not really sure what the best buffer sizes are for you. I guess just make it a multiple of the bytes / channels your using.

Hello @benyBoy​ , I have the same doubts as you .. did you find a solution ? thank you

Hello @benyBoy (Community Member)

Did you ever get anywhere on this?