/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #define ARM_MATH_CM4 #include "main.h" #include "arm_math.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #ifndef HSEM_ID_0 #define HSEM_ID_0 (0U) /* HW semaphore 0*/ #endif /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ I2S_HandleTypeDef hi2s1; DMA_HandleTypeDef hdma_spi1_tx; DMA_HandleTypeDef hdma_spi1_rx; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ static void MX_GPIO_Init(void); static void MX_DMA_Init(void); static void MX_I2S1_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* FIR filter designed with http://t-filter.appspot.com sampling frequency: 48000 Hz * 0 Hz - 2000 Hz gain = 1 desired ripple = 5 dB actual ripple = 3.284632065621469 dB * 5000 Hz - 24000 Hz gain = 0 desired attenuation = -30 dB actual attenuation = -32.02295267957132 dB */ #define FILTER_TAP_NUM 16 #define BLOCK_SIZE_FLOAT 512 #define BLOCK_SIZE_U16 2048 /*static float filter_taps[FILTER_TAP_NUM] = { -0.0021834891907904987, 0.023133081888390004, 0.03440125360693663, 0.054016706019288735, 0.07610902012650608, 0.09772535709704201, 0.11593264129629442, 0.12810228628568973, 0.13238343618749146, 0.12810228628568973, 0.11593264129629442, 0.09772535709704201, 0.07610902012650608, 0.054016706019288735, 0.03440125360693663, 0.023133081888390004, -0.0021834891907904987 };*/ //FIR BP fs48kHz,Order15 static float filter_taps[FILTER_TAP_NUM] = { -0.0195752460187690, 0.0119915552629445, 0.00717283698280682, -0.0490010630870986, 0.0710715985018322, -0.0529488863637266, -0.0747295317750623, 0.581375225878972, 0.581375225878972, -0.0747295317750623, -0.0529488863637266, 0.0710715985018322, -0.0490010630870986, 0.00717283698280682, 0.0119915552629445, -0.0195752460187690 }; arm_fir_instance_f32 firsettings_l, firsettings_r; //fir state size is always number_of_samples + number_of_fir_tabs - 1 float fir_l_state [BLOCK_SIZE_FLOAT + FILTER_TAP_NUM - 1]; float fir_r_state [BLOCK_SIZE_FLOAT + FILTER_TAP_NUM - 1]; uint16_t rxBuf[BLOCK_SIZE_U16*2]; uint16_t txBuf[BLOCK_SIZE_U16*2]; float l_buf_in [BLOCK_SIZE_FLOAT*2]; float r_buf_in [BLOCK_SIZE_FLOAT*2]; float l_buf_out [BLOCK_SIZE_FLOAT*2]; float r_buf_out [BLOCK_SIZE_FLOAT*2]; uint8_t callback_state = 0; /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* USER CODE BEGIN Boot_Mode_Sequence_1 */ /*HW semaphore Clock enable*/ __HAL_RCC_HSEM_CLK_ENABLE(); /* Activate HSEM notification for Cortex-M4*/ HAL_HSEM_ActivateNotification(__HAL_HSEM_SEMID_TO_MASK(HSEM_ID_0)); /* Domain D2 goes to STOP mode (Cortex-M4 in deep-sleep) waiting for Cortex-M7 to perform system initialization (system clock config, external memory configuration.. ) */ HAL_PWREx_ClearPendingEvent(); HAL_PWREx_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFE, PWR_D2_DOMAIN); /* Clear HSEM flag */ __HAL_HSEM_CLEAR_FLAG(__HAL_HSEM_SEMID_TO_MASK(HSEM_ID_0)); /* USER CODE END Boot_Mode_Sequence_1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_DMA_Init(); MX_GPIO_Init(); MX_I2S1_Init(); /* USER CODE BEGIN 2 */ //init FIR structure arm_fir_init_f32(&firsettings_l, FILTER_TAP_NUM, &filter_taps[0], &fir_l_state[0], BLOCK_SIZE_FLOAT); arm_fir_init_f32(&firsettings_r, FILTER_TAP_NUM, &filter_taps[0], &fir_r_state[0], BLOCK_SIZE_FLOAT); //start i2s with 2048 samples transmission => 4096*u16 words HAL_I2SEx_TransmitReceive_DMA (&hi2s1, txBuf, rxBuf, BLOCK_SIZE_U16); int offset_r_ptr; int offset_w_ptr, w_ptr; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin); if (callback_state != 0) { //decide if it was half or cplt callback if (callback_state == 1) { offset_r_ptr = 0; offset_w_ptr = 0; w_ptr = 0; } else if (callback_state == 2) { offset_r_ptr = BLOCK_SIZE_U16; offset_w_ptr = BLOCK_SIZE_FLOAT; w_ptr = BLOCK_SIZE_FLOAT; } //restore input sample buffer to float array for (int i=offset_r_ptr; i>16)&0xFFFF; txBuf[i+1] = ((int)l_buf_out[w_ptr])&0xFFFF; txBuf[i+2] = (((int)r_buf_out[w_ptr])>>16)&0xFFFF; txBuf[i+3] = ((int)r_buf_out[w_ptr])&0xFFFF; w_ptr++; } callback_state = 0; } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s1){ callback_state = 1; } void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s1){ callback_state = 2; } /** * @brief I2S1 Initialization Function * @param None * @retval None */ static void MX_I2S1_Init(void) { /* USER CODE BEGIN I2S1_Init 0 */ /* USER CODE END I2S1_Init 0 */ /* USER CODE BEGIN I2S1_Init 1 */ /* USER CODE END I2S1_Init 1 */ hi2s1.Instance = SPI1; hi2s1.Init.Mode = I2S_MODE_MASTER_TX; hi2s1.Init.Standard = I2S_STANDARD_PHILIPS; hi2s1.Init.DataFormat = I2S_DATAFORMAT_24B; hi2s1.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE; hi2s1.Init.AudioFreq = I2S_AUDIOFREQ_48K; hi2s1.Init.CPOL = I2S_CPOL_LOW; hi2s1.Init.FirstBit = I2S_FIRSTBIT_MSB; hi2s1.Init.WSInversion = I2S_WS_INVERSION_DISABLE; hi2s1.Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_RIGHT; hi2s1.Init.MasterKeepIOState = I2S_MASTER_KEEP_IO_STATE_DISABLE; if (HAL_I2S_Init(&hi2s1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN I2S1_Init 2 */ /* USER CODE END I2S1_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_Stream3_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn); /* DMA1_Stream4_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn); } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : B1_Pin */ GPIO_InitStruct.Pin = B1_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pins : LD1_Pin LD3_Pin */ GPIO_InitStruct.Pin = LD1_Pin|LD3_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pin : LD2_Pin */ GPIO_InitStruct.Pin = LD2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct); } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/