Compare commits
46 Commits
v1.5
...
fix-stc15f
Author | SHA1 | Date | |
---|---|---|---|
9202399a84 | |||
3cf2cb38e7 | |||
384471f765 | |||
df2fbc23cd | |||
77df068efd | |||
2fb96d6236 | |||
c2fd3ab710 | |||
0d5e8e645f | |||
1ec855e6a1 | |||
d708a00e9e | |||
5c2950f084 | |||
c5d509d1fa | |||
0e020f2aa4 | |||
b46d81a184 | |||
ad5a532ab9 | |||
b3741af045 | |||
1e78d62f5d | |||
d0597578de | |||
eaeab65044 | |||
a19fc406a3 | |||
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 |
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 }}
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -10,3 +10,6 @@ __pycache__/
|
||||
/debian/stcgal*
|
||||
/debian/files
|
||||
/.vscode
|
||||
.coverage
|
||||
coverage.xml
|
||||
htmlcov/
|
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 pyusb
|
||||
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"
|
15
README.md
15
README.md
@ -1,4 +1,6 @@
|
||||
[](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
|
||||
===============================
|
||||
@ -32,6 +34,17 @@ Features
|
||||
* Automatic power-cycling with DTR toggle or a custom shell command
|
||||
* Automatic UART protocol detection
|
||||
|
||||
Quickstart
|
||||
----------
|
||||
|
||||
Install stcgal (might need root/administrator privileges):
|
||||
|
||||
pip3 install stcgal
|
||||
|
||||
Call stcgal and show usage:
|
||||
|
||||
stcgal -h
|
||||
|
||||
Further information
|
||||
-------------------
|
||||
|
||||
|
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
|
||||
|
15
doc/FAQ.md
15
doc/FAQ.md
@ -3,11 +3,13 @@ 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.
|
||||
By design, it is not possible to read back code flash memory 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.
|
||||
|
||||
On some STC MCUs, you can erase code flash memory without erasing EEPROM. That means you can create a program to dump the EEPROM. stcgal does not have any native support to do that at this time.
|
||||
|
||||
### Which serial interfaces have been tested with stcgal?
|
||||
|
||||
The following USB-based UART interface chips have been successfully 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)
|
||||
@ -20,13 +22,18 @@ Interfaces that are known to not work:
|
||||
|
||||
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.
|
||||
* Serial interface compatibility issues with protocol autodetection (for instance with some fake FTDI USB UART chips). Try to explicitly provide the protocol variant with the option ```-P```.
|
||||
* Other 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?
|
||||
|
||||
@ -40,7 +47,7 @@ Various remedies are possible to avoid parasitic powering.
|
||||
|
||||
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
|
||||
### 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.
|
||||
|
||||
|
@ -1,16 +1,15 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
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 if the dependencies
|
||||
are already installed.
|
||||
stcgal requires Python 3.5 (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 git+https://github.com/grigorig/stcgal.git```
|
||||
to install the latest version of stcgal globally on your system.
|
||||
* 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.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
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.
|
||||
stcgal should fully support STC 89/90/10/11/12/15/8 series MCUs.
|
||||
|
||||
So far, stcgal was tested with the following MCU models:
|
||||
|
||||
@ -20,7 +20,7 @@ So far, stcgal was tested with the following MCU models:
|
||||
* STC15F104E (BSL version: 6.7Q)
|
||||
* STC15F204EA (BSL version: 6.7R)
|
||||
* STC15L104W (BSL version: 7.1.4Q)
|
||||
* STC15F104W (BSL version: 7.1.4Q)
|
||||
* STC15F104W (BSL version: 7.1.4Q and 7.2.5Q)
|
||||
* IAP15F2K61S2 (BSL version: 7.1.4S)
|
||||
* STC15L2K16S2 (BSL version: 7.2.4S)
|
||||
* IAP15L2K61S2 (BSL version: 7.2.5S)
|
||||
|
36
doc/USAGE.md
36
doc/USAGE.md
@ -4,12 +4,14 @@ Usage
|
||||
Call stcgal with ```-h``` for usage information.
|
||||
|
||||
```
|
||||
usage: stcgal.py [-h] [-a] [-P {stc89,stc12a,stc12,stc15a,stc15,auto}]
|
||||
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.0 - an STC MCU ISP flash tool
|
||||
(C) 2014-2015 Grigori Goronzy
|
||||
stcgal 1.5 - an STC MCU ISP flash tool
|
||||
(C) 2014-2018 Grigori Goronzy and others
|
||||
https://github.com/grigorig/stcgal
|
||||
|
||||
positional arguments:
|
||||
@ -20,18 +22,20 @@ 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
|
||||
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)
|
||||
-t TRIM, --trim TRIM RC oscillator frequency in kHz (STC15 series only)
|
||||
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.
|
||||
@ -43,6 +47,7 @@ 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
|
||||
@ -51,11 +56,10 @@ and MCU series is as follows:
|
||||
* ```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.
|
||||
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
|
||||
|
||||
@ -92,6 +96,8 @@ Target options:
|
||||
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
|
||||
@ -195,8 +201,8 @@ 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.
|
||||
value. Generally, frequencies between 4000 and 30000 kHz can be achieved.
|
||||
If trimming fails, stcgal will abort.
|
||||
|
||||
### Automatic power-cycling
|
||||
|
||||
|
57
doc/reverse-engineering/mcudb_flags.txt
Normal file
57
doc/reverse-engineering/mcudb_flags.txt
Normal file
@ -0,0 +1,57 @@
|
||||
STC15F103
|
||||
00064F50 63 C3 08 00 2C FC 47 00 9B F2 00 00 00 0C 00 00 c...,.G.........
|
||||
00064F60 00 08 00 00 00 00 00 00 00 20 00 00 07 03 00 00 ......... ......
|
||||
|
||||
STC15L103
|
||||
00065110 61 C3 08 00 90 FB 47 00 DB F2 00 00 00 0C 00 00 a.....G.........
|
||||
00065120 00 08 00 00 00 00 00 00 00 20 00 00 07 03 00 00 ......... ......
|
||||
|
||||
STC15F104E
|
||||
00065190 E3 02 08 00 AC B1 47 00 94 F2 00 00 00 10 00 00 ......G.........
|
||||
000651A0 00 04 00 00 00 00 00 00 00 20 00 00 07 00 00 00 ......... ......
|
||||
|
||||
STC15L104W
|
||||
X Y Z
|
||||
00065050 E1 C3 08 00 B8 B1 47 00 D4 F2 00 00 00 10 00 00 ......G.........
|
||||
00065060 00 04 00 00 00 00 00 00 00 20 00 00 07 03 00 00 ......... ......
|
||||
|
||||
STC15L104E
|
||||
000651B0 E1 02 08 00 94 B1 47 00 D4 F2 00 00 00 10 00 00 ......G.........
|
||||
000651C0 00 04 00 00 00 00 00 00 00 20 00 00 07 00 00 00 ......... ......
|
||||
|
||||
|
||||
byte X bit 1: F vs L? low => L part, high => F part
|
||||
byte Z: protocol/model generation number?
|
||||
|
||||
IAP15F2K61S2
|
||||
00063750 AF 0B 09 00 08 06 48 00 49 F4 00 00 00 F4 00 00 ......H.I.......
|
||||
00063760 00 00 00 00 00 00 00 00 00 00 01 00 07 00 00 00 ................
|
||||
|
||||
STC15F2K08S2
|
||||
00063650 A3 0B 09 00 78 06 48 00 01 F4 00 00 00 20 00 00 ....x.H...... ..
|
||||
00063660 00 D4 00 00 00 00 00 00 00 00 01 00 07 00 00 00 ................
|
||||
|
||||
STC15F2K32S2
|
||||
000636B0 A3 0B 09 00 48 06 48 00 04 F4 00 00 00 80 00 00 ....H.H.........
|
||||
000636C0 00 74 00 00 00 00 00 00 00 00 01 00 07 00 00 00 .t..............
|
||||
|
||||
STC15F2K60S2
|
||||
00063730 A3 0B 09 00 64 B2 47 00 08 F4 00 00 00 F0 00 00 ....d.G.........
|
||||
00063740 00 04 00 00 00 00 00 00 00 00 01 00 07 00 00 00 ................
|
||||
|
||||
IRC15F2K63S2
|
||||
00063770 BF 0C 09 00 F8 05 48 00 4A F4 00 00 00 FE 00 00 ......H.J.......
|
||||
00063780 00 00 00 00 00 00 00 00 00 00 01 00 07 00 00 00 ................
|
||||
|
||||
IRC15F1K63S
|
||||
00064470 BE 8C 09 00 20 00 48 00 20 F4 00 00 00 FE 00 00 .... .H. .......
|
||||
00064480 00 00 00 00 00 00 00 00 00 00 01 00 07 00 00 00 ................
|
||||
|
||||
IRC15W207S
|
||||
000648B0 B7 CC 0A 00 AC FE 47 00 56 F5 00 00 00 1E 00 00 ......G.V.......
|
||||
000648C0 00 00 00 00 00 00 00 00 00 20 00 00 07 00 00 00 ......... ......
|
||||
|
||||
STC15H4K56S4
|
||||
00063610 AF 8B 0E 00 98 06 48 00 07 F6 00 00 00 E0 00 00 ......H.........
|
||||
00063620 00 00 00 00 00 00 00 00 00 00 01 00 07 00 00 00 ................
|
||||
|
108
doc/reverse-engineering/stc15w4.txt
Normal file
108
doc/reverse-engineering/stc15w4.txt
Normal file
@ -0,0 +1,108 @@
|
||||
fresh chip, RC frequency untuned, caught with stcgal
|
||||
|
||||
2015-12-10 23:39:46.886233: PC
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F
|
||||
2015-12-10 23:39:50.989044: MCU
|
||||
46 B9 68 00 34 50 8D FF 73 96 F5 7B 9F FF FF FF
|
||||
FF FF 25 EF 00 00 73 54 00 F5 28 04 06 70 96 02
|
||||
15 19 1C 1E 23 00 EC E0 04 D7 F8 73 BF FF FF 15
|
||||
09 25 60 16 92 16
|
||||
2015-12-10 23:39:51.231028: PC
|
||||
46 B9 6A 00 07 82 00 F3 16
|
||||
|
||||
Checking target MCU ...
|
||||
MCU type: STC15W4K56S4
|
||||
F/W version: 7.3.4T
|
||||
|
||||
Current H/W Option:
|
||||
. Current system clock source is internal IRC oscillator
|
||||
. IRC is unadjusted
|
||||
. Oscillator gain is HIGH
|
||||
. Wakeup Timer frequency: 36.351KHz
|
||||
. Do not detect the level of P3.2 and P3.3 next download
|
||||
. Power-on reset, use the extra power-on delay
|
||||
. RESET pin behaves as I/O pin
|
||||
. Interrupt while detect a Low-Voltage
|
||||
. Thresh voltage level of the built-in LVD : 2.78 V
|
||||
. Permit EEPROM operation under Low-Voltag
|
||||
. CPU-Core supply level : 3.38 V
|
||||
. Hardware do not enable Watch-Dog-Timer
|
||||
. Watch-Dog-Timer pre-scalar : 64
|
||||
. Watch-Dog-Timer stop count in idle mode
|
||||
. Program can modify the Watch-Dog-Timer scalar
|
||||
. Erase user EEPROM area at next download
|
||||
. Do not control 485 at next download
|
||||
. Do not check user password next download
|
||||
. TXD is independent IO
|
||||
. TXD pin as quasi-bidirectional mode after reset
|
||||
. P2.0 output HIGH level after reset
|
||||
|
||||
. MCU type: STC15W4K56S4
|
||||
F/W version: 7.3.4T
|
||||
|
||||
Complete !
|
||||
|
||||
Waiting for MCU, please cycle power: done
|
||||
Target model:
|
||||
Name: STC15W4K56S4
|
||||
Magic: F528
|
||||
Code flash: 56.0 KB
|
||||
EEPROM flash: 3.0 KB
|
||||
Target frequency: 0.000 MHz
|
||||
Target BSL version: 7.3.4T
|
||||
Target wakeup frequency: 36.351 KHz
|
||||
Target options:
|
||||
reset_pin_enabled=False
|
||||
clock_source=internal
|
||||
clock_gain=high
|
||||
watchdog_por_enabled=False
|
||||
watchdog_stop_idle=True
|
||||
watchdog_prescale=64
|
||||
low_voltage_reset=False
|
||||
low_voltage_threshold=3
|
||||
eeprom_lvd_inhibit=False
|
||||
eeprom_erase_enabled=True
|
||||
bsl_pindetect_enabled=False
|
||||
por_reset_delay=long
|
||||
rstout_por_state=high
|
||||
uart2_passthrough=False
|
||||
uart2_pin_mode=normal
|
||||
Disconnected!
|
||||
|
||||
|
||||
cpu core supply level
|
||||
|
||||
2.68v
|
||||
46 B9 68 00 34 50 8D FF 73 96 F7 BC 9F 00 5B 7A C0 FD 27 ED 00 00 73 54 00 F5 28 04 06 70 96 02 15 19 1C 1E 23 00 EC E0 04 D7 EA 92 FF FF FF 15 09 25 60 14 BD 16
|
||||
|
||||
3.33v
|
||||
46 B9 68 00 34 50 8D FF 73 96 F7 BC 9F 00 5B 92 30 FD 25 EA 00 FC 73 54 00 F5 28 04 06 70 96 02 15 19 1C 1E 23 00 EC E0 04 D7 F7 92 FF FF FF 15 09 25 60 15 49 16
|
||||
|
||||
3.63v
|
||||
46 B9 68 00 34 50 8D FF 73 96 F7 BC 9F 00 5B 7A C0 FD 25 EF 00 00 73 54 00 F5 28 04 06 70 96 02 15 19 1C 1E 23 00 EC E0 04 D7 FD 92 FF FF FF 15 09 25 60 14 D0 16
|
||||
|
||||
3.73v
|
||||
46 B9 68 00 34 50 8D FF 73 96 F7 BC 9F 00 5B 92 30 FD 25 EA 00 00 73 54 00 F5 28 04 06 70 96 02 15 19 1C 1E 23 00 EC E0 04 D7 FF 92 FF FF FF 15 09 25 60 14 55 16
|
||||
^^
|
||||
core voltage
|
||||
voltage: ff -> 3.73v
|
||||
fd -> 3.63v
|
||||
f7 -> 3.33v
|
||||
ea -> 2.68v
|
||||
|
32
doc/reverse-engineering/stc8-new.txt
Normal file
32
doc/reverse-engineering/stc8-new.txt
Normal file
@ -0,0 +1,32 @@
|
||||
Cycling power: done
|
||||
Waiting for MCU: <- Packet data: 46 B9 68 00 30 50 FF FF FF FF 8F 00 04 FF FF 8B FD FF 27 3E F5 73 73 55 00 F6 41 0A 88 86 6F 8F 08 20 20 20 01 00 00 20 05 3C 18 05 22 32 FF 12 18 16
|
||||
-> Packet data: 46 B9 6A 00 07 FF 01 70 16
|
||||
done
|
||||
Target model:
|
||||
Name: STC8F2K08S2
|
||||
Magic: F641
|
||||
Code flash: 8.0 KB
|
||||
EEPROM flash: 56.0 KB
|
||||
Target frequency: 0.000 MHz
|
||||
Target BSL version: 7.3.10U
|
||||
Target wakeup frequency: 34.950 KHz
|
||||
Target ref. voltage: 1340 mV
|
||||
Target mfg. date: 2018-05-22
|
||||
Target options:
|
||||
reset_pin_enabled=False
|
||||
clock_gain=high
|
||||
watchdog_por_enabled=False
|
||||
watchdog_stop_idle=True
|
||||
watchdog_prescale=64
|
||||
low_voltage_reset=False
|
||||
low_voltage_threshold=2
|
||||
eeprom_erase_enabled=True
|
||||
bsl_pindetect_enabled=False
|
||||
por_reset_delay=long
|
||||
rstout_por_state=high
|
||||
uart1_remap=False
|
||||
uart2_passthrough=False
|
||||
uart2_pin_mode=normal
|
||||
epwm_open_drain=False
|
||||
program_eeprom_split=29440
|
||||
Disconnected!
|
35
doc/reverse-engineering/untrimmed.txt
Normal file
35
doc/reverse-engineering/untrimmed.txt
Normal file
@ -0,0 +1,35 @@
|
||||
Cycling power: done
|
||||
Waiting for MCU: done
|
||||
Protocol detected: stc8
|
||||
Target model:
|
||||
Name: STC8F2K08S2
|
||||
Magic: F641
|
||||
Code flash: 8.0 KB
|
||||
EEPROM flash: 56.0 KB
|
||||
Target frequency: 0.000 MHz
|
||||
Target BSL version: 7.3.10U
|
||||
Target wakeup frequency: 34.950 KHz
|
||||
Target ref. voltage: 1340 mV
|
||||
Target mfg. date: 2018-05-22
|
||||
Target options:
|
||||
reset_pin_enabled=False
|
||||
clock_gain=high
|
||||
watchdog_por_enabled=False
|
||||
watchdog_stop_idle=True
|
||||
watchdog_prescale=64
|
||||
low_voltage_reset=False
|
||||
low_voltage_threshold=2
|
||||
eeprom_erase_enabled=True
|
||||
bsl_pindetect_enabled=False
|
||||
por_reset_delay=long
|
||||
rstout_por_state=high
|
||||
uart1_remap=False
|
||||
uart2_passthrough=False
|
||||
uart2_pin_mode=normal
|
||||
epwm_open_drain=False
|
||||
program_eeprom_split=29440
|
||||
Loading flash: 80 bytes (Intel HEX)
|
||||
<- Packet data: 46 B9 68 00 30 50 FF FF FF FF 8F 00 04 FF FF 8B FD FF 27 38 F5 73 73 55 00 F6 41 0A 88 86 6F 8F 08 20 20 20 01 00 00 20 05 3C 18 05 22 32 FF 12 12 16
|
||||
Protocol error: uncalibrated, please provide a trim value
|
||||
-> Packet data: 46 B9 6A 00 07 FF 01 70 16
|
||||
Disconnected!
|
2
setup.py
2
setup.py
@ -31,7 +31,6 @@ setup(
|
||||
name = "stcgal",
|
||||
version = stcgal.__version__,
|
||||
packages = find_packages(exclude=["doc", "tests"]),
|
||||
data_files = [("doc", ["README.md", "doc/FAQ.md", "doc/MODELS.md", "doc/USAGE.md"])],
|
||||
install_requires = ["pyserial>=3.0", "tqdm>=4.0.0"],
|
||||
extras_require = {
|
||||
"usb": ["pyusb>=1.0.0"]
|
||||
@ -59,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.5"
|
||||
__version__ = "1.6"
|
||||
|
@ -126,7 +126,7 @@ class StcGal:
|
||||
print("WARNING: eeprom_image truncated!", file=sys.stderr)
|
||||
eedata = eedata[0:ee_size]
|
||||
if len(bindata) < code_size:
|
||||
bindata += bytes(code_size - len(bindata))
|
||||
bindata += bytes([0xff] * (code_size - len(bindata)))
|
||||
elif len(bindata) > code_size:
|
||||
print("WARNING: eeprom_image overlaps code_image!", file=sys.stderr)
|
||||
bindata = bindata[0:code_size]
|
||||
@ -144,9 +144,22 @@ class StcGal:
|
||||
self.protocol.program_options()
|
||||
self.protocol.disconnect()
|
||||
|
||||
def erase_mcu(self):
|
||||
"""Erase MCU without programming"""
|
||||
|
||||
code_size = self.protocol.model.code
|
||||
|
||||
self.protocol.handshake()
|
||||
self.protocol.erase_flash(code_size, code_size)
|
||||
self.protocol.disconnect()
|
||||
|
||||
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,11 +191,17 @@ 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:
|
||||
self.program_mcu()
|
||||
return 0
|
||||
elif self.opts.erase:
|
||||
self.erase_mcu()
|
||||
else:
|
||||
self.protocol.disconnect()
|
||||
return 0
|
||||
except NameError as ex:
|
||||
@ -215,18 +234,21 @@ def cli():
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="stcgal {} - an STC MCU ISP flash tool\n".format(stcgal.__version__) +
|
||||
"(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='?')
|
||||
exclusives = parser.add_mutually_exclusive_group()
|
||||
exclusives.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='?')
|
||||
exclusives.add_argument("-e", "--erase", help="only erase flash memory", action="store_true")
|
||||
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
|
||||
|
@ -155,8 +155,8 @@ class IHex:
|
||||
def make_line(self, line_type, addr, data):
|
||||
line = struct.pack(">BHB", len(data), addr, line_type)
|
||||
line += data
|
||||
line += chr(self.calc_checksum(line))
|
||||
return ":" + line.encode("hex").upper() + "\r\n"
|
||||
line += bytes([self.calc_checksum(line)])
|
||||
return ":" + line.hex().upper() + "\r\n"
|
||||
|
||||
def write(self):
|
||||
"""Write Intel HEX data to string"""
|
||||
@ -207,7 +207,7 @@ class IHex:
|
||||
output += self.make_line(
|
||||
0x05, 0, struct.pack(">I", self.start))
|
||||
|
||||
output += self.make_line(0x01, 0, "")
|
||||
output += self.make_line(0x01, 0, b"")
|
||||
return output
|
||||
|
||||
def write_file(self, fname):
|
||||
|
@ -1394,16 +1394,19 @@ class Stc15Protocol(Stc15AProtocol):
|
||||
# hardware UART. Only one family of models seems to lack a hardware
|
||||
# UART, and we can isolate those with a check on the magic.
|
||||
# This is a bit of a hack, but it works.
|
||||
bauds = self.baud_transfer if (self.mcu_magic >> 8) == 0xf2 else self.baud_transfer * 4
|
||||
packet += struct.pack(">H", int(65535 - program_speed / bauds))
|
||||
packet += bytes(user_trim)
|
||||
if (self.mcu_magic >> 8) == 0xf2:
|
||||
packet += struct.pack(">H", int(65536 - program_speed / self.baud_transfer))
|
||||
packet += struct.pack(">H", int(65536 - program_speed / 2 * 3 / self.baud_transfer))
|
||||
else:
|
||||
packet += struct.pack(">H", int(65536 - program_speed / (self.baud_transfer * 4)))
|
||||
packet += bytes(reversed(user_trim))
|
||||
iap_wait = self.get_iap_delay(program_speed)
|
||||
packet += bytes([iap_wait])
|
||||
self.write_packet(packet)
|
||||
response = self.read_packet()
|
||||
if len(response) < 1 or response[0] != 0x01:
|
||||
raise StcProtocolException("incorrect magic in handshake packet")
|
||||
time.sleep(0.2)
|
||||
time.sleep(0.1)
|
||||
self.ser.baudrate = self.baud_transfer
|
||||
|
||||
def switch_baud_ext(self):
|
||||
@ -1413,14 +1416,17 @@ class Stc15Protocol(Stc15AProtocol):
|
||||
sys.stdout.flush()
|
||||
packet = bytes([0x01])
|
||||
packet += bytes([self.freq_count_24, 0x40])
|
||||
packet += struct.pack(">H", int(65535 - self.mcu_clock_hz / self.baud_transfer / 4))
|
||||
bauds = int(65536 - self.mcu_clock_hz / self.baud_transfer / 4)
|
||||
if bauds >= 65536:
|
||||
raise StcProtocolException("baudrate adjustment failed")
|
||||
packet += struct.pack(">H", bauds)
|
||||
iap_wait = self.get_iap_delay(self.mcu_clock_hz)
|
||||
packet += bytes([0x00, 0x00, iap_wait])
|
||||
self.write_packet(packet)
|
||||
response = self.read_packet()
|
||||
if len(response) < 1 or response[0] != 0x01:
|
||||
raise StcProtocolException("incorrect magic in handshake packet")
|
||||
time.sleep(0.2)
|
||||
time.sleep(0.1)
|
||||
self.ser.baudrate = self.baud_transfer
|
||||
|
||||
# for switching back to RC, program factory values
|
||||
@ -1664,7 +1670,7 @@ class Stc8Protocol(Stc15Protocol):
|
||||
sys.stdout.flush()
|
||||
packet = bytes([0x01, 0x00, 0x00])
|
||||
bauds = self.baud_transfer * 4
|
||||
packet += struct.pack(">H", round(65535 - 24E6 / bauds))
|
||||
packet += struct.pack(">H", round(65536 - 24E6 / bauds))
|
||||
packet += bytes([user_trim[1], user_trim[0]])
|
||||
iap_wait = self.get_iap_delay(24E6)
|
||||
packet += bytes([iap_wait])
|
||||
|
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]
|
62
tests/test_ihex.py
Normal file
62
tests/test_ihex.py
Normal file
@ -0,0 +1,62 @@
|
||||
#
|
||||
# Copyright (c) 2021 Grigori Goronzy <greg@chown.ath.cx>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
|
||||
import unittest
|
||||
import stcgal.ihex
|
||||
|
||||
class IHEXTests(unittest.TestCase):
|
||||
"""Tests for IHEX reader"""
|
||||
|
||||
def test_simple(self):
|
||||
"""Test reading a basic, valid file"""
|
||||
lines = [
|
||||
b":0B00000068656C6C6F5F776F726C645A",
|
||||
b":00000001FF"
|
||||
]
|
||||
bindata = stcgal.ihex.IHex.read(lines).extract_data()
|
||||
self.assertEqual(bindata, b"hello_world")
|
||||
|
||||
def test_empty(self):
|
||||
"""Test reading an empty file"""
|
||||
lines = []
|
||||
bindata = stcgal.ihex.IHex.read(lines).extract_data()
|
||||
self.assertEqual(bindata, b"")
|
||||
|
||||
def test_invalid(self):
|
||||
"""Test invalid encoded data"""
|
||||
lines = [
|
||||
":abc"
|
||||
]
|
||||
with self.assertRaises(ValueError):
|
||||
stcgal.ihex.IHex.read(lines)
|
||||
|
||||
def test_roundtrip(self):
|
||||
"""Test round-trip through encoder/decoder"""
|
||||
bindata = b"12345678"
|
||||
for mode in (8, 16, 32):
|
||||
with self.subTest(mode):
|
||||
hexer = stcgal.ihex.IHex()
|
||||
hexer.set_mode(mode)
|
||||
hexer.insert_data(0, bindata)
|
||||
encoded = hexer.write().encode("ASCII").splitlines()
|
||||
decoded = stcgal.ihex.IHex.read(encoded).extract_data()
|
||||
self.assertEqual(decoded, bindata)
|
@ -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
|
||||
@ -127,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")
|
||||
@ -134,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"])
|
||||
|
Reference in New Issue
Block a user