Bus I2C en VHDL
Répondre à la discussion
Affichage des résultats 1 à 7 sur 7

Bus I2C en VHDL



  1. #1
    Bartacus

    Bus I2C en VHDL


    ------

    Bonjour,

    J'ai posté un topic récemment qui avait pour but de contrôler un capteur d'image à l'aide d'un FPGA.

    Ce sujet étant trop complexe on m'a demandé de ne me concentrer que sur le bus I2C liant le capteur au FPGA.

    Le but est de lire la version du capteur à l'aide du bus I2C. (registre : 0001 0011 0010 0100 (LSB))
    La programmation se fait en VHDL sur le logiciel libero IDE.

    j'ai essayé le code du site suivant:
    http://www.eewiki.net/pages/viewpage...)-CodeDownload

    mais je n'ai pas la possibilité par la suite de gérer les IO :/

    Je ne m'y connait pas trop, voir pas du tout et j'aurais aimé avec vos avis et vos conseils sur ce projet svp.

    Bartacus,

    -----

  2. #2
    indri

    Re : Bus I2C en VHDL

    Pour utilisé ce code, tu dois inclure cette sous-entité dans ton code, lui assigné les bon signaux (les sorties doivent être les pins du bus i²c) et ton code doit gérer les différent signaux d'entrée (comme l'exemple)!

    As-tu déjà utilisé des "components" dans un code?
    Dernière modification par indri ; 27/05/2013 à 10h53.
    Là où va le vent...

  3. #3
    Bartacus

    Re : Bus I2C en VHDL

    Est ce qu'il est possible de faire un fichier/dossier qui n'utilise uniquement que la liaison I2C? Où la seul fonction serait de lire le registre.

    Pour les components j'ai vus ça dans un exemple oui.

    J'aimerais savoir également si on est obligé de passer par la partie Design? (partie schématique), ou si le fichier VHDL peut suffir?

  4. #4
    Bartacus

    Re : Bus I2C en VHDL

    J'ai utilisé une autre source VHDL:

    library IEEE;

    use IEEE.std_logic_1164.all;
    use IEEE.std_logic_arith.all;
    use IEEE.std_logic_unsigned.all;

    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

    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';
    -- 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 start--
    else --
    etat(2)<='1'; -- si l'@ est ok on continu --
    end if;

    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
    elsif (SDA='1') then --
    etat(0)<='0'; -- si pas d'ack on repart dans un mode d'attente de start--
    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(3)<='1'; --il y avait etat<=etat(3)<='1', mais j'avais une erreur car etat est sur 4 bit et etat(3) sur 1 (je pense)
    -- si pas d'ack on part pour la generation de stop --
    else --
    etat(2)<='0'; -- si l'adresse est ok on continu --
    end if;

    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;
    Je passe à la phase où il me faut attribuer les PIN mais je me retrouve avec une 30ène de IO. Est ce qu'il me faut juste attribuer SDA et SCL ?

    Merci de vos réponses

  5. A voir en vidéo sur Futura
  6. #5
    Bartacus

    Re : Bus I2C en VHDL

    Je me permet de faire remonter ce sujet et je vais essayé de reformuler une question.

    Est ce qu'il est possible, avant de me lancer, de ne câbler que la liaison I2C (+ l'alim et la masse) entre le capteur d'image (MT9V034) et le FPGA (Proasic3l) pour la tester (avec le registre cité plus haut)?
    Avec bien sûr la liaison USB entre le FPGA et l'ordi.

    De cette façon je n'aurais qu'à programmer la liaison VHDL. (?)

    Merci à vous et n'hésitez pas si je ne suis pas assez clair.

    bartacus

  7. #6
    indri

    Re : Bus I2C en VHDL

    ben oui...

    Tous le reste tu le gère en interne!
    Là où va le vent...

  8. #7
    Bartacus

    Re : Bus I2C en VHDL

    D'accord merci.

    J'ai décidé de partir de nouveau sur un autre code source (que j'ai mis en pièce jointe car il y a trop de caractères).

    Je me retrouve avec les IO suivant:

    ack_i
    adr_o[0 à 7]
    clk_i
    cyc_o
    dat_i[0 à 7]
    dat_o[0 à 7]
    err_i
    i2c_scl_io
    i2c_sda_io
    lock_o
    rst_i
    rty_i
    sel_o[o]
    stall_i
    stb_o
    we_o
    clk_i j'y met mon horloge (pour moi PIN E4)
    i2c_scl_io (PIN D11)
    i2c_sda_io (PIN G11)

    Pour le reste donc il y en a qui se règle en interne.
    J'aurais tendance à mettre mon registre à envoyer dans "dat_o", j'aurais donc la réponse (dans un hyperterminal) grâce à dat_i. Mais pour le reste je ne vois pas trop.

    J'ai trouvé cette ligne dans la data sheet du capteur qui m'intrigue:

    {S_CTRL_ADR1, S_CTRL_ADR0} Slave Address Write/Read Mode
    00 0x90 Write
    0x91 Read

    Voici le lien (page 16): ftp://oceane.obs-vlfr.fr/pub/besson/....%20A%20EN.pdf

    Merci pour ta réponse
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. Bus i2c
    Par mzzoo dans le forum Électronique
    Réponses: 2
    Dernier message: 03/04/2013, 18h38
  2. Bus i2c et 16f628
    Par invited94a265e dans le forum Électronique
    Réponses: 10
    Dernier message: 25/12/2010, 17h46
  3. bus I2C
    Par inviteedcf41c6 dans le forum Électronique
    Réponses: 2
    Dernier message: 29/06/2008, 23h28
  4. Bus I2C
    Par Eleomir dans le forum Électronique
    Réponses: 15
    Dernier message: 15/04/2007, 10h58
  5. Bus I2c
    Par invite66afc259 dans le forum Électronique
    Réponses: 6
    Dernier message: 30/10/2005, 13h53
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...