Forum: Mikrocontroller und Digitale Elektronik TWI Kommunikation zu PCA9555 hängt nach einer gewissen Zeit


von Michael (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

derzeit benutze ich den TWI vom SAM4 über die ASF Funktionen. Anfangs 
war es etwas holprig wie manche hier vielleicht wissen und zu guter 
letzt laufen nun TWI0 und 1. Dachte ich zummindest :)

Slaves sind PCA9555PW als IO-Erweiterungen. Ich habe die Elektronik mal 
länger laufen lassen. Es sollte nur eine LED am IO Extender getoggelt 
werden im sekundentakt. Dazu lese ich jeweils den aktuellen Portzustand 
(von Port 1 und Port 0). Toggle das entsprechende Bit der LED und 
schreibe Port 1 und Port 0 wieder zurück. Das ganze funktioniert 
eigentlich, nur nach etwa 15min bis 3Std habe ich es jetzt regelmäßig 
erlebt, dass ich der TWI beim lesen der Ports aufhängt.


In der twi_master_read kommt er in der while(cnt>0) nicht weiter.
Der Master soll zwei Bytes lesen. Bereits nach dem ersten Byte gibt der 
Master ein NACK und sendet STOP wobei die Funktion erst ein Byte 
empfangen hat, welches auch noch im TWI_RHR liegt. Die Variable cnt ist 
aber noch auf 1. Und gefühlte Tausendmal geht es auch ohne Probleme bis 
genau dieses Problem auftritt. Hatte soetwas schonmal einer in der Form? 
Ich weiß nicht so recht ob ich den PCA9555 verdächtigen soll oder die 
ASF TWI Routine die "eigentlich" funktioniert.

Ein letztes Oszilloskopbild konnte ich auch bekommen. Habe die Infos mal 
zusammgestellt und als Bild angehängt.
Der Aktuelle Staus der Variablen ist auch als Screen angehängt, sowie 
die TWI-Register. An der Adresse 0x200036E0 steht 0xff (dieses Byte hat 
er empfangen) und 0x200036E1 ist auf 0x00 (hat ermeiner Meinung nach 
auch noch nicht gelesen, also irgendwas im Speicher).

Die twi_master_read() schaut so aus:
1
uint32_t twi_master_read(Twi *p_twi, twi_packet_t *p_packet)
2
{
3
  uint32_t status, cnt = p_packet->length;
4
  uint8_t *buffer = p_packet->buffer;
5
  
6
    /* Check argument */
7
    if (cnt == 0) {
8
      return TWI_INVALID_ARGUMENT;
9
    }
10
11
    /* Set read mode, slave address and 3 internal address byte lengths */
12
    p_twi->TWI_MMR = 0;
13
    p_twi->TWI_MMR = TWI_MMR_MREAD | TWI_MMR_DADR(p_packet->chip) |
14
        ((p_packet->addr_length << TWI_MMR_IADRSZ_Pos) &
15
        TWI_MMR_IADRSZ_Msk);
16
17
    /* Set internal address for remote chip */
18
    p_twi->TWI_IADR = 0;
19
    p_twi->TWI_IADR = twi_mk_addr(p_packet->addr, p_packet->addr_length);
20
21
    /* Send a START Condition */
22
    p_twi->TWI_CR = TWI_CR_START;
23
24
    while (cnt > 0) {
25
//HIER hängt er (bei den 3 if Abfragen)
26
      status = p_twi->TWI_SR;
27
      if (status & TWI_SR_NACK) {
28
        return TWI_RECEIVE_NACK;
29
      }
30
31
      /* Last byte ? */
32
      if (cnt == 1) {
33
        p_twi->TWI_CR = TWI_CR_STOP;
34
      }
35
36
      if (!(status & TWI_SR_RXRDY)) {
37
        continue;
38
      }^
39
      *buffer++ = p_twi->TWI_RHR;
40
      
41
      
42
      cnt--;
43
    }
44
45
    while (!(p_twi->TWI_SR & TWI_SR_TXCOMP)) {
46
    }
47
48
    p_twi->TWI_SR;
49
  
50
  return TWI_SUCCESS;
51
}

Habe schon die Taktrate von 50kHz bis 300kHz variiert und konnte keinen 
Unterschied feststellen. Gefühlt hängt er schneller mit kleineren 
Taktraten, als mit schnellen. Aber das ist nur so ein Gefühl.
Mit und ohne Debugger habe ich es auch probiert. Hängt sich in beiden 
fällen auf.

PS: Erschreckt euch nicht bei dem Oszibild. Ich habe einmal "gezoomt" 
und da steht mein Scope garnicht drauf. Darum ist SCL etwas spitz 
geworden und geschwungen. Schaut live schön glatt und eckig aus.

von Peter D. (peda)


Lesenswert?

Michael schrieb:
> //HIER hängt er (bei den 3 if Abfragen)
>       status = p_twi->TWI_SR;

Gib dann mal status aus, was da noch für Bits alle gesetzt sind.

von Michael (Gast)


Lesenswert?

Variable Status hat den exakten Wert wie in dem Register-Screenshot, 
0x0000f00d. Oder meinst du was anderes?
Der Fehler ist auch immer reproduziertbar.

von Stephan D. (stephan_d10)


Lesenswert?

Hallo Michael,

darf ich fragen wie das ausgegangen ist?
Ich hänge (genau wie der TWI bus) allerdings am Ende in der TXCOMP 
while().

Kann jemand einen GETESTETEN I2C Bit-Bang Treiber empfehlen? (SAM4s)
Darf auch was kosten...

Viele Grüße, Stephan

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.