comparison service/arduinoNode/write_arduino_code.py @ 229:07ee72a042db

refactor to write_arduino_node Ignore-this: 7b613fe7aa1cef2c88f190db1fcc1c4a
author drewp@bigasterisk.com
date Thu, 28 Jan 2016 00:21:31 -0800
parents
children 3010238b94a0
comparison
equal deleted inserted replaced
228:f609e1eee4db 229:07ee72a042db
1 import tempfile, subprocess, logging, os
2 log = logging.getLogger('arduino_code')
3
4 def writeMakefile(dev, tag, allLibs):
5 return '''
6 BOARD_TAG = %(tag)s
7 USER_LIB_PATH := %(libs)s
8 ARDUINO_LIBS = %(arduinoLibs)s
9 MONITOR_PORT = %(dev)s
10
11 include /usr/share/arduino/Arduino.mk
12 ''' % {
13 'dev': dev,
14 'tag': tag,
15 'libs': os.path.abspath('arduino-libraries'),
16 'arduinoLibs': ' '.join(allLibs),
17 }
18
19 def writeCode(baudrate, devs, devCommandNum):
20 generated = {
21 'baudrate': baudrate,
22 'includes': '',
23 'global': '',
24 'setups': '',
25 'polls': '',
26 'idles': '',
27 'actions': '',
28 }
29 for attr in ['includes', 'global', 'setups', 'polls', 'idles',
30 'actions']:
31 for dev in devs:
32 if attr == 'includes':
33 gen = '\n'.join('#include "%s"\n' % inc
34 for inc in dev.generateIncludes())
35 elif attr == 'global': gen = dev.generateGlobalCode()
36 elif attr == 'setups': gen = dev.generateSetupCode()
37 elif attr == 'polls': gen = dev.generatePollCode()
38 elif attr == 'idles': gen = dev.generateIdleCode()
39 elif attr == 'actions':
40 code = dev.generateActionCode()
41 if code:
42 gen = '''else if (cmd == %(cmdNum)s) {
43 %(code)s
44 Serial.write('k');
45 }
46 ''' % dict(cmdNum=devCommandNum[dev.uri],
47 code=code)
48 else:
49 gen = ''
50 else:
51 raise NotImplementedError
52
53 if gen:
54 generated[attr] += '// for %s\n%s\n' % (dev.uri, gen.strip())
55
56 code = '''
57 %(includes)s
58
59 %(global)s
60 byte frame=1;
61 unsigned long lastFrame=0;
62
63 void setup() {
64 Serial.begin(%(baudrate)d);
65 Serial.flush();
66 %(setups)s
67 }
68
69 void idle() {
70 // this slowdown is to spend somewhat less time PWMing, to reduce
71 // leaking from on channels to off ones (my shift register has no
72 // latching)
73 if (micros() < lastFrame + 80) {
74 return;
75 }
76 lastFrame = micros();
77 frame++;
78 %(idles)s
79 }
80
81 void loop() {
82 byte head, cmd;
83 idle();
84 if (Serial.available() >= 2) {
85 head = Serial.read();
86 if (head != 0x60) {
87 Serial.flush();
88 return;
89 }
90 cmd = Serial.read();
91 if (cmd == 0x00) { // poll
92 %(polls)s
93 Serial.write('x');
94 } else if (cmd == 0x01) { // get code checksum
95 Serial.write("CODE_CHECKSUM");
96 }
97 %(actions)s
98 }
99 }
100 ''' % generated
101 return code
102
103 def indent(code):
104 try:
105 with tempfile.SpooledTemporaryFile() as codeFile:
106 codeFile.write(code)
107 codeFile.seek(0)
108 code = subprocess.check_output([
109 'indent',
110 '-linux',
111 '-fc1', # ok to indent comments
112 '-i4', # 4-space indent
113 '-sob' # swallow blanks (not working)
114 ], stdin=codeFile)
115 except OSError as e:
116 log.warn("indent failed (%r)", e)
117 return code
118