Hallo, ich habe ein "Netzwerk" aus mehreren atmega32. Diese Kommunizieren über i2c. Es wird nur gesendet im Master Transmitter Modus und Empfangen im Slave Receiver. Alle atmega sind sowohl Slave und Master. Das Funktioniert soweit prima, jedoch bekomme ich ein Problem wenn ich versuche zu senden (Master Transmitter) und etwas Empfange. Als Test lasse ich einfach beide atmegas Texte hin und her schicken. Was klappt bis ich senden will während ein Empfang läuft. Irgendwie habe ich noch keine Möglichkeit gefunden festzustellen, ob der i2c/TWI frei ist. Ich dachte ich kann "jederzeit" sagen sende ein Startcondition und sobald es geht wird dies ausgeführt und ein Interrupt ausgelöst. Das geht nicht. Bin das PDF des atmega nun mehrfach durch. Habe ich etwas übersehen ? Der i2c Code ist so alleine nicht Lauffähig, daher bringt das Posten hier vermutlich nichts. Ich hoffe es hat trotzdem noch jemand einen Tipp. Ich dachte ein Flag setzen sobald ich etwas Empfange sollte reichen, aber scheinbar deckt das nicht alle Sonderfälle ab. Gruss Juergen
Gast
#2403567
>Als Test lasse ich einfach beide atmegas Texte hin und her schicken. Was >klappt bis ich senden will während ein Empfang läuft. Solange die TWI Hardware arbeitet darfst du nicht daran rumfummeln. Also laufende Übertragung abschließen und dann Start anfordern. >Irgendwie habe ich noch keine Möglichkeit gefunden festzustellen, ob der >i2c/TWI frei ist. Brauch dich ja auch nicht zu interessieren. >Der i2c Code ist so alleine nicht Lauffähig, daher bringt das Posten >hier vermutlich nichts. Ich hoffe es hat trotzdem noch jemand einen >Tipp. Poste deinen Code! Solange keiner sieht was du mit TWI anstellst kann dir keiner helfen. >Ich dachte ein Flag setzen sobald ich etwas Empfange sollte reichen, >aber scheinbar deckt das nicht alle Sonderfälle ab. Von wo bis wo setzt du das Flag? Code??
Gast
#2403568
Alle Master müssen den I2C-Bus auf Startbedingung überwachen und eigene Starts unterdrücken, bis wieder ein Stop empfangen wird. Für die seltenen Fälle, bei denen mehr als ein Master gleichzeitig Start signalisiert, muss eine Bus-Arbitration durchgeführt werden. Dabei müssen alle Master sofort ihre Übertragung abbrechen, wenn sie selbst SDA=1 gesetzt haben, aber tatsächlich SDA=0 ist. Bei I2C-Teilnehmern, die gleichzeitig Master und Slave sein können, gibts dabei noch ein spezielles Problem. Wenn bei einer Bus-Arbitration ein Slave adressiert werden sollte, der aber selbst gerade als Master an der Bus-Arbitration beteiligt ist, kann auf die Adressierung dieses Teilnehmers kein ACK erfolgen. All diese Probleme, die in einem Single-Master Sytem gar nicht erst auftreten würden, müssen von der Software abgefangen werden.
Das Flag was ich weiter oben erwähnt habe, ist schon wieder drausen. Es hat ja nicht funktioniert :-( Ich kann den Code auf die schnelle nur hier "inline" posten. Ach ja, das Makro "_BVC()" ist "((0<<x))" und für mich einfacher mal ein Flag zu löschen und dazu zu nehmen. Wie gesagt der Code ist nur auf MT und SR ausgelegt.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | |
204 | |
205 | |
206 | |
207 | |
208 | |
209 | |
210 | |
211 | |
212 | |
213 | |
214 | |
215 | |
216 | |
217 | |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | |
230 | |
231 | |
232 | |
233 | |
234 | |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | |
241 | |
242 | |
243 | |
244 | |
245 | |
246 | |
247 | |
248 | |
249 | |
250 | |
251 | |
252 | |
253 | |
254 | |
255 | |
256 | |
257 | |
258 | |
259 | |
260 | |
261 | |
262 | |
263 | |
264 | |
265 | |
266 | |
267 | |
268 | |
269 | |
270 | |
271 | |
272 | |
273 | |
274 | |
275 | |
276 | |
277 | |
278 | |
279 | |
280 | |
Gast
#2403785
Hier ein parr Sachen die mir aufgefallen sind: Wofür i2cStatus.status? Wird nur geschrieben. sendI2C prüft anhand von i2cStatus.txPos ob TWI arbeitslos ist, kann so aber NIE erkennen ob das TWI gerade im SR Modus ist. Wenn du also gerade Daten empfängst und sendI2C aufrufst geht das garantiert schief. Vorschlag: Definiere für i2cStatus.status ein i2c_rvc_data und setzt das in TW_SR_SLA_ACK. sendI2C darf nur noch senden wenn i2cStatus.status == i2c_Idle. Beachte auch das es diverse Möglichkeiten gibt den Master Status zu verlieren: 0x38, 0x68, 0x78. Du fängst aber im Moment nur 0x38 ab.
Hallo, i2cStatus.txPos dient dazu wie voll der Sendespeicher ist. Im Moment Unterstütze ich nur 1 Packet in der Queue. Daher schicke ich den avr in eine while bis das letzte Packet verschickt wurde. Will ich mal ausbauen, aber Schritt für Schritt :-) Die noch nicht abgefangenen Sonderfälle sind in Arbeit. Ich will mich da erst mal rein arbeiten. Mit dem Vorschlag für den i2cStatus.status. So hat ich das auch umgesetzt, nur in einer extra Variablen. Nur kam es trotzdem noch vor. Das ich ein Start senden will und ein Empfang anfängt. Aber ich versuche das gleich nochmal, vielleicht habe ich mich gestern auch vertan. Ich werde berichten :-) Gruss Juergen
Gast
#2406038
Ich habe gestern das och modifiziert und es scheint doch zu gehen. Ich lasse zwei master sich gegenseitig Meldungen schicken, die dann auf die Serielle ausgegeben werden. Und das ganze mir richtig speed :-) Nun habe ich noch folgendes Problem: Wird der "Bus Master" während der Übertragung resetet, bleibt der Bus natürlich belegt und ist bis zu einem Reset beider Master nicht nutzbar. Der "Salve Receiver" denkt der Bus ist noch belegt. Der MT der neu gestartet wurde fängt aber auch keine Übertragung an. Ich nehme an das passiert nur wärend der Übertragung eines bytes. Starte ich beide CPUs neu läuft alles wieder prima. Wie kann man so etwas sinnvoll handhaben ? Wenn für eine gewisse Zeit nichts passiert, einfach mal ein Stop senden ??? Für Tipps wäre ich dankbar. Gruss Juergen
Gast
#2406149
Freut mich das es jetzt klappt. Ich habe hier einen timeout Zähler in jedem µC laufen. Der wird bei jedem TWI-IRQ zurückgesetzt. Wenn sich für eine gewisse Zeit nichts auf dem Bus tut gibt es einen Init des TWI und der Bus ist wieder frei. Und noch so als Tipp: Bau eine CRC ein. Wenn du dann nach der CRC noch ein Dummy Byte sendest kann der Slave durch ACK/NACK dem Master mitteilen ob die CRC gepasst hat.
Hallo, wenn ich einen Fehler feststelle. Sagen wir der Bus ist für eine gewisse Zeit still und der Verdacht da ist was faul. Nun möchte ich das TWI in einen definierten Zustand bringen. Was muss ich dann machen ? Ist folgendes ausreichend ?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
Nachdem TWEA ja auch die Hardware freigibt, bin ich mir da unsicher. Ich möchte aus einem Fehler, egal ob Master oder Slave in einen definierten Zustand (Idle) wechseln. Natürlich nur bei Fehler die Fatal sind, also zu Busausfällen führen, weil ein Slave hängt oder nicht mehr reagiert oder der Master während dem Transfer resetet/abgeschaltet wurde. Gruss Juergen
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.