//----------------------------------------------------
/**
	\file		ctk/inc/umodbus.h
	\ingroup	serial
	\ingroup	all

	\brief		Funkce pro seriovou komunikaci protokol Modbus RTU
				<<< ALL >>>

	\author		ConTeK s.r.o., Ing. Vladimir Kastner
	\version	01.01
	\date		10.10.2009
*/
//----------------------------------------------------


#ifndef _UMODBUS_H_
#define _UMODBUS_H_			//!< Definice pritomnosti knihovny

#include <ctktypes.h>
#include <comm.h>
#include <ucrc16.h>
#include <ucnp1c.h>
#include <hwmodel.h>

//----------------------------------------------------
/**
	\brief	Definice Modbas RTU protokolu Remote Terminal Unit
			definice fizycke vrstvy:
				1 start bit
				8 data bits, nejnizsi bit zasilany prvni
				1 paritni bit, sudy/lichy/none
				1 stop bit pri paritnim bitu, 2 stop bity pokud neni paritni bit
				----------------------------------------------------------------
				11 bitu celkem / znak
				T cas odpovidajici delce jednoho znaku
				T = 11 * 1/BdRate
				T9600	= 1.15 ms
				T4800	= 2.3 ms
				T2400	= 4.6 ms
				T1200	= 9.2 ms
				T600	= 18.3 ms
				T300	= 36.7 ms
				T200	= 55 ms
				T150	= 73.3 ms
				T100	= 110 ms
				T50		= 220 ms
				T25		= 440 ms
			definice protokulu:
				zprava musi byt odvysilana jako jediny stream
				vysilac:	prodleva mezi telegramy > 3,5 znaku [4T]
							opakovani po xx
				prijimac:	je-li prodleva mezi znaky > 1,5 znaku [2T] -> pak nova zprava, stara prijata data vymazat
				RTU ramec:
				            +------------------------------------------+
				            |         ADU Application Data Unit        |
				            |        +-----------------------+         |
				            |        | PDU Protocol Data Unit|         |
				+-----------+--------+----------+------------+---------+-----------+
				|    START  | ADDRESS| FUNCTION |    DATA    |CRC LO,HI|    END    |
				+-----------+--------+----------+------------+---------+-----------+
				|T1–T2–T3–T4| 8 BITS |  8 BITS  | n x 8 BITS | 16 BITS |T1–T2–T3–T4|
				+-----------+--------+----------+------------+---------+-----------+
				ADDRESS:		       0 broadcast adresa, prijimaji vsichni, neodpovi zadny
								  1..247 adresa slave jednotky
								248..255 rezerva
				FUNCTION:		pozadavek/odpoved/chybova odpoved, request/response/exeption response
								  1..255 platna hodnota
								  1..127 pozadavek/odpoved, request = response
								128..255 chybova odpoved, exeption response = request | 0x80
								  1.. 64 verejne funkce
								 65.. 71 uzivatelsky definovane funkce
								 72.. 99 verejne funkce
								100..109 uzivatelsky definovane funkce
								110..127 verejne funkce

				DATA:			dle FUNCTION
				CRC:			CRC LO,HI, nejnizsi bit prvni

			DATA:
				MODICON ADDR:	    0.. 9999 civky, coils, 1 bit, R/W
								10000..19999 diskretni vstupy, discrete inputs, 1 bit, R
								30000..39999 vstupni registry, input registers, 16 bits, R
								40000..49999 uchovavaci registry, holding registers, 16 bits, R/W
				ADDR:			MODICON ADDR - pocatecni adresa MODICON ADDR, zasilana adresa

*/
//----------------------------------------------------


//----------------------------------------------------
/**
	\brief	FUNCTION
*/
//----------------------------------------------------
#define MSGID_MDB_ERR_MSK			0x80	//!< Maska pro chybovou odpoved, nastavenim = chybova odpoved

#define MSGID_MDB_RD_COILS			 1		//!< Read Coil Status
#define MSGID_MDB_RD_INPS			 2		//!< Read Input Status
#define MSGID_MDB_RD_REGS			 3		//!< Read Holding Registers
#define MSGID_MDB_RD_INREGS			 4		//!< Read Input Registers
#define MSGID_MDB_WR_COIL			 5		//!< Force Single Coil
#define MSGID_MDB_WR_REG			 6		//!< Preset Single Holding Register
#define MSGID_MDB_RD_EXCEPT			 7		//!< Read Exception Status
#define MSGID_MDB_MK_DIAG			 8		//!< Diagnostics
//
#define MSGID_MDB_PROGR				 9		//!< Program
//
#define MSGID_MDB_POLL				10		//!< Poll
//
#define MSGID_MDB_RD_EVENTCNTS		11		//!< Fetch Comm. Event Ctr.
#define MSGID_MDB_RD_EVENTLOGS		12		//!< Fetch Comm. Event Log
//
#define MSGID_MDB_PROGRAMCTRL		13		//!< Program Controller
//
#define MSGID_MDB_POLLCNTR			14		//!< Poll Controller
//
#define MSGID_MDB_WR_COILS			15		//!< Force Multiple Coils
#define MSGID_MDB_WR_REGS			16		//!< Preset Multiple Registers
#define MSGID_MDB_RD_IDENT			17		//!< Report Slave ID
//
#define MSGID_MDB_PROGRAM			18		//!< Program
//
#define MSGID_MDB_RESET				19		//!< Reset Comm. Link
//
#define MSGID_MDB_RD_FILERECS		20		//!< Read General Reference
#define MSGID_MDB_WR_FILERECS		21		//!< Write General Reference
#define MSGID_MDB_WR_REGMSK			22		//!< Mask Write 4X Register
#define MSGID_MDB_RW_REGS			23		//!< Read/Write 4X Registers
#define MSGID_MDB_RD_FIFO			24		//!< Read FIFO Queue

//---------------------------------------------------
//!	\name	Definice typu
//@{
#ifdef MSVC
//#pragma pack(show)
#pragma pack(push,1)
//#pragma pack(show)
#endif // MSVC

typedef uint16_t	subfce_mbt;			//!< Subfunkce diagnostiky !!! pozor !!! nejprve Hi a pote Lo byte
typedef uint16_t	address_mbt;		//!< Adresa civky/inp/registru, !!! pozor !!! nejprve Hi a pote Lo byte
typedef uint16_t	number_mbt;			//!< Pocet civek/registu, !!! pozor !!! nejprve Hi a pote Lo byte
typedef uint16_t	wdata_mbt;			//!< Data registru/civky, !!! pozor !!! nejprve Hi a pote Lo byte
typedef uint8_t		bdata_mbt;			//!< Data civek/inp
typedef uint8_t		bcount_mbt;			//!< Pocet byte
typedef uint8_t		wcount_mbt;			//!< Pocet byte
//@}

//----------------------------------------------------
/**
	\name	Podfunkce diagnostiky
*/
//----------------------------------------------------
//@{
#define SFDIAG_RD_QDATA			00		//!< Return Query Data
#define SFDIAG_RST_COPTION		01		//!< Restart Comm Option
#define SFDIAG_RD_DIAGREG		02		//!< Return Diagnostic Register
#define SFDIAG_CHNG_ADELIMIT	03		//!< Change ASCII Input Delimiter
#define SFDIAG_SET_LISTENMODE	04		//!< Force Listen Only Mode
//#define SFDIAG_05_09_RESERVED	05		//!< 05–09 Reserved
#define SFDIAG_CLR_DIAGREGS		10		//!< Clear Ctrs and Diagnostic Reg.
#define SFDIAG_RD_BUSMESS		11		//!< Return Bus Message Count
#define SFDIAG_RD_BUSERR		12		//!< Return Bus Comm. Error Count
#define SFDIAG_RD_BUSEXCEPT		13		//!< Return Bus Exception Error Cnt
#define SFDIAG_RD_MESS			14		//!< Return Slave Message Count
#define SFDIAG_RD_NORESP		15		//!< Return Slave No Response Cnt
#define SFDIAG_RD_NAK			16		//!< Return Slave NAK Count
#define SFDIAG_RD_BUSY			17		//!< Return Slave Busy Count
#define SFDIAG_RD_CHOVER		18		//!< Return Bus Char. Overrun Cnt
#define SFDIAG_RD_OVER			19		//!< Return Overrun Error Count
#define SFDIAG_CLR_OVER			20		//!< Clear Overrun Counter and Flag
#define SFDIAG_RD_CLR_MODBUS	21		//!< Get/Clear Modbus Plus Statistics
#define SFDIAG_22_up_RESERVED	22		//!< 22–up Reserved
//@}


//----------------------------------------------------
/**
	\name	Chybove kody, EXEPTION CODE
*/
//----------------------------------------------------
//@{
#define ERR_MDB_ILLEGAL_FUNCTION		01	//!< ILLEGAL FUNCTION The function code received in the query is not an allowable action for the slave.
											//!< If a Poll Program Complete command was issued, this code indicates that no program function preceded it.
#define ERR_MDB_ILLEGAL_DATA_ADDRESS	02	//!< ILLEGAL DATA ADDRESS The data address received in the query is not an allowable address for the slave.
#define ERR_MDB_ILLEGAL_DATA_VALUE		03	//!< ILLEGAL DATA VALUE A value contained in the query data field is not an allowable value for the slave.
#define ERR_MDB_SLAVE_DEVICE_FAILURE	04	//!< SLAVE DEVICE FAILURE An unrecoverable error occurred while the slave was attempting to perform the requested action.
#define ERR_MDB_ACKNOWLEDGE				05	//!< ACKNOWLEDGE The slave has accepted the request and is processing it, but a long duration of time will be required to do so.
											//!< This response is returned to prevent a timeout error from occurring in the master.
											//!< The master can next issue a Poll Program Complete message to determine if processing is completed.
#define ERR_MDB_SLAVE_DEVICE_BUSY		06	//!< SLAVE DEVICE BUSY	The slave is engaged in processing a long–duration program command.
											//!< The master should retransmit the message later when the slave is free.
#define ERR_MDB_NEGATIVE_ACKNOWLEDGE	07	//!< NEGATIVE ACKNOWLEDGE	The slave cannot perform the program function received in the query. This code is returned for an unsuccessful
											//!< programming request using function code 13 or 14 decimal.
											//!< The master should request diagnostic or	error information from the slave.
#define ERR_MDB_MEMORY_PARITY_ERROR		08	//!< MEMORY PARITY ERROR	The slave attempted to read extended memory, but detected a parity error in the memory.
											//!<										The master can retry the request, but service may be required on the slave device.

//----------------------------------------------------
/**
	\name	Definice typu
*/
//----------------------------------------------------
//@{
//! Read Coil Status
#define MdbSBytes( _number ) ( ( (_number) + 7 ) >> 3 )	//!< Prevede pocet civek na pocet byte
#define MDB_MAX_RDCOILS		2000						//!< Maximalni pocet ctenych civek
#define MDB_MAX_RDCOILSB	MdbSBytes( MDB_MAX_RDCOILS )//!< Maximalni byte pro ctene civky

typedef struct
{
    address_mbt			Addr;							//!< Adresa prvni civky
    number_mbt			Number;							//!< Pocet civek

#ifndef MSVC
} __attribute__((packed)) rqRDCOILS_mbt;
#else
} rqRDCOILS_mbt;
#endif // MSVC

typedef struct
{
    bcount_mbt			BCnt;							//!< Adresa prvni civky
    bdata_mbt			Data[MDB_MAX_RDCOILSB];			//!< Pocet civek

#ifndef MSVC
} __attribute__((packed)) rsRDCOILS_mbt;
#else
} rsRDCOILS_mbt;
#endif // MSVC

typedef struct
{
    bcount_mbt			BCnt;							//!< Adresa prvni civky
    bdata_mbt			Data[MDB_MAX_RDCOILSB];			//!< Pocet civek

} rsRDCOILSu_mbt;

//! Read Input Status
#define MDB_MAX_RDINPS		MDB_MAX_RDCOILS				//!< Maximalni pocet ctenych vstupu
#define MDB_MAX_RDINPSB		MDB_MAX_RDCOILSB			//!< Maximalni byte pro ctene vstupy

#define rqRDINPS_mbt	rqRDCOILS_mbt
#define rsRDINPS_mbt	rsRDCOILS_mbt
#define rsRDINPSu_mbt	rsRDCOILSu_mbt

//! Read Holding Registers
#define MDB_MAX_RDREGS		125							//!< Maximalni pocet ctenych registru

typedef struct
{
    address_mbt			Addr;							//!< Adresa prvniho registru
    number_mbt			Number;							//!< Pocet registru

#ifndef MSVC
} __attribute__((packed)) rqRDREGS_mbt;
#else
} rqRDREGS_mbt;
#endif // MSVC

typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
    wdata_mbt			Data[MDB_MAX_RDREGS];			//!< Data

#ifndef MSVC
} __attribute__((packed)) rsRDREGS_mbt;
#else
} rsRDREGS_mbt;
#endif // MSVC

typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
    wdata_mbt			Data[MDB_MAX_RDREGS];			//!< Data

} rsRDREGSu_mbt;

//!< Read Input Registers
#define MDB_MAX_RDINREGS	MDB_MAX_RDREGS				//!< Maximalni pocet ctenych registru

#define rqRDINREGS_mbt	rqRDREGS_mbt
#define rsRDINREGS_mbt	rsRDREGS_mbt
#define rsRDINREGSu_mbt	rsRDREGSu_mbt

//! Force Single Coil
typedef struct
{
    address_mbt			Addr;							//!< Adresa civky
    wdata_mbt			Data;							//!< Hodnota, ON=0xFF00

#ifndef MSVC
} __attribute__((packed)) rqWRCOIL_mbt;
#else
} rqWRCOIL_mbt;
#endif // MSVC

typedef struct
{
    address_mbt			Addr;							//!< Adresa civky
    wdata_mbt			Data;							//!< Hodnota, ON=0xFF00

#ifndef MSVC
} __attribute__((packed)) rsWRCOIL_mbt;
#else
} rsWRCOIL_mbt;
#endif // MSVC

typedef struct
{
    address_mbt			Addr;							//!< Adresa civky
    wdata_mbt			Data;							//!< Hodnota, ON=0xFF00

} rsWRCOILu_mbt;

//! Preset Single Holding Register
typedef struct
{
    address_mbt			Addr;							//!< Adresa registru
    wdata_mbt			Data;							//!< Hodnota

#ifndef MSVC
} __attribute__((packed)) rqWRREG_mbt;
#else
} rqWRREG_mbt;
#endif // MSVC

typedef struct
{
    address_mbt			Addr;							//!< Adresa registru
    wdata_mbt			Data;							//!< Hodnota

#ifndef MSVC
} __attribute__((packed)) rsWRREG_mbt;
#else
} rsWRREG_mbt;
#endif // MSVC

//!< Read Exception Status
typedef struct
{

#ifndef MSVC
} __attribute__((packed)) rqRDEXCEPT_mbt;
#else
} rqRDEXCEPT_mbt;
#endif // MSVC

typedef struct
{
    bdata_mbt			Data;							//!< Hodnota

#ifndef MSVC
} __attribute__((packed)) rsRDEXCEPT_mbt;
#else
} rsRDEXCEPT_mbt;
#endif // MSVC

//!< Diagnostics
typedef struct
{
	subfce_mbt			SubFce;							//!< Subfunkce
	wdata_mbt			Data;							//!< Data

#ifndef MSVC
} __attribute__((packed)) rqMKDIAG_mbt;
#else
} rqMKDIAG_mbt;
#endif // MSVC

typedef struct
{
	subfce_mbt			SubFce;							//!< Subfunkce
	wdata_mbt			Data;							//!< Data

#ifndef MSVC
} __attribute__((packed)) rsMKDIAG_mbt;
#else
} rsMKDIAG_mbt;
#endif // MSVC

//! Fetch Comm. Event Counter
typedef struct
{

#ifndef MSVC
} __attribute__((packed)) rqRDEVENTCNTS_mbt;
#else
} rqRDEVENTCNTS_mbt;
#endif // MSVC

typedef struct
{
    wdata_mbt			Status;							//!< Status
    number_mbt			Number;							//!< Pocet

#ifndef MSVC
} __attribute__((packed)) rsRDEVENTCNTS_mbt;
#else
} rsRDEVENTCNTS_mbt;
#endif // MSVC

//! Fetch Comm. Event Log
#define MDB_MAX_EVENTLOGS		64						//!< Maximalni pocet udalosti

typedef struct
{

#ifndef MSVC
} __attribute__((packed)) rqRDEVENTLOGS_mbt;
#else
} rqRDEVENTLOGS_mbt;
#endif // MSVC

typedef struct
{
	bcount_mbt			BCnt;							//!< Pocet byte
    wdata_mbt			Status;							//!< Status
    number_mbt			EventCnt;						//!< Pocet udalosti
    number_mbt			MsgCnt;							//!< Pocet zprav
	bdata_mbt			Event[MDB_MAX_EVENTLOGS];		//!< Udalosti

#ifndef MSVC
} __attribute__((packed)) rsRDEVENTLOGS_mbt;
#else
} rsRDEVENTLOGS_mbt;
#endif // MSVC

typedef struct
{
	bcount_mbt			BCnt;							//!< Pocet byte
    wdata_mbt			Status;							//!< Status
    number_mbt			EventCnt;						//!< Pocet udalosti
    number_mbt			MsgCnt;							//!< Pocet zprav
	bdata_mbt			Event[MDB_MAX_EVENTLOGS];		//!< Udalosti

} rsRDEVENTLOGSu_mbt;

//! Force Multiple Coils
#define MDB_MAX_WRCOILS		1968						//!< Maximalni pocet zapisovanych civek
#define MDB_MAX_WRCOILSB	( MDB_MAX_WRCOILS + 7 ) >> 3 //!< Maximalni pole pro ctene civky

typedef struct
{
    address_mbt			Addr;							//!< Adresa prvni civky
    number_mbt			Number;							//!< Pocet civek
    bcount_mbt			BCnt;							//!< Pocet byte
	bdata_mbt			Data[MDB_MAX_WRCOILSB];			//!< Civky

#ifndef MSVC
} __attribute__((packed)) rqWRCOILS_mbt;
#else
} rqWRCOILS_mbt;
#endif // MSVC

typedef struct
{
    address_mbt			Addr;							//!< Adresa prvni civky
    number_mbt			Number;							//!< Pocet civek
    bcount_mbt			BCnt;							//!< Pocet byte
	bdata_mbt			Data[MDB_MAX_WRCOILSB];			//!< Civky

} rqWRCOILSu_mbt;

typedef struct
{
    address_mbt			Addr;							//!< Adresa prvni civky
    number_mbt			Number;							//!< Pocet civek

#ifndef MSVC
} __attribute__((packed)) rsWRCOILS_mbt;
#else
} rsWRCOILS_mbt;
#endif // MSVC

//! Preset Multiple Registers
#define MDB_MAX_WRREGS		120							//!< Maximalni pocet zapisovanych registru

typedef struct
{
    address_mbt			Addr;							//!< Adresa prvniho registru
    number_mbt			Number;							//!< Pocet registru
    bcount_mbt			BCnt;							//!< Pocet byte
    wdata_mbt			Data[MDB_MAX_WRREGS];			//!< Data

#ifndef MSVC
} __attribute__((packed)) rqWRREGS_mbt;
#else
} rqWRREGS_mbt;
#endif // MSVC

typedef struct
{
    address_mbt			Addr;							//!< Adresa prvniho registru
    number_mbt			Number;							//!< Pocet registru
    bcount_mbt			BCnt;							//!< Pocet byte
    wdata_mbt			Data[MDB_MAX_WRREGS];			//!< Data

} rqWRREGSu_mbt;

typedef struct
{
    address_mbt			Addr;							//!< Adresa prvniho registru
    number_mbt			Number;							//!< Pocet registru

#ifndef MSVC
} __attribute__((packed)) rsWRREGS_mbt;
#else
} rsWRREGS_mbt;
#endif // MSVC

//! Report Slave ID
#define MDB_MAX_RDIDENT		80							//!< Maximalni pocet ctrnych byte
typedef struct
{

#ifndef MSVC
} __attribute__((packed)) rqRDIDENT_mbt;
#else
} rqRDIDENT_mbt;
#endif // MSVC

typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
    bdata_mbt			Ident;							//!< Ident zarizeni
    bdata_mbt			RunSts;							//!< Run Status
    bdata_mbt			Data[MDB_MAX_RDIDENT];			//!< Data

#ifndef MSVC
} __attribute__((packed)) rsRDIDENT_mbt;
#else
} rsRDIDENT_mbt;
#endif // MSVC

typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
    bdata_mbt			Ident;							//!< Ident zarizeni
    bdata_mbt			RunSts;							//!< Run Status
    bdata_mbt			Data[MDB_MAX_RDIDENT];			//!< Data

} rsRDIDENTu_mbt;

//! Read General Reference
#define MDB_MAX_FILERECS		10						//!< Maximalni pocet zaznamu
#define MDB_MAX_FILERECSB		245						//!< Maximalni pocet byte

typedef struct
{
	bdata_mbt			Ref;							//!< Reference = 06
    address_mbt			AddrFile;						//!< Adresa souboru
    address_mbt			AddrRec;						//!< Adresa zaznamu
    number_mbt			Number;							//!< Pocet zaznamu

#ifndef MSVC
} __attribute__((packed)) RQRECS_mbt;
#else
} RQRECS_mbt;
#endif // MSVC

#define MDB_MAX_RECS		100							//!< Maximalni pocet dat zaznamu

typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
	bdata_mbt			Ref;							//!< Reference = 06
    wdata_mbt			Data[MDB_MAX_RECS];				//!< Zaznamy

#ifndef MSVC
} __attribute__((packed)) RSRECS_mbt;
#else
} RSRECS_mbt;
#endif // MSVC

typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
	bdata_mbt			Ref;							//!< Reference = 06
    wdata_mbt			Data[MDB_MAX_RECS];				//!< Zaznamy

} RSRECSu_mbt;

typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
    RQRECS_mbt			Rec[MDB_MAX_FILERECS];			//!< Zadosti o zaznamy

#ifndef MSVC
} __attribute__((packed)) rqRDFILERECS_mbt;
#else
} rqRDFILERECS_mbt;
#endif // MSVC

typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
    RSRECS_mbt			Rec[MDB_MAX_FILERECS];			//!< Ctene o zaznamy

#ifndef MSVC
} __attribute__((packed)) rsRDFILERECS_mbt;
#else
} rsRDFILERECS_mbt;
#endif // MSVC

typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
    RSRECSu_mbt			Rec[MDB_MAX_FILERECS];			//!< Ctene o zaznamy

} rsRDFILERECSu_mbt;

//! Write General Reference
typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
    RSRECS_mbt			Rec[MDB_MAX_FILERECS];			//!< Zadosti o zaznamy

#ifndef MSVC
} __attribute__((packed)) rqWRFILERECS_mbt;
#else
} rqWRFILERECS_mbt;
#endif // MSVC

typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
    RQRECS_mbt			Rec[MDB_MAX_FILERECS];		//!< Ctene o zaznamy

#ifndef MSVC
} __attribute__((packed)) rsWRFILERECS_mbt;
#else
} rsWRFILERECS_mbt;
#endif // MSVC

//! Mask Write 4X Register
typedef struct
{
    address_mbt			Addr;							//!< Adresa registru
    wdata_mbt			AndMsk;							//!< And maska
    wdata_mbt			OrMsk;							//!< Or maska

#ifndef MSVC
} __attribute__((packed)) rqWRREGMSK_mbt;
#else
} rqWRREGMSK_mbt;
#endif // MSVC

typedef struct
{
    address_mbt			Addr;							//!< Adresa registru
    wdata_mbt			AndMsk;							//!< And maska
    wdata_mbt			OrMsk;							//!< Or maska

#ifndef MSVC
} __attribute__((packed)) rsWRREGMSK_mbt;
#else
} rsWRREGMSK_mbt;
#endif // MSVC

//! Read/Write 4X Registers
#define MDB_MAX_RWREGS			118						//!< Maximalni pocet zaznamu

typedef struct
{
	address_mbt			RAddr;							//!< Adresa registru pro cteni
    number_mbt			RNumber;						//!< Pocet zaznamu pro cteni
	address_mbt			WAddr;							//!< Adresa registru pro zapis
    number_mbt			WNumber;						//!< Pocet zaznamu pro zapis
    bcount_mbt			BCnt;							//!< Pocet byte pro zapis
	wdata_mbt			Data[MDB_MAX_RWREGS];			//!< Zapisovana data

#ifndef MSVC
} __attribute__((packed)) rqRWREGS_mbt;
#else
} rqRWREGS_mbt;
#endif // MSVC

typedef struct
{
    bcount_mbt			BCnt;							//!< Pocet byte
	wdata_mbt			Data[MDB_MAX_RWREGS];			//!< Ctena data

#ifndef MSVC
} __attribute__((packed)) rsRWREGS_mbt;
#else
} rsRWREGS_mbt;
#endif // MSVC

//! Read FIFO Queue
#define MDB_MAX_RDFIFO			32						//!< Maximalni pocet zaznamu

typedef struct
{
	address_mbt			Addr;							//!< Adresa fifo

#ifndef MSVC
} __attribute__((packed)) rqRDFIFO_mbt;
#else
} rqRDFIFO_mbt;
#endif // MSVC

typedef struct
{
    wcount_mbt			BCnt;							//!< Pocet byte, !!! Pozor word !!!
    number_mbt			FLength;						//!< Delka fifo <= 31
	wdata_mbt			Data[MDB_MAX_RDFIFO];			//!< Data z fifo

#ifndef MSVC
} __attribute__((packed)) rsRDFIFO_mbt;
#else
} rsRDFIFO_mbt;
#endif // MSVC

typedef struct
{
    bdata_mbt			Error;							//!< Chybova odpoved

#ifndef MSVC
} __attribute__((packed)) rsERROR_mbt;
#else
} rsERROR_mbt;
#endif // MSVC

//@}

//----------------------------------------------------
/**
	\name	Definice zprav
*/
//----------------------------------------------------


//----------------------------------------------------
/**
	\brief	Struktura definujici PDU (Protocol Data Unit) Modbus
*/

//----------------------------------------------------
/**
	\name	PDU zadosti o data
*/
//----------------------------------------------------

typedef struct
{
	uint8_t				Function;							//!< Funkce

	union
	{
#ifdef MSVC
 #pragma warning( push )
 #pragma warning( disable: 4200 )
#endif // MSVC

	uint8_t				Data[0];							//!< Obecny buffer

#ifdef MSVC
 #pragma warning( pop )
#endif // MSVC

	rqRDCOILS_mbt		rqRdCoils;							//!< Read Coil Status
	rqRDINPS_mbt		rqRdInps;							//!< Read Input Status
	rqRDREGS_mbt		rqRdRegs;							//!< Read Holding Registers
	rqRDINREGS_mbt		rqRdInRegs;							//!< Read Input Registers
	rqWRCOIL_mbt		rqWrCoil;							//!< Write Coils
	rqWRREG_mbt			rqWrReg;							//!< Preset Single Holding Register
	rqRDEXCEPT_mbt		rqRdExcept;							//!< Read Exception Status
	rqMKDIAG_mbt		rqMkDiag;							//!< Diagnostics
	rqRDEVENTCNTS_mbt	rqRdEventCnts;						//!< Fetch Comm. Event Counter
	rqRDEVENTLOGS_mbt	rqRdEventLogs;						//!< Fetch Comm. Event Log
	rqWRCOILS_mbt		rqWrCoils;							//!< Force Multiple Coils
	rqWRREGS_mbt		rqWrRegs;							//!< Preset Multiple Registers
	rqRDIDENT_mbt		rqRdIdent;							//!< Report Slave ID
	rqRDFILERECS_mbt	rqRdFileRecs;						//!< Read General Reference
	rqWRFILERECS_mbt	rqWrFileRecs;						//!< Write General Reference
	rqWRREGMSK_mbt		rqWrRegMsk;							//!< Mask Write 4X Register
	rqRWREGS_mbt		rqRWRegs;							//!< Read/Write 4X Registers
	rqRDFIFO_mbt		rqRdFifo;							//!< Read FIFO Queue
	} Data;

#ifndef MSVC
} __attribute__((packed)) RQMDBPDU;
#else
} RQMDBPDU;
#endif // MSVC


//----------------------------------------------------
/**
	\name	PDU odpovedi s daty
*/
//----------------------------------------------------

typedef struct
{
	uint8_t				Function;							//!< Funkce

	union
	{
#ifdef MSVC
 #pragma warning( push )
 #pragma warning( disable: 4200 )
#endif // MSVC

	uint8_t				Data[0];							//!< Obecny buffer

#ifdef MSVC
 #pragma warning( pop )
#endif // MSVC

	rsRDCOILS_mbt		rsRdCoils;							//!< Read Coil Status
	rsRDINPS_mbt		rsRdInps;							//!< Read Input Status
	rsRDREGS_mbt		rsRdRegs;							//!< Read Holding Registers
	rsRDINREGS_mbt		rsRdInRegs;							//!< Read Input Registers
	rsWRCOIL_mbt		rsWrCoil;							//!< Write Coils
	rsWRREG_mbt			rsWrReg;							//!< Preset Single Holding Register
	rsRDEXCEPT_mbt		rsRdExcept;							//!< Read Exception Status
	rsMKDIAG_mbt		rsMkDiag;							//!< Diagnostics
	rsRDEVENTCNTS_mbt	rsRdEventCnts;						//!< Fetch Comm. Event Counter
	rsRDEVENTLOGS_mbt	rsRdEventLogs;						//!< Fetch Comm. Event Log
	rsWRCOILS_mbt		rsWrCoils;							//!< Force Multiple Coils
	rsWRREGS_mbt		rsWrRegs;							//!< Preset Multiple Registers
	rsRDIDENT_mbt		rsRdIdent;							//!< Report Slave ID
	rsRDFILERECS_mbt	rsRdFileRecs;						//!< Read General Reference
	rsWRFILERECS_mbt	rsWrFileRecs;						//!< Write General Reference
	rsWRREGMSK_mbt		rsWrRegMsk;							//!< Mask Write 4X Register
	rsRWREGS_mbt		rsRWRegs;							//!< Read/Write 4X Registers
	rsRDFIFO_mbt		rsRdFifo;							//!< Read FIFO Queue
	rsERROR_mbt			rsError;							//!< Chybova odpoved
	} Data;

#ifndef MSVC
} __attribute__((packed)) RSMDBPDU;
#else
} RSMDBPDU;
#endif // MSVC

//----------------------------------------------------
/**
	\brief	Struktura definujici ADU (Aplication Data Unit) Modbus

	\note	neodkazovat se na polozku _crc ve strukture SENDBUF
			pouze vyhrazuje 2 bajty pro crc. Nikdy se na
			tuto polozku neodkazujte, protoze obsahuje crc
			pouze u nejdelsi zpravy.
*/


//----------------------------------------------------
/**
	\name	ADU zadosti o data
*/
//----------------------------------------------------

typedef struct
{
	uint8_t				DAddr;								//!< Adresa zarizeni, Device Address
	RQMDBPDU			PDU;								//!< PDU
	crc16_t				Crc;								//!< vyhrazeno pro crc

#ifndef MSVC
} __attribute__((packed)) RQMDBADU;
#else
} RQMDBADU;
#endif // MSVC

//----------------------------------------------------
/**
	\name	PDU odpovedi s daty
*/
//----------------------------------------------------

typedef struct
{
	uint8_t				DAddr;								//!< Adresa zarizeni
	RSMDBPDU			PDU;								//!< PDU
	crc16_t				Crc;								//!< vyhrazeno pro crc

#ifndef MSVC
} __attribute__((packed)) RSMDBADU;
#else
} RSMDBADU;
#endif // MSVC

#ifdef MSVC
#pragma pack(pop)
//#pragma pack(show)
#endif // MSVC


//----------------------------------------------------
//! Struktura definujici obecny vysilaci buffer zadosti

typedef struct
{
	BUFDESC		Desc;		//!< popisovac bufferu
	RQMDBADU	Msg;		//!< Modbus zpravy
} RQMDBBUFDESC;
//@}

//----------------------------------------------------
//! Struktura definujici obecny prijimaci buffer odpovedi

typedef struct
{
	BUFDESC		Desc;		//!< popisovac bufferu
	RSMDBADU	Msg;		//!< Modbus zpravy
} RSMDBBUFDESC;
//@}

//----------------------------------------------------
/**
	\brief	Forward deklarace kontextu
*/
//----------------------------------------------------

//! Master
struct _MMDBDESC;

//! Slave
struct _SMDBDESC;


//----------------------------------------------------
/**
	\name	Metody objektu
*/
//----------------------------------------------------
//@{

// Master
typedef void (* cmbMTick) ( struct _MMDBDESC * prt );

// Slave
typedef void (* cmbSTick) ( struct _SMDBDESC * prt );

//! definice CallBacku a zprav
// master

//----------------------------------------------------
//! \brief	Funkce zjistujici, zda je mozne odvysilat dalsi pozadavek
bool_t MdbMReadyToSend( struct _MMDBDESC * mdb );

