Forum: Mikrocontroller und Digitale Elektronik I2C_WaitOnFlagUntilTimeout verursacht jedesmal einen Timeout


von Thomas K. (Gast)


Lesenswert?

Guten Morgen, ich habe schon seit längerem ein Problem mit den I²C 
Funktionen aus der HAL für STM32. Vielleicht wisst ihr wie ich dieses 
Problem beheben kann denn sitze da schon seit Woche dran.

bei der typischen HAL_I2C_Master_Transmit(); Funktion taucht eine 
weitere Funktion auf eine Abfrage für einen Timeout die in der Regel 
übersprungen werden sollte, die I2C_WaitOnFlagUntilTimeout(); Funktion.

Das innere dieser Funktion sieht so aus:

static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef 
*hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t 
Tickstart)
{


  /* Wait until flag is set */
  while((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status)
  { 
//flagstatus von typ enum kann entweder set oder reset sein
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY) //springt immer in die if (timeout=25ms 
, hal_max_delay = 0xFFFFFFFF)
    {
      tickstart_g = Tickstart;
      gettick_g = HAL_GetTick();
      if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
      {
        hi2c->PreviousState = I2C_STATE_NONE;
        hi2c->State= HAL_I2C_STATE_READY;
        hi2c->Mode = HAL_I2C_MODE_NONE;

        /* Process Unlocked */
        __HAL_UNLOCK(hi2c);

        return HAL_TIMEOUT;
      }
    }
  }

  return HAL_OK;
}



Diese Funktion prüft ob flag gesetzt ist oder nicht, bei set gibt es den 
rückgabewert HAL_TIMEOUT zurück, dadurch wird bestätigt das der bus 
beschäftigt ist und bei Reset gibt er den Rückgabewert HAL_OK.

Und ich bekomme immer einen Timeot zurück egal was ich mache fehlt mir 
irgendwas grundlegendes dabei? Wie schaffe ich das mir dieser Ausdruck 
((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status) den 
Rückgabewert HAL_OK liefert?

von pegel (Gast)


Lesenswert?

Mit dieser Funktion hatte ich noch nie zu tun.
Bist du sicher, dass dein I²C richtig konfiguriert, die Adresse richtig 
und das ACK anliegt?

von Thomas K. (Gast)


Lesenswert?

pegel schrieb:
> Mit dieser Funktion hatte ich noch nie zu tun.
> Bist du sicher, dass dein I²C richtig konfiguriert, die Adresse richtig
> und das ACK anliegt?

Also diese Funktion liegt in der Master_transmit funktion zunächst habe 
ich über CubeMX I²C eingeschaltet. Danach habe ich über den handler 
hi2c1 versucht irgendein Signal zu senden damit ich es auf den 
Oszilloskop sehen kann:


HAL_I2C_Master_Transmit(&hi2c1, 0x52, &buff[0], 1, 10);

Aber in dieser Transmit Funktion bleibt er dann in einer Abfrage 
stecken:

if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, 
I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
    {
      return HAL_BUSY;
    }

und gibt mir als Rückgabewert einen Timeout zurück statt HAL_OK, wobei 
die Funktion ja übersprungen würde.

von Vincent H. (vinci)


Lesenswert?

Um welchen Prozessor handelt es sich? Tritt das Problem eventuell nur 
beim allerletzten zu übertragenden Byte auf?

Grad der I2C Teil der ST-Bibliotheken ist leider katastrophal. Ich hab 
Mitte letzten Jahres einen Race-Condition Bug bezüglich dem RXNE-Flag in 
der L4-Library gemeldet und von ST nicht einmal eine Antwort bekommen. 
Was die Sache noch schlimmer machst ist, dass der Bug in der F7-Library 
scheinbar ebenfalls drin war und dort schon viel früher gemeldet wurde.

Lange Rede kurzer Sinn. Prüfe genau nach Datenblatt ob die Reihenfolge 
der Flag-Abfragen Sinn macht. Eventuell kommt an exakt dieser Stelle 
überhaupt kein Busy mehr...

von Thomas K. (Gast)


Lesenswert?

Vincent H. schrieb:
> Lange Rede kurzer Sinn. Prüfe genau nach Datenblatt ob die Reihenfolge
> der Flag-Abfragen Sinn macht. Eventuell kommt an exakt dieser Stelle
> überhaupt kein Busy mehr...

Also zunächst wollte ich einen Sensor ansprechen, aber als das nicht 
klappte wollte ich mit dem Oszilloskop erstmal prüfen ob ich überhaupt 
ein Signal kriege. Nun habe ich ein oszilloskop an der Clockleitung doch 
erhalte nichts, die Sache ist ich denke nicht das eine so grundlegende 
Funktion schon Software Fehler hat, weil die auch oft benutzt wird. Es 
scheint mir als würde irgendetwas kleines fehlen aber ich finde nicht 
heraus was es ist.

von Vincent H. (vinci)


Lesenswert?

Gar nichts?

- I2C Clock Source konfiguriert?
- I2C Clock (der von der Peripherie selbst) aufgedreht?

von pegel (Gast)


Lesenswert?

Wenn du es mit CubeMX gemacht hast sollte alles eingestellt sein.
Welcher Sensor ist es denn?

Ausserdem gebe ich immer die Typen für die Funktion mit an nachdem ich 
mal Probleme damit hatte.

Dein:
HAL_I2C_Master_Transmit(&hi2c1, 0x52, &buff[0], 1, 10);

würde wenn wir buff gleich definiert haben zu:
HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)0x52, (uint8_t*)buff, 1, 10);

Wichtig ist aber erst einmal das der Sensor an den richtigen Pins mit 
der richtigen Adresse über die richtigen Pullups angesteuert wird.

von pegel (Gast)


Lesenswert?

Kannst ja deine .ioc Datei anhängen. Dann sehen wir nach ob die 
Konfiguration und die Pins stimmen.

von Thomas K. (Gast)


Lesenswert?

Hallo,

danke für die Antworten bei meinem Sensor handelt es sich um den VL53L1x 
von ST hier habe ich mein ganzes Projekt hochgeladen: 
https://drive.google.com/open?id=1EY7RbFfVB3nhfKes4ZXp-38BKprBphBq

hoffentlich könnt ihr mir helfen was die I²C Verbindung angeht.

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.