From 108f165ca2c901445b92aa65397ea957a9693b18 Mon Sep 17 00:00:00 2001 From: Anton Mukhin Date: Wed, 17 Jan 2024 15:52:55 +0300 Subject: [PATCH 1/3] WIP: Add new features for board version 2 --- .project | 2 +- Core/Inc/board_logic.h | 6 +- Core/Inc/main.h | 13 +++ Core/Inc/stm32f0xx_it.h | 2 + Core/Src/board_logic.c | 134 ++++++++++++++++++++------ Core/Src/main.c | 89 +++++++++++++++-- Core/Src/stm32f0xx_hal_msp.c | 49 +++++++++- Core/Src/stm32f0xx_it.c | 29 ++++++ Relay_RS485.ioc => Relay_RS485_V2.ioc | 106 ++++++++++++++------ V1-V2_HW_changes.txt | 12 +++ 10 files changed, 374 insertions(+), 68 deletions(-) rename Relay_RS485.ioc => Relay_RS485_V2.ioc (71%) create mode 100644 V1-V2_HW_changes.txt diff --git a/.project b/.project index 3d1ae64..3a509a7 100644 --- a/.project +++ b/.project @@ -1,6 +1,6 @@ - Relay_RS485 + Relay_RS485_V2 diff --git a/Core/Inc/board_logic.h b/Core/Inc/board_logic.h index 5e8f448..1bff2a2 100644 --- a/Core/Inc/board_logic.h +++ b/Core/Inc/board_logic.h @@ -6,7 +6,7 @@ #ifndef BOARD_LOGIC_H_ #define BOARD_LOGIC_H_ -#define MODBUS_FIRMWARE_VERSION ( /*major*/ 10 + /*minor*/ 1 * 0x100) +#define MODBUS_FIRMWARE_VERSION ( /*major*/ 11 + /*minor*/ 0 * 0x100) #define MODBUS_BOARD_TYPE (8) //Relay Module board ID #define REL_MAIN_BIT (1u<<0) @@ -16,7 +16,11 @@ #define MOTOR_MAX 255 +void estop_reset(void); +void board_init(void); +void set_pwm(uint8_t unit, uint16_t duty); void loop_iterate(); void timer1_ovf_isr(void); +void update_service_indication(void); #endif diff --git a/Core/Inc/main.h b/Core/Inc/main.h index f4fb327..3882b76 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -59,6 +59,16 @@ void Error_Handler(void); /* USER CODE END EFP */ /* Private defines -----------------------------------------------------------*/ +#define WATER_Pin GPIO_PIN_0 +#define WATER_GPIO_Port GPIOA +#define WATER_EXTI_IRQn EXTI0_1_IRQn +#define ESTOP_Pin GPIO_PIN_1 +#define ESTOP_GPIO_Port GPIOA +#define ESTOP_EXTI_IRQn EXTI0_1_IRQn +#define LIGHTS_Pin GPIO_PIN_4 +#define LIGHTS_GPIO_Port GPIOA +#define RL_EN_Pin GPIO_PIN_5 +#define RL_EN_GPIO_Port GPIOA #define LED_AUX_Pin GPIO_PIN_6 #define LED_AUX_GPIO_Port GPIOA #define LED_MAIN_Pin GPIO_PIN_7 @@ -67,6 +77,9 @@ void Error_Handler(void); #define LED_ERR_GPIO_Port GPIOB #define LED_ACT_Pin GPIO_PIN_1 #define LED_ACT_GPIO_Port GPIOB +#define LIGHTS_SW_Pin GPIO_PIN_8 +#define LIGHTS_SW_GPIO_Port GPIOA +#define LIGHTS_SW_EXTI_IRQn EXTI4_15_IRQn #define TXEN_Pin GPIO_PIN_11 #define TXEN_GPIO_Port GPIOA #define RL_AUX_Pin GPIO_PIN_15 diff --git a/Core/Inc/stm32f0xx_it.h b/Core/Inc/stm32f0xx_it.h index a70c270..0c9bf14 100644 --- a/Core/Inc/stm32f0xx_it.h +++ b/Core/Inc/stm32f0xx_it.h @@ -51,6 +51,8 @@ void HardFault_Handler(void); void SVC_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); +void EXTI0_1_IRQHandler(void); +void EXTI4_15_IRQHandler(void); void DMA1_Channel2_3_IRQHandler(void); void TIM1_BRK_UP_TRG_COM_IRQHandler(void); void TIM1_CC_IRQHandler(void); diff --git a/Core/Src/board_logic.c b/Core/Src/board_logic.c index b548e70..839b5f9 100644 --- a/Core/Src/board_logic.c +++ b/Core/Src/board_logic.c @@ -12,8 +12,10 @@ #define BOARD_DESC_LEN (16) +extern TIM_HandleTypeDef htim1; extern TIM_HandleTypeDef htim3; -static const char board_description[BOARD_DESC_LEN] = "RS485_Relay V1R1"; +extern TIM_HandleTypeDef htim14; +static const char board_description[BOARD_DESC_LEN] = "RS485_Relay V2R1"; extern uint16_t tranfer_errors_count; extern uint16_t last_rx_time; @@ -28,11 +30,59 @@ extern uint16_t last_rx_time; #define LED_ACT_ON HAL_GPIO_WritePin(LED_ACT_GPIO_Port, LED_ACT_Pin, GPIO_PIN_SET) #define LED_ACT_OFF HAL_GPIO_WritePin(LED_ACT_GPIO_Port, LED_ACT_Pin, GPIO_PIN_RESET) -uint16_t relays=0; -uint16_t motor_pwm=0; -uint16_t led_time_act=0; -void update_service_indication(void); +uint16_t relays = 0; +uint16_t status = 0; +uint16_t motor1_pwm = 0; +uint16_t motor2_pwm = 0; +uint16_t lights_pwm = 0; +uint16_t led_time_act = 0; + +void estop_reset(void) { + HAL_GPIO_WritePin(RL_EN_GPIO_Port, RL_EN_Pin, GPIO_PIN_RESET); + HAL_Delay(1); + HAL_GPIO_WritePin(RL_EN_GPIO_Port, RL_EN_Pin, GPIO_PIN_SET); +} + +void board_init(void) { + // Activate (normalize) E-STOP trigger + estop_reset(); + + // 1ms timer start + HAL_TIM_Base_Start_IT(&htim1); +} + +void set_pwm(uint8_t unit, uint16_t duty) { + uint32_t channel; + TIM_HandleTypeDef* tim; + + switch (unit) { + case 1: // motor 1 + tim = &htim3; + channel = TIM_CHANNEL_1; + break; + case 2: // motor 2 + tim = &htim3; + channel = TIM_CHANNEL_2; + break; + case 3: // lights + tim = &htim14; + channel = TIM_CHANNEL_1; + break; + default: + return; + } + + if (duty > MOTOR_MAX) duty = MOTOR_MAX; + if (duty < MOTOR_MIN) duty = MOTOR_MIN; + if (duty == 0) + HAL_TIM_PWM_Stop(tim, channel); + else { + HAL_TIM_PWM_Start(tim, channel); + __HAL_TIM_SetCompare(tim, channel, duty); + HAL_Delay(5); + } +} void loop_iterate() { @@ -82,22 +132,13 @@ void timer1_ovf_isr(void) //1 ms void update_service_indication(void) { - if(led_time_act) - { + if (led_time_act) { LED_ACT_ON; led_time_act--; - } - else + } else LED_ACT_OFF; -/* - if(led_time_g) - { - LED_G_ON; - led_time_g--; - } - else - LED_G_OFF; - */ + + } @@ -125,9 +166,22 @@ uint8_t read_register(uint16_t address, uint16_t* value) { *value = relays; } - else if (address == 0x2002) //Read motor pwm + else if (address == 0x2002) //Read motor 1 pwm { - *value = motor_pwm; + *value = motor1_pwm; + } + else if (address == 0x2003) //Read motor 2 pwm + { + *value = motor2_pwm; + } + else if (address == 0x2004) //Read Lights pwm + { + *value = lights_pwm; + } + else if (address == 0x2004) //Read status + { + *value = status; + status &= 0b011; // Reset light button press event status } else return 1; @@ -137,7 +191,7 @@ uint8_t read_register(uint16_t address, uint16_t* value) uint8_t write_register(uint16_t address, uint16_t value) { uint8_t ret; - ret=0; + ret = 0; #ifdef UART_DEBUG printf("Write A=0x%X D=0x%X\n\r",address,value); #endif @@ -146,15 +200,21 @@ uint8_t write_register(uint16_t address, uint16_t value) relays = value; break; case 0x2002: - motor_pwm = value; - if(motor_pwm>MOTOR_MAX)motor_pwm=MOTOR_MAX; - if(motor_pwmInstance==TIM14) + { + /* USER CODE BEGIN TIM14_MspInit 0 */ + + /* USER CODE END TIM14_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM14_CLK_ENABLE(); + /* USER CODE BEGIN TIM14_MspInit 1 */ + + /* USER CODE END TIM14_MspInit 1 */ + } } @@ -139,12 +150,12 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) /* USER CODE BEGIN TIM3_MspPostInit 0 */ /* USER CODE END TIM3_MspPostInit 0 */ - __HAL_RCC_GPIOB_CLK_ENABLE(); /**TIM3 GPIO Configuration PB4 ------> TIM3_CH1 + PB5 ------> TIM3_CH2 */ - GPIO_InitStruct.Pin = GPIO_PIN_4; + GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; @@ -155,6 +166,27 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) /* USER CODE END TIM3_MspPostInit 1 */ } + else if(htim->Instance==TIM14) + { + /* USER CODE BEGIN TIM14_MspPostInit 0 */ + + /* USER CODE END TIM14_MspPostInit 0 */ + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**TIM14 GPIO Configuration + PA4 ------> TIM14_CH1 + */ + GPIO_InitStruct.Pin = LIGHTS_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF4_TIM14; + HAL_GPIO_Init(LIGHTS_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN TIM14_MspPostInit 1 */ + + /* USER CODE END TIM14_MspPostInit 1 */ + } } /** @@ -180,6 +212,17 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) /* USER CODE END TIM1_MspDeInit 1 */ } + else if(htim_base->Instance==TIM14) + { + /* USER CODE BEGIN TIM14_MspDeInit 0 */ + + /* USER CODE END TIM14_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM14_CLK_DISABLE(); + /* USER CODE BEGIN TIM14_MspDeInit 1 */ + + /* USER CODE END TIM14_MspDeInit 1 */ + } } diff --git a/Core/Src/stm32f0xx_it.c b/Core/Src/stm32f0xx_it.c index 318028b..86982e6 100644 --- a/Core/Src/stm32f0xx_it.c +++ b/Core/Src/stm32f0xx_it.c @@ -143,6 +143,35 @@ void SysTick_Handler(void) /* please refer to the startup file (startup_stm32f0xx.s). */ /******************************************************************************/ +/** + * @brief This function handles EXTI line 0 and 1 interrupts. + */ +void EXTI0_1_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI0_1_IRQn 0 */ + + /* USER CODE END EXTI0_1_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(WATER_Pin); + HAL_GPIO_EXTI_IRQHandler(ESTOP_Pin); + /* USER CODE BEGIN EXTI0_1_IRQn 1 */ + + /* USER CODE END EXTI0_1_IRQn 1 */ +} + +/** + * @brief This function handles EXTI line 4 to 15 interrupts. + */ +void EXTI4_15_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI4_15_IRQn 0 */ + + /* USER CODE END EXTI4_15_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(LIGHTS_SW_Pin); + /* USER CODE BEGIN EXTI4_15_IRQn 1 */ + + /* USER CODE END EXTI4_15_IRQn 1 */ +} + /** * @brief This function handles DMA1 channel 2 and 3 interrupts. */ diff --git a/Relay_RS485.ioc b/Relay_RS485_V2.ioc similarity index 71% rename from Relay_RS485.ioc rename to Relay_RS485_V2.ioc index 6e18ac4..437ff36 100644 --- a/Relay_RS485.ioc +++ b/Relay_RS485_V2.ioc @@ -24,7 +24,7 @@ Dma.USART1_TX.1.PeriphInc=DMA_PINC_DISABLE Dma.USART1_TX.1.Priority=DMA_PRIORITY_LOW Dma.USART1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority File.Version=6 -GPIO.groupedBy= +GPIO.groupedBy=Group By Peripherals KeepUserPlacement=false Mcu.CPN=STM32F030K6T6 Mcu.Family=STM32F0 @@ -34,33 +34,43 @@ Mcu.IP2=RCC Mcu.IP3=SYS Mcu.IP4=TIM1 Mcu.IP5=TIM3 -Mcu.IP6=USART1 -Mcu.IPNb=7 +Mcu.IP6=TIM14 +Mcu.IP7=USART1 +Mcu.IPNb=8 Mcu.Name=STM32F030K6Tx Mcu.Package=LQFP32 Mcu.Pin0=PF0-OSC_IN Mcu.Pin1=PF1-OSC_OUT -Mcu.Pin10=PA14 -Mcu.Pin11=PA15 -Mcu.Pin12=PB3 -Mcu.Pin13=PB4 -Mcu.Pin14=VP_SYS_VS_Systick -Mcu.Pin15=VP_TIM1_VS_ClockSourceINT -Mcu.Pin2=PA6 -Mcu.Pin3=PA7 -Mcu.Pin4=PB0 -Mcu.Pin5=PB1 -Mcu.Pin6=PA9 -Mcu.Pin7=PA10 -Mcu.Pin8=PA11 -Mcu.Pin9=PA13 -Mcu.PinsNb=16 +Mcu.Pin10=PA8 +Mcu.Pin11=PA9 +Mcu.Pin12=PA10 +Mcu.Pin13=PA11 +Mcu.Pin14=PA13 +Mcu.Pin15=PA14 +Mcu.Pin16=PA15 +Mcu.Pin17=PB3 +Mcu.Pin18=PB4 +Mcu.Pin19=PB5 +Mcu.Pin2=PA0 +Mcu.Pin20=VP_SYS_VS_Systick +Mcu.Pin21=VP_TIM1_VS_ClockSourceINT +Mcu.Pin22=VP_TIM14_VS_ClockSourceINT +Mcu.Pin3=PA1 +Mcu.Pin4=PA4 +Mcu.Pin5=PA5 +Mcu.Pin6=PA6 +Mcu.Pin7=PA7 +Mcu.Pin8=PB0 +Mcu.Pin9=PB1 +Mcu.PinsNb=23 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F030K6Tx -MxCube.Version=6.9.2 -MxDb.Version=DB.6.0.92 +MxCube.Version=6.10.0 +MxDb.Version=DB.6.0.100 NVIC.DMA1_Channel2_3_IRQn=true\:2\:0\:true\:false\:true\:false\:true\:true +NVIC.EXTI0_1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.EXTI4_15_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.ForceEnableDMAVector=true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false @@ -70,6 +80,16 @@ NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false NVIC.TIM1_BRK_UP_TRG_COM_IRQn=true\:3\:0\:true\:false\:true\:true\:true\:true NVIC.TIM1_CC_IRQn=true\:3\:0\:true\:false\:true\:true\:true\:true NVIC.USART1_IRQn=true\:1\:0\:true\:false\:true\:true\:true\:true +PA0.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI +PA0.GPIO_Label=WATER +PA0.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING +PA0.Locked=true +PA0.Signal=GPXTI0 +PA1.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI +PA1.GPIO_Label=ESTOP +PA1.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING +PA1.Locked=true +PA1.Signal=GPXTI1 PA10.Locked=true PA10.Mode=Asynchronous PA10.Signal=USART1_RX @@ -85,6 +105,14 @@ PA15.GPIOParameters=GPIO_Label PA15.GPIO_Label=RL_AUX PA15.Locked=true PA15.Signal=GPIO_Output +PA4.GPIOParameters=GPIO_Label +PA4.GPIO_Label=LIGHTS +PA4.Signal=S_TIM14_CH1 +PA5.GPIOParameters=PinState,GPIO_Label +PA5.GPIO_Label=RL_EN +PA5.Locked=true +PA5.PinState=GPIO_PIN_SET +PA5.Signal=GPIO_Output PA6.GPIOParameters=GPIO_Label PA6.GPIO_Label=LED_AUX PA6.Locked=true @@ -93,6 +121,11 @@ PA7.GPIOParameters=GPIO_Label PA7.GPIO_Label=LED_MAIN PA7.Locked=true PA7.Signal=GPIO_Output +PA8.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI +PA8.GPIO_Label=LIGHTS_SW +PA8.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING +PA8.Locked=true +PA8.Signal=GPXTI8 PA9.Locked=true PA9.Mode=Asynchronous PA9.Signal=USART1_TX @@ -110,6 +143,7 @@ PB3.Locked=true PB3.Signal=GPIO_Output PB4.Locked=true PB4.Signal=S_TIM3_CH1 +PB5.Signal=S_TIM3_CH2 PF0-OSC_IN.Mode=HSE-External-Oscillator PF0-OSC_IN.Signal=RCC_OSC_IN PF1-OSC_OUT.Mode=HSE-External-Oscillator @@ -135,8 +169,8 @@ ProjectManager.MainLocation=Core/Src ProjectManager.NoMain=false ProjectManager.PreviousToolchain=STM32CubeIDE ProjectManager.ProjectBuild=false -ProjectManager.ProjectFileName=Relay_RS485.ioc -ProjectManager.ProjectName=Relay_RS485 +ProjectManager.ProjectFileName=Relay_RS485_V2.ioc +ProjectManager.ProjectName=Relay_RS485_V2 ProjectManager.ProjectStructure= ProjectManager.RegisterCallBack= ProjectManager.StackSize=0x400 @@ -145,7 +179,7 @@ ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=true -ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_TIM3_Init-TIM3-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_TIM3_Init-TIM3-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true,7-MX_TIM14_Init-TIM14-false-HAL-true RCC.AHBFreq_Value=48000000 RCC.APB1Freq_Value=48000000 RCC.APB1TimFreq_Value=48000000 @@ -163,20 +197,38 @@ RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK RCC.TimSysFreq_Value=48000000 RCC.USART1Freq_Value=48000000 RCC.VCOOutput2Freq_Value=8000000 +SH.GPXTI0.0=GPIO_EXTI0 +SH.GPXTI0.ConfNb=1 +SH.GPXTI1.0=GPIO_EXTI1 +SH.GPXTI1.ConfNb=1 +SH.GPXTI8.0=GPIO_EXTI8 +SH.GPXTI8.ConfNb=1 +SH.S_TIM14_CH1.0=TIM14_CH1,PWM Generation1 CH1 +SH.S_TIM14_CH1.ConfNb=1 SH.S_TIM3_CH1.0=TIM3_CH1,PWM Generation1 CH1 SH.S_TIM3_CH1.ConfNb=1 +SH.S_TIM3_CH2.0=TIM3_CH2,PWM Generation2 CH2 +SH.S_TIM3_CH2.ConfNb=1 TIM1.IPParameters=Prescaler,Period -TIM1.Period=100 -TIM1.Prescaler=479 +TIM1.Period=100-1 +TIM1.Prescaler=480-1 +TIM14.Channel=TIM_CHANNEL_1 +TIM14.IPParameters=Channel,Prescaler,Period,OCMode_PWM +TIM14.OCMode_PWM=TIM_OCMODE_PWM1 +TIM14.Period=255 +TIM14.Prescaler=6-1 TIM3.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 -TIM3.IPParameters=Channel-PWM Generation1 CH1,Prescaler,Period +TIM3.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2 +TIM3.IPParameters=Channel-PWM Generation1 CH1,Prescaler,Period,Channel-PWM Generation2 CH2 TIM3.Period=255 -TIM3.Prescaler=239 +TIM3.Prescaler=240-1 USART1.BaudRate=9600 USART1.IPParameters=VirtualMode-Asynchronous,BaudRate USART1.VirtualMode-Asynchronous=VM_ASYNC VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_TIM14_VS_ClockSourceINT.Mode=Enable_Timer +VP_TIM14_VS_ClockSourceINT.Signal=TIM14_VS_ClockSourceINT VP_TIM1_VS_ClockSourceINT.Mode=Internal VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT board=custom diff --git a/V1-V2_HW_changes.txt b/V1-V2_HW_changes.txt new file mode 100644 index 0000000..497d160 --- /dev/null +++ b/V1-V2_HW_changes.txt @@ -0,0 +1,12 @@ +New in Relay_V2 MCU: + +PA0 - INPUT - Water level (HIGH - we have water) +PA1 - INPUT - E-STOP button (HIGH - normal state. should be interrupt-driven on falling edge detection) +PA2 \ +PA3 ---------- Test points TP4, TP5 (ADC / USART1 / GPIO) +PA4 - OUTPUT - LED Lights TIM14 CH1 PWM output +PA5 - OUTPUT - RL_EN. Sets E-STOP trigger to controllable state (resets to normal state). LOW to activate. Should be HIGH by default. +PA8 - INPUT - LED Lights switch +PB5 - OUTPUT - Second DC motor channel. TIM3 CH2 PWM +PB6 \ +PB7 ---------- Test points TP1, TP2 (USART1, I2C1, GPIO) \ No newline at end of file From 651e3b02d13ad97d6b44a16766aeb56a9a72e0db Mon Sep 17 00:00:00 2001 From: Anton Mukhin Date: Thu, 18 Jan 2024 15:26:13 +0300 Subject: [PATCH 2/3] Smooth LED lights level change --- Core/Inc/board_logic.h | 12 ++++---- Core/Src/board_logic.c | 66 +++++++++++++++++++++++++++-------------- Core/Src/main.c | 8 +---- Core/Src/modbus_logic.c | 11 ++----- 4 files changed, 54 insertions(+), 43 deletions(-) diff --git a/Core/Inc/board_logic.h b/Core/Inc/board_logic.h index 1bff2a2..8f6e2d4 100644 --- a/Core/Inc/board_logic.h +++ b/Core/Inc/board_logic.h @@ -9,18 +9,20 @@ #define MODBUS_FIRMWARE_VERSION ( /*major*/ 11 + /*minor*/ 0 * 0x100) #define MODBUS_BOARD_TYPE (8) //Relay Module board ID -#define REL_MAIN_BIT (1u<<0) -#define REL_AUX_BIT (1u<<1) +#define REL_MAIN_BIT (1u<<0) +#define REL_AUX_BIT (1u<<1) -#define MOTOR_MIN 0 -#define MOTOR_MAX 255 +#define PWM_DUTY_MIN 0 +#define PWM_DUTY_MAX 255 +#define PWM_LIGHTS_STEP 20 // Time step in ms between LED light PWM changes +#define LIGHTS_TIME 1000 // Time in ms to spend for smooth lights level change void estop_reset(void); void board_init(void); +uint16_t clamp_duty(uint16_t duty); void set_pwm(uint8_t unit, uint16_t duty); void loop_iterate(); -void timer1_ovf_isr(void); void update_service_indication(void); #endif diff --git a/Core/Src/board_logic.c b/Core/Src/board_logic.c index 839b5f9..3219457 100644 --- a/Core/Src/board_logic.c +++ b/Core/Src/board_logic.c @@ -17,7 +17,6 @@ extern TIM_HandleTypeDef htim3; extern TIM_HandleTypeDef htim14; static const char board_description[BOARD_DESC_LEN] = "RS485_Relay V2R1"; extern uint16_t tranfer_errors_count; -extern uint16_t last_rx_time; #define REL_MAIN_ON HAL_GPIO_WritePin(RL_MAIN_GPIO_Port, RL_MAIN_Pin, GPIO_PIN_SET) #define REL_MAIN_OFF HAL_GPIO_WritePin(RL_MAIN_GPIO_Port, RL_MAIN_Pin, GPIO_PIN_RESET) @@ -36,6 +35,8 @@ uint16_t status = 0; uint16_t motor1_pwm = 0; uint16_t motor2_pwm = 0; uint16_t lights_pwm = 0; +uint16_t lights_pwm_target = 0; +int16_t lights_pwm_delta = 0; uint16_t led_time_act = 0; void estop_reset(void) { @@ -52,6 +53,13 @@ void board_init(void) { HAL_TIM_Base_Start_IT(&htim1); } + +uint16_t clamp_duty(uint16_t duty) { + if (duty > PWM_DUTY_MAX) return PWM_DUTY_MAX; + if (duty < PWM_DUTY_MIN) return PWM_DUTY_MIN; + return duty; +} + void set_pwm(uint8_t unit, uint16_t duty) { uint32_t channel; TIM_HandleTypeDef* tim; @@ -73,8 +81,7 @@ void set_pwm(uint8_t unit, uint16_t duty) { return; } - if (duty > MOTOR_MAX) duty = MOTOR_MAX; - if (duty < MOTOR_MIN) duty = MOTOR_MIN; + duty = clamp_duty(duty); if (duty == 0) HAL_TIM_PWM_Stop(tim, channel); else { @@ -114,22 +121,6 @@ void loop_iterate() HAL_Delay(1); } -// Timer1 overflow interrupt service routine -void timer1_ovf_isr(void) //1 ms -{ - static uint32_t count_1sec=0; - if(last_rx_time<0xFFFF)last_rx_time++; - - update_service_indication(); - - if(++count_1sec==1000) - { - count_1sec = 0; - //led_time_g += 10; - } - -} - void update_service_indication(void) { if (led_time_act) { @@ -208,8 +199,14 @@ uint8_t write_register(uint16_t address, uint16_t value) set_pwm(2, motor2_pwm); break; case 0x2004: - lights_pwm = value; - set_pwm(3, lights_pwm); + lights_pwm_target = clamp_duty(value); + if (lights_pwm_target != lights_pwm) { + lights_pwm_delta = (lights_pwm_target - lights_pwm) / LIGHTS_TIME / PWM_LIGHTS_STEP; + if (lights_pwm_delta == 0) { + if (lights_pwm_target - lights_pwm > 0) lights_pwm_delta = 1; + else lights_pwm_delta = -1; + } + } break; case 0x2020: if (value == 1) { @@ -230,10 +227,35 @@ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) status = status | 0b010; } if(GPIO_Pin == LIGHTS_SW_Pin) { - status |= 0b100; // Set "lights switch pressed" status bit + // Set "lights switch pressed" status bit + status |= 0b100; } if(GPIO_Pin == WATER_Pin) { // Set or reset "water" status bit status |= HAL_GPIO_ReadPin(WATER_GPIO_Port, WATER_Pin); } } + +// Timers overflow interrupt +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { + // check if the interrupt comes from TIM1 + if(htim->Instance == TIM1) { + static uint32_t count_ms = 0; + + update_service_indication(); + + // Check if we should change lights pwm for smooth transition + if (lights_pwm != lights_pwm_target) { + // Change pwm only every 20ms (PWM_LIGHTS_STEP) + if(++count_ms == PWM_LIGHTS_STEP) { + count_ms = 0; + + lights_pwm += lights_pwm_delta; + // Set lights pwm to target if the difference is less than the delta + if (abs(lights_pwm_target - lights_pwm) < abs(lights_pwm_delta)) + lights_pwm = lights_pwm_target; + set_pwm(3, lights_pwm); + } + } + } +} diff --git a/Core/Src/main.c b/Core/Src/main.c index c1e7f22..eeee9cc 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -428,13 +428,7 @@ static void MX_GPIO_Init(void) } /* USER CODE BEGIN 4 */ -void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) -{ - if(htim->Instance == TIM1) //check if the interrupt comes from TIM1 - { - timer1_ovf_isr(); - } -} + /* USER CODE END 4 */ /** diff --git a/Core/Src/modbus_logic.c b/Core/Src/modbus_logic.c index ef52a60..2f273f3 100644 --- a/Core/Src/modbus_logic.c +++ b/Core/Src/modbus_logic.c @@ -15,7 +15,7 @@ uint8_t recv_buffer[BUFFERS_SIZE]; uint8_t send_buffer[BUFFERS_SIZE]; uint16_t bytes_to_send = 0; -uint16_t last_rx_time = 0xFFFF; +//uint16_t last_rx_time = 0xFFFF; enum recv_state cmd_receiving = RECV_IDLE; enum send_state cmd_sending = SEND_IDLE; uint16_t tranfer_errors_count; @@ -79,14 +79,7 @@ void modbus_loop_iterate() { if (cmd_receiving == RECV_ERROR) { - // poor man's way to synchronize packets - //if(last_rx_time>=BUS_IDLE_TIME) - //{ - cmd_receiving = RECV_IDLE; - //TXEN_485 = 1; - //delay_us(10); - //TXEN_485 = 0; - //} + cmd_receiving = RECV_IDLE; } if (cmd_receiving == RECV_IDLE) { From 87f6a0bf3ba03f0ec67641422738da3fdca1500b Mon Sep 17 00:00:00 2001 From: Anton Mukhin Date: Fri, 14 Jun 2024 18:27:46 +0300 Subject: [PATCH 3/3] E-STOP, Light button and pump status functionality fixed/implemented; FW is ready for testing! --- Core/Inc/board_logic.h | 5 ++- Core/Src/board_logic.c | 33 +++++++++++---- Relay_RS485_V2 Debug.launch | 82 +++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 11 deletions(-) create mode 100644 Relay_RS485_V2 Debug.launch diff --git a/Core/Inc/board_logic.h b/Core/Inc/board_logic.h index 8f6e2d4..866d8f4 100644 --- a/Core/Inc/board_logic.h +++ b/Core/Inc/board_logic.h @@ -14,14 +14,15 @@ #define PWM_DUTY_MIN 0 #define PWM_DUTY_MAX 255 -#define PWM_LIGHTS_STEP 20 // Time step in ms between LED light PWM changes -#define LIGHTS_TIME 1000 // Time in ms to spend for smooth lights level change +#define PWM_LIGHTS_STEP 20 // Time step in ms between LED light PWM updates +#define LIGHTS_TIME 600 // Time in ms to spend for smooth lights level change void estop_reset(void); void board_init(void); uint16_t clamp_duty(uint16_t duty); void set_pwm(uint8_t unit, uint16_t duty); +void set_light(uint16_t duty); void loop_iterate(); void update_service_indication(void); diff --git a/Core/Src/board_logic.c b/Core/Src/board_logic.c index 3219457..4551776 100644 --- a/Core/Src/board_logic.c +++ b/Core/Src/board_logic.c @@ -5,6 +5,7 @@ #include #include +#include #include "main.h" #include "modbus_logic.h" @@ -49,6 +50,10 @@ void board_init(void) { // Activate (normalize) E-STOP trigger estop_reset(); + // Check if E-STOP is not shorted + if (HAL_GPIO_ReadPin(ESTOP_GPIO_Port, ESTOP_Pin) == GPIO_PIN_RESET) + status = status | 0b010; + // 1ms timer start HAL_TIM_Base_Start_IT(&htim1); } @@ -91,6 +96,17 @@ void set_pwm(uint8_t unit, uint16_t duty) { } } +void set_light(uint16_t duty) { + lights_pwm_target = clamp_duty(duty); + if (lights_pwm_target != lights_pwm) { + lights_pwm_delta = (lights_pwm_target - lights_pwm) / (LIGHTS_TIME / PWM_LIGHTS_STEP); + if (lights_pwm_delta == 0) { + if (lights_pwm_target - lights_pwm > 0) lights_pwm_delta = 1; + else lights_pwm_delta = -1; + } + } +} + void loop_iterate() { @@ -169,7 +185,7 @@ uint8_t read_register(uint16_t address, uint16_t* value) { *value = lights_pwm; } - else if (address == 0x2004) //Read status + else if (address == 0x2010) //Read status { *value = status; status &= 0b011; // Reset light button press event status @@ -188,6 +204,7 @@ uint8_t write_register(uint16_t address, uint16_t value) #endif switch (address) { case 0x2001: + if (status & 0b010) break; // Check if we are in emergency stop mode relays = value; break; case 0x2002: @@ -199,14 +216,7 @@ uint8_t write_register(uint16_t address, uint16_t value) set_pwm(2, motor2_pwm); break; case 0x2004: - lights_pwm_target = clamp_duty(value); - if (lights_pwm_target != lights_pwm) { - lights_pwm_delta = (lights_pwm_target - lights_pwm) / LIGHTS_TIME / PWM_LIGHTS_STEP; - if (lights_pwm_delta == 0) { - if (lights_pwm_target - lights_pwm > 0) lights_pwm_delta = 1; - else lights_pwm_delta = -1; - } - } + set_light(value); break; case 0x2020: if (value == 1) { @@ -225,14 +235,19 @@ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == ESTOP_Pin) { status = status | 0b010; + relays = 0; } if(GPIO_Pin == LIGHTS_SW_Pin) { // Set "lights switch pressed" status bit status |= 0b100; + if (lights_pwm_target > 0) set_light(0); + else set_light(255); } if(GPIO_Pin == WATER_Pin) { // Set or reset "water" status bit status |= HAL_GPIO_ReadPin(WATER_GPIO_Port, WATER_Pin); + if (HAL_GPIO_ReadPin(WATER_GPIO_Port, WATER_Pin)) status |= 1; + else status &= ~1; } } diff --git a/Relay_RS485_V2 Debug.launch b/Relay_RS485_V2 Debug.launch new file mode 100644 index 0000000..88b614d --- /dev/null +++ b/Relay_RS485_V2 Debug.launch @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +