# Copyright (c) 2024 JJTech # Copyright (c) 2024 Nicolás Alvarez # # 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', 'Bit'), ('addr', 'Address'), ('data', 'Data'), ('rw', 'R/W Bit'), ) annotation_rows = ( ('bits', 'Bits', (0,)), ('values', 'Values', (1,2,3)), ) 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) self.set_state('INITIAL') def set_state(self, state): self.state = state self.num = 0 self.bitcount = 0 self.startsample = 0 def decode_txs(self, bits): for bit, start, end in bits: if bit == "reset": self.set_state("INITIAL") continue bit = int(bit) if self.state == 'INITIAL': if self.startsample == 0: self.startsample = start self.num |= (bit << self.bitcount) self.bitcount += 1 if self.bitcount == 7: self.put(self.startsample, end, self.out_ann, [1, [ f'Address: #0x{self.num:04x}', f'Addr: #0x{self.num:04x}', f'#0x{self.num:04x}', f'0x{self.num:x}' ]]) self.set_state('RW') elif self.state == 'RW': if bit: label = ['Write', 'W'] else: label = ['Read', 'R'] self.dir=bit self.put(start, end, self.out_ann, [3, label]) self.set_state('DATA') elif self.state == 'DATA': if self.startsample == 0: self.startsample = start self.num |= (bit << self.bitcount) self.bitcount += 1 if self.bitcount == 8: self.put(self.startsample, end, self.out_ann, [2, [ f'Data {"to write" if self.dir else "read"}: 0x{self.num:x}', f'Data {"W" if self.dir else "R"}: 0x{self.num:x}', f'Data: 0x{self.num:x}', f'D: 0x{self.num:x}', f'0x{self.num:x}', ]]) self.set_state('INITIAL') def decode_edges(self): while True: self.wait({0: 'f'}) fall_sample = self.samplenum self.wait({0: 'r'}) raise_sample = self.samplenum yield (fall_sample, raise_sample) def decode_bits(self, edges): """ Measures the timings between edges and decodes them into bits. Yields tuples with ("reset"|"0"|"1", start, end). """ 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 for fall_sample, raise_sample in edges: 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']]) yield ("reset", ann_start, ann_end) elif MIN_ZERO <= t <= MAX_ZERO: self.put(ann_start, ann_end, self.out_ann, [0, ['0']]) yield ("0", ann_start, ann_end) elif MIN_ONE <= t <= MAX_ONE: self.put(ann_start, ann_end, self.out_ann, [0, ['1']]) yield ("1", ann_start, ann_end) def decode(self): print("DECODE") assert self.sample_rate is not None for tx in self.decode_txs(self.decode_bits(self.decode_edges())): pass