Compare commits
45 Commits
stc8
...
github-act
Author | SHA1 | Date | |
---|---|---|---|
51ac52d3a3 | |||
43dbb2ef64 | |||
d7ed8bd530 | |||
6b83017de9 | |||
2d7ccf8b3d | |||
77b3f0e1b7 | |||
5d3214060b | |||
7e413b09ec | |||
3aa08b67c0 | |||
42f93bc481 | |||
dbfc1b3f50 | |||
9d47588ad2 | |||
217e5fb17e | |||
3875b1f415 | |||
8e31765cba | |||
75db655419 | |||
1c062ed0c7 | |||
4fe0a30072 | |||
7d9f512b6d | |||
6544699a84 | |||
f5089af93a | |||
bc829ce54c | |||
97d0d1123b | |||
5032b631bf | |||
9ae334ec25 | |||
05984a6c49 | |||
e0e2ab5526 | |||
4cc0deb8e9 | |||
5ab2a73411 | |||
4a40d5613a | |||
83c0b47f62 | |||
b0e882ff32 | |||
ccd4b1e26b | |||
71d7257422 | |||
0ff7e16f38 | |||
aca713595b | |||
69b83f0ea1 | |||
170008971d | |||
cd229eab47 | |||
ce251f9d30 | |||
11d2ea22e6 | |||
c7c4937628 | |||
ac119e180e | |||
fcbc560ade | |||
7b4758499b |
50
.github/workflows/python.yml
vendored
Normal file
50
.github/workflows/python.yml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
name: Python package
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [3.5, 3.7, 3.8]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pyusb coverage coveralls pyserial PyYAML tqdm
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
- name: Build package
|
||||
run: |
|
||||
python setup.py build
|
||||
- name: Test with unittest
|
||||
run: |
|
||||
coverage run --source=stcgal setup.py test
|
||||
- name: Coveralls
|
||||
run: |
|
||||
coveralls
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COVERALLS_FLAG_NAME: ${{ matrix.python-version }}
|
||||
COVERALLS_PARALLEL: true
|
||||
|
||||
coveralls:
|
||||
name: Finish Coveralls
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
container: python:3-slim
|
||||
steps:
|
||||
- name: Finished
|
||||
run: |
|
||||
pip3 install --upgrade coveralls
|
||||
coveralls --finish
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
33
.travis.yml
33
.travis.yml
@ -1,33 +0,0 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
language: python
|
||||
cache:
|
||||
- pip
|
||||
python:
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
- "pypy3"
|
||||
before_install:
|
||||
- sudo apt install rpm dpkg-dev debhelper dh-python python3-setuptools fakeroot python3-serial python3-yaml
|
||||
install:
|
||||
- pip install pyserial pyusb tqdm
|
||||
script:
|
||||
- python setup.py build
|
||||
- python setup.py test
|
||||
before_deploy:
|
||||
- deactivate
|
||||
- python3 setup.py bdist_rpm
|
||||
- dpkg-buildpackage -uc -us
|
||||
- cp ../*.deb dist/
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key: $GH_TOKEN
|
||||
file_glob: true
|
||||
file:
|
||||
- dist/stcgal*_all.deb
|
||||
- dist/stcgal*.noarch.rpm
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
python: "3.4"
|
298
README.md
298
README.md
@ -1,10 +1,12 @@
|
||||
[](https://travis-ci.org/grigorig/stcgal)
|
||||
[](https://github.com/grigorig/stcgal/actions?query=workflow%3A%22Python+package%22)
|
||||
[](https://coveralls.io/github/grigorig/stcgal?branch=master)
|
||||
[](https://badge.fury.io/py/stcgal)
|
||||
|
||||
stcgal - STC MCU ISP flash tool
|
||||
===============================
|
||||
|
||||
stcgal is a command line flash programming tool for STC MCU Ltd. [1]
|
||||
8051 compatible microcontrollers. The name was inspired by avrdude [2].
|
||||
stcgal is a command line flash programming tool for [STC MCU Ltd](http://stcmcu.com/).
|
||||
8051 compatible microcontrollers.
|
||||
|
||||
STC microcontrollers have an UART/USB based boot strap loader (BSL). It
|
||||
utilizes a packet-based protocol to flash the code memory and IAP
|
||||
@ -17,43 +19,10 @@ stcgal is a full-featured Open Source replacement for STC's Windows
|
||||
software; it supports a wide range of MCUs, it is very portable and
|
||||
suitable for automation.
|
||||
|
||||
[1] http://stcmcu.com/
|
||||
[2] http://www.nongnu.org/avrdude/
|
||||
|
||||
Supported MCU models
|
||||
--------------------
|
||||
|
||||
stcgal should fully support STC 89/90/10/11/12/15 series MCUs. Support for STC8 series MCUs is work in progress.
|
||||
|
||||
So far, stcgal was tested with the following MCU models:
|
||||
|
||||
* STC89C52RC (BSL version: 4.3C/6.6C)
|
||||
* STC90C52RC (BSL version: 4.3C)
|
||||
* STC89C54RD+ (BSL version: 4.3C)
|
||||
* STC12C2052 (BSL version: 5.8D)
|
||||
* STC12C2052AD (BSL version: 5.8D)
|
||||
* STC12C5608AD (BSL version: 6.0G)
|
||||
* STC12C5A16S2 (BSL version: 6.2I)
|
||||
* STC12C5A60S2 (BSL version: 6.2I/7.1I)
|
||||
* STC11F02E (BSL version: 6.5K)
|
||||
* STC10F04XE (BSL version: 6.5J)
|
||||
* STC11F08XE (BSL version: 6.5M)
|
||||
* STC12C5204AD (BSL version: 6.6H)
|
||||
* STC15F104E (BSL version: 6.7Q)
|
||||
* STC15F204EA (BSL version: 6.7R)
|
||||
* STC15L104W (BSL version: 7.1.4Q)
|
||||
* STC15F104W (BSL version: 7.1.4Q)
|
||||
* IAP15F2K61S2 (BSL version: 7.1.4S)
|
||||
* STC15L2K16S2 (BSL version: 7.2.4S)
|
||||
* STC15W408AS (BSL version: 7.2.4T)
|
||||
* STC15W4K56S4 (BSL version: 7.3.4T, UART and USB mode)
|
||||
* STC8A8K64S4A12 (BSL version: 7.3.9U)
|
||||
|
||||
Compatibility reports, both negative and positive, are welcome.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Support for STC 89/90/10/11/12/15/8 series
|
||||
* UART and USB BSL support
|
||||
* Display part info
|
||||
* Determine operating frequency
|
||||
@ -65,256 +34,27 @@ Features
|
||||
* Automatic power-cycling with DTR toggle or a custom shell command
|
||||
* Automatic UART protocol detection
|
||||
|
||||
Installation
|
||||
------------
|
||||
Quickstart
|
||||
----------
|
||||
|
||||
stcgal requires Python 3.2 (or later) and pySerial. USB support is
|
||||
optional and requires pyusb 1.0.0b2 or later. You can run stcgal
|
||||
directly with the included ```stcgal.py``` script. The recommended
|
||||
method for permanent installation is to use Python's setuptools. Run
|
||||
```./setup.py build``` to build and ```sudo ./setup.py install```
|
||||
to install stcgal. A permanent installation provides the ```stcgal```
|
||||
command.
|
||||
Install stcgal (might need root/administrator privileges):
|
||||
|
||||
pip3 install stcgal
|
||||
|
||||
Usage
|
||||
-----
|
||||
Call stcgal and show usage:
|
||||
|
||||
Call stcgal with ```-h``` for usage information.
|
||||
stcgal -h
|
||||
|
||||
```
|
||||
usage: stcgal.py [-h] [-a] [-P {stc89,stc12a,stc12,stc15a,stc15,auto}]
|
||||
[-p PORT] [-b BAUD] [-l HANDSHAKE] [-o OPTION] [-t TRIM] [-D]
|
||||
[code_image] [eeprom_image]
|
||||
Further information
|
||||
-------------------
|
||||
|
||||
stcgal 1.0 - an STC MCU ISP flash tool
|
||||
(C) 2014-2015 Grigori Goronzy
|
||||
https://github.com/grigorig/stcgal
|
||||
[Installation](doc/INSTALL.md)
|
||||
|
||||
positional arguments:
|
||||
code_image code segment file to flash (BIN/HEX)
|
||||
eeprom_image eeprom segment file to flash (BIN/HEX)
|
||||
[How to use stcgal](doc/USAGE.md)
|
||||
|
||||
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
|
||||
-b BAUD, --baud BAUD transfer baud rate (default: 19200)
|
||||
-l HANDSHAKE, --handshake HANDSHAKE
|
||||
handshake baud rate (default: 2400)
|
||||
-o OPTION, --option OPTION
|
||||
set option (can be used multiple times)
|
||||
-t TRIM, --trim TRIM RC oscillator frequency in kHz (STC15 series only)
|
||||
-D, --debug enable debug output
|
||||
```
|
||||
[Frequently Asked Questions](doc/FAQ.md)
|
||||
|
||||
Most importantly, ```-p``` sets the serial port to be used for programming.
|
||||
|
||||
### Protocols
|
||||
|
||||
STC MCUs use a variety of related but incompatible protocols for the
|
||||
BSL. The protocol can be specified with the ```-P``` flag. By default
|
||||
UART protocol autodetection is used. The mapping between protocols
|
||||
and MCU series is as follows:
|
||||
|
||||
* ```stc89``` STC89/90 series
|
||||
* ```stc12a``` STC12x052 series and possibly others
|
||||
* ```stc12b``` STC12x52 series, STC12x56 series and possibly others
|
||||
* ```stc12``` Most STC10/11/12 series
|
||||
* ```stc15a``` STC15x104E and STC15x204E(A) series
|
||||
* ```stc15``` Most STC15 series
|
||||
* ```stc8``` STC8 series
|
||||
* ```usb15``` USB support on STC15W4 series
|
||||
* ```auto``` Automatic detection of UART based protocols (default)
|
||||
|
||||
The text files in the doc/ subdirectory provide an overview over
|
||||
the reverse engineered protocols used by the BSLs. For more details,
|
||||
please read the source code.
|
||||
|
||||
### Getting MCU information
|
||||
|
||||
Call stcgal without any file to program. It will dump information
|
||||
about the MCU, e.g.:
|
||||
|
||||
```
|
||||
$ ./stcgal.py -P stc15
|
||||
Waiting for MCU, please cycle power: done
|
||||
Target model:
|
||||
Name: IAP15F2K61S2
|
||||
Magic: F449
|
||||
Code flash: 61.0 KB
|
||||
EEPROM flash: 0.0 KB
|
||||
Target frequency: 10.046 MHz
|
||||
Target BSL version: 7.1S
|
||||
Target wakeup frequency: 34.771 KHz
|
||||
Target options:
|
||||
reset_pin_enabled=False
|
||||
clock_source=internal
|
||||
clock_gain=high
|
||||
watchdog_por_enabled=False
|
||||
watchdog_stop_idle=True
|
||||
watchdog_prescale=256
|
||||
low_voltage_reset=True
|
||||
low_voltage_threshold=3
|
||||
eeprom_lvd_inhibit=True
|
||||
eeprom_erase_enabled=False
|
||||
bsl_pindetect_enabled=False
|
||||
por_reset_delay=long
|
||||
rstout_por_state=high
|
||||
uart2_passthrough=False
|
||||
uart2_pin_mode=normal
|
||||
Disconnected!
|
||||
```
|
||||
|
||||
### Program the flash memory
|
||||
|
||||
stcgal supports Intel HEX encoded files as well as binary files. Intel
|
||||
HEX is autodetected by file extension (.hex, .ihx or .ihex).
|
||||
|
||||
Call stcgal just like before, but provide the path to the code image:
|
||||
|
||||
```
|
||||
$ ./stcgal.py -P stc15 hello.hex
|
||||
Waiting for MCU, please cycle power: done
|
||||
Target model:
|
||||
Name: IAP15F2K61S2
|
||||
Magic: F449
|
||||
Code flash: 61.0 KB
|
||||
EEPROM flash: 0.0 KB
|
||||
Target frequency: 10.046 MHz
|
||||
Target BSL version: 7.1S
|
||||
Target wakeup frequency: 34.771 KHz
|
||||
Target options:
|
||||
reset_pin_enabled=False
|
||||
clock_source=internal
|
||||
clock_gain=high
|
||||
watchdog_por_enabled=False
|
||||
watchdog_stop_idle=True
|
||||
watchdog_prescale=256
|
||||
low_voltage_reset=True
|
||||
low_voltage_threshold=3
|
||||
eeprom_lvd_inhibit=True
|
||||
eeprom_erase_enabled=False
|
||||
bsl_pindetect_enabled=False
|
||||
por_reset_delay=long
|
||||
rstout_por_state=high
|
||||
uart2_passthrough=False
|
||||
uart2_pin_mode=normal
|
||||
Loading flash: 80 bytes (Intel HEX)
|
||||
Trimming frequency: 10.046 MHz
|
||||
Switching to 19200 baud: done
|
||||
Erasing flash: done
|
||||
Writing 256 bytes: .... done
|
||||
Setting options: done
|
||||
Target UID: 0D000021022632
|
||||
Disconnected!
|
||||
```
|
||||
|
||||
You can also program the EEPROM part of the memory, if applicable. Add
|
||||
the EEPROM image path to the commandline after the flash image path.
|
||||
|
||||
stcgal uses a conservative baud rate of 19200 bps by
|
||||
default. Programming can be sped up by choosing a faster baud rate
|
||||
with the flag ```-b```.
|
||||
|
||||
### Device options
|
||||
|
||||
stcgal dumps a number of target options. These can be modified as
|
||||
well. Provide one (or more) ```-o``` flags followed by a key-value
|
||||
pair on the commandline to adjust these settings. For instance, you can
|
||||
enable the external crystal as clock source:
|
||||
|
||||
```
|
||||
$ ./stcgal.py -P stc15 -o clock_source=external hello.bin
|
||||
```
|
||||
|
||||
Please note that device options can only be set when flash memory is
|
||||
programmed!
|
||||
|
||||
#### Option keys
|
||||
|
||||
Not all parts support all options. The protocols or parts that support each option are listed in the description.
|
||||
|
||||
Option key | Possible values | Protocols/Models | Description
|
||||
------------------------------|-------------------|---------------------|------------
|
||||
```cpu_6t_enabled``` | true/false | STC89 only | 6T fast mode
|
||||
```bsl_pindetect_enabled``` | true/false | All | BSL only enabled when P3.2/P3.3 or P1.0/P1.1 (depends on model) are low
|
||||
```eeprom_erase_enabled``` | true/false | All | Erase EEPROM with next programming cycle
|
||||
```clock_gain``` | low/high | All with XTAL pins | Clock gain for external crystal
|
||||
```ale_enabled``` | true/false | STC89 only | ALE pin enabled if true, normal GPIO if false
|
||||
```xram_enabled``` | true/false | STC89 only | Use internal XRAM (STC89 only)
|
||||
```watchdog_por_enabled``` | true/false | All | Watchdog state after power-on reset (POR)
|
||||
```low_voltage_reset``` | low/high | STC12A/STC12 | Low-voltage reset level (low: ~3.3V, high: ~3.7V)
|
||||
```low_voltage_reset``` | true/false | STC12 | Enable RESET2 pin low voltage detect
|
||||
```low_voltage_reset``` | true/false | STC15A | Enable low-voltage reset (brownout)
|
||||
```clock_source``` | internal/external | STC12A+ with XTAL | Use internal (RC) or external (crystal) clock
|
||||
```watchdog_stop_idle``` | true/false | STC12A+ | Stop watchdog in IDLE mode
|
||||
```watchdog_prescale``` | 2,4,8,...,256 | STC12A+ | Watchdog timer prescaler, must be a power of two.
|
||||
```reset_pin_enabled``` | true/false | STC12+ | RESET pin enabled if true, normal GPIO if false
|
||||
```oscillator_stable_delay``` | 4096,...,32768 | STC11F series only | Crystal stabilization delay in clocks. Must be a power of two.
|
||||
```por_reset_delay``` | short/long | STC12+ | Power-on reset (POR) delay
|
||||
```low_voltage_threshold``` | 0...7 | STC15A+ | Low-voltage detection threshold. Model specific.
|
||||
```eeprom_lvd_inhibit``` | true/false | STC15A+ | Ignore EEPROM writes in low-voltage situations
|
||||
```rstout_por_state``` | low/high | STC15+ | RSTOUT/RSTSV pin state after power-on reset
|
||||
```uart1_remap``` | true/false | STC8 | Remap UART1 pins (P3.0/P3.1) to UART2 pins (P3.6/P3.7)
|
||||
```uart2_passthrough``` | true/false | STC15+ | Pass-through UART1 to UART2 pins (for single-wire UART mode)
|
||||
```uart2_pin_mode``` | push-pull/normal | STC15+ | Output mode of UART2 TX pin
|
||||
```cpu_core_voltage``` | low/mid/high | STC15W+ | CPU core voltage (low: ~2.7V, mid: ~3.3V, high: ~3.6V)
|
||||
```epwm_open_drain``` | true/false | STC8 | Use open-drain pin mode for EPWM pins after power-on reset
|
||||
```program_eeprom_split``` | 512 - 65024 | STC8A8 w/ 64 KB | Select split between code flash and EEPROM flash (in 512 byte blocks)
|
||||
|
||||
### Frequency trimming
|
||||
|
||||
If the internal RC oscillator is used (```clock_source=internal```),
|
||||
stcgal can execute a trim procedure to adjust it to a given value. This
|
||||
is only supported by STC15 series and newer. The trim values are stored
|
||||
with device options. Use the ```-t``` flag to request trimming to a certain
|
||||
value. Generally, frequencies between 4 and 35 MHz can be achieved. If
|
||||
trimming fails, stcgal will abort.
|
||||
|
||||
### Automatic power-cycling
|
||||
|
||||
STC's microcontrollers require a power-on reset to invoke the bootloader,
|
||||
which can be inconvenient. stcgal can use the DTR control signal of a
|
||||
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"
|
||||
```
|
||||
|
||||
### Exit status
|
||||
|
||||
The exit status is 0 if no error occured while executing stcgal. Any
|
||||
error, such as a protocol error or I/O error, results in an exit
|
||||
status of 1. If the the user aborted stcgal by pressing CTRL-C,
|
||||
that results in an exit status of 2.
|
||||
|
||||
### USB support
|
||||
|
||||
STC15W4 series have an USB-based BSL that can be optionally
|
||||
used. USB support in stcgal is experimental and might change in the
|
||||
future. USB mode is enabled by using the ```usb15``` protocol. The
|
||||
port (```-p```) flag as well as the baudrate options are ignored for
|
||||
the USB protocol. RC frequency trimming is not supported.
|
||||
[List of tested MCU models](doc/MODELS.md)
|
||||
|
||||
License
|
||||
-------
|
||||
|
10
TODO.md
10
TODO.md
@ -1,10 +0,0 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- some more documentation / comments
|
||||
- private member naming, other style issues
|
||||
- sensible default serial port (e.g. on windows)
|
||||
- automatic protocol detection
|
||||
- verify stc12a/stc12 options (e.g. low_voltage_threshold)
|
||||
- also verify low_voltage_threshold on stc15
|
||||
- check if stc15 handles 64 byte blocks correctly
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
||||
stcgal (1.6) unstable; urgency=low
|
||||
|
||||
* Update to 1.6
|
||||
|
||||
-- Grigori Goronzy <greg@chown.ath.cx> Mon, 24 Sep 2018 22:56:31 +0200
|
||||
|
||||
stcgal (1.4) unstable; urgency=low
|
||||
|
||||
* Update to 1.4
|
||||
|
4
debian/docs
vendored
4
debian/docs
vendored
@ -1,2 +1,4 @@
|
||||
README.md
|
||||
TODO.md
|
||||
doc/USAGE.md
|
||||
doc/MODELS.md
|
||||
doc/FAQ.md
|
||||
|
72
doc/FAQ.md
Normal file
72
doc/FAQ.md
Normal file
@ -0,0 +1,72 @@
|
||||
Frequently Asked Questions
|
||||
==========================
|
||||
|
||||
### Is it possible to read code (or EEPROM) memory out of a chip?
|
||||
|
||||
By design, this is not possible with STC's bootloader protocols. This is considered a security feature by STC. There is no known workaround at this time. See issue #7 for more details and discussion.
|
||||
|
||||
### Which serial interfaces have been tested with stcgal?
|
||||
|
||||
stcgal should work fine with common 16550 compatible UARTs that are traditionally available on many platforms. However, nowadays, USB-based UARTs are the typical case. The following USB-based UART interface chips have been successfully tested with stcgal:
|
||||
|
||||
* FT232 family (OS: Linux, Windows)
|
||||
* CH340/CH341 (OS: Windows, Linux requires Kernel 4.10)
|
||||
* PL2303 (OS: Windows, Linux)
|
||||
* CP2102 (OS: Windows, Linux, macOS)
|
||||
|
||||
Interfaces that are known to not work:
|
||||
|
||||
* Raspberry Pi Mini UART (lacks parity support, enable the PL011 UART instead)
|
||||
|
||||
In general, stcgal requires accurate baud rate timings and parity support.
|
||||
|
||||
### stcgal fails to start with the error `module 'serial' has no attribute 'PARITY_NONE'` or similar
|
||||
|
||||
There is a module name conflict between the PyPI package 'serial' (a data serialization library) and the PyPI package 'pyserial' (the serial port access library needed by stcgal). You have to uninstall the 'serial' package (`pip3 uninstall serial`) and reinstall 'pyserial' (`pip3 install --force-reinstall pyserial`) to fix this. There is no other known solution at the moment.
|
||||
|
||||
### stcgal fails to recognize the MCU and is stuck at "Waiting for MCU"
|
||||
|
||||
There are a number of issues that can result in this symptom:
|
||||
|
||||
* Electrical issues and wrong connections. Make sure that RX/TX, GND and VCC are connected correctly. If you do not use the autoreset feature, also make sure to connect power only after stcgal starts, as the bootloader is only invoked on power-on reset.
|
||||
* Parasitic powering through I/O pins. The MCU can be powered through I/O pins (such as RX/TX) even if VCC is not connected. In this case, the power-on reset logic does not work. See next question.
|
||||
* Serial interface incompatibilities. Some USB-based UARTs have bad compatibility with STC MCUs for various reasons. You can try to lower the handshake baudrate from the standard 2400 baud to 1200 baud with the option `-l 1200`, which works around these issues in some cases.
|
||||
|
||||
### How can I avoid parasitic powering?
|
||||
|
||||
Various remedies are possible to avoid parasitic powering.
|
||||
|
||||
* You can try to connect a resistor (< 1k) between MCU VCC and GND to short-circuit injected power and hopefully drop the voltage below the brown-out value.
|
||||
* Another option is to insert series resistor on I/O lines that might inject power. Try a value like 1k on the RX/TX lines, for instance.
|
||||
* Yet another possibility is to switch GND instead of VCC. This should be a fairly reliable solution in most cases.
|
||||
|
||||
### RC frequency trimming fails
|
||||
|
||||
First, make sure that the frequency specified uses the correct unit. The frequency is specified in kHz and the safe range is approximately 5000 kHz - 30000 kHz. Furthermore, frequency trimming uses the UART clock as the clock reference, so UART incompatibilities or clock inaccuracies can also result in issues with frequency trimming. If possible, try another UART chip.
|
||||
|
||||
### Baud rate switching fails or flash programming fails
|
||||
|
||||
This can especially happen at high programming baud rates, e.g. 115200 baud. Try a lower baudrate, or stick to the default of 19200 baud. Some USB UARTs are known to cause problems due to inaccurate timing as well, which can lead to various issues.
|
||||
|
||||
### How can I use the autoreset feature?
|
||||
|
||||
The standard autoreset feature works somewhat similarly to Arduino. DTR is an active low signal, and is asserted on startup of stcgal for 500 ms and then deasserted for the rest of the programming sequence. On a standard USB UART, this results in 500 ms low pulse, followed by a high phase. The stcgal author recommends the following circuit:
|
||||
|
||||
```
|
||||
VCC --o o-- MCU GND
|
||||
| |
|
||||
.-. |
|
||||
| | 1k |
|
||||
| | |
|
||||
'_' |
|
||||
| |
|
||||
| ||-+
|
||||
DTR --o --||<- BS170/BSS138
|
||||
||-| (N-CH MOSFET)
|
||||
|
|
||||
|
|
||||
GND ---------o
|
||||
```
|
||||
|
||||
This circuit uses an N-channel MOSFET as a low-side switch to switch the MCU's GND. VCC is directly connected. This avoids parasitic powering issues. The pull-up resistor ensures that the MCU is switched on when the DTR input is floating.
|
||||
|
17
doc/INSTALL.md
Normal file
17
doc/INSTALL.md
Normal file
@ -0,0 +1,17 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
stcgal requires Python 3.2 (or later), pyserial 3.0 or later and
|
||||
TQDM 4.0.0 or later. USB support is optional and requires pyusb
|
||||
1.0.0b2 or later. You can run stcgal directly with the included
|
||||
```stcgal.py``` script if the dependencies are already installed.
|
||||
|
||||
There are several options for permanent installation:
|
||||
|
||||
* Use Python3 and ```pip```. Run ```pip3 install stcgal``` to
|
||||
install the latest release of stcgal globally on your system.
|
||||
This may require administrator/root permissions for write access
|
||||
to system directories.
|
||||
|
||||
* Use setuptools. Run ```./setup.py build``` to build and
|
||||
```sudo ./setup.py install``` to install stcgal.
|
32
doc/MODELS.md
Normal file
32
doc/MODELS.md
Normal file
@ -0,0 +1,32 @@
|
||||
Supported MCU models
|
||||
====================
|
||||
|
||||
stcgal should fully support STC 89/90/10/11/12/15/8 series MCUs.
|
||||
|
||||
So far, stcgal was tested with the following MCU models:
|
||||
|
||||
* STC89C52RC (BSL version: 4.3C/6.6C)
|
||||
* STC90C52RC (BSL version: 4.3C)
|
||||
* STC89C54RD+ (BSL version: 4.3C)
|
||||
* STC12C2052 (BSL version: 5.8D)
|
||||
* STC12C2052AD (BSL version: 5.8D)
|
||||
* STC12C5608AD (BSL version: 6.0G)
|
||||
* STC12C5A16S2 (BSL version: 6.2I)
|
||||
* STC12C5A60S2 (BSL version: 6.2I/7.1I)
|
||||
* STC11F02E (BSL version: 6.5K)
|
||||
* STC10F04XE (BSL version: 6.5J)
|
||||
* STC11F08XE (BSL version: 6.5M)
|
||||
* STC12C5204AD (BSL version: 6.6H)
|
||||
* STC15F104E (BSL version: 6.7Q)
|
||||
* STC15F204EA (BSL version: 6.7R)
|
||||
* STC15L104W (BSL version: 7.1.4Q)
|
||||
* STC15F104W (BSL version: 7.1.4Q)
|
||||
* IAP15F2K61S2 (BSL version: 7.1.4S)
|
||||
* STC15L2K16S2 (BSL version: 7.2.4S)
|
||||
* IAP15L2K61S2 (BSL version: 7.2.5S)
|
||||
* STC15W408AS (BSL version: 7.2.4T)
|
||||
* STC15W4K56S4 (BSL version: 7.3.4T, UART and USB mode)
|
||||
* STC8A8K64S4A12 (BSL version: 7.3.9U)
|
||||
* STC8F2K08S2 (BSL version: 7.3.10U)
|
||||
|
||||
Compatibility reports, both negative and positive, are welcome.
|
18
doc/PyPI.md
Normal file
18
doc/PyPI.md
Normal file
@ -0,0 +1,18 @@
|
||||
stcgal - STC MCU ISP flash tool
|
||||
===============================
|
||||
|
||||
stcgal is a command line flash programming tool for [STC MCU Ltd](http://stcmcu.com/).
|
||||
8051 compatible microcontrollers.
|
||||
|
||||
STC microcontrollers have an UART/USB based boot strap loader (BSL). It
|
||||
utilizes a packet-based protocol to flash the code memory and IAP
|
||||
memory over a serial link. This is referred to as in-system programming
|
||||
(ISP). The BSL is also used to configure various (fuse-like) device
|
||||
options. Unfortunately, this protocol is not publicly documented and
|
||||
STC only provide a (crude) Windows GUI application for programming.
|
||||
|
||||
stcgal is a full-featured Open Source replacement for STC's Windows
|
||||
software; it supports a wide range of MCUs, it is very portable and
|
||||
suitable for automation.
|
||||
|
||||
[See the GitHub page for more information](https://github.com/grigorig/stcgal).
|
245
doc/USAGE.md
Normal file
245
doc/USAGE.md
Normal file
@ -0,0 +1,245 @@
|
||||
Usage
|
||||
=====
|
||||
|
||||
Call stcgal with ```-h``` for usage information.
|
||||
|
||||
```
|
||||
usage: stcgal.py [-h] [-a] [-r RESETCMD]
|
||||
[-P {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,usb15,auto}]
|
||||
[-p PORT] [-b BAUD] [-l HANDSHAKE] [-o OPTION] [-t TRIM] [-D]
|
||||
[-V]
|
||||
[code_image] [eeprom_image]
|
||||
|
||||
stcgal 1.5 - an STC MCU ISP flash tool
|
||||
(C) 2014-2018 Grigori Goronzy and others
|
||||
https://github.com/grigorig/stcgal
|
||||
|
||||
positional arguments:
|
||||
code_image code segment file to flash (BIN/HEX)
|
||||
eeprom_image eeprom segment file to flash (BIN/HEX)
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-a, --autoreset cycle power automatically by asserting DTR
|
||||
-r RESETCMD, --resetcmd RESETCMD
|
||||
shell command for board power-cycling (instead of DTR
|
||||
assertion)
|
||||
-P {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,usb15,auto}, --protocol {stc89,stc12a,stc12b,stc12,stc15a,stc15,stc8,usb15,auto}
|
||||
protocol version (default: auto)
|
||||
-p PORT, --port PORT serial port device
|
||||
-b BAUD, --baud BAUD transfer baud rate (default: 19200)
|
||||
-l HANDSHAKE, --handshake HANDSHAKE
|
||||
handshake baud rate (default: 2400)
|
||||
-o OPTION, --option OPTION
|
||||
set option (can be used multiple times, see
|
||||
documentation)
|
||||
-t TRIM, --trim TRIM RC oscillator frequency in kHz (STC15+ series only)
|
||||
-D, --debug enable debug output
|
||||
-V, --version print version info and exit
|
||||
```
|
||||
|
||||
Most importantly, ```-p``` sets the serial port to be used for programming.
|
||||
|
||||
### Protocols
|
||||
|
||||
STC MCUs use a variety of related but incompatible protocols for the
|
||||
BSL. The protocol can be specified with the ```-P``` flag. By default
|
||||
UART protocol autodetection is used. The mapping between protocols
|
||||
and MCU series is as follows:
|
||||
|
||||
* ```auto``` Automatic detection of UART based protocols (default)
|
||||
* ```stc89``` STC89/90 series
|
||||
* ```stc12a``` STC12x052 series and possibly others
|
||||
* ```stc12b``` STC12x52 series, STC12x56 series and possibly others
|
||||
* ```stc12``` Most STC10/11/12 series
|
||||
* ```stc15a``` STC15x104E and STC15x204E(A) series
|
||||
* ```stc15``` Most STC15 series
|
||||
* ```stc8``` STC8 series
|
||||
* ```usb15``` USB support on STC15W4 series
|
||||
|
||||
The text files in the doc/reverse-engineering subdirectory provide an
|
||||
overview over the reverse engineered protocols used by the BSLs. For
|
||||
more details, please read the source code.
|
||||
|
||||
### Getting MCU information
|
||||
|
||||
Call stcgal without any file to program. It will dump information
|
||||
about the MCU, e.g.:
|
||||
|
||||
```
|
||||
$ ./stcgal.py -P stc15
|
||||
Waiting for MCU, please cycle power: done
|
||||
Target model:
|
||||
Name: IAP15F2K61S2
|
||||
Magic: F449
|
||||
Code flash: 61.0 KB
|
||||
EEPROM flash: 0.0 KB
|
||||
Target frequency: 10.046 MHz
|
||||
Target BSL version: 7.1S
|
||||
Target wakeup frequency: 34.771 KHz
|
||||
Target options:
|
||||
reset_pin_enabled=False
|
||||
clock_source=internal
|
||||
clock_gain=high
|
||||
watchdog_por_enabled=False
|
||||
watchdog_stop_idle=True
|
||||
watchdog_prescale=256
|
||||
low_voltage_reset=True
|
||||
low_voltage_threshold=3
|
||||
eeprom_lvd_inhibit=True
|
||||
eeprom_erase_enabled=False
|
||||
bsl_pindetect_enabled=False
|
||||
por_reset_delay=long
|
||||
rstout_por_state=high
|
||||
uart2_passthrough=False
|
||||
uart2_pin_mode=normal
|
||||
Disconnected!
|
||||
```
|
||||
|
||||
If the identification fails, see the [FAQ](FAQ.md) for troubleshooting.
|
||||
|
||||
### Program the flash memory
|
||||
|
||||
stcgal supports Intel HEX encoded files as well as binary files. Intel
|
||||
HEX is autodetected by file extension (.hex, .ihx or .ihex).
|
||||
|
||||
Call stcgal just like before, but provide the path to the code image:
|
||||
|
||||
```
|
||||
$ ./stcgal.py -P stc15 hello.hex
|
||||
Waiting for MCU, please cycle power: done
|
||||
Target model:
|
||||
Name: IAP15F2K61S2
|
||||
Magic: F449
|
||||
Code flash: 61.0 KB
|
||||
EEPROM flash: 0.0 KB
|
||||
Target frequency: 10.046 MHz
|
||||
Target BSL version: 7.1S
|
||||
Target wakeup frequency: 34.771 KHz
|
||||
Target options:
|
||||
reset_pin_enabled=False
|
||||
clock_source=internal
|
||||
clock_gain=high
|
||||
watchdog_por_enabled=False
|
||||
watchdog_stop_idle=True
|
||||
watchdog_prescale=256
|
||||
low_voltage_reset=True
|
||||
low_voltage_threshold=3
|
||||
eeprom_lvd_inhibit=True
|
||||
eeprom_erase_enabled=False
|
||||
bsl_pindetect_enabled=False
|
||||
por_reset_delay=long
|
||||
rstout_por_state=high
|
||||
uart2_passthrough=False
|
||||
uart2_pin_mode=normal
|
||||
Loading flash: 80 bytes (Intel HEX)
|
||||
Trimming frequency: 10.046 MHz
|
||||
Switching to 19200 baud: done
|
||||
Erasing flash: done
|
||||
Writing 256 bytes: .... done
|
||||
Setting options: done
|
||||
Target UID: 0D000021022632
|
||||
Disconnected!
|
||||
```
|
||||
|
||||
You can also program the EEPROM part of the memory, if applicable. Add
|
||||
the EEPROM image path to the commandline after the flash image path.
|
||||
|
||||
stcgal uses a conservative baud rate of 19200 bps by
|
||||
default. Programming can be sped up by choosing a faster baud rate
|
||||
with the flag ```-b```.
|
||||
|
||||
### Device options
|
||||
|
||||
stcgal dumps a number of target options. These can be modified as
|
||||
well. Provide one (or more) ```-o``` flags followed by a key-value
|
||||
pair on the commandline to adjust these settings. For instance, you can
|
||||
enable the external crystal as clock source:
|
||||
|
||||
```
|
||||
$ ./stcgal.py -P stc15 -o clock_source=external hello.bin
|
||||
```
|
||||
|
||||
Please note that device options can only be set when flash memory is
|
||||
programmed!
|
||||
|
||||
#### Option keys
|
||||
|
||||
Not all parts support all options. The protocols or parts that support each option are listed in the description.
|
||||
|
||||
Option key | Possible values | Protocols/Models | Description
|
||||
------------------------------|-------------------|---------------------|------------
|
||||
```cpu_6t_enabled``` | true/false | STC89 only | 6T fast mode
|
||||
```bsl_pindetect_enabled``` | true/false | All | BSL only enabled when P3.2/P3.3 or P1.0/P1.1 (depends on model) are low
|
||||
```eeprom_erase_enabled``` | true/false | All | Erase EEPROM with next programming cycle
|
||||
```clock_gain``` | low/high | All with XTAL pins | Clock gain for external crystal
|
||||
```ale_enabled``` | true/false | STC89 only | ALE pin enabled if true, normal GPIO if false
|
||||
```xram_enabled``` | true/false | STC89 only | Use internal XRAM (STC89 only)
|
||||
```watchdog_por_enabled``` | true/false | All | Watchdog state after power-on reset (POR)
|
||||
```low_voltage_reset``` | low/high | STC12A/STC12 | Low-voltage reset level (low: ~3.3V, high: ~3.7V)
|
||||
```low_voltage_reset``` | true/false | STC12 | Enable RESET2 pin low voltage detect
|
||||
```low_voltage_reset``` | true/false | STC15A | Enable low-voltage reset (brownout)
|
||||
```clock_source``` | internal/external | STC12A+ with XTAL | Use internal (RC) or external (crystal) clock
|
||||
```watchdog_stop_idle``` | true/false | STC12A+ | Stop watchdog in IDLE mode
|
||||
```watchdog_prescale``` | 2,4,8,...,256 | STC12A+ | Watchdog timer prescaler, must be a power of two.
|
||||
```reset_pin_enabled``` | true/false | STC12+ | RESET pin enabled if true, normal GPIO if false
|
||||
```oscillator_stable_delay``` | 4096,...,32768 | STC11F series only | Crystal stabilization delay in clocks. Must be a power of two.
|
||||
```por_reset_delay``` | short/long | STC12+ | Power-on reset (POR) delay
|
||||
```low_voltage_threshold``` | 0...7 | STC15A+ | Low-voltage detection threshold. Model specific.
|
||||
```eeprom_lvd_inhibit``` | true/false | STC15A+ | Ignore EEPROM writes in low-voltage situations
|
||||
```rstout_por_state``` | low/high | STC15+ | RSTOUT/RSTSV pin state after power-on reset
|
||||
```uart1_remap``` | true/false | STC8 | Remap UART1 pins (P3.0/P3.1) to UART2 pins (P3.6/P3.7)
|
||||
```uart2_passthrough``` | true/false | STC15+ | Pass-through UART1 to UART2 pins (for single-wire UART mode)
|
||||
```uart2_pin_mode``` | push-pull/normal | STC15+ | Output mode of UART2 TX pin
|
||||
```cpu_core_voltage``` | low/mid/high | STC15W+ | CPU core voltage (low: ~2.7V, mid: ~3.3V, high: ~3.6V)
|
||||
```epwm_open_drain``` | true/false | STC8 | Use open-drain pin mode for EPWM pins after power-on reset
|
||||
```program_eeprom_split``` | 512 - 65024 | STC8A8 w/ 64 KB | Select split between code flash and EEPROM flash (in 512 byte blocks)
|
||||
|
||||
### Frequency trimming
|
||||
|
||||
If the internal RC oscillator is used (```clock_source=internal```),
|
||||
stcgal can execute a trim procedure to adjust it to a given value. This
|
||||
is only supported by STC15 series and newer. The trim values are stored
|
||||
with device options. Use the ```-t``` flag to request trimming to a certain
|
||||
value. Generally, frequencies between 4000 and 30000 kHz can be achieved.
|
||||
If trimming fails, stcgal will abort.
|
||||
|
||||
### Automatic power-cycling
|
||||
|
||||
STC's microcontrollers require a power-on reset to invoke the bootloader,
|
||||
which can be inconvenient. stcgal can use the DTR control signal of a
|
||||
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"
|
||||
```
|
||||
|
||||
### Exit status
|
||||
|
||||
The exit status is 0 if no error occured while executing stcgal. Any
|
||||
error, such as a protocol error or I/O error, results in an exit
|
||||
status of 1. If the the user aborted stcgal by pressing CTRL-C,
|
||||
that results in an exit status of 2.
|
||||
|
||||
### USB support
|
||||
|
||||
STC15W4 series have an USB-based BSL that can be optionally
|
||||
used. USB support in stcgal is experimental and might change in the
|
||||
future. USB mode is enabled by using the ```usb15``` protocol. The
|
||||
port (```-p```) flag as well as the baudrate options are ignored for
|
||||
the USB protocol. RC frequency trimming is not supported.
|
@ -1,13 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
# This curious script dumps all model info from STC-ISP.
|
||||
# Data is directly read from the binary.
|
||||
# Offsets are for stc-isp-15xx-v6.85K.exe, sha1sum aa66e4c1ab49de27369b83c954a7c202acce0950
|
||||
# Offsets are for stc-isp-15xx-v6.86O.exe, sha1sum f70e317d758ef8c942613a8b0540147d7170589b
|
||||
|
||||
MCU_TABLE_OFFSET = 0x00064550
|
||||
MCU_TABLE_SIZE = 941
|
||||
MCU_TABLE_OFFSET = 0x0006ac80
|
||||
MCU_TABLE_SIZE = 984
|
||||
MCU_RECORD_SIZE = 32
|
||||
MCU_NAMES_OFFSET = 0x0007e80c
|
||||
MCU_NAMES_PTR_OFFSET = 0x0047e80c
|
||||
MCU_NAMES_OFFSET = 0x00087810
|
||||
MCU_NAMES_PTR_OFFSET = 0x00487810
|
||||
|
||||
import struct
|
||||
import sys
|
@ -20,7 +20,8 @@ Status packet
|
||||
-------------
|
||||
|
||||
46 B9 68 00 30 50 00 54 62 58 5D 00 04 FF FD 8B BF FF 27 4A F7 FE 73 55 00 F6 28 09 85 E3 5F 80 07 20 20 20 01 00 00 FE 05 3A 17 05 25 91 FF 10 AE 16
|
||||
^^^^^ wakeup clock
|
||||
^^^^^ wakeup clock ^^^^^ reference voltage
|
||||
^^^^^^^^ mfg. date
|
||||
|
||||
Clock set to 20 MHz by STC-ISP (encoding is different compared to STC15):
|
||||
|
7
setup.py
7
setup.py
@ -24,14 +24,14 @@
|
||||
import stcgal
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
with open("doc/PyPI.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
setup(
|
||||
name = "stcgal",
|
||||
version = stcgal.__version__,
|
||||
packages = find_packages(exclude=["doc", "tests"]),
|
||||
install_requires = ["pyserial"],
|
||||
install_requires = ["pyserial>=3.0", "tqdm>=4.0.0"],
|
||||
extras_require = {
|
||||
"usb": ["pyusb>=1.0.0"]
|
||||
},
|
||||
@ -50,7 +50,7 @@ setup(
|
||||
license = "MIT License",
|
||||
platforms = "any",
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Environment :: Console",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
@ -58,7 +58,6 @@ setup(
|
||||
"Operating System :: Microsoft :: Windows",
|
||||
"Operating System :: MacOS",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.4",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Topic :: Software Development :: Embedded Systems",
|
||||
|
@ -1 +1 @@
|
||||
__version__ = "1.4"
|
||||
__version__ = "1.6"
|
||||
|
@ -147,6 +147,10 @@ class StcGal:
|
||||
def run(self):
|
||||
"""Run programmer, main entry point."""
|
||||
|
||||
if self.opts.version:
|
||||
print("stcgal {}".format(stcgal.__version__))
|
||||
return 0
|
||||
|
||||
try:
|
||||
self.protocol.connect(autoreset=self.opts.autoreset, resetcmd=self.opts.resetcmd)
|
||||
if isinstance(self.protocol, StcAutoProtocol):
|
||||
@ -178,6 +182,10 @@ class StcGal:
|
||||
sys.stdout.flush()
|
||||
print("I/O error: %s" % ex, file=sys.stderr)
|
||||
return 1
|
||||
except Exception as ex:
|
||||
sys.stdout.flush()
|
||||
print("Unexpected error: %s" % ex, file=sys.stderr)
|
||||
return 1
|
||||
|
||||
try:
|
||||
if self.opts.code_image:
|
||||
@ -214,19 +222,20 @@ def cli():
|
||||
# check arguments
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="stcgal {} - an STC MCU ISP flash tool\n".format(stcgal.__version__) +
|
||||
"(C) 2014-2017 Grigori Goronzy\nhttps://github.com/grigorig/stcgal")
|
||||
"(C) 2014-2018 Grigori Goronzy and others\nhttps://github.com/grigorig/stcgal")
|
||||
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("-r", "--resetcmd", help="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", "stc8", "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)
|
||||
parser.add_argument("-l", "--handshake", help="handshake baud rate (default: 2400)", type=BaudType(), default=2400)
|
||||
parser.add_argument("-o", "--option", help="set option (can be used multiple times)", action="append")
|
||||
parser.add_argument("-t", "--trim", help="RC oscillator frequency in kHz (STC15 series only)", type=float, default=0.0)
|
||||
parser.add_argument("-o", "--option", help="set option (can be used multiple times, see documentation)", action="append")
|
||||
parser.add_argument("-t", "--trim", help="RC oscillator frequency in kHz (STC15+ series only)", type=float, default=0.0)
|
||||
parser.add_argument("-D", "--debug", help="enable debug output", action="store_true")
|
||||
parser.add_argument("-V", "--version", help="print version info and exit", action="store_true")
|
||||
opts = parser.parse_args()
|
||||
|
||||
# run programmer
|
||||
|
@ -32,14 +32,26 @@ class MCUModelDatabase:
|
||||
MCUModel = collections.namedtuple("MCUModel", ["name", "magic", "total", "code", "eeprom"])
|
||||
|
||||
models = (
|
||||
MCUModel(name='STC8F8K08S4A10', magic=0xf611, total=65536, code=8192, eeprom=57344),
|
||||
MCUModel(name='STC8F8K16S4A10', magic=0xf612, total=65536, code=16384, eeprom=49152),
|
||||
MCUModel(name='STC8F8K24S4A10', magic=0xf613, total=65536, code=24576, eeprom=40960),
|
||||
MCUModel(name='STC8F8K32S4A10', magic=0xf614, total=65536, code=32768, eeprom=32768),
|
||||
MCUModel(name='STC8F8K40S4A10', magic=0xf615, total=65536, code=40960, eeprom=24576),
|
||||
MCUModel(name='STC8F8K48S4A10', magic=0xf616, total=65536, code=49152, eeprom=16384),
|
||||
MCUModel(name='STC8F8K56S4A10', magic=0xf617, total=65536, code=57344, eeprom=8192),
|
||||
MCUModel(name='STC8F8K64S4A10', magic=0xf618, total=65536, code=65024, eeprom=512),
|
||||
MCUModel(name='STC8F1K02S2', magic=0xf661, total=20480, code=2048, eeprom=10240),
|
||||
MCUModel(name='STC8F1K04S2', magic=0xf662, total=20480, code=4096, eeprom=8192),
|
||||
MCUModel(name='STC8F1K06S2', magic=0xf663, total=20480, code=6144, eeprom=6144),
|
||||
MCUModel(name='STC8F1K08S2', magic=0xf664, total=20480, code=8192, eeprom=4096),
|
||||
MCUModel(name='STC8F1K10S2', magic=0xf665, total=20480, code=10240, eeprom=2048),
|
||||
MCUModel(name='STC8F1K12S2', magic=0xf666, total=20480, code=12288, eeprom=0),
|
||||
MCUModel(name='STC8F1K17S2', magic=0xf667, total=20480, code=17408, eeprom=0),
|
||||
MCUModel(name='STC8F1K02', magic=0xf671, total=20480, code=2048, eeprom=10240),
|
||||
MCUModel(name='STC8F1K04', magic=0xf672, total=20480, code=4096, eeprom=8192),
|
||||
MCUModel(name='STC8F1K06', magic=0xf673, total=20480, code=6144, eeprom=6144),
|
||||
MCUModel(name='STC8F1K08', magic=0xf674, total=20480, code=8192, eeprom=4096),
|
||||
MCUModel(name='STC8F1K10', magic=0xf675, total=20480, code=10240, eeprom=2048),
|
||||
MCUModel(name='STC8F1K12', magic=0xf676, total=20480, code=12288, eeprom=0),
|
||||
MCUModel(name='STC8F1K17', magic=0xf677, total=20480, code=17408, eeprom=0),
|
||||
MCUModel(name='STC15U4K16S4', magic=0xf580, total=65536, code=16384, eeprom=44032),
|
||||
MCUModel(name='STC15U4K24S4', magic=0xf581, total=65536, code=24576, eeprom=35840),
|
||||
MCUModel(name='STC15U4K32S4', magic=0xf582, total=65536, code=32768, eeprom=27648),
|
||||
MCUModel(name='STC15U4K40S4', magic=0xf583, total=65536, code=40960, eeprom=19456),
|
||||
MCUModel(name='STC15U4K48S4', magic=0xf584, total=65536, code=49152, eeprom=11264),
|
||||
MCUModel(name='STC15U4K56S4', magic=0xf585, total=65536, code=57344, eeprom=3072),
|
||||
MCUModel(name='STC8A8K08S4A12', magic=0xf621, total=65536, code=8192, eeprom=57344),
|
||||
MCUModel(name='STC8A8K16S4A12', magic=0xf622, total=65536, code=16384, eeprom=49152),
|
||||
MCUModel(name='STC8A8K24S4A12', magic=0xf623, total=65536, code=24576, eeprom=40960),
|
||||
@ -47,7 +59,26 @@ class MCUModelDatabase:
|
||||
MCUModel(name='STC8A8K40S4A12', magic=0xf625, total=65536, code=40960, eeprom=24576),
|
||||
MCUModel(name='STC8A8K48S4A12', magic=0xf626, total=65536, code=49152, eeprom=16384),
|
||||
MCUModel(name='STC8A8K56S4A12', magic=0xf627, total=65536, code=57344, eeprom=8192),
|
||||
MCUModel(name='STC8A8K60S4A12', magic=0xf629, total=65536, code=61440, eeprom=4096),
|
||||
MCUModel(name='STC8A8K64S4A12', magic=0xf628, total=65536, code=65024, eeprom=512),
|
||||
MCUModel(name='STC8A4K08S2A12', magic=0xf651, total=65536, code=8192, eeprom=57344),
|
||||
MCUModel(name='STC8A4K16S2A12', magic=0xf652, total=65536, code=16384, eeprom=49152),
|
||||
MCUModel(name='STC8A4K24S2A12', magic=0xf653, total=65536, code=24576, eeprom=40960),
|
||||
MCUModel(name='STC8A4K32S2A12', magic=0xf654, total=65536, code=32768, eeprom=32768),
|
||||
MCUModel(name='STC8A4K40S2A12', magic=0xf655, total=65536, code=40960, eeprom=24576),
|
||||
MCUModel(name='STC8A4K48S2A12', magic=0xf656, total=65536, code=49152, eeprom=16384),
|
||||
MCUModel(name='STC8A4K56S2A12', magic=0xf657, total=65536, code=57344, eeprom=8192),
|
||||
MCUModel(name='STC8A4K60S2A12', magic=0xf659, total=65536, code=61440, eeprom=4096),
|
||||
MCUModel(name='STC8A4K64S2A12', magic=0xf658, total=65536, code=65024, eeprom=512),
|
||||
MCUModel(name='STC8F8K08S4A12', magic=0xf611, total=65536, code=8192, eeprom=57344),
|
||||
MCUModel(name='STC8F8K16S4A12', magic=0xf612, total=65536, code=16384, eeprom=49152),
|
||||
MCUModel(name='STC8F8K24S4A12', magic=0xf613, total=65536, code=24576, eeprom=40960),
|
||||
MCUModel(name='STC8F8K32S4A12', magic=0xf614, total=65536, code=32768, eeprom=32768),
|
||||
MCUModel(name='STC8F8K40S4A12', magic=0xf615, total=65536, code=40960, eeprom=24576),
|
||||
MCUModel(name='STC8F8K48S4A12', magic=0xf616, total=65536, code=49152, eeprom=16384),
|
||||
MCUModel(name='STC8F8K56S4A12', magic=0xf617, total=65536, code=57344, eeprom=8192),
|
||||
MCUModel(name='STC8F8K60S4A12', magic=0xf619, total=65536, code=61440, eeprom=4096),
|
||||
MCUModel(name='STC8F8K64S4A12', magic=0xf618, total=65536, code=65024, eeprom=512),
|
||||
MCUModel(name='STC8F2K08S4', magic=0xf631, total=65536, code=8192, eeprom=57344),
|
||||
MCUModel(name='STC8F2K16S4', magic=0xf632, total=65536, code=16384, eeprom=49152),
|
||||
MCUModel(name='STC8F2K24S4', magic=0xf633, total=65536, code=24576, eeprom=40960),
|
||||
@ -55,7 +86,17 @@ class MCUModelDatabase:
|
||||
MCUModel(name='STC8F2K40S4', magic=0xf635, total=65536, code=40960, eeprom=24576),
|
||||
MCUModel(name='STC8F2K48S4', magic=0xf636, total=65536, code=49152, eeprom=16384),
|
||||
MCUModel(name='STC8F2K56S4', magic=0xf637, total=65536, code=57344, eeprom=8192),
|
||||
MCUModel(name='STC8F2K60S4', magic=0xf639, total=65536, code=61440, eeprom=4096),
|
||||
MCUModel(name='STC8F2K64S4', magic=0xf638, total=65536, code=65024, eeprom=512),
|
||||
MCUModel(name='STC8F2K08S2', magic=0xf641, total=65536, code=8192, eeprom=57344),
|
||||
MCUModel(name='STC8F2K16S2', magic=0xf642, total=65536, code=16384, eeprom=49152),
|
||||
MCUModel(name='STC8F2K24S2', magic=0xf643, total=65536, code=24576, eeprom=40960),
|
||||
MCUModel(name='STC8F2K32S2', magic=0xf644, total=65536, code=32768, eeprom=32768),
|
||||
MCUModel(name='STC8F2K40S2', magic=0xf645, total=65536, code=40960, eeprom=24576),
|
||||
MCUModel(name='STC8F2K48S2', magic=0xf646, total=65536, code=49152, eeprom=16384),
|
||||
MCUModel(name='STC8F2K56S2', magic=0xf647, total=65536, code=57344, eeprom=8192),
|
||||
MCUModel(name='STC8F2K60S2', magic=0xf649, total=65536, code=61440, eeprom=4096),
|
||||
MCUModel(name='STC8F2K64S2', magic=0xf648, total=65536, code=65024, eeprom=512),
|
||||
MCUModel(name='STC15H4K08S4', magic=0xf601, total=65536, code=8192, eeprom=57344),
|
||||
MCUModel(name='STC15H4K16S4', magic=0xf602, total=65536, code=16384, eeprom=49152),
|
||||
MCUModel(name='STC15H4K24S4', magic=0xf603, total=65536, code=24576, eeprom=40960),
|
||||
@ -222,6 +263,7 @@ class MCUModelDatabase:
|
||||
MCUModel(name='STC15W412S', magic=0xf51c, total=16384, code=12288, eeprom=1024),
|
||||
MCUModel(name='IAP15W413S', magic=0xf55d, total=16384, code=13312, eeprom=0),
|
||||
MCUModel(name='IRC15W415S', magic=0xf55e, total=16384, code=15872, eeprom=0),
|
||||
MCUModel(name='JX15W415S', magic=0xf55f, total=16384, code=15872, eeprom=0),
|
||||
MCUModel(name='STC15W401AS', magic=0xf52a, total=16384, code=1024, eeprom=12288),
|
||||
MCUModel(name='STC15W402AS', magic=0xf52b, total=16384, code=2048, eeprom=11264),
|
||||
MCUModel(name='STC15W404AS', magic=0xf51e, total=16384, code=4096, eeprom=9216),
|
||||
@ -247,6 +289,7 @@ class MCUModelDatabase:
|
||||
MCUModel(name='STC15W4K48S4', magic=0xf527, total=65536, code=49152, eeprom=11264),
|
||||
MCUModel(name='STC15W4K56S4', magic=0xf528, total=65536, code=57344, eeprom=3072),
|
||||
MCUModel(name='IAP15W4K58S4', magic=0xf569, total=65536, code=59392, eeprom=0),
|
||||
MCUModel(name='IAP15W4K58S4-Stu', magic=0xf56d, total=65536, code=59392, eeprom=0),
|
||||
MCUModel(name='IAP15W4K61S4', magic=0xf56a, total=65536, code=62464, eeprom=0),
|
||||
MCUModel(name='IRC15W4K63S4', magic=0xf56b, total=65536, code=65024, eeprom=0),
|
||||
MCUModel(name='U8W', magic=0xf56c, total=65536, code=62464, eeprom=0),
|
||||
@ -975,6 +1018,7 @@ class MCUModelDatabase:
|
||||
MCUModel(name='STC90LE516AD', magic=0xf190, total=65536, code=63488, eeprom=0),
|
||||
|
||||
# Warning, these definitions lack a valid eeprom size.
|
||||
# XXX: It's unknown whether these actually exist, they were removed in STC-ISP.
|
||||
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),
|
||||
|
@ -1554,6 +1554,8 @@ class Stc8Protocol(Stc15Protocol):
|
||||
def __init__(self, port, handshake, baud, trim):
|
||||
Stc15Protocol.__init__(self, port, handshake, baud, trim)
|
||||
self.trim_divider = None
|
||||
self.reference_voltage = None
|
||||
self.mfg_date = ()
|
||||
|
||||
def initialize_options(self, status_packet):
|
||||
"""Initialize options"""
|
||||
@ -1567,19 +1569,24 @@ class Stc8Protocol(Stc15Protocol):
|
||||
def initialize_status(self, packet):
|
||||
"""Decode status packet and store basic MCU info"""
|
||||
|
||||
if len(packet) < 39:
|
||||
raise StcProtocolException("invalid status packet")
|
||||
|
||||
self.mcu_clock_hz, = struct.unpack(">I", packet[1:5])
|
||||
# XXX: external clock not supported nor tested
|
||||
self.external_clock = False
|
||||
# all ones means no calibration
|
||||
# new chips are shipped without any calibration
|
||||
# XXX: somehow check if that still holds
|
||||
if self.mcu_clock_hz == 0xffffffff: self.mcu_clock_hz = 0
|
||||
|
||||
# pre-calibrated trim adjust for 24 MHz, range 0x40
|
||||
self.freq_count_24 = packet[4]
|
||||
|
||||
# wakeup timer factory value
|
||||
self.wakeup_freq, = struct.unpack(">H", packet[23:25])
|
||||
self.reference_voltage, = struct.unpack(">H", packet[35:37])
|
||||
self.mfg_date = (
|
||||
2000 + Utils.decode_packed_bcd(packet[37]),
|
||||
Utils.decode_packed_bcd(packet[38]),
|
||||
Utils.decode_packed_bcd(packet[39])
|
||||
)
|
||||
|
||||
bl_version, bl_stepping = struct.unpack("BB", packet[17:19])
|
||||
bl_minor = packet[22] & 0x0f
|
||||
@ -1587,6 +1594,12 @@ class Stc8Protocol(Stc15Protocol):
|
||||
bl_minor, chr(bl_stepping))
|
||||
self.bsl_version = bl_version
|
||||
|
||||
def print_mcu_info(self):
|
||||
"""Print additional STC8 info"""
|
||||
super().print_mcu_info()
|
||||
print("Target ref. voltage: %d mV" % self.reference_voltage)
|
||||
print("Target mfg. date: %04d-%02d-%02d" % self.mfg_date)
|
||||
|
||||
def calibrate(self):
|
||||
"""Calibrate selected user frequency frequency and switch to selected baudrate."""
|
||||
|
||||
@ -1600,8 +1613,6 @@ class Stc8Protocol(Stc15Protocol):
|
||||
target_user_count = round(user_speed / (self.baud_handshake/2))
|
||||
|
||||
# calibration, round 1
|
||||
# XXX: challenges need work. the ranges and how they related to clock frequency
|
||||
# is different. A clock divider is used for lower frequencies.
|
||||
print("Trimming frequency: ", end="")
|
||||
sys.stdout.flush()
|
||||
packet = bytes([0x00])
|
||||
@ -1653,7 +1664,7 @@ class Stc8Protocol(Stc15Protocol):
|
||||
sys.stdout.flush()
|
||||
packet = bytes([0x01, 0x00, 0x00])
|
||||
bauds = self.baud_transfer * 4
|
||||
packet += struct.pack(">H", int(65535 - 24E6 / bauds))
|
||||
packet += struct.pack(">H", round(65535 - 24E6 / bauds))
|
||||
packet += bytes([user_trim[1], user_trim[0]])
|
||||
iap_wait = self.get_iap_delay(24E6)
|
||||
packet += bytes([iap_wait])
|
||||
|
@ -52,6 +52,11 @@ class Utils:
|
||||
|
||||
return sep.join(["%02X" % x for x in bytes(bytestr)])
|
||||
|
||||
@classmethod
|
||||
def decode_packed_bcd(cls, byt):
|
||||
"""Decode two-digit packed BCD value"""
|
||||
return (byt & 0x0f) + (10 * (byt >> 4))
|
||||
|
||||
|
||||
class BaudType:
|
||||
"""Check baud rate for validity"""
|
||||
|
20
tests/stc8a8k64s4a12.yml
Normal file
20
tests/stc8a8k64s4a12.yml
Normal file
@ -0,0 +1,20 @@
|
||||
name: STC8A8K64S4A12 programming test
|
||||
protocol: stc8
|
||||
code_data: [49, 50, 51, 52, 53, 54, 55, 56, 57]
|
||||
responses:
|
||||
- [0x50, 0x01, 0x6E, 0x0B, 0xD0, 0x78, 0x00, 0x01, 0xFF, 0xFF, 0x8B, 0xBF, 0xFF, 0x28, 0x43, 0xF7, 0xFE, 0x73, 0x55, 0x00, 0xF6, 0x28, 0x09, 0x85, 0xE3, 0x5F, 0x80, 0x07, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0xFE, 0x05, 0x3A, 0x17, 0x05, 0x25, 0x91, 0xFF]
|
||||
- [0x00, 0x0C, 0x37, 0x49, 0x3B, 0x8D, 0x3F, 0xE0, 0x44, 0x57, 0x48, 0x9E, 0x4D, 0x06, 0x51, 0x35, 0x55, 0x94, 0x59, 0xCF, 0x5D, 0xDA, 0x62, 0x3C, 0x66, 0xDA]
|
||||
- [0x00, 0x0C, 0x51, 0x59, 0x51, 0x8C, 0x51, 0xB3, 0x51, 0x71, 0x51, 0x9B, 0x51, 0xC2, 0x51, 0x77, 0x51, 0xAA, 0x51, 0xC8, 0x51, 0x62, 0x51, 0x89, 0x51, 0xB0]
|
||||
- [0x01]
|
||||
- [0x05]
|
||||
- [0x03, 0xF6, 0x28, 0x02, 0xBC, 0x26, 0x98, 0xDF]
|
||||
- [0x02, 0x54]
|
||||
- [0x02, 0x54]
|
||||
- [0x02, 0x54]
|
||||
- [0x02, 0x54]
|
||||
- [0x02, 0x54]
|
||||
- [0x02, 0x54]
|
||||
- [0x02, 0x54]
|
||||
- [0x02, 0x54]
|
||||
- [0x07, 0x54]
|
||||
- [0x04, 0x54]
|
5
tests/stc8f2k08s2-untrimmed.yml
Normal file
5
tests/stc8f2k08s2-untrimmed.yml
Normal file
@ -0,0 +1,5 @@
|
||||
name: STC8F2K08S2 untrimmed programming test
|
||||
protocol: stc8
|
||||
code_data: [49, 50, 51, 52, 53, 54, 55, 56, 57]
|
||||
responses:
|
||||
- [0x50, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x00, 0x04, 0xFF, 0xFF, 0x8B, 0xFD, 0xFF, 0x27, 0x38, 0xF5, 0x73, 0x73, 0x55, 0x00, 0xF6, 0x41, 0x0A, 0x88, 0x86, 0x6F, 0x8F, 0x08, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0x20, 0x05, 0x3C, 0x18, 0x05, 0x22, 0x32, 0xFF]
|
@ -85,6 +85,7 @@ class TestProgramFuzzed(unittest.TestCase):
|
||||
"./tests/stc89c52rc.yml",
|
||||
"./tests/stc15l104w.yml",
|
||||
"./tests/stc15f104e.yml",
|
||||
"./tests/stc8a8k64s4a12.yml",
|
||||
]
|
||||
fuzzer = ByteArrayFuzzer()
|
||||
fuzzer.cut_propability = 0.01
|
||||
|
@ -27,6 +27,7 @@ from unittest.mock import patch
|
||||
import yaml
|
||||
import stcgal.frontend
|
||||
import stcgal.protocols
|
||||
from stcgal.protocols import StcProtocolException
|
||||
|
||||
def convert_to_bytes(list_of_lists):
|
||||
"""Convert lists of integer lists to list of byte lists"""
|
||||
@ -43,6 +44,7 @@ def get_default_opts():
|
||||
opts.trim = 22118
|
||||
opts.eeprom_image = None
|
||||
opts.debug = False
|
||||
opts.version = False
|
||||
opts.code_image.name = "test.bin"
|
||||
opts.code_image.read.return_value = b"123456789"
|
||||
return opts
|
||||
@ -99,6 +101,15 @@ class ProgramTests(unittest.TestCase):
|
||||
"""Test a programming cycle with STC15 protocol, W4 series"""
|
||||
self._program_yml("./tests/stc15w4k56s4.yml", serial_mock, read_mock)
|
||||
|
||||
@patch("stcgal.protocols.StcBaseProtocol.read_packet")
|
||||
@patch("stcgal.protocols.Stc89Protocol.write_packet")
|
||||
@patch("stcgal.protocols.serial.Serial", autospec=True)
|
||||
@patch("stcgal.protocols.time.sleep")
|
||||
@patch("sys.stdout")
|
||||
def test_program_stc8a8(self, out, sleep_mock, serial_mock, write_mock, read_mock):
|
||||
"""Test a programming cycle with STC8 protocol, STC8A8 series"""
|
||||
self._program_yml("./tests/stc8a8k64s4a12.yml", serial_mock, read_mock)
|
||||
|
||||
@unittest.skip("trace is broken")
|
||||
@patch("stcgal.protocols.StcBaseProtocol.read_packet")
|
||||
@patch("stcgal.protocols.Stc89Protocol.write_packet")
|
||||
@ -118,6 +129,24 @@ class ProgramTests(unittest.TestCase):
|
||||
"""Test a programming cycle with STC15 protocol, L1 series"""
|
||||
self._program_yml("./tests/stc15l104w.yml", serial_mock, read_mock)
|
||||
|
||||
@patch("stcgal.protocols.StcBaseProtocol.read_packet")
|
||||
@patch("stcgal.protocols.Stc89Protocol.write_packet")
|
||||
@patch("stcgal.protocols.serial.Serial", autospec=True)
|
||||
@patch("stcgal.protocols.time.sleep")
|
||||
@patch("sys.stdout")
|
||||
def test_program_stc8_untrimmed(self, out, sleep_mock, serial_mock, write_mock, read_mock):
|
||||
"""Test error with untrimmed MCU"""
|
||||
with open("./tests/stc8f2k08s2-untrimmed.yml") as test_file:
|
||||
test_data = yaml.load(test_file.read(), Loader=yaml.SafeLoader)
|
||||
opts = get_default_opts()
|
||||
opts.trim = 0.0
|
||||
opts.protocol = test_data["protocol"]
|
||||
opts.code_image.read.return_value = bytes(test_data["code_data"])
|
||||
serial_mock.return_value.inWaiting.return_value = 1
|
||||
read_mock.side_effect = convert_to_bytes(test_data["responses"])
|
||||
gal = stcgal.frontend.StcGal(opts)
|
||||
self.assertEqual(gal.run(), 1)
|
||||
|
||||
def test_program_stc15w4_usb(self):
|
||||
"""Test a programming cycle with STC15W4 USB protocol"""
|
||||
self.skipTest("USB not supported yet, trace missing")
|
||||
@ -125,7 +154,7 @@ class ProgramTests(unittest.TestCase):
|
||||
def _program_yml(self, yml, serial_mock, read_mock):
|
||||
"""Program MCU with data from YAML file"""
|
||||
with open(yml) as test_file:
|
||||
test_data = yaml.load(test_file.read())
|
||||
test_data = yaml.load(test_file.read(), Loader=yaml.SafeLoader)
|
||||
opts = get_default_opts()
|
||||
opts.protocol = test_data["protocol"]
|
||||
opts.code_image.read.return_value = bytes(test_data["code_data"])
|
||||
|
@ -64,6 +64,14 @@ class TestUtils(unittest.TestCase):
|
||||
with self.assertRaises(Exception):
|
||||
Utils.hexstr([400, 500])
|
||||
|
||||
def test_decode_packed_bcd(self):
|
||||
"""Test packed BCD decoder"""
|
||||
self.assertEqual(Utils.decode_packed_bcd(0x01), 1)
|
||||
self.assertEqual(Utils.decode_packed_bcd(0x10), 10)
|
||||
self.assertEqual(Utils.decode_packed_bcd(0x11), 11)
|
||||
self.assertEqual(Utils.decode_packed_bcd(0x25), 25)
|
||||
self.assertEqual(Utils.decode_packed_bcd(0x99), 99)
|
||||
|
||||
class TestBaudType(unittest.TestCase):
|
||||
"""Test BaudType class"""
|
||||
|
||||
|
Reference in New Issue
Block a user