ed@448: import serial edouard@453: import exceptions edouard@453: import ctypes edouard@453: import time ed@448: from threading import Lock ed@448: edouard@482: MAX_PACKET_SIZE=64 edouard@482: ed@448: LPC_STATUS=dict(STARTED = 0x01, ed@448: STOPPED = 0x02, ed@448: DEBUG = 0x03) ed@448: ed@448: class LPCError(exceptions.Exception): ed@448: """Exception class""" ed@448: def __init__(self, msg): ed@448: self.msg = msg ed@448: return ed@448: ed@448: def __str__(self): ed@448: return "LPC communication error ! " + str(self.msg) ed@448: ed@448: class LPCProto: ed@448: def __init__(self, port, rate, timeout): edouard@453: # serialize access lock edouard@453: self.TransactionLock = Lock() ed@448: # open serial port edouard@453: # self.serialPort = serial.Serial( port, rate, timeout = timeout ) edouard@453: # Debugging serial stuff edouard@453: self._serialPort = serial.Serial( port, rate, timeout = timeout ) edouard@453: class myser: edouard@453: def read(self_,cnt): edouard@453: res = self._serialPort.read(cnt) edouard@453: print "Recv :", map(hex,map(ord,res)) edouard@453: return res edouard@453: def write(self_, str): edouard@453: print "Send :", map(hex,map(ord,str)) edouard@453: self._serialPort.write(str) edouard@453: def flush(self_): edouard@453: self._serialPort.flush() edouard@453: self.serialPort = myser() edouard@453: # start with empty ed@448: self.serialPort.flush() ed@448: # handshake edouard@453: self.HandleTransaction(IDLETransaction()) ed@448: ed@448: def HandleTransaction(self, transaction): ed@448: self.TransactionLock.acquire() ed@448: try: ed@448: transaction.SetPseudoFile(self.serialPort) ed@448: # send command, wait ack (timeout) ed@448: transaction.SendCommand() ed@448: current_plc_status = transaction.GetCommandAck() ed@448: if current_plc_status is not None: ed@448: res = transaction.ExchangeData() ed@448: else: ed@448: raise LPCError("LPC transaction error - controller did not answer as expected") ed@448: finally: ed@448: self.TransactionLock.release() ed@448: return current_plc_status, res ed@448: ed@448: class LPCTransaction: edouard@453: def __init__(self, command, optdata = ""): edouard@453: self.Command = command edouard@453: self.OptData = optdata edouard@453: self.pseudofile = None ed@448: edouard@453: def SetPseudoFile(self, pseudofile): ed@448: self.pseudofile = pseudofile ed@448: ed@448: def SendCommand(self): ed@448: # send command thread ed@448: self.pseudofile.write(chr(self.Command)) ed@448: ed@448: def GetCommandAck(self): edouard@453: res = self.pseudofile.read(2) edouard@453: if len(res) == 2: edouard@453: comm_status, current_plc_status = map(ord, res) edouard@453: else: edouard@453: raise LPCError("LPC transaction error - controller did not ack order") ed@448: # LPC returns command itself as an ack for command ed@448: if(comm_status == self.Command): ed@448: return current_plc_status ed@448: return None ed@448: edouard@453: def SendData(self): edouard@453: length = len(self.OptData) edouard@453: # transform length into a byte string edouard@453: # we presuppose endianess of LPC same as PC edouard@482: lengthstr = ctypes.string_at(ctypes.pointer(ctypes.c_int(length)),4) edouard@482: buffer = lengthstr + self.OptData edouard@482: ################################################################### edouard@482: # TO BE REMOVED AS SOON AS USB IS FIXED IN CONTROLLER edouard@482: ################################################################### edouard@482: length += 4 edouard@482: cursor = 0 edouard@482: while cursor < length: edouard@482: next_cursor = cursor + MAX_PACKET_SIZE edouard@482: # sent just enough bytes to not crash controller edouard@482: self.pseudofile.write(buffer[cursor:next_cursor]) edouard@482: # if sent quantity was 128 edouard@482: if next_cursor <= length: edouard@482: self.GetCommandAck() edouard@482: cursor = next_cursor edouard@453: edouard@453: def GetData(self): edouard@453: lengthstr = self.pseudofile.read(4) edouard@453: # transform a byte string into length edouard@453: length = ctypes.cast(ctypes.c_char_p(lengthstr), ctypes.POINTER(ctypes.c_int)).contents.value edouard@453: return self.pseudofile.read(length) edouard@453: edouard@453: def ExchangeData(self): edouard@453: pass edouard@453: edouard@453: class IDLETransaction(LPCTransaction): edouard@453: def __init__(self): edouard@453: LPCTransaction.__init__(self, 0x00) edouard@453: edouard@453: class STARTTransaction(LPCTransaction): edouard@453: def __init__(self): edouard@453: LPCTransaction.__init__(self, 0x01) edouard@453: edouard@453: class STOPTransaction(LPCTransaction): edouard@453: def __init__(self): edouard@453: LPCTransaction.__init__(self, 0x02) edouard@453: edouard@453: class SET_TRACE_VARIABLETransaction(LPCTransaction): edouard@453: def __init__(self, data): edouard@453: LPCTransaction.__init__(self, 0x04, data) edouard@453: ExchangeData = LPCTransaction.SendData edouard@453: edouard@453: class GET_TRACE_VARIABLETransaction(LPCTransaction): edouard@453: def __init__(self): edouard@453: LPCTransaction.__init__(self, 0x05) edouard@453: ExchangeData = LPCTransaction.GetData edouard@453: edouard@453: class SET_FORCED_VARIABLETransaction(LPCTransaction): edouard@453: def __init__(self, data): edouard@453: LPCTransaction.__init__(self, 0x06, data) edouard@453: ExchangeData = LPCTransaction.SendData edouard@453: edouard@453: class GET_PLCIDTransaction(LPCTransaction): edouard@453: def __init__(self): edouard@453: LPCTransaction.__init__(self, 0x07) edouard@453: ExchangeData = LPCTransaction.GetData edouard@453: ed@448: if __name__ == "__main__": edouard@453: TestConnection = LPCProto(6,115200,2) edouard@482: # TestConnection.HandleTransaction(GET_PLCIDTransaction()) edouard@453: TestConnection.HandleTransaction(STARTTransaction()) edouard@482: # TestConnection.HandleTransaction(SET_TRACE_VARIABLETransaction( edouard@482: # "\x03\x00\x00\x00"*200)) edouard@482: # TestConnection.HandleTransaction(STARTTransaction()) edouard@453: while True: edouard@482: #time.sleep(0.5) edouard@453: TestConnection.HandleTransaction(SET_TRACE_VARIABLETransaction( edouard@482: "\x01\x00\x00\x00"*200)) edouard@453: #print map(hex,map(ord,TestConnection.HandleTransaction(GET_TRACE_VARIABLETransaction()))) edouard@453: #TestConnection.HandleTransaction(STOPTransaction())