Forum: Mikrocontroller und Digitale Elektronik Vorgang bei READ / WRITE bei SMBUS Kommunikation mit BQ40Z50


von David R. (Firma: Acesomed GmbH) (devdave)


Lesenswert?

Hallo,

ich versuche einen Treiber für einen BQ40Z50 Akku zu implementieren der 
über SMBUS auf einem STM32H7xx kommuniziert.

Ich benutze hierfür das STM32 SMBus/PMBusTM Expansion Package (AN4502)

Die Initialisierung des SmbusStacks funktioniert soweit. Es hapert 
allerdings
 meiner READ bzw WRITE Methode.
HEADER FILE:
...
1
SMBUS_StackHandleTypeDef smbusStackHandle;
...

INIT Methode: (CHIP_DATA[] ist die Commandtable)
1
  uint32_t BQ40Z50::init() {
2
    smbusStackHandle.CMD_table = (st_command_t *) &CHIP_DATA[0];
3
    smbusStackHandle.CMD_tableSize = sizeof(CHIP_DATA)/sizeof(CHIP_DATA[0]);
4
    smbusStackHandle.StateMachine = SMBUS_SMS_NONE;
5
    smbusStackHandle.Device = &BSP_BATTERY_I2C;
6
    smbusStackHandle.SRByte = 0x55U;
7
    smbusStackHandle.CurrentCommand = NULL;
8
    if(initSmbus() == HAL_OK){
9
      return 0;
10
    }
11
    else return 1;
12
}

INITSMBUS Methode:
1
  HAL_StatusTypeDef BQ40Z50::initSmbus() {
2
    HAL_StatusTypeDef r = STACK_SMBUS_Init(&smbusStackHandle);
3
    if(r == HAL_OK){
4
      uint32_t t = HAL_GetTick();
5
      while(!STACK_SMBUS_IsReady(&smbusStackHandle)){
6
  if((HAL_GetTick() - t) > 100){
7
    return HAL_ERROR;
8
  }
9
      }
10
      smbusInitialized = true;
11
      return r;
12
    }
13
  }

WRITE Methode:
1
template <typename DATATYPE>
2
   uint16_t writeRegister(st_command_t *cmd, int16_t data) {
3
     uint8_t* ioBuffer = STACK_SMBUS_GetBuffer(&smbusStackHandle);
4
     (*((DATATYPE*)ioBuffer)) = data;
5
     HAL_StatusTypeDef r = STACK_SMBUS_HostCommand(&smbusStackHandle, 
6
       const_cast<st_command_t*>(cmd), 0x16, WRITE);
7
     if(r != HAL_OK){
8
       return 0;
9
     } else {
10
  uint8_t t = HAL_GetTick();
11
  while ( ! STACK_SMBUS_IsReady(&smbusStackHandle)) {
12
    if(HAL_GetTick() - t > 100){
13
      printf("TIMEOUT\n");
14
      return 0;
15
    }else break;
16
       }
17
       return 2;
18
    }
19
  }

READ Methode:
1
  template <typename DATATYPE>
2
  DATATYPE readRegister(st_command_t* cmd) {
3
    HAL_StatusTypeDef r = STACK_SMBUS_HostCommand(&smbusStackHandle, 
4
      const_cast<st_command_t*>(cmd), BSP_BATTERY_ADDR, READ);
5
    uint32_t t = HAL_GetTick();
6
    while ( ! STACK_SMBUS_IsReady(&smbusStackHandle)) {
7
      if((HAL_GetTick() - t) > 100){
8
  return -1;
9
      }
10
    }
11
    if(!smbusInitialized){
12
      return -1;
13
    }
14
    uint8_t* ioBuffer = STACK_SMBUS_GetBuffer(&smbusStackHandle);
15
    DATATYPE result = (*((DATATYPE*)ioBuffer));
16
    return result;
17
  }

Ich kann alle Register auslesen. Aber
1. Beim READ Vorgang zeigt mir mein Logic Analyzer am Ende immer ein 
NACK.
2. Normalerweise sollte ja bei jedem Readvorgang der Buffer des smbus 
mit dem neuen Readresult überschrieben werden. Tut er aber nicht.
3. Wenn ich ein Register beschreibe kommt ein ACK zurück. Eigentlich 
müsste dann aber beim anschliessenden lesen ja das Geschriebene gelesen 
werden können. Es kommt dann aber meist was falsches raus.

Meine Frage nun. Könnte sich jemand mit smbus Erfahrung die Methoden mal 
anschauen und mir sagen ob da evtl was fehlt?

Vielen Dank schon mal im Vorraus :-)

: Bearbeitet durch User
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.