|
@@ -120,10 +120,14 @@ class App:
|
120
|
120
|
print("in:",msg[1])
|
121
|
121
|
|
122
|
122
|
|
123
|
|
- def _parse_error( self, msg ):
|
|
123
|
+ def _parse_error( self, msg, cmd_str=None ):
|
|
124
|
+
|
|
125
|
+ if cmd_str:
|
|
126
|
+ msg += " Command:{}".format(cmd_str)
|
|
127
|
+
|
124
|
128
|
return (None,msg)
|
125
|
129
|
|
126
|
|
- def _parse_int( self, token, var_label, max_value ):
|
|
130
|
+ def _parse_int( self, token, var_label, min_value, max_value ):
|
127
|
131
|
# convert the i2c destination address to an integer
|
128
|
132
|
try:
|
129
|
133
|
int_value = int(token)
|
|
@@ -131,11 +135,75 @@ class App:
|
131
|
135
|
return self._parse_error("Synax error: '{}' is not a legal integer.".format(token))
|
132
|
136
|
|
133
|
137
|
# validate the i2c address value
|
134
|
|
- if 0 > int_value or int_value > max_value:
|
|
138
|
+ if min_value > int_value or int_value > max_value:
|
135
|
139
|
return self._parse_error("Syntax error: '{}' {} out of range 0 to {}.".format(token,int_value,max_value))
|
136
|
140
|
|
137
|
141
|
return (int_value,None)
|
138
|
142
|
|
|
143
|
+ def parse_app_cmd( self, cmd_str ):
|
|
144
|
+ """
|
|
145
|
+ Command syntax <opcode> <remote_i2c_addr> <value>
|
|
146
|
+ """
|
|
147
|
+
|
|
148
|
+ op_tok_idx = 0
|
|
149
|
+ i2c_tok_idx = 1
|
|
150
|
+ val_tok_idx = 2
|
|
151
|
+
|
|
152
|
+ cmdD = {
|
|
153
|
+ 'p':{ 'reg':0, 'n':1, 'min':0, 'max':4 }, # timer pre-scalar: sets timer tick rate
|
|
154
|
+ 't':{ 'reg':1, 'n':2, 'min':0, 'max':10e7 }, # microseconds
|
|
155
|
+ 'd':{ 'reg':3, 'n':1, 'min':0, 'max':100 }, # pwm duty cylce (0-100%)
|
|
156
|
+ 'f':{ 'reg':4, 'n':1, 'min':1, 'max':5 }, # pwm frequency divider 1=1,2=8,3=64,4=256,5=1024
|
|
157
|
+ }
|
|
158
|
+
|
|
159
|
+ cmd_str = cmd_str.strip()
|
|
160
|
+
|
|
161
|
+ tokenL = cmd_str.split(' ')
|
|
162
|
+
|
|
163
|
+ # validate the counf of tokens
|
|
164
|
+ if len(tokenL) != 3:
|
|
165
|
+ return self._parse_error("Syntax error: Invalid token count.",cmd_str)
|
|
166
|
+
|
|
167
|
+ opcode = tokenL[op_tok_idx]
|
|
168
|
+
|
|
169
|
+ # validate the opcode
|
|
170
|
+ if opcode not in cmdD:
|
|
171
|
+ return self._parse_error("Syntax error: Invalid opcode.",cmd_str)
|
|
172
|
+
|
|
173
|
+ # convert the i2c destination address to an integer
|
|
174
|
+ i2c_addr, msg = self._parse_int( tokenL[i2c_tok_idx], "i2c address", 0,127 )
|
|
175
|
+
|
|
176
|
+ if i2c_addr is None:
|
|
177
|
+ return (None,msg)
|
|
178
|
+
|
|
179
|
+ d = cmdD[ opcode ]
|
|
180
|
+
|
|
181
|
+ # get the value
|
|
182
|
+ value, msg = self._parse_int( tokenL[val_tok_idx], "command value", d['min'], d['max'] )
|
|
183
|
+
|
|
184
|
+ if value is None:
|
|
185
|
+ return (value,msg)
|
|
186
|
+
|
|
187
|
+ dataL = [ value ]
|
|
188
|
+
|
|
189
|
+ if opcode == 't':
|
|
190
|
+
|
|
191
|
+ coarse = int(value/(32*254))
|
|
192
|
+ fine = int((value - coarse*32*254)/32)
|
|
193
|
+ dataL = [ coarse, fine ]
|
|
194
|
+
|
|
195
|
+ elif opcode == 'd':
|
|
196
|
+ dataL = [ int(value * 255 / 100.0) ]
|
|
197
|
+
|
|
198
|
+ cmd_bV = bytearray( [ ord('w'), i2c_addr, d['reg'], len(dataL) ] + dataL )
|
|
199
|
+
|
|
200
|
+ if False:
|
|
201
|
+ print('cmd_bV:')
|
|
202
|
+ for x in cmd_bV:
|
|
203
|
+ print(int(x))
|
|
204
|
+
|
|
205
|
+ return (cmd_bV,None)
|
|
206
|
+
|
139
|
207
|
def parse_cmd( self, cmd_str ):
|
140
|
208
|
|
141
|
209
|
op_tok_idx = 0
|
|
@@ -143,7 +211,11 @@ class App:
|
143
|
211
|
reg_tok_idx = 2
|
144
|
212
|
rdn_tok_idx = 3
|
145
|
213
|
|
146
|
|
- cmd_str.strip()
|
|
214
|
+ cmd_str = cmd_str.strip()
|
|
215
|
+
|
|
216
|
+ # if this is a high level command
|
|
217
|
+ if cmd_str[0] not in ['r','w']:
|
|
218
|
+ return self.parse_app_cmd( cmd_str )
|
147
|
219
|
|
148
|
220
|
# convert the command string to tokens
|
149
|
221
|
tokenL = cmd_str.split(' ')
|
|
@@ -163,16 +235,16 @@ class App:
|
163
|
235
|
if op_code == 'r' and len(tokenL) != 4:
|
164
|
236
|
return self._parse_error("Syntax error: Illegal read syntax.")
|
165
|
237
|
|
166
|
|
- if op_code == 'w' and len(tokenL) == 4:
|
|
238
|
+ if op_code == 'w' and len(tokenL) < 4:
|
167
|
239
|
return self._parse_error("Syntax error: Illegal write command too short.")
|
168
|
240
|
|
169
|
241
|
# convert the i2c destination address to an integer
|
170
|
|
- i2c_addr, msg = self._parse_int( tokenL[i2c_tok_idx], "i2c address", 127 )
|
|
242
|
+ i2c_addr, msg = self._parse_int( tokenL[i2c_tok_idx], "i2c address", 0,127 )
|
171
|
243
|
|
172
|
244
|
if i2c_addr is None:
|
173
|
245
|
return (None,msg)
|
174
|
246
|
|
175
|
|
- reg_addr, msg = self._parse_int( tokenL[reg_tok_idx], "reg address", 255 )
|
|
247
|
+ reg_addr, msg = self._parse_int( tokenL[reg_tok_idx], "reg address", 0, 255 )
|
176
|
248
|
|
177
|
249
|
if reg_addr is None:
|
178
|
250
|
return (None,msg)
|
|
@@ -181,7 +253,7 @@ class App:
|
181
|
253
|
|
182
|
254
|
# parse and validate the count of bytes to read
|
183
|
255
|
if op_code == 'r':
|
184
|
|
- op_byteN, msg = self._parse_int( tokenL[ rdn_tok_idx ], "read byte count", 255 )
|
|
256
|
+ op_byteN, msg = self._parse_int( tokenL[ rdn_tok_idx ], "read byte count", 0, 255 )
|
185
|
257
|
|
186
|
258
|
if op_byteN is None:
|
187
|
259
|
return (None,msg)
|
|
@@ -191,7 +263,7 @@ class App:
|
191
|
263
|
elif op_code == 'w':
|
192
|
264
|
|
193
|
265
|
for j,i in enumerate(range(reg_tok_idx+1,len(tokenL))):
|
194
|
|
- value, msg = self._parse_int( tokenL[i], "write value: %i" % (j), 255 )
|
|
266
|
+ value, msg = self._parse_int( tokenL[i], "write value: %i" % (j), 0, 255 )
|
195
|
267
|
|
196
|
268
|
if value is None:
|
197
|
269
|
return (None,msg)
|
|
@@ -238,7 +310,7 @@ class App:
|
238
|
310
|
|
239
|
311
|
# if a serial msg was received
|
240
|
312
|
if msg is not None and msg[0] == DATA_MSG:
|
241
|
|
- print("ser:",msg[1])
|
|
313
|
+ print("ser:",msg[1],int(msg[1][0]))
|
242
|
314
|
|
243
|
315
|
|
244
|
316
|
self.serialProc.quit()
|
|
@@ -252,7 +324,7 @@ def parse_args():
|
252
|
324
|
ap = argparse.ArgumentParser(description=descStr)
|
253
|
325
|
|
254
|
326
|
|
255
|
|
- ap.add_argument("-s","--setup", default="cfg/p_ac.yml", help="YAML configuration file.")
|
|
327
|
+ ap.add_argument("-s","--setup", default="picadae_cmd.yml", help="YAML configuration file.")
|
256
|
328
|
ap.add_argument("-c","--cmd", nargs="*", help="Give a command as multiple tokens")
|
257
|
329
|
ap.add_argument("-r","--run", help="Run a named command list from the setup file.")
|
258
|
330
|
ap.add_argument("-l","--log_level",choices=logL, default="warning", help="Set logging level: debug,info,warning,error,critical. Default:warning")
|