From 06405f20a51b0cf5f5dc6adf0f3fb4cf32241309 Mon Sep 17 00:00:00 2001 From: Peace Kotamnives Date: Fri, 8 Sep 2023 14:18:13 -0400 Subject: [PATCH] Squashed 'sm_cm_config/' content from commit 137e4c2 git-subtree-dir: sm_cm_config git-subtree-split: 137e4c2b3ec9e8ed066eac9506a740976820314f --- .gitignore | 132 ++++++++++ LICENSE | 21 ++ README.md | 2 + data/zynqmon.yml | 111 ++++++++ data/zynqmon_2.yml | 200 ++++++++++++++ src/mcu_generate.ipynb | 152 +++++++++++ src/mcu_generate.py | 34 +++ src/test2.xml | 296 +++++++++++++++++++++ src/xml_generate.ipynb | 576 +++++++++++++++++++++++++++++++++++++++++ src/xml_generate.py | 257 ++++++++++++++++++ src/yamltest.ipynb | 194 ++++++++++++++ 11 files changed, 1975 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 data/zynqmon.yml create mode 100644 data/zynqmon_2.yml create mode 100644 src/mcu_generate.ipynb create mode 100644 src/mcu_generate.py create mode 100644 src/test2.xml create mode 100644 src/xml_generate.ipynb create mode 100644 src/xml_generate.py create mode 100644 src/yamltest.ipynb diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..bac671c8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,132 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# testing xml output +src/test.xml diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..8b5c50b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Apollo platform for CMS and ATLAS at CERN + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 00000000..57714e99 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# sm_cm_config +Configuration files for SM and CM firmware diff --git a/data/zynqmon.yml b/data/zynqmon.yml new file mode 100644 index 00000000..d8d2eab9 --- /dev/null +++ b/data/zynqmon.yml @@ -0,0 +1,111 @@ +name: zynqmon configuration file +cm_hw_rev: 1A +sm_hw_rev: 1A +sm_fw_rev: 1A +revision: 1 +psmon_single_instance: &psmon_one [TEMP1, TEMP3, VIN, VOUT, IOUT, RESERVED, RESERVED, RESERVED] + +config: + - name: firefly + start: 0 + count: 25 + mcu_call: firefly_temps + type: int8 + extra: Table=CM_FF_MON;Column=Temp_C;Status=1; + names: + - K01 12 Tx GTH + - K01 12 Rx GTH + - K02 12 Tx GTH + - K02 12 Rx GTH + - K03 12 Tx GTH + - K03 12 Rx GTH + - K04 4 XCVR GTY + - K05 4 XCVR GTY + - K06 4 XCVR GTY + - K07 12 Tx GTY + - K07 12 Rx GTY + - V01 4 XCVR GTY + - V02 4 XCVR GTY + - V03 4 XCVR GTY + - V04 4 XCVR GTY + - V05 4 XCVR GTY + - V06 4 XCVR GTY + - V07 4 XCVR GTY + - V08 4 XCVR GTY + - V09 4 XCVR GTY + - V10 4 XCVR GTY + - V11 12 Tx GTY + - V11 12 Rx GTY + - V12 12 Tx GTY + - V12 12 Rx GTY + - name: psmon + start: 32 + count: 8 + mcu_call: psmon + type: fp16 + extra: Table=CM_MON;Status=2 + names: + - 1V8 + - 3V3 + - KVCCINT1_1 + - KVCCINT1_2 + - VVCCINT1_1 + - VVCCINT1_2 + - VVCCINT2_1 + - VVCCINT2_2 + postfixes: *psmon_one + - name: adcmon + start: 96 + count: 21 + mcu_call: adcmon + type: fp16 + extra: Table=CM_MON;Status=2;Column=ADC + names: + - VCC_12V + - VCC_2V5 + - VCC_M3V3 + - VCC_3V3 + - VCC_1V8 + - VCC_M1V8 + - V_VCCINT + - K_VCCINT + - V_MGTY1_AVTT + - V_MGTY2_AVTT + - K_MGTH_AVTT + - K_MGTY_AVTT + - V_MGTY1_VCCAUX + - V_MGTY2_VCCAUX + - K_MGTY_VCCAUX + - K_MGTH_VCCAUX + - V_MGTY1_AVCC + - V_MGTY2_AVCC + - K_MGTY_AVCC + - K_MGTH_AVCC + - TM4C_TEMP + - name: uptime + start: 192 + count: 1 + type: uint32_t + mcu_call: uptime + extra: Table=CM_MON;Column=Minutes;Status=1 + names: + - MCU_UPTIME + - name: gitversion + start: 118 + count: 20 + type: char + size: 5 + mcu_call: gitversion + names: + - MCU_FW_VER + - name: fpga + start: 128 + count: 4 + type: fp16 + extra: Table=CM_MON;Column=Temp_C;Status=2; + mcu_call: fpga + names: + - F1_TEMP_SLR0 + - F2_TEMP_SLR0 + - F1_TEMP_SLR1 + - F2_TEMP_SLR1 diff --git a/data/zynqmon_2.yml b/data/zynqmon_2.yml new file mode 100644 index 00000000..30cd346d --- /dev/null +++ b/data/zynqmon_2.yml @@ -0,0 +1,200 @@ +name: zynqmon configuration file +cm_hw_rev: 2B +sm_hw_rev: 1A +sm_fw_rev: 1A +revision: 1 + + +config: + - name: firefly + start: 0 + count: 40 + mcu_call: firefly_info + type: uint16_t + extra: Table=CM_FF_MON;Status=1 + names: + - F1_P1_Tx12 + - F1_P1_Rx12 + - F1_P2_Tx12 + - F1_P2_Rx12 + - F1_P3_Tx12 + - F1_P3_Rx12 + - F1_P4_XCVR4 + - F1_P5_XCVR4 + - F1_P6_XCVR4 + - F1_P7_XCVR4 + - F2_P1_Tx12 + - F2_P1_Rx12 + - F2_P2_Tx12 + - F2_P2_Rx12 + - F2_P3_Tx12 + - F2_P3_Rx12 + - F2_P4_XCVR4 + - F2_P5_XCVR4 + - F2_P6_XCVR4 + - F2_P7_XCVR4 + postfixes: + - Temp_C + - OptPow + - name: uptime + start: 44 + count: 1 + type: uint32_t + mcu_call: uptime + extra: Table=CM_MON;Column=Minutes;Status=1 + names: + - MCU_UPTIME + - name: psmon + start: 47 + count: 84 + mcu_call: psmon + type: fp16 + extra: Table=CM_MON;Status=2 + names: + - 1V8 + - 3V3 + - F1VCCINT1_S1 + - F1VCCINT1_S2 + - F1VCCINT2_S1 + - F1VCCINT2_S2 + - F2VCCINT1_S1 + - F2VCCINT1_S2 + - F2VCCINT2_S1 + - F2VCCINT2_S2 + - F1AVTT + - F1AVCC + - F2AVTT + - F2AVCC + postfixes: + - TEMP1 + - TEMP3 + - VIN + - VOUT + - IOUT + - STATUS_WORD + - name: gitversion + start: 132 + count: 10 + type: char + size: 5 + mcu_call: gitversion + names: + - MCU_FW_VER + - name: adcmon + start: 143 + count: 21 + mcu_call: adcmon + type: fp16 + extra: Table=CM_MON;Status=1;Column=ADC + names: + - VCC_V120 + - VCC_MV33 + - VCC_V33 + - VCC_V40 + - VCC_V18 + - F1_VCCINT + - F1_AVCC + - F1_AVTT + - F1_VCCAUX + - F2_VCCINT + - F2_AVCC + - F2_AVTT + - F2_VCCAUX + - CUR_V_V12 + - CUR_V_MV33 + - CUR_V_V40 + - CUR_V_F1VCCAUX + - CUR_V_F2VCCAUX + - F1_TEMP + - F2_TEMP + - TM4C_TEMP + - name: fpga + start: 165 + count: 8 + type: fp16 + extra: Table=CM_MON;Column=Temp_C;Status=2; + mcu_call: fpga + names: + - F1_TEMP_SLR0 + - F1_TEMP_SLR1 + - F1_TEMP_SLR2 + - F1_TEMP_SLR3 + - F2_TEMP_SLR0 + - F2_TEMP_SLR1 + - F2_TEMP_SLR2 + - F2_TEMP_SLR3 + - name: allclkmon + start: 174 + count: 40 + type: uint16_t + extra: Table=CM_CLK_MON;Status=1 + mcu_call: allclkmon + names: + - R0A + - R0B + - R1A + - R1B + - R1C + postfixes: + - PN_BASE0 + - PN_BASE1 + - DEVICE_REV + - I2C_ADDR + - STATUS_OR_LOSXAXB + - LOS_OR_LOSOOF_IN + - LOSIN_FLG_OR_LOL + - STICKY_FLG + - name: clkr0aconfigversion + start: 216 + count: 4 + type: char + size: 2 + mcu_call: clkr0aconfigversion + names: + - MCU_CLKR0A_VER + - name: clkr0bconfigversion + start: 220 + count: 4 + type: char + size: 2 + mcu_call: clkr0bconfigversion + names: + - MCU_CLKR0B_VER + - name: clkr1aconfigversion + start: 224 + count: 4 + type: char + size: 2 + mcu_call: clkr1aconfigversion + names: + - MCU_CLKR1A_VER + - name: clkr1bconfigversion + start: 228 + count: 4 + type: char + size: 2 + mcu_call: clkr1bconfigversion + names: + - MCU_CLKR1B_VER + - name: clkr1cconfigversion + start: 232 + count: 4 + type: char + size: 2 + mcu_call: clkr1cconfigversion + names: + - MCU_CLKR1C_VER + - name: firefly_bits + start: 236 + count: 8 + type: uint16_t + extra: Table=CM_FFARGV_MON;Status=1 + mcu_call: firefly_bits + names: + - F1_FFL12CH + - F1_FFLDAQ + - F2_FFL12CH + - F2_FFLDAQ + postfixes: + - IS_FF25Gbs + - IS_PRESENT diff --git a/src/mcu_generate.ipynb b/src/mcu_generate.ipynb new file mode 100644 index 00000000..a21fb711 --- /dev/null +++ b/src/mcu_generate.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "import yaml\n", + "from pprint import pprint\n", + "import dicttoxml\n", + "# there is also dict2xml available in pypy (python3)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "with open('../data/zynqmon_2.yml') as f:\n", + " data = yaml.load(f, Loader=yaml.FullLoader)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "firefly\n", + "psmon\n", + "adcmon\n", + "uptime\n", + "gitversion\n", + "fpga\n" + ] + } + ], + "source": [ + "config = data['config']\n", + "for c in config:\n", + " print(c['name'])" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# size = 0\n", + "# for c in config:\n", + "# # generate C call\n", + "# expected_length = len(c['names'])\n", + "# if 'postfixes' in c:\n", + "# expected_length *= len(c['postfixes'])\n", + "# if '32' in c['type']:\n", + "# expected_length *= 2\n", + "# if 'size' in c:\n", + "# expected_length *= c['size']*4 # size in 4 byte words -- extra factor of 4\n", + "# #if ( c['count'] != expected_length ) :\n", + "# # print(f\"// mismatch: {expected_length}, size {c['count']}\")\n", + "# print(f\"// {c['name']}, size {expected_length}\")\n", + "# print(f\"zm_set_{c['mcu_call']}(&zynqmon_data[{size}], {c['start']});\")\n", + "# size += expected_length\n", + "# print(f\"#define ZMON_VALID_ENTRIES {size}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "// firefly, size 20\n", + "zm_set_firefly_temps(&zynqmon_data[0], 0);\n", + "// psmon, size 70\n", + "zm_set_psmon(&zynqmon_data[20], 32);\n", + "// adcmon, size 21\n", + "zm_set_adcmon(&zynqmon_data[90], 128);\n", + "// uptime, size 2\n", + "zm_set_uptime(&zynqmon_data[111], 192);\n", + "// gitversion, size 10.0\n", + "zm_set_gitversion(&zynqmon_data[113], 118);\n", + "// fpga, size 8\n", + "zm_set_fpga(&zynqmon_data[123], 150);\n", + "#define ZMON_VALID_ENTRIES 131\n" + ] + } + ], + "source": [ + "size = 0\n", + "for c in config:\n", + " # generate C call\n", + " expected_length = len(c['names'])\n", + " if 'postfixes' in c:\n", + " expected_length *= len(c['postfixes'])\n", + " if '32' in c['type']:\n", + " expected_length *= 2\n", + " elif 'char' in c['type']:\n", + " expected_length = expected_length/2.\n", + " if 'size' in c:\n", + " expected_length *= c['size']*4 # size in 4 byte words -- extra factor of 4\n", + " #if ( c['count'] != expected_length ) :\n", + " # print(f\"// mismatch: {expected_length}, size {c['count']}\")\n", + " print(f\"// {c['name']}, size {expected_length}\")\n", + " print(f\"zm_set_{c['mcu_call']}(&zynqmon_data[{size}], {c['start']});\")\n", + " size += int(expected_length)\n", + "print(f\"#define ZMON_VALID_ENTRIES {size}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "interpreter": { + "hash": "d1bcf2015140efba1309a3b878c8a09b28a5da1fac13dcbb304588e5a25844fe" + }, + "kernelspec": { + "display_name": "Python 3.8.12 64-bit ('base': conda)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12 (main, Jun 1 2022, 06:36:29) \n[Clang 12.0.0 ]" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/src/mcu_generate.py b/src/mcu_generate.py new file mode 100644 index 00000000..291333e0 --- /dev/null +++ b/src/mcu_generate.py @@ -0,0 +1,34 @@ +import yaml +from pprint import pprint +#import dicttoxml +# there is also dict2xml available in pypy (python3) + + + +with open('../data/zynqmon_2.yml') as f: + data = yaml.load(f, Loader=yaml.FullLoader) + + +config = data['config'] +for c in config: + print(c['name']) + + +size = 0 +for c in config: + # generate C call + expected_length = len(c['names']) + if 'postfixes' in c: + expected_length *= len(c['postfixes']) + if '32' in c['type']: + expected_length *= 2 + elif 'char' in c['type']: + expected_length = expected_length/2. + if 'size' in c: + expected_length *= c['size']*4 # size in 4 byte words -- extra factor of 4 + #if ( c['count'] != expected_length ) : + # print(f"// mismatch: {expected_length}, size {c['count']}") + print(f"// {c['name']}, size {expected_length}") + print(f"zm_set_{c['mcu_call']}(&zynqmon_data[{size}], {c['start']});") + size += int(expected_length) +print(f"#define ZMON_VALID_ENTRIES {size}") diff --git a/src/test2.xml b/src/test2.xml new file mode 100644 index 00000000..425baf9f --- /dev/null +++ b/src/test2.xml @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/xml_generate.ipynb b/src/xml_generate.ipynb new file mode 100644 index 00000000..65814d8f --- /dev/null +++ b/src/xml_generate.ipynb @@ -0,0 +1,576 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "import yaml\n", + "from pprint import pprint\n", + "import xml.etree.ElementTree as ET\n" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "verbose=False" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "with open('../data/zynqmon_2.yml') as f:\n", + " y = yaml.load(f, Loader=yaml.FullLoader)\n", + " if (verbose) :\n", + " pprint(y)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "def makeNode(parent: ET.Element, id: str, c: dict, addr2: int, parent_id: str) -> ET.Element:\n", + " node = ET.SubElement(parent, 'node')\n", + " id = id.replace(' ', '_')\n", + " start = c['start']\n", + " count = c['count']\n", + " node.set('id', id)\n", + " # address is half of the sensor address since these are 32 bit addresses\n", + " addr = int(addr2/2)\n", + " remain = addr2 % 2\n", + " node.set('address', str(hex(addr)))\n", + " # this appears to be on all the nodes\n", + " node.set(\"permission\", \"r\")\n", + " # set parameter based on the type\n", + " if (c['type'] == 'int8'):\n", + " width = 8\n", + " format = \"d\"\n", + " elif (c['type'] == 'int16'):\n", + " width = 16\n", + " format = \"d16\"\n", + " elif (c['type'] == 'fp16'):\n", + " width = 16\n", + " format = \"fp16\"\n", + " elif (c['type'] == 'char'):\n", + " width = 8\n", + " format = \"c\"\n", + " elif (c['type'] == 'uint32_t'):\n", + " width = 32\n", + " format = \"u\"\n", + " else:\n", + " print(\"ERROR: unknown type\", c['type'])\n", + " return None\n", + " if 'size' in c: # if there is a size, it cannot have a mask\n", + " node.set('size', str(hex(c['size'])))\n", + " else: \n", + " mask = (1 << width) - 1\n", + " if (remain == 0):\n", + " node.set('mask', \"0x{0:08X}\".format(mask))\n", + " else:\n", + " node.set('mask', \"0x{0:08X}\".format(mask << 16))\n", + " if 'extra' in c:\n", + " extra = c['extra']\n", + " if not \"Column\" in extra:\n", + " extra = extra + \";Column=\" + id\n", + " if not \"Row\" in extra :\n", + " if parent_id != \"\":\n", + " extra = \"Row=\" + parent_id + \";\" + extra\n", + " else:\n", + " extra = \"Row=\" + id + \";\" + extra\n", + " else:\n", + " extra = \"\"\n", + " node.set('parameters', \"Format=\" + format + \";\" + extra)\n", + " return node\n" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [], + "source": [ + "# This is the parent (root) tag\n", + "# onto which other tags would be\n", + "# created\n", + "cm = ET.Element('node')\n", + "cm.set('id', 'CM')\n", + "cm.set('address', '0x00000000')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [], + "source": [ + "config = y['config']\n", + "\n", + "for c in config: # loop over entries in configuration (sensor category)\n", + " i = 0 # counter over the number of sensors within a category\n", + " names = c['names']\n", + " for n in names: # loop over names of sensors within a category\n", + " if 'postfixes' in c:\n", + " pp = node = ET.SubElement(cm, 'node')\n", + " pp.set('id', n)\n", + " start = c['start']\n", + " addr = int((start + i)/2)\n", + " #addr = int((start + i)/2)\n", + " pp.set('address', str(hex(addr)))\n", + " #pp.set(\"mask\", \"0x{0:08X}\".format(0xFFFFFFFF))\n", + " postfixes = c['postfixes']\n", + " j = 0\n", + " for p in postfixes:\n", + " if p == 'RESERVED':\n", + " i += 1\n", + " j += 1\n", + " continue\n", + " if verbose: \n", + " print(\"adding postfix\", p, \"to node\", n)\n", + " node = makeNode(pp, p, c, j, n)\n", + " i += 1\n", + " j += 1\n", + " else:\n", + " start = c['start']\n", + " makeNode(cm, n, c, start+i, \"\")\n", + " i += 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "config = y['config']\n", + "\n", + "for c in config: # loop over entries in configuration (sensor category)\n", + " print(\"here\", c['name'])\n", + " if not 'start' in c:\n", + " pprint(c)\n", + " start = c['start']\n", + " count = c['count']\n", + " i = 0 # counter over the number of sensors within a category\n", + " names = c['names']\n", + " if 'prefixes' in c:\n", + " postfixes = c['postfixes']\n", + " else:\n", + " postfixes = ' '\n", + " for p in prefixes:\n", + " for n in names: # loop over sensor names\n", + " node = ET.SubElement(cm, 'node')\n", + " if ( len(p.lstrip()) > 0 ):\n", + " id = p +\"_\" + n.replace(' ', '_')\n", + " else:\n", + " id = n.replace(' ', '_')\n", + " node.set('id', id)\n", + " addr = int((start + i)/2) ## address is half of the sensor address since these are 32 bit addresses\n", + " remain = (start + i) % 2\n", + " node.set('address', str(hex(addr)))\n", + " i += 1 # offset for next sensor\n", + " # this appears to be on all the nodes\n", + " node.set(\"permission\", \"r\")\n", + " # set parameter based on the type\n", + " if ( c['type'] == 'int8' ):\n", + " width=8\n", + " format = \"d\"\n", + " elif ( c['type'] == 'fp16' ):\n", + " width=16\n", + " format = \"fp16\"\n", + " elif ( c['type'] == 'char' ):\n", + " width=8\n", + " format = \"c\"\n", + " elif ( c['type'] == 'uint32_t' ):\n", + " width=32\n", + " format = \"u\"\n", + " else:\n", + " print(\"ERROR: unknown type\", c['type'])\n", + " break\n", + " mask = (1 << width) - 1\n", + " if (remain == 0):\n", + " node.set('mask', \"0x{0:08X}\".format(mask))\n", + " else:\n", + " node.set('mask', \"0x{0:08X}\".format(mask<<16))\n", + " if 'extra' in c:\n", + " extra = c['extra']\n", + " else:\n", + " extra = \"\"\n", + " node.set('parameters', \"format=\" + format + \";\" + extra)\n", + " if 'size' in c:\n", + " print(\"size:\", c['size'], c['name'])\n", + " node.set('size', str(hex(c['size'])))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "s_xml = ET.tostring(cm).decode()\n", + "\n", + "tree = ET.ElementTree(cm)\n", + "ET.indent(tree, space='\\t')\n", + "tree.write(\"test2.xml\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n" + ] + } + ], + "source": [ + "from bs4 import BeautifulSoup\n", + "\n", + "bs = BeautifulSoup(s_xml, 'xml')\n", + "pretty_xml = bs.prettify()\n", + "with open(\"test.xml\", \"w\") as f:\n", + " print(pretty_xml, file=f)\n", + "print(pretty_xml)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "def calcSize(c: dict) -> int:\n", + " if 'size' in c:\n", + " size = c['size']*2 # extra factor of 2 for 16 to 32 bit\n", + " else:\n", + " size = 1\n", + " if '32' in c['type']:\n", + " size = size * 2\n", + " elif 'char' in c['type']:\n", + " size = size // 2\n", + " return size\n" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[name: firefly start: 0 end: 19 size: 20,\n", + " name: psmon start: 32 end: 115 size: 84,\n", + " name: adcmon start: 128 end: 148 size: 21,\n", + " name: uptime start: 192 end: 193 size: 2,\n", + " name: gitversion start: 118 end: 122 size: 5,\n", + " name: fpga start: 150 end: 157 size: 8,\n", + " name: clocks start: 158 end: 161 size: 4,\n", + " name: clocks start: 172 end: 191 size: 20]\n" + ] + } + ], + "source": [ + "# check overlaps\n", + "# create an object with a name, and a start end end register\n", + "# do so for every entry\n", + "# then ensure that no two objects overlap\n", + "\n", + "# create a class to hold a name, start, end, and size\n", + "# add a method to check if two objects overlap\n", + "# and a pretty print method\n", + "from itertools import chain\n", + "class reg:\n", + " def __init__(self, name, start, end, size):\n", + " self.name = name\n", + " self.start = start\n", + " self.end = end\n", + " self.size = size\n", + " def __str__(self):\n", + " return \"name: \" + self.name + \" start: \" + str(self.start) + \" end: \" + str(self.end) + \" size: \" + str(self.size)\n", + " def __repr__(self):\n", + " return \"name: \" + self.name + \" start: \" + str(self.start) + \" end: \" + str(self.end) + \" size: \" + str(self.size)\n", + " def overlaps(self, other):\n", + " if (self.start <= other.start and self.end >= other.start):\n", + " return True\n", + " if (self.start <= other.end and self.end >= other.end):\n", + " return True\n", + " if (self.start >= other.start and self.end <= other.end):\n", + " return True\n", + " return False\n", + "\n", + "# create a list of objects\n", + "entries = []\n", + "for c in config: # loop over entries in configuration (sensor category)\n", + " if not 'start' in c:\n", + " pprint(c)\n", + " start = c['start']\n", + " count = c['count']\n", + " i = 0 # counter over the number of sensors within a category\n", + " names = c['names']\n", + " if 'postfixes' in c:\n", + " postfixes = c['postfixes']\n", + " else:\n", + " postfixes = ' '\n", + " size = calcSize(c) \n", + " thislength = len(postfixes) * len(names)*size\n", + " entries.append(reg(c['name'], start, start + thislength - 1, thislength))\n", + "pprint(entries)\n", + "\n", + "# check for overlaps\n", + "for i in range(len(entries)):\n", + " for j in range(i+1, len(entries)):\n", + " if entries[i].overlaps(entries[j]):\n", + " print(f\"{entries[i].name} overlaps with {entries[j].name}\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "interpreter": { + "hash": "d1bcf2015140efba1309a3b878c8a09b28a5da1fac13dcbb304588e5a25844fe" + }, + "kernelspec": { + "display_name": "Python 3.8.12 ('base')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.15" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/src/xml_generate.py b/src/xml_generate.py new file mode 100644 index 00000000..160487c0 --- /dev/null +++ b/src/xml_generate.py @@ -0,0 +1,257 @@ +# %% +import yaml +from pprint import pprint +import xml.etree.ElementTree as ET + + +# %% +verbose=False + +# %% +with open('../data/zynqmon_2.yml') as f: + y = yaml.load(f, Loader=yaml.FullLoader) + if (verbose) : + pprint(y) + + +# %% +def makeNode(parent: ET.Element, id: str, c: dict, addr2: int, parent_id: str) -> ET.Element: + node = ET.SubElement(parent, 'node') + id = id.replace(' ', '_') + start = c['start'] + count = c['count'] + node.set('id', id) + # address is half of the sensor address since these are 32 bit addresses + addr = int(addr2/2) + remain = addr2 % 2 + node.set('address', str(hex(addr))) + # this appears to be on all the nodes + node.set("permission", "r") + # set parameter based on the type + if (c['type'] == 'int8'): + width = 8 + format = "d" + elif (c['type'] == 'int16'): + width = 16 + format = "d" + elif (c['type'] == 'fp16'): + width = 16 + format = "fp16" + elif (c['type'] == 'char'): + node.set('mode', "incremental") + format = "c" + elif (c['type'] == 'uint32_t'): + width = 32 + format = "u" + elif (c['type'] == 'uint16_t'): + width = 16 + format = "u" + else: + print("ERROR: unknown type", c['type']) + return None + if 'size' in c: # if there is a size, it cannot have a mask + node.set('size', str(hex(c['size']))) + else: + mask = (1 << width) - 1 + if (remain == 0): + node.set('mask', "0x{0:08X}".format(mask)) + else: + node.set('mask', "0x{0:08X}".format(mask << 16)) + if 'extra' in c: + extra = c['extra'] + if not "Column" in extra: + extra = extra + ";Column=" + id #this semicolon asks for no semicolon in extra when postfixes are included + if not "Row" in extra : + if parent_id != "": + extra = "Row=" + parent_id + ";" + extra + else: + extra = "Row=" + id + ";" + extra + else: + extra = "" + node.set('parameters', "Format=" + format + ";" + extra) + return node + + +# %% +# This is the parent (root) tag +# onto which other tags would be +# created +cm = ET.Element('node') +cm.set('id', 'CM') +cm.set('address', '0x00000000') + + +# %% +config = y['config'] + +for c in config: # loop over entries in configuration (sensor category) + i = 0 # counter over the number of sensors within a category + names = c['names'] + for n in names: # loop over names of sensors within a category + if 'postfixes' in c: + pp = node = ET.SubElement(cm, 'node') + pp.set('id', n) + start = c['start'] + addr = int((start + i)/2) + #addr = int((start + i)/2) + pp.set('address', str(hex(addr))) + #pp.set("mask", "0x{0:08X}".format(0xFFFFFFFF)) + postfixes = c['postfixes'] + j = 0 + for p in postfixes: + if p == 'RESERVED': + i += 1 + j += 1 + continue + if verbose: + print("adding postfix", p, "to node", n) + node = makeNode(pp, p, c, j, n) + i += 1 + j += 1 + else: + start = c['start'] + makeNode(cm, n, c, start+i, "") + i += 1 + +# %% [markdown] +# config = y['config'] +# +# for c in config: # loop over entries in configuration (sensor category) +# print("here", c['name']) +# if not 'start' in c: +# pprint(c) +# start = c['start'] +# count = c['count'] +# i = 0 # counter over the number of sensors within a category +# names = c['names'] +# if 'prefixes' in c: +# postfixes = c['postfixes'] +# else: +# postfixes = ' ' +# for p in prefixes: +# for n in names: # loop over sensor names +# node = ET.SubElement(cm, 'node') +# if ( len(p.lstrip()) > 0 ): +# id = p +"_" + n.replace(' ', '_') +# else: +# id = n.replace(' ', '_') +# node.set('id', id) +# addr = int((start + i)/2) ## address is half of the sensor address since these are 32 bit addresses +# remain = (start + i) % 2 +# node.set('address', str(hex(addr))) +# i += 1 # offset for next sensor +# # this appears to be on all the nodes +# node.set("permission", "r") +# # set parameter based on the type +# if ( c['type'] == 'int8' ): +# width=8 +# format = "d" +# elif ( c['type'] == 'fp16' ): +# width=16 +# format = "fp16" +# elif ( c['type'] == 'char' ): +# width=8 +# format = "c" +# elif ( c['type'] == 'uint32_t' ): +# width=32 +# format = "u" +# else: +# print("ERROR: unknown type", c['type']) +# break +# mask = (1 << width) - 1 +# if (remain == 0): +# node.set('mask', "0x{0:08X}".format(mask)) +# else: +# node.set('mask', "0x{0:08X}".format(mask<<16)) +# if 'extra' in c: +# extra = c['extra'] +# else: +# extra = "" +# node.set('parameters', "format=" + format + ";" + extra) +# if 'size' in c: +# print("size:", c['size'], c['name']) +# node.set('size', str(hex(c['size']))) +# + +# %% [markdown] +# + +# %% +tree = ET.ElementTree(cm) +ET.indent(tree, space='\t') +tree.write("test2.xml") + +# %% +def calcSize(c: dict) -> int: + if 'size' in c: + size = c['size']*2 # extra factor of 2 for 16 to 32 bit + else: + size = 1 + if '32' in c['type']: + size = size * 2 + elif 'char' in c['type']: + size = size // 2 + return size + + +# %% +# check overlaps +# create an object with a name, and a start end end register +# do so for every entry +# then ensure that no two objects overlap + +# create a class to hold a name, start, end, and size +# add a method to check if two objects overlap +# and a pretty print method +from itertools import chain +class reg: + def __init__(self, name, start, end, size): + self.name = name + self.start = start + self.end = end + self.size = size + def __str__(self): + return "name: " + self.name + " start: " + str(self.start) + " end: " + str(self.end) + " size: " + str(self.size) + def __repr__(self): + return "name: " + self.name + " start: " + str(self.start) + " end: " + str(self.end) + " size: " + str(self.size) + def overlaps(self, other): + if (self.start <= other.start and self.end >= other.start): + return True + if (self.start <= other.end and self.end >= other.end): + return True + if (self.start >= other.start and self.end <= other.end): + return True + return False + def overloads(self, other): + if (self.start >= 237): + return True + return False + +# create a list of objects +entries = [] +for c in config: # loop over entries in configuration (sensor category) + if not 'start' in c: + pprint(c) + start = c['start'] + count = c['count'] + i = 0 # counter over the number of sensors within a category + names = c['names'] + if 'postfixes' in c: + postfixes = c['postfixes'] + else: + postfixes = ' ' + size = calcSize(c) + thislength = len(postfixes) * len(names)*size + entries.append(reg(c['name'], start, start + thislength - 1, thislength)) +pprint(entries) + +# check for overlaps and overloads +for i in range(len(entries)): + for j in range(i+1, len(entries)): + if entries[i].overlaps(entries[j]): + print(f"{entries[i].name} overlaps with {entries[j].name}") + +if entries[len(entries)-1].overloads(entries[len(entries)-1]): + print(f"{entries[len(entries)-1].name} overloads") + + diff --git a/src/yamltest.ipynb b/src/yamltest.ipynb new file mode 100644 index 00000000..38bd0b9d --- /dev/null +++ b/src/yamltest.ipynb @@ -0,0 +1,194 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import yaml\n", + "from pprint import pprint\n", + "import dicttoxml\n", + "# there is also dict2xml available in pypy (python3)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'cm_hw_rev': '1A',\n", + " 'config': [{'count': 25,\n", + " 'mcu_call': 'firefly_temps',\n", + " 'name': 'firefly',\n", + " 'names': ['K01 12 Tx GTH',\n", + " 'K01 12 Rx GTH',\n", + " 'K02 12 Tx GTH',\n", + " 'K02 12 Rx GTH',\n", + " 'K03 12 Tx GTH',\n", + " 'K03 12 Rx GTH',\n", + " 'K04 4 XCVR GTY',\n", + " 'K05 4 XCVR GTY',\n", + " 'K06 4 XCVR GTY',\n", + " 'K07 12 Tx GTY',\n", + " 'K07 12 Rx GTY',\n", + " 'V01 4 XCVR GTY',\n", + " 'V02 4 XCVR GTY',\n", + " 'V03 4 XCVR GTY',\n", + " 'V04 4 XCVR GTY',\n", + " 'V05 4 XCVR GTY',\n", + " 'V06 4 XCVR GTY',\n", + " 'V07 4 XCVR GTY',\n", + " 'V08 4 XCVR GTY',\n", + " 'V09 4 XCVR GTY',\n", + " 'V10 4 XCVR GTY',\n", + " 'V11 12 Tx GTY',\n", + " 'V11 12 Rx GTY',\n", + " 'V12 12 Tx GTY',\n", + " 'V12 12 Rx GTY'],\n", + " 'start': 0,\n", + " 'type': 'int8'},\n", + " {'count': 8,\n", + " 'mcu_call': 'psmon',\n", + " 'name': 'psmon',\n", + " 'names': ['TEMP1',\n", + " 'TEMP3',\n", + " 'VIN',\n", + " 'VOUT',\n", + " 'IOUT',\n", + " 'RESERVED',\n", + " 'RESERVED',\n", + " 'RESERVED'],\n", + " 'prefix': None,\n", + " 'start': 32,\n", + " 'type': 'fp16'},\n", + " {'count': 21,\n", + " 'mcu_call': 'adcmon',\n", + " 'name': 'adcmon',\n", + " 'names': ['VCC_12V',\n", + " 'VCC_2V5',\n", + " 'VCC_M3V3',\n", + " 'VCC_3V3',\n", + " 'VCC_1V8',\n", + " 'VCC_M1V8',\n", + " 'V_VCCINT',\n", + " 'K_VCCINT',\n", + " 'V_MGTY1_AVTT',\n", + " 'V_MGTY2_AVTT',\n", + " 'K_MGTH_AVTT',\n", + " 'K_MGTY_AVTT',\n", + " 'V_MGTY1_VCCAUX',\n", + " 'V_MGTY2_VCCAUX',\n", + " 'K_MGTY_VCCAUX',\n", + " 'K_MGTH_VCCAUX',\n", + " 'V_MGTY1_AVCC',\n", + " 'V_MGTY2_AVCC',\n", + " 'K_MGTY_AVCC',\n", + " 'K_MGTH_AVCC',\n", + " 'TM4C_TEMP'],\n", + " 'start': 40,\n", + " 'type': 'fp16'},\n", + " {'count': 2,\n", + " 'mcu_call': 'uptime',\n", + " 'name': 'uptime',\n", + " 'names': ['Uptime'],\n", + " 'start': 192,\n", + " 'type': 'uint32_t'},\n", + " {'count': 20,\n", + " 'mcu_call': 'gitversion',\n", + " 'name': 'gitversion',\n", + " 'names': ['Git_Version'],\n", + " 'start': 194,\n", + " 'type': 'char'},\n", + " {'count': 2,\n", + " 'mcu_call': 'fpga',\n", + " 'name': 'fpga',\n", + " 'names': ['F1_TEMP', 'F2_TEMP'],\n", + " 'start': 128,\n", + " 'type': 'float16'}],\n", + " 'name': 'zynqmon configuration file',\n", + " 'psmon_single_instance': ['TEMP1',\n", + " 'TEMP3',\n", + " 'VIN',\n", + " 'VOUT',\n", + " 'IOUT',\n", + " 'RESERVED',\n", + " 'RESERVED',\n", + " 'RESERVED'],\n", + " 'revision': 1,\n", + " 'sm_fw_rev': '1A',\n", + " 'sm_hw_rev': '1A'}\n" + ] + } + ], + "source": [ + "with open('../data/zynqmon.yml') as f:\n", + " data = yaml.load(f, Loader=yaml.FullLoader)\n", + " pprint(data)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "b'zynqmon configuration file1A1A1A1firefly025fireflyint8K01 12 Tx GTHK01 12 Rx GTHK02 12 Tx GTHK02 12 Rx GTHK03 12 Tx GTHK03 12 Rx GTHK04 4 XCVR GTYK05 4 XCVR GTYK06 4 XCVR GTYK07 12 Tx GTYK07 12 Rx GTYV01 4 XCVR GTYV02 4 XCVR GTYV03 4 XCVR GTYV04 4 XCVR GTYV05 4 XCVR GTYV06 4 XCVR GTYV07 4 XCVR GTYV08 4 XCVR GTYV09 4 XCVR GTYV10 4 XCVR GTYV11 12 Tx GTYV11 12 Rx GTYV12 12 Tx GTYV12 12 Rx GTYpsmon2020psmonfp16TEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDadcmon4021adcmonfp16VCC_12VVCC_2V5VCC_M3V3VCC_3V3VCC_1V8VCC_M1V8V_VCCINTK_VCCINTV_MGTY1_AVTTV_MGTY2_AVTTK_MGTH_AVTTK_MGTY_AVTTV_MGTY1_VCCAUXV_MGTY2_VCCAUXK_MGTY_VCCAUXK_MGTH_VCCAUXV_MGTY1_AVCCV_MGTY2_AVCCK_MGTY_AVCCK_MGTH_AVCCTM4C_TEMPuptime1922uint16uptimeUptimegitversion19420chargitversionGit_Version'\n", + "b'firefly025fireflyint8K01 12 Tx GTHK01 12 Rx GTHK02 12 Tx GTHK02 12 Rx GTHK03 12 Tx GTHK03 12 Rx GTHK04 4 XCVR GTYK05 4 XCVR GTYK06 4 XCVR GTYK07 12 Tx GTYK07 12 Rx GTYV01 4 XCVR GTYV02 4 XCVR GTYV03 4 XCVR GTYV04 4 XCVR GTYV05 4 XCVR GTYV06 4 XCVR GTYV07 4 XCVR GTYV08 4 XCVR GTYV09 4 XCVR GTYV10 4 XCVR GTYV11 12 Tx GTYV11 12 Rx GTYV12 12 Tx GTYV12 12 Rx GTYpsmon2020psmonfp16TEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDTEMP1TEMP3VINVOUTIOUTRESERVEDRESERVEDRESERVEDadcmon4021adcmonfp16VCC_12VVCC_2V5VCC_M3V3VCC_3V3VCC_1V8VCC_M1V8V_VCCINTK_VCCINTV_MGTY1_AVTTV_MGTY2_AVTTK_MGTH_AVTTK_MGTY_AVTTV_MGTY1_VCCAUXV_MGTY2_VCCAUXK_MGTY_VCCAUXK_MGTH_VCCAUXV_MGTY1_AVCCV_MGTY2_AVCCK_MGTY_AVCCK_MGTH_AVCCTM4C_TEMPuptime1922uint16uptimeUptimegitversion19420chargitversionGit_Version'\n" + ] + } + ], + "source": [ + "\n", + "xml = dicttoxml.dicttoxml(data, attr_type=False)\n", + "print(xml)\n", + "\n", + "# dump xml to file\n", + "with open('/tmp/zynqmon.xml', 'wb') as f:\n", + " f.write(xml)\n", + "\n", + "plmem = dicttoxml.dicttoxml(data['config'], attr_type=False)\n", + "print(plmem)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "interpreter": { + "hash": "d1bcf2015140efba1309a3b878c8a09b28a5da1fac13dcbb304588e5a25844fe" + }, + "kernelspec": { + "display_name": "Python 3.8.12 64-bit ('base': conda)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.12" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +}