summaryrefslogtreecommitdiff
path: root/hidflash.py
blob: a9df48c99a1ee5ea75b3e6b70599402bf4dfdbff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env python

from hidapi import hidapi
from elftools.elf.elffile import ELFFile

import ctypes, time, sys

e = ELFFile(open(sys.argv[1]))

buf = ''

for segment in sorted(e.iter_segments(), key = lambda x: x.header.p_paddr):
	if segment.header.p_type != 'PT_LOAD':
		continue
	
	data = segment.data()
	lma = segment.header.p_paddr
	
	# Workaround for LD aligning segments to a larger boundary than 8k.
	if lma == 0x8000000:
		lma += 0x2000
		data = data[0x2000:]
	
	# Add padding if necessary.
	buf += '\0' * (lma - 0x8002000 - len(buf))
	
	buf += data

# Align to 64B
if len(buf) & (64 - 1):
	buf += '\0' * (64 - (len(buf) & (64 - 1)))

# Open device
dev = hidapi.hid_open(0x1d50, 0x60f7, None)

if not dev:
	dev = hidapi.hid_open(0x1d50, 0x60f8, None)
	
	if not dev: 
		raise RuntimeError('Device not found.')
	
	print 'Found runtime device, resetting to bootloader.'
	
	# Reset bootloader
	if hidapi.hid_send_feature_report(dev, ctypes.c_char_p('\x00\x10'), 2) != 2:
		raise RuntimeError('Reset failed.')
	
	time.sleep(1)
	
	hidapi.hid_exit()
	
	dev = hidapi.hid_open(0x1d50, 0x60f7, None)
	
	if not dev: 
		raise RuntimeError('Device not found.')

print 'Found bootloader device, starting flashing.'

# Prepare
if hidapi.hid_send_feature_report(dev, ctypes.c_char_p('\x00\x20'), 2) != 2:
	raise RuntimeError('Prepare failed.')

# Flash
while buf:
	if hidapi.hid_write(dev, ctypes.c_char_p('\x00' + buf[:64]), 65) != 65:
		raise RuntimeError('Writing failed.')
	buf = buf[64:]

# Finish
if hidapi.hid_send_feature_report(dev, ctypes.c_char_p('\x00\x21'), 2) != 2:
	raise RuntimeError('Finish failed.')

print 'Flashing finished, resetting to runtime.'

# Reset
if hidapi.hid_send_feature_report(dev, ctypes.c_char_p('\x00\x11'), 2) != 2:
	raise RuntimeError('Reset failed.')

time.sleep(1)

hidapi.hid_exit()

if hidapi.hid_open(0x1d50, 0x6080, None):
	print 'Done, everything ok.'
	
elif hidapi.hid_open(0x1d50, 0x6084, None):
	print 'Still in bootloader mode.'

else:
	print 'Device disappeared.'