Example #1
0
def xmodem_transive(blks: [bytes], ser: serial.Serial):
    ser.apply_settings({'timeout': 2.7})

    tp1 = datetime.datetime.now()
    i = 0
    rpt = 0
    unit = b''
    while True:

        # Each block of the transfer looks like:
        # <SOH><blk #><255-blk #><--128 data bytes--><cksum>
        xmd_idx = (i + 1) & 0xff
        blk = blks[i]
        unit = SOH + struct.pack(
            'BB', xmd_idx, 255 - xmd_idx) + blk + calc_xmodem_crc_byte(blk)

        #incoming = ser.read_all()
        incoming = ser.read(1)

        # (reading) timeout expired, ACK/NAK get garbaged?
        #   or NAK received, resent in both situation.
        if incoming == b'' or NAK in incoming:
            rpt += 1
            print("{:03d}/{:03d} blocks repeating {}\r".format(
                i, len(blocks), '.' * rpt),
                  end='')
            time.sleep(0.1 + (rpt / 70) * random.random())

        # procced.
        elif ACK in incoming:
            i += 1
            rpt = 0
            print("{:03d}/{:03d} blocks transmited".format(i, len(blocks)))
            time.sleep(0.03)

        # quit loop if retry too much or finished.
        if 10 < rpt or i == len(blks):
            break

        ser.reset_input_buffer()
        ser.write(unit)

    # Note: no SENDRE EOT here, as RECIEVER will timeout.
    time.sleep(3)
    response = ser.read_all()
    tp2 = datetime.datetime.now()

    # TODO: failed when i != len(blocks)?
    # TODO: check XIC in response against calculated one, whether they two match.
    print("{:03d}/{:03d} blocks transmited in {} seconds".format(
        i, len(blocks), (tp2 - tp1).seconds))
    print("response:<{}>".format(response))
Example #2
0
	def open_port(self,port_name,rd_callback=None,serial_setting=None):
		stop_try_count = 0
		while self.get_args(port_name) is not None and stop_try_count < 2:
			self.stop_port(port_name)
			time.sleep(1)
			stop_try_count += 1
		print ('start open',port_name,stop_try_count)
		ser = Serial(port_name,timeout=60)
		ser_info = ser.get_settings()
		print ('default ser_info',ser_info)
		#{'parity': 'N', 'baudrate': 9600, 'bytesize': 8, 'xonxoff': False, 'rtscts': False, 'timeout': 10, 
		#'inter_byte_timeout': None, 'stopbits': 1, 'dsrdtr': False, 'write_timeout': None}
		if serial_setting is not None:
			try:
				print ('serial_setting',serial_setting)
				if 'showtime' in serial_setting and isinstance(serial_setting['showtime'],int):
					self._show_timestamp = True if serial_setting['showtime'] > 0 else False
				if 'localecho' in serial_setting and isinstance(serial_setting['localecho'],int):
					self._local_echo = True if serial_setting['localecho'] > 0 else False
				
				if 'baudrate' in serial_setting and serial_setting['baudrate'].isdigit():
					ser_info['baudrate'] = int(serial_setting['baudrate'])
				if 'databit' in serial_setting and serial_setting['databit'].isdigit():
					ser_info['bytesize'] = int(serial_setting['databit'])
				if 'stopbit' in serial_setting and serial_setting['stopbit'].count('.') <= 1:
					split_list = serial_setting['stopbit'].split('.')
					num_list = [n for n in split_list if n.isdigit()]
					if len(split_list) == len(num_list):
						ser_info['stopbits'] = float(serial_setting['stopbit'])
				if 'checkbit' in serial_setting and len(serial_setting['checkbit']) > 0:
					ser_info['parity'] = serial_setting['checkbit'][0]
				#if 'flowctrl' in serial_setting:
				#	ser_info['rtscts'] = serial_setting['flowctrl']
				print ('to apply setting',ser_info)
				ser.apply_settings(ser_info)
			except Exception as e:
				print ("set apply_settings err:%s"%e)
				pass
		
		#ser_info = ser.get_settings()
		print ('port %s setting ok',port_name)
		read_thread = Thread(target=self.port_thread_read,args=(port_name,))
		read_thread.setDaemon(True)
		self.set_args(port_name, {'handle':ser,'start':False,'name':port_name,'type':'serial','exception':0,'read_callback':rd_callback,'thread':read_thread,'quit':False})
		
		return (port_name,ser_info)