/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2023 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "app_touchgfx.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include #include "st7789v.h" #include "xpt2046.h" #include "FLASH_SECTOR_F4.h" #include #include "stm32f4xx_hal_adc_ex.h" #include "touchgfx/Screen.hpp" #include //#include /* 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 ---------------------------------------------------------*/ ADC_HandleTypeDef hadc1; CRC_HandleTypeDef hcrc; SPI_HandleTypeDef hspi1; SPI_HandleTypeDef hspi2; DMA_HandleTypeDef hdma_spi1_tx; TIM_HandleTypeDef htim1; TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim3; TIM_HandleTypeDef htim4; /* USER CODE BEGIN PV */ __IO uint8_t User_ButtonState = 0; __IO uint8_t ButnState = 0; SCREEN_Buf disp_buf; // flash static uint32_t flash_buf[128]; bool flash_flag = false; bool get_data_from_flash = false; static const double temp_ref[] = {334.274, 241.323, 176.133, 129.9, 96.761, 72.765, 55.218, 42.268, 32.624, 25.381, 19.897, 15.711, 12.493, 10, 8.056, 6.530, 5.324, 4.365, 3.599, 2.982, 2.484, 2.079, 1.748, 1.476, 1.252, 1.066, 0.9116, 0.7825, 0.6741, 0.5828, 0.5057, 0.4402, 0.3844, 0.3367}; //Sleep counter uint32_t SleepTickCnt = 0;//SLEEP_TIME; bool Sleep_status = false; // motor static MOTOR_Hash_Map motor_mode[MODE_MAX]; uint8_t motor_timeCnt = 0; uint8_t run_flag = false; static uint8_t node_num = 0; bool long_press = false; // buzzer uint8_t sound_flag = 0; uint16_t vol_timeline; uint16_t vol_timeCnt = 0; //uint32_t time_to_upd_flash = 0; extern bool finish; bool rebuildHome = false; bool rebuildSettings = false; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_DMA_Init(void); static void MX_CRC_Init(void); static void MX_SPI1_Init(void); static void MX_SPI2_Init(void); static void MX_TIM2_Init(void); static void MX_ADC1_Init(void); static void MX_TIM1_Init(void); static void MX_TIM3_Init(void); static void MX_TIM4_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ //Encoder uint16_t iCounter, preCounter = 0; uint8_t encoder_Event = 0; void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){ //Encoder if (htim->Instance != TIM3){ return; } int val; iCounter = __HAL_TIM_GET_COUNTER(htim); //SleepTickCnt = 0; if(Sleep_status){ Sleep_status = false; } else{ if(preCounter != iCounter){ val = preCounter - iCounter; if(val < 0){ val = 255; if (encoder_Event){ ButnState = 0x02; Sound_Set_Func(disp_buf.buz_status, disp_buf.buzzer_volume, VOLTIMELINE); encoder_Event = 0; } else encoder_Event = 1; } else{ val = 1; if (encoder_Event == 2){ ButnState = 0x03; Sound_Set_Func(disp_buf.buz_status, disp_buf.buzzer_volume, VOLTIMELINE); encoder_Event = 0; } else encoder_Event = 2; } preCounter = iCounter; } } } //BTN btn_status_t BTN_flag = BTN_RELASED; uint8_t btnCnt_en = 0; void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ switch(GPIO_Pin){ case BTN_Pin: //SleepTickCnt = 0; if(Sleep_status){ Sleep_status = false; } else btnCnt_en = 1; break; default: break; } } static void WDT_Init (uint16_t tw){ IWDG->KR=0x5555; IWDG->PR=7; IWDG->RLR=tw*40/256; IWDG->KR=0xAAAA; IWDG->KR=0xCCCC; } static void WDT_Rst (void){ IWDG->KR=0xAAAA; } /* 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 */ SysTick_Config(SystemCoreClock / 1000); /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_CRC_Init(); MX_SPI1_Init(); MX_SPI2_Init(); MX_TIM2_Init(); MX_ADC1_Init(); MX_TIM1_Init(); MX_TIM3_Init(); MX_TIM4_Init(); MX_TouchGFX_Init(); /* USER CODE BEGIN 2 */ HAL_ADC_Start(&hadc1); //HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY); Init_DISP_Para(); Init_Pattern(); TFT_Set_Func(disp_buf.screen_brightness); LED_Set_Func(disp_buf.led_status, disp_buf.light_brightness); Sound_Set_Func(disp_buf.buz_status, disp_buf.buzzer_volume, VOLTIMELINE); if (disp_buf.rpm > 10){ disp_buf.rpm = 5; } disp_buf.buzzer_volume = 1; //disp_buf.buz_status = true; #if 1 // 0 for motor test, 1 for normal work Motor_Set_Func(PAUSE, 0); #else while (1){ for (uint8_t i = 0; i < 100; i++){ Motor_Set_Func(CLOCKWISE, i); HAL_Delay(50); } for (uint8_t i = 100; i > 0; i--){ Motor_Set_Func(CLOCKWISE, i); HAL_Delay(50); } Motor_Set_Func(PAUSE, 0); HAL_Delay(2000); for (uint8_t i = 0; i < 100; i++){ Motor_Set_Func(COUNTERCLOCKWISE, i); HAL_Delay(50); } for (uint8_t i = 100; i > 0; i--){ Motor_Set_Func(COUNTERCLOCKWISE, i); HAL_Delay(50); } Motor_Set_Func(PAUSE, 0); HAL_Delay(2000); } #endif Sleep_status = false; ILI9341_Init(); XPT2046_Init(); HAL_TIM_Base_Start_IT(&htim2); HAL_TIM_Encoder_Start_IT(&htim3, TIM_CHANNEL_ALL); //User_ButtonState = 0x01; #if 0 // direct LCD backlight on static GPIO_InitTypeDef GPIO_InitStruct = {0}; HAL_GPIO_DeInit(GPIOE, GPIO_PIN_9); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_SET); GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); #endif //TFT_Set_Func(100); //while(1){} /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ //finish = true; BTN_flag = BTN_PRESS; WDT_Init(10000); while (1) { WDT_Rst(); if(ButnState != 0){ if (SleepTickCnt != 0){ SleepTickCnt = SLEEP_TIME; User_ButtonState = ButnState; } ButnState = 0; } if (finish == false){ if(BTN_flag == BTN_PRESS){ BTN_flag = BTN_RELASED; if (SleepTickCnt != 0){ User_ButtonState = 0x01; } else { rebuildHome = true; rebuildSettings = true; } SleepTickCnt = SLEEP_TIME; long_press = false; if(disp_buf.motor_status == MOTOR_RUN){ //ILI9341_Init(); rebuildHome = true; } } } if (SleepTickCnt != 0){ if (finish == true){ //ILI9341_Init(); rebuildHome = true; User_ButtonState = 0x01; //BTN_flag = BTN_RELASED; } MX_TouchGFX_Process(); } else { if (finish == true){ //ILI9341_Init(); rebuildHome = true; User_ButtonState = 0x01; //BTN_flag = BTN_RELASED; MX_TouchGFX_Process(); } else { TFT_full(0); } } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ #if 0 if (disp_buf.motor_status != MOTOR_RUN) { long_press = false; } if(BTN_flag == BTN_LONG_PRESS){ BTN_flag = BTN_RELASED; User_ButtonState = 0x04; long_press = true; Sound_Set_Func(disp_buf.buz_status, disp_buf.buzzer_volume, VOLTIMELINE); } #endif Temp_Correction_Func(); if(sound_flag == 2){ sound_flag = 0; Sound_Set_Func(disp_buf.buz_status, 0, 0); } #if 0 if(disp_buf.motor_status){ if(!run_flag){ motor_timeCnt = 0; run_flag = 1; } else{ RunMotorCycle(disp_buf.pattern, disp_buf.rpm); } } //#else if(disp_buf.motor_status == MOTOR_RUN){ if(!run_flag){ motor_timeCnt = 0; run_flag = 1; } else{ RunMotorCycle(disp_buf.pattern, disp_buf.rpm); } } else if (disp_buf.motor_status == MOTOR_PAUSE) { run_flag = false; Motor_Set_Func(PAUSE, 0); } else { Motor_Set_Func(PAUSE, 0); motor_timeCnt = 0; run_flag = false; //Init_DISP_Para(); } #endif SleepMode_Func(disp_buf.screen_timeout, disp_buf.screen_brightness); if((flash_flag == true) && (disp_buf.motor_status != MOTOR_RUN)){ flash_flag = false; FLASH_Update(); } if (get_data_from_flash == true){ get_data_from_flash = false; Init_DISP_Para(); } if(disp_buf.disp_runtime_min == 0){ static uint16_t sound_ran_time = 0xffff; if ((disp_buf.disp_runtime_sec == 3) || (disp_buf.disp_runtime_sec == 2) || (disp_buf.disp_runtime_sec == 1)){ if (sound_ran_time != disp_buf.disp_runtime_sec){ Sound_Set_Func(disp_buf.buz_status, disp_buf.buzzer_volume, 250); sound_ran_time = disp_buf.disp_runtime_sec; } } } } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {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_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 4; RCC_OscInitStruct.PLL.PLLN = 100; 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_3) != HAL_OK) { Error_Handler(); } } /** * @brief ADC1 Initialization Function * @param None * @retval None */ static void MX_ADC1_Init(void) { /* USER CODE BEGIN ADC1_Init 0 */ /* USER CODE END ADC1_Init 0 */ ADC_ChannelConfTypeDef sConfig = {0}; /* USER CODE BEGIN ADC1_Init 1 */ /* USER CODE END ADC1_Init 1 */ /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */ hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = DISABLE; hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_11; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN ADC1_Init 2 */ /* USER CODE END ADC1_Init 2 */ } /** * @brief CRC Initialization Function * @param None * @retval None */ static void MX_CRC_Init(void) { /* USER CODE BEGIN CRC_Init 0 */ /* USER CODE END CRC_Init 0 */ /* USER CODE BEGIN CRC_Init 1 */ /* USER CODE END CRC_Init 1 */ hcrc.Instance = CRC; if (HAL_CRC_Init(&hcrc) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN CRC_Init 2 */ /* USER CODE END CRC_Init 2 */ } /** * @brief SPI1 Initialization Function * @param None * @retval None */ static void MX_SPI1_Init(void) { /* USER CODE BEGIN SPI1_Init 0 */ /* USER CODE END SPI1_Init 0 */ /* USER CODE BEGIN SPI1_Init 1 */ /* USER CODE END SPI1_Init 1 */ /* SPI1 parameter configuration*/ hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN SPI1_Init 2 */ /* USER CODE END SPI1_Init 2 */ } /** * @brief SPI2 Initialization Function * @param None * @retval None */ static void MX_SPI2_Init(void) { /* USER CODE BEGIN SPI2_Init 0 */ /* USER CODE END SPI2_Init 0 */ /* USER CODE BEGIN SPI2_Init 1 */ /* USER CODE END SPI2_Init 1 */ /* SPI2 parameter configuration*/ hspi2.Instance = SPI2; hspi2.Init.Mode = SPI_MODE_MASTER; hspi2.Init.Direction = SPI_DIRECTION_2LINES; hspi2.Init.DataSize = SPI_DATASIZE_8BIT; hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi2.Init.TIMode = SPI_TIMODE_DISABLE; hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi2.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN SPI2_Init 2 */ /* USER CODE END SPI2_Init 2 */ } /** * @brief TIM1 Initialization Function * @param None * @retval None */ static void MX_TIM1_Init(void) { /* USER CODE BEGIN TIM1_Init 0 */ /* USER CODE END TIM1_Init 0 */ TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; /* USER CODE BEGIN TIM1_Init 1 */ /* USER CODE END TIM1_Init 1 */ htim1.Instance = TIM1; htim1.Init.Prescaler = 250-1; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 100-1; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { Error_Handler(); } sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; sBreakDeadTimeConfig.DeadTime = 0; sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM1_Init 2 */ /* USER CODE END TIM1_Init 2 */ HAL_TIM_MspPostInit(&htim1); } /** * @brief TIM2 Initialization Function * @param None * @retval None */ static void MX_TIM2_Init(void) { /* USER CODE BEGIN TIM2_Init 0 */ /* USER CODE END TIM2_Init 0 */ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM2_Init 1 */ /* USER CODE END TIM2_Init 1 */ htim2.Instance = TIM2; htim2.Init.Prescaler = 25000-1; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 100-1; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM2_Init 2 */ /* USER CODE END TIM2_Init 2 */ } /** * @brief TIM3 Initialization Function * @param None * @retval None */ static void MX_TIM3_Init(void) { /* USER CODE BEGIN TIM3_Init 0 */ /* USER CODE END TIM3_Init 0 */ TIM_Encoder_InitTypeDef sConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM3_Init 1 */ /* USER CODE END TIM3_Init 1 */ htim3.Instance = TIM3; htim3.Init.Prescaler = 0; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 65535; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; sConfig.EncoderMode = TIM_ENCODERMODE_TI12; sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC1Prescaler = TIM_ICPSC_DIV1; sConfig.IC1Filter = 15; sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC2Prescaler = TIM_ICPSC_DIV1; sConfig.IC2Filter = 15; if (HAL_TIM_Encoder_Init(&htim3, &sConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM3_Init 2 */ /* USER CODE END TIM3_Init 2 */ } /** * @brief TIM4 Initialization Function * @param None * @retval None */ static void MX_TIM4_Init(void) { /* USER CODE BEGIN TIM4_Init 0 */ /* USER CODE BEGIN TIM4_Init 0 */ /* USER CODE END TIM4_Init 0 */ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; /* USER CODE BEGIN TIM4_Init 1 */ /* USER CODE END TIM4_Init 1 */ htim4.Instance = TIM4; htim4.Init.Prescaler = 125-1; htim4.Init.CounterMode = TIM_COUNTERMODE_UP; htim4.Init.Period = 100-1; htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim4) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_Init(&htim4) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM4_Init 2 */ HAL_TIM_Base_MspInit(&htim4); /* USER CODE END TIM4_Init 2 */ HAL_TIM_MspPostInit(&htim4); return; /* USER CODE END TIM4_Init 0 */ //TIM_ClockConfigTypeDef sClockSourceConfig = {0}; //TIM_MasterConfigTypeDef sMasterConfig = {0}; //TIM_OC_InitTypeDef sConfigOC = {0}; /* USER CODE BEGIN TIM4_Init 1 */ /* USER CODE END TIM4_Init 1 */ htim4.Instance = TIM4; htim4.Init.Prescaler = 125-1; htim4.Init.CounterMode = TIM_COUNTERMODE_UP; htim4.Init.Period = 100-1; htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_PWM_Init(&htim4) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM4_Init 2 */ /* USER CODE END TIM4_Init 2 */ HAL_TIM_MspPostInit(&htim4); } /** * Enable DMA controller clock */ static void MX_DMA_Init(void) { /* DMA controller clock enable */ __HAL_RCC_DMA2_CLK_ENABLE(); /* DMA interrupt init */ /* DMA2_Stream3_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA2_Stream3_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_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOA, DC_Pin|RESET_Pin|SPI1_NSS_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(T_CS_GPIO_Port, T_CS_Pin, GPIO_PIN_RESET); /*Configure GPIO pins : DC_Pin RESET_Pin SPI1_NSS_Pin */ GPIO_InitStruct.Pin = DC_Pin|RESET_Pin|SPI1_NSS_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pin : T_CS_Pin */ GPIO_InitStruct.Pin = T_CS_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(T_CS_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : T_IRQ_Pin */ GPIO_InitStruct.Pin = T_IRQ_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(T_IRQ_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : BTN_Pin */ GPIO_InitStruct.Pin = BTN_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(BTN_GPIO_Port, &GPIO_InitStruct); /* EXTI interrupt init*/ HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); } /* USER CODE BEGIN 4 */ void FLASH_Update(void){ flash_buf[FLASH_STATUS] = 1; flash_buf[LED_STATUS] = disp_buf.led_status; flash_buf[BUZ_STATUS] = disp_buf.buz_status; flash_buf[RUN_MIN] = disp_buf.runtime_min; flash_buf[RUN_SEC] = disp_buf.runtime_sec; flash_buf[TEMP_UNIT] = disp_buf.uint_type; flash_buf[RPM_VAL] = disp_buf.rpm; flash_buf[MODE_NUM] = disp_buf.pattern; flash_buf[LIGHT_BRIGHT] = disp_buf.light_brightness; flash_buf[SCREEN_BRIGHT] = disp_buf.screen_brightness; flash_buf[SLEEP_STATUS] = disp_buf.screen_timeout; flash_buf[BUZ_VOLUME] = disp_buf.buzzer_volume; Flash_Write_Data(0x080E0000, flash_buf, 12); } #ifdef __cplusplus extern "C" { #endif extern void touchgfxSignalVSync(void); #ifdef __cplusplus } #endif void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim->Instance == TIM2){ touchgfxSignalVSync(); } } // initialize the screen parameters uint32_t flash_rx[128]; void Init_DISP_Para(void){ Flash_Read_Data(0x080E0000, flash_buf, 12); if(flash_buf[FLASH_STATUS] == 1){ disp_buf.led_status = flash_buf[LED_STATUS]; disp_buf.buz_status = flash_buf[BUZ_STATUS]; disp_buf.runtime_min = flash_buf[RUN_MIN]; disp_buf.runtime_sec = flash_buf[RUN_SEC]; disp_buf.uint_type = flash_buf[TEMP_UNIT]; disp_buf.rpm = flash_buf[RPM_VAL]; disp_buf.pattern = flash_buf[MODE_NUM]; disp_buf.light_brightness = flash_buf[LIGHT_BRIGHT]; disp_buf.screen_brightness = flash_buf[SCREEN_BRIGHT]; disp_buf.screen_timeout = flash_buf[SLEEP_STATUS]; disp_buf.buzzer_volume = flash_buf[BUZ_VOLUME]; } else{ disp_buf.led_status = ON; disp_buf.buz_status = ON; disp_buf.runtime_min = 15; disp_buf.runtime_sec = 0; disp_buf.uint_type = 'C'; disp_buf.rpm = RPM_MAX; disp_buf.pattern = 0; disp_buf.light_brightness = 5;//LED_BRIGHTNESS_MAX; disp_buf.screen_brightness = DISP_BRIGHTNESS_MAX; disp_buf.screen_timeout = OFF; disp_buf.buzzer_volume = 1; //VOLUME_MAX; } disp_buf.disp_status = HOME; disp_buf.motor_status = MOTOR_STOP; disp_buf.disp_runtime_min = disp_buf.runtime_min; disp_buf.disp_runtime_sec = disp_buf.runtime_sec; disp_buf.temp_val = 0; if (disp_buf.rpm == 0){ disp_buf.rpm = 1; } } void Init_Pattern(){ // Default ----- motor_mode[0].node_len = 4; // Pattern length motor_mode[0].node[0].timeline = 1; motor_mode[0].node[0].dir = CLOCKWISE; motor_mode[0].node[1].timeline = PAUSE_TIME_S; motor_mode[0].node[1].dir = PAUSE; motor_mode[0].node[2].timeline = 1; motor_mode[0].node[2].dir = COUNTERCLOCKWISE; motor_mode[0].node[3].timeline = PAUSE_TIME_S; motor_mode[0].node[3].dir = PAUSE; // Mode 1 ----- motor_mode[1].node_len = 4; // Pattern length motor_mode[1].node[0].timeline = 3; motor_mode[1].node[0].dir = CLOCKWISE; motor_mode[1].node[1].timeline = PAUSE_TIME_S; motor_mode[1].node[1].dir = PAUSE; motor_mode[1].node[2].timeline = 3; motor_mode[1].node[2].dir = COUNTERCLOCKWISE; motor_mode[1].node[3].timeline = PAUSE_TIME_S; motor_mode[1].node[3].dir = PAUSE; // Mode 2 ----- motor_mode[2].node_len = 4; // Pattern length motor_mode[2].node[0].timeline = 10; motor_mode[2].node[0].dir = CLOCKWISE; motor_mode[2].node[1].timeline = PAUSE_TIME_S; motor_mode[2].node[1].dir = PAUSE; motor_mode[2].node[2].timeline = 10; motor_mode[2].node[2].dir = COUNTERCLOCKWISE; motor_mode[2].node[3].timeline = PAUSE_TIME_S; motor_mode[2].node[3].dir = PAUSE; } // setting the MOTOR void Motor_Set_Func(uint8_t dir, uint16_t speed_val){ #if 0 float persent; if(speed_val <= 0 ) persent = 0; else{ if(speed_val > RPM_MAX) speed_val = RPM_MAX; persent = speed_val * 100 / RPM_MAX; } #else uint16_t persent = 60 + (4 * speed_val); if (persent > 100) { persent = 100; } #endif static uint8_t increase = 0; static uint16_t pwm_persent = 0; increase++; if (increase >= 5){ increase = 0; if ((dir == CLOCKWISE) || (dir == COUNTERCLOCKWISE)){ //if (SleepTickCnt != 0){ if (pwm_persent < persent){ pwm_persent++; } else { pwm_persent = persent; } // } else { // pwm_persent = persent; // } } } static bool pwm_start = false; switch(dir){ case CLOCKWISE: TIM4->CCR2 = 0; TIM4->CCR1 = pwm_persent;//(persent); if (pwm_start == false) { HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2); pwm_start = true; } break; case COUNTERCLOCKWISE: TIM4->CCR1 = 0; TIM4->CCR2 = pwm_persent;//(persent); if (pwm_start == false) { HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2); pwm_start = true; } break; default: TIM4->CCR1 = 0; TIM4->CCR2 = 0; pwm_persent = 0; if (pwm_start != false) { HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_1); HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_2); pwm_start = false; } break; } } // Motor driver void RunMotorCycle(uint8_t pattern, uint16_t speed){ if(node_num >= motor_mode[pattern].node_len){ run_flag = 0; node_num = 0; // disp_buf.motor_status = false; Motor_Set_Func(PAUSE, 0); return; } if(motor_timeCnt < motor_mode[pattern].node[node_num].timeline){ Motor_Set_Func(motor_mode[pattern].node[node_num].dir, speed); } else { motor_timeCnt = 0; //run_flag = 0; node_num+=1; //Motor_Set_Func(PAUSE, 0); } } // setting the brightness of TFT screen void TFT_Set_Func(uint8_t brightness){ // The range of the display: 30 ~ 100Hz. // float persent; static bool pwm_start = false; // if(brightness <= 0) persent = 0; // else{ // if(brightness > DISP_BRIGHTNESS_MAX) brightness = DISP_BRIGHTNESS_MAX; // persent = brightness * 70 / DISP_BRIGHTNESS_MAX + 30; // } TIM1->CCR1 = (uint16_t)brightness * 10; // 30 is minimum value of the display frequency if (pwm_start == false) { HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); pwm_start = true; } } void SleepMode_Func(bool sleep, uint8_t brightness){ if(sleep){ if(Sleep_status) brightness = 0; TFT_Set_Func(brightness); } } // LED Control Function void LED_Set_Func(bool status, uint8_t light_val){ //float persent; static bool pwm_run = false; if(status){ // if(light_val > LED_BRIGHTNESS_MAX) light_val = LED_BRIGHTNESS_MAX; // if(light_val <= 0) persent = 0; // else persent = light_val * 60 / LED_BRIGHTNESS_MAX + 40; TIM4->CCR3 = (uint16_t)light_val*10;//(100 - persent); if (pwm_run == false) { HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3); pwm_run = true; } } else{ TIM4->CCR3 = 0; if (pwm_run != false) { HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_3); pwm_run = false; } } } // Buzzer Control Function void Sound_Set_Func(bool status, uint8_t volume, uint16_t timeline){ volatile uint16_t persent; static bool pwm_run = false; if(status){ // If buzzer is enabled if(volume <= 0) persent = 0; else{ if(volume > VOLUME_MAX) volume = VOLUME_MAX; persent = (volume * 50) / VOLUME_MAX; } TIM1->CCR2 = persent >> 2; if (pwm_run == false) { HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); pwm_run = true; } if(persent == 0) sound_flag = 0; else{ sound_flag = 1; vol_timeline = timeline; } } else{ // If buzzer is disabled TIM1->CCR2 = 0; if (pwm_run != false) { HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2); pwm_run = false; } } } static const float _fir_coefficient[] = { -0.00284683, -0.00803552, -0.01439099, -0.01685624, -0.00823138, 0.01749503, 0.06086587, 0.11439408, 0.16388395, 0.19372203, 0.19372203, 0.16388395, 0.11439408, 0.06086587, 0.01749503, -0.00823138, -0.01685624, -0.01439099, -0.00803552, -0.00284683 }; #define _filter_depth (sizeof(_fir_coefficient) / sizeof(_fir_coefficient[0])) float samples[_filter_depth]; static float filter (float in_data, float *bufer_pnt, bool fill_buf) { if (fill_buf == true) { for (uint16_t i = 0; i < _filter_depth; i++) { bufer_pnt[i] = in_data; } } for (uint16_t i = 1; i < _filter_depth; i++) { bufer_pnt[i - 1] = bufer_pnt[i]; } bufer_pnt[_filter_depth - 1] = in_data; float samples_sum = 0; for (uint16_t i = 0; i < _filter_depth; i++) { samples_sum += (float) bufer_pnt[i] * _fir_coefficient[i]; } return samples_sum; } /** * @brief Calculate temperature of NTC * @param [in] analog ADC value * @param [in] baseDiv if connected like (GND -- Rt -- ADC -- R -- VCC) R/Rt * @param [in] B B param of termistor * @param [in] t t0 of termistor (25 deg C) * @param [in] res ADC resolution * @retval temperature in deg C */ float NTC_compute(float analog, float baseDiv, uint16_t B, uint8_t t, uint8_t res) { analog = baseDiv / ((float)((1 << res) - 1) / analog - 1.0f); analog = (log(analog) / B) + 1.0f / (t + 273.15f); return (1.0f / analog - 273.15f); } double LPOUT=0,LPACC=0; extern float test_trmp; bool update_temp = true; const int K = 500; void Temp_Correction_Func(void){ static bool first_filter_run = true; LPOUT=0,LPACC=0; int i = 0; if (update_temp == false) { return; } update_temp = false; // Get ADC value // HAL_ADC_Start(&hadc1); // HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY); //for(i = 0; i < K; i++){ LPACC = HAL_ADC_GetValue(&hadc1); //HAL_Delay(1); //} LPOUT = LPACC;// / K; #if 0 LPOUT = LPOUT * 5.1 / (4096.0 - LPOUT); if(temp_ref[0] + 0.2 <= LPOUT) disp_buf.temp_val = -40.0; else if(temp_ref[33] - 0.2 >= LPOUT) disp_buf.temp_val = 125.0; else{ for(i = 0; i < 34; i++){ if((temp_ref[i] + 0.2 >= LPOUT) && (temp_ref[i] - 0.2 <= LPOUT)){ disp_buf.temp_val = (i * 5) - 40; break; } else if(temp_ref[i] < LPOUT){ if(temp_ref[i-1] - 0.2 > LPOUT){ if(LPOUT <= temp_ref[i] + ((temp_ref[i-1]-temp_ref[i])/5)){ disp_buf.temp_val = (i * 5) - 40 - 1; } else if(LPOUT <= temp_ref[i] + (temp_ref[i-1]-temp_ref[i])*2/5){ disp_buf.temp_val = (i * 5) - 40 - 2; } else if(LPOUT <= temp_ref[i] + (temp_ref[i-1]-temp_ref[i])*3/5){ disp_buf.temp_val = (i * 5) - 40 - 3; } else disp_buf.temp_val = (i * 5) - 40 - 4; break; } } } } #elif 0 double output_voltage, thermistor_resistance, therm_res_ln; //float thermistor_adc_val = LPOUT; output_voltage = ( ((float)LPOUT * 3.3) / (4095.0)); thermistor_resistance = ( ( 3.3 * ( 10.0 / output_voltage ) ) - 10 ); /* Resistance in kilo ohms */ thermistor_resistance = thermistor_resistance * 1000 ; /* Resistance in ohms */ therm_res_ln = log(thermistor_resistance); /* Steinhart-Hart Thermistor Equation: */ /* Temperature in Kelvin = 1 / (A + B[ln(R)] + C[ln(R)]^3) */ /* where A = 0.001129148, B = 0.000234125 and C = 8.76741*10^-8 */ disp_buf.temp_val = ( 1 / ( 0.001129148 + ( 0.000234125 * therm_res_ln ) + ( 0.0000000876741 * therm_res_ln * therm_res_ln * therm_res_ln ) ) ); /* Temperature in Kelvin */ disp_buf.temp_val -= 273.15; disp_buf.temp_val += 70.0; disp_buf.temp_val = filter(disp_buf.temp_val, samples, first_filter_run); first_filter_run = false; #else /* test data temperature R of thermistor ADC value -40 334274 4034 0 32624 3542 25 10000 2712 70 1748 1045 125 337 235 ex LPOUT = 2712; // should return 25 deg C */ disp_buf.temp_val = NTC_compute((float) LPOUT, 5.1/10.0, 3984.0, 25, 12); //disp_buf.temp_val = 10.0 + (10.0 * ((float) rand()/(float)RAND_MAX)); disp_buf.temp_val = filter(disp_buf.temp_val, samples, first_filter_run); first_filter_run = false; #endif } /* 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 */