Advertisement
AnatolySharapov

comport.py

Apr 9th, 2021
333
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.61 KB | None | 0 0
  1. # !/usr/bin/python
  2. # coding = utf8
  3. # https://pyserial.readthedocs.io/en/latest/shortintro.html
  4.  
  5. # Document Reference No.: FT_000161
  6. # Aliasing Vcp Baud Rates Application Note AN_120
  7. # Version 1.2
  8.  
  9. # MSB of the divisor is 0, so divisor is dividing a 3 MHz clock.
  10. # Each field consists of 4 bytes, ordered as follows: Byte0, Byte1, Byte2, Byte3.
  11. # Bits 13 through 0 denote the integer divisor
  12. # while bits 16, 15 and 14 denote the sub-integer divisor, as follows
  13. # 10,27,00,00 are re-arranged as 00,00,27,10
  14. # This gives 0000 0000 0000 0000 0010 0111 0001 0000
  15. # 16,15,14 = 000 - sub-integer divisor = 0
  16.  
  17. # FtdiPort.NT.HW.AddReg]
  18. # HKR,,"ConfigData",1,11,00,3F,3F,10,27,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,
  19. # 71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,00,00,00,1A,00,00,00,
  20. # 0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00
  21.  
  22. # HKR,,"ConfigData",1,11,00,3F,3F,
  23. # 10,27,00,00, => divisor = 0'h2710 = 0'd10000, rate = 300
  24. # 88,13,00,00, => divisor = 5000,  rate = 600
  25. # C4,09,00,00, => divisor = 2500,  rate = 1,200
  26. # E2,04,00,00, => divisor = 1250,  rate = 2,400
  27. # 71,02,00,00, => divisor = 625,   rate = 4,800
  28. # 38,41,00,00, => divisor = 312.5, rate = 9,600
  29. # 9C,80,00,00, => divisor = 156,   rate = 19,23075
  30. # 4E,C0,00,00, => divisor = 78,    rate = 38,4615
  31. # 34,00,00,00, => divisor = 52,    rate = 57,69225
  32. # 1A,00,00,00, => divisor = 26,    rate = 115,3845
  33. # 0D,00,00,00, => divisor = 13,    rate = 230,76925
  34. # 06,40,00,00, => divisor = 6.5,   rate = 461,53825
  35. # 03,80,00,00, => divisor = 3.25,  rate = 923,077
  36. # 00,00,00,00, => RESERVED
  37. # D0,80,00,00 => divisor = 208.25, rate = 14,40575
  38.  
  39. # Altera Cyclone III clock is 64 MHz, so let's assume that we could manage to
  40. # achieve highest possible uart rate for FT2232H stated as 12 MBaud
  41.  
  42. # At page 11/17 see 4.4 Aliasing the FT232H, FT2232H and FT4232H for Baud Rates
  43. # up to 12 MBaud sayng that to alias baud rates between 3 MBaud and 12 MBaud it is
  44. # necessary to use driver version 2.4.20 or later and the most significant bit
  45. # (MSB) of the divisor must be a 1. This will ensure the divisor is dividing a
  46. # 12 MHz clock and not a 3 MHz clock.
  47. # To alias a rate of 12 MBaud to the standard 921600 baud menu option under windows:
  48. # find the best divisor, check that it is sufficiently accurate and then modify the
  49. # appropriate INF file entry.
  50. # 12000000 / 921600 = 13.0208
  51. # The best divisor is 13.25
  52. # 12000000 / 13.25 = 905660 (approx)
  53. # 921600 / 905660 = 101.76%
  54. # This is just within the required 3% tolerance
  55. # Set bits 16:15:14 to 010 for a sub-integer divisor of 0.25, and the lower bits to
  56. # 0'd13 = 0'hD
  57. # MSB must be a 1 as the master clock is 12 MHz
  58. # This gives 1000 0000 0000 0000 1000 0000 0000 1101.
  59. # This gives the 4 bytes as 80 00 80 0D.
  60. # These are re-arranged as 0D,80,00,80
  61.  
  62. # Replace the 03,80,00,00, entry for the 923077 baud with 0D,80,00,80.
  63. # Incorporating these two changes the FTDIPORT.INF entry becomes
  64. # FtdiPort.NT.HW.AddReg]
  65. # HKR,,"ConfigData",1,11,00,3F,3F,10,27,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,
  66. # 71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,00,00,00,1A,00,00,00,
  67. # 0D,00,00,00,06,40,00,00,0D,80,00,80,00,00,00,00,D0,80,00,00
  68.  
  69. # To alias a rate of 12 MBaud to the standard 19200 baud menu option under windows:
  70. # Note: Divisor = 1 and Divisor = 0 are special cases. A divisor of 0 will give 12 MBaud, and a
  71. # divisor of 1 will give 8MBaud. Sub-integer divisors are not allowed if the main divisor (n) is
  72. # either 0 or 1.
  73. # So replace the 9C,80,00,00, entry for the 19,200 baud with 00,00,00,80.
  74.  
  75. # Incorporating these two changes the FTDIPORT.INF entry becomes
  76. # FtdiPort.NT.HW.AddReg]
  77. # HKR,,"ConfigData",1,11,00,3F,3F,10,27,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,
  78. # 71,02,00,00,38,41,00,00,00,00,00,80,4E,C0,00,00,34,00,00,00,1A,00,00,00,
  79. # 0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00
  80.  
  81. # https://superuser.com/questions/954184/disable-automatic-driver-installation-in-windows-10
  82.  
  83. import os
  84. import serial
  85. import msvcrt
  86.  
  87. print(" ////////////////////////////////////////////////////////////////////")
  88. print(" File name     : comport.py                                          ")
  89. print(" Author        : Anatoly A. Sharapov                                 ")
  90. print(" Email         : a.a.sharapov@gmail.com                              ")
  91. print(" Phone         : +7 903 231-11-26                                    ")
  92. print(" Company       : PJS MIEA                                            ")
  93. print(" Dep           : 311                                                 ")
  94. print(" Description   : python comport script for reading from com port     ")
  95. print(" Last revision : 30.03.2021                                          ")
  96. print(" ////////////////////////////////////////////////////////////////////")
  97.  
  98. is_debug = 0
  99. is_log = 1
  100. ser_buf_size = 4096
  101. ser_baudrate = 19200
  102.  
  103. is_crc8_included = 1
  104. if is_crc8_included:
  105.     if is_debug:
  106.         print("crc8 is included")
  107.     packet_size = 4 # crc8, addr, data_high, data_low
  108. else:
  109.     if is_debug:
  110.         print("crc8 is not included")
  111.     packet_size = 3 # addr, data_high, data_low    
  112.  
  113. ThisPCLocation = os.environ.get('ThisPCLocation')
  114. print("ThisPCLocation = {:s}".format(ThisPCLocation))
  115.  
  116. if ThisPCLocation== "HOME":
  117.     com_port = 'COM4'
  118. else: # ThisPCLocation== "MIEA":
  119.     com_port = 'COM14'
  120.    
  121. def _two_8bits_hex_to_16bits_hex(data_high_byte, data_low_byte):
  122.     return data_high_byte << 8 | data_low_byte  
  123.  
  124. def CheckBits(bit1, bit2):
  125.     if bit1 == bit2:
  126.         print("Error occured")
  127.        
  128. def ReadData(num_bytes):
  129.     bytes_read = ser.read(num_bytes) # read up to num_bytes bytes
  130.                                      # or as much is in the buffer
  131.     num_bytes_read = len(bytes_read)
  132.     return num_bytes_read != num_bytes, num_bytes_read, bytes_read
  133.  
  134. def ParseData(bytes):    
  135.     addr = bytes[0]
  136.     data = _two_8bits_hex_to_16bits_hex(bytes[1], bytes[2])
  137.     return addr, data
  138.    
  139. def ReadBuf(data_prev):
  140.     bytes_read = ser.read(ser_buf_size) # read up to buf_size bytes
  141.                                         # or as much is in the buffer
  142.     num_bytes_read = len(bytes_read)
  143.     if is_log:    
  144.         miea1_data_file.write("ReadBuf --------------> num_bytes_read = {:#d}\n".format(num_bytes_read))
  145.     if is_debug:    
  146.         print("ReadBuf -> data_prev = {:#x}, num_bytes_read = {:#d}" .format(data_prev, num_bytes_read))
  147.     i = 0
  148.     addr_list = []
  149.     if data_prev == 0:
  150.         data_list = []
  151.     else:
  152.         data_list = [data_prev]        
  153.     while num_bytes_read >= i + packet_size:
  154.         if is_crc8_included:
  155.             addr, data = ParseData([bytes_read[i+1], bytes_read[i+2], bytes_read[i+3]])
  156.         else:
  157.             addr, data = ParseData([bytes_read[i], bytes_read[i+1], bytes_read[i+2]])
  158.         if is_log:    
  159.             miea1_data_file.write("ReadBuf -> address = {:#o}, data = {:#x}\n".format(addr, data))
  160.         if is_debug and i < packet_size:
  161.             print("ReadBuf -> data_first = {:#x}" .format(data))
  162.         if is_debug and i > num_bytes_read - packet_size:
  163.             print("ReadBuf -> data_last = {:#x}" .format(data))            
  164.         addr_list.append(addr)
  165.         data_list.append(data)
  166.         i += packet_size
  167.     if is_debug:    
  168.         print("ReadBuf -> data_last = {:#x}, len(data_list) = {:#d}" .format(data, len(data_list)))        
  169.     return num_bytes_read, addr_list, data_list  
  170.    
  171. def CheckDataList(data_list, buf_num):
  172.     data_list_len = len(data_list)
  173.     data_last = 0
  174.     if is_debug:
  175.         print("CheckDataList -> data_list_len = {:#d}".format(data_list_len))
  176.     if data_list_len > 1:
  177.         data_previous = data_list[0]
  178.         if is_debug:
  179.             print("CheckDataList -> data_previous = {:#x}".format(data_previous))
  180.         for i in range(1, data_list_len):
  181.             data_next = data_list[i]
  182.             if is_debug:
  183.                 print("CheckDataList -> data_next = {:#x}".format(data_next))
  184.             if not (data_next == data_previous + 1 or data_next == 0 and data_previous == 0xffff):
  185.                 print("At buf_num = {:#d}, num = {:#d} failure detected: data_previous = {:#x} data_next = {:#x}" .format(buf_num, i, data_previous, data_next))
  186.                 return False, data_last
  187.             data_previous = data_next
  188.         data_last = data_next    
  189.         return True, data_last
  190.     return False, data_last    
  191.  
  192. ser = serial.Serial(port = com_port,
  193.                     baudrate = ser_baudrate,
  194.                     bytesize = 8,
  195.                     parity = 'N',
  196.                     stopbits = 1,                    
  197.                     timeout = None,
  198.                     xonxoff = 0,                    
  199.                     rtscts = 0)
  200.                    
  201. if not ser.is_open:
  202.     ser.open()
  203.  
  204. # https://pyserial.readthedocs.io/en/latest/pyserial_api.html    
  205. ser.flush()
  206. ser.flush()
  207.  
  208. print("Port {:s} is opened with baudrate = {:#d} (possibly aliased)".format(ser.name, ser_baudrate))
  209. miea1_data_file = open('miea1_data.txt', 'w')
  210.  
  211. print("Com port reading and checking in progress and will be stopped")  
  212. print("in case any error detected. Print any key to interrupt.")                  
  213.  
  214. num = 0
  215. done = False
  216.  
  217. # 1st read buf
  218. buf_num = 0
  219. num_bytes_read, addr_list, data_list = ReadBuf(0) # 1st buf - no prevous data
  220.  
  221. progress = {
  222.     0 : '-',
  223.     1 : '\\',
  224.     2 : '|',
  225.     3 : '/'
  226. }
  227.    
  228. while not done:
  229.  
  230.     if is_debug:
  231.         print("num = {:#d}" .format(num))
  232.     else:
  233.         try:
  234.             print(progress[buf_num % len(progress)], end = '\b', flush = True)
  235.         except KeyError as e:
  236.             # можно также присвоить значение по умолчанию вместо бросания исключения
  237.             raise ValueError('Undefined unit: {}'.format(e.args[0]))    
  238.             done = True
  239.    
  240.     num += num_bytes_read
  241.    
  242.     CheckDataListResult, data_last = CheckDataList(data_list, buf_num)
  243.     buf_num += 1
  244.    
  245.     if not CheckDataListResult:
  246.         done = True  
  247.  
  248.     if msvcrt.kbhit():
  249.         print("\nYou pressed ", msvcrt.getch(),", so now the process will quit")
  250.         done = True
  251.  
  252.     num_bytes_read, addr_list, data_list = ReadBuf(data_last)
  253.  
  254. ser.close()
  255. miea1_data_file.close()  
  256.  
  257. if not ser.is_open:                    
  258.     print ("Port is closed")  
  259.    
  260.  
  261. # ThisPCLocation = HOME
  262. # Port COM4 is opened with baudrate = 19200 (possibly aliased)
  263. # Com port reading and checking in progress and will be stopped
  264. # in case any error detected. Print any key to interrupt.
  265. # At buf_num = 1850, num = 765 failure detected: data_previous = 0x3373 data_next = 0x8536
  266. # Port is closed
  267.  
  268.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement