├── .github └── workflows │ └── main.yml ├── .gitignore ├── .pio └── libdeps │ └── esp32dev │ └── integrity.dat ├── .vscode ├── c_cpp_properties.json ├── settings.json └── tasks.json ├── BUILD.sh ├── CMakeLists.txt ├── Makefile ├── README.md ├── WAV.log ├── analog.png ├── capture ├── OscScreenGrabLAN.py ├── Rigol_functions.py └── telnetlib_receive_all.py ├── components ├── Makefile ├── emul_ip │ ├── CMakeLists.txt │ ├── component.mk │ ├── emul_ip.c │ ├── emul_ip.h │ ├── lwip_ethoc.c │ └── lwip_ethoc.h ├── libscpi │ ├── CMakeLists.txt │ ├── Makefile │ ├── component.mk │ ├── inc │ │ └── scpi │ │ │ ├── cc.h │ │ │ ├── config.h │ │ │ ├── constants.h │ │ │ ├── error.h │ │ │ ├── expression.h │ │ │ ├── ieee488.h │ │ │ ├── minimal.h │ │ │ ├── parser.h │ │ │ ├── scpi.h │ │ │ ├── types.h │ │ │ ├── units.h │ │ │ └── utils.h │ └── src │ │ ├── error.c │ │ ├── expression.c │ │ ├── fifo.c │ │ ├── fifo_private.h │ │ ├── ieee488.c │ │ ├── lexer.c │ │ ├── lexer_private.h │ │ ├── minimal.c │ │ ├── parser.c │ │ ├── parser_private.h │ │ ├── scpi.g │ │ ├── units.c │ │ ├── utils.c │ │ └── utils_private.h └── pi2s │ ├── i2s_parallel.c │ └── i2s_parallel.h ├── linux ├── Makefile ├── main.c ├── sampling.c └── scpi-server.py ├── main ├── CMakeLists.txt ├── Header.h ├── Kconfig.projbuild ├── analog-testdata.c ├── analog.c ├── analog.h ├── app-config.h ├── app_main.c ├── audio_example_file.h ├── collector.c ├── collector.h ├── component.mk ├── draw_osc.c ├── esp32_sump.c ├── esp32_sump.h ├── espScope.cpp ├── hack-ledc.c ├── hack-ledc.h ├── ota_server.c ├── ota_server.h ├── read_chars.c ├── read_chars.h ├── sampler.c ├── sampler.h ├── scpi-def.c ├── scpi-def.h ├── scpi_server.c ├── scpi_server.h ├── scpi_sock_server.c └── sump_server.c ├── platformio.ini ├── rigol.png ├── scopecmd ├── Makefile └── src │ ├── cfgmap.cpp │ ├── cfgmap.h │ ├── freetmc.h │ ├── freetmc_remote.cpp │ ├── freetmc_remote.h │ ├── netcomm.cpp │ ├── netcomm.h │ ├── protocol.h │ ├── rigoltmc.h │ ├── rigolwfm.h │ ├── rigwfm.cpp │ ├── scopecmd.cpp │ └── simple_except.h ├── sdkconfig.esp32dev ├── sigrok.png ├── sigrok_build └── CMakeLists.txt ├── sump_uart.png ├── toflash.c └── uart.png /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: ESP Code Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | test_builds: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | matrix: 15 | test-platform: 16 | - esp32dev 17 | env: 18 | name: esp32-sigrok.bin 19 | 20 | steps: 21 | - name: Select Python 3.12.8 22 | uses: actions/setup-python@v1 23 | with: 24 | python-version: '3.12.8' 25 | architecture: 'x64' 26 | 27 | - name: Install PlatformIO 28 | run: | 29 | pip install -U https://github.com/platformio/platformio-core/archive/master.zip 30 | platformio update 31 | 32 | - name: Check out the Release 33 | uses: actions/checkout@v4 34 | 35 | - name: Run PlatformIO for ${{ matrix.test-platform }} 36 | run: platformio run -e ${{ matrix.test-platform }} 37 | 38 | - uses: actions/upload-artifact@v4 39 | with: 40 | name: ${{ env.name }} 41 | path: .pio/build/esp32dev/firmware.bin 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | bsav 3 | cbuild 4 | old_build 5 | # Object files 6 | *.o 7 | *.ko 8 | *.obj 9 | *.elf 10 | 11 | # Precompiled Headers 12 | *.gch 13 | *.pch 14 | 15 | # Libraries 16 | *.lib 17 | *.a 18 | *.la 19 | *.lo 20 | 21 | # Shared objects (inc. Windows DLLs) 22 | *.dll 23 | *.so 24 | *.so.* 25 | *.dylib 26 | 27 | # Executables 28 | *.exe 29 | *.out 30 | *.app 31 | *.i*86 32 | *.x86_64 33 | *.hex 34 | 35 | # Debug files 36 | .vscode 37 | *.dSYM/ 38 | *.su 39 | build 40 | sdkconfig 41 | scopecmd/scopecmd 42 | linux/test 43 | sdkconfig.old 44 | sdkconfig.sav 45 | hardcopy.0 46 | screenlog.0 47 | capture/OscScreenGrabLAN.py.log 48 | capture/Rigol_functions.pyc 49 | capture/telnetlib_receive_all.pyc 50 | capture/captures 51 | data 52 | -------------------------------------------------------------------------------- /.pio/libdeps/esp32dev/integrity.dat: -------------------------------------------------------------------------------- 1 | esp_adc 2 | libscpi -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Mac", 5 | "includePath": [ 6 | "/usr/include", 7 | "/usr/local/include", 8 | "${workspaceRoot}" 9 | ], 10 | "defines": [], 11 | "intelliSenseMode": "clang-x64", 12 | "browse": { 13 | "path": [ 14 | "/usr/include", 15 | "/usr/local/include", 16 | "${workspaceRoot}" 17 | ], 18 | "limitSymbolsToIncludedHeaders": true, 19 | "databaseFilename": "" 20 | }, 21 | "macFrameworkPath": [ 22 | "/System/Library/Frameworks", 23 | "/Library/Frameworks" 24 | ], 25 | "compilerPath": "/usr/bin/clang", 26 | "cStandard": "c11", 27 | "cppStandard": "c++17" 28 | }, 29 | { 30 | "name": "Linux", 31 | "includePath": [ 32 | "~/esp/esp-idf/components", 33 | "~/esp/esp-idf/components/driver/include", 34 | "~/esp/esp-idf/components/newlib/include", 35 | "~/esp/esp-idf/components/freertos/include", 36 | "~/esp/esp-idf/components/esp32/include", 37 | "~/esp/esp-idf/components/log/include", 38 | "~/esp/esp-idf/components/nvs_flash/include", 39 | "~/esp/esp-idf/components/heap/include", 40 | "~/esp/esp-idf/components/tcpip_adapter/include", 41 | "~/esp/esp-idf/components/soc/include", 42 | "~/esp/esp-idf/components/lwip/include/lwip", 43 | "~/esp/esp-idf/components/lwip/include/lwip/port", 44 | "~/esp/esp-idf/components/soc/esp32/include", 45 | "${workspaceRoot}/build/include", 46 | "${workspaceRoot}/components/tft", 47 | "${workspaceRoot}/components/spiffs", 48 | "${workspaceRoot}/components/spidriver", 49 | "/usr/include/c++/7", 50 | "/usr/include/c++/7.2.0/tr1", 51 | "/usr/include/c++/7.2.0", 52 | "/usr/include/c++/7.2.0/x86_64-pc-linux-gnu/", 53 | "/usr/include/x86_64-linux-gnu/c++/7", 54 | "/usr/include/c++/7/backward", 55 | "/usr/lib/gcc/x86_64-linux-gnu/7/include", 56 | "/usr/local/include", 57 | "/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed", 58 | "/usr/include/x86_64-linux-gnu", 59 | "/usr/include", 60 | "/usr/include/linux", 61 | "${workspaceRoot}", 62 | "/usr/include/c++/7.2.1/tr1", 63 | "${workspaceRoot}/components/libscpi/inc", 64 | "/usr/include/c++/7.2.1", 65 | "/usr/include/c++/7.2.1/x86_64-pc-linux-gnu" 66 | ], 67 | "defines": [], 68 | "intelliSenseMode": "clang-x64", 69 | "browse": { 70 | "path": [ 71 | "~/esp/esp-idf/components", 72 | "~/esp/esp-idf/components/newlib/include/", 73 | "~/esp/esp-idf/components/driver/include", 74 | "~/esp/esp-idf/components/newlib/include", 75 | "~/esp/esp-idf/components/freertos/include", 76 | "~/esp/esp-idf/components/esp32/include", 77 | "~/esp/esp-idf/components/log/include", 78 | "~/esp/esp-idf/components/nvs_flash/include", 79 | "~/esp/esp-idf/components/heap/include", 80 | "~/esp/esp-idf/components/tcpip_adapter/include", 81 | "~/esp/esp-idf/components/soc/include", 82 | "~/esp/esp-idf/components/lwip/include/lwip", 83 | "~/esp/esp-idf/components/lwip/include/lwip/port", 84 | "~/esp/esp-idf/components/soc/esp32/include", 85 | "${workspaceRoot}/build/include", 86 | "/usr/include/c++/7", 87 | "/usr/include/c++/7.2.0/tr1", 88 | "/usr/include/c++/7.2.0", 89 | "/usr/include/c++/7.2.0/x86_64-pc-linux-gnu/", 90 | "/usr/include/x86_64-linux-gnu/c++/7", 91 | "/usr/include/c++/7/backward", 92 | "/usr/lib/gcc/x86_64-linux-gnu/7/include", 93 | "/usr/local/include", 94 | "/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed", 95 | "/usr/include/x86_64-linux-gnu", 96 | "/usr/include", 97 | "${workspaceRoot}" 98 | ], 99 | "limitSymbolsToIncludedHeaders": true, 100 | "databaseFilename": "" 101 | }, 102 | "compilerPath": "/usr/bin/clang", 103 | "cStandard": "c11", 104 | "cppStandard": "c++17", 105 | "compileCommands": "${workspaceFolder}/build/compile_commands.json" 106 | }, 107 | { 108 | "name": "Win32", 109 | "includePath": [ 110 | "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include", 111 | "${workspaceRoot}", 112 | "d:/msys2/home/Olof/esp/esp-idf/components", 113 | "d:/msys2/home/Olof/esp/esp-idf/components/newlib/include/", 114 | "d:/msys2/home/Olof/esp/esp-idf/components/driver/include", 115 | "d:/msys2/home/Olof/esp/esp-idf/components/newlib/include", 116 | "d:/msys2/home/Olof/esp/esp-idf/components/freertos/include", 117 | "d:/msys2/home/Olof/esp/esp-idf/components/esp32/include", 118 | "d:/msys2/home/Olof/esp/esp-idf/components/log/include", 119 | "d:/msys2/home/Olof/esp/esp-idf/components/nvs_flash/include", 120 | "d:/msys2/home/Olof/esp/esp-idf/components/heap/include", 121 | "d:/msys2/home/Olof/esp/esp-idf/components/tcpip_adapter/include", 122 | "d:/msys2/home/Olof/esp/esp-idf/components/soc/include", 123 | "d:/msys2/home/Olof/esp/esp-idf/components/lwip/include/lwip", 124 | "d:/msys2/home/Olof/esp/esp-idf/components/lwip/include/lwip/port", 125 | "d:/msys2/home/Olof/esp/esp-idf/components/soc/esp32/include" 126 | ], 127 | "defines": [ 128 | "_DEBUG", 129 | "UNICODE" 130 | ], 131 | "intelliSenseMode": "msvc-x64", 132 | "browse": { 133 | "path": [ 134 | "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*", 135 | "${workspaceRoot}", 136 | "d:/msys2/home/Olof/esp/esp-idf/components", 137 | "d:/msys2/home/Olof/esp/esp-idf/components/newlib/include/", 138 | "d:/msys2/home/Olof/esp/esp-idf/components/driver/include", 139 | "d:/msys2/home/Olof/esp/esp-idf/components/newlib/include", 140 | "d:/msys2/home/Olof/esp/esp-idf/components/freertos/include", 141 | "d:/msys2/home/Olof/esp/esp-idf/components/esp32/include", 142 | "d:/msys2/home/Olof/esp/esp-idf/components/log/include", 143 | "d:/msys2/home/Olof/esp/esp-idf/components/nvs_flash/include", 144 | "d:/msys2/home/Olof/esp/esp-idf/components/heap/include", 145 | "d:/msys2/home/Olof/esp/esp-idf/components/tcpip_adapter/include", 146 | "d:/msys2/home/Olof/esp/esp-idf/components/soc/include", 147 | "d:/msys2/home/Olof/esp/esp-idf/components/lwip/include/lwip", 148 | "d:/msys2/home/Olof/esp/esp-idf/components/lwip/include/lwip/port", 149 | "d:/msys2/home/Olof/esp/esp-idf/components/soc/esp32/include" 150 | ], 151 | "limitSymbolsToIncludedHeaders": true, 152 | "databaseFilename": "" 153 | }, 154 | "compilerPath": "/usr/bin/clang", 155 | "cStandard": "c11", 156 | "cppStandard": "c++17" 157 | } 158 | ], 159 | "version": 4 160 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "freertos.h": "c", 4 | "esp_event.h": "c", 5 | "esp_wifi.h": "c", 6 | "parser.hpp": "c", 7 | "zlib.h": "c", 8 | "freertosconfig.h": "c", 9 | "sdkconfig.h": "c", 10 | "system_error": "c", 11 | "*.ipp": "c", 12 | "*.tcc": "c", 13 | "string_view": "c", 14 | "scpi-def.h": "c", 15 | "condition_variable": "c", 16 | "array": "c", 17 | "sstream": "c", 18 | "istream": "c", 19 | "optional": "c", 20 | "ostream": "c", 21 | "ratio": "c", 22 | "type_traits": "c", 23 | "bitset": "c" 24 | } 25 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "command": "/usr/bin/bash", 4 | "args": ["-c"], 5 | "type": "shell", 6 | "presentation" : { "reveal": "always" }, 7 | "options": { 8 | "cwd": "${workspaceRoot}", 9 | }, 10 | "tasks": [ 11 | { 12 | "label": "build app", 13 | "args": ["/usr/bin/make app"], 14 | "group": "build", 15 | "problemMatcher": { 16 | "owner": "cpp", 17 | "fileLocation": "absolute", 18 | "pattern": { 19 | "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 20 | "file": 1, 21 | "line": 2, 22 | "column": 3, 23 | "severity": 4, 24 | "message": 5 25 | } 26 | } 27 | }, 28 | { 29 | "label": "clean app", 30 | "args": ["make app-clean"] 31 | }, 32 | { 33 | "label": "monitor", 34 | "args": ["make monitor"] 35 | }, 36 | { 37 | "label": "flash app", 38 | "args": ["make app-flash"] 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /BUILD.sh: -------------------------------------------------------------------------------- 1 | make 2 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following five lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 6 | list(APPEND EXTRA_COMPONENT_DIRS components/libscpi) 7 | project(sigrok) 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This is a project Makefile. It is assumed the directory this Makefile resides in is a 3 | # project subdirectory. 4 | # 5 | 6 | PROJECT_NAME := sigrok 7 | 8 | include $(IDF_PATH)/make/project.mk 9 | 10 | -------------------------------------------------------------------------------- /WAV.log: -------------------------------------------------------------------------------- 1 | :RUN 2 | *OPC? 3 | 1 4 | :ACQ:MDEP 1400 5 | *OPC? 6 | 1 7 | :STOP 8 | *OPC? 9 | 1 10 | :RUN 11 | *OPC? 12 | 1 13 | :WAV:FORM BYTE 14 | *OPC? 15 | 1 16 | :WAV:MODE NORM 17 | *OPC? 18 | 1 19 | :WAV:SOUR CHAN1 20 | *OPC? 21 | 1 22 | :WAV:YREF? 23 | 127 24 | :WAV:STAT? 25 | IDLE,1400 26 | :WAV:DATA? 27 | #900000140014005X892H9PT8Z7UGZJX50KVIGGQU24I5908YT0QF7P2CE2CJCI5GJQ9V6P7W3LQL0456T67LLV7BWZ2JFQUBXH8OU8P0EMZAO4I0OW47VRJGE9PJ8KLDGYYWLDHQ6XUTPB1L9PCAR10ORCS9VO2PS7N67WXVFTV3A3LLSUTA9IIEF4U0N8WCYFCKKK068CF553BWI0TOO2STUZLMJX5CUIRP0W4KNPVJLP6V4R03GR2NTGQP7KNFD4GON7LJ4B5JHK17Y85GZLNFU6OXY4PACYXG1EUBXW7KVCDVUPD6PRX99O4HIML21JJ6JTUDZOP74VG05GWIDBCK1ZXHHTAZ12E9LAFSB0EXNVU4LPVRVA7K97YD6S7X2XHVKYWO27E9HQA7ITYHRFHEX496PAY97DTW1JMWC18GNWV65CDN1JZQ6AQY53QFP50UQ0ICABRXJW2GZ7BIIJUTQ2Y76SG16QRTFA07D6DMJYJWZV8QWT2BQG4X3G3PGS4Y0J0BP45HJJNR65KM330ZMKBQKM3KFHHJ9Q6P7NG6UHN26T1Q60QS6NZJHNO3W8VVT8R87SWU6VOKDHVJ9DX1LLKKEBW5I4XKWZ3F9VUVJ3N3XCO43SBJU4EPQ8323XO89WHVM6VK38B2H61KE4FUUOGS83GO28HTCOEIZEOW3LGATD1KY2G44VDPQXAT2JOAF546E71V0YRDPL5O1XQ91KRRY4M2ERX22PAMZVCY5DBSRVNITBUB0XUNBEI509WOB9XV69ZU076FFJ9EC5W88O7FWJG7GJ2I1UGUHP7Q1XW3YP6KCJDCQB6KVC9QAR8C8P8KB6QV53GDOLJAQNDQQH3EKT7END0MQJJZATDZK3C3HE3RA6ZKTFQQ3TKPBCGIL2SFX4HMKIAOOE93YQXOFIAF1ZRSRABEIE9WI621RXFYAL0JEDBZ4JLEGX4W41A9K912KFOB6CHYGJQIQLS374ABTEP4NN13SKQMSUDS1Y9FEUWEA20CDJOTKKMDDQ8Q269QNEL69SCN3EC4P64R1WO8LRB4TWGUV441U2ROJTH14TOQY27W6GHS22VBRVFLDPECK4SMND4GS0261G7I2BI2AI4QQK4XJUX7ONV0P8T6QWKC77KY0LJB4FP1340H3EAR5CJA5Z2559I2DCTPRBIAAR4N8AXVQQVICLP0G69INLL3MINLJOBY0OGUQEOFWC6ZMDZE28T3VCP393WGJFPHF4DLFZBC0BAEJ5BR2LP5J64ZKDJS4AG1W3M2TJKE8UCEVR6K5O2DA2LVU77BSNVNZBK2YY95SH1WHCG0JHT785CKI6DOVNAWDZI34GDOIGEF9K3OV8X92EU05L579Y8NF6E666I4OF18H068AV7D9WM0D3GPV3ER1GE736UTVQHZU2JT5GOHL4WPKWB6MJL6V9BVFTRPNYXQUL68EW218EICVM9GJXANWCQAJ2QB73BTVMMW1ORQ3T4V8Z4LY8NPEE4ODXR0QUTLEI5ETXIDYGT459EWFJ28BKUHYHO7E1V0R2PN6POWFJLYUM06URFRT2KLS12UNVT6D94GJBDLM2D61O489NIUQZXBJUEJ9GIXWOQTCIJV7BFPWFWTDLAIS1HN1YI054DV40A65TPFYYCV3C5W1ARES6V4AYMDC43Z7T6GPOILAHBN8Q6CDY7PXIEA5TXSFJJFMYK5S46AMWHNRB1FF0SMRS3YA8RJ01E1YC2AJ4E5DLHLGBB2Q3BGMW0NRJP4NRGP7F7B1D14AC1KQH12HWO9PQENR8FI049AQVP2DO3PYDEUJA10OIK1F0RFXG25VHX4RC96JWUVE9M6K71V9IITUFWKTXM8XLKY36GNLPBSGAK9FGMHHTB2OLS0SVXPYAUQUG8JKY6MTUOZ2HKEM641VM1ETXIXYVU893PQBF35VFNREZRW8YCA1SFPI11S0UVAV8Z93JOGCELI5V27YSJ0PCO89C5MCL5Q6CMWS5RCIQ4PFE7UZMO2AX4G7OGZYCTS3AFSARKT87BM7MVG8GE1NYWELX31KSFX9B6L5F5IOTEDHXLRQZ7AOY03SN3FKKNZAHGNTTGTDPDLIBZ9FH3M0J8ZAQE51O4CDDF8HD6G501U0YEEALA09YYSGJ5O7PKOMGKL9F2HHSDWDGKC1P8176N7OA76BTF1KQTJXJ0QNGA56NMW048HP4VF39HYSBPKVF8B7SYYB25XBFA9I14B7JAK4ICMJ0PI3C0ORXEKT13PBLBNX0R6UIO1MTOTN1R2QFOQA3OYO000TC0R971NWTAS71LF98N4T6GSEDWN553E08OEKJ8ZILDGNA7R9ITHCNJZAIN9WO5M2TFF5Z34BL7DLV2FTGJ3LS5XJA6TJ5J963S676BSNCIXG8IPT8F5C15JYGS5V7I4FAIQWQK5KJXH603AIDWEWM1DR89WGNLR43I7G8ZKLSINGBO1FSQ55LX4N2HOLJZE5JUPP2ZOE1CLIVVZZ785XCJUKBH1IBYC28SEYNEVTK0BZOQRQFIK5OS1VK9TEPKD3OC9LRDWD6WRBZLOA9B19WYDJK43MMNCIX1IAXWEGUA4WJHA1256FVVQLZ8FE05SQ83VFTRU2188739YJ8OF2QB43SJDPQJBR6IWUBCEEJDX4DK5RYDXZJLGXG4R1ATZ1YN9T3ASLN56LF3JW9TQAU391WE938QMJ49SYYLYLQVGMZKAIWVNNSMB2H7ZK3UKB42AZYAIAEH5XX95XLFLKBAHNUR8M8Z6HN4KLH5R12KWR2ACDPNC380D44JB4AYPO5VO62QNMPMNHRDBWT2OQHUNXGP9L210H1PIOHKUA9ZVURILA6V23XRQ6R7R55DKUPR7YRTTIT9IJC642ING0NKTLIU8X0R6VKL8W0FGB1HVWMVL4EQG0JDJB7UVR08YFKVZDEDX3IYYKYUOJANACLVRHQHLXEE09GGGGBXBN9P1UCOZC2HDGO3CZPAIH2FB9GD9TM5LF42FFI6Q6RQP8H0SDIDRWROG3YEK37X5H1ZBN5W7JDFYX59NXPH1LAA38BP97VX08TDJ1TJF4WD1IIIY2T23JKL4544JCLRPAOPKUWDY1GWITATO3UL0S2LOW633ND3LPC3ZAICX99JY8BUWDVWKVKEDK3D7DD1LZKICP5MPW0UIR4ZFRZU10HCWHPNLF9EAW0Q3I7OURO1TSF8EFXOG94X7DCP9QWXH0H8VDJKMOHQRP4GLG0MZ2ZZ6MYE4D6FBBV475IL43AGZZ7VC840F4GE2R4E5YQPTTHDVPMMJ21YQ7QO36ZIU1A0KHIVQ1G2YFU8RAOKTO5RXZYADW00TBH0EVJR1TVHNJF0FDGNR1HBZGKZDVL2Y20WU46WUA2PMFGQ99ZKDAXU55FPWV91S9KZ1ZTVE9SUF1A0SEUOHFX02BHTSQ5J8HD4BX0Q3ZOKQKPOAHLXV3XATFMH1DD16BMJTABDTZKC8V0GBNWGNR5BOV54D4JE158BK14WBI1Y6ODSJ2D7BGVZJCV74QYAW70QCOJ4I79IUPT27VYL8GR3XPX0A3V7X4USJLNMALHMR7EYE2ZG74N7UBX65TG4E7MI3BDEFPCHAT3SSNJDXRJY3665PAF9QPDMEVKN9C0TGB713XYFHGAZO1PGYP1HPRVDMDZIAAGSLS0W8QAK0ACX4LOFK4151VD06AE8O6L0B4FGOUI3PV9WCJ49C1NBDC2T255N5UO6JYMFPU05GDHG9UJ3VLR3Y0FDUZJNBFJFHO4DBXT4CCOEKIJXWI88KKMI5WH69WBL0ZMBPN7JQHB0HA9HNFSUB6PVCAXB0EMFNN8WFUVQI4Z15SA5LE9OF8ORLCETQNAOCNK37FLMUGQ46L3N5170JX4TTTP2B4XBMLGR1NUSO1DQRHL5SN53N9GE0ORE5J0CB3HCKNPJLJXNGJ6ZX9MDVRURIF64TVP4IBBSAUO75IEOR2MOHM32I2LMAFQEAW6DBSXY4HX9XC3ZJGYOC39EQY24HZ16GXZ1TL9VEQKXCWE9U2R6H1F0VM8IKPR0OU1FBP0XOA7CUJLFZ26ZIYY48UQIU9EBICM430NTRB11DVK87XC5BB1 28 | -------------------------------------------------------------------------------- /analog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ebiroll/esp32_sigrok/cb8852eddf003c1938a9311f3d459f3b16454b0a/analog.png -------------------------------------------------------------------------------- /capture/Rigol_functions.py: -------------------------------------------------------------------------------- 1 | import pip 2 | import sys 3 | import logging 4 | 5 | __author__ = 'RoGeorge' 6 | 7 | 8 | def log_running_python_versions(): 9 | logging.info("Python version: " + str(sys.version) + ", " + str(sys.version_info)) # () required in Python 3. 10 | 11 | installed_packages = pip.get_installed_distributions() 12 | installed_packages_list = sorted(["%s==%s" % (i.key, i.version) for i in installed_packages]) 13 | logging.info("Installed Python modules: " + str(installed_packages_list)) 14 | 15 | 16 | def command(tn, scpi): 17 | logging.info("SCPI to be sent: " + scpi) 18 | answer_wait_s = 1 19 | response = "" 20 | while response != "1\n": 21 | tn.write("*OPC?\n") # previous operation(s) has completed ? 22 | logging.info("Send SCPI: *OPC? # May I send a command? 1==yes") 23 | response = tn.read_until("\n", 1) # wait max 1s for an answer 24 | logging.info("Received response: " + response) 25 | 26 | tn.write(scpi + "\n") 27 | logging.info("Sent SCPI: " + scpi) 28 | response = tn.read_until("\n", answer_wait_s) 29 | logging.info("Received response: " + response) 30 | return response 31 | 32 | 33 | # first TMC byte is '#' 34 | # second is '0'..'9', and tells how many of the next ASCII chars 35 | # should be converted into an integer. 36 | # The integer will be the length of the data stream (in bytes) 37 | # after all the data bytes, the last char is '\n' 38 | def tmc_header_bytes(buff): 39 | return 2 + int(buff[1]) 40 | 41 | 42 | def expected_data_bytes(buff): 43 | return int(buff[2:tmc_header_bytes(buff)]) 44 | 45 | 46 | def expected_buff_bytes(buff): 47 | return tmc_header_bytes(buff) + expected_data_bytes(buff) + 1 48 | 49 | 50 | def get_memory_depth(tn): 51 | # Define number of horizontal grid divisions for DS1054Z 52 | h_grid = 12 53 | 54 | # ACQuire:MDEPth 55 | mdep = command(tn, ":ACQ:MDEP?") 56 | 57 | # if mdep is "AUTO" 58 | if mdep == "AUTO\n": 59 | # ACQuire:SRATe 60 | srate = command(tn, ":ACQ:SRAT?") 61 | 62 | # TIMebase[:MAIN]:SCALe 63 | scal = command(tn, ":TIM:SCAL?") 64 | 65 | # mdep = h_grid * scal * srate 66 | mdep = h_grid * float(scal) * float(srate) 67 | 68 | # return mdep 69 | return int(mdep) 70 | -------------------------------------------------------------------------------- /components/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean all test install 2 | 3 | all: 4 | $(MAKE) -C libscpi 5 | $(MAKE) -C ../linux 6 | 7 | clean: 8 | $(MAKE) clean -C libscpi 9 | $(MAKE) clean -C ../linux 10 | 11 | test: 12 | $(MAKE) test -C libscpi 13 | 14 | install: 15 | $(MAKE) install -C libscpi -------------------------------------------------------------------------------- /components/emul_ip/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #idf_component_register(SRCS "emul_ip.c" "lwip_ethoc.c" 2 | # INCLUDE_DIRS ".") 3 | set(COMPONENT_SRCS "emul_ip.c" "lwip_ethoc.c") 4 | set(COMPONENT_ADD_INCLUDEDIRS ".") 5 | 6 | register_component() 7 | -------------------------------------------------------------------------------- /components/emul_ip/component.mk: -------------------------------------------------------------------------------- 1 | COMPONENT_SRCDIRS:=. 2 | COMPONENT_ADD_INCLUDEDIRS:=. 3 | -------------------------------------------------------------------------------- /components/emul_ip/emul_ip.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack 4 | * port for uC/OS-II RTOS on TIC6711 DSK 5 | * 6 | * File : tcp_ip.c 7 | * By : ZengMing @ DEP,Tsinghua University,Beijing,China 8 | ********************************************************************************************************* 9 | */ 10 | #if 0 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "lwip/opt.h" 16 | #include "lwip/def.h" 17 | #include "lwip/mem.h" 18 | #include "lwip/pbuf.h" 19 | #include "lwip/sys.h" 20 | #include "lwip/timeouts.h" 21 | //#include "lwip/timers.h" 22 | #include 23 | #include "lwip/netif.h" 24 | #include "netif/etharp.h" 25 | #include "lwip/tcpip.h" 26 | #include "lwip/init.h" 27 | //#include "esp_event.h" 28 | #include "esp_event_loop.h" 29 | 30 | 31 | #include "arch/sys_arch.h" 32 | //#include "port/arch/sys_arch.h" 33 | // -- Generic network interface -- 34 | 35 | 36 | //QueueHandle_t esp_event_loop_get_queue(void); 37 | 38 | extern err_t ethoc_init(struct netif *netif); 39 | 40 | int is_running_qemu() { 41 | int *quemu_test=(int *) 0x3ff005f0; 42 | int ret_val; 43 | 44 | if (*quemu_test==0x42) { 45 | printf("Running in qemu\n"); 46 | ret_val=1; 47 | } else { 48 | ret_val=0; 49 | } 50 | 51 | return ret_val; 52 | } 53 | 54 | 55 | struct netif ethoc_if; 56 | //struct netif loop_if; 57 | 58 | void ethernet_hardreset(void); //These reset codes are built for C6711 DSP 59 | void tcpip_init_done_ok(void * arg); 60 | 61 | 62 | void task_lwip_init(void * pParam) 63 | { 64 | ip4_addr_t ipaddr, netmask, gw; 65 | sys_sem_t sem; 66 | 67 | // From esp-idf 68 | //lwip_init(); 69 | //sys_init(); 70 | tcpip_adapter_init(); 71 | //ethernet_hardreset();//hard reset of EthernetDaughterCard 72 | // This should be done in lwip_init 73 | # if 0 74 | #if LWIP_STATS 75 | stats_init(); 76 | #endif 77 | 78 | // initial lwIP stack 79 | sys_init(); 80 | mem_init(); 81 | memp_init(); 82 | pbuf_init(); 83 | netif_init(); 84 | #endif // The initiation above is done in tcpip_init 85 | 86 | 87 | //add loop interface //set local loop-interface 127.0.0.1 88 | /* 89 | IP4_ADDR(&gw, 127,0,0,1); 90 | IP4_ADDR(&ipaddr, 127,0,0,1); 91 | IP4_ADDR(&netmask, 255,0,0,0); 92 | netif_add(&loop_if, &ipaddr, &netmask, &gw, NULL, loopif_init, 93 | tcpip_input); 94 | */ 95 | //add interface 96 | IP4_ADDR(&gw, 192,168,4,1); 97 | IP4_ADDR(&ipaddr, 192,168,4,3); 98 | IP4_ADDR(&netmask, 255,255,255,0); 99 | 100 | netif_add(ðoc_if, &ipaddr, &netmask, &gw, NULL, ethoc_init, tcpip_input); 101 | netif_set_default(ðoc_if); 102 | 103 | 104 | printf("TCP/IP initializing...\n"); 105 | //if (sys_sem_new(&sem,0)!=ERR_OK) { 106 | // printf("Failed creating semaphore\n"); 107 | //} 108 | // OLAS 109 | //tcpip_init(tcpip_init_done_ok, &sem); 110 | //sys_sem_wait(sem); 111 | //sys_sem_free(sem); 112 | printf("TCP/IP initialized.\n"); 113 | 114 | netif_set_up(ðoc_if); 115 | 116 | // Fake got_ip event 117 | 118 | //if (esp_event_loop_get_queue()!=NULL) { 119 | system_event_t evt; 120 | 121 | //ip4_addr_set(&ip_info->ip, ip_2_ip4(&netif->ip_addr)); 122 | //ip4_addr_set(&ip_info->netmask, ip_2_ip4(&netif->netmask)); 123 | //ip4_addr_set(&ip_info->gw, ip_2_ip4(&netif->gw)); 124 | 125 | //notify event 126 | evt.event_id = SYSTEM_EVENT_STA_GOT_IP; 127 | memcpy(&evt.event_info.got_ip.ip_info.ip, &ipaddr, sizeof(ipaddr)); 128 | memcpy(&evt.event_info.got_ip.ip_info.netmask, &netmask, sizeof(netmask)); 129 | memcpy(&evt.event_info.got_ip.ip_info.gw, &gw, sizeof(gw)); 130 | 131 | //memcpy(&evt.event_info.got_ip.ip_info, &ipaddr, sizeof(tcpip_adapter_ip_info_t)); 132 | 133 | esp_event_send(&evt); 134 | //} 135 | 136 | 137 | printf("Applications started.\n"); 138 | 139 | vTaskDelete(NULL); 140 | 141 | //--------------------------------------------------------------------- 142 | //All thread(task) of lwIP must have their PRI between 10 and 14. 143 | //------------------------------------------------------------ 144 | //sys_thread_new(httpd_init, (void*)"httpd",10); 145 | //httpd_init(); 146 | //--------------------------------------------------------------------- 147 | 148 | 149 | //DSP_C6x_TimerInit(); // Timer interrupt enabled 150 | // Ethernet interrupt 151 | //DSP_C6x_Int4Init(); // Int4(Ethernet Chip int) enabled 152 | 153 | 154 | /* Block for ever. */ 155 | //sem = sys_sem_new(0); 156 | //sys_sem_wait(sem); 157 | //printf("Finished\n"); 158 | } 159 | 160 | //--------------------------------------------------------- 161 | void tcpip_init_done_ok(void * arg) 162 | { 163 | sys_sem_t *sem; 164 | sem = arg; 165 | sys_sem_signal(*sem); 166 | } 167 | 168 | 169 | /*-----------------------------------------------------------*/ 170 | /* This function do the hard reset of EthernetDaughterCard * 171 | * through the DaughterBoardControl0 signal in DB-IF */ 172 | /*-----------------------------------------------------------*/ 173 | void ethernet_hardreset(void) //These reset codes are built for C6711 DSK 174 | { 175 | 176 | } 177 | #endif 178 | 179 | 180 | -------------------------------------------------------------------------------- /components/emul_ip/emul_ip.h: -------------------------------------------------------------------------------- 1 | #ifndef __QEMUL_IP_ 2 | #define __QEMUL_IP__ 3 | 4 | int is_running_qemu(); 5 | 6 | void task_lwip_init(void * pParam); 7 | 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /components/emul_ip/lwip_ethoc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack 4 | * port for uC/OS-II RTOS on TIC6711 DSK 5 | * 6 | * File : tcp_ip.c 7 | * By : ZengMing @ DEP,Tsinghua University,Beijing,China 8 | * Reference: YangYe's source code for SkyEye project 9 | ********************************************************************************************************* 10 | */ 11 | 12 | #ifndef _NE2K_H_ 13 | #define _NE2K_H_ 14 | 15 | #include "lwip/netif.h" 16 | 17 | 18 | #define MIN_PACKET_SIZE 60 /* smallest legal size packet, no fcs */ 19 | #define MAX_PACKET_SIZE 1514 /* largest legal size packet, no fcs */ 20 | 21 | 22 | //#define DELAY 0x590b2 //0.5s test by ming 23 | //#define DELAY_2S 0xbf000 //2s test 24 | //#define DELAY_MS 0x38F4 //20ms test 25 | 26 | 27 | // Open core registers 28 | #define OC_BASE 0x3ff69000 29 | #define OC_DESC_START 0x3ff69400 30 | #define OC_BUF_START 0x3FFF8000 31 | 32 | // End of peripherals 0x3FF7_FFFF 33 | // Data 0x3FF6_9000 0x3FF6_AFFF 8 KB EMAC 34 | 35 | /* register offsets */ 36 | #define MODER 0x00 37 | #define INT_SOURCE 0x04 38 | #define INT_MASK 0x08 39 | #define IPGT 0x0c 40 | #define IPGR1 0x10 41 | #define IPGR2 0x14 42 | #define PACKETLEN 0x18 43 | #define COLLCONF 0x1c 44 | #define TX_BD_NUM 0x20 45 | #define CTRLMODER 0x24 46 | #define MIIMODER 0x28 47 | #define MIICOMMAND 0x2c 48 | #define MIIADDRESS 0x30 49 | #define MIITX_DATA 0x34 50 | #define MIIRX_DATA 0x38 51 | #define MIISTATUS 0x3c 52 | #define MAC_ADDR0 0x40 53 | #define MAC_ADDR1 0x44 54 | #define ETH_HASH0 0x48 55 | #define ETH_HASH1 0x4c 56 | #define ETH_TXCTRL 0x50 57 | #define ETH_END 0x54 58 | 59 | 60 | #define EN0_MIISTATUS *(unsigned char *)(OC_BASE+0x3c) /* WR Starting page of ring buffer */ 61 | 62 | 63 | 64 | /* mode register */ 65 | #define MODER_RXEN (1 << 0) /* receive enable */ 66 | #define MODER_TXEN (1 << 1) /* transmit enable */ 67 | #define MODER_NOPRE (1 << 2) /* no preamble */ 68 | #define MODER_BRO (1 << 3) /* broadcast address */ 69 | #define MODER_IAM (1 << 4) /* individual address mode */ 70 | #define MODER_PRO (1 << 5) /* promiscuous mode */ 71 | #define MODER_IFG (1 << 6) /* interframe gap for incoming frames */ 72 | #define MODER_LOOP (1 << 7) /* loopback */ 73 | #define MODER_NBO (1 << 8) /* no back-off */ 74 | #define MODER_EDE (1 << 9) /* excess defer enable */ 75 | #define MODER_FULLD (1 << 10) /* full duplex */ 76 | #define MODER_RESET (1 << 11) /* FIXME: reset (undocumented) */ 77 | #define MODER_DCRC (1 << 12) /* delayed CRC enable */ 78 | #define MODER_CRC (1 << 13) /* CRC enable */ 79 | #define MODER_HUGE (1 << 14) /* huge packets enable */ 80 | #define MODER_PAD (1 << 15) /* padding enabled */ 81 | #define MODER_RSM (1 << 16) /* receive small packets */ 82 | 83 | /* interrupt source and mask registers */ 84 | #define INT_MASK_TXF (1 << 0) /* transmit frame */ 85 | #define INT_MASK_TXE (1 << 1) /* transmit error */ 86 | #define INT_MASK_RXF (1 << 2) /* receive frame */ 87 | #define INT_MASK_RXE (1 << 3) /* receive error */ 88 | #define INT_MASK_BUSY (1 << 4) 89 | #define INT_MASK_TXC (1 << 5) /* transmit control frame */ 90 | #define INT_MASK_RXC (1 << 6) /* receive control frame */ 91 | 92 | #define INT_MASK_TX (INT_MASK_TXF | INT_MASK_TXE) 93 | #define INT_MASK_RX (INT_MASK_RXF | INT_MASK_RXE) 94 | 95 | #define INT_MASK_ALL ( \ 96 | INT_MASK_TXF | INT_MASK_TXE | \ 97 | INT_MASK_RXF | INT_MASK_RXE | \ 98 | INT_MASK_TXC | INT_MASK_RXC | \ 99 | INT_MASK_BUSY \ 100 | ) 101 | 102 | /* packet length register */ 103 | #define PACKETLEN_MIN(min) (((min) & 0xffff) << 16) 104 | #define PACKETLEN_MAX(max) (((max) & 0xffff) << 0) 105 | #define PACKETLEN_MIN_MAX(min, max) (PACKETLEN_MIN(min) | \ 106 | PACKETLEN_MAX(max)) 107 | 108 | /* transmit buffer number register */ 109 | #define TX_BD_NUM_VAL(x) (((x) <= 0x80) ? (x) : 0x80) 110 | 111 | /* control module mode register */ 112 | #define CTRLMODER_PASSALL (1 << 0) /* pass all receive frames */ 113 | #define CTRLMODER_RXFLOW (1 << 1) /* receive control flow */ 114 | #define CTRLMODER_TXFLOW (1 << 2) /* transmit control flow */ 115 | 116 | /* MII mode register */ 117 | #define MIIMODER_CLKDIV(x) ((x) & 0xfe) /* needs to be an even number */ 118 | #define MIIMODER_NOPRE (1 << 8) /* no preamble */ 119 | 120 | /* MII command register */ 121 | #define MIICOMMAND_SCAN (1 << 0) /* scan status */ 122 | #define MIICOMMAND_READ (1 << 1) /* read status */ 123 | #define MIICOMMAND_WRITE (1 << 2) /* write control data */ 124 | 125 | /* MII address register */ 126 | #define MIIADDRESS_FIAD(x) (((x) & 0x1f) << 0) 127 | #define MIIADDRESS_RGAD(x) (((x) & 0x1f) << 8) 128 | #define MIIADDRESS_ADDR(phy, reg) (MIIADDRESS_FIAD(phy) | \ 129 | MIIADDRESS_RGAD(reg)) 130 | 131 | /* MII transmit data register */ 132 | #define MIITX_DATA_VAL(x) ((x) & 0xffff) 133 | 134 | /* MII receive data register */ 135 | #define MIIRX_DATA_VAL(x) ((x) & 0xffff) 136 | 137 | /* MII status register */ 138 | #define MIISTATUS_LINKFAIL (1 << 0) 139 | #define MIISTATUS_BUSY (1 << 1) 140 | #define MIISTATUS_INVALID (1 << 2) 141 | 142 | /* TX buffer descriptor */ 143 | #define TX_BD_CS (1 << 0) /* carrier sense lost */ 144 | #define TX_BD_DF (1 << 1) /* defer indication */ 145 | #define TX_BD_LC (1 << 2) /* late collision */ 146 | #define TX_BD_RL (1 << 3) /* retransmission limit */ 147 | #define TX_BD_RETRY_MASK (0x00f0) 148 | #define TX_BD_RETRY(x) (((x) & 0x00f0) >> 4) 149 | #define TX_BD_UR (1 << 8) /* transmitter underrun */ 150 | #define TX_BD_CRC (1 << 11) /* TX CRC enable */ 151 | #define TX_BD_PAD (1 << 12) /* pad enable for short packets */ 152 | #define TX_BD_WRAP (1 << 13) 153 | #define TX_BD_IRQ (1 << 14) /* interrupt request enable */ 154 | #define TX_BD_READY (1 << 15) /* TX buffer ready */ 155 | #define TX_BD_LEN(x) (((x) & 0xffff) << 16) 156 | #define TX_BD_LEN_MASK (0xffff << 16) 157 | 158 | #define TX_BD_STATS (TX_BD_CS | TX_BD_DF | TX_BD_LC | \ 159 | TX_BD_RL | TX_BD_RETRY_MASK | TX_BD_UR) 160 | 161 | /* RX buffer descriptor */ 162 | #define RX_BD_LC (1 << 0) /* late collision */ 163 | #define RX_BD_CRC (1 << 1) /* RX CRC error */ 164 | #define RX_BD_SF (1 << 2) /* short frame */ 165 | #define RX_BD_TL (1 << 3) /* too long */ 166 | #define RX_BD_DN (1 << 4) /* dribble nibble */ 167 | #define RX_BD_IS (1 << 5) /* invalid symbol */ 168 | #define RX_BD_OR (1 << 6) /* receiver overrun */ 169 | #define RX_BD_MISS (1 << 7) 170 | #define RX_BD_CF (1 << 8) /* control frame */ 171 | #define RX_BD_WRAP (1 << 13) 172 | #define RX_BD_IRQ (1 << 14) /* interrupt request enable */ 173 | #define RX_BD_EMPTY (1 << 15) 174 | #define RX_BD_LEN(x) (((x) & 0xffff) << 16) 175 | 176 | #define RX_BD_STATS (RX_BD_LC | RX_BD_CRC | RX_BD_SF | RX_BD_TL | \ 177 | RX_BD_DN | RX_BD_IS | RX_BD_OR | RX_BD_MISS) 178 | 179 | #define ETHOC_BUFSIZ 1536 180 | #define ETHOC_ZLEN 64 181 | #define ETHOC_BD_BASE 0x400 182 | #define ETHOC_TIMEOUT (HZ / 2) 183 | #define ETHOC_MII_TIMEOUT (1 + (HZ / 5)) 184 | 185 | 186 | 187 | 188 | #endif /* _NE2K_H_ */ 189 | -------------------------------------------------------------------------------- /components/libscpi/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS 2 | "src/error.c" 3 | "src/fifo.c" 4 | "src/ieee488.c" 5 | "src/lexer_private.h" 6 | "src/parser.c" 7 | "src/scpi.g" 8 | "src/utils.c" 9 | "src/expression.c" 10 | "src/fifo_private.h" 11 | "src/lexer.c" 12 | "src/minimal.c" 13 | "src/parser_private.h" 14 | "src/units.c" 15 | "src/utils_private.h" 16 | INCLUDE_DIRS "inc") 17 | 18 | #set(COMPONENT_SRCS 19 | #src/error.c 20 | #src/fifo.c 21 | #src/ieee488.c 22 | #src/lexer_private.h 23 | #src/parser.c 24 | #src/scpi.g 25 | #src/utils.c 26 | #src/expression.c 27 | #src/fifo_private.h 28 | #src/lexer.c 29 | #src/minimal.c 30 | #src/parser_private.h 31 | #src/units.c 32 | #src/utils_private.h 33 | #) 34 | #set(COMPONENT_ADD_INCLUDEDIRS "inc") 35 | #register_component() 36 | -------------------------------------------------------------------------------- /components/libscpi/Makefile: -------------------------------------------------------------------------------- 1 | VERSION = 2.1.0 2 | LIBNAME = scpi 3 | 4 | CFLAGS += -g -Wextra -Wmissing-prototypes -Wimplicit -Iinc 5 | CFLAGS_SHARED += $(CFLAGS) -fPIC 6 | LDFLAGS += -lm -Wl,--as-needed 7 | #TESTCFLAGS += $(CFLAGS) `pkg-config --cflags cunit` 8 | #TESTLDFLAGS += $(LDFLAGS) `pkg-config --libs cunit` 9 | TESTCFLAGS += $(CFLAGS) 10 | TESTLDFLAGS += $(LDFLAGS) -lcunit 11 | 12 | OBJDIR=obj 13 | OBJDIR_STATIC=$(OBJDIR)/static 14 | OBJDIR_SHARED=$(OBJDIR)/shared 15 | DISTDIR=dist 16 | TESTDIR=test 17 | 18 | PREFIX := $(DESTDIR)/usr/local 19 | LIBDIR := $(PREFIX)/lib 20 | INCDIR := $(PREFIX)/include 21 | 22 | STATICLIBFLAGS = rcs 23 | SHAREDLIBFLAGS = $(LDFLAGS) -shared -Wl,-soname,$(SHAREDLIB) 24 | 25 | STATICLIB = lib$(LIBNAME).a 26 | SHAREDLIB = lib$(LIBNAME).so 27 | SHAREDLIBVER = $(SHAREDLIB).$(VERSION) 28 | 29 | SRCS = $(addprefix src/, \ 30 | error.c fifo.c ieee488.c \ 31 | minimal.c parser.c units.c utils.c \ 32 | lexer.c expression.c \ 33 | ) 34 | 35 | OBJS_STATIC = $(addprefix $(OBJDIR_STATIC)/, $(notdir $(SRCS:.c=.o))) 36 | OBJS_SHARED = $(addprefix $(OBJDIR_SHARED)/, $(notdir $(SRCS:.c=.o))) 37 | 38 | HDRS = $(addprefix inc/scpi/, \ 39 | scpi.h constants.h error.h \ 40 | ieee488.h minimal.h parser.h types.h units.h \ 41 | expression.h \ 42 | ) \ 43 | $(addprefix src/, \ 44 | lexer_private.h utils_private.h fifo_private.h \ 45 | parser_private.h \ 46 | ) \ 47 | 48 | 49 | TESTS = $(addprefix $(TESTDIR)/, \ 50 | test_fifo.c test_scpi_utils.c test_lexer_parser.c test_parser.c\ 51 | ) 52 | 53 | TESTS_OBJS = $(TESTS:.c=.o) 54 | TESTS_BINS = $(TESTS_OBJS:.o=.test) 55 | 56 | .PHONY: all clean static shared test install 57 | 58 | all: static shared 59 | 60 | static: $(DISTDIR)/$(STATICLIB) 61 | 62 | shared: $(DISTDIR)/$(SHAREDLIBVER) 63 | 64 | clean: 65 | $(RM) -r $(OBJDIR) $(DISTDIR) $(TESTS_BINS) $(TESTS_OBJS) 66 | 67 | test: $(TESTS_BINS) 68 | $(TESTS_BINS:.test=.test &&) true 69 | 70 | install: $(DISTDIR)/$(STATICLIB) $(DISTDIR)/$(SHAREDLIBVER) 71 | test -d $(PREFIX) || mkdir $(PREFIX) 72 | test -d $(LIBDIR) || mkdir $(LIBDIR) 73 | test -d $(INCDIR) || mkdir $(INCDIR) 74 | test -d $(INCDIR)/scpi || mkdir $(INCDIR)/scpi 75 | install -m 0644 $(DISTDIR)/$(STATICLIB) $(LIBDIR) 76 | install -m 0644 $(DISTDIR)/$(SHAREDLIBVER) $(LIBDIR) 77 | install -m 0644 inc/scpi/*.h $(INCDIR)/scpi 78 | 79 | $(OBJDIR_STATIC): 80 | mkdir -p $@ 81 | 82 | $(OBJDIR_SHARED): 83 | mkdir -p $@ 84 | 85 | $(DISTDIR): 86 | mkdir -p $@ 87 | 88 | $(OBJDIR_STATIC)/%.o: src/%.c $(HDRS) | $(OBJDIR_STATIC) 89 | $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< 90 | 91 | $(OBJDIR_SHARED)/%.o: src/%.c $(HDRS) | $(OBJDIR_SHARED) 92 | $(CC) -c $(CFLAGS_SHARED) $(CPPFLAGS) -o $@ $< 93 | 94 | $(DISTDIR)/$(STATICLIB): $(OBJS_STATIC) | $(DISTDIR) 95 | $(AR) $(STATICLIBFLAGS) $(DISTDIR)/$(STATICLIB) $(OBJS_STATIC) 96 | 97 | $(DISTDIR)/$(SHAREDLIBVER): $(OBJS_SHARED) | $(DISTDIR) 98 | $(CC) $(SHAREDLIBFLAGS) -o $(DISTDIR)/$(SHAREDLIBVER) $(OBJS_SHARED) 99 | 100 | $(TESTDIR)/%.o: $(TESTDIR)/%.c 101 | $(CC) -c $(TESTCFLAGS) $(CPPFLAGS) -o $@ $< 102 | 103 | $(TESTDIR)/%.test: $(TESTDIR)/%.o $(DISTDIR)/$(STATICLIB) 104 | $(CC) $< -o $@ $(DISTDIR)/$(STATICLIB) $(TESTLDFLAGS) 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /components/libscpi/component.mk: -------------------------------------------------------------------------------- 1 | COMPONENT_SRCDIRS:=src 2 | COMPONENT_ADD_INCLUDEDIRS:=inc 3 | -------------------------------------------------------------------------------- /components/libscpi/inc/scpi/cc.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file cc.h 30 | * 31 | * @brief compiler detection 32 | * 33 | * 34 | */ 35 | 36 | #ifndef __SCPI_CC_H_ 37 | #define __SCPI_CC_H_ 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | #if defined(__STDC__) 44 | # define C89 1 45 | # if defined(__STDC_VERSION__) 46 | # define C90 1 47 | # if (__STDC_VERSION__ >= 199409L) 48 | # define C94 1 49 | # endif 50 | # if (__STDC_VERSION__ >= 199901L) 51 | # define C99 1 52 | # endif 53 | # endif 54 | #endif 55 | 56 | #if POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700 57 | #define HAVE_STRNDUP 1 58 | #define HAVE_STRNLEN 1 59 | #endif 60 | 61 | #if _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L || C99 62 | #define HAVE_SNPRINTF 1 63 | #endif 64 | 65 | #if _POSIX_C_SOURCE >= 200112L 66 | #define HAVE_STRNCASECMP 1 67 | #endif 68 | 69 | #if _BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L || C99 70 | #define HAVE_ISNAN 1 71 | #endif 72 | 73 | #if _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L || C99 74 | #define HAVE_ISFINITE 1 75 | #define HAVE_SIGNBIT 1 76 | #endif 77 | 78 | #if XOPEN_SOURCE >= 600 || _BSD_SOURCE || _SVID_SOURCE || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L 79 | #define HAVE_STRTOLL 1 80 | #endif 81 | 82 | #if _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L || C99 83 | #define HAVE_STRTOF 1 84 | #endif 85 | 86 | #if _ISOC99_SOURCE || C99 87 | #define HAVE_STDBOOL 1 88 | #endif 89 | 90 | /* Compiler specific */ 91 | /* RealView/Keil ARM Compiler, e.g. Cortex-M CPUs */ 92 | #if defined(__CC_ARM) 93 | #define HAVE_STRNCASECMP 1 94 | #endif 95 | 96 | /* National Instruments (R) CVI x86/x64 PC platform */ 97 | #if defined(_CVI_) 98 | #define HAVE_STRNICMP 1 99 | #endif 100 | 101 | /* 8bit PIC - PIC16, etc */ 102 | #if defined(_MPC_) 103 | #define HAVE_STRNICMP 1 104 | #endif 105 | 106 | /* PIC24 */ 107 | #if defined(__C30__) 108 | #endif 109 | 110 | /* PIC32mx */ 111 | #if defined(__C32__) 112 | #define HAVE_FINITE 1 113 | #endif 114 | 115 | /* AVR libc */ 116 | #if defined(__AVR__) 117 | #include 118 | #define HAVE_DTOSTRE 1 119 | #undef HAVE_STRTOF 120 | #define HAVE_STRTOF 0 121 | #endif 122 | 123 | /* default values */ 124 | #ifndef HAVE_STRNLEN 125 | #define HAVE_STRNLEN 0 126 | #endif 127 | 128 | #ifndef HAVE_STRDUP 129 | #define HAVE_STRDUP 0 130 | #endif 131 | 132 | #ifndef HAVE_STRNICMP 133 | #define HAVE_STRNICMP 0 134 | #endif 135 | 136 | #ifndef HAVE_STDBOOL 137 | #define HAVE_STDBOOL 0 138 | #endif 139 | 140 | #ifndef HAVE_SNPRINTF 141 | #define HAVE_SNPRINTF 0 142 | #endif 143 | 144 | #ifndef HAVE_STRNCASECMP 145 | #define HAVE_STRNCASECMP 0 146 | #endif 147 | 148 | #ifndef HAVE_ISNAN 149 | #define HAVE_ISNAN 0 150 | #endif 151 | 152 | #ifndef HAVE_ISFINITE 153 | #define HAVE_ISFINITE 0 154 | #endif 155 | 156 | #ifndef HAVE_FINITE 157 | #define HAVE_FINITE 0 158 | #endif 159 | 160 | #ifndef HAVE_SIGNBIT 161 | #define HAVE_SIGNBIT 0 162 | #endif 163 | 164 | #ifndef HAVE_STRTOLL 165 | #define HAVE_STRTOLL 0 166 | #endif 167 | 168 | #ifndef HAVE_STRTOF 169 | #define HAVE_STRTOF 0 170 | #endif 171 | 172 | #ifdef __cplusplus 173 | } 174 | #endif 175 | 176 | #endif /* __SCPI_CC_H_ */ -------------------------------------------------------------------------------- /components/libscpi/inc/scpi/config.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file config.h 30 | * @date Wed Mar 20 12:21:26 UTC 2013 31 | * 32 | * @brief SCPI Configuration 33 | * 34 | * 35 | */ 36 | 37 | #ifndef __SCPI_CONFIG_H_ 38 | #define __SCPI_CONFIG_H_ 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | #include "cc.h" 45 | 46 | #ifdef SCPI_USER_CONFIG 47 | #include "scpi_user_config.h" 48 | #endif 49 | 50 | /* set the termination character(s) */ 51 | #define LINE_ENDING_CR "\r" /* use a carriage return as termination charcter */ 52 | #define LINE_ENDING_LF "\n" /* use a line feed as termination charcter */ 53 | #define LINE_ENDING_CRLF "\r\n" /* use carriage return + line feed as termination charcters */ 54 | 55 | // WAS LINE_ENDING_CRLF 56 | #ifndef SCPI_LINE_ENDING 57 | #define SCPI_LINE_ENDING LINE_ENDING_LF 58 | #endif 59 | 60 | /** 61 | * Detect, if it has limited resources or it is running on a full blown operating system. 62 | * All values can be overiden by scpi_user_config.h 63 | */ 64 | #define SYSTEM_BARE_METAL 0 65 | #define SYSTEM_FULL_BLOWN 1 66 | 67 | /* This should cover all windows compilers (msvc, mingw, cvi) and all Linux/OSX/BSD and other UNIX compatible systems (gcc, clang) */ 68 | #if defined(_WIN32) || defined(_WIN64) || defined(__unix) || defined(__unix__) || defined(__APPLE__) 69 | #define SYSTEM_TYPE SYSTEM_FULL_BLOWN 70 | #else 71 | #define SYSTEM_TYPE SYSTEM_BARE_METAL 72 | #endif 73 | 74 | /** 75 | * Enable full error list 76 | * 0 = Minimal set of errors 77 | * 1 = Full set of errors 78 | * 79 | * For small systems, full set of errors will occupy large ammount of data 80 | * It is enabled by default on full blown systems and disabled on limited bare metal systems 81 | */ 82 | #ifndef USE_FULL_ERROR_LIST 83 | #define USE_FULL_ERROR_LIST SYSTEM_TYPE 84 | #endif 85 | 86 | /** 87 | * Enable also LIST_OF_USER_ERRORS to be included 88 | * 0 = Use only library defined errors 89 | * 1 = Use also LIST_OF_USER_ERRORS 90 | */ 91 | #ifndef USE_USER_ERROR_LIST 92 | #define USE_USER_ERROR_LIST 0 93 | #endif 94 | 95 | #ifndef USE_DEVICE_DEPENDENT_ERROR_INFORMATION 96 | #define USE_DEVICE_DEPENDENT_ERROR_INFORMATION SYSTEM_TYPE 97 | #endif 98 | 99 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION 100 | #ifndef USE_MEMORY_ALLOCATION_FREE 101 | #define USE_MEMORY_ALLOCATION_FREE 1 102 | #endif 103 | #endif 104 | 105 | #ifndef USE_COMMAND_TAGS 106 | #define USE_COMMAND_TAGS 1 107 | #endif 108 | 109 | #ifndef USE_DEPRECATED_FUNCTIONS 110 | #define USE_DEPRECATED_FUNCTIONS 1 111 | #endif 112 | 113 | #ifndef USE_CUSTOM_DTOSTR 114 | #define USE_CUSTOM_DTOSTR 0 115 | #endif 116 | 117 | #ifndef USE_UNITS_IMPERIAL 118 | #define USE_UNITS_IMPERIAL 0 119 | #endif 120 | 121 | #ifndef USE_UNITS_ANGLE 122 | #define USE_UNITS_ANGLE SYSTEM_TYPE 123 | #endif 124 | 125 | #ifndef USE_UNITS_PARTICLES 126 | #define USE_UNITS_PARTICLES SYSTEM_TYPE 127 | #endif 128 | 129 | #ifndef USE_UNITS_DISTANCE 130 | #define USE_UNITS_DISTANCE SYSTEM_TYPE 131 | #endif 132 | 133 | #ifndef USE_UNITS_MAGNETIC 134 | #define USE_UNITS_MAGNETIC SYSTEM_TYPE 135 | #endif 136 | 137 | #ifndef USE_UNITS_LIGHT 138 | #define USE_UNITS_LIGHT SYSTEM_TYPE 139 | #endif 140 | 141 | #ifndef USE_UNITS_ENERGY_FORCE_MASS 142 | #define USE_UNITS_ENERGY_FORCE_MASS SYSTEM_TYPE 143 | #endif 144 | 145 | #ifndef USE_UNITS_TIME 146 | #define USE_UNITS_TIME SYSTEM_TYPE 147 | #endif 148 | 149 | #ifndef USE_UNITS_TEMPERATURE 150 | #define USE_UNITS_TEMPERATURE SYSTEM_TYPE 151 | #endif 152 | 153 | #ifndef USE_UNITS_RATIO 154 | #define USE_UNITS_RATIO SYSTEM_TYPE 155 | #endif 156 | 157 | #ifndef USE_UNITS_POWER 158 | #define USE_UNITS_POWER 1 159 | #endif 160 | 161 | #ifndef USE_UNITS_FREQUENCY 162 | #define USE_UNITS_FREQUENCY 1 163 | #endif 164 | 165 | #ifndef USE_UNITS_ELECTRIC 166 | #define USE_UNITS_ELECTRIC 1 167 | #endif 168 | 169 | #ifndef USE_UNITS_ELECTRIC_CHARGE_CONDUCTANCE 170 | #define USE_UNITS_ELECTRIC_CHARGE_CONDUCTANCE SYSTEM_TYPE 171 | #endif 172 | 173 | /* define local macros depending on existance of strnlen */ 174 | #if HAVE_STRNLEN 175 | #define SCPIDEFINE_strnlen(s, l) strnlen((s), (l)) 176 | #else 177 | #define SCPIDEFINE_strnlen(s, l) BSD_strnlen((s), (l)) 178 | #endif 179 | 180 | /* define local macros depending on existance of strncasecmp and strnicmp */ 181 | #if HAVE_STRNCASECMP 182 | #define SCPIDEFINE_strncasecmp(s1, s2, l) strncasecmp((s1), (s2), (l)) 183 | #elif HAVE_STRNICMP 184 | #define SCPIDEFINE_strncasecmp(s1, s2, l) strnicmp((s1), (s2), (l)) 185 | #else 186 | #define SCPIDEFINE_strncasecmp(s1, s2, l) OUR_strncasecmp((s1), (s2), (l)) 187 | #endif 188 | 189 | #if HAVE_DTOSTRE 190 | #define SCPIDEFINE_floatToStr(v, s, l) dtostre((double)(v), (s), 6, DTOSTR_PLUS_SIGN | DTOSTR_ALWAYS_SIGN | DTOSTR_UPPERCASE) 191 | #elif USE_CUSTOM_DTOSTRE 192 | #define SCPIDEFINE_floatToStr(v, s, l) SCPI_dtostre((v), (s), (l), 6, 0) 193 | #elif HAVE_SNPRINTF 194 | #define SCPIDEFINE_floatToStr(v, s, l) snprintf((s), (l), "%g", (v)) 195 | #else 196 | #define SCPIDEFINE_floatToStr(v, s, l) SCPI_dtostre((v), (s), (l), 6, 0) 197 | #endif 198 | 199 | #if HAVE_DTOSTRE 200 | #define SCPIDEFINE_doubleToStr(v, s, l) dtostre((v), (s), 15, DTOSTR_PLUS_SIGN | DTOSTR_ALWAYS_SIGN | DTOSTR_UPPERCASE) 201 | #elif USE_CUSTOM_DTOSTRE 202 | #define SCPIDEFINE_doubleToStr(v, s, l) SCPI_dtostre((v), (s), (l), 15, 0) 203 | #elif HAVE_SNPRINTF 204 | #define SCPIDEFINE_doubleToStr(v, s, l) snprintf((s), (l), "%.15lg", (v)) 205 | #else 206 | #define SCPIDEFINE_doubleToStr(v, s, l) SCPI_dtostre((v), (s), (l), 15, 0) 207 | #endif 208 | 209 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION 210 | 211 | #if USE_MEMORY_ALLOCATION_FREE 212 | #include 213 | #include 214 | #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 2 215 | #if HAVE_STRNDUP 216 | #define SCPIDEFINE_strndup(h, s, l) strndup((s), (l)) 217 | #else 218 | #define SCPIDEFINE_strndup(h, s, l) OUR_strndup((s), (l)) 219 | #endif 220 | #define SCPIDEFINE_free(h, s, r) free((s)) 221 | #else 222 | #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 3 223 | #define SCPIDEFINE_strndup(h, s, l) scpiheap_strndup((h), (s), (l)) 224 | #define SCPIDEFINE_free(h, s, r) scpiheap_free((h), (s), (r)) 225 | #define SCPIDEFINE_get_parts(h, s, l1, s2, l2) scpiheap_get_parts((h), (s), (l1), (s2), (l2)) 226 | #endif 227 | #else 228 | #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 1 229 | #define SCPIDEFINE_strndup(h, s, l) NULL 230 | #define SCPIDEFINE_free(h, s, r) 231 | #endif 232 | 233 | #if HAVE_SIGNBIT 234 | #define SCPIDEFINE_signbit(n) signbit(n) 235 | #else 236 | #define SCPIDEFINE_signbit(n) ((n)<0) 237 | #endif 238 | 239 | #if HAVE_FINITE 240 | #define SCPIDEFINE_isfinite(n) finite(n) 241 | #elif HAVE_ISFINITE 242 | #define SCPIDEFINE_isfinite(n) isfinite(n) 243 | #else 244 | #define SCPIDEFINE_isfinite(n) (!SCPIDEFINE_isnan((n)) && ((n) < INFINITY) && ((n) > -INFINITY)) 245 | #endif 246 | 247 | #if HAVE_STRTOF 248 | #define SCPIDEFINE_strtof(n, p) strtof((n), (p)) 249 | #else 250 | #define SCPIDEFINE_strtof(n, p) strtod((n), (p)) 251 | #endif 252 | 253 | #if HAVE_STRTOLL 254 | #define SCPIDEFINE_strtoll(n, p, b) strtoll((n), (p), (b)) 255 | #define SCPIDEFINE_strtoull(n, p, b) strtoull((n), (p), (b)) 256 | #else 257 | #define SCPIDEFINE_strtoll(n, p, b) strtoll((n), (p), (b)) 258 | #define SCPIDEFINE_strtoull(n, p, b) strtoull((n), (p), (b)) 259 | extern long long int strtoll(const char *nptr, char **endptr, int base); 260 | extern unsigned long long int strtoull(const char *nptr, char **endptr, int base); 261 | /* TODO: implement OUR_strtoll and OUR_strtoull */ 262 | /* #warning "64bit string to int conversion not implemented" */ 263 | #endif 264 | 265 | #if HAVE_ISNAN 266 | #define SCPIDEFINE_isnan(n) isnan((n)) 267 | #else 268 | #define SCPIDEFINE_isnan(n) ((n) != (n)) 269 | #endif 270 | 271 | #ifndef NAN 272 | #define NAN (0.0 / 0.0) 273 | #endif 274 | 275 | #ifndef INFINITY 276 | #define INFINITY (1.0 / 0.0) 277 | #endif 278 | 279 | #ifdef __cplusplus 280 | } 281 | #endif 282 | 283 | #endif 284 | -------------------------------------------------------------------------------- /components/libscpi/inc/scpi/constants.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file scpi_constants.h 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief SCPI Device constants 33 | * 34 | * 35 | */ 36 | 37 | #ifndef SCPI_CONSTANTS_H 38 | #define SCPI_CONSTANTS_H 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | /* 21.21 :VERSion? 45 | * YYYY.V 46 | * YYYY = SCPI year 47 | * V = SCPI revision 48 | */ 49 | #define SCPI_STD_VERSION_REVISION "1999.0" 50 | 51 | /* 21.8 :ERRor Subsystem 52 | * The maximum string length of plus is 255 characters. 53 | */ 54 | #define SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH 255 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif /* SCPI_CONSTANTS_H */ 61 | 62 | -------------------------------------------------------------------------------- /components/libscpi/inc/scpi/expression.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2015 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file expression.h 30 | * 31 | * @brief Expressions handling 32 | * 33 | * 34 | */ 35 | #ifndef SCPI_EXPRESSION_H 36 | #define SCPI_EXPRESSION_H 37 | 38 | #include "scpi/config.h" 39 | #include "scpi/types.h" 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | enum _scpi_expr_result_t { 46 | SCPI_EXPR_OK = 0, 47 | SCPI_EXPR_ERROR, 48 | SCPI_EXPR_NO_MORE, 49 | }; 50 | typedef enum _scpi_expr_result_t scpi_expr_result_t; 51 | 52 | scpi_expr_result_t SCPI_ExprNumericListEntry(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, scpi_parameter_t * valueFrom, scpi_parameter_t * valueTo); 53 | scpi_expr_result_t SCPI_ExprNumericListEntryInt(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, int32_t * valueFrom, int32_t * valueTo); 54 | scpi_expr_result_t SCPI_ExprNumericListEntryDouble(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, double * valueFrom, double * valueTo); 55 | scpi_expr_result_t SCPI_ExprChannelListEntry(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, int32_t * valuesFrom, int32_t * valuesTo, size_t length, size_t * dimensions); 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif /* SCPI_EXPRESSION_H */ 62 | -------------------------------------------------------------------------------- /components/libscpi/inc/scpi/ieee488.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file scpi_ieee488.h 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief Implementation of IEEE488.2 commands and state model 33 | * 34 | * 35 | */ 36 | 37 | #ifndef SCPI_IEEE488_H 38 | #define SCPI_IEEE488_H 39 | 40 | #include "scpi/types.h" 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | scpi_result_t SCPI_CoreCls(scpi_t * context); 47 | scpi_result_t SCPI_CoreEse(scpi_t * context); 48 | scpi_result_t SCPI_CoreEseQ(scpi_t * context); 49 | scpi_result_t SCPI_CoreEsrQ(scpi_t * context); 50 | scpi_result_t SCPI_CoreIdnQ(scpi_t * context); 51 | scpi_result_t SCPI_CoreOpc(scpi_t * context); 52 | scpi_result_t SCPI_CoreOpcQ(scpi_t * context); 53 | scpi_result_t SCPI_CoreRst(scpi_t * context); 54 | scpi_result_t SCPI_CoreSre(scpi_t * context); 55 | scpi_result_t SCPI_CoreSreQ(scpi_t * context); 56 | scpi_result_t SCPI_CoreStbQ(scpi_t * context); 57 | scpi_result_t SCPI_CoreTstQ(scpi_t * context); 58 | scpi_result_t SCPI_CoreWai(scpi_t * context); 59 | 60 | 61 | #define STB_R01 0x01 /* Not used */ 62 | #define STB_PRO 0x02 /* Protection Event Flag */ 63 | #define STB_QMA 0x04 /* Error/Event queue message available */ 64 | #define STB_QES 0x08 /* Questionable status */ 65 | #define STB_MAV 0x10 /* Message Available */ 66 | #define STB_ESR 0x20 /* Standard Event Status Register */ 67 | #define STB_SRQ 0x40 /* Service Request */ 68 | #define STB_OPS 0x80 /* Operation Status Flag */ 69 | 70 | 71 | #define ESR_OPC 0x01 /* Operation complete */ 72 | #define ESR_REQ 0x02 /* Request Control */ 73 | #define ESR_QER 0x04 /* Query Error */ 74 | #define ESR_DER 0x08 /* Device Dependent Error */ 75 | #define ESR_EER 0x10 /* Execution Error (e.g. range error) */ 76 | #define ESR_CER 0x20 /* Command error (e.g. syntax error) */ 77 | #define ESR_URQ 0x40 /* User Request */ 78 | #define ESR_PON 0x80 /* Power On */ 79 | 80 | 81 | scpi_reg_val_t SCPI_RegGet(scpi_t * context, scpi_reg_name_t name); 82 | void SCPI_RegSet(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t val); 83 | void SCPI_RegSetBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits); 84 | void SCPI_RegClearBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits); 85 | 86 | void SCPI_EventClear(scpi_t * context); 87 | 88 | #ifdef __cplusplus 89 | } 90 | #endif 91 | 92 | #endif /* SCPI_IEEE488_H */ 93 | 94 | -------------------------------------------------------------------------------- /components/libscpi/inc/scpi/minimal.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file scpi_minimal.h 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief SCPI minimal implementation 33 | * 34 | * 35 | */ 36 | 37 | #ifndef SCPI_MINIMAL_H 38 | #define SCPI_MINIMAL_H 39 | 40 | #include "scpi/types.h" 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | scpi_result_t SCPI_Stub(scpi_t * context); 47 | scpi_result_t SCPI_StubQ(scpi_t * context); 48 | 49 | scpi_result_t SCPI_SystemVersionQ(scpi_t * context); 50 | scpi_result_t SCPI_SystemErrorNextQ(scpi_t * context); 51 | scpi_result_t SCPI_SystemErrorCountQ(scpi_t * context); 52 | scpi_result_t SCPI_StatusQuestionableEventQ(scpi_t * context); 53 | scpi_result_t SCPI_StatusQuestionableConditionQ(scpi_t * context); 54 | scpi_result_t SCPI_StatusQuestionableEnableQ(scpi_t * context); 55 | scpi_result_t SCPI_StatusQuestionableEnable(scpi_t * context); 56 | scpi_result_t SCPI_StatusOperationConditionQ(scpi_t * context); 57 | scpi_result_t SCPI_StatusOperationEventQ(scpi_t * context); 58 | scpi_result_t SCPI_StatusOperationEnableQ(scpi_t * context); 59 | scpi_result_t SCPI_StatusOperationEnable(scpi_t * context); 60 | scpi_result_t SCPI_StatusPreset(scpi_t * context); 61 | 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif /* SCPI_MINIMAL_H */ 68 | 69 | -------------------------------------------------------------------------------- /components/libscpi/inc/scpi/parser.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file scpi_parser.h 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief SCPI parser implementation 33 | * 34 | * 35 | */ 36 | 37 | #ifndef SCPI_PARSER_H 38 | #define SCPI_PARSER_H 39 | 40 | #include 41 | #include "scpi/types.h" 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | void SCPI_Init(scpi_t * context, 47 | const scpi_command_t * commands, 48 | scpi_interface_t * interface, 49 | const scpi_unit_def_t * units, 50 | const char * idn1, const char * idn2, const char * idn3, const char * idn4, 51 | char * input_buffer, size_t input_buffer_length, 52 | scpi_error_t * error_queue_data, int16_t error_queue_size); 53 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE 54 | void SCPI_InitHeap(scpi_t * context, char * error_info_heap, size_t error_info_heap_length); 55 | #endif 56 | 57 | scpi_bool_t SCPI_Input(scpi_t * context, const char * data, int len); 58 | scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len); 59 | 60 | size_t SCPI_ResultCharacters(scpi_t * context, const char * data, size_t len); 61 | #define SCPI_ResultMnemonic(context, data) SCPI_ResultCharacters((context), (data), strlen(data)) 62 | #define SCPI_ResultUInt8Base(c, v, b) SCPI_ResultUInt32Base((c), (v), (uint8_t)(b)) 63 | #define SCPI_ResultUInt8(c, v) SCPI_ResultUInt32Base((c), (uint8_t)(v), 10) 64 | #define SCPI_ResultInt8(c, v) SCPI_ResultInt32((c), (int8_t)(v)) 65 | #define SCPI_ResultUInt16Base(c, v, b) SCPI_ResultUInt32Base((c), (uint16_t)(v), (b)) 66 | #define SCPI_ResultUInt16(c, v) SCPI_ResultUInt32Base((c), (uint16_t)(v), 10) 67 | #define SCPI_ResultInt16(c, v) SCPI_ResultInt32((c), (int16_t)(v)) 68 | size_t SCPI_ResultUInt32Base(scpi_t * context, uint32_t val, int8_t base); 69 | #define SCPI_ResultUInt32(c, v) SCPI_ResultUInt32Base((c), (v), 10) 70 | size_t SCPI_ResultInt32(scpi_t * context, int32_t val); 71 | size_t SCPI_ResultUInt64Base(scpi_t * context, uint64_t val, int8_t base); 72 | #define SCPI_ResultUInt64(c, v) SCPI_ResultUInt64Base((c), (v), 10) 73 | size_t SCPI_ResultInt64(scpi_t * context, int64_t val); 74 | size_t SCPI_ResultFloat(scpi_t * context, float val); 75 | size_t SCPI_ResultDouble(scpi_t * context, double val); 76 | size_t SCPI_ResultText(scpi_t * context, const char * data); 77 | size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error); 78 | size_t SCPI_ResultArbitraryBlock(scpi_t * context, const void * data, size_t len); 79 | size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len); 80 | size_t SCPI_ResultArbitraryBlockData(scpi_t * context, const void * data, size_t len); 81 | size_t SCPI_ResultBool(scpi_t * context, scpi_bool_t val); 82 | 83 | size_t SCPI_ResultArrayInt8(scpi_t * context, const int8_t * array, size_t count, scpi_array_format_t format); 84 | size_t SCPI_ResultArrayUInt8(scpi_t * context, const uint8_t * array, size_t count, scpi_array_format_t format); 85 | size_t SCPI_ResultArrayInt16(scpi_t * context, const int16_t * array, size_t count, scpi_array_format_t format); 86 | size_t SCPI_ResultArrayUInt16(scpi_t * context, const uint16_t * array, size_t count, scpi_array_format_t format); 87 | size_t SCPI_ResultArrayInt32(scpi_t * context, const int32_t * array, size_t count, scpi_array_format_t format); 88 | size_t SCPI_ResultArrayUInt32(scpi_t * context, const uint32_t * array, size_t count, scpi_array_format_t format); 89 | size_t SCPI_ResultArrayInt64(scpi_t * context, const int64_t * array, size_t count, scpi_array_format_t format); 90 | size_t SCPI_ResultArrayUInt64(scpi_t * context, const uint64_t * array, size_t count, scpi_array_format_t format); 91 | size_t SCPI_ResultArrayFloat(scpi_t * context, const float * array, size_t count, scpi_array_format_t format); 92 | size_t SCPI_ResultArrayDouble(scpi_t * context, const double * array, size_t count, scpi_array_format_t format); 93 | 94 | scpi_bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, scpi_bool_t mandatory); 95 | scpi_bool_t SCPI_ParamIsValid(scpi_parameter_t * parameter); 96 | scpi_bool_t SCPI_ParamErrorOccurred(scpi_t * context); 97 | scpi_bool_t SCPI_ParamIsNumber(scpi_parameter_t * parameter, scpi_bool_t suffixAllowed); 98 | scpi_bool_t SCPI_ParamToInt32(scpi_t * context, scpi_parameter_t * parameter, int32_t * value); 99 | scpi_bool_t SCPI_ParamToUInt32(scpi_t * context, scpi_parameter_t * parameter, uint32_t * value); 100 | scpi_bool_t SCPI_ParamToInt64(scpi_t * context, scpi_parameter_t * parameter, int64_t * value); 101 | scpi_bool_t SCPI_ParamToUInt64(scpi_t * context, scpi_parameter_t * parameter, uint64_t * value); 102 | scpi_bool_t SCPI_ParamToFloat(scpi_t * context, scpi_parameter_t * parameter, float * value); 103 | scpi_bool_t SCPI_ParamToDouble(scpi_t * context, scpi_parameter_t * parameter, double * value); 104 | scpi_bool_t SCPI_ParamToChoice(scpi_t * context, scpi_parameter_t * parameter, const scpi_choice_def_t * options, int32_t * value); 105 | scpi_bool_t SCPI_ChoiceToName(const scpi_choice_def_t * options, int32_t tag, const char ** text); 106 | 107 | scpi_bool_t SCPI_ParamInt32(scpi_t * context, int32_t * value, scpi_bool_t mandatory); 108 | scpi_bool_t SCPI_ParamUInt32(scpi_t * context, uint32_t * value, scpi_bool_t mandatory); 109 | scpi_bool_t SCPI_ParamInt64(scpi_t * context, int64_t * value, scpi_bool_t mandatory); 110 | scpi_bool_t SCPI_ParamUInt64(scpi_t * context, uint64_t * value, scpi_bool_t mandatory); 111 | scpi_bool_t SCPI_ParamFloat(scpi_t * context, float * value, scpi_bool_t mandatory); 112 | scpi_bool_t SCPI_ParamDouble(scpi_t * context, double * value, scpi_bool_t mandatory); 113 | scpi_bool_t SCPI_ParamCharacters(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory); 114 | scpi_bool_t SCPI_ParamArbitraryBlock(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory); 115 | scpi_bool_t SCPI_ParamCopyText(scpi_t * context, char * buffer, size_t buffer_len, size_t * copy_len, scpi_bool_t mandatory); 116 | 117 | extern const scpi_choice_def_t scpi_bool_def[]; 118 | scpi_bool_t SCPI_ParamBool(scpi_t * context, scpi_bool_t * value, scpi_bool_t mandatory); 119 | scpi_bool_t SCPI_ParamChoice(scpi_t * context, const scpi_choice_def_t * options, int32_t * value, scpi_bool_t mandatory); 120 | 121 | scpi_bool_t SCPI_ParamArrayInt32(scpi_t * context, int32_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); 122 | scpi_bool_t SCPI_ParamArrayUInt32(scpi_t * context, uint32_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); 123 | scpi_bool_t SCPI_ParamArrayInt64(scpi_t * context, int64_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); 124 | scpi_bool_t SCPI_ParamArrayUInt64(scpi_t * context, uint64_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); 125 | scpi_bool_t SCPI_ParamArrayFloat(scpi_t * context, float *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); 126 | scpi_bool_t SCPI_ParamArrayDouble(scpi_t * context, double *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); 127 | 128 | scpi_bool_t SCPI_IsCmd(scpi_t * context, const char * cmd); 129 | #if USE_COMMAND_TAGS 130 | int32_t SCPI_CmdTag(scpi_t * context); 131 | #endif /* USE_COMMAND_TAGS */ 132 | scpi_bool_t SCPI_Match(const char * pattern, const char * value, size_t len); 133 | scpi_bool_t SCPI_CommandNumbers(scpi_t * context, int32_t * numbers, size_t len, int32_t default_value); 134 | 135 | #if USE_DEPRECATED_FUNCTIONS 136 | /* deprecated finction, should be removed later */ 137 | #define SCPI_ResultIntBase(context, val, base) SCPI_ResultInt32Base ((context), (val), (base), TRUE) 138 | #define SCPI_ResultInt(context, val) SCPI_ResultInt32 ((context), (val)) 139 | #define SCPI_ParamToInt(context, parameter, value) SCPI_ParamToInt32((context), (parameter), (value)) 140 | #define SCPI_ParamToUnsignedInt(context, parameter, value) SCPI_ParamToUInt32((context), (parameter), (value)) 141 | #define SCPI_ParamInt(context, value, mandatory) SCPI_ParamInt32((context), (value), (mandatory)) 142 | #define SCPI_ParamUnsignedInt(context, value, mandatory) SCPI_ParamUInt32((context), (value), (mandatory)) 143 | #endif /* USE_DEPRECATED_FUNCTIONS */ 144 | 145 | #ifdef __cplusplus 146 | } 147 | #endif 148 | 149 | #endif /* SCPI_PARSER_H */ 150 | 151 | -------------------------------------------------------------------------------- /components/libscpi/inc/scpi/scpi.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file scpi.h 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief SCPI library include file 33 | * 34 | * 35 | */ 36 | 37 | #ifndef SCPI_H 38 | #define SCPI_H 39 | 40 | #include "scpi/parser.h" 41 | #include "scpi/ieee488.h" 42 | #include "scpi/error.h" 43 | #include "scpi/constants.h" 44 | #include "scpi/minimal.h" 45 | #include "scpi/units.h" 46 | #include "scpi/utils.h" 47 | #include "scpi/expression.h" 48 | 49 | #endif /* SCPI_H */ 50 | 51 | -------------------------------------------------------------------------------- /components/libscpi/inc/scpi/units.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file scpi_units.h 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief SCPI Units 33 | * 34 | * 35 | */ 36 | 37 | #ifndef SCPI_UNITS_H 38 | #define SCPI_UNITS_H 39 | 40 | #include "scpi/types.h" 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | extern const scpi_unit_def_t scpi_units_def[]; 47 | extern const scpi_choice_def_t scpi_special_numbers_def[]; 48 | 49 | scpi_bool_t SCPI_ParamNumber(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, scpi_bool_t mandatory); 50 | 51 | scpi_bool_t SCPI_ParamTranslateNumberVal(scpi_t * context, scpi_parameter_t * parameter); 52 | size_t SCPI_NumberToStr(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, char * str, size_t len); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif /* SCPI_UNITS_H */ 59 | 60 | -------------------------------------------------------------------------------- /components/libscpi/inc/scpi/utils.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2015 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file utils.h 30 | * 31 | * @brief Conversion routines and string manipulation routines 32 | * 33 | * 34 | */ 35 | 36 | #ifndef SCPI_UTILS_H 37 | #define SCPI_UTILS_H 38 | 39 | #include 40 | #include "scpi/types.h" 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | size_t SCPI_UInt32ToStrBase(uint32_t val, char * str, size_t len, int8_t base); 47 | size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len); 48 | size_t SCPI_UInt64ToStrBase(uint64_t val, char * str, size_t len, int8_t base); 49 | size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len); 50 | size_t SCPI_FloatToStr(float val, char * str, size_t len); 51 | size_t SCPI_DoubleToStr(double val, char * str, size_t len); 52 | 53 | /* deprecated finction, should be removed later */ 54 | #define SCPI_LongToStr(val, str, len, base) SCPI_Int32ToStr((val), (str), (len), (base), TRUE) 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif /* SCPI_UTILS_H */ 61 | 62 | -------------------------------------------------------------------------------- /components/libscpi/src/error.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file scpi_error.c 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief Error handling and storing routines 33 | * 34 | * 35 | */ 36 | 37 | #include 38 | 39 | #include "scpi/parser.h" 40 | #include "scpi/ieee488.h" 41 | #include "scpi/error.h" 42 | #include "fifo_private.h" 43 | #include "scpi/constants.h" 44 | 45 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION 46 | #define SCPI_ERROR_SETVAL(e, c, i) do { (e)->error_code = (c); (e)->device_dependent_info = (i); } while(0) 47 | #else 48 | #define SCPI_ERROR_SETVAL(e, c, i) do { (e)->error_code = (c); (void)(i);} while(0) 49 | #endif 50 | 51 | /** 52 | * Initialize error queue 53 | * @param context - scpi context 54 | */ 55 | void SCPI_ErrorInit(scpi_t * context, scpi_error_t * data, int16_t size) { 56 | fifo_init(&context->error_queue, data, size); 57 | } 58 | 59 | /** 60 | * Emit no error 61 | * @param context scpi context 62 | */ 63 | static void SCPI_ErrorEmitEmpty(scpi_t * context) { 64 | if ((SCPI_ErrorCount(context) == 0) && (SCPI_RegGet(context, SCPI_REG_STB) & STB_QMA)) { 65 | SCPI_RegClearBits(context, SCPI_REG_STB, STB_QMA); 66 | 67 | if (context->interface && context->interface->error) { 68 | context->interface->error(context, 0); 69 | } 70 | } 71 | } 72 | 73 | /** 74 | * Emit error 75 | * @param context scpi context 76 | * @param err Error to emit 77 | */ 78 | static void SCPI_ErrorEmit(scpi_t * context, int16_t err) { 79 | SCPI_RegSetBits(context, SCPI_REG_STB, STB_QMA); 80 | 81 | if (context->interface && context->interface->error) { 82 | context->interface->error(context, err); 83 | } 84 | } 85 | 86 | /** 87 | * Clear error queue 88 | * @param context - scpi context 89 | */ 90 | void SCPI_ErrorClear(scpi_t * context) { 91 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION 92 | scpi_error_t error; 93 | while (fifo_remove(&context->error_queue, &error)) { 94 | SCPIDEFINE_free(&context->error_info_heap, error.device_dependent_info, false); 95 | } 96 | #endif 97 | fifo_clear(&context->error_queue); 98 | 99 | SCPI_ErrorEmitEmpty(context); 100 | } 101 | 102 | /** 103 | * Pop error from queue 104 | * @param context - scpi context 105 | * @param error 106 | * @return 107 | */ 108 | scpi_bool_t SCPI_ErrorPop(scpi_t * context, scpi_error_t * error) { 109 | if (!error || !context) return FALSE; 110 | SCPI_ERROR_SETVAL(error, 0, NULL); 111 | fifo_remove(&context->error_queue, error); 112 | 113 | SCPI_ErrorEmitEmpty(context); 114 | 115 | return TRUE; 116 | } 117 | 118 | /** 119 | * Return number of errors/events in the queue 120 | * @param context 121 | * @return 122 | */ 123 | int32_t SCPI_ErrorCount(scpi_t * context) { 124 | int16_t result = 0; 125 | 126 | fifo_count(&context->error_queue, &result); 127 | 128 | return result; 129 | } 130 | 131 | static scpi_bool_t SCPI_ErrorAddInternal(scpi_t * context, int16_t err, char * info, size_t info_len) { 132 | scpi_error_t error_value; 133 | char * info_ptr = info ? SCPIDEFINE_strndup(&context->error_info_heap, info, info_len) : NULL; 134 | SCPI_ERROR_SETVAL(&error_value, err, info_ptr); 135 | if (!fifo_add(&context->error_queue, &error_value)) { 136 | SCPIDEFINE_free(&context->error_info_heap, error_value.device_dependent_info, true); 137 | fifo_remove_last(&context->error_queue, &error_value); 138 | SCPIDEFINE_free(&context->error_info_heap, error_value.device_dependent_info, true); 139 | SCPI_ERROR_SETVAL(&error_value, SCPI_ERROR_QUEUE_OVERFLOW, NULL); 140 | fifo_add(&context->error_queue, &error_value); 141 | return FALSE; 142 | } 143 | return TRUE; 144 | } 145 | 146 | struct error_reg { 147 | int16_t from; 148 | int16_t to; 149 | scpi_reg_val_t esrBit; 150 | }; 151 | 152 | #define ERROR_DEFS_N 9 153 | 154 | static const struct error_reg errs[ERROR_DEFS_N] = { 155 | {-100, -199, ESR_CER}, /* Command error (e.g. syntax error) ch 21.8.9 */ 156 | {-200, -299, ESR_EER}, /* Execution Error (e.g. range error) ch 21.8.10 */ 157 | {-300, -399, ESR_DER}, /* Device specific error -300, -399 ch 21.8.11 */ 158 | { 1, 32767, ESR_DER}, /* Device designer provided specific error 1, 32767 ch 21.8.11 */ 159 | {-400, -499, ESR_QER}, /* Query error -400, -499 ch 21.8.12 */ 160 | {-500, -599, ESR_PON}, /* Power on event -500, -599 ch 21.8.13 */ 161 | {-600, -699, ESR_URQ}, /* User Request Event -600, -699 ch 21.8.14 */ 162 | {-700, -799, ESR_REQ}, /* Request Control Event -700, -799 ch 21.8.15 */ 163 | {-800, -899, ESR_OPC}, /* Operation Complete Event -800, -899 ch 21.8.16 */ 164 | }; 165 | 166 | /** 167 | * Push error to queue 168 | * @param context 169 | * @param err - error number 170 | * @param info - additional text information or NULL for no text 171 | * @param info_len - length of text or 0 for automatic length 172 | */ 173 | void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info, size_t info_len) { 174 | int i; 175 | /* automatic calculation of length */ 176 | if (info && info_len == 0) { 177 | info_len = SCPIDEFINE_strnlen(info, SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH); 178 | } 179 | scpi_bool_t queue_overflow = !SCPI_ErrorAddInternal(context, err, info, info_len); 180 | 181 | for (i = 0; i < ERROR_DEFS_N; i++) { 182 | if ((err <= errs[i].from) && (err >= errs[i].to)) { 183 | SCPI_RegSetBits(context, SCPI_REG_ESR, errs[i].esrBit); 184 | } 185 | } 186 | 187 | SCPI_ErrorEmit(context, err); 188 | if (queue_overflow) { 189 | SCPI_ErrorEmit(context, SCPI_ERROR_QUEUE_OVERFLOW); 190 | } 191 | 192 | if (context) { 193 | context->cmd_error = TRUE; 194 | } 195 | } 196 | 197 | /** 198 | * Push error to queue 199 | * @param context - scpi context 200 | * @param err - error number 201 | */ 202 | void SCPI_ErrorPush(scpi_t * context, int16_t err) { 203 | SCPI_ErrorPushEx(context, err, NULL, 0); 204 | return; 205 | } 206 | 207 | /** 208 | * Translate error number to string 209 | * @param err - error number 210 | * @return Error string representation 211 | */ 212 | const char * SCPI_ErrorTranslate(int16_t err) { 213 | switch (err) { 214 | #define X(def, val, str) case def: return str; 215 | #if USE_FULL_ERROR_LIST 216 | #define XE X 217 | #else 218 | #define XE(def, val, str) 219 | #endif 220 | LIST_OF_ERRORS 221 | 222 | #if USE_USER_ERROR_LIST 223 | LIST_OF_USER_ERRORS 224 | #endif 225 | #undef X 226 | #undef XE 227 | default: return "Unknown error"; 228 | } 229 | } 230 | 231 | 232 | -------------------------------------------------------------------------------- /components/libscpi/src/fifo.c: -------------------------------------------------------------------------------- 1 | 2 | #include "fifo_private.h" 3 | 4 | /** 5 | * Initialize fifo 6 | * @param fifo 7 | */ 8 | void fifo_init(scpi_fifo_t * fifo, scpi_error_t * data, int16_t size) { 9 | fifo->wr = 0; 10 | fifo->rd = 0; 11 | fifo->count = 0; 12 | fifo->data = data; 13 | fifo->size = size; 14 | } 15 | 16 | /** 17 | * Empty fifo 18 | * @param fifo 19 | */ 20 | void fifo_clear(scpi_fifo_t * fifo) { 21 | fifo->wr = 0; 22 | fifo->rd = 0; 23 | fifo->count = 0; 24 | } 25 | 26 | /** 27 | * Test if fifo is empty 28 | * @param fifo 29 | * @return 30 | */ 31 | scpi_bool_t fifo_is_empty(scpi_fifo_t * fifo) { 32 | return fifo->count == 0; 33 | } 34 | 35 | /** 36 | * Test if fifo is full 37 | * @param fifo 38 | * @return 39 | */ 40 | scpi_bool_t fifo_is_full(scpi_fifo_t * fifo) { 41 | return fifo->count == fifo->size; 42 | } 43 | 44 | /** 45 | * Add element to fifo. If fifo is full, return FALSE. 46 | * @param fifo 47 | * @param err 48 | * @param info 49 | * @return 50 | */ 51 | scpi_bool_t fifo_add(scpi_fifo_t * fifo, const scpi_error_t * value) { 52 | /* FIFO full? */ 53 | if (fifo_is_full(fifo)) { 54 | return FALSE; 55 | } 56 | if (!value) { 57 | return FALSE; 58 | } 59 | 60 | fifo->data[fifo->wr] = *value; 61 | fifo->wr = (fifo->wr + 1) % (fifo->size); 62 | fifo->count += 1; 63 | return TRUE; 64 | } 65 | 66 | /** 67 | * Remove element form fifo 68 | * @param fifo 69 | * @param value 70 | * @return FALSE - fifo is empty 71 | */ 72 | scpi_bool_t fifo_remove(scpi_fifo_t * fifo, scpi_error_t * value) { 73 | /* FIFO empty? */ 74 | if (fifo_is_empty(fifo)) { 75 | return FALSE; 76 | } 77 | 78 | if (value) { 79 | *value = fifo->data[fifo->rd]; 80 | } 81 | 82 | fifo->rd = (fifo->rd + 1) % (fifo->size); 83 | fifo->count -= 1; 84 | 85 | return TRUE; 86 | } 87 | 88 | /** 89 | * Remove last element from fifo 90 | * @param fifo 91 | * @param value 92 | * @return FALSE - fifo is empty 93 | */ 94 | scpi_bool_t fifo_remove_last(scpi_fifo_t * fifo, scpi_error_t * value) { 95 | /* FIFO empty? */ 96 | if (fifo_is_empty(fifo)) { 97 | return FALSE; 98 | } 99 | 100 | fifo->wr = (fifo->wr + fifo->size - 1) % (fifo->size); 101 | 102 | if (value) { 103 | *value = fifo->data[fifo->wr]; 104 | } 105 | fifo->count -= 1; 106 | 107 | return TRUE; 108 | } 109 | 110 | /** 111 | * Retrive number of elements in fifo 112 | * @param fifo 113 | * @param value 114 | * @return 115 | */ 116 | scpi_bool_t fifo_count(scpi_fifo_t * fifo, int16_t * value) { 117 | *value = fifo->count; 118 | return TRUE; 119 | } 120 | -------------------------------------------------------------------------------- /components/libscpi/src/fifo_private.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file scpi_fifo.h 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief basic FIFO implementation 33 | * 34 | * 35 | */ 36 | 37 | #ifndef SCPI_FIFO_H 38 | #define SCPI_FIFO_H 39 | 40 | #include "scpi/types.h" 41 | #include "utils_private.h" 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | void fifo_init(scpi_fifo_t * fifo, scpi_error_t * data, int16_t size) LOCAL; 48 | void fifo_clear(scpi_fifo_t * fifo) LOCAL; 49 | scpi_bool_t fifo_is_empty(scpi_fifo_t * fifo) LOCAL; 50 | scpi_bool_t fifo_is_full(scpi_fifo_t * fifo) LOCAL; 51 | scpi_bool_t fifo_add(scpi_fifo_t * fifo, const scpi_error_t * value) LOCAL; 52 | scpi_bool_t fifo_remove(scpi_fifo_t * fifo, scpi_error_t * value) LOCAL; 53 | scpi_bool_t fifo_remove_last(scpi_fifo_t * fifo, scpi_error_t * value) LOCAL; 54 | scpi_bool_t fifo_count(scpi_fifo_t * fifo, int16_t * value) LOCAL; 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif /* SCPI_FIFO_H */ 61 | -------------------------------------------------------------------------------- /components/libscpi/src/lexer_private.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file lexer.h 30 | * @date Thu Mar 21 15:00:58 UTC 2013 31 | * 32 | * @brief SCPI Lexer 33 | * 34 | * 35 | */ 36 | 37 | #ifndef SCPI_LEXER_H 38 | #define SCPI_LEXER_H 39 | 40 | #include "scpi/types.h" 41 | #include "utils_private.h" 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | int scpiLex_IsEos(lex_state_t * state) LOCAL; 48 | int scpiLex_WhiteSpace(lex_state_t * state, scpi_token_t * token) LOCAL; 49 | int scpiLex_ProgramHeader(lex_state_t * state, scpi_token_t * token) LOCAL; 50 | int scpiLex_CharacterProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 51 | int scpiLex_DecimalNumericProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 52 | int scpiLex_SuffixProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 53 | int scpiLex_NondecimalNumericData(lex_state_t * state, scpi_token_t * token) LOCAL; 54 | int scpiLex_StringProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 55 | int scpiLex_ArbitraryBlockProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 56 | int scpiLex_ProgramExpression(lex_state_t * state, scpi_token_t * token) LOCAL; 57 | int scpiLex_Comma(lex_state_t * state, scpi_token_t * token) LOCAL; 58 | int scpiLex_Semicolon(lex_state_t * state, scpi_token_t * token) LOCAL; 59 | int scpiLex_Colon(lex_state_t * state, scpi_token_t * token) LOCAL; 60 | int scpiLex_NewLine(lex_state_t * state, scpi_token_t * token) LOCAL; 61 | int scpiLex_SpecificCharacter(lex_state_t * state, scpi_token_t * token, char chr) LOCAL; 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif /* SCPI_LEXER_H */ 68 | 69 | -------------------------------------------------------------------------------- /components/libscpi/src/minimal.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file scpi_minimal.c 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief SCPI minimal implementation 33 | * 34 | * 35 | */ 36 | 37 | 38 | #include "scpi/parser.h" 39 | #include "scpi/minimal.h" 40 | #include "scpi/constants.h" 41 | #include "scpi/error.h" 42 | #include "scpi/ieee488.h" 43 | #include "utils_private.h" 44 | 45 | /** 46 | * Command stub function 47 | * @param context 48 | * @return 49 | */ 50 | scpi_result_t SCPI_Stub(scpi_t * context) { 51 | (void) context; 52 | return SCPI_RES_OK; 53 | } 54 | 55 | /** 56 | * Query command stub function 57 | * @param context 58 | * @return 59 | */ 60 | scpi_result_t SCPI_StubQ(scpi_t * context) { 61 | SCPI_ResultInt32(context, 0); 62 | return SCPI_RES_OK; 63 | } 64 | 65 | /** 66 | * SYSTem:VERSion? 67 | * @param context 68 | * @return 69 | */ 70 | scpi_result_t SCPI_SystemVersionQ(scpi_t * context) { 71 | SCPI_ResultMnemonic(context, SCPI_STD_VERSION_REVISION); 72 | return SCPI_RES_OK; 73 | } 74 | 75 | /** 76 | * SYSTem:ERRor[:NEXT]? 77 | * @param context 78 | * @return 79 | */ 80 | scpi_result_t SCPI_SystemErrorNextQ(scpi_t * context) { 81 | scpi_error_t error; 82 | SCPI_ErrorPop(context, &error); 83 | SCPI_ResultError(context, &error); 84 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION 85 | SCPIDEFINE_free(&context->error_info_heap, error.device_dependent_info, false); 86 | #endif 87 | return SCPI_RES_OK; 88 | } 89 | 90 | /** 91 | * SYSTem:ERRor:COUNt? 92 | * @param context 93 | * @return 94 | */ 95 | scpi_result_t SCPI_SystemErrorCountQ(scpi_t * context) { 96 | SCPI_ResultInt32(context, SCPI_ErrorCount(context)); 97 | 98 | return SCPI_RES_OK; 99 | } 100 | 101 | /** 102 | * STATus:QUEStionable:CONDition? 103 | * @param context 104 | * @return 105 | */ 106 | scpi_result_t SCPI_StatusQuestionableConditionQ(scpi_t * context) { 107 | /* return value */ 108 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_QUESC)); 109 | 110 | return SCPI_RES_OK; 111 | } 112 | 113 | /** 114 | * STATus:QUEStionable[:EVENt]? 115 | * @param context 116 | * @return 117 | */ 118 | scpi_result_t SCPI_StatusQuestionableEventQ(scpi_t * context) { 119 | /* return value */ 120 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_QUES)); 121 | 122 | /* clear register */ 123 | SCPI_RegSet(context, SCPI_REG_QUES, 0); 124 | 125 | return SCPI_RES_OK; 126 | } 127 | 128 | /** 129 | * STATus:QUEStionable:ENABle? 130 | * @param context 131 | * @return 132 | */ 133 | scpi_result_t SCPI_StatusQuestionableEnableQ(scpi_t * context) { 134 | /* return value */ 135 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_QUESE)); 136 | 137 | return SCPI_RES_OK; 138 | } 139 | 140 | /** 141 | * STATus:QUEStionable:ENABle 142 | * @param context 143 | * @return 144 | */ 145 | scpi_result_t SCPI_StatusQuestionableEnable(scpi_t * context) { 146 | int32_t new_QUESE; 147 | if (SCPI_ParamInt32(context, &new_QUESE, TRUE)) { 148 | SCPI_RegSet(context, SCPI_REG_QUESE, (scpi_reg_val_t) new_QUESE); 149 | } 150 | return SCPI_RES_OK; 151 | } 152 | 153 | /** 154 | * STATus:OPERation:CONDition? 155 | * @param context 156 | * @return 157 | */ 158 | scpi_result_t SCPI_StatusOperationConditionQ(scpi_t * context) { 159 | /* return value */ 160 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_OPERC)); 161 | 162 | return SCPI_RES_OK; 163 | } 164 | 165 | /** 166 | * STATus:OPERation[:EVENt]? 167 | * @param context 168 | * @return 169 | */ 170 | scpi_result_t SCPI_StatusOperationEventQ(scpi_t * context) { 171 | /* return value */ 172 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_OPER)); 173 | 174 | /* clear register */ 175 | SCPI_RegSet(context, SCPI_REG_OPER, 0); 176 | 177 | return SCPI_RES_OK; 178 | } 179 | 180 | /** 181 | * STATus:OPERation:ENABle? 182 | * @param context 183 | * @return 184 | */ 185 | scpi_result_t SCPI_StatusOperationEnableQ(scpi_t * context) { 186 | /* return value */ 187 | SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_OPERE)); 188 | 189 | return SCPI_RES_OK; 190 | } 191 | 192 | /** 193 | * STATus:OPERation:ENABle 194 | * @param context 195 | * @return 196 | */ 197 | scpi_result_t SCPI_StatusOperationEnable(scpi_t * context) { 198 | int32_t new_OPERE; 199 | if (SCPI_ParamInt32(context, &new_OPERE, TRUE)) { 200 | SCPI_RegSet(context, SCPI_REG_OPERE, (scpi_reg_val_t) new_OPERE); 201 | } 202 | return SCPI_RES_OK; 203 | } 204 | 205 | /** 206 | * STATus:PRESet 207 | * @param context 208 | * @return 209 | */ 210 | scpi_result_t SCPI_StatusPreset(scpi_t * context) { 211 | /* clear STATUS:... */ 212 | SCPI_RegSet(context, SCPI_REG_QUES, 0); 213 | return SCPI_RES_OK; 214 | } 215 | -------------------------------------------------------------------------------- /components/libscpi/src/parser_private.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file parser_private.h 30 | * 31 | * @brief SCPI Parser private definitions 32 | * 33 | * 34 | */ 35 | 36 | #ifndef SCPI_PARSER_PRIVATE_H 37 | #define SCPI_PARSER_PRIVATE_H 38 | 39 | #include "scpi/types.h" 40 | #include "utils_private.h" 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | int scpiParser_parseProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; 47 | int scpiParser_parseAllProgramData(lex_state_t * state, scpi_token_t * token, int * numberOfParameters) LOCAL; 48 | int scpiParser_detectProgramMessageUnit(scpi_parser_state_t * state, char * buffer, int len) LOCAL; 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif /* SCPI_PARSER_PRIVATE_H */ 55 | 56 | -------------------------------------------------------------------------------- /components/libscpi/src/scpi.g: -------------------------------------------------------------------------------- 1 | grammar scpi; 2 | 3 | terminatedProgramMessage 4 | : programMessage NL? EOF 5 | ; 6 | 7 | programMessage 8 | : programMessageUnit (SEMICOLON programMessageUnit)* 9 | ; 10 | 11 | 12 | programMessageUnit 13 | : WS* programHeader (WS programData (COMMA programData)*)? 14 | ; 15 | 16 | programHeader 17 | : compoundProgramHeader 18 | | commonProgramHeader 19 | ; 20 | 21 | compoundProgramHeader 22 | : COLON? PROGRAM_MNEMONIC (COLON PROGRAM_MNEMONIC)* QUESTION? 23 | ; 24 | 25 | commonProgramHeader 26 | : STAR PROGRAM_MNEMONIC QUESTION? 27 | ; 28 | 29 | programDataSeparator 30 | : WS* 31 | ; 32 | 33 | programData 34 | : WS* programDataType WS* 35 | ; 36 | 37 | programDataType 38 | : nondecimalNumericProgramData 39 | | characterProgramData 40 | | decimalNumericProgramData 41 | | stringProgramData 42 | | arbitraryBlockProgramData 43 | | expressionProgramData 44 | // | suffixProgramData 45 | ; 46 | 47 | nondecimalNumericProgramData 48 | : HEXNUM 49 | | OCTNUM 50 | | BINNUM 51 | ; 52 | 53 | characterProgramData 54 | : PROGRAM_MNEMONIC 55 | ; 56 | 57 | decimalNumericProgramData 58 | : DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX 59 | ; 60 | 61 | //suffixProgramData 62 | // : PROGRAM_MNEMONIC//SUFFIX_PROGRAM_DATA 63 | // ; 64 | 65 | stringProgramData 66 | : SINGLE_QUOTE_PROGRAM_DATA 67 | | DOUBLE_QUOTE_PROGRAM_DATA 68 | ; 69 | 70 | expressionProgramData 71 | : PROGRAM_EXPRESSION 72 | ; 73 | 74 | // support only nonzero prefix 75 | arbitraryBlockProgramData 76 | : SHARP NONZERO_DIGIT NUMBER .* 77 | ; 78 | 79 | PROGRAM_MNEMONIC : ALPHA (ALPHA | DIGIT | UNDERSCORE)*; 80 | HEXNUM : SHARP H HEXDIGIT*; 81 | BINNUM : SHARP Q OCTDIGIT*; 82 | OCTNUM : SHARP B BINDIGIT*; 83 | UNDERSCORE : '_'; 84 | SEMICOLON : ';'; 85 | QUESTION : '?'; 86 | COLON : ':'; 87 | COMMA : ','; 88 | STAR : '*'; 89 | NL : '\r'? '\n' ; 90 | WS : (SPACE | TAB); 91 | 92 | DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX : DECIMAL_NUMERIC_PROGRAM_DATA WS* (SUFFIX_PROGRAM_DATA)?; 93 | fragment DECIMAL_NUMERIC_PROGRAM_DATA : MANTISA WS* (EXPONENT)?; 94 | SINGLE_QUOTE_PROGRAM_DATA : SINGLE_QUOTE ( (NON_SINGLE_QUOTE) | (SINGLE_QUOTE SINGLE_QUOTE))* SINGLE_QUOTE; 95 | DOUBLE_QUOTE_PROGRAM_DATA : DOUBLE_QUOTE ( (NON_DOUBLE_QUOTE) | (DOUBLE_QUOTE DOUBLE_QUOTE))* DOUBLE_QUOTE; 96 | //SUFFIX_PROGRAM_DATA : SLASH? (ALPHA+ (MINUS? DIGIT)?) ((SLASH | DOT) (ALPHA+ (MINUS? DIGIT)?))*; 97 | fragment SUFFIX_PROGRAM_DATA : SLASH? ALPHA+ ((SLASH | DOT) ALPHA+)*; 98 | //fragment SUFFIX_PROGRAM_DATA : ALPHA+; 99 | 100 | fragment PROGRAM_EXPRESSION_CHARACTER : (SPACE | '!' | '$'..'&' | '*'..':' | '<' ..'~'); 101 | PROGRAM_EXPRESSION : LBRACKET PROGRAM_EXPRESSION_CHARACTER RBRACKET; 102 | 103 | fragment PLUSMN : (PLUS | MINUS); 104 | fragment MANTISA : PLUSMN? ( (NUMBER) | (NUMBER DOT NUMBER?) | (DOT NUMBER)); 105 | 106 | //fragment EXPONENT : WS* E WS* PLUSMN? NUMBER; 107 | fragment EXPONENT : E WS* PLUSMN? NUMBER; 108 | 109 | fragment NUMBER : DIGIT+; 110 | 111 | fragment LBRACKET : '('; 112 | fragment RBRACKET : ')'; 113 | 114 | fragment ALPHA : ('a'..'z'|'A'..'Z'); 115 | fragment DIGIT : ('0'..'9'); 116 | fragment NONZERO_DIGIT : ('1'..'9'); 117 | 118 | fragment HEXDIGIT : (DIGIT | 'a'..'f' | 'A'..'F'); 119 | fragment OCTDIGIT : ('0'..'7'); 120 | fragment BINDIGIT : ('0' | '1'); 121 | 122 | fragment SHARP : '#'; 123 | 124 | fragment E : ('E'|'e'); 125 | fragment H : ('H'|'h'); 126 | fragment Q : ('Q'|'q'); 127 | fragment B : ('B'|'b'); 128 | 129 | fragment SPACE : ' '; 130 | fragment TAB : '\t'; 131 | 132 | fragment PLUS : '+'; 133 | fragment MINUS : '-'; 134 | fragment DOT : '.'; 135 | fragment SLASH : '/'; 136 | fragment SINGLE_QUOTE : '\''; 137 | fragment DOUBLE_QUOTE : '"'; 138 | fragment NON_SINGLE_QUOTE : ~SINGLE_QUOTE; 139 | fragment NON_DOUBLE_QUOTE : ~DOUBLE_QUOTE; 140 | 141 | 142 | -------------------------------------------------------------------------------- /components/libscpi/src/utils_private.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file scpi_utils.h 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief Conversion routines and string manipulation routines 33 | * 34 | * 35 | */ 36 | 37 | #ifndef SCPI_UTILS_PRIVATE_H 38 | #define SCPI_UTILS_PRIVATE_H 39 | 40 | #include 41 | #include "scpi/config.h" 42 | #include "scpi/types.h" 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | #if defined(__GNUC__) && (__GNUC__ >= 4) 49 | #define LOCAL __attribute__((visibility ("hidden"))) 50 | #else 51 | #define LOCAL 52 | #endif 53 | 54 | char * strnpbrk(const char *str, size_t size, const char *set) LOCAL; 55 | scpi_bool_t compareStr(const char * str1, size_t len1, const char * str2, size_t len2) LOCAL; 56 | scpi_bool_t compareStrAndNum(const char * str1, size_t len1, const char * str2, size_t len2, int32_t * num) LOCAL; 57 | size_t UInt32ToStrBaseSign(uint32_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) LOCAL; 58 | size_t UInt64ToStrBaseSign(uint64_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) LOCAL; 59 | size_t strBaseToInt32(const char * str, int32_t * val, int8_t base) LOCAL; 60 | size_t strBaseToUInt32(const char * str, uint32_t * val, int8_t base) LOCAL; 61 | size_t strBaseToInt64(const char * str, int64_t * val, int8_t base) LOCAL; 62 | size_t strBaseToUInt64(const char * str, uint64_t * val, int8_t base) LOCAL; 63 | size_t strToFloat(const char * str, float * val) LOCAL; 64 | size_t strToDouble(const char * str, double * val) LOCAL; 65 | scpi_bool_t locateText(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; 66 | scpi_bool_t locateStr(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; 67 | size_t skipWhitespace(const char * cmd, size_t len) LOCAL; 68 | scpi_bool_t matchPattern(const char * pattern, size_t pattern_len, const char * str, size_t str_len, int32_t * num) LOCAL; 69 | scpi_bool_t matchCommand(const char * pattern, const char * cmd, size_t len, int32_t *numbers, size_t numbers_len, int32_t default_value) LOCAL; 70 | scpi_bool_t composeCompoundCommand(const scpi_token_t * prev, scpi_token_t * current) LOCAL; 71 | 72 | #define SCPI_DTOSTRE_UPPERCASE 1 73 | #define SCPI_DTOSTRE_ALWAYS_SIGN 2 74 | #define SCPI_DTOSTRE_PLUS_SIGN 4 75 | char * SCPI_dtostre(double __val, char * __s, size_t __ssize, unsigned char __prec, unsigned char __flags); 76 | 77 | scpi_array_format_t SCPI_GetNativeFormat(void); 78 | uint16_t SCPI_Swap16(uint16_t val); 79 | uint32_t SCPI_Swap32(uint32_t val); 80 | uint64_t SCPI_Swap64(uint64_t val); 81 | 82 | #if !HAVE_STRNLEN 83 | size_t BSD_strnlen(const char *s, size_t maxlen) LOCAL; 84 | #endif 85 | 86 | #if !HAVE_STRNCASECMP && !HAVE_STRNICMP 87 | int OUR_strncasecmp(const char *s1, const char *s2, size_t n) LOCAL; 88 | #endif 89 | 90 | #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE 91 | void scpiheap_init(scpi_error_info_heap_t * heap, char * error_info_heap, size_t error_info_heap_length); 92 | char * scpiheap_strndup(scpi_error_info_heap_t * heap, const char *s, size_t n) LOCAL; 93 | void scpiheap_free(scpi_error_info_heap_t * heap, char *s, scpi_bool_t rollback) LOCAL; 94 | scpi_bool_t scpiheap_get_parts(scpi_error_info_heap_t * heap, const char *s1, size_t * len1, const char ** s2, size_t * len2) LOCAL; 95 | #endif 96 | 97 | #if !HAVE_STRNDUP 98 | char *OUR_strndup(const char *s, size_t n); 99 | #endif 100 | 101 | #ifndef min 102 | #define min(a, b) (((a) < (b)) ? (a) : (b)) 103 | #endif 104 | 105 | #ifndef max 106 | #define max(a, b) (((a) > (b)) ? (a) : (b)) 107 | #endif 108 | 109 | #if 0 110 | #define max(a,b) \ 111 | ({ __typeof__ (a) _a = (a); \ 112 | __typeof__ (b) _b = (b); \ 113 | _a > _b ? _a : _b; }) 114 | 115 | #define min(a,b) \ 116 | ({ __typeof__ (a) _a = (a); \ 117 | __typeof__ (b) _b = (b); \ 118 | _a < _b ? _a : _b; }) 119 | 120 | #endif 121 | 122 | #ifdef __cplusplus 123 | } 124 | #endif 125 | 126 | #endif /* SCPI_UTILS_PRIVATE_H */ 127 | 128 | -------------------------------------------------------------------------------- /components/pi2s/i2s_parallel.h: -------------------------------------------------------------------------------- 1 | #ifndef I2S_PARALLEL_H 2 | #define I2S_PARALLEL_H 3 | 4 | #include 5 | #include "soc/i2s_struct.h" 6 | 7 | typedef enum { 8 | I2S_PARALLEL_BITS_8=8, 9 | I2S_PARALLEL_BITS_16=16, 10 | I2S_PARALLEL_BITS_32=32, 11 | } i2s_parallel_cfg_bits_t; 12 | 13 | typedef struct { 14 | void *memory; 15 | size_t size; 16 | } i2s_parallel_buffer_desc_t; 17 | 18 | typedef struct { 19 | int gpio_bus[24]; 20 | int gpio_clk; 21 | int clkspeed_hz; 22 | i2s_parallel_cfg_bits_t bits; 23 | i2s_parallel_buffer_desc_t *bufa; 24 | i2s_parallel_buffer_desc_t *bufb; 25 | } i2s_parallel_config_t; 26 | 27 | void i2s_parallel_setup(i2s_dev_t *dev, const i2s_parallel_config_t *cfg); 28 | void i2s_parallel_flip_to_buffer(i2s_dev_t *dev, int bufid); 29 | 30 | void i2s_parallel_start(i2s_dev_t *dev); 31 | void i2s_parallel_stop(i2s_dev_t *dev); 32 | 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /linux/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROG = test 3 | 4 | SRCS = main.c ../main/scpi-def.c sampling.c 5 | CFLAGS += -g -std=c99 -Wextra -Wmissing-prototypes -Wimplicit -I ../components/libscpi/inc/ 6 | LDFLAGS += -lm ../components/libscpi/dist/libscpi.a -Wl,--as-needed 7 | 8 | .PHONY: clean all 9 | 10 | all: $(PROG) 11 | 12 | OBJS = $(SRCS:.c=.o) 13 | 14 | .c.o: 15 | $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< 16 | 17 | $(PROG): $(OBJS) 18 | $(CC) -o $@ $(OBJS) $(CFLAGS) $(LDFLAGS) 19 | 20 | clean: 21 | $(RM) $(PROG) $(OBJS) 22 | -------------------------------------------------------------------------------- /linux/main.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file main.c 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief TCP/IP SCPI Server 33 | * 34 | * 35 | */ 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #include "scpi/scpi.h" 50 | #include "../main/scpi-def.h" 51 | 52 | 53 | /* a global output buffer to collect output data until it will be 'flushed' */ 54 | #define SCPI_OUPUT_BUFFER_SIZE (14012) 55 | char SCPI_outputBuffer[SCPI_OUPUT_BUFFER_SIZE]; 56 | unsigned int SCPI_outputBuffer_idx = 0; 57 | 58 | 59 | 60 | size_t SCPI_Write(scpi_t * context, const char * data, size_t len) { 61 | 62 | if ((SCPI_outputBuffer_idx + len) > (SCPI_OUPUT_BUFFER_SIZE - 1)) { 63 | len = (SCPI_OUPUT_BUFFER_SIZE - 1) - SCPI_outputBuffer_idx; /* limit length to left over space */ 64 | /* apparently there is no mechanism to cope with buffers that are too small */ 65 | } 66 | memcpy(&SCPI_outputBuffer[SCPI_outputBuffer_idx], data, len); 67 | SCPI_outputBuffer_idx += len; 68 | 69 | SCPI_outputBuffer[SCPI_outputBuffer_idx] = '\0'; 70 | /* return fwrite(data, 1, len, stdout); */ 71 | return len; 72 | /* 73 | (void) context; 74 | 75 | if (context->user_context != NULL) { 76 | int fd = *(int *) (context->user_context); 77 | return write(fd, data, len); 78 | } 79 | */ 80 | return 0; 81 | } 82 | 83 | scpi_result_t SCPI_Flush(scpi_t * context) { 84 | //(void) context; 85 | if (context->user_context != NULL) { 86 | int fd = *(int *) (context->user_context); 87 | //SCPI_outputBuffer[SCPI_outputBuffer_idx] = 0x0; 88 | //SCPI_outputBuffer_idx++; 89 | 90 | // Hmmm??? ACHTUNG 91 | //SCPI_outputBuffer[SCPI_outputBuffer_idx] = 0x0a; 92 | //SCPI_outputBuffer_idx++; 93 | 94 | int tmp=SCPI_outputBuffer_idx; 95 | SCPI_outputBuffer_idx=0; 96 | return write(fd, SCPI_outputBuffer, tmp); 97 | } 98 | 99 | return SCPI_RES_OK; 100 | } 101 | 102 | int SCPI_Error(scpi_t * context, int_fast16_t err) { 103 | (void) context; 104 | /* BEEP */ 105 | fprintf(stderr, "**ERROR: %d, \"%s\"\r\n", (int16_t) err, SCPI_ErrorTranslate(err)); 106 | return 0; 107 | } 108 | 109 | scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { 110 | (void) context; 111 | 112 | if (SCPI_CTRL_SRQ == ctrl) { 113 | fprintf(stderr, "**SRQ: 0x%X (%d)\r\n", val, val); 114 | } else { 115 | fprintf(stderr, "**CTRL %02x: 0x%X (%d)\r\n", ctrl, val, val); 116 | } 117 | return SCPI_RES_OK; 118 | } 119 | 120 | scpi_result_t SCPI_Reset(scpi_t * context) { 121 | (void) context; 122 | 123 | fprintf(stderr, "**Reset\r\n"); 124 | return SCPI_RES_OK; 125 | } 126 | 127 | scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context) { 128 | (void) context; 129 | 130 | return SCPI_RES_ERR; 131 | } 132 | 133 | static int createServer(int port) { 134 | int fd; 135 | int rc; 136 | int on = 1; 137 | struct sockaddr_in servaddr; 138 | 139 | /* Configure TCP Server */ 140 | memset(&servaddr, 0, sizeof (servaddr)); 141 | servaddr.sin_family = AF_INET; 142 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 143 | servaddr.sin_port = htons(port); 144 | 145 | /* Create socket */ 146 | fd = socket(AF_INET, SOCK_STREAM, 0); 147 | if (fd < 0) { 148 | perror("socket() failed"); 149 | exit(-1); 150 | } 151 | 152 | /* Set address reuse enable */ 153 | rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)); 154 | if (rc < 0) { 155 | perror("setsockopt() failed"); 156 | close(fd); 157 | exit(-1); 158 | } 159 | 160 | /* Set non blocking */ 161 | rc = ioctl(fd, FIONBIO, (char *) &on); 162 | if (rc < 0) { 163 | perror("ioctl() failed"); 164 | close(fd); 165 | exit(-1); 166 | } 167 | 168 | /* Bind to socket */ 169 | rc = bind(fd, (struct sockaddr *) &servaddr, sizeof (servaddr)); 170 | if (rc < 0) { 171 | perror("bind() failed"); 172 | close(fd); 173 | exit(-1); 174 | } 175 | 176 | /* Listen on socket */ 177 | listen(fd, 1); 178 | if (rc < 0) { 179 | perror("listen() failed"); 180 | close(fd); 181 | exit(-1); 182 | } 183 | 184 | return fd; 185 | } 186 | 187 | static int waitServer(int fd) { 188 | fd_set fds; 189 | struct timeval timeout; 190 | int rc; 191 | int max_fd; 192 | 193 | FD_ZERO(&fds); 194 | max_fd = fd; 195 | FD_SET(fd, &fds); 196 | 197 | timeout.tv_sec = 5; 198 | timeout.tv_usec = 0; 199 | 200 | rc = select(max_fd + 1, &fds, NULL, NULL, &timeout); 201 | 202 | return rc; 203 | } 204 | 205 | /* 206 | * 207 | */ 208 | int main(int argc, char** argv) { 209 | (void) argc; 210 | (void) argv; 211 | int rc; 212 | 213 | int listenfd; 214 | char smbuffer[1024]; 215 | 216 | /* user_context will be pointer to socket */ 217 | scpi_context.user_context = NULL; 218 | 219 | SCPI_Init(&scpi_context, 220 | scpi_commands, 221 | &scpi_interface, 222 | scpi_units_def, 223 | SCPI_IDN1, SCPI_IDN2, SCPI_IDN3, SCPI_IDN4, 224 | scpi_input_buffer, SCPI_INPUT_BUFFER_LENGTH, 225 | scpi_error_queue_data, SCPI_ERROR_QUEUE_SIZE); 226 | 227 | listenfd = createServer(5555); 228 | 229 | while (1) { 230 | int clifd; 231 | struct sockaddr_in cliaddr; 232 | socklen_t clilen; 233 | 234 | clilen = sizeof (cliaddr); 235 | clifd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen); 236 | 237 | if (clifd < 0) continue; 238 | 239 | printf("Connection established %s\r\n", inet_ntoa(cliaddr.sin_addr)); 240 | 241 | scpi_context.user_context = &clifd; 242 | 243 | while (1) { 244 | rc = waitServer(clifd); 245 | if (rc < 0) { /* failed */ 246 | perror(" recv() failed"); 247 | break; 248 | } 249 | if (rc == 0) { /* timeout */ 250 | SCPI_Input(&scpi_context, NULL, 0); 251 | } 252 | if (rc > 0) { /* something to read */ 253 | rc = recv(clifd, smbuffer, sizeof (smbuffer), 0); 254 | if (rc < 0) { 255 | if (errno != EWOULDBLOCK) { 256 | perror(" recv() failed"); 257 | break; 258 | } 259 | } else if (rc == 0) { 260 | printf("Connection closed\r\n"); 261 | break; 262 | } else { 263 | SCPI_Input(&scpi_context, smbuffer, rc); 264 | /* To dump inpput */ 265 | smbuffer[rc]=0; 266 | printf("%s",smbuffer); 267 | } 268 | } 269 | } 270 | 271 | close(clifd); 272 | } 273 | 274 | return (EXIT_SUCCESS); 275 | } 276 | 277 | -------------------------------------------------------------------------------- /linux/sampling.c: -------------------------------------------------------------------------------- 1 | // This works as a proxy, receiving udp packets from 2 | #include 3 | #include 4 | int trig_pin; 5 | 6 | #define NUM_SAMPLES 1024*1024 7 | 8 | static int maxSamples=NUM_SAMPLES; 9 | 10 | void set_mem_depth(int depth) { 11 | if (depth 5 | #include 6 | #include 7 | 8 | #include "freertos/FreeRTOS.h" 9 | #include "freertos/task.h" 10 | #include "freertos/event_groups.h" 11 | #include "esp_event_loop.h" 12 | #include 13 | #include 14 | 15 | #include "ota_server.h" 16 | 17 | #define FIRMWARE_REV " Rev: 0.1" 18 | 19 | 20 | void KillAllThreads(void); 21 | 22 | 23 | -------------------------------------------------------------------------------- /main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "Wifi and TFT Configuration" 2 | 3 | config WIFI_SSID 4 | string "WiFi SSID" 5 | default "myssid" 6 | help 7 | SSID (network name) for the example to connect to. 8 | 9 | config WIFI_PASSWORD 10 | string "WiFi Password" 11 | default "mypassword" 12 | help 13 | WiFi password (WPA or WPA2) for the example to use. 14 | 15 | config EXAMPLE_USE_TFT 16 | bool "Use TFT display after analouge aquisition" 17 | default n 18 | help 19 | The analouge data will be displayed on TFT when pressing the boot button 20 | 21 | 22 | config EXAMPLE_DISPLAY_TYPE 23 | int 24 | default 0 if EXAMPLE_DISPLAY_TYPE0 25 | default 1 if EXAMPLE_DISPLAY_TYPE1 26 | default 2 if EXAMPLE_DISPLAY_TYPE2 27 | default 3 if EXAMPLE_DISPLAY_TYPE3 28 | 29 | choice 30 | prompt "Select predefined display configuration" 31 | default EXAMPLE_DISPLAY_TYPE0 32 | help 33 | Select predefined display configuration 34 | 35 | config EXAMPLE_DISPLAY_TYPE0 36 | bool "None" 37 | config EXAMPLE_DISPLAY_TYPE1 38 | bool "ESP-WROVER-KIT Display" 39 | config EXAMPLE_DISPLAY_TYPE2 40 | bool "Adafruit TFT Feather display" 41 | config EXAMPLE_DISPLAY_TYPE3 42 | bool "M5Stack TFT display" 43 | endchoice 44 | 45 | endmenu 46 | -------------------------------------------------------------------------------- /main/analog.h: -------------------------------------------------------------------------------- 1 | #ifndef __ESP32_ANALOG 2 | #define __ESP32_ANALOG 3 | 4 | #include "freertos/FreeRTOS.h" 5 | #include "freertos/task.h" 6 | 7 | #define SAMPLING_DONE_BIT 1 8 | 9 | #define NUM_SAMPLES 2048 10 | //14000 11 | 12 | typedef enum TrigState { 13 | Triggered, 14 | Auto, 15 | Running, 16 | Waiting, 17 | Stopped 18 | } TrigState_t; 19 | 20 | TrigState_t get_trig_state(); 21 | 22 | typedef enum TrigType { 23 | Pos, 24 | Neg, 25 | RiseFall, 26 | Invalid 27 | } TrigType_t; 28 | 29 | void setAnalogTrig(TrigType_t trig_type); 30 | 31 | uint8_t* get_values(); 32 | 33 | uint16_t* get_digital_values(); 34 | 35 | int* get_sample_values(); 36 | 37 | 38 | // Param is task handle of task to notify 39 | void sample_thread(void *param); 40 | 41 | void setTimescale(float scale); 42 | 43 | void start_sampling(bool single); 44 | 45 | bool samples_finnished(); 46 | 47 | 48 | extern TaskHandle_t xHandlingTask; 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /main/app-config.h: -------------------------------------------------------------------------------- 1 | /// CHANGE CONFIGURATION HERE!! 2 | #undef CONFIG_EXAMPLE_USE_TFT 3 | #undef SUMP_OVER_UART 4 | #undef SUMP_OVER_UART 5 | #define SCPI_ON_NETWORK 1 6 | //#define SUMP_ON_NETWORK 1 7 | #undef DEBUG_SUMP 8 | //#define DEBUG_LOG_ENABLE 1 9 | //#define OTA_RUN_SERVER 1 10 | 11 | // First pin for parallell input 13-29, note that some pins are ot used, (20,24,28,29) 12 | #define PARALLEL_0 13 13 | 14 | #define UART_TEST_OUTPUT 1 15 | #define UART_OUTPUT_PIN 17 16 | #define UART_RX_PIN 19 17 | 18 | // This might be used for sampling with DMA 19 | //#define USE_CAMERA_IF 1 20 | #define PIXEL_LEDC_PIN 22 21 | 22 | #define PULSE_PIN 15 23 | //#define RMT_PULSES 1 24 | 25 | 26 | 27 | #undef RUN_IN_QEMU 28 | 29 | -------------------------------------------------------------------------------- /main/collector.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "soc/i2s_struct.h" 4 | #include "config.h" 5 | #include "rom/lldesc.h" 6 | #include "soc/i2s_struct.h" 7 | #include "soc/i2s_reg.h" 8 | #include "driver/periph_ctrl.h" 9 | #include "soc/io_mux_reg.h" 10 | #include "esp_heap_caps.h" 11 | #include "esp_system.h" 12 | #include "esp_task_wdt.h" 13 | #include "driver/ledc.h" 14 | 15 | 16 | #define CAPTURE_SIZE 14000 17 | 18 | #define ledPin 27 //Led on while running and Blinks while transfering data. 19 | 20 | 21 | typedef enum { 22 | I2S_PARALLEL_BITS_8 = 8, 23 | I2S_PARALLEL_BITS_16 = 16, 24 | I2S_PARALLEL_BITS_32 = 32, 25 | } i2s_parallel_cfg_bits_t; 26 | 27 | typedef struct { 28 | //void* memory; 29 | size_t size; 30 | } i2s_parallel_buffer_desc_t; 31 | 32 | typedef struct { 33 | int gpio_bus[24]; 34 | int gpio_clk; 35 | int clkspeed_hz; 36 | i2s_parallel_cfg_bits_t bits; 37 | i2s_parallel_buffer_desc_t* buf; 38 | } i2s_parallel_config_t; 39 | 40 | typedef struct { 41 | volatile lldesc_t* dmadesc; 42 | int desccount; 43 | } i2s_parallel_state_t; 44 | 45 | void i2s_conf_reset(); 46 | 47 | void enable_out_clock( int freq_in_hz ); 48 | 49 | void start_dma_capture(void); 50 | 51 | 52 | #define DMA_MAX (4096-4) 53 | 54 | 55 | 56 | //Calculate the amount of dma descs needed for a buffer desc 57 | static int calc_needed_dma_descs_for(i2s_parallel_buffer_desc_t *desc) { 58 | int ret = (desc->size + DMA_MAX - 1) / DMA_MAX; 59 | return ret; 60 | } 61 | 62 | typedef union { 63 | struct { 64 | uint8_t sample2; 65 | uint8_t unused2; 66 | uint8_t sample1; 67 | uint8_t unused1; 68 | }; 69 | struct{ 70 | uint16_t val2; 71 | uint16_t val1; 72 | }; 73 | uint32_t val; 74 | } dma_elem_t; 75 | 76 | typedef enum { 77 | /* camera sends byte sequence: s1, s2, s3, s4, ... 78 | * fifo receives: 00 s1 00 s2, 00 s2 00 s3, 00 s3 00 s4, ... 79 | */ 80 | SM_0A0B_0B0C = 0, 81 | /* camera sends byte sequence: s1, s2, s3, s4, ... 82 | * fifo receives: 00 s1 00 s2, 00 s3 00 s4, ... 83 | */ 84 | SM_0A0B_0C0D = 1, 85 | /* camera sends byte sequence: s1, s2, s3, s4, ... 86 | * fifo receives: 00 s1 00 00, 00 s2 00 00, 00 s3 00 00, ... 87 | */ 88 | SM_0A00_0B00 = 3, 89 | } i2s_sampling_mode_t; 90 | 91 | typedef struct { 92 | lldesc_t *dma_desc; 93 | dma_elem_t **dma_buf; 94 | bool dma_done; 95 | size_t dma_desc_count; 96 | size_t dma_desc_cur; 97 | int dma_desc_triggered; 98 | size_t dma_received_count; 99 | size_t dma_filtered_count; 100 | size_t dma_buf_width; 101 | size_t dma_sample_count; 102 | size_t dma_val_per_desc; 103 | size_t dma_sample_per_desc; 104 | i2s_sampling_mode_t sampling_mode; 105 | // dma_filter_t dma_filter; 106 | intr_handle_t i2s_intr_handle; 107 | // QueueHandle_t data_ready; 108 | // SemaphoreHandle_t frame_ready; 109 | // TaskHandle_t dma_filter_task; 110 | } camera_state_t; 111 | 112 | 113 | void i2s_parallel_setup( const i2s_parallel_config_t *cfg); 114 | 115 | 116 | #define CHANPIN GPIO.in 117 | 118 | uint8_t channels_to_read=3; 119 | 120 | /* extended commands -- self-test unsupported, but metadata is returned. */ 121 | #define SUMP_SELF_TEST 0x03 122 | #define SUMP_GET_METADATA 0x04 123 | 124 | #define MAX_CAPTURE_SIZE CAPTURE_SIZE 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /main/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # "main" pseudo-component makefile. 3 | # 4 | # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) 5 | -------------------------------------------------------------------------------- /main/draw_osc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "freertos/FreeRTOS.h" 8 | #include "freertos/task.h" 9 | #include "esp_system.h" 10 | #include "driver/gpio.h" 11 | #include "esp_system.h" 12 | #include "esp_heap_caps.h" 13 | 14 | #if CONFIG_EXAMPLE_USE_TFT 15 | 16 | 17 | #include "tftspi.h" 18 | #include "tft.h" 19 | #include "analog.h" 20 | 21 | 22 | const int LCD_WIDTH = 320; 23 | const int LCD_HEIGHT = 240; 24 | const int DOTS_DIV = 30; 25 | 26 | 27 | 28 | #define CH1COLOR TFT_YELLOW 29 | #define CH2COLOR TFT_CYAN 30 | #define SAMPLES 320 31 | 32 | short data[SAMPLES]; 33 | short old_data[SAMPLES]; 34 | 35 | short slow_data[SAMPLES]; 36 | short old_slow_data[SAMPLES]; 37 | 38 | 39 | // NUM_SAMPLES 2048 40 | 41 | void DrawGrid() 42 | { 43 | for (int x = 0; x <= SAMPLES; x += 2) // Horizontal Line 44 | { 45 | for (int y = 0; y <= LCD_HEIGHT; y += DOTS_DIV) 46 | { 47 | TFT_drawPixel(x, y, TFT_DARKGREY,0); 48 | } 49 | if (LCD_HEIGHT == 240) 50 | { 51 | TFT_drawPixel(x, LCD_HEIGHT - 1, TFT_DARKGREY,0); 52 | } 53 | } 54 | for (int x = 0; x <= SAMPLES; x += DOTS_DIV) // Vertical Line 55 | { 56 | for (int y = 0; y <= LCD_HEIGHT; y += 2) 57 | { 58 | TFT_drawPixel(x, y, TFT_LIGHTGREY,0); 59 | } 60 | } 61 | } 62 | 63 | #if 0 64 | void DrawGrid(int x) 65 | { 66 | if ((x % 2) == 0) 67 | { 68 | for (int y = 0; y <= LCD_HEIGHT; y += DOTS_DIV) 69 | { 70 | TFT_drawPixel(x, y, GREY,1); 71 | } 72 | } 73 | if ((x % DOTS_DIV) == 0) 74 | { 75 | for (int y = 0; y <= LCD_HEIGHT; y += 2) 76 | { 77 | TFT_drawPixel(x, y, GREY,1); 78 | } 79 | } 80 | } 81 | #endif 82 | 83 | void DrawSlowGraph() 84 | { 85 | DrawGrid(); 86 | 87 | for (int x = 0; x < (SAMPLES - 1); x++) 88 | { 89 | TFT_drawLine(x, LCD_HEIGHT/2 - old_slow_data[x], x + 1, 1+LCD_HEIGHT/2 - old_slow_data[x + 1], TFT_BLACK); 90 | TFT_drawLine(x, LCD_HEIGHT/2 - slow_data[x], x + 1, 1+LCD_HEIGHT/2 - slow_data[x + 1], TFT_GREEN); 91 | } 92 | } 93 | 94 | 95 | void DrawGraph() 96 | { 97 | DrawGrid(); 98 | 99 | for (int x = 0; x < (SAMPLES - 1); x++) 100 | { 101 | TFT_drawLine(x, LCD_HEIGHT/2 - old_data[x], x + 1, 1+LCD_HEIGHT/2 - old_data[x + 1], TFT_BLACK); 102 | TFT_drawLine(x, LCD_HEIGHT/2 - data[x], x + 1, 1+LCD_HEIGHT/2 - data[x + 1], TFT_WHITE); 103 | } 104 | } 105 | 106 | 107 | void drawSampleData(int* in_data,int num_samples) { 108 | 109 | for (int x = 0; x < SAMPLES ; x++) { 110 | data[x]=(short) -50 + in_data[x]/8; 111 | } 112 | DrawGraph(); 113 | for (int x = 0; x < SAMPLES ; x++) { 114 | old_data[x]=data[x]; 115 | } 116 | 117 | int skip=SAMPLES; 118 | 119 | for (int x = 0; x < SAMPLES && skip < num_samples; x++) { 120 | int tmp= -120 + (in_data[skip]/4+in_data[skip+1]/4+in_data[skip+2]/4+in_data[skip+3]/4)/8; 121 | slow_data[x]=(short) tmp; 122 | skip+=4; 123 | } 124 | DrawSlowGraph(); 125 | for (int x = 0; x < SAMPLES ; x++) { 126 | old_slow_data[x]=slow_data[x]; 127 | } 128 | 129 | 130 | 131 | } 132 | 133 | 134 | 135 | #endif -------------------------------------------------------------------------------- /main/esp32_sump.h: -------------------------------------------------------------------------------- 1 | #ifndef __ESP32_SUMP 2 | #define __ESP32_SUMP 3 | 4 | /* 5 | * HydraBus/HydraNFC 6 | * ESP32 sigrok 7 | * 8 | * Copyright (C) 2015 Nicolas OBERLI 9 | * 2017 Olof Astrand 10 | * 11 | * Licensed under the Apache License, Version 2.0 (the "License"); 12 | * you may not use this file except in compliance with the License. 13 | * You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software 18 | * distributed under the License is distributed on an "AS IS" BASIS, 19 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | * See the License for the specific language governing permissions and 21 | * limitations under the License. 22 | */ 23 | #include "lwip/tcpip.h" 24 | #include "freertos/FreeRTOS.h" 25 | #include "freertos/queue.h" 26 | //#include "task.h" 27 | //#include "esp_system.h" 28 | //#include "lwip/tcp.h" 29 | //#include "lwip/inet.h" 30 | #include "lwip/sockets.h" 31 | #include "lwip/api.h" 32 | #include 33 | 34 | 35 | #define SUMP_RESET 0x00 36 | #define SUMP_RUN 0x01 37 | #define SUMP_ID 0x02 38 | #define SUMP_DESC 0x04 39 | #define SUMP_XON 0x11 40 | #define SUMP_XOFF 0x13 41 | #define SUMP_DIV 0x80 42 | #define SUMP_CNT 0x81 43 | #define SUMP_FLAGS 0x82 44 | #define SUMP_TRIG_1 0xc0 45 | #define SUMP_TRIG_2 0xc4 46 | #define SUMP_TRIG_3 0xc8 47 | #define SUMP_TRIG_4 0xcc 48 | #define SUMP_TRIG_VALS_1 0xc1 49 | #define SUMP_TRIG_VALS_2 0xc5 50 | #define SUMP_TRIG_VALS_3 0xc9 51 | #define SUMP_TRIG_VALS_4 0xcd 52 | 53 | #define SUMP_STATE_IDLE 0 54 | #define SUMP_STATE_ARMED 1 55 | #define SUMP_STATE_RUNNNING 2 56 | #define SUMP_STATE_TRIGGED 3 57 | 58 | typedef struct { 59 | uint32_t trigger_masks[4]; 60 | uint32_t trigger_values[4]; 61 | uint32_t read_count; 62 | uint32_t delay_count; 63 | uint32_t divider; 64 | uint8_t state; 65 | uint8_t channels; 66 | } sump_config; 67 | 68 | typedef struct _sump_t { 69 | int uart_portno; 70 | struct netconn *io; 71 | struct netconn *io_listen; 72 | 73 | QueueHandle_t evtQueue; 74 | } sump_context_t; 75 | 76 | 77 | typedef int(*sump_read_timeout_t)(sump_context_t * context, unsigned char * data,unsigned int len, size_t timeout); 78 | typedef int(*sump_read_chars_t)(sump_context_t * context, unsigned char * data,unsigned int len); 79 | typedef int(*sump_write_t)(sump_context_t * context, const char * data, size_t len); 80 | typedef int (*sump_error_callback_t)(sump_context_t * context, int_fast16_t error); 81 | typedef int (*sump_flush_t)(sump_context_t * context); 82 | 83 | 84 | struct _sump_interface_t { 85 | sump_error_callback_t error; 86 | sump_write_t write; 87 | sump_read_timeout_t read_timeout; 88 | sump_read_chars_t read_chars; 89 | sump_flush_t flush; 90 | }; 91 | 92 | typedef int SUMP_result_t; 93 | 94 | typedef struct _sump_interface_t sump_interface_t; 95 | 96 | enum _sump_result_t { 97 | SUMP_RES_OK = 1, 98 | SUMP_RES_ERR = -1 99 | }; 100 | 101 | void sump_init(); 102 | void sump_uart(); 103 | void sump(sump_context_t *context,sump_interface_t *io); 104 | #endif -------------------------------------------------------------------------------- /main/hack-ledc.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _ESP32_HAL_LEDC_H_ 16 | #define _ESP32_HAL_LEDC_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | #include 24 | 25 | typedef enum { 26 | NOTE_C, NOTE_Cs, NOTE_D, NOTE_Eb, NOTE_E, NOTE_F, NOTE_Fs, NOTE_G, NOTE_Gs, NOTE_A, NOTE_Bb, NOTE_B, NOTE_MAX 27 | } note_t; 28 | 29 | //channel 0-15 resolution 1-16bits freq limits depend on resolution 30 | double ledcSetup(uint8_t channel, double freq, uint8_t resolution_bits); 31 | void ledcWrite(uint8_t channel, uint32_t duty); 32 | double ledcWriteTone(uint8_t channel, double freq); 33 | double ledcWriteNote(uint8_t channel, note_t note, uint8_t octave); 34 | uint32_t ledcRead(uint8_t channel); 35 | double ledcReadFreq(uint8_t channel); 36 | void ledcAttachPin(uint8_t pin, uint8_t channel); 37 | void ledcDetachPin(uint8_t pin); 38 | 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif /* _ESP32_HAL_LEDC_H_ */ 45 | -------------------------------------------------------------------------------- /main/ota_server.c: -------------------------------------------------------------------------------- 1 | //https://github.com/yanbe/esp-idf-ota-template/blob/master/components/ota_server/ota_server.c 2 | 3 | #include "Header.h" 4 | 5 | #include "esp_wifi.h" 6 | #include "esp_system.h" 7 | #include "esp_log.h" 8 | #include "esp_ota_ops.h" 9 | #include "lwip/sockets.h" 10 | 11 | 12 | const int OTA_CONNECTED_BIT = BIT0; 13 | static const char * TAG = "OTA"; 14 | extern EventGroupHandle_t ota_event_group; 15 | /*socket*/ 16 | static int connect_socket = 0; 17 | 18 | void ota_server_task(void *param) 19 | { 20 | xEventGroupWaitBits(ota_event_group, OTA_CONNECTED_BIT, false, true, portMAX_DELAY); 21 | //ota_server_start(); 22 | vTaskDelete(NULL); 23 | } 24 | 25 | #if 0 26 | static esp_err_t event_handler(void *ctx, system_event_t *event) 27 | { 28 | switch (event->event_id) 29 | { 30 | case SYSTEM_EVENT_STA_START: 31 | esp_wifi_connect(); 32 | printf("Connectiing To SSID:%s : Pass:%s\r\n", CONFIG_WIFI_SSID, CONFIG_WIFI_PASSWORD); 33 | break; 34 | case SYSTEM_EVENT_STA_GOT_IP: 35 | printf("got ip:%s", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); 36 | xEventGroupSetBits(ota_event_group, OTA_CONNECTED_BIT); 37 | break; 38 | case SYSTEM_EVENT_STA_DISCONNECTED: 39 | printf("SYSTEM_EVENT_STA_DISCONNECTED\r\n"); 40 | esp_wifi_connect(); 41 | xEventGroupClearBits(ota_event_group, OTA_CONNECTED_BIT); 42 | break; 43 | default: 44 | break; 45 | } 46 | return ESP_OK; 47 | } 48 | 49 | void initialise_wifi(void) 50 | { 51 | 52 | tcpip_adapter_init(); 53 | ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); 54 | wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); 55 | ESP_ERROR_CHECK(esp_wifi_init(&cfg)); 56 | wifi_config_t sta_config = { 57 | .sta = { 58 | .ssid = CONFIG_WIFI_SSID, 59 | .password = CONFIG_WIFI_PASSWORD, 60 | .bssid_set = false 61 | } 62 | }; 63 | ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); 64 | ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config)); 65 | ESP_ERROR_CHECK(esp_wifi_start()); 66 | } 67 | #endif 68 | 69 | static int get_socket_error_code(int socket) 70 | { 71 | int result; 72 | u32_t optlen = sizeof(int); 73 | 74 | int err = getsockopt(socket, SOL_SOCKET, SO_ERROR, &result, &optlen); 75 | 76 | if (err == -1) 77 | { 78 | ESP_LOGE(TAG, "getsockopt failed:%s", strerror(err)); 79 | return -1; 80 | } 81 | return result; 82 | } 83 | 84 | static int show_socket_error_reason(const char *str, int socket) 85 | { 86 | int err = get_socket_error_code(socket); 87 | 88 | if (err != 0) 89 | { 90 | ESP_LOGW(TAG, "%s socket error %d %s", str, err, strerror(err)); 91 | } 92 | 93 | return err; 94 | } 95 | 96 | static esp_err_t create_tcp_server() 97 | { 98 | ESP_LOGI(TAG, "server socket....port=%d", OTA_LISTEN_PORT); 99 | int server_socket = 0; 100 | struct sockaddr_in server_addr; 101 | server_socket = socket(AF_INET, SOCK_STREAM, 0); 102 | 103 | if (server_socket < 0) 104 | { 105 | show_socket_error_reason("create_server", server_socket); 106 | return ESP_FAIL; 107 | } 108 | 109 | server_addr.sin_family = AF_INET; 110 | server_addr.sin_port = htons(OTA_LISTEN_PORT); 111 | server_addr.sin_addr.s_addr = htonl(INADDR_ANY); 112 | if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) 113 | { 114 | show_socket_error_reason("bind_server", server_socket); 115 | close(server_socket); 116 | return ESP_FAIL; 117 | } 118 | 119 | if (listen(server_socket, 5) < 0) 120 | { 121 | show_socket_error_reason("listen_server", server_socket); 122 | close(server_socket); 123 | return ESP_FAIL; 124 | } 125 | 126 | struct sockaddr_in client_addr; 127 | unsigned int socklen = sizeof(client_addr); 128 | connect_socket = accept(server_socket, (struct sockaddr *)&client_addr, &socklen); 129 | 130 | if (connect_socket < 0) 131 | { 132 | show_socket_error_reason("accept_server", connect_socket); 133 | close(server_socket); 134 | return ESP_FAIL; 135 | } 136 | /*connection established,now can send/recv*/ 137 | ESP_LOGI(TAG, "tcp connection established!"); 138 | return ESP_OK; 139 | } 140 | 141 | #if 0 142 | void ota_server_start(void) 143 | { 144 | uint8_t percent_loaded; 145 | 146 | ESP_ERROR_CHECK( create_tcp_server() ); 147 | 148 | const esp_partition_t *update_partition = esp_ota_get_next_update_partition(NULL); 149 | 150 | ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", update_partition->subtype, update_partition->address); 151 | 152 | //https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/log.html 153 | // I dont want to see all the Log esp_image stuff while its flashing it 154 | esp_log_level_set("esp_image", ESP_LOG_ERROR); // set all components to ERROR level ESP_LOG_NONE 155 | 156 | 157 | // We dont want any other thread running during this update. 158 | //SuspendAllThreads(); 159 | KillAllThreads(); 160 | 161 | int recv_len; 162 | char ota_buff[OTA_BUFF_SIZE] = {0}; 163 | bool is_req_body_started = false; 164 | int content_length = -1; 165 | int content_received = 0; 166 | 167 | esp_ota_handle_t ota_handle; 168 | 169 | 170 | do { 171 | recv_len = recv(connect_socket, ota_buff, OTA_BUFF_SIZE, 0); 172 | 173 | if (recv_len > 0) 174 | { 175 | if (!is_req_body_started) 176 | { 177 | const char *content_length_start = "Content-Length: "; 178 | char *content_length_start_p = strstr(ota_buff, content_length_start) + strlen(content_length_start); 179 | sscanf(content_length_start_p, "%d", &content_length); 180 | ESP_LOGI(TAG, "Detected content length: %d", content_length); 181 | ESP_ERROR_CHECK( esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &ota_handle) ); 182 | const char *header_end = "\r\n\r\n"; 183 | char *body_start_p = strstr(ota_buff, header_end) + strlen(header_end); 184 | int body_part_len = recv_len - (body_start_p - ota_buff); 185 | esp_ota_write(ota_handle, body_start_p, body_part_len); 186 | content_received += body_part_len; 187 | is_req_body_started = true; 188 | } 189 | else 190 | { 191 | esp_ota_write(ota_handle, ota_buff, recv_len); 192 | content_received += recv_len; 193 | 194 | percent_loaded = (((float)content_received / (float)content_length) * 100.00); 195 | ESP_LOGI(TAG, "Uploaded %03u%%", percent_loaded); 196 | } 197 | } 198 | else if (recv_len < 0) 199 | { 200 | ESP_LOGI(TAG, "Error: recv data error! errno=%d", errno); 201 | } 202 | 203 | } while (recv_len > 0 && content_received < content_length); 204 | 205 | // ESP_LOGI(TAG, "OTA Transferred Finished: %d bytes", content_received); 206 | 207 | 208 | char res_buff[128]; 209 | int send_len; 210 | send_len = sprintf(res_buff, "200 OK\n\n"); 211 | send(connect_socket, res_buff, send_len, 0); 212 | vTaskDelay(2000 / portTICK_PERIOD_MS); 213 | close(connect_socket); 214 | 215 | ESP_ERROR_CHECK( esp_ota_end(ota_handle) ); 216 | 217 | esp_err_t err = esp_ota_set_boot_partition(update_partition); 218 | 219 | if (err == ESP_OK) 220 | { 221 | const esp_partition_t *boot_partition = esp_ota_get_boot_partition(); 222 | 223 | ESP_LOGI(TAG, "***********************************************************"); 224 | ESP_LOGI(TAG, "OTA Successful"); 225 | ESP_LOGI(TAG, "Next Boot Partition Subtype %d At Offset 0x%x", boot_partition->subtype, boot_partition->address); 226 | ESP_LOGI(TAG, "***********************************************************"); 227 | } 228 | else 229 | { 230 | ESP_LOGI(TAG, "!!! OTA Failed !!!"); 231 | } 232 | 233 | 234 | for (int x = 3; x >= 1; x--) 235 | { 236 | ESP_LOGI(TAG, "Prepare to restart system...%d", x); 237 | vTaskDelay(1000 / portTICK_PERIOD_MS); 238 | } 239 | 240 | esp_restart(); 241 | } 242 | #endif -------------------------------------------------------------------------------- /main/ota_server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define OTA_LISTEN_PORT 8032 4 | #define OTA_BUFF_SIZE 1024 5 | 6 | 7 | extern const int OTA_CONNECTED_BIT; 8 | 9 | 10 | void ota_server_task(void *param); 11 | void ota_server_start(void); 12 | void initialise_wifi(void); 13 | 14 | extern EventGroupHandle_t ota_event_group; 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /main/read_chars.c: -------------------------------------------------------------------------------- 1 | #include "driver/uart.h" 2 | #include 3 | 4 | #define ESP_REG(addr) *((volatile uint32_t *)(addr)) 5 | #include "read_chars.h" 6 | 7 | char *readLine(uart_port_t uart,char *line,int len) { 8 | int size; 9 | char *ptr = line; 10 | while(1) { 11 | size = uart_read_bytes(uart, (unsigned char *)ptr, 1, portMAX_DELAY); 12 | if (size == 1) { 13 | if (*ptr == '\n') { 14 | *ptr = 0; 15 | return line; 16 | } 17 | ptr++; 18 | } // End of read a character 19 | } // End of loop 20 | } // End of readLine 21 | 22 | 23 | // This function polls uart data 24 | char *pollLine(uart_port_t uart,char *line,int len) { 25 | //int size; 26 | volatile uint32_t* FIFO=0; 27 | volatile uint32_t* RX_STATUS=0; 28 | 29 | char *ptr = line; 30 | switch (uart) { 31 | case UART_NUM_0: 32 | FIFO=(uint32_t*)0x3ff40000; 33 | RX_STATUS=(uint32_t*)0x3ff4001c; 34 | break; 35 | case UART_NUM_1: 36 | FIFO=(uint32_t*)0x3ff50000; 37 | RX_STATUS=(uint32_t*)0x3ff5001c; 38 | break; 39 | 40 | //case UART_NUM_2: 41 | // FIFO=(uint32_t*)0x3ff6e000; 42 | // RX_STATUS=(uint32_t*)0x3ff6e01c; 43 | //break; 44 | default: 45 | break; 46 | } 47 | 48 | while(1) { 49 | if (ESP_REG(RX_STATUS)>0) { 50 | *ptr=(ESP_REG(FIFO) & 0x000000ff); 51 | //printf("GOT:%c\n",(char)*ptr); 52 | if (*ptr == '\n') { 53 | *ptr = 0; 54 | return line; 55 | } 56 | ptr++; 57 | } 58 | vTaskDelay(100 / portTICK_PERIOD_MS); 59 | } 60 | } 61 | 62 | 63 | int char_read_timeout(unsigned char *buff, int num_bytes, int timeout) { 64 | int size; 65 | int num_read=0; 66 | unsigned char *ptr = buff; 67 | //printf("+"); 68 | 69 | { 70 | size = uart_read_bytes(0, (unsigned char *)ptr, 1, timeout); // portMAX_DELAY); 71 | //printf("%c\n",*ptr); 72 | if (size == 1) { 73 | num_read++; 74 | ptr++; 75 | return num_read; 76 | } else { 77 | //printf("."); 78 | return num_read; 79 | } 80 | // End of read a character 81 | } // End of loop 82 | } 83 | 84 | int char_read(unsigned char *buff, int num_bytes) { 85 | int size; 86 | int ret=num_bytes; 87 | unsigned char *ptr = buff; 88 | while(num_bytes>0) { 89 | size = uart_read_bytes(0, ptr, 1, portMAX_DELAY); 90 | if (size == 1) { 91 | num_bytes--; 92 | ptr++; 93 | } // End of read a character 94 | } // End of loop 95 | return (ret); 96 | } 97 | 98 | -------------------------------------------------------------------------------- /main/read_chars.h: -------------------------------------------------------------------------------- 1 | #ifndef READ_CHARS_H 2 | #define READ_CHARS_H 1 3 | #include "driver/uart.h" 4 | 5 | extern int char_read_timeout(unsigned char *buff, int num_bytes, int timeout); 6 | extern int char_read(unsigned char *buff, int num_bytes); 7 | 8 | extern char *readLine(uart_port_t uart,char *line,int len); 9 | extern char *pollLine(uart_port_t uart,char *line,int len); 10 | 11 | #endif -------------------------------------------------------------------------------- /main/sampler.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "soc/i2s_struct.h" 4 | #include "config.h" 5 | #include "rom/lldesc.h" 6 | #include "soc/i2s_struct.h" 7 | #include "soc/i2s_reg.h" 8 | #include "driver/periph_ctrl.h" 9 | #include "soc/io_mux_reg.h" 10 | #include "esp_heap_caps.h" 11 | #include "esp_system.h" 12 | #include "esp_task_wdt.h" 13 | #include "driver/ledc.h" 14 | 15 | 16 | #define CAPTURE_SIZE 1400 17 | 18 | #define ledPin 27 //Led on while running and Blinks while transfering data. 19 | 20 | 21 | void enable_out_clock( int freq_in_hz ); 22 | 23 | 24 | #define DMA_MAX (4096-4) 25 | 26 | typedef union { 27 | struct { 28 | uint8_t sample2; 29 | uint8_t unused2; 30 | uint8_t sample1; 31 | uint8_t unused1; 32 | }; 33 | struct{ 34 | uint16_t val2; 35 | uint16_t val1; 36 | }; 37 | uint32_t val; 38 | } dma_elem_t; 39 | 40 | 41 | uint8_t* get_values(); 42 | 43 | uint16_t* get_digital_values(); 44 | 45 | int* get_sample_values(); 46 | 47 | 48 | // Param is task handle of task to notify 49 | void sample_thread(void *param); 50 | 51 | void setTimescale(float scale); 52 | 53 | void start_sampling(); 54 | 55 | bool samples_finnished(); 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /main/scpi-def.h: -------------------------------------------------------------------------------- 1 | #ifndef __SCPI_DEF_H_ 2 | #define __SCPI_DEF_H_ 3 | 4 | #include "scpi/scpi.h" 5 | 6 | #define SCPI_INPUT_BUFFER_LENGTH 256 7 | #define SCPI_ERROR_QUEUE_SIZE 17 8 | 9 | #define SCPI_IDN1 "RIGOL TECHNOLOGIES" 10 | //#define SCPI_IDN1 "RIGOL TECHNOLOGIES,DS1102E,DS1EB104702974,00.02.05.01.00" 11 | //# firmware < 0.2.4, using raw data format. 12 | //#define SCPI_IDN2 "VS5022D" 13 | //#define SCPI_IDN3 "VS50234567" 14 | //#define SCPI_IDN4 "00.02.03.03.00" 15 | // 00.02.04 16 | //#define SCPI_IDN1 "Rigol Technologies,MSO2302A,DS1EXXXXXXXXXX,00.02.05.02.00" 17 | #define SCPI_IDN2 "MSO2302A" 18 | #define SCPI_IDN3 "DS1EXXXXXXXXXX" 19 | #define SCPI_IDN4 "00.02.05.02.00" 20 | 21 | 22 | extern const scpi_command_t scpi_commands[]; 23 | extern scpi_interface_t scpi_interface; 24 | extern char scpi_input_buffer[]; 25 | extern scpi_error_t scpi_error_queue_data[]; 26 | extern scpi_t scpi_context; 27 | 28 | size_t SCPI_Write(scpi_t * context, const char * data, size_t len); 29 | int SCPI_Error(scpi_t * context, int_fast16_t err); 30 | scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val); 31 | scpi_result_t SCPI_Reset(scpi_t * context); 32 | scpi_result_t SCPI_Flush(scpi_t * context); 33 | 34 | 35 | scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context); 36 | 37 | #endif /* __SCPI_DEF_H_ */ 38 | 39 | -------------------------------------------------------------------------------- /main/scpi_server.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCPI_SERVER_H_ 2 | #define _SCPI_SERVER_H_ 3 | 4 | 5 | #include 6 | 7 | void scpi_server_init(TaskHandle_t *pvCreatedTask); 8 | 9 | void SCPI_AddError(int16_t err); 10 | void SCPI_RequestControl(void); 11 | 12 | 13 | #endif /* _SCPI_SERVER_H_ */ 14 | -------------------------------------------------------------------------------- /main/scpi_sock_server.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2012-2013 Jan Breuer, 3 | * 4 | * All Rights Reserved 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * @file main.c 30 | * @date Thu Nov 15 10:58:45 UTC 2012 31 | * 32 | * @brief TCP/IP SCPI Server 33 | * 34 | * 35 | */ 36 | 37 | #include 38 | //#include 39 | //#include 40 | 41 | #include "lwip/tcpip.h" 42 | #include "freertos/FreeRTOS.h" 43 | //#include "task.h" 44 | #include "esp_system.h" 45 | #include "lwip/tcp.h" 46 | #include "lwip/inet.h" 47 | #include "lwip/sockets.h" 48 | 49 | #include "scpi/scpi.h" 50 | #include "scpi-def.h" 51 | 52 | 53 | /* a global output buffer to collect output data until it will be 'flushed' */ 54 | #define SCPI_OUPUT_BUFFER_SIZE (14100) 55 | char SCPI_outputBuffer[SCPI_OUPUT_BUFFER_SIZE]; 56 | unsigned int SCPI_outputBuffer_idx = 0; 57 | 58 | 59 | size_t SCPI_Write(scpi_t * context, const char * data, size_t len) { 60 | 61 | if ((SCPI_outputBuffer_idx + len) > (SCPI_OUPUT_BUFFER_SIZE - 1)) { 62 | len = (SCPI_OUPUT_BUFFER_SIZE - 1) - SCPI_outputBuffer_idx; /* limit length to left over space */ 63 | /* apparently there is no mechanism to cope with buffers that are too small */ 64 | } 65 | memcpy(&SCPI_outputBuffer[SCPI_outputBuffer_idx], data, len); 66 | SCPI_outputBuffer_idx += len; 67 | 68 | SCPI_outputBuffer[SCPI_outputBuffer_idx] = '\0'; 69 | /* return fwrite(data, 1, len, stdout); */ 70 | return len; 71 | /* 72 | (void) context; 73 | 74 | if (context->user_context != NULL) { 75 | int fd = *(int *) (context->user_context); 76 | return write(fd, data, len); 77 | } 78 | */ 79 | return 0; 80 | } 81 | 82 | scpi_result_t SCPI_Flush(scpi_t * context) { 83 | //(void) context; 84 | if (context->user_context != NULL) { 85 | int fd = *(int *) (context->user_context); 86 | //SCPI_outputBuffer[SCPI_outputBuffer_idx] = 0x0; 87 | //SCPI_outputBuffer_idx++; 88 | 89 | // Hmmm??? ACHTUNG 90 | //SCPI_outputBuffer[SCPI_outputBuffer_idx] = 0x0a; 91 | //SCPI_outputBuffer_idx++; 92 | 93 | int tot=SCPI_outputBuffer_idx; 94 | int numWritten=0; 95 | while (numWritten 0) { /* something to read */ 258 | rc = recv(clifd, smbuffer, sizeof (smbuffer), 0); 259 | if (rc < 0) { 260 | if (errno != EWOULDBLOCK) { 261 | perror(" recv() failed"); 262 | break; 263 | } 264 | } else if (rc == 0) { 265 | printf("Connection closed\r\n"); 266 | break; 267 | } else { 268 | // To debug input 269 | //smbuffer[rc]=0; 270 | //printf("%s\n",smbuffer); 271 | SCPI_Input(&scpi_context, smbuffer, rc); 272 | } 273 | } 274 | } 275 | 276 | close(clifd); 277 | } 278 | 279 | return; 280 | } 281 | 282 | #define SCPI_THREAD_PRIO (tskIDLE_PRIORITY + 2) 283 | 284 | 285 | extern TaskHandle_t xTaskList[20]; 286 | extern uint8_t xtaskListCounter; 287 | 288 | void scpi_server_init(TaskHandle_t *pvCreatedTask) { 289 | printf("scpi server thread\n"); 290 | sys_thread_t tmp=sys_thread_new("SCPI", scpi_server_thread, NULL, 5 * DEFAULT_THREAD_STACKSIZE, SCPI_THREAD_PRIO); 291 | xTaskList[xtaskListCounter]=tmp; 292 | } 293 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; http://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | src_dir = main 13 | lib_dir = components 14 | 15 | [env:esp32dev] 16 | platform = espressif32 17 | board = esp32dev 18 | framework = espidf 19 | lib_deps = libscpi, esp_adc 20 | -------------------------------------------------------------------------------- /rigol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ebiroll/esp32_sigrok/cb8852eddf003c1938a9311f3d459f3b16454b0a/rigol.png -------------------------------------------------------------------------------- /scopecmd/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | CC = gcc 4 | CXX = g++ 5 | 6 | 7 | LIBS = -lstdc++ 8 | 9 | 10 | CFLAGS = -g -fsanitize=address -std=c++11 11 | #CFLAGS += `pkg-config --cflags libusb-1.0` 12 | 13 | #LIBS += `pkg-config --libs libusb-1.0` 14 | 15 | OBJS = obj/scopecmd.cpp.o 16 | OBJS += obj/cfgmap.cpp.o 17 | OBJS += obj/netcomm.cpp.o 18 | #OBJS += obj/freetmc_local.cpp.o 19 | OBJS += obj/freetmc_remote.cpp.o 20 | 21 | 22 | all: scopecmd 23 | 24 | obj: 25 | mkdir -p obj 26 | 27 | scopecmd: obj src/simple_except.h src/freetmc.h src/netcomm.h src/freetmc_remote.h src/rigoltmc.h $(OBJS) 28 | $(CXX) $(CFLAGS) $(OBJS) $(LIBS) -o scopecmd 29 | 30 | 31 | obj/%.cpp.o: src/%.cpp 32 | $(CXX) -c $(CFLAGS) $< -o $@ 33 | 34 | 35 | clean: 36 | rm -rf obj/*.o 37 | 38 | -------------------------------------------------------------------------------- /scopecmd/src/cfgmap.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "cfgmap.h" 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | //****************************************************************************** 9 | 10 | void EscapeStr(const string & input, string & output) 11 | { 12 | string::const_iterator ch; 13 | for(ch = input.begin(); ch != input.end(); ++ch) 14 | { 15 | if(isprint(*ch) && *ch != '\\') 16 | { 17 | output += *ch; 18 | } 19 | else 20 | { 21 | char bfr[16]; 22 | snprintf(bfr, 16, "\\%04X", (int)*ch); 23 | output += bfr; 24 | } 25 | } 26 | } // EscapeStr() 27 | 28 | void UnescapeStr(const string & input, string & output) 29 | { 30 | string::const_iterator ch; 31 | ch = input.begin(); 32 | while(ch != input.end()) 33 | { 34 | if(*ch == '\\') 35 | { 36 | ++ch; 37 | char bfr[16]; 38 | int j = 0; 39 | while(j < 4 && ch != input.end()) 40 | bfr[j++] = *(ch++); 41 | bfr[j] = '\0'; 42 | output += (char)strtol(bfr, NULL, 16); 43 | } 44 | else 45 | { 46 | output += *(ch++); 47 | } 48 | } 49 | } // UnescapeStr() 50 | 51 | void ReadParams(const std::string & path, configmap_t & params) 52 | { 53 | FILE * fin = fopen(path.c_str(), "rb"); 54 | int ch = fgetc(fin); 55 | while(ch != EOF) 56 | { 57 | string key; 58 | while(ch != EOF && ch != ':') { 59 | key += (char)ch; 60 | ch = fgetc(fin); 61 | } 62 | 63 | if(ch == ':') 64 | ch = fgetc(fin); 65 | else 66 | break; 67 | 68 | string encValue; 69 | while(ch != EOF && ch != '\n') { 70 | encValue += (char)ch; 71 | ch = fgetc(fin); 72 | } 73 | string value; 74 | UnescapeStr(encValue, value); 75 | params[key] = value; 76 | 77 | if(ch == '\n') 78 | ch = fgetc(fin); 79 | } 80 | fclose(fin); 81 | } // ReadParams() 82 | 83 | void WriteParams(const std::string & path, const configmap_t & params) 84 | { 85 | FILE * fout = fopen(path.c_str(), "wb"); 86 | configmap_t::const_iterator pitr; 87 | for(pitr = params.begin(); pitr != params.end(); ++pitr) 88 | { 89 | string escaped; 90 | EscapeStr(pitr->second, escaped); 91 | // Don't try to merge these. c_str() uses a static buffer. 92 | fprintf(fout, "%s:", pitr->first.c_str()); 93 | fprintf(fout, "%s\n", escaped.c_str()); 94 | } 95 | fclose(fout); 96 | } // WriteParams() 97 | 98 | //****************************************************************************** 99 | 100 | // g++ -DTEST_CFGMAP cfgmap.cpp -o test_cfgmap 101 | #ifdef TEST_CFGMAP 102 | 103 | #include 104 | #include 105 | #include 106 | 107 | 108 | int testsFailed = 0; 109 | 110 | void TestValue(const std::string & key, const std::string & value, const configmap_t & params) 111 | { 112 | configmap_t::const_iterator pitr = params.find(key); 113 | if(pitr == params.end()) { 114 | cerr << "Test failed, key \"" << key << "\" not found in params" << endl; 115 | exit(EXIT_FAILURE); 116 | } 117 | if(pitr->second != value) { 118 | ++testsFailed; 119 | cerr << "Test failed, expected value \"" << value << "\", found \"" << pitr->second << "\"" << endl; 120 | } 121 | } 122 | 123 | void TestSplit(const char * s, char ch, size_t n, ...) 124 | { 125 | vector result; 126 | split(s, ch, result); 127 | 128 | if(result.size() != n) { 129 | cerr << "split() test failed: split(" << s << ")" << endl; 130 | cerr << "Incorrect size: " << result.size() << ", expected: " << n << endl; 131 | ++testsFailed; 132 | return; 133 | } 134 | 135 | vector::iterator subs = result.begin(); 136 | va_list va; 137 | va_start(va, n); 138 | for(int j = 0; j < n; ++j, ++subs) 139 | { 140 | char * expSubs = va_arg(va, char *); 141 | if(*subs != expSubs) { 142 | cerr << "split() test failed: split(" << s << ")" << endl; 143 | cerr << "Incorrect substring: \"" << *subs << "\", expected \"" << expSubs << "\"" << endl; 144 | ++testsFailed; 145 | break; 146 | } 147 | } 148 | va_end(va); 149 | } 150 | 151 | int main(int argc, char * argv[]) 152 | { 153 | configmap_t params; 154 | params["foo"] = "bar"; 155 | params[""] = "keyless"; 156 | params["valueless"] = ""; 157 | params["Sernum"] = "5164:6135:FA"; 158 | params["addr"] = "192.168.3.21"; 159 | params["complexString"] = "\\1, 2, 3,\n\\4, 5, 6"; 160 | WriteParams("test.cfg", params); 161 | 162 | configmap_t rparams; 163 | ReadParams("test.cfg", rparams); 164 | 165 | configmap_t::const_iterator pitr; 166 | for(pitr = params.begin(); pitr != params.end(); ++pitr) 167 | TestValue(pitr->first, pitr->second, rparams); 168 | 169 | 170 | TestSplit("a:b:c", ':', 3, "a", "b", "c"); 171 | TestSplit(":a:b:c:", ':', 5, "", "a", "b", "c", ""); 172 | TestSplit("abc:def:ghi", ':', 3, "abc", "def", "ghi"); 173 | TestSplit(":abc:def:ghi:", ':', 5, "", "abc", "def", "ghi", ""); 174 | TestSplit("", ':', 1, ""); 175 | TestSplit(":", ':', 2, "", ""); 176 | 177 | 178 | cerr << testsFailed << " tests failed" << endl; 179 | 180 | return EXIT_SUCCESS; 181 | } 182 | #endif 183 | 184 | -------------------------------------------------------------------------------- /scopecmd/src/cfgmap.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CFGMAP_H 3 | #define CFGMAP_H 4 | 5 | #include 6 | #include 7 | 8 | //****************************************************************************** 9 | 10 | // A simple text-based key-value store. 11 | // Read and write key-value parameters in newline-terminated, colon-separated format. 12 | // Each line starts with the key, which consists of all characters up to the colon, and 13 | // the value consists of all characters from the colon up to the first newline. 14 | // All printable characters are written directly, with one exception: \ characters are 15 | // escaped as \005C. All unprintable characters are similarly escaped, so arbitrary binary 16 | // data can be stored or even hand-written. 17 | 18 | typedef std::map configmap_t; 19 | 20 | inline bool Get(const configmap_t & cfg, const std::string & key, std::string & value) 21 | { 22 | std::map::const_iterator ent = cfg.find(key); 23 | if(ent != cfg.end()) { 24 | value = ent->second; 25 | return true; 26 | } 27 | return false; 28 | } 29 | 30 | // Collect all keys with given prefix. Use to emulate hierarchical structure, arrays, etc. 31 | template 32 | inline void KeysWithPrefix(const configmap_t & cfg, const std::string & prefix, cont_t & keys) 33 | { 34 | std::map::const_iterator ent; 35 | for(ent = cfg.begin(); ent != cfg.end(); ++ent) 36 | if(ent->first.substr(0, prefix.length()) == prefix) 37 | keys.push_back(ent->first); 38 | } 39 | 40 | // A variant of KeysWithPrefix(): rather than collecting the complete keys into a list or vector, 41 | // creates another map associating each value with the remainder of the keys. 42 | // That is, given: 43 | // foo.name:thing 1 44 | // foo.size:42 45 | // foo.color:green 46 | // bar.name:thing 2 47 | // bar.size:3.14159 48 | // bar.color:microwave 49 | // 50 | // KeysWithPrefix() with a prefix of "foo." will give: 51 | // name:thing 1 52 | // size:42 53 | // color:green 54 | // 55 | inline void EntriesWithPrefix(const configmap_t & cfg, const std::string & prefix, configmap_t & submap) 56 | { 57 | std::map::const_iterator ent; 58 | for(ent = cfg.begin(); ent != cfg.end(); ++ent) 59 | if(ent->first.substr(0, prefix.length()) == prefix) 60 | submap[ent->first.substr(prefix.length())] = ent->second; 61 | } 62 | 63 | // Split a string into substrings on a given delimeter 64 | // Splitting an empty string yields an empty string. 65 | // A delimiter at the start or end of the string produces an empty string. 66 | // split("a:b:c", ':') -> "a", "b", "c" 67 | // split("", ':') -> "" 68 | // split(":", ':') -> "", "" 69 | // split(":a:b:c:", ':') -> "", "a", "b", "c", "" 70 | template 71 | inline void split(const std::string & str, char ch, cont_t & result) 72 | // inline void split(const std::string & str, char ch, std::vector & result) 73 | { 74 | if(str.length() == 0) { 75 | result.push_back(""); 76 | return; 77 | } 78 | 79 | if(str.length() == 1) 80 | { 81 | if(str[0] != ch) { 82 | result.push_back(str); 83 | } 84 | else { 85 | result.push_back(""); 86 | result.push_back(""); 87 | } 88 | return; 89 | } 90 | 91 | std::string::const_iterator begin, end; 92 | begin = str.begin(); 93 | end = begin; 94 | while(begin < str.end()) 95 | { 96 | while(end < str.end() && *end != ch) 97 | ++end; 98 | 99 | result.push_back(std::string(begin, end)); 100 | begin = end + 1; 101 | end = begin; 102 | } 103 | if(str[str.length() - 1] == ch) 104 | result.push_back(""); 105 | } 106 | 107 | void ReadParams(const std::string & path, configmap_t & params); 108 | void WriteParams(const std::string & path, const configmap_t & params); 109 | 110 | //****************************************************************************** 111 | #endif // CFGMAP_H 112 | -------------------------------------------------------------------------------- /scopecmd/src/freetmc.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FREETMC_H 3 | #define FREETMC_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | //#include 13 | #include 14 | 15 | #include "simple_except.h" 16 | 17 | //****************************************************************************** 18 | 19 | struct IDN_Response { 20 | std::string manufacturer; 21 | std::string model; 22 | std::string serial; 23 | std::string version; 24 | }; 25 | 26 | 27 | 28 | class TMC_Device { 29 | public: 30 | TMC_Device() {} 31 | virtual ~TMC_Device() {} 32 | 33 | virtual size_t Write(const uint8_t * msg, size_t len) = 0; 34 | virtual size_t Write(const std::vector & msg) {return Write(&msg[0], msg.size());} 35 | virtual size_t Write(const std::string & msg) {return Write((const uint8_t*)&msg[0], msg.size());} 36 | 37 | virtual void StartRead(uint8_t * msg, size_t nbytes) = 0; 38 | virtual ssize_t FinishRead(uint8_t * msg, size_t nbytes) = 0; 39 | virtual size_t Read(uint8_t * msg, size_t nbytes) { 40 | StartRead(msg, nbytes); 41 | return FinishRead(msg, nbytes); 42 | } 43 | virtual size_t Read(std::vector & msg, size_t nbytes) { 44 | msg.resize(nbytes); 45 | size_t bytesRead = Read(&msg[0], nbytes); 46 | msg.resize(bytesRead); 47 | return bytesRead; 48 | } 49 | 50 | // Direct queries 51 | void Cmd(const std::string & opt) {Write(opt);} 52 | void CmdVA(const std::string & format, va_list ap) { 53 | char * fstr; 54 | vasprintf(&fstr, format.c_str(), ap); 55 | if(fstr != NULL) { 56 | Write(fstr); 57 | free(fstr); 58 | } 59 | } 60 | void CmdF(const std::string & format, ...) { 61 | va_list ap; 62 | va_start(ap, format); 63 | CmdVA(format, ap); 64 | va_end(ap); 65 | } 66 | 67 | // Basic query, returns response as string 68 | std::string Query(const std::string & str, size_t maxSize = 1024) { 69 | Write(str); 70 | std::vector resp; 71 | Read(resp, maxSize); 72 | return std::string(resp.begin(), resp.end()); 73 | } 74 | std::string QueryF(size_t maxSize, const std::string & format, ...) { 75 | va_list ap; 76 | va_start(ap, format); 77 | CmdVA(format, ap); 78 | va_end(ap); 79 | std::vector resp; 80 | Read(resp, maxSize); 81 | return std::string(resp.begin(), resp.end()); 82 | } 83 | std::string QueryF(const std::string & format, ...) { 84 | va_list ap; 85 | va_start(ap, format); 86 | CmdVA(format, ap); 87 | va_end(ap); 88 | std::vector resp; 89 | Read(resp, 1024); 90 | return std::string(resp.begin(), resp.end()); 91 | } 92 | 93 | // Query returning binary data 94 | void BinQuery(std::vector & resp, const std::string & str, size_t maxSize = 1024) { 95 | Write(str); 96 | Read(resp, maxSize); 97 | } 98 | 99 | // Query returning floating point parameter 100 | double FloatQuery(const std::string & format, ...) { 101 | va_list ap; 102 | va_start(ap, format); 103 | CmdVA(format, ap); 104 | va_end(ap); 105 | std::vector resp; 106 | Read(resp, 1024); 107 | return strtod((char *)&resp[0], NULL); 108 | } 109 | 110 | // Query returning integer parameter 111 | int64_t IntQuery(const std::string & format, ...) { 112 | va_list ap; 113 | va_start(ap, format); 114 | CmdVA(format, ap); 115 | va_end(ap); 116 | std::vector resp; 117 | Read(resp, 1024); 118 | return strtol((char *)&resp[0], NULL, 0); 119 | } 120 | 121 | // Standard queries 122 | IDN_Response Identify() { 123 | std::string resp = Query("*IDN?"); 124 | // std::cout << "IDN: " << resp << std::endl; 125 | IDN_Response idn; 126 | size_t start = 0, end = resp.find_first_of(','); 127 | idn.manufacturer = resp.substr(start, end - start); 128 | start = end + 1; 129 | end = resp.find_first_of(',', start); 130 | idn.model = resp.substr(start, end - start); 131 | start = end + 1; 132 | end = resp.find_first_of(',', start); 133 | idn.serial = resp.substr(start, end - start); 134 | start = end + 1; 135 | end = resp.find_first_of(',', start); 136 | idn.version = resp.substr(start, end - start); 137 | return idn; 138 | } 139 | }; 140 | 141 | 142 | //****************************************************************************** 143 | #endif // FREETMC_H 144 | -------------------------------------------------------------------------------- /scopecmd/src/freetmc_remote.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "freetmc_remote.h" 3 | 4 | //****************************************************************************** 5 | 6 | 7 | TMC_RemoteDevice::TMC_RemoteDevice(uint16_t vendID, uint16_t prodID, const std::string & sernum, int sockfd): 8 | conn(sockfd), 9 | seqNum(0) 10 | { 11 | #if 0 12 | // conn.SetBlocking(); 13 | std::vector bfr(sernum.size() + PKT_HEADER_SIZE); 14 | std::copy(sernum.begin(), sernum.end(), bfr.begin() + PKT_HEADER_SIZE); 15 | bfr[0] = 1; 16 | bfr[1] = 1; 17 | bfr[2] = seqNum++; 18 | bfr[3] = ~bfr[2]; 19 | *(uint32_t*)&(bfr)[4] = htonl(sernum.size()); 20 | *(uint32_t*)&(bfr)[8] = htonl((uint32_t)vendID << 16 | prodID); 21 | // *(uint16_t*)&(bfr)[8] = htons(vendID); 22 | // *(uint16_t*)&(bfr)[10] = htons(prodID); 23 | 24 | // Is this some kind of identify sent?? 25 | conn.SendMessage(&bfr[0], bfr.size()); 26 | #endif 27 | } 28 | 29 | TMC_RemoteDevice::~TMC_RemoteDevice() 30 | { 31 | 32 | } 33 | 34 | size_t TMC_RemoteDevice::Write(const uint8_t * msg, size_t len) 35 | { 36 | #if 0 37 | std::vector bfr(len + PKT_HEADER_SIZE); 38 | std::copy(msg, msg + len, bfr.begin() + PKT_HEADER_SIZE); 39 | bfr[0] = 10; 40 | bfr[1] = 0; 41 | bfr[2] = seqNum++; 42 | bfr[3] = ~bfr[2]; 43 | *(uint32_t*)&(bfr)[4] = htonl(len); 44 | *(uint32_t*)&(bfr)[8] = 0; 45 | conn.SendMessage(&bfr[0], bfr.size()); 46 | #endif 47 | conn.SendMessage((uint8_t *)msg, len); 48 | 49 | return len; 50 | } 51 | 52 | void TMC_RemoteDevice::StartRead(uint8_t * msg, size_t len) 53 | { 54 | #if 0 55 | uint8_t bfr[PKT_HEADER_SIZE]; 56 | bfr[0] = 10; 57 | bfr[1] = 0; 58 | bfr[2] = seqNum++; 59 | bfr[3] = ~bfr[2]; 60 | *(uint32_t*)&(bfr)[4] = 0; 61 | *(uint32_t*)&(bfr)[8] = htonl(len); 62 | conn.SendMessage(bfr, PKT_HEADER_SIZE); 63 | #endif 64 | //conn.SendMessage((uint8_t *)msg,len); 65 | 66 | } 67 | 68 | ssize_t TMC_RemoteDevice::FinishRead(uint8_t * msg, size_t len) 69 | { 70 | std::vector * resp = conn.WaitPopMessage(); 71 | size_t nbytes = std::min(len, resp->size()); 72 | memcpy(msg , &(*resp->begin()) , nbytes); 73 | 74 | 75 | //size_t nbytes = std::min(len, resp->size() - PKT_HEADER_SIZE); 76 | //std::copy(resp->begin() + PKT_HEADER_SIZE, resp->begin() + PKT_HEADER_SIZE + nbytes, msg); 77 | //delete resp; 78 | return nbytes; 79 | } 80 | 81 | //****************************************************************************** 82 | -------------------------------------------------------------------------------- /scopecmd/src/freetmc_remote.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef REMOTEDEVICE_H 3 | #define REMOTEDEVICE_H 4 | 5 | #include "netcomm.h" 6 | #include "freetmc.h" 7 | #include "protocol.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | //****************************************************************************** 17 | 18 | class TMC_RemoteDevice: public TMC_Device { 19 | FramedConnection conn; 20 | uint8_t seqNum; 21 | public: 22 | TMC_RemoteDevice(uint16_t vendID, uint16_t prodID, const std::string & sernum, int sockfd); 23 | virtual ~TMC_RemoteDevice(); 24 | 25 | virtual size_t Write(const uint8_t * msg, size_t len); 26 | 27 | virtual void StartRead(uint8_t * msg, size_t len); 28 | virtual ssize_t FinishRead(uint8_t * msg, size_t len); 29 | }; 30 | 31 | 32 | //****************************************************************************** 33 | #endif // REMOTEDEVICE_H 34 | -------------------------------------------------------------------------------- /scopecmd/src/netcomm.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef NETCOMM_H 3 | #define NETCOMM_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | #include "simple_except.h" 28 | 29 | 30 | 31 | //****************************************************************************** 32 | class Host; 33 | class Client; 34 | struct Socket { 35 | struct sockaddr_storage other_addr; 36 | int sockfd; 37 | std::string other; 38 | 39 | Socket(): sockfd(-1) {} 40 | ~Socket() {if(sockfd != -1) Close();} 41 | friend class Host; 42 | friend class Client; 43 | 44 | int Close() {return close(sockfd);} 45 | int Shutdown(int how) {return shutdown(sockfd, how);} 46 | int ShutdownRx(int how) {return shutdown(sockfd, 0);} 47 | int ShutdownTx(int how) {return shutdown(sockfd, 1);} 48 | int ShutdownRxTx(int how) {return shutdown(sockfd, 2);} 49 | 50 | // flags: MSG_OOB, MSG_PEEK, MSG_WAITALL 51 | int Recv(std::vector & buf, size_t maxdata, int flags = 0) { 52 | buf.resize(maxdata); 53 | ssize_t status = recv(sockfd, &buf[0], maxdata, 0); 54 | if(status >= 0) 55 | buf.resize(status); 56 | return status; 57 | } 58 | // flags: MSG_OOB, MSG_DONTROUTE 59 | int Send(const std::vector & buf, int flags = 0) { 60 | return send(sockfd, &buf[0], buf.size(), 0); 61 | } 62 | }; 63 | //****************************************************************************** 64 | 65 | // This class wraps SLIP-style message framing around a socket. Received messages 66 | // are queued for handling. 67 | class FramedConnection { 68 | int sockfd; 69 | std::queue *> buffers; 70 | std::vector * currentBuffer; 71 | bool escaped; 72 | bool good; 73 | 74 | public: 75 | FramedConnection(int s); 76 | 77 | void SetNonblocking(); 78 | void SetBlocking(); 79 | 80 | // Returns true if connection is usable, otherwise false. 81 | bool Good() {return good;} 82 | 83 | // Handles any pending incoming data. 84 | // Throws FormattedError if connection is lost. 85 | bool Poll(); 86 | 87 | // Pop a message from the queue if any complete message has been received, 88 | // else return NULL. Does not poll socket. 89 | // Message must be deleted by caller. 90 | std::vector * PopMessage(); 91 | 92 | // Pop a message from the queue if any complete message has been received, 93 | // else block and poll until one is received. 94 | // Message must be deleted by caller. 95 | std::vector * WaitPopMessage(); 96 | 97 | // Send a message. 98 | // Throws FormattedError if connection is lost. 99 | void SendMessage(uint8_t bfr[], size_t len); 100 | }; 101 | 102 | //****************************************************************************** 103 | 104 | class Host { 105 | int listenfd; 106 | 107 | public: 108 | Host(const std::string & port, int backlog = 10); 109 | ~Host(); 110 | 111 | void Close(); 112 | 113 | Socket * Accept(); 114 | }; 115 | 116 | //****************************************************************************** 117 | 118 | Socket * ClientConnect(const std::string & host, const std::string & port); 119 | 120 | 121 | //****************************************************************************** 122 | 123 | // This class manages a server discovery mechanism listening for queries broadcast to 124 | // a given address on a query port, and responding to the sender on a separate response port. 125 | class DiscoverableServer { 126 | int reqSock; 127 | std::string addr; 128 | int qport; 129 | int rport; 130 | 131 | public: 132 | DiscoverableServer(const std::string & a, uint16_t qp, uint16_t rp); 133 | 134 | bool Poll(double secs = 0.001); 135 | 136 | void SendResponse(uint8_t * buffer, size_t msgLen, sockaddr_in & srcAddr, socklen_t srcAddrLen); 137 | 138 | // Override this to send a response with any needed server info 139 | virtual bool HandleRequest(uint8_t * buffer, size_t msgLen, sockaddr_in & srcAddr, socklen_t srcAddrLen) = 0; 140 | }; 141 | 142 | //****************************************************************************** 143 | class ServerFinder { 144 | int respSock; 145 | std::string addr; 146 | int qport; 147 | int rport; 148 | 149 | public: 150 | ServerFinder(const std::string & a, uint16_t qp, uint16_t rp); 151 | ~ServerFinder(); 152 | 153 | void SendQuery(uint8_t * buffer, size_t msgLen); 154 | 155 | bool Poll(double secs = 0.001); 156 | 157 | bool PollFor(double secs); 158 | 159 | // Override this to handle responding servers 160 | virtual bool HandleResponse(uint8_t * buffer, size_t msgLen, sockaddr_in & srcAddr, socklen_t srcAddrLen) = 0; 161 | }; 162 | 163 | //****************************************************************************** 164 | #endif // NETCOMM_H 165 | -------------------------------------------------------------------------------- /scopecmd/src/protocol.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PROTOCOL_H 3 | #define PROTOCOL_H 4 | 5 | //****************************************************************************** 6 | 7 | #define DISC_QUERY_PORT (49393) 8 | #define DISC_RESP_PORT (49394) 9 | #define DISC_BCAST_ADDR ("225.0.0.50") 10 | 11 | 12 | #define PKT_HEADER_SIZE (8) 13 | 14 | #define PKT_CMD(msg) (((uint16_t)(msg)[0] << 8) | (msg)[1]) 15 | #define PKT_SetCMD(msg, cmd) do {(msg)[0] = (cmd) >> 8; (msg)[1] = (cmd) & 0xFF;} while(0) 16 | 17 | #define PKT_SEQ(msg) ((msg)[2]) 18 | #define PKT_SEQ2(msg) ((msg)[3]) 19 | #define PKT_SEQ_GOOD(msg) ((msg)[2] == (0xFF & ~((msg)[3]))) 20 | #define PKT_SetSeq(msg, seq) do {(msg)[2] = (seq); (msg)[3] = (~(seq)) & 0xFF;} while(0) 21 | 22 | #define PKT_PAYLOAD_SIZE(msg) (ntohl(*(uint32_t*)&(msg)[4])) 23 | #define PKT_SetPayloadSize(msg, size) *(uint32_t*)&(msg)[4] = htonl(size) 24 | 25 | #define PKT_SIZE(msg) (PKT_PAYLOAD_SIZE(msg) + PKT_HEADER_SIZE) 26 | 27 | #define PKT_PAYLOAD(msg) (&(msg)[PKT_HEADER_SIZE]) 28 | 29 | 30 | #define CMD_PING (0x0000) 31 | #define CMD_DISCONNECT (0x0002) 32 | // #define CMD_SERVNAME (0x0100) 33 | // #define CMD_LIST_DEVICES (0x0101) 34 | #define CMD_CONNECT_DEVICE (0x0200) 35 | #define CMD_DEVICE_COMM (0x0F00) 36 | 37 | //****************************************************************************** 38 | #endif // PROTOCOL_H 39 | -------------------------------------------------------------------------------- /scopecmd/src/rigoltmc.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef RIGOLTMC_H 3 | #define RIGOLTMC_H 4 | 5 | #include "freetmc.h" 6 | 7 | class DS1000E: public TMC_Device { 8 | TMC_Device * tmcDev; 9 | public: 10 | DS1000E(TMC_Device * tmc): tmcDev(tmc) {} 11 | 12 | virtual size_t Write(const uint8_t * msg, size_t len) {tmcDev->Write(msg, len);} 13 | virtual void StartRead(uint8_t * msg, size_t nbytes) {return tmcDev->StartRead(msg, nbytes);} 14 | virtual ssize_t FinishRead(uint8_t * msg, size_t nbytes) {return tmcDev->FinishRead(msg, nbytes);} 15 | 16 | // Main API 17 | 18 | void Reset() {Cmd("*RST");} 19 | 20 | // "RAW" mode requires STOP state (?) 21 | // "MAX" mode: same as NOR when in RUN state, same as RAW in STOP state. 22 | // 23 | // (short mem) (long mem) 24 | // NOR RAW RAW 25 | // 26 | // MATH 600 600 600 27 | // FFT 512 512 512 28 | // CHx 600 8192 524288 29 | // HCHx 600 16384 1048576 30 | // DIGITAL 600 600 600 31 | std::string CurrentMode() {return Query(":WAV:POIN:MODE?");} 32 | void NormalMode() {Cmd(":WAV:POIN:MODE NOR");} 33 | void RawMode() {Cmd(":WAV:POIN:MODE RAW");} 34 | void MaxMode() {Cmd(":WAV:POIN:MODE MAX");} 35 | 36 | void WaveData(std::vector & resp, int channel, size_t maxSize = 1024*1024) { 37 | CmdF(":WAV:DATA? CHAN%c", '1' + channel); 38 | TMC_Device::Read(resp, maxSize); 39 | } 40 | 41 | 42 | double SampleRateDigital() {return FloatQuery(":ACQ:SAMP? DIGITAL");} 43 | double SampleRate(int channel) {return FloatQuery(":ACQ:SAMP? CHAN%c", '1' + channel);} 44 | 45 | double ChanScale(int channel) {return FloatQuery(":CHAN%c:SCAL?", '1' + channel);} 46 | double ChanOffset(int channel) {return FloatQuery(":CHAN%c:OFFS?", '1' + channel);} 47 | 48 | double TimeScale() {return FloatQuery(":TIM:SCAL?");} 49 | double TimeOffset() {return FloatQuery(":TIM:OFFS?");} 50 | 51 | void Run() {Cmd(":RUN");} 52 | void Stop() {Cmd(":STOP");} 53 | void Auto() {Cmd(":AUTO");} 54 | void HardCopy() {Cmd(":HARD");} 55 | void Force() {Cmd(":FORC");} 56 | 57 | void Beep() {Cmd(":BEEP:ACT");} 58 | 59 | void KeyLock(bool locked) {Cmd((locked) ? ":KEY:LOCK ENAB" : ":KEY:LOCK DIS");} 60 | void KeyRun() {Cmd(":KEY:RUN");} 61 | }; 62 | 63 | #endif // RIGOLTMC_H 64 | -------------------------------------------------------------------------------- /scopecmd/src/rigolwfm.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef RIGOLWFM_H 3 | #define RIGOLWFM_H 4 | 5 | // Based on code from http://www.mathworks.com/matlabcentral/fileexchange/18999-read-binary-rigol-waveforms 6 | // and file format information derived from http://meteleskublesku.cz/wfm_view/file_wfm.zip 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "units.h" 16 | #include "sigproc.h" 17 | 18 | namespace rigwfm { 19 | 20 | class Rigol_Exception: public std::exception { 21 | protected: 22 | std::string msg; 23 | public: 24 | Rigol_Exception(const std::string & m): msg(m) {} 25 | virtual ~Rigol_Exception() throw() {} 26 | virtual const char* what() const throw() {return msg.c_str();} 27 | }; 28 | 29 | 30 | enum trig_t { 31 | kEdgeTrigger = 0x0000, 32 | kPulseTrigger = 0x0101, 33 | kSlopeTrigger = 0x0202, 34 | kVideoTrigger = 0x0303, 35 | kAltTrigger = 0x0004,// Not 0404? 36 | kPatternTrigger = 0x0505, 37 | kDurationTrigger = 0x0606 38 | }; 39 | enum trigsrc_t { 40 | // if triggersource == 0 41 | // trigger.source = 'ch1'; 42 | // elseif triggersource == 1 43 | // trigger.source = 'ch2'; 44 | // elseif triggersource == 2 45 | // trigger.source = 'ext'; 46 | // elseif triggersource == 3 47 | // trigger.source = 'ext/5'; 48 | // elseif triggersource == 5 49 | // trigger.source = 'acLine'; 50 | // elseif triggersource == 7 51 | // trigger.source = 'dig.ch'; 52 | // else 53 | }; 54 | 55 | struct RigolData { 56 | double scale;// Volts/div 57 | double offset;// Volts 58 | double scale2;// Volts/div, apparently identical to scale 59 | double offset2;// Volts, apparently identical to offset 60 | double attenuation;// Dimensionless 61 | bool inverted; 62 | bool inverted2; 63 | std::vector data;// Volts, with scaling, offset, and attenuation accounted for 64 | // WARNING: first 4 samples appear to be garbage 65 | 66 | RigolData(): 67 | scale(1), 68 | offset(0), 69 | attenuation(1), 70 | inverted(false) 71 | {} 72 | 73 | friend std::ostream & operator<<(std::ostream & ostrm, const RigolData & data); 74 | }; 75 | 76 | // 77 | struct RigolWaveform { 78 | uint32_t npoints; // Number of data points 79 | double tscale;// time per div, seconds 80 | double tdelay;// time delay, seconds 81 | double fs;// sample frequency, Hz 82 | double duration;// Total waveform time, seconds 83 | 84 | double scaleM; 85 | double delayM; 86 | 87 | trig_t trigger; 88 | trigsrc_t triggerSource; 89 | 90 | RigolData channels[2]; 91 | 92 | RigolWaveform(const std::string & fpath); 93 | void ReadChannelInfo(int ch, size_t dataLoc, FILE * fin); 94 | 95 | friend std::ostream & operator<<(std::ostream & ostrm, const RigolWaveform & waveform); 96 | }; 97 | 98 | template 99 | void freadpp(T & val, size_t offset, FILE * fin) { 100 | fseek(fin, offset, SEEK_SET); 101 | fread(&val, sizeof(T), 1, fin); 102 | } 103 | template 104 | void freadpp(T & val, size_t offset, size_t num, FILE * fin) { 105 | fseek(fin, offset, SEEK_SET); 106 | fread(&val, sizeof(T), num, fin); 107 | } 108 | 109 | inline RigolWaveform::RigolWaveform(const std::string & fpath): 110 | tscale(1), 111 | tdelay(0), 112 | duration(0) 113 | { 114 | FILE * fin = fopen(fpath.c_str(), "r"); 115 | if(!fin) 116 | throw Rigol_Exception("File doesn't exist"); 117 | 118 | uint8_t checkbytes[2]; 119 | freadpp(checkbytes, 0, 2, fin); 120 | if(checkbytes[0] != 165 ||checkbytes[1] != 165) 121 | { 122 | fclose(fin); 123 | throw Rigol_Exception("Not Rigol waveform file"); 124 | } 125 | 126 | uint8_t ch1enab, ch2enab; 127 | uint64_t tscaleI; 128 | int64_t tdelayI; 129 | int64_t scaleMI; 130 | int64_t delayMI; 131 | float fsF; 132 | uint16_t triggerI; 133 | uint16_t triggerSrcI; 134 | 135 | freadpp(npoints, 28, fin); 136 | freadpp(ch1enab, 49, fin); 137 | freadpp(ch2enab, 73, fin); 138 | 139 | freadpp(tscaleI, 84, fin); 140 | freadpp(tdelayI, 92, fin); 141 | freadpp(fsF, 100, fin); 142 | freadpp(scaleM, 104, fin); 143 | freadpp(delayM, 112, fin); 144 | 145 | freadpp(triggerI, 142, fin); 146 | freadpp(triggerSrcI, 144, fin); 147 | 148 | tscale = tscaleI*1e-12; 149 | tdelay = tdelayI*1e-12; 150 | duration = tscale*12;// time per div*12 divs 151 | fs = fsF; 152 | scaleM = scaleMI*1e-12; 153 | delayM = delayMI*1e-12; 154 | 155 | trigger = (trig_t)triggerI; 156 | triggerSource = (trigsrc_t)triggerSrcI; 157 | 158 | size_t dataLoc = 272; 159 | if(ch1enab == 1) { 160 | ReadChannelInfo(0, dataLoc, fin); 161 | dataLoc += npoints; 162 | } 163 | if(ch2enab == 1) { 164 | ReadChannelInfo(1, dataLoc, fin); 165 | } 166 | 167 | fclose(fin); 168 | } 169 | 170 | inline void RigolWaveform::ReadChannelInfo(int ch, size_t dataLoc, FILE * fin) 171 | { 172 | RigolData & channel = channels[ch]; 173 | size_t base = (ch == 0)? 36 : 60; 174 | 175 | int32_t scale; 176 | int16_t offset; 177 | uint16_t attenuation; 178 | uint8_t inverted; 179 | uint8_t inverted2; 180 | int32_t scale2; 181 | int16_t offset2; 182 | freadpp(scale, base, fin); 183 | freadpp(offset, base + 4, fin); 184 | freadpp(attenuation, base + 10, fin); 185 | freadpp(inverted, base + 12, fin); 186 | freadpp(inverted2, base + 14, fin); 187 | freadpp(scale2, base + 16, fin); 188 | freadpp(offset2, base + 20, fin); 189 | 190 | if(attenuation == 0x3F80) 191 | channel.attenuation = 1; 192 | else if(attenuation == 0x4120) 193 | channel.attenuation = 10; 194 | else if(attenuation == 0x42C8) 195 | channel.attenuation = 100; 196 | else if(attenuation == 0x447A) 197 | channel.attenuation = 1000; 198 | else { 199 | fclose(fin); 200 | throw Rigol_Exception("Bad attenuation value"); 201 | } 202 | 203 | channel.scale = scale*1e-6*channel.attenuation; 204 | channel.offset = offset/250.0*channel.attenuation; 205 | channel.scale2 = scale2*1e-6*channel.attenuation; 206 | channel.offset2 = offset2/250.0*channel.attenuation; 207 | 208 | channel.inverted = inverted; 209 | channel.inverted2 = inverted2; 210 | 211 | std::vector data(npoints, 255); 212 | freadpp(data[0], dataLoc, npoints, fin); 213 | 214 | channel.data.resize(npoints); 215 | for(int j = 0; j < npoints; ++j) 216 | channel.data[j] = ((125.0 - (float)data[j])/250.0f*channel.scale)*10.0 - channel.offset; 217 | } 218 | 219 | inline std::ostream & operator<<(std::ostream & ostrm, const RigolWaveform & waveform) 220 | { 221 | ostrm << "tscale: " << FmtSec(waveform.tscale) 222 | << ", tdelay: " << FmtSec(waveform.tdelay) 223 | << ", fs: " << FmtHz(waveform.fs) << std::endl; 224 | ostrm << "duration: " << FmtSec(waveform.duration) << std::endl; 225 | ostrm << "npoints: " << waveform.npoints << std::endl; 226 | ostrm << "scaleM: " << waveform.scaleM << std::endl; 227 | ostrm << "delayM: " << waveform.delayM << std::endl; 228 | ostrm << "trigger: " << waveform.trigger << ", trigger source: " << waveform.triggerSource << std::endl; 229 | 230 | if(waveform.channels[0].data.empty() && waveform.channels[1].data.empty()) 231 | ostrm << "no channels enabled" << std::endl; 232 | if(!waveform.channels[0].data.empty() && waveform.channels[1].data.empty()) 233 | ostrm << "channel 1" << std::endl; 234 | if(waveform.channels[0].data.empty() && !waveform.channels[1].data.empty()) 235 | ostrm << "channel 2" << std::endl; 236 | if(!waveform.channels[0].data.empty() && !waveform.channels[1].data.empty()) 237 | ostrm << "channels 1 and 2" << std::endl; 238 | 239 | ostrm << std::endl << "channel 1:" << std::endl << waveform.channels[0]; 240 | ostrm << std::endl << "channel 2:" << std::endl << waveform.channels[1]; 241 | return ostrm; 242 | } 243 | 244 | inline std::ostream & operator<<(std::ostream & ostrm, const RigolData & data) 245 | { 246 | ostrm << "scale: " << data.scale << std::endl; 247 | ostrm << "offset: " << data.offset << std::endl; 248 | ostrm << "scale2: " << data.scale2 << std::endl; 249 | ostrm << "offset2: " << data.offset2 << std::endl; 250 | ostrm << "attenuation: " << data.attenuation << std::endl; 251 | ostrm << "inverted: " << data.inverted << std::endl; 252 | ostrm << "inverted2: " << data.inverted2 << std::endl; 253 | return ostrm; 254 | } 255 | 256 | 257 | } // namespace rigwfm 258 | #endif // RIGOLWFM_H 259 | -------------------------------------------------------------------------------- /scopecmd/src/rigwfm.cpp: -------------------------------------------------------------------------------- 1 | // g++ `GraphicsMagick++-config --cxxflags --cppflags --ldflags --libs` rigwfm.cpp -o rigwfm 2 | // for i in *.wfm; do ./rigwfm ${i} ${i}.png; done 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #include "rigolwfm.h" 18 | 19 | using namespace std; 20 | using namespace rigwfm; 21 | using namespace Magick; 22 | 23 | // Ternary value type 24 | // 0: false, 1: true, -1: neither (undefined boolean value) 25 | typedef int8_t tern_t; 26 | 27 | const tern_t unknown = -1; 28 | 29 | 30 | struct PlotOpts { 31 | int smoothing; 32 | double startT, endT;// start and end time referenced from start, in sample periods 33 | tern_t ch1enab; 34 | tern_t ch2enab; 35 | 36 | PlotOpts(): 37 | smoothing(1), 38 | startT(DBL_MIN), 39 | endT(DBL_MAX), 40 | ch1enab(unknown), 41 | ch2enab(unknown) 42 | {} 43 | }; 44 | 45 | 46 | // Plot waveform as DrawablePolyline 47 | // smoothing: n consecutive points are averaged together to do a simple low pass filter 48 | void PlotChannel(Image & image, std::list & drawList, const PlotOpts & opts, const RigolData & channel); 49 | void PlotWaveform(const std::string foutPath, const PlotOpts & opts, const RigolWaveform & wfm); 50 | void PlotGrid(Image & image, std::list & drawList, const PlotOpts & opts, const RigolWaveform & wfm); 51 | 52 | void ParseOpts(PlotOpts & opts, int argc, const char * argv[]); 53 | 54 | int main(int argc, const char * argv[]) 55 | { 56 | if(argc < 3) 57 | { 58 | cerr << "Usage: rigwfm WAVEFORM_FILE IMAGE_FILE"; 59 | return EXIT_FAILURE; 60 | } 61 | 62 | InitializeMagick(*argv); 63 | 64 | try { 65 | PlotOpts opts; 66 | opts.smoothing = 4; 67 | 68 | ParseOpts(opts, argc, argv); 69 | 70 | RigolWaveform waveform(argv[1]); 71 | cout << waveform << endl; 72 | 73 | if(opts.ch1enab == unknown) opts.ch1enab = !waveform.channels[0].data.empty(); 74 | if(opts.ch2enab == unknown) opts.ch1enab = !waveform.channels[1].data.empty(); 75 | 76 | PlotWaveform(argv[2], opts, waveform); 77 | } 78 | catch(exception & err) 79 | { 80 | cout << "Caught exception: " << err.what() << endl; 81 | return EXIT_FAILURE; 82 | } 83 | 84 | return EXIT_SUCCESS; 85 | } 86 | 87 | static const char * optString = "Il:o:vh?"; 88 | static const struct option longOpts[] = { 89 | {"plot", no_argument, NULL, 'p'}, 90 | {"smoothing", required_argument, NULL, 0}, 91 | {"tstart", required_argument, NULL, 0}, 92 | {"tend", required_argument, NULL, 0}, 93 | {"tcenter", required_argument, NULL, 0}, 94 | {"file", required_argument, NULL, 'f'}, 95 | {NULL, 0, NULL, 0} 96 | }; 97 | void ParseOpts(PlotOpts & opts, int argc, const char * argv[]) 98 | { 99 | int renderPlot = 0; 100 | int opt, optInd = 0; 101 | do { 102 | opt = getopt_long(argc, argv, optString, longOpts, &optInd); 103 | // optarg, optind, optopt 104 | switch(opt) { 105 | case p: 106 | break; 107 | 108 | case 0: 109 | if(strcmp("randomize", longOpts[longIndex].name) == 0) { 110 | globalArgs.randomized = 1; 111 | } 112 | break 113 | 114 | case -1: 115 | break; 116 | } 117 | } while(opt != -1); 118 | } 119 | 120 | 121 | void PlotWaveform(const std::string foutPath, const PlotOpts & opts, const RigolWaveform & wfm) 122 | { 123 | // Image image = Image("1024x512", "white"); 124 | Image image = Image("2048x512", "white"); 125 | 126 | std::list drawList; 127 | drawList.push_back(DrawablePushGraphicContext()); 128 | drawList.push_back(DrawableViewbox(0, 0, image.columns(), image.rows())); 129 | 130 | drawList.push_back(DrawableFillColor(Color())); 131 | 132 | PlotGrid(image, drawList, opts, wfm); 133 | 134 | drawList.push_back(DrawableStrokeWidth(1.0)); 135 | if(opts.ch1enab) { 136 | drawList.push_back(DrawableStrokeColor("#F00")); 137 | PlotChannel(image, drawList, opts, wfm.channels[0]); 138 | } 139 | if(opts.ch1enab) { 140 | drawList.push_back(DrawableStrokeColor("#00F")); 141 | PlotChannel(image, drawList, opts, wfm.channels[1]); 142 | } 143 | 144 | // opts.startT = wfm.npoints/2.0 - 6*50e-6*wfm.fs; 145 | // opts.endT = wfm.npoints/2.0 - 5*50e-6*wfm.fs;; 146 | // // opts.startT = wfm.npoints/2.0 - 6*5e-3*wfm.fs; 147 | // // opts.endT = wfm.npoints/2.0 + 0; 148 | // // opts.endT = wfm.npoints/2.0 + 6*5e-3*wfm.fs; 149 | // drawList.push_back(DrawableStrokeColor("#0B0")); 150 | // PlotChannel(image, drawList, opts, wfm.channels[0]); 151 | 152 | drawList.push_back(DrawablePopGraphicContext()); 153 | 154 | image.draw(drawList); 155 | image.write(std::string(foutPath)); 156 | } 157 | 158 | void PlotGrid(Image & image, std::list & drawList, const PlotOpts & opts, const RigolWaveform & wfm) 159 | { 160 | // Vertical rules 161 | // Trigger delay, etc are referenced from the midpoint of the captured waveform 162 | double midT = wfm.npoints/2.0/wfm.fs; 163 | double vrule; 164 | drawList.push_back(DrawableStrokeColor("#444")); 165 | for(int j = 1; j < 6; ++j) { 166 | vrule = wfm.fs*(midT - wfm.tscale*j)*image.columns()/wfm.npoints; 167 | drawList.push_back(DrawableLine(vrule, 0, vrule, image.rows())); 168 | vrule = wfm.fs*(midT + wfm.tscale*j)*image.columns()/wfm.npoints; 169 | drawList.push_back(DrawableLine(vrule, 0, vrule, image.rows())); 170 | } 171 | drawList.push_back(DrawableStrokeWidth(0.5)); 172 | drawList.push_back(DrawableStrokeColor("#AAA")); 173 | for(int j = 1; j < 7; ++j) { 174 | for(int k = 1; k < 5; ++k) { 175 | vrule = wfm.fs*(midT - wfm.tscale*(j - k/5.0))*image.columns()/wfm.npoints; 176 | drawList.push_back(DrawableLine(vrule, 0, vrule, image.rows())); 177 | vrule = wfm.fs*(midT + wfm.tscale*(j - k/5.0))*image.columns()/wfm.npoints; 178 | drawList.push_back(DrawableLine(vrule, 0, vrule, image.rows())); 179 | } 180 | } 181 | 182 | drawList.push_back(DrawableStrokeWidth(2.0)); 183 | drawList.push_back(DrawableStrokeColor("#000")); 184 | vrule = wfm.fs*(midT - wfm.tscale*6)*image.columns()/wfm.npoints; 185 | drawList.push_back(DrawableLine(vrule, 0, vrule, image.rows())); 186 | vrule = wfm.fs*midT*image.columns()/wfm.npoints; 187 | drawList.push_back(DrawableLine(vrule, 0, vrule, image.rows())); 188 | vrule = wfm.fs*(midT + wfm.tscale*6)*image.columns()/wfm.npoints; 189 | drawList.push_back(DrawableLine(vrule, 0, vrule, image.rows())); 190 | 191 | // Trigger position 192 | drawList.push_back(DrawableStrokeWidth(1.0)); 193 | drawList.push_back(DrawableStrokeColor("#990")); 194 | vrule = wfm.fs*(midT - wfm.tdelay)*image.columns()/wfm.npoints; 195 | drawList.push_back(DrawableLine(vrule, 0, vrule, image.rows())); 196 | 197 | // Horizontal rules 198 | double hrule; 199 | drawList.push_back(DrawableStrokeColor("#444")); 200 | for(int j = 1; j < 4; ++j) { 201 | hrule = image.rows() - (4 - j)*(image.rows()/8.0); 202 | drawList.push_back(DrawableLine(0, hrule, image.columns(), hrule)); 203 | hrule = image.rows() - (4 + j)*(image.rows()/8.0); 204 | drawList.push_back(DrawableLine(0, hrule, image.columns(), hrule)); 205 | } 206 | drawList.push_back(DrawableStrokeWidth(0.5)); 207 | drawList.push_back(DrawableStrokeColor("#AAA")); 208 | for(int j = 1; j < 5; ++j) { 209 | for(int k = 1; k < 5; ++k) { 210 | hrule = image.rows() - (4 + k/5.0 - j)*(image.rows()/8.0); 211 | drawList.push_back(DrawableLine(0, hrule, image.columns(), hrule)); 212 | hrule = image.rows() - (4 - k/5.0 + j)*(image.rows()/8.0); 213 | drawList.push_back(DrawableLine(0, hrule, image.columns(), hrule)); 214 | } 215 | } 216 | 217 | drawList.push_back(DrawableStrokeWidth(2.0)); 218 | drawList.push_back(DrawableStrokeColor("#000")); 219 | hrule = image.rows() - (4)*(image.rows()/8.0); 220 | drawList.push_back(DrawableLine(0, hrule, image.columns(), hrule)); 221 | hrule = image.rows() - (0)*(image.rows()/8.0); 222 | drawList.push_back(DrawableLine(0, hrule, image.columns(), hrule)); 223 | hrule = image.rows() - (8)*(image.rows()/8.0); 224 | drawList.push_back(DrawableLine(0, hrule, image.columns(), hrule)); 225 | } 226 | 227 | void PlotChannel(Image & image, std::list & drawList, const PlotOpts & opts, const RigolData & channel) 228 | { 229 | double width = image.columns(), height = image.rows(); 230 | 231 | double startT = (opts.startT != DBL_MIN)? opts.startT : 0.0; 232 | double endT = (opts.endT != DBL_MAX)? opts.endT : channel.data.size(); 233 | 234 | std::list vertices; 235 | double yscl = height/8.0/channel.scale; 236 | double yoff = channel.offset; 237 | size_t npts = endT - startT; 238 | if(width >= npts) 239 | { 240 | double dx = (double)npts/width; 241 | for(int j = 0; j < width; ++j) { 242 | double y = SincReconstruct(channel.data, (float)j*dx + startT, 64); 243 | vertices.push_back(Coordinate(j, height/2 - (y + yoff)*yscl)); 244 | } 245 | } 246 | else 247 | { 248 | for(int j = std::max(0, (int)floor(startT)); (j + opts.smoothing) <= channel.data.size(); j += opts.smoothing) { 249 | double y = 0; 250 | for(int k = 0; k < opts.smoothing; ++k) 251 | y += channel.data[j + k]; 252 | y /= opts.smoothing; 253 | vertices.push_back(Coordinate(((double)j - startT)/npts*width, height/2 - (y + yoff)*yscl)); 254 | } 255 | } 256 | drawList.push_back(DrawablePolyline(vertices)); 257 | } 258 | 259 | -------------------------------------------------------------------------------- /scopecmd/src/simple_except.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SIMPLE_EXCEPT_H 3 | #define SIMPLE_EXCEPT_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | #if(1) 12 | #define FORMATTED_ERROR_CONS \ 13 | va_list ap; \ 14 | va_start(ap, format); \ 15 | char * fstr; \ 16 | vasprintf(&fstr, format.c_str(), ap); \ 17 | if(fstr != NULL) { \ 18 | msg = fstr; \ 19 | free(fstr); \ 20 | } \ 21 | va_end(ap); 22 | #else 23 | #define FORMATTED_ERROR_CONS \ 24 | va_list ap; \ 25 | va_start(ap, format); \ 26 | char fstr[1024]; \ 27 | vsnprintf(fstr, 1024, format.c_str(), ap); \ 28 | msg = fstr; \ 29 | va_end(ap); 30 | #endif 31 | 32 | class FormattedError: public std::exception { 33 | protected: 34 | std::string msg; 35 | public: 36 | FormattedError(const std::string & format, ...) {FORMATTED_ERROR_CONS} 37 | virtual ~FormattedError() throw() {} 38 | virtual const char* what() const throw() {return msg.c_str();} 39 | }; 40 | 41 | #define FORMATTED_ERROR_CLASS(className, superClassName) \ 42 | class className: public superClassName { \ 43 | protected: \ 44 | std::string msg; \ 45 | public: \ 46 | className(const std::string & format, ...) {FORMATTED_ERROR_CONS} \ 47 | virtual ~className() throw() {} \ 48 | virtual const char* what() const throw() {return msg.c_str();} \ 49 | }; 50 | 51 | #endif // SIMPLE_EXCEPT_H 52 | -------------------------------------------------------------------------------- /sigrok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ebiroll/esp32_sigrok/cb8852eddf003c1938a9311f3d459f3b16454b0a/sigrok.png -------------------------------------------------------------------------------- /sigrok_build/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 2.8.12) 3 | 4 | include(GNUInstallDirs) 5 | 6 | project(olas-cli) 7 | 8 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake") 9 | 10 | #=============================================================================== 11 | #= User Options 12 | #------------------------------------------------------------------------------- 13 | 14 | option(DISABLE_WERROR "Build without -Werror" FALSE) 15 | 16 | if(NOT CMAKE_BUILD_TYPE) 17 | set(CMAKE_BUILD_TYPE Debug CACHE STRING 18 | "Choose the type of build (None, Debug, Release, RelWithDebInfo, MinSizeRel)." 19 | FORCE) 20 | endif() 21 | 22 | #=============================================================================== 23 | #= Dependencies 24 | #------------------------------------------------------------------------------- 25 | 26 | #list(APPEND PKGDEPS glib-2.0>=2.28.0) 27 | #list(APPEND PKGDEPS glibmm-2.4>=2.28.0) 28 | #list(APPEND PKGDEPS libsigrokcxx>=0.6.0) 29 | 30 | if(ENABLE_DECODE) 31 | list(APPEND PKGDEPS libsigrokdecode>=0.6.0) 32 | endif() 33 | 34 | 35 | # Find the platform's thread library (needed for C++11 threads). 36 | # This will set ${CMAKE_THREAD_LIBS_INIT} to the correct, OS-specific value. 37 | find_package(Threads REQUIRED) 38 | 39 | list(APPEND PKGDEPS glib-2.0>=2.28.0) 40 | 41 | #=============================================================================== 42 | #= Sources 43 | #------------------------------------------------------------------------------- 44 | 45 | include_directories( 46 | #sigrok-cli 47 | /usr/include/glib-2.0 48 | /usr/lib/glib-2.0/include 49 | /usr/include/libusb-1.0/ 50 | libsigrok/src/ 51 | /usr/include/tirpc 52 | libsigrok 53 | libsigrok/include/libsigrok/ 54 | /usr/include/libftdi1 55 | ) 56 | 57 | set(sigrok_SOURCES 58 | libsigrok/src/transform/invert.c 59 | libsigrok/src/transform/nop.c 60 | libsigrok/src/transform/scale.c 61 | libsigrok/src/transform/transform.c 62 | libsigrok/src/analog.c 63 | libsigrok/src/backend.c 64 | libsigrok/src/conversion.c 65 | libsigrok/src/device.c 66 | libsigrok/src/drivers.c 67 | libsigrok/src/error.c 68 | libsigrok/src/ezusb.c 69 | libsigrok/src/fallback.c 70 | libsigrok/src/hwdriver.c 71 | libsigrok/src/log.c 72 | libsigrok/src/resource.c 73 | libsigrok/src/serial.c 74 | libsigrok/src/serial_hid.c 75 | libsigrok/src/serial_libsp.c 76 | # If you do not have bluez, remove these 77 | libsigrok/src/serial_bt.c 78 | libsigrok/src/bt/bt_bluez.c 79 | 80 | libsigrok/src/session.c 81 | libsigrok/src/session_driver.c 82 | libsigrok/src/session_file.c 83 | libsigrok/src/soft-trigger.c 84 | libsigrok/src/std.c 85 | libsigrok/src/strutil.c 86 | libsigrok/src/sw_limits.c 87 | libsigrok/src/trigger.c 88 | libsigrok/src/usb.c 89 | libsigrok/src/version.c 90 | libsigrok/src/input/binary.c 91 | libsigrok/src/input/chronovu_la8.c 92 | libsigrok/src/input/csv.c 93 | libsigrok/src/input/input.c 94 | libsigrok/src/input/logicport.c 95 | libsigrok/src/input/raw_analog.c 96 | libsigrok/src/input/trace32_ad.c 97 | libsigrok/src/input/wav.c 98 | libsigrok/src/input/vcd.c 99 | libsigrok/src/input/null.c 100 | #libsigrok/src/scpi/helpers.c 101 | libsigrok/src/scpi/scpi.c 102 | #libsigrok/src/scpi/scpi_libgpib.c 103 | libsigrok/src/scpi/scpi_serial.c 104 | libsigrok/src/scpi/scpi_tcp.c 105 | libsigrok/src/scpi/scpi_usbtmc_libusb.c 106 | #libsigrok/src/scpi/scpi_visa.c 107 | libsigrok/src/scpi/scpi_vxi.c 108 | libsigrok/src/scpi/vxi_clnt.c 109 | libsigrok/src/scpi/vxi_xdr.c 110 | libsigrok/src/output/analog.c 111 | libsigrok/src/output/ascii.c 112 | libsigrok/src/output/binary.c 113 | libsigrok/src/output/bits.c 114 | libsigrok/src/output/chronovu_la8.c 115 | libsigrok/src/output/csv.c 116 | libsigrok/src/output/hex.c 117 | libsigrok/src/output/ols.c 118 | libsigrok/src/output/wavedrom.c 119 | libsigrok/src/output/output.c 120 | libsigrok/src/output/srzip.c 121 | libsigrok/src/output/wav.c 122 | libsigrok/src/output/vcd.c 123 | libsigrok/src/output/null.c 124 | libsigrok/src/modbus/modbus.c 125 | libsigrok/src/modbus/modbus_serial_rtu.c 126 | libsigrok/src/driver_list_start.c 127 | libsigrok/src/hardware/openbench-logic-sniffer/api.c 128 | libsigrok/src/hardware/openbench-logic-sniffer/protocol.c 129 | libsigrok/src/hardware/rigol-ds/api.c 130 | libsigrok/src/hardware/rigol-ds/protocol.c 131 | libsigrok/src/hardware/pipistrello-ols/api.c 132 | libsigrok/src/hardware/pipistrello-ols/protocol.c 133 | libsigrok/src/driver_list_stop.c 134 | ) 135 | 136 | set(cli_SOURCES 137 | sigrok-cli/anykey.c 138 | sigrok-cli/decode.c 139 | sigrok-cli/device.c 140 | sigrok-cli/input.c 141 | sigrok-cli/main.c 142 | sigrok-cli/options.c 143 | sigrok-cli/parsers.c 144 | sigrok-cli/session.c 145 | sigrok-cli/output.c 146 | sigrok-cli/show.c 147 | ) 148 | 149 | 150 | #=============================================================================== 151 | #= Global Definitions 152 | #------------------------------------------------------------------------------- 153 | 154 | add_definitions(-DQT_NO_KEYWORDS) 155 | add_definitions(-D__STDC_LIMIT_MACROS) 156 | add_definitions(-DSC_PACKAGE_VERSION_STRING="test ver") 157 | add_definitions(-Wall -Wextra) 158 | #add_definitions(-std=c++11) 159 | 160 | if(ENABLE_DECODE) 161 | add_definitions(-DENABLE_DECODE) 162 | endif() 163 | 164 | #if(NOT DISABLE_WERROR) 165 | # add_definitions(-Werror) 166 | #endif() 167 | 168 | if(ENABLE_SIGNALS) 169 | add_definitions(-DENABLE_SIGNALS) 170 | endif() 171 | 172 | #=============================================================================== 173 | #= Global Include Directories 174 | #------------------------------------------------------------------------------- 175 | 176 | #include_directories( 177 | # ${CMAKE_CURRENT_BINARY_DIR} 178 | # ${CMAKE_CURRENT_SOURCE_DIR} 179 | #) 180 | 181 | add_executable(olas-cli 182 | ${cli_SOURCES} 183 | ${sigrok_SOURCES} 184 | ) 185 | 186 | target_link_libraries(olas-cli rt tirpc pthread usb-1.0 serialport glib-2.0 m zip ftdi1) 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /sump_uart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ebiroll/esp32_sigrok/cb8852eddf003c1938a9311f3d459f3b16454b0a/sump_uart.png -------------------------------------------------------------------------------- /toflash.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | // 4 | // qemu_toflash 5 | // 6 | // python /home/olas/esp/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 7 | // 0x1000 /home/olas/esp/esp-idf/examples/system/ota/build/bootloader/bootloader.bin 8 | // 0x10000 /home/olas/esp/esp-idf/examples/system/ota/build/ota.bin 9 | // 0x8000 /home/olas/esp/esp-idf/examples/system/ota/build/partitions_two_ota.bin 10 | // 11 | 12 | void merge_flash(char *binfile,char *flashfile,int flash_pos,int patch_hash) 13 | { 14 | FILE *fbin; 15 | FILE *fflash; 16 | unsigned char *tmp_data; 17 | int j=0; 18 | 19 | int file_size=0; 20 | int flash_size=0; 21 | 22 | fbin = fopen(binfile, "rb"); 23 | if (fbin == NULL) { 24 | printf(" Can't open '%s' for reading.\n", binfile); 25 | return; 26 | } 27 | 28 | if (fseek(fbin, 0 , SEEK_END) != 0) { 29 | /* Handle Error */ 30 | } 31 | file_size = ftell(fbin); 32 | 33 | if (fseek(fbin, 0 , SEEK_SET) != 0) { 34 | /* Handle Error */ 35 | } 36 | 37 | fflash = fopen(flashfile, "rb+"); 38 | if (fflash == NULL) { 39 | printf(" Can't open '%s' for writing.\n", flashfile); 40 | return; 41 | } 42 | if (fseek(fflash, 0 , SEEK_END) != 0) { 43 | /* Handle Error */ 44 | } 45 | flash_size = ftell(fflash); 46 | rewind(fflash); 47 | fseek(fflash,flash_pos,SEEK_SET); 48 | 49 | 50 | tmp_data=malloc((1+file_size)*sizeof(char)); 51 | 52 | if (file_size<=0) { 53 | printf("Not able to get file size %s",binfile); 54 | } 55 | 56 | int len_read=fread(tmp_data,sizeof(char),file_size,fbin); 57 | 58 | if (patch_hash==1) { 59 | for (j=0;j<33;j++) 60 | { 61 | tmp_data[file_size-j]=0; 62 | } 63 | } 64 | 65 | 66 | int len_write=fwrite(tmp_data,sizeof(char),file_size,fflash); 67 | 68 | if (len_read!=len_write) { 69 | printf("Not able to merge %s",binfile); 70 | } 71 | 72 | fclose(fbin); 73 | 74 | if (fseek(fflash, 0x3E8000*4 , SEEK_SET) != 0) { 75 | } 76 | 77 | fclose(fflash); 78 | 79 | free(tmp_data); 80 | } 81 | 82 | 83 | int main(int argc,char *argv[]) 84 | { 85 | 86 | // Overwrites esp32flash.bin file 87 | system("dd if=/dev/zero bs=1M count=4 | tr \"\\000\" \"\\377\" > esp32flash.bin"); 88 | 89 | // Add bootloader 90 | merge_flash("build/bootloader/bootloader.bin","esp32flash.bin",0x1000,0); 91 | // Add partitions, test OTA here 92 | //merge_flash("build/partitions_two_ota.bin","esp32flash.bin",0x8000,0); 93 | merge_flash("build/partition_table/partition-table.bin","esp32flash.bin",0x8000,0); 94 | // Add application 95 | merge_flash(argv[1],"esp32flash.bin",0x10000,0); 96 | 97 | system("cp esp32flash.bin ~/qemu_esp32"); 98 | } 99 | 100 | -------------------------------------------------------------------------------- /uart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ebiroll/esp32_sigrok/cb8852eddf003c1938a9311f3d459f3b16454b0a/uart.png --------------------------------------------------------------------------------