//---------------------------------------------------------------------------

#ifndef commFTDIH
#define commFTDIH
//---------------------------------------------------------------------------

#include <Classes.hpp>
#include <setupapi.h>
#include <dbt.h>
#include "ftd2xx.h"


/*
 * Data size definitions.
 */

#define  AS_NODATA_SIZE    0
#define  AS_ERROR_SIZE     4
#define  AS_FLOAT_SIZE     4
#define  AS_LONG_SIZE      4
#define  AS_ULONG_SIZE     4
#define  AS_BLONG_SIZE     4
#define  AS_SHORT_SIZE     2
#define  AS_USHORT_SIZE    2
#define  AS_BSHORT_SIZE    2
#define  AS_CHAR_SIZE      1
#define  AS_UCHAR_SIZE     1
#define  AS_BCHAR_SIZE     1
#define  AS_SHORT_2_SIZE   4
#define  AS_USHORT_2_SIZE  4
#define  AS_BSHORT_2_SIZE  4
#define  AS_CHAR_4_SIZE    4
#define  AS_UCHAR_4_SIZE   4
#define  AS_BCHAR_4_SIZE   4
#define  AS_CHAR_2_SIZE    2
#define  AS_UCHAR_2_SIZE   2
#define  AS_BCHAR_2_SIZE   2
#define  AS_MEMID_SIZE     4
#define  AS_CHKSUM_SIZE    4
#define  AS_ACHAR_SIZE     1
#define  AS_ACHAR_2_SIZE   2
#define  AS_ACHAR_4_SIZE   4
#define  AS_DATE_SIZE	   4

/*
 * Data type definitions.
 */

#define  AS_NODATA   0
#define  AS_ERROR    1
#define  AS_FLOAT    2
#define  AS_LONG     3
#define  AS_ULONG    4
#define  AS_BLONG    5
#define  AS_SHORT    6
#define  AS_USHORT   7
#define  AS_BSHORT   8
#define  AS_CHAR     9
#define  AS_UCHAR    10
#define  AS_BCHAR    11
#define  AS_SHORT_2  12
#define  AS_USHORT_2 13
#define  AS_BSHORT_2 14
#define  AS_CHAR_4   15
#define  AS_UCHAR_4  16
#define  AS_BCHAR_4  17
#define  AS_CHAR_2   18
#define  AS_UCHAR_2  19
#define  AS_BCHAR_2  20
#define  AS_MEMID    21
#define  AS_CHKSUM   22
#define  AS_ACHAR    23
#define  AS_ACHAR_2  24
#define  AS_ACHAR_4  25
#define  AS_DATE     100


/* Definice kodu servisu (polozka Service Code):       */

#define IDS     0      /* Identification service       */
#define NSS     1      /* Node Synchronization service */
#define DDS     2      /* Data Download Service        */
#define DUS     3      /* Data Upload Service          */
/* Uzivatelem definovane sluzby 100 - 255              */
#define RCRS    102    /* Read Configuration Register Service */
#define SCRS    103    /* Set Configuration Register Service */
#define RNS     104    /* Read Name Service */

/* Definice datove casti zpravy typu eed.              */

typedef struct eed_data {
			unsigned short   error_code;
			unsigned char    operation_id;
			unsigned char    location_id;
		} EED_DATA;


typedef union msg_data {
			unsigned int 	 ulong_val;
			int     	 	 long_val;
			unsigned short	 uint_val;
			short     	 	 int_val;
			short	     	 int2_val[2];
			unsigned short 	 uint2_val[2];
			char	      	 char4_val[4];
			char	      	 char2_val[2];
			char	      	 char_val;
			float	     	 float_val;
			EED_DATA  	 	 eed_val;
		} MSG_DATA;

/* Struktura definujici obsah ramce, ktery je prenasen po can. */
/* Ramec je rozdeleny na hlavicku a datovou cast. Hlavicka je  */
/* 4 bajty dlouha, datova cast je 0 - 4 bajty dlouha.          */

typedef struct canaero_msg {
			unsigned char    node_id;       /* Adresa zarizeni na can */
			unsigned char    data_type;     /* Datovy typ prenasene hodnoty */
			unsigned char    service_code;  /* Kod servisu nebo 0 */
			unsigned char    message_code;  /* Inkrementuje se s kazdou zpravou */
			MSG_DATA message_data;  /* Prenasena hodnota - zavisle na typu hodnoty */
		} CANAERO_MSG;

/* Struktura definujici CAN zpravu pro ulozeni do bufferu */
/* Ramec je rozdelen na ID, delku a vlastni data 		  */
/* 8B dlouha datova cast, 4B ID a 1B delka zpravy 		  */

typedef struct can_msg {
			unsigned int	can_id;			/* CAN identifikator, 11 bitu nebo 29 bitu */
			unsigned short	msg_len;		/* delka CAN zpravy */
			unsigned char	msg_data[8];    /* data do velikosti 8 bajtu */
		} CAN_MSG;

//---------------------------------------------------------------------------
class TCommFTDI : public TObject
{

private:

		#define MSG_BUF_LEN 	24   /* Maximalni delka bufferu pro ulozeni zpravy */
		#define END_OF_MESSAGE 	13
		#define EOF          	(-1)
		#define RX_BUFF_LEN		1024

		BOOL isFTDIOpen;
		short RxBufferStartIdx;
		short RxBufferEndIdx;
		char  RxBuffer[RX_BUFF_LEN];
		unsigned char msg_buf[MSG_BUF_LEN]; /* Buffer pro prijmutou zpravu */

		BOOL TCommFTDI::CommFTDIConvertData(unsigned char *s, unsigned char *d, unsigned short len);
		BOOL TCommFTDI::CommFTDIhexdec(unsigned char c, unsigned char *d);
		BOOL TCommFTDI::CommFTDIRecMessage(CAN_MSG *can_message);
		unsigned char TCommFTDI::CommFTDISerialGetBuffer(void);
		BOOL TCommFTDI::CommFTDIProcessMessage(unsigned char msg_len, CAN_MSG *can_message);
		BOOL TCommFTDI::CommFTDIProcessHeader(unsigned short *id, unsigned char *len);

public:

		FT_HANDLE ftHandle;

		TCommFTDI();
		BOOL TCommFTDI::CommFTDIIsOpen(void);
		FT_STATUS TCommFTDI::CommFTDICheckStatus(void);
		FT_STATUS TCommFTDI::CommFTDIOpen(unsigned int ftBaudRate);
		FT_STATUS TCommFTDI::CommFTDIClose(void);
		BOOL TCommFTDI::CommFTDISendAeroPacket(unsigned short can_id, unsigned char len, CANAERO_MSG *canaero_msg);
		BOOL TCommFTDI::CommFTDISendCANPacket(CAN_MSG *can_message);
		BOOL TCommFTDI::CommFTDIReceiveAeroPacket(unsigned short *can_id, unsigned char *len, CANAERO_MSG *canaero_msg);
		BOOL TCommFTDI::CommFTDIReceiveCANPacket(CAN_MSG *can_message);
		FT_STATUS TCommFTDI::SetDTR(void);
		FT_STATUS TCommFTDI::ClrDTR(void);
		FT_STATUS TCommFTDI::SetRTS(void);
		FT_STATUS TCommFTDI::ClrRTS(void);

};

#endif
