"$Id: pld9.src,v 1.19 2001/11/20 16:54:48 warren Exp $
"==============================================================================
#TITLE	 'TIM	PLD9:	TTCrx	interface';
#ENGINEER 'John Lane	/ Dominic A	Hayes	/ Matthew Warren';
#COMPANY	 'University College	London';
#COMMENT	 '';


"==============================================================================
"CVS Update	Log
"==============================================================================
"$Log: pld9.src,v $
"Revision 1.19  2001/11/20 16:54:48  warren
"removed all sgb assignments
"
"Revision 1.18  2001/11/14 20:13:01  warren
"I2C reads working, long delay reset for TTCrx
"
"Revision 1.17  2001/10/25 18:02:18  warren
"fixed TTCcmd register error
"Added sgb testpoints for TTC signal timing tests
"
"Revision 1.16  2001/08/30 12:21:10  warren
"Worrked on I2C
"Tidied, Capitalization
"
"Revision 1.15  2001/08/13 10:49:18  warren
"better code docs
"
"Revision 1.14  2001/08/10 15:35:33  warren
"All new I2C code
"
"Revision 1.13	 2001/08/08	18:42:48	 warren
"new I2C	stuff	and related	simulation
"and signal	names	case names
"
"Revision 1.12	 2001/07/23	11:18:47	 warren
"renamed	signals with proper polarity n prefixes and removed LOW_TRUEs
"
"Revision 1.11	 2001/07/19	10:45:09	 warren
"removed	unused spare bus lines
"
"Revision 1.10	 2001/06/22	13:09:53	 warren
"Changed	some signal	names	to	upper/lowercase variations	- code unchanged
"
"Revision 1.9	2001/06/15 17:02:00	warren
"Cleaned	up	code organisation
"
"Revision 1.8	2001/04/03 15:46:11	warren
"OA_rst stuff
"


"==============================================================================
"Mods	Log
"==============================================================================
"23may00	L1Accept	->	L1Ain, BCntRes	->	BCRin, EvCntRes -> ECRin.
"24may00	reserved, s1_5	removed.
"05jul00	Resetb o/p added just in case.
"14sep00	rstRegTTCdata eqn	added.
"26sep00	DEFAULT_TO LAST_VALUE added to some	register	definitions.
"03oct00	Added	CLK_EN_BY to reg2c and reg28 and	tidied the vme	write	logic	MRMW
"01Nov00	Changed byte order in TTCData	reg to [SubAddr,Dout] -	JBL
"21Mar01	Sorted out nOA_rst polarity
"			Added	OA_rst to keep	things legible
"14Jun01	Re-orgaised	Layout, renamed RegisterCommand to RegisterCmd
"07Aug01	Tied Resetb(TTCrx) to nOA_rst
"08Aug01	Added	I2C read	state_machine -- extensively simulate tested	...
"23Oct01 Fixed TTCCmdReg[7..0] reset polarity
"06Oct01 removed dboe->dboein pins -- not needed any more
"07Oct01 Added long (50us) resetb (TTXrc) reset pulse generator
"        Fixed I2C code for reads (data was reversed)


"==============================================================================
"CODE
"==============================================================================

			INPUT		nOA_rst;
VIRTUAL	NODE		OA_rst;
						OA_rst =	/nOA_rst;

BIPUT		db[15..0]
				ENABLED_BY dboe; "*** was dboe

OUTPUT	dboe;   "\ linked on the board
INPUT		dboein; "/ *** not needed anymore


INPUT		RunMode;	 "From pld3

OUTPUT	Resetb;			"Reset to TTCrx, just in case

			"Resetb =	nOA_rst;
			
			
NODE		TTCrx_resetb_timer_max;
			
NODE		TTCrx_resetb_timer[10..0]
				CLOCKED_BY 	clk9
				CLOCK_ENABLED_BY /TTCrx_resetb_timer_max
				RESET_BY		OA_rst;
				
			TTCrx_resetb_timer =	TTCrx_resetb_timer .+. 1;				
				
				
			"IF TTCrx_resetb_timer = 2 THEN "*** for sim only
			IF TTCrx_resetb_timer = 1111111111b THEN "*** for fit
				TTCrx_resetb_timer_max = 1;
				resetb = 1;

			ELSE					
				TTCrx_resetb_timer_max = 0;
				resetb =	0;
				
			END IF;





" CLOCKS
"------------------------------------------------------------------------------
INPUT		BCclk1b,		"BufFERed Clock40Des1,
			clk9,			"
			BCclk2b;		"BufFERed Clock40Des2;



" STROBES
"------------------------------------------------------------------------------
INPUT		TTCReady,
			SinErrStr,
			DbErrStr,
			DoutStr,
			BrcstStr1,
			BrcstStr2,
			BCntStr,
			EvCntLStr,
			EvCntHStr;


OUTPUT	L1CntLowStrobe,				"Clocked	EvCntLStr.		to	pld4a
			L1CntHighStrobe,				"Clocked	EvCntHStr.		to	pld4a
			BCntStrobe						"Clocked	BCntStr.			to	pld4b
				CLOCKED_BY clk9
				RESET_BY	OA_rst;


			L1CntHighStrobe.D	= EvCntHStr;
			L1CntLowStrobe.D	= EvCntLStr;
			BCntStrobe.D		= BCntStr;


NODE		strobe;							"OR of the 3 xxCntStr
			strobe				= EvCntHStr	OR	EvCntLStr OR BCntStr;


" BUSES
"------------------------------------------------------------------------------
INPUT		BCnt[11..0],
			Brcst[7..2],
			Dout[7..0],
			SubAddr[7..0],
			DQ[3..0];


" DECODED Brcst COMMANDS
"------------------------------------------------------------------------------
OUTPUT	CALin,
			FERin,
			Sparein
				CLOCKED_BY clk9
				RESET_BY	OA_rst
				DEFAULT_TO 0;


			" Short Format	Commands
			"=---------------------=
			IF	(BrcstStr2)	THEN
				CALin.D	 =	Brcst[6];
			END IF;

			IF	(BrcstStr1)	THEN
				FERin.D	 =	Brcst[2];
			END IF;

			Sparein.D =	0;



" COMMANDS
"------------------------------------------------------------------------------
INPUT		L1Ain,	"L1Ain.
			BCRin,	"BCRin.
			ECRin;	"ECRin.



" DECODED BCnt	COMMANDS
"------------------------------------------------------------------------------
OUTPUT	BCntIn[11..0]
				CLOCKED_BY clk9
				CLOCK_ENABLED_BY strobe
				RESET_BY	OA_rst;

			BCntIn.D	= BCnt;



" DECODED Dout, SubAddr, DQ COMMANDS
"------------------------------------------------------------------------------
OUTPUT	TTIDin[9..0]
				CLOCKED_BY clk9
				CLOCK_ENABLED_BY ClkEnTType
				RESET_BY	OA_rst;

NODE		ClkEnTType DEFAULT_TO 0;

OUTPUT	TTypeStrobe
				CLOCKED_BY clk9
				RESET_BY	OA_rst
				DEFAULT_TO 0;

NODE		RegisterTTCselect[3..0]			"Reg28
				CLOCKED_BY nLEb2
				CLOCK_ENABLED_BY (bWriteb AND	Reg28)
				RESET_BY	OA_rst;

			RegisterTTCselect	= db[3..0];


NODE		RegisterTTCdata[15..0]	"reg26
				CLOCKED_BY clk9
				CLOCK_ENABLED_BY ClkEnRegTTCdata
				RESET_BY	rstRegTTCdata;

NODE		ClkEnRegTTCdata DEFAULT_TO	0;
NODE		rstRegTTCdata;							"resets RegisterTTCdata
NODE		wr26 DEFAULT_TO 0;					"VME write to Reg26



			"Long	Format Data
			"=----------------=
			IF	(DoutStr) THEN
				IF	(DQ =	RegisterTTCselect) THEN
					ClkEnRegTTCdata =	1;
				END IF;
			END IF;

			RegisterTTCdata =	[	SubAddr[7..0],	Dout[7..0] ];

			rstRegTTCdata	 =	 (OA_rst	OR	wr26);



			" TType
			"=-----=
			IF	(DoutStr) THEN
				IF	( (SubAddr = 0) AND (DQ	= 0) ) THEN
					TTypestrobe.D = 1;
					ClkEnTType = 1;
				END IF;
			END IF;

			TTIDin[7..0].D	= Dout[7..0];
			TTIDin[9..8].D	= 0;




" SHORT FORMAT	COMMANDS	REGISTER
"------------------------------------------------------------------------------

NODE		RegisterCmd0[5..0]
				CLOCKED_BY clk9
				CLOCK_ENABLED_BY BrcstStr1
				RESET_BY	/rstRegCmd;

NODE		RegisterCmd1[7..6]
				CLOCKED_BY clk9
				CLOCK_ENABLED_BY BrcstStr2
				RESET_BY	/rstRegCmd;

NODE		RegisterCmd2[15..8];			"Self-clocking	register.


NODE		RegisterCmd[15..0]; "reg2E		"Combined Commands Register.

NODE		rstRegCmd;
NODE		wr2E
				DEFAULT_TO 0;

			rstRegCmd =	/(wr2E OR OA_rst); "self-clocking async reset; LOW	resets

			RegisterCmd0[5..2]	= Brcst[5..2];
			RegisterCmd0[1]		= ECRin;		 "Brcst[1]
			RegisterCmd0[0]		= BCRin;		 "Brcst[0]

			RegisterCmd1[7..6]	= Brcst[7..6];

			RegisterCmd2[15]		= 0;
			RegisterCmd2[14]		= rstRegCmd	AND (TTCReady	OR	RegisterCmd2[14]);
			RegisterCmd2[13]		= rstRegCmd	AND (SinErrStr	OR	RegisterCmd2[13]);
			RegisterCmd2[12]		= rstRegCmd	AND (DbErrStr	OR	RegisterCmd2[12]);
			RegisterCmd2[11]		= rstRegCmd	AND (DoutStr	OR	RegisterCmd2[11]);
			RegisterCmd2[10]		= rstRegCmd	AND (BrcstStr2	OR	RegisterCmd2[10]);
			RegisterCmd2[9]		= rstRegCmd	AND (BrcstStr1	OR	RegisterCmd2[ 9]);
			RegisterCmd2[8]		= rstRegCmd	AND (L1Ain		OR	RegisterCmd2[ 8]);

			RegisterCmd[15..0] =	[	RegisterCmd2[15..8],
											RegisterCmd1[7..6],
											RegisterCmd0[5..0]	];



"------------------------------------------------------------------------------
"
" I2C	INTERFACE
"
"------------------------------------------------------------------------------

"	Background:
"  -----------
"	The I2C system works in cycles, triggered by the I2C_Go bit.
"	Each cycle uses 2 separate I2C datagrams (ie 2x start->stop)
"  The I2C spec reckons it can be done with one 'complex mode' datagram,
"  but I figure 2 is safer.
"	datagram 1 writes the i2c chip_id + TTCrx register_id
"	datagram 2 writes the i2c chip_id + R/W data to/from TTCrx reg.
"  The I2C address space is (as I understand it) defined as follows:
" 	[ TTCrx I2C_ID[5:0], Data/nRegPointer, Read/nWrite ]
"	Using the TTCrx default I2C ID: 0 (anti spec. btw *) the following useful
"  I2C ADDRESSES on the TTXrx: 
"	 0x02 = Write Reg_Pointer (to setup TTXrx reg access)
"	 0x01 = Read Data
"	 0x00 = Write Data

"  *[The I2C spec reserves certain addresses, but I don't think the TTCrx obeys this]
"
"	This actual addressing is hidden from the TIM user. who only needs to specify
"	the R/nW, the TTCrx reg_pointer and the data if writing

"  ------------------------------------------------------------
"  USAGE:
"  ------------------------------------------------------------

"  I2C Register Definition (0x2C)
"  -------------------------------
"	 bit 15	=	(W)I2C_Go, (R)I2C_Busy
"	 bit 14	=	I2C_Enable (I2C clock Enable)
"	 bit 13	=	I2C_Read_nWrite
"	 bit 12:8 =	I2C_Pointer (TTCrx Register Number)	
"   bit 7:0	=	I2C_Data (read from/to write to TTrx)
"	
"
"  1) Enable the I2C clock (1MHz)
"     wr 0x4000

"  2) Read TTCrx I2C Status register (22d = 10110b):
"      2C wr 0xF600  [ ie. go, ena, rd,  reg_id,   data   ]     
"                    [      1   1    1   10110   00000000 ] = F600
"                    NOTE: during reads the data is ignored.
"      2C rd
"      Data returned in the lower byte


"   I2C_Busy
"   --------
"   During the I2C cycle the I2C_Busy bit is set.
"   If the I2C 'hangs' I2C_Busy bit will stay set 
"   The TTCrx requires 50us to reset, 
"   during this time the I2C_Busy bit will stay set
 

"  Examples :
"  -------------------------
"  1)  Read TTCrx Status (22d)
"        2C wr 0xf600
"        2C rd

"  2)  Read TTCrx Control Reg (3d)
"        2C wr 0xE300
"        2C rd

"  3)  Write TTCrx Delay Reg (0d) with 1
"        2C wr 0xC001

"  4)  Read TTCrx Delay Reg (0d)
"        2C wr 0xE000
"        2C rd
  


"----------------------------------------------------------
"Generate Serial Transfer clock
"----------------------------------------------------------

NODE		I2CClockCounter[4..0]
					CLOCKED_BY	clk9
					"CLOCK_ENABLED_BY I2C_Enable
					RESET_BY /I2C_Enable OR OA_rst;


NODE		I2CClockCounter_max
				DEFAULT_TO 0;

												 "###	set clock freq	here 20Mhz/(x-1)
			IF	I2CClockCounter =	21 THEN "*** should be 21 
				  I2CClockCounter_max =	1;
				  I2CClockCounter	= 0;
			ELSE
				I2CClockCounter =	I2CClockCounter .+. 1;


			END IF;

"###### for	simulation only use below (less clocks)
"NODE		I2C_clk;
"			I2C_clk = clk9;

T_FLOP	I2C_clk
				CLOCKED_BY I2CClockCounter_max
				RESET_BY	OA_rst;
			I2C_clk.T =	1;


"----------------------------------------------------------
"I2C pins and OEs
"----------------------------------------------------------

"INPUT 	SCL, SDA; "*** this is for debug only


BIPUT	SCL						"Serial CLock.	(i2c MASTER	issues clock)
				ENABLED_BY /xSCL;

BIPUT	SDA
				ENABLED_BY /xSDA;	"Serial Data.
			SCL =	0;
			SDA =	0;

NODE		xSCL,		"*** these required so we never actually
			xSDA		"		drive	the bus
				DEFAULT_TO 1;



"----------------------------------------------------------
"I2C Register Definition (Reg2C)
"----------------------------------------------------------




NODE		I2C_OA_rst;
		
NODE		I2C_Busy;

NODE		I2C_Go
				CLOCKED_BY nLEb2
				CLOCK_ENABLED_BY (bWriteb AND	Reg2C)
				RESET_BY	i2c_reset OR I2C_OA_rst;
				
NODE		I2C_Enable,
			I2C_Read_nWrite,
			I2C_Pointer[4..0]
				CLOCKED_BY nLEb2
				CLOCK_ENABLED_BY (bWriteb AND	Reg2C)
				RESET_BY	OA_rst;
			
NODE		I2C_Data[7..0]
				CLOCKED_BY i2c_data_clk
				RESET_BY	OA_rst;


			I2C_Go				= db[15];
			I2C_Enable			= db[14];
			I2C_Read_nWrite	= db[13];
			I2C_Pointer[4..0]	= db[12..8];
			

NODE		RegisterI2C[15..0];	"Reg2C
			RegisterI2C[15..0] =	[
											I2C_Busy,
											I2C_Enable,
											I2C_Read_nWrite,
											I2C_Pointer[4..0],
											I2C_Data[7..0]
										];

			I2C_OA_rst = /I2C_Enable OR OA_rst;			
			I2C_Busy = I2C_Go OR /resetb;



"------------------------------------------------------------------------------
"THE I2C MACHINE
"------------------------------------------------------------------------------

NODE		i2c_reset,
			i2c_data_clk,
			i2c_data_shift_clk
				DEFAULT_TO 0;

			IF	(I2C_Busy) THEN
				I2C_Data[7..0]	= [I2C_Data[6..0], SDA];
				i2c_data_clk =	i2c_data_shift_clk;

			ELSIF	(bWriteb	AND Reg2C) THEN
				I2C_Data	= db[7..0];
				i2c_data_clk =	nLEb2;

			ELSE
				I2C_Data	= I2C_Data;

			END IF;
						
																			
NODE		i2c_data_mode_set,
			i2c_data_npointer_reset
				DEFAULT_TO 0;
										
NODE		i2c_data_npointer
				CLOCKED_BY	i2c_data_mode_set
				RESET_BY i2c_data_npointer_reset OR OA_rst;
			i2c_data_npointer = 1;

NODE		i2c_write_data[7..0];
			
			IF (i2c_data_npointer) THEN
				i2c_write_data = I2C_Data;
				
			ELSE
				i2c_write_data = [0,0,0, I2C_Pointer];

			END IF;
				
			
			
NODE		i2c_id[7..0];
			i2c_id[7..2] =	0;	"*** this is a preset, it may need to be from ???

			i2c_id[1] =	i2c_Data_nPointer;
			i2c_id[0] =	i2c_Read_nWrite AND i2c_Data_nPointer;



"--------------------------------------------------------------------
"The actual machine
"--------------------------------------------------------------------


			STATE_MACHINE	i2c_machine
				CLOCKED_BY	i2c_clk
				RESET_BY		I2C_OA_rst;
			

				STATE	reset_state:		"This state sets the defaults
					xSCL = 1;				"for all state variables
					xSDA = 1;
					
					i2c_data_npointer_reset = 1;
						
					IF	(I2C_Go) THEN
						GOTO	start0;
					
					ELSE
						GOTO reset_state;
					
					END IF;


			"---------------------------------------------------------
			"SEND	START	CONDITION
			"---------------------------------------------------------
				STATE	start0:			"idle time to gather wits
					xSCL = 1;
					xSDA = 1;
					GOTO	start1;

			
				STATE	start1:
					xSCL = 1;
					xSDA = 0;				"data low first
					GOTO	start2;

				STATE	start2:
					xSCL = 0;				" then clock low
					xSDA = 0;

					GOTO	send_id7;


			"---------------------------------------------------------
			"SEND	I2C CHIP	ID
			"---------------------------------------------------------
				"ID7 --------
				STATE	send_id7:
					xSCL = 0;
					xSDA = i2c_id[7];
					GOTO	send_id7c;

				STATE	send_id7c:
					xSCL = 1;
					xSDA = i2c_id[7];
					GOTO	send_id6;

				"ID6 ---------
				STATE	send_id6:
					xSCL = 0;
					xSDA = i2c_id[6];
					GOTO	send_id6c;

				STATE	send_id6c:
					xSCL = 1;
					xSDA = i2c_id[6];
					GOTO	send_id5;

				"ID5 --------
				STATE	send_id5:
					xSCL = 0;
					xSDA = i2c_id[5];
					GOTO	send_id5c;

				STATE	send_id5c:
					xSCL = 1;
					xSDA = i2c_id[5];
					GOTO	send_id4;

				"ID4 --------
				STATE	send_id4:
					xSCL = 0;
					xSDA = i2c_id[4];
					GOTO	send_id4c;

				STATE	send_id4c:
					xSCL = 1;
					xSDA = i2c_id[4];
					GOTO	send_id3;

				"ID3 --------
				STATE	send_id3:
					xSCL = 0;
					xSDA = i2c_id[3];
					GOTO	send_id3c;

				STATE	send_id3c:
					xSCL = 1;
					xSDA = i2c_id[3];
					GOTO	send_id2;

				"ID2 --------
				STATE	send_id2:
					xSCL = 0;
					xSDA = i2c_id[2];
					GOTO	send_id2c;

				STATE	send_id2c:
					xSCL = 1;
					xSDA = i2c_id[2];

					GOTO	send_id1;

				"ID1 --------
				STATE	send_id1:
					xSCL = 0;
					xSDA = i2c_id[1];

					GOTO	send_id1c;

				STATE	send_id1c:
					xSCL = 1;
					xSDA = i2c_id[1];

					GOTO	send_id0;

				"ID0 --------
				STATE	send_id0:
					xSCL = 0;
					xSDA = i2c_id[0];

					GOTO	send_id0c;

				STATE	send_id0c:
					xSCL = 1;
					xSDA = i2c_id[0];

					GOTO	send_id_done;

				"ID tidy	finish -----
				STATE	send_id_done:
					xSCL = 0;
					xSDA = 0;

					GOTO	id_release_bus;

				"-----------------------
				"ID: WAIT FOR SLAVE ACK
				"-----------------------
				STATE	id_release_bus:
					xSCL = 0;
					xSDA = 1;			"release sdl

					GOTO	id_wait_ack;

				"--------
				STATE	id_wait_ack:
					xSDA = 1;	  
					xSCL = 1;

					IF	SDA =	0 THEN 	"read data
						GOTO id_action_ack;
						
					ELSE
						GOTO id_wait_ack;

					END IF;						"*** should be timeout here
					
				STATE id_action_ack:
					xSCL = 0;
					xSDA = 1;
					
					IF (/i2c_data_npointer) THEN 
						GOTO write_byte7; 	" --- WRITE POINTER
						
					ELSIF (i2c_Read_nWrite) THEN
						GOTO	read_byte7;		"--- I2C	READ MODE ---
												
					ELSE
						GOTO  write_byte7; 	"--- I2C WRITE MODE --
							
					END IF;



			"---------------------------------------------------------
			"READ	BYTE
			"---------------------------------------------------------
				"read_byte7	--------
				STATE	read_byte7:
					xSCL = 0;
					xSDA = 1;
					i2c_data_shift_clk =	0;
					GOTO	read_byte7c;


				STATE	read_byte7c:
					xSCL = 1;
					xSDA = 1;
					i2c_data_shift_clk =	1;
					GOTO	read_byte6;


				"read_byte6	---------
				STATE	read_byte6:
					xSCL = 0;
					xSDA = 1;
					i2c_data_shift_clk =	0;
					GOTO	read_byte6c;

				STATE	read_byte6c:
					xSCL = 1;
					xSDA = 1;
					i2c_data_shift_clk =	1;
					GOTO	read_byte5;

				"read_byte5	--------
				STATE	read_byte5:
					xSCL = 0;
					xSDA = 1;
					i2c_data_shift_clk =	0;
					GOTO	read_byte5c;

				STATE	read_byte5c:
					xSCL = 1;
					xSDA = 1;
					i2c_data_shift_clk =	1;
					GOTO	read_byte4;

				"read_byte4	--------
				STATE	read_byte4:
					xSCL = 0;
					xSDA = 1;
					i2c_data_shift_clk =	0;
					GOTO	read_byte4c;

				STATE	read_byte4c:
					xSCL = 1;
					xSDA = 1;
					i2c_data_shift_clk =	1;
					GOTO	read_byte3;

				"read_byte3	--------
				STATE	read_byte3:
					xSCL = 0;
					xSDA = 1;
					i2c_data_shift_clk =	0;
					GOTO	read_byte3c;

				STATE	read_byte3c:
					xSCL = 1;
					xSDA = 1;
					i2c_data_shift_clk =	1;
					GOTO	read_byte2;

				"read_byte2	--------
				STATE	read_byte2:
					xSCL = 0;
					xSDA = 1;
					i2c_data_shift_clk =	0;
					GOTO	read_byte2c;

				STATE	read_byte2c:
					xSCL = 1;
					xSDA = 1;
					i2c_data_shift_clk =	1;
					GOTO	read_byte1;

				"read_byte1	--------
				STATE	read_byte1:
					xSCL = 0;
					xSDA = 1;
					i2c_data_shift_clk =	0;
					GOTO	read_byte1c;

				STATE	read_byte1c:
					xSCL = 1;
					xSDA = 1;
					i2c_data_shift_clk =	1;
					GOTO	read_byte0;

				"read_byte0	--------
				STATE	read_byte0:
					xSCL = 0;
					xSDA = 1;
					i2c_data_shift_clk =	0;
					GOTO	read_byte0c;

				STATE	read_byte0c:
					xSCL = 1;
					xSDA = 1;
					i2c_data_shift_clk =	1;
					GOTO	read_byte_done;


				"---------------------
				"READ SEND ACK
				"---------------------
				STATE	read_byte_done:
					xSCL = 0;
					xSDA = 1;
					i2c_data_shift_clk =	0;
					GOTO	give_ack0;

				STATE	give_ack0:
					xSCL = 0;
					xSDA = 0;
					GOTO	give_ack1;

				STATE	give_ack1:
					xSCL = 1;
					xSDA = 0;
					GOTO	send_stop;


			"---------------------------------------------------------
			"WRITE BYTE
			"---------------------------------------------------------
				"write_byte7 --------
				STATE	write_byte7:
					xSCL = 0;
					xSDA = i2c_write_data[7];
					GOTO	write_byte7c;


				STATE	write_byte7c:
					xSCL = 1;
					xSDA = i2c_write_data[7];
					GOTO	write_byte6;


				"write_byte6 ---------
				STATE	write_byte6:
					xSCL = 0;
					xSDA = i2c_write_data[6];
					GOTO	write_byte6c;

				STATE	write_byte6c:
					xSCL = 1;
					xSDA = i2c_write_data[6];
					GOTO	write_byte5;

				"write_byte5 --------
				STATE	write_byte5:
					xSCL = 0;
					xSDA = i2c_write_data[5];
					GOTO	write_byte5c;

				STATE	write_byte5c:
					xSCL = 1;
					xSDA = i2c_write_data[5];
					GOTO	write_byte4;

				"write_byte4 --------
				STATE	write_byte4:
					xSCL = 0;
					xSDA = i2c_write_data[4];
					GOTO	write_byte4c;

				STATE	write_byte4c:
					xSCL = 1;
					xSDA = i2c_write_data[4];
					GOTO	write_byte3;

				"write_byte3 --------
				STATE	write_byte3:
					xSCL = 0;
					xSDA = i2c_write_data[3];
					GOTO	write_byte3c;

				STATE	write_byte3c:
					xSCL = 1;
					xSDA = i2c_write_data[3];
					GOTO	write_byte2;

				"write_byte2 --------
				STATE	write_byte2:
					xSCL = 0;
					xSDA = i2c_write_data[2];
					GOTO	write_byte2c;

				STATE	write_byte2c:
					xSCL = 1;
					xSDA = i2c_write_data[2];
					GOTO	write_byte1;

				"write_byte1 --------
				STATE	write_byte1:
					xSCL = 0;
					xSDA = i2c_write_data[1];
					GOTO	write_byte1c;

				STATE	write_byte1c:
					xSCL = 1;
					xSDA = i2c_write_data[1];
					GOTO	write_byte0;

				"write_byte0 --------
				STATE	write_byte0:
					xSCL = 0;
					xSDA = i2c_write_data[0];
					GOTO	write_byte0c;

				STATE	write_byte0c:
					xSCL = 1;
					xSDA = i2c_write_data[0];
					GOTO	wr_release_bus;


				"---------------------------
				"WRITE: WAIT FOR SLAVE ACK
				"---------------------------
				STATE	wr_release_bus: "This delay helps show	ACKS on scope/sim	etc
					xSCL = 0;
					xSDA = 1;
					GOTO	wr_release_bus1;

				STATE	wr_release_bus1:
					xSCL = 1;
					xSDA = 1;
					GOTO	wr_wait_ack;

				"--------
				STATE	wr_wait_ack:
					xSCL = 1;
					xSDA = 1;

					IF	SDA =	0 THEN
						GOTO	wr_action_ack;		"everything	is	fine,	continue

					ELSE		   "*** this may need a timeout counter .....
						GOTO	 wr_wait_ack;

					END IF;
			

				STATE wr_action_ack:
	 				xSCL = 0;
					xSDA = 1;
					GOTO	send_stop;
					
				 


			"---------------------------------------------------------
			"SEND	STOP
			"---------------------------------------------------------
				STATE	send_stop:
					xSCL = 0;
					xSDA = 0;
					GOTO	send_stop1;

				STATE	send_stop1:
					xSCL = 1;
					xSDA = 0;
					GOTO	send_stop2;

				STATE	send_stop2:
					xSCL = 1;
					xSDA = 1;
					GOTO	finished;

				STATE	finished:
					xSCL = 1;
					xSDA = 1;
					
					IF	(/i2c_data_npointer) THEN
						GOTO repeat_for_data;
						
					ELSE
						i2c_reset = 1;
						GOTO reset_state;
					
					END IF;
					
					
				"--------------------------	
				STATE	repeat_for_data:
					i2c_data_mode_set = 1;
					GOTO	start0;
					
			"----------------------------
			"EMERGENCY STOP
			"----------------------------
			"*** other stuff could be added here ....				
		comp_off
				STATE	emergency_stop:
					xSCL = 0;
					xSDA = 0;
					GOTO	emergency_send_stop1;

				STATE	emergency_send_stop1:
					xSCL = 1;
					xSDA = 0;
					GOTO	emergency_send_stop2;

				STATE	emergency_send_stop2:
					xSCL = 1;
					xSDA = 1;
					i2c_reset = 1; 	"*** DONT RESET: leave the thing BUSY
					GOTO reset_state;
		comp_on
				


			"---------------------------------------------------------
			END i2c_machine;




"------------------------------------------------------------------------------
" VME	ACCESS
"------------------------------------------------------------------------------


INPUT		bWriteb,
			bReadb,
			nLEb2;

INPUT		Reg26,			"RegisterTTCdata.
			Reg28,			"RegisterTTCselect.
			Reg2E;			"RegisterCmd.

INPUT		Reg2C;			"RegisterI2C.




			IF		(bWriteb	AND Reg26) THEN
				wr26 = 1;							"resets TTCdata register.
			ELSIF	(bWriteb	AND Reg2E) THEN
				wr2E = 1;							"resets Commands register.
			END IF;

			IF	(bReadb)	THEN
				IF	(Reg26) THEN
					db	= RegisterTTCdata;

				ELSIF	(Reg28) THEN
					db[3..0]	= RegisterTTCselect;
					db[15..4] =	0;	"*** not	needed but better	for debug

				ELSIF	(Reg2C) THEN
					db	= RegisterI2C;

				ELSIF	(Reg2E) THEN
					db	= RegisterCmd;

				END IF;
			END IF;


			dboe = bReadb AND	(Reg26 OR Reg28 OR Reg2C OR Reg2E);		"OE



"==============================================================================
" SPARE I/O
"==============================================================================

"*** I2C Test
"OUTPUT	sgbC[7..0];				"TIM1
"			
"			sgbC[0] = SCL;				"pl163
"			sgbC[1] = SDA;				"pl164
"			sgbC[2] = xSCL;			"pl165
"			sgbC[3] = xSDA;			"pl166
"			sgbC[4] = I2C_enable;	"pl167
"			sgbC[5] = I2C_GO;			"pl168
"			sgbC[6] = i2c_data_clk;	"pl169
"			sgbC[7] = I2C_reset;		"pl170


"OUTPUT	sgbC[7..0];

"			sgbC[5] = BCntStr;
"			sgbC[4] = EvCntHStr;        
"			sgbC[3] = EvCntLStr;        
"			sgbC[2] = L1CntHighStrobe;	                  
"			sgbC[1] = L1CntLowStrobe;
"			sgbC[0] = BCntStrobe;			
                   
                   

INPUT		sgbA[7..0];		 "Spare global	bus A
INPUT		sgbB[7..0];		 "Spare global	bus B
INPUT 	sgbC[7..0];		 "Spare global	bus C
INPUT		sgbD[5..0];		 "Spare global	bus D

INPUT		s3_9[7..0];		 "Spare local bus
INPUT		s8_9[7..0];		 "Spare local bus







"==============================================================================