Merge lp:~cdwilson/python-msp430-tools/feature-add-custom-bsl-hardware-support into lp:python-msp430-tools

Proposed by Christopher Wilson
Status: Merged
Merged at revision: 450
Proposed branch: lp:~cdwilson/python-msp430-tools/feature-add-custom-bsl-hardware-support
Merge into: lp:python-msp430-tools
Diff against target: 438 lines (+357/-7)
8 files modified
README.txt (+4/-3)
msp430/bsl/target/__init__.py (+0/-3)
msp430/bsl/target/__main__.py (+9/-0)
msp430/bsl/target/fcdprog.py (+70/-0)
msp430/bsl/target/telosb.py (+256/-0)
scripts/msp430-bsl-fcdprog.py (+7/-0)
scripts/msp430-bsl-telosb.py (+7/-0)
setup.py (+4/-1)
To merge this branch: bzr merge lp:~cdwilson/python-msp430-tools/feature-add-custom-bsl-hardware-support
Reviewer Review Type Date Requested Status
zsquareplusc Approve
Review via email: mp+92713@code.launchpad.net

Description of the change

Add support for custom BSL hardware.

Instead of modifying target.py to support a variety of custom BSL hardware, each hardware target is implemented as a <CustomHardware>Target class that lives in a msp430.bsl.target.<customhw>.py module. These custom classes subclass SerialBSLTarget, which allows for the addition of extra options and functionality that are not supported by the base SerialBSLTarget class. More importantly, this segregation allows for the peculiarities of individual hardware to be supported without bloating the default BSL implementation.

Although msp430.bsl.target has been converted from a module to a package, it can still be called from the command line (i.e. "python -m msp430.bsl.target ...")

Convenience scripts are provided for each custom BSL target as "msp430-bsl-<customhw>"

Let me know what you think, feedback appreciated :)

To post a comment you must log in.
451. By Christopher Wilson

Fix ascii schematic in docstring for TelosBTarget

Revision history for this message
zsquareplusc (zsquareplusc) wrote :

merged

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README.txt'
2--- README.txt 2011-02-19 17:30:51 +0000
3+++ README.txt 2012-02-13 17:15:20 +0000
4@@ -12,7 +12,7 @@
5 Download tools
6 ==============
7 Command line tools, e.g. ``python -m msp430.gdb.target``. They can up and
8-donwload memory of MSP430 targets.
9+download memory of MSP430 targets.
10
11 - ``msp430.jtag.target`` JTAG interface
12 - ``msp430.bsl.target`` F1x, F2x, F4x BSL
13@@ -54,8 +54,9 @@
14 A simple assembler and linker, also a disassembler, supporting MSP430(X).
15
16 ``msp430.bsl``
17- Support for the boot strap loader. ``msp430.bsl.target`` is the main module
18- for the downloader.
19+ Support for the boot strap loader. ``msp430.bsl.target`` is the main
20+ package for the downloader and contains subclassed modules for target
21+ specific BSL hardware.
22
23 ``msp430.bsl5``
24 Support for the boot strap loader of F5xx/F6xx devices. ``msp430.bsl5.hid``
25
26=== added directory 'msp430/bsl/target'
27=== renamed file 'msp430/bsl/target.py' => 'msp430/bsl/target/__init__.py'
28--- msp430/bsl/target.py 2011-02-02 00:48:50 +0000
29+++ msp430/bsl/target/__init__.py 2012-02-13 17:15:20 +0000
30@@ -502,6 +502,3 @@
31 # run the main application
32 bsl_target = SerialBSLTarget()
33 bsl_target.main()
34-
35-if __name__ == '__main__':
36- main()
37
38=== added file 'msp430/bsl/target/__main__.py'
39--- msp430/bsl/target/__main__.py 1970-01-01 00:00:00 +0000
40+++ msp430/bsl/target/__main__.py 2012-02-13 17:15:20 +0000
41@@ -0,0 +1,9 @@
42+#!/usr/bin/env python
43+# -*- coding: utf-8 -*-
44+#
45+# Copyright (c) 2012 Christopher Wilson <cwilson@cdwilson.us>
46+# All Rights Reserved.
47+# Simplified BSD License (see LICENSE.txt for full text)
48+
49+import msp430.bsl.target
50+msp430.bsl.target.main()
51
52=== added file 'msp430/bsl/target/fcdprog.py'
53--- msp430/bsl/target/fcdprog.py 1970-01-01 00:00:00 +0000
54+++ msp430/bsl/target/fcdprog.py 2012-02-13 17:15:20 +0000
55@@ -0,0 +1,70 @@
56+#!/usr/bin/env python
57+# -*- coding: utf-8 -*-
58+#
59+# Copyright (c) 2012 Christopher Wilson <cwilson@cdwilson.us>
60+# All Rights Reserved.
61+# Simplified BSD License (see LICENSE.txt for full text)
62+
63+from msp430.bsl.target import SerialBSLTarget
64+
65+
66+class FCDProgTarget(SerialBSLTarget):
67+ """\
68+ Flying Camp Design MSP430 BSL Programmer target
69+
70+ http://www.flyingcampdesign.com
71+ """
72+
73+ def __init__(self):
74+ SerialBSLTarget.__init__(self)
75+
76+ def add_extra_options(self):
77+ SerialBSLTarget.add_extra_options(self)
78+
79+ # by default, invert TEST/TCK
80+ if self.parser.has_option("--invert-test"):
81+ option = self.parser.get_option("--invert-test")
82+ option.action = "store_false"
83+ option.default = True
84+ option.help = "do not invert RTS line (default inverted)"
85+ group = self.parser.get_option_group("--invert-test")
86+ self.parser.remove_option("--invert-test")
87+ group.add_option(option)
88+
89+ # by default, invert RST
90+ if self.parser.has_option("--invert-reset"):
91+ option = self.parser.get_option("--invert-reset")
92+ option.action = "store_false"
93+ option.default = True
94+ option.help = "do not invert DTR line (default inverted)"
95+ group = self.parser.get_option_group("--invert-reset")
96+ self.parser.remove_option("--invert-reset")
97+ group.add_option(option)
98+
99+ # by default, swap TEST/TCK and RST
100+ if self.parser.has_option("--swap-reset-test"):
101+ option = self.parser.get_option("--swap-reset-test")
102+ option.action = "store_false"
103+ option.default = True
104+ option.help = "do not exchange RST and TEST signals (DTR/RTS) (default swapped)"
105+ group = self.parser.get_option_group("--swap-reset-test")
106+ self.parser.remove_option("--swap-reset-test")
107+ group.add_option(option)
108+
109+ # by default, use 38400 baud
110+ if self.parser.has_option("--speed"):
111+ option = self.parser.get_option("--speed")
112+ option.default = 38400
113+ option.help = "change baud rate (default %s)" % option.default
114+ group = self.parser.get_option_group("--speed")
115+ self.parser.remove_option("--speed")
116+ group.add_option(option)
117+
118+
119+def main():
120+ # run the main application
121+ bsl_target = FCDProgTarget()
122+ bsl_target.main()
123+
124+if __name__ == '__main__':
125+ main()
126
127=== added file 'msp430/bsl/target/telosb.py'
128--- msp430/bsl/target/telosb.py 1970-01-01 00:00:00 +0000
129+++ msp430/bsl/target/telosb.py 2012-02-13 17:15:20 +0000
130@@ -0,0 +1,256 @@
131+#!/usr/bin/env python
132+# -*- coding: utf-8 -*-
133+#
134+# Copyright (c) 2012 Christopher Wilson <cwilson@cdwilson.us>
135+# All Rights Reserved.
136+# Simplified BSD License (see LICENSE.txt for full text)
137+
138+import time
139+from optparse import OptionGroup
140+from msp430.bsl.target import SerialBSLTarget
141+
142+
143+class TelosBTarget(SerialBSLTarget):
144+ """\
145+ Telos B target
146+
147+ The Telos B wireless sensor mote has an onboard ADG715 I2C switch that
148+ controls the TCK and RST signals on the MCU. This switch is normally
149+ disabled, preventing TCK or RST from being accidentally driven low by
150+ the BSL hardware.
151+ _________ __________
152+ | ADG715 | | MSP430
153+ | | | ..
154+ DTR-->| SDA | | ..
155+ RTS-->| SCL | | ..
156+ | | | ..
157+ |-S8--//--| | ..
158+ | ... | | ..
159+ .---|-S1--//--|---| TCK
160+ |---|-S0--//--|---| RST
161+ | |_________| |__________
162+ _|_
163+ \_/ <--GND
164+
165+ The Telos B schematic can be downloaded from
166+ http://webs.cs.berkeley.edu/tos/hardware/telos/telos-revb-2004-09-27.pdf
167+
168+ I2C code adapted from tos-bsl found at
169+ http://code.google.com/p/tinyos-main/
170+ """
171+
172+ def __init__(self):
173+ SerialBSLTarget.__init__(self)
174+ self.i2c_switch_addr = 0x90
175+ self.i2c_control_delay = 0
176+ self.invertSCL = False
177+ self.invertSDA = False
178+ self.swapSCLSDA = False
179+
180+ def add_extra_options(self):
181+ SerialBSLTarget.add_extra_options(self)
182+
183+ # by default, use 38400 baud
184+ if self.parser.has_option("--speed"):
185+ option = self.parser.get_option("--speed")
186+ option.default = 38400
187+ option.help = "change baud rate (default %s)" % option.default
188+ group = self.parser.get_option_group("--speed")
189+ self.parser.remove_option("--speed")
190+ group.add_option(option)
191+
192+ group = OptionGroup(self.parser, "I2C switch settings")
193+
194+ group.add_option("--invert-scl",
195+ dest="invert_scl",
196+ action="store_true",
197+ help="invert I2C switch SCL line",
198+ default=False)
199+
200+ group.add_option("--invert-sda",
201+ dest="invert_sda",
202+ action="store_true",
203+ help="invert I2C switch SDA line",
204+ default=False)
205+
206+ group.add_option("--swap-scl-sda",
207+ dest="swap_scl_sda",
208+ action="store_true",
209+ help="swap I2C switch SCL and SDA lines",
210+ default=False)
211+
212+ self.parser.add_option_group(group)
213+
214+ def parse_extra_options(self):
215+ SerialBSLTarget.parse_extra_options(self)
216+
217+ if self.options.invert_scl:
218+ self.invertSCL = True
219+
220+ if self.options.invert_sda:
221+ self.invertSDA = True
222+
223+ if self.options.swap_scl_sda:
224+ self.swapSCLSDA = True
225+
226+ def set_SCL(self, level):
227+ """\
228+ Controls SCL pin (0: VCC; 1: GND; unless inverted flag is set)
229+ """
230+
231+ # invert signal if configured
232+ if self.invertSCL:
233+ level = not level
234+ # set pin level
235+ if self.swapSCLSDA:
236+ self.serial.setDTR(not level)
237+ else:
238+ self.serial.setRTS(not level)
239+ time.sleep(self.i2c_control_delay)
240+
241+
242+ def set_SDA(self, level):
243+ """\
244+ Controls SDA pin (0: VCC; 1: GND; unless inverted flag is set)
245+ """
246+
247+ # invert signal if configured
248+ if self.invertSDA:
249+ level = not level
250+ # set pin level
251+ if self.swapSCLSDA:
252+ self.serial.setRTS(not level)
253+ else:
254+ self.serial.setDTR(not level)
255+ time.sleep(self.i2c_control_delay)
256+
257+ def i2c_start(self):
258+ """Bit bang start sequence on I2C bus"""
259+
260+ self.set_SDA(True)
261+ self.set_SCL(True)
262+ self.set_SDA(False)
263+
264+ def i2c_stop(self):
265+ """Bit bang stop sequence on I2C bus"""
266+
267+ self.set_SDA(False)
268+ self.set_SCL(True)
269+ self.set_SDA(True)
270+
271+ def i2c_write_bit(self, bit):
272+ """Bit bang a single bit on I2C bus"""
273+
274+ self.set_SCL(False)
275+ self.set_SDA(bit)
276+ self.set_SCL(True)
277+ self.set_SCL(False)
278+
279+ def i2c_write_byte(self, byte):
280+ """Bit bang a single byte on I2C bus"""
281+
282+ self.i2c_write_bit(byte & 0x80);
283+ self.i2c_write_bit(byte & 0x40);
284+ self.i2c_write_bit(byte & 0x20);
285+ self.i2c_write_bit(byte & 0x10);
286+ self.i2c_write_bit(byte & 0x08);
287+ self.i2c_write_bit(byte & 0x04);
288+ self.i2c_write_bit(byte & 0x02);
289+ self.i2c_write_bit(byte & 0x01);
290+ self.i2c_write_bit(0); # "acknowledge"
291+
292+ def i2c_write_cmd(self, addr, cmdbyte):
293+ """Bit bang cmdbyte to slave addr on I2C bus"""
294+
295+ self.i2c_start()
296+ self.i2c_write_byte(addr)
297+ self.i2c_write_byte(cmdbyte)
298+ self.i2c_stop()
299+
300+ def i2c_switch_write_cmd(self, cmdbyte):
301+ """Bit bang cmdbyte to I2C switch"""
302+
303+ self.i2c_write_cmd(self.i2c_switch_addr, cmdbyte)
304+ time.sleep(self.control_delay)
305+
306+ def i2c_switch_write_bsl_sequence(self, sequence):
307+ """\
308+ Write a sequence (array) of state tuples (RST, TEST) to the BSL pins
309+ """
310+
311+ for RST, TEST in sequence:
312+ if not self.invertRST:
313+ RST ^= 1
314+ if not self.invertTEST:
315+ TEST ^= 1
316+ if self.swapResetTest:
317+ S0 = TEST
318+ S1 = RST << 1
319+ else:
320+ S0 = RST
321+ S1 = TEST << 1
322+ self.i2c_switch_write_cmd(S0|S1)
323+
324+ def start_bsl(self):
325+ """\
326+ Start the ROM-BSL using the pulse pattern on TEST and RST.
327+ """
328+
329+ self.logger.info('ROM-BSL start pulse pattern')
330+
331+ # enabling switch port x connects that port to GND
332+ # i.e. setting bit x in the cmdbyte drives that pin to GND
333+
334+ # "BSL entry sequence at dedicated JTAG pins"
335+ # rst !s0: 0 0 0 0 1 1
336+ # tck !s1: 1 0 1 0 0 1
337+ # s0|s1: 1 3 1 3 2 0
338+
339+ # "BSL entry sequence at shared JTAG pins"
340+ # rst !s0: 0 0 0 0 1 1
341+ # tck !s1: 0 1 0 1 1 0
342+ # s0|s1: 3 1 3 1 0 2
343+
344+ bsl_entry_sequence = [
345+ # (rst, test)
346+ (0, 1),
347+ (0, 0),
348+ (0, 1),
349+ (0, 0),
350+ (1, 0),
351+ (1, 1),
352+ ]
353+
354+ self.i2c_switch_write_bsl_sequence(bsl_entry_sequence)
355+
356+ time.sleep(0.250) # give MSP430's oscillator time to stabilize
357+
358+ self.serial.flushInput() # clear buffers
359+
360+ def reset(self):
361+ """Reset the device."""
362+
363+ self.logger.info('Reset device')
364+
365+ # "Reset sequence"
366+ # rst !s0: 0 1 1
367+ # tck !s1: 0 0 1
368+ # s0|s1: 3 2 0
369+
370+ reset_sequence = [
371+ # (rst, test)
372+ (0, 0),
373+ (1, 0),
374+ (1, 1),
375+ ]
376+
377+ self.i2c_switch_write_bsl_sequence(reset_sequence)
378+
379+
380+def main():
381+ # run the main application
382+ bsl_target = TelosBTarget()
383+ bsl_target.main()
384+
385+if __name__ == '__main__':
386+ main()
387
388=== added symlink 'scripts/msp430-bsl-fcdprog'
389=== target is u'msp430-bsl-fcdprog.py'
390=== added file 'scripts/msp430-bsl-fcdprog.py'
391--- scripts/msp430-bsl-fcdprog.py 1970-01-01 00:00:00 +0000
392+++ scripts/msp430-bsl-fcdprog.py 2012-02-13 17:15:20 +0000
393@@ -0,0 +1,7 @@
394+#!/usr/bin/env python
395+
396+# command line stub for
397+# https://launchpad.net/python-msp430-tools
398+
399+import msp430.bsl.target.fcdprog
400+msp430.bsl.target.fcdprog.main()
401
402=== added symlink 'scripts/msp430-bsl-telosb'
403=== target is u'msp430-bsl-telosb.py'
404=== added file 'scripts/msp430-bsl-telosb.py'
405--- scripts/msp430-bsl-telosb.py 1970-01-01 00:00:00 +0000
406+++ scripts/msp430-bsl-telosb.py 2012-02-13 17:15:20 +0000
407@@ -0,0 +1,7 @@
408+#!/usr/bin/env python
409+
410+# command line stub for
411+# https://launchpad.net/python-msp430-tools
412+
413+import msp430.bsl.target.telosb
414+msp430.bsl.target.telosb.main()
415
416=== modified file 'setup.py'
417--- setup.py 2012-01-22 17:56:27 +0000
418+++ setup.py 2012-02-13 17:15:20 +0000
419@@ -22,6 +22,7 @@
420 'msp430',
421 'msp430.asm',
422 'msp430.bsl',
423+ 'msp430.bsl.target',
424 'msp430.bsl5',
425 'msp430.gdb',
426 'msp430.jtag',
427@@ -40,8 +41,10 @@
428 'msp430/bsl5/RAM_BSL.00.05.04.34.txt',
429 ]},
430 scripts=[
431+ 'scripts/msp430-bsl',
432 'scripts/msp430-bsl-legacy',
433- 'scripts/msp430-bsl',
434+ 'scripts/msp430-bsl-fcdprog',
435+ 'scripts/msp430-bsl-telosb',
436 'scripts/msp430-compare',
437 'scripts/msp430-convert',
438 'scripts/msp430-downloader',

Subscribers

People subscribed via source and target branches