334 lines
15 KiB
GDScript
334 lines
15 KiB
GDScript
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
|