2 # SPDX-License-Identifier: GPL-2.0+
4 # This is simply to aide in creating the entries in the order of the value of
5 # the device-global NI signal/terminal constants defined in comedi.h
8 from csv_collection import CSVCollection
11 def c_to_o(filename, prefix='\t\t\t\t\t ni_routing/', suffix=' \\'):
12 if not filename.endswith('.c'):
14 return prefix + filename.rpartition('.c')[0] + '.o' + suffix
17 def routedict_to_structinit_single(name, D, return_name=False):
20 '\t.family = "{}",'.format(name),
21 '\t.register_values = {',
23 '\t\t * destination = {',
24 '\t\t * source = register value,',
30 # print table with index0:src, index1:dest
31 D0 = D # (src-> dest->reg_value)
35 for src, destD in D.items():
36 for dest, val in destD.items():
37 D0.setdefault(dest, {})[src] = val
40 D0 = sorted(D0.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
42 for D0_sig, D1_D in D0:
43 D1 = sorted(D1_D.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
45 lines.append('\t\t[B({})] = {{'.format(D0_sig))
46 for D1_sig, value in D1:
47 if not re.match('[VIU]\([^)]*\)', value):
48 sys.stderr.write('Invalid register format: {}\n'.format(repr(value)))
50 'Register values should be formatted with V(),I(),or U()\n')
51 raise RuntimeError('Invalid register values format')
52 lines.append('\t\t\t[B({})]\t= {},'.format(D1_sig, value))
53 lines.append('\t\t},')
56 lines = '\n'.join(lines)
63 def routedict_to_routelist_single(name, D, indent=1):
75 # data is src -> dest-list
80 # data is dest -> src-list
84 for src, destD in D.items():
85 for dest, val in destD.items():
86 D0.setdefault(dest, {})[src] = val
88 # Sort by order of device-global names (numerically)
89 D0 = sorted(D0.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
91 lines = [ '{I0}.device = "{name}",\n'
92 '{I0}.routes = (struct ni_route_set[]){{'
93 .format(name=name, **indents) ]
94 for D0_sig, D1_D in D0:
95 D1 = [ k for k,v in D1_D.items() if v ]
96 D1.sort(key=lambda i: eval(i, comedi_h.__dict__, Locals))
98 lines.append('{I1}{{\n{I2}.{keyname} = {D0_sig},\n'
99 '{I2}.{valname} = (int[]){{'
100 .format(keyname=keyname, valname=valname, D0_sig=D0_sig, **indents)
103 lines.append( '{I3}{D1_sig},'.format(D1_sig=D1_sig, **indents) )
104 lines.append( '{I3}0, /* Termination */'.format(**indents) )
106 lines.append('{I2}}}\n{I1}}},'.format(**indents))
108 lines.append('{I1}{{ /* Termination of list */\n{I2}.{keyname} = 0,\n{I1}}},'
109 .format(keyname=keyname, **indents))
111 lines.append('{I0}}},'.format(**indents))
113 return '\n'.join(lines)
116 class DeviceRoutes(CSVCollection):
117 MKFILE_SEGMENTS = 'device-route.mk'
118 SET_C = 'ni_device_routes.c'
119 ITEMS_DIR = 'ni_device_routes'
123 output_file_top = """\
124 // SPDX-License-Identifier: GPL-2.0+
126 * comedi/drivers/ni_routing/{filename}
127 * List of valid routes for specific NI boards.
129 * COMEDI - Linux Control and Measurement Device Interface
130 * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
132 * This program is free software; you can redistribute it and/or modify
133 * it under the terms of the GNU General Public License as published by
134 * the Free Software Foundation; either version 2 of the License, or
135 * (at your option) any later version.
137 * This program is distributed in the hope that it will be useful,
138 * but WITHOUT ANY WARRANTY; without even the implied warranty of
139 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
140 * GNU General Public License for more details.
144 * The contents of this file are generated using the tools in
145 * comedi/drivers/ni_routing/tools
147 * Please use those tools to help maintain the contents of this file.
150 #include "ni_device_routes.h"
151 #include "{extern_h}"\
152 """.format(filename=SET_C, extern_h=os.path.join(ITEMS_DIR, EXTERN_H))
155 /* SPDX-License-Identifier: GPL-2.0+ */
157 * comedi/drivers/ni_routing/{filename}
158 * List of valid routes for specific NI boards.
160 * COMEDI - Linux Control and Measurement Device Interface
161 * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
163 * This program is free software; you can redistribute it and/or modify
164 * it under the terms of the GNU General Public License as published by
165 * the Free Software Foundation; either version 2 of the License, or
166 * (at your option) any later version.
168 * This program is distributed in the hope that it will be useful,
169 * but WITHOUT ANY WARRANTY; without even the implied warranty of
170 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
171 * GNU General Public License for more details.
175 * The contents of this file are generated using the tools in
176 * comedi/drivers/ni_routing/tools
178 * Please use those tools to help maintain the contents of this file.
181 #ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
182 #define _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
184 #include "../ni_device_routes.h"
188 #endif //_COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
191 single_output_file_top = """\
192 // SPDX-License-Identifier: GPL-2.0+
194 * comedi/drivers/ni_routing/{filename}
195 * List of valid routes for specific NI boards.
197 * COMEDI - Linux Control and Measurement Device Interface
198 * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
200 * This program is free software; you can redistribute it and/or modify
201 * it under the terms of the GNU General Public License as published by
202 * the Free Software Foundation; either version 2 of the License, or
203 * (at your option) any later version.
205 * This program is distributed in the hope that it will be useful,
206 * but WITHOUT ANY WARRANTY; without even the implied warranty of
207 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
208 * GNU General Public License for more details.
212 * The contents of this file are generated using the tools in
213 * comedi/drivers/ni_routing/tools
215 * Please use those tools to help maintain the contents of this file.
218 #include "../ni_device_routes.h"
219 #include "{extern_h}"
221 struct ni_device_routes {table_name} = {{\
224 def __init__(self, pattern='csv/device_routes/*.csv'):
225 super(DeviceRoutes,self).__init__(pattern)
227 def to_listinit(self):
228 chunks = [ self.output_file_top,
230 'struct ni_device_routes *const ni_device_routes_list[] = {'
232 # put the sheets in lexical order of device numbers then bus
233 sheets = sorted(self.items(), key=lambda i : tuple(i[0].split('-')[::-1]) )
236 objs = [c_to_o(self.SET_C)]
238 for sheet,D in sheets:
240 dev_table_name = 'ni_{}_device_routes'.format(S.replace('-','_'))
241 sheet_filename = os.path.join(self.ITEMS_DIR,'{}.c'.format(S))
242 externs.append('extern struct ni_device_routes {};'.format(dev_table_name))
244 chunks.append('\t&{},'.format(dev_table_name))
247 self.single_output_file_top.format(
248 filename = sheet_filename,
249 table_name = dev_table_name,
250 extern_h = self.EXTERN_H,
252 routedict_to_routelist_single(S, D),
256 objs.append(c_to_o(sheet_filename))
258 with open(os.path.join(self.OUTPUT_DIR, sheet_filename), 'w') as f:
259 f.write('\n'.join(s_chunks))
262 with open(os.path.join(self.OUTPUT_DIR, self.MKFILE_SEGMENTS), 'w') as f:
263 f.write('# This is the segment that should be included in comedi/drivers/Makefile\n')
264 f.write('ni_routing-objs\t\t\t\t+= \\\n')
265 f.write('\n'.join(objs))
268 EXTERN_H = os.path.join(self.ITEMS_DIR, self.EXTERN_H)
269 with open(os.path.join(self.OUTPUT_DIR, EXTERN_H), 'w') as f:
270 f.write(self.extern_header.format(
271 filename=EXTERN_H, externs='\n'.join(externs)))
273 chunks.append('\tNULL,') # terminate list
275 return '\n'.join(chunks)
278 filename=os.path.join(self.OUTPUT_DIR, self.SET_C)
281 os.makedirs(os.path.join(self.OUTPUT_DIR, self.ITEMS_DIR))
284 with open(filename,'w') as f:
285 f.write( self.to_listinit() )
289 class RouteValues(CSVCollection):
290 MKFILE_SEGMENTS = 'route-values.mk'
291 SET_C = 'ni_route_values.c'
292 ITEMS_DIR = 'ni_route_values'
296 output_file_top = """\
297 // SPDX-License-Identifier: GPL-2.0+
299 * comedi/drivers/ni_routing/{filename}
300 * Route information for NI boards.
302 * COMEDI - Linux Control and Measurement Device Interface
303 * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
305 * This program is free software; you can redistribute it and/or modify
306 * it under the terms of the GNU General Public License as published by
307 * the Free Software Foundation; either version 2 of the License, or
308 * (at your option) any later version.
310 * This program is distributed in the hope that it will be useful,
311 * but WITHOUT ANY WARRANTY; without even the implied warranty of
312 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
313 * GNU General Public License for more details.
317 * This file includes the tables that are a list of all the values of various
318 * signals routes available on NI hardware. In many cases, one does not
319 * explicitly make these routes, rather one might indicate that something is
320 * used as the source of one particular trigger or another (using
323 * The contents of this file are generated using the tools in
324 * comedi/drivers/ni_routing/tools
326 * Please use those tools to help maintain the contents of this file.
329 #include "ni_route_values.h"
330 #include "{extern_h}"\
331 """.format(filename=SET_C, extern_h=os.path.join(ITEMS_DIR, EXTERN_H))
334 /* SPDX-License-Identifier: GPL-2.0+ */
336 * comedi/drivers/ni_routing/{filename}
337 * List of valid routes for specific NI boards.
339 * COMEDI - Linux Control and Measurement Device Interface
340 * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
342 * This program is free software; you can redistribute it and/or modify
343 * it under the terms of the GNU General Public License as published by
344 * the Free Software Foundation; either version 2 of the License, or
345 * (at your option) any later version.
347 * This program is distributed in the hope that it will be useful,
348 * but WITHOUT ANY WARRANTY; without even the implied warranty of
349 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
350 * GNU General Public License for more details.
354 * The contents of this file are generated using the tools in
355 * comedi/drivers/ni_routing/tools
357 * Please use those tools to help maintain the contents of this file.
360 #ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
361 #define _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
363 #include "../ni_route_values.h"
367 #endif //_COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
370 single_output_file_top = """\
371 // SPDX-License-Identifier: GPL-2.0+
373 * comedi/drivers/ni_routing/{filename}
374 * Route information for {sheet} boards.
376 * COMEDI - Linux Control and Measurement Device Interface
377 * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
379 * This program is free software; you can redistribute it and/or modify
380 * it under the terms of the GNU General Public License as published by
381 * the Free Software Foundation; either version 2 of the License, or
382 * (at your option) any later version.
384 * This program is distributed in the hope that it will be useful,
385 * but WITHOUT ANY WARRANTY; without even the implied warranty of
386 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
387 * GNU General Public License for more details.
391 * This file includes a list of all the values of various signals routes
392 * available on NI 660x hardware. In many cases, one does not explicitly make
393 * these routes, rather one might indicate that something is used as the source
394 * of one particular trigger or another (using *_src=TRIG_EXT).
396 * The contents of this file can be generated using the tools in
397 * comedi/drivers/ni_routing/tools. This file also contains specific notes to
398 * this family of devices.
400 * Please use those tools to help maintain the contents of this file, but be
401 * mindful to not lose the notes already made in this file, since these notes
402 * are critical to a complete undertsanding of the register values of this
406 #include "../ni_route_values.h"
407 #include "{extern_h}"
409 const struct family_route_values {table_name} = {{\
412 def __init__(self, pattern='csv/route_values/*.csv'):
413 super(RouteValues,self).__init__(pattern)
415 def to_structinit(self):
416 chunks = [ self.output_file_top,
418 'const struct family_route_values *const ni_all_route_values[] = {'
420 # put the sheets in lexical order for consistency
421 sheets = sorted(self.items(), key=lambda i : i[0] )
424 objs = [c_to_o(self.SET_C)]
426 for sheet,D in sheets:
428 fam_table_name = '{}_route_values'.format(S.replace('-','_'))
429 sheet_filename = os.path.join(self.ITEMS_DIR,'{}.c'.format(S))
430 externs.append('extern const struct family_route_values {};'.format(fam_table_name))
432 chunks.append('\t&{},'.format(fam_table_name))
435 self.single_output_file_top.format(
436 filename = sheet_filename,
437 sheet = sheet.upper(),
438 table_name = fam_table_name,
439 extern_h = self.EXTERN_H,
441 routedict_to_structinit_single(S, D),
445 objs.append(c_to_o(sheet_filename))
447 with open(os.path.join(self.OUTPUT_DIR, sheet_filename), 'w') as f:
448 f.write('\n'.join(s_chunks))
451 with open(os.path.join(self.OUTPUT_DIR, self.MKFILE_SEGMENTS), 'w') as f:
452 f.write('# This is the segment that should be included in comedi/drivers/Makefile\n')
453 f.write('ni_routing-objs\t\t\t\t+= \\\n')
454 f.write('\n'.join(objs))
457 EXTERN_H = os.path.join(self.ITEMS_DIR, self.EXTERN_H)
458 with open(os.path.join(self.OUTPUT_DIR, EXTERN_H), 'w') as f:
459 f.write(self.extern_header.format(
460 filename=EXTERN_H, externs='\n'.join(externs)))
462 chunks.append('\tNULL,') # terminate list
464 return '\n'.join(chunks)
467 filename=os.path.join(self.OUTPUT_DIR, self.SET_C)
470 os.makedirs(os.path.join(self.OUTPUT_DIR, self.ITEMS_DIR))
473 with open(filename,'w') as f:
474 f.write( self.to_structinit() )
479 if __name__ == '__main__':
481 parser = argparse.ArgumentParser()
482 parser.add_argument( '--route_values', action='store_true',
483 help='Extract route values from csv/route_values/*.csv' )
484 parser.add_argument( '--device_routes', action='store_true',
485 help='Extract route values from csv/device_routes/*.csv' )
486 args = parser.parse_args()
488 if args.route_values:
489 KL.append( RouteValues )
490 if args.device_routes:
491 KL.append( DeviceRoutes )
493 parser.error('nothing to do...')