cancel
Showing results for 
Search instead for 
Did you mean: 

About output waveform problem of CS42L51

Younjun
Associate II

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​

1 ACCEPTED SOLUTION

Accepted Solutions
Younjun
Associate II

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.

View solution in original post

2 REPLIES 2
Younjun
Associate II

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
Associate II

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.