osd-contiki/examples/osd/arduino-roller/tools/lookuptable.py
2016-01-24 21:30:35 +01:00

177 lines
5.6 KiB
Python

#!/usr/bin/python
"""
Benutzung:
python lookuptable.py bla.csv bla.h bla.c
liest bla.csv aus, interpoliert das ganze und schreibt eine tabelle in bla.c und bla.h
Achtung, bla.c und bla.h werden brutal ueberschrieben!
Das csv muss tabs, kommas oder semikolons als trenner haben und folgende felder enthalten:
#LowValue
wird als y fuer alle x-werte, die kleiner als der kleinste x-Wert im csv sind, benutzt
#HighValue
wird als y fuer alle x-werte, die groesser als der groesste x-Wert im csv sind, benutzt
#DataType
Datentyp der y-Werte (uint16_t oder uint8_t)
#IndexType
Datentyp der x-Werte (uint16_t oder uint8_t)
#ArrayName
Name des Arrays
Siehe example.csv!!
Benutzung auf eigene Gefahr.
"""
import fileinput
import re
import os
import sys
# bei bedarf ergaezen.
AdditionalIncludes = [ '<avr/pgmspace.h>', '<inttypes.h>' ]
def create_printable_table(table, dataType, arrayName):
""" returns a string with the table in *.c format """
result = '/** autogenerated lookup table */\n'
result += 'const ' + dataType + " g_LOOKUP_" + arrayName + '[] PROGMEM =\n'
result += '{\n'
for x in sorted(table.keys()):
y = table[x]
result += ' /* ' + repr(x).rjust(12) + ' */ ' + repr(y).rjust(12) + ',\n'
result += '};'
return result
def create_lookup_function(dataType, indexType, arrayName, biggestKey, highValue):
header = ''
body = ''
header += '/**\n'
header += ' * autogenerated lookup function for ' + arrayName + "\n"
header += ' * @param i x value\n'
header += ' * @return f(i), or ' + str(highValue) + ' if i is out of range\n'
header += ' */\n'
header += dataType + ' lookup_' + arrayName + '(' + indexType + ' i);'
body += dataType + ' lookup_' + arrayName + '(' + indexType + ' i)\n'
body += '{\n'
body += ' if (i <= ' + str(biggestKey) + ')\n'
body += ' return '
if dataType == 'uint16_t':
body += 'pgm_read_word(&g_LOOKUP_' + arrayName + '[i]);\n'
elif dataType == 'uint8_t':
body += 'pgm_read_byte(&g_LOOKUP_' + arrayName + '[i]);\n'
else:
body += 'ERROR: no suitable datatype\n'
body += ' else\n'
body += ' return ' + str(highValue) + '; /* #HighValue */\n'
body += '}\n'
return header, body
def interpolate_lookup_table(table, lowValue):
#sortieren, durchgehen und interpolieren.
oldX = 0
for nextX in sorted(table.keys()):
if not oldX in table.keys():
if oldX == 0:
startY = lowValue
nextY = lowValue
else:
startY = table[oldX]
nextY = table[nextX]
for thisX in range(oldX, nextX): # die punkte zwischen den stuetzstellen durchgehen
thisY = startY + (nextY - startY) * (thisX - oldX) / (nextX - oldX) # lin. interpol.
table[thisX] = thisY
oldX = nextX
return table
def parse_csv(filename):
dataType = 'uint16_t'
indexType = 'uint8_t'
arrayName = 'TestArray'
lowestKey = 'ERROR'
biggestKey = 'ERROR'
highValue = 'ERROR'
lowValue = 'ERROR'
data = {}
csvFile = open(filename, 'r')
for line in csvFile:
zeile = line.strip().strip('"')
if re.match('\#', zeile):
myLine = re.split('[\t ;,]+', zeile)
if re.match('\#LowValue', myLine[0]):
lowValue = int(myLine[1].strip('"'))
elif re.match('\#HighValue', myLine[0]):
highValue = int(myLine[1].strip('"'))
elif re.match('\#DataType', myLine[0]):
dataType = str(myLine[1].strip('"'))
elif re.match('\#IndexType', myLine[0]):
indexType = str(myLine[1].strip('"'))
elif re.match('\#ArrayName', myLine[0]):
arrayName = str(myLine[1].strip('"'))
elif re.match('[0-9]+[,;\t]+[0-9]+', zeile):
myLine = re.split('[\t ;,]+', zeile)
data[int(myLine[0])] = int(myLine[1])
lowestKey = min(data.keys());
biggestKey = max(data.keys());
return dataType, indexType, arrayName, biggestKey, lowestKey, highValue, lowValue, data
def write_header_file(filename, content, additionalIncludes):
headerfile = open(filename, 'w')
includeGuard = re.sub('\.', '_', filename) + '_'
headerfile.write('#ifndef ' + includeGuard + '\n')
headerfile.write('#define ' + includeGuard + '\n\n')
for h in additionalIncludes:
headerfile.write('#include ' + h + '\n')
headerfile.write('\n')
headerfile.write(content)
headerfile.write('\n\n#endif /* ' + includeGuard + ' */\n\n')
headerfile.close()
return
def write_body_file(bodyFileName, headerFileName, table, funct):
bodyfile = open(bodyFileName, 'w')
bodyfile.write('#include "' + headerFileName + '"\n\n')
bodyfile.write(table)
bodyfile.write('\n\n')
bodyfile.write(funct)
bodyfile.write('\n\n')
bodyfile.close()
return
def print_usage():
print "MOEP: Benutzung python", sys.argv[0], "bla.csv bla.h bla.c"
print "bla.csv muss existieren, bla.h und bla.c werden ueberschrieben"
if len(sys.argv) < 4:
print_usage()
sys.exit()
csvFile = sys.argv[1]
headerFileName = sys.argv[2]
bodyFileName = sys.argv[3]
dataType, indexType, arrayName, biggestKey, lowestKey, highValue, lowValue, data = parse_csv(csvFile)
fullTable = interpolate_lookup_table(data, lowValue)
header, body = create_lookup_function(dataType, indexType, arrayName, biggestKey, highValue)
write_header_file(headerFileName, header, AdditionalIncludes)
write_body_file(bodyFileName, headerFileName, create_printable_table(fullTable, dataType, arrayName), body)
sys.exit()