mirror of
https://gitea.ecohim.ru:3000/RS485_BSV/RS485_BSV_fw.git
synced 2025-08-04 07:27:06 +03:00
263 lines
6.1 KiB
C
263 lines
6.1 KiB
C
/*
|
|
* board_logic.c
|
|
*
|
|
* Created on: Jul 25, 2024
|
|
* Author: User
|
|
*/
|
|
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#include "main.h"
|
|
#include "modbus_logic.h"
|
|
#include "board_logic.h"
|
|
|
|
#define BOARD_DESC_LEN (14)
|
|
static const char board_description[BOARD_DESC_LEN] = "RS485_BSV V1R1";
|
|
extern uint16_t tranfer_errors_count;
|
|
|
|
extern TIM_HandleTypeDef htim6;
|
|
extern ADC_HandleTypeDef hadc1;
|
|
extern DAC_HandleTypeDef hdac;
|
|
|
|
#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)
|
|
|
|
|
|
hvs_t hvs = {0};
|
|
|
|
// Time for LED_ACT to be on
|
|
uint16_t led_time_act = 0;
|
|
|
|
// Raw ADC values buffer (circular DMA)
|
|
uint32_t rawADC[4] = {0};
|
|
|
|
// ADC Buffers
|
|
uint16_t volt_buff[ADC_BUFF_LENGTH] = {0};
|
|
uint16_t curr_buff[ADC_BUFF_LENGTH] = {0};
|
|
uint8_t buff_index = 0;
|
|
|
|
|
|
uint16_t config = 0;
|
|
uint16_t config_new = 0;
|
|
uint8_t config_update_flag = 0;
|
|
uint8_t adc_sum_flag = 0;
|
|
|
|
|
|
void board_init(void) {
|
|
// ADC
|
|
HAL_ADCEx_Calibration_Start(&hadc1);
|
|
HAL_ADC_Start_DMA(&hadc1, rawADC, 4);
|
|
|
|
// DAC
|
|
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
|
|
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0);
|
|
HAL_DAC_Start(&hdac, DAC_CHANNEL_2);
|
|
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, 0);
|
|
|
|
// 1ms timer start
|
|
HAL_TIM_Base_Start_IT(&htim6);
|
|
}
|
|
|
|
|
|
|
|
void loop_iterate() {
|
|
|
|
if(hvs.update_voltage_flag) {
|
|
uint32_t value = (uint32_t)(hvs.set_voltage*K_DAC_VOLTAGE);
|
|
if(value > 4095) value = 4095;
|
|
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value);
|
|
hvs.update_voltage_flag = 0;
|
|
}
|
|
|
|
if(hvs.update_current_flag)
|
|
{
|
|
uint32_t value = (uint32_t)(hvs.set_current*K_DAC_CURRENT);
|
|
if(value > 4095) value = 4095;
|
|
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, value);
|
|
hvs.update_current_flag = 0;
|
|
}
|
|
|
|
if(config_update_flag) {
|
|
// HVS ON
|
|
if((config^config_new) & CONF_BIT_HVS_EN) {
|
|
if(config_new & CONF_BIT_HVS_EN) SET_HVS_ON;
|
|
else SET_HVS_OFF;
|
|
}
|
|
|
|
config = config_new;
|
|
config_update_flag = 0;
|
|
}
|
|
|
|
// Time to calculate ADC results
|
|
if (adc_sum_flag) {
|
|
uint32_t volt_sum = 0, curr_sum = 0;
|
|
|
|
for (uint8_t i = 0; i < ADC_BUFF_LENGTH; i++) {
|
|
volt_sum += volt_buff[i];
|
|
curr_sum += curr_buff[i];
|
|
}
|
|
volt_sum = volt_sum / ADC_BUFF_LENGTH;
|
|
curr_sum = curr_sum / ADC_BUFF_LENGTH;
|
|
|
|
hvs.voltage = (float)volt_sum / K_ADC_VOLTAGE;
|
|
hvs.current = (float)curr_sum / K_ADC_CURRENT;
|
|
hvs.v_15 = (float)rawADC[2] / K_ADC_15V;
|
|
hvs.v_24 = (float)rawADC[3] / K_ADC_24V;
|
|
|
|
adc_sum_flag = 0;
|
|
}
|
|
|
|
|
|
/* */
|
|
modbus_loop_iterate();
|
|
HAL_Delay(1);
|
|
}
|
|
|
|
void update_service_indication(void) {
|
|
if (led_time_act) {
|
|
LED_ACT_ON;
|
|
led_time_act--;
|
|
} else
|
|
LED_ACT_OFF;
|
|
}
|
|
|
|
uint16_t update_status(void) {
|
|
uint16_t s = 0;
|
|
|
|
if(GET_HVS_CONN) {
|
|
// 0 - COVER OPEN - Xray board
|
|
// 1 - GLASS OPEN - Xray board
|
|
// 2 - NO WATER - Xray board
|
|
// 3 - JP1 - Xray board
|
|
// 4 - JP2 - Xray board
|
|
// 5 - was reserved but now it is Connection flag:
|
|
s |= (1u<<5);
|
|
if(GET_HVS_ENABLE) s |= (1u<<6);
|
|
if(GET_HVS_READY) s |= (1u<<7);
|
|
if(GET_HVS_XRAYON) s |= (1u<<8);
|
|
if(GET_HVS_NOLINK) s |= (1u<<9);
|
|
if(GET_HVS_OVERHEAT) s |= (1u<<10);
|
|
if(GET_HVS_OVERLOAD) s |= (1u<<11);
|
|
//12 - reserved
|
|
//13 - THERMSW - Xray board
|
|
//14 - SHTR_OPTO - Xray board
|
|
}
|
|
return s;
|
|
}
|
|
|
|
void adc_bufferize(void) {
|
|
volt_buff[buff_index] = rawADC[0];
|
|
curr_buff[buff_index] = rawADC[1];
|
|
if (++buff_index >= ADC_BUFF_LENGTH) {
|
|
buff_index = 0;
|
|
adc_sum_flag = 1;
|
|
}
|
|
}
|
|
|
|
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 status
|
|
*value = update_status();
|
|
}
|
|
else if (address == 0x2002) { //Read config
|
|
*value = config;
|
|
}
|
|
else if (address == 0x2010) { //Read tube voltage set
|
|
*value = ceil(hvs.set_voltage*100);
|
|
}
|
|
else if (address == 0x2011) { //Read tube current set
|
|
*value = ceil(hvs.set_current);
|
|
}
|
|
else if (address == 0x2012) { //Read tube voltage
|
|
if (GET_HVS_CONN)
|
|
*value = ceil(hvs.voltage*100);
|
|
else
|
|
*value = 0;
|
|
}
|
|
else if (address == 0x2013) { //Read tube current
|
|
if (GET_HVS_CONN)
|
|
*value = ceil(hvs.current);
|
|
else
|
|
*value = 0;
|
|
}
|
|
else if (address == 0x2014) { //Read 24V supply voltage
|
|
if (GET_HVS_CONN)
|
|
*value = ceil(hvs.v_24*100);
|
|
else
|
|
*value = 0;
|
|
}
|
|
else if (address == 0x2015) { //Read 15V supply voltage
|
|
if (GET_HVS_CONN)
|
|
*value = ceil(hvs.v_15*100);
|
|
else
|
|
*value = 0;
|
|
}
|
|
|
|
else
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
uint8_t write_register(uint16_t address, uint16_t value)
|
|
{
|
|
uint8_t ret = 0;
|
|
#ifdef UART_DEBUG
|
|
printf("Write A=0x%X D=0x%X\n\r",address,value);
|
|
#endif
|
|
switch (address) {
|
|
case 0x2002: //Write config
|
|
config_new = value;
|
|
config_update_flag = 1;
|
|
break;
|
|
case 0x2010: //Voltage set
|
|
hvs.set_voltage = (float)value/100;
|
|
if (hvs.set_voltage > HVS_U_LIMIT) hvs.set_voltage = HVS_U_LIMIT;
|
|
hvs.update_voltage_flag = 1;
|
|
break;
|
|
case 0x2011: //Current set
|
|
hvs.set_current = (float)value;
|
|
if (hvs.set_current > HVS_I_LIMIT) hvs.set_current = HVS_I_LIMIT;
|
|
hvs.update_current_flag = 1;
|
|
break;
|
|
|
|
default:
|
|
ret = 1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
// Timers overflow interrupt
|
|
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
|
// check if the interrupt comes from TIM6 (1ms timer)
|
|
if(htim->Instance == TIM6) {
|
|
// ACT LED update
|
|
update_service_indication();
|
|
|
|
// bufferize the ADC values
|
|
adc_bufferize();
|
|
}
|
|
}
|
|
|