Pages: [1]   Go Down
Author Topic: Communicating with a BQ2013H over HDQ bus  (Read 1398 times)
0 Members and 1 Guest are viewing this topic.
Montréal, Qc
Offline Offline
Full Member
***
Karma: 0
Posts: 185
Practice safe hex!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello, I built a circuit which includes a bq2013h battery gas gauge. The IC uses a proprietary communication protocol called HDQ which is very similar to 1-Wire except that it's faster, devices don't send a presence pulse and it transmits words at a time rather than bits at a time. Sadly I had to pick the component with possibly the worst datasheet and app notes TI has ever publish (no, really I mean it!). So I'm having quiet a few issues. A whole word must be sent in a minmum of 190uS, bus is MSB first. As per the datasheet, the slave should pull the line low (there's a 4.7K pull up) once it's received a command register address. But using the code below I never get this ACK from the slave. The only code available anywhere is some weird 8085 asm compiled for a 16CXX PIC and it uses a uart rather than a digital IO.

Two app notes describing the protocol
http://focus.ti.com/lit/an/slua408/slua408.pdf
http://focus.ti.com/lit/ug/spru688/spru688.pdf

The first one specifies that "If the host implements the HDQ communication using a discrete processor I/O port, the timing of the transmitted HDQ data and the sampling of the received HDQ data depends on the host processor timing of the transitions on the HDQ line."

Which I interpret as "the slave will copy the host's timing as long as the host respects the min/max timings of the slave". Doesn't seem to be the case. The same app note also says "The procedure is to set the UART baud rate to 57,600 with no parity and 2 stop bits. This yields a data word with 11 bits total (start bit, 8 data bits, and 2 stop bits). At a baud rate of 57,600 (17.3 µs per bit), this is a total communication time of 190.9 µs and meets the required HDQ bit
timing of 190 µs minimum." As such, I've assumed that these minimum timing + a little extra should do just fine and that's what is replicated below.

Sadly this got me nowhere. Got anymore ideas? Anyone? Anyone? Buller?

P.S. I thought HDQ was another brand name for 1-Wire (TWI vs I2C) when I choose the IC, but now it's on the PCB already

Code:
uint8_t HDQ::read(uint8_t reg)
{
      uint8_t result            = 0;
      uint8_t maxTries      = 255;
      uint8_t ii;
      
      // Compute read mask
      reg |= HDQ_ADDR_MASK_READ;
      
      HDQ::doBreak();
      
      sbi(*modeReg, pin);            // Set pin as output
      cbi(*outputReg, pin);      // Bring pin low
      
      // Wait the minimum break time
      
      delayMicroseconds(1);
      
      // Bring the pin back high
      cbi(*outputReg, pin);
      delayMicroseconds(20);
      
      for (ii = 0; ii < 8; ii++)
      {
            sbi(*outputReg, pin);
            delayMicroseconds(5);
            
            // Toggle the pin for this bit, MSB first
            if (reg<<ii & B10000000) {
                  sbi(*outputReg, pin);
            }
            else {
                  cbi(*outputReg, pin);
            }
            
            delayMicroseconds(15);
      }
      
      sbi(*outputReg, pin);
      delayMicroseconds(40);
      
      cbi(*modeReg, pin);      // Set pin as input
      
      // Wait for the slave to toggle a low
      while (_HDQ_readPin() != 0);
      
      Serial.println("Got ACK");
      
      for (ii = 0; ii < 8; ii++)
      {
            delayMicroseconds(10);
            
            result |= _HDQ_readPin()<<(7 - ii);
            
            delayMicroseconds(10);
      }
      
      delayMicroseconds(40);
      
      return result;
}
Logged

"Pilots believe in a clean living... they never drink wisky from a dirty glass."

Montréal, Qc
Offline Offline
Full Member
***
Karma: 0
Posts: 185
Practice safe hex!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So after quiet some more tinker and digging through the app notes... I present to you the HDQ library smiley-grin (Not that it will be any popular, there are only a handful of HDQ devices ;o)

You can view the source here: http://trac.mlalonde.net/cral/browser/HDQ.

Usage example:

Code:
HDQ HDQ(ARDUINO_PIN);

uint8_t r = HDQ.read(0x1e);

Serial.print("Register 0x1e: ");
Serial.print(" 0x");
Serial.println(r, HEX);

The only other thing needed is to have a string pull up (4.7K did the job, I saw 10K used in the app notes).
« Last Edit: February 09, 2008, 12:42:31 am by xSmurf » Logged

"Pilots believe in a clean living... they never drink wisky from a dirty glass."

Pages: [1]   Go Up
Jump to: