From f2b66320c28d1323d46075d067a119ac41f3c3b6 Mon Sep 17 00:00:00 2001 From: Michele Balistreri Date: Fri, 26 May 2023 08:05:39 +0200 Subject: [PATCH] add basic backlight control --- app/hal.h | 6 ++ app/screen/st7789.c | 4 + stm32/Core/Inc/main.h | 4 + stm32/Core/Src/main.c | 68 ++++++++++++++-- stm32/Core/Src/stm32.c | 10 +++ stm32/Core/Src/stm32h5xx_hal_msp.c | 56 ++++++++++++- stm32/stm32.ioc | 122 ++++++++++++++++------------- 7 files changed, 208 insertions(+), 62 deletions(-) diff --git a/app/hal.h b/app/hal.h index 7563207..e5f939a 100644 --- a/app/hal.h +++ b/app/hal.h @@ -126,4 +126,10 @@ hal_err_t hal_flash_program(const uint32_t* data, uint32_t* addr); hal_err_t hal_flash_erase(uint32_t block); hal_err_t hal_flash_end_program(); +// PWM +typedef enum { + PWM_BACKLIGHT, +} hal_pwm_output_t; + +hal_err_t hal_pwm_set_dutycycle(hal_pwm_output_t out, uint8_t cycle); #endif diff --git a/app/screen/st7789.c b/app/screen/st7789.c index bf2a3d3..60070a0 100644 --- a/app/screen/st7789.c +++ b/app/screen/st7789.c @@ -6,6 +6,8 @@ #if (_SCREEN_MODEL == ST7789) +#define LCD_BL_DEFAULT 75 + static hal_err_t st7789_write_cmd(uint8_t cmd) { hal_gpio_set(GPIO_LCD_CMD_DATA, GPIO_RESET); return hal_spi_send(SPI_LCD, &cmd, 1); @@ -52,6 +54,8 @@ hal_err_t screen_init() { return HAL_FAIL; } + hal_pwm_set_dutycycle(PWM_BACKLIGHT, LCD_BL_DEFAULT); + return st7789_write_cmd(ST7789_DISPON); } diff --git a/stm32/Core/Inc/main.h b/stm32/Core/Inc/main.h index 9260d65..7724b27 100644 --- a/stm32/Core/Inc/main.h +++ b/stm32/Core/Inc/main.h @@ -61,6 +61,7 @@ extern SMARTCARD_HandleTypeDef hsmartcard6; extern UART_HandleTypeDef huart3; extern PCD_HandleTypeDef hpcd_USB_DRD_FS; extern TIM_HandleTypeDef htim6; +extern TIM_HandleTypeDef htim2; extern DMA_HandleTypeDef handle_GPDMA2_Channel5; /* USER CODE END EC */ @@ -70,6 +71,8 @@ extern DMA_HandleTypeDef handle_GPDMA2_Channel5; /* USER CODE END EM */ +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + /* Exported functions prototypes ---------------------------------------------*/ void Error_Handler(void); void MX_GPIO_Init(void); @@ -86,6 +89,7 @@ void MX_USART3_UART_Init(void); void MX_TIM6_Init(void); void MX_SPI5_Init(void); void MX_USART6_SMARTCARD_Init(void); +void MX_TIM2_Init(void); /* USER CODE BEGIN EFP */ void SystemClock_Config(void); diff --git a/stm32/Core/Src/main.c b/stm32/Core/Src/main.c index 0f8ae44..a11a438 100644 --- a/stm32/Core/Src/main.c +++ b/stm32/Core/Src/main.c @@ -54,6 +54,7 @@ RNG_HandleTypeDef hrng; SPI_HandleTypeDef hspi5; DMA_HandleTypeDef handle_GPDMA1_Channel0; +TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim6; UART_HandleTypeDef huart3; @@ -423,6 +424,65 @@ void MX_SPI5_Init(void) } +/** + * @brief TIM2 Initialization Function + * @param None + * @retval None + */ +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}; + TIM_OC_InitTypeDef sConfigOC = {0}; + + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ + htim2.Instance = TIM2; + htim2.Init.Prescaler = 2499; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + htim2.Init.Period = 999; + htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + 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(); + } + if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &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(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM2_Init 2 */ + + /* USER CODE END TIM2_Init 2 */ + HAL_TIM_MspPostInit(&htim2); + +} + /** * @brief TIM6 Initialization Function * @param None @@ -441,7 +501,7 @@ void MX_TIM6_Init(void) /* USER CODE END TIM6_Init 1 */ htim6.Instance = TIM6; - htim6.Init.Prescaler = (HAL_RCC_GetHCLKFreq() / 1000000); + htim6.Init.Prescaler = ((HAL_RCC_GetHCLKFreq() / 1000000) - 1); htim6.Init.CounterMode = TIM_COUNTERMODE_UP; htim6.Init.Period = 65535; htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; @@ -745,10 +805,8 @@ void MX_GPIO_Init(void) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIO_LCD_RST_GPIO_Port, &GPIO_InitStruct); - /*Configure GPIO pins : PA2 PA3 PA5 PA7 - PA10 */ - GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_5|GPIO_PIN_7 - |GPIO_PIN_10; + /*Configure GPIO pins : PA2 PA3 PA7 PA10 */ + GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_7|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); diff --git a/stm32/Core/Src/stm32.c b/stm32/Core/Src/stm32.c index 5f73355..a237c5a 100644 --- a/stm32/Core/Src/stm32.c +++ b/stm32/Core/Src/stm32.c @@ -152,6 +152,7 @@ hal_err_t hal_init() { MX_GPIO_Init(); MX_TIM6_Init(); + MX_TIM2_Init(); MX_GPDMA2_Init(); MX_GPDMA1_Init(); @@ -172,6 +173,8 @@ hal_err_t hal_init() { MX_ICACHE_Init(); + HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); + return HAL_SUCCESS; } @@ -407,3 +410,10 @@ hal_err_t hal_flash_end_program() { void hal_tick() { HAL_IncTick(); } + +hal_err_t hal_pwm_set_dutycycle(hal_pwm_output_t out, uint8_t cycle) { + assert(out == PWM_BACKLIGHT); + assert(cycle <= 100); + __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, (cycle * 10)); + return HAL_SUCCESS; +} diff --git a/stm32/Core/Src/stm32h5xx_hal_msp.c b/stm32/Core/Src/stm32h5xx_hal_msp.c index 74b0cc5..6949bb2 100644 --- a/stm32/Core/Src/stm32h5xx_hal_msp.c +++ b/stm32/Core/Src/stm32h5xx_hal_msp.c @@ -58,7 +58,9 @@ extern DMA_HandleTypeDef handle_GPDMA1_Channel0; /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ -/** + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + /** * Initializes the Global MSP. */ void HAL_MspInit(void) @@ -492,7 +494,18 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) */ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { - if(htim_base->Instance==TIM6) + if(htim_base->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspInit 0 */ + + /* USER CODE END TIM2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM2_CLK_ENABLE(); + /* USER CODE BEGIN TIM2_MspInit 1 */ + + /* USER CODE END TIM2_MspInit 1 */ + } + else if(htim_base->Instance==TIM6) { /* USER CODE BEGIN TIM6_MspInit 0 */ @@ -506,6 +519,32 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) } +void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(htim->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspPostInit 0 */ + + /* USER CODE END TIM2_MspPostInit 0 */ + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**TIM2 GPIO Configuration + PA5 ------> TIM2_CH1 + */ + GPIO_InitStruct.Pin = GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN TIM2_MspPostInit 1 */ + + /* USER CODE END TIM2_MspPostInit 1 */ + } + +} /** * @brief TIM_Base MSP De-Initialization * This function freeze the hardware resources used in this example @@ -514,7 +553,18 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) */ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { - if(htim_base->Instance==TIM6) + if(htim_base->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspDeInit 0 */ + + /* USER CODE END TIM2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM2_CLK_DISABLE(); + /* USER CODE BEGIN TIM2_MspDeInit 1 */ + + /* USER CODE END TIM2_MspDeInit 1 */ + } + else if(htim_base->Instance==TIM6) { /* USER CODE BEGIN TIM6_MspDeInit 0 */ diff --git a/stm32/stm32.ioc b/stm32/stm32.ioc index 7588a1a..9d9fe23 100644 --- a/stm32/stm32.ioc +++ b/stm32/stm32.ioc @@ -88,12 +88,13 @@ Mcu.IP11=RCC Mcu.IP12=RNG Mcu.IP13=SPI5 Mcu.IP14=SYS -Mcu.IP15=TIM6 -Mcu.IP16=UCPD1 -Mcu.IP17=USART3 -Mcu.IP18=USART6 -Mcu.IP19=USB +Mcu.IP15=TIM2 +Mcu.IP16=TIM6 +Mcu.IP17=UCPD1 +Mcu.IP18=USART3 +Mcu.IP19=USART6 Mcu.IP2=DEBUG +Mcu.IP20=USB Mcu.IP3=GPDMA1 Mcu.IP4=GPDMA2 Mcu.IP5=HASH @@ -101,7 +102,7 @@ Mcu.IP6=I2C2 Mcu.IP7=ICACHE Mcu.IP8=LINKEDLIST Mcu.IP9=NVIC -Mcu.IPNb=20 +Mcu.IPNb=21 Mcu.Name=STM32H563ZITx Mcu.Package=LQFP144 Mcu.Pin0=PE2 @@ -111,60 +112,62 @@ Mcu.Pin11=PF9 Mcu.Pin12=PA0 Mcu.Pin13=PA1 Mcu.Pin14=PA4 -Mcu.Pin15=PA6 -Mcu.Pin16=PB0 -Mcu.Pin17=PF11 -Mcu.Pin18=PF15 -Mcu.Pin19=PE10 +Mcu.Pin15=PA5 +Mcu.Pin16=PA6 +Mcu.Pin17=PB0 +Mcu.Pin18=PF11 +Mcu.Pin19=PF15 Mcu.Pin2=PE4 -Mcu.Pin20=PE11 -Mcu.Pin21=PE12 -Mcu.Pin22=PB13 -Mcu.Pin23=PB14 -Mcu.Pin24=PB15 -Mcu.Pin25=PD8 -Mcu.Pin26=PD9 -Mcu.Pin27=PG4 -Mcu.Pin28=PG5 -Mcu.Pin29=PG6 +Mcu.Pin20=PE10 +Mcu.Pin21=PE11 +Mcu.Pin22=PE12 +Mcu.Pin23=PB13 +Mcu.Pin24=PB14 +Mcu.Pin25=PB15 +Mcu.Pin26=PD8 +Mcu.Pin27=PD9 +Mcu.Pin28=PG4 +Mcu.Pin29=PG5 Mcu.Pin3=PE5 -Mcu.Pin30=PG7 -Mcu.Pin31=PG8 -Mcu.Pin32=PC6 -Mcu.Pin33=PC7 -Mcu.Pin34=PC8 -Mcu.Pin35=PA8 -Mcu.Pin36=PA9 -Mcu.Pin37=PA11 -Mcu.Pin38=PA12 -Mcu.Pin39=PA13(JTMS/SWDIO) +Mcu.Pin30=PG6 +Mcu.Pin31=PG7 +Mcu.Pin32=PG8 +Mcu.Pin33=PC6 +Mcu.Pin34=PC7 +Mcu.Pin35=PC8 +Mcu.Pin36=PA8 +Mcu.Pin37=PA9 +Mcu.Pin38=PA11 +Mcu.Pin39=PA12 Mcu.Pin4=PE6 -Mcu.Pin40=PA14(JTCK/SWCLK) -Mcu.Pin41=PA15(JTDI) -Mcu.Pin42=PC10 -Mcu.Pin43=PC11 -Mcu.Pin44=PD3 -Mcu.Pin45=PG9 -Mcu.Pin46=PG11 -Mcu.Pin47=PG14 -Mcu.Pin48=PB3(JTDO/TRACESWO) -Mcu.Pin49=PB4(NJTRST) +Mcu.Pin40=PA13(JTMS/SWDIO) +Mcu.Pin41=PA14(JTCK/SWCLK) +Mcu.Pin42=PA15(JTDI) +Mcu.Pin43=PC10 +Mcu.Pin44=PC11 +Mcu.Pin45=PD3 +Mcu.Pin46=PG9 +Mcu.Pin47=PG11 +Mcu.Pin48=PG14 +Mcu.Pin49=PB3(JTDO/TRACESWO) Mcu.Pin5=PC13 -Mcu.Pin50=PB8 -Mcu.Pin51=PE0 -Mcu.Pin52=VP_GPDMA1_VS_GPDMACH0 -Mcu.Pin53=VP_GPDMA2_VS_GPDMACH5 -Mcu.Pin54=VP_HASH_VS_HASH -Mcu.Pin55=VP_ICACHE_VS_ICACHE -Mcu.Pin56=VP_PWR_VS_SECSignals -Mcu.Pin57=VP_RNG_VS_RNG -Mcu.Pin58=VP_SYS_VS_None -Mcu.Pin59=VP_TIM6_VS_ClockSourceINT +Mcu.Pin50=PB4(NJTRST) +Mcu.Pin51=PB8 +Mcu.Pin52=PE0 +Mcu.Pin53=VP_GPDMA1_VS_GPDMACH0 +Mcu.Pin54=VP_GPDMA2_VS_GPDMACH5 +Mcu.Pin55=VP_HASH_VS_HASH +Mcu.Pin56=VP_ICACHE_VS_ICACHE +Mcu.Pin57=VP_PWR_VS_SECSignals +Mcu.Pin58=VP_RNG_VS_RNG +Mcu.Pin59=VP_SYS_VS_None Mcu.Pin6=PF0 +Mcu.Pin60=VP_TIM2_VS_ClockSourceINT +Mcu.Pin61=VP_TIM6_VS_ClockSourceINT Mcu.Pin7=PF1 Mcu.Pin8=PF3 Mcu.Pin9=PF4 -Mcu.PinsNb=60 +Mcu.PinsNb=62 Mcu.ThirdPartyNb=0 Mcu.UserConstants=SC_DEFAULT_BAUD_RATE,10752;SC_DEFAULT_PSC,25 Mcu.UserName=STM32H563ZITx @@ -226,6 +229,7 @@ PA4.GPIOParameters=GPIO_Speed PA4.GPIO_Speed=GPIO_SPEED_FREQ_HIGH PA4.Mode=Slave_8_bits_External_Synchro PA4.Signal=DCMI_HSYNC +PA5.Signal=S_TIM2_CH1 PA6.GPIOParameters=GPIO_Speed PA6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH PA6.Mode=Slave_8_bits_External_Synchro @@ -448,7 +452,7 @@ ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=STM32CubeIDE ProjectManager.ToolChainLocation= ProjectManager.UnderRoot=true -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-true-HAL-false,2-MX_GPIO_Init-GPIO-true-HAL-false,3-MX_GPDMA1_Init-GPDMA1-true-HAL-false,4-MX_GPDMA2_Init-GPDMA2-true-HAL-false,5-MX_UCPD1_Init-UCPD1-true-LL-false,6-MX_USB_PCD_Init-USB-true-HAL-false,7-MX_DCMI_Init-DCMI-true-HAL-false,8-MX_RNG_Init-RNG-true-HAL-false,9-MX_ICACHE_Init-ICACHE-true-HAL-false,10-MX_HASH_Init-HASH-true-HAL-false,11-MX_I2C2_Init-I2C2-true-HAL-false,12-MX_USART3_UART_Init-USART3-true-HAL-false,13-MX_TIM6_Init-TIM6-true-HAL-false,14-MX_SPI5_Init-SPI5-true-HAL-false,15-MX_USART6_SMARTCARD_Init-USART6-true-HAL-false,0-MX_CORTEX_M33_NS_Init-CORTEX_M33_NS-false-HAL-true,0-MX_PWR_Init-PWR-false-HAL-true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-true-HAL-false,2-MX_GPIO_Init-GPIO-true-HAL-false,3-MX_GPDMA1_Init-GPDMA1-true-HAL-false,4-MX_GPDMA2_Init-GPDMA2-true-HAL-false,5-MX_UCPD1_Init-UCPD1-true-LL-false,6-MX_USB_PCD_Init-USB-true-HAL-false,7-MX_DCMI_Init-DCMI-true-HAL-false,8-MX_RNG_Init-RNG-true-HAL-false,9-MX_ICACHE_Init-ICACHE-true-HAL-false,10-MX_HASH_Init-HASH-true-HAL-false,11-MX_I2C2_Init-I2C2-true-HAL-false,12-MX_USART3_UART_Init-USART3-true-HAL-false,13-MX_TIM6_Init-TIM6-true-HAL-false,14-MX_SPI5_Init-SPI5-true-HAL-false,15-MX_USART6_SMARTCARD_Init-USART6-true-HAL-false,16-MX_TIM2_Init-TIM2-true-HAL-false,0-MX_CORTEX_M33_NS_Init-CORTEX_M33_NS-false-HAL-true,0-MX_PWR_Init-PWR-false-HAL-true RCC.ADCFreq_Value=250000000 RCC.AHBFreq_Value=250000000 RCC.APB1Freq_Value=250000000 @@ -550,6 +554,8 @@ SH.GPXTI13.0=GPIO_EXTI13 SH.GPXTI13.ConfNb=1 SH.GPXTI7.0=GPIO_EXTI7 SH.GPXTI7.ConfNb=1 +SH.S_TIM2_CH1.0=TIM2_CH1,PWM Generation1 CH1 +SH.S_TIM2_CH1.ConfNb=1 SPI5.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_8 SPI5.CLKPolarity=SPI_POLARITY_HIGH SPI5.CalculateBaudRate=31.25 MBits/s @@ -559,9 +565,15 @@ SPI5.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRate SPI5.Mode=SPI_MODE_MASTER SPI5.NSSPMode=SPI_NSS_PULSE_DISABLE SPI5.VirtualType=VM_MASTER +TIM2.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM2.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 +TIM2.IPParameters=Channel-PWM Generation1 CH1,Prescaler,PeriodNoDither,PulseNoDither_1,AutoReloadPreload +TIM2.PeriodNoDither=999 +TIM2.Prescaler=2499 +TIM2.PulseNoDither_1=0 TIM6.IPParameters=Prescaler TIM6.IPParametersWithoutCheck=Prescaler -TIM6.Prescaler=(HAL_RCC_GetHCLKFreq() / 1000000) +TIM6.Prescaler=((HAL_RCC_GetHCLKFreq() / 1000000) - 1) USART3.IPParameters=VirtualMode,RxPinLevelInvertParam,OverSampling USART3.OverSampling=UART_OVERSAMPLING_8 USART3.RxPinLevelInvertParam=ADVFEATURE_RXINV_ENABLE @@ -594,6 +606,8 @@ VP_RNG_VS_RNG.Mode=RNG_Activate VP_RNG_VS_RNG.Signal=RNG_VS_RNG VP_SYS_VS_None.Mode=None VP_SYS_VS_None.Signal=SYS_VS_None +VP_TIM2_VS_ClockSourceINT.Mode=Internal +VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT VP_TIM6_VS_ClockSourceINT.Mode=Enable_Timer VP_TIM6_VS_ClockSourceINT.Signal=TIM6_VS_ClockSourceINT board=NUCLEO-H563ZI