I2C_WaitOnFlagUntilTimeout verursacht jedesmal einen Timeout

Gast #5700513
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?
Gast #5700567
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.
#5700583
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...
Gast #5700595
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.
Gast #5700656
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren