blob: 532eb6372a5adb7e88d20f42e175ca0cd35b1864 [file] [log] [blame]
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0+
# vim: ts=2:sw=2:et:tw=80:nowrap
# This is simply to aide in creating the entries in the order of the value of
# the device-global NI signal/terminal constants defined in comedi.h
import comedi_h
import os, sys, re
from csv_collection import CSVCollection
def c_to_o(filename, prefix='\t\t\t\t\t ni_routing/', suffix=' \\'):
if not filename.endswith('.c'):
return ''
return prefix + filename.rpartition('.c')[0] + '.o' + suffix
def routedict_to_structinit_single(name, D, return_name=False):
Locals = dict()
lines = [
'\t.family = "{}",'.format(name),
'\t.register_values = {',
'\t\t/*',
'\t\t * destination = {',
'\t\t * source = register value,',
'\t\t * ...',
'\t\t * }',
'\t\t */',
]
if (False):
# print table with index0:src, index1:dest
D0 = D # (src-> dest->reg_value)
#D1 : destD
else:
D0 = dict()
for src, destD in D.items():
for dest, val in destD.items():
D0.setdefault(dest, {})[src] = val
D0 = sorted(D0.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
for D0_sig, D1_D in D0:
D1 = sorted(D1_D.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
lines.append('\t\t[B({})] = {{'.format(D0_sig))
for D1_sig, value in D1:
if not re.match('[VIU]\([^)]*\)', value):
sys.stderr.write('Invalid register format: {}\n'.format(repr(value)))
sys.stderr.write(
'Register values should be formatted with V(),I(),or U()\n')
raise RuntimeError('Invalid register values format')
lines.append('\t\t\t[B({})]\t= {},'.format(D1_sig, value))
lines.append('\t\t},')
lines.append('\t},')
lines = '\n'.join(lines)
if return_name:
return N, lines
else:
return lines
def routedict_to_routelist_single(name, D, indent=1):
Locals = dict()
indents = dict(
I0 = '\t'*(indent),
I1 = '\t'*(indent+1),
I2 = '\t'*(indent+2),
I3 = '\t'*(indent+3),
I4 = '\t'*(indent+4),
)
if (False):
# data is src -> dest-list
D0 = D
keyname = 'src'
valname = 'dest'
else:
# data is dest -> src-list
keyname = 'dest'
valname = 'src'
D0 = dict()
for src, destD in D.items():
for dest, val in destD.items():
D0.setdefault(dest, {})[src] = val
# Sort by order of device-global names (numerically)
D0 = sorted(D0.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
lines = [ '{I0}.device = "{name}",\n'
'{I0}.routes = (struct ni_route_set[]){{'
.format(name=name, **indents) ]
for D0_sig, D1_D in D0:
D1 = [ k for k,v in D1_D.items() if v ]
D1.sort(key=lambda i: eval(i, comedi_h.__dict__, Locals))
lines.append('{I1}{{\n{I2}.{keyname} = {D0_sig},\n'
'{I2}.{valname} = (int[]){{'
.format(keyname=keyname, valname=valname, D0_sig=D0_sig, **indents)
)
for D1_sig in D1:
lines.append( '{I3}{D1_sig},'.format(D1_sig=D1_sig, **indents) )
lines.append( '{I3}0, /* Termination */'.format(**indents) )
lines.append('{I2}}}\n{I1}}},'.format(**indents))
lines.append('{I1}{{ /* Termination of list */\n{I2}.{keyname} = 0,\n{I1}}},'
.format(keyname=keyname, **indents))
lines.append('{I0}}},'.format(**indents))
return '\n'.join(lines)
class DeviceRoutes(CSVCollection):
MKFILE_SEGMENTS = 'device-route.mk'
SET_C = 'ni_device_routes.c'
ITEMS_DIR = 'ni_device_routes'
EXTERN_H = 'all.h'
OUTPUT_DIR = 'c'
output_file_top = """\
// SPDX-License-Identifier: GPL-2.0+
/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
/*
* comedi/drivers/ni_routing/{filename}
* List of valid routes for specific NI boards.
*
* COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* The contents of this file are generated using the tools in
* comedi/drivers/ni_routing/tools
*
* Please use those tools to help maintain the contents of this file.
*/
#include "ni_device_routes.h"
#include "{extern_h}"\
""".format(filename=SET_C, extern_h=os.path.join(ITEMS_DIR, EXTERN_H))
extern_header = """\
/* SPDX-License-Identifier: GPL-2.0+ */
/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
/*
* comedi/drivers/ni_routing/{filename}
* List of valid routes for specific NI boards.
*
* COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* The contents of this file are generated using the tools in
* comedi/drivers/ni_routing/tools
*
* Please use those tools to help maintain the contents of this file.
*/
#ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
#define _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
#include "../ni_device_routes.h"
{externs}
#endif //_COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
"""
single_output_file_top = """\
// SPDX-License-Identifier: GPL-2.0+
/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
/*
* comedi/drivers/ni_routing/{filename}
* List of valid routes for specific NI boards.
*
* COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* The contents of this file are generated using the tools in
* comedi/drivers/ni_routing/tools
*
* Please use those tools to help maintain the contents of this file.
*/
#include "../ni_device_routes.h"
#include "{extern_h}"
struct ni_device_routes {table_name} = {{\
"""
def __init__(self, pattern='csv/device_routes/*.csv'):
super(DeviceRoutes,self).__init__(pattern)
def to_listinit(self):
chunks = [ self.output_file_top,
'',
'struct ni_device_routes *const ni_device_routes_list[] = {'
]
# put the sheets in lexical order of device numbers then bus
sheets = sorted(self.items(), key=lambda i : tuple(i[0].split('-')[::-1]) )
externs = []
objs = [c_to_o(self.SET_C)]
for sheet,D in sheets:
S = sheet.lower()
dev_table_name = 'ni_{}_device_routes'.format(S.replace('-','_'))
sheet_filename = os.path.join(self.ITEMS_DIR,'{}.c'.format(S))
externs.append('extern struct ni_device_routes {};'.format(dev_table_name))
chunks.append('\t&{},'.format(dev_table_name))
s_chunks = [
self.single_output_file_top.format(
filename = sheet_filename,
table_name = dev_table_name,
extern_h = self.EXTERN_H,
),
routedict_to_routelist_single(S, D),
'};',
]
objs.append(c_to_o(sheet_filename))
with open(os.path.join(self.OUTPUT_DIR, sheet_filename), 'w') as f:
f.write('\n'.join(s_chunks))
f.write('\n')
with open(os.path.join(self.OUTPUT_DIR, self.MKFILE_SEGMENTS), 'w') as f:
f.write('# This is the segment that should be included in comedi/drivers/Makefile\n')
f.write('ni_routing-objs\t\t\t\t+= \\\n')
f.write('\n'.join(objs))
f.write('\n')
EXTERN_H = os.path.join(self.ITEMS_DIR, self.EXTERN_H)
with open(os.path.join(self.OUTPUT_DIR, EXTERN_H), 'w') as f:
f.write(self.extern_header.format(
filename=EXTERN_H, externs='\n'.join(externs)))
chunks.append('\tNULL,') # terminate list
chunks.append('};')
return '\n'.join(chunks)
def save(self):
filename=os.path.join(self.OUTPUT_DIR, self.SET_C)
try:
os.makedirs(os.path.join(self.OUTPUT_DIR, self.ITEMS_DIR))
except:
pass
with open(filename,'w') as f:
f.write( self.to_listinit() )
f.write( '\n' )
class RouteValues(CSVCollection):
MKFILE_SEGMENTS = 'route-values.mk'
SET_C = 'ni_route_values.c'
ITEMS_DIR = 'ni_route_values'
EXTERN_H = 'all.h'
OUTPUT_DIR = 'c'
output_file_top = """\
// SPDX-License-Identifier: GPL-2.0+
/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
/*
* comedi/drivers/ni_routing/{filename}
* Route information for NI boards.
*
* COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* This file includes the tables that are a list of all the values of various
* signals routes available on NI hardware. In many cases, one does not
* explicitly make these routes, rather one might indicate that something is
* used as the source of one particular trigger or another (using
* *_src=TRIG_EXT).
*
* The contents of this file are generated using the tools in
* comedi/drivers/ni_routing/tools
*
* Please use those tools to help maintain the contents of this file.
*/
#include "ni_route_values.h"
#include "{extern_h}"\
""".format(filename=SET_C, extern_h=os.path.join(ITEMS_DIR, EXTERN_H))
extern_header = """\
/* SPDX-License-Identifier: GPL-2.0+ */
/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
/*
* comedi/drivers/ni_routing/{filename}
* List of valid routes for specific NI boards.
*
* COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* The contents of this file are generated using the tools in
* comedi/drivers/ni_routing/tools
*
* Please use those tools to help maintain the contents of this file.
*/
#ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
#define _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
#include "../ni_route_values.h"
{externs}
#endif //_COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
"""
single_output_file_top = """\
// SPDX-License-Identifier: GPL-2.0+
/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
/*
* comedi/drivers/ni_routing/{filename}
* Route information for {sheet} boards.
*
* COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* This file includes a list of all the values of various signals routes
* available on NI 660x hardware. In many cases, one does not explicitly make
* these routes, rather one might indicate that something is used as the source
* of one particular trigger or another (using *_src=TRIG_EXT).
*
* The contents of this file can be generated using the tools in
* comedi/drivers/ni_routing/tools. This file also contains specific notes to
* this family of devices.
*
* Please use those tools to help maintain the contents of this file, but be
* mindful to not lose the notes already made in this file, since these notes
* are critical to a complete undertsanding of the register values of this
* family.
*/
#include "../ni_route_values.h"
#include "{extern_h}"
const struct family_route_values {table_name} = {{\
"""
def __init__(self, pattern='csv/route_values/*.csv'):
super(RouteValues,self).__init__(pattern)
def to_structinit(self):
chunks = [ self.output_file_top,
'',
'const struct family_route_values *const ni_all_route_values[] = {'
]
# put the sheets in lexical order for consistency
sheets = sorted(self.items(), key=lambda i : i[0] )
externs = []
objs = [c_to_o(self.SET_C)]
for sheet,D in sheets:
S = sheet.lower()
fam_table_name = '{}_route_values'.format(S.replace('-','_'))
sheet_filename = os.path.join(self.ITEMS_DIR,'{}.c'.format(S))
externs.append('extern const struct family_route_values {};'.format(fam_table_name))
chunks.append('\t&{},'.format(fam_table_name))
s_chunks = [
self.single_output_file_top.format(
filename = sheet_filename,
sheet = sheet.upper(),
table_name = fam_table_name,
extern_h = self.EXTERN_H,
),
routedict_to_structinit_single(S, D),
'};',
]
objs.append(c_to_o(sheet_filename))
with open(os.path.join(self.OUTPUT_DIR, sheet_filename), 'w') as f:
f.write('\n'.join(s_chunks))
f.write( '\n' )
with open(os.path.join(self.OUTPUT_DIR, self.MKFILE_SEGMENTS), 'w') as f:
f.write('# This is the segment that should be included in comedi/drivers/Makefile\n')
f.write('ni_routing-objs\t\t\t\t+= \\\n')
f.write('\n'.join(objs))
f.write('\n')
EXTERN_H = os.path.join(self.ITEMS_DIR, self.EXTERN_H)
with open(os.path.join(self.OUTPUT_DIR, EXTERN_H), 'w') as f:
f.write(self.extern_header.format(
filename=EXTERN_H, externs='\n'.join(externs)))
chunks.append('\tNULL,') # terminate list
chunks.append('};')
return '\n'.join(chunks)
def save(self):
filename=os.path.join(self.OUTPUT_DIR, self.SET_C)
try:
os.makedirs(os.path.join(self.OUTPUT_DIR, self.ITEMS_DIR))
except:
pass
with open(filename,'w') as f:
f.write( self.to_structinit() )
f.write( '\n' )
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument( '--route_values', action='store_true',
help='Extract route values from csv/route_values/*.csv' )
parser.add_argument( '--device_routes', action='store_true',
help='Extract route values from csv/device_routes/*.csv' )
args = parser.parse_args()
KL = list()
if args.route_values:
KL.append( RouteValues )
if args.device_routes:
KL.append( DeviceRoutes )
if not KL:
parser.error('nothing to do...')
for K in KL:
doc = K()
doc.save()