Files
PRD_TU_MP550/scripts/FS.gd

297 lines
14 KiB
GDScript
Raw 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.

extends Node
const ONLINE_TIMEOUT = 5.0 ## Время ожидания пакета от ячейки, секунды
const RETRY_COUNT = 5 ## Количество повторных отправок
## Блок управления ФС
class ClientFs extends Node:
## Сигналы статусов
signal connected(unit: ClientFs)
signal data_fs(unit: ClientFs)
signal disconnected(unit: ClientFs)
signal error_connect(unit: ClientFs)
signal line_changed(unit: ClientFs) ## Вызывается когда меняется состояние связи с ячейкой
## Коды выполняемых команд
enum CmdCode {
START_SESSION = 0x0, ## Команда начала сессии
READ_CARRIER = 0x1F, ## Команда получение несущей частоты
SET_CARRIER = 0x1E, ## Команда установки несущей частоты
READ_ATT = 0x1A, ## Команда чтения аттенюации
SET_ATT = 0x1B, ## Команда установки аттенюации
SET_CONFIGURE = 0x01, ## Команда для записи регистров а AXI
READ_GEN_STATUS = 0x05, ## Команда получения статуса генератора
SET_GEN_STATUS = 0x06, ## Команда установки статуса генератора
STATUS_CAN_MACRO = 0x31, ## Команда для чтения/записи статуса CAN
BASE_CAN_MACRO_WRITE = 0x30, ## Команда для записи последовательности CAN-команд
BASE_CAN_MACRO_READ = 0x33, ## Команда для чтения последовательности CAN-команд
BASE_GET_CURRENT_TEMP = 0x36, ## Команда получения температуры
}
enum GROUP {
BASE = 0x00,
GENERATOR = 0x03,
RF = 0x06,
}
## Состояние автомата выполнения команды
enum CmdState {
UNCK, ## Номер команды не ининциирован
SEND, ## Буфер готов для отправки
WAIT, ## Ожидание выполнения
DONE, ## Команда выполнена
FAIL ## Команда не выполнена
}
const CRC32_TABLE: Array = [
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]
const INDEX_SIZE: int = 0xC
const GROUP_OFFSET: int = 0x0
const CMD_OFFSET: int = 0x1
const COUNTER_OFFSET: int = 0x4
const PAYLOAD_OFFSET: int = 0x8
const INIT: int = 0xFFFFFFFF
const FINAL_XOR_VALUE: int = 0x00000000
var self_name: String
var _status: int = 0
var _stream: StreamPeerTCP = StreamPeerTCP.new()
var _peerstream: PacketPeer = PacketPeerStream.new()
var command_stack: Array
var status: = PackedByteArray() ## Поле "состояние прибора"
var counter: int = 0
var send_count: int = 0
var missed_packets: int = 0
var online: bool = false ## Состояние связи с ФС
func _init(nm):
self.self_name = nm
func _ready() -> void:
_status = _stream.get_status()
## Основной процесс отслеживания сосотяни соединения
func _process(_delta: float) -> void:
if _stream.poll() != OK:
print('Ошибка _stream.poll')
return
var new_status: int = _stream.get_status()
if new_status != _status:
_status = new_status
match _status:
_stream.STATUS_NONE:
online = false
emit_signal("disconnected", _stream.get_connected_host())
_stream.STATUS_CONNECTED:
_peerstream.set_stream_peer(_stream)
online = true
emit_signal("connected", _stream.get_connected_host())
_stream.STATUS_ERROR:
print_debug("Error with socket stream.")
online = false
emit_signal("error_connect", _stream.get_connected_host())
if _status == _stream.STATUS_CONNECTED:
var available_bytes: int = _peerstream.get_stream_peer().get_available_bytes()
if available_bytes > 0:
var data: Array = _stream.get_partial_data(available_bytes)
if data[0] != OK:
print_debug("Error getting data from stream: ", data[0])
emit_signal("error_connect")
else:
#parse_data(data[1])
emit_signal("data_fs", data[1])
if not command_stack.is_empty():
send_fs_data()
func connect_to_host(host: String, port: int) -> void:
print('Connect to %s:%s' % [host, port])
if _stream.get_status() == 2:
print_debug("Already connected to host.")
return
_status = _stream.STATUS_NONE
command_stack = []
counter = 0
send_count = 0
if _stream.connect_to_host(host, port) != OK:
print_debug("Error connecting to host.")
emit_signal("error_connect")
func crc32(data: PackedByteArray) -> int:
var crc = INIT
for byte in data:
var index = (crc ^ byte) & 0xFF
crc = (CRC32_TABLE[index] ^ (crc >> 8)) & 0xFFFFFFFF
# Возвращаем только последние 4 байта в обратном порядке
var final_crc = crc ^ FINAL_XOR_VALUE
return final_crc
func _form_packet(group: int, cmd: int, index_size: int, data = null) -> PackedByteArray:
var previous_count = send_count
send_count = counter
print([self_name, previous_count, counter])
if previous_count != 0 && (counter - previous_count) != 1:
var skipped = counter - previous_count - 1
missed_packets += skipped
print_debug("ALARM: Пропущено %d пакетов (было: %d, стало: %d)" % [skipped, previous_count, counter])
print_debug("Группа: %d, Команда: %d" % [group, cmd])
# Формируем пакет
var packet = PackedByteArray()
packet.resize(index_size)
packet.encode_u8(GROUP_OFFSET, group)
packet.encode_u8(CMD_OFFSET, cmd)
packet.encode_u32(COUNTER_OFFSET, counter)
counter += 1
if data:
packet.encode_float(PAYLOAD_OFFSET, data)
return packet
func send_packet_to(packet: PackedByteArray) -> void:
var crc = crc32(packet)
packet.resize(packet.size() + 4)
packet.encode_u32(packet.size() - 4, crc)
command_stack.append(packet)
func send_fs_data() -> bool:
if _status != _stream.STATUS_CONNECTED:
print("Send_fs_data Error: Stream is not currently connected.")
return false
var error: int = _stream.put_data(command_stack.pop_front())
if error != OK:
print("Error writing to stream: ", error)
return false
return true
# Приемник данных от ФС
func parse_data(data_from_fs: PackedByteArray) -> void:
print_debug('Принял пакет от ФС: %s' % data_from_fs)
var _GRP = data_from_fs.decode_u8(0x0)
var _CMD = data_from_fs.decode_u8(0x1)
func start_session():
command_stack = []
counter = 0
send_count = 0
var packet = _form_packet(GROUP.BASE, CmdCode.START_SESSION, INDEX_SIZE)
send_packet_to(packet)
## MSK модуляция
func set_configure_state_msk_modul_1() -> void:
var index_size = 0x20
var packet = _form_packet(GROUP.GENERATOR, CmdCode.SET_CONFIGURE, index_size)
packet.encode_u8(0x3, 0x09)
packet.encode_u16(0x8, 0x0014)
send_packet_to(packet)
## Constant модуляция
func set_configure_state_msk_const():
var index_size = 0x20
var packet = _form_packet(GROUP.GENERATOR, CmdCode.SET_CONFIGURE, index_size)
packet.encode_u8(0x3, 0x09)
packet.encode_u16(0x8, 0x0014)
packet.encode_u8(0x1C, 0x0f)
send_packet_to(packet)
func set_gen_state(button_state: bool):
var index_size = 0x1C
var packet = _form_packet(GROUP.GENERATOR, CmdCode.SET_GEN_STATUS, index_size)
packet.encode_u16(0x8, 0x0010)
packet.encode_u32(0xC, button_state) ## MODE GEN STATUS
send_packet_to(packet)
func status_can_macro_exec(button_state: bool):
var index_size = 0x1C
var packet = _form_packet(GROUP.BASE, CmdCode.STATUS_CAN_MACRO, index_size)
packet.encode_u16(0x8, 0x0010)
packet.encode_u32(0xC, button_state) ## mode can status
send_packet_to(packet)
func set_carrier(installation_frequency: int):
var index_size = 0x1C
var packet = _form_packet(GROUP.BASE, CmdCode.SET_CARRIER, index_size)
packet.encode_u16(0x8, 0x10)
packet.encode_u64(0xC, installation_frequency) ## uint64_t freq low dword/high dword
send_packet_to(packet)
func set_att_batch(attenuation: float):
var index_size = 0x1C
var packet = _form_packet(GROUP.RF, CmdCode.SET_ATT, index_size)
packet.encode_u16(0x8, 0x10)
packet.encode_float(0x18, attenuation)
send_packet_to(packet)
func set_base_can_macro(installation_can_frequency: int):
var index_size = 0x34
var packet = _form_packet(GROUP.BASE, CmdCode.BASE_CAN_MACRO_WRITE, index_size)
packet.encode_u16(0x08, 0x28)
packet.encode_u8(0x1C, 0x01)
packet.encode_u8(0x1D, 0x42)
packet.encode_u8(0x1F, 0x04)
packet.encode_u16(0x20, installation_can_frequency)
packet.encode_u16(0x28, 0x2aff)
packet.encode_u8(0x2B, 0x04)
send_packet_to(packet)
func get_carrier():
var packet = _form_packet(GROUP.BASE, CmdCode.READ_CARRIER, INDEX_SIZE)
send_packet_to(packet)
func get_att_batch():
var packet = _form_packet(GROUP.RF, CmdCode.READ_ATT, INDEX_SIZE)
send_packet_to(packet)
func get_gen_state():
var packet = _form_packet(GROUP.GENERATOR, CmdCode.READ_GEN_STATUS, INDEX_SIZE)
send_packet_to(packet)
func get_base_current_temp():
var packet = _form_packet(GROUP.BASE, CmdCode.BASE_GET_CURRENT_TEMP, INDEX_SIZE)
send_packet_to(packet)
func get_base_can_macro():
var packet = _form_packet(GROUP.BASE, CmdCode.BASE_CAN_MACRO_READ, INDEX_SIZE)
send_packet_to(packet)
# Разорвать соединение с ФС
func disconnect_fs() -> void:
_stream.disconnect_from_host()