#include "at32f403a_407.h" #include "modbus_params.h" #include "modbus_dio_params.h" #include "modbus_ai_params.h" #include "modbus_ao_params.h" #include "io.h" #include "uptime.h" #include "rtc.h" #include "digital_input.h" #include "digital_output.h" #include "log.h" #include "log_dio.h" #include "log_ai.h" #include "settings_api.h" #include "common_config.h" #include "swap.h" #include "common_gpio.h" #include "monitoring.h" #include "rtc_battery.h" #include mb_param_t mb_param[MB_PARAM_MAX]; uint32_t rtc_sinhro; // Пароль для установки системных настроек uint16_t psw; bool psw_ok = false; uint8_t fw_version[8]; uint16_t save_sys_cmd = 0; // Команда сохранения системных настроек uint16_t system_cmd = 0; // Команда управления контроллером uint64_t value_64 = 0; uint8_t value_8 = 0; uint8_t arch_channel = 0; void get_time(uint8_t* buf, uint8_t size); void get_din_mode(uint8_t* buf, uint8_t size); void get_log_entries_number(uint8_t* buf, uint8_t size); void get_arch_ch_1(uint8_t* buf, uint8_t size); void get_arch_ch_2(uint8_t* buf, uint8_t size); void get_arch_ch_3(uint8_t* buf, uint8_t size); void get_arch_ch_4(uint8_t* buf, uint8_t size); void get_arch_ch_5(uint8_t* buf, uint8_t size); void get_arch_ch_6(uint8_t* buf, uint8_t size); void get_arch_ch_7(uint8_t* buf, uint8_t size); void get_arch_ch_8(uint8_t* buf, uint8_t size); void get_arch_ch_9(uint8_t* buf, uint8_t size); void get_arch_ch_10(uint8_t* buf, uint8_t size); void get_arch_ch_11(uint8_t* buf, uint8_t size); void get_arch_ch_12(uint8_t* buf, uint8_t size); void (*get_ch_entries_number[12])(uint8_t* buf, uint8_t size) = { get_arch_ch_1, get_arch_ch_2, get_arch_ch_3, get_arch_ch_4, get_arch_ch_5, get_arch_ch_6, get_arch_ch_7, get_arch_ch_8, get_arch_ch_9, get_arch_ch_10, get_arch_ch_11, get_arch_ch_12 }; void get_rtc(uint8_t* buf, uint8_t size); // void mb_init_params(void) { uint16_t index = 0; uint16_t addr = 0; #if defined (MDIO_88) // 56 параметров index = mb_init_dio_params(0); #endif #if defined (MAI_12) index = mb_init_ai_params(0); #endif #if defined (MAO_4) index = mb_init_ao_params(0); #endif // ---------------------------------------------------------------------- // // Управление контроллером. Системные параметры. // ---------------------------------------------------------------------- // // Управление контроллером mb_param[index].reg = 0x0800; mb_param[index].size = 1; mb_param[index].param = (uint8_t*)&system_cmd; // mb_param[index].set = mb_control; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // uptime mb_param[index].reg = 0x0801; mb_param[index].size = 2; mb_param[index].param = (uint8_t*)&uptime; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // RTC mb_param[index].reg = 0x0803; mb_param[index].size = 4; mb_param[index].param = (uint8_t*)&value_64; // mb_param[index].set = mb_set_rtc; mb_param[index].get = get_rtc; mb_param[index].check_handler = mb_check_dummy; index++; // Напряжение на батарее RTC mb_param[index].reg = 0x0807; mb_param[index].size = 2; mb_param[index].param = (uint8_t*)&bat_voltage; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Состояние модуля mb_param[index].reg = 0x0809; mb_param[index].size = 2; mb_param[index].param = (uint8_t*)&mon_state; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Пользовательская информация. Текстовая строка. mb_param[index].reg = 0x080B; mb_param[index].size = 16; mb_param[index].param = (uint8_t*)&settings.info; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Безопасный режим работы mb_param[index].reg = 0x081B; mb_param[index].size = 1; mb_param[index].param = (uint8_t*)&settings.save_mode; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Время до перехода в безопасный режим работы mb_param[index].reg = 0x081C; mb_param[index].size = 1; mb_param[index].param = (uint8_t*)&settings.save_delay; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // ---------------------------------------------------------------------- // // Журналы/рахивы // ---------------------------------------------------------------------- // // Емкость журнала (максимальная) mb_param[index].reg = 0x0900; mb_param[index].size = 1; mb_param[index].param = (uint8_t*)&log_entries_capacity; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Текущее количество записей в журнале mb_param[index].reg = 0x0901; mb_param[index].size = 1; mb_param[index].param = NULL; // mb_param[index].set = NULL; mb_param[index].get = get_log_entries_number; mb_param[index].check_handler = mb_check_dummy; index++; // Емкость архива (максимальная) mb_param[index].reg = 0x0902; mb_param[index].size = 1; mb_param[index].param = (uint8_t*)&archive_entries_capacity; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; uint8_t channel_number = log_get_arch_channel_number(); // Текущее количество записей в архиве по каждому каналу addr = 0x0903; for (int i = 0; i < channel_number; i++) { mb_param[index].reg = addr; mb_param[index].size = 1; mb_param[index].param = NULL; mb_param[index].set = NULL; mb_param[index].get = get_ch_entries_number[i]; mb_param[index].check_handler = mb_check_dummy; addr++; index++; } // Период архива. addr = 0x090F; for (int i = 0; i < channel_number; i++) { mb_param[index].reg = addr; mb_param[index].size = 1; mb_param[index].param = (uint8_t*)&settings.period_archive[i]; // Счетчик ипульсов mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_archiv_per; addr++; index++; } // ---------------------------------------------------------------------- // // Производственные параметры // ---------------------------------------------------------------------- // // Код модели (только чтение). Определяется прошивкой. mb_param[index].reg = 0x0080; mb_param[index].size = 1; mb_param[index].param = (uint8_t*)&model_code; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Ревизия платы (только чтение). Резисторы на плате. mb_param[index].reg = 0x0081; mb_param[index].size = 1; mb_param[index].param = (uint8_t*)&board_rev; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Дата производства Unix формат (чтение/запись по паролю) mb_param[index].reg = 0x0082; mb_param[index].size = 2; mb_param[index].param = (uint8_t*)&temp_sys_settings.prod_date; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Серийный номер (чтение/запись по паролю). mb_param[index].reg = 0x0084; mb_param[index].size = 2; mb_param[index].param = (uint8_t*)&temp_sys_settings.sn; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Версия ПО (только чтение). memcpy(&fw_version, FW_VERSION, 8); mb_param[index].reg = 0x0086; mb_param[index].size = 4; mb_param[index].param = (uint8_t*)&fw_version; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Статус тестирования (чтение/запись по паролю). mb_param[index].reg = 0x008A; mb_param[index].size = 1; mb_param[index].param = (uint8_t*)&temp_sys_settings.test_state; // mb_param[index].set = NULL; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Пароль mb_param[index].reg = 0x0090; mb_param[index].size = 1; mb_param[index].param = (uint8_t*)&psw; // mb_param[index].set = mb_password; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; // Команда на сохранение системных настроек mb_param[index].reg = 0x0091; mb_param[index].size = 1; mb_param[index].param = (uint8_t*)&save_sys_cmd; // mb_param[index].set = mb_sys_settings_save; mb_param[index].get = NULL; mb_param[index].check_handler = mb_check_dummy; index++; } // Возвращает размер параметра в регистрах bool mb_find_param(uint16_t reg, uint16_t *index, uint16_t *size) { for (uint16_t i = 0; i < MB_PARAM_MAX; i++) { if (mb_param[i].reg == reg) { *index = i; *size = mb_param[i].size; return true; } } return false; } // mb_delay_action_t mb_set_param(uint8_t *buf, uint16_t index) { uint8_t *ptr = mb_param[index].param; // Если параметр только для чтения if (mb_param[index].check_handler == NULL) return MB_NO_ACTION; for (uint16_t i = 0; i < 2*mb_param[index].size; i++) { *ptr = buf[2*mb_param[index].size - 1 - i]; ptr++; } /* if (mb_param[index].check_handler != NULL) mb_param[index].check_handler(); */ mb_param[index].check_handler(); if (mb_param[index].set != NULL) return mb_param[index].set(); else return MB_NO_ACTION; /* if (mb_param[index].f_activity) return mb_param[index].set_handler(); else return MB_NO_ACTION; */ } // void mb_get_param(uint8_t *buf, uint16_t index) { uint8_t *ptr; if (mb_param[index].get != NULL) { mb_param[index].get(buf, mb_param[index].size); return; } ptr = mb_param[index].param + 2*mb_param[index].size - 1; for (uint16_t i = 0; i < 2*mb_param[index].size; i++) { *buf = *ptr; buf++; ptr--; } } // -------------------------------------------------------------------------- // // Чтение параметров // -------------------------------------------------------------------------- // #if 0 void get_time(uint8_t* buf, uint8_t size) { uint32_t rtc_unix = RTC_GetUnixTime(); uint8_t *ptr = (uint8_t*)&rtc_unix + 2*size - 1; for (uint16_t i = 0; i < 2*size; i++) { *buf = *ptr; buf++; ptr--; } } #endif // void get_din_mode(uint8_t* buf, uint8_t size) { } // void get_log_entries_number(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_capacity()); memcpy(buf, &capacity, 2); //buf = (uint8_t*)&capacity; } // void get_arch_ch_1(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(0)); memcpy(buf, &capacity, 2); } // void get_arch_ch_2(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(1)); memcpy(buf, &capacity, 2); } // void get_arch_ch_3(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(2)); memcpy(buf, &capacity, 2); } // void get_arch_ch_4(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(3)); memcpy(buf, &capacity, 2); } // void get_arch_ch_5(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(4)); memcpy(buf, &capacity, 2); } // void get_arch_ch_6(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(5)); memcpy(buf, &capacity, 2); } // void get_arch_ch_7(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(6)); memcpy(buf, &capacity, 2); } // void get_arch_ch_8(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(7)); memcpy(buf, &capacity, 2); } // void get_arch_ch_9(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(8)); memcpy(buf, &capacity, 2); } // void get_arch_ch_10(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(9)); memcpy(buf, &capacity, 2); } // void get_arch_ch_11(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(10)); memcpy(buf, &capacity, 2); } // void get_arch_ch_12(uint8_t* buf, uint8_t size) { static uint16_t capacity; capacity = swap_uint16(log_arch_capacity(11)); memcpy(buf, &capacity, 2); } // void get_rtc(uint8_t* buf, uint8_t size) { uint64_t rtc = swap_uint64(rtc_get_ms()); memcpy(buf, &rtc, 8); } // -------------------------------------------------------------------------- // // Установка параметров // -------------------------------------------------------------------------- // // mb_delay_action_t mb_set_time(void) { TM_RTC_SetDataTimeUnix(rtc_sinhro); return MB_NO_ACTION; } // mb_delay_action_t mb_password(void) { if (psw != MB_PASSWORD) return MB_PAS_ERR; else { if (psw_ok == false) { psw_ok = true; return MB_PAS_OK; } else return MB_NO_ACTION; } } // mb_delay_action_t mb_sys_settings_save(void) { if (save_sys_cmd == 1) return MB_SAVE_SYS_SETTINGS; else return MB_NO_ACTION; } // mb_delay_action_t mb_control(void) { if (system_cmd == MB_COM_SETTINGS_SAVE) return MB_SAVE_SETTINGS; else if (system_cmd == MB_COM_LOG_CLEAR) return MB_LOG_CLEAR; else if ((system_cmd >= (uint8_t)MB_COM_ARCH_CLEAR_1) && (system_cmd <= (uint8_t)MB_COM_ARCH_CLEAR_8)) { arch_channel = system_cmd; return MB_ARCHIVE_CLEAR; } return MB_NO_ACTION; #if 0 if (system_cmd == 1) return MB_SAVE_SETTINGS; else if (system_cmd == 2) return MB_DEF_SETTINGS; else if (system_cmd == 3) return MB_RESET; else if (system_cmd == 4) return MB_PART_DEF_SETTINGS; return MB_NO_ACTION; #endif } // mb_delay_action_t mb_set_rtc(void) { float delta; uint64_t now = rtc_get_ms(); if (now >= value_64) delta = (float)(now - value_64); else delta = (float)(value_64 - now); rtc_set_in_ms((uint32_t)(value_64/1000)); // -------------------------------------------------------------------------- // // EVENT. Перевод времени. log_add_entry(LOG_CLOCK_CHANGE, LOG_EVENT_STATE_OK, 0, delta); return MB_NO_ACTION; } // -------------------------------------------------------------------------- // // Проверка параметров // // -------------------------------------------------------------------------- // // void mb_check_dummy(void) { } // void mb_check_archiv_per(void) { uint8_t channel_number = log_get_arch_channel_number(); for (uint8_t i = 0; i < channel_number; i++) { if (settings.period_archive[i] > (uint16_t)MAX_ARCHIVE_PERIOD) settings.period_archive[i] = (uint16_t)MAX_ARCHIVE_PERIOD; } }