stc8usb 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stc8usb/__init__.py +1 -0
- stc8usb/stc8usb.py +321 -0
- stc8usb-0.2.0.dist-info/LICENSE +21 -0
- stc8usb-0.2.0.dist-info/METADATA +90 -0
- stc8usb-0.2.0.dist-info/RECORD +8 -0
- stc8usb-0.2.0.dist-info/WHEEL +5 -0
- stc8usb-0.2.0.dist-info/entry_points.txt +2 -0
- stc8usb-0.2.0.dist-info/top_level.txt +1 -0
stc8usb/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .stc8usb import _main
|
stc8usb/stc8usb.py
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# ===================================================================================
|
|
3
|
+
# Project: stc8usb - USB Programming Tool for STC8H8KxxU Microcontrollers
|
|
4
|
+
# Version: v0.2
|
|
5
|
+
# Year: 2023
|
|
6
|
+
# Author: Stefan Wagner
|
|
7
|
+
# Github: https://github.com/wagiminator
|
|
8
|
+
# License: MIT License
|
|
9
|
+
# ===================================================================================
|
|
10
|
+
#
|
|
11
|
+
# Description:
|
|
12
|
+
# ------------
|
|
13
|
+
# Simple Python tool for flashing STC8H8KxxU microcontrollers via USB utilizing the
|
|
14
|
+
# factory built-in embedded USB boot loader.
|
|
15
|
+
# !!! THIS TOOL IS IN AN EARLY STAGE OF DEVELOPMENT !!!
|
|
16
|
+
#
|
|
17
|
+
# Dependencies:
|
|
18
|
+
# -------------
|
|
19
|
+
# - pyhidapi
|
|
20
|
+
#
|
|
21
|
+
# Operating Instructions:
|
|
22
|
+
# -----------------------
|
|
23
|
+
# You need to install pyhidapi to use stc8usb.
|
|
24
|
+
# Install it via "python3 -m pip install hid".
|
|
25
|
+
#
|
|
26
|
+
# By default Linux will not expose enough permission to access the USB bootloader.
|
|
27
|
+
# In order to fix this, open a terminal and run the following commands:
|
|
28
|
+
# echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="34bf", ATTR{idProduct}=="1001", MODE="666"' | sudo tee /etc/udev/rules.d/99-STC-ISP.rules
|
|
29
|
+
# sudo udevadm control --reload-rules
|
|
30
|
+
#
|
|
31
|
+
# The bootloader must be started manually for new uploads. To do this, the board must
|
|
32
|
+
# first be disconnected from the USB port and all voltage sources. Now press the BOOT
|
|
33
|
+
# button and keep it pressed while reconnecting the board to the USB port of your PC.
|
|
34
|
+
# The chip now starts in bootloader mode, the BOOT button can be released and new
|
|
35
|
+
# firmware can be uploaded via USB. If there is no BOOT button on the board, you have
|
|
36
|
+
# to short pin P3.2 to ground while connecting.
|
|
37
|
+
#
|
|
38
|
+
# Run "python3 stc8usb.py -t 24000000 -f firmware.bin".
|
|
39
|
+
|
|
40
|
+
# ===================================================================================
|
|
41
|
+
# Libraries
|
|
42
|
+
# ===================================================================================
|
|
43
|
+
|
|
44
|
+
import sys
|
|
45
|
+
import hid
|
|
46
|
+
import argparse
|
|
47
|
+
|
|
48
|
+
# ===================================================================================
|
|
49
|
+
# Main Function
|
|
50
|
+
# ===================================================================================
|
|
51
|
+
|
|
52
|
+
def _main():
|
|
53
|
+
# Parse command line arguments
|
|
54
|
+
parser = argparse.ArgumentParser(description='Minimal command line interface for stc8usb')
|
|
55
|
+
parser.add_argument('-t', '--trim', help='trim IRC to frequency in Hz')
|
|
56
|
+
parser.add_argument('-e', '--erase', action='store_true', help='perform chip erase (implied with -f)')
|
|
57
|
+
parser.add_argument('-f', '--flash', help='write BIN file to flash')
|
|
58
|
+
args = parser.parse_args(sys.argv[1:])
|
|
59
|
+
|
|
60
|
+
# Establish connection to USB-to-serial converter
|
|
61
|
+
try:
|
|
62
|
+
print('Connecting to MCU via USB ...')
|
|
63
|
+
isp = Programmer()
|
|
64
|
+
except Exception as ex:
|
|
65
|
+
sys.stderr.write('ERROR: ' + str(ex) + '!\n')
|
|
66
|
+
sys.exit(1)
|
|
67
|
+
|
|
68
|
+
# Performing actions
|
|
69
|
+
try:
|
|
70
|
+
# Connect to and identify MCU
|
|
71
|
+
isp.connect()
|
|
72
|
+
print('SUCCESS: Found %s v%s @ %s.' % (isp.chipname, isp.chipverstr, isp.foscstr))
|
|
73
|
+
|
|
74
|
+
# Perform chip erase
|
|
75
|
+
if (args.erase) or (args.flash is not None) or (args.trim is not None):
|
|
76
|
+
print('Performing chip erase ...')
|
|
77
|
+
isp.erase()
|
|
78
|
+
print('SUCCESS: Chip is erased.')
|
|
79
|
+
|
|
80
|
+
# Flash binary file
|
|
81
|
+
if args.flash is not None:
|
|
82
|
+
print('Flashing %s to %s ...' % (args.flash, isp.chipname))
|
|
83
|
+
with open(args.flash, 'rb') as f: data = f.read()
|
|
84
|
+
isp.writeflash(0, data)
|
|
85
|
+
print('SUCCESS: %d bytes written.' % len(data))
|
|
86
|
+
|
|
87
|
+
# Set frequency
|
|
88
|
+
if args.trim is not None:
|
|
89
|
+
print('Setting frequency ...')
|
|
90
|
+
isp.setfreq(int(args.trim))
|
|
91
|
+
print('SUCCESS: Frequency set to %s Hz.' % args.trim)
|
|
92
|
+
|
|
93
|
+
# Close connection
|
|
94
|
+
isp.disconnect()
|
|
95
|
+
|
|
96
|
+
except Exception as ex:
|
|
97
|
+
sys.stderr.write('ERROR: ' + str(ex) + '!\n')
|
|
98
|
+
isp.close()
|
|
99
|
+
sys.exit(1)
|
|
100
|
+
|
|
101
|
+
print('DONE.')
|
|
102
|
+
sys.exit(0)
|
|
103
|
+
|
|
104
|
+
# ===================================================================================
|
|
105
|
+
# Programmer Class
|
|
106
|
+
# ===================================================================================
|
|
107
|
+
|
|
108
|
+
class Programmer:
|
|
109
|
+
# Init programmer
|
|
110
|
+
def __init__(self):
|
|
111
|
+
# Find programmer
|
|
112
|
+
try:
|
|
113
|
+
self.dev = hid.Device(STC_VID, STC_PID)
|
|
114
|
+
except:
|
|
115
|
+
raise Exception('Unable to open device')
|
|
116
|
+
|
|
117
|
+
# Close connection
|
|
118
|
+
def close(self):
|
|
119
|
+
self.dev.close()
|
|
120
|
+
|
|
121
|
+
#--------------------------------------------------------------------------------
|
|
122
|
+
|
|
123
|
+
# Transmit data block
|
|
124
|
+
def transmit(self, data):
|
|
125
|
+
size = len(data) + 6
|
|
126
|
+
parity = STC_TX_CODE + (size >> 8) + (size & 0xff)
|
|
127
|
+
for x in range(len(data)):
|
|
128
|
+
parity += data[x]
|
|
129
|
+
block = [STC_PREFIX, STC_PREFIX ^ 0xff, STC_TX_CODE]
|
|
130
|
+
block += size.to_bytes(2, byteorder='big')
|
|
131
|
+
block += data
|
|
132
|
+
block += parity.to_bytes(2, byteorder='big')
|
|
133
|
+
block += [STC_SUFFIX]
|
|
134
|
+
block = self.paddata(bytes(block), STC_HID_SIZE, 0x00)
|
|
135
|
+
self.dev.write(block)
|
|
136
|
+
|
|
137
|
+
# Receive data block
|
|
138
|
+
def receive(self):
|
|
139
|
+
reply = self.dev.read(STC_HID_SIZE, STC_TIMEOUT)
|
|
140
|
+
if len(reply) != STC_HID_SIZE:
|
|
141
|
+
raise Exception('No response from device')
|
|
142
|
+
size = int.from_bytes(reply[3:5], byteorder='big')
|
|
143
|
+
return reply[5:size-1]
|
|
144
|
+
|
|
145
|
+
#--------------------------------------------------------------------------------
|
|
146
|
+
|
|
147
|
+
# Connect to and identify MCU
|
|
148
|
+
def connect(self):
|
|
149
|
+
self.transmit([STC_CMD_INIT])
|
|
150
|
+
reply = self.receive()
|
|
151
|
+
|
|
152
|
+
# Get chip ID
|
|
153
|
+
self.chipid = int.from_bytes(reply[20:22], byteorder='big')
|
|
154
|
+
|
|
155
|
+
# Find chip in dictionary
|
|
156
|
+
self.device = None
|
|
157
|
+
for d in STC_DEVICES:
|
|
158
|
+
if d['id'] == self.chipid:
|
|
159
|
+
self.device = d
|
|
160
|
+
if self.device is None:
|
|
161
|
+
raise Exception('Unsupported chip (ID: 0x%04x)' % self.chipid)
|
|
162
|
+
self.chipname = self.device['name']
|
|
163
|
+
self.flash_size = self.device['flash_size']
|
|
164
|
+
|
|
165
|
+
# Get chip version
|
|
166
|
+
self.chipversion = reply[17]
|
|
167
|
+
self.chipverstr = '%d.%d.%d%c' % (reply[17] >> 4, reply[17] & 0x0f, \
|
|
168
|
+
reply[22] & 0x0f, reply[18])
|
|
169
|
+
|
|
170
|
+
# Get USER-IRC oscillator frequency
|
|
171
|
+
self.fosc = int.from_bytes(reply[1:5], byteorder='big')
|
|
172
|
+
if self.fosc == 0xffffffff:
|
|
173
|
+
self.foscstr = 'untrimmed frequency'
|
|
174
|
+
else:
|
|
175
|
+
self.foscstr = str(self.fosc) + ' Hz'
|
|
176
|
+
|
|
177
|
+
# Set BAUD (dummy)
|
|
178
|
+
self.transmit([STC_CMD_BAUD_SET, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80])
|
|
179
|
+
self.receive()
|
|
180
|
+
self.transmit([STC_CMD_BAUD_CHECK, 0x00, 0x00, 0x5a, 0xa5])
|
|
181
|
+
self.receive()
|
|
182
|
+
|
|
183
|
+
# Disconnect from MCU
|
|
184
|
+
def disconnect(self):
|
|
185
|
+
self.transmit([STC_CMD_EXIT])
|
|
186
|
+
self.dev.close()
|
|
187
|
+
|
|
188
|
+
#--------------------------------------------------------------------------------
|
|
189
|
+
|
|
190
|
+
# Erase flash
|
|
191
|
+
def erase(self):
|
|
192
|
+
self.transmit([STC_CMD_ERASE, 0, 0, STC_BREAK, STC_BREAK ^ 0xff])
|
|
193
|
+
reply = self.receive()
|
|
194
|
+
if reply is None or reply[0] != STC_CMD_ERASE:
|
|
195
|
+
raise Exception('Failed to erase flash')
|
|
196
|
+
|
|
197
|
+
# Write data to flash
|
|
198
|
+
def writeflash(self, addr, data):
|
|
199
|
+
data = self.paddata(data, STC_PAGE_SIZE, 0xff)
|
|
200
|
+
size = len(data)
|
|
201
|
+
if size > (self.flash_size - addr):
|
|
202
|
+
raise Exception('Not enough memory')
|
|
203
|
+
cmd = STC_CMD_WRITE
|
|
204
|
+
while size > 0:
|
|
205
|
+
blocksize = min(size, STC_PAGE_SIZE)
|
|
206
|
+
block = [cmd]
|
|
207
|
+
block += addr.to_bytes(2, byteorder='big')
|
|
208
|
+
block += [STC_BREAK, STC_BREAK ^ 0xff]
|
|
209
|
+
block += data[:blocksize]
|
|
210
|
+
self.transmit(block)
|
|
211
|
+
reply = self.receive()
|
|
212
|
+
if reply is None or reply[0] != STC_CMD_WRITE_CONT:
|
|
213
|
+
raise Exception('Failed to write to address 0x%04x' % addr)
|
|
214
|
+
cmd = STC_CMD_WRITE_CONT
|
|
215
|
+
data = data[blocksize:]
|
|
216
|
+
addr += blocksize
|
|
217
|
+
size -= blocksize
|
|
218
|
+
|
|
219
|
+
# Set frequency by writing option bytes
|
|
220
|
+
def setfreq(self, freq):
|
|
221
|
+
trim = None
|
|
222
|
+
for f in STC_FREQUENCIES:
|
|
223
|
+
if f['freq'] == freq:
|
|
224
|
+
trim = f['trim']
|
|
225
|
+
if trim is None:
|
|
226
|
+
raise Exception('Unsupported frequency')
|
|
227
|
+
block = [STC_CMD_OPTIONS, 0, 0, STC_BREAK, STC_BREAK ^ 0xff]
|
|
228
|
+
block += STC_BLOCK_OPTIONS1
|
|
229
|
+
block += freq.to_bytes(4, byteorder='big')
|
|
230
|
+
block += trim
|
|
231
|
+
block += STC_BLOCK_OPTIONS2
|
|
232
|
+
self.transmit(block)
|
|
233
|
+
reply = self.receive()
|
|
234
|
+
if reply is None or reply[0] != STC_CMD_OPTIONS:
|
|
235
|
+
raise Exception('Failed to write option bytes')
|
|
236
|
+
|
|
237
|
+
# Pad data
|
|
238
|
+
def paddata(self, data, pagesize, filler):
|
|
239
|
+
if (len(data) % pagesize) > 0:
|
|
240
|
+
data += bytes([filler]) * (pagesize - (len(data) % pagesize))
|
|
241
|
+
return data
|
|
242
|
+
|
|
243
|
+
# ===================================================================================
|
|
244
|
+
# Device Constants
|
|
245
|
+
# ===================================================================================
|
|
246
|
+
|
|
247
|
+
STC_VID = 0x34bf
|
|
248
|
+
STC_PID = 0x1001
|
|
249
|
+
STC_HID_SIZE = 64
|
|
250
|
+
STC_PAGE_SIZE = 128
|
|
251
|
+
STC_TIMEOUT = 1000
|
|
252
|
+
|
|
253
|
+
STC_PREFIX = 0x46
|
|
254
|
+
STC_BREAK = 0x5a
|
|
255
|
+
STC_SUFFIX = 0x16
|
|
256
|
+
STC_TX_CODE = 0x6a
|
|
257
|
+
STC_RX_CODE = 0x68
|
|
258
|
+
STC_RPL_INFO = 0x50
|
|
259
|
+
|
|
260
|
+
STC_CMD_INIT = 0x00
|
|
261
|
+
STC_CMD_BAUD_SET = 0x01
|
|
262
|
+
STC_CMD_BAUD_CHECK = 0x05
|
|
263
|
+
STC_CMD_ERASE = 0x03
|
|
264
|
+
STC_CMD_OPTIONS = 0x04
|
|
265
|
+
STC_CMD_WRITE = 0x32
|
|
266
|
+
STC_CMD_WRITE_CONT = 0x02
|
|
267
|
+
STC_CMD_EXIT = 0xff
|
|
268
|
+
|
|
269
|
+
STC_BLOCK_OPTIONS1 = [0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff,
|
|
270
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
271
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff]
|
|
272
|
+
STC_BLOCK_OPTIONS2 = [0xff, 0xff, 0xff, 0xff, 0x3e, 0xbf, 0xaf, 0xf7, 0xfe]
|
|
273
|
+
|
|
274
|
+
# ===================================================================================
|
|
275
|
+
# Device Dictionary
|
|
276
|
+
# ===================================================================================
|
|
277
|
+
|
|
278
|
+
STC_DEVICES = [
|
|
279
|
+
{'name': 'STC8H8K16U', 'id': 0xF781, 'flash_size': 16384},
|
|
280
|
+
{'name': 'STC8H8K32U', 'id': 0xF782, 'flash_size': 32768},
|
|
281
|
+
{'name': 'STC8H8K60U', 'id': 0xF783, 'flash_size': 61440},
|
|
282
|
+
{'name': 'STC8H8K64U', 'id': 0xF784, 'flash_size': 65024},
|
|
283
|
+
{'name': 'STC8H8K48U', 'id': 0xF785, 'flash_size': 49152}
|
|
284
|
+
]
|
|
285
|
+
|
|
286
|
+
STC_FREQUENCIES = [
|
|
287
|
+
{'freq': 250000, 'trim': [0x48, 0x20, 96]},
|
|
288
|
+
{'freq': 500000, 'trim': [0x48, 0x20, 48]},
|
|
289
|
+
{'freq': 1000000, 'trim': [0x48, 0x20, 24]},
|
|
290
|
+
{'freq': 2000000, 'trim': [0x48, 0x20, 12]},
|
|
291
|
+
{'freq': 3000000, 'trim': [0x48, 0x20, 8]},
|
|
292
|
+
{'freq': 4000000, 'trim': [0x48, 0x20, 6]},
|
|
293
|
+
{'freq': 5000000, 'trim': [0x73, 0x30, 8]},
|
|
294
|
+
{'freq': 6000000, 'trim': [0x48, 0x20, 4]},
|
|
295
|
+
{'freq': 8000000, 'trim': [0x48, 0x20, 3]},
|
|
296
|
+
{'freq': 10000000, 'trim': [0x73, 0x30, 4]},
|
|
297
|
+
{'freq': 12000000, 'trim': [0x48, 0x20, 2]},
|
|
298
|
+
{'freq': 16000000, 'trim': [0xc6, 0x30, 3]},
|
|
299
|
+
{'freq': 20000000, 'trim': [0x73, 0x30, 2]},
|
|
300
|
+
{'freq': 24000000, 'trim': [0x48, 0x20, 1]},
|
|
301
|
+
{'freq': 27000000, 'trim': [0x7a, 0x20, 1]},
|
|
302
|
+
{'freq': 30000000, 'trim': [0xb1, 0x20, 1]},
|
|
303
|
+
{'freq': 35000000, 'trim': [0x44, 0x30, 1]},
|
|
304
|
+
{'freq': 40000000, 'trim': [0x73, 0x30, 1]},
|
|
305
|
+
{'freq': 48000000, 'trim': [0xc6, 0x30, 1]},
|
|
306
|
+
|
|
307
|
+
{'freq': 1382400, 'trim': [0x28, 0x20, 16]},
|
|
308
|
+
{'freq': 2764800, 'trim': [0x28, 0x20, 8]},
|
|
309
|
+
{'freq': 5529600, 'trim': [0x28, 0x20, 4]},
|
|
310
|
+
{'freq': 11059200, 'trim': [0x28, 0x20, 2]},
|
|
311
|
+
{'freq': 18432000, 'trim': [0x56, 0x30, 2]},
|
|
312
|
+
{'freq': 22118400, 'trim': [0x28, 0x20, 1]},
|
|
313
|
+
{'freq': 33177600, 'trim': [0xe9, 0x20, 1]},
|
|
314
|
+
{'freq': 36864000, 'trim': [0x56, 0x30, 1]},
|
|
315
|
+
{'freq': 44236800, 'trim': [0x9f, 0x30, 1]}
|
|
316
|
+
]
|
|
317
|
+
|
|
318
|
+
# ===================================================================================
|
|
319
|
+
|
|
320
|
+
if __name__ == "__main__":
|
|
321
|
+
_main()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Stefan Wagner
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: stc8usb
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: USB Programming Tool for STC8H8KxxU Microcontrollers
|
|
5
|
+
Home-page: https://github.com/wagiminator/MCU-Flash-Tools
|
|
6
|
+
Author: Stefan Wagner
|
|
7
|
+
Author-email: Stefan Wagner <wagiminator@web.de>
|
|
8
|
+
Maintainer-email: Stefan Wagner <wagiminator@web.de>
|
|
9
|
+
License: MIT License
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2023 Stefan Wagner
|
|
12
|
+
|
|
13
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
14
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
15
|
+
in the Software without restriction, including without limitation the rights
|
|
16
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
17
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
18
|
+
furnished to do so, subject to the following conditions:
|
|
19
|
+
|
|
20
|
+
The above copyright notice and this permission notice shall be included in all
|
|
21
|
+
copies or substantial portions of the Software.
|
|
22
|
+
|
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
24
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
25
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
26
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
27
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
28
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
29
|
+
SOFTWARE.
|
|
30
|
+
Project-URL: Homepage, https://wagiminator.github.io/
|
|
31
|
+
Project-URL: Repository, https://github.com/wagiminator/MCU-Flash-Tools
|
|
32
|
+
Project-URL: Issues, https://github.com/wagiminator/MCU-Flash-Tools/issues
|
|
33
|
+
Keywords: STC,STC8,STC8H8K64U,microcontroller
|
|
34
|
+
Classifier: Development Status :: 4 - Beta
|
|
35
|
+
Classifier: Programming Language :: Python :: 3
|
|
36
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
37
|
+
Classifier: Operating System :: OS Independent
|
|
38
|
+
Classifier: Intended Audience :: Developers
|
|
39
|
+
Classifier: Topic :: Software Development :: Embedded Systems
|
|
40
|
+
Requires-Python: >=3.8
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
License-File: LICENSE
|
|
43
|
+
Requires-Dist: hid
|
|
44
|
+
|
|
45
|
+
# stc8usb - USB Programming Tool for STC8H8KxxU Microcontrollers
|
|
46
|
+
## Description
|
|
47
|
+
This tool allows you to flash STC8H8KxxU microcontrollers through their USB interface, using the pre-installed embedded USB bootloader.
|
|
48
|
+
|
|
49
|
+
## Preparations
|
|
50
|
+
Because the USB bootloader functions as a Human Interface Device (HID), there's no need to install drivers. However, Linux doesn't initially grant sufficient permissions to access the bootloader. To resolve this issue, open a terminal and execute the following commands:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="34bf", ATTR{idProduct}=="1001", MODE="666"' | sudo tee /etc/udev/rules.d/99-STC-ISP.rules
|
|
54
|
+
sudo udevadm control --reload-rules
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
- Install [Python3](https://www.pythontutorial.net/getting-started/install-python/).
|
|
59
|
+
- Install [pip](https://pip.pypa.io/en/stable/installation/).
|
|
60
|
+
- Install stc8usb:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
pip install stc8usb
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
To initiate new uploads, the bootloader needs to be manually started. Begin by unplugging the board from the USB port and disconnecting all power sources. Then, press and hold the BOOT button while reconnecting the board to your PC's USB port. This action triggers the chip to enter bootloader mode. Once in this mode, you can release the BOOT button and proceed to upload new firmware via USB.
|
|
68
|
+
|
|
69
|
+
If your board doesn't have a BOOT button, you'll need to short pin P3.2 to ground while connecting to achieve the same effect.
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
Usage: stc8usb [-h] [-t TRIM] [-e] [-f FLASH]
|
|
73
|
+
|
|
74
|
+
Optional arguments:
|
|
75
|
+
-h, --help show this help message and exit
|
|
76
|
+
-t TRIM, --trim TRIM set MCU system frequency
|
|
77
|
+
-e, --erase perform chip erase (implied with -f)
|
|
78
|
+
-f FLASH, --flash FLASH write BIN file to flash
|
|
79
|
+
|
|
80
|
+
Example:
|
|
81
|
+
stc8usb -t 24000000 -f firmware.bin
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Links
|
|
85
|
+
- [MCU Flash Tools](https://github.com/wagiminator/MCU-Flash-Tools)
|
|
86
|
+
- [MCU Templates](https://github.com/wagiminator/MCU-Templates)
|
|
87
|
+
- [MCU Development Boards](https://github.com/wagiminator/Development-Boards)
|
|
88
|
+
- [AVR Development Boards](https://github.com/wagiminator/AVR-Development-Boards)
|
|
89
|
+
- [AVR Programmers](https://github.com/wagiminator/AVR-Programmer)
|
|
90
|
+
- [SAMD Development Boards](https://github.com/wagiminator/SAMD-Development-Boards)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
stc8usb/__init__.py,sha256=DDwQn_GFt_rff2fsgVs2s7DrqZuzRkivE9db5RBtB98,26
|
|
2
|
+
stc8usb/stc8usb.py,sha256=flYdM9trSbDDoOnuO8w5X-dgbfLXzIyC_Ot3FJLDLLQ,12235
|
|
3
|
+
stc8usb-0.2.0.dist-info/LICENSE,sha256=kph2e2d1k_-VvrU6YbwdbUJ2GKXsFgBGCSym5wVv2j8,1089
|
|
4
|
+
stc8usb-0.2.0.dist-info/METADATA,sha256=APLYpMpfeG_IBnP1-vWdGrSADs-QHd-UVwGI-IKKAEg,4413
|
|
5
|
+
stc8usb-0.2.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
6
|
+
stc8usb-0.2.0.dist-info/entry_points.txt,sha256=hYlzgFW2FOnpnT9iha545aDI7EBb2Vb3C50xXvNNszs,42
|
|
7
|
+
stc8usb-0.2.0.dist-info/top_level.txt,sha256=v1iXuIe8A6-AoKC3Q3qPMustVK3BYcSYaLWXDu2yTYU,8
|
|
8
|
+
stc8usb-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
stc8usb
|