2626parser = optparse .OptionParser ("%prog [options] [commands]" ,
2727 description = "Communicate with Mesa ethernet cards using the LBP16 protocol" )
2828parser .add_option ("-i" , "--ip" , dest = "sip" ,
29- help = "IP address of board" ,
29+ help = "IP address of board (default: 192.168.1.121) " ,
3030 metavar = "X.Y.Z.W" , default = "192.168.1.121" )
3131parser .add_option ("-p" , "--port" , dest = "sport" ,
32- help = "UDP port of board" , type = "int" , default = 27181 )
32+ help = "UDP port of board (default: 27181) " , type = "int" , default = 27181 )
3333parser .add_option ("-t" , "--timeout" , dest = "timeout" ,
34- help = "Response timeout in seconds" , type = "float" , default = .2 )
35- parser .add_option ("-s" , "--space" , dest = "space" , default = None ,
34+ help = "Response timeout in seconds (default: 0.2) " , type = "float" , default = .2 )
35+ parser .add_option ("-s" , "--space" , dest = "space" , default = 0 ,
3636 choices = ["0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" ],
37- help = "Address space to read or write" )
37+ help = "Address space to read or write (default: 0, the hm2 register file) " )
3838parser .add_option ("--info" , dest = "info" , action = "store_true" ,
3939 default = False ,
4040 help = "Select info area for read operation (default: memory space)" )
4141parser .add_option ("-a" , "--address" , type = "int" , dest = "address" , default = None ,
4242 help = "Base address to read or write" )
4343parser .add_option ("-I" , "--increment" , dest = "increment" , action = "store_true" ,
4444 default = True ,
45- help = "auto-increment address" )
45+ help = "auto-increment address (enabled by default, use --no-increment to disable) " )
4646parser .add_option ("-n" , "--no-increment" , dest = "increment" ,
4747 action = "store_false" ,
4848 help = "do not auto-increment address" )
49+ parser .add_option ("--size" , dest = "size" ,
50+ help = "Transfer size in number of bytes (default: look up preferred transfer size in the space's info area)" ,
51+ type = "int" , default = 0 )
4952parser .add_option ("-r" , "--read" , type = "int" , dest = "read" , default = None ,
5053 help = "Number of bytes to read" )
5154parser .add_option ("-w" , "--write" , type = "string" , dest = "write" , default = None ,
5255 help = "Hex-coded Values to read" )
56+
57+ parser .add_option ("--read-info" , dest = "read_info" , default = False ,
58+ action = "store_true" ,
59+ help = "Read and decode the info area of the selected memory space." )
60+
5361options , args = parser .parse_args ()
5462if options .space : options .space = int (options .space )
5563
5866s = socket .socket (socket .AF_INET , socket .SOCK_DGRAM , 0 )
5967s .settimeout (options .timeout )
6068
61- def transact (sdata , quiet = False , response = True ):
62- sdata = "" .join (sdata .split ()).decode ("hex" )
69+ def transact (sdata :bytes , quiet = False , response = True ):
6370 s .sendto (sdata , (options .sip , options .sport ))
6471 if not response : return
6572 try :
6673 data , daddr = s .recvfrom (1280 )
67- if not quiet : print ("<" , data .encode ( " hex" ))
68- if not quiet : print (" " , re .sub ('[^ -~]' , '.' , data ))
74+ if not quiet : print ("<" , data .hex ( ))
75+ if not quiet : print (" " , re .sub ('[^ -~]' , '.' , data . decode ( 'utf-7' , errors = 'replace' ) ))
6976 return data
7077 except socket .timeout :
7178 if not quiet : print ("! no response" )
@@ -80,21 +87,21 @@ def interact():
8087 except KeyboardInterrupt :
8188 pass
8289
83- def make_read_request (space , info , size , increment , address , nbytes ) :
90+ def make_read_request (space : int , info : bool , size : int , increment : bool , address : int , nbytes : int ) -> bytes :
8491 return struct .pack ("<HH" ,
8592 (1 << 14 ) | (space << 10 ) | (info << 13 )
86- | (sizemap [size ] << 8 ) | (increment << 7 ) | (nbytes / size ),
93+ | (sizemap [size ] << 8 ) | (increment << 7 ) | int (nbytes / size ),
8794 address )
8895
89- def make_write_request (space , info , size , increment , address , bytes ):
96+ def make_write_request (space : int , info : bool , size : int , increment : bool , address : int , data : bytes ) -> bytes :
9097 return struct .pack ("<HH" ,
9198 (1 << 15 ) | (1 << 14 ) | (space << 10 ) | (info << 13 )
92- | (sizemap [size ] << 8 ) | (increment << 7 ) | (len (bytes ) / size ),
93- address ) + bytes
99+ | (sizemap [size ] << 8 ) | (increment << 7 ) | int (len (data ) / size ),
100+ address ) + data
94101
95- def optimal_size (space , info , address , nbytes ):
102+ def optimal_size (space : int , info : bool , address : int , nbytes : int ):
96103 if info : return 2
97- info = transact (make_read_request (space , True , 2 , True , 2 , 4 ). encode ( "hex" ) , quiet = True )
104+ info = transact (make_read_request (space , True , 2 , True , 2 , 4 ), quiet = True )
98105 if info is None :
99106 raise RuntimeError ("Failed to get information about memory space %d" % space )
100107 memsizes , memranges = struct .unpack ("<HH" , info )
@@ -108,25 +115,86 @@ def optimal_size(space, info, address, nbytes):
108115 return b
109116 raise ValueError ("Access size incompatible with address or length (address=%d nbytes=%d memsizes=%d)" % (address , nbytes , memsizes ))
110117
118+ def get_uint16 (data :bytes , offset :int ):
119+ return (data [offset + 1 ] << 8 ) | data [offset ]
120+
121+ def print_info (data :bytes ):
122+ print (f"info area for memory space { options .space } :" )
123+
124+ cookie = get_uint16 (data , 0 )
125+ print (f" cookie: 0x{ cookie :04x} " )
126+
127+ memsize = get_uint16 (data , 2 )
128+ memsize_writable = memsize & 0x8000
129+ memsize_type = (memsize & 0x7f00 ) >> 8
130+ memsize_access = memsize & 0x000f
131+ print (f" memsize: 0x{ memsize :04x} " )
132+
133+ print (" Writable" if memsize_writable else " Read-Only" )
134+
135+ if (memsize_type == 0x01 ):
136+ print (" type=01 (Register)" )
137+ elif (memsize_type == 0x02 ):
138+ print (" type=02 (Memory)" )
139+ elif (memsize_type == 0x0e ):
140+ print (" type=0e (EEPROM)" )
141+ elif (memsize_type == 0x0f ):
142+ print (" type=0f (Flash)" )
143+ else :
144+ print (f" type={ memsize_type :02x} (unknown)" )
145+
146+ print (f" access=0x{ memsize_access :01x} " , end = '' )
147+ if memsize_access & 0x1 :
148+ print (" 8-bit" , end = '' )
149+ if memsize_access & 0x2 :
150+ print (" 16-bit" , end = '' )
151+ if memsize_access & 0x4 :
152+ print (" 32-bit" , end = '' )
153+ if memsize_access & 0x8 :
154+ print (" 64-bit" , end = '' )
155+ print ()
156+
157+ memranges = get_uint16 (data , 4 )
158+ e = (memranges & 0xf800 ) >> 11
159+ p = (memranges & 0x07c0 ) >> 6
160+ s = memranges & 0x003f
161+ print (f" memranges: 0x{ memranges :04x} " )
162+ print (f" erase block size: { e } ({ 2 ** e } bytes)" )
163+ print (f" page size: { p } ({ 2 ** p } bytes)" )
164+ print (f" Ps address range: { s } ({ 2 ** s } bytes)" )
165+
166+ addr_ptr = get_uint16 (data , 6 )
167+ print (f" addr ptr: 0x{ addr_ptr :04x} " )
168+
169+ name = str (data [8 :], encoding = 'utf-7' )
170+ print (f" name: { name } " )
171+
172+
111173if options .read :
112- if options .space is None : raise SystemExit ("--read must specify --space" )
113174 if options .address is None : raise SystemExit ("--read must specify --address" )
114- size = optimal_size ( options . space , options . info , options . address , options . read if options .increment else 0 )
115- command = make_read_request (options .space , options .info , size , options .increment , options .address , options .read )
116- command = command . encode ( "hex" )
117- print (">" , command )
175+ if options .size == 0 :
176+ options . size = optimal_size (options .space , options .info , options .address , options .read if options .increment else 0 )
177+ command = make_read_request ( options . space , options . info , options . size , options . increment , options . address , options . read )
178+ print (">" , command . hex () )
118179 transact (command )
119180
120181elif options .write :
121- if options .space is None : raise SystemExit ("--write must specify --space" )
122182 if options .address is None : raise SystemExit ("--write must specify --address" )
123- write = options .write . decode ( "hex" )
124- size = optimal_size ( options . space , options . info , options . address , len ( write ) if options .increment else 0 )
125- command = make_write_request (options .space , options .info , size , options .increment , options .address , write )
126- command = command . encode ( "hex" )
127- print (">" , command )
183+ write = bytes . fromhex ( options .write )
184+ if options .size == 0 :
185+ options . size = optimal_size (options .space , options .info , options .address , len ( write ) if options .increment else 0 )
186+ command = make_write_request ( options . space , options . info , options . size , options . increment , options . address , write )
187+ print (">" , command . hex () )
128188 transact (command , response = False )
129189
190+ elif options .read_info :
191+ if options .size == 0 :
192+ options .size = optimal_size (options .space , True , 0x0000 , 16 )
193+ command = make_read_request (options .space , True , options .size , options .increment , 0x00 , 0x10 )
194+ print (">" , command .hex ())
195+ data = transact (command )
196+ print_info (data )
197+
130198elif args :
131199 for a in args :
132200 transact (a )
0 commit comments