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