Exemple #1
0
    def read_fuses(self, dev):
        """Reads the fuse and lock bits from the target and returns them as a named tuple."""

        # set up constants

        buf = [
            asm.ldi(29, RFLB | SPMEN),  # ldi r29, RFLB | SPMEN
            asm.ldi(31, 0),  # ldi r31, 0 ; (high byte of Z)
        ]

        # there are four bytes to read

        for index in reversed(range(4)):

            # read fuse/lock bit into r0

            buf += [
                asm.ldi(30, index),  # ldi r31, index ; (low byte of Z)
                asm.out(dev.reg_spmcsr, 29),  # out SPMCSR, r29 ; RFLB | SPMEN
                asm.lpm(),  # lpm
            ]

            # move into another register if not reading index 0

            if index != 0:
                buf += [
                    asm.mov(index, 0),  # mov r[index], r0
                ]

        # execute generated code

        self._exec(buf)

        # read r0-r3 which now contain the bytes that were read

        return Fuses(*self.read_regs(0, 4))
Exemple #2
0
    def read_fuses(self, dev):
        """Reads the fuse and lock bits from the target and returns them as a named tuple."""

        # set up constants

        buf = [
            asm.ldi(29, RFLB | SPMEN),       # ldi r29, RFLB | SPMEN
            asm.ldi(31, 0),                  # ldi r31, 0 ; (high byte of Z)
        ]

        # there are four bytes to read

        for index in reversed(range(4)):

            # read fuse/lock bit into r0

            buf += [
                asm.ldi(30, index),          # ldi r31, index ; (low byte of Z)
                asm.out(dev.reg_spmcsr, 29), # out SPMCSR, r29 ; RFLB | SPMEN
                asm.lpm(),                   # lpm
            ]

            # move into another register if not reading index 0

            if index != 0:
                buf += [
                    asm.mov(index, 0),       # mov r[index], r0
                ]

        # execute generated code

        self._exec(buf)

        # read r0-r3 which now contain the bytes that were read

        return Fuses(*self.read_regs(0, 4))
Exemple #3
0
    def write_flash_page(self, dev, start, data):
        if start % dev.flash_pagesize != 0:
            raise DWException("Bad page offset")

        if len(data) != dev.flash_pagesize:
            raise DWException("Bad page size")

        prof = (SimpleProfiler if self.enable_log else DummyProfiler)()
        prof.step("Starting page write")

        # set up constants in registers

        self.write_regs(
            26,
            [
                SPMEN,  # r26
                PGERS | SPMEN,  # r27
                PGWRT | SPMEN,  # r28
                CTPB | SPMEN,  # r29
                start & 0xff,
                (start >> 8) & 0xff  # r30:r31(Z)
            ])

        # clear self-programming buffer

        prof.step("Write constants")

        self._exec([
            asm.movw(24, 30),  # movw r24, r30
            asm.out(dev.reg_spmcsr, 29),  # out SPMCSR, r29 ; CTPB | SPMEN
            asm.spm()
        ])  # spm

        self.iface.send_break()

        prof.step("Clear buffer")

        # erase flash page

        self._exec([
            asm.out(dev.reg_spmcsr, 27),  # out SPMCSR, r27 ; PGERS | SPMEN
            asm.spm(),  # spm
        ])

        # wait for erase to complete
        self.iface.send_break()

        prof.step("Erase page")

        # write data to buffer

        # How many instruction bytes to write at once
        # The maximum suitable value for this is probably related to USB buffer sizes etc.
        CHUNK_LEN = 16

        for ci in range(0, len(data), CHUNK_LEN):
            buf = []

            for ii in range(ci, ci + CHUNK_LEN, 2):
                if dev.reg_dwdr:
                    buf += [
                        asm.in_(dev.reg_dwdr, 0),
                        bytes([data[ii]]),  # in r0, DWDR ; (low byte)
                        asm.in_(dev.reg_dwdr, 1),
                        bytes([data[ii + 1]])
                    ]  # in r1, DWDR ; (high byte)
                else:
                    buf += [
                        asm.ldi(22, data[ii]),  # ldi r22, (low byte)
                        asm.ldi(23, data[ii + 1]),  # ldi r23, (high byte)
                        asm.movw(0, 22)
                    ]  # movw r0, r22

                buf += [
                    asm.out(dev.reg_spmcsr, 26),  # out SPMCSR, r26 ; SPMEN
                    asm.spm(),  # spm
                    asm.adiw(30, 2)
                ]  # adiw Z, 2

            self._exec(buf)

        prof.step("Write data")

        # write buffer to flash

        self._exec([
            asm.movw(30, 24),  # movw r30, r24
            asm.out(dev.reg_spmcsr, 28),  # out SPMCSR, r28 ; PGWRT | SPMEN
            asm.spm()
        ])  # spm

        # wait for write to complete
        self.iface.send_break()

        prof.step("Write flash")
Exemple #4
0
    def write_flash_page(self, dev, start, data):
        if start % dev.flash_pagesize != 0:
            raise DWException("Bad page offset")

        if len(data) != dev.flash_pagesize:
            raise DWException("Bad page size")

        prof = (SimpleProfiler if self.enable_log else DummyProfiler)()
        prof.step("Starting page write")

        # set up constants in registers

        self.write_regs(26, [
            SPMEN,                            # r26
            PGERS | SPMEN,                    # r27
            PGWRT | SPMEN,                    # r28
            CTPB | SPMEN,                     # r29
            start & 0xff, (start >> 8) & 0xff # r30:r31(Z)
        ])

        # clear self-programming buffer

        prof.step("Write constants")

        self._exec([
            asm.movw(24, 30),            # movw r24, r30
            asm.out(dev.reg_spmcsr, 29), # out SPMCSR, r29 ; CTPB | SPMEN
            asm.spm()])                  # spm

        self.iface.send_break()

        prof.step("Clear buffer")

        # erase flash page

        self._exec([
            asm.out(dev.reg_spmcsr, 27), # out SPMCSR, r27 ; PGERS | SPMEN
            asm.spm(),                   # spm
        ])

        # wait for erase to complete
        self.iface.send_break()

        prof.step("Erase page")

        # write data to buffer

        # How many instruction bytes to write at once
        # The maximum suitable value for this is probably related to USB buffer sizes etc.
        CHUNK_LEN = 16

        for ci in range(0, len(data), CHUNK_LEN):
            buf = []

            for ii in range(ci, ci + CHUNK_LEN, 2):
                if dev.reg_dwdr:
                    buf += [
                        asm.in_(dev.reg_dwdr, 0), bytes([data[ii]]),     # in r0, DWDR ; (low byte)
                        asm.in_(dev.reg_dwdr, 1), bytes([data[ii + 1]])] # in r1, DWDR ; (high byte)
                else:
                    buf += [
                        asm.ldi(22, data[ii]),                           # ldi r22, (low byte)
                        asm.ldi(23, data[ii + 1]),                       # ldi r23, (high byte)
                        asm.movw(0, 22)]                                 # movw r0, r22

                buf += [
                    asm.out(dev.reg_spmcsr, 26),                         # out SPMCSR, r26 ; SPMEN
                    asm.spm(),                                           # spm
                    asm.adiw(30, 2)]                                     # adiw Z, 2

            self._exec(buf)

        prof.step("Write data")

        # write buffer to flash

        self._exec([
            asm.movw(30, 24),            # movw r30, r24
            asm.out(dev.reg_spmcsr, 28), # out SPMCSR, r28 ; PGWRT | SPMEN
            asm.spm()])                  # spm

        # wait for write to complete
        self.iface.send_break()

        prof.step("Write flash")