/* USER CODE BEGIN Header */ /** ****************************************************************************** * @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) 2019 STMicroelectronics International N.V. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted, provided that the following conditions are met: * * 1. Redistribution 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 other * contributors to this software may be used to endorse or promote products * derived from this software without specific written permission. * 4. This software, including modifications and/or derivative works of this * software, must execute solely and exclusively on microcontroller or * microprocessor devices manufactured by or for STMicroelectronics. * 5. Redistribution and use of this software other than as permitted under * this license is void and will automatically terminate your rights under * this license. * * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT * SHALL STMICROELECTRONICS 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. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #define MAIN_C #include "core/main.h" #include "usb_device.h" #include "core/gpio.h" //#include "drivers/spi/spi.h" #include "drivers/flash/base/extmem_flash.h" #include "app/usbapp/usb_application_flash.h" #include "app/usbapp/usb_application_enumspy.h" #include "app/thermo/tsensor.h" #include "app/thermo/NTCtsensor.h" #include "app/control_table/control_table.h" #include "app/automat/automat.h" #include "app/led/led.h" #include "app/vbat/vbat.h" #include "app/nfm/nfm_base.h" #include "stm32l1xx_hal_i2c.h" #include "drivers/keycontrol/keycontrol.h" #include "drivers/adc/adc.h" #include "drivers/power_management/power_management.h" #include "app/nfm/nfm_base.h" #include "core/sleep_and_exti.h" #include "core_cm3.h" // SCB, SCB_SHCSR_USGFAULTENA #include "stm32l1xx_hal_conf.h" // TICK_INT_PRIORITY() #include "stm32l1xx_hal_cortex.h" // HAL_NVIC_SetPriority() #include "core/config.h" #include "core/config_pins.h" #include "core/debugpins.h" #include "core/csect.h" #include "my_assert.h" #include "static_assert.h" #if CONFIG_NOIRQ_SNPRINTF #include // va_list #endif // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #if CONFIG_STACKOVERFLOW_CONTROLSECTION // CSTACK overflow protection/notification section // Place specially prepared signature into the area before CSTACK block in RAM // to provide easy control of stack overflow. extern void size_cstack_protect; // Size of area: see .icf #pragma location=".cstacktail" // Protection section name // Fill the area with signature: static __root volatile uint32_t cstacktail[8] = { 0xEFBEADDE, 0xEFBEADDE, 0xEFBEADDE, 0xEFBEADDE, 0xEFBEADDE, 0xEFBEADDE, 0xEFBEADDE, 0xEFBEADDE }; #endif // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #if DEBUG_TRACE static volatile int debugcnt = 0; static int getdebugcnt() { int r = 0; __DI__ r = debugcnt; debugcnt++; __EI__ return r; } #define MAX_TRACEPOINTS 16 static volatile int g_debug_tracepoints[ MAX_TRACEPOINTS ] = {0}; void debug_trace( int idx ) { if( idx < MAX_TRACEPOINTS ) g_debug_tracepoints[idx] = getdebugcnt(); } #endif // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ static volatile bool xUSBPlugged = false; static volatile bool xUSBActive = false; static volatile bool xAutomatActive = false; //static volatile bool g_bHarmUpEnable = false; //static volatile uint32_t g_nHarmUpTimestamp = 0ul; #if CONFIG_REBOOT_FEATURE static volatile bool g_RebootRequest = false; #endif #if CONFIG_VBATMON static volatile uint32_t xVBatVoltage = 0; #endif #if CONFIG_USB static eNFMUSBInterface_t usbDeviceInterface = #if CONFIG_USB_OVERRIDE_IFACE_USBTMC eNFM_IfaceUSBTMC; #else eNFM_IfaceUSBVendor; #endif #endif void SystemClock_Config(void); void SystemClock_Config_Low(void); #if CONFIG_EXTREME_LOWPOWTEST void GPIO_Init_LowPowerTest(void) { /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; /*Configure all GPIO pins of port C*/ GPIO_InitStruct.Pin = GPIO_PIN_All; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /*Configure all GPIO pins of port A ,except PA13 and PA14 (SWD)*/ GPIO_InitStruct.Pin = GPIO_PIN_All & (~(GPIO_PIN_13|GPIO_PIN_14)); GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure all GPIO pins of port B*/ GPIO_InitStruct.Pin = GPIO_PIN_All; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_DISABLE(); __HAL_RCC_GPIOH_CLK_DISABLE(); __HAL_RCC_GPIOA_CLK_DISABLE(); __HAL_RCC_GPIOB_CLK_DISABLE(); } #endif #if CONFIG_EXTREME_LOWPOWTEST static void main_extreme_low_power() { __HAL_RCC_COMP_CLK_ENABLE(); __HAL_RCC_SYSCFG_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); GPIO_Init_LowPowerTest(); SystemClock_Config_Low(); SleepManagerHandle.Init(); while(1) SleepManagerHandle.Sleep(); } #endif /** * @brief The application entry point. * @retval int */ #if CONFIG_USB_DYNAMIC_CLOCK_ADOPT && CONFIG_USB static void SysConfig_USBConnected() { __DI__ // need to disable interrupts to setup SystemTick correctly SystemClock_Config(); #if CONFIG_SYSTICK == CONFIG_SYSTICK_NORMAL #if CONFIG_SYSTICK_BOOST_MULTIPLIER HAL_SYSTICK_Config( SystemCoreClock / 1000 / (CONFIG_SYSTICK_BOOST_MULTIPLIER) ); // CONFIG_SYSTICK_BOOST_MULTIPLIER times per 1ms HAL_NVIC_SetPriority( SysTick_IRQn, TICK_INT_PRIORITY, 0 ); #else HAL_SYSTICK_Config( SystemCoreClock / 1000 ); // 1 times per 1ms HAL_NVIC_SetPriority( SysTick_IRQn, TICK_INT_PRIORITY, 0 ); #endif #else HAL_SYSTICK_Config( SystemCoreClock / 1000 ); // 1 times per 1ms HAL_NVIC_SetPriority( SysTick_IRQn, TICK_INT_PRIORITY, 0 ); #endif __EI__ #if CONFIG_EXTMEM /* Reinitialize the external memory */ ExtMemHandle.Init(); #endif #if CONFIG_NFMBASECLASS #if CONFIG_USB_OVERRIDE_IFACE_USBTMC usbDeviceInterface = eNFM_IfaceUSBTMC; #else #if CONFIG_USB_OVERRIDE_IFACE_VENDOR usbDeviceInterface = eNFM_IfaceUSBVendor; #else if( ! NFMClass->methods.usbInterface.getInterface( &usbDeviceInterface ) ) { usbDeviceInterface = eNFM_IfaceUSBVendor; } #endif #endif #else #if CONFIG_USB_OVERRIDE_IFACE_USBTMC usbDeviceInterface = eNFM_IfaceUSBTMC; #else usbDeviceInterface = eNFM_IfaceUSBVendor; #endif #endif USB_Device_Init( (eUSBDeviceInterface_t)usbDeviceInterface ); } #endif #if CONFIG_USB_DYNAMIC_CLOCK_ADOPT && CONFIG_USB static void SysConfig_USBDisconnected() { USB_Device_DeInit(); #if CONFIG_EXTMEM #if CONFIG_AUTOMAT_MODE == 0 /* Deinitialize the external memory */ ExtMemHandle.DeInit( true ); #else // later... #endif #endif __DI__ // need to disable interrupts to setup SystemTick correctly SystemClock_Config_Low(); #if CONFIG_SYSTICK == CONFIG_SYSTICK_NORMAL #if CONFIG_SYSTICK_BOOST_MULTIPLIER HAL_SYSTICK_Config( SystemCoreClock / 1000 / (CONFIG_SYSTICK_BOOST_MULTIPLIER) ); // CONFIG_SYSTICK_BOOST_MULTIPLIER times per 1ms HAL_NVIC_SetPriority( SysTick_IRQn, TICK_INT_PRIORITY, 0 ); #else HAL_SYSTICK_Config( SystemCoreClock / 1000 ); // 1 times per 1ms HAL_NVIC_SetPriority( SysTick_IRQn, TICK_INT_PRIORITY, 0 ); #endif #else HAL_SYSTICK_Config( SystemCoreClock / 1000 ); // 1 times per 1ms HAL_NVIC_SetPriority( SysTick_IRQn, TICK_INT_PRIORITY, 0 ); #endif __EI__ } #endif #if CONFIG_USBIRQ_TEST void USBIRQ_Test() { #warning Тест ошибки чтения памяти через USB при длительном запрещении прерываний USB HAL_NVIC_DisableIRQ( USB_LP_IRQn ); for( size_t i = 0; i < 1024; ++i ) __NOP(); HAL_NVIC_EnableIRQ( USB_LP_IRQn ); } #endif //#if CONFIG_HARMUP_INTERVAL > 0 //void harmup_init() //{ // g_bHarmUpEnable = true; // g_nHarmUpTimestamp = HAL_GetTick(); // // LEDHandle.SetHarmupStatus( !g_bHarmUpEnable ); //} // //void harmup_serve() //{ // if( g_bHarmUpEnable ) // { // if( (HAL_GetTick() - g_nHarmUpTimestamp)/1000 > (CONFIG_HARMUP_INTERVAL) ) // { // g_bHarmUpEnable = false; // // LEDHandle.SetHarmupStatus( !g_bHarmUpEnable ); // } // } //} //#endif #if CONFIG_REBOOT_FEATURE void RebootRequest() { __DI__ g_RebootRequest = true; // set global flag __EI__ } #endif #if CONFIG_NOIRQ_SNPRINTF // @_snprintf // Limits the depth of stack usage during @snprintf by // disabling interrupts. int _snprintf( char * buffer, size_t szBuffer, const char * format, ... ) { int rc; __DI__ va_list args; va_start (args, format); rc = vsnprintf(buffer, szBuffer, format, args); va_end (args); __EI__ return rc; } #endif int main(void) { // Validate the CSTACK protection area size my_assert( sizeof(cstacktail) == (size_t)(&size_cstack_protect) ); /* MCU Configuration--------------------------------------------------------*/ #if CONFIG_USB && CONFIG_AUTOMAT_MODE && CONFIG_AUTOMAT_MODE_USB_POWERBANK bool bEnumerateAwaiting = false; bool bUsbPowerBankConnected = false; #endif // Enable MemFault, BusFault and UsgFault handlers SCB->SHCSR |= SCB_SHCSR_USGFAULTENA; SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA; SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA; #if CONFIG_EXTREME_LOWPOWTEST main_extreme_low_power(); #endif /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); // Initialize GPIO // Need init before SysClock and USB to determine the clock freq MX_GPIO_Init(); #if CONFIG_ADC ADC1Handle.Init(eADCRes_12bit); #endif #if CONFIG_PM // Initialization and set of all pins except FPGA power control pin. It will be set separately after all init routine. PMHandle.Init(); HAL_Wait_100us(500); // Задержка 0.5 с #endif #if CONFIG_TABLE TableHandle.Init(); #endif #if CONFIG_PM PMHandle.INPTRG_EN(false); #endif #if CONFIG_LEDS LEDHandle.Init(); setLedColor(eLed_color_grn); #endif //DebugPins_Init(); #if CONFIG_SLEEPMANAGER // Initialize Sleep/Wakeup manager // Need init before SysClock and USB to determine the clock freq SleepManagerHandle.Init(); #endif // Initialize system clock #if CONFIG_USB_DYNAMIC_CLOCK_ADOPT && CONFIG_USB // First USB presense detecting... #if CONFIG_SLEEPMANAGER xUSBPlugged = SleepManagerHandle.GetUSBPlugged(); #else xUSBPlugged = true; #endif __DI__ // need to disable interrupts to setup SystemTick correctly if( xUSBPlugged ) SystemClock_Config(); else SystemClock_Config_Low(); #if CONFIG_SYSTICK == CONFIG_SYSTICK_NORMAL #if CONFIG_SYSTICK_BOOST_MULTIPLIER HAL_SYSTICK_Config( SystemCoreClock / 1000 / (CONFIG_SYSTICK_BOOST_MULTIPLIER) ); // CONFIG_SYSTICK_BOOST_MULTIPLIER times per 1ms HAL_NVIC_SetPriority( SysTick_IRQn, TICK_INT_PRIORITY, 0 ); #endif #endif __EI__ #else __DI__ // need to disable interrupts to setup SystemTick correctly /* Configure the system clock */ #if (CONFIG_SYSCLOCK == CONFIG_SYSCLOCK_NORMAL) || (CONFIG_SYSCLOCK == CONFIG_SYSCLOCK_HIGH) SystemClock_Config(); #endif #if CONFIG_SYSCLOCK == CONFIG_SYSCLOCK_LOW #if CONFIG_USB #warning Invalid clock while USB is used! #endif SystemClock_Config_Low(); #endif //----------------------- #if CONFIG_USB // xUSBPlugged = true; // #endif // //----------------------- #if CONFIG_SYSTICK == CONFIG_SYSTICK_NORMAL #if CONFIG_SYSTICK_BOOST_MULTIPLIER HAL_SYSTICK_Config( SystemCoreClock / 1000 / (CONFIG_SYSTICK_BOOST_MULTIPLIER) ); // CONFIG_SYSTICK_BOOST_MULTIPLIER times per 1ms HAL_NVIC_SetPriority( SysTick_IRQn, TICK_INT_PRIORITY, 0 ); #endif #endif __EI__ #endif // Configure the system tick #if CONFIG_SYSTICK == CONFIG_SYSTICK_NORMAL #endif #if CONFIG_EXTMEM /* Initialize External Non-Volatile memory */ ExtMemHandle.Init(); #endif #if CONFIG_NFMBASECLASS nfmbase_init(); #endif #if CONFIG_NFMBASECLASS && CONFIG_KEYSW #error The modes "CONFIG_NFMBASECLASS" and "CONFIG_KEYSW" are incompatible #endif #if CONFIG_SYSTICK == CONFIG_SYSTICK_LOW // power consumption debug HAL_SYSTICK_Config( 5000000 ); HAL_NVIC_SetPriority( SysTick_IRQn, TICK_INT_PRIORITY, 0 ); #endif #if CONFIG_USB_OVERRIDE_IFACE_USBTMC && CONFIG_USB_OVERRIDE_IFACE_VENDOR #error Invalid configuration: choose only one overriding interface. #endif #if !CONFIG_USB_USBTMC_ENABLE && CONFIG_USB_OVERRIDE_IFACE_USBTMC #error Invalid configuration: USBTMC is disabled and can not be overriding interface. #endif #if CONFIG_USB // Install USB Hook #if CONFIG_SLEEPMANAGER SleepManagerHandle.SetUSBWakeup( true ); #endif #if CONFIG_USB_DYNAMIC_CLOCK_ADOPT if( xUSBPlugged ) { #if CONFIG_NFMBASECLASS #if CONFIG_USB_OVERRIDE_IFACE_USBTMC usbDeviceInterface = eNFM_IfaceUSBTMC; #else #if CONFIG_USB_OVERRIDE_IFACE_VENDOR usbDeviceInterface = eNFM_IfaceVendor; #else if( ! NFMClass->methods.usbInterface.getInterface( &usbDeviceInterface ) ) { usbDeviceInterface = eNFM_IfaceUSBVendor; } #endif #endif #else #if CONFIG_USB_OVERRIDE_IFACE_USBTMC usbDeviceInterface = eNFM_IfaceUSBTMC; #else usbDeviceInterface = eNFM_IfaceUSBVendor; #endif #endif // Initialize USB USB_Device_Init( (eUSBDeviceInterface_t)usbDeviceInterface ); } #else #if CONFIG_NFMBASECLASS #if CONFIG_USB_OVERRIDE_IFACE_USBTMC usbDeviceInterface = eNFM_IfaceUSBTMC; NFMClass->methods.usbInterface.setInterface( usbDeviceInterface ); #else #if CONFIG_USB_OVERRIDE_IFACE_VENDOR usbDeviceInterface = eNFM_IfaceUSBVendor; NFMClass->methods.usbInterface.setInterface( usbDeviceInterface ); #else if( ! NFMClass->methods.usbInterface.getInterface( &usbDeviceInterface ) ) { usbDeviceInterface = eNFM_IfaceUSBVendor; } #endif #endif #else #if CONFIG_USB_OVERRIDE_IFACE_USBTMC usbDeviceInterface = eNFM_IfaceUSBTMC; #else usbDeviceInterface = eNFM_IfaceUSBVendor; #endif #endif // Initialize USB once and forever USB_Device_Init( (eUSBDeviceInterface_t)usbDeviceInterface ); #endif #endif #if CONFIG_AUTOMAT_MODE #if CONFIG_USB_DYNAMIC_CLOCK_ADOPT && CONFIG_USB if( !xUSBPlugged ) { #endif #if CONFIG_SYSTICK_BOOST_MULTIPLIER xAutomatActive = NFMAutomatHandle.Init( CONFIG_SYSTICK_BOOST_MULTIPLIER ); #else xAutomatActive = NFMAutomatHandle.Init( 1 ); #endif #if CONFIG_LEDS LEDHandle.SetAutomatAlarm( !xAutomatActive ); #endif #if CONFIG_USB_DYNAMIC_CLOCK_ADOPT && CONFIG_USB } #endif #endif #if CONFIG_AUTOMAT_MODE && CONFIG_AUTOMAT_MODE_USB_POWERBANK if( xUSBPlugged ) { #warning Feature: Запрошена функция работы от USB-Power-Bank, т.е. питание на разъем USB подано, и событие Plugged сработало, но требуется работать в режиме Automat если нет энумерации в течение некоторого времени. bEnumerateAwaiting = true; // mode: awaiting for enumerating UsbApplicationEnumSpyHandle.startEnumerateTimeout(); } #endif #if CONFIG_LEDS LEDHandle.SetUSBConnectivity( xUSBPlugged ); #endif #if CONFIG_NFMBASECLASS && CONFIG_NFMBASECLASS_TEST nfmbase_test(); #endif #if CONFIG_SCPI_TEST extern void scpi_parser_test(); extern void scpi_command_test(); //scpi_parser_test(); scpi_command_test(); #endif #if CONFIG_HARMUP_INTERVAL > 0 // initialize HarmUp procedure LEDHandle.harmup_init(); #else LEDHandle.SetHarmupStatus( true ); #endif #if CONFIG_REBOOT_FEATURE uint32_t l_RebootRequestStamp = 0; bool l_RebootRequest = false; #endif HAL_GPIO_WritePin( GPIOA, GPIO_PIN_3, GPIO_PIN_SET); //POWER ON FPGA BOARD while (1) { #if CONFIG_USB #if CONFIG_EXTMEM // serve USB application if( xUSBPlugged ) { usb_application_flash_serve(); } #endif #endif #if CONFIG_ADC && CONFIG_PM //PMHandle.PM_Serve(); #endif #if CONFIG_SLEEPMANAGER && CONFIG_SLEEPMANAGER_EXTRASLEEP SleepManagerHandle.Sleep(); #endif #if CONFIG_USB_DYNAMIC_CLOCK_ADOPT && CONFIG_USB #if CONFIG_SLEEPMANAGER SleepManagerHandle.Sleep(); #endif #if CONFIG_USBIRQ_TEST USBIRQ_Test(); #endif #if CONFIG_HARMUP_INTERVAL > 0 // serve for HarmUp procedure LEDHandle.harmup_serve(); #endif { #if CONFIG_SLEEPMANAGER bool temp__xUSBPlugged = SleepManagerHandle.GetUSBPlugged(); xUSBActive = SleepManagerHandle.GetUSBActive(); #else bool temp__xUSBPlugged = true; xUSBActive = true; #endif #if CONFIG_AUTOMAT_MODE && CONFIG_AUTOMAT_MODE_USB_POWERBANK if( !temp__xUSBPlugged && bUsbPowerBankConnected ) { // When USB-unplug event detected -> reset @bUsbPowerBankConnected bUsbPowerBankConnected = false; } if( bEnumerateAwaiting && temp__xUSBPlugged ) { // USB is plugged and the device waits for enumeration if( UsbApplicationEnumSpyHandle.checkEnumerateTimeout() ) { bEnumerateAwaiting = false; // The host had not enumerate the device for a long time bUsbPowerBankConnected = true; } } #endif #if CONFIG_AUTOMAT_MODE && CONFIG_AUTOMAT_MODE_USB_POWERBANK // Emulate USB unplugged when USB-Power-Bank mode is active if( bUsbPowerBankConnected ) { // Emulate USB unplugged temp__xUSBPlugged = false; } #endif #if CONFIG_REBOOT_FEATURE { __DI__ if( g_RebootRequest ) { l_RebootRequest = true; // set local flag #if CONFIG_REBOOT_FEATURE l_RebootRequestStamp = HAL_GetTick(); #endif g_RebootRequest = false; // reset global flag } __EI__ if( l_RebootRequest ) { #if CONFIG_REBOOT_FEATURE if( HAL_GetTick() - l_RebootRequestStamp > CONFIG_REBOOT_FEATURE_DELAY ) { #endif if( xUSBPlugged && xUSBActive ) { temp__xUSBPlugged = false; // force reset PLUG indicator } #if CONFIG_REBOOT_FEATURE } #endif } } #endif if( xUSBPlugged != temp__xUSBPlugged ) { if( temp__xUSBPlugged ) { #if CONFIG_AUTOMAT_MODE NFMAutomatHandle.DeInit(); xAutomatActive = false; #endif #if CONFIG_LEDS LEDHandle.SetAutomatAlarm( false ); #endif SysConfig_USBConnected(); #if CONFIG_USB && CONFIG_AUTOMAT_MODE && CONFIG_AUTOMAT_MODE_USB_POWERBANK #warning Feature: Запрошена функция работы от USB-Power-Bank, т.е. питание на разъем USB подано, и событие Plugged сработало, но требуется работать в режиме Automat если нет энумерации в течение некоторого времени. bEnumerateAwaiting = true; // mode: awaiting for enumerating UsbApplicationEnumSpyHandle.startEnumerateTimeout(); #endif } else { SysConfig_USBDisconnected(); #if CONFIG_AUTOMAT_MODE && CONFIG_AUTOMAT_MODE_USB_POWERBANK UsbApplicationEnumSpyHandle.stopEnumerateTimeout(); bEnumerateAwaiting = false; #endif #if CONFIG_AUTOMAT_MODE #if CONFIG_SYSTICK_BOOST_MULTIPLIER xAutomatActive = NFMAutomatHandle.Init( CONFIG_SYSTICK_BOOST_MULTIPLIER ); #else xAutomatActive = NFMAutomatHandle.Init( 1 ); #endif #if CONFIG_LEDS LEDHandle.SetAutomatAlarm( !xAutomatActive ); #endif #endif #if CONFIG_EXTMEM #if CONFIG_AUTOMAT_MODE /* Deinitialize the external memory */ ExtMemHandle.DeInit( true ); #endif #endif } #if CONFIG_SYSTICK == CONFIG_SYSTICK_LOW // power consumption debug HAL_SYSTICK_Config( 5000000 ); HAL_NVIC_SetPriority( SysTick_IRQn, TICK_INT_PRIORITY, 0 ); #endif xUSBPlugged = temp__xUSBPlugged; #if CONFIG_LEDS LEDHandle.SetUSBConnectivity( xUSBPlugged ); #endif } #if CONFIG_REBOOT_FEATURE if( l_RebootRequest ) { #if CONFIG_REBOOT_FEATURE if( HAL_GetTick() - l_RebootRequestStamp > CONFIG_REBOOT_FEATURE_DELAY ) { #endif __DI__ #if CONFIG_EXTMEM /* Deinitialize External Non-Volatile memory */ ExtMemHandle.DeInit( true ); #endif // Deinitialize USB USB_Device_DeInit(); HAL_NVIC_SystemReset(); __EI__ while(1); #if CONFIG_REBOOT_FEATURE } #endif } #endif } #else #if CONFIG_SLEEPMANAGER xUSBPlugged = SleepManagerHandle.GetUSBPlugged(); xUSBActive = SleepManagerHandle.GetUSBActive(); SleepManagerHandle.Sleep(); #else // ACM2543: USB is always connected /*xUSBPlugged = false;*/ /*xUSBActive = false;*/ #endif #if CONFIG_HARMUP_INTERVAL > 0 // serve for HarmUp procedure LEDHandle.harmup_serve(); #endif #if CONFIG_REBOOT_FEATURE { __DI__ if( g_RebootRequest ) { l_RebootRequest = true; // set local flag #if CONFIG_REBOOT_FEATURE l_RebootRequestStamp = HAL_GetTick(); #endif g_RebootRequest = false; // reset global flag } __EI__ if( l_RebootRequest ) { #if CONFIG_REBOOT_FEATURE if( HAL_GetTick() - l_RebootRequestStamp > CONFIG_REBOOT_FEATURE_DELAY ) { #endif __DI__ #if CONFIG_EXTMEM /* Deinitialize External Non-Volatile memory */ ExtMemHandle.DeInit( true ); #endif // Deinitialize USB USB_Device_DeInit(); HAL_NVIC_SystemReset(); __EI__ while(1); #if CONFIG_REBOOT_FEATURE } #endif } } #endif #endif #if CONFIG_AUTOMAT_MODE if( !xUSBPlugged ) { #if CONFIG_TSENSOR int8_t automat_temperature = THERMO_SENSOR_AVGTEMP_TO_INT( ThermoSensor.GetTempAVG() ); #else int8_t automat_temperature = THERMO_SENSOR_AVGTEMP_TO_INT( THERMO_SENSOR_INVALID_TEMP_VALUE ); #endif NFMAutomatHandle.TemperatureUpdate( automat_temperature, ThermoSensor.GetReady() ); } #endif } } /** * @brief System Clock Configuration * @retval None */ #if (CONFIG_SYSCLOCK == CONFIG_SYSCLOCK_NORMAL) || (CONFIG_SYSCLOCK == CONFIG_SYSCLOCK_HIGH) || CONFIG_USB_DYNAMIC_CLOCK_ADOPT void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /**Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /**Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; #if CONFIG_CRYSTAL == CONFIG_CRYSTAL_12MHZ RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8; #elif CONFIG_CRYSTAL == CONFIG_CRYSTAL_16MHZ RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6; #elif CONFIG_CRYSTAL == CONFIG_CRYSTAL_8MHZ RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12; #elif CONFIG_CRYSTAL == CONFIG_CRYSTAL_4MHZ RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL24; #else #error Invalid Crystal Ocsillator Frequency specified #endif RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3; 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; #if CONFIG_SYSCLOCK == CONFIG_SYSCLOCK_HIGH RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // two times greater than RCC_SYSCLKSOURCE_HSE (see PLL settings) #else RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE; #endif RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // System Clock Divider RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; #if (PREFETCH_ENABLE == 0) __HAL_FLASH_PREFETCH_BUFFER_DISABLE(); #endif /* PREFETCH_ENABLE */ #if CONFIG_FLASH_64BIT_MANAGE // NOTE: Enabling 64-bit access must be performed before // changing the FLASH LATENCY and changing the CPU clock // Refer: RM0038, STM32L151CB User Manual, ch. 3.3.1. DocID15965 __HAL_FLASH_ACC64_ENABLE(); // enable 64-bit flash access to enhance performance #endif #if CONFIG_SYSCLOCK == CONFIG_SYSCLOCK_HIGH // On High frequency it is required to add one cycle to flash access latency. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { Error_Handler(); } #else if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } #endif #if (PREFETCH_ENABLE != 0) __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); #endif /* PREFETCH_ENABLE */ //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_NOCLOCK, RCC_MCODIV_1); /* { // Configure GPIO pin for MCO function GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = CONFIG_PIN__MCO; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = CONFIG_AF__MCO; HAL_GPIO_Init(CONFIG_PORT__MCO, &GPIO_InitStruct); } */ } #endif #if CONFIG_VBATMON bool SystemClock_HSI( bool state ) { bool bRet = false; { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = ((state)?RCC_HSI_ON:RCC_HSI_OFF); RCC_OscInitStruct.HSICalibrationValue = 0; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } else { bRet = true; } } return true; } #else bool SystemClock_HSI( bool state ){ (void)state; return false; } #endif #if (CONFIG_SYSCLOCK == CONFIG_SYSCLOCK_LOW) || CONFIG_USB_DYNAMIC_CLOCK_ADOPT || CONFIG_EXTREME_LOWPOWTEST void SystemClock_Config_Low(void) { { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; /**Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /**Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.MSICalibrationValue = 0; #if CONFIG_MSI_FREQ == CONFIG_MSI_FREQ_4MHZ RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6; #elif CONFIG_MSI_FREQ == CONFIG_MSI_FREQ_2MHZ RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5; #elif CONFIG_MSI_FREQ == CONFIG_MSI_FREQ_1MHZ RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4; #else #warning MSI Frequency set to the default RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5; // 2MHz #endif RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } } __HAL_FLASH_PREFETCH_BUFFER_DISABLE(); { RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /**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_MSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // System Clock Divider RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; //RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; //RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) //FLASH_LATENCY_1? { Error_Handler(); } } { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_OFF; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } } #if CONFIG_FLASH_64BIT_MANAGE // Disable 64-bit FLASH access, reduce power consumption // NOTE: Disable 64-bit access must be performed after // changing the FLASH LATENCY and changing the CPU clock // Refer: RM0038, STM32L151CB User Manual, ch. 3.3.1. DocID15965 __HAL_FLASH_ACC64_DISABLE(); // disable 64-bit flash access to enhance performance #endif //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_NOCLOCK, RCC_MCODIV_1); // { // DeConfigure GPIO pin (MCO function) // GPIO_InitTypeDef GPIO_InitStruct = {0}; // GPIO_InitStruct.Pin = CONFIG_PIN__MCO; // GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; // GPIO_InitStruct.Pull = GPIO_NOPULL; // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // HAL_GPIO_Init(CONFIG_PORT__MCO, &GPIO_InitStruct); // } } #endif /** * @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 */ } void HAL_Wait_us( size_t n ) { #warning need to debug. Sometimes the delay is wrong! especially for 1us HAL_Wait_1us( 10*n ); // need to debug. Sometimes the delay is wrong! especially for 1us } void HAL_Wait_10us( size_t n ) { HAL_Wait_1us( 10*n ); } void HAL_Wait_100us( size_t n ) { HAL_Wait_1us( 100*n ); } #pragma optimize=speed static void HAL_Wait_1us( size_t us ) { int cycles = (1 + (HAL_RCC_GetHCLKFreq() >> 20)); if( cycles <= 4 ) // up to 4MHZ clock { void sys_delayus_up4MHZ( int us, int cycles ); sys_delayus_up4MHZ( us, cycles ); } else if( cycles <= 8 ) // up to 8MHZ clock { void sys_delayus_up8MHZ( int us, int cycles ); sys_delayus_up8MHZ( us, cycles ); } else if( cycles <= 16 ) // up to 16MHZ clock { void sys_delayus_up16MHZ( int us, int cycles ); sys_delayus_up16MHZ( us, cycles ); } else { void sys_delayus_up96MHZ( int us, int cycles ); sys_delayus_up96MHZ( us, cycles ); } } #pragma optimize=none static void sys_delayus_up4MHZ( int us, int cycles ) { int m = cycles * us; for( int i = cycles + cycles; i < m; ++i ) asm("nop"); } #pragma optimize=none static void sys_delayus_up8MHZ( int us, int cycles ) // 4...8MHz { for( int i = (cycles*us)>>2; i > (us>>1); --i ); } #pragma optimize=none static void sys_delayus_up16MHZ( int us, int cycles ) // 8...16MHz { for( int i = (cycles*us)>>2; i > (us>>1); --i ); } #pragma optimize=none static void sys_delayus_up96MHZ( int us, int cycles ) { for( int i = (cycles*us)>>2; i > (us>>1); --i ); } #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 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) */ while(1) { HAL_NVIC_SystemReset(); } } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/