Esempio n. 1
0
 def set_baudrate(self, baudrate):
     """\
     Change the BSL baud rate on the target and switch the serial port.
     """
     family = msp430.target.identify_device(self.device_id, self.bsl_version)
     if family == msp430.target.F1x:
         table = F1x_baudrate_args
     elif family == msp430.target.F2x:
         table = F2x_baudrate_args
     elif family == msp430.target.F4x:
         table = F4x_baudrate_args
     else:
         raise bsl.BSLError('No baud rate table for {}'.format(family))
     self.logger.info('changing baud rate to {}'.format(baudrate))
     try:
         a, l = table[baudrate]
     except:
         raise ValueError('unsupported baud rate {}'.format(baudrate))
     else:
         self.BSL_CHANGEBAUD(a, l)
         time.sleep(0.010)   # recommended delay
         self.serial.baudrate = baudrate
Esempio n. 2
0
    def open_connection(self):
        self.logger = logging.getLogger('BSL')
        self.open(
            self.options.port,
            ignore_answer=self.options.ignore_answer,
        )
        self.control_delay = self.options.control_delay

        if self.options.extra_erase_cycles is not None:
            self.main_erase_cycles += self.options.extra_erase_cycles

        if self.options.test_on_tx:
            self.testOnTX = True

        if self.options.invert_test:
            self.invertTEST = True

        if self.options.invert_reset:
            self.invertRST = True

        if self.options.swap_reset_test:
            self.swapResetTest = True

        self.set_TEST(True)
        self.set_RST(True)

        if self.options.start_pattern:
            self.start_bsl(self.options.prompt_before_release)

        if self.options.do_mass_erase:
            self.extra_timeout = 6
            self.mass_erase()
            self.extra_timeout = None
            self.BSL_TXPWORD('\xff' * 32)
            # remove mass_erase from action list so that it is not done
            # twice
            self.remove_action(self.mass_erase)
        else:
            if self.options.password is not None:
                password = msp430.memory.load(self.options.password).get_range(
                    0xffe0, 0xffff)
                self.logger.info('Transmitting password: {}'.format(
                    password.encode('hex')))
                self.BSL_TXPWORD(password)

        # check for extended features (e.g. >64kB support)
        self.logger.debug('Checking if device has extended features')
        self.check_extended()

        if self.options.replace_bsl:
            family = msp430.target.identify_device(self.device_id,
                                                   self.bsl_version)
            if family == msp430.target.F1x:
                bsl_name = 'BL_150S_14x.txt'
            elif family == msp430.target.F4x:
                bsl_name = 'BL_150S_44x.txt'
            else:
                raise bsl.BSLError('No replacement BSL for {}'.format(family))

            self.logger.info(
                'Download replacement BSL as requested by --replace-bsl')
            replacement_bsl_txt = pkgutil.get_data('msp430.bsl', bsl_name)
            replacement_bsl = msp430.memory.load('BSL',
                                                 BytesIO(replacement_bsl_txt),
                                                 format='titext')
            self.program_file(replacement_bsl)

            bsl_start_address = struct.unpack("<H",
                                              replacement_bsl.get(0x0220,
                                                                  2))[0]
            self.execute(bsl_start_address)
            self.logger.info(
                'Starting new BSL at 0x{:04x}'.format(bsl_start_address))
            time.sleep(0.050)  # give BSL some time to initialize
            #~ if self.options.password is not None:
            #~ self.BSL_TXPWORD(password)
        else:
            if self.bsl_version <= 0x0110:
                self.logger.info('Buggy BSL, applying patch')
                patch_txt = pkgutil.get_data('msp430.bsl', 'patch.txt')
                patch = msp430.memory.load('PATCH',
                                           BytesIO(patch_txt),
                                           format='titext')
                self.program_file(patch)
                self.patch_in_use = True

        if self.options.speed is not None:
            try:
                self.set_baudrate(self.options.speed)
            except bsl.BSLError:
                raise bsl.BSLError(
                    "--speed option not supported by BSL on target")
Esempio n. 3
0
    def bsl(self, cmd, message='', expect=None):
        """\
        Low level access to the serial communication.

        This function sends a command and waits until it receives an answer
        (including timeouts). It will return a string with the data part of
        the answer (an empty string for simple DATA_ACKs). In case of a failure
        read timeout or rejected commands by the slave, it will raise an
        exception.

        If the parameter "expect" is not None, "expect" bytes are expected in
        the answer, an exception is raised if the answer length does not match.
        If "expect" is None, DATA_ACK and DATA_FRAME are accepted and the
        answer is just returned.

        Frame format:
        +-----+-----+----+----+-----------+----+----+
        | HDR | CMD | L1 | L2 | D1 ... DN | CL | CH |
        +-----+-----+----+----+-----------+----+----+
        """
        # first synchronize with slave
        self.sync()
        self.logger.debug('Command 0x{:02x} {}'.format(cmd,
                                                       message.encode('hex')))
        # prepare command with checksum
        txdata = struct.pack('<cBBB', bsl.DATA_FRAME, cmd, len(message),
                             len(message)) + message
        txdata += struct.pack('<H',
                              self.checksum(txdata)
                              ^ 0xffff)  # append checksum
        #~ self.logger.debug('Sending command: %r' % (txdata,))
        # transmit command
        self.serial.write(txdata)
        # wait for command answer
        if self.blindWrite:
            time.sleep(0.100)
            return
        if self.ignore_answer:
            return
        self.logger.debug('Reading answer...')
        if self.extra_timeout is None:
            ans = self.serial.read(1)
        else:
            for timeout in range(self.extra_timeout):
                ans = self.serial.read(1)
                if ans:
                    break
        # depending on answer type, read more, raise exceptions etc.
        if ans == '':
            raise bsl.BSLTimeout('timeout while reading answer (ack)')
        elif ans == bsl.DATA_NAK:
            self.logger.debug('Command failed (DATA_NAK)')
            raise bsl.BSLError('command failed (DATA_NAK)')
        elif ans == bsl.CMD_FAILED:
            self.logger.debug('Command failed (CMD_FAILED)')
            raise bsl.BSLError('command failed (CMD_FAILED)')
        elif ans == bsl.DATA_ACK:
            self.logger.debug('Simple ACK')
            if expect is not None and expect > 0:
                raise bsl.BSLError('expected data, but received a simple ACK')
            return ''
        elif ans == bsl.DATA_FRAME:
            self.logger.debug('Data frame...')
            head = self.serial.read(3)
            if len(head) != 3:
                raise bsl.BSLTimeout('timeout while reading answer (header)')
            (self.dummy, l1, l2) = struct.unpack('<BBB', head)
            if l1 != l2:
                raise bsl.BSLError('broken answer (L1 != L2)')
            if l1:
                data = self.serial.read(l1)
                if len(data) != l1:
                    raise bsl.BSLTimeout('timeout while reading answer (data)')
            else:
                data = ''
            checksum = self.serial.read(2)
            if len(checksum) != 2:
                raise bsl.BSLTimeout('timeout while reading answer (checksum)')
            if self.checksum(ans + head + data) ^ 0xffff == struct.unpack(
                    "<H", checksum)[0]:
                if expect is not None and len(data) != expect:
                    raise bsl.BSLError(
                        'expected {} bytes, got {} bytes'.format(
                            expect, len(data)))
                self.logger.debug('Data frame: {}'.format(data.encode('hex')))
                return data
            else:
                raise bsl.BSLError('checksum error in answer')
        else:
            self.logger.debug('unexpected answer {!r}'.format(ans))
            raise bsl.BSLError('unexpected answer: {!r}'.format(ans))