library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.I2C; -- ******* SCCB Camera Bus Implementation ******* -- -- WARNING: This is work in progress! -- -- ******************************************** package SCCB is subtype tByte is std_logic_vector(7 downto 0); type tSccbWriteState is (SccbWrite, SccbWrite_IDAddr, SccbWrite_IDAddr_Ack, SccbWrite_SubAddr, SccbWrite_SubAddr_Ack, SccbWrite_Data, SccbWrite_Data_Ack, SccbWrite_Stop ); type tSccbReadState is (SccbRead, SccbRead_IDAddr, SccbRead_IDAddr_Ack, SccbRead_Data, SccbRead_Data_Ack, SccbRead_Stop ); type tSCCBdata is record done : boolean; success : boolean; wstate : tSccbWriteState; rstate : tSccbReadState; I2Cdata : I2C.tI2Cdata; end record; constant tSCCBdata_Default : tSCCBdata := ( done => False, success => False, wstate => SccbWrite, rstate => SccbRead, I2CData => I2C.tI2Cdata_Default ); procedure Sccb3PhaseWriteCycle ( signal state : inout tSCCBdata; signal SCL : out std_logic; signal SDA : inout std_ulogic; signal IDAddr : in tByte; signal SubAddr : in tByte; signal DataByte : in tByte; signal done : inout boolean ); procedure Sccb2PhaseWriteCycle ( signal state : inout tSCCBdata; signal SCL : out std_logic; signal SDA : inout std_ulogic; signal IDAddr : in tByte; signal SubAddr : in tByte; signal done : inout boolean ); procedure Sccb2PhaseReadCycle ( signal state : inout tSCCBdata; signal SCL : out std_logic; signal SDA : inout std_ulogic; signal IDAddr : in tByte; signal DataByte : out tByte; signal done : inout boolean ); end SCCB; package body SCCB is procedure Sccb3PhaseWriteCycle ( signal state : inout tSCCBdata; signal SCL : out std_logic; signal SDA : inout std_ulogic; signal IDAddr : in tByte; signal SubAddr : in tByte; signal DataByte : in tByte; signal done : inout boolean ) is begin if not done then case state.wstate is when SccbWrite => if not state.done then I2C.ioMasterStart(state.I2Cdata, SDA, state.done); else state.done <= False; state.wstate <= SccbWrite_IDAddr; end if; when SccbWrite_IDAddr => if not state.done then I2C.ioMasterSend(state.I2Cdata, SCL, SDA, IDAddr, state.done); else state.done <= False; state.wstate <= SccbWrite_IDAddr_Ack; end if; when SccbWrite_IDAddr_Ack => if not state.done then I2C.ioMasterAck(state.I2Cdata, SCL, SDA, state.done, state.success); else state.done <= False; state.wstate <= SccbWrite_SubAddr; end if; when SccbWrite_SubAddr => if not state.done then I2C.ioMasterSend(state.I2Cdata, SCL, SDA, SubAddr, state.done); else state.done <= False; state.wstate <= SccbWrite_SubAddr_Ack; end if; when SccbWrite_SubAddr_Ack => if not state.done then I2C.ioMasterAck(state.I2Cdata, SCL, SDA, state.done, state.success); else state.done <= False; state.wstate <= SccbWrite_Data; end if; when SccbWrite_Data => if not state.done then I2C.ioMasterSend(state.I2Cdata, SCL, SDA, DataByte, state.done); else state.done <= False; state.wstate <= SccbWrite_Data_Ack; end if; when SccbWrite_Data_Ack => if not state.done then I2C.ioMasterAck(state.I2Cdata, SCL, SDA, state.done, state.success); else state.done <= False; state.wstate <= SccbWrite_Stop; end if; when SccbWrite_Stop => if not state.done then I2C.ioMasterStop(state.I2Cdata, SCL, SDA, state.done); else state.done <= False; state.wstate <= SccbWrite; done <= True; end if; end case; end if; end procedure; procedure Sccb2PhaseWriteCycle ( signal state : inout tSCCBdata; signal SCL : out std_logic; signal SDA : inout std_ulogic; signal IDAddr : in tByte; signal SubAddr : in tByte; signal done : inout boolean ) is begin if not done then case state.wstate is when SccbWrite => if not state.done then I2C.ioMasterStart(state.I2Cdata, SDA, state.done); else state.done <= False; state.wstate <= SccbWrite_IDAddr; end if; when SccbWrite_IDAddr => if not state.done then I2C.ioMasterSend(state.I2Cdata, SCL, SDA, IDAddr, state.done); else state.done <= False; state.wstate <= SccbWrite_IDAddr_Ack; end if; when SccbWrite_IDAddr_Ack => if not state.done then I2C.ioMasterAck(state.I2Cdata, SCL, SDA, state.done, state.success); else state.done <= False; state.wstate <= SccbWrite_SubAddr; end if; when SccbWrite_SubAddr => if not state.done then I2C.ioMasterSend(state.I2Cdata, SCL, SDA, SubAddr, state.done); else state.done <= False; state.wstate <= SccbWrite_SubAddr_Ack; end if; when SccbWrite_SubAddr_Ack => if not state.done then I2C.ioMasterAck(state.I2Cdata, SCL, SDA, state.done, state.success); else state.done <= False; state.wstate <= SccbWrite_Stop; end if; when SccbWrite_Stop => if not state.done then I2C.ioMasterStop(state.I2Cdata, SCL, SDA, state.done); else state.done <= False; state.wstate <= SccbWrite; done <= True; end if; when others => null; end case; end if; end procedure; procedure Sccb2PhaseReadCycle ( signal state : inout tSCCBdata; signal SCL : out std_logic; signal SDA : inout std_ulogic; signal IDAddr : in tByte; signal DataByte : out tByte; signal done : inout boolean ) is begin if not done then case state.rstate is when SccbRead => if not state.done then I2C.ioMasterStart(state.I2Cdata, SDA, state.done); else state.done <= False; state.rstate <= SccbRead_IDAddr; end if; when SccbRead_IDAddr => if not state.done then I2C.ioMasterSend(state.I2Cdata, SCL, SDA, IDAddr, state.done); else state.done <= False; state.rstate <= SccbRead_IDAddr_Ack; end if; when SccbRead_IDAddr_Ack => if not state.done then I2C.ioMasterAck(state.I2Cdata, SCL, SDA, state.done, state.success); else state.done <= False; state.rstate <= SccbRead_Data; end if; when SccbRead_Data => if not state.done then I2C.ioMasterRecv(state.I2Cdata, SCL, SDA, DataByte, state.done); else state.done <= False; state.rstate <= SccbRead_Data_Ack; end if; when SccbRead_Data_Ack => if not state.done then I2C.ioMasterAck(state.I2Cdata, SCL, SDA, state.done, state.success); else state.done <= False; state.rstate <= SccbRead_Stop; end if; when SccbRead_Stop => if not state.done then I2C.ioMasterStop(state.I2Cdata, SCL, SDA, state.done); else state.done <= False; state.rstate <= SccbRead; done <= True; end if; end case; end if; end procedure; end SCCB;