//////////////////////////////////////////////////////////////////
//
// App:			Shared
// Author:		Milan Korinek
// Version:		1.0
// Notice:		Shared struct and enums
//////////////////////////////////////////////////////////////////

#ifndef __DIGITAL_IO_USB_CARD_DRIVER_SHARED_H__
#define __DIGITAL_IO_USB_CARD_DRIVER_SHARED_H__

/* ============================================ */
/*			     	   Macros			        */
/* ============================================ */

#ifdef __cplusplus
#	define NOMANGLE extern "C"
#else
#	define NOMANGLE
#endif

#ifdef WIN32
#	ifdef COMPILING_DLL
#		define EXPORT NOMANGLE __declspec(dllexport)
#	else
#		define EXPORT NOMANGLE __declspec(dllimport)
#	endif
#else
#	define EXPORT NOMANGLE
#endif

#ifdef __cplusplus
#	define to_enum(value, type) (static_cast<type>(value))
#else
#	define to_enum(value, type)((int)value)
#endif

// Needed for Atmel Studio
#ifdef ATMEL_STUDIO_GCC
#ifndef _In_
#	define _In_
#endif

#ifndef _Out_
#	define _Out_
#endif

#ifndef _Inout_
#	define _Inout_
#endif

#ifndef UINT
#	define UINT uint32_t
#endif

#ifndef UINT32
#	define UINT32 uint32_t
#endif

#ifndef UINT8
#	define UINT8 uint8_t
#endif

#ifndef BOOL
#	define BOOL bool
#endif

#ifndef TRUE
#	define TRUE true
#endif

#ifndef FALSE
#	define FALSE false
#endif
#endif


/* ============================================ */
/*				Constants and enums				*/
/* ============================================ */

//! Product name of Digital I/O USB card
#define DIO_USB_DEVICE_NAME				"Digital I/O USB card"

//! Serial number template: 'DIO' - constant, 'L' - Model, 'C' - number of channels, 'Y' - year, 'M' - month, 'x' - ID 
#define DIO_USB_SERIAL_NUMBER_TEMPLATE	"DIOLLLCCCCYYMMxxxxxxxx"

//! Vendor ID of Atmel
#define DIO_USB_DEVICE_VID				0x03EB

//! Product ID of Atmel ASF Vendor Class
#define DIO_USB_DEVICE_PID				0x2423

//! Endpoint Interrupt In address
#define DIO_EP_INTERRUPT_IN				0x83

//! Endpoint Interrupt Out address
#define DIO_EP_INTERRUPT_OUT			0x06

//! Endpoint Bulk In address
#define DIO_EP_BULK_IN					0x81

//! Endpoint Bulk Out address
#define DIO_EP_BULK_OUT					0x02

//!  Allocated length for all strings used in this API
#define DIO_STRING_MAX_LEN				256

//!  Allocated length for label
#define DIO_LABEL_MAX_LEN				10

//! The maximum number of supported devices
#define DIO_MAX_DEVICES_SUPPORT			32

//! The maximum number of device ports (one port == eight channels)
#define DIO_MAX_PORTS					4

//! Each port has constant number of channels
#define DIO_CHANNELS_ON_PORT			8

//! The maximum number of device channels
#define DIO_MAX_CHANNELS				32


//! Digital I/O USB card return errors

//! Error bases
#define DIO_ERRORS_BASE_SUCCESS			0
#define DIO_ERRORS_BASE_SUCCESS_LAST	99

#define DIO_ERRORS_BASE_FAIL			100
#define DIO_ERRORS_BASE_FAIL_LAST		199

//! Errors definition
typedef enum _DIO_Errors {
	//! Operation is successfully.
	DIO_ERROR_SUCCESS					= DIO_ERRORS_BASE_SUCCESS,
	//! Object is already initiated.
	DIO_ERROR_ALREADY_INIT,
	//! Object is already used.
	DIO_ERROR_ALREADY_USED,
	//! Object already exists.
	DIO_ERROR_ALREADY_EXIST,
	//! Object is already freed.
	DIO_ERROR_ALREADY_FREE,
	
	//! Memory is full, can not create new object.
	DIO_ERROR_FAIL_FULL					= DIO_ERRORS_BASE_FAIL,
	//! Memory is empty/no object available
	DIO_ERROR_FAIL_EMPTY,
	//! Object initialization failed.
	DIO_ERROR_FAIL_INIT,
	//! Can not free object.
	DIO_ERROR_FAIL_FREE,
	//! Can not create new object.
	DIO_ERROR_FAIL_CREATE,
	//! Reuested object not exists.
	DIO_ERROR_FAIL_NOT_EXISTS,
	//! Object is not initialized. You must initialize object first.
	DIO_ERROR_FAIL_NOT_INIT,
	//! Device is disconnected. Can not perform requested operation.
	DIO_ERROR_FAIL_DISCONNECTED,
	//! Object is corrupted. Unknown internal state. You can try free object.
	DIO_ERROR_FAIL_CORRUPTED,
	//! Internal share memory is corrupted.
	DIO_ERROR_FAIL_SHARE_MEM,
	//! Some function failed from libusbK API.
	DIO_ERROR_FAIL_LIBUSBK,
	//! Can not manipulate with object because object is used by other process
	DIO_ERROR_FAIL_USED,
	//! Unknown request - bad parameter.
	DIO_ERROR_FAIL_UNKNOWN_REQUEST,
	//! Could not send data to Digital I/O USB card
	DIO_ERROR_FAIL_SEND,
	//! Could not send data to Digital I/O USB card
	DIO_ERROR_FAIL_RECEIVE,
	//! Unknown error
	DIO_ERROR_FAIL_UNKNOWN,

} DIO_Errors_t;

//! Mode of Digital I/O USB card
typedef enum _DIO_E_Mode {

	//! Same behavior as USB-DIO-32 - ACCES I/O - Question-answer mode
	DIO_E_MODE_ACCES_DIO		= 0,

	//! Digital I/O USB card will be process program from card memory
	DIO_E_MODE_SCRIPTER			= 1,

} DIO_E_Mode_t;


//! Port direction
typedef enum _DIO_E_PortDir {

	//! Set port as input
	DIO_E_PORTDIR_INPUT			= 0,

	//! Set port as output
	DIO_E_PORTDIR_OUTPUT		= 1,

	//! Set port to high impedance. It is not supported by Digital I/O USB card V1.1. Port will be set as input
	DIO_E_PORTDIR_HIGH_Z		= 2,

} DIO_E_PortDir_t;

//! Port pull resistors
typedef enum _DIO_E_PullRes {

	//! Set pull-down resistors
	DIO_E_PULLRES_PULLDOWN		= 0,

	//! Set pull-up resistors
	DIO_E_PULLRES_PULLUP		= 1,

	//! Disconnect pull resistors
	DIO_E_PULLRES_HIGH_Z		= 2,

} DIO_E_PullRes_t;

//! Testing script commands
typedef enum _DIO_E_Command {
	
	//! No operation, can be use for alignment (instead of comments)
	DIO_E_COMMAND_NOP			= 0,

	//! Cycle-Loop command, start point. Arg1 = Cycle label, Arg2 = Number of repetitions.
	DIO_E_COMMAND_CYCLE			= 1,

	//! GoTo command, start point. Arg1 = Goto label.
	DIO_E_COMMAND_GOTO			= 2,

	//! GoTo command, target point. Arg1 = Goto label.
	DIO_E_COMMAND_LABEL			= 3,

} DIO_E_Command_t;

//! Result status of script line or whole script
typedef enum _DIO_E_ScriptResult {

	//! Unknown result
	DIO_E_RESULT_UNKNOWN		= 0,

	//! Operation is in progress
	DIO_E_RESULT_IN_PROGRESS	= 1,

	//! Operation completed successfully
	DIO_E_RESULT_SUCCESS		= 2,

	//! Error, timout
	DIO_E_RESULT_ERR_TIMEOUT	= 3,

	//! Error, desired pattern does not correspond
	DIO_E_RESULT_ERR_NOT_MATCH	= 4,
} DIO_E_ScriptResult_t;

//! Packet types
typedef enum _Packet_Types{

	//! Control endpoint: port direction, pull-up/pull-down resistors settings
	E_PACKET_TYPE_BASIC_CONFIGURE = 0,

	//! Interrupt endpoint: Relevant for mode Access DIO. Data will be 
	// immediate write/read to/from ports (from interrupt).
	E_PACKET_TYPE_IMMEDIATE_READ,

	//! Interrupt endpoint: Relevant for mode Access DIO. Data will be 
	// immediate write/read to/from ports (from interrupt).
	E_PACKET_TYPE_IMMEDIATE_WRITE,

} E_Packet_Types_t;

//! Connection state of Digital I/O USB card
typedef enum _E_DeviceConnectionState {

	//! Device is now disconnected.
	E_DEVICE_CONNECTION_STATE_DISCONNECTED = 0,

	//! Device is now disconnected, but was connected (only for configured devices).
	E_DEVICE_CONNECTION_STATE_WAS_CONNECTED = 1,

	//! Device is now connected, but was disconnected (only for configured devices).
	E_DEVICE_CONNECTION_STATE_WAS_DISCONNECTED = 2,

	//! Device is now connected.
	E_DEVICE_CONNECTION_STATE_CONNECTED = 3,

} E_DeviceConnectionState_t;

//! Device states
typedef enum _E_DeviceState {

	//! Device is closed
	E_DEVICE_STATE_CLOSE = 0,

	//! Device is unconfigured
	E_DEVICE_STATE_UNCONFIGURED,

	//! Device is configured
	E_DEVICE_STATE_CONFIGURED,

	//! Unknown state, device will be ignored
	E_DEVICE_STATE_IGNORE = 255,

} E_DeviceState_t;

/* ============================================ */
/*			     	Structures				    */
/* ============================================ */

//! Basic device information
typedef struct _DIO_DeviceInfo {

	//! USB VID (Vendor ID)
	UINT32 VID;

	//! USB PID (Product ID)
	UINT32 PID;

	//! Device name
	char Name[DIO_STRING_MAX_LEN];

	//! Serial number of device
	char SerialNumber[DIO_STRING_MAX_LEN];

	//! Address of device
	UINT32 Module;

	//! Device version
	char Version[DIO_STRING_MAX_LEN];

	//! Count of ports
	UINT32 Ports;

	//! Count of channels
	UINT32 Channels;

} DIO_DeviceInfo_t;

//! Behavior of Digital I/O USB card
typedef struct _DIO_Behavior {

	//! Mode of Digital I/O USB card
	DIO_E_Mode_t Mode;

} DIO_Behavior_t;

//! Port configuration
typedef struct _DIO_PortConfig {

	//! Default settings of outputs
	UINT8				OutputDefault;

	//! Port direction settings
	DIO_E_PortDir_t		PortDirection;

	//! Port pull resistors settings
	DIO_E_PullRes_t		PullResistors;

} DIO_PortConfig_t;

//! One script line
typedef struct _DIO_ScriptLine {

	//! Array of outputs setting (ports configured as inputs will be ignored)
	UINT8 Outputs[DIO_MAX_PORTS];

	//! Array of mask 0, inputs must stay Low (ports configured as outputs will be ignored)
	UINT8 Mask_Zero[DIO_MAX_PORTS];

	//! Array of mask 1, inputs must stay High
	UINT8 Mask_Ones[DIO_MAX_PORTS];

	//! Array of /, inputs must be changed from Low to High
	UINT8 Mask_Rise[DIO_MAX_PORTS];

	//! Array of \, inputs must be changed from High to Low
	UINT8 Mask_Fall[DIO_MAX_PORTS];

	//! Inputs must not be changed during this time interval
	UINT32 WaitTime;

	//! inputs defined in Mask_Rise and Mask_Fall masks must be changed during this time interval
	UINT32 Timeout;

} DIO_ScriptLine_t;

//! One script command
typedef struct _DIO_ScriptCommand{

	//! Command type
	DIO_E_Command_t Command;

	//! Label, will be converted to number
	char CommandArguments1[DIO_LABEL_MAX_LEN];

	//! Argument for loop, count of repeating
	UINT32 CommandArguments2;

	//! Reserved
	UINT32 CommandArguments3;
} DIO_ScriptCommand_t;

//! Result of one script line
typedef struct _DIO_ScriptLineResult{

	//! Result
	DIO_E_ScriptResult_t CommandLineResult;

	//! Pass time
	UINT32 PassTime;

	//! State of all ports
	UINT8 * PortsState;
} DIO_ScriptLineResult_t;


#endif /* __DIGITAL_IO_USB_CARD_DRIVER_SHARED_H__ */