initial commit
This commit is contained in:
@@ -0,0 +1,670 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# *****************************************************************************
|
||||
#
|
||||
# pinconfig.py
|
||||
#
|
||||
# @brief Script for generating a BSP pin file.
|
||||
|
||||
# *****************************************************************************
|
||||
|
||||
# *****************************************************************************
|
||||
#
|
||||
# Copyright (c) 2020, Ambiq Micro
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
#
|
||||
# Third party software included in this distribution is subject to the
|
||||
# additional license terms as defined in the /docs/licenses directory.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
#
|
||||
# *****************************************************************************
|
||||
|
||||
# *****************************************************************************
|
||||
# Imported modules
|
||||
# *****************************************************************************
|
||||
import argparse
|
||||
import textwrap
|
||||
import os.path
|
||||
import rsonlite
|
||||
|
||||
|
||||
# *****************************************************************************
|
||||
# Templates
|
||||
# *****************************************************************************
|
||||
filetemplateC = '''
|
||||
//*****************************************************************************
|
||||
//
|
||||
// {filename}
|
||||
//! @file
|
||||
//!
|
||||
//! @brief BSP pin configuration definitions.
|
||||
//!
|
||||
//! @addtogroup BSP Board Support Package (BSP)
|
||||
//! @ingroup BSP
|
||||
//! @{{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include "am_bsp.h"
|
||||
{pin_defs}
|
||||
//*****************************************************************************
|
||||
//
|
||||
// End Doxygen group.
|
||||
//! @}}
|
||||
//
|
||||
//*****************************************************************************
|
||||
'''.strip()
|
||||
|
||||
|
||||
filetemplateH = '''
|
||||
//*****************************************************************************
|
||||
//
|
||||
// {filename}
|
||||
//! @file
|
||||
//!
|
||||
//! @brief BSP pin configuration definitions.
|
||||
//!
|
||||
//! @addtogroup BSP Board Support Package (BSP)
|
||||
//! @addtogroup apollo3_bsp BSP for the Apollo3 EVB.
|
||||
//! @ingroup BSP
|
||||
//! @{{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (c) 2020, Ambiq Micro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// Third party software included in this distribution is subject to the
|
||||
// additional license terms as defined in the /docs/licenses directory.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef {headerdef}
|
||||
#define {headerdef}
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "am_mcu_apollo.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{{
|
||||
#endif
|
||||
{pin_defs}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}}
|
||||
#endif
|
||||
|
||||
#endif // {headerdef}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// End Doxygen group.
|
||||
//! @}}
|
||||
//
|
||||
//*****************************************************************************
|
||||
'''.strip()
|
||||
|
||||
|
||||
sectiontemplate = '''
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// {pin_descr}
|
||||
//
|
||||
//*****************************************************************************
|
||||
'''.strip()
|
||||
|
||||
|
||||
# *****************************************************************************
|
||||
#
|
||||
# Globals
|
||||
#
|
||||
# *****************************************************************************
|
||||
|
||||
# *****************************************************************************
|
||||
#
|
||||
# Command line support.
|
||||
#
|
||||
# *****************************************************************************
|
||||
def read_arguments():
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('input', help='input src file name')
|
||||
parser.add_argument('CorH', help='C to create C file, H to create H file',
|
||||
choices=['C','H','c','h'])
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
# *****************************************************************************
|
||||
# parse_input()
|
||||
# *****************************************************************************
|
||||
def parse_input(filename):
|
||||
'''
|
||||
Simple wrapper to pull an rsonlite list from given file.
|
||||
'''
|
||||
with open(filename) as f:
|
||||
data = f.read()
|
||||
return rsonlite.loads(data)
|
||||
|
||||
# *****************************************************************************
|
||||
# list_to_dict()
|
||||
# *****************************************************************************
|
||||
def list_to_dict(L):
|
||||
'''
|
||||
rsonlite loads data from the rson files as a very-nested list. This
|
||||
function converts that list to a set of nested dictionaries. At each level,
|
||||
the dictionary keys correspond to the "headings", and the dictionary values
|
||||
are a list of the items under that "heading". Values assigned by
|
||||
equals-sign statements are (unfortunately) also converted to (key, list)
|
||||
pairs, the same way that subheadings are.
|
||||
'''
|
||||
if len(L) == 1:
|
||||
return L[0]
|
||||
else:
|
||||
D = dict()
|
||||
for x in L:
|
||||
if x[0] in D:
|
||||
D[x[0]] = D[x[0]] + [list_to_dict(x[1])]
|
||||
else:
|
||||
D[x[0]] = [list_to_dict(x[1])]
|
||||
return D
|
||||
|
||||
# *****************************************************************************
|
||||
# get_val()
|
||||
# *****************************************************************************
|
||||
def get_val(name, D):
|
||||
'''
|
||||
get_val is just a helper to make it more obvious when you are trying to get
|
||||
at an equals-sign-assigned value from the rson file dictionary.
|
||||
'''
|
||||
if name not in D:
|
||||
return "ERROR: {} VALUE MISSING".format(name)
|
||||
else:
|
||||
return D[name][0]
|
||||
|
||||
# *****************************************************************************
|
||||
# get_version()
|
||||
# *****************************************************************************
|
||||
def get_version(filename):
|
||||
'''
|
||||
Given the filename of an 'src' file, this function will return a 'pin'
|
||||
object corresponding to the fields described in the src file.
|
||||
'''
|
||||
# Read in the contents of the src file, and use the rsonlite library to
|
||||
# parse them into a list.
|
||||
rson_data = parse_input(filename)
|
||||
|
||||
# Convert the list to a dictionary.
|
||||
rson_dict = list_to_dict(rson_data)
|
||||
|
||||
if 'pinsrc_ver' in rson_dict:
|
||||
# Convert rson list object to int
|
||||
ssrcver = rson_dict["pinsrc_ver"][0]
|
||||
if ssrcver[0:2].lower() == "0x":
|
||||
source_version = int(ssrcver, 16)
|
||||
else:
|
||||
source_version = int(ssrcver, 10)
|
||||
else:
|
||||
# If no src file version given, assume version for Apollo3
|
||||
source_version = 0x0003
|
||||
|
||||
return source_version
|
||||
|
||||
# *****************************************************************************
|
||||
# get_pinobj()
|
||||
# *****************************************************************************
|
||||
def get_pinobj(filename):
|
||||
'''
|
||||
Given the filename of an 'src' file, this function will return a 'pin'
|
||||
object corresponding to the fields described in the src file.
|
||||
'''
|
||||
|
||||
# Set the location for the supplementary files (infoblock, base addresses, etc.)
|
||||
srcdir = os.path.dirname(filename)
|
||||
|
||||
# Read in the contents of the src file, and use the rsonlite library to
|
||||
# parse them into a list.
|
||||
rson_data = parse_input(filename)
|
||||
|
||||
# Convert the list to a dictionary.
|
||||
rson_dict = list_to_dict(rson_data)
|
||||
|
||||
# Convert the dictionary to a block object, which will create field
|
||||
# objects as necessary. Return this object to the caller.
|
||||
return pinobj(rson_dict)
|
||||
|
||||
|
||||
# *****************************************************************************
|
||||
# pinfields
|
||||
# *****************************************************************************
|
||||
class pinfields:
|
||||
def __init__(self, pindict):
|
||||
|
||||
self.name = ''
|
||||
self.desc = ''
|
||||
self.pinnum = 0
|
||||
self.powersw = ''
|
||||
self.pullup = ''
|
||||
self.func_sel = ''
|
||||
self.drvstrength = 0
|
||||
self.intdir = 0
|
||||
self.GPOutcfg = ''
|
||||
self.GPinput = ''
|
||||
self.GPRdZero = ''
|
||||
self.IOMnum = ''
|
||||
self.CEnum = ''
|
||||
self.CEpol = ''
|
||||
self.bIomMSPIn = ''
|
||||
|
||||
intnotgiven = 65535
|
||||
strnotgiven = 'none_given'
|
||||
|
||||
if 'name' in pindict:
|
||||
self.name = get_val('name', pindict)
|
||||
else:
|
||||
self.name = strnotgiven
|
||||
|
||||
if 'desc' in pindict:
|
||||
self.desc = get_val('desc', pindict)
|
||||
else:
|
||||
self.desc = strnotgiven
|
||||
|
||||
if 'pinnum' in pindict:
|
||||
self.pinnum = int(get_val('pinnum', pindict))
|
||||
else:
|
||||
self.pinnum = intnotgiven
|
||||
|
||||
if 'powersw' in pindict:
|
||||
self.powersw = get_val('powersw', pindict)
|
||||
else:
|
||||
self.powersw = strnotgiven
|
||||
|
||||
if 'pullup' in pindict:
|
||||
self.pullup = get_val('pullup', pindict)
|
||||
else:
|
||||
self.pullup = strnotgiven
|
||||
|
||||
if 'func_sel' in pindict:
|
||||
self.func_sel = get_val('func_sel', pindict)
|
||||
else:
|
||||
self.func_sel = strnotgiven
|
||||
|
||||
if 'drvstrength' in pindict:
|
||||
self.drvstrength = int(get_val('drvstrength', pindict))
|
||||
else:
|
||||
self.drvstrength = intnotgiven
|
||||
|
||||
if 'intdir' in pindict:
|
||||
self.intdir = get_val('intdir', pindict)
|
||||
else:
|
||||
self.intdir = strnotgiven
|
||||
|
||||
if 'GPOutcfg' in pindict:
|
||||
self.GPOutcfg = get_val('GPOutcfg', pindict)
|
||||
else:
|
||||
self.GPOutcfg = strnotgiven
|
||||
|
||||
if 'GPinput' in pindict:
|
||||
self.GPinput = get_val('GPinput', pindict)
|
||||
else:
|
||||
self.GPinput = strnotgiven
|
||||
|
||||
if 'GPRdZero' in pindict:
|
||||
self.GPRdZero = get_val('GPRdZero', pindict)
|
||||
else:
|
||||
self.GPRdZero = strnotgiven
|
||||
|
||||
if 'IOMnum' in pindict:
|
||||
self.IOMnum = get_val('IOMnum', pindict)
|
||||
elif 'MSPInum' in pindict:
|
||||
self.IOMnum = get_val('MSPInum', pindict)
|
||||
else:
|
||||
self.IOMnum = strnotgiven
|
||||
|
||||
if 'CEnum' in pindict:
|
||||
self.CEnum = get_val('CEnum', pindict)
|
||||
else:
|
||||
self.CEnum = strnotgiven
|
||||
|
||||
if 'CEpol' in pindict:
|
||||
self.CEpol = get_val('CEpol', pindict)
|
||||
else:
|
||||
self.CEpol = strnotgiven
|
||||
|
||||
if 'bIomMSPIn' in pindict:
|
||||
self.bIomMSPIn = get_val('bIomMSPIn', pindict)
|
||||
else:
|
||||
self.bIomMSPIn = strnotgiven
|
||||
|
||||
#
|
||||
# Check for an invalid field in the src file. If so, report it.
|
||||
#
|
||||
for fld in pindict:
|
||||
if fld != 'name' and \
|
||||
fld != 'desc' and \
|
||||
fld != 'pinnum' and \
|
||||
fld != 'powersw' and \
|
||||
fld != 'pullup' and \
|
||||
fld != 'func_sel' and \
|
||||
fld != 'drvstrength' and \
|
||||
fld != 'intdir' and \
|
||||
fld != 'GPOutcfg' and \
|
||||
fld != 'GPinput' and \
|
||||
fld != 'GPRdZero' and \
|
||||
fld != 'IOMnum' and \
|
||||
fld != 'MSPInum' and \
|
||||
fld != 'CEnum' and \
|
||||
fld != 'CEpol' and \
|
||||
fld != 'bIomMSPIn':
|
||||
print("Invalid field: '%s.%s'" % (self.name, fld))
|
||||
|
||||
|
||||
# *****************************************************************************
|
||||
# pinobj
|
||||
# *****************************************************************************
|
||||
class pinobj:
|
||||
def __init__(self, pindict):
|
||||
self.name = 'name'
|
||||
self.srcver=0x0000
|
||||
self.pins = []
|
||||
|
||||
if 'pinsrc_ver' in pindict:
|
||||
# Convert rson list object to int
|
||||
ssrcver = pindict["pinsrc_ver"][0]
|
||||
if ssrcver[0:2].lower() == "0x":
|
||||
self.srcver = int(ssrcver,16)
|
||||
else:
|
||||
self.srcver = int(ssrcver,10)
|
||||
else:
|
||||
# If no src file version given, assume version for Apollo3
|
||||
self.srcver = 0x0003
|
||||
|
||||
# Run through all the pins given in the src file
|
||||
if 'pin' in pindict:
|
||||
#
|
||||
# Run through the 'pin' list.
|
||||
#
|
||||
for pin in pindict['pin']:
|
||||
self.pins.append(pinfields(pin))
|
||||
|
||||
# *****************************************************************************
|
||||
# write_Cfiles()
|
||||
# *****************************************************************************
|
||||
|
||||
def write_Cfiles(pinobj, bCreateC):
|
||||
#
|
||||
# Initializations
|
||||
#
|
||||
intnotgiven = 65535
|
||||
strnotgiven = 'none_given'
|
||||
strCfile = ''
|
||||
strHfile = ''
|
||||
|
||||
for pin in pinobj.pins:
|
||||
sectiondesc = pin.name.strip() + ' pin'
|
||||
if pin.desc == strnotgiven:
|
||||
sectiondesc += '.'
|
||||
else:
|
||||
sectiondesc += ': ' + pin.desc.strip()
|
||||
if sectiondesc[-1] != '.':
|
||||
sectiondesc += '.'
|
||||
strCfile += '\n'
|
||||
strCfile += sectiontemplate.format(pin_descr=sectiondesc)
|
||||
strCfile += '\n'
|
||||
strHfile += '\n'
|
||||
strHfile += sectiontemplate.format(pin_descr=sectiondesc)
|
||||
strHfile += '\n'
|
||||
|
||||
if pin.pinnum != intnotgiven:
|
||||
strHfile += '#define AM_BSP_GPIO_%-20s' % pin.name + '%d\n' % pin.pinnum
|
||||
strHfile += 'extern const am_hal_gpio_pincfg_t g_AM_BSP_GPIO_%s;\n' % pin.name
|
||||
#strHfile += '\n'
|
||||
|
||||
strCfile += 'const am_hal_gpio_pincfg_t g_AM_BSP_GPIO_%s =\n' % pin.name
|
||||
strCfile += '{\n'
|
||||
strCfile += '%-25s' % ' .uFuncSel' + '= %s,\n' % pin.func_sel
|
||||
|
||||
if pin.powersw != strnotgiven:
|
||||
if (pin.powersw.lower() == "vdd") or \
|
||||
(pin.powersw.lower() == "vss") or \
|
||||
(pin.powersw.lower() == "none"):
|
||||
strCfile += '%-25s' % ' .ePowerSw' + '= AM_HAL_GPIO_PIN_POWERSW_%s,\n' % pin.powersw.upper()
|
||||
else:
|
||||
strCfile += '%-25s' % ' .ePowerSw' + '= %s,\n' % pin.powersw
|
||||
|
||||
if pin.pullup != strnotgiven:
|
||||
if (pin.pullup.lower() == "none") or \
|
||||
(pin.pullup.lower() == "weak") or \
|
||||
(pin.pullup.lower() == "pulldown") or \
|
||||
(pin.pullup.lower() == "1_5k") or \
|
||||
(pin.pullup.lower() == "6k") or \
|
||||
(pin.pullup.lower() == "12k") or \
|
||||
(pin.pullup.lower() == "24k"):
|
||||
strCfile += '%-25s' % ' .ePullup' + '= AM_HAL_GPIO_PIN_PULLUP_%s,\n' % pin.pullup.upper()
|
||||
elif (pin.pullup == "1_5") or \
|
||||
(pin.pullup == "6") or \
|
||||
(pin.pullup == "12") or \
|
||||
(pin.pullup == "24"):
|
||||
strCfile += '%-25s' % ' .ePullup' + '= AM_HAL_GPIO_PIN_PULLUP_%sK,\n' % pin.pullup
|
||||
else:
|
||||
strCfile += '%-25s' % ' .ePullup' + '= %s,\n' % pin.pullup
|
||||
|
||||
if pin.drvstrength != intnotgiven:
|
||||
if (pin.drvstrength != 2) and (pin.drvstrength != 4) and \
|
||||
(pin.drvstrength != 8) and (pin.drvstrength != 12):
|
||||
pin.drvstrength = 2
|
||||
strCfile += '%-25s' % ' .eDriveStrength' + '= AM_HAL_GPIO_PIN_DRIVESTRENGTH_%dMA,\n' % pin.drvstrength
|
||||
|
||||
if pin.GPOutcfg != strnotgiven:
|
||||
if (pin.GPOutcfg.lower() == "disable") or \
|
||||
(pin.GPOutcfg.lower() == "pushpull") or \
|
||||
(pin.GPOutcfg.lower() == "opendrain") or \
|
||||
(pin.GPOutcfg.lower() == "tristate"):
|
||||
strCfile += '%-25s' % ' .eGPOutcfg' + '= AM_HAL_GPIO_PIN_OUTCFG_%s,\n' % pin.GPOutcfg.upper()
|
||||
else:
|
||||
strCfile += '%-25s' % ' .eGPOutcfg' + '= %s,\n' % pin.GPOutcfg
|
||||
|
||||
if pin.GPinput != strnotgiven:
|
||||
if (pin.GPinput.lower() == "true"):
|
||||
strCfile += '%-25s' % ' .eGPInput' + '= AM_HAL_GPIO_PIN_INPUT_ENABLE,\n'
|
||||
elif (pin.GPinput.lower() == "false"):
|
||||
strCfile += '%-25s' % ' .eGPInput' + '= AM_HAL_GPIO_PIN_INPUT_NONE,\n'
|
||||
else:
|
||||
strCfile += '%-25s' % ' .eGPInput' + '= %s,\n' % pin.GPinput
|
||||
|
||||
if pin.GPRdZero != strnotgiven:
|
||||
if (pin.GPRdZero.lower() == "true") or \
|
||||
(pin.GPRdZero.lower() == "zero"):
|
||||
strCfile += '%-25s' % ' .eGPRdZero' + '= AM_HAL_GPIO_PIN_RDZERO_ZERO,\n'
|
||||
elif (pin.GPRdZero.lower() == "false") or \
|
||||
(pin.GPRdZero.lower() == "readpin"):
|
||||
strCfile += '%-25s' % ' .eGPRdZero' + '= AM_HAL_GPIO_PIN_RDZERO_READPIN,\n'
|
||||
else:
|
||||
strCfile += '%-25s' % ' .eGPRdZero' + '= %s,\n' % pin.GPRdZero
|
||||
|
||||
if pin.intdir != strnotgiven:
|
||||
if (pin.intdir.lower() == "none") or \
|
||||
(pin.intdir.lower() == "lo2hi") or \
|
||||
(pin.intdir.lower() == "hi2lo") or \
|
||||
(pin.intdir.lower() == "either"):
|
||||
strCfile += '%-25s' % ' .eIntDir' + '= AM_HAL_GPIO_PIN_INTDIR_%s,\n' % pin.intdir.upper()
|
||||
else:
|
||||
strCfile += '%-25s' % ' .eIntDir' + '= %s,\n' % pin.intdir
|
||||
|
||||
if (pin.bIomMSPIn != strnotgiven):
|
||||
if pinobj.srcver >= 0x0003:
|
||||
if ((pin.bIomMSPIn[0:1].lower() != "m") and (pin.bIomMSPIn != "0")):
|
||||
bIom = 1
|
||||
else:
|
||||
bIom = 0
|
||||
strCfile += '%-25s' % ' .bIomMSPIn' + '= %d,\n' % bIom
|
||||
|
||||
if pin.IOMnum != strnotgiven:
|
||||
strCfile += '%-25s' % ' .uIOMnum' + '= %s,\n' % str(pin.IOMnum)
|
||||
|
||||
if pin.CEnum != strnotgiven:
|
||||
strCfile += '%-25s' % ' .uNCE' + '= %s,\n' % str(pin.CEnum)
|
||||
|
||||
# Create the define
|
||||
strtmp = '#define AM_BSP_%s_CHNL' % (pin.name)
|
||||
strHfile += '%-40s' % strtmp + '%s\n' % str((pin.CEnum))
|
||||
|
||||
if pin.CEpol != strnotgiven:
|
||||
if (pin.CEpol.lower() == "low") or \
|
||||
(pin.CEpol.lower() == "high"):
|
||||
strCfile += '%-25s' % ' .eCEpol' + '= AM_HAL_GPIO_PIN_CEPOL_ACTIVE%s,\n' % pin.CEpol.upper()
|
||||
elif (pin.CEpol.lower() == "activelow") or \
|
||||
(pin.CEpol.lower() == "activehigh"):
|
||||
strCfile += '%-25s' % ' .eCEpol' + '= AM_HAL_GPIO_PIN_CEPOL_%s,\n' % pin.CEpol.upper()
|
||||
else:
|
||||
strCfile += '%-25s' % ' .eCEpol' + '= %s,\n' % pin.CEpol
|
||||
|
||||
|
||||
# Eliminate the last comma from the last structure member
|
||||
strCfile = strCfile[:-2]
|
||||
|
||||
# Terminate the structure
|
||||
strCfile += '\n};\n'
|
||||
|
||||
if bCreateC:
|
||||
#
|
||||
# Develop and print the C file
|
||||
#
|
||||
S = filetemplateC.format(filename='am_bsp_pins.c', pin_defs=strCfile);
|
||||
print(S)
|
||||
else:
|
||||
#
|
||||
# Develop and print the H file
|
||||
#
|
||||
S = filetemplateH.format(filename='am_bsp_pins.h',
|
||||
pin_defs=strHfile,
|
||||
headerdef='AM_BSP_PINS_H')
|
||||
print(S)
|
||||
|
||||
|
||||
# *****************************************************************************
|
||||
#
|
||||
# main
|
||||
#
|
||||
# *****************************************************************************
|
||||
if __name__ == '__main__':
|
||||
|
||||
#
|
||||
# Get arguments.
|
||||
# First arg is a string for the input .src file.
|
||||
# Second arg must be a C or H.
|
||||
#
|
||||
args = read_arguments()
|
||||
if args.CorH.upper() == 'C':
|
||||
bCreateC = True
|
||||
else:
|
||||
bCreateC = False
|
||||
|
||||
version = get_version(args.input)
|
||||
|
||||
# Redirect the script based on the version number.
|
||||
|
||||
if version & 0xFF == 0x03:
|
||||
pinobj = get_pinobj(args.input)
|
||||
|
||||
#
|
||||
# pinobj.pins is a list of the pins
|
||||
#
|
||||
write_Cfiles(pinobj, bCreateC)
|
||||
@@ -0,0 +1,294 @@
|
||||
'''
|
||||
rsonlite -- an extremely lightweight version of rson.
|
||||
|
||||
Copyright (c) 2012, Patrick Maupin
|
||||
|
||||
License :: MIT
|
||||
|
||||
http://pypi.python.org/pypi/rsonlite
|
||||
http://code.google.com/p/rson/
|
||||
|
||||
rsonlite makes it easy to build a file parser for
|
||||
declarative hierarchical data structures using indentation.
|
||||
(Spaces only, tabs not considered indentation.)
|
||||
|
||||
The only special characters are '#', '=', and indentation:
|
||||
|
||||
- Indentation denotes a key/value relationship. The
|
||||
value is indented from the key.
|
||||
|
||||
- = Denotes the start of a free-format string. These
|
||||
strings can contain '=' and '#' characters, and
|
||||
even be multi-line, but every line in the string
|
||||
must be indented past the initial equal sign.
|
||||
|
||||
Note that, for multi-line strings, indentation is
|
||||
preserved but normalized such that at least one
|
||||
line starts in the left column. This allows for
|
||||
restructuredText or Python code to exist inside
|
||||
multi-line strings.
|
||||
|
||||
- # Denotes the start of a line comment, when not
|
||||
inside a free-format string.
|
||||
|
||||
The only Python objects resulting from parsing a file
|
||||
with rsonlite are:
|
||||
|
||||
- strings:
|
||||
free-format strings (described above) can
|
||||
contain any character, but the whitespace
|
||||
before/after the string may be stripped.
|
||||
|
||||
Regular strings must fit on a single line and
|
||||
cannot contain '=' or '#' characters.
|
||||
|
||||
Regular strings may be used as keys in key/value
|
||||
pairs, but free-format strings may not.
|
||||
|
||||
- tuple:
|
||||
A key/value pair is a two-element tuple. The key is always
|
||||
a string. The value is always a list.
|
||||
|
||||
- list:
|
||||
The top level is a list, and the value element of every
|
||||
key/value pair tuple is also a list. Lists can contain
|
||||
strings and key/value pair tuples.
|
||||
'''
|
||||
|
||||
import re
|
||||
|
||||
version = __version__ = '0.1.0'
|
||||
|
||||
# Our attempt at rationalizing differences between Python 2 and Python 3.
|
||||
|
||||
try:
|
||||
basestring
|
||||
except NameError:
|
||||
basestring = str
|
||||
class unicode: pass
|
||||
|
||||
# Use OrderedDict if it's available
|
||||
|
||||
try:
|
||||
from collections import OrderedDict as stddict
|
||||
except ImportError:
|
||||
stddict = dict
|
||||
|
||||
# Splits the entire file into probable tokens.
|
||||
|
||||
splitter = re.compile('(\n *|=[^\n]*|#[^\n]*|[^\n#=]+)').findall
|
||||
|
||||
class RsonToken(str):
|
||||
''' A string that may be annotated with location information
|
||||
'''
|
||||
def __new__(cls, s, line, col):
|
||||
self = str.__new__(cls, s)
|
||||
self.line = line
|
||||
self.col = col
|
||||
return self
|
||||
def __add__(self, other):
|
||||
return RsonToken(str(self) + other, self.line, self.col)
|
||||
|
||||
|
||||
def gettoks(source):
|
||||
''' Convert string into (probable) tokens
|
||||
(some tokens may be recombined later, e.g. if they
|
||||
contain # or = but were already inside a string)
|
||||
'''
|
||||
|
||||
# Use "regular" strings, whatever that means for the given Python
|
||||
if isinstance(source, unicode):
|
||||
source = source.encode('utf-8', 'replace')
|
||||
elif not isinstance(source, basestring):
|
||||
source = source.decode('utf-8', 'replace')
|
||||
|
||||
# Convert MS-DOS or Mac line endings to the one true way, and
|
||||
# prefix the source with a linefeed to simplify the tokenization.
|
||||
source = '\n' + source.replace('\r\n', '\n').replace('\r', '\n')
|
||||
|
||||
line = 0
|
||||
for tok in splitter(source):
|
||||
if tok.startswith('\n'):
|
||||
line += 1
|
||||
col = len(tok)
|
||||
else:
|
||||
yield RsonToken(tok, line, col)
|
||||
col += len(tok)
|
||||
|
||||
def multiline(lineinfo, dedent):
|
||||
''' Returns one string for each line,
|
||||
properly dedented.
|
||||
'''
|
||||
linenum = lineinfo[0].line
|
||||
for tok in lineinfo:
|
||||
while linenum < tok.line:
|
||||
yield ''
|
||||
linenum += 1
|
||||
yield (tok.col - dedent) * ' ' + tok.rstrip()
|
||||
linenum += 1
|
||||
|
||||
def getfreeformat(toklist, firsttok, firstcol):
|
||||
''' Returns a free-formatted string.
|
||||
'''
|
||||
curline = firsttok.line
|
||||
firstpart = firsttok[1:].strip() # Get past = sign
|
||||
lineinfo = []
|
||||
while toklist and toklist[-1].col > firstcol:
|
||||
tok = toklist.pop()
|
||||
if tok.line == curline:
|
||||
lineinfo[-1] += tok
|
||||
else:
|
||||
lineinfo.append(tok)
|
||||
curline = tok.line
|
||||
if lineinfo:
|
||||
dedent = min(tok.col for tok in lineinfo)
|
||||
if firstpart:
|
||||
lineinfo.insert(0, RsonToken(firstpart, firsttok.line, dedent))
|
||||
firstpart = '\n'.join(multiline(lineinfo, dedent))
|
||||
return RsonToken(firstpart, firsttok.line, firsttok.col)
|
||||
|
||||
def loads(source):
|
||||
''' load a string into an rsonlite datastructure.
|
||||
If the source is not a string instance, then
|
||||
loads will attempt to convert it into a string
|
||||
instance, by encoding to UTF-8 on Python 2,
|
||||
or decoding from UTF-8 on Python 3.
|
||||
'''
|
||||
toklist = list(gettoks(source))
|
||||
toklist.reverse()
|
||||
result = [None]
|
||||
stack = []
|
||||
curcol = -1
|
||||
curlist = result
|
||||
while toklist:
|
||||
tok = toklist.pop()
|
||||
if tok.startswith('#'):
|
||||
continue
|
||||
col = tok.col
|
||||
if col > curcol:
|
||||
stack.append((curcol, curlist))
|
||||
oldlist = curlist
|
||||
curcol, curlist = col, []
|
||||
oldlist[-1] = oldlist[-1], curlist
|
||||
while col < curcol:
|
||||
curcol, curlist = stack.pop()
|
||||
if col != curcol:
|
||||
err = IndentationError('unindent does not match any outer indentation level')
|
||||
err.filename = '<rsonlite>'
|
||||
err.lineno = tok.line
|
||||
raise err
|
||||
if tok.startswith('='):
|
||||
curlist.append(getfreeformat(toklist, tok, col))
|
||||
else:
|
||||
curlist.append(RsonToken(tok.rstrip(), tok.line, tok.col))
|
||||
if toklist and toklist[-1].line == tok.line:
|
||||
tok = toklist.pop()
|
||||
if tok.startswith('='):
|
||||
curlist[-1] = curlist[-1], [getfreeformat(toklist, tok, col)]
|
||||
else:
|
||||
assert tok.startswith('#') # else problem in regex...
|
||||
result, = result
|
||||
return [] if result is None else result[1]
|
||||
|
||||
def dumps(data, indent=' ', initial_indent=''):
|
||||
''' Dump a string loaded with loads back out.
|
||||
'''
|
||||
def getstring(data, indent2):
|
||||
if '\n' in data:
|
||||
data = ('\n'+indent2).join([''] + data.split('\n'))
|
||||
return data
|
||||
|
||||
def recurse(data, indent2):
|
||||
assert isinstance(data, list), repr(data)
|
||||
for data in data:
|
||||
if isinstance(data, tuple):
|
||||
key, value = data
|
||||
if len(value) == 1 and isinstance(value[0], basestring):
|
||||
append('%s%s = %s' % (indent2, key, getstring(value[0], indent2+indent)))
|
||||
else:
|
||||
append('%s%s' % (indent2, key))
|
||||
recurse(value, indent2 + indent)
|
||||
else:
|
||||
assert isinstance(data, basestring)
|
||||
if '\n' in data or '=' in data or '#' in data:
|
||||
append(indent2 + '=')
|
||||
append(getstring(data, indent2 + ' '))
|
||||
else:
|
||||
append('%s%s' % (indent2, data))
|
||||
result = []
|
||||
append = result.append
|
||||
recurse(data, initial_indent)
|
||||
append('')
|
||||
return '\n'.join(result)
|
||||
|
||||
def pretty(data, indent=' '):
|
||||
''' Pretty-print a string loaded by loads into
|
||||
something that makes it easy to see the actual
|
||||
structure of the data. The return value of
|
||||
this should be parseable by eval()
|
||||
'''
|
||||
def recurse(data, indent2):
|
||||
assert isinstance(data, list)
|
||||
for data in data:
|
||||
assert isinstance(data, (tuple, basestring))
|
||||
if isinstance(data, tuple) and (
|
||||
len(data[1]) != 1 or not isinstance(data[1][0], basestring)):
|
||||
append('%s(%s, [' % (indent2, repr(data[0])))
|
||||
recurse(data[1], indent2 + indent)
|
||||
append('%s])' % (indent2))
|
||||
else:
|
||||
append('%s%s,' % (indent2, repr(data)))
|
||||
result = []
|
||||
append = result.append
|
||||
append('[')
|
||||
recurse(data, indent)
|
||||
append(']')
|
||||
append('')
|
||||
return '\n'.join(result)
|
||||
|
||||
##########################################################################
|
||||
# These higher-level functions might suffice for simple data, and also
|
||||
# provide a template for designing similar functions.
|
||||
|
||||
def stringparse(s, special=dict(true=True, false=False, null=None)):
|
||||
''' This gives an example of handling the JSON special identifiers
|
||||
true, false and null, and also of handling simple arrays.
|
||||
'''
|
||||
if s in special:
|
||||
return special[s]
|
||||
if s.startswith('[') and s.endswith(']'):
|
||||
t = s[1:-1]
|
||||
for ch in '"\'[]{}\n':
|
||||
if ch in t:
|
||||
return s
|
||||
return [x.strip() for x in t.split(',')]
|
||||
return s
|
||||
|
||||
def simpleparse(source, stringparse=stringparse, stddict=stddict):
|
||||
''' Return the simplest structure that uses dicts instead
|
||||
of tuples, and doesn't lose any source information.
|
||||
Use ordered dicts if they are available.
|
||||
'''
|
||||
def recurse(mylist):
|
||||
if len(mylist) == 1 and isinstance(mylist[0], basestring):
|
||||
return stringparse(mylist[0])
|
||||
keys = [x[0] for x in mylist if isinstance(x, tuple)]
|
||||
if not keys:
|
||||
return mylist # simple list
|
||||
if len(set(keys)) == len(mylist):
|
||||
return stddict((x, recurse(y)) for (x, y) in mylist)
|
||||
# Complicated. Make a list that might have multiple dicts
|
||||
result = []
|
||||
curdict = None
|
||||
for item in mylist:
|
||||
if not isinstance(item, tuple):
|
||||
result.append(stringparse(item))
|
||||
curdict = None
|
||||
continue
|
||||
key, value = item
|
||||
if curdict is None or key in curdict:
|
||||
curdict = stddict()
|
||||
result.append(curdict)
|
||||
curdict[key] = recurse(value)
|
||||
return result
|
||||
return recurse(source if isinstance(source, list) else loads(source))
|
||||
Reference in New Issue
Block a user