Compare commits
11 Commits
delay-calc
...
ci-test
Author | SHA1 | Date | |
---|---|---|---|
771fb3361b | |||
cfa0e39702 | |||
43887a9189 | |||
c400641684 | |||
353f28cdc8 | |||
c23ed8f996 | |||
e9f66d8874 | |||
e27e7bedcb | |||
3c180ff8dc | |||
0dbca5c163 | |||
079affc4f3 |
22
README.md
22
README.md
@ -61,7 +61,7 @@ Features
|
||||
* Set device options
|
||||
* Read unique device ID (STC 10/11/12/15)
|
||||
* Trim RC oscillator frequency (STC 15)
|
||||
* Automatic power-cycling with DTR toggle or a custom shell command
|
||||
* Automatic power-cycling with DTR toggle
|
||||
* Automatic UART protocol detection
|
||||
|
||||
Installation
|
||||
@ -96,9 +96,6 @@ positional arguments:
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-a, --autoreset cycle power automatically by asserting DTR
|
||||
-r RESETCMD, --resetcmd RESETCMD
|
||||
Use this shell command for board power-cycling
|
||||
(instead of DTR assertion)
|
||||
-P {stc89,stc12a,stc12,stc15a,stc15,auto}, --protocol {stc89,stc12a,stc12,stc15a,stc15,auto}
|
||||
protocol version
|
||||
-p PORT, --port PORT serial port device
|
||||
@ -279,22 +276,7 @@ serial interface to automate this. The DTR signal is asserted for
|
||||
approximately 500 ms when the autoreset feature is enabled with the
|
||||
```-a``` flag. This requires external circuitry to actually switch the
|
||||
power. In some cases, when the microcontroller draws only little power,
|
||||
it is possible to directly supply power from the DTR signal.
|
||||
|
||||
As an alternative to DTR, you can use a custom shell command or an external
|
||||
script (via -r option) to reset the device. You should specify the command
|
||||
along with -a option. Do not forget the quotes!
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
$ ./stcgal.py -P stc15 -a -r "echo 1 > /sys/class/gpio/gpio666/value"
|
||||
```
|
||||
or
|
||||
|
||||
```
|
||||
$ ./stcgal.py -P stc15 -a -r "./powercycle.sh"
|
||||
```
|
||||
it is possible to directly supply power from the DTR signal, however.
|
||||
|
||||
### Exit status
|
||||
|
||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,9 +1,3 @@
|
||||
stcgal (1.4) unstable; urgency=low
|
||||
|
||||
* Update to 1.4
|
||||
|
||||
-- Grigori <greg@chown.ath.cx> Tue, 19 Sep 2017 17:57:11 +0200
|
||||
|
||||
stcgal (1.3) unstable; urgency=low
|
||||
|
||||
* Update to 1.3
|
||||
|
@ -1 +1 @@
|
||||
__version__ = "1.4"
|
||||
__version__ = "1.3"
|
||||
|
@ -132,7 +132,8 @@ class StcGal:
|
||||
"""Run programmer, main entry point."""
|
||||
|
||||
try:
|
||||
self.protocol.connect(autoreset=self.opts.autoreset, resetcmd=self.opts.resetcmd)
|
||||
self.protocol.connect(autoreset=self.opts.autoreset)
|
||||
|
||||
if self.opts.protocol == "auto":
|
||||
if not self.protocol.protocol_name:
|
||||
raise StcProtocolException("cannot detect protocol")
|
||||
@ -202,7 +203,6 @@ def cli():
|
||||
parser.add_argument("code_image", help="code segment file to flash (BIN/HEX)", type=argparse.FileType("rb"), nargs='?')
|
||||
parser.add_argument("eeprom_image", help="eeprom segment file to flash (BIN/HEX)", type=argparse.FileType("rb"), nargs='?')
|
||||
parser.add_argument("-a", "--autoreset", help="cycle power automatically by asserting DTR", action="store_true")
|
||||
parser.add_argument("-r", "--resetcmd", help="Use this shell command for board power-cycling (instead of DTR assertion)", action="store")
|
||||
parser.add_argument("-P", "--protocol", help="protocol version (default: auto)", choices=["stc89", "stc12a", "stc12b", "stc12", "stc15a", "stc15", "usb15", "auto"], default="auto")
|
||||
parser.add_argument("-p", "--port", help="serial port device", default="/dev/ttyUSB0")
|
||||
parser.add_argument("-b", "--baud", help="transfer baud rate (default: 19200)", type=BaudType(), default=19200)
|
||||
|
@ -973,46 +973,6 @@ class MCUModelDatabase:
|
||||
MCUModel(name='STC90LE513AD', magic=0xf18d, total=65536, code=53248, eeprom=10240),
|
||||
MCUModel(name='STC90LE514AD', magic=0xf18e, total=65536, code=57344, eeprom=6144),
|
||||
MCUModel(name='STC90LE516AD', magic=0xf190, total=65536, code=63488, eeprom=0),
|
||||
|
||||
# Warning, these definitions lack a valid eeprom size.
|
||||
MCUModel(name='STC15F04AD', magic=0xd444, total=4096, code=4096, eeprom=0),
|
||||
MCUModel(name='STC15F06AD', magic=0xd446, total=6144, code=6144, eeprom=0),
|
||||
MCUModel(name='STC15F08AD', magic=0xd448, total=8192, code=8192, eeprom=0),
|
||||
MCUModel(name='STC15F10AD', magic=0xd44a, total=10240, code=10240, eeprom=0),
|
||||
MCUModel(name='STC15F12AD', magic=0xd44c, total=12288, code=12288, eeprom=0),
|
||||
MCUModel(name='STC15F04CCP', magic=0xd434, total=4096, code=4096, eeprom=0),
|
||||
MCUModel(name='STC15F06CCP', magic=0xd436, total=6144, code=6144, eeprom=0),
|
||||
MCUModel(name='STC15F08CCP', magic=0xd438, total=8192, code=8192, eeprom=0),
|
||||
MCUModel(name='STC15F10CCP', magic=0xd43a, total=10240, code=10240, eeprom=0),
|
||||
MCUModel(name='STC15F12CCP', magic=0xd43c, total=12288, code=12288, eeprom=0),
|
||||
MCUModel(name='STC15F04', magic=0xd404, total=4096, code=4096, eeprom=0),
|
||||
MCUModel(name='STC15F06', magic=0xd406, total=6144, code=6144, eeprom=0),
|
||||
MCUModel(name='STC15F08', magic=0xd408, total=8192, code=8192, eeprom=0),
|
||||
MCUModel(name='STC15F10', magic=0xd40a, total=10240, code=10240, eeprom=0),
|
||||
MCUModel(name='STC15F12', magic=0xd40c, total=12288, code=12288, eeprom=0),
|
||||
MCUModel(name='IAP15F08AD', magic=0xd458, total=8192, code=8192, eeprom=0),
|
||||
MCUModel(name='IAP15F10AD', magic=0xd45a, total=10240, code=10240, eeprom=0),
|
||||
MCUModel(name='IAP15F12AD', magic=0xd45c, total=12288, code=12288, eeprom=0),
|
||||
MCUModel(name='IAP15F14AD', magic=0xd45e, total=14336, code=14336, eeprom=0),
|
||||
MCUModel(name='STC15L04AD', magic=0xd4c4, total=4096, code=4096, eeprom=0),
|
||||
MCUModel(name='STC15L06AD', magic=0xd4c6, total=6144, code=6144, eeprom=0),
|
||||
MCUModel(name='STC15L08AD', magic=0xd4c8, total=8192, code=8192, eeprom=0),
|
||||
MCUModel(name='STC15L10AD', magic=0xd4ca, total=10240, code=10240, eeprom=0),
|
||||
MCUModel(name='STC15L12AD', magic=0xd4cc, total=12288, code=12288, eeprom=0),
|
||||
MCUModel(name='STC15L04CCP', magic=0xd4b4, total=4096, code=4096, eeprom=0),
|
||||
MCUModel(name='STC15L06CCP', magic=0xd4b6, total=6144, code=6144, eeprom=0),
|
||||
MCUModel(name='STC15L08CCP', magic=0xd4b8, total=8192, code=8192, eeprom=0),
|
||||
MCUModel(name='STC15L10CCP', magic=0xd4ba, total=10240, code=10240, eeprom=0),
|
||||
MCUModel(name='STC15L12CCP', magic=0xd4bc, total=12288, code=12288, eeprom=0),
|
||||
MCUModel(name='STC15L04', magic=0xd484, total=4096, code=4096, eeprom=0),
|
||||
MCUModel(name='STC15L06', magic=0xd486, total=6144, code=6144, eeprom=0),
|
||||
MCUModel(name='STC15L08', magic=0xd488, total=8192, code=8192, eeprom=0),
|
||||
MCUModel(name='STC15L10', magic=0xd48a, total=10240, code=10240, eeprom=0),
|
||||
MCUModel(name='STC15L12', magic=0xd48c, total=12288, code=12288, eeprom=0),
|
||||
MCUModel(name='IAP15L08AD', magic=0xd4d8, total=8192, code=8192, eeprom=0),
|
||||
MCUModel(name='IAP15L10AD', magic=0xd4da, total=10240, code=10240, eeprom=0),
|
||||
MCUModel(name='IAP15L12AD', magic=0xd4dc, total=12288, code=12288, eeprom=0),
|
||||
MCUModel(name='IAP15L14AD', magic=0xd4de, total=14336, code=14336, eeprom=0),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -1028,3 +988,6 @@ class MCUModelDatabase:
|
||||
print(" Magic: %02X%02X" % (model.magic >> 8, model.magic & 0xff))
|
||||
print(" Code flash: %.1f KB" % (model.code / 1024.0))
|
||||
print(" EEPROM flash: %.1f KB" % (model.eeprom / 1024.0))
|
||||
|
||||
|
||||
|
||||
|
@ -238,39 +238,10 @@ class StcBaseProtocol:
|
||||
|
||||
return iap_wait
|
||||
|
||||
def delay_safely_written(self, length):
|
||||
"""
|
||||
Delay until data has been safely written and sent to device.
|
||||
Some buggy serial drivers don't implement tcdrain/flush correctly.
|
||||
That is, they wait until all data has been written to USB, but they
|
||||
do not wait until the data has actually finished transmission.
|
||||
Add additional delay to work around.
|
||||
"""
|
||||
|
||||
bit_time = 1.0 / self.ser.baudrate
|
||||
byte_time = bit_time * 11.0 # start, 8 data bits, stop, parity
|
||||
clock_safety_factor = 2.5 # additional delay in case clock is slow
|
||||
time.sleep(byte_time * length * clock_safety_factor)
|
||||
|
||||
def set_option(self, name, value):
|
||||
self.options.set_option(name, value)
|
||||
|
||||
def reset_device(self, resetcmd=False):
|
||||
if not resetcmd:
|
||||
print("Cycling power: ", end="")
|
||||
sys.stdout.flush()
|
||||
self.ser.setDTR(True)
|
||||
time.sleep(0.5)
|
||||
self.ser.setDTR(False)
|
||||
print("done")
|
||||
else:
|
||||
print("Cycling power via shell cmd: " + resetcmd)
|
||||
os.system(resetcmd)
|
||||
|
||||
print("Waiting for MCU: ", end="")
|
||||
sys.stdout.flush()
|
||||
|
||||
def connect(self, autoreset=False, resetcmd=False):
|
||||
def connect(self, autoreset=False):
|
||||
"""Connect to MCU and initialize communication.
|
||||
|
||||
Set up serial port, send sync sequence and get part info.
|
||||
@ -289,7 +260,14 @@ class StcBaseProtocol:
|
||||
self.ser.flushInput()
|
||||
|
||||
if autoreset:
|
||||
self.reset_device(resetcmd)
|
||||
print("Cycling power: ", end="")
|
||||
sys.stdout.flush()
|
||||
self.ser.setDTR(True)
|
||||
time.sleep(0.5)
|
||||
self.ser.setDTR(False)
|
||||
print("done")
|
||||
print("Waiting for MCU: ", end="")
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
print("Waiting for MCU, please cycle power: ", end="")
|
||||
sys.stdout.flush()
|
||||
@ -462,7 +440,7 @@ class Stc89Protocol(StcBaseProtocol):
|
||||
packet += struct.pack(">H", brt)
|
||||
packet += bytes([0xff - (brt >> 8), brt_csum, delay, iap])
|
||||
self.write_packet(packet)
|
||||
self.delay_safely_written(len(packet))
|
||||
time.sleep(0.2)
|
||||
self.ser.baudrate = self.baud_transfer
|
||||
response = self.read_packet()
|
||||
self.ser.baudrate = self.baud_handshake
|
||||
@ -476,7 +454,7 @@ class Stc89Protocol(StcBaseProtocol):
|
||||
packet += struct.pack(">H", brt)
|
||||
packet += bytes([0xff - (brt >> 8), brt_csum, delay])
|
||||
self.write_packet(packet)
|
||||
self.delay_safely_written(len(packet))
|
||||
time.sleep(0.2)
|
||||
self.ser.baudrate = self.baud_transfer
|
||||
response = self.read_packet()
|
||||
if response[0] != 0x8e:
|
||||
@ -652,7 +630,7 @@ class Stc12AProtocol(Stc12AOptionsMixIn, Stc89Protocol):
|
||||
sys.stdout.flush()
|
||||
packet = bytes([0x8f, 0xc0, brt, 0x3f, brt_csum, delay, iap])
|
||||
self.write_packet(packet)
|
||||
self.delay_safely_written(len(packet))
|
||||
time.sleep(0.2)
|
||||
self.ser.baudrate = self.baud_transfer
|
||||
response = self.read_packet()
|
||||
self.ser.baudrate = self.baud_handshake
|
||||
@ -664,7 +642,7 @@ class Stc12AProtocol(Stc12AOptionsMixIn, Stc89Protocol):
|
||||
sys.stdout.flush()
|
||||
packet = bytes([0x8e, 0xc0, brt, 0x3f, brt_csum, delay])
|
||||
self.write_packet(packet)
|
||||
self.delay_safely_written(len(packet))
|
||||
time.sleep(0.2)
|
||||
self.ser.baudrate = self.baud_transfer
|
||||
response = self.read_packet()
|
||||
if response[0] != 0x8e:
|
||||
@ -849,7 +827,7 @@ class Stc12BaseProtocol(StcBaseProtocol):
|
||||
sys.stdout.flush()
|
||||
packet = bytes([0x8f, 0xc0, brt, 0x3f, brt_csum, delay, iap])
|
||||
self.write_packet(packet)
|
||||
self.delay_safely_written(len(packet))
|
||||
time.sleep(0.2)
|
||||
self.ser.baudrate = self.baud_transfer
|
||||
response = self.read_packet()
|
||||
self.ser.baudrate = self.baud_handshake
|
||||
@ -861,7 +839,7 @@ class Stc12BaseProtocol(StcBaseProtocol):
|
||||
sys.stdout.flush()
|
||||
packet = bytes([0x8e, 0xc0, brt, 0x3f, brt_csum, delay])
|
||||
self.write_packet(packet)
|
||||
self.delay_safely_written(len(packet))
|
||||
time.sleep(0.2)
|
||||
self.ser.baudrate = self.baud_transfer
|
||||
response = self.read_packet()
|
||||
if response[0] != 0x84:
|
||||
@ -1135,7 +1113,7 @@ class Stc15AProtocol(Stc12Protocol):
|
||||
packet += struct.pack(">B", 230400 // self.baud_transfer)
|
||||
packet += bytes([0xa1, 0x64, 0xb8, 0x00, iap_wait, 0x20, 0xff, 0x00])
|
||||
self.write_packet(packet)
|
||||
self.delay_safely_written(len(packet))
|
||||
time.sleep(0.2)
|
||||
self.ser.baudrate = self.baud_transfer
|
||||
response = self.read_packet()
|
||||
if response[0] != 0x84:
|
||||
@ -1321,6 +1299,7 @@ class Stc15Protocol(Stc15AProtocol):
|
||||
response = self.read_packet()
|
||||
if response[0] != 0x01:
|
||||
raise StcProtocolException("incorrect magic in handshake packet")
|
||||
time.sleep(0.2)
|
||||
self.ser.baudrate = self.baud_transfer
|
||||
|
||||
def switch_baud_ext(self):
|
||||
@ -1337,6 +1316,7 @@ class Stc15Protocol(Stc15AProtocol):
|
||||
response = self.read_packet()
|
||||
if response[0] != 0x01:
|
||||
raise StcProtocolException("incorrect magic in handshake packet")
|
||||
time.sleep(0.2)
|
||||
self.ser.baudrate = self.baud_transfer
|
||||
|
||||
# for switching back to RC, program factory values
|
||||
@ -1524,7 +1504,7 @@ class StcUsb15Protocol(Stc15Protocol):
|
||||
host2dev = usb.util.CTRL_TYPE_VENDOR | usb.util.CTRL_RECIPIENT_DEVICE | usb.util.CTRL_OUT
|
||||
self.dev.ctrl_transfer(host2dev, request, value, index, chunks)
|
||||
|
||||
def connect(self, autoreset=False, resetcmd=False):
|
||||
def connect(self, autoreset=False):
|
||||
"""Connect to USB device and read info packet"""
|
||||
|
||||
# USB support is optional. Provide an error if pyusb is not available.
|
||||
|
Reference in New Issue
Block a user