Skip to main content
Younjun
Associate II
April 26, 2022
Solved

About output waveform problem of CS42L51

Hi,

This is my previous question(link).

I'm implementing 24bit, 44.1kHz audio out code using STM32H7B3-discovery.

In previous question, i set SAI(I2S format) buffer like below.

0693W00000LyztVQAR.pngI set SAI_A block to output.

And, this is my SAI_A setting.

0693W00000LyzuiQAB.png0693W00000LyzusQAB.png0693W00000Lyzv2QAB.png0693W00000Lyzv7QAB.png​

​

I set tx buffer to zero and BufferOutCtl.buff also filled zero.

​

This is my output waveform.

0693W00000LyzvMQAR.png​

I thought that if I filled the buffer with 4 bytes of data and sent it to dma, it would be as below.0693W00000Lyzw5QAB.pngBut, I got noise waveform.

​

I checked clock.​

  • LRCK : 44.1kHz
  • MCLK : 11.29MHz

​

​

​

​

This is main code.

 
#define FULL_TXRX_SIZE	256
#define HALF_TXRX_SIZE	128
 
ALIGN_32BYTES (static AUDIO_IN_BufferTypeDef BufferInCtl) __attribute__((section(".RAM_D3")));
ALIGN_32BYTES (static AUDIO_OUT_BufferTypeDef BufferOutCtl) __attribute__((section(".RAM_D3")));
 
 
 
