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