268 lines
12 KiB
GDScript
268 lines
12 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, LOAD_KEMS, WRITE_FLASH_END}
|
||
|
||
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: bool ## флаг загрузки платы
|
||
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 ## Флаг, что надо записать данные в ячейку ЭМС
|
||
|
||
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):
|
||
var 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 = (status[0] >> bit_load) & 1
|
||
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 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:
|
||
state_cmd = WRITE
|
||
cur_dev_num = unit_ems.isa_ports[base_addr_isa + 2]
|
||
if not check_dev_number():
|
||
return
|
||
on_wr_device(cur_dev_num)
|
||
elif (unit_ems.cmd_code_rx == 1) and state_cmd == WR_DEV_NUM_R:
|
||
state_cmd = READ
|
||
cur_dev_num = unit_ems.isa_ports[base_addr_isa + 2]
|
||
if not check_dev_number():
|
||
return
|
||
on_wr_device(cur_dev_num)
|
||
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: # Пробег закончен, выбираем последнее устройство
|
||
state_cmd = WAIT
|
||
state_board = WAIT
|
||
read_done = true
|
||
cur_dev_index -= 1
|
||
need_next_dev = false
|
||
else:
|
||
state_cmd = 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):
|
||
state_board = WAIT
|
||
state_cmd = WAIT
|
||
#load_flash()
|
||
#emit_signal('write_msg', 'Произведена запись в ПЗУ ячейки ЯУ-07')
|
||
|
||
# Выбор текущего устройства и проверка правильности его номера
|
||
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: continue
|
||
if ports.has('%d'%(base_addr_isa + 6)):
|
||
cur_dev.ports_data[base_addr_isa + 6] = int(ports['%d'%(base_addr_isa + 6)])
|
||
else: continue
|
||
if ports.has('%d'%(base_addr_isa + 8)):
|
||
cur_dev.ports_data[base_addr_isa + 8] = int(ports['%d'%(base_addr_isa + 8)])
|
||
else: continue
|
||
if ports.has('%d'%(base_addr_isa + 10)):
|
||
cur_dev.ports_data[base_addr_isa + 10] = int(ports['%d'%(base_addr_isa + 10)])
|
||
else: continue
|