/** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** ** This notice applies to any and all portions of this file * that are not between comment pairs USER CODE BEGIN and * USER CODE END. Other portions of this file, whether * inserted by the user or by software development tools * are owned by their respective copyright owners. * * COPYRIGHT(c) 2018 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32l4xx_hal.h" /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ ADC_HandleTypeDef hadc1; ADC_HandleTypeDef hadc2; ADC_HandleTypeDef hadc3; DCMI_HandleTypeDef hdcmi; DFSDM_Channel_HandleTypeDef hdfsdm1_channel1; DFSDM_Channel_HandleTypeDef hdfsdm1_channel2; I2C_HandleTypeDef hi2c1; I2C_HandleTypeDef hi2c2; UART_HandleTypeDef hlpuart1; UART_HandleTypeDef huart1; UART_HandleTypeDef huart2; QSPI_HandleTypeDef hqspi; SAI_HandleTypeDef hsai_BlockA1; SAI_HandleTypeDef hsai_BlockB1; SD_HandleTypeDef hsd1; SPI_HandleTypeDef hspi1; SPI_HandleTypeDef hspi2; PCD_HandleTypeDef hpcd_USB_OTG_FS; SRAM_HandleTypeDef hsram1; SRAM_HandleTypeDef hsram2; /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_ADC1_Init(void); static void MX_ADC2_Init(void); static void MX_ADC3_Init(void); static void MX_DCMI_Init(void); static void MX_DFSDM1_Init(void); static void MX_FMC_Init(void); static void MX_I2C1_Init(void); static void MX_I2C2_Init(void); static void MX_LPUART1_UART_Init(void); static void MX_USART1_UART_Init(void); static void MX_USART2_UART_Init(void); static void MX_QUADSPI_Init(void); static void MX_SAI1_Init(void); static void MX_SDMMC1_SD_Init(void); static void MX_SPI1_Init(void); static void MX_SPI2_Init(void); static void MX_USB_OTG_FS_PCD_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE END PFP */ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * * @retval None */ 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_ADC1_Init(); MX_ADC2_Init(); MX_ADC3_Init(); MX_DCMI_Init(); MX_DFSDM1_Init(); MX_FMC_Init(); MX_I2C1_Init(); MX_I2C2_Init(); MX_LPUART1_UART_Init(); MX_USART1_UART_Init(); MX_USART2_UART_Init(); MX_QUADSPI_Init(); MX_SAI1_Init(); MX_SDMMC1_SD_Init(); MX_SPI1_Init(); MX_SPI2_Init(); MX_USB_OTG_FS_PCD_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* 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; RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInit; /**Configure LSE Drive Capability */ HAL_PWR_EnableBkUpAccess(); __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); /**Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.MSICalibrationValue = 0; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_9; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; RCC_OscInitStruct.PLL.PLLM = 5; RCC_OscInitStruct.PLL.PLLN = 71; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV6; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Initializes the CPU, AHB and APB busses 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_DIV4; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2 |RCC_PERIPHCLK_LPUART1|RCC_PERIPHCLK_SAI1 |RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_I2C2 |RCC_PERIPHCLK_DFSDM1|RCC_PERIPHCLK_USB |RCC_PERIPHCLK_SDMMC1|RCC_PERIPHCLK_ADC; PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1; PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1; PeriphClkInit.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1; PeriphClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1; PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1; PeriphClkInit.Dfsdm1ClockSelection = RCC_DFSDM1CLKSOURCE_PCLK; PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1; PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_PLLSAI1; PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI; PeriphClkInit.PLLSAI1.PLLSAI1M = 5; PeriphClkInit.PLLSAI1.PLLSAI1N = 20; PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV2; PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2; PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2; PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK|RCC_PLLSAI1_48M2CLK |RCC_PLLSAI1_ADC1CLK; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure the main internal regulator output voltage */ if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure the Systick interrupt time */ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); /**Configure the Systick */ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /**Enable MSI Auto calibration */ HAL_RCCEx_EnableMSIPLLMode(); /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } /* ADC1 init function */ static void MX_ADC1_Init(void) { ADC_MultiModeTypeDef multimode; ADC_ChannelConfTypeDef sConfig; /**Common config */ hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; 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.ContinuousConvMode = DISABLE; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.NbrOfDiscConversion = 1; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED; hadc1.Init.OversamplingMode = DISABLE; if (HAL_ADC_Init(&hadc1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure the ADC multi-mode */ multimode.Mode = ADC_MODE_INDEPENDENT; if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_4; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* ADC2 init function */ static void MX_ADC2_Init(void) { ADC_ChannelConfTypeDef sConfig; /**Common config */ hadc2.Instance = ADC2; hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; hadc2.Init.Resolution = ADC_RESOLUTION_12B; hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc2.Init.LowPowerAutoWait = DISABLE; hadc2.Init.ContinuousConvMode = DISABLE; hadc2.Init.NbrOfConversion = 1; hadc2.Init.DiscontinuousConvMode = DISABLE; hadc2.Init.NbrOfDiscConversion = 1; hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc2.Init.DMAContinuousRequests = DISABLE; hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED; hadc2.Init.OversamplingMode = DISABLE; if (HAL_ADC_Init(&hadc2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_9; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* ADC3 init function */ static void MX_ADC3_Init(void) { ADC_ChannelConfTypeDef sConfig; /**Common config */ hadc3.Instance = ADC3; hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; hadc3.Init.Resolution = ADC_RESOLUTION_12B; hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc3.Init.LowPowerAutoWait = DISABLE; hadc3.Init.ContinuousConvMode = DISABLE; hadc3.Init.NbrOfConversion = 1; hadc3.Init.DiscontinuousConvMode = DISABLE; hadc3.Init.NbrOfDiscConversion = 1; hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc3.Init.DMAContinuousRequests = DISABLE; hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED; hadc3.Init.OversamplingMode = DISABLE; if (HAL_ADC_Init(&hadc3) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_13; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* DCMI init function */ static void MX_DCMI_Init(void) { hdcmi.Instance = DCMI; hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_FALLING; hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_LOW; hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW; hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME; hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B; hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE; hdcmi.Init.ByteSelectMode = DCMI_BSM_ALL; hdcmi.Init.ByteSelectStart = DCMI_OEBS_ODD; hdcmi.Init.LineSelectMode = DCMI_LSM_ALL; hdcmi.Init.LineSelectStart = DCMI_OELS_ODD; if (HAL_DCMI_Init(&hdcmi) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* DFSDM1 init function */ static void MX_DFSDM1_Init(void) { hdfsdm1_channel1.Instance = DFSDM1_Channel1; hdfsdm1_channel1.Init.OutputClock.Activation = ENABLE; hdfsdm1_channel1.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM; hdfsdm1_channel1.Init.OutputClock.Divider = 2; hdfsdm1_channel1.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS; hdfsdm1_channel1.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE; hdfsdm1_channel1.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS; hdfsdm1_channel1.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING; hdfsdm1_channel1.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL; hdfsdm1_channel1.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER; hdfsdm1_channel1.Init.Awd.Oversampling = 1; hdfsdm1_channel1.Init.Offset = 0; hdfsdm1_channel1.Init.RightBitShift = 0x00; if (HAL_DFSDM_ChannelInit(&hdfsdm1_channel1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } hdfsdm1_channel2.Instance = DFSDM1_Channel2; hdfsdm1_channel2.Init.OutputClock.Activation = ENABLE; hdfsdm1_channel2.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM; hdfsdm1_channel2.Init.OutputClock.Divider = 2; hdfsdm1_channel2.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS; hdfsdm1_channel2.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE; hdfsdm1_channel2.Init.Input.Pins = DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS; hdfsdm1_channel2.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING; hdfsdm1_channel2.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL; hdfsdm1_channel2.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER; hdfsdm1_channel2.Init.Awd.Oversampling = 1; hdfsdm1_channel2.Init.Offset = 0; hdfsdm1_channel2.Init.RightBitShift = 0x00; if (HAL_DFSDM_ChannelInit(&hdfsdm1_channel2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* I2C1 init function */ static void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.Timing = 0x00000E14; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure Analogue filter */ if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure Digital filter */ if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* I2C2 init function */ static void MX_I2C2_Init(void) { hi2c2.Instance = I2C2; hi2c2.Init.Timing = 0x00000E14; hi2c2.Init.OwnAddress1 = 0; hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c2.Init.OwnAddress2 = 0; hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK; hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure Analogue filter */ if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure Digital filter */ if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* LPUART1 init function */ static void MX_LPUART1_UART_Init(void) { hlpuart1.Instance = LPUART1; hlpuart1.Init.BaudRate = 209700; hlpuart1.Init.WordLength = UART_WORDLENGTH_7B; hlpuart1.Init.StopBits = UART_STOPBITS_1; hlpuart1.Init.Parity = UART_PARITY_NONE; hlpuart1.Init.Mode = UART_MODE_TX_RX; hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&hlpuart1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* USART1 init function */ static void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_7B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS; huart1.Init.OverSampling = UART_OVERSAMPLING_16; huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* USART2 init function */ static void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_7B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* QUADSPI init function */ static void MX_QUADSPI_Init(void) { /* QUADSPI parameter configuration*/ hqspi.Instance = QUADSPI; hqspi.Init.ClockPrescaler = 255; hqspi.Init.FifoThreshold = 1; hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE; hqspi.Init.FlashSize = 1; hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE; hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0; hqspi.Init.FlashID = QSPI_FLASH_ID_1; hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE; if (HAL_QSPI_Init(&hqspi) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* SAI1 init function */ static void MX_SAI1_Init(void) { hsai_BlockA1.Instance = SAI1_Block_A; hsai_BlockA1.Init.Protocol = SAI_FREE_PROTOCOL; hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_TX; hsai_BlockA1.Init.DataSize = SAI_DATASIZE_24; hsai_BlockA1.Init.FirstBit = SAI_FIRSTBIT_MSB; hsai_BlockA1.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE; hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS; hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE; hsai_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE; hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY; hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_192K; hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE; hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE; hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING; hsai_BlockA1.Init.TriState = SAI_OUTPUT_NOTRELEASED; hsai_BlockA1.FrameInit.FrameLength = 8; hsai_BlockA1.FrameInit.ActiveFrameLength = 1; hsai_BlockA1.FrameInit.FSDefinition = SAI_FS_STARTFRAME; hsai_BlockA1.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; hsai_BlockA1.FrameInit.FSOffset = SAI_FS_FIRSTBIT; hsai_BlockA1.SlotInit.FirstBitOffset = 0; hsai_BlockA1.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE; hsai_BlockA1.SlotInit.SlotNumber = 1; hsai_BlockA1.SlotInit.SlotActive = 0x00000000; if (HAL_SAI_Init(&hsai_BlockA1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } hsai_BlockB1.Instance = SAI1_Block_B; hsai_BlockB1.Init.Protocol = SAI_FREE_PROTOCOL; hsai_BlockB1.Init.AudioMode = SAI_MODESLAVE_RX; hsai_BlockB1.Init.DataSize = SAI_DATASIZE_24; hsai_BlockB1.Init.FirstBit = SAI_FIRSTBIT_MSB; hsai_BlockB1.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE; hsai_BlockB1.Init.Synchro = SAI_SYNCHRONOUS; hsai_BlockB1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE; hsai_BlockB1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY; hsai_BlockB1.Init.SynchroExt = SAI_SYNCEXT_DISABLE; hsai_BlockB1.Init.MonoStereoMode = SAI_STEREOMODE; hsai_BlockB1.Init.CompandingMode = SAI_NOCOMPANDING; hsai_BlockB1.Init.TriState = SAI_OUTPUT_NOTRELEASED; hsai_BlockB1.FrameInit.FrameLength = 24; hsai_BlockB1.FrameInit.ActiveFrameLength = 1; hsai_BlockB1.FrameInit.FSDefinition = SAI_FS_STARTFRAME; hsai_BlockB1.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; hsai_BlockB1.FrameInit.FSOffset = SAI_FS_FIRSTBIT; hsai_BlockB1.SlotInit.FirstBitOffset = 0; hsai_BlockB1.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE; hsai_BlockB1.SlotInit.SlotNumber = 1; hsai_BlockB1.SlotInit.SlotActive = 0x00000000; if (HAL_SAI_Init(&hsai_BlockB1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* SDMMC1 init function */ static void MX_SDMMC1_SD_Init(void) { hsd1.Instance = SDMMC1; hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; hsd1.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE; hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B; hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; hsd1.Init.ClockDiv = 0; if (HAL_SD_Init(&hsd1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } if (HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* SPI1 init function */ static void MX_SPI1_Init(void) { /* SPI1 parameter configuration*/ hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_4BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT; 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 = 7; hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; if (HAL_SPI_Init(&hspi1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* SPI2 init function */ static void MX_SPI2_Init(void) { /* SPI2 parameter configuration*/ hspi2.Instance = SPI2; hspi2.Init.Mode = SPI_MODE_MASTER; hspi2.Init.Direction = SPI_DIRECTION_2LINES; hspi2.Init.DataSize = SPI_DATASIZE_4BIT; hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi2.Init.TIMode = SPI_TIMODE_DISABLE; hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi2.Init.CRCPolynomial = 7; hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; if (HAL_SPI_Init(&hspi2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* USB_OTG_FS init function */ static void MX_USB_OTG_FS_PCD_Init(void) { hpcd_USB_OTG_FS.Instance = USB_OTG_FS; hpcd_USB_OTG_FS.Init.dev_endpoints = 6; hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL; hpcd_USB_OTG_FS.Init.ep0_mps = DEP0CTL_MPS_64; hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED; hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE; hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE; hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE; hpcd_USB_OTG_FS.Init.battery_charging_enable = DISABLE; hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE; hpcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE; if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /* FMC initialization function */ static void MX_FMC_Init(void) { FMC_NORSRAM_TimingTypeDef Timing; /** Perform the SRAM1 memory initialization sequence */ hsram1.Instance = FMC_NORSRAM_DEVICE; hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE; /* hsram1.Init */ hsram1.Init.NSBank = FMC_NORSRAM_BANK2; hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE; hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM; hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16; hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE; hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW; hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS; hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_DISABLE; hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE; hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE; hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE; hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE; hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY; hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE; hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE; /* Timing */ Timing.AddressSetupTime = 15; Timing.AddressHoldTime = 15; Timing.DataSetupTime = 255; Timing.BusTurnAroundDuration = 15; Timing.CLKDivision = 16; Timing.DataLatency = 17; Timing.AccessMode = FMC_ACCESS_MODE_A; /* ExtTiming */ if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /** Perform the SRAM2 memory initialization sequence */ hsram2.Instance = FMC_NORSRAM_DEVICE; hsram2.Extended = FMC_NORSRAM_EXTENDED_DEVICE; /* hsram2.Init */ hsram2.Init.NSBank = FMC_NORSRAM_BANK1; hsram2.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE; hsram2.Init.MemoryType = FMC_MEMORY_TYPE_SRAM; hsram2.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16; hsram2.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE; hsram2.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW; hsram2.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS; hsram2.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE; hsram2.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE; hsram2.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE; hsram2.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE; hsram2.Init.WriteBurst = FMC_WRITE_BURST_DISABLE; hsram2.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY; hsram2.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE; hsram2.Init.PageSize = FMC_PAGE_SIZE_NONE; /* Timing */ Timing.AddressSetupTime = 15; Timing.AddressHoldTime = 15; Timing.DataSetupTime = 255; Timing.BusTurnAroundDuration = 15; Timing.CLKDivision = 16; Timing.DataLatency = 17; Timing.AccessMode = FMC_ACCESS_MODE_A; /* ExtTiming */ if (HAL_SRAM_Init(&hsram2, &Timing, NULL) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } } /** Configure pins as * Analog * Input * Output * EVENT_OUT * EXTI PI6 ------> S_TIM8_CH2 PH15 ------> TIM8_CH3N PH13 ------> TIM8_CH1N PB9 ------> S_TIM4_CH4 PA8 ------> LPTIM2_OUT */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOI_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); HAL_PWREx_EnableVddIO2(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOH, MFX_WAKEUP_Pin|LCD_PWR_ON_Pin|MIC_VDD_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(Audio_RST_GPIO_Port, Audio_RST_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET); /*Configure GPIO pins : JOY_DOWN_Pin JOY_LEFT_Pin JOY_UP_Pin */ GPIO_InitStruct.Pin = JOY_DOWN_Pin|JOY_LEFT_Pin|JOY_UP_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); /*Configure GPIO pin : STMOD_INT_Pin */ GPIO_InitStruct.Pin = STMOD_INT_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(STMOD_INT_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : LCD_BL_Pin */ GPIO_InitStruct.Pin = LCD_BL_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(LCD_BL_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : ARD_D6_Pin */ GPIO_InitStruct.Pin = ARD_D6_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF3_TIM8; HAL_GPIO_Init(ARD_D6_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pins : ARD_D3_Pin ARD_D9_Pin */ GPIO_InitStruct.Pin = ARD_D3_Pin|ARD_D9_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF3_TIM8; HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); /*Configure GPIO pin : ARD_D5_Pin */ GPIO_InitStruct.Pin = ARD_D5_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF2_TIM4; HAL_GPIO_Init(ARD_D5_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : LCD_TE_Pin */ GPIO_InitStruct.Pin = LCD_TE_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(LCD_TE_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pins : MFX_WAKEUP_Pin LCD_PWR_ON_Pin MIC_VDD_Pin */ GPIO_InitStruct.Pin = MFX_WAKEUP_Pin|LCD_PWR_ON_Pin|MIC_VDD_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); /*Configure GPIO pin : Audio_RST_Pin */ GPIO_InitStruct.Pin = Audio_RST_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(Audio_RST_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : CTP_INT_Pin */ GPIO_InitStruct.Pin = CTP_INT_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(CTP_INT_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : DCMI_CLK_Pin */ GPIO_InitStruct.Pin = DCMI_CLK_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF14_LPTIM2; HAL_GPIO_Init(DCMI_CLK_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : MFX_IRQ_OUT_Pin */ GPIO_InitStruct.Pin = MFX_IRQ_OUT_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(MFX_IRQ_OUT_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : JOY_RIGHT_Pin */ GPIO_InitStruct.Pin = JOY_RIGHT_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLDOWN; HAL_GPIO_Init(JOY_RIGHT_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : STMOD_RESET_Pin */ GPIO_InitStruct.Pin = STMOD_RESET_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(STMOD_RESET_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : LED1_Pin */ GPIO_InitStruct.Pin = LED1_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct); } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @param file: The file name as string. * @param line: The line in file as a number. * @retval None */ void _Error_Handler(char *file, int line) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ 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, 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****/