aboutsummaryrefslogtreecommitdiff
path: root/ui_remote.py
blob: c4f5c996b4d0d676841335b631a1e6c44e6580a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/env python

# ui_remote.py - naive script to poke and prod the altimeter firmware over
# GDB/MI. Useful for rapid UI development/testing, all while probably not being
# strictly threadsafe. We're not triggering an ISR on the remote, so PC could
# already be in the middle of an ISR when we fire a UI event, which should
# never be allowed to happen in normal use.
# Useful nonetheless.
#
# FIXME allow smarter queueing of UI events in this script so they can be
#       batched into the same (slow) interrupt-and-continue window.
#

import atexit
import curses
import pygdbmi.gdbcontroller
import sys


def interrupt_run_continue(mi, command):
    mi.write('interrupt')
    mi.write(command)
    mi.write('continue &')


def main():
    def curses_init():
        stdscr = curses.initscr()
        curses.cbreak()
        curses.noecho()
        return stdscr

    def curses_end():
        curses.nocbreak()
        stdscr.keypad(False)
        curses.echo()
        curses.endwin()

    # Give pygdbmi hardcoded GDB, ELF paths, remote. Good enough for now
    mi = pygdbmi.gdbcontroller.GdbController(
        command=["/usr/bin/avr-gdb", '--interpreter=mi3'])
    mi.write('file build/altimeter_sim.elf', timeout_sec=5)
    mi.write('target remote :1234')
    mi.write('continue &')

    # atexit covers crash cases which is nice
    atexit.register(curses_end)
    stdscr = curses_init()

    stdscr.addstr(0, 0, "UI remote control via GDB. Press q to quit")
    stdscr.addstr(1, 0, "w: up  s: down  a: hold  d: short press")
    running = True
    while running:
        stdscr.addstr(2, 0, "ready")
        stdscr.clrtoeol()
        key = stdscr.getch()
        stdscr.addstr(2, 0, "busy")
        stdscr.clrtoeol()
        stdscr.refresh()
        if key == ord('q'):
            running = False
        elif key == ord('w'):
            interrupt_run_continue(mi, 'call up()')
        elif key == ord('s'):
            interrupt_run_continue(mi, 'call down()')
        elif key == ord('a'):
            interrupt_run_continue(mi, 'call hold()')
        elif key == ord('d'):
            interrupt_run_continue(mi, 'call press()')
        else:
            stdscr.addstr(1, 0, str(key))


if __name__ == "__main__":
    sys.exit(main())