edouard@453: import ctypes
Lolitech@545: from LPCProto import *
edouard@482: 
Lolitech@554: LPC_STATUS={0xaa : "Started",
Lolitech@554:             0x55 : "Stopped"}
ed@448: 
Lolitech@545: class LPCAppProto(LPCProto):
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:
Lolitech@563:                 raise LPCProtoError("controller did not answer as expected")
Lolitech@563:         except Exception, e:
edouard@576:             raise LPCProtoError("application mode transaction error : "+str(e))
ed@448:         finally:
ed@448:             self.TransactionLock.release()
edouard@508:         return LPC_STATUS.get(current_plc_status,"Broken"), res
ed@448:     
Lolitech@545: class LPCAppTransaction:
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:
Lolitech@545:             raise LPCProtoError("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
Lolitech@536:         return self.pseudofile.write(buffer)
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: 
Lolitech@545: class IDLETransaction(LPCAppTransaction):
edouard@453:     def __init__(self):
edouard@570:         LPCAppTransaction.__init__(self, 0x07)
edouard@570:     ExchangeData = LPCAppTransaction.GetData
edouard@453: 
Lolitech@545: class STARTTransaction(LPCAppTransaction):
edouard@453:     def __init__(self):
Lolitech@545:         LPCAppTransaction.__init__(self, 0x01)
edouard@453:     
Lolitech@545: class STOPTransaction(LPCAppTransaction):
edouard@453:     def __init__(self):
Lolitech@545:         LPCAppTransaction.__init__(self, 0x02)
edouard@453: 
Lolitech@545: class RESETTransaction(LPCAppTransaction):
Lolitech@545:     def __init__(self):
Lolitech@545:         LPCAppTransaction.__init__(self, 0x03)
Lolitech@545: 
Lolitech@545: class SET_TRACE_VARIABLETransaction(LPCAppTransaction):
edouard@453:     def __init__(self, data):
Lolitech@545:         LPCAppTransaction.__init__(self, 0x04, data)
Lolitech@545:     ExchangeData = LPCAppTransaction.SendData
edouard@453: 
Lolitech@545: class GET_TRACE_VARIABLETransaction(LPCAppTransaction):
edouard@453:     def __init__(self):
Lolitech@545:         LPCAppTransaction.__init__(self, 0x05)
Lolitech@545:     ExchangeData = LPCAppTransaction.GetData
edouard@453: 
Lolitech@545: class GET_PLCIDTransaction(LPCAppTransaction):
edouard@453:     def __init__(self):
Lolitech@545:         LPCAppTransaction.__init__(self, 0x07)
Lolitech@545:     ExchangeData = LPCAppTransaction.GetData
edouard@453: 
ed@448: if __name__ == "__main__":
edouard@571:     __builtins__.BMZ_DBG = True
Lolitech@545:     TestConnection = LPCAppProto(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@508:     while True:
edouard@508:         TestConnection.HandleTransaction(SET_TRACE_VARIABLETransaction(
edouard@508:            "\x01\x00\x00\x00"+
edouard@508:            "\x04"+
edouard@508:            "\x01\x02\x02\x04"+
edouard@508:            "\x01\x00\x00\x00"+
edouard@508:            "\x08"+
edouard@508:            "\x01\x02\x02\x04"+
edouard@508:            "\x01\x02\x02\x04"+
edouard@508:            "\x01\x00\x00\x00"+
edouard@508:            "\x04"+
edouard@508:            "\x01\x02\x02\x04"))
edouard@502:     #status,res = TestConnection.HandleTransaction(GET_TRACE_VARIABLETransaction())
edouard@502:     #print len(res)
edouard@502:     #print "GOT : ", map(hex, map(ord, res))
edouard@453:     #TestConnection.HandleTransaction(STOPTransaction())