Skip to content

Instantly share code, notes, and snippets.

@nicolas17
Last active November 8, 2025 06:54
Show Gist options
  • Select an option

  • Save nicolas17/16e7b51ae861cce6000aa5904826168d to your computer and use it in GitHub Desktop.

Select an option

Save nicolas17/16e7b51ae861cce6000aa5904826168d to your computer and use it in GitHub Desktop.
HDQ decoder for sigrok
# Copyright (c) 2024 JJTech <[email protected]>
#
# SPDX-License-Identifier: GPL-2.0-or-later
"""
HDQ (High-speed Data Queue) is a simple protocol used for Texas Instruments
'Gas Gauge' battery fuel gauges. It is used to read and write data to the fuel
gauge's memory.
Similarly to the '1-wire' protocol, it is a single-wire protocol that uses a
single data line to communicate with the fuel gauge.
Protocol documentation: https://www.ti.com/lit/pdf/slua408
"""
import sigrokdecode as srd # type: ignore
from .pd import Decoder
# Copyright (c) 2024 JJTech <[email protected]>
# Copyright (c) 2024 Nicolás Alvarez <[email protected]>
#
# SPDX-License-Identifier: GPL-2.0-or-later
import sigrokdecode as srd # type: ignore
class Decoder(srd.Decoder):
api_version = 3
id = 'hdq'
name = 'HDQ'
longname = 'HDQ (High-speed Data Queue)'
desc = 'Texas Instruments Gas Gauge battery fuel gauge protocol'
license = 'mit'
inputs = ['logic']
outputs = ['hdq']
tags = ['Embedded/industrial']
channels = (
{'id': 'data', 'name': 'Data', 'desc': 'Data line'},
)
options = ()
annotations = (
('bit', 'Value'),
)
annotation_rows = (
('bits', 'Values', (0,)),
)
def __init__(self):
print("INIT")
self.reset()
def reset(self):
print("RESET")
self.sample_rate = None
self.previous_sample_num = 0
def metadata(self, key, value):
print("METADATA")
if key == srd.SRD_CONF_SAMPLERATE:
self.sample_rate = value
def start(self):
print("START")
self.out_ann = self.register(srd.OUTPUT_ANN)
def decode(self):
print("DECODE")
assert self.sample_rate is not None
MICRO = 1_000_000
MIN_BREAK = self.sample_rate * 190 // MICRO
MIN_ZERO = self.sample_rate * 86 // MICRO
MAX_ZERO = self.sample_rate * 145 // MICRO
MIN_ONE = self.sample_rate * 17 // MICRO
MAX_ONE = self.sample_rate * 50 // MICRO
while True:
self.wait({0: 'f'})
fall_sample = self.samplenum
self.wait({0: 'r'})
raise_sample = self.samplenum
t = raise_sample - fall_sample
ann_start = fall_sample
ann_end = raise_sample
if t > MIN_BREAK:
self.put(ann_start, ann_end, self.out_ann, [0, ['Reset']])
elif MIN_ZERO <= t <= MAX_ZERO:
self.put(ann_start, ann_end, self.out_ann, [0, ['0']])
elif MIN_ONE <= t <= MAX_ONE:
self.put(ann_start, ann_end, self.out_ann, [0, ['1']])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment