Forum: Mikrocontroller und Digitale Elektronik TWI Multimastersystem: Controller bleibt im Mastermode


von Thomas Frosch (Gast)


Lesenswert?

Hi Leute,

habe mich mal wieder daran versucht eine I2C oder eben TWI Verbindung 
zwischen zwei Controllern aufzubauen.

Bei mir gibt es immer nur Master liest von Slave dabei können beide 
Controller Master oder Slave sein. Der eine Controller ist ein Atmega8 
der andere ein Atmega32.

Die Kommunikation funktioniert auch weitgehend.

Kann von jedem Controller zum anderen was senden.

Jedoch sende ich von Controller A etwas zu B ist A ja praktisch der 
Master.
Diesen vorgang kann ich beliebig oft wiederholen. Möchte ich 
anschließend was von B nach A senden, startet Controller B die 
übertragung mit dem Status 8 = TWI_START (Start wurde übermittelt) und 
anschließend kommt der Status 32 = TWI_MTX_ADR_NACK (Adresse und Write 
wurde übermittelt aber kein Ack empfangen)

dies wird dann durch meine State Machine unendlich oft wiederholt.

Resete ich nun während dessen den Controller A (Controller der zuerst im 
Mastermode war und nun im Slavemode Daten empfangen soll)
Empfängt er die Daten und Controller B kehrt in den Ruhezustand zurück 
(d.h. der Status ist nicht mehr abwechselnd 8 und 32).

Also sieht es so aus, als würde sich ein Controller wenn er einmal im 
Mastermode ist nicht mehr als Slave adressieren lässt. Gibt es 
irgendeine Möglichkeit nur die TWI einheit zu reseten sobald eine 
Masterübertragung abgeschlossen ist? Will nicht jedesmal den ganzen 
Controller reseten, da er später noch andere Funktionen ausführen soll.

Ich habe mal irgendwo was von einem allgemeinen Bug in Atmel TWI 
Einheiten gelesen, dass Multimaster da nicht so funktioniert. Kann mich 
allerdings nicht mehr an die Einzelheiten erinnern und ob das überhaupt 
stimmt.

Hat jemand davon schon gehört?


Hier noch ein ausschnitt meiner Statemachine in der ISR. Gestartet wird 
der Sendemodus woanders.
1
ISR(TWI_vect) 
2
{
3
  //******************* SENDEN=1 ********************
4
  
5
  DEBUG_WRITES("\tTWSR=");
6
  DEBUG_ZAHLX(3,TWSR);
7
  DEBUG_WRITES(" ");
8
  DEBUG_ZAHLX(1,TWI_Aktion);
9
  
10
  
11
  if (((TWSR == TWI_START) || (TWSR == TWI_REP_START)) && TWI_Aktion == TWI_SENDEN)
12
  {  
13
    DEBUG_WRITES(" #1");
14
    TWDR = (ReceiverAddress << 1) + 0;        //Empfänger Adresse ins Datenregister und mit +0 SCHREIBEN
15
    TWCR = (1<<TWIE)|(1<<TWINT) | (1<<TWEN);    //TWINT -> Interupt Flag löschen, TWEN -> TWI Aktivieren
16
  }
17
  else if (((TWSR == TWI_MTX_ADR_ACK) || (TWSR == TWI_MTX_DATA_ACK)) && TWI_Aktion == TWI_SENDEN)
18
  {          //24              40
19
    
20
    // Puffer leer?
21
    if (twie_p_transmitRead == twie_p_transmitWrite) 
22
    {
23
      DEBUG_WRITES(" #2no");
24
      TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)|(0<<TWWC);    
25
      
26
      //TWSTO -> Stop senden, TWINT -> Interupt Flag löschen, TWEN -> TWI Aktivieren
27
      TWI_Aktion = TWI_NO;
28
      
29
      // Wait until stop condition is executed and bus released
30
      while (TWCR & (1<<TWINT));
31
      
32
      DEBUG_WRITES(" #go on");
33
      
34
    }
35
    else
36
    {
37
      DEBUG_WRITES(" #2>");
38
      /*
39
      // Pufferfüllstand ermitteln
40
      int8_t result = twie_p_transmitWrite - twie_p_transmitRead;
41
      if (result < 0)
42
        result += TWIE_REC_BUFFER_SIZE;
43
      
44
      // Maximalen Pufferfüllstand merken
45
      if (result > twie_maxtransmit)
46
        twie_maxtransmit = result;
47
      */
48
      
49
      // Nächste Leseposition ermitteln
50
      if (++twie_p_transmitRead >= (twie_transmitBuffer + TWIE_TRA_BUFFER_SIZE))
51
        twie_p_transmitRead = twie_transmitBuffer;
52
      
53
      // Daten lesen und übergeben
54
      TWDR = *twie_p_transmitRead;
55
      DEBUG_WRITEC(*twie_p_transmitRead);
56
      DEBUG_WRITES("<");
57
      TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEN);     //TWINT -> Interupt Flag löschen, TWEN -> TWI Aktivieren
58
    }
59
  }
60
  else if(((TWSR == TWI_MTX_ADR_NACK) || (TWSR == TWI_ARB_LOST)) && (TWI_Aktion == TWI_SENDEN))
61
  {            //32            56  
62
    DEBUG_WRITES(" #2.5");
63
    //TWCR= (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
64
    
65
    TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
66
    //TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEN) | (1<<TWSTO) | (1<<TWEA); //TWINT -> Interupt Flag löschen, TWEN -> TWI Aktivieren, TWSTO -> Stopbedingung
67
    TWI_Aktion = TWI_NO;
68
    busy = 255;
69
  }
70
  else if (/*(TWSR == TWI_MTX_DATA_NACK) && */(TWI_Aktion == TWI_SENDEN))
71
  {  
72
    DEBUG_WRITES(" #3");
73
    //Datenübertragung abschließen
74
    //TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEN) | (1<<TWSTO) | (1<<TWEA); //TWINT -> Interupt Flag löschen, TWEN -> TWI Aktivieren, TWSTO -> Stopbedingung, TWEA -> Acknowledge mitsenden
75
    //TALPointer = TALPointer_temp;
76
    TWI_Aktion = TWI_NO;
77
  }
78
79
  
80
  
81
  
82
//ACK nach empfangenen Daten senden/ ACK nach gesendeten Daten erwarten
83
#define TWCR_ACK   TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC);  
84
85
//NACK nach empfangenen Daten senden/ NACK nach gesendeten Daten erwarten     
86
#define TWCR_NACK   TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC);
87
88
//switched to the non adressed slave mode...
89
#define TWCR_RESET   TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC);  
90
  
91
  //******************* EMPFANGEN=2 ********************
92
93
  else if ((TWSR == TWI_SRX_ADR_ACK) && (TWI_Aktion == TWI_NO))    //96 0x60
94
  {
95
    DEBUG_WRITES(" #4");
96
    TWI_Aktion = TWI_EMPFANGEN;
97
    TWCR_ACK;
98
  }
99
  else if ((TWSR == TWI_SRX_ADR_DATA_ACK) && (TWI_Aktion == TWI_EMPFANGEN))  
100
  {          // 128 0x80
101
    DEBUG_WRITES(" #5>");
102
    uint8_t *twie_p_temp = twie_p_receiveWrite + 1;
103
  
104
    // Nächste Schreibposition ermitteln
105
    if (twie_p_temp >= twie_receiveBuffer + TWIE_REC_BUFFER_SIZE)
106
      twie_p_temp = twie_receiveBuffer;
107
      
108
    // Speicher im Puffer frei?
109
    if (twie_p_temp != twie_p_receiveRead)
110
    {
111
      twie_p_receiveWrite = twie_p_temp;
112
      *twie_p_receiveWrite = TWDR;
113
      DEBUG_WRITEC(*twie_p_receiveWrite);
114
      DEBUG_WRITES("<");
115
    }
116
    else
117
    {
118
      //Overflow
119
    }
120
  
121
    TWCR_ACK;
122
  }
123
  else if ((TWSR == TWI_SRX_STOP_RESTART) && (TWI_Aktion == TWI_EMPFANGEN))
124
  {          //160
125
    DEBUG_WRITES(" #7");
126
    TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEN)  | (1<<TWEA) | (1<<TWSTO);  //
127
    TWI_Aktion = TWI_NO;
128
  }
129
  else
130
  {
131
    TWCR_ACK;
132
    TWI_Aktion = TWI_NO;
133
  }
134
  
135
  /*
136
  else if ((TWSR == TWI_SRX_ADR_DATA_NACK) && (TWI_Aktion == TWI_EMPFANGEN)) 
137
  {  //        136 0x88
138
    DEBUG_WRITES(" #6>");
139
    uint8_t *twie_p_temp = twie_p_receiveWrite + 1;
140
  
141
    // Nächste Schreibposition ermitteln
142
    if (twie_p_temp >= twie_receiveBuffer + TWIE_REC_BUFFER_SIZE)
143
      twie_p_temp = twie_receiveBuffer;
144
      
145
    // Speicher im Puffer frei?
146
    if (twie_p_temp != twie_p_receiveRead)
147
    {
148
      twie_p_receiveWrite = twie_p_temp;
149
      *twie_p_receiveWrite = TWDR;
150
      DEBUG_WRITEC(*twie_p_receiveWrite);
151
      DEBUG_WRITES("<");
152
    }
153
    else
154
    {
155
      //Overflow
156
    }
157
    
158
    TWCR = (1<<TWIE)|(1<<TWINT) | (1<<TWEN)  | (1<<TWEA); //| (1<<TWSTO)
159
    TWI_Aktion = TWI_NO;
160
    
161
  
162
  
163
  }
164
  else if ((TWSR == TWI_SRX_STOP_RESTART) && (TWI_Aktion == TWI_EMPFANGEN))
165
  {          //160
166
    DEBUG_WRITES(" #7");
167
    TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEN)  | (1<<TWEA);  // | (1<<TWSTO)
168
    TWI_Aktion = TWI_NO;
169
  }
170
  */
171
  return;
172
}

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.