typedef bool_t (* cmbMReadyToSend)( struct _MMDBDESC * prt );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_COILS
void MdbMRdCoilsReq( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number );
typedef void (* cmbMRdCoilsRs)( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number, bdata_mbt * ValueArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_INPS
void MdbMRdInpsReq( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number );
typedef void (* cmbMRdInpsRs)( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number, bdata_mbt * ValueArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_REGS
void MdbMRdRegsReq( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number );
typedef void (* cmbMRdRegsRs)( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number, wdata_mbt * ValueArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_INREGS
void MdbMRdInRegsReq( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number );
typedef void (* cmbMRdInRegsRs)( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number, wdata_mbt * ValueArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_COIL
void MdbMWrCoilReq( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt Addr, bool_t Value );
typedef void (* cmbMWrCoilRs)( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt Addr, bool_t Value );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_REG
void MdbMWrRegReq( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt Addr, wdata_mbt Value );
typedef void (* cmbMWrRegRs)( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt Addr, wdata_mbt Value );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_EXCEPT
void MdbMRdExceptReq( struct _MMDBDESC * mdb, dnode_t DAddr );
typedef void (* cmbMRdExceptRs)( struct _MMDBDESC * mdb, dnode_t DAddr, bdata_mbt Value );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_MK_DIAG
void MdbMMkDiagReq( struct _MMDBDESC * mdb, dnode_t DAddr, subfce_mbt SubFce, wdata_mbt Data );
typedef void (* cmbMMkDiagRs)( struct _MMDBDESC * mdb, dnode_t DAddr, subfce_mbt SubFce, wdata_mbt Data );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_EVENTCNTS
void MdbMRdEventCntsReq( struct _MMDBDESC * mdb, dnode_t DAddr );
typedef void (* cmbMRdEventCntsRs)( struct _MMDBDESC * mdb, dnode_t DAddr, wdata_mbt Status, wdata_mbt Count );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_EVENTLOGS
void MdbMRdEventLogsReq( struct _MMDBDESC * mdb, dnode_t DAddr );
typedef void (* cmbMRdEventLogsRs)( struct _MMDBDESC * mdb, dnode_t DAddr, wdata_mbt Status, wdata_mbt EventCnt, wdata_mbt MsgCnt, number_mbt Number, bdata_mbt * EventArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_COILS
void MdbMWrCoilsReq( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number, bdata_mbt * ValueArray );
typedef void (* cmbMWrCoilsRs)( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_REGS
void MdbMWrRegsReq( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number, wdata_mbt * ValueArray );
typedef void (* cmbMWrRegsRs)( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartAddr, number_mbt Number );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_IDENT
void MdbMRdIdentReq( struct _MMDBDESC * mdb, dnode_t DAddr );
typedef void (* cmbMRdIdentRs)( struct _MMDBDESC * mdb, dnode_t DAddr, bdata_mbt Ident, bool_t RunStatus, number_mbt Number, bdata_mbt * DataArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_FILERECS
void MdbMRdFileRecReq( struct _MMDBDESC * mdb, dnode_t DAddr, bcount_mbt ByteCount, bdata_mbt * DataArray );
typedef void (* cmbMRdFileRecRs)( struct _MMDBDESC * mdb, dnode_t DAddr, bcount_mbt ByteCount, bdata_mbt * DataArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_FILERECS
void MdbMWrFileRecReq( struct _MMDBDESC * mdb, dnode_t DAddr, bcount_mbt ByteCount, bdata_mbt * DataArray );
typedef void (* cmbMWrFileRecRs)( struct _MMDBDESC * mdb, dnode_t DAddr, bcount_mbt ByteCount, bdata_mbt * DataArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_REGMSK
void MdbMWrRegMskReq( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt Addr, wdata_mbt AndValue, wdata_mbt OrValue );
typedef void (* cmbMWrRegMstRs)( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt Addr, wdata_mbt AndValue, wdata_mbt OrValue );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RW_REGS
void MdbMRWRegsReq( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt StartRAddr, number_mbt RNumber, address_mbt StartWAddr, number_mbt WNumber, wdata_mbt * ValueArray );
typedef void (* cmbMRWRegsRs)( struct _MMDBDESC * mdb, dnode_t DAddr, number_mbt RNumber, wdata_mbt * ValueArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_FIFO
void MdbMRdFifoReq( struct _MMDBDESC * mdb, dnode_t DAddr, address_mbt FifoAddr );
typedef void (* cmbMRdFifoRs)( struct _MMDBDESC * mdb, dnode_t DAddr, number_mbt Number, number_mbt FifoCount, wdata_mbt * ValueArray );

typedef void (* cmbMErrorRs)( struct _MMDBDESC * mdb, dnode_t DAddr, bdata_mbt Error, RQMDBBUFDESC * SndDesc );

typedef void (* cmbMNoResponse)( struct _MMDBDESC * prt, RQMDBBUFDESC * SndDesc, dnode_t DAddr );

typedef void (* cmbMErrorMsg)( struct _MMDBDESC * mdb, RSMDBBUFDESC * RecDesc );
//@}

//----------------------------------------------------
//! \brief	Funkce zjistujici, zda je mozne odvysilat dalsi odpoved
bool_t MdbSReadyToSend( struct _SMDBDESC * mdb );
typedef bool_t (* cmbSReadyToSend)( struct _SMDBDESC * prt );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_COILS
typedef void (* cmbSRdCoilsRq)( struct _SMDBDESC * mdb, address_mbt StartAddr, number_mbt Number );
void MdbSRdCoilsRsp( struct _SMDBDESC * mdb, bcount_mbt ByteCount, bdata_mbt * ByteValueArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_INPS
typedef void (* cmbSRdInpsRq)( struct _SMDBDESC * mdb, address_mbt StartAddr, number_mbt Number );
void MdbSRdInpsRsp( struct _SMDBDESC * mdb, bcount_mbt ByteCount, bdata_mbt * ByteValueArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_REGS
typedef void (* cmbSRdRegsRq)( struct _SMDBDESC * mdb, address_mbt StartAddr, number_mbt Number );
void MdbSRdRegsRsp( struct _SMDBDESC * mdb, number_mbt Number, wdata_mbt * ValueArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_INREGS
typedef void (* cmbSRdInRegsRq)( struct _SMDBDESC * mdb, address_mbt StartAddr, number_mbt Number );
void MdbSRdInRegsRsp( struct _SMDBDESC * mdb, number_mbt Number, wdata_mbt * ValueArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_COIL
typedef void (* cmbSWrCoilRq)( struct _SMDBDESC * mdb, address_mbt Addr, bool_t Value );
void MdbSWrCoilRsp( struct _SMDBDESC * mdb, address_mbt Addr, bool_t Value );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_REG
typedef void (* cmbSWrRegRq)( struct _SMDBDESC * mdb, address_mbt Addr, wdata_mbt Value );
void MdbSWrRegRsp( struct _SMDBDESC * mdb, address_mbt Addr, wdata_mbt Value );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_EXCEPT
typedef void (* cmbSRdExceptRq)( struct _SMDBDESC * mdb );
void MdbSRdExceptRsp( struct _SMDBDESC * mdb, bdata_mbt Value );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_MK_DIAG
typedef void (* cmbSMkDiagRq)( struct _SMDBDESC * mdb, subfce_mbt SubFce, wdata_mbt Data );
void MdbSMkDiagRsp( struct _SMDBDESC * mdb, subfce_mbt SubFce, wdata_mbt Data );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_EVENTCNTS
typedef void (* cmbSRdEventCntsRq)( struct _SMDBDESC * mdb );
void MdbSRdEventCntsRsp( struct _SMDBDESC * mdb, wdata_mbt Status, number_mbt Count );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_EVENTLOGS
typedef void (* cmbSRdEventLogsRq)( struct _SMDBDESC * mdb );
void MdbSRdEventLogsRsp( struct _SMDBDESC * mdb, wdata_mbt Status, number_mbt EventCount, number_mbt MsgCount,  number_mbt Number, bdata_mbt * EventArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_COILS
typedef void (* cmbSWrCoilsRq)( struct _SMDBDESC * mdb, address_mbt StartAddr, number_mbt Number, bdata_mbt * ValueArray );
void MdbSWrCoilsRsp( struct _SMDBDESC * mdb, address_mbt StartAddr, number_mbt Number );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_REGS
typedef void (* cmbSWrRegsRq)( struct _SMDBDESC * mdb, address_mbt StartAddr, number_mbt Number, wdata_mbt * ValueArray );
void MdbSWrRegsRsp( struct _SMDBDESC * mdb, address_mbt StartAddr, number_mbt Number );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_IDENT
typedef void (* cmbSRdIdentRq)( struct _SMDBDESC * mdb );
void MdbSRdIdentRsp( struct _SMDBDESC * mdb, bdata_mbt Ident, bool_t RunStatus, number_mbt Number, bdata_mbt * DataArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_FILERECS
typedef void (* cmbSRdFileRecRq)( struct _SMDBDESC * mdb, bcount_mbt ByteCount, bdata_mbt * DataArray );
void MdbSRdFileRecRsp( struct _SMDBDESC * mdb, bcount_mbt ByteCount, bdata_mbt * DataArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_FILERECS
typedef void (* cmbSWrFileRecRq)( struct _SMDBDESC * mdb, bcount_mbt ByteCount, bdata_mbt * DataArray );
void MdbSWrFileRecRsp( struct _SMDBDESC * mdb, bcount_mbt ByteCount, bdata_mbt * DataArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_WR_REGMSK
typedef void (* cmbSWrRegMstRq)( struct _SMDBDESC * mdb, address_mbt Addr, wdata_mbt AndValue, wdata_mbt OrValue );
void MdbSWrRegMskRsp( struct _SMDBDESC * mdb, address_mbt Addr, wdata_mbt AndValue, wdata_mbt OrValue );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RW_REGS
typedef void (* cmbSRWRegsRq)( struct _SMDBDESC * mdb, address_mbt StartRAddr, number_mbt RNumber, address_mbt StartWAddr, number_mbt WNumber, wdata_mbt * ValueArray );
void MdbSRWRegsRsp( struct _SMDBDESC * mdb, number_mbt RNumber, wdata_mbt * ValueArray );

//----------------------------------------------------
//! \brief	Funkce a callback pro MSGID_MDB_RD_FIFO
typedef void (* cmbSRdFifoRq)( struct _SMDBDESC * mdb, address_mbt FifoAddr );
void MdbSRdFifoRsp( struct _SMDBDESC * mdb, number_mbt Number, number_mbt FifoCount, wdata_mbt * ValueArray );

void MdbSErrorRsp( struct _SMDBDESC * mdb, uint8_t Function, bdata_mbt Error );

typedef void (* cmbSErrorMsg)( struct _SMDBDESC * mdb, RQMDBBUFDESC * RecDesc );

//----------------------------------------------------
//! \brief	Struktura popisujici stav Modbus automatu

// Master
typedef struct _MMDBDESC
{
	volatile bool_t			flRunning;			//!< je inicializovano, po ininializaci na TRUE, pred ukoncenim FALSE

	COMMDESC *			CmmL1;				//!< Ovladac seriove linky

	volatile bool_t			mflTick;			//!< Tcik je vykonavan
	volatile uint8_t		mState;				//!< Stav automatu
	volatile bool_t			mflState;			//!< Automat je vykonavan
	dnode_t				mDAddr;				//!< Posledni DNode zpravy
	uint8_t				mFunction;			//!< Posledni Function zpravy
	RQMDBBUFDESC		mSendBuf;			//!< Buffer odesilaneho paketu
	pktsize_t			mSendSize;			//!< Velikost zpravy pro opakovani
	bool_t				mReqPending;		//!< Priznak probihajiciho pozadavku
	ticks_t				mRetryCount;		//!< Pocet opakovani
	ticks_t				mRetryCountCnt;		//!< Pocitadlo opakovani vysilani
	ticks_t				mRetryTimer;		//!< Casovac pro opakovani zpravy
	ticks_t				mRetryTimeout;		//!< Timeout pro opakovani zpravy
	ticks_t				mWaitTime;			//!< Prodleva mezi zpravami
	ticks_t				mWaitTimer;			//!< Casovac pro prodlevu

	cmbMReadyToSend		MReadyToSend;		//!< ready to master send

	cmbMRdCoilsRs		cbMRdCoilsRs;
	cmbMRdInpsRs		cbMRdInpsRs;
	cmbMRdRegsRs		cbMRdRegsRs;
	cmbMRdInRegsRs		cbMRdInRegsRs;
	cmbMWrCoilRs		cbMWrCoilRs;
	cmbMWrRegRs			cbMWrRegRs;
	cmbMRdExceptRs		cbMRdExceptRs;
	cmbMMkDiagRs		cbMMkDiagRs;
	cmbMRdEventCntsRs	cbMRdEventCntsRs;
	cmbMRdEventLogsRs	cbMRdEventLogsRs;
	cmbMWrCoilsRs		cbMWrCoilsRs;
	cmbMWrRegsRs		cbMWrRegsRs;
	cmbMRdIdentRs		cbMRdIdentRs;
	cmbMRdFileRecRs		cbMRdFileRecRs;
	cmbMWrFileRecRs		cbMWrFileRecRs;
	cmbMWrRegMstRs		cbMWrRegMstRs;
	cmbMRWRegsRs		cbMRWRegsRs;
	cmbMRdFifoRs		cbMRdFifoRs;

	cmbMErrorRs			cbMErrorRs;

	cmbMNoResponse		cbMNoResponse;

 	cmbMErrorMsg		cbMErrorMsg;		//!< callback pri chybne zprave

	// buffery
	RSMDBBUFDESC		mrecvbuf1;
	RSMDBBUFDESC		mrecvbuf2;

	// metody
	cmbMTick			Tick;				//!< tick knihovny

} MMDBDESC;

// Slave
typedef struct _SMDBDESC
{
	volatile bool_t			flRunning;			//!< je inicializovano, po ininializaci na TRUE, pred ukoncenim FALSE

	COMMDESC *			CmmL1;				//!< Ovladac seriove linky

	volatile bool_t			sflTick;			//!< Tick je vykonavan
	volatile uint8_t		sState;				//!< Stav automatu
	volatile bool_t			sflState;			//!< Automat je vykonavan
	dnode_t				sDAddr;				//!< Posledni DNode zpravy
	ticks_t				sWaitTime;			//!< Prodleva mezi zpravami
	ticks_t				sWaitTimer;			//!< Casovac pro prodlevu

	RSMDBBUFDESC		sSendBuf;			//!< Slave buffer odesilaneho paketu

	cmbSReadyToSend		SReadyToSend;		//!< ready to slave send

	cmbSRdCoilsRq		cbSRdCoilsRq;
	cmbSRdInpsRq		cbSRdInpsRq;
	cmbSRdRegsRq		cbSRdRegsRq;
	cmbSRdInRegsRq		cbSRdInRegsRq;
	cmbSWrCoilRq		cbSWrCoilRq;
	cmbSWrRegRq			cbSWrRegRq;
	cmbSRdExceptRq		cbSRdExceptRq;
	cmbSMkDiagRq		cbSMkDiagRq;
	cmbSRdEventCntsRq	cbSRdEventCntsRq;
	cmbSRdEventLogsRq	cbSRdEventLogsRq;
	cmbSWrCoilsRq		cbSWrCoilsRq;
	cmbSWrRegsRq		cbSWrRegsRq;
	cmbSRdIdentRq		cbSRdIdentRq;
	cmbSRdFileRecRq		cbSRdFileRecRq;
	cmbSWrFileRecRq		cbSWrFileRecRq;
	cmbSWrRegMstRq		cbSWrRegMstRq;
	cmbSRWRegsRq		cbSRWRegsRq;
	cmbSRdFifoRq		cbSRdFifoRq;
 	cmbSErrorMsg		cbSErrorMsg;		//!< callback pri chybne zprave

	// buffery
	RQMDBBUFDESC		srecvbuf1;
	RQMDBBUFDESC		srecvbuf2;

	// metody
	cmbSTick			Tick;				//!< tick knihovny

} SMDBDESC;


//----------------------------------------------------
/**
	\brief	Funkce pro inicializaci komunikaèního automatu

	\param	prt			Struktura kontextu automatu

	\return	TRUE		inicializace probehla v poradku
			FALSE		chyba
*/
//----------------------------------------------------

// Master
bool_t MdbMInitialize( MMDBDESC * mdb, COMMDESC * CmmL1, ticks_t RetryTimeout, ticks_t RetryCount, ticks_t WaitTime );

ticks_t MdbMGetRetryCount( const MMDBDESC * const mdb );

ticks_t MdbMGetRetryTimeout( const MMDBDESC * const mdb );

void MdbMSetRetry( MMDBDESC * const mdb, const ticks_t RetryCount, const ticks_t RetryTimeout );

// Slave
bool_t MdbSInitialize( SMDBDESC * mdb, COMMDESC * CmmL1, ticks_t WaitTime );

//----------------------------------------------------
/**
	\brief	Funkce pro ukonceni komunikaèního automatu

*/
//----------------------------------------------------

#ifdef ALL_FINALIZE

// Master
void MdbMFinalize( MMDBDESC * mdb );

// Slave
void MdbSFinalize( SMDBDESC * mdb );

#else

 // Master
 #define MdbFinalize( mdb )

 // Slave
 #define MdbFinalize( mdb )

#endif // ALL_FINALIZE

#endif // _UMODBUS_H_
