+class bsl_standard(BootStrapLoader):
+ """
+ This class supports the TI RS-232C programmer presented in slaa096d.
+ The programmer and the MSP430 being programmed are powered from power
+ scavenged off the DTR and RTS lines. Therefore, it is important that
+ DTR and RTS are asserted for some period before programming to charge
+ the programmer's power capacitor. Recall that an asserted RS-232
+ signal generates a voltage between +3v and +15v.
+
+ Per the documentation the signals' assertion states map as follows:
+ rs232.DTR -> (invert) -> msp430.RST
+ rs232.RTS -> (invert) -> msp430.TTCK
+ msp430.TTCK -> msp430.TCK
+ msp430.TTCK -> (invert) -> msp430.TEST
+ """
+ def __init__(self, *args, **kargs):
+ BootStrapLoader.__init__(self, *args, **kargs)
+
+ def mayuseBSL(self):
+ return 1
+
+ def speed(self):
+ return None
+
+ def setRST(self, assertme):
+ """
+ Calling setRST(1) asserts the RST signal at the msp430. Since RST
+ is active low, asserted=GND and unasserted=Vcc.
+
+ Do not override this method
+ """
+ self.lsetRST(assertme)
+ if (self.slowmode):
+ time.sleep(0.040)
+
+ def setTTCK(self, assertme):
+ """
+ Calling setTTCK(1) asserts TTCK. TTCK is a pseudo-signal that
+ acts as TCK and/or TEST. TCK is active high and TEST is active low.
+
+ Do not override this method
+ """
+ self.lsetTTCK(assertme)
+ if (self.slowmode):
+ time.sleep(0.040)
+
+ def lsetRST(self, assertme):
+ """ rs232.DTR -> (invert) -> msp430.RST """
+ self.serialport.setDTR(not assertme)
+
+ def lsetTTCK(self, assertme):
+ """ rs232.RTS -> (invert) -> msp430.TTCK """
+ self.serialport.setRTS(not assertme)
+
+ def bslInit(self):
+ """ Initial state: RST and TTCK are unasserted """
+ self.setRST(0)
+ self.setTTCK(0)
+
+ def bslPrepare(self):
+ """
+ bslInit unaserted RST and TTCK, which asserted DTR and RTS. Wait
+ a while to allow the programmer power cap to charge from the V+
+ supplied by DTR and RTS.
+ """
+ time.sleep(0.250)
+
+ def bslDone(self):
+ """ Unasserting RST and TTCK also cuts power to the programmer """
+ self.setRST(0)
+ self.setTTCK(0)
+
+ def bslReset(self, invokeBSL=0):
+ if DEBUG > 1: sys.stderr.write("* bslReset(invokeBSL=%s)\n" % invokeBSL)
+ self.bslInit()
+ self.bslPrepare()
+ self.setRST(1)
+ if invokeBSL:
+ self.setTTCK(1)
+ self.setTTCK(0)
+ self.setTTCK(1)
+ self.setRST(0)
+ self.setTTCK(0)
+ else:
+ self.setRST(0)
+ time.sleep(0.250) # Allow MSP430 oscillator time to stabilize
+ self.serialport.flushInput()
+
+
+class bsl_telosa(bsl_standard):
+ """
+ The telosa hardware allows for programming its MSP430 via a USB port
+ through a USB/serial chip. The mapping of serial to uC signals differ
+ from the standard TI bsl hardware supported in bsl_standard. DTR from
+ the USB/serial chip is tied directly to TCK and RST is configured
+ through inverters and a type D flip-flop to help prevent spurious uC
+ resets.
+
+ The signals' assertion states map as follows:
+ usbserial.RTS -> msp430.RST
+ usbserial.DTR -> msp430.TCK
+
+ When performing a bslReset(), RST must first be asserted by clearing
+ the onboard flip-flop:
+ assert usbserial.DTR
+ assert usbserial.RTS
+ unassert usbserial.DTR
+ """
+ def __init__(self, *args, **kargs):
+ bsl_standard.__init__(self, *args, **kargs)
+
+ def lsetRST(self, assertme):
+ """ rs232.RTS -> msp430.RST """
+ self.serialport.setRTS(assertme);
+
+ def lsetTTCK(self, assertme):
+ """ rs232.DTR -> msp430.TTCK """
+ self.serialport.setDTR(assertme);
+
+ def bslPrepare(self):
+ """ Run the standard bslPrepare, then set the telosa flip-flop """
+ bsl_standard.bslPrepare(self)
+ self.serialport.setDTR(1)
+ self.serialport.setRTS(1)
+ self.serialport.setDTR(0)
+
+
+class bsl_telosb(bsl_standard):
+ """
+ The telosb allows programming of its MSP430 via a USB port through a
+ USB/serial chip. It incorporates an I2C switch, whose SDA and SCL
+ inputs driven by the serial DTR and RTS signals. Switch outputs are
+ tied to the uC RST and TCK pins.
+
+ The signals' assertion states map as follows:
+ usbserial.RTS -> (invert) -> I2C.SCL
+ usbserial.DTR -> (invert) -> I2C.SDA
+ """
+ def __init__(self, *args, **kargs):
+ bsl_standard.__init__(self, *args, **kargs)
+
+ def mayuseBSL(self):
+ return 0
+
+ def speed(self):
+ return 38400
+
+ def setSCL(self, level):
+ self.serialport.setRTS(not level)
+
+ def setSDA(self, level):
+ self.serialport.setDTR(not level)
+
+ def i2cStart(self):
+ self.setSDA(1)
+ self.setSCL(1)
+ self.setSDA(0)
+
+ def i2cStop(self):
+ self.setSDA(0)
+ self.setSCL(1)
+ self.setSDA(1)
+
+ def i2cWriteBit(self, bit):
+ self.setSCL(0)
+ self.setSDA(bit)
+ time.sleep(2e-6)
+ self.setSCL(1)
+ time.sleep(1e-6)
+ self.setSCL(0)
+
+ def i2cWriteByte(self, byte):
+ self.i2cWriteBit( byte & 0x80 );
+ self.i2cWriteBit( byte & 0x40 );
+ self.i2cWriteBit( byte & 0x20 );
+ self.i2cWriteBit( byte & 0x10 );
+ self.i2cWriteBit( byte & 0x08 );
+ self.i2cWriteBit( byte & 0x04 );
+ self.i2cWriteBit( byte & 0x02 );
+ self.i2cWriteBit( byte & 0x01 );
+ self.i2cWriteBit( 0 ); # "acknowledge"
+
+ def i2cWriteCmd(self, addr, cmdbyte):
+ self.i2cStart()
+ self.i2cWriteByte( 0x90 | (addr << 1) )
+ self.i2cWriteByte( cmdbyte )
+ self.i2cStop()
+
+ def bslInit(self):
+ """ Not needed for telosb """
+
+ def bslDone(self):
+ """ Not needed for telosb """
+
+ def bslReset(self,invokeBSL=0):
+ # "BSL entry sequence at dedicated JTAG pins"
+ # rst !s0: 0 0 0 0 1 1
+ # tck !s1: 1 0 1 0 0 1
+ # s0|s1: 1 3 1 3 2 0
+
+ # "BSL entry sequence at shared JTAG pins"
+ # rst !s0: 0 0 0 0 1 1
+ # tck !s1: 0 1 0 1 1 0
+ # s0|s1: 3 1 3 1 0 2
+
+ if invokeBSL:
+ self.i2cWriteCmd(0,1)
+ self.i2cWriteCmd(0,3)
+ self.i2cWriteCmd(0,1)
+ self.i2cWriteCmd(0,3)
+ self.i2cWriteCmd(0,2)
+ self.i2cWriteCmd(0,0)
+ else:
+ self.i2cWriteCmd(0,3)
+ self.i2cWriteCmd(0,2)
+ self.i2cWriteCmd(0,0)
+ time.sleep(0.250) #give MSP430's oscillator time to stabilize
+ self.serialport.flushInput() #clear buffers
+
+
+class bsl_cp2103(bsl_standard):
+ """
+ Some boards allow programming of their MSP430 via an onboard cp2103
+ USB/serial chip configured such that two of its gpio pins are tied
+ directly to the RST and TCK pins of the uC. In this configuration the
+ RST and TCK signals are pulled up and the cp2103's gpio pins are
+ configured as open drain outputs. The gpio pins are active low and
+ are unasserted on power-up.
+
+ The signals' assertion states map as follows:
+ usbserial.GPIO_3 -> msp430.RST
+ usbserial.GPIO_2 -> msp430.TCK
+ """
+ def __init__(self, *args, **kargs):
+ bsl_standard.__init__(self, *args, **kargs)
+ self.cp2103 = None
+
+ def mayuseBSL(self):
+ return 0
+
+ def speed(self):
+ return 38400
+
+ def lsetRST(self, assertme):
+ """ usbserial.GPIO_3 -> msp430.RST """
+ self.cp2103.setGpio3(assertme);
+
+ def lsetTTCK(self, assertme):
+ """ usbserial.GPIO_2 -> msp430.TTCK """
+ self.cp2103.setGpio2(assertme);
+
+ def bslInit(self):
+ if not self.cp2103:
+ # We can't define cp2103 until the first call to bslInit, since
+ # self.serialport is not instantiated until then.
+ self.cp2103 = cp2103_factory(self.serialport)
+ bsl_standard.bslInit(self)
+
+
+GPIOBIC = 0x89f2
+GPIOBIS = 0x89f3
+GPIO_2 = 0x04
+GPIO_3 = 0x08
+
+class cp2103_posix:
+ """
+ Implements cp2103 gpio access for posix systems using ioctl() calls.
+ Requires a cp210x driver providing gpio control.
+ """
+ def __init__(self, serialport):
+ sys.stderr.write("cp2103_posix\n")
+ self.fd = serialport.fd
+
+ def setGpio2(self, assertme):
+ """ set not assertme to the gpio pin """
+ if not self.fd: raise "connection not open"
+ if assertme:
+ fcntl.ioctl(self.fd, GPIOBIC, GPIO_2)
+ else:
+ fcntl.ioctl(self.fd, GPIOBIS, GPIO_2)
+ time.sleep(0.010) # no sleep = too fast
+
+ def setGpio3(self, assertme):
+ """ set not assertme to the gpio pin """
+ if not self.fd: raise "connection not open"
+ if assertme:
+ fcntl.ioctl(self.fd, GPIOBIC, GPIO_3)
+ else:
+ fcntl.ioctl(self.fd, GPIOBIS, GPIO_3)
+ time.sleep(0.010) # no sleep = too fast
+
+
+class cp2103_cygwin:
+ """
+ Implements cp2103 gpio access for windows cygwin systems via the
+ cp210x VCP and the CP210xRuntime.dll.
+ """
+ def __init__(self, serialport):
+ import cp210xrt
+ sys.stderr.write("cp2103_cygwin\n")
+ self.fd = serialport.fd
+
+ def setGpio2(self, assertme):
+ """ set not assertme to the gpio pin """
+ import cp210xrt
+ if assertme:
+ cp210xrt.writeLatch(self.fd, GPIO_2, 0)
+ else:
+ cp210xrt.writeLatch(self.fd, GPIO_2, GPIO_2)
+
+ def setGpio3(self, assertme):
+ """ set not assertme to the gpio pin """
+ import cp210xrt
+ if assertme:
+ cp210xrt.writeLatch(self.fd, GPIO_3, 0)
+ else:
+ cp210xrt.writeLatch(self.fd, GPIO_3, GPIO_3)
+
+
+def cp2103_factory(serialport):
+ import os;
+ if os.name == 'posix':
+ if sys.platform == 'cygwin':
+ return cp2103_cygwin(serialport)
+ else:
+ return cp2103_posix(serialport)
+ else:
+ raise "No cp2103 support is available for your platform."
+
+
+def getClass(classname, modulename="__main__"):
+ """ Used by main() to select the appropriate bsl class based on device """
+ return getattr(__import__(modulename, globals(), locals(), [classname]),
+ classname)
+
+