comparison service/arduinoNode/arduinoNode.py @ 1034:43a2170bbdb8

refactor to write_arduino_node Ignore-this: 7b613fe7aa1cef2c88f190db1fcc1c4a darcs-hash:c3e034630c13dbaf7a73397f82ffc0da68be32fb
author drewp <drewp@bigasterisk.com>
date Thu, 28 Jan 2016 00:21:31 -0800
parents 208b960fde31
children 0aa54404df19
comparison
equal deleted inserted replaced
1033:bf03f5185e8f 1034:43a2170bbdb8
12 from rdflib.parser import StringInputSource 12 from rdflib.parser import StringInputSource
13 from twisted.internet import reactor, task 13 from twisted.internet import reactor, task
14 from docopt import docopt 14 from docopt import docopt
15 15
16 import devices 16 import devices
17 import write_arduino_code
17 import dotrender 18 import dotrender
18 import rdflib_patch 19 import rdflib_patch
19 rdflib_patch.fixQnameOfUriWithTrailingSlash() 20 rdflib_patch.fixQnameOfUriWithTrailingSlash()
20 21
21 logging.basicConfig(level=logging.DEBUG) 22 logging.basicConfig(level=logging.DEBUG)
170 log.info("Board %s doesn't care about these statements:", self.uri) 171 log.info("Board %s doesn't care about these statements:", self.uri)
171 for s in unused: 172 for s in unused:
172 log.info("%r", s) 173 log.info("%r", s)
173 174
174 def generateArduinoCode(self): 175 def generateArduinoCode(self):
175 generated = { 176 code = write_arduino_code.writeCode(self.baudrate, self._devs, self._devCommandNum)
176 'baudrate': self.baudrate, 177 code = write_arduino_code.indent(code)
177 'includes': '',
178 'global': '',
179 'setups': '',
180 'polls': '',
181 'idles': '',
182 'actions': '',
183 }
184 for attr in ['includes', 'global', 'setups', 'polls', 'idles',
185 'actions']:
186 for dev in self._devs:
187 if attr == 'includes':
188 gen = '\n'.join('#include "%s"\n' % inc
189 for inc in dev.generateIncludes())
190 elif attr == 'global': gen = dev.generateGlobalCode()
191 elif attr == 'setups': gen = dev.generateSetupCode()
192 elif attr == 'polls': gen = dev.generatePollCode()
193 elif attr == 'idles': gen = dev.generateIdleCode()
194 elif attr == 'actions':
195 code = dev.generateActionCode()
196 if code:
197 gen = '''else if (cmd == %(cmdNum)s) {
198 %(code)s
199 Serial.write('k');
200 }
201 ''' % dict(cmdNum=self._devCommandNum[dev.uri],
202 code=code)
203 else:
204 gen = ''
205 else:
206 raise NotImplementedError
207
208 if gen:
209 generated[attr] += '// for %s\n%s\n' % (dev.uri, gen.strip())
210
211 code = '''
212 %(includes)s
213
214 %(global)s
215 byte frame=0;
216 unsigned long lastFrame=0;
217
218 void setup() {
219 Serial.begin(%(baudrate)d);
220 Serial.flush();
221 %(setups)s
222 }
223
224 void idle() {
225 // this slowdown is to spend somewhat less time PWMing, to reduce
226 // leaking from on channels to off ones (my shift register has no
227 // latching)
228 if (micros() < lastFrame + 80) {
229 return;
230 }
231 lastFrame = micros();
232 frame++;
233 %(idles)s
234 }
235
236 void loop() {
237 byte head, cmd;
238 idle();
239 if (Serial.available() >= 2) {
240 head = Serial.read();
241 if (head != 0x60) {
242 Serial.flush();
243 return;
244 }
245 cmd = Serial.read();
246 if (cmd == 0x00) { // poll
247 %(polls)s
248 Serial.write('x');
249 } else if (cmd == 0x01) { // get code checksum
250 Serial.write("CODE_CHECKSUM");
251 }
252 %(actions)s
253 }
254 }
255 ''' % generated
256 try:
257 with tempfile.SpooledTemporaryFile() as codeFile:
258 codeFile.write(code)
259 codeFile.seek(0)
260 code = subprocess.check_output([
261 'indent',
262 '-linux',
263 '-fc1', # ok to indent comments
264 '-i4', # 4-space indent
265 '-sob' # swallow blanks (not working)
266 ], stdin=codeFile)
267 except OSError as e:
268 log.warn("indent failed (%r)", e)
269 cksum = hashlib.sha1(code).hexdigest() 178 cksum = hashlib.sha1(code).hexdigest()
270 code = code.replace('CODE_CHECKSUM', cksum) 179 code = code.replace('CODE_CHECKSUM', cksum)
271 return code, cksum 180 return code, cksum
272 181
273 def _readBoardChecksum(self, length): 182 def _readBoardChecksum(self, length):
311 finally: 220 finally:
312 self.open() 221 self.open()
313 222
314 def _arduinoMake(self, workDir, code): 223 def _arduinoMake(self, workDir, code):
315 with open(workDir + '/makefile', 'w') as makefile: 224 with open(workDir + '/makefile', 'w') as makefile:
316 makefile.write(''' 225 makefile.write(write_arduino_code.writeMakefile(
317 BOARD_TAG = %(tag)s 226 dev=self.dev,
318 USER_LIB_PATH := %(libs)s 227 tag=self.graph.value(self.uri, ROOM['boardTag']),
319 ARDUINO_LIBS = %(arduinoLibs)s 228 allLibs=sum((d.generateArduinoLibs() for d in self._devs), [])))
320 MONITOR_PORT = %(dev)s
321
322 include /usr/share/arduino/Arduino.mk
323 ''' % {
324 'dev': self.dev,
325 'tag': self.graph.value(self.uri, ROOM['boardTag']),
326 'libs': os.path.abspath('arduino-libraries'),
327 'arduinoLibs': ' '.join(sum((d.generateArduinoLibs()
328 for d in self._devs), [])),
329 })
330 229
331 with open(workDir + '/main.ino', 'w') as main: 230 with open(workDir + '/main.ino', 'w') as main:
332 main.write(code) 231 main.write(code)
333 232
334 subprocess.check_call(['make', 'upload'], cwd=workDir) 233 subprocess.check_call(['make', 'upload'], cwd=workDir)