Forum: FPGA, VHDL & Co. I2C Master bekommt kein ACK


von GS (chromosoma)


Angehängte Dateien:

Lesenswert?

Abend.
Gegeben ist Terasic DE10-Standard board (sehr ähnlich zu DE1-SoC) mit 
WM8731 audio CODEC.

Ich will jetzt einen einfachen Audio Interface auf dem FPGA realisieren.

WM8731 ist mit FPGA  über I2C Schnittstelle angeschlossen.

Das Problem ist, dass mein I2C Controller kein ACK sieht. Es gibt zwar 
ein ACK, aber nur wenn der letzter gesendeter Bit ein '0' ist. Ich denke 
in diesem Fall wird die SDA Leitung  von FPGA auf LOW gezogen, und der 
Controller "denkt", es wäre ein ACK von WM8731.
Ist der letzter Bit ein '1', so wartet I2C Controller ewig auf ACK...
Irgenwie verstehe ich nicht, was ich falsch mache. Meine Simulation 
sieht meine Meinung nach OK aus, die I2C Adresse stimmt auch.

Hier ist mein beschiedener, selbst  geschriebener I2C Controller:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity test_1 is
6
7
port(
8
9
LEDR: out std_logic_vector(9 downto 0);
10
KEY: in std_logic_vector(3 downto 0);
11
SW: in std_logic_vector(9 downto 0);
12
------------------------
13
AUD_BCLK: out std_logic;
14
AUD_XCK: out std_logic;
15
AUD_ADCLRCK: out std_logic;
16
AUD_ADCDAT: in std_logic;
17
AUD_DACLRCK: out std_logic;
18
AUD_DACDAT: out std_logic;
19
------------------
20
FPGA_I2C_SCLK: out std_logic;
21
FPGA_I2C_SDAT: inout std_logic;
22
-------------------------
23
CLOCK_50 : in std_logic
24
);
25
end test_1;
26
27
28
architecture main of test_1 is
29
signal single_shot: std_logic:='0';
30
signal spi_clk_en: std_logic:='0';
31
signal clk_codec:std_logic:='0';
32
signal aud_prsc: integer range 0 to 255:=0;
33
signal codec_prsc: integer range 0 to 10 :=0;
34
signal data_H: std_logic_vector( 6 downto 0);
35
signal data_L: std_logic_vector( 8 downto 0);
36
signal input_index: integer range 0 to 31:=0;
37
signal rec_flag: std_logic:='0';
38
signal datain: std_logic_vector(31 downto 0):=(others=>'0');
39
signal clk_SPI: std_logic:='0';
40
signal spi_presc: integer range 0 to 50000000:=0;
41
signal spi_addr: std_logic_vector(7 downto 0):="00110100";
42
signal data_index: integer range 0 to 15:=0;
43
signal data_out: std_logic_vector(15 downto 0);
44
type fsm is (send_addr,ack1,ack2,ack3,data_high,data_low,sby,start, stop);
45
signal SPI_flag: std_logic:='0';
46
signal fsm_spi: fsm:=sby;
47
48
begin
49
AUD_XCK<=clk_codec;
50
AUD_BCLK<=clk_codec;
51
data_out(15 downto 9)<=data_H;
52
data_out(8 downto 0)<=data_L;
53
54
55
 process (CLOCK_50)
56
  begin
57
  if rising_edge(cloCK_50) then
58
  ---------------SPI clock----------------------
59
    if(spi_presc<5000)then
60
    spi_presc<=spi_presc+1;
61
    else
62
    Clk_SPI<=not CLK_SPI;
63
    spi_presc<=0;
64
    end if;
65
  ------------------CODEC clock-----------------
66
    if(codec_prsc<4)then
67
     codec_prsc<=codec_prsc+1;
68
    else
69
    codec_prsc<=0;
70
    clk_codec<=not clk_codec;
71
     end if;
72
  ----------------------------------------------
73
  
74
    IF (spi_clk_en='1')then
75
      FPGA_I2C_SCLK<= not clk_SPI;
76
    else 
77
      FPGA_I2C_SCLK<='1';
78
    end if;
79
  
80
  
81
  end if;  
82
  end process;
83
  
84
  ----------------------SPI-FSM-----------------
85
 process (clk_SPI)
86
  begin
87
  
88
  if rising_edge(clk_SPI) then
89
  if (SW(1)='1') then---hard reset
90
  fsm_spi<=sby;
91
  end if;
92
  
93
  case fsm_spi is
94
    when send_addr=>
95
                   -----sende Adresse-----------------
96
       spi_clk_en<='1';
97
       LEDR(9 downto 6)<="0011";
98
      if(data_index>0)then
99
         FPGA_I2C_SDAT<=spi_addr(data_index);
100
        data_index<=data_index-1;
101
      else
102
        FPGA_I2C_SDAT<=spi_addr(data_index);
103
        data_index<=15;---  data  length
104
        fsm_spi<=ack1;
105
      end if;
106
    when ack1=>
107
                ------------warte auf ACK-------------------
108
        LEDR(9 downto 6)<="0100";
109
        FPGA_I2C_SDAT<='Z';
110
        if(FPGA_I2C_SDAT='0')then
111
        fsm_spi<=data_high;
112
        end if;
113
    when data_high=>
114
                ---------sende erste 8 bits und warte auf ACK----------
115
        LEDR(9 downto 6)<="0101";
116
        if(data_index>7)then
117
         FPGA_I2C_SDAT<=data_out(data_index);
118
        data_index<=data_index-1;
119
        else
120
          FPGA_I2C_SDAT<='Z';
121
          if(FPGA_I2C_SDAT='0')then
122
            fsm_spi<=data_low;
123
          end if;
124
        end if;
125
126
     when data_low=>
127
                   --------------------und jetzt die nächste 8 bit----------
128
        LEDR(9 downto 6)<="1000";
129
        if(data_index>0)then
130
              FPGA_I2C_SDAT<=data_out(data_index);
131
        data_index<=data_index-1;
132
        else
133
        FPGA_I2C_SDAT<=data_out(data_index);
134
        fsm_spi<=ack3;
135
        end if;
136
    when ack3=>
137
        LEDR(9 downto 6)<="1001";
138
        FPGA_I2C_SDAT<='Z';
139
        if(FPGA_I2C_SDAT='0')then
140
        fsm_spi<= stop;
141
        end if;
142
     when sby =>
143
        LEDR(9 downto 6)<="0001";
144
        FPGA_I2C_SDAT<='1';        
145
        data_index<=7;--- addr length
146
        if (SPI_flag='1')then
147
        fsm_spi<=start;
148
        end if;
149
    when start =>
150
                               --------start Bedienung-----------
151
        LEDR(9 downto 6)<="0010";
152
              fsm_spi<=send_addr;
153
        FPGA_I2C_SDAT<='0';
154
    when stop =>
155
                               --------- stop Bedienung ------------
156
        LEDR(9 downto 6)<="1010";
157
                    FPGA_I2C_SDAT<='1';
158
        fsm_spi<=sby;
159
160
        spi_clk_en<='0';
161
162
    when others=>NULL;
163
  end case;
164
 end if;
165
end process;
166
  
167
  
168
169
 
170
 process(clk_SPI)
171
 begin
172
 if rising_edge(clk_SPI) and single_shot='1' then
173
  single_shot<='0';
174
  if (KEY(0)='0' ) then ----wake up from stand by 
175
  SPI_flag<='1';
176
  data_H<="0000110";
177
  data_L<="001101010";
178
  elsif (KEY(1)='0' ) then---DSP mode,16 bit, data at 2nd BLCK, slave mode
179
  SPI_flag<='1';
180
  data_H<="0000110";
181
  data_L<="000010011";
182
  elsif (KEY(2)='0') then---activ control
183
  SPI_flag<='1';
184
  data_H<="0001001";
185
  data_L<="111111111";
186
  elsif (KEY(3)='0' AND SW(0)='0') then---remove mute
187
  SPI_flag<='1';
188
  data_H<="0000000";
189
  data_L<="100010111";
190
  elsif (KEY(3)='0' AND SW(0)='1') then---reset
191
  SPI_flag<='1';
192
  data_H<="0001111";
193
  data_L<="000000000";
194
  end if;
195
 
196
 end if;
197
 
198
 
199
 if rising_edge(clk_SPI) and single_shot='0' then
