Master I2C
Transcription
Master I2C
Raguin Alexis Reynaud Julien Polytech’Clermont-Ferranf CUST 2007 Projet B1. Master I2C Cette étude de master I2C a été effectuée pour pouvoir s’adapter sur un bus OPB. D’où l’intérêt de séparer le bus d’adresse, du bus de donnée et de récupérer plusieurs signaux. Les lignes ci-dessous sont des raccourcis pour aller directement au chapitre désiré: CLK_gene (Génération d’horloge). Code VHDL FSM (Machine à etats finis) Entree / Sortie Reseau de Petri Symbol de la FSM Code VHDL Pour tout renseignement, contact : [email protected] Projet B1 Co-Design Page 1 sur 9 Raguin Alexis Reynaud Julien Polytech’Clermont-Ferranf CUST 2007 CLK_gene (Génération d’horloge). Ce système permet de générer les 2 horloges nécessaires au système Une horloge pour la commande des signaux SDA Une horloge pour la commande des signaux SCL avec un retard d’un quart de temps. Son code VHDL : clk_gen_I2C.vhd : Pour les tests le timer1 est inhibé, car il adapte le sytème I2C (100KHZ) à l’horloge du système (100 MHz). entity clk_gen_I2C is Port ( Gclk : in STD_LOGIC; clk_scl : out STD_LOGIC; clk_sda : out STD_LOGIC); end clk_gen_I2C; architecture Behavioral of clk_gen_I2C is --signal timer1 : std_logic_vector(7 downto 0):="00000000"; signal timer2 : std_logic_vector(1 downto 0):="00"; begin process(Gclk) begin if(Gclk'event and Gclk='1') then --timer1<=timer1+1; -IF(timer1>248) then -timer1<=(others=>'0'); timer2<=timer2+1; if (timer2=1 or timer2=2) then clk_sda<='1'; else clk_sda<='0'; end if; if (timer2>1 ) then clk_scl<='1'; else clk_scl<='0'; end if; -end IF; end if; end process; --clk_scl<=timer2(1); -- technique utilisé avant --clk_sda<=timer2(1) xor timer2(0); -- technique utilisé avant end Behavioral; Projet B1 Co-Design Page 2 sur 9 Raguin Alexis Reynaud Julien Polytech’Clermont-Ferranf CUST 2007 FSM (34 MacroCells): C’est le cerveau du système I2C maître, elle est active sur front descendant de l’horloge SDA. Ses entrées/sorties : adresse_in : in STD_LOGIC_VECTOR (6 downto 0); -- adresse de l'esclave donnee_in : in STD_LOGIC_VECTOR (7 downto 0); -- Donnee a envoyer donnee_out : out STD_LOGIC_VECTOR (7 downto 0); -- Donnee recu ready1_busy0 : out STD_LOGIC; -- Bus I2C occupe ou libre end_data : out STD_LOGIC; -- fin d’envoie de la donnée Read1_Write0 : in STD_LOGIC; -- Mode écriture ou lecture START : in STD_LOGIC; -- Condition de départ asynchrone loop_mode : in STD_LOGIC; -- actif a l'état haut, permet d'envoyer plusieurs donnée en mode écriture test_debug_SDA_ack : in STD_LOGIC; -- a supprimer-- permet lors des tests de simuler l'ACK addr_ok : out STD_LOGIC; -- Valide si l'adresse est reconnue par un esclave SCL : out STD_LOGIC; -- signal SCL du bus IIC SDA : inout STD_LOGIC); -- signal SDA du bus IIC Projet B1 Co-Design Page 3 sur 9 Raguin Alexis Reynaud Julien Polytech’Clermont-Ferranf CUST 2007 Réseau de Petri Projet B1 Co-Design Page 4 sur 9 Raguin Alexis Reynaud Julien Polytech’Clermont-Ferranf CUST 2007 Symbole de la FSM : Projet B1 Co-Design Page 5 sur 9 Raguin Alexis Reynaud Julien Polytech’Clermont-Ferranf CUST 2007 Son code VHDL : FSM_master_I2C.vhd entity FSM_master_I2C is Port ( adresse_in : in STD_LOGIC_VECTOR (6 downto 0); -- addresse de l'esclave donnee_in : in STD_LOGIC_VECTOR (7 downto 0); -- Donnee a envoyer donnee_out : out STD_LOGIC_VECTOR (7 downto 0); -- Donnee recu ready1_busy0 : out STD_LOGIC; -Bus I2C occupe ou libre end_data : out STD_LOGIC; -- fin denvoie de la donnee Read1_Write0 : in STD_LOGIC; -Mode ecriture ou lecture START : in STD_LOGIC; -- Condition de depart asynchrone loop_mode : in STD_LOGIC; -- actif a l'etat haut, permet d'envoyer plusieur donnee en mode ecriture test_debug_SDA_ack : in STD_LOGIC;-- a supprimer-- permet lors des tests de simuler l'ACK clk_SCL : in STD_LOGIC;-- a supprimer -- permet de verifier le bonne etat clk SCL clk_SDA : in STD_LOGIC;-- a supprimer -- permet de verifier le bonne etat clk SDA addr_ok : out STD_LOGIC; -Valide si l'adresse est reconnue par un esclave SCL : out STD_LOGIC; -- signal SCL du bus IIC SDA : out STD_LOGIC); -- signal SDA du bus IIC -SDA : inout STD_LOGIC); -- a recativer avec l'esclave (plus simple pour les tests) end FSM_master_I2C; architecture Behavioral of FSM_master_I2C is signal memo_SCL : std_logic:='0'; signal compt : std_logic_vector(2 downto 0):=(others=>'0'); signal data_mem : std_logic_vector(7 downto 0):=(others=>'0'); signal etat : std_logic_vector(3 downto 0):=(others=>'0'); begin process(clk_SCL,etat) begin IF clk_SCL'event and clk_SCL='1' then -- par la suite il sera possible que le test de l'ack soit fait dans ce process -- qui est actif sur etat haut de SCL -- a suivre ... if(etat(3 downto 1)="000" ) then --or etat="1111"; memo_SCL<='0'; else memo_SCL<='1'; Projet B1 Co-Design Page 6 sur 9 Raguin Alexis Reynaud Julien Polytech’Clermont-Ferranf CUST 2007 end if; end IF; end process; process(clk_SDA,START) begin -- La condition de START est detecté de maniere asynchrone -- Elle place le systeme en condition de depart if START='1' then etat<="0001"; SDA<='1'; else IF clk_SDA'event and clk_SDA='1' then compt<=compt+1; case etat is when "0000" => -- Etape d'attente rien ne se passe dedans SDA<='1'; when "0001" => -- Etape de depart SDA<='0'; etat(1)<='1'; data_mem <= adresse_in & Read1_Write0; compt<=(others=>'0'); when "0011" => -- envoie de l'adresse data_mem<=data_mem(6 downto 0)&'0'; SDA<=data_mem(7); if (compt=7) then etat(0)<='0'; end if; when "0010" => -- Etape de test de l'acknowledge SDA<='Z'; compt<=(others=>'0'); if (Read1_Write0='0') then -- mode Write data_mem <= donnee_in; -- on charge la donnee a envoyer end if; etat(3)<=Read1_Write0; -- selectionne le mode RW if(test_debug_SDA_ack='0') then -- permet le test d'ack en mode debug etat(2)<='1'; ---start --- Ci dessous est la partie qui sera utilisé sur un esclave, ici inhibé pour les tests elsif (SDA='1') then etat(1)<='0'; -- si pas d'ack on repart dans un mode d'attente de else etat(2)<='1'; -- si l'@ est ok on continu end if; Projet B1 Co-Design Page 7 sur 9 Raguin Alexis Reynaud Julien Polytech’Clermont-Ferranf CUST 2007 when "0110" => -- mode write -- envoie de donnee data_mem<=data_mem(6 downto 0)&'0'; -- registre a decalage SDA<=data_mem(7); if (compt=7) then etat(0)<='1'; end if; when "0111" => -- test de l'ack SDA<='Z'; -- On libere la ligne if(test_debug_SDA_ack='0') then -- permet le test d'ack en mode debug if(loop_mode='1') then -- On test si on doit envoyer plusieurs données etat(0)<='0'; compt<=(others=>'0'); -- intialisation du compteur data_mem <= donnee_in; -- on charge la donnee else -- etat(3)<='1'; end if; Ci dessous est la partie qui sera utilisé sur un esclave, ici inhibé pour les tests --start ----- -- ---stop --- elsif (SDA='1') then etat(0)<='0'; -- si pas d'ack on repart dans un mode d'attente de else etat(3)<='0'; end if; when "1110" => -- mode Read reception de donnee data_mem<=data_mem(6 downto 0)&SDA; -- a reactiver avec l'esclave data_mem<=data_mem(6 downto 0)&test_debug_SDA_ack; if (compt=7) then etat(2)<='0'; end if; when "1010" => -- mode Read test d'ack de reception de donnee SDA<='Z'; donnee_out<=data_mem; SDA<='0'; etat(2)<='1'; if(test_debug_SDA_ack='1') then -- permet le test d'ack en mode debug etat(0)<='1'; Ci dessous est la partie qui sera utilisé sur un esclave, ici inhibé pour les tests elsif (SDA='1') then etat<=etat(3)<='1'; -- si pas d'ack on part pour la generation de else etat(2)<='0'; -- si l'adresse est ok on continu end if; Projet B1 Co-Design Page 8 sur 9 Raguin Alexis Reynaud Julien Polytech’Clermont-Ferranf CUST 2007 when "1111"=> -- condition de stop SDA<='0'; etat<=(others=>'0');-- On repart a l'etat d'initialisation when others => etat<=(others=>'0'); -- etat d'attente de start end case; end IF; end if; end process; -- Generation des sorties : ready1_busy0<='1' when (etat="0000") else '0'; end_data <='1' when(etat(2 downto 0)="110" and compt=7) else '0'; addr_ok <= etat(3) or etat(2) ; SCL<='1' when(memo_SCL='0') else clk_SCL; end Behavioral; Projet B1 Co-Design Page 9 sur 9