import time import serial import binascii class TPLBirdySlim: port = None def __init__(self, serialPortName): self.port = serial.Serial( port=serialPortName, baudrate=57600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=30, xonxoff=False, rtscts=False, dsrdtr=False ) print(self.port.name) if self.port.is_open: self.port.close() self.port.open() self.port.reset_input_buffer() self.port.reset_output_buffer() def _changeBaudrate(self, newRate): if self.port.is_open: self.port.close() self.port.baudrate = newRate self.port.open() self.port.reset_input_buffer() self.port.reset_output_buffer() def checksum(self, data): cs = 0x00 for x in data: cs = (cs + x % 256) & 0xFF return cs & 0xFF def sendCMD(self, data): cmd = [] cmd.append(0x02) cmd.append(len(data)) cmd.extend(data) cmd.append(0x03) cmd.append(self.checksum(cmd.copy())) cmd.append(0x04) print(">", binascii.hexlify(bytes(cmd))) self.port.write(cmd) self.port.flush() def readSingleByte(self): return int.from_bytes(self.port.read(1), 'little') def wait4Response(self): #first Byte is always 0x02 if self.readSingleByte() != 0x02: return None dataLength = self.readSingleByte() reply = [] for x in range(dataLength): reply.append(self.readSingleByte()) if self.readSingleByte() != 0x03: return None pCRC = self.readSingleByte() pCRCData = [0x02, dataLength] pCRCData.extend(reply) pCRCData.extend([0x03]) rCRC = self.checksum(pCRCData) if self.readSingleByte() != 0x04: return None if pCRC != rCRC: return None # crc mismatch return reply def askHighspeed(self): self.sendCMD([0x25,0x01]) return self.wait4Response() def switchToHighspeed(self): resp = self.askHighspeed() if len(resp) == 1 and resp[0] == 0x06: self._changeBaudrate(115200) return True else: return False def readE2P(self, addr, size=0x80): _addr = addr.to_bytes(2, byteorder='big') _cmd = [0x29, 0x00, 0x00, _addr[0], _addr[1], size] self.sendCMD(_cmd) resp = self.wait4Response() print(">", binascii.hexlify(bytes(resp))) if resp[0:5] != _cmd[0:5]: print(resp[0:5], _cmd[0:5]) return None # mismatch return resp[5:] def writeE2P(self, addr, data): _addr = addr.to_bytes(2, byteorder='big') _cmd = [0x2A, 0x00, 0x00, _addr[0], _addr[1]] _cmd.extend(data) self.sendCMD(_cmd) resp = self.wait4Response() if resp[0:4] != _cmd[0:4]: print("resp mismatch", resp, _cmd) return False # mismatch if resp[5] != len(data): print("length mismatch") return False # mismatch if resp[6:] != _cmd[5:]: print("resp mismatch", resp, _cmd) return False # mismatch return True #def boskrypt_mode(self): # self.sendCMD([0xF3,0xF3]) def getDeviceInfo(self): self.sendCMD([0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff]) return self.wait4Response() def writeSerialNumber(self, newSerial): _cmd = [0x13] _cmd.extend(newSerial) self.sendCMD(_cmd) resp = self.wait4Response() if _cmd[2:] != resp[2:]: return False return True def checkE2PData(self, data): return len(data) / 0x80 == 0xCD test = TPLBirdySlim('/dev/ttyUSB0') #test.sendCMD([0x10,0x08]) test.sendCMD([0x01,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,]) print(bytes(test.wait4Response())) test.sendCMD([0x12,]) # get Serial print(bytes(test.wait4Response())) test.sendCMD([0xEF,]) # get CEIC? print(bytes(test.wait4Response())) loraProvCMD = [0x2B, 0x00, 0x44,0x00 ] #abp try AppEUI = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] DevEUI = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] AppKey = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ] AppSKey = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] NwkSKey = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] DevAddr = [ 0x00, 0x00, 0x00, 0x00 ] loraProvCMD.extend(AppSKey) loraProvCMD.extend(AppEUI) loraProvCMD.extend(DevEUI) loraProvCMD.extend(AppSKey) loraProvCMD.extend(NwkSKey) loraProvCMD.extend(DevAddr) test.sendCMD(loraProvCMD) print(bytes(test.wait4Response()))