200
 SPI_flag<='0';
201
 end if;
202
 
203
 if rising_edge(clk_SPI) and KEY="1111" then
204
 single_shot<='1';
205
 end if;
206
 end process;
207
 
208
209
end main;


P.S.

Ich habe schon sein mehr als einem Jahr nichts mit FPGA/VHDL gemacht, 
könnte sein dass ich irgendwas fundamentales vergessen/übersehen habe.

von Ben (Gast)


Lesenswert?

DE-10 mir W8731? Meinst du das DE-1 Bord mit Cyclone 2?

von GS (chromosoma)


Lesenswert?


von KJlaus (Gast)


Lesenswert?

Böser K. schrieb:
> Ist der letzter Bit ein '1', so wartet I2C Controller ewig auf ACK...

Ich versteh zwar nichts von VHDL, aber "warten auf ACK" kann es bei I2C 
nicht geben. Der Master taktet 8 mal und schiebt dabei ein Byte auf SDA 
raus. Dann macht er den 9ten Takt und liest dabei SDA ein. Da kann es 
kein "warten" geben, er bestimmt den Takt. Und wenn der Pegel von SDA 
vom letzten ausgegebenen Bit abhängt, fehlt der Pullup an SDA. Der muß 
klein genug sein, daß er in einer halben Bitzeit auch gegen die 
Kapazität der Signalleitung ein HIGH erzeugt.

MfG Klaus

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Böser K. schrieb:
> if rising_edge(cloCK_50) then
>   ---------------SPI clock----------------------
>     if(spi_presc<5000)then
>     spi_presc<=spi_presc+1;
>     else
>     Clk_SPI<=not CLK_SPI;
>     spi_presc<=0;
>     end if;
So werden im FPGA keine Takte erzeugt, auf die mit 'event (aka 
rising_edge() oder falling_edge()) reagiert wird. Warum verwendest du 
nicht Clock-Enables wie der Rest der Welt?

> Hier ist mein beschiedener, selbst  geschriebener I2C Controller:
> FPGA_I2C_SDAT<='Z';
>           if(FPGA_I2C_SDAT='0')then
>             fsm_spi<=data_low;
>           end if;
Und die Testbench? Gibt die an der richtigen Stelle ein ACK zurück? 
Offenbar nicht, denn da ist nur ein 'Z' zu sehen...

Und natürlich darfst du, wenn du als 9. Bit kein ACK bekommst nicht 
einfach bis zum nächsten "low" stehen bleiben, sondern musst dann die 
Übertragung beenden und nochmal von vorn beginnen.

: Bearbeitet durch Moderator
von Achim S. (Gast)


Lesenswert?

Neben den schon erwähnten Mängeln noch ein Hinweis zu

Böser K. schrieb:
> Es gibt zwar
> ein ACK, aber nur wenn der letzter gesendeter Bit ein '0' ist.

Du setzt bei der selben Taktflanke SDA auf Z und fragst das Acknowledge 
ab. Mit der Abfrage erwischst du noch den "alten" Wert von SDA vor der 
Taktflanke (also die '0', die du selbst zuvor getrieben hast).

Böser K. schrieb:
> when ack1=>
>                 ------------warte auf ACK-------------------
>         LEDR(9 downto 6)<="0100";
>         FPGA_I2C_SDAT<='Z';
>         if(FPGA_I2C_SDAT='0')then
>         fsm_spi<=data_high;
>         end if;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Achim S. schrieb:
> Du setzt bei der selben Taktflanke SDA auf Z und fragst das Acknowledge
> ab. Mit der Abfrage erwischst du noch den "alten" Wert von SDA vor der
> Taktflanke
Stimmt, und deshalb ist beim I2C durchaus definiert, wann man die Pegel 
wechseln und abfragen darf. Jedenfalls niemals mit der Taktflanke...

Quelle: http://www.nxp.com/documents/user_manual/UM10204.pdf

von GS (chromosoma)


Lesenswert?

Ok, ich bin doof, jetzt läuft alles. Die SDA ändere ich jetzt so wie im 
Datenblatt, außerdem war die STOP Bedienung falsch realisiert, da fehlte 
noch ein Takt.

Vielen dank für die Hilfe.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.