cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G0C1E-EV jack headset recording

Ander Susperregui
Associate III

I am trying to record audio from a STM32G01CE-EV by using a microphone from a headphone connected through the jack connector. I am not able to get any proper data and I dont know if I am approaching the problem properly. How should I read the data of the microphone ( ADC, DMA, I2S)? Or if anyone knows is it possible to read the data through jack with an ADC? im not so sure anymore

1 ACCEPTED SOLUTION

Accepted Solutions
Ander Susperregui
Associate III

Finally managed using ADC via DMA by a timer interruption.

View solution in original post

4 REPLIES 4
TDK
Guru

> STM32G01CE-EV

You mean STM32G0C1E-EV?

I2S requires a digital signal, while ADC converts an analog signal.

A quick look at the user manual shows the microphone is directly connected to the microcontroller, so you should use the ADC to sample it.

0693W00000HpfNVQAZ.png 

There don't appear to be examples for the microphone on that board, but the concept is straightforward. Use the user manual to ensure the hardware connections are correct as sometimes jumpers need to move to use different board features as pins are often overprescribed.

If you feel a post has answered your question, please click "Accept as Solution".

Sorry to reply this late,

I have tried with the ADC to convert the data of the microphone but I dont know if the data is correct. I have tried to transmit it through DAC with DMA but I only hear noise and I dont know what is the main problem. How should I configure the timer to obtain data in a frecuency of 16Khz I think I am not sampling properly the data even though I have used the demonstration example to configure the modules.

The main project is to transmit real time audio though CAN FD from a STM32 to a linux based iMX8X and reproduce there. The problem is that I dont think I am getting proper values with the ADC I have configured. I only hear noise and I dont know how else I have to configure.

I just want to try now to hear what I get from the ADC, into the DAC of the SMT32, to ensure the values Im getting. I have tried, but I only hear noise and I dont know how to get proper data. Any idea?

 This is more or less some parts of my program, I only use processDSP() on while(1) so there is nothing else functioning in the loop. Do you see any problem to be able to sample my microphone and listen to it on the headphones?

uint32_t *outbufPtr;

 uint32_t *inbufPtr;

uint32_t adc_val[FULLBUFFERSIZE];

uint32_t dac_val[FULLBUFFERSIZE];

HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_val, FULLBUFFERSIZE);

  HAL_TIM_Base_Start(&htim6);

  HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t *) dac_val, FULLBUFFERSIZE, DAC_ALIGN_12B_R);

static void MX_ADC1_Init(void)

{

 /* USER CODE BEGIN ADC1_Init 0 */

 /* USER CODE END ADC1_Init 0 */

 ADC_ChannelConfTypeDef sConfig = {0};

 /* USER CODE BEGIN ADC1_Init 1 */

 /* USER CODE END ADC1_Init 1 */

 /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)

 */

 hadc1.Instance = ADC1;

 hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;

 hadc1.Init.Resolution = ADC_RESOLUTION_12B;

 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;

 hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

 hadc1.Init.LowPowerAutoWait = DISABLE;

 hadc1.Init.LowPowerAutoPowerOff = DISABLE;

 hadc1.Init.ContinuousConvMode = DISABLE;

 hadc1.Init.NbrOfConversion = 1;

 hadc1.Init.DiscontinuousConvMode = DISABLE;

 hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T6_TRGO;

 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;

 hadc1.Init.DMAContinuousRequests = ENABLE;

 hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;

 hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_39CYCLES_5;

 hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_39CYCLES_5;

 hadc1.Init.OversamplingMode = ENABLE;

 hadc1.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_4;

 hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_2;

 hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;

 hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;

 if (HAL_ADC_Init(&hadc1) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure Regular Channel

 */

 sConfig.Channel = ADC_CHANNEL_6;

 sConfig.Rank = ADC_REGULAR_RANK_1;

 sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN ADC1_Init 2 */

 /* USER CODE END ADC1_Init 2 */

}

/**

 * @brief DAC1 Initialization Function

 * @param None

 * @retval None

 */

static void MX_DAC1_Init(void)

{

 /* USER CODE BEGIN DAC1_Init 0 */

 /* USER CODE END DAC1_Init 0 */

 DAC_ChannelConfTypeDef sConfig = {0};

 /* USER CODE BEGIN DAC1_Init 1 */

 /* USER CODE END DAC1_Init 1 */

 /** DAC Initialization

 */

 hdac1.Instance = DAC1;

 if (HAL_DAC_Init(&hdac1) != HAL_OK)

 {

  Error_Handler();

 }

 /** DAC channel OUT1 config

 */

 sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;

 sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;

 sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;

 sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;

 sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;

 if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN DAC1_Init 2 */

 /* USER CODE END DAC1_Init 2 */

}

static void MX_TIM6_Init(void)

{

 /* USER CODE BEGIN TIM6_Init 0 */

 /* USER CODE END TIM6_Init 0 */

 TIM_MasterConfigTypeDef sMasterConfig = {0};

 /* USER CODE BEGIN TIM6_Init 1 */

 /* USER CODE END TIM6_Init 1 */

 htim6.Instance = TIM6;

 htim6.Init.Prescaler = 0;

 htim6.Init.CounterMode = TIM_COUNTERMODE_UP;

 htim6.Init.Period = 4000;

 htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

 if (HAL_TIM_Base_Init(&htim6) != HAL_OK)

 {

  Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

 if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN TIM6_Init 2 */

 /* USER CODE END TIM6_Init 2 */

}

/**

 * Enable DMA controller clock

 */

static void MX_DMA_Init(void)

{

 /* DMA controller clock enable */

 __HAL_RCC_DMA1_CLK_ENABLE();

 /* DMA interrupt init */

 /* DMA1_Channel1_IRQn interrupt configuration */

 HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

 /* DMA1_Channel2_3_IRQn interrupt configuration */

 HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);

}

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc)

{

  mitad= 1;

  // First half of the ADC Buffer is half buff

  inbufPtr = &adc_val[0];

  //outbufPtr = &TxData[DATASIZE];

  outbufPtr = &dac_val[DATASIZE];

}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)

{

  lleno= 1;

  inbufPtr = &adc_val[DATASIZE];

  //outbufPtr = &TxData[0];

  outbufPtr = &dac_val[0];

}

void processDSP()

{

  for(int n=0; n < DATASIZE;n++)

  outbufPtr[n]=inbufPtr[n];

}

Ander Susperregui
Associate III

Finally managed using ADC via DMA by a timer interruption.