Files
RS485_Relay2_fw/Core/Src/board_logic.c
2024-01-17 15:52:55 +03:00

240 lines
5.1 KiB
C

/*
* board_logic.c
*
*/
#include <stdint.h>
#include <stdio.h>
#include "main.h"
#include "modbus_logic.h"
#include "board_logic.h"
#define BOARD_DESC_LEN (16)
extern TIM_HandleTypeDef htim1;
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)
#define REL_AUX_ON HAL_GPIO_WritePin(RL_AUX_GPIO_Port, RL_AUX_Pin, GPIO_PIN_SET)
#define REL_AUX_OFF HAL_GPIO_WritePin(RL_AUX_GPIO_Port, RL_AUX_Pin, GPIO_PIN_RESET)
#define LED_MAIN_ON HAL_GPIO_WritePin(LED_MAIN_GPIO_Port, LED_MAIN_Pin, GPIO_PIN_SET)
#define LED_MAIN_OFF HAL_GPIO_WritePin(LED_MAIN_GPIO_Port, LED_MAIN_Pin, GPIO_PIN_RESET)
#define LED_AUX_ON HAL_GPIO_WritePin(LED_AUX_GPIO_Port, LED_AUX_Pin, GPIO_PIN_SET)
#define LED_AUX_OFF HAL_GPIO_WritePin(LED_AUX_GPIO_Port, LED_AUX_Pin, GPIO_PIN_RESET)
#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 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()
{
if(relays&REL_MAIN_BIT)
{
REL_MAIN_ON;
LED_MAIN_ON;
}
else
{
REL_MAIN_OFF;
LED_MAIN_OFF;
}
if(relays&REL_AUX_BIT)
{
REL_AUX_ON;
LED_AUX_ON;
}
else
{
REL_AUX_OFF;
LED_AUX_OFF;
}
/* */
modbus_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) {
LED_ACT_ON;
led_time_act--;
} else
LED_ACT_OFF;
}
uint8_t read_register(uint16_t address, uint16_t* value)
{
if (address == 0x0001)
*value = MODBUS_PROTOCOL_VERSION;
else if (address == 0x0002)
*value = MODBUS_FIRMWARE_VERSION;
else if (address == 0x0003)
*value = MODBUS_BOARD_TYPE;
else if (address == 0x0004)
*value = tranfer_errors_count;
else if (address == 0x0005)
*value = 0; // supported data rate: unknown
else if (address >= 0x0010 && address <= 0x0099)
{
int index = address - 0x0010;
if (index < BOARD_DESC_LEN)
*value = board_description[index];
else
*value = 0;
}
else if (address == 0x2001) //Read relays state
{
*value = relays;
}
else if (address == 0x2002) //Read motor 1 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;
return 0;
}
uint8_t write_register(uint16_t address, uint16_t value)
{
uint8_t ret;
ret = 0;
#ifdef UART_DEBUG
printf("Write A=0x%X D=0x%X\n\r",address,value);
#endif
switch (address) {
case 0x2001:
relays = value;
break;
case 0x2002:
motor1_pwm = value;
set_pwm(1, motor1_pwm);
break;
case 0x2003:
motor2_pwm = value;
set_pwm(2, motor2_pwm);
break;
case 0x2004:
lights_pwm = value;
set_pwm(3, lights_pwm);
break;
case 0x2020:
if (value == 1) {
estop_reset();
status &= 0b101;
}
break;
default:
ret = 1;
}
return ret;
}
// Pin external interrupts handler
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == ESTOP_Pin) {
status = status | 0b010;
}
if(GPIO_Pin == LIGHTS_SW_Pin) {
status |= 0b100; // Set "lights switch pressed" status bit
}
if(GPIO_Pin == WATER_Pin) {
// Set or reset "water" status bit
status |= HAL_GPIO_ReadPin(WATER_GPIO_Port, WATER_Pin);
}
}