1- #!/usr/bin/env python2
1+ #!/usr/bin/env python
2+
3+ # Copyright (c) 2016-2020, Pycom Limited.
4+ #
5+ # This software is licensed under the GNU GPL version 3 or any
6+ # later version, with permitted additional terms. For more information
7+ # see the Pycom Licence v1.0 document supplied with this file, or
8+ # available at https://www.pycom.io/opensource/licensing
29
310from __future__ import print_function
411
1320 from local_settings import DEBUG
1421except :
1522 DEBUG = False
16- __version__ = '0.9.2 '
23+ __version__ = '0.9.3 '
1724
1825CMD_PEEK = (0x0 )
1926CMD_POKE = (0x01 )
4552ADRESL_ADDR = (0x09B )
4653ADRESH_ADDR = (0x09C )
4754
55+ TRISA_ADDR = (0x08C )
4856TRISC_ADDR = (0x08E )
4957
5058PORTA_ADDR = (0x00C )
@@ -77,7 +85,7 @@ def exit_with_error(code, msg):
7785def warn (msg ):
7886 eprint ('warning:' , msg )
7987
80-
88+
8189def print_debug (msg ):
8290 if DEBUG :
8391 eprint (msg )
@@ -89,12 +97,11 @@ def __init__(self, port):
8997 # we need bytesize to be 5 bits in order for the PIC to process the commands
9098 try :
9199 self .serial = serial .Serial (port , baudrate = 115200 , bytesize = serial .FIVEBITS , timeout = 0.25 , exclusive = True )
92- print_debug ("Connected in exclusive mode" )
93100 connected = True
94101 except Exception as e :
95102 connected = False
96- if not connected :
97103 print_debug ("Not connecting in exclusive mode because: %s" % str (e ))
104+ if not connected :
98105 try :
99106 self .serial = serial .Serial (port , baudrate = 115200 , bytesize = serial .FIVEBITS , timeout = 0.25 )
100107 except Exception as e :
@@ -109,31 +116,43 @@ def __init__(self, port):
109116 except Exception :
110117 pass
111118
112- def _write (self , data , read = True ):
119+ def _write (self , data , read = True , num_read_bytes = 1 ):
113120 self .serial .write (data )
114121 if read :
115122 r_data = self .serial .read (2 )
116123 if not r_data :
117124 raise Exception ('Timeout while waiting for Rx data' )
118- return struct .unpack ('B' , r_data [0 ])[0 ]
125+ if num_read_bytes == 2 :
126+ (b1 , b2 ) = struct .unpack ('BB' , r_data )
127+ return 256 * b2 + b1
128+ else :
129+ if sys .version_info [0 ] < 3 :
130+ return struct .unpack ('B' , r_data [0 ])[0 ]
131+ else :
132+ return r_data [0 ]
133+
134+ def _flush (self , num_read_bytes = 10 ):
135+ r_data = self .serial .read (num_read_bytes )
136+ # print(r_data)
137+ return
119138
120- def _send_cmd (self , cmd ):
121- return self ._write (bytearray ([cmd ]))
139+ def _send_cmd (self , cmd , num_read_bytes = 1 ):
140+ return self ._write (bytearray ([cmd ]), True , num_read_bytes )
122141
123142 def read_hw_version (self ):
124- return self ._send_cmd (CMD_HW_VER )
143+ return self ._send_cmd (CMD_HW_VER , 2 )
125144
126145 def read_fw_version (self ):
127- return self ._send_cmd (CMD_FW_VER )
146+ return self ._send_cmd (CMD_FW_VER , 2 )
128147
129148 def read_product_id (self ):
130- return self ._send_cmd (CMD_PROD_ID )
149+ return self ._send_cmd (CMD_PROD_ID , 2 )
131150
132151 def peek_memory (self , addr ):
133152 return self ._write (bytearray ([CMD_PEEK , addr & 0xFF , (addr >> 8 ) & 0xFF ]))
134153
135154 def poke_memory (self , addr , value ):
136- self ._write (bytearray ([CMD_POKE , addr & 0xFF , (addr >> 8 ) & 0xFF , value & 0xFF ]), False )
155+ self ._write (bytearray ([CMD_POKE , addr & 0xFF , (addr >> 8 ) & 0xFF , value & 0xFF ]), False )
137156
138157 def magic_write_read (self , addr , _and = 0xFF , _or = 0 , _xor = 0 ):
139158 return self ._write (bytearray ([CMD_MAGIC , addr & 0xFF , (addr >> 8 ) & 0xFF , _and & 0xFF , _or & 0xFF , _xor & 0xFF ]))
@@ -163,6 +182,11 @@ def reset_pycom_module(self):
163182 self .set_bits_in_memory (TRISC_ADDR , 1 << 5 )
164183
165184 def enter_pycom_programming_mode (self , reset = True ):
185+ print_debug ("Entering programming mode with reset={}" .format (reset ))
186+ # make RA5 an output
187+ self .mask_bits_in_memory (TRISA_ADDR , ~ (1 << 5 ))
188+ # drive RA5 low
189+ self .mask_bits_in_memory (PORTA_ADDR , ~ (1 << 5 ))
166190 # make RC0 an output
167191 self .mask_bits_in_memory (TRISC_ADDR , ~ (1 << 0 ))
168192 # set RC0 low
@@ -173,13 +197,20 @@ def enter_pycom_programming_mode(self, reset=True):
173197 # We should keep RC0 low at this point in case someone
174198 # presses the reset button before the firmware upgrade
175199 # as this is mandatory for the regular expansion board
200+ self ._flush ()
176201
177202 def exit_pycom_programming_mode (self , reset = True ):
203+ print_debug ("Leaving programming mode with reset={}" .format (reset ))
204+ # make RA5 an output
205+ self .mask_bits_in_memory (TRISA_ADDR , ~ (1 << 5 ))
206+ # drive RA5 high
207+ self .set_bits_in_memory (PORTA_ADDR , 1 << 5 )
178208 # make RC0 an input
179209 # This will prevent issues with the RGB LED
180210 self .set_bits_in_memory (TRISC_ADDR , 1 << 0 )
181211 if reset :
182212 self .reset_pycom_module ()
213+ self ._flush ()
183214
184215 def isdetected (self ):
185216 return self .detected
@@ -210,6 +241,11 @@ def main(args):
210241 elif args .exit :
211242 pic .exit_pycom_programming_mode (not args .noreset )
212243
244+ # print debug info about current PIC product
245+ print_debug ("read_product_id(): 0x%X" % pic .read_product_id ())
246+ print_debug ("read_hw_version(): 0x%X" % pic .read_hw_version ())
247+ print_debug ("read_fw_version(): 0x%X" % pic .read_fw_version ())
248+
213249 pic .close ()
214250
215251
0 commit comments