#ifndef _X_PARALLEL_BUS_H
#define _X_PARALLEL_BUS_H

#define MAX_WAIT_ERROR_PARALLEL_BUS 3 // ìàêñ. êîë-âî îæèäàíèß ÷òåíèß ñ øèíû



typedef union {
    unsigned int all;
    struct {
      unsigned int started:1;
	  unsigned int error:1;
	  unsigned int cmd_start:1;
	  unsigned int count_error:4;
	  unsigned int slave_addr_error:4;
	  unsigned int init:1;
	  unsigned int was_started:1;
	  unsigned int rezerv:3;

    } bit;
} X_PARALLEL_BUS_flags;


typedef struct {
				 unsigned int setup_error_count_read; 	// íàñòðîéêà ìàêñ êîë-âà ïîïûòîê ÷òåíèé ñ øèíû äî âîçíèêíîâåíèß îøèáêè
				 int size_table; 				// êîë-âî äàííûõ â îáìåíå (ñ÷èòàåòñß àâòîìàòè÷åñêè ïðè âûçîâå ôóíêöèè add_table
				 unsigned int tms_adr_data_finish;  	//êîíå÷íûé àäðåñ â ïàìßòè TMS äëß ïîëó÷åíèß äàííûõ ñ øèíû , äîëæåí áûòü ñâîáîäåí îò ñïåö ðåãèñòðîâ 
				 unsigned int tms_adr_data_start;  		// íà÷àëüíûé àäðåñ â ïàìßòè TMS äëß ïîëó÷åíèß äàííûõ ñ øèíû, äîëæåí áûòü ñâîáîäåí îò ñïåö ðåãèñòðîâ
                 int free_table;                // êîë-âî ñâîáîäíûç äàííûõ â òàáëèöå
} X_PARALLEL_BUS_Setup;

#define X_PARALLEL_BUS_Setup_DEFAULTS {MAX_WAIT_ERROR_PARALLEL_BUS, -1, 0, 0, -1}

typedef struct { X_PARALLEL_BUS_flags flags;  		// ôëàãè   
          		 X_PARALLEL_BUS_Setup setup;		// íàñòðîéêà
				 unsigned int slave_addr;  			// íîìåð ïåðèô.ïëàòû
				 unsigned int reg_addr;    			// àäðåñ âíóòðåííåãî ðåãèñòðà  äëß ïàðàë. øèíû â ïåðèô.ïëàòå
				 unsigned int error_count_start; 	// îáùåå êîëè÷-âî îøèáîê çàïóñêà øèíû
				 unsigned int count_read; 			// îáùåå êîëè÷-âî ÷òåíèß øèíû
				 unsigned int adr_table_read; 		// íîìåð èç òàáëèöû äëß ÷òåíèß = 0 _ (size_table-1) , 
				 									// adr_table_read + tms_adr_data_start
				 unsigned int data_table_read; 		// ïðî÷èòàííûé áàéò èç parallel bus, 


//				 unsigned int error_count_write;	// îáùåå êîëè÷-âî îøèáîê çàïèñè
//				 unsigned int error_count_hold; 	// îáùåå êîëè÷-âî îøèáîê çàõâàòà øèíû 
				 void (*clear_table)(); 					// Pointer to read function
				 void (*add_table)(); 					// Pointer to read function
				 void (*start)(); 					// Pointer to read function
				 void (*stop)(); 					// Pointer to read function
				 void (*restart)(); 				// Pointer to read function
				 void (*init)(); 					// Pointer to init function
				 void (*read_status)(); 			// Pointer to init function
				 void (*read_one_data)(); 			// Pointer to init function
                 int (*check_free_table)();           // Pointer to init function

				 }X_PARALLEL_BUS;



/*
// òàéìàóò îæèäàíèß âûïîëåíèß êîìàíäû
#define TIME_OUT_SERIAL_BUS	10000 // max 65535


#define CMD_SERIAL_BUS_READ		0x0000
#define CMD_SERIAL_BUS_WRITE	0x8000

*/


typedef X_PARALLEL_BUS *X_PARALLEL_BUS_handle;

#define X_PARALLEL_BUS_DEFAULTS { 0, \
                                X_PARALLEL_BUS_Setup_DEFAULTS, \
						    	0, \
						    	0, \
                                0, \
						    	0, \
						    	0, \
						    	0, \
						    	(void (*)(Uint32))x_parallel_bus_clear_table,\
						    	(void (*)(Uint32))x_parallel_bus_add_table,\
						    	(void (*)(Uint32))x_parallel_bus_start,\
						    	(void (*)(Uint32))x_parallel_bus_stop,\
						    	(void (*)(Uint32))x_parallel_bus_restart,\
						    	(void (*)(Uint32))x_parallel_bus_init,\
						    	(void (*)(Uint32))x_parallel_bus_read_status,\
						    	(void (*)(Uint32))x_parallel_bus_read_one_data,\
						    	(int (*)(Uint32))x_parallel_bus_check_free_table\
						    } 


void x_parallel_bus_clear_table(X_PARALLEL_BUS_handle);
void x_parallel_bus_add_table(X_PARALLEL_BUS_handle);
void x_parallel_bus_start(X_PARALLEL_BUS_handle);
void x_parallel_bus_stop(X_PARALLEL_BUS_handle);

void x_parallel_bus_restart(X_PARALLEL_BUS_handle);
void x_parallel_bus_init(X_PARALLEL_BUS_handle);

void x_parallel_bus_read_status(X_PARALLEL_BUS_handle);

void x_parallel_bus_read_one_data(X_PARALLEL_BUS_handle);
int x_parallel_bus_check_free_table(X_PARALLEL_BUS_handle);

extern X_PARALLEL_BUS x_parallel_bus_project;


#define read_pbus_value(bit,adr,res)  		{if (bit) res = i_ReadMemory(adr++); else res = 0; }
#define read_pbus_value_full(bit,adr,res)  	{res = i_ReadMemory(adr++); }

#define read_pbus_adc_value(bit,adr,res)  		{if (bit) res = i_ReadMemory(adr++) & 0xfff; else res = 0; }
#define read_pbus_adc_value_full(bit,adr,res)  	{res = i_ReadMemory(adr++) & 0xfff; }

// ver 2
#define read_pbus_value_v2(bit,adr,res)         {if (bit) { res = i_ReadMemory(adr); i_WriteMemory(adr++,0x0); } else res = 0; }
#define read_pbus_value_full_v2(bit,adr,res)    {res = i_ReadMemory(adr); i_WriteMemory(adr++,0x0); }

#define read_pbus_adc_value_v2(bit,adr,res)         {if (bit) { res = i_ReadMemory(adr) & 0xfff; i_WriteMemory(adr++,0x0);} else res = 0; }
#define read_pbus_adc_value_full_v2(bit,adr,res)    {res = i_ReadMemory(adr) & 0xfff; i_WriteMemory(adr++,0x0); }



#endif // end _X_PARALLEL_BUS_H