Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * @file : main.c
- * @brief : Main program body
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2021 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * 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 ------------------------------------------------------------------*/
- #include "main.h"
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- #include <math.h>
- /* USER CODE END Includes */
- /* Private typedef -----------------------------------------------------------*/
- /* USER CODE BEGIN PTD */
- /* USER CODE END PTD */
- /* Private define ------------------------------------------------------------*/
- /* USER CODE BEGIN PD */
- /* USER CODE END PD */
- /* Private macro -------------------------------------------------------------*/
- /* USER CODE BEGIN PM */
- /* USER CODE END PM */
- /* Private variables ---------------------------------------------------------*/
- I2C_HandleTypeDef hi2c3;
- I2S_HandleTypeDef hi2s2;
- /* USER CODE BEGIN PV */
- /* USER CODE END PV */
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- static void MX_GPIO_Init(void);
- static void MX_I2C3_Init(void);
- static void MX_I2S2_Init(void);
- /* USER CODE BEGIN PFP */
- /* USER CODE END PFP */
- /* Private user code ---------------------------------------------------------*/
- /* USER CODE BEGIN 0 */
- enum CodecRegister {
- CODEC_REG_LEFT_LINE_IN = 0x00,
- CODEC_REG_RIGHT_LINE_IN = 0x01,
- CODEC_REG_LEFT_HEADPHONES_OUT = 0x02,
- CODEC_REG_RIGHT_HEADPHONES_OUT = 0x03,
- CODEC_REG_ANALOGUE_ROUTING = 0x04,
- CODEC_REG_DIGITAL_ROUTING = 0x05,
- CODEC_REG_POWER_MANAGEMENT = 0x06,
- CODEC_REG_DIGITAL_FORMAT = 0x07,
- CODEC_REG_SAMPLE_RATE = 0x08,
- CODEC_REG_ACTIVE = 0x09,
- CODEC_REG_RESET = 0x0f,
- };
- enum CodecSettings {
- CODEC_INPUT_0_DB = 0x17,
- CODEC_INPUT_UPDATE_BOTH = 0x40,
- CODEC_HEADPHONES_MUTE = 0x00,
- CODEC_MIC_BOOST = 0x1,
- CODEC_MIC_MUTE = 0x2,
- CODEC_ADC_MIC = 0x4,
- CODEC_ADC_LINE = 0x0,
- CODEC_OUTPUT_DAC_ENABLE = 0x10,
- CODEC_OUTPUT_MONITOR = 0x20,
- CODEC_DEEMPHASIS_NONE = 0x00,
- CODEC_DEEMPHASIS_32K = 0x01,
- CODEC_DEEMPHASIS_44K = 0x02,
- CODEC_DEEMPHASIS_48K = 0x03,
- CODEC_SOFT_MUTE = 0x01,
- CODEC_ADC_HPF = 0x00,
- CODEC_POWER_DOWN_LINE_IN = 0x01,
- CODEC_POWER_DOWN_MIC = 0x02,
- CODEC_POWER_DOWN_ADC = 0x04,
- CODEC_POWER_DOWN_DAC = 0x08,
- CODEC_POWER_DOWN_LINE_OUT = 0x10,
- CODEC_POWER_DOWN_OSCILLATOR = 0x20,
- CODEC_POWER_DOWN_CLOCK_OUTPUT = 0x40,
- CODEC_POWER_DOWN_EVERYTHING = 0x80,
- CODEC_PROTOCOL_MASK_MSB_FIRST = 0x00,
- CODEC_PROTOCOL_MASK_LSB_FIRST = 0x01,
- CODEC_PROTOCOL_MASK_PHILIPS = 0x02,
- CODEC_PROTOCOL_MASK_DSP = 0x03,
- CODEC_FORMAT_MASK_16_BIT = 0x00 << 2,
- CODEC_FORMAT_MASK_20_BIT = 0x01 << 2,
- CODEC_FORMAT_MASK_24_BIT = 0x02 << 2,
- CODEC_FORMAT_MASK_32_BIT = 0x03 << 2,
- CODEC_FORMAT_LR_SWAP = 0x20,
- CODEC_FORMAT_MASTER = 0x40,
- CODEC_FORMAT_SLAVE = 0x00,
- CODEC_FORMAT_INVERT_CLOCK = 0x80,
- CODEC_RATE_48K_48K = 0x00 << 2,
- CODEC_RATE_8K_8K = 0x03 << 2,
- CODEC_RATE_96K_96K = 0x07 << 2,
- CODEC_RATE_32K_32K = 0x06 << 2,
- CODEC_RATE_44K_44K = 0x08 << 2,
- };
- uint8_t init_codec() {
- uint8_t status = 0;
- uint8_t val = 0;
- // reset codec
- status += HAL_I2C_Mem_Write(&hi2c3, (0x1A << 1 ), CODEC_REG_RESET, 1, &val, 1, HAL_MAX_DELAY);
- // config headphone outputs
- // val = CODEC_HEADPHONES_MUTE;
- // status += HAL_I2C_Mem_Write(&hi2c3, (0x1A << 1 ), CODEC_REG_LEFT_HEADPHONES_OUT, 1, &val, 1, HAL_MAX_DELAY);
- // status += HAL_I2C_Mem_Write(&hi2c3, (0x1A << 1 ), CODEC_REG_RIGHT_HEADPHONES_OUT, 1, &val, 1, HAL_MAX_DELAY);
- // config analog routing
- val = CODEC_MIC_MUTE | CODEC_ADC_LINE | CODEC_OUTPUT_DAC_ENABLE;
- status += HAL_I2C_Mem_Write(&hi2c3, (0x1A << 1 ), CODEC_REG_ANALOGUE_ROUTING, 1, &val, 1, HAL_MAX_DELAY);
- // Configure digital routing
- val = CODEC_DEEMPHASIS_NONE;
- status += HAL_I2C_Mem_Write(&hi2c3, (0x1A << 1 ), CODEC_REG_DIGITAL_ROUTING, 1, &val, 1, HAL_MAX_DELAY);
- // config power management
- val = CODEC_POWER_DOWN_MIC;
- status += HAL_I2C_Mem_Write(&hi2c3, (0x1A << 1 ), CODEC_REG_POWER_MANAGEMENT, 1, &val, 1, HAL_MAX_DELAY);
- // format byte
- val = CODEC_PROTOCOL_MASK_PHILIPS | CODEC_FORMAT_MASK_16_BIT | CODEC_FORMAT_MASTER;
- status += HAL_I2C_Mem_Write(&hi2c3, (0x1A << 1 ), CODEC_REG_DIGITAL_FORMAT, 1, &val, 1, HAL_MAX_DELAY);
- val = CODEC_RATE_48K_48K;
- status += HAL_I2C_Mem_Write(&hi2c3, (0x1A << 1 ), CODEC_REG_SAMPLE_RATE, 1, &val, 1, HAL_MAX_DELAY);
- // For now codec is not active.
- val = 0x01;
- status += HAL_I2C_Mem_Write(&hi2c3, (0x1A << 1 ), CODEC_REG_ACTIVE, 1, &val, 1, HAL_MAX_DELAY);
- return status;
- }
- static int16_t audio_data[2 * 1200];
- void play_tone() {
- for (int i = 0; i < 1200; i++) {
- int16_t value = (int16_t)(32000.0 * sin(2.0 * M_PI * i / 48.0));
- audio_data[i * 2] = value;
- audio_data[i * 2 + 1] = value;
- }
- }
- /* USER CODE END 0 */
- /**
- * @brief The application entry point.
- * @retval int
- */
- int main(void)
- {
- /* USER CODE BEGIN 1 */
- /* USER CODE END 1 */
- /* MCU Configuration--------------------------------------------------------*/
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
- /* USER CODE BEGIN Init */
- /* USER CODE END Init */
- /* Configure the system clock */
- SystemClock_Config();
- /* USER CODE BEGIN SysInit */
- /* USER CODE END SysInit */
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_I2C3_Init();
- MX_I2S2_Init();
- /* USER CODE BEGIN 2 */
- uint8_t status = init_codec();
- play_tone();
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- HAL_I2S_Transmit(&hi2s2, (uint16_t*)audio_data, 2 * 1200, HAL_MAX_DELAY);
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- }
- /* USER CODE END 3 */
- }
- /**
- * @brief System Clock Configuration
- * @retval None
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
- RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
- /** Configure the main internal regulator output voltage
- */
- __HAL_RCC_PWR_CLK_ENABLE();
- __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
- /** Initializes the RCC Oscillators according to the specified parameters
- * in the RCC_OscInitTypeDef structure.
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
- RCC_OscInitStruct.PLL.PLLM = 8;
- RCC_OscInitStruct.PLL.PLLN = 168;
- RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
- RCC_OscInitStruct.PLL.PLLQ = 4;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
- /** Initializes the CPU, AHB and APB buses clocks
- */
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
- {
- Error_Handler();
- }
- PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
- PeriphClkInitStruct.PLLI2S.PLLI2SN = 192;
- PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
- if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
- }
- /**
- * @brief I2C3 Initialization Function
- * @param None
- * @retval None
- */
- static void MX_I2C3_Init(void)
- {
- /* USER CODE BEGIN I2C3_Init 0 */
- /* USER CODE END I2C3_Init 0 */
- /* USER CODE BEGIN I2C3_Init 1 */
- /* USER CODE END I2C3_Init 1 */
- hi2c3.Instance = I2C3;
- hi2c3.Init.ClockSpeed = 100000;
- hi2c3.Init.DutyCycle = I2C_DUTYCYCLE_2;
- hi2c3.Init.OwnAddress1 = 0;
- hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
- hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
- hi2c3.Init.OwnAddress2 = 0;
- hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
- hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
- if (HAL_I2C_Init(&hi2c3) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN I2C3_Init 2 */
- /* USER CODE END I2C3_Init 2 */
- }
- /**
- * @brief I2S2 Initialization Function
- * @param None
- * @retval None
- */
- static void MX_I2S2_Init(void)
- {
- /* USER CODE BEGIN I2S2_Init 0 */
- /* USER CODE END I2S2_Init 0 */
- /* USER CODE BEGIN I2S2_Init 1 */
- /* USER CODE END I2S2_Init 1 */
- hi2s2.Instance = SPI2;
- hi2s2.Init.Mode = I2S_MODE_MASTER_TX;
- hi2s2.Init.Standard = I2S_STANDARD_PHILIPS;
- hi2s2.Init.DataFormat = I2S_DATAFORMAT_16B;
- hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
- hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_48K;
- hi2s2.Init.CPOL = I2S_CPOL_LOW;
- hi2s2.Init.ClockSource = I2S_CLOCK_PLL;
- hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
- if (HAL_I2S_Init(&hi2s2) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN I2S2_Init 2 */
- /* USER CODE END I2S2_Init 2 */
- }
- /**
- * @brief GPIO Initialization Function
- * @param None
- * @retval None
- */
- static void MX_GPIO_Init(void)
- {
- /* GPIO Ports Clock Enable */
- __HAL_RCC_GPIOH_CLK_ENABLE();
- __HAL_RCC_GPIOB_CLK_ENABLE();
- __HAL_RCC_GPIOC_CLK_ENABLE();
- __HAL_RCC_GPIOA_CLK_ENABLE();
- }
- /* 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 */
- /* 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,
- tex: 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****/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement