/* * Copyright (c) 2020 AIIT XUOS Lab * XiUOS is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * http://license.coscl.org.cn/MulanPSL2 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. */ /** * @file board.c * @brief support stm32l476rgt6 nucleo board init configure and start-up * @version 1.0 * @author AIIT XUOS Lab * @date 2025-03-04 */ #include #include #include #include #include "stm32l4xx_hal.h" #include "connect_usart.h" #include "connect_spi.h" #include "connect_usb.h" void Error_Handler(void) { while (1) { /** error handler */ } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** 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_6; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 40; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** 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_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2 |RCC_PERIPHCLK_USART3|RCC_PERIPHCLK_UART4 |RCC_PERIPHCLK_UART5|RCC_PERIPHCLK_USB; PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1; PeriphClkInit.Uart4ClockSelection = RCC_UART4CLKSOURCE_PCLK1; PeriphClkInit.Uart5ClockSelection = RCC_UART5CLKSOURCE_PCLK1; PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1; PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI; PeriphClkInit.PLLSAI1.PLLSAI1M = 1; PeriphClkInit.PLLSAI1.PLLSAI1N = 24; PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7; PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2; PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2; PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } /** Configure the main internal regulator output voltage */ if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) { Error_Handler(); } /** Enable MSI Auto calibration */ HAL_RCCEx_EnableMSIPLLMode(); __HAL_RCC_SYSCFG_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); } void SysTick_Handler(int irqn, void *arg) { TickAndTaskTimesliceUpdate(); HAL_IncTick(); } DECLARE_HW_IRQ(SysTick_IRQn, SysTick_Handler, NONE); void InitBoardHardware() { HAL_Init(); /* enable interrupt */ __set_PRIMASK(0); /* System clock initialization */ SystemClock_Config(); InitBoardMemory((void *)MEMORY_START_ADDRESS, (void *)MEMORY_END_ADDRESS); #ifdef BSP_USING_UART HwUsartInit(); InstallConsole(SERIAL_BUS_NAME_2, SERIAL_DRV_NAME_2, SERIAL_2_DEVICE_NAME_0); #endif #ifdef BSP_USING_SPI HwSpiInit(); #endif #ifdef BSP_USING_USB HwUsbDeviceInit(); #endif /* disable interrupt */ __set_PRIMASK(1); }