Files
uarep-ctl/scenes/эмс/yems-boards.gd

334 lines
15 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class_name yems_boards extends Node
class EmsBoard:
enum {WAIT, WR_DEV_NUM_W, WRITE, WR_DEV_NUM_R, READ, READ_FLASH, WRITE_FLASH,
WRITE_FLASH_BEGIN, WRITE_FLASH_END, LOADING} ## Состояния платы
enum LoadState {NOT_LOAD, DONE, IN_PROCESS, FAIL, NOT_DEFINED}
const modulation_dev: Dictionary = { ## Словарь соответствия диапазона номеру устройства
0 : 50,
1 : 51,
2 : 52,
3 : 51,
4 : 52,
5 : 51,
6 : 52, }
var id_board: int ## id платы
var in_devs: Dictionary ## Словарь с входными устройствами.
var out_devs: Dictionary ## Словарь с выходными устройствами.
var base_addr_isa: int ## Базовый адрес ячейки isa.
var ports_to_wr: Array ## Порты для записи
var in_tbl: Array
var out_tbl: Array
var online: bool ## статус платы
var ems_load: int = LoadState.NOT_DEFINED ## состояние загрузки платы
var state_cmd = WAIT ## текущее состояние платы ЭМС
var state_board = WAIT ## текущее состояние платы ЭМС
var cur_dev ## Текущее устройство
var cur_dev_num: = 0 ## Номер текущего устройства
var cur_dev_index: = 0 ## Индекс текущего устройства в списке
var dev_num_list: = Array() ## Список всех устройств
var need_next_dev: bool = false ## Нужно ли переходить к следующему устройству
var unit_ems ## Юнит эмс
var read_done: bool = false ## Флаг, что данные из ячейки прочитанны
var need_flash_rd: bool = false ## Флаг, что надо прочитать флеш
var need_flash_wr: bool = false ## Флаг, что надо записать данные в флеш
var need_write: bool = false ## Флаг, что надо записать данные в ячейку ЭМС
var ems_g_fn: String = '' ## Имя файла настроек ЭМС-Г
var cmd_array: Array ## Очередь выполнения команд
signal upd_delay_offset(board, cur_dev) ## Сигнал о обновлении данных задержек
signal upd_o_state(board, cur_dev) ## Сигнал о обновлении данных режима выходов
func _init(id, base_addr, in_table, out_table, u):
id_board = id
in_tbl = in_table
out_tbl = out_table
base_addr_isa = base_addr
unit_ems = u
for i in range(4):
ports_to_wr.append(base_addr_isa + 4 + i * 2) # Заполнение списка портами для записи
dev_num_list = in_tbl + out_tbl
## Устанавливает состояние входов и выходов платы
func set_status(status: PackedByteArray):
if not status.size():
push_error('status.size():%d' % status.size())
return
var offset = 0
if id_board < 3:
offset = yemsconsts.STATUS_OFFSET[id_board]
var bit_online = 0 + id_board
var bit_load = 3 + id_board
online = (status[0] >> bit_online) & 1
ems_load = LoadState.DONE if ((status[0] >> bit_load) & 1) else LoadState.NOT_LOAD
else:
online = status[0] & 1
var bit_load = 4
if online:
if (ems_load != LoadState.IN_PROCESS) and (ems_load != LoadState.FAIL):
if (ems_load == LoadState.NOT_DEFINED) or not (((status[0] >> bit_load) & 1)):
ems_load = LoadState.NOT_LOAD
else:
ems_load = LoadState.NOT_DEFINED
set_wait()
var in_blank = int(status[1 + offset] | (status[2 + offset] << 8) | (status[3 + offset] << 16) | \
(status[4 + offset] << 24) | (status[5 + offset] << 32))
var in_imp = int(status[7 + offset] | (status[8 + offset] << 8) | (status[9 + offset] << 16) | \
(status[10 + offset] << 24) | (status[11 + offset] << 32))
var out_blank = int(status[13 + offset] | (status[14 + offset] << 8) | (status[15 + offset] << 16) | \
(status[16 + offset] << 24) | (status[17 + offset] << 32))
var out_imp = int(status[19 + offset] | (status[20 + offset] << 8) | (status[21 + offset] << 16)| \
(status[22 + offset] << 24) | (status[23 + offset] << 32))
var out_kz = int(status[25 + offset] | (status[26 + offset] << 8))
if id_board > 0:
out_kz = 0
for in_dev in in_devs.values():
if (in_blank >> (in_dev.id - 1)) & 1:
in_dev.state = 1
elif (in_imp >> (in_dev.id - 1)) & 1:
in_dev.state = 2
else:
in_dev.state = 0
for out_dev in out_devs.values():
if (out_kz >> (out_dev.id - yemsconsts.STATUS_OUT_OFFSET)) & 1:
out_dev.state = 3
elif (out_blank >> (out_dev.id - yemsconsts.STATUS_OUT_OFFSET)) & 1:
out_dev.state = 1
elif (out_imp >> (out_dev.id - yemsconsts.STATUS_OUT_OFFSET)) & 1:
out_dev.state = 2
else:
out_dev.state = 0
## Отправка команды на запись или чтение порта
func on_wr_device(dev_number):
if (state_cmd == WR_DEV_NUM_W) or (state_cmd == WR_DEV_NUM_R):
unit_ems.send_isa(unit_ems.CmdCode.WRITE_ISA, [base_addr_isa + 2, dev_number])
elif state_cmd == WRITE:
var ports: Array = []
if not check_dev_number():
return
for port in cur_dev.ports_data:
if port in ports_to_wr:
var data = cur_dev.ports_data[port]
ports.append(port)
ports.append(data)
unit_ems.send_isa(unit_ems.CmdCode.WRITE_ISA, ports)
elif state_cmd == READ:
var ports: Array = []
for port in cur_dev.ports_data:
if port in ports_to_wr:
ports.append(port)
unit_ems.send_isa(unit_ems.CmdCode.READ_ISA, ports)
## Проверяет правильность выполнения команды записи номера устройства
func check_set_dev(cmd_s):
if unit_ems.isa_ports.has(base_addr_isa + 2):
cur_dev_num = unit_ems.isa_ports[base_addr_isa + 2]
state_cmd = cmd_s
if not check_dev_number():
return
on_wr_device(cur_dev_num)
## Обработчик сообщения, о том, что команда выполнена (машина состояний)
func on_command_done(_yau_07):
if not check_dev_number():
return
if (unit_ems.cmd_code_rx == 1) and state_cmd == WR_DEV_NUM_W:
check_set_dev(WRITE)
elif (unit_ems.cmd_code_rx == 1) and state_cmd == WR_DEV_NUM_R:
check_set_dev(READ)
elif (state_cmd == READ) or (state_cmd == WRITE) \
and ((unit_ems.cmd_code_rx == 1) or (unit_ems.cmd_code_rx == 0)):
for key in unit_ems.isa_ports.keys():
if cur_dev.ports_data.has(key):
cur_dev.ports_data[key] = unit_ems.isa_ports[key]
cur_dev.set_delay_offset()
emit_signal('upd_delay_offset', self, cur_dev)
if cur_dev is yemsdevs.OutDev: # Если это выход, заполняем комбобоксы и чекбатоны
cur_dev.set_mode()
cur_dev.set_btns_state()
emit_signal('upd_o_state', self, cur_dev)
if need_next_dev: # Если нужно вычитать все устройства, выбираем следующее
cur_dev_index += 1
if cur_dev_index < len(dev_num_list):
cur_dev_num = dev_num_list[cur_dev_index][0]
if state_cmd == READ:
state_cmd = WR_DEV_NUM_R
on_wr_device(cur_dev_num)
else:
state_cmd = WR_DEV_NUM_W
on_wr_device(cur_dev_num)
else: # Пробег закончен, выбираем последнее устройство
set_wait()
read_done = true
cur_dev_index -= 1
need_next_dev = false
else:
if cmd_array.size():
execute_cmd()
else:
set_wait()
elif (state_cmd == READ_FLASH) and (unit_ems.cmd_code_rx == unit_ems.CmdCode.READ_FLASH_MP550):
on_read_flash()
elif (state_cmd == WRITE_FLASH) and (unit_ems.cmd_code_rx == unit_ems.CmdCode.WRITE_FLASH_MP550):
set_wait()
elif state_board == LOADING:
var bit_load = 4
if ((unit_ems.status[0] >> bit_load) & 1):
ems_load = LoadState.DONE
set_wait()
## Выбор текущего устройства и проверка правильности его номера
func check_dev_number():
cur_dev = get_dev()
if not cur_dev:
state_cmd = WAIT
return false
return true
## Возвращает устройство по текущему номеру, если он есть в словарях
func get_dev():
if in_devs.has(cur_dev_num):
return in_devs[cur_dev_num]
elif out_devs.has(cur_dev_num):
return out_devs[cur_dev_num]
else:
return null
## Запуск чтения/записи данных из/в ячейки КЭМС
func start_rw_kems(read: bool):
cur_dev_index = 0
cur_dev_num = dev_num_list[cur_dev_index][0]
need_next_dev = true
if read:
state_cmd = WR_DEV_NUM_R
else:
state_cmd = WR_DEV_NUM_W
need_write = false
on_wr_device(cur_dev_num)
## Устанавливает связь между входом и выходом
func set_connection(o_dev, i_dev, val):
cur_dev_num = o_dev
if check_dev_number():
cur_dev.set_dot(i_dev, val)
state_cmd = WR_DEV_NUM_W
on_wr_device(cur_dev_num)
## Изменяет режим работы выхода
func change_mode(o_dev, mode):
cur_dev_num = o_dev
if check_dev_number():
cur_dev.set_sw_mode(mode)
state_cmd = WR_DEV_NUM_W
on_wr_device(cur_dev_num)
## Устанавливает задержи устройства
func set_delay(dev_index, val, is_delay, read):
cur_dev_num = dev_index
if check_dev_number():
if not read:
if is_delay:
cur_dev.set_delay(val)
else:
cur_dev.set_offset(val)
state_cmd = WR_DEV_NUM_W
else:
state_cmd = WR_DEV_NUM_R
on_wr_device(cur_dev_num)
## Отправка команды чтения флеш
func read_flash():
unit_ems.send_flash(unit_ems.CmdCode.READ_FLASH_MP550, [], yemsconsts.NUM_BYTE_FROM_FLASH, id_board)
state_cmd = READ_FLASH
## Обработчик выполнения команды чтения флеш, заполняет прочитанными данными устройства
func on_read_flash():
need_flash_rd = false
var amount_dev = unit_ems.flash_len / 10
for i in amount_dev:
var cur_i = i * 10
cur_dev_num = unit_ems.flash_data.decode_u16(cur_i)
if not check_dev_number(): continue
cur_dev.ports_data[base_addr_isa + 4] = unit_ems.flash_data.decode_u16(cur_i + 2)
cur_dev.ports_data[base_addr_isa + 6] = unit_ems.flash_data.decode_u16(cur_i + 4)
cur_dev.ports_data[base_addr_isa + 8] = unit_ems.flash_data.decode_u16(cur_i + 6)
cur_dev.ports_data[base_addr_isa + 10] = unit_ems.flash_data.decode_u16(cur_i + 8)
start_rw_kems(false)
## Команда записи в флеш текущих данных из программы
func write_flash():
need_flash_wr = false
var fl_data: Array = []
var cur_dev_temp = cur_dev_num
for i in yemsconsts.NUM_INPUT:
cur_dev_num = i + 1
append_data_to_flash(fl_data)
for i in yemsconsts.NUM_OUTPUT:
cur_dev_num = i + yemsconsts.STATUS_OUT_OFFSET
append_data_to_flash(fl_data)
unit_ems.send_flash(unit_ems.CmdCode.WRITE_FLASH_MP550, fl_data, 0, id_board)
cur_dev_num = cur_dev_temp
state_cmd = WRITE_FLASH
## Заполнение данными с устройств массива для записи флеш
func append_data_to_flash(fl_data):
fl_data.append(cur_dev_num)
if check_dev_number():
fl_data.append(cur_dev.ports_data[base_addr_isa + 4])
fl_data.append(cur_dev.ports_data[base_addr_isa + 6])
fl_data.append(cur_dev.ports_data[base_addr_isa + 8])
fl_data.append(cur_dev.ports_data[base_addr_isa + 10])
else:
for j in range(4):
fl_data.append(0)
## Выстевление в устройства данных прочитанных из файла
func btn_load(json_data):
for item in json_data.keys():
var ports: Dictionary = json_data[item]
cur_dev_num = int(item)
if not check_dev_number(): continue
if ports.has('%d'%(base_addr_isa + 4)):
cur_dev.ports_data[base_addr_isa + 4] = int(ports['%d'%(base_addr_isa + 4)])
else: return false
if ports.has('%d'%(base_addr_isa + 6)):
cur_dev.ports_data[base_addr_isa + 6] = int(ports['%d'%(base_addr_isa + 6)])
else: return false
if ports.has('%d'%(base_addr_isa + 8)):
cur_dev.ports_data[base_addr_isa + 8] = int(ports['%d'%(base_addr_isa + 8)])
else: return false
if ports.has('%d'%(base_addr_isa + 10)):
cur_dev.ports_data[base_addr_isa + 10] = int(ports['%d'%(base_addr_isa + 10)])
else: return false
return true
func set_load_done():
state_board = LOADING
unit_ems.send_load_ems_done(unit_ems.CmdCode.LOAD_EMS_DONE)
func execute_cmd():
if len(cmd_array):
state_board = WRITE
var cmd: Array = cmd_array.pop_front()
change_mode(cmd[0], cmd[1])
func add_cmd(band, mode_state):
var state = 2
if mode_state:
state = 3
cmd_array.append([modulation_dev[band], state])
func get_dev_mode(fs_index):
return out_devs[modulation_dev[fs_index/4]].mode
func set_wait():
state_cmd = WAIT
state_board = WAIT