Skip to content

Commit 4c14053

Browse files
Merge pull request #1 from hyp0dermik-code/api_v3
Api v3
2 parents 5bbc915 + 61da1ae commit 4c14053

1 file changed

Lines changed: 84 additions & 86 deletions

File tree

pd.py

Lines changed: 84 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class Decoder(srd.Decoder):
5656

5757
)
5858
annotation_rows = (
59-
('bit', 'Bits', (0,)),
59+
('bits', 'Bits', (0,)),
6060
('dshot_data', 'DShot Data', (1,2,3)),
6161
('dshot_errors', 'Dshot Errors', (4,)),
6262
)
@@ -68,138 +68,136 @@ def __init__(self):
6868

6969
def reset(self):
7070
self.samplerate = None
71-
self.oldpin = None
72-
self.ss_packet = None
73-
self.ss = None
74-
self.es = None
75-
self.bits = []
71+
# self.oldpin = None
72+
# self.ss_packet = None
73+
# self.ss = None
74+
# self.es = None
75+
# self.bits = []
7676
self.inreset = False
7777
self.bidirectional = False
7878
self.dshot_period = 3.33e-6
7979
self.actual_period = None
80+
self.halfbitwidth = None
81+
self.currbit_ss = None
82+
self.currbit_es = None
83+
self.samples_toreset = None
84+
self.samples_pp = None
8085

8186

8287
def start(self):
8388
self.bidirectional = True if self.options['bidir'] == 'True' else False
8489
self.dshot_period = self.dshot_period_lookup[self.options['dshot_rate']]
90+
self.samples_pp = int(self.samplerate*self.dshot_period)
91+
self.samples_toreset = self.samples_pp*3
92+
# self.halfbitwidth = int((self.samplerate / self.dshot_period) / 2.0)
8593
#print("start period",self.dshot_period)
8694
self.out_ann = self.register(srd.OUTPUT_ANN)
8795

8896
def metadata(self, key, value):
8997
if key == srd.SRD_CONF_SAMPLERATE:
9098
self.samplerate = value
9199

92-
def handle_bits(self, samplenum):
93-
if len(self.bits) == 16:
94-
dshot_value = int(reduce(lambda a, b: (a << 1) | b, self.bits[:11]))
95-
telem_request = self.bits[11]
96-
received_crc = int(reduce(lambda a, b: (a << 1) | b, self.bits[12:]))
100+
def handle_bits(self, results):
101+
#ss, es, bit
102+
#print(results)
103+
bits = [result[2] for result in results]
104+
# print(bits)
105+
106+
107+
if len(bits) == 16:
108+
dshot_value = int(reduce(lambda a, b: (a << 1) | b, bits[:11]))
109+
telem_request = bits[11]
110+
received_crc = int(reduce(lambda a, b: (a << 1) | b, bits[12:]))
97111

98-
value_tocrc = int(reduce(lambda a, b: (a << 1) | b, self.bits[:12]))
99-
100-
calculated_crc = ((~(value_tocrc ^ (value_tocrc >> 4) ^ (value_tocrc >> 8))) & 0x0F)
112+
value_tocrc = int(reduce(lambda a, b: (a << 1) | b, bits[:12]))
113+
114+
if self.bidirectional:
115+
calculated_crc = int((~(value_tocrc ^ (value_tocrc >> 4) ^ (value_tocrc >> 8)))&0x0F)
116+
else:
117+
calculated_crc = int(((value_tocrc ^ (value_tocrc >> 4) ^ (value_tocrc >> 8)))&0x0F)
101118

102-
crc_ok = True if value_tocrc == calculated_crc else False
119+
if received_crc == calculated_crc:
120+
crc_ok = True
121+
else:
122+
crc_ok = False
103123

104124
# TODO: Align this correctly
105-
crc_startsample = samplenum-(self.actual_period*5)
125+
crc_startsample = results[12][0]
106126

107127
# Split annotation based on value type
108128
if dshot_value < 48:
109129
# Command
110-
self.put(self.ss_packet, crc_startsample, self.out_ann,
130+
self.put(results[0][0], crc_startsample, self.out_ann,
111131
[1, ['%04d' % dshot_value]])
112132
else:
113133
# Throttle
114-
self.put(self.ss_packet, crc_startsample, self.out_ann,
134+
self.put(results[0][0], crc_startsample, self.out_ann,
115135
[2, ['%04d' % dshot_value]])
116136

117-
self.put(crc_startsample, samplenum, self.out_ann, [3, ['Calc CRC: '+('%04d' % calculated_crc)+' TXed CRC:'+('%04d' % received_crc)]])
137+
self.put(crc_startsample, results[15][1], self.out_ann, [3, ['Calc CRC: '+('%04d' % calculated_crc)+' TXed CRC:'+('%04d' % received_crc)]])
118138
if not crc_ok:
119-
self.put(crc_startsample, samplenum, self.out_ann,
139+
self.put(crc_startsample, results[15][1], self.out_ann,
120140
[4, ['CRC INVALID']])
121141

122142

123143
self.bits = []
124144
self.ss_packet = None
125145
else:
126-
self.put(self.es, self.samplenum, self.out_ann,
127-
[1, ['ERROR: INVALID PACKET LENGTH', 'ERR', 'E']])
128-
146+
return
147+
# self.put(results[0][0], results[-1::1][1], self.out_ann,
148+
# [1, ['ERROR: INVALID PACKET LENGTH', 'ERR', 'E']])
129149

130-
def handle_bit(self):
131-
if self.ss and self.es:
132-
period = self.samplenum - self.ss
133-
duty = self.es - self.ss
134-
# Ideal duty for T0H: 33%, T1H: 66%.
135-
bit_ = (duty / period) > 0.5
136150

137-
self.put(self.ss, self.samplenum, self.out_ann,
138-
[0, ['%d' % bit_]])
151+
def handle_bit(self, ss, es, nb_ss):
139152

140-
self.bits.append(bit_)
141-
self.actual_period = period
142-
#self.handle_bits(self.samplenum)
143-
if self.ss_packet is None:
144-
self.ss_packet = self.samplenum
145-
self.ss = self.samplenum
153+
period = nb_ss - ss
154+
duty = es - ss
155+
# Ideal duty for T0H: 33%, T1H: 66%.
156+
bit_ = (duty / period) > 0.5
146157

147-
def handle_notbit(self):
148-
self.inreset = False
149-
self.es = self.samplenum
150-
151-
def check_reset(self):
152-
# Decode last bit value.
153-
tH = (self.es - self.ss) / self.samplerate
154-
155-
# High if greater than half the period
156-
bit_ = True if tH >= (self.dshot_period/2) else False
158+
self.put(ss, nb_ss, self.out_ann,
159+
[0, ['%d' % bit_]])
160+
return [ss,nb_ss,bit_]
157161

158-
self.bits.append(bit_)
159-
self.handle_bits(self.es)
160-
161-
self.put(self.ss, self.es, self.out_ann, [0, ['%d' % bit_]])
162-
# self.put(self.es, self.samplenum, self.out_ann,
163-
# [1, ['RESET', 'RST', 'R']])
164-
165-
self.inreset = True
166-
self.bits = []
167-
self.ss_packet = None
168-
self.ss = None
162+
169163
def decode(self):
170164
if not self.samplerate:
171165
raise SamplerateError('Cannot decode without samplerate.')
172-
166+
167+
results = []
173168
while True:
174-
# TODO: Come up with more appropriate self.wait() conditions.
175-
(pin,) = self.wait()
176-
177-
if self.oldpin is None:
178-
self.oldpin = pin
179-
continue
180-
181-
# Check idle condition if longer is greater than 2x max period
182-
# TODO: Confirm this with spec
183169
if not self.bidirectional:
184-
if not self.inreset and not pin and self.es is not None and \
185-
self.ss is not None and \
186-
(self.samplenum - self.es) / self.samplerate > self.dshot_period*2:
187-
self.check_reset()
188-
if not self.oldpin and pin:
189-
# Rising edge
190-
self.handle_bit()
191-
elif self.oldpin and not pin:
192-
# Falling edge
193-
self.handle_notbit()
170+
pins = self.wait([{0: 'r'},{0: 'f'},{'skip':self.samples_toreset}])
194171
else:
195-
if self.oldpin and not pin:
196-
# Falling edge.
197-
self.handle_bit()
198-
elif not self.oldpin and pin:
199-
# Rising edge.
200-
self.handle_notbit()
201-
202-
self.oldpin = pin
172+
pins = self.wait([{0: 'f'},{0: 'r'},{'skip':self.samples_toreset}])
173+
174+
if self.currbit_ss and self.currbit_es and self.matched[2]:
175+
# Assume end of packet if have seen start and end of a potential bit but no further change within 3 periods
176+
# TODO: Confirm wait period this works with spec
177+
results += [self.handle_bit(self.currbit_ss,self.currbit_es,(self.currbit_ss+self.samples_pp))]
178+
self.currbit_ss = None
179+
self.currbit_es = None
180+
181+
# Pass results to decoder
182+
self.handle_bits(results)
183+
results = []
184+
185+
186+
if self.matched[0] and not self.currbit_ss and not self.currbit_es:
187+
# Start of bit
188+
self.currbit_ss = self.samplenum
189+
elif self.matched[1] and self.currbit_ss and not self.currbit_es:
190+
# End of bit
191+
self.currbit_es = self.samplenum
192+
elif self.matched[0] and self.currbit_es and self.currbit_ss:
193+
# Have complete bit, can handle bit now
194+
result = [self.handle_bit(self.currbit_ss,self.currbit_es,self.samplenum)]
195+
# print(result)
196+
results += result
197+
self.currbit_ss = self.samplenum
198+
self.currbit_es = None
199+
200+
203201

204202

205203

0 commit comments

Comments
 (0)