Multiplexer control script added.

This commit is contained in:
klaute 2016-08-29 17:48:24 +02:00
parent 0479d19b28
commit 03632dfc10

334
tools/muxctrl.py Executable file
View file

@ -0,0 +1,334 @@
###############################################################################
import argparse
import threading
import time
import serial
import copy
###############################################################################
parser = argparse.ArgumentParser(description='USB2SerialMux control helper tool.')
parser.add_argument("-g", "--getbaudrate", default=False, help="", action='store_true')
parser.add_argument("-s", "--setbaudrate", type=int, help="Something like 9600 or 115200.")
parser.add_argument("-m", "--getmuxline", default=False, help="", action='store_true')
parser.add_argument("-l", "--setmuxline", type=int, help="Something like 0 to 7.")
parser.add_argument("-r", "--resettobtldr", default=False, help="Reset the device to the LUFA bootloader.", action='store_true')
###############################################################################
MSG_SOD1 = 0x3c
MSG_SOD2 = 0x3e
MSG_EOD1 = 0x0d
MSG_EOD2 = 0x0a
MSG_TYPE_ANSWER_OK = 0x01
MSG_TYPE_ANSWER_NOK = 0x02
MSG_TYPE_BAUDRATE = 0x03
MSG_TYPE_MUXLINE = 0x04
CC_CMD_SET_BAUDRATE = 0x0A
CC_CMD_GET_BAUDRATE = 0x14
CC_CMD_SET_MUX_LINE = 0x1E
CC_CMD_GET_MUX_LINE = 0x28
CC_CMD_START_BTLDR = 0x32
CC_CMD_GET_BAUDRATE_DATA_TO_RECV 4
CC_CMD_SET_BAUDRATE_DATA_TO_RECV 0
CC_CMD_GET_MUX_LINE_DATA_TO_RECV 1
CC_CMD_SET_MUX_LINE_DATA_TO_RECV 0
CC_CMD_START_BTLDR_DATA_TO_RECV 0
###############################################################################
TIMEOUT_CNT_MAX = 1000
MAIN_LOOP_DELAY_S = 0.05
THREAD_LOOP_DELAY_S = 0.01
###############################################################################
baudrate = 0xffffffff
muxLine = 0xff
###############################################################################
CC_STATE_WAIT_SOD1 = 0x01
CC_STATE_WAIT_SOD2 = 0x02
CC_STATE_READ_DATA = 0x03
CC_STATE_WAIT_EOD1 = 0x04
CC_STATE_WAIT_EOD2 = 0x05
cc_state = CC_STATE_WAIT_SOD1
cc_cmd_list = [ CC_CMD_SET_BAUDRATE,
CC_CMD_GET_BAUDRATE,
CC_CMD_SET_MUX_LINE,
CC_CMD_GET_MUX_LINE,
CC_CMD_START_BTLDR, ]
cc_state_fn = { CC_STATE_WAIT_SOD1 : cc_state_fn_wait_for_sod1,
CC_STATE_WAIT_SOD2 : cc_state_fn_wait_for_sod2,
CC_STATE_WAIT_EOD1 : cc_state_fn_wait_for_eod1,
CC_STATE_WAIT_EOD2 : cc_state_fn_wait_for_eod2,
CC_STATE_GET_TYPE : cc_state_fn_get_type,
CC_STATE_READ_DATA : cc_state_fn_read_data, }
cc_cmd_data_to_read = { CC_CMD_SET_BAUDRATE : CC_CMD_SET_BAUDRATE_DATA_TO_RECV,
CC_CMD_GET_BAUDRATE : CC_CMD_GET_BAUDRATE_DATA_TO_RECV,
CC_CMD_SET_MUX_LINE : CC_CMD_SET_MUX_LINE_DATA_TO_RECV,
CC_CMD_GET_MUX_LINE : CC_CMD_GET_MUX_LINE_DATA_TO_RECV,
CC_CMD_START_BTLDR : CC_CMD_START_BTLDR_DATA_TO_RECV, }
cc_data_read = 0
cc_type = 0
cc_data_buffer = []
# yes a separate counter to manage the order of the received messages
cc_message_cnt = 0
cc_received_messages = []
###############################################################################
thread_obj = None
thread_lock = None
###############################################################################
########## function to call by the thread
def processReceivedData():
incoming = []
thread_started = True
for thread_stop == False:
# 1. read byte from serial port into incoming
# 2. process the received data
for c in incoming:
cc_state_fn[cc_state](c)
time.sleep(THREAD_LOOP_DELAY_S)
thread_started = False
##########
def startReceiverThread():
if thread_started == False:
thread_lock = threading.Lock()
thread_obj = threading.Thread(target=processReceivedData)
thread_obj.start()
thread_stop = False
##########
def stopReceiverThread():
thread_stop = True
thread_obj.join() # wait for the thread to finish
##### CC_STATE_WAIT_SOD1
def cc_state_fn_wait_for_sod1(c):
cc_data_read = 0
cc_type = 0
cc_data_buffer = []
if c == MSG_SOD1:
cc_state = CC_STATE_WAIT_SOD2
else
cc_state = CC_STATE_WAIT_SOD1
##### CC_STATE_WAIT_SOD2
def cc_state_fn_wait_for_sod2(c):
if c == MSG_SOD2:
cc_state = CC_STATE_GET_TYPE
else
cc_state = CC_STATE_WAIT_SOD1
##### CC_STATE_GET_TYPE
def cc_state_fn_get_type(c):
if c in cc_cmd_list:
cc_type = c
if cc_cmd_data_to_read[cc_type] > 0:
cc_state = CC_STATE_READ_DATA
else:
cc_state = CC_STATE_WAIT_EOD1
else
cc_state = CC_STATE_WAIT_SOD1
##### CC_STATE_READ_DATA
def cc_state_fn_read_data(c):
if cc_data_read <= cc_state_data_to_read[cc_state] - 1:
cc_data_buffer[cc_data_read] = c
cc_data_read = cc_data_read + 1
if cc_data_read == cc_state_data_to_read[cc_state]:
cc_state = CC_STATE_WAIT_EOD1
##### CC_STATE_WAIT_EOD1
def cc_state_fn_wait_for_eod1(c):
if c == MSG_EOD1:
cc_state = CC_STATE_WAIT_EOD2
else
cc_state = CC_STATE_WAIT_SOD1
##### CC_STATE_WAIT_EOD2
def cc_state_fn_wait_for_eod2(c):
if c == MSG_EOD2:
# TODO process or save the data
is_message_read = False
thread_lock.acquire()
cc_received_messages.append([ cc_message_cnt, cc_type, is_message_read, copy.deepcopy(cc_data_buffer) ])
thread_lock.release()
cc_message_cnt = cc_message_cnt + 1
cc_state = CC_STATE_WAIT_SOD1
###############################################################################
def getBaudrate():
print "send: get baudrate " % CC_CMD_GET_BAUDRATE
sendSerialData([CC_CMD_GET_BAUDRATE])
def setBaudrate(b):
print "send: set baudrate " % CC_CMD_SET_BAUDRATE
sendSerialData([CC_CMD_SET_BAUDRATE,
(baudrate & 0xff000000) >> 24,
(baudrate & 0xff0000) >> 16,
(baudrate & 0xff00) >> 8,
(baudrate & 0xff)])
###############################################################################
def getMuxLine():
print "send: get mux line " % CC_CMD_GET_MUX_LINE
sendSerialData([CC_CMD_GET_MUX_LINE])
def setMuxLine(l):
print "send: set mux line " % CC_CMD_SET_MUX_LINE
sendSerialData([CC_CMD_SET_MUX_LINE, muxLine])
###############################################################################
def getStatus():
getBaudrate()
getMuxLine()
###############################################################################
def resetToBtldr():
print "send: reset to bootloader message " % CC_CMD_START_BTLDR
sendSerialData([CC_CMD_START_BTLDR])
###############################################################################
#####
def openSerialDevice(d):
pass
#####
def closeSerialDevice():
pass
#####
def sendSerialData(data):
for c in data:
pass
###############################################################################
if __name__ == "__main__":
# parse the commandline arguments
args = parser.parse_args()
dataSend = 0
timeout = 0
# 1. open serial device or abort
openSerialDevice("/dev/ttyACM0")
# 2. start thread to poll processReceivedData()
startReceiverThread()
# 3. get status
getStatus()
# 4. get and process the commandline arguments/parameter
if args.resettobtldr == True:
resetToBtldr()
else:
if args.getbaudrate == True:
getBaudrate()
dataSend = dataSend + 1
if args.getmuxline == True:
getMuxLine()
dataSend = dataSend + 1
if args.setbaudrate != None:
baudrate = map(int, args.setbaudrate)
setBaudrate(baudrate)
dataSend = dataSend + 1
if args.setmuxline != None:
muxLine = map(int, args.setmuxline)
if muxLine < 0:
muxLine = 0
if muxLine > 7:
muxLine = 7
setMuxLine(muxLine)
dataSend = dataSend + 1
# 5. start main loop
for dataSend > 0 and timeout < TIMEOUT_CNT_MAX:
thread_lock.acquire()
tmp_messages = copy.deepcopy(cc_received_messages)
thread_lock.release()
# 5.1 wait for the response(s)
for e in tmp_messages:
if e[2] == False: # test for unread message
# process it and set the data to read
if e[1] == MSG_TYPE_ANSWER_OK:
print "recv: OK"
elif e[1] == MSG_TYPE_ANSWER_NOK:
print "recv: NOT OK"
elif e[1] == MSG_TYPE_BAUDRATE:
baudrate = e[3][0] << 24
baudrate = baudrate + e[3][1] << 16
baudrate = baudrate + e[3][2] << 8
baudrate = baudrate + e[3][3]
print "recv: baudrate = " % baudrate
elif e[1] == MSG_TYPE_MUXLINE:
muxLine = e[3][0]
print "recv: muxLine = " % muxLine
else:
print "err: unknown type " % e[1]
break
thread_lock.acquire()
cc_received_messages[e[0]][2] = True
thread_lock.release()
timeout = 0 # reset the timeout
# reduce the number of messages to receive
dataSend = dataSend - 1
# manage the timeout behaviour
time.sleep(MAIN_LOOP_DELAY_S)
timeout = timeout + 1
# 6. stop data processing thread
stopReceiverThread()
# 7. close serial device
closeSerialDevice()
exit(0)