//..............................................................................
//
// Packet header definitions for Modbus
//

import "io_Modbus.jnc"
import "crc16.jnc"

//..............................................................................

struct ModbusReadFrame
{
	uint8_t m_deviceAddress;
	io.ModbusReadPdu m_read;
	uint16_t m_crc;

	[ packetTemplateAction ]
	initialize()
	{
		*this = null;
		m_deviceAddress = 1;
		m_read.m_func = io.ModbusFunc.ReadHoldingRegisters;
		m_read.m_count = 1;
	}

	[ packetTemplateAction ]
	calcChecksum()
	{
		updateModbusChecksum(this);
	}
}

// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

struct ModbusWriteFrame
{
	uint8_t m_deviceAddress;
	io.ModbusWritePdu m_write;
	uint16_t m_crc;

	[ packetTemplateAction ]
	initialize()
	{
		*this = null;
		m_deviceAddress = 1;
		m_write.m_func = io.ModbusFunc.WriteRegister;
	}

	[ packetTemplateAction ]
	calcChecksum()
	{
		updateModbusChecksum(this);
	}
}

// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

struct ModbusWriteMultipleFrame
{
	uint8_t m_deviceAddress;
	io.ModbusWriteMultiplePdu m_write;

	[ packetTemplateAction ]
	initialize()
	{
		*this = null;
		m_deviceAddress = 1;
		m_write.m_func = io.ModbusFunc.WriteMultipleRegisters;
		m_write.m_count = 1;
	}

	[ packetTemplateAction ]
	calcChecksum()
	{
		updateModbusChecksum(this);
	}
}

//..............................................................................

updateModbusChecksum(void* p)
{
	size_t size = dynamic sizeof(p);
	if (size < 2)
		return;

	size -= 2;
	*(uint16_t*)(p + size) = crc16_ansi(p, size, 0xffff);
}

//..............................................................................
