@@ -36,7 +36,7 @@ class State(Enum):
3636 TELEM = 2
3737
3838
39- class State_Telem (Enum ):
39+ class State_Dshot (Enum ):
4040 RESET = 0
4141 START = 1
4242 RECV = 2
@@ -94,7 +94,8 @@ def __init__(self):
9494
9595 def reset (self ):
9696 self .state = State .CMD
97- self .state_telem = State_Telem .START
97+ self .state_telem = State_Dshot .START
98+ self .state_dshot = State_Dshot .START
9899
99100 self .samplerate = None
100101 self .inreset = False
@@ -118,7 +119,9 @@ def metadata(self, key, value):
118119 if key == srd .SRD_CONF_SAMPLERATE :
119120 self .samplerate = value
120121
121-
122+ def display_bit (self , bitseq , annot ):
123+ self .put (bitseq .ss , bitseq .es , self .out_ann ,
124+ [annot , ['%d' % bool (bitseq )]])
122125
123126 def display_dshot (self ,dshot ):
124127 crc_startsample = dshot .results [12 ].ss
@@ -139,84 +142,93 @@ def display_dshot(self,dshot):
139142 self .put (crc_startsample , dshot .results [15 ].es , self .out_ann ,
140143 [4 , ['CRC INVALID' ]])
141144
145+ def display_telem (self , telem ):
146+ crc_startsample = telem .results [12 ].ss
147+ self .put (crc_startsample , telem .results [15 ].es , self .out_ann ,
148+ [3 , ['Calc CRC: ' + ('%04d' % telem .crc_calc ) + ' TXed CRC:' + ('%04d' % telem .crc_recv )]])
149+ if not telem .crc_ok :
150+ self .put (crc_startsample , telem .results [15 ].es , self .out_ann ,
151+ [4 , ['CRC INVALID' ]])
152+
142153
143- def complete_DshotBit (self , * args ):
144- bitseq = BitDshot (* args )
145154
146- self .put (bitseq .ss , bitseq .es , self .out_ann ,
147- [0 , ['%d' % bool (bitseq )]])
148- return [bitseq ]
149155
150156 def decode (self ):
151157 if not self .samplerate :
152158 raise SamplerateError ('Cannot decode without samplerate.' )
153159
154160 dshot_value = DshotCmd (self .dshot_cfg )
155161 telem_value = DshotTelem (self .dshot_cfg )
156- results = []
157- telem = 0b0
158- tlm_start = 0
159162
160163 #bitseq = BitDshot()
161164 while True :
162165
163166 match self .state :
164167 case State .CMD :
165- if not self .dshot_cfg .bidirectional :
166- pins = self .wait ([{0 : 'r' }, {0 : 'f' }, {'skip' : self .dshot_cfg .samples_after_motorcmd }])
167- else :
168- pins = self .wait ([{0 : 'f' }, {0 : 'r' }, {'skip' : self .dshot_cfg .samples_after_motorcmd }])
169- #TODO: Increase skip to maximum time for effiency
170- #TODO: Mark any changes in this time as errors? Option to reduce load?
171-
172- if self .currbit_ss and self .currbit_es and self .matched [2 ]:
173- # Assume end of packet if have seen start and end of a potential bit but no further change within 3 periods
174- # TODO: Confirm wait period this works with spec
175-
176- args = self .currbit_ss , self .currbit_es , (self .currbit_ss + self .dshot_cfg .samples_pp )
177- results += self .complete_DshotBit (* args )
178- self .currbit_ss = None
179- self .currbit_es = None
180- #print(results)
181- # Pass results to decoder
182-
183- result = dshot_value .handle_bits_dshot (results )
184- if result :
185- self .display_dshot (dshot_value )
186- if result and self .dshot_cfg .bidirectional :
187- self .state = State .TELEM
188-
189- results = []
190- #dshot_value = DshotCmd(self.dshot_cfg)
191-
192- if self .matched [0 ] and not self .currbit_ss and not self .currbit_es :
193- # Start of bit
194- self .currbit_ss = self .samplenum
195- elif self .matched [1 ] and self .currbit_ss and not self .currbit_es :
196- # End of bit
197- self .currbit_es = self .samplenum
198- elif self .matched [0 ] and self .currbit_es and self .currbit_ss :
199- # Have complete bit, can handle bit now
200- args = self .currbit_ss , self .currbit_es , self .samplenum
201- results += self .complete_DshotBit (* args )
202-
203- self .currbit_ss = self .samplenum
204- self .currbit_es = None
168+ match self .state_dshot :
169+ case State_Dshot .RESET :
170+ dshot_value = DshotCmd (self .dshot_cfg )
171+ self .state_dshot = State_Dshot .START
172+
173+ case State_Dshot .START :
174+ if not self .dshot_cfg .bidirectional :
175+ pins = self .wait ([{0 : 'r' }, {0 : 'f' }, {'skip' : self .dshot_cfg .samples_after_motorcmd }])
176+ else :
177+ pins = self .wait ([{0 : 'f' }, {0 : 'r' }, {'skip' : self .dshot_cfg .samples_after_motorcmd }])
178+ #TODO: Increase skip to maximum time for effiency
179+ #TODO: Mark any changes in this time as errors? Option to reduce load?
180+
181+ if self .currbit_ss and self .currbit_es and self .matched [2 ]:
182+ # Assume end of packet if have seen start and end of a potential bit but no further change within 3 periods
183+ # TODO: Confirm wait period this works with spec
184+
185+ args = self .currbit_ss , self .currbit_es , (self .currbit_ss + self .dshot_cfg .samples_pp )
186+ curr_bit = BitDshot (* args )
187+ dshot_value .add_bit (curr_bit )
188+ self .display_bit (curr_bit ,0 )
189+ self .currbit_ss = None
190+ self .currbit_es = None
191+ #print(results)
192+ # Pass results to decoder
193+
194+ result = dshot_value .handle_bits_dshot ()
195+ if result :
196+ self .display_dshot (dshot_value )
197+ self .state_dshot = State_Dshot .RESET
198+ if result and self .dshot_cfg .bidirectional :
199+ self .state = State .TELEM
200+
201+
202+ if self .matched [0 ] and not self .currbit_ss and not self .currbit_es :
203+ # Start of bit
204+ self .currbit_ss = self .samplenum
205+ elif self .matched [1 ] and self .currbit_ss and not self .currbit_es :
206+ # End of bit
207+ self .currbit_es = self .samplenum
208+ elif self .matched [0 ] and self .currbit_es and self .currbit_ss :
209+ # Have complete bit, can handle bit now
210+ args = self .currbit_ss , self .currbit_es , self .samplenum
211+ curr_bit = BitDshot (* args )
212+ dshot_value .add_bit (curr_bit )
213+ self .display_bit (curr_bit ,0 )
214+
215+ self .currbit_ss = self .samplenum
216+ self .currbit_es = None
205217 case State .TELEM :
206218 match self .state_telem :
207- case State_Telem .RESET :
208- telem = 0b0
209- self .state_telem = State_Telem .START
219+ case State_Dshot .RESET :
220+ telem_value = DshotTelem ( self . dshot_cfg )
221+ self .state_telem = State_Dshot .START
210222
211- case State_Telem .START :
223+ case State_Dshot .START :
212224 # First wait for falling edge (idle high)
213225 pins = self .wait ([{0 : 'f' }])
214226 # Save start pulse
215227 tlm_start = self .samplenum
216228 # Switch to receiving state
217- self .state_telem = State_Telem .RECV
229+ self .state_telem = State_Dshot .RECV
218230 # TODO: Check if still low after 1/8 bitlength for error det?
219- case State_Telem .RECV :
231+ case State_Dshot .RECV :
220232 # First conditions skips half bit width and matches low
221233 # Second condition skips half bit width and matches high
222234 pins = self .wait ([{0 : 'l' , 'skip' : self .dshot_cfg .telem_baudrate_midpoint },
@@ -225,24 +237,22 @@ def decode(self):
225237 # Append next bit
226238 args = (self .samplenum - self .dshot_cfg .telem_baudrate_midpoint ), self .samplenum , (self .samplenum + self .dshot_cfg .telem_baudrate_midpoint )
227239 curr_bit = Bit_DshotTelem (* args ,self .matched )
228- self .put (curr_bit .ss ,curr_bit .es ,
229- self .out_ann ,
230- [5 , ['%04d' % curr_bit .bit_ ]])
231-
240+ self .display_bit (curr_bit ,5 )
232241 telem_value .add_bit (curr_bit )
233242
234243
235244 # Skip half bitwidth to end of bit
236245 pins = self .wait ([{'skip' : self .dshot_cfg .telem_baudrate_midpoint }])
237246
238- if telem_value .bits .bit_length () >= 20 :
247+ if telem_value .bits .bit_length () >= 20 - 1 :
239248 telem_value .process_telem ()
240-
249+ self . display_telem ( telem_value )
241250 # Reset
242- self .state_telem = State_Telem .RESET
251+ self .state_telem = State_Dshot .RESET
243252 # Except Dshot packet next
244253 self .state = State .CMD
245254
255+
246256 # If not mark as error
247257
248258 # Then skip x samples and sample
0 commit comments