cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with the PDM2PCM-Lib and a STM32L151

bub
Associate

I'm having problems with the PDM2PCM lib and am getting desperate.

I have a STM32L151 with an external clock source of 8.192 MHz. The SYSCLK runs with 16.384 MHz. The APB2 (SPI1) runs with 4.096 MHz.

I'm sampling a PDM mic with an 8-bit SPI at 2.048 MHz. The prescaler is on 2, CPOL is low and CPHA is on the 2nd edge.

I'm using the DMA in circular mode, byte-oriented and with memory increment to fill the PDM buffer. I transfer 512 bytes.

My PDM buffer has 2 x 256 bytes for pseudo double buffering and as PCM buffer I have 32 x 16-bit unsigned (uint16_t).

On each half-transfer and full-transfer (every 1ms each), I execute the PDM_Filter function with half of the PDM buffer to fill the PCM buffer. Thus I should get 32 samples per 1ms. I have 64 as decimation factor.

Unfortunately, all I get is junk. Where could the reasoning error be or what did I not understand correctly? Thank you very very much for the help!

Here are some more excerpts from my code:

//buffers

#define PDMBUFFERSIZE 256*2

#define PCMBUFFERSIZE 32

uint16_t pcmbuffer[PCMBUFFERSIZE];

uint8_t pdmbuffer[PDMBUFFERSIZE];

...

/**

 * @brief SPI1 Initialization Function

 * @param None

 * @retval None

 */

static void MX_SPI1_Init(void)

{

 /* USER CODE BEGIN SPI1_Init 0 */

 /* USER CODE END SPI1_Init 0 */

 /* USER CODE BEGIN SPI1_Init 1 */

 /* USER CODE END SPI1_Init 1 */

 /* SPI1 parameter configuration*/

 hspi1.Instance = SPI1;

 hspi1.Init.Mode = SPI_MODE_MASTER;

 hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;

 hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

 hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;

 hspi1.Init.NSS = SPI_NSS_SOFT;

 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;

 hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

 hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

 hspi1.Init.CRCPolynomial = 10;

 if (HAL_SPI_Init(&hspi1) != HAL_OK)

 {

   Error_Handler();

 }

 /* USER CODE BEGIN SPI1_Init 2 */

 /* USER CODE END SPI1_Init 2 */

}

...

/*Enables and resets CRC-32 from STM32 HW */   

__HAL_RCC_CRC_CLK_ENABLE();   

CRC->CR = CRC_CR_RESET;

//Initialize PDM Filter structure   

FilterHandler.bit_order = PDM_FILTER_BIT_ORDER_MSB;   

FilterHandler.endianness = PDM_FILTER_ENDIANNESS_LE;   

FilterHandler.high_pass_tap = 2122358088; // Coff = 0.988 -> get this number as 0.988*(2^31-1)

FilterHandler.out_ptr_channels = 1;   

FilterHandler.in_ptr_channels = 1;

PDM_Filter_Init(&FilterHandler);

FilterConfig.output_samples_number = PCMBUFFERSIZE;

FilterConfig.mic_gain = 1;

FilterConfig.decimation_factor = PDM_FILTER_DEC_FACTOR_64;

PDM_Filter_setConfig((PDM_Filter_Handler_t *)&FilterHandler, &FilterConfig);

...

//start mic-recording

MicWokeUp = FALSE;

HAL_SPI_Receive_DMA(&hspi1, pdmbuffer, PDMBUFFERSIZE);

HAL_Delay(200);

MicWokeUp = TRUE;

...

/**

 * @brief This function handles DMA Half Transfer interrupt.

 */

void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi)

{

   //1. half buffer

   if (MicWokeUp == TRUE){

      HAL_GPIO_WritePin(H3_GPIO_Port, H3_Pin, GPIO_PIN_SET);

      PDM_Filter(&pdmtestbuffer[0], &pcmbuffer[0], &FilterHandler);

      PCMBufferReady = TRUE;

      HAL_GPIO_WritePin(H3_GPIO_Port, H3_Pin, GPIO_PIN_RESET);

   }

}

/**

 * @brief This function handles DMA Full Transfer interrupt.

 */

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)

{

   //2. half buffer

   if (MicWokeUp == TRUE){

      HAL_GPIO_WritePin(H4_GPIO_Port, H4_Pin, GPIO_PIN_SET);

      PDM_Filter(&pdmtestbuffer[PDMBUFFERSIZE/2], &pcmbuffer[0], &FilterHandler);

      PCMBufferReady = TRUE;

      HAL_GPIO_WritePin(H4_GPIO_Port, H4_Pin, GPIO_PIN_RESET);

   }

}

...

//pcm data ready?

if (PCMBufferReady == TRUE){

   PCMBufferReady = FALSE;

   //copy pcmbuffer to flashbuffer

   HAL_GPIO_WritePin(H5_GPIO_Port, H5_Pin, GPIO_PIN_SET);

   for (PCMBufferIndex = 0 ; PCMBufferIndex < PCMBUFFERSIZE; PCMBufferIndex++){

      FlashPageBuffer[FlashPageBufferIndex] = ((pcmbuffer[PCMBufferIndex]&0xff00)>>8);            

      FlashPageBufferIndex++;

   }

   HAL_GPIO_WritePin(H5_GPIO_Port, H5_Pin, GPIO_PIN_RESET);

}

0 REPLIES 0