/* * board_logic.c * * Created on: Jul 25, 2024 * Author: User */ #include #include #include #include #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) { if (GET_HVS_CONN) { volt_buff[buff_index] = rawADC[0]; curr_buff[buff_index] = rawADC[1]; } else { volt_buff[buff_index] = 0; curr_buff[buff_index] = 0; } 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(); } }