Multiplexer control script added.
This commit is contained in:
parent
0479d19b28
commit
03632dfc10
1 changed files with 334 additions and 0 deletions
334
tools/muxctrl.py
Executable file
334
tools/muxctrl.py
Executable 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)
|
Loading…
Reference in a new issue