int main(void) {
	uint16_t b_cnt = 0, b_ptr = 0;
 
	BSP_AUDIO_Init_t out_aduio;
	BSP_AUDIO_Init_t in_aduio;
	uint32_t pin_state = 0;
 
	/* Configure the MPU attributes as Write Through for SDRAM*/
	MPU_Config();
	/* Enable the CPU Cache */
	CPU_CACHE_Enable();
 
	/* STM32H7xx HAL library initialization:
	 - Configure the Systick to generate an interrupt each 1 msec
	 - Set NVIC Group Priority to 4
	 - Low Level Initialization
	 */
	HAL_Init();
 
	/* Configure the system clock to 280 MHz */
	SystemClock_Config();
 
	BSP_LED_Init(LED3);
	BSP_LED_Init(LED2);
	out_aduio.Device = AUDIO_OUT_DEVICE_HEADPHONE;
	out_aduio.ChannelsNbr = 2;
	out_aduio.SampleRate = AUDIO_FREQUENCY_44K;
	out_aduio.BitsPerSample = AUDIO_RESOLUTION_24B;
	out_aduio.Volume = 100;
 
	in_aduio.Device = IN_DEVICE;
	in_aduio.ChannelsNbr = 2;
	in_aduio.SampleRate = AUDIO_FREQUENCY_44K;
	in_aduio.BitsPerSample = AUDIO_RESOLUTION_24B;
	in_aduio.Volume = 100;
 
	/* -2- Configure EXTI15_10 (connected to PC.13 pin) in interrupt mode */
	EXTI15_10_IRQHandler_Config();
 
	BSP_AUDIO_IN_Init(AUDIO_INOUT_INSTANCE, &in_aduio);
	//BSP_AUDIO_OUT_Init(AUDIO_INOUT_INSTANCE, &out_aduio);
 
	/* Final Output double buffer structure */
	BufferInCtl.state = PLAY_BUFFER_OFFSET_NONE;
	BufferInCtl.fptr = 0;
	BufferOutCtl.state = PLAY_BUFFER_OFFSET_NONE;
	BufferOutCtl.fptr = 0;
 
#if CLEAN_DCACHE
	/* Clean Data Cache to update the content of the SRAM */
	SCB_InvalidateDCache_by_Addr((uint32_t*) &BufferInCtl.buff[0], FULL_TXRX_SIZE);
	SCB_CleanDCache_by_Addr((uint32_t*) &BufferOutCtl.buff[0], FULL_TXRX_SIZE);
	memset(&BufferInCtl.buff[0], 0x00, FULL_TXRX_SIZE);
	memset(&BufferOutCtl.buff[0], 0x00, FULL_TXRX_SIZE);
#endif
 
	BSP_AUDIO_OUT_Play(AUDIO_INOUT_INSTANCE, (uint8_t*) &BufferOutCtl.buff[0], FULL_TXRX_SIZE);
	//BSP_AUDIO_IN_Record(AUDIO_INOUT_INSTANCE, (uint8_t*) &BufferInCtl.buff[0], FULL_TXRX_SIZE);
 
	for (b_cnt = 0; b_cnt < FULL_TXRX_SIZE; b_cnt += 8) {
		slotb[b_cnt] = 0x00;
		slotb[b_cnt + 1] = 0x00;
		slotb[b_cnt + 2] = 0x00;
		slotb[b_cnt + 3] = 0;
		slotb[b_cnt + 4] = 0;
		slotb[b_cnt + 5] = 0;
		slotb[b_cnt + 6] = 0;
		slotb[b_cnt + 7] = 0;
	}
	p_bff = slotb;
 
	/* Infinite loop */
	while (1) {
 
		if (rx_half_flag) {
			SCB_InvalidateDCache_by_Addr((uint32_t*) &BufferInCtl.buff[0], HALF_TXRX_SIZE);
			memcpy(rx_buffer, &BufferInCtl.buff[0], HALF_TXRX_SIZE);
			rx_half_flag = 0;
		}
		if (rx_full_flag) {
			SCB_InvalidateDCache_by_Addr((uint32_t*) &BufferInCtl.buff[HALF_TXRX_SIZE], HALF_TXRX_SIZE);
			memcpy(rx_buffer + HALF_TXRX_SIZE, &BufferInCtl.buff[HALF_TXRX_SIZE], HALF_TXRX_SIZE);
			rx_full_flag = 0;
		}
 
		if (tx_half_flag) {
			SCB_CleanDCache_by_Addr((uint32_t*) &BufferOutCtl.buff[0], HALF_TXRX_SIZE);
			memcpy(&BufferOutCtl.buff[0], p_bff, HALF_TXRX_SIZE);
			tx_half_flag = 0;
		}
		if (tx_full_flag) {
			SCB_CleanDCache_by_Addr((uint32_t*) &BufferOutCtl.buff[HALF_TXRX_SIZE], HALF_TXRX_SIZE);
			memcpy(&BufferOutCtl.buff[HALF_TXRX_SIZE], p_bff + HALF_TXRX_SIZE, HALF_TXRX_SIZE);
			tx_full_flag = 0;
		}
	}
}

And, This is my modified BSP_AUDIO_In_init().

​

int32_t BSP_AUDIO_IN_Init(uint32_t Instance, BSP_AUDIO_Init_t *AudioInit) {
	uint32_t i;
	int32_t ret = BSP_ERROR_NONE;
 
	if (Instance >= AUDIO_IN_INSTANCES_NBR) {
		ret = BSP_ERROR_WRONG_PARAM;
	} else {
		/* Store the audio record context */
		Audio_In_Ctx[Instance].Device = AudioInit->Device;
		Audio_In_Ctx[Instance].ChannelsNbr = AudioInit->ChannelsNbr;
		Audio_In_Ctx[Instance].SampleRate = AudioInit->SampleRate;
		Audio_In_Ctx[Instance].BitsPerSample = AudioInit->BitsPerSample;
		Audio_In_Ctx[Instance].Volume = AudioInit->Volume;
		Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_RESET;
 
		Audio_Out_Ctx[Instance].Device = AudioInit->Device;
		Audio_Out_Ctx[Instance].Instance = Instance;
		Audio_Out_Ctx[Instance].SampleRate = AudioInit->SampleRate;
		Audio_Out_Ctx[Instance].BitsPerSample = AudioInit->BitsPerSample;
		Audio_Out_Ctx[Instance].ChannelsNbr = AudioInit->ChannelsNbr;
		Audio_Out_Ctx[Instance].Volume = AudioInit->Volume;
		Audio_Out_Ctx[Instance].State = AUDIO_OUT_STATE_RESET;
 
		if (Instance != 2U) {
			/* Un-reset audio codec if not currently used by audio out instances */
			if ((Audio_Out_Ctx[0].State == AUDIO_OUT_STATE_RESET) && (Audio_Out_Ctx[1].State == AUDIO_OUT_STATE_RESET)) {
				(void) CS42L51_PowerUp();
				/* Initialize the codec internal registers */
				if (CS42L51_Probe() != BSP_ERROR_NONE) {
					ret = BSP_ERROR_COMPONENT_FAILURE;
				}
			}
		}
 
		if (ret == BSP_ERROR_NONE) {
 
			if (Instance == 0U) {
				/* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */
				if (MX_SAI1_ClockConfig(&haudio_out_sai, AudioInit->SampleRate) != HAL_OK) {
					ret = BSP_ERROR_CLOCK_FAILURE;
				}
				if (MX_SAI1_ClockConfig(&haudio_in_sai, AudioInit->SampleRate) != HAL_OK) {
					ret = BSP_ERROR_CLOCK_FAILURE;
				} else {
					haudio_in_sai.Instance = AUDIO_IN_SAIx;
					haudio_out_sai.Instance = AUDIO_OUT_SAIx;
					SAI_MspInit(&haudio_in_sai);
					SAI_MspInit(&haudio_out_sai);
					MX_SAI_Config mx_config;
 
					/* Prepare haudio_in_sai handle */
					mx_config.AudioFrequency = Audio_In_Ctx[Instance].SampleRate;
					mx_config.AudioMode = SAI_MODESLAVE_RX;
					mx_config.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
					mx_config.MonoStereoMode = (AudioInit->ChannelsNbr == 1U) ? SAI_MONOMODE : SAI_STEREOMODE;
					mx_config.DataSize = SAI_DATASIZE_24;
					mx_config.FrameLength = 64;
					mx_config.ActiveFrameLength = 32;
					mx_config.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
					mx_config.Synchro = SAI_SYNCHRONOUS;
					mx_config.SynchroExt = SAI_SYNCEXT_DISABLE;
					mx_config.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
 
					if (MX_SAI1_Block_B_Init(&haudio_in_sai, &mx_config) != HAL_OK) {
						/* Return BSP_ERROR_PERIPH_FAILURE when operations are not correctly done */
						ret = BSP_ERROR_PERIPH_FAILURE;
					} else {
						/* Prepare haudio_out_sai handle */
						mx_config.AudioMode = SAI_MODEMASTER_TX;
						mx_config.Synchro = SAI_ASYNCHRONOUS;
 
						if (MX_SAI1_Block_A_Init(&haudio_out_sai, &mx_config) != HAL_OK) {
							/* Return BSP_ERROR_PERIPH_FAILURE when operations are not correctly done */
							ret = BSP_ERROR_PERIPH_FAILURE;
						}
					}
#if (USE_AUDIO_CODEC_CS42L51 == 1)
					if (ret == BSP_ERROR_NONE) {
						CS42L51_Init_t codec_init;
 
						/* Fill codec_init structure */
						codec_init.OutputDevice = ((Audio_Out_Ctx[0].State == AUDIO_OUT_STATE_RESET) && (Audio_Out_Ctx[1].State == AUDIO_OUT_STATE_RESET)) ? CS42L51_OUT_NONE : CS42L51_OUT_HEADPHONE;
						codec_init.Frequency = AudioInit->SampleRate;
						codec_init.Resolution = CS42L51_RESOLUTION_16b; /* Not used */
						codec_init.Volume = AudioInit->Volume;
						codec_init.InputDevice = CS42L51_IN_LINE1;
						/* Initialize the codec internal registers */
						if (Audio_Drv->Init(Audio_CompObj, &codec_init) < 0) {
							ret = BSP_ERROR_COMPONENT_FAILURE;
						} else {
							/* Update audio in context state */
							Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_STOP;
							Audio_Out_Ctx[Instance].State = AUDIO_OUT_STATE_STOP;
						}
					}
#endif /*USE_AUDIO_CODEC_CS42L51 == 1)*/
				}
			} 
			/* Update BSP AUDIO IN state */
			Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_STOP;
		}
	}
 
	/* Return BSP status */
	return ret;
}

Has anyone experienced these symptoms?

I attached my CS42L51 register setting.

​

Regards,

Youngjun​

    This topic has been closed for replies.
    Younjun
    YounjunBest answer
    Associate II
    April 26, 2022

    The problem has been resolved.

    I missed below code.

    HAL_SAI_Receive_DMA(&haudio_in_sai, (uint8_t*) pBuf, (uint16_t) (NbrOfBytes / (Audio_In_Ctx[Instance].BitsPerSample / 8U)))

    ​My Audio_in_Ctx[Instance].BitPerSample was 24.

    I modified this value to 32.

    2 replies

    Younjun
    YounjunAuthor
    Associate II
    April 26, 2022

    I attach more pictures.

    ​

    I send input buffer data to output buffer.(100Hz 100mVpp sine wave from function generator)

    while (1) {
     
    		if (rx_half_flag) {
    			SCB_InvalidateDCache_by_Addr((uint32_t*) &BufferInCtl.buff[0], HALF_TXRX_SIZE);
    			memcpy(rx_buffer, &BufferInCtl.buff[0], HALF_TXRX_SIZE);
    			rx_half_flag = 0;
    		}
    		if (rx_full_flag) {
    			SCB_InvalidateDCache_by_Addr((uint32_t*) &BufferInCtl.buff[HALF_TXRX_SIZE], HALF_TXRX_SIZE);
    			memcpy(rx_buffer + HALF_TXRX_SIZE, &BufferInCtl.buff[HALF_TXRX_SIZE], HALF_TXRX_SIZE);
    			rx_full_flag = 0;
    		}
     
    		if (tx_half_flag) {
    			SCB_CleanDCache_by_Addr((uint32_t*) &BufferOutCtl.buff[0], HALF_TXRX_SIZE);
    			memcpy(&BufferOutCtl.buff[0], rx_buffer, HALF_TXRX_SIZE);
    			tx_half_flag = 0;
    		}
    		if (tx_full_flag) {
    			SCB_CleanDCache_by_Addr((uint32_t*) &BufferOutCtl.buff[HALF_TXRX_SIZE], HALF_TXRX_SIZE);
    			memcpy(&BufferOutCtl.buff[HALF_TXRX_SIZE], rx_buffer + HALF_TXRX_SIZE, HALF_TXRX_SIZE);
    			tx_full_flag = 0;
    		}
    	}

    ​

    ​

    ​when i set frame size to 16bit,

    • mx_config.DataSize = SAI_DATASIZE_16;
    • mx_config.FrameLength = 32;
    • mx_config.ActiveFrameLength = 16;​

    the waveform is clear.

    0693W00000Lz04xQAB.jpg 

    This is 24bit frame size.

    • mx_config.DataSize = SAI_DATASIZE_24;
    • mx_config.FrameLength = 64;
    • mx_config.ActiveFrameLength = 32;

    0693W00000Lz066QAB.jpg 

    Younjun
    YounjunAuthorBest answer
    Associate II
    April 26, 2022

    The problem has been resolved.

    I missed below code.

    HAL_SAI_Receive_DMA(&haudio_in_sai, (uint8_t*) pBuf, (uint16_t) (NbrOfBytes / (Audio_In_Ctx[Instance].BitsPerSample / 8U)))

    ​My Audio_in_Ctx[Instance].BitPerSample was 24.

    I modified this value to 32.