📄 tos-bsl.in
字号:
def comDone(self):
"""Closes the used serial port.
This function must be called at the end of a program,
otherwise the serial port might not be released and can not be
used in other programs.
Returns zero if the function is successful."""
if DEBUG > 1: sys.stderr.write("* comDone()")
self.SetRSTpin(1) #disable power
self.SetTESTpin(0) #disable power
self.serialport.close()
def comRxHeader(self):
"""receive header and split data"""
if DEBUG > 1: sys.stderr.write("* comRxHeader()\n")
hdr = self.serialport.read(1)
if not hdr: raise BSLException("Timeout")
rxHeader = ord(hdr) & 0xf0;
rxNum = ord(hdr) & 0x0f;
if self.protocolMode == self.MODE_BSL:
self.reqNo = 0
self.seqNo = 0
rxNum = 0
if DEBUG > 1: sys.stderr.write("* comRxHeader() OK\n")
return rxHeader, rxNum
def comRxFrame(self, rxNum):
if DEBUG > 1: sys.stderr.write("* comRxFrame()\n")
rxFrame = chr(self.DATA_FRAME | rxNum)
if DEBUG > 2: sys.stderr.write(" comRxFrame() header...\n")
rxFramedata = self.serialport.read(3)
if len(rxFramedata) != 3: raise BSLException("Timeout")
rxFrame = rxFrame + rxFramedata
if DEBUG > 3: sys.stderr.write(" comRxFrame() check header...\n")
if rxFrame[1] == chr(0) and rxFrame[2] == rxFrame[3]: #Add. header info. correct?
rxLengthCRC = ord(rxFrame[2]) + 2 #Add CRC-Bytes to length
if DEBUG > 2: sys.stderr.write(" comRxFrame() receiving data, size: %s\n" % rxLengthCRC)
rxFramedata = self.serialport.read(rxLengthCRC)
if len(rxFramedata) != rxLengthCRC: raise BSLException("Timeout")
rxFrame = rxFrame + rxFramedata
#Check received frame:
if DEBUG > 3: sys.stderr.write(" comRxFrame() crc check\n")
#rxLength+4: Length with header but w/o CRC:
checksum = self.calcChecksum(rxFrame, ord(rxFrame[2]) + 4)
if rxFrame[ord(rxFrame[2])+4] == chr(0xff & checksum) and \
rxFrame[ord(rxFrame[2])+5] == chr(0xff & (checksum >> 8)): #Checksum correct?
#Frame received correctly (=> send next frame)
if DEBUG > 2: sys.stderr.write("* comRxFrame() OK\n")
return rxFrame
else:
if DEBUG: sys.stderr.write(" comRxFrame() Checksum wrong\n")
else:
if DEBUG: sys.stderr.write(" comRxFrame() Header corrupt %r" % rxFrame)
raise BSLException(self.ERR_COM) #Frame has errors!
def comTxHeader(self, txHeader):
"""send header"""
if DEBUG > 1: sys.stderr.write("* txHeader()\n")
self.serialport.write(txHeader)
def comTxRx(self, cmd, dataOut, length):
"""Sends the command cmd with the data given in dataOut to the
microcontroller and expects either an acknowledge or a frame
with result from the microcontroller. The results are stored
in dataIn (if not a NULL pointer is passed).
In this routine all the necessary protocol stuff is handled.
Returns zero if the function was successful."""
if DEBUG > 1: sys.stderr.write("* comTxRx()\n")
txFrame = []
rxHeader = 0
rxNum = 0
dataOut = list(dataOut) #convert to a list for simpler data fill in
#Transmitting part ----------------------------------------
#Prepare data for transmit
if (length % 2) != 0:
#/* Fill with one byte to have even number of bytes to send */
if self.protocolMode == self.MODE_BSL:
dataOut.append(0xFF) #fill with 0xFF
else:
dataOut.append(0) #fill with zero
txFrame = "%c%c%c%c" % (self.DATA_FRAME | self.seqNo, cmd, len(dataOut), len(dataOut))
self.reqNo = (self.seqNo + 1) % self.MAX_FRAME_COUNT
txFrame = txFrame + string.join(dataOut,'')
checksum = self.calcChecksum(txFrame, length + 4)
txFrame = txFrame + chr(checksum & 0xff)
txFrame = txFrame + chr((checksum >> 8) & 0xff)
accessAddr = (0x0212 + (checksum^0xffff)) & 0xfffe #0x0212: Address of wCHKSUM
if self.BSLMemAccessWarning and accessAddr < self.BSL_CRITICAL_ADDR:
sys.stderr.write("WARNING: This command might change data at address %04x or %04x!\n" % (accessAddr, accessAddr + 1))
self.serialport.flushInput() #clear receiving queue
#TODO: Check after each transmitted character,
#TODO: if microcontroller did send a character (probably a NAK!).
for c in txFrame:
self.serialport.write(c)
if DEBUG > 3: sys.stderr.write("\ttx %02x" % ord(c))
#if self.serialport.inWaiting(): break #abort when BSL replies, probably NAK
else:
if DEBUG > 1: sys.stderr.write( " comTxRx() transmit OK\n")
#Receiving part -------------------------------------------
rxHeader, rxNum = self.comRxHeader() #receive header
if DEBUG > 1: sys.stderr.write(" comTxRx() rxHeader=0x%02x, rxNum=%d, seqNo=%d, reqNo=%s\n" % (rxHeader, rxNum, self.seqNo, self.reqNo))
if rxHeader == self.DATA_ACK: #acknowledge/OK
if DEBUG > 2: sys.stderr.write(" comTxRx() DATA_ACK\n")
if rxNum == self.reqNo:
self.seqNo = self.reqNo
if DEBUG > 2: sys.stderr.write("* comTxRx() DATA_ACK OK\n")
return #Acknowledge received correctly => next frame
raise BSLException(self.ERR_FRAME_NUMBER)
elif rxHeader == self.DATA_NAK: #not acknowledge/error
if DEBUG > 2: sys.stderr.write("* comTxRx() DATA_NAK\n")
raise BSLException(self.ERR_RX_NAK)
elif rxHeader == self.DATA_FRAME: #receive data
if DEBUG > 2: sys.stderr.write("* comTxRx() DATA_FRAME\n")
if rxNum == self.reqNo:
rxFrame = self.comRxFrame(rxNum)
return rxFrame
raise BSLException(self.ERR_FRAME_NUMBER)
elif rxHeader == self.CMD_FAILED: #Frame ok, but command failed.
if DEBUG > 2: sys.stderr.write("* comTxRx() CMD_FAILED\n")
raise BSLException(self.ERR_CMD_FAILED)
raise BSLException("Unknown header 0x%02x\nAre you downloading to RAM into an old device that requires the patch? Try option -U" % rxHeader)
def SetDTR(self, level, invert):
"""Controls DTR pin (0: GND; 1: VCC; unless inverted flag is set)"""
if invert:
self.serialport.setDTR(not level)
else:
self.serialport.setDTR(level)
if self.slowmode:
time.sleep(0.040)
def SetRTS(self, level, invert):
"""Controls RTS pin (0: GND; 1: VCC; unless inverted flag is set)"""
if invert:
self.serialport.setRTS(not level)
else:
self.serialport.setRTS(level)
if self.slowmode:
time.sleep(0.040)
def SetRSTpin(self, level=1):
"""Controls RST/NMI pin (0: GND; 1: VCC; unless inverted flag is set)"""
if self.swapRSTTEST:
self.SetRTS(level, self.invertRST)
else:
self.SetDTR(level, self.invertRST)
def SetTESTpin(self, level=1):
"""Controls TEST pin (inverted on board: 0: VCC; 1: GND; unless inverted flag is set)"""
if self.swapRSTTEST:
self.SetDTR(level, self.invertTEST)
else:
self.SetRTS(level, self.invertTEST)
def telosSetSCL(self, level):
self.serialport.setRTS(not level)
def telosSetSDA(self, level):
self.serialport.setDTR(not level)
def telosI2CStart(self):
self.telosSetSDA(1)
self.telosSetSCL(1)
self.telosSetSDA(0)
def telosI2CStop(self):
self.telosSetSDA(0)
self.telosSetSCL(1)
self.telosSetSDA(1)
def telosI2CWriteBit(self, bit):
self.telosSetSCL(0)
self.telosSetSDA(bit)
time.sleep(2e-6)
self.telosSetSCL(1)
time.sleep(1e-6)
self.telosSetSCL(0)
def telosI2CWriteByte(self, byte):
self.telosI2CWriteBit( byte & 0x80 );
self.telosI2CWriteBit( byte & 0x40 );
self.telosI2CWriteBit( byte & 0x20 );
self.telosI2CWriteBit( byte & 0x10 );
self.telosI2CWriteBit( byte & 0x08 );
self.telosI2CWriteBit( byte & 0x04 );
self.telosI2CWriteBit( byte & 0x02 );
self.telosI2CWriteBit( byte & 0x01 );
self.telosI2CWriteBit( 0 ); # "acknowledge"
def telosI2CWriteCmd(self, addr, cmdbyte):
self.telosI2CStart()
self.telosI2CWriteByte( 0x90 | (addr << 1) )
self.telosI2CWriteByte( cmdbyte )
self.telosI2CStop()
def telosBReset(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.telosI2CWriteCmd(0,1)
self.telosI2CWriteCmd(0,3)
self.telosI2CWriteCmd(0,1)
self.telosI2CWriteCmd(0,3)
self.telosI2CWriteCmd(0,2)
self.telosI2CWriteCmd(0,0)
else:
self.telosI2CWriteCmd(0,3)
self.telosI2CWriteCmd(0,2)
self.telosI2CWriteCmd(0,0)
time.sleep(0.250) #give MSP430's oscillator time to stabilize
self.serialport.flushInput() #clear buffers
def bslReset(self, invokeBSL=0):
"""Applies BSL entry sequence on RST/NMI and TEST/VPP pins
Parameters:
invokeBSL = 1: complete sequence
invokeBSL = 0: only RST/NMI pin accessed
RST is inverted twice on boot loader hardware
TEST is inverted (only once)
Need positive voltage on DTR, RTS for power-supply of hardware"""
if self.telosI2C:
self.telosBReset(invokeBSL)
return
if DEBUG > 1: sys.stderr.write("* bslReset(invokeBSL=%s)\n" % invokeBSL)
self.SetRSTpin(1) #power suply
self.SetTESTpin(1) #power suply
time.sleep(0.250) #charge capacitor on boot loader hardware
if self.telosLatch:
self.SetTESTpin(0)
self.SetRSTpin(0)
self.SetTESTpin(1)
self.SetRSTpin(0) #RST pin: GND
if invokeBSL:
self.SetTESTpin(1) #TEST pin: GND
self.SetTESTpin(0) #TEST pin: Vcc
self.SetTESTpin(1) #TEST pin: GND
self.SetTESTpin(0) #TEST pin: Vcc
self.SetRSTpin (1) #RST pin: Vcc
self.SetTESTpin(1) #TEST pin: GND
else:
self.SetRSTpin(1) #RST pin: Vcc
time.sleep(0.250) #give MSP430's oscillator time to stabilize
self.serialport.flushInput() #clear buffers
def bslSync(self,wait=0):
"""Transmits Synchronization character and expects to receive Acknowledge character
if wait is 0 it must work the first time. otherwise if wait is 1
it is retried (forever).
"""
loopcnt = 5 #Max. tries to get synchronization
if DEBUG > 1: sys.stderr.write("* bslSync(wait=%d)\n" % wait)
while wait or loopcnt:
loopcnt = loopcnt - 1 #count down tries
self.serialport.flushInput() #clear input, in case a prog is running
self.serialport.write(chr(self.BSL_SYNC)) #Send synchronization byte
c = self.serialport.read(1) #read answer
if c == chr(self.DATA_ACK): #ACk
if DEBUG > 1: sys.stderr.write(" bslSync() OK\n")
return #Sync. successful
elif not c: #timeout
if loopcnt > 4:
if DEBUG > 1:
sys.stderr.write(" bslSync() timeout, retry ...\n")
elif loopcnt == 4:
#nmi may have caused the first reset to be ignored, try again
self.bslReset(0)
self.bslReset(1)
elif loopcnt > 0:
if DEBUG > 1:
sys.stderr.write(" bslSync() timeout, retry ...\n")
else :
if DEBUG > 1:
sys.stderr.write(" bslSync() timeout\n")
else: #garbage
if DEBUG > 1: sys.stderr.write(" bslSync() failed (0x%02x), retry ...\n" % ord(c))
raise BSLException(self.ERR_BSL_SYNC) #Sync. failed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -