Example #1
0
def test_program(success):
    # prepare
    calls = []
    fpga = TinyFPGAB(None, lambda *a: calls.append(('progress', a)))
    # patching methods
    fpga.erase = lambda *a: calls.append(('erase', a))
    fpga.write = lambda *a: calls.append(('write', a))
    if success:
        fpga.read = lambda *a: calls.append(('read', a)) or DATA
    else:
        fpga.read = lambda *a: calls.append(('read', a)) or 'This is a fail'
    # run
    output = fpga.program(0x123456, DATA)
    # check
    assert output == success
    expected_calls = [
        ('progress', ('Erasing designated flash pages', )),
        ('erase', (0x123456, 35)),
        ('progress', ('Writing bitstream', )),
        ('write', (0x123456, DATA)),
        ('progress', ('Verifying bitstream', )),
        ('read', (0x123456, 35)),
    ]

    if success:
        expected_calls.extend([
            ('progress', ('Success!',)),
        ])
    else:
        expected_calls.extend([
            ('progress', ('Need to rewrite some pages...',)),
            ('progress', ('len: 000023 00000e',)),
            ('progress', ('rewriting page 123456',)),
            ('erase', (1193046, 35)),
            ('write', (1193046, b'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('erase', (1193046, 35)),
            ('write', (1193046, b'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('erase', (1193046, 35)),
            ('write', (1193046, b'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('erase', (1193046, 35)),
            ('write', (1193046, b'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('erase', (1193046, 35)),
            ('write', (1193046, b'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('erase', (1193046, 35)),
            ('write', (1193046, b'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('progress', ('Verification Failed!',)),
        ])

    assert calls == expected_calls
Example #2
0
def test_program(success):
    # prepare
    calls = []
    fpga = TinyFPGAB(None, lambda *a: calls.append(('progress', a)))
    # patching methods
    fpga.erase = lambda *a: calls.append(('erase', a))
    fpga.write = lambda *a: calls.append(('write', a))
    if success:
        fpga.read = lambda *a: calls.append(('read', a)) or DATA
    else:
        fpga.read = lambda *a: calls.append(('read', a)) or 'This is a fail'
    # run
    output = fpga.program(0x123456, DATA)
    # check
    assert output == success
    expected_calls = [
        ('progress', ('Erasing designated flash pages', )),
        ('erase', (0x123456, 35)),
        ('progress', ('Writing bitstream', )),
        ('write', (0x123456, DATA)),
        ('progress', ('Verifying bitstream', )),
        ('read', (0x123456, 35)),
    ]

    if success:
        expected_calls.extend([
            ('progress', ('Success!', )),
        ])
    else:
        expected_calls.extend([
            ('progress', ('Need to rewrite some pages...', )),
            ('progress', ('len: 000023 00000e', )),
            ('progress', ('rewriting page 123456', )),
            ('erase', (1193046, 35)),
            ('write', (1193046, 'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('erase', (1193046, 35)),
            ('write', (1193046, 'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('erase', (1193046, 35)),
            ('write', (1193046, 'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('erase', (1193046, 35)),
            ('write', (1193046, 'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('erase', (1193046, 35)),
            ('write', (1193046, 'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('erase', (1193046, 35)),
            ('write', (1193046, 'Thequickbrownfoxjumpsoverthelazydog')),
            ('read', (1193046, 35)),
            ('progress', ('Verification Failed!', )),
        ])

    assert calls == expected_calls
Example #3
0
def test_program_bitstream(success):
    # prepare
    calls = []
    fpga = TinyFPGAB(None, lambda *a: calls.append(('progress', a)))
    # patching methods
    fpga.wake = lambda *a: calls.append(('wake', a))
    fpga.read_sts = lambda *a: calls.append(('read_sts', a))
    fpga.read = lambda *a: calls.append(('read', a))
    if success:
        fpga.program = lambda *a: calls.append(('program', a)) or True
    else:
        fpga.program = lambda *a: calls.append(('program', a)) or False
    fpga.boot = lambda *a: calls.append(('boot', a))
    # run
    output = fpga.program_bitstream(0x123456, DATA)
    # check
    assert output == success
    expected_calls = [
        ('progress', ('Waking up SPI flash', )),
        ('progress', ('35 bytes to program', )),
        ('program', (0x123456, DATA)),
    ]
    if success:
        expected_calls.append(('boot', ()))
    assert calls == expected_calls
Example #4
0
def test_program_bitstream(success):
    # prepare
    calls = []
    fpga = TinyFPGAB(None, lambda *a: calls.append(('progress', a)))
    # patching methods
    fpga.wake = lambda *a: calls.append(('wake', a))
    fpga.read_sts = lambda *a: calls.append(('read_sts', a))
    fpga.read = lambda *a: calls.append(('read', a))
    if success:
        fpga.program = lambda *a: calls.append(('program', a)) or True
    else:
        fpga.program = lambda *a: calls.append(('program', a)) or False
    fpga.boot = lambda *a: calls.append(('boot', a))
    # run
    output = fpga.program_bitstream(0x123456, DATA)
    # check
    assert output == success
    expected_calls = [
        ('progress', ('Waking up SPI flash', )),
        ('progress', ('35 bytes to program', )),
        ('program', (0x123456, DATA)),
    ]
    if success:
        expected_calls.append(('boot', ()))
    assert calls == expected_calls
Example #5
0
def test_read(length, serial_outs):
    # prepare
    serial = FakeSerial(DATA[:length])
    fpga = TinyFPGAB(serial)
    # run
    output = fpga.read(0x123456, length)
    # check
    assert output == DATA[:length]
    assert not serial.read_data
    serial.assert_written([d.decode('hex') for d in serial_outs])
Example #6
0
def test_read(length, serial_outs):
    # prepare
    serial = FakeSerial(DATA[:length])
    fpga = TinyFPGAB(serial)
    # run
    output = fpga.read(0x123456, length)
    # check
    assert output == DATA[:length]
    assert not serial.read_data
    serial.assert_written([bytearray.fromhex(d) for d in serial_outs])
Example #7
0
def test_program(success):
    # prepare
    calls = []
    fpga = TinyFPGAB(None, lambda *a: calls.append(('progress', a)))
    # patching methods
    fpga.erase = lambda *a: calls.append(('erase', a))
    fpga.write = lambda *a: calls.append(('write', a))
    if success:
        fpga.read = lambda *a: calls.append(('read', a)) or DATA
    else:
        fpga.read = lambda *a: calls.append(('read', a)) or 'This is a fail'
    # run
    output = fpga.program(0x123456, DATA)
    # check
    assert output == success
    assert calls == [
        ('progress', ('Erasing designated flash pages', )),
        ('erase', (0x123456, 35)),
        ('progress', ('Writing bitstream', )),
        ('write', (0x123456, DATA)),
        ('progress', ('Verifying bitstream', )),
        ('read', (0x123456, 35)),
        ('progress', ('Success!' if success else 'Verification Failed!', )),
    ]
Example #8
0
def test_is_bootloader_active(success_after):
    # prepare
    calls = []
    fpga = TinyFPGAB(None)
    read_id = ['ABC'] * success_after + ['\x1f\x84\x01']
    # patching methods
    fpga.wake = lambda *a: calls.append(('wake', a))
    fpga.read = lambda *a: calls.append(('read', a))
    fpga.read_id = lambda *a: calls.append(('read_id', a)) or read_id.pop(0)
    # run
    output = fpga.is_bootloader_active()
    # check
    assert output == (success_after < 6)
    expected_calls = [
        ('wake', ()),
        ('read', (0, 16)),
        ('wake', ()),
        ('read_id', ()),
    ] * min(success_after + 1, 6)
    assert calls == expected_calls
Example #9
0
def test_is_bootloader_active(success_after):
    # prepare
    calls = []
    fpga = TinyFPGAB(None)
    read_id = ['ABC'] * success_after + [b'\x1f\x84\x01']
    # patching methods
    fpga.wake = lambda *a: calls.append(('wake', a))
    fpga.read = lambda *a: calls.append(('read', a))
    fpga.read_id = lambda *a: calls.append(('read_id', a)) or read_id.pop(0)
    # run
    output = fpga.is_bootloader_active()
    # check
    assert output == (success_after < 6)
    expected_calls = [
        ('wake', ()),
        ('read', (0, 16)),
        ('wake', ()),
        ('read_id', ()),
    ] * min(success_after + 1, 6)
    assert calls == expected_calls
Example #10
0
def test_erase(offset, length, block_len, serial_outs):
    # prepare
    calls = []
    serial = FakeSerial()
    fpga = TinyFPGAB(serial)
    fpga.write_enable = lambda: None  # patch write_enable
    fpga.wait_while_busy = lambda: None  # patch wait_while_busy
    fpga.read = lambda *a: calls.append(('read', a)) \
        or DATA_4096[a[0] % 4096:][:a[1]]
    fpga.write = lambda *a: calls.append(('write', a))
    # run
    assert fpga.erase(offset, length) is None
    # check
    assert not serial.read_data
    serial.assert_written([d.decode('hex') for d in serial_outs])
    expected_calls = []
    restore_first_block = None
    if offset % block_len > 0:  # restore start of first block
        restore_offset = offset & ~(block_len - 1)
        restore_len = offset % block_len
        expected_calls.append(('read', (restore_offset, restore_len)))
        expected_calls.append(
            ('write', (restore_offset, DATA_4096[:restore_len])))
        restore_first_block = restore_offset
    if (offset + length) % block_len > 0:  # restore end of last block
        restore_offset = offset + length
        restore_len = block_len - (restore_offset % block_len)
        read_call = ('read', (restore_offset, restore_len))
        if restore_first_block == ((offset + length) & ~(block_len - 1)):
            # restore before and after erase in same block
            expected_calls.insert(1, read_call)  # 2nd read before 1st write
        else:
            expected_calls.append(read_call)  # 2nd read after 1st write
        expected_calls.append(
            ('write', (restore_offset,
                       DATA_4096[restore_offset % block_len:])))
    assert calls == expected_calls
Example #11
0
def test_erase(offset, length, block_len, serial_outs):
    # prepare
    calls = []
    serial = FakeSerial()
    fpga = TinyFPGAB(serial)
    fpga.write_enable = lambda: None  # patch write_enable
    fpga.wait_while_busy = lambda: None  # patch wait_while_busy
    fpga.read = lambda *a: calls.append(('read', a)) \
        or DATA_4096[a[0] % 4096:][:a[1]]
    fpga.write = lambda *a: calls.append(('write', a))
    # run
    assert fpga.erase(offset, length) is None
    # check
    assert not serial.read_data
    serial.assert_written([bytearray.fromhex(d) for d in serial_outs])
    expected_calls = []
    restore_first_block = None
    if offset % block_len > 0:  # restore start of first block
        restore_offset = offset & ~(block_len - 1)
        restore_len = offset % block_len
        expected_calls.append((
            'read', (restore_offset, restore_len)))
        expected_calls.append((
            'write', (restore_offset, DATA_4096[:restore_len])))
        restore_first_block = restore_offset
    if (offset + length) % block_len > 0:  # restore end of last block
        restore_offset = offset + length
        restore_len = block_len - (restore_offset % block_len)
        read_call = ('read', (restore_offset, restore_len))
        if restore_first_block == ((offset + length) & ~(block_len - 1)):
            # restore before and after erase in same block
            expected_calls.insert(1, read_call)  # 2nd read before 1st write
        else:
            expected_calls.append(read_call)  # 2nd read after 1st write
        expected_calls.append((
            'write', (restore_offset, DATA_4096[restore_offset % block_len:])))
    assert calls == expected_calls