├── software ├── libcariboulite │ ├── .gitignore │ ├── src │ │ ├── soapy_api │ │ │ ├── README.md │ │ │ ├── CaribouliteSession.cpp │ │ │ └── CaribouliteSensors.cpp │ │ ├── hat │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── test_hat.c │ │ │ ├── CMakeLists.txt │ │ │ └── eeprom_utils.h │ │ ├── at86rf215 │ │ │ ├── .gitignore │ │ │ ├── CMakeLists.txt │ │ │ └── at86rf215.h │ │ ├── datatypes │ │ │ ├── .gitignore │ │ │ ├── circular_buffer.cpp │ │ │ ├── entropy.h │ │ │ ├── test_tiny_list.c │ │ │ ├── tiny_stack.h │ │ │ ├── tiny_queue.h │ │ │ ├── test_circular_buffer.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── entropy.c │ │ │ ├── tiny_list.h │ │ │ └── test_tsqueue.c │ │ ├── io_utils │ │ │ ├── .gitignore │ │ │ ├── io_utils_i2c.h │ │ │ ├── io_utils_fs.h │ │ │ ├── io_utils_sys_info.h │ │ │ ├── CMakeLists.txt │ │ │ ├── io_utils.h │ │ │ ├── io_utils_spi.h │ │ │ ├── io_utils_i2c.c │ │ │ └── rpi │ │ │ │ └── rpi.h │ │ ├── rffc507x │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── CMakeLists.txt │ │ │ └── test_rffc507x.c │ │ ├── zf_log │ │ │ ├── .gitignore │ │ │ ├── CMakeLists.txt │ │ │ └── zf_log_config.h │ │ ├── caribou_fpga │ │ │ ├── .gitignore │ │ │ └── CMakeLists.txt │ │ ├── caribou_smi │ │ │ ├── .gitignore │ │ │ ├── kernel │ │ │ │ ├── .gitignore │ │ │ │ └── README.md │ │ │ ├── CMakeLists.txt │ │ │ ├── smi_utils.h │ │ │ ├── caribou_smi_modules.c │ │ │ └── caribou_smi.h │ │ ├── caribou_programming │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── CMakeLists.txt │ │ │ └── caribou_prog.h │ │ ├── production_utils │ │ │ ├── .gitignore │ │ │ ├── production_utils.h │ │ │ ├── test_lcd.c │ │ │ ├── hat_powermon_test.c │ │ │ ├── python │ │ │ │ ├── usblcd.py │ │ │ │ └── lcd_task.py │ │ │ ├── CMakeLists.txt │ │ │ ├── lcd.h │ │ │ ├── hat_powermon.h │ │ │ └── production_testing.h │ │ ├── cariboulite_events.c │ │ ├── cariboulite_events.h │ │ ├── cariboulite_test_app.c │ │ └── cariboulite_internal.h │ ├── cariboulite.pc.in │ ├── test │ │ ├── fpga_comm_test.c │ │ └── caribou_programmer.c │ └── README.md ├── gr-caribouLite │ ├── python │ │ └── caribouLite │ │ │ ├── bindings │ │ │ ├── README.md │ │ │ ├── docstrings │ │ │ │ ├── README.md │ │ │ │ └── caribouLiteSource_pydoc_template.h │ │ │ ├── CMakeLists.txt │ │ │ ├── python_bindings.cc │ │ │ ├── caribouLiteSource_python.cc │ │ │ ├── bind_oot_file.py │ │ │ └── header_utils.py │ │ │ ├── .gitignore │ │ │ ├── __init__.py │ │ │ └── CMakeLists.txt │ ├── docs │ │ ├── doxygen │ │ │ ├── doxyxml │ │ │ │ ├── __pycache__ │ │ │ │ │ ├── base.cpython-39.pyc │ │ │ │ │ ├── text.cpython-39.pyc │ │ │ │ │ ├── __init__.cpython-39.pyc │ │ │ │ │ └── doxyindex.cpython-39.pyc │ │ │ │ ├── generated │ │ │ │ │ ├── __pycache__ │ │ │ │ │ │ ├── index.cpython-39.pyc │ │ │ │ │ │ ├── __init__.cpython-39.pyc │ │ │ │ │ │ ├── compound.cpython-39.pyc │ │ │ │ │ │ ├── indexsuper.cpython-39.pyc │ │ │ │ │ │ └── compoundsuper.cpython-39.pyc │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── index.py │ │ │ │ ├── text.py │ │ │ │ └── __init__.py │ │ │ ├── other │ │ │ │ ├── group_defs.dox │ │ │ │ └── main_page.dox │ │ │ ├── pydoc_macros.h │ │ │ └── CMakeLists.txt │ │ ├── README.caribouLite │ │ └── CMakeLists.txt │ ├── examples │ │ └── README │ ├── apps │ │ └── CMakeLists.txt │ ├── grc │ │ ├── CMakeLists.txt │ │ └── caribouLite_caribouLiteSource.block.yml │ ├── cmake │ │ ├── Modules │ │ │ ├── targetConfig.cmake.in │ │ │ └── gnuradio-caribouLiteConfig.cmake │ │ └── cmake_uninstall.cmake.in │ ├── include │ │ └── gnuradio │ │ │ └── caribouLite │ │ │ ├── CMakeLists.txt │ │ │ ├── api.h │ │ │ └── caribouLiteSource.h │ ├── .conda │ │ ├── recipe │ │ │ ├── conda_build_config.yaml │ │ │ ├── build.sh │ │ │ └── bld.bat │ │ └── conda-forge.yml │ ├── MANIFEST.md │ ├── lib │ │ ├── caribouLiteSource_impl.h │ │ └── CMakeLists.txt │ └── .cmake-format.py ├── utils │ ├── .gitignore │ ├── generate_bin_blob │ ├── CMakeLists.txt │ └── README.md ├── devicetrees │ ├── cariboulite.dtbo │ ├── compile.sh │ ├── README.md │ ├── cariboulite-overlay.dts │ └── h_files │ │ └── smi_dev_dtbo.h └── README.md ├── examples ├── cpp │ ├── .gitignore │ ├── CMakeLists.txt │ ├── cpr.h │ └── modes.h ├── python │ ├── .gitignore │ ├── read_test.py │ └── soapy_psd.py ├── README.md ├── c │ ├── CMakeLists.txt │ └── main.c ├── cpp_api │ └── CMakeLists.txt └── lora_receiver │ ├── CMakeLists.txt │ └── main.cpp ├── kitspace.yml ├── firmware ├── top.bin ├── .gitignore.bak ├── shell.nix ├── .gitignore ├── Makefile ├── lvds_rx.v ├── spi_slave.v ├── spi_if.v ├── complex_fifo.v └── sys_ctrl.v ├── docs ├── fpga │ ├── resources.xlsx │ ├── system_view.png │ ├── FPGA_diagram_internal.png │ └── generic_module_block.png ├── images │ ├── progress.png │ ├── rpi_imager.png │ ├── settings.png │ ├── test_app.png │ ├── distro_download.png │ ├── soapySDRUtils.png │ ├── imager_choose_device.png │ └── finished_imager_safe_remove.png ├── screenshots │ ├── sdr_pp_ism.png │ └── sdr_pp_fm_radio.png ├── datasheet │ └── CaribouLite_DS_R1.0.pdf ├── README.md ├── sims │ ├── find_ref_freq.m │ └── freq_gen.m └── flashing │ └── README.md ├── hardware └── rev2 │ ├── assembly │ ├── cariboulite_ad.PDF │ ├── full_bom │ │ └── cariboulite_bom.xlsx │ └── ism_bom │ │ └── cariboulite_ism_bom.xlsx │ ├── schematics │ ├── CaribouLite.PDF │ └── CaribouLite_ism.PDF │ └── pcb │ ├── stack │ └── cariboulite_r2.8.xls │ ├── ncdrill │ ├── cariboulite_r2.8.LDP │ └── cariboulite_r2.8.DRR │ └── gerber │ ├── cariboulite_r2.8.RUL │ ├── cariboulite_r2.8.EXTREP │ └── cariboulite_r2.8.Outline ├── .gitmodules ├── driver ├── udev │ ├── 40-cariboulite.rules │ └── install.sh ├── .gitignore ├── README.md └── CMakeLists.txt └── .gitignore /software/libcariboulite/.gitignore: -------------------------------------------------------------------------------- 1 | build -------------------------------------------------------------------------------- /software/libcariboulite/src/soapy_api/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/cpp/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /software/gr-caribouLite/python/caribouLite/bindings/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /software/utils/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /examples/python/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | __pycache__ 3 | -------------------------------------------------------------------------------- /kitspace.yml: -------------------------------------------------------------------------------- 1 | bom: hardware/rev2/pcb/assy/cariboulite_r2_bom.xlsx 2 | -------------------------------------------------------------------------------- /software/libcariboulite/src/hat/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /software/libcariboulite/src/at86rf215/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /software/libcariboulite/src/datatypes/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /software/libcariboulite/src/io_utils/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /software/libcariboulite/src/rffc507x/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /software/libcariboulite/src/zf_log/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /firmware/top.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/firmware/top.bin -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_fpga/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_smi/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_programming/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_smi/kernel/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /software/libcariboulite/src/datatypes/circular_buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "circular_buffer.h" 2 | -------------------------------------------------------------------------------- /software/libcariboulite/src/production_utils/.gitignore: -------------------------------------------------------------------------------- 1 | # build directories 2 | build 3 | -------------------------------------------------------------------------------- /docs/fpga/resources.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/fpga/resources.xlsx -------------------------------------------------------------------------------- /docs/fpga/system_view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/fpga/system_view.png -------------------------------------------------------------------------------- /docs/images/progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/images/progress.png -------------------------------------------------------------------------------- /docs/images/rpi_imager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/images/rpi_imager.png -------------------------------------------------------------------------------- /docs/images/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/images/settings.png -------------------------------------------------------------------------------- /docs/images/test_app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/images/test_app.png -------------------------------------------------------------------------------- /docs/images/distro_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/images/distro_download.png -------------------------------------------------------------------------------- /docs/images/soapySDRUtils.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/images/soapySDRUtils.png -------------------------------------------------------------------------------- /docs/screenshots/sdr_pp_ism.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/screenshots/sdr_pp_ism.png -------------------------------------------------------------------------------- /software/gr-caribouLite/python/caribouLite/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.pyc 3 | *.pyo 4 | build*/ 5 | examples/grc/*.py 6 | -------------------------------------------------------------------------------- /software/utils/generate_bin_blob: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/software/utils/generate_bin_blob -------------------------------------------------------------------------------- /docs/fpga/FPGA_diagram_internal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/fpga/FPGA_diagram_internal.png -------------------------------------------------------------------------------- /docs/fpga/generic_module_block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/fpga/generic_module_block.png -------------------------------------------------------------------------------- /docs/images/imager_choose_device.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/images/imager_choose_device.png -------------------------------------------------------------------------------- /docs/screenshots/sdr_pp_fm_radio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/screenshots/sdr_pp_fm_radio.png -------------------------------------------------------------------------------- /docs/datasheet/CaribouLite_DS_R1.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/datasheet/CaribouLite_DS_R1.0.pdf -------------------------------------------------------------------------------- /software/devicetrees/cariboulite.dtbo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/software/devicetrees/cariboulite.dtbo -------------------------------------------------------------------------------- /hardware/rev2/assembly/cariboulite_ad.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/hardware/rev2/assembly/cariboulite_ad.PDF -------------------------------------------------------------------------------- /hardware/rev2/schematics/CaribouLite.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/hardware/rev2/schematics/CaribouLite.PDF -------------------------------------------------------------------------------- /docs/images/finished_imager_safe_remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/docs/images/finished_imager_safe_remove.png -------------------------------------------------------------------------------- /hardware/rev2/pcb/stack/cariboulite_r2.8.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/hardware/rev2/pcb/stack/cariboulite_r2.8.xls -------------------------------------------------------------------------------- /hardware/rev2/schematics/CaribouLite_ism.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/hardware/rev2/schematics/CaribouLite_ism.PDF -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "software/libcariboulite/src/iir"] 2 | path = software/libcariboulite/src/iir 3 | url = https://github.com/berndporr/iir1 4 | -------------------------------------------------------------------------------- /hardware/rev2/assembly/full_bom/cariboulite_bom.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/hardware/rev2/assembly/full_bom/cariboulite_bom.xlsx -------------------------------------------------------------------------------- /hardware/rev2/assembly/ism_bom/cariboulite_ism_bom.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/hardware/rev2/assembly/ism_bom/cariboulite_ism_bom.xlsx -------------------------------------------------------------------------------- /software/gr-caribouLite/python/caribouLite/bindings/docstrings/README.md: -------------------------------------------------------------------------------- 1 | This directory stores templates for docstrings that are scraped from the include header files for each block 2 | -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_smi/kernel/README.md: -------------------------------------------------------------------------------- 1 | This directory contains generated files. 2 | Do not edit directly. 3 | Editing can be done through the "[root]/driver/" directory. -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/__pycache__/base.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/software/gr-caribouLite/docs/doxygen/doxyxml/__pycache__/base.cpython-39.pyc -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/__pycache__/text.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/software/gr-caribouLite/docs/doxygen/doxyxml/__pycache__/text.cpython-39.pyc -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/software/gr-caribouLite/docs/doxygen/doxyxml/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/__pycache__/doxyindex.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/software/gr-caribouLite/docs/doxygen/doxyxml/__pycache__/doxyindex.cpython-39.pyc -------------------------------------------------------------------------------- /software/gr-caribouLite/examples/README: -------------------------------------------------------------------------------- 1 | It is considered good practice to add examples in here to demonstrate the 2 | functionality of your OOT module. Python scripts, GRC flow graphs or other 3 | code can go here. 4 | -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/generated/__pycache__/index.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/software/gr-caribouLite/docs/doxygen/doxyxml/generated/__pycache__/index.cpython-39.pyc -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/generated/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/software/gr-caribouLite/docs/doxygen/doxyxml/generated/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/generated/__pycache__/compound.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/software/gr-caribouLite/docs/doxygen/doxyxml/generated/__pycache__/compound.cpython-39.pyc -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/generated/__pycache__/indexsuper.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/software/gr-caribouLite/docs/doxygen/doxyxml/generated/__pycache__/indexsuper.cpython-39.pyc -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/generated/__pycache__/compoundsuper.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpunk/cariboulite/main/software/gr-caribouLite/docs/doxygen/doxyxml/generated/__pycache__/compoundsuper.cpython-39.pyc -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/other/group_defs.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * \defgroup block GNU Radio CARIBOULITE C++ Signal Processing Blocks 3 | * \brief All C++ blocks that can be used from the CARIBOULITE GNU Radio 4 | * module are listed here or in the subcategories below. 5 | * 6 | */ 7 | -------------------------------------------------------------------------------- /software/libcariboulite/src/datatypes/entropy.h: -------------------------------------------------------------------------------- 1 | #ifndef __ENTROPY_H__ 2 | #define __ENTROPY_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | 11 | int add_entropy(uint8_t byte); 12 | 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif // __ENTROPY_H__ -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/generated/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Contains generated files produced by generateDS.py. 3 | 4 | These do the real work of parsing the doxygen xml files but the 5 | resultant classes are not very friendly to navigate so the rest of the 6 | doxyxml module processes them further. 7 | """ 8 | -------------------------------------------------------------------------------- /software/libcariboulite/src/cariboulite_events.c: -------------------------------------------------------------------------------- 1 | #ifndef ZF_LOG_LEVEL 2 | #define ZF_LOG_LEVEL ZF_LOG_VERBOSE 3 | #endif 4 | #define ZF_LOG_DEF_SRCLOC ZF_LOG_SRCLOC_LONG 5 | #define ZF_LOG_TAG "CARIBOULITE Events" 6 | #include "zf_log/zf_log.h" 7 | 8 | #include "cariboulite.h" 9 | #include "cariboulite_events.h" 10 | 11 | -------------------------------------------------------------------------------- /software/libcariboulite/cariboulite.pc.in: -------------------------------------------------------------------------------- 1 | prefix="@BIN_DEST@" 2 | exec_prefix="${prefix}"/bin 3 | libdir="${prefix}/lib" 4 | includedir="${prefix}/include" 5 | 6 | Name: @PROJECT_NAME@ 7 | Description: @CMAKE_PROJECT_DESCRIPTION@ 8 | Version: @PROJECT_VERSION@ 9 | Cflags: -I${includedir} 10 | Libs: -L${libdir} -l@PROJECT_NAME@ 11 | 12 | -------------------------------------------------------------------------------- /hardware/rev2/pcb/ncdrill/cariboulite_r2.8.LDP: -------------------------------------------------------------------------------- 1 | Layer Pairs Export File for PCB: C:\projects\cariboulite_hardware\src\cariboulite_r2.CSPcbDoc 2 | LayersSetName=Top_Bot_Thru_Holes|DrillFile=cariboulite_r2.txt|LayerPairs=gtl,gbl 3 | LayersSetName=Component Side_1_Blind_Vias|DrillFile=|LayerPairs=gtl,g1 4 | LayersSetName=2_Solder Side_Blind_Vias|DrillFile=|LayerPairs=g2,gbl 5 | -------------------------------------------------------------------------------- /software/gr-caribouLite/apps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-caribouLite 5 | # 6 | # SPDX-License-Identifier: GPL-3.0-or-later 7 | # 8 | 9 | include(GrPython) 10 | 11 | gr_python_install(PROGRAMS DESTINATION bin) 12 | -------------------------------------------------------------------------------- /driver/udev/40-cariboulite.rules: -------------------------------------------------------------------------------- 1 | # SMI Devices 2 | KERNEL=="smi", SUBSYSTEM=="smi-stream-dev", MODE="0666" 3 | 4 | # Other RPI Devices 5 | SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0666" 6 | SUBSYSTEM=="spidev", GROUP="spi", MODE="0666" 7 | SUBSYSTEM=="bcm2835-gpiomem", GROUP="gpio", MODE="0666" 8 | SUBSYSTEM=="mem", KERNEL=="mem|kmem|port", GROUP="kmem", MODE="0666" 9 | 10 | -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/other/main_page.dox: -------------------------------------------------------------------------------- 1 | /*! \mainpage 2 | 3 | Welcome to the GNU Radio CARIBOULITE Block 4 | 5 | This is the intro page for the Doxygen manual generated for the CARIBOULITE 6 | block (docs/doxygen/other/main_page.dox). Edit it to add more detailed 7 | documentation about the new GNU Radio modules contained in this 8 | project. 9 | 10 | */ 11 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # License 2 | Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. 3 | -------------------------------------------------------------------------------- /software/gr-caribouLite/grc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-caribouLite 5 | # 6 | # SPDX-License-Identifier: GPL-3.0-or-later 7 | # 8 | 9 | install(FILES 10 | caribouLite_caribouLiteSource.block.yml DESTINATION share/gnuradio/grc/blocks) 11 | -------------------------------------------------------------------------------- /software/devicetrees/compile.sh: -------------------------------------------------------------------------------- 1 | echo "Compiling device tree file" 2 | dtc -O dtb -o cariboulite.dtbo -b 0 -@ cariboulite-overlay.dts 3 | 4 | echo "Generating code blob" 5 | mkdir h_files 6 | ../utils/generate_bin_blob ./cariboulite.dtbo cariboulite_dtbo ./h_files/cariboulite_dtbo.h 7 | 8 | echo "Copying dtbo blob h-file to the code directory" 9 | cp ./h_files/cariboulite_dtbo.h ../libcariboulite/src/ 10 | -------------------------------------------------------------------------------- /software/gr-caribouLite/cmake/Modules/targetConfig.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # SPDX-License-Identifier: GPL-3.0-or-later 6 | # 7 | 8 | include(CMakeFindDependencyMacro) 9 | 10 | set(target_deps "@TARGET_DEPENDENCIES@") 11 | foreach(dep IN LISTS target_deps) 12 | find_dependency(${dep}) 13 | endforeach() 14 | include("${CMAKE_CURRENT_LIST_DIR}/@TARGET@Targets.cmake") 15 | -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/README.caribouLite: -------------------------------------------------------------------------------- 1 | This is the caribouLite-write-a-block package meant as a guide to building 2 | out-of-tree packages. To use the caribouLite blocks, the Python namespaces 3 | is in 'caribouLite', which is imported as: 4 | 5 | import caribouLite 6 | 7 | See the Doxygen documentation for details about the blocks available 8 | in this package. A quick listing of the details can be found in Python 9 | after importing by using: 10 | 11 | help(caribouLite) 12 | -------------------------------------------------------------------------------- /software/libcariboulite/src/hat/README.md: -------------------------------------------------------------------------------- 1 | [EEPROM Programming Tutorial](https://github.com/cariboulabs/cariboulite/tree/main/docs/flashing) 2 | 3 | # License 4 | Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. 5 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # CaribouLite Examples 2 | This folder contains examples categorized by programming languages: 3 | - `cpp` - C/C++ examples 4 | - `python` - python applets and example 5 | 6 | # License 7 | Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License. -------------------------------------------------------------------------------- /examples/c/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2) 2 | project(test_app) 3 | 4 | # Find the package using pkg-config 5 | find_package(PkgConfig REQUIRED) 6 | pkg_check_modules(CARIBOULITE REQUIRED cariboulite) 7 | 8 | # Add the executable 9 | add_executable(test_app main.c) 10 | 11 | # Include directories from the cariboulite package 12 | target_include_directories(test_app PRIVATE ${CARIBOULITE_INCLUDE_DIRS}) 13 | 14 | # Link against the cariboulite library 15 | target_link_libraries(test_app PRIVATE ${CARIBOULITE_LIBRARIES}) 16 | -------------------------------------------------------------------------------- /software/libcariboulite/test/fpga_comm_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cariboulite.h" 3 | #include "cariboulite_setup.h" 4 | #include "cariboulite_config_default.h" 5 | 6 | CARIBOULITE_CONFIG_DEFAULT(cariboulite_sys); 7 | 8 | int main() 9 | { 10 | printf("fpga api test program!\n"); 11 | 12 | cariboulite_setup_io (&cariboulite_sys); 13 | cariboulite_init_submodules (&cariboulite_sys); 14 | cariboulite_release_submodules(&cariboulite_sys); 15 | cariboulite_release_io (&cariboulite_sys); 16 | 17 | return 0; 18 | } -------------------------------------------------------------------------------- /examples/cpp_api/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2) 2 | project(test_app) 3 | 4 | # Find the package using pkg-config 5 | find_package(PkgConfig REQUIRED) 6 | pkg_check_modules(CARIBOULITE REQUIRED cariboulite) 7 | 8 | # Add the executable 9 | add_executable(test_app main.cpp) 10 | 11 | # Include directories from the cariboulite package 12 | target_include_directories(test_app PRIVATE ${CARIBOULITE_INCLUDE_DIRS}) 13 | 14 | # Link against the cariboulite library 15 | target_link_libraries(test_app PRIVATE ${CARIBOULITE_LIBRARIES} -lcariboulite) 16 | -------------------------------------------------------------------------------- /docs/sims/find_ref_freq.m: -------------------------------------------------------------------------------- 1 | function ref = find_ref_freq(f) 2 | f_rf_mod_32 = f / 32e6; 3 | f_rf_mod_26 = f / 26e6; 4 | f_rf_mod_32 = f_rf_mod_32 - floor(f_rf_mod_32); 5 | f_rf_mod_26 = f_rf_mod_26 - floor(f_rf_mod_26); 6 | f_rf_mod_32 = f_rf_mod_32 * 32e6; 7 | f_rf_mod_26 = f_rf_mod_26 * 26e6; 8 | if (f_rf_mod_32 > 16e6) 9 | f_rf_mod_32 = 32e6 - f_rf_mod_32; 10 | endif 11 | if (f_rf_mod_26 > 13e6) 12 | f_rf_mod_26 = 26e6 - f_rf_mod_26; 13 | endif 14 | 15 | if f_rf_mod_32 > f_rf_mod_26 16 | ref = 32e6; 17 | else 18 | ref = 26e6; 19 | endif 20 | endfunction -------------------------------------------------------------------------------- /software/devicetrees/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | This directory contains the device-tree overlays to be embedded within the HAT ID EEPROM. Important files: 3 | 1. `cariboulite-overlay.dts`: The source file of the device-tree overlay 4 | 2. `compile.sh`: run this to compile and create the `dtbo` binary file. 5 | The binary file is the actual overlay that is read by the linux kernel. 6 | 7 | Upon compilation the `dts` file is converted into its binary representation (`dtbo`). Then an h-file is created to embed this binary file into our EEPROM utility (see `cariboulite_dtbo.h` in the h_files sub-dir). 8 | 9 | -------------------------------------------------------------------------------- /software/gr-caribouLite/include/gnuradio/caribouLite/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011,2012 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-caribouLite 5 | # 6 | # SPDX-License-Identifier: GPL-3.0-or-later 7 | # 8 | 9 | ######################################################################## 10 | # Install public header files 11 | ######################################################################## 12 | install(FILES api.h 13 | caribouLiteSource.h DESTINATION include/gnuradio/caribouLite) 14 | -------------------------------------------------------------------------------- /software/libcariboulite/src/rffc507x/README.md: -------------------------------------------------------------------------------- 1 | # RFFC5072 2 | Raspberry Pi SPI drivers for Qorvo's RFFC5072 - synthesizer integrated RF mixers 3 | This file was derived from code written by HackRF Team: (https://github.com/mossmann/hackrf) 4 | 1. 2012 Michael Ossmann 5 | 2. 2014 Jared Boone 6 | and was modified by David Michaeli (cariboulabs.co@gmail.com) to adapt if for the CaribouLite project running on Linux OS (RPI). 7 | The license for the modified code is licensed according to the original license accoring to: https://github.com/mossmann/hackrf/blob/master/COPYING 8 | 9 | 10 | -------------------------------------------------------------------------------- /software/gr-caribouLite/.conda/recipe/conda_build_config.yaml: -------------------------------------------------------------------------------- 1 | # this is the channel and label where packages will be uploaded to if enabled 2 | # (see ../README.md) 3 | channel_targets: 4 | - gnuradio main 5 | # override the conda-forge pin for gnuradio-core by uncommenting 6 | # and specifying a different version here 7 | #gnuradio_core: 8 | #- "3.10.1" 9 | gnuradio_extra_pin: 10 | # always leave one entry with the empty string 11 | - "" 12 | # add version strings here like to get builds for versions other than 13 | # the conda-forge-wide default or version specified above for gnuradio_core 14 | #- "3.9.5" 15 | -------------------------------------------------------------------------------- /software/gr-caribouLite/include/gnuradio/caribouLite/api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Free Software Foundation, Inc. 3 | * 4 | * This file was generated by gr_modtool, a tool from the GNU Radio framework 5 | * This file is a part of gr-caribouLite 6 | * 7 | * SPDX-License-Identifier: GPL-3.0-or-later 8 | * 9 | */ 10 | 11 | #ifndef INCLUDED_CARIBOULITE_API_H 12 | #define INCLUDED_CARIBOULITE_API_H 13 | 14 | #include 15 | 16 | #ifdef gnuradio_caribouLite_EXPORTS 17 | #define CARIBOULITE_API __GR_ATTR_EXPORT 18 | #else 19 | #define CARIBOULITE_API __GR_ATTR_IMPORT 20 | #endif 21 | 22 | #endif /* INCLUDED_CARIBOULITE_API_H */ 23 | -------------------------------------------------------------------------------- /examples/lora_receiver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2) 2 | project(cariboulite_util) 3 | 4 | # Find the package using pkg-config 5 | find_package(PkgConfig REQUIRED) 6 | pkg_check_modules(CARIBOULITE REQUIRED cariboulite) 7 | 8 | find_package(libsigmf REQUIRED) 9 | 10 | # Add the executable 11 | add_executable(cariboulite_util main.cpp) 12 | 13 | # Include directories from the cariboulite package 14 | target_include_directories(cariboulite_util PRIVATE ${CARIBOULITE_INCLUDE_DIRS}) 15 | 16 | # Link against the cariboulite library 17 | target_link_libraries(cariboulite_util PRIVATE ${CARIBOULITE_LIBRARIES} -lcariboulite libsigmf::libsigmf) 18 | -------------------------------------------------------------------------------- /software/README.md: -------------------------------------------------------------------------------- 1 | # CaribouLite Software 2 | Containing all the software side for: 3 | - `libcariboulite`: SDR APIs library - including SoapySDR 4 | - `devicetrees`: linux device-trees overlays sources and binaries 5 | - `utils`: various utilities 6 | - `examples`: Example code - mainly C/C++ and python. Coming soon! 7 | 8 | # License 9 | Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License. -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_programming/README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | This Lattice ICE40 programming and management library was originally written by Eric Brombaugh (https://github.com/emeb) and used in https://github.com/emeb/icehat ("...RPi hat which comprises a Lattice iCE40 Ultra FPGA type ice5LP4K-SG48..."). 3 | 4 | # License 5 | Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License. -------------------------------------------------------------------------------- /software/gr-caribouLite/python/caribouLite/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2008,2009 Free Software Foundation, Inc. 3 | # 4 | # SPDX-License-Identifier: GPL-3.0-or-later 5 | # 6 | 7 | # The presence of this file turns this directory into a Python package 8 | 9 | ''' 10 | This is the GNU Radio CARIBOULITE module. Place your Python package 11 | description here (python/__init__.py). 12 | ''' 13 | import os 14 | 15 | # import pybind11 generated symbols into the caribouLite namespace 16 | try: 17 | # this might fail if the module is python-only 18 | from .caribouLite_python import * 19 | except ModuleNotFoundError: 20 | pass 21 | 22 | # import any pure python here 23 | # 24 | -------------------------------------------------------------------------------- /software/libcariboulite/src/datatypes/test_tiny_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "tiny_list.h" 3 | #include "tiny_queue.h" 4 | 5 | int a = 0; 6 | 7 | tiny_queue_st queue; 8 | 9 | int main () 10 | { 11 | tiny_queue_init (&queue); 12 | 13 | tiny_queue_enqueue (queue, &a, sizeof (a)); a++; 14 | tiny_queue_enqueue (queue, &a, sizeof (a)); a++; 15 | tiny_queue_enqueue (queue, &a, sizeof (a)); a++; 16 | 17 | tiny_list_print (queue); 18 | 19 | tiny_queue_dequeue (queue, &a, NULL); 20 | tiny_list_print (queue); 21 | tiny_queue_dequeue (queue, &a, NULL); 22 | tiny_list_print (queue); 23 | tiny_queue_dequeue (queue, &a, NULL); 24 | tiny_list_print (queue); 25 | 26 | tiny_queue_free (queue); 27 | } -------------------------------------------------------------------------------- /software/libcariboulite/src/cariboulite_events.h: -------------------------------------------------------------------------------- 1 | #ifndef __CARIBOULITE_EVENTS_H__ 2 | #define __CARIBOULITE_EVENTS_H__ 3 | 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include "caribou_smi/caribou_smi.h" 10 | 11 | void caribou_smi_error_event(caribou_smi_channel_en channel, void* context); 12 | void caribou_smi_rx_data_event(caribou_smi_channel_en channel, caribou_smi_sample_complex_int16 *cplx_vec, size_t num_samples_in_vec, void* context); 13 | size_t caribou_smi_tx_data_event(caribou_smi_channel_en channel, caribou_smi_sample_complex_int16 *cplx_vec, size_t *num_samples_in_vec, void* context); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif // __CARIBOULITE_EVENTS_H__ -------------------------------------------------------------------------------- /software/gr-caribouLite/.conda/recipe/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | cmake -E make_directory buildconda 6 | cd buildconda 7 | 8 | cmake_config_args=( 9 | -DCMAKE_BUILD_TYPE=Release 10 | -DCMAKE_INSTALL_PREFIX=$PREFIX 11 | -DLIB_SUFFIX="" 12 | -DENABLE_DOXYGEN=OFF 13 | -DENABLE_TESTING=ON 14 | ) 15 | 16 | cmake ${CMAKE_ARGS} -G "Ninja" .. "${cmake_config_args[@]}" 17 | cmake --build . --config Release -- -j${CPU_COUNT} 18 | cmake --build . --config Release --target install 19 | 20 | if [[ "${CONDA_BUILD_CROSS_COMPILATION:-}" != "1" || "${CROSSCOMPILING_EMULATOR}" != "" ]]; then 21 | ctest --build-config Release --output-on-failure --timeout 120 -j${CPU_COUNT} 22 | fi 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | # build directories 55 | installations 56 | build 57 | -------------------------------------------------------------------------------- /driver/.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | # build directories 55 | installations 56 | build 57 | -------------------------------------------------------------------------------- /software/libcariboulite/src/production_utils/production_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __PRODUCTION_UTILS_H__ 2 | #define __PRODUCTION_UTILS_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | typedef struct 9 | { 10 | bool available; 11 | int wlan_id; 12 | char essid[512]; 13 | bool internet_access; 14 | } production_wifi_status_st; 15 | 16 | int production_utils_rpi_leds_init(int state); 17 | int production_utils_rpi_leds_set_state(int led_green, int led_red); 18 | void production_utils_rpi_leds_blink_fatal_error(void); 19 | void production_utils_rpi_leds_blink_start_tests(void); 20 | int production_check_wifi_state(production_wifi_status_st* wifi_stat); 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | 26 | #endif //__PRODUCTION_UTILS_H__ -------------------------------------------------------------------------------- /firmware/.gitignore.bak: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | # build directories 55 | installations 56 | build 57 | -------------------------------------------------------------------------------- /firmware/shell.nix: -------------------------------------------------------------------------------- 1 | # This is a nix-shell for use with the nix package manager. 2 | # If you have nix installed, you may simply run `nix-shell` 3 | # in this repo, and have all dependencies ready in the new shell. 4 | 5 | {pkgs ? import (builtins.fetchTarball { 6 | # Descriptive name to make the store path easier to identify 7 | name = "nixos-2021-05"; 8 | # Commit hash 9 | url = "https://github.com/NixOS/nixpkgs/archive/refs/tags/21.05.tar.gz"; 10 | # Hash obtained using `nix-prefetch-url --unpack ` 11 | sha256 = "1ckzhh24mgz6jd1xhfgx0i9mijk6xjqxwsshnvq789xsavrmsc36"; 12 | }) {}}: 13 | 14 | 15 | pkgs.mkShell { 16 | buildInputs = with pkgs; 17 | [ 18 | yosys 19 | nextpnr 20 | icestorm 21 | ]; 22 | 23 | } -------------------------------------------------------------------------------- /software/utils/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(cariboulite_utils) 3 | set(CMAKE_BUILD_TYPE Release) 4 | 5 | #Bring the headers, such as Student.h into the project 6 | set(SUPER_DIR ${PROJECT_SOURCE_DIR}/..) 7 | include_directories(/.) 8 | include_directories(${SUPER_DIR}) 9 | 10 | set(SOURCE_GEN_BLOB generate_bin_blob.c) 11 | set(EXTERN_LIBS ) 12 | 13 | #Generate the static library from the sources 14 | add_executable(generate_bin_blob ${SOURCE_GEN_BLOB}) 15 | target_link_libraries(generate_bin_blob ${EXTERN_LIBS}) 16 | 17 | #Set the location for library installation -- i.e., /usr/lib in this case 18 | # not really necessary in this example. Use "sudo make install" to apply 19 | install(TARGETS generate_bin_blob DESTINATION /usr/lib) -------------------------------------------------------------------------------- /software/libcariboulite/src/datatypes/tiny_stack.h: -------------------------------------------------------------------------------- 1 | #ifndef __TINY_STACK_H__ 2 | #define __TINY_STACK_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include "tiny_list.h" 10 | 11 | typedef tiny_list_st* tiny_stack_st; 12 | 13 | #define tiny_stack_init(s_ptr) (tiny_list_init(s_ptr)) 14 | #define tiny_stack_free(s) (tiny_list_free(s)) 15 | #define tiny_stack_enqueue(s,d_array,l) (tiny_list_add((s),(d_array),(l),pos_head)) 16 | #define tiny_stack_dequeue(s,d_array,l_ptr) (tiny_list_remove((s),(d_array),(l_ptr),pos_head)) 17 | #define tiny_stack_is_empty(s) (tiny_list_num_elements(s)==0) 18 | #define tiny_stack_empty(s) (tiny_list_remove_all (s)) 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif //__TINY_STACK_H__ -------------------------------------------------------------------------------- /software/libcariboulite/src/production_utils/test_lcd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "lcd.h" 3 | 4 | void callback(void* context, int key1, int key2) 5 | { 6 | static int k1 = 0; 7 | static int k2 = 0; 8 | lcd_st* dev = (lcd_st*)context; 9 | printf("Pressed %d, %d\n", key1, key2); 10 | 11 | if (key1 != k1 || key2 != k2) 12 | { 13 | char buf1[10]; 14 | char buf2[10]; 15 | sprintf(buf1, "Key1: %d", key1); 16 | sprintf(buf2, "Key2: %d", key2); 17 | lcd_writeln(dev, buf1, buf2, 1); 18 | k1 = key1; 19 | k2 = key2; 20 | } 21 | } 22 | 23 | int main () 24 | { 25 | lcd_st dev = {0}; 26 | lcd_init(&dev, callback, &dev); 27 | lcd_clear_screan(&dev); 28 | 29 | sleep(1); 30 | lcd_writeln(&dev, "Hello", "World", 1); 31 | 32 | lcd_close(&dev); 33 | return 0; 34 | } -------------------------------------------------------------------------------- /driver/README.md: -------------------------------------------------------------------------------- 1 | # SMI Stream Driver 2 | SMI streaming async module. Previously located under the userspace driver 'caribou_smi' and was integrated into it. Currently an autonomous driver to be loaded by the kernel in runtime. 3 | The driver replaces the legacy broadcom SMI driver. 4 | 5 | # Installation 6 | Use `../install.sh` to start the installation sequence: 7 | 1. Update kernel headers - this kernel driver needs to be "updated" on each kernel update done on the system. This means that the `install.sh` should be run again. This part in the sequence required internet connectivity. 8 | 2. Create the build directory, and build the kernel module. 9 | 3. Installing the ko.xz file into the `/ilb/modules` directory + `depmod` 10 | 4. TBD 11 | 12 | # Installing UDEV Rules 13 | // The artifacts - TBD 14 | 15 | -------------------------------------------------------------------------------- /firmware/.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | # build directories 55 | installations 56 | build 57 | h-files 58 | *.asc 59 | *.bin 60 | *.blif 61 | *.json 62 | *.nix 63 | -------------------------------------------------------------------------------- /software/libcariboulite/src/io_utils/io_utils_i2c.h: -------------------------------------------------------------------------------- 1 | #ifndef __IO_UTILS_I2C_H__ 2 | #define __IO_UTILS_I2C_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | 11 | typedef struct 12 | { 13 | int bus; 14 | uint8_t address; 15 | char i2c_device_file[32]; 16 | 17 | int fd; 18 | } io_utils_i2c_st; 19 | 20 | int io_utils_i2c_open(io_utils_i2c_st* dev, int bus, uint8_t address); 21 | int io_utils_i2c_close(io_utils_i2c_st* dev); 22 | int io_utils_i2c_write(io_utils_i2c_st* dev, uint8_t *data, size_t len); 23 | int io_utils_i2c_read(io_utils_i2c_st* dev, uint8_t *data, size_t len); 24 | int io_utils_i2c_read_reg(io_utils_i2c_st* dev, uint8_t reg, uint8_t *data, size_t len); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | 30 | #endif // __IO_UTILS_I2C_H__ 31 | -------------------------------------------------------------------------------- /software/gr-caribouLite/MANIFEST.md: -------------------------------------------------------------------------------- 1 | title: The CARIBOULITE OOT Module 2 | brief: Short description of gr-caribouLite 3 | tags: # Tags are arbitrary, but look at CGRAN what other authors are using 4 | - sdr 5 | author: 6 | - Author Name 7 | copyright_owner: 8 | - Copyright Owner 1 9 | license: 10 | gr_supported_version: # Put a comma separated list of supported GR versions here 11 | #repo: # Put the URL of the repository here, or leave blank for default 12 | #website: # If you have a separate project website, put it here 13 | #icon: # Put a URL to a square image here that will be used as an icon on CGRAN 14 | --- 15 | A longer, multi-line description of gr-caribouLite. 16 | You may use some *basic* Markdown here. 17 | If left empty, it will try to find a README file instead. 18 | -------------------------------------------------------------------------------- /hardware/rev2/pcb/gerber/cariboulite_r2.8.RUL: -------------------------------------------------------------------------------- 1 | DRC Rules Export File for PCB: C:\projects\cariboulite_hardware\src\cariboulite_r2.CSPcbDoc 2 | RuleKind=SolderMaskExpansion|RuleName=SolderMaskExpansion|Scope=Board|Minimum=1.50 3 | RuleKind=Width|RuleName=Width|Scope=Board|Minimum=3.50 4 | RuleKind=Clearance|RuleName=Clearance|Scope=Board|Minimum=3.20 5 | RuleKind=ShortCircuit|RuleName=ShortCircuit|Scope=Board|Allowed=0 6 | RuleKind=MinimumAnnularRing|RuleName=MinimumAnnularRing|Scope=Board|Minimum=3.00 7 | RuleKind=Clearance|RuleName=Clearance_DIFF|Scope=Board|Minimum=3.20 8 | RuleKind=Clearance|RuleName=Clearance_RF|Scope=Board|Minimum=4.00 9 | RuleKind=Width|RuleName=Width_RF|Scope=Board|Minimum=3.50 10 | RuleKind=Clearance|RuleName=Clearance_SMI|Scope=Board|Minimum=5.00 11 | RuleKind=Clearance|RuleName=Clearance_CLK|Scope=Board|Minimum=3.50 12 | -------------------------------------------------------------------------------- /software/gr-caribouLite/.conda/recipe/bld.bat: -------------------------------------------------------------------------------- 1 | setlocal EnableDelayedExpansion 2 | @echo on 3 | 4 | :: Make a build folder and change to it 5 | cmake -E make_directory buildconda 6 | cd buildconda 7 | 8 | :: configure 9 | cmake -G "Ninja" ^ 10 | -DCMAKE_BUILD_TYPE=Release ^ 11 | -DCMAKE_INSTALL_PREFIX="%LIBRARY_PREFIX%" ^ 12 | -DCMAKE_PREFIX_PATH="%LIBRARY_PREFIX%" ^ 13 | -DGR_PYTHON_DIR="%SP_DIR%" ^ 14 | -DENABLE_DOXYGEN=OFF ^ 15 | -DENABLE_TESTING=ON ^ 16 | .. 17 | if errorlevel 1 exit 1 18 | 19 | :: build 20 | cmake --build . --config Release -- -j%CPU_COUNT% 21 | if errorlevel 1 exit 1 22 | 23 | :: install 24 | cmake --build . --config Release --target install 25 | if errorlevel 1 exit 1 26 | 27 | :: test 28 | ctest --build-config Release --output-on-failure --timeout 120 -j%CPU_COUNT% 29 | if errorlevel 1 exit 1 30 | -------------------------------------------------------------------------------- /software/libcariboulite/src/datatypes/tiny_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef __TINY_QUEUE_H__ 2 | #define __TINY_QUEUE_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include "tiny_list.h" 10 | 11 | typedef tiny_list_st* tiny_queue_st; 12 | 13 | #define tiny_queue_init(q_ptr) (tiny_list_init(q_ptr)) 14 | #define tiny_queue_free(q) (tiny_list_free(q)) 15 | #define tiny_queue_enqueue(q,d_array,l) (tiny_list_add((q),(d_array),(l),pos_head)) 16 | #define tiny_queue_dequeue(q,d_array,l_ptr) (tiny_list_remove((q),(d_array),(l_ptr),pos_tail)) 17 | #define tiny_queue_is_empty(q) (tiny_list_num_elements(q)==0) 18 | #define tiny_queue_num_elements(q) (tiny_list_num_elements(q)) 19 | #define tiny_queue_empty(q) (tiny_list_remove_all (q)) 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif //__TINY_QUEUE_H__ -------------------------------------------------------------------------------- /software/libcariboulite/src/hat/test_hat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../cariboulite_dtbo.h" 3 | #include "hat.h" 4 | 5 | 6 | hat_st hat = 7 | { 8 | .vendor_name = "CaribouLabs LTD", 9 | .product_name = "CaribouLite RPI Hat", 10 | .product_id = 0x01, 11 | .product_version = 0x01, 12 | .device_tree_buffer = cariboulite_dtbo, 13 | .device_tree_buffer_size = sizeof(cariboulite_dtbo), 14 | 15 | .dev = { 16 | .i2c_address = 0x50, // the i2c address of the eeprom chip 17 | .eeprom_type = eeprom_type_24c32, 18 | }, 19 | }; 20 | 21 | int main() 22 | { 23 | if (hat_init(&hat) != 0) 24 | { 25 | printf("error\n"); 26 | return 0; 27 | } 28 | 29 | hat_print(&hat); 30 | 31 | hat_board_info_st info = {0}; 32 | hat_detect_board(&info); 33 | hat_print_board_info(&info); 34 | 35 | hat_close(&hat); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /software/gr-caribouLite/python/caribouLite/bindings/docstrings/caribouLiteSource_pydoc_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | #include "pydoc_macros.h" 10 | #define D(...) DOC(gr, caribouLite, __VA_ARGS__) 11 | /* 12 | This file contains placeholders for docstrings for the Python bindings. 13 | Do not edit! These were automatically extracted during the binding process 14 | and will be overwritten during the build process 15 | */ 16 | 17 | 18 | 19 | static const char *__doc_gr_caribouLite_caribouLiteSource = R"doc()doc"; 20 | 21 | 22 | static const char *__doc_gr_caribouLite_caribouLiteSource_caribouLiteSource = R"doc()doc"; 23 | 24 | 25 | static const char *__doc_gr_caribouLite_caribouLiteSource_make = R"doc()doc"; 26 | 27 | 28 | -------------------------------------------------------------------------------- /software/libcariboulite/test/caribou_programmer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cariboulite.h" 3 | #include "cariboulite_setup.h" 4 | #include "cariboulite_config_default.h" 5 | 6 | CARIBOULITE_CONFIG_DEFAULT(cariboulite_sys); 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | if (argc < 2) 11 | { 12 | printf("ICE40 FPGA Programming Tool for the CaribouLite Board\n"); 13 | printf("---------------------------\n\n"); 14 | printf("Usage: use the .bin file output only!\n"); 15 | printf(" caribou_programmer \n"); 16 | return 0; 17 | } 18 | else 19 | { 20 | printf("Programming bin file '%s'\n", argv[1]); 21 | } 22 | 23 | cariboulite_setup_io (&cariboulite_sys); 24 | cariboulite_configure_fpga (&cariboulite_sys, cariboulite_firmware_source_file, argv[1]); 25 | cariboulite_release_io (&cariboulite_sys); 26 | 27 | return 0; 28 | } -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/pydoc_macros.h: -------------------------------------------------------------------------------- 1 | #ifndef PYDOC_MACROS_H 2 | #define PYDOC_MACROS_H 3 | 4 | #define __EXPAND(x) x 5 | #define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT 6 | #define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1)) 7 | #define __CAT1(a, b) a##b 8 | #define __CAT2(a, b) __CAT1(a, b) 9 | #define __DOC1(n1) __doc_##n1 10 | #define __DOC2(n1, n2) __doc_##n1##_##n2 11 | #define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3 12 | #define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4 13 | #define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5 14 | #define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6 15 | #define __DOC7(n1, n2, n3, n4, n5, n6, n7) \ 16 | __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7 17 | #define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__)) 18 | 19 | #endif // PYDOC_MACROS_H 20 | -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_programming/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(cariboulite) 3 | set(CMAKE_BUILD_TYPE Release) 4 | 5 | #Bring the headers, such as Student.h into the project 6 | set(SUPER_DIR ${PROJECT_SOURCE_DIR}/..) 7 | include_directories(/.) 8 | include_directories(${SUPER_DIR}) 9 | 10 | #However, the file(GLOB...) allows for wildcard additions: 11 | set(SOURCES_LIB caribou_prog.c) 12 | #add_compile_options(-Wall -Wextra -pedantic -Werror) 13 | add_compile_options(-Wall -Wextra -Wno-missing-braces) 14 | 15 | #Generate the static library from the sources 16 | add_library(caribou_prog STATIC ${SOURCES_LIB}) 17 | target_include_directories(caribou_prog PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 18 | 19 | #Set the location for library installation -- i.e., /usr/lib in this case 20 | # not really necessary in this example. Use "sudo make install" to apply 21 | install(TARGETS caribou_prog DESTINATION /usr/lib) -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-caribouLite 5 | # 6 | # SPDX-License-Identifier: GPL-3.0-or-later 7 | # 8 | 9 | ######################################################################## 10 | # Setup dependencies 11 | ######################################################################## 12 | find_package(Doxygen) 13 | 14 | ######################################################################## 15 | # Begin conditional configuration 16 | ######################################################################## 17 | if(ENABLE_DOXYGEN) 18 | 19 | ######################################################################## 20 | # Add subdirectories 21 | ######################################################################## 22 | add_subdirectory(doxygen) 23 | 24 | endif(ENABLE_DOXYGEN) 25 | -------------------------------------------------------------------------------- /driver/udev/install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | 4 | ## FUNCTIONS 5 | install() { 6 | printf "Installing UDEV rules...\n" 7 | sudo cp 40-cariboulite.rules /etc/udev/rules.d/ 8 | sudo udevadm control --reload-rules && udevadm trigger 9 | printf "Installation finished\n" 10 | } 11 | 12 | uninstall() { 13 | printf "Uninstalling UDEV rules...\n" 14 | if [ -f "/etc/udev/rules.d/40-cariboulite.rules" ]; then 15 | sudo rm "/etc/udev/rules.d/40-cariboulite.rules" 16 | fi 17 | sudo udevadm control --reload-rules && udevadm trigger 18 | printf "Uninstallation finished\n" 19 | } 20 | 21 | 22 | ## FLOW 23 | printf "CaribouLite UDEV Rules (un)installation\n" 24 | printf "=======================================\n\n" 25 | 26 | if [ "$1" == "install" ]; then 27 | install 28 | 29 | exit 0 30 | elif [ "$1" == "uninstall" ]; then 31 | uninstall 32 | 33 | exit 0 34 | else 35 | printf "Usage: $0 [install|uninstall]\n" 36 | exit 1 37 | fi -------------------------------------------------------------------------------- /software/libcariboulite/src/production_utils/hat_powermon_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "hat_powermon.h" 4 | 5 | 6 | void callback(void* context, hat_powermon_state_st *state) 7 | { 8 | printf("MON: %d. SW_ST: %d, FLT: %d, I: %.2f, V: %.2f, P: %.2f\n", 9 | state->monitor_active, 10 | state->load_switch_state, 11 | state->fault, 12 | state->i_ma, 13 | state->v_mv, 14 | state->p_mw); 15 | } 16 | 17 | int main () 18 | { 19 | int ver, subver; 20 | bool led1=false, led2=false; 21 | hat_power_monitor_st dev = {0}; 22 | hat_powermon_init(&dev, 0x25, callback, &dev); 23 | 24 | while (1) 25 | { 26 | sleep(5); 27 | led1 = !led1; 28 | led2 = !led2; 29 | hat_powermon_set_power_state(&dev, led1); 30 | //hat_powermon_set_leds_state(&dev, led1, led2); 31 | 32 | hat_powermon_read_versions(&dev, &ver, &subver); 33 | printf("VER: %d, SUBVER: %d\n", ver, subver); 34 | } 35 | 36 | hat_powermon_release(&dev); 37 | return 0; 38 | } -------------------------------------------------------------------------------- /software/libcariboulite/src/production_utils/python/usblcd.py: -------------------------------------------------------------------------------- 1 | from lcd2usb import LCD 2 | from subprocess import * 3 | import threading 4 | from time import sleep, strftime 5 | from datetime import datetime 6 | 7 | # =========================================================================== 8 | # Clock Example 9 | # =========================================================================== 10 | lcd = LCD() 11 | 12 | cmd = "ip addr show eth0 | grep inet | awk '{print $2}' | cut -d/ -f1" 13 | 14 | print ("Press CTRL+Z to exit") 15 | 16 | def run_cmd(cmd): 17 | p = Popen(cmd, shell=True, stdout=PIPE) 18 | output = p.communicate()[0] 19 | return output 20 | 21 | while(True): 22 | lcd.clear() 23 | lcd.set_contrast(190) 24 | lcd.set_brightness(255) 25 | ipaddr = run_cmd(cmd) 26 | lcd.goto(0,0) 27 | lcd.write(datetime.now().strftime('%b %d %H:%M:%S\n')) 28 | lcd.goto(0,1) 29 | lcd.write('IP %s' % (ipaddr)) 30 | sleep(1) 31 | -------------------------------------------------------------------------------- /software/libcariboulite/src/hat/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(cariboulite) 3 | set(CMAKE_BUILD_TYPE Release) 4 | 5 | # Bring the headers 6 | set(SUPER_DIR ${PROJECT_SOURCE_DIR}/..) 7 | include_directories(/.) 8 | include_directories(${SUPER_DIR}) 9 | 10 | # Source files 11 | set(SOURCES_LIB hat.c eeprom_utils.c) 12 | set(SOURCES ${SOURCES_LIB} test_hat.c) 13 | set(EXTERN_LIBS ${SUPER_DIR}/io_utils/build/libio_utils.a ${SUPER_DIR}/zf_log/build/libzf_log.a -lpthread) 14 | add_compile_options(-Wall -Wextra -Wmissing-braces) 15 | 16 | #Generate the static library from the sources 17 | add_library(hat STATIC ${SOURCES_LIB}) 18 | target_link_libraries(hat rt m pthread) 19 | 20 | #add_executable(test_hat ${SOURCES}) 21 | #target_link_libraries(test_hat rt pthread ${EXTERN_LIBS}) 22 | 23 | # Set the location for library installation -- i.e., /usr/lib in this case 24 | # not really necessary in this example. Use "sudo make install" to apply 25 | install(TARGETS hat DESTINATION /usr/lib) -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_smi/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(cariboulite) 3 | set(CMAKE_BUILD_TYPE Release) 4 | 5 | # Bring the headers 6 | #add_subdirectory(kernel "${CMAKE_CURRENT_BINARY_DIR}/kernel_build") 7 | 8 | set(SUPER_DIR ${PROJECT_SOURCE_DIR}/..) 9 | include_directories(/.) 10 | include_directories(${SUPER_DIR}) 11 | 12 | # allows for wildcard additions: 13 | set(SOURCES_LIB caribou_smi.c smi_utils.c caribou_smi_modules.c) 14 | set(SOURCES ${SOURCES_LIB} test_caribou_smi.c) 15 | set(EXTERN_LIBS ${SUPER_DIR}/io_utils/build/libio_utils.a ${SUPER_DIR}/zf_log/build/libzf_log.a -lpthread) 16 | add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-missing-braces -Wno-unused-function -O3) 17 | 18 | # Generate the static library from the sources 19 | add_library(caribou_smi STATIC ${SOURCES_LIB}) 20 | #add_dependencies(caribou_smi smi_modules) 21 | 22 | #add_executable(test_caribou_smi ${SOURCES}) 23 | #target_link_libraries(test_caribou_smi ${EXTERN_LIBS} m rt pthread) -------------------------------------------------------------------------------- /software/libcariboulite/src/hat/eeprom_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __EEPROM_UTILS_H__ 2 | #define __EEPROM_UTILS_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | 11 | /* EEPROM types */ 12 | typedef enum 13 | { 14 | eeprom_type_24c32 = 4096, 15 | eeprom_type_24c64 = 8192, 16 | eeprom_type_24c128 = 16384, 17 | eeprom_type_24c256 = 32768, 18 | eeprom_type_24c512 = 65536, 19 | eeprom_type_24c1024 = 131072, 20 | } eeprom_type_en; 21 | 22 | typedef struct 23 | { 24 | uint8_t i2c_address; 25 | eeprom_type_en eeprom_type; 26 | char eeprom_type_name[32]; 27 | 28 | int bus; 29 | int eeprom_size; 30 | int initialized; 31 | } eeprom_utils_st; 32 | 33 | int eeprom_init_device(eeprom_utils_st *ee); 34 | int eeprom_close_device(eeprom_utils_st *ee); 35 | int eeprom_write(eeprom_utils_st *ee, char* buffer, int length); 36 | int eeprom_read(eeprom_utils_st *ee, char* buffer, int length); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif // __EEPROM_UTILS_H__ -------------------------------------------------------------------------------- /software/gr-caribouLite/.conda/conda-forge.yml: -------------------------------------------------------------------------------- 1 | # See https://conda-forge.org/docs/maintainer/conda_forge_yml.html for 2 | # documentation on possible keys and values. 3 | 4 | # uncomment to enable cross-compiled builds 5 | #build_platform: 6 | # linux_aarch64: linux_64 7 | # linux_ppc64le: linux_64 8 | # osx_arm64: osx_64 9 | clone_depth: 0 10 | github_actions: 11 | cancel_in_progress: false 12 | store_build_artifacts: true 13 | os_version: 14 | linux_64: cos7 15 | provider: 16 | linux: github_actions 17 | osx: github_actions 18 | win: github_actions 19 | # uncomment to enable emulated builds for additional linux platforms 20 | #linux_aarch64: github_actions 21 | #linux_ppc64le: github_actions 22 | recipe_dir: .conda/recipe 23 | # skip unnecessary files since this is not a full-fledged conda-forge feedstock 24 | skip_render: 25 | - README.md 26 | - LICENSE.txt 27 | - .gitattributes 28 | - .gitignore 29 | - build-locally.py 30 | - LICENSE 31 | test: native_and_emulated 32 | # enable uploads to Anaconda Cloud from specified branches only 33 | upload_on_branch: main 34 | -------------------------------------------------------------------------------- /examples/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(cariboulite_soapy1090) 3 | set(CMAKE_BUILD_TYPE Release) 4 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 5 | 6 | ######################################################################## 7 | ## Feature registration 8 | ######################################################################## 9 | #include(FeatureSummary) 10 | #include(CMakeDependentOption) 11 | #cmake_dependent_option(ENABLE_APPS "Enable command line applications" ON "ENABLE_LIBRARY" OFF) 12 | #add_feature_info(Apps ENABLE_APPS "command line applications") 13 | #if (NOT ENABLE_APPS) 14 | # return() 15 | #endif() 16 | 17 | ######################################################################## 18 | # Build utility executable 19 | ######################################################################## 20 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g") 21 | 22 | add_executable(caribou_dump1090 23 | dump1090.cpp 24 | modes.c 25 | cpr.c 26 | ) 27 | 28 | target_link_libraries(caribou_dump1090 SoapySDR iir_static) 29 | #install(TARGETS caribou_dump1090 DESTINATION ${CMAKE_INSTALL_BINDIR}) 30 | -------------------------------------------------------------------------------- /firmware/Makefile: -------------------------------------------------------------------------------- 1 | PROG = ../software/libcariboulite/build/test/ice40programmer 2 | filename = top 3 | pcf_file = ./io.pcf 4 | 5 | top.bin: 6 | yosys -p 'synth_ice40 -top top -json $(filename).json -blif $(filename).blif' -p 'ice40_opt' -p 'fsm_opt' $(filename).v 7 | #nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc 8 | nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc --freq 64 --parallel-refine --opt-timing --timing-allow-fail 9 | #nextpnr-ice40 --json blinky.json --pcf blinky.pcf --asc blinky.asc --gui 10 | icepack $(filename).asc $(filename).bin 11 | 12 | build: top.bin 13 | echo "Generating code blob" 14 | ../software/utils/generate_bin_blob ./top.bin cariboulite_firmware ./h-files/cariboulite_fpga_firmware.h 15 | 16 | echo "Copying firmware blob to the software lib" 17 | cp ./h-files/cariboulite_fpga_firmware.h ../software/libcariboulite/src/ 18 | 19 | prog: build 20 | $(PROG) $(filename).bin 21 | 22 | prog_only: 23 | $(PROG) $(filename).bin 24 | 25 | clean: 26 | rm -rf $(filename).json $(filename).blif $(filename).asc $(filename).bin 27 | -------------------------------------------------------------------------------- /software/gr-caribouLite/cmake/Modules/gnuradio-caribouLiteConfig.cmake: -------------------------------------------------------------------------------- 1 | find_package(PkgConfig) 2 | 3 | PKG_CHECK_MODULES(PC_GR_CARIBOULITE gnuradio-caribouLite) 4 | 5 | FIND_PATH( 6 | GR_CARIBOULITE_INCLUDE_DIRS 7 | NAMES gnuradio/caribouLite/api.h 8 | HINTS $ENV{CARIBOULITE_DIR}/include 9 | ${PC_CARIBOULITE_INCLUDEDIR} 10 | PATHS ${CMAKE_INSTALL_PREFIX}/include 11 | /usr/local/include 12 | /usr/include 13 | ) 14 | 15 | FIND_LIBRARY( 16 | GR_CARIBOULITE_LIBRARIES 17 | NAMES gnuradio-caribouLite 18 | HINTS $ENV{CARIBOULITE_DIR}/lib 19 | ${PC_CARIBOULITE_LIBDIR} 20 | PATHS ${CMAKE_INSTALL_PREFIX}/lib 21 | ${CMAKE_INSTALL_PREFIX}/lib64 22 | /usr/local/lib 23 | /usr/local/lib64 24 | /usr/lib 25 | /usr/lib64 26 | ) 27 | 28 | include("${CMAKE_CURRENT_LIST_DIR}/gnuradio-caribouLiteTarget.cmake") 29 | 30 | INCLUDE(FindPackageHandleStandardArgs) 31 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GR_CARIBOULITE DEFAULT_MSG GR_CARIBOULITE_LIBRARIES GR_CARIBOULITE_INCLUDE_DIRS) 32 | MARK_AS_ADVANCED(GR_CARIBOULITE_LIBRARIES GR_CARIBOULITE_INCLUDE_DIRS) 33 | -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_fpga/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(cariboulite) 3 | set(CMAKE_BUILD_TYPE Release) 4 | 5 | # Bring the headers 6 | set(SUPER_DIR ${PROJECT_SOURCE_DIR}/..) 7 | include_directories(/.) 8 | include_directories(${SUPER_DIR}) 9 | 10 | # Source files 11 | set(SOURCES_LIB caribou_fpga.c) 12 | set(SOURCES ${SOURCES_LIB} test_caribou_fpga.c) 13 | set(EXTERN_LIBS 14 | ${SUPER_DIR}/io_utils/build/libio_utils.a 15 | ${SUPER_DIR}/caribou_programming/build/libcaribou_prog.a 16 | ${SUPER_DIR}/zf_log/build/libzf_log.a 17 | -lpthread) 18 | #add_compile_options(-Wall -Wextra -pedantic -Werror) 19 | add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-missing-braces) 20 | 21 | #Generate the static library from the sources 22 | add_library(caribou_fpga STATIC ${SOURCES_LIB}) 23 | #add_executable(test_caribou_fpga ${SOURCES}) 24 | #target_link_libraries(test_caribou_fpga rt pthread ${EXTERN_LIBS}) 25 | 26 | # Set the location for library installation -- i.e., /usr/lib in this case 27 | # not really necessary in this example. Use "sudo make install" to apply 28 | install(TARGETS caribou_fpga DESTINATION /usr/lib) -------------------------------------------------------------------------------- /software/libcariboulite/src/rffc507x/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(cariboulite) 3 | set(CMAKE_BUILD_TYPE Release) 4 | 5 | #Bring the headers, such as Student.h into the project 6 | set(SUPER_DIR ${PROJECT_SOURCE_DIR}/..) 7 | include_directories(/.) 8 | include_directories(${SUPER_DIR}) 9 | 10 | #However, the file(GLOB...) allows for wildcard additions: 11 | set(SOURCES_LIB rffc507x.c) 12 | set(SOURCES rffc507x.c test_rffc507x.c) 13 | set(EXTERN_LIBS ${SUPER_DIR}/io_utils/build/libio_utils.a ${SUPER_DIR}/zf_log/build/libzf_log.a -lpthread) 14 | #add_compile_options(-Wall -Wextra -pedantic -Werror) 15 | add_compile_options(-Wall -Wextra -Wno-missing-braces) 16 | 17 | #Generate the static library from the sources 18 | add_library(rffc507x STATIC ${SOURCES_LIB}) 19 | target_link_libraries(rffc507x rt m pthread) 20 | 21 | #add_executable(test_rffc507x ${SOURCES}) 22 | #target_link_libraries(test_rffc507x rt m pthread ${EXTERN_LIBS}) 23 | 24 | #Set the location for library installation -- i.e., /usr/lib in this case 25 | # not really necessary in this example. Use "sudo make install" to apply 26 | install(TARGETS rffc507x DESTINATION /usr/lib) 27 | -------------------------------------------------------------------------------- /software/libcariboulite/src/at86rf215/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(cariboulite) 3 | set(CMAKE_BUILD_TYPE Release) 4 | 5 | #Bring the headers, such as Student.h into the project 6 | set(SUPER_DIR ${PROJECT_SOURCE_DIR}/..) 7 | include_directories(/.) 8 | include_directories(${SUPER_DIR}) 9 | 10 | #However, the file(GLOB...) allows for wildcard additions: 11 | set(SOURCES_LIB at86rf215.c at86rf215_events.c at86rf215_radio.c at86rf215_baseband.c) 12 | set(SOURCES ${SOURCES_LIB} test_at86rf215.c) 13 | set(EXTERN_LIBS ${SUPER_DIR}/io_utils/build/libio_utils.a ${SUPER_DIR}/zf_log/build/libzf_log.a -lpthread) 14 | #add_compile_options(-Wall -Wextra -pedantic -Werror) 15 | add_compile_options(-Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-braces) 16 | 17 | #Generate the static library from the sources 18 | add_library(at86rf215 STATIC ${SOURCES_LIB}) 19 | #add_executable(test_at86rf215 ${SOURCES}) 20 | #target_link_libraries(test_at86rf215 rt pthread ${EXTERN_LIBS}) 21 | 22 | #Set the location for library installation -- i.e., /usr/lib in this case 23 | # not really necessary in this example. Use "sudo make install" to apply 24 | install(TARGETS at86rf215 DESTINATION /usr/lib) -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_programming/caribou_prog.h: -------------------------------------------------------------------------------- 1 | #ifndef __CARIBOU_PROG_H__ 2 | #define __CARIBOU_PROG_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include "io_utils/io_utils.h" 11 | #include "io_utils/io_utils_spi.h" 12 | 13 | /** 14 | * @brief caribou-sdr programmer context 15 | */ 16 | typedef struct 17 | { 18 | int cs_pin; 19 | int cdone_pin; 20 | int reset_pin; 21 | int verbose; 22 | 23 | io_utils_spi_st* io_spi; 24 | 25 | int io_spi_handle; 26 | int initialized; 27 | } caribou_prog_st; 28 | 29 | int caribou_prog_init(caribou_prog_st *dev, io_utils_spi_st* io_spi); 30 | int caribou_prog_release(caribou_prog_st *dev); 31 | int caribou_prog_configure(caribou_prog_st *dev, char *bitfilename); 32 | int caribou_prog_configure_from_buffer( caribou_prog_st *dev, 33 | uint8_t *buffer, 34 | uint32_t buffer_size); 35 | 36 | /* 37 | * Hard reset pin toggling function 38 | Level: if -1 => a full reset (1=>0=>1) cycle is performed 39 | if 0 / 1 => the pin is reset or set accordingly 40 | */ 41 | int caribou_prog_hard_reset(caribou_prog_st *dev, int level); 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif // __CARIBOU_PROG_H__ 48 | -------------------------------------------------------------------------------- /software/libcariboulite/src/datatypes/test_circular_buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "circular_buffer.h" 2 | #include 3 | #include 4 | 5 | 6 | circular_buffer *buf = NULL; 7 | 8 | uint32_t data1[100] = {0}; 9 | uint32_t data2[100] = {0}; 10 | 11 | void producer(int times) 12 | { 13 | while (true) 14 | { 15 | sleep(0); 16 | printf("THREAD! PUT1 100, ret %lu\n", buf->put(data1, 100)); 17 | sleep(0); 18 | printf("PUT1 60, ret %lu\n", buf->put(data1, 60)); 19 | } 20 | } 21 | 22 | void consumer(int times) 23 | { 24 | printf("Capacity = %lu\n", buf->capacity()); 25 | while (true) 26 | { 27 | printf("GET1 100, ret %lu\n", buf->get(data2, 100)); 28 | printf("GET1 100, ret %lu\n", buf->get(data2, 100)); 29 | printf("GET1 100, ret %lu\n", buf->get(data2, 100)); 30 | printf("GET1 100, ret %lu\n", buf->get(data2, 60)); 31 | } 32 | 33 | printf("finished\n"); 34 | } 35 | 36 | int main () 37 | { 38 | for (int i = 0; i < 100; i++) 39 | { 40 | data1[i] = i; 41 | data2[i] = i*i; 42 | } 43 | 44 | buf = new circular_buffer(200, true, true); 45 | 46 | int times = 1; 47 | std::thread t1(producer, times); 48 | std::thread t2(consumer, times); 49 | 50 | t2.join(); 51 | t1.join(); 52 | 53 | delete buf; 54 | return 0; 55 | } -------------------------------------------------------------------------------- /software/devicetrees/cariboulite-overlay.dts: -------------------------------------------------------------------------------- 1 | // Description: Overlay to enable character device interface for SMI. 2 | // Original Author: Luke Wren 3 | // Adaptation to CaribouLite: David Michaeli (cariboulabs.co@gmail.com) 4 | 5 | 6 | /dts-v1/; 7 | /plugin/; 8 | 9 | /{ 10 | compatible = "brcm,bcm2835"; 11 | 12 | fragment@0 { 13 | target = <&soc>; 14 | __overlay__ { 15 | smi_dev { 16 | compatible = "brcm,bcm2835-smi-dev"; 17 | smi_handle = <&smi>; 18 | status = "okay"; 19 | }; 20 | }; 21 | }; 22 | 23 | fragment@1 { 24 | target = <&smi>; 25 | __overlay__ { 26 | pinctrl-names = "default"; 27 | pinctrl-0 = <&smi_pins>; 28 | status = "okay"; 29 | /* assigned-clock-rates = <500000000>; */ 30 | }; 31 | }; 32 | 33 | fragment@2 { 34 | target = <&gpio>; 35 | __overlay__ { 36 | smi_pins: smi_pins { 37 | /* Don't configure the top two address bits, as these are already used as ID_SD and ID_SC */ 38 | brcm,pins = <2 3 6 7 8 9 10 11 12 13 14 15 24 25>; 39 | brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5>; 40 | 41 | /* /CS, /WE and /OE are pulled high, as they are generally active low signals */ 42 | brcm,pull = <2 2 2 2 0 0 0 0 0 0 0 0 0 0>; 43 | }; 44 | }; 45 | }; 46 | }; 47 | -------------------------------------------------------------------------------- /software/libcariboulite/src/production_utils/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(cariboulite) 3 | set(CMAKE_BUILD_TYPE Release) 4 | 5 | #Bring the headers, such as Student.h into the project 6 | set(SUPER_DIR ${PROJECT_SOURCE_DIR}/..) 7 | include_directories(/.) 8 | include_directories(${SUPER_DIR}) 9 | 10 | #However, the file(GLOB...) allows for wildcard additions: 11 | set(SOURCES_LCD lcd.c test_lcd.c) 12 | set(SOURCES_POWERMON hat_powermon.c hat_powermon_test.c) 13 | set(SOURCES_LIB production_utils.c hat_powermon.c lcd.c production_testing.c) 14 | #add_compile_options(-Wall -Wextra -pedantic -Werror) 15 | add_compile_options(-Wall -Wextra -Wno-missing-braces) 16 | 17 | add_executable(test_lcd ${SOURCES_LCD}) 18 | target_link_libraries(test_lcd rt m pthread zmq ${SUPER_DIR}/zf_log/build/libzf_log.a ${SUPER_DIR}/io_utils/build/libio_utils.a ${EXTERN_LIBS}) 19 | 20 | add_executable(test_power_mon ${SOURCES_POWERMON}) 21 | target_link_libraries(test_power_mon rt m pthread zmq ${SUPER_DIR}/zf_log/build/libzf_log.a ${SUPER_DIR}/io_utils/build/libio_utils.a ${EXTERN_LIBS}) 22 | 23 | #Generate the static library from the sources 24 | add_library(production_utils STATIC ${SOURCES_LIB}) 25 | target_include_directories(production_utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 26 | -------------------------------------------------------------------------------- /software/libcariboulite/src/production_utils/lcd.h: -------------------------------------------------------------------------------- 1 | #ifndef __LCD_H__ 2 | #define __LCD_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | typedef void (*lcd_key_callback)(void* context, int key1, int key2); 18 | typedef enum 19 | { 20 | lcd_button_bottom = 0, 21 | lcd_button_top = 1, 22 | } lcd_button_en; 23 | 24 | typedef struct 25 | { 26 | // thread 27 | pthread_t comm_thread; 28 | bool thread_running; 29 | void* cb_context; 30 | lcd_key_callback cb; 31 | pid_t py_pid; 32 | 33 | // key state 34 | int key1; 35 | int key2; 36 | 37 | // lcd 38 | void *context; 39 | void *requester; 40 | } lcd_st; 41 | 42 | int lcd_init(lcd_st* dev, lcd_key_callback cb, void* cb_context); 43 | int lcd_close(lcd_st* dev); 44 | int lcd_clear_screan(lcd_st* dev); 45 | int lcd_write(lcd_st* dev, int row, int col, char* text); 46 | int lcd_writeln(lcd_st* dev, char* line1, char* line2, int clear); 47 | int lcd_get_keys(lcd_st* dev, int* key1, int* key2); 48 | int lcd_set_params(lcd_st* dev, int brightness, int contrast); 49 | 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif //__LCD_H__ -------------------------------------------------------------------------------- /software/libcariboulite/src/io_utils/io_utils_fs.h: -------------------------------------------------------------------------------- 1 | #ifndef __IO_UTILS_FS_H__ 2 | #define __IO_UTILS_FS_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | // files 22 | int io_utils_file_exists(char* fname, int *size, int *dir, int *file, int *dev); 23 | int io_utils_write_to_file(char* fname, char* data, int size_of_data); 24 | int io_utils_read_from_file(char* fname, char* data, int len_to_read); 25 | int io_utils_read_string_from_file(char* path, char* filename, char* data, int len); 26 | 27 | // i2c 28 | int io_utils_i2cbus_exists(void); 29 | void io_utils_parse_command(char *line, char **argv); 30 | int io_utils_probe_gpio_i2c(void); 31 | 32 | // command execution 33 | int io_utils_execute_command(char **argv); 34 | int io_utils_execute_command_read(char *cmd, char* res, int res_size); 35 | pid_t io_utils_execute_command_parallel(char **argv); 36 | int io_utils_wait_command_parallel(pid_t pid); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif // __IO_UTILS_FS_H__ 43 | -------------------------------------------------------------------------------- /software/libcariboulite/src/io_utils/io_utils_sys_info.h: -------------------------------------------------------------------------------- 1 | #ifndef __IO_UTILS_SYS_INFO_H__ 2 | #define __IO_UTILS_SYS_INFO_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | typedef enum 20 | { 21 | io_utils_processor_BCM2835 = 0, 22 | io_utils_processor_BCM2836 = 1, 23 | io_utils_processor_BCM2837 = 2, 24 | io_utils_processor_BCM2711 = 3, 25 | io_utils_processor_UNKNOWN = 4, 26 | } io_utils_processor_type_en; 27 | 28 | typedef struct 29 | { 30 | int p1_revision; 31 | char *ram; 32 | char *manufacturer; 33 | char *processor; 34 | char *type; 35 | char revision[1024]; 36 | char serial_number[32]; 37 | 38 | io_utils_processor_type_en processor_type; 39 | uint32_t ram_size_mbytes; 40 | uint32_t phys_reg_base; 41 | uint32_t sys_clock_hz; 42 | uint32_t bus_reg_base; 43 | } io_utils_sys_info_st; 44 | 45 | int io_utils_get_rpi_info(io_utils_sys_info_st *info); 46 | void io_utils_print_rpi_info(io_utils_sys_info_st *info); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif // __IO_UTILS_SYS_INFO_H__ 53 | -------------------------------------------------------------------------------- /software/libcariboulite/src/datatypes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(cariboulite) 3 | set(CMAKE_BUILD_TYPE Release) 4 | 5 | #Bring the headers, such as Student.h into the project 6 | set(SUPER_DIR ${PROJECT_SOURCE_DIR}/..) 7 | include_directories(/.) 8 | include_directories(${SUPER_DIR}) 9 | 10 | #However, the file(GLOB...) allows for wildcard additions: 11 | set(SOURCES_LIB tsqueue.c tiny_list.c circular_buffer.cpp entropy.c) 12 | #add_compile_options(-Wall -Wextra -pedantic -Werror) 13 | add_compile_options(-Wall -Wextra -pedantic -Wno-missing-braces) 14 | 15 | #Generate the static library from the sources 16 | add_library(datatypes STATIC ${SOURCES_LIB}) 17 | target_include_directories(datatypes PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 18 | 19 | #add_executable(test_tsqueue test_tsqueue.c) 20 | #target_link_libraries(test_tsqueue datatypes pthread) 21 | 22 | #add_executable(test_circular_buffer test_circular_buffer.cpp) 23 | #target_link_libraries(test_circular_buffer datatypes pthread) 24 | 25 | add_executable(test_tiny_list test_tiny_list.c) 26 | target_link_libraries(test_tiny_list datatypes pthread) 27 | 28 | #Set the location for library installation -- i.e., /usr/lib in this case 29 | # not really necessary in this example. Use "sudo make install" to apply 30 | install(TARGETS datatypes DESTINATION /usr/lib) -------------------------------------------------------------------------------- /software/gr-caribouLite/include/gnuradio/caribouLite/caribouLiteSource.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2023 CaribouLabs LTD. 4 | * 5 | * SPDX-License-Identifier: GPL-3.0-or-later 6 | */ 7 | 8 | #ifndef INCLUDED_CARIBOULITE_CARIBOULITESOURCE_H 9 | #define INCLUDED_CARIBOULITE_CARIBOULITESOURCE_H 10 | 11 | #include 12 | #include 13 | 14 | namespace gr { 15 | namespace caribouLite { 16 | 17 | /*! 18 | * \brief <+description of block+> 19 | * \ingroup caribouLite 20 | * 21 | */ 22 | class CARIBOULITE_API caribouLiteSource : virtual public gr::sync_block 23 | { 24 | public: 25 | typedef std::shared_ptr sptr; 26 | 27 | /*! 28 | * \brief Return a shared_ptr to a new instance of caribouLite::caribouLiteSource. 29 | * 30 | * To avoid accidental use of raw pointers, caribouLite::caribouLiteSource's 31 | * constructor is in a private implementation 32 | * class. caribouLite::caribouLiteSource::make is the public interface for 33 | * creating new instances. 34 | */ 35 | static sptr make(int channel=0, bool enable_agc=false, float rx_gain=40, float rx_bw=2500000, float sample_rate=4000000, float freq=900000000); 36 | }; 37 | 38 | } // namespace caribouLite 39 | } // namespace gr 40 | 41 | #endif /* INCLUDED_CARIBOULITE_CARIBOULITESOURCE_H */ 42 | -------------------------------------------------------------------------------- /software/gr-caribouLite/python/caribouLite/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-caribouLite 5 | # 6 | # SPDX-License-Identifier: GPL-3.0-or-later 7 | # 8 | 9 | ######################################################################## 10 | # Include python install macros 11 | ######################################################################## 12 | include(GrPython) 13 | if(NOT PYTHONINTERP_FOUND) 14 | return() 15 | endif() 16 | 17 | add_subdirectory(bindings) 18 | 19 | ######################################################################## 20 | # Install python sources 21 | ######################################################################## 22 | gr_python_install(FILES __init__.py DESTINATION ${GR_PYTHON_DIR}/gnuradio/caribouLite) 23 | 24 | ######################################################################## 25 | # Handle the unit tests 26 | ######################################################################## 27 | include(GrTest) 28 | 29 | set(GR_TEST_TARGET_DEPS gnuradio-caribouLite) 30 | 31 | # Create a package directory that tests can import. It includes everything 32 | # from `python/`. 33 | add_custom_target( 34 | copy_module_for_tests ALL 35 | COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} 36 | ${PROJECT_BINARY_DIR}/test_modules/gnuradio/caribouLite/) 37 | -------------------------------------------------------------------------------- /software/libcariboulite/src/datatypes/entropy.c: -------------------------------------------------------------------------------- 1 | #ifndef ZF_LOG_LEVEL 2 | #define ZF_LOG_LEVEL ZF_LOG_VERBOSE 3 | #endif 4 | #define ZF_LOG_DEF_SRCLOC ZF_LOG_SRCLOC_LONG 5 | #define ZF_LOG_TAG "ENTROPY" 6 | #include "zf_log/zf_log.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "entropy.h" 18 | 19 | 20 | typedef struct { 21 | int bit_count; /* number of bits of entropy in data */ 22 | int byte_count; /* number of bytes of data in array */ 23 | unsigned char buf[1]; 24 | } entropy_t; 25 | 26 | //===================================================== 27 | int add_entropy(uint8_t byte) 28 | { 29 | int rand_fid = open("/dev/urandom", O_RDWR); 30 | if (rand_fid != 0) 31 | { 32 | // error opening device 33 | ZF_LOGE("Opening /dev/urandom device file failed"); 34 | return -1; 35 | } 36 | 37 | entropy_t ent = 38 | { 39 | .bit_count = 8, 40 | .byte_count = 1, 41 | .buf = {byte}, 42 | }; 43 | 44 | if (ioctl(rand_fid, RNDADDENTROPY, &ent) != 0) 45 | { 46 | ZF_LOGE("IOCTL to /dev/urandom device file failed"); 47 | } 48 | 49 | if (close(rand_fid) !=0 ) 50 | { 51 | ZF_LOGE("Closing /dev/urandom device file failed"); 52 | return -1; 53 | } 54 | 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /software/libcariboulite/README.md: -------------------------------------------------------------------------------- 1 | # CaribouLite RPI API 2 | This folder contains the low-level and SoapySDR APIs for CaribouLite 3 | 4 | # Building 5 | To start from scratch we need to check for the dependencies and install them as needed. 6 | 7 | Dependencies installation: 8 | ``` 9 | # Update the package definitions 10 | sudo apt update 11 | 12 | # We used gcc version 8.3+ 13 | sudo apt install gcc 14 | 15 | # We used libsoapysdr-dev version 0.6.1-4+ 16 | sudo apt install libsoapysdr-dev libpthread-stubs0-dev 17 | 18 | # cmake version 3.15+ 19 | sudo apt install cmake 20 | ``` 21 | 22 | Now to compile we use `cmake` as follows: 23 | 24 | ``` 25 | # create the building directory to contain 26 | # compilation / linking artifacts. if already exists skip 27 | # the creation 28 | mkdir build 29 | 30 | # goto the build directory 31 | cd build 32 | 33 | # tell cmake to create the Makefiles 34 | # according to the code in the parent directory 35 | cmake ../ 36 | 37 | # build the code (this will take about 30 seconds @ RPi4) 38 | make 39 | 40 | # install the package in your Linux 41 | # environment (including SoapyAPIs) 42 | sudo make install 43 | ``` 44 | 45 | # License 46 | Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License. -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/text.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 5 | # This file is a part of gr-caribouLite 6 | # 7 | # SPDX-License-Identifier: GPL-3.0-or-later 8 | # 9 | # 10 | """ 11 | Utilities for extracting text from generated classes. 12 | """ 13 | 14 | 15 | def is_string(txt): 16 | if isinstance(txt, str): 17 | return True 18 | try: 19 | if isinstance(txt, str): 20 | return True 21 | except NameError: 22 | pass 23 | return False 24 | 25 | 26 | def description(obj): 27 | if obj is None: 28 | return None 29 | return description_bit(obj).strip() 30 | 31 | 32 | def description_bit(obj): 33 | if hasattr(obj, 'content'): 34 | contents = [description_bit(item) for item in obj.content] 35 | result = ''.join(contents) 36 | elif hasattr(obj, 'content_'): 37 | contents = [description_bit(item) for item in obj.content_] 38 | result = ''.join(contents) 39 | elif hasattr(obj, 'value'): 40 | result = description_bit(obj.value) 41 | elif is_string(obj): 42 | return obj 43 | else: 44 | raise Exception( 45 | 'Expecting a string or something with content, content_ or value attribute') 46 | # If this bit is a paragraph then add one some line breaks. 47 | if hasattr(obj, 'name') and obj.name == 'para': 48 | result += "\n\n" 49 | return result 50 | -------------------------------------------------------------------------------- /software/gr-caribouLite/cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | # http://www.vtk.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F 2 | 3 | IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 4 | MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 5 | ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 6 | 7 | FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 8 | STRING(REGEX REPLACE "\n" ";" files "${files}") 9 | FOREACH(file ${files}) 10 | MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 11 | IF(EXISTS "$ENV{DESTDIR}${file}") 12 | EXEC_PROGRAM( 13 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 14 | OUTPUT_VARIABLE rm_out 15 | RETURN_VALUE rm_retval 16 | ) 17 | IF(NOT "${rm_retval}" STREQUAL 0) 18 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 19 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 20 | ELSEIF(IS_SYMLINK "$ENV{DESTDIR}${file}") 21 | EXEC_PROGRAM( 22 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 23 | OUTPUT_VARIABLE rm_out 24 | RETURN_VALUE rm_retval 25 | ) 26 | IF(NOT "${rm_retval}" STREQUAL 0) 27 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 28 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 29 | ELSE(EXISTS "$ENV{DESTDIR}${file}") 30 | MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 31 | ENDIF(EXISTS "$ENV{DESTDIR}${file}") 32 | ENDFOREACH(file) 33 | -------------------------------------------------------------------------------- /hardware/rev2/pcb/gerber/cariboulite_r2.8.EXTREP: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------------------ 2 | Gerber File Extension Report For: cariboulite_r2.GBR 26/05/2022 15:06:27 3 | ------------------------------------------------------------------------------------------ 4 | 5 | 6 | ------------------------------------------------------------------------------------------ 7 | Layer Extension Layer Description 8 | ------------------------------------------------------------------------------------------ 9 | .GTL Component Side 10 | .G1 Layer 1 11 | .G2 Layer 2 12 | .GBL Solder Side 13 | .GTO Top Overlay 14 | .GTP Top Paste 15 | .GTS Top Solder 16 | .GBS Bottom Solder 17 | .GBP Bottom Paste 18 | .GBO Bottom Overlay 19 | .Outline Outline 20 | .GD1 Drill Drawing 21 | .GD2 Drill Drawing 22 | .GD3 Drill Drawing 23 | ------------------------------------------------------------------------------------------ 24 | -------------------------------------------------------------------------------- /software/libcariboulite/src/io_utils/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(cariboulite) 3 | set(CMAKE_BUILD_TYPE Release) 4 | 5 | #Bring the headers, such as Student.h into the project 6 | set(SUPER_DIR ${PROJECT_SOURCE_DIR}/..) 7 | include_directories(/.) 8 | include_directories(${SUPER_DIR}) 9 | 10 | #However, the file(GLOB...) allows for wildcard additions: 11 | set(SOURCES_LIB io_utils.c io_utils_spi.c io_utils_sys_info.c io_utils_fs.c io_utils_i2c.c) 12 | #set(SOURCES_PIG_LIB pigpio/pigpio.c pigpio/command.c) 13 | set(SOURCES_RPI_LIB rpi/rpi.c) 14 | set(SOURCES_SPIDEV_LIB spidev/spi.c) 15 | set(EXTERN_LIBS ${SUPER_DIR}/zf_log/build/libzf_log.a) 16 | #add_compile_options(-Wall -Wextra -pedantic -Werror) 17 | #add_compile_options(-Wall -Wextra) 18 | add_compile_options(-Wno-missing-braces -Wno-format-zero-length -Wall) 19 | 20 | 21 | set(THREADS_PREFER_PTHREAD_FLAG TRUE) 22 | find_package(Threads REQUIRED) 23 | 24 | #Generate the static library from the sources 25 | #add_library(io_utils STATIC ${SOURCES_LIB} ${SOURCES_PIG_LIB}) 26 | add_library(io_utils STATIC ${SOURCES_LIB} ${SOURCES_RPI_LIB} ${SOURCES_SPIDEV_LIB}) 27 | target_include_directories(io_utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 28 | target_link_libraries(io_utils PRIVATE pthread) 29 | 30 | #add_executable(test_io_utils main.c) 31 | #target_link_libraries(test_io_utils io_utils pthread ${EXTERN_LIBS}) 32 | 33 | #Set the location for library installation -- i.e., /usr/lib in this case 34 | # not really necessary in this example. Use "sudo make install" to apply 35 | install(TARGETS io_utils DESTINATION /usr/lib) -------------------------------------------------------------------------------- /software/libcariboulite/src/datatypes/tiny_list.h: -------------------------------------------------------------------------------- 1 | #ifndef __TINY_LIST_H__ 2 | #define __TINY_LIST_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | typedef enum 14 | { 15 | pos_head = 0, 16 | pos_tail = 1, 17 | } tiny_list_pos_en; 18 | 19 | struct tiny_list_node_t 20 | { 21 | void* data; 22 | unsigned int len; 23 | 24 | struct tiny_list_node_t *last; 25 | struct tiny_list_node_t *next; 26 | }; 27 | 28 | typedef struct tiny_list_node_t tiny_list_node_st; 29 | 30 | typedef struct 31 | { 32 | pthread_mutex_t mtx; 33 | struct tiny_list_node_t* head; 34 | struct tiny_list_node_t* tail; 35 | 36 | unsigned int num_of_elements; 37 | } tiny_list_st; 38 | 39 | 40 | int tiny_list_init (tiny_list_st** list); 41 | void tiny_list_free (tiny_list_st* list); 42 | int tiny_list_add (tiny_list_st* list, void* data, unsigned int len, tiny_list_pos_en pos); 43 | int tiny_list_remove (tiny_list_st* list, void* data, unsigned int *len, tiny_list_pos_en pos); 44 | void tiny_list_remove_all (tiny_list_st* list); 45 | int tiny_list_peek (tiny_list_st* list, void* data, unsigned int *len, tiny_list_pos_en pos); 46 | int tiny_list_num_elements (tiny_list_st* list); 47 | void tiny_list_print (tiny_list_st* list); 48 | tiny_list_node_st* tiny_list_create_node (void *data, unsigned int len); 49 | tiny_list_node_st* tiny_list_destroy_node (tiny_list_node_st* node); 50 | void tiny_list_print_node (tiny_list_node_st* node); 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif //__TINY_LIST_H__ -------------------------------------------------------------------------------- /software/gr-caribouLite/python/caribouLite/bindings/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # SPDX-License-Identifier: GPL-3.0-or-later 6 | # 7 | 8 | ######################################################################## 9 | # Check if there is C++ code at all 10 | ######################################################################## 11 | if(NOT caribouLite_sources) 12 | message(STATUS "No C++ sources... skipping python bindings") 13 | return() 14 | endif(NOT caribouLite_sources) 15 | 16 | ######################################################################## 17 | # Check for pygccxml 18 | ######################################################################## 19 | gr_python_check_module_raw("pygccxml" "import pygccxml" PYGCCXML_FOUND) 20 | 21 | include(GrPybind) 22 | 23 | ######################################################################## 24 | # Python Bindings 25 | ######################################################################## 26 | 27 | list(APPEND caribouLite_python_files 28 | caribouLiteSource_python.cc python_bindings.cc) 29 | 30 | gr_pybind_make_oot(caribouLite ../../.. gr::caribouLite "${caribouLite_python_files}") 31 | 32 | # copy bindings extension for use in QA test module 33 | add_custom_command( 34 | TARGET caribouLite_python 35 | POST_BUILD 36 | COMMAND ${CMAKE_COMMAND} -E copy $ 37 | ${PROJECT_BINARY_DIR}/test_modules/gnuradio/caribouLite/) 38 | 39 | install( 40 | TARGETS caribouLite_python 41 | DESTINATION ${GR_PYTHON_DIR}/gnuradio/caribouLite 42 | COMPONENT pythonapi) 43 | -------------------------------------------------------------------------------- /software/utils/README.md: -------------------------------------------------------------------------------- 1 | # Utilities 2 | 3 | ## `generate_bin_blob.c` 4 | converts a binary file into C/C++ h-file code with versioning and dating. We use this converter to embed the device-tree overlays binaries and FPGA firmware binaries directly into the library code. 5 | In such way, the lib is self contained and doesn't have floating around dependencies. 6 | 7 | Usage: 8 | ``` 9 | $ ./generate_bin_blob input_file.bin variable_name output_file.h 10 | ``` 11 | 12 | **The output file will have the following structure:** 13 | 14 | ``` 15 | #ifndef __cariboulite_dtbo_h__ 16 | #define __cariboulite_dtbo_h__ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | /* 27 | * Time tagging of the module through the 'struct tm' structure 28 | * Date: 2021-09-17 29 | * Time: 09:56:44 30 | */ 31 | struct tm cariboulite_dtbo_date_time = { 32 | .tm_sec = 44, 33 | .tm_min = 56, 34 | .tm_hour = 9, 35 | .tm_mday = 17, 36 | .tm_mon = 8, /* +1 */ 37 | .tm_year = 121, /* +1900 */ 38 | }; 39 | 40 | /* 41 | * Data blob of variable cariboulite_dtbo: 42 | * Size: 1112 bytes 43 | * Original filename: ./cariboulite.dtbo 44 | */ 45 | uint8_t cariboulite_dtbo[] = { 46 | 0xD0, 0x0D, 0xFE, 0xED, 0x00, 0x00, 0x04, 0x58, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x03, 0xDC, 47 | 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 48 | ... 49 | 0x6D, 0x69, 0x00, 0x67, 0x70, 0x69, 0x6F, 0x00, 50 | }; 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif // __cariboulite_dtbo_h__ 57 | ``` 58 | 59 | -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-caribouLite 5 | # 6 | # SPDX-License-Identifier: GPL-3.0-or-later 7 | # 8 | 9 | ######################################################################## 10 | # Create the doxygen configuration file 11 | ######################################################################## 12 | file(TO_NATIVE_PATH ${PROJECT_SOURCE_DIR} top_srcdir) 13 | file(TO_NATIVE_PATH ${PROJECT_BINARY_DIR} top_builddir) 14 | file(TO_NATIVE_PATH ${PROJECT_SOURCE_DIR} abs_top_srcdir) 15 | file(TO_NATIVE_PATH ${PROJECT_BINARY_DIR} abs_top_builddir) 16 | 17 | set(HAVE_DOT ${DOXYGEN_DOT_FOUND}) 18 | set(enable_html_docs YES) 19 | set(enable_latex_docs NO) 20 | set(enable_mathjax NO) 21 | set(enable_xml_docs YES) 22 | 23 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in 24 | ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) 25 | 26 | set(BUILT_DIRS ${CMAKE_CURRENT_BINARY_DIR}/xml ${CMAKE_CURRENT_BINARY_DIR}/html) 27 | 28 | ######################################################################## 29 | # Make and install doxygen docs 30 | ######################################################################## 31 | add_custom_command( 32 | OUTPUT ${BUILT_DIRS} 33 | COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 34 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 35 | COMMENT "Generating documentation with doxygen") 36 | 37 | add_custom_target(doxygen_target ALL DEPENDS ${BUILT_DIRS}) 38 | 39 | install(DIRECTORY ${BUILT_DIRS} DESTINATION ${GR_PKG_DOC_DIR}) 40 | -------------------------------------------------------------------------------- /examples/cpp/cpr.h: -------------------------------------------------------------------------------- 1 | // Part of dump1090, a Mode S message decoder for RTLSDR devices. 2 | // 3 | // cpr.h - Compact Position Reporting prototypes 4 | // 5 | // Copyright (c) 2014,2015 Oliver Jowett 6 | // 7 | // This file is free software: you may copy, redistribute and/or modify it 8 | // under the terms of the GNU General Public License as published by the 9 | // Free Software Foundation, either version 2 of the License, or (at your 10 | // option) any later version. 11 | // 12 | // This file is distributed in the hope that it will be useful, but 13 | // WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | // General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | 20 | #ifndef DUMP1090_CPR_H 21 | #define DUMP1090_CPR_H 22 | 23 | int decodeCPRairborne(int even_cprlat, int even_cprlon, 24 | int odd_cprlat, int odd_cprlon, 25 | int fflag, 26 | double *out_lat, double *out_lon); 27 | 28 | int decodeCPRsurface(double reflat, double reflon, 29 | int even_cprlat, int even_cprlon, 30 | int odd_cprlat, int odd_cprlon, 31 | int fflag, 32 | double *out_lat, double *out_lon); 33 | 34 | int decodeCPRrelative(double reflat, double reflon, 35 | int cprlat, int cprlon, 36 | int fflag, int surface, 37 | double *out_lat, double *out_lon); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /software/gr-caribouLite/python/caribouLite/bindings/python_bindings.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | 10 | #include 11 | 12 | #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 13 | #include 14 | 15 | namespace py = pybind11; 16 | 17 | // Headers for binding functions 18 | /**************************************/ 19 | // The following comment block is used for 20 | // gr_modtool to insert function prototypes 21 | // Please do not delete 22 | /**************************************/ 23 | // BINDING_FUNCTION_PROTOTYPES( 24 | void bind_caribouLiteSource(py::module& m); 25 | // ) END BINDING_FUNCTION_PROTOTYPES 26 | 27 | 28 | // We need this hack because import_array() returns NULL 29 | // for newer Python versions. 30 | // This function is also necessary because it ensures access to the C API 31 | // and removes a warning. 32 | void* init_numpy() 33 | { 34 | import_array(); 35 | return NULL; 36 | } 37 | 38 | PYBIND11_MODULE(caribouLite_python, m) 39 | { 40 | // Initialize the numpy C API 41 | // (otherwise we will see segmentation faults) 42 | init_numpy(); 43 | 44 | // Allow access to base block methods 45 | py::module::import("gnuradio.gr"); 46 | 47 | /**************************************/ 48 | // The following comment block is used for 49 | // gr_modtool to insert binding function calls 50 | // Please do not delete 51 | /**************************************/ 52 | // BINDING_FUNCTION_CALLS( 53 | bind_caribouLiteSource(m); 54 | // ) END BINDING_FUNCTION_CALLS 55 | } -------------------------------------------------------------------------------- /software/gr-caribouLite/lib/caribouLiteSource_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2023 CaribouLabs LTD. 4 | * 5 | * SPDX-License-Identifier: GPL-3.0-or-later 6 | */ 7 | 8 | #ifndef INCLUDED_CARIBOULITE_CARIBOULITESOURCE_IMPL_H 9 | #define INCLUDED_CARIBOULITE_CARIBOULITESOURCE_IMPL_H 10 | 11 | #include 12 | #include 13 | #include "circular_buffer.h" 14 | 15 | namespace gr 16 | { 17 | namespace caribouLite 18 | { 19 | class caribouLiteSource_impl : public caribouLiteSource 20 | { 21 | private: 22 | CaribouLiteRadio::RadioType _channel; 23 | bool _enable_agc; 24 | float _rx_gain; 25 | float _rx_bw; 26 | float _sample_rate; 27 | float _frequency; 28 | size_t _mtu_size; 29 | 30 | CaribouLite* _cl; 31 | CaribouLiteRadio *_radio; 32 | circular_buffer *_rx_queue; 33 | 34 | private: 35 | void receivedSamples(CaribouLiteRadio* radio, const std::complex* samples, CaribouLiteMeta* sync, size_t num_samples); 36 | 37 | public: 38 | caribouLiteSource_impl(int channel, bool enable_agc, float rx_gain, float rx_bw, float sample_rate, float freq); 39 | ~caribouLiteSource_impl(); 40 | 41 | int work( 42 | int noutput_items, 43 | gr_vector_const_void_star &input_items, 44 | gr_vector_void_star &output_items 45 | ); 46 | }; 47 | 48 | } // namespace caribouLite 49 | } // namespace gr 50 | 51 | #endif /* INCLUDED_CARIBOULITE_CARIBOULITESOURCE_IMPL_H */ 52 | -------------------------------------------------------------------------------- /hardware/rev2/pcb/gerber/cariboulite_r2.8.Outline: -------------------------------------------------------------------------------- 1 | G04* 2 | G04 #@! TF.GenerationSoftware,Altium Limited,CircuitStudio,1.5.2 (30)* 3 | G04* 4 | G04 Layer_Color=16740166* 5 | %FSLAX25Y25*% 6 | %MOIN*% 7 | G70* 8 | G01* 9 | G75* 10 | %ADD49C,0.00500*% 11 | D49* 12 | X1276749Y699502D02* 13 | G03* 14 | X1290528Y713281I0J13780D01* 15 | G01* 16 | X1034623Y712769D02* 17 | G03* 18 | X1047891Y699502I13268J0D01* 19 | G01* 20 | X1048995Y817730D02* 21 | G03* 22 | X1034623Y803358I0J-14372D01* 23 | G01* 24 | X1290528Y813564D02* 25 | G03* 26 | X1286362Y817730I-4166J0D01* 27 | G01* 28 | X1047891Y699502D02* 29 | X1276749Y699502D01* 30 | X1034623Y712769D02* 31 | X1034623Y796470D01* 32 | X1290528Y718006D02* 33 | Y767631D01* 34 | X1084591Y815466D02* 35 | X1107961D01* 36 | X1034623Y796470D02* 37 | Y803358D01* 38 | X1290528Y713281D02* 39 | Y718006D01* 40 | X1110224Y817730D02* 41 | X1286362D01* 42 | X1290528Y767631D02* 43 | Y813564D01* 44 | X1082327Y817730D02* 45 | X1084591Y815466D01* 46 | X1048995Y817730D02* 47 | X1082327D01* 48 | X1107961Y815466D02* 49 | X1110224Y817730D01* 50 | X1276749Y699502D02* 51 | G03* 52 | X1290528Y713281I0J13780D01* 53 | G01* 54 | X1034623Y712769D02* 55 | G03* 56 | X1047891Y699502I13268J0D01* 57 | G01* 58 | X1048995Y817730D02* 59 | G03* 60 | X1034623Y803358I0J-14372D01* 61 | G01* 62 | X1290528Y813564D02* 63 | G03* 64 | X1286362Y817730I-4166J0D01* 65 | G01* 66 | X1047891Y699502D02* 67 | X1276749Y699502D01* 68 | X1034623Y712769D02* 69 | X1034623Y796470D01* 70 | X1290528Y718006D02* 71 | Y767631D01* 72 | X1084591Y815466D02* 73 | X1107961D01* 74 | X1034623Y796470D02* 75 | Y803358D01* 76 | X1290528Y713281D02* 77 | Y718006D01* 78 | X1110224Y817730D02* 79 | X1286362D01* 80 | X1290528Y767631D02* 81 | Y813564D01* 82 | X1082327Y817730D02* 83 | X1084591Y815466D01* 84 | X1048995Y817730D02* 85 | X1082327D01* 86 | X1107961Y815466D02* 87 | X1110224Y817730D01* 88 | M02* 89 | -------------------------------------------------------------------------------- /docs/sims/freq_gen.m: -------------------------------------------------------------------------------- 1 | clc; 2 | close all; 3 | clear; 4 | 5 | CARIBOULITE_6G_MIN = 1e6; 6 | CARIBOULITE_6G_MAX = 6000e6; 7 | CARIBOULITE_MIN_LO = 85e6; 8 | CARIBOULITE_MAX_LO = 4200e6; 9 | CARIBOULITE_2G4_MIN = 2385e6; 10 | CARIBOULITE_2G4_MAX = 2495e6; 11 | CARIBOULITE_S1G_MIN1 = 377e6; 12 | CARIBOULITE_S1G_MAX1 = 530e6; 13 | CARIBOULITE_S1G_MIN2 = 779e6; 14 | CARIBOULITE_S1G_MAX2 = 1020e6; 15 | 16 | f_vec = 1e6:1e6:6000e6; 17 | ref_vec = f_vec * 0; 18 | mod_vec = f_vec * 0; 19 | lo_vec = f_vec * 0; 20 | rf_vec = f_vec * 0; 21 | 22 | for ii=1:length(f_vec) 23 | if f_vec(ii)>=CARIBOULITE_6G_MIN & f_vec(ii)=CARIBOULITE_2G4_MIN & f_vec(ii)=CARIBOULITE_2G4_MAX & f_vec(ii)<=CARIBOULITE_6G_MAX 33 | ref_vec(ii) = find_ref_freq(f_vec(ii)); 34 | mod_vec(ii) = CARIBOULITE_2G4_MIN; 35 | lo_vec(ii) = f_vec(ii) - mod_vec(ii); 36 | rf_vec(ii) = mod_vec(ii) + lo_vec(ii); 37 | endif 38 | endfor 39 | 40 | figure; 41 | subplot(4,1,1); 42 | plot(f_vec / 1e6, ref_vec / 1e6); xlabel('Frequency [MHz]'); ylabel('Ref Freq [Mhz]'); title('Ref Frequency'); axis tight; 43 | subplot(4,1,2); 44 | plot(f_vec / 1e6, mod_vec / 1e6); xlabel('Frequency [MHz]'); ylabel('Modem Freq [Mhz]'); title('Chosen Modem Frequency [MHz]'); axis tight; 45 | subplot(4,1,3); 46 | plot(f_vec / 1e6, lo_vec / 1e6); xlabel('Frequency [MHz]'); ylabel('LO Freq [Mhz]'); title('LO Frequency [MHz]'); axis tight; 47 | subplot(4,1,4); 48 | plot(f_vec / 1e6, rf_vec / 1e6); xlabel('Frequency [MHz]'); ylabel('RF Freq [Mhz]'); title('RF Frequency [MHz]'); axis tight; -------------------------------------------------------------------------------- /software/libcariboulite/src/io_utils/io_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __IO_UTILS_H__ 2 | #define __IO_UTILS_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "rpi/rpi.h" 13 | //#include "pigpio/pigpio.h" 14 | 15 | typedef enum 16 | { 17 | io_utils_pull_off = 0, 18 | io_utils_pull_down = 1, 19 | io_utils_pull_up = 2, 20 | } io_utils_pull_en; 21 | 22 | typedef enum 23 | { 24 | io_utils_dir_input = 0, 25 | io_utils_dir_output = 1, 26 | } io_utils_dir_en; 27 | 28 | typedef enum 29 | { 30 | io_utils_alt_gpio_in = 0, 31 | io_utils_alt_gpio_out = 1, 32 | io_utils_alt_0 = 4, 33 | io_utils_alt_1 = 5, 34 | io_utils_alt_2 = 6, 35 | io_utils_alt_3 = 7, 36 | io_utils_alt_4 = 3, 37 | io_utils_alt_5 = 2, 38 | } io_utils_alt_en; 39 | 40 | int io_utils_setup(void); 41 | void io_utils_cleanup(void); 42 | void io_utils_set_pullupdn(int gpio, io_utils_pull_en pud); 43 | void io_utils_setup_gpio(int gpio, io_utils_dir_en direction, io_utils_pull_en pud); 44 | int io_utils_get_gpio_mode(int gpio, int print); 45 | void io_utils_set_gpio_mode(int gpio, io_utils_alt_en mode); 46 | void io_utils_write_gpio(int gpio, int value); 47 | void io_utils_write_gpio_with_wait(int gpio, int value, int nopcnt); 48 | int io_utils_wait_gpio_state(int gpio, int state, int cnt); 49 | int io_utils_read_gpio(int gpio); 50 | char* io_utils_get_alt_from_mode(io_utils_alt_en mode); 51 | 52 | // for compliance 53 | typedef void (*gpioAlertFuncEx_t) (int gpio, int level, uint32_t tick, void *userdata); 54 | int io_utils_setup_interrupt( int gpio, 55 | gpioAlertFuncEx_t cb, 56 | void* context); 57 | 58 | void io_utils_usleep(int usec); 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | 64 | #endif // __IO_UTILS_H__ -------------------------------------------------------------------------------- /software/libcariboulite/src/production_utils/python/lcd_task.py: -------------------------------------------------------------------------------- 1 | from lcd2usb import LCD 2 | import zmq 3 | 4 | 5 | def main(): 6 | button_polarity = 0 7 | 8 | # invoke LCD instance 9 | lcd = LCD() 10 | 11 | major, minor = lcd.version 12 | # print('Firmware version %d.%d' % (major, minor)) 13 | if minor == 9: 14 | button_polarity = 1 15 | 16 | lcd.set_contrast(190) 17 | lcd.set_brightness(255) 18 | 19 | # create communication pipe 20 | context = zmq.Context() 21 | socket = context.socket(zmq.REP) 22 | socket.bind("tcp://*:55550") 23 | 24 | working = True 25 | 26 | while working: 27 | # Wait for next request from client 28 | input = socket.recv().decode("utf-8") 29 | output = "ok" 30 | 31 | s = input.split(",") 32 | 33 | event = int(s[0]) 34 | if event == 0: # clear 35 | lcd.clear() 36 | 37 | elif event == 1: # text output 38 | row = int(s[1]) 39 | col = int(s[2]) 40 | text = s[3] 41 | lcd.goto(col,row) 42 | lcd.write(text) 43 | 44 | elif event == 2: 45 | brightness = int(s[1]) 46 | contrast = int(s[2]) 47 | lcd.set_brightness(brightness) 48 | lcd.set_contrast(contrast) 49 | 50 | elif event == 3: 51 | if button_polarity == 0: 52 | key1, key2 = lcd.keys 53 | else: 54 | key2, key1 = lcd.keys 55 | output = "{}{}".format(int(key1), int(key2)) 56 | 57 | elif event == 9: # quit task 58 | print("EXITING") 59 | working = False 60 | 61 | # send response 62 | socket.send(output.encode('utf-8')) 63 | 64 | if __name__ == '__main__': 65 | main() 66 | -------------------------------------------------------------------------------- /software/gr-caribouLite/python/caribouLite/bindings/caribouLiteSource_python.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | 10 | /***********************************************************************************/ 11 | /* This file is automatically generated using bindtool and can be manually edited */ 12 | /* The following lines can be configured to regenerate this file during cmake */ 13 | /* If manual edits are made, the following tags should be modified accordingly. */ 14 | /* BINDTOOL_GEN_AUTOMATIC(0) */ 15 | /* BINDTOOL_USE_PYGCCXML(0) */ 16 | /* BINDTOOL_HEADER_FILE(caribouLiteSource.h) */ 17 | /* BINDTOOL_HEADER_FILE_HASH(9ce2846f2939a8b8e624a4612154ad52) */ 18 | /***********************************************************************************/ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace py = pybind11; 25 | 26 | #include 27 | // pydoc.h is automatically generated in the build directory 28 | #include 29 | 30 | void bind_caribouLiteSource(py::module& m) 31 | { 32 | 33 | using caribouLiteSource = gr::caribouLite::caribouLiteSource; 34 | 35 | 36 | py::class_>(m, "caribouLiteSource", D(caribouLiteSource)) 38 | 39 | .def(py::init(&caribouLiteSource::make), 40 | D(caribouLiteSource,make) 41 | ) 42 | 43 | 44 | 45 | 46 | ; 47 | 48 | 49 | 50 | 51 | } 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /software/libcariboulite/src/zf_log/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2) 2 | 3 | # zf_log target (required) 4 | set(HEADERS_DIR ${CMAKE_CURRENT_SOURCE_DIR}) 5 | set(HEADERS zf_log.h) 6 | set(SOURCES zf_log.c) 7 | 8 | set(CMAKE_C_STANDARD 99) 9 | set(CMAKE_C_STANDARD_REQUIRED ON) 10 | set(CMAKE_C_EXTENSIONS OFF) 11 | if(MSVC) 12 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /WX") 13 | else() 14 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra") 15 | endif() 16 | 17 | add_library(zf_log ${HEADERS} ${SOURCES}) 18 | target_include_directories(zf_log PUBLIC $) 19 | if(ZF_LOG_LIBRARY_PREFIX) 20 | target_compile_definitions(zf_log PRIVATE "ZF_LOG_LIBRARY_PREFIX=${ZF_LOG_LIBRARY_PREFIX}") 21 | endif() 22 | if(ZF_LOG_USE_ANDROID_LOG) 23 | target_compile_definitions(zf_log PRIVATE "ZF_LOG_USE_ANDROID_LOG") 24 | target_link_libraries(zf_log log) 25 | endif() 26 | if(ZF_LOG_USE_NSLOG) 27 | target_compile_definitions(zf_log PRIVATE "ZF_LOG_USE_NSLOG") 28 | target_link_libraries(zf_log "-framework CoreFoundation") 29 | endif() 30 | if(ZF_LOG_USE_DEBUGSTRING) 31 | target_compile_definitions(zf_log PRIVATE "ZF_LOG_USE_DEBUGSTRING") 32 | endif() 33 | if(ZF_LOG_USE_CONFIG_HEADER OR DEFINED ENV{ZF_LOG_USE_CONFIG_HEADER}) 34 | target_compile_definitions(zf_log PRIVATE "ZF_LOG_USE_CONFIG_HEADER") 35 | endif() 36 | if(ZF_LOG_OPTIMIZE_SIZE) 37 | target_compile_definitions(zf_log PRIVATE "ZF_LOG_OPTIMIZE_SIZE") 38 | endif() 39 | 40 | # install (optional) 41 | if(ZF_LOG_CONFIGURE_INSTALL) 42 | if(NOT DEFINED INSTALL_INCLUDE_DIR) 43 | set(INSTALL_INCLUDE_DIR include) 44 | endif() 45 | if(NOT DEFINED INSTALL_LIB_DIR) 46 | set(INSTALL_LIB_DIR lib) 47 | endif() 48 | install(TARGETS zf_log EXPORT zf_log 49 | INCLUDES DESTINATION ${INSTALL_INCLUDE_DIR} 50 | ARCHIVE DESTINATION ${INSTALL_LIB_DIR}) 51 | install(DIRECTORY ${HEADERS_DIR}/ 52 | DESTINATION ${INSTALL_INCLUDE_DIR} 53 | FILES_MATCHING PATTERN "zf_*.h*") 54 | endif() 55 | -------------------------------------------------------------------------------- /software/gr-caribouLite/grc/caribouLite_caribouLiteSource.block.yml: -------------------------------------------------------------------------------- 1 | id: caribouLite_caribouLiteSource 2 | label: CaribouLite Source 3 | category: '[caribouLite]' 4 | flags: throttle 5 | 6 | templates: 7 | imports: 8 | from gnuradio import caribouLite 9 | make: 10 | caribouLite.caribouLiteSource(${channel}, ${enable_agc}, ${rx_gain}, ${rx_bw}, ${sample_rate}, ${freq}) 11 | 12 | 13 | # Make one 'parameters' list entry for every parameter you want settable from the GUI. 14 | # Keys include: 15 | # * id (makes the value accessible as keyname, e.g. in the make entry) 16 | # * label (label shown in the GUI) 17 | # * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...) 18 | # * default 19 | parameters: 20 | - id: channel 21 | label: S1G(0) or HiF(1) 22 | dtype: int 23 | default: 0 24 | 25 | - id: enable_agc 26 | label: Enable AGC 27 | dtype: bool 28 | default: False 29 | 30 | - id: rx_gain 31 | label: Rx gain [dB] 32 | dtype: float 33 | default: 40.0 34 | 35 | - id: rx_bw 36 | label: Rx bandwidth [Hz] 37 | dtype: float 38 | default: 2500000.0 39 | 40 | - id: sample_rate 41 | label: Sample rate [Hz] 42 | dtype: float 43 | default: 4000000.0 44 | 45 | - id: freq 46 | label: Frequency [Hz] 47 | dtype: float 48 | default: 900000000.0 49 | 50 | 51 | # Make one 'inputs' list entry per input and one 'outputs' list entry per output. 52 | # Keys include: 53 | # * label (an identifier for the GUI) 54 | # * domain (optional - stream or message. Default is stream) 55 | # * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...) 56 | # * vlen (optional - data stream vector length. Default is 1) 57 | # * optional (optional - set to 1 for optional inputs. Default is 0) 58 | inputs: 59 | 60 | 61 | outputs: 62 | - label: samples 63 | domain: stream 64 | dtype: complex 65 | 66 | 67 | # 'file_format' specifies the version of the GRC yml format used in the file 68 | # and should usually not be changed. 69 | file_format: 1 70 | -------------------------------------------------------------------------------- /examples/c/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static cariboulite_lib_version_st version = {0}; 5 | static uint32_t serial_number = 0; 6 | cariboulite_version_en hw_ver; 7 | char hw_name[128]; 8 | char hw_uuid[128]; 9 | 10 | int main () 11 | { 12 | // board detection 13 | bool detected = cariboulite_detect_connected_board(&hw_ver, hw_name, hw_uuid); 14 | if (detected) printf("Detection: %d, HWVer: %d, HWName: %s, UUID: %s\n", detected, hw_ver, hw_name, hw_uuid); 15 | else 16 | { 17 | printf("No board detection, Exiting\n"); 18 | return 0; 19 | } 20 | 21 | // library version 22 | cariboulite_get_lib_version(&version); 23 | printf("Version: %02d.%02d.%02d\n", version.major_version, version.minor_version, version.revision); 24 | 25 | // init 26 | cariboulite_init(false, cariboulite_log_level_none); 27 | 28 | // board serial number 29 | serial_number = cariboulite_get_sn(); 30 | printf("Serial Number: %08X\n", serial_number); 31 | 32 | // channels names and freqs 33 | char ch_name[64]; 34 | int ch_num_ranges; 35 | float low_freq_vec[3]; // the actual size determined by ch_num_ranges but here we just statically allocated 36 | float high_freq_vec[3]; 37 | int channels[2] = {cariboulite_channel_s1g, cariboulite_channel_hif}; 38 | 39 | for (int ch_ind = 0; ch_ind < 2; ch_ind ++) 40 | { 41 | cariboulite_get_channel_name(channels[ch_ind], ch_name, sizeof(ch_name)); 42 | ch_num_ranges = cariboulite_get_num_frequency_ranges(channels[ch_ind]); 43 | printf("Channel: %d, Name: %s, Num. Freq. Ranges: %d\n", channels[ch_ind], ch_name, ch_num_ranges); 44 | cariboulite_get_frequency_limits(channels[ch_ind], low_freq_vec, high_freq_vec, NULL); 45 | for (int i = 0; i < ch_num_ranges; i++) 46 | { 47 | printf(" Range %d: [%.2f, %.2f]\n", i, low_freq_vec[i], high_freq_vec[i]); 48 | } 49 | } 50 | 51 | cariboulite_close(); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /software/libcariboulite/src/zf_log/zf_log_config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _ZF_LOG_CONFIG_H_ 4 | #define _ZF_LOG_CONFIG_H_ 5 | 6 | #if !defined(_WIN32) && !defined(_WIN64) 7 | 8 | #if defined(__linux__) 9 | #if !defined(__ANDROID__) && !defined(_GNU_SOURCE) 10 | #define _GNU_SOURCE 11 | #endif 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "zf_log.h" 19 | 20 | #define ZF_LOG_EXTERN_GLOBAL_OUTPUT 1 21 | 22 | #define DO(expr) while((expr) < 0 && errno == EINTR) 23 | 24 | static struct target 25 | { 26 | const char *ip; /* IPv4 address */ 27 | const int port; /* port number */ 28 | 29 | struct sockaddr_in addr; /* housekeeping */ 30 | int fd; /* ... */ 31 | 32 | } sink = {"239.192.0.1", 42099, {0}, -2}; 33 | 34 | static void socket_output_init() 35 | { 36 | sink.addr.sin_family = AF_INET; 37 | sink.addr.sin_port = htons(sink.port); 38 | 39 | if (sink.ip && inet_pton(AF_INET, sink.ip, &sink.addr.sin_addr) == 1) 40 | if ((sink.fd = socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, 0)) != -1) 41 | { 42 | int optval = 0x200000; 43 | setsockopt(sink.fd, SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)); 44 | } 45 | 46 | if (sink.fd < 0) zf_log_set_output_v(ZF_LOG_OUT_STDERR); /* install fallback */ 47 | } 48 | 49 | static void socket_output_callback(const zf_log_message *msg, void *arg) 50 | { 51 | static pthread_once_t socket_is_initialized = PTHREAD_ONCE_INIT; 52 | pthread_once(&socket_is_initialized, socket_output_init); 53 | 54 | if (sink.fd < 0) zf_log_out_stderr_callback(msg, arg); /* trigger fallback */ 55 | else 56 | DO(sendto(sink.fd, msg->buf, (msg->p - msg->buf), 0, (struct sockaddr *)&sink.addr, sizeof(sink.addr))); 57 | } 58 | 59 | ZF_LOG_DEFINE_GLOBAL_OUTPUT = {ZF_LOG_PUT_STD, 0, socket_output_callback}; 60 | 61 | #endif /* !defined(_WIN32) && !defined(_WIN64) */ 62 | #endif /* _ZF_LOG_CONFIG_H_ */ 63 | -------------------------------------------------------------------------------- /software/gr-caribouLite/.cmake-format.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Marcus Müller 2 | # SPDX-License-Identifier: LGPL-3.0-or-later 3 | class _clang_format_options: 4 | def __init__(self, clangfile=None): 5 | if not clangfile: 6 | clangfile = ".clang-format" 7 | self.lines = [] 8 | with open(clangfile, encoding="utf-8") as opened: 9 | for line in opened: 10 | if line.strip().startswith("#"): 11 | continue 12 | self.lines.append(line.rstrip().split(":")) 13 | 14 | def __getitem__(self, string): 15 | path = string.split(".") 16 | value = None 17 | for crumble in path: 18 | for line in self.lines: 19 | if line[0].strip() == crumble: 20 | if len(line) > 1: 21 | value = line[1].strip().rstrip() 22 | break 23 | return value 24 | 25 | 26 | _clang_format = _clang_format_options() 27 | 28 | with section("parse"): 29 | additional_commands = { 30 | 'gr_python_install': { 31 | 'flags': [], 32 | 'kwargs': { 33 | "PROGRAMS": "*", 34 | "FILES": "*", 35 | "DESTINATION": "*" 36 | } 37 | }, 38 | } 39 | 40 | with section("markup"): 41 | first_comment_is_literal = True 42 | enable_markup = False 43 | 44 | with section("format"): 45 | disable = False 46 | line_width = int(_clang_format["ColumnLimit"]) 47 | tab_size = int(_clang_format["IndentWidth"]) 48 | min_prefix_chars = tab_size 49 | max_prefix_chars = 3 * tab_size 50 | use_tabchars = _clang_format["UseTab"] in ("ForIndentation", 51 | "ForContinuationAndIndentation", 52 | "Always") 53 | separate_ctrl_name_with_space = False 54 | separate_fn_name_with_space = False 55 | dangle_parens = False 56 | command_case = 'canonical' 57 | keyword_case = 'upper' 58 | 59 | with section("lint"): 60 | max_arguments = 6 61 | max_localvars = 20 62 | max_statements = 75 63 | -------------------------------------------------------------------------------- /software/gr-caribouLite/python/caribouLite/bindings/bind_oot_file.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | import argparse 3 | from gnuradio.bindtool import BindingGenerator 4 | import sys 5 | import tempfile 6 | 7 | parser = argparse.ArgumentParser(description='Bind a GR Out of Tree Block') 8 | parser.add_argument('--module', type=str, 9 | help='Name of gr module containing file to bind (e.g. fft digital analog)') 10 | 11 | parser.add_argument('--output_dir', default=tempfile.gettempdir(), 12 | help='Output directory of generated bindings') 13 | parser.add_argument('--prefix', help='Prefix of Installed GNU Radio') 14 | 15 | parser.add_argument( 16 | '--filename', help="File to be parsed") 17 | 18 | parser.add_argument( 19 | '--defines', help='Set additional defines for precompiler', default=(), nargs='*') 20 | parser.add_argument( 21 | '--include', help='Additional Include Dirs, separated', default=(), nargs='*') 22 | 23 | parser.add_argument( 24 | '--status', help='Location of output file for general status (used during cmake)', default=None 25 | ) 26 | parser.add_argument( 27 | '--flag_automatic', default='0' 28 | ) 29 | parser.add_argument( 30 | '--flag_pygccxml', default='0' 31 | ) 32 | 33 | args = parser.parse_args() 34 | 35 | prefix = args.prefix 36 | output_dir = args.output_dir 37 | defines = tuple(','.join(args.defines).split(',')) 38 | includes = ','.join(args.include) 39 | name = args.module 40 | 41 | namespace = ['gr', name] 42 | prefix_include_root = name 43 | 44 | 45 | with warnings.catch_warnings(): 46 | warnings.filterwarnings("ignore", category=DeprecationWarning) 47 | 48 | bg = BindingGenerator(prefix, namespace, 49 | prefix_include_root, output_dir, define_symbols=defines, addl_includes=includes, 50 | catch_exceptions=False, write_json_output=False, status_output=args.status, 51 | flag_automatic=True if args.flag_automatic.lower() in [ 52 | '1', 'true'] else False, 53 | flag_pygccxml=True if args.flag_pygccxml.lower() in ['1', 'true'] else False) 54 | bg.gen_file_binding(args.filename) 55 | -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 5 | # This file is a part of gr-caribouLite 6 | # 7 | # SPDX-License-Identifier: GPL-3.0-or-later 8 | # 9 | # 10 | """ 11 | Python interface to contents of doxygen xml documentation. 12 | 13 | Example use: 14 | See the contents of the example folder for the C++ and 15 | doxygen-generated xml used in this example. 16 | 17 | >>> # Parse the doxygen docs. 18 | >>> import os 19 | >>> this_dir = os.path.dirname(globals()['__file__']) 20 | >>> xml_path = this_dir + "/example/xml/" 21 | >>> di = DoxyIndex(xml_path) 22 | 23 | Get a list of all top-level objects. 24 | 25 | >>> print([mem.name() for mem in di.members()]) 26 | [u'Aadvark', u'aadvarky_enough', u'main'] 27 | 28 | Get all functions. 29 | 30 | >>> print([mem.name() for mem in di.in_category(DoxyFunction)]) 31 | [u'aadvarky_enough', u'main'] 32 | 33 | Check if an object is present. 34 | 35 | >>> di.has_member(u'Aadvark') 36 | True 37 | >>> di.has_member(u'Fish') 38 | False 39 | 40 | Get an item by name and check its properties. 41 | 42 | >>> aad = di.get_member(u'Aadvark') 43 | >>> print(aad.brief_description) 44 | Models the mammal Aadvark. 45 | >>> print(aad.detailed_description) 46 | Sadly the model is incomplete and cannot capture all aspects of an aadvark yet. 47 | 48 | This line is uninformative and is only to test line breaks in the comments. 49 | >>> [mem.name() for mem in aad.members()] 50 | [u'aadvarkness', u'print', u'Aadvark', u'get_aadvarkness'] 51 | >>> aad.get_member(u'print').brief_description 52 | u'Outputs the vital aadvark statistics.' 53 | 54 | """ 55 | 56 | from .doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther 57 | 58 | 59 | def _test(): 60 | import os 61 | this_dir = os.path.dirname(globals()['__file__']) 62 | xml_path = this_dir + "/example/xml/" 63 | di = DoxyIndex(xml_path) 64 | # Get the Aadvark class 65 | aad = di.get_member('Aadvark') 66 | aad.brief_description 67 | import doctest 68 | return doctest.testmod() 69 | 70 | 71 | if __name__ == "__main__": 72 | _test() 73 | -------------------------------------------------------------------------------- /software/gr-caribouLite/docs/doxygen/doxyxml/generated/index.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Generated Mon Feb 9 19:08:05 2009 by generateDS.py. 5 | """ 6 | 7 | from xml.dom import minidom 8 | 9 | import os 10 | import sys 11 | from . import compound 12 | 13 | from . import indexsuper as supermod 14 | 15 | 16 | class DoxygenTypeSub(supermod.DoxygenType): 17 | def __init__(self, version=None, compound=None): 18 | supermod.DoxygenType.__init__(self, version, compound) 19 | 20 | def find_compounds_and_members(self, details): 21 | """ 22 | Returns a list of all compounds and their members which match details 23 | """ 24 | 25 | results = [] 26 | for compound in self.compound: 27 | members = compound.find_members(details) 28 | if members: 29 | results.append([compound, members]) 30 | else: 31 | if details.match(compound): 32 | results.append([compound, []]) 33 | 34 | return results 35 | 36 | 37 | supermod.DoxygenType.subclass = DoxygenTypeSub 38 | # end class DoxygenTypeSub 39 | 40 | 41 | class CompoundTypeSub(supermod.CompoundType): 42 | def __init__(self, kind=None, refid=None, name='', member=None): 43 | supermod.CompoundType.__init__(self, kind, refid, name, member) 44 | 45 | def find_members(self, details): 46 | """ 47 | Returns a list of all members which match details 48 | """ 49 | 50 | results = [] 51 | 52 | for member in self.member: 53 | if details.match(member): 54 | results.append(member) 55 | 56 | return results 57 | 58 | 59 | supermod.CompoundType.subclass = CompoundTypeSub 60 | # end class CompoundTypeSub 61 | 62 | 63 | class MemberTypeSub(supermod.MemberType): 64 | 65 | def __init__(self, kind=None, refid=None, name=''): 66 | supermod.MemberType.__init__(self, kind, refid, name) 67 | 68 | 69 | supermod.MemberType.subclass = MemberTypeSub 70 | # end class MemberTypeSub 71 | 72 | 73 | def parse(inFilename): 74 | 75 | doc = minidom.parse(inFilename) 76 | rootNode = doc.documentElement 77 | rootObj = supermod.DoxygenType.factory() 78 | rootObj.build(rootNode) 79 | 80 | return rootObj 81 | -------------------------------------------------------------------------------- /software/libcariboulite/src/io_utils/io_utils_spi.h: -------------------------------------------------------------------------------- 1 | #ifndef __IO_UTILS_SPI_H__ 2 | #define __IO_UTILS_SPI_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "io_utils.h" 13 | #include "spidev/spi.h" 14 | 15 | 16 | #define IO_UTILS_MAX_CHIPS 10 17 | 18 | typedef enum 19 | { 20 | io_utils_spi_chip_type_fpga_comm = 0, 21 | io_utils_spi_chip_type_rffc = 1, 22 | io_utils_spi_chip_type_modem = 2, 23 | io_utils_spi_chip_ice40_prog = 3, 24 | io_utils_spi_chip_type_modem_bitbang = 4, 25 | } io_utils_spi_chip_type_en; 26 | 27 | typedef enum 28 | { 29 | io_utils_spi_read_write = 0, 30 | io_utils_spi_read = 1, 31 | io_utils_spi_write = 2, 32 | } io_utils_spi_dir_en; 33 | 34 | typedef struct 35 | { 36 | int spi_dev_id; // either spidev0 or spidev1 37 | int spi_dev_channel; // the channel number (2 cs for spidev0, 3 cs of spidev1) 38 | spi_t spidev; 39 | } io_utils_hard_spi_st; 40 | 41 | typedef struct 42 | { 43 | int cs_pin; 44 | int clock; 45 | int mode; 46 | int miso_mosi_swap; 47 | io_utils_hard_spi_st hard_dev; 48 | 49 | int initialized; 50 | io_utils_spi_chip_type_en chip_type; 51 | int is_hard_spi; 52 | } io_utils_spi_chip_st; 53 | 54 | typedef struct 55 | { 56 | // pins 57 | int miso; 58 | int mosi; 59 | int sck; 60 | 61 | io_utils_spi_chip_st chips[IO_UTILS_MAX_CHIPS]; 62 | int num_of_chips; 63 | io_utils_spi_chip_st *current_chip; 64 | pthread_mutex_t mtx; 65 | int initialized; 66 | } io_utils_spi_st; 67 | 68 | int io_utils_spi_init(io_utils_spi_st* dev); 69 | int io_utils_spi_close(io_utils_spi_st* dev); 70 | int io_utils_spi_add_chip(io_utils_spi_st* dev, int cs_pin, int speed, int swap_mi_mo, int mode, 71 | io_utils_spi_chip_type_en chip_type, io_utils_hard_spi_st *hard_dev); 72 | int io_utils_spi_remove_chip(io_utils_spi_st* dev, int chip_handle); 73 | int io_utils_spi_suspend(io_utils_spi_st* dev, bool suspend); 74 | int io_utils_spi_transmit(io_utils_spi_st* dev, int chip_handle, 75 | const unsigned char* tx_buf, 76 | unsigned char* rx_buf, 77 | size_t length, 78 | io_utils_spi_dir_en dir); 79 | void io_utils_spi_print_setup(io_utils_spi_st* dev); 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | 85 | #endif // __IO_UTILS_SPI_H__ -------------------------------------------------------------------------------- /driver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(smi_modules VERSION 0.1.0 LANGUAGES C) 3 | set(CMAKE_C_STANDARD 11) 4 | set(CMAKE_C_STANDARD_REQUIRED ON) 5 | 6 | # Module info 7 | add_definitions(-D__KERNEL__ -DMODULE) 8 | 9 | # Find the kernel release 10 | execute_process( 11 | COMMAND uname -r 12 | OUTPUT_VARIABLE KERNEL_RELEASE 13 | OUTPUT_STRIP_TRAILING_WHITESPACE 14 | ) 15 | 16 | # Find the headers 17 | find_path( 18 | KERNELHEADERS_DIR 19 | NAMES 20 | include/linux/user.h 21 | include/generated/autoconf.h 22 | PATHS /usr/src/linux-headers-${KERNEL_RELEASE} 23 | ) 24 | 25 | message(STATUS "Kernel release: ${KERNEL_RELEASE}") 26 | message(STATUS "Kernel headers: ${KERNELHEADERS_DIR}") 27 | 28 | function(compile_module obj) 29 | set(TARGET_NAME ${obj}) 30 | add_custom_target(${TARGET_NAME} ALL cp -f ${CMAKE_CURRENT_SOURCE_DIR}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_BINARY_DIR}/ 31 | COMMAND echo "compiling module ${obj}.ko...") 32 | list(LENGTH ARGN argn_len) 33 | set(i 0) 34 | set(depend_objlist "") 35 | while(i LESS ${argn_len}) 36 | list(GET ARGN ${i} argn_value) 37 | set(depend_objlist "${depend_objlist} ${argn_value}.o") 38 | math(EXPR i "${i} + 1") 39 | endwhile() 40 | 41 | add_custom_command(TARGET ${TARGET_NAME} 42 | POST_BUILD 43 | COMMAND cp Makefile Makefile.bak 44 | COMMAND echo "obj-m += ${obj}.o" > ${CMAKE_CURRENT_BINARY_DIR}/Makefile 45 | #COMMAND echo "MY_CFLAGS += -g -DDEBUG" >> ${CMAKE_CURRENT_BINARY_DIR}/Makefile 46 | #COMMAND echo "ccflags-y += -g -DDEBUG" >> ${CMAKE_CURRENT_BINARY_DIR}/Makefile 47 | #COMMAND echo "CC += -g -DDEBUG" >> ${CMAKE_CURRENT_BINARY_DIR}/Makefile 48 | COMMAND echo "ccflags-y += -O2 -DMODULE -D__KERNEL__" >> ${CMAKE_CURRENT_BINARY_DIR}/Makefile 49 | COMMAND echo "${obj}-objs:=${depend_objlist}" >> ${CMAKE_CURRENT_BINARY_DIR}/Makefile 50 | #COMMAND make -C ${KERNELHEADERS_DIR} M=${CMAKE_CURRENT_BINARY_DIR} modules EXTRA_CFLAGS="-g" 51 | COMMAND make -C ${KERNELHEADERS_DIR} M=${CMAKE_CURRENT_BINARY_DIR} modules 52 | COMMAND cp Makefile Makefile.op 53 | COMMAND cp Makefile.bak Makefile 54 | ) 55 | endfunction() 56 | 57 | #compile_module(bcm2835_smi) 58 | compile_module(smi_stream_dev) 59 | #compile_module(bcm2835_smi_dev) 60 | -------------------------------------------------------------------------------- /examples/python/read_test.py: -------------------------------------------------------------------------------- 1 | from PySimpleGUI.PySimpleGUI import Canvas, Column 2 | from PySimpleGUI import Window, WIN_CLOSED, Slider, Button, theme, Text, Radio, Image, InputText, Canvas 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | import time 6 | import SoapySDR 7 | from SoapySDR import SOAPY_SDR_RX, SOAPY_SDR_TX, SOAPY_SDR_CS16 8 | 9 | """ 10 | Build a dictionaly of parameters 11 | """ 12 | def MakeParameters(): 13 | params = { 14 | "DriverName": "Cariboulite", 15 | "ChannelName": "S1G", 16 | "RxChannel": 0, 17 | "NumOfComplexSample": 4*16384, 18 | "RxFrequencyHz": 915e6, 19 | "UseAGC": True, 20 | "Gain": 50.0, 21 | "RXBandwidth": 0.02e6} 22 | return params 23 | 24 | 25 | """ 26 | Setup the RX channel 27 | """ 28 | def SetupReceiver(sdr, params): 29 | # Gain mode 30 | sdr.setGainMode(SOAPY_SDR_RX, params["RxChannel"], params["UseAGC"]) 31 | 32 | # Set RX gain (if not using AGC) 33 | sdr.setGain(SOAPY_SDR_RX, params["RxChannel"], params["Gain"]) 34 | 35 | # Rx Frequency 36 | sdr.setFrequency(SOAPY_SDR_RX, params["RxChannel"], params["RxFrequencyHz"]) 37 | 38 | # Rx BW 39 | sdr.setBandwidth(SOAPY_SDR_RX, params["RxChannel"], params["RXBandwidth"]) 40 | 41 | # Make the stream 42 | return sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [params["RxChannel"]]) # Setup data stream 43 | 44 | 45 | """ 46 | Main 47 | """ 48 | if __name__ == "__main__": 49 | params = MakeParameters() 50 | 51 | # Memory buffers 52 | samples = np.empty(2 * params["NumOfComplexSample"], np.int16) 53 | 54 | # Initialize Soapy 55 | sdr = SoapySDR.Device(dict(driver=params["DriverName"], channel=params["ChannelName"])) 56 | rxStream = SetupReceiver(sdr, params=params) 57 | sdr.activateStream(rxStream) 58 | 59 | # Read samples into buffer 60 | for ii in range(1,10): 61 | sr = sdr.readStream(rxStream, [samples], params["NumOfComplexSample"], timeoutUs=int(5e6)) 62 | rc = sr.ret 63 | if (rc != params["NumOfComplexSample"]): 64 | print("Error Reading Samples from Device (error code = %d)!" % rc) 65 | exit 66 | 67 | # convert to float complex 68 | I = samples[::2].astype(np.float32) 69 | Q = samples[1::2].astype(np.float32) 70 | complexFloatSamples = I + 1j*Q 71 | 72 | # plot samples 73 | fig = plt.figure() 74 | plt.plot(I) 75 | plt.plot(Q) 76 | plt.show() 77 | 78 | print("Goodbye") 79 | -------------------------------------------------------------------------------- /hardware/rev2/pcb/ncdrill/cariboulite_r2.8.DRR: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------- 2 | NCDrill File Report For: cariboulite_r2.CSPcbDoc 26/05/2022 15:06:32 3 | --------------------------------------------------------------------------- 4 | 5 | Layer Pair : Component Side to Solder Side 6 | ASCII RoundHoles File : cariboulite_r2.TXT 7 | 8 | Tool Hole Size Hole Type Hole Count Plated Tool Travel 9 | --------------------------------------------------------------------------- 10 | T2 8mil (0.2032mm) Round 805 48.18 Inch (1223.77 mm) 11 | T3 18.11mil (0.45999mm) Round 4 0.80 Inch (20.24 mm) 12 | T4 23.62mil (0.59995mm) Round 2 0.16 Inch (4.05 mm) 13 | T5 31.5mil (0.8001mm) Round 2 1.37 Inch (34.72 mm) 14 | T6 35.43mil (0.89992mm) Round 40 4.10 Inch (104.14 mm) 15 | T7 108.27mil (2.75006mm) Round 3 NPTH 4.74 Inch (120.39 mm) 16 | --------------------------------------------------------------------------- 17 | Totals 856 59.34 Inch (1507.31 mm) 18 | Layer Pair : Component Side to Layer 1 19 | ASCII RoundHoles File : cariboulite_r2.TX1 20 | 21 | Tool Hole Size Hole Type Hole Count Plated Tool Travel 22 | --------------------------------------------------------------------------- 23 | T1 4mil (0.1016mm) Round 661 25.72 Inch (653.39 mm) 24 | --------------------------------------------------------------------------- 25 | Totals 661 25.72 Inch (653.39 mm) 26 | Layer Pair : Layer 2 to Solder Side 27 | ASCII RoundHoles File : cariboulite_r2.TX2 28 | 29 | Tool Hole Size Hole Type Hole Count Plated Tool Travel 30 | --------------------------------------------------------------------------- 31 | T1 4mil (0.1016mm) Round 736 31.61 Inch (802.91 mm) 32 | --------------------------------------------------------------------------- 33 | Totals 736 31.61 Inch (802.91 mm) 34 | --------------------------------------------------------------------------- 35 | Totals 2253 116.68 Inch (2963.62 mm) 36 | 37 | Total Processing Time (hh:mm:ss) : 00:00:00 38 | -------------------------------------------------------------------------------- /software/libcariboulite/src/cariboulite_test_app.c: -------------------------------------------------------------------------------- 1 | #ifndef ZF_LOG_LEVEL 2 | #define ZF_LOG_LEVEL ZF_LOG_VERBOSE 3 | #endif 4 | 5 | #define ZF_LOG_DEF_SRCLOC ZF_LOG_SRCLOC_LONG 6 | #define ZF_LOG_TAG "CARIBOULITE Test" 7 | #include "zf_log/zf_log.h" 8 | 9 | #include 10 | #include 11 | 12 | #include "cariboulite_setup.h" 13 | #include "cariboulite_events.h" 14 | #include "cariboulite.h" 15 | #include "hat/hat.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | struct sigaction act; 23 | int program_running = 1; 24 | int signal_shown = 0; 25 | CARIBOULITE_CONFIG_DEFAULT(cariboulite_sys); 26 | 27 | int app_menu(sys_st* sys); 28 | 29 | //================================================= 30 | int stop_program () 31 | { 32 | if (program_running) ZF_LOGD("program termination requested"); 33 | program_running = 0; 34 | return 0; 35 | } 36 | 37 | //================================================= 38 | void sighandler( struct sys_st_t *sys, 39 | void* context, 40 | int signal_number, 41 | siginfo_t *si) 42 | { 43 | if (signal_shown != signal_number) 44 | { 45 | ZF_LOGI("Received signal %d", signal_number); 46 | signal_shown = signal_number; 47 | } 48 | 49 | switch (signal_number) 50 | { 51 | case SIGINT: 52 | case SIGTERM: 53 | case SIGABRT: 54 | case SIGILL: 55 | case SIGSEGV: 56 | case SIGFPE: stop_program(); break; 57 | default: return; break; 58 | } 59 | } 60 | 61 | //================================================= 62 | int main(int argc, char *argv[]) 63 | { 64 | // init the program 65 | cariboulite_sys.force_fpga_reprogramming = 0; 66 | if (cariboulite_init_driver(&cariboulite_sys, NULL)!=0) 67 | { 68 | ZF_LOGE("driver init failed, terminating..."); 69 | return -1; 70 | } 71 | 72 | // setup the signal handler 73 | cariboulite_setup_signal_handler (&cariboulite_sys, sighandler, signal_handler_op_last, &cariboulite_sys); 74 | 75 | sleep(1); 76 | while (program_running) 77 | { 78 | int ret = app_menu(&cariboulite_sys); 79 | 80 | if (ret < 0) 81 | { 82 | ZF_LOGE("Error occurred, terminating..."); 83 | break; 84 | } 85 | else if (ret == 0) 86 | { 87 | ZF_LOGI("Quit command => terminating..."); 88 | break; 89 | } 90 | } 91 | 92 | // close the driver and release resources 93 | cariboulite_release_driver(&cariboulite_sys); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_smi/smi_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H__ 2 | #define __UTILS_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | 11 | #define TIMING_PERF_SYNC (0) 12 | 13 | #if (TIMING_PERF_SYNC) 14 | #define TIMING_PERF_SYNC_VARS \ 15 | struct timeval tv_pre = {0}; \ 16 | struct timeval tv_post = {0}; \ 17 | long long total_samples = 0,last_total_samples = 0; \ 18 | double time_pre = 0, batch_time = 0, sample_rate = 0; \ 19 | double time_post = 0, process_time = 0; \ 20 | double temp_pre; \ 21 | double num_samples = 0, num_samples_avg = 0; 22 | 23 | #define TIMING_PERF_SYNC_TICK \ 24 | gettimeofday(&tv_pre, NULL); 25 | 26 | #define TIMING_PERF_SYNC_TOCK \ 27 | gettimeofday(&tv_post, NULL); \ 28 | num_samples = (double)(st->read_ret_value) / 4.0; \ 29 | num_samples_avg = num_samples_avg*0.1 + num_samples*0.9; \ 30 | temp_pre = tv_pre.tv_sec + ((double)(tv_pre.tv_usec)) / 1e6; \ 31 | time_post = tv_post.tv_sec + ((double)(tv_post.tv_usec)) / 1e6; \ 32 | batch_time = temp_pre - time_pre; \ 33 | sample_rate = sample_rate*0.1 + (num_samples / batch_time) * 0.9; \ 34 | process_time = process_time*0.1 + (time_post - temp_pre)*0.9; \ 35 | time_pre = temp_pre; \ 36 | total_samples += st->read_ret_value; \ 37 | if ((total_samples - last_total_samples) > 4000000*4) \ 38 | { \ 39 | last_total_samples = total_samples; \ 40 | ZF_LOGD("sample_rate = %.2f SPS, process_time = %.2f usec" \ 41 | ", num_samples_avg = %.1f", \ 42 | sample_rate, process_time * 1e6, num_samples_avg); \ 43 | } 44 | #else 45 | #define TIMING_PERF_SYNC_VARS 46 | #define TIMING_PERF_SYNC_TICK 47 | #define TIMING_PERF_SYNC_TOCK 48 | #endif 49 | 50 | 51 | void smi_utils_set_realtime_priority(int priority_deter); 52 | void smi_utils_dump_hex(const void* data, size_t size); 53 | void smi_utils_dump_hex_simple(const void* data, size_t size, size_t delim); 54 | void smi_utils_dump_bin(const uint8_t* data, size_t size); 55 | void smi_utils_print_bin(const uint32_t v); 56 | int smi_utils_allocate_buffer_vec(uint8_t*** mat, int num_buffers, int buffer_size); 57 | void smi_utils_release_buffer_vec(uint8_t** mat, int num_buffers, int buffer_size); 58 | int smi_utils_search_offset_in_buffer(uint8_t *buff, int len); 59 | uint8_t smi_utils_lfsr(uint8_t n); 60 | double smi_calculate_performance(size_t bytes, struct timeval *old_time, double old_mbps); 61 | unsigned int smi_utils_count_bit(unsigned int x); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif // __UTILS_H__ -------------------------------------------------------------------------------- /software/libcariboulite/src/at86rf215/at86rf215.h: -------------------------------------------------------------------------------- 1 | #ifndef __AT86RF215_H__ 2 | #define __AT86RF215_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "at86rf215_common.h" 9 | #include "at86rf215_radio.h" 10 | 11 | 12 | int at86rf215_init(at86rf215_st* dev, 13 | io_utils_spi_st* io_spi); 14 | int at86rf215_close(at86rf215_st* dev); 15 | void at86rf215_reset(at86rf215_st* dev); 16 | 17 | void at86rf215_get_versions(at86rf215_st* dev, uint8_t *pn, uint8_t *vn); 18 | int at86rf215_print_version(at86rf215_st* dev); 19 | void at86rf215_set_clock_output(at86rf215_st* dev, 20 | at86rf215_drive_current_en drv_level, 21 | at86rf215_clock_out_freq_en clock_val); 22 | void at86rf215_setup_rf_irq(at86rf215_st* dev, uint8_t active_low, 23 | uint8_t show_masked_irq, 24 | at86rf215_drive_current_en drive); 25 | void at86rf215_set_xo_trim(at86rf215_st* dev, uint8_t fast_start, float cap_trim); 26 | void at86rf215_get_iq_if_cfg(at86rf215_st* dev, at86rf215_iq_interface_config_st* cfg, int verbose); 27 | void at86rf215_setup_iq_if(at86rf215_st* dev, at86rf215_iq_interface_config_st* cfg); 28 | void at86rf215_setup_iq_radio_transmit (at86rf215_st* dev, at86rf215_rf_channel_en radio); 29 | void at86rf215_setup_iq_radio_receive(at86rf215_st *dev, at86rf215_rf_channel_en radio, uint64_t freq_hz, 30 | int iqloopback, at86rf215_iq_clock_data_skew_en skew); 31 | void at86rf215_stop_iq_radio_receive (at86rf215_st* dev, at86rf215_rf_channel_en radio); 32 | void at86rf215_setup_iq_radio_continues_tx (at86rf215_st* dev, at86rf215_rf_channel_en radio); 33 | void at86rf215_setup_iq_radio_dac_value_override (at86rf215_st* dev, at86rf215_rf_channel_en ch, 34 | uint32_t freq_hz, 35 | uint8_t tx_power ); 36 | void at86rf215_setup_iq_radio_dac_value_override_no_freq (at86rf215_st* dev, 37 | at86rf215_rf_channel_en ch, 38 | uint8_t tx_power); 39 | int64_t at86rf215_setup_channel ( at86rf215_st* dev, at86rf215_rf_channel_en ch, uint64_t freq_hz ); 40 | double at86rf215_check_freq (at86rf215_st* dev, at86rf215_rf_channel_en ch, uint64_t freq_hz ); 41 | 42 | // EVENTS 43 | 44 | void event_node_init(event_st* ev); 45 | void event_node_close(event_st* ev); 46 | void event_node_wait_ready(event_st* ev); 47 | void event_node_signal_ready(event_st* ev, int ready); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif // __AT86RF215_H__ -------------------------------------------------------------------------------- /examples/python/soapy_psd.py: -------------------------------------------------------------------------------- 1 | # PySimpleGUI 2 | from PySimpleGUI.PySimpleGUI import Canvas, Column 3 | from PySimpleGUI import Window, WIN_CLOSED, Slider, Button, theme, Text, Radio, Image, InputText, Canvas 4 | 5 | # Numpy 6 | import matplotlib.pyplot as plt 7 | from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk 8 | import numpy as np 9 | from numpy.lib.arraypad import pad 10 | 11 | # System 12 | import time 13 | 14 | # Soapy 15 | import SoapySDR 16 | from SoapySDR import SOAPY_SDR_RX, SOAPY_SDR_TX, SOAPY_SDR_CS16 17 | 18 | 19 | def setup_receiver(sdr, channel, freq_hz): 20 | use_agc = False # Use or don't use the AGC 21 | # The wide channel parameters 22 | sdr.setGainMode(SOAPY_SDR_RX, channel, use_agc) # Set the gain mode 23 | sdr.setGain(SOAPY_SDR_RX, channel, 0) # Set the gain 24 | sdr.setFrequency(SOAPY_SDR_RX, channel, freq_hz) # Tune the LO 25 | sdr.setBandwidth(SOAPY_SDR_RX, channel, 2500e5) 26 | rx_stream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [channel]) # Setup data stream 27 | return rx_stream 28 | 29 | def update_receiver_freq(sdr, stream, channel, freq_hz): 30 | sdr.setFrequency(SOAPY_SDR_RX, channel, freq_hz) 31 | 32 | 33 | ## 34 | ## GLOBAL AREA 35 | ## 36 | 37 | # Data and Source Configuration 38 | rx_chan = 0 39 | N = 16384 # Number of complex samples per transfer 40 | rx_buff = np.empty(2 * N, np.int16) # Create memory buffer for data stream 41 | freq = 915e6 42 | 43 | # Initialize Soapy 44 | sdr = SoapySDR.Device(dict(driver="CaribouLite")) 45 | rx_stream = setup_receiver(sdr, rx_chan, freq) 46 | sdr.activateStream(rx_stream) 47 | 48 | sr = sdr.readStream(rx_stream, [rx_buff], N, timeoutUs=int(5e6)) 49 | # Make sure that the proper number of samples was read 50 | rc = sr.ret 51 | if (rc != N): 52 | print("Error Reading Samples from Device (error code = %d)!" % rc) 53 | exit 54 | 55 | s_real = rx_buff[::2].astype(np.float32) 56 | s_imag = -rx_buff[1::2].astype(np.float32) 57 | x = s_real + 1j*s_imag 58 | 59 | ## PSD 60 | Fs = 4e6 61 | #N = 2048 62 | #x = x[0:N] # we will only take the FFT of the first 1024 samples, see text below 63 | x = x * np.hamming(len(x)) # apply a Hamming window 64 | 65 | PSD = (np.abs(np.fft.fft(x))/N)**2 66 | PSD_log = 10.0*np.log10(PSD) 67 | PSD_shifted = np.fft.fftshift(PSD_log) 68 | 69 | center_freq = freq 70 | f = np.arange(Fs/-2.0, Fs/2.0, Fs/N) # start, stop, step. centered around 0 Hz 71 | #f += center_freq # now add center frequency 72 | 73 | fig = plt.figure() 74 | plt.plot(f, PSD_shifted) 75 | plt.show() 76 | 77 | fig = plt.figure() 78 | plt.plot(s_real) 79 | plt.plot(s_imag) 80 | plt.show() -------------------------------------------------------------------------------- /firmware/lvds_rx.v: -------------------------------------------------------------------------------- 1 | module lvds_rx ( 2 | input i_rst_b, 3 | input i_ddr_clk, 4 | input [1:0] i_ddr_data, 5 | 6 | input i_fifo_full, 7 | output o_fifo_write_clk, 8 | output o_fifo_push, 9 | output reg [31:0] o_fifo_data, 10 | input i_sync_input, 11 | output [ 1:0] o_debug_state 12 | ); 13 | 14 | // Internal FSM States 15 | localparam state_idle = 2'b00, state_i_phase = 2'b01, state_q_phase = 2'b11; 16 | 17 | // Modem sync symbols 18 | localparam modem_i_sync = 2'b10, modem_q_sync = 2'b01; 19 | 20 | // Internal Registers 21 | reg [1:0] r_state_if; 22 | reg [2:0] r_phase_count; 23 | reg r_sync_input; 24 | 25 | // Initial conditions 26 | initial begin 27 | r_state_if = state_idle; 28 | r_phase_count = 3'b111; 29 | end 30 | 31 | // Global Assignments 32 | assign o_fifo_write_clk = i_ddr_clk; 33 | assign o_debug_state = r_state_if; 34 | 35 | // Main Process 36 | always @(posedge i_ddr_clk or negedge i_rst_b) begin 37 | if (i_rst_b == 1'b0) begin 38 | r_state_if <= state_idle; 39 | o_fifo_push <= 1'b0; 40 | r_phase_count <= 3'b111; 41 | r_sync_input <= 1'b0; 42 | end else begin 43 | case (r_state_if) 44 | state_idle: begin 45 | if (i_ddr_data == modem_i_sync) begin 46 | r_state_if <= state_i_phase; 47 | o_fifo_data <= {30'b000000000000000000000000000000, i_ddr_data}; 48 | r_sync_input <= i_sync_input; // mark the sync input for this sample 49 | end 50 | r_phase_count <= 3'b111; 51 | o_fifo_push <= 1'b0; 52 | end 53 | 54 | state_i_phase: begin 55 | if (r_phase_count == 3'b000) begin 56 | if (i_ddr_data == modem_q_sync) begin 57 | r_phase_count <= 3'b110; 58 | r_state_if <= state_q_phase; 59 | end else begin 60 | r_state_if <= state_idle; 61 | end 62 | end else begin 63 | 64 | r_phase_count <= r_phase_count - 1; 65 | end 66 | o_fifo_push <= 1'b0; 67 | o_fifo_data <= {o_fifo_data[29:0], i_ddr_data}; 68 | end 69 | 70 | state_q_phase: begin 71 | if (r_phase_count == 3'b000) begin 72 | o_fifo_push <= ~i_fifo_full; 73 | r_state_if <= state_idle; 74 | o_fifo_data <= {o_fifo_data[29:0], i_ddr_data[1], r_sync_input}; 75 | end else begin 76 | o_fifo_push <= 1'b0; 77 | r_phase_count <= r_phase_count - 1; 78 | o_fifo_data <= {o_fifo_data[29:0], i_ddr_data}; 79 | end 80 | 81 | end 82 | endcase 83 | end 84 | end 85 | 86 | endmodule 87 | -------------------------------------------------------------------------------- /examples/lora_receiver/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // Print Board Information 8 | void printInfo(CaribouLite& cl) 9 | { 10 | std::cout << "Initialized CaribouLite: " << cl.IsInitialized() << std::endl; 11 | std::cout << "API Versions: " << cl.GetApiVersion() << std::endl; 12 | std::cout << "Hardware Serial Number: " << std::hex << cl.GetHwSerialNumber() << std::endl; 13 | std::cout << "System Type: " << cl.GetSystemVersionStr() << std::endl; 14 | std::cout << "Hardware Unique ID: " << cl.GetHwGuid() << std::endl; 15 | } 16 | 17 | // Detect the board before instantiating it 18 | void detectBoard() 19 | { 20 | CaribouLite::SysVersion ver; 21 | std::string name; 22 | std::string guid; 23 | 24 | if (CaribouLite::DetectBoard(&ver, name, guid)) 25 | { 26 | std::cout << "Detected Version: " << CaribouLite::GetSystemVersionStr(ver) << ", Name: " << name << ", GUID: " << guid << std::endl; 27 | } 28 | else 29 | { 30 | std::cout << "Undetected CaribouLite!" << std::endl; 31 | } 32 | } 33 | 34 | // Rx Callback (async) 35 | void receivedSamples(CaribouLiteRadio* radio, const std::complex* samples, CaribouLiteMeta* sync, size_t num_samples) 36 | { 37 | std::cout << "Radio: " << radio->GetRadioName() << " Received " << std::dec << num_samples << " samples" << std::endl; 38 | 39 | } 40 | 41 | 42 | // Main entry 43 | int main () 44 | { 45 | // try detecting the board before getting the instance 46 | detectBoard(); 47 | 48 | // get driver instance - use "CaribouLite&" rather than "CaribouLite" (ref) 49 | CaribouLite &cl = CaribouLite::GetInstance(); 50 | 51 | // print the info after connecting 52 | printInfo(cl); 53 | 54 | // get the radios 55 | CaribouLiteRadio *s1g = cl.GetRadioChannel(CaribouLiteRadio::RadioType::S1G); 56 | CaribouLiteRadio *hif = cl.GetRadioChannel(CaribouLiteRadio::RadioType::HiF); 57 | 58 | // write radio information 59 | std::cout << "First Radio Name: " << s1g->GetRadioName() << " MtuSize: " << std::dec << s1g->GetNativeMtuSample() << " Samples" << std::endl; 60 | std::cout << "First Radio Name: " << hif->GetRadioName() << " MtuSize: " << std::dec << hif->GetNativeMtuSample() << " Samples" << std::endl; 61 | 62 | // start receiving until enter pressed on 900MHz 63 | s1g->SetFrequency(900000000); 64 | s1g->SetRxGain(50); 65 | s1g->SetAgc(false); 66 | s1g->StartReceiving(receivedSamples); 67 | 68 | getchar(); 69 | 70 | hif->SetFrequency(900000000); 71 | hif->StartReceiving(receivedSamples, 20000); 72 | 73 | getchar(); 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /software/devicetrees/h_files/smi_dev_dtbo.h: -------------------------------------------------------------------------------- 1 | #ifndef __smi_dev_dtbo_h__ 2 | #define __smi_dev_dtbo_h__ 3 | 4 | #include 5 | #include 6 | 7 | uint8_t smi_dev_dtbo[] = { 8 | 0xD0, 0x0D, 0xFE, 0xED, 0x00, 0x00, 0x01, 0x94, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x01, 0x68, 9 | 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x62, 0x72, 0x63, 0x6D, 13 | 0x2C, 0x62, 0x63, 0x6D, 0x32, 0x38, 0x33, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 14 | 0x66, 0x72, 0x61, 0x67, 0x6D, 0x65, 0x6E, 0x74, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 15 | 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 16 | 0x5F, 0x5F, 0x6F, 0x76, 0x65, 0x72, 0x6C, 0x61, 0x79, 0x5F, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x01, 17 | 0x73, 0x6D, 0x69, 0x5F, 0x64, 0x65, 0x76, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 18 | 0x00, 0x00, 0x00, 0x00, 0x62, 0x72, 0x63, 0x6D, 0x2C, 0x62, 0x63, 0x6D, 0x32, 0x38, 0x33, 0x35, 19 | 0x2D, 0x73, 0x6D, 0x69, 0x2D, 0x64, 0x65, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 20 | 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 21 | 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x1D, 0x6F, 0x6B, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 23 | 0x5F, 0x5F, 0x66, 0x69, 0x78, 0x75, 0x70, 0x73, 0x5F, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 24 | 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x24, 0x2F, 0x66, 0x72, 0x61, 0x67, 0x6D, 0x65, 0x6E, 25 | 0x74, 0x40, 0x30, 0x3A, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3A, 0x30, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x28, 0x2F, 0x66, 0x72, 0x61, 27 | 0x67, 0x6D, 0x65, 0x6E, 0x74, 0x40, 0x30, 0x2F, 0x5F, 0x5F, 0x6F, 0x76, 0x65, 0x72, 0x6C, 0x61, 28 | 0x79, 0x5F, 0x5F, 0x2F, 0x73, 0x6D, 0x69, 0x5F, 0x64, 0x65, 0x76, 0x3A, 0x73, 0x6D, 0x69, 0x5F, 29 | 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x3A, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 30 | 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x74, 0x69, 0x62, 31 | 0x6C, 0x65, 0x00, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0x73, 0x6D, 0x69, 0x5F, 0x68, 0x61, 32 | 0x6E, 0x64, 0x6C, 0x65, 0x00, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x6F, 0x63, 0x00, 33 | 0x73, 0x6D, 0x69, 0x00, 34 | }; 35 | 36 | #endif // __smi_dev_dtbo_h__ 37 | -------------------------------------------------------------------------------- /software/libcariboulite/src/production_utils/hat_powermon.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRV_POWER_MON_H__ 2 | #define __DRV_POWER_MON_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | #include "io_utils/io_utils_i2c.h" 12 | 13 | 14 | typedef enum 15 | { 16 | HAT_POWERMON_REG_VERSION = 0, // read only, bits[3:0] = Version, bits[7:0] = Sub-Version 17 | HAT_POWERMON_REG_LOAD_SW_STATE = 1, // read / write, 0x00 = Load switch is off, 0x01 = Load switch is on 18 | HAT_POWERMON_REG_LED1_STATE = 2, // read / write, 0x00 = off, 0x01 = on 19 | HAT_POWERMON_REG_LED2_STATE = 3, // read / write, 0x00 = off, 0x01 = on 20 | HAT_POWERMON_REG_FAULT_STATE = 4, // read only, 0x00 = OK, 0x01 = Fault 21 | HAT_POWERMON_REG_CURRENT = 5, // read only, Val = real_current_mA / 5.0, possible currents [0.0 mA .. 1,275 mA] truncated if above 1.275 A, 5 mA resolution 22 | HAT_POWERMON_REG_VOLTAGE = 6, // read only Val = real_voltage_mV / 25.0, possible voltages [0.0 mV .. 6375 mV] truncated if above 6.375 V, 25 mV resolution 23 | HAT_POWERMON_REG_POWER = 7, // read only Val = real_power_mW / 125.0, possible powers [0.0 mW .. 8,128.125 mW] truncated if above 8.128125 Watt, 125 mW resolution 24 | HAT_POWERMON_REGS_MAX = 8, 25 | } HAT_POWERMON_REG_en; 26 | 27 | typedef struct 28 | { 29 | bool monitor_active; 30 | bool load_switch_state; 31 | bool fault; 32 | float i_ma; 33 | float v_mv; 34 | float p_mw; 35 | } hat_powermon_state_st; 36 | 37 | typedef struct 38 | { 39 | int ver; 40 | int subver; 41 | } hat_powermon_version_st; 42 | 43 | 44 | typedef void (*hat_powermon_callback)(void* context, hat_powermon_state_st* state); 45 | 46 | typedef struct 47 | { 48 | io_utils_i2c_st i2c_dev; 49 | hat_powermon_callback cb; 50 | void *context; 51 | 52 | hat_powermon_state_st state; 53 | hat_powermon_version_st version; 54 | 55 | pthread_t reader_thread; 56 | bool thread_running; 57 | } hat_power_monitor_st; 58 | 59 | int hat_powermon_init(hat_power_monitor_st* dev, uint8_t i2c_addr, hat_powermon_callback cb, void* context); 60 | int hat_powermon_release(hat_power_monitor_st* dev); 61 | 62 | int hat_powermon_set_power_state(hat_power_monitor_st* dev, bool on); 63 | int hat_powermon_get_power_state(hat_power_monitor_st* dev, bool *on); 64 | int hat_powermon_set_leds_state(hat_power_monitor_st* dev, bool led1, bool led2); 65 | int hat_powermon_get_leds_state(hat_power_monitor_st* dev, bool *led1, bool *led2); 66 | int hat_powermon_read_fault(hat_power_monitor_st* dev, bool* fault); 67 | int hat_powermon_read_data(hat_power_monitor_st* dev, float *i, float *v, float *p); 68 | int hat_powermon_read_versions(hat_power_monitor_st* dev, int *ver, int *subver); 69 | 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif // __DRV_POWER_MON_H__ -------------------------------------------------------------------------------- /software/libcariboulite/src/soapy_api/CaribouliteSession.cpp: -------------------------------------------------------------------------------- 1 | #include "Cariboulite.hpp" 2 | #include "cariboulite_config_default.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | std::mutex SoapyCaribouliteSession::sessionMutex; 9 | size_t SoapyCaribouliteSession::sessionCount = 0; 10 | sys_st SoapyCaribouliteSession::sys = {0}; 11 | 12 | 13 | void soapy_sighandler( struct sys_st_t *sys, 14 | void* context, 15 | int signum, 16 | siginfo_t *si) 17 | { 18 | SoapySDR_logf(SOAPY_SDR_DEBUG, "Received signal %d", signum); 19 | switch (signum) 20 | { 21 | case SIGINT: printf("soapy_sighandler caught SIGINT\n"); break; 22 | case SIGTERM: printf("soapy_sighandler caught SIGTERM\n"); break; 23 | case SIGABRT: printf("soapy_sighandler caught SIGABRT\n"); break; 24 | case SIGILL: printf("soapy_sighandler caught SIGILL\n"); break; 25 | case SIGSEGV: printf("soapy_sighandler caught SIGSEGV\n"); break; 26 | case SIGFPE: printf("soapy_sighandler caught SIGFPE\n"); break; 27 | default: printf("soapy_sighandler caught Unknown Signal %d\n", signum); return; break; 28 | } 29 | 30 | SoapySDR_logf(SOAPY_SDR_INFO, "soapy_sighandler killing soapy_cariboulite (cariboulite_release_driver)"); 31 | std::lock_guard lock(SoapyCaribouliteSession::sessionMutex); 32 | cariboulite_release_driver(&(SoapyCaribouliteSession::sys)); 33 | //SoapyCaribouliteSession::sessionCount = 0; 34 | } 35 | 36 | 37 | //======================================================== 38 | SoapyCaribouliteSession::SoapyCaribouliteSession(void) 39 | { 40 | std::lock_guard lock(sessionMutex); 41 | SoapySDR_logf(SOAPY_SDR_INFO, "SoapyCaribouliteSession, sessionCount: %ld", sessionCount); 42 | if (sessionCount == 0) 43 | { 44 | CARIBOULITE_CONFIG_DEFAULT(temp); 45 | memcpy(&sys, &temp, sizeof(sys_st)); 46 | 47 | sys.force_fpga_reprogramming = false; 48 | cariboulite_set_log_level(cariboulite_log_level_info); 49 | int ret = cariboulite_init_driver(&sys, NULL); 50 | if (ret != 0) 51 | { 52 | SoapySDR::logf(SOAPY_SDR_ERROR, "cariboulite_init_driver() failed"); 53 | } 54 | 55 | // setup the signal handler 56 | cariboulite_setup_signal_handler (&sys, soapy_sighandler, signal_handler_op_first, (void*)this); 57 | 58 | } 59 | sessionCount++; 60 | } 61 | 62 | //======================================================== 63 | SoapyCaribouliteSession::~SoapyCaribouliteSession(void) 64 | { 65 | std::lock_guard lock(sessionMutex); 66 | //SoapySDR_logf(SOAPY_SDR_INFO, "~SoapyCaribouliteSession, sessionCount: %ld", sessionCount); 67 | sessionCount--; 68 | if (sessionCount == 0) 69 | { 70 | cariboulite_release_driver(&sys); 71 | } 72 | //SoapySDR_logf(SOAPY_SDR_INFO, "~SoapyCaribouliteSession CaribouLite released"); 73 | } 74 | -------------------------------------------------------------------------------- /software/gr-caribouLite/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011,2012,2016,2018,2019 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-caribouLite 5 | # 6 | # SPDX-License-Identifier: GPL-3.0-or-later 7 | # 8 | 9 | ######################################################################## 10 | # Setup library 11 | ######################################################################## 12 | include(GrPlatform) #define LIB_SUFFIX 13 | 14 | find_package(PkgConfig REQUIRED) 15 | pkg_check_modules(CARIBOULITE REQUIRED cariboulite) 16 | 17 | list(APPEND caribouLite_sources 18 | caribouLiteSource_impl.cc) 19 | 20 | set(caribouLite_sources 21 | "${caribouLite_sources}" 22 | PARENT_SCOPE) 23 | if(NOT caribouLite_sources) 24 | message(STATUS "No C++ sources... skipping lib/") 25 | return() 26 | endif(NOT caribouLite_sources) 27 | 28 | add_library(gnuradio-caribouLite SHARED ${caribouLite_sources}) 29 | target_link_libraries(gnuradio-caribouLite gnuradio::gnuradio-runtime ${CARIBOULITE_LIBRARIES} -lcariboulite) 30 | target_include_directories( 31 | gnuradio-caribouLite 32 | PUBLIC $ 33 | PUBLIC $ 34 | ${CARIBOULITE_INCLUDE_DIRS}) 35 | set_target_properties(gnuradio-caribouLite PROPERTIES DEFINE_SYMBOL "gnuradio_caribouLite_EXPORTS") 36 | 37 | if(APPLE) 38 | set_target_properties(gnuradio-caribouLite PROPERTIES INSTALL_NAME_DIR 39 | "${CMAKE_INSTALL_PREFIX}/lib") 40 | endif(APPLE) 41 | 42 | ######################################################################## 43 | # Install built library files 44 | ######################################################################## 45 | include(GrMiscUtils) 46 | gr_library_foo(gnuradio-caribouLite) 47 | 48 | ######################################################################## 49 | # Print summary 50 | ######################################################################## 51 | message(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}") 52 | message(STATUS "Building for version: ${VERSION} / ${LIBVER}") 53 | 54 | ######################################################################## 55 | # Build and register unit test 56 | ######################################################################## 57 | include(GrTest) 58 | 59 | # If your unit tests require special include paths, add them here 60 | #include_directories() 61 | # List all files that contain Boost.UTF unit tests here 62 | list(APPEND test_caribouLite_sources) 63 | # Anything we need to link to for the unit tests go here 64 | list(APPEND GR_TEST_TARGET_DEPS gnuradio-caribouLite) 65 | 66 | if(NOT test_caribouLite_sources) 67 | message(STATUS "No C++ unit tests... skipping") 68 | return() 69 | endif(NOT test_caribouLite_sources) 70 | 71 | foreach(qa_file ${test_caribouLite_sources}) 72 | gr_add_cpp_test("caribouLite_${qa_file}" ${CMAKE_CURRENT_SOURCE_DIR}/${qa_file}) 73 | endforeach(qa_file) 74 | -------------------------------------------------------------------------------- /software/gr-caribouLite/python/caribouLite/bindings/header_utils.py: -------------------------------------------------------------------------------- 1 | # Utilities for reading values in header files 2 | 3 | from argparse import ArgumentParser 4 | import re 5 | 6 | 7 | class PybindHeaderParser: 8 | def __init__(self, pathname): 9 | with open(pathname, 'r') as f: 10 | self.file_txt = f.read() 11 | 12 | def get_flag_automatic(self): 13 | # p = re.compile(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)') 14 | # m = p.search(self.file_txt) 15 | m = re.search(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)', self.file_txt) 16 | if (m and m.group(1) == '1'): 17 | return True 18 | else: 19 | return False 20 | 21 | def get_flag_pygccxml(self): 22 | # p = re.compile(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)') 23 | # m = p.search(self.file_txt) 24 | m = re.search(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)', self.file_txt) 25 | if (m and m.group(1) == '1'): 26 | return True 27 | else: 28 | return False 29 | 30 | def get_header_filename(self): 31 | # p = re.compile(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)') 32 | # m = p.search(self.file_txt) 33 | m = re.search(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)', self.file_txt) 34 | if (m): 35 | return m.group(1) 36 | else: 37 | return None 38 | 39 | def get_header_file_hash(self): 40 | # p = re.compile(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)') 41 | # m = p.search(self.file_txt) 42 | m = re.search(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)', self.file_txt) 43 | if (m): 44 | return m.group(1) 45 | else: 46 | return None 47 | 48 | def get_flags(self): 49 | return f'{self.get_flag_automatic()};{self.get_flag_pygccxml()};{self.get_header_filename()};{self.get_header_file_hash()};' 50 | 51 | 52 | def argParse(): 53 | """Parses commandline args.""" 54 | desc = 'Reads the parameters from the comment block in the pybind files' 55 | parser = ArgumentParser(description=desc) 56 | 57 | parser.add_argument("function", help="Operation to perform on comment block of pybind file", choices=[ 58 | "flag_auto", "flag_pygccxml", "header_filename", "header_file_hash", "all"]) 59 | parser.add_argument( 60 | "pathname", help="Pathname of pybind c++ file to read, e.g. blockname_python.cc") 61 | 62 | return parser.parse_args() 63 | 64 | 65 | if __name__ == "__main__": 66 | # Parse command line options and set up doxyxml. 67 | args = argParse() 68 | 69 | pbhp = PybindHeaderParser(args.pathname) 70 | 71 | if args.function == "flag_auto": 72 | print(pbhp.get_flag_automatic()) 73 | elif args.function == "flag_pygccxml": 74 | print(pbhp.get_flag_pygccxml()) 75 | elif args.function == "header_filename": 76 | print(pbhp.get_header_filename()) 77 | elif args.function == "header_file_hash": 78 | print(pbhp.get_header_file_hash()) 79 | elif args.function == "all": 80 | print(pbhp.get_flags()) 81 | -------------------------------------------------------------------------------- /firmware/spi_slave.v: -------------------------------------------------------------------------------- 1 | module spi_slave ( 2 | // Control/Data Signals, 3 | input i_sys_clk, // FPGA Clock 4 | output reg o_rx_data_valid, // Data Valid pulse (1 clock cycle) 5 | output reg [7:0] o_rx_byte, // Byte received on MOSI 6 | input i_tx_data_valid, // Data Valid pulse to register i_tx_byte 7 | input [7:0] i_tx_byte, // Byte to serialize to MISO. 8 | 9 | // SPI Interface 10 | input i_spi_sck, 11 | output reg o_spi_miso, 12 | input i_spi_mosi, 13 | input i_spi_cs_b 14 | ); 15 | 16 | reg [2:0] r_rx_bit_count; 17 | reg [2:0] r_tx_bit_count; 18 | reg [7:0] r_temp_rx_byte; 19 | reg [7:0] r_rx_byte; 20 | reg r_rx_done; 21 | reg r2_rx_done; 22 | reg r3_rx_done; 23 | reg [7:0] r_tx_byte; 24 | 25 | // Purpose: Recover SPI Byte in SPI Clock Domain 26 | // Samples line on correct edge of SPI Clock 27 | always @(posedge i_spi_sck /* or posedge i_spi_cs_b*/) begin 28 | if (i_spi_cs_b) begin 29 | r_rx_bit_count <= 0; 30 | r_rx_done <= 1'b0; 31 | end else begin 32 | r_rx_bit_count <= r_rx_bit_count + 1; 33 | r_temp_rx_byte <= {r_temp_rx_byte[6:0], i_spi_mosi}; 34 | 35 | if (r_rx_bit_count == 3'b111) begin 36 | r_rx_done <= 1'b1; 37 | r_rx_byte <= {r_temp_rx_byte[6:0], i_spi_mosi}; 38 | end else if (r_rx_bit_count == 3'b010) begin 39 | r_rx_done <= 1'b0; 40 | end 41 | end 42 | end 43 | 44 | 45 | 46 | // Purpose: Cross from SPI Clock Domain to main FPGA clock domain 47 | // Assert o_rx_data_valid for 1 clock cycle when o_rx_byte has valid data. 48 | always @(posedge i_sys_clk) begin 49 | // Here is where clock domains are crossed. 50 | // This will require timing constraint created, can set up long path. 51 | r2_rx_done <= r_rx_done; 52 | r3_rx_done <= r2_rx_done; 53 | if (r3_rx_done == 1'b0 && r2_rx_done == 1'b1) begin // rising edge 54 | o_rx_data_valid <= 1'b1; // Pulse Data Valid 1 clock cycle 55 | o_rx_byte <= r_rx_byte; 56 | end else begin 57 | o_rx_data_valid <= 1'b0; 58 | end 59 | end 60 | 61 | reg [2:0] SCKr; 62 | always @(posedge i_sys_clk) SCKr <= {SCKr[1:0], i_spi_sck}; 63 | wire SCK_risingedge = (SCKr[2:1] == 2'b01); // now we can detect SCK rising edges 64 | 65 | // Purpose: Transmits 1 SPI Byte whenever SPI clock is toggling 66 | // Will transmit read data back to SW over MISO line. 67 | // Want to put data on the line immediately when CS goes low. 68 | always @(posedge i_sys_clk) begin 69 | if (i_spi_cs_b || i_tx_data_valid) begin 70 | r_tx_byte <= i_tx_byte; 71 | r_tx_bit_count <= 3'b110; 72 | o_spi_miso <= i_tx_byte[3'b111]; // Reset to MSb 73 | end else begin 74 | if (SCK_risingedge) begin 75 | r_tx_bit_count <= r_tx_bit_count - 1; 76 | o_spi_miso <= r_tx_byte[r_tx_bit_count]; 77 | 78 | if (r_tx_bit_count == 3'b000) begin 79 | r_tx_byte <= 8'b00000000; 80 | end 81 | 82 | end 83 | end 84 | end 85 | endmodule // SPI_Slave 86 | -------------------------------------------------------------------------------- /docs/flashing/README.md: -------------------------------------------------------------------------------- 1 | # EEPROM 2 | Each CaribouLite is pre-configured by the contract manufacturer before shipping. The Full and the ISM versions are further distinguishable by the configuration resistors placed on the back side of the board (marked as "**CFG/1234**"). 3 | 4 | CaribouLite doesn't have an FPGA configuration flash device, as the ICE40 device is dynamically configured by the RPI quickly and on-demand. It rather has a general board configuration device (EEPROM) as required by RPi's HAT device rules. 5 | 6 | ## EEPROM Data Structure 7 | The code is located [here](https://github.com/cariboulabs/cariboulite/tree/main/software/libcariboulite/src/cariboulite_eeprom) and is based on [RPi EERPROM Utils Tools](https://github.com/raspberrypi/hats/tree/master/eepromutils) provided by RaspberryPi. The ID EEPROM internal structure is described [here](https://github.com/raspberrypi/hats/blob/master/eeprom-format.md). 8 | 9 | The general structure is as follows: 10 | 1. **HEADER**: containing a valid header key (SIGN), its version, the number of ATOMs that follow the header and the total size of the EEPROM contents. 11 | 2. **VENDOR INFO**: Product information and Vendor information, and the product UID (unique 128bit identifier / serial number). 12 | 3. **GPIO MAP**: a listing of CaribouLite's RPi GPIO states and flags, for each GPIO pin (GPIO2-GPIO27). 13 | 4. **DEVICE TREE**: as the system is booting, the RPi kernel automatically reads this ATOM from the EEPROM and sets it as an overlay. As a result, the kernel modules needed for CaribouLite to operate (SMI, SPI, etc.) are probed on startup and configured according to the overlay. 14 | 5. **PROPRIETARY DATA**: this part contains additional configuration information for the board - I/Q imbalance calibration values, Tx-Power calibration, TCXO calibration, GPIO and PMOD states, etc. Some of these values shall be programmed by the CM, others are just place-holders for the user to better organize his work. 15 | 16 | ## Gracefully Accessing Data 17 | To access the EEPROM data, one can use our code which also validates and decodes the information. The easier way to access the information within the programmed EEPROM is to use Raspbian's Linux `sysfs` as follows: 18 | 19 | ``` 20 | cd /proc/device-tree/hat/ 21 | 22 | # name 23 | cat name 24 | 25 | # product: "CaribouLite RPI Hat" 26 | cat product 27 | 28 | # product_id: "0x0001" 29 | cat product_id 30 | 31 | # product_ver: "0x0001" 32 | cat product_ver 33 | 34 | # uuid: "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE" GUID format 35 | # which is also the board's raw serial number 36 | cat uuid 37 | 38 | # vendor: "CaribouLabs.co" 39 | cat vendor 40 | ``` 41 | 42 | ## Reprogramming the EEPROM 43 | Reprogramming the EEPROM is possible using our EEPROM utilities. 44 | More info - coming soon. 45 | 46 | # License 47 | Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. 48 | -------------------------------------------------------------------------------- /software/libcariboulite/src/production_utils/production_testing.h: -------------------------------------------------------------------------------- 1 | #ifndef ___PRODUCTION_TESTS_H__ 2 | #define ___PRODUCTION_TESTS_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "lcd.h" 13 | #include "hat_powermon.h" 14 | #include "io_utils/io_utils_sys_info.h" 15 | 16 | typedef int (*test_function)(void* context, void* tests, int test_num); 17 | #define PROD_TESTING_PWR_MON_ADDR (0x25) 18 | 19 | typedef struct 20 | { 21 | io_utils_sys_info_st rpi_info; 22 | } production_tester_st; 23 | 24 | typedef enum 25 | { 26 | production_sys_version_ism = 0, 27 | production_sys_version_full = 1, 28 | } production_sys_version_en; 29 | 30 | typedef struct 31 | { 32 | // inputs 33 | char name_short[20]; 34 | char test_name[128]; 35 | uint32_t test_number; 36 | test_function func; 37 | uint32_t group; 38 | bool started; 39 | bool finished; 40 | 41 | // timing 42 | struct tm start_time_of_test; 43 | struct tm end_time_of_test; 44 | 45 | // outputs 46 | void* test_result_context; 47 | float test_result_float; 48 | char test_result_textual[512]; 49 | bool test_pass; 50 | } production_test_st; 51 | 52 | typedef struct 53 | { 54 | lcd_st lcd; 55 | hat_power_monitor_st powermon; 56 | production_tester_st tester; 57 | 58 | production_test_st *tests; 59 | uint32_t number_of_tests; 60 | void* context; 61 | 62 | // git 63 | char git_pat_path[256]; 64 | char git_repo[256]; 65 | char git_res_directory[256]; 66 | 67 | char git_pat_pass[256]; 68 | char git_pat_user[256]; 69 | 70 | char git_base_command[600]; 71 | char git_add_command[1400]; 72 | char git_commit_command[1400]; 73 | char git_push_command[1400]; 74 | char git_pull_command[1400]; 75 | 76 | // state 77 | uint32_t current_test_number; 78 | bool current_tests_pass; 79 | 80 | // temporary data 81 | bool serial_number_written_and_valid; 82 | uint32_t serial_number; 83 | production_sys_version_en operator_set_version; 84 | 85 | bool system_type_valid; 86 | char product_name[64]; 87 | } production_sequence_st; 88 | 89 | int production_init(production_sequence_st* prod, production_test_st* tests, int num_tests, void* context); 90 | int production_set_git_repo(production_sequence_st* prod, char* pat, char* repo, char* dir); 91 | int production_rewind(production_sequence_st* prod); 92 | int production_close(production_sequence_st* prod); 93 | int production_start_tests(production_sequence_st* prod); 94 | int production_generate_report(production_sequence_st* prod, char* path, uint32_t serial_number); 95 | int production_generate_event_file(char* path, char* event, char* tester); 96 | int production_wait_for_button(production_sequence_st* prod, lcd_button_en but, char* top_line, char* bottom_line); 97 | int production_wait_input(production_sequence_st* prod, lcd_button_en *but, char* top_line, char* bottom_line); 98 | void production_git_sync_sequence(production_sequence_st* prod, char* commit_string); 99 | int production_monitor_power_fault(production_sequence_st* prod, bool* fault, float *i, float* v, float* p); 100 | 101 | 102 | #ifdef __cplusplus 103 | } 104 | #endif 105 | 106 | #endif // ___PRODUCTION_TESTS_H__ 107 | -------------------------------------------------------------------------------- /software/libcariboulite/src/io_utils/io_utils_i2c.c: -------------------------------------------------------------------------------- 1 | #define ZF_LOG_LEVEL ZF_LOG_VERBOSE 2 | #define ZF_LOG_DEF_SRCLOC ZF_LOG_SRCLOC_LONG 3 | #define ZF_LOG_TAG "IO_UTILS_I2C" 4 | #include "zf_log/zf_log.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "io_utils_i2c.h" 25 | 26 | //=================================================================== 27 | int io_utils_i2c_open(io_utils_i2c_st* dev, int bus, uint8_t address) 28 | { 29 | dev->bus = bus; 30 | dev->address = address; 31 | sprintf(dev->i2c_device_file, "/dev/i2c-%d", dev->bus); 32 | 33 | dev->fd = open(dev->i2c_device_file, O_RDWR); 34 | if (dev->fd == -1) 35 | { 36 | ZF_LOGE("opening device file '%s' failed", dev->i2c_device_file); 37 | return -1; 38 | } 39 | 40 | return 0; 41 | } 42 | 43 | //=================================================================== 44 | int io_utils_i2c_close(io_utils_i2c_st* dev) 45 | { 46 | return close(dev->fd); 47 | } 48 | 49 | //=================================================================== 50 | int io_utils_i2c_write(io_utils_i2c_st* dev, uint8_t *data, size_t len) 51 | { 52 | struct i2c_msg message = { .addr = dev->address, 53 | .flags = 0, 54 | .len = len, 55 | .buf = data}; 56 | 57 | struct i2c_rdwr_ioctl_data ioctl_data = { &message, 1 }; 58 | int result = ioctl(dev->fd, I2C_RDWR, &ioctl_data); 59 | if (result != 1) 60 | { 61 | ZF_LOGE("writing to i2c failed"); 62 | return -1; 63 | } 64 | 65 | return 0; 66 | } 67 | 68 | //=================================================================== 69 | int io_utils_i2c_read(io_utils_i2c_st* dev, uint8_t *data, size_t len) 70 | { 71 | struct i2c_msg messages = { 72 | .addr = dev->address, 73 | .flags = I2C_M_RD | I2C_M_NOSTART, 74 | .len = len, 75 | .buf = data 76 | }; 77 | 78 | struct i2c_rdwr_ioctl_data ioctl_data = { &messages, 1 }; 79 | 80 | int result = ioctl(dev->fd, I2C_RDWR, &ioctl_data); 81 | if (result != 1) 82 | { 83 | ZF_LOGE("reading from i2c failed"); 84 | return -1; 85 | } 86 | 87 | return 0; 88 | } 89 | 90 | //=================================================================== 91 | int io_utils_i2c_read_reg(io_utils_i2c_st* dev, uint8_t reg, uint8_t *data, size_t len) 92 | { 93 | struct i2c_msg messages[] = { { 94 | .addr = dev->address, 95 | .flags = 0, 96 | .len = 1, 97 | .buf = ®, 98 | }, 99 | { 100 | .addr = dev->address, 101 | .flags = I2C_M_RD, 102 | .len = len, 103 | .buf = data, 104 | } 105 | }; 106 | 107 | struct i2c_rdwr_ioctl_data ioctl_data = { messages, 2 }; 108 | int result = ioctl(dev->fd, I2C_RDWR, &ioctl_data); 109 | if (result != 2) 110 | { 111 | ZF_LOGE("reading reg from i2c failed (res = %d)", result); 112 | return -1; 113 | } 114 | return 0; 115 | } 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /firmware/spi_if.v: -------------------------------------------------------------------------------- 1 | `include "spi_slave.v" 2 | 3 | module spi_if ( 4 | input i_rst_b, // FPGA Reset 5 | input i_sys_clk, // FPGA Clock 6 | 7 | output reg [4:0] o_ioc, 8 | output reg [7:0] o_data_in, // data that was received over SPI 9 | input [7:0] i_data_out, // data to be sent over the SPI 10 | output reg [3:0] o_cs, 11 | output reg o_fetch_cmd, 12 | output reg o_load_cmd, 13 | 14 | // SPI Interface 15 | input i_spi_sck, 16 | output o_spi_miso, 17 | input i_spi_mosi, 18 | input i_spi_cs_b 19 | ); 20 | 21 | localparam 22 | state_idle = 3'b000, 23 | state_fetch1 = 3'b001, 24 | state_fetch2 = 3'b010, 25 | state_load = 3'b011, 26 | state_post_op= 3'b100; 27 | 28 | // internal registers / wires 29 | reg [2:0] state_if; 30 | wire w_rx_data_valid; 31 | wire [7:0] w_rx_data; 32 | reg r_tx_data_valid; 33 | reg [7:0] r_tx_byte; 34 | 35 | reg [4:0] r_ioc; 36 | reg [7:0] r_data; 37 | 38 | // Initial conditions 39 | initial begin 40 | state_if = state_idle; 41 | end 42 | 43 | spi_slave spi ( 44 | .i_sys_clk (i_sys_clk), 45 | .o_rx_data_valid(w_rx_data_valid), 46 | .o_rx_byte (w_rx_data), 47 | .i_tx_data_valid(r_tx_data_valid), 48 | .i_tx_byte (r_tx_byte), 49 | 50 | .i_spi_sck (i_spi_sck), 51 | .o_spi_miso(o_spi_miso), 52 | .i_spi_mosi(i_spi_mosi), 53 | .i_spi_cs_b(i_spi_cs_b) 54 | ); 55 | 56 | always @(posedge i_sys_clk) begin 57 | if (i_rst_b == 1'b0) begin 58 | state_if <= state_idle; 59 | end else if (w_rx_data_valid == 1'b1) begin 60 | // whenever a new byte arrives 61 | case (state_if) 62 | //---------------------------------- 63 | state_idle: begin 64 | o_ioc = w_rx_data[4:0]; 65 | case (w_rx_data[6:5]) 66 | 2'b00: o_cs <= 4'b0001; 67 | 2'b01: o_cs <= 4'b0010; 68 | 2'b10: o_cs <= 4'b0100; 69 | 2'b11: o_cs <= 4'b1000; 70 | endcase 71 | 72 | if (w_rx_data[7] == 1'b1) begin // write command 73 | state_if <= state_load; 74 | end else begin // read command 75 | o_fetch_cmd <= 1'b1; 76 | state_if <= state_fetch1; 77 | end 78 | 79 | o_load_cmd <= 1'b0; 80 | r_tx_data_valid <= 1'b0; 81 | end 82 | //---------------------------------- 83 | state_load: begin 84 | o_data_in <= w_rx_data; 85 | o_load_cmd <= 1'b1; 86 | state_if <= state_idle; 87 | end 88 | //---------------------------------- 89 | state_post_op: begin 90 | o_fetch_cmd <= 1'b0; 91 | o_load_cmd <= 1'b0; 92 | state_if <= state_idle; 93 | end 94 | endcase 95 | end else begin 96 | if (state_if == state_fetch1) begin 97 | o_fetch_cmd <= 1'b0; 98 | state_if <= state_fetch2; 99 | end else if (state_if == state_fetch2) begin 100 | r_tx_byte <= i_data_out; 101 | r_tx_data_valid <= 1'b1; 102 | state_if <= state_post_op; 103 | end else begin 104 | o_load_cmd <= 1'b0; 105 | r_tx_data_valid <= 1'b0; 106 | end 107 | end 108 | 109 | end 110 | endmodule // spi_if 111 | -------------------------------------------------------------------------------- /software/libcariboulite/src/datatypes/test_tsqueue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "tsqueue.h" 4 | 5 | tsqueue_st q = {0}; 6 | pthread_t tid; 7 | pthread_attr_t attr; 8 | #define RAND_DIVISOR 1000000000 9 | 10 | // Producer Thread 11 | void *producer(void *param) 12 | { 13 | int item = 0; 14 | 15 | while(1) 16 | { 17 | // sleep for a random period of time 18 | /*int rNum = rand() / RAND_DIVISOR; 19 | sleep(rNum); 20 | */ 21 | 22 | //getchar(); 23 | 24 | // generate a random number 25 | //item = rand(); 26 | item ++; 27 | 28 | int res = tsqueue_insert_push_buffer(&q, (uint8_t*)&item, sizeof(item), 0, 200, 1); 29 | if (res != 0) 30 | { 31 | if (res == TSQUEUE_NOT_INITIALIZED) fprintf(stderr, "Queue not inited\n"); 32 | if (res == TSQUEUE_FAILED_FULL) fprintf(stderr, "Queue is full!\n"); 33 | if (res == TSQUEUE_SEM_FAILED) fprintf(stderr, "Push semaphore failed\n"); 34 | if (res == TSQUEUE_TIMEOUT) fprintf(stderr, "Push TIMEOUT\n"); 35 | } 36 | else 37 | { 38 | printf("producer produced and pushed %d\n", item); 39 | } 40 | } 41 | } 42 | 43 | // Consumer Thread 44 | void *consumer(void *param) 45 | { 46 | tsqueue_item_st* item = NULL; 47 | 48 | int i = 0; 49 | while(1) 50 | { 51 | /* sleep for a random period of time */ 52 | //int rNum = rand() / RAND_DIVISOR; 53 | //sleep(1); 54 | 55 | //getchar(); 56 | int res; 57 | if (i==0) res = tsqueue_pop_item(&q, &item, 200); 58 | else res = tsqueue_peek_item(&q, &item, 200); 59 | 60 | if (i==0) printf("POP ==> "); 61 | else printf("PEEK ==> "); 62 | if (res != 0) 63 | { 64 | if (res == TSQUEUE_NOT_INITIALIZED) fprintf(stderr, "Queue not inited\n"); 65 | if (res == TSQUEUE_SEM_FAILED) fprintf(stderr, "Pop semaphore failed\n"); 66 | if (res == TSQUEUE_FAILED_EMPTY) fprintf(stderr, "Pop failed - Empty!!\n"); 67 | if (res == TSQUEUE_TIMEOUT) fprintf(stderr, "Pop TIMEOUT\n"); 68 | } 69 | else 70 | { 71 | int val = *((uint32_t*)item->data); 72 | printf("consumer consumed %d\n", val); 73 | } 74 | i = !i; 75 | } 76 | } 77 | 78 | // Main 79 | int main(int argc, char *argv[]) 80 | { 81 | int res = 0; 82 | 83 | if(argc != 4) 84 | { 85 | fprintf(stderr, "USAGE:./main.out \n"); 86 | return 1; 87 | } 88 | 89 | int mainSleepTime = atoi(argv[1]); /* Time in seconds for main to sleep */ 90 | int numProd = atoi(argv[2]); /* Number of producer threads */ 91 | int numCons = atoi(argv[3]); /* Number of consumer threads */ 92 | 93 | res = tsqueue_init(&q, 4, 4); 94 | 95 | // Create the producer threads 96 | for(int i = 0; i < numProd; i++) 97 | { 98 | pthread_create(&tid, &attr, producer,NULL); 99 | } 100 | 101 | // Create the consumer threads 102 | for(int i = 0; i < numCons; i++) 103 | { 104 | pthread_create(&tid, &attr, consumer,NULL); 105 | } 106 | 107 | sleep(mainSleepTime); 108 | printf("Exit the program\n"); 109 | 110 | res = tsqueue_release(&q); 111 | return 0; 112 | } -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_smi/caribou_smi_modules.c: -------------------------------------------------------------------------------- 1 | #ifndef ZF_LOG_LEVEL 2 | #define ZF_LOG_LEVEL ZF_LOG_VERBOSE 3 | #endif 4 | 5 | #define ZF_LOG_DEF_SRCLOC ZF_LOG_SRCLOC_LONG 6 | #define ZF_LOG_TAG "CARIBOU_SMI_MODULES" 7 | 8 | #define _GNU_SOURCE 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "zf_log/zf_log.h" 20 | #include "caribou_smi.h" 21 | #include "kernel/smi_stream_dev_gen.h" 22 | 23 | 24 | #define delete_module(name, flags) syscall(__NR_delete_module, name, flags) 25 | #define init_module(module_image, len, param_values) syscall(__NR_init_module, module_image, len, param_values) 26 | #define finit_module(fd, param_values, flags) syscall(__NR_finit_module, fd, param_values, flags) 27 | 28 | //=========================================================== 29 | int caribou_smi_check_modules_loaded(char* mod_name) 30 | { 31 | char line[256] = {0}; 32 | int found = 0; 33 | FILE *fid = fopen ("/proc/modules", "r"); 34 | if (fid == NULL) 35 | { 36 | return -1; 37 | } 38 | 39 | while (fgets(line, sizeof(line), fid)) 40 | { 41 | char* srch = strstr(line, mod_name); 42 | if (srch != NULL) 43 | { 44 | if (!isspace(srch[strlen(mod_name)])) continue; 45 | found = 1; 46 | } 47 | } 48 | fclose(fid); 49 | return found; 50 | } 51 | 52 | //=========================================================== 53 | int caribou_smi_remove_module(char* module_name) 54 | { 55 | if (delete_module(module_name, O_NONBLOCK) != 0) 56 | { 57 | ZF_LOGE("Module removing '%s' failed", module_name); 58 | return -1; 59 | } 60 | return 0; 61 | } 62 | 63 | //=========================================================== 64 | int caribou_smi_insert_smi_modules(char* module_name, 65 | uint8_t* buffer, 66 | size_t len, 67 | const char* params) 68 | { 69 | if (init_module(buffer, len, params) != 0) 70 | { 71 | ZF_LOGE("Module insertion '%s' failed", module_name); 72 | return -1; 73 | } 74 | return 0; 75 | } 76 | 77 | //=========================================================== 78 | int caribou_smi_check_modules(bool reload) 79 | { 80 | int ret = 0; 81 | int bcm_smi_dev_loaded = caribou_smi_check_modules_loaded("bcm2835_smi_dev"); 82 | int smi_stream_dev_loaded = caribou_smi_check_modules_loaded("smi_stream_dev"); 83 | int bcm_smi_loaded = caribou_smi_check_modules_loaded("bcm2835_smi"); 84 | 85 | if (bcm_smi_loaded != 1) 86 | { 87 | ZF_LOGE("SMI base driver not loaded - check device tree"); 88 | return -1; 89 | } 90 | 91 | if (smi_stream_dev_loaded == 1 && reload) 92 | { 93 | ZF_LOGD("Unloading smi-stream module"); 94 | ret = caribou_smi_remove_module("smi_stream_dev"); 95 | smi_stream_dev_loaded = 0; 96 | } 97 | 98 | if (bcm_smi_dev_loaded == 1) 99 | { 100 | ret = caribou_smi_remove_module("bcm2835_smi_dev"); 101 | } 102 | 103 | 104 | if (ret != 0) 105 | { 106 | ZF_LOGE("Error unloading module from system"); 107 | return -1; 108 | } 109 | 110 | if (!smi_stream_dev_loaded || reload) 111 | { 112 | ZF_LOGD("Loading smi-stream module"); 113 | return caribou_smi_insert_smi_modules("smi_stream_dev", smi_stream_dev, sizeof(smi_stream_dev), ""); 114 | } 115 | return 0; 116 | } 117 | 118 | 119 | -------------------------------------------------------------------------------- /software/libcariboulite/src/soapy_api/CaribouliteSensors.cpp: -------------------------------------------------------------------------------- 1 | #include "Cariboulite.hpp" 2 | 3 | //======================================================== 4 | std::vector Cariboulite::listSensors(const int direction, const size_t channel) const 5 | { 6 | std::vector lst; 7 | 8 | if (direction == SOAPY_SDR_RX) lst.push_back( "RSSI" ); 9 | if (direction == SOAPY_SDR_RX) lst.push_back( "ENERGY" ); 10 | lst.push_back( "PLL_LOCK_MODEM" ); 11 | if (channel == cariboulite_channel_hif) 12 | { 13 | lst.push_back( "PLL_LOCK_MIXER" ); 14 | } 15 | 16 | return(lst); 17 | } 18 | 19 | //======================================================== 20 | SoapySDR::ArgInfo Cariboulite::getSensorInfo(const int direction, const size_t channel, const std::string &key) const 21 | { 22 | SoapySDR::ArgInfo info; 23 | if (direction == SOAPY_SDR_RX) 24 | { 25 | if (key == "RSSI") 26 | { 27 | info.name = "RX RSSI"; 28 | info.key = "RSSI"; 29 | info.type = info.FLOAT; 30 | info.description = "Modem level RSSI measurment"; 31 | info.range = SoapySDR::Range(-127, 4); 32 | return info; 33 | } 34 | if (key == "ENERGY") 35 | { 36 | info.name = "RX ENERGY"; 37 | info.key = "ENERGY"; 38 | info.type = info.FLOAT; 39 | info.description = "Modem level ENERGY (EDC) measurment"; 40 | info.range = SoapySDR::Range(-127, 4); 41 | return info; 42 | } 43 | } 44 | 45 | if (key == "PLL_LOCK_MODEM") 46 | { 47 | info.name = "PLL Lock Modem"; 48 | info.key = "PLL_MODEM"; 49 | info.type = info.BOOL; 50 | info.description = "Modem PLL locking indication"; 51 | return info; 52 | } 53 | 54 | if (channel == cariboulite_channel_hif && key == "PLL_LOCK_MIXER") 55 | { 56 | info.name = "PLL Lock Mixer"; 57 | info.key = "PLL_MIXER"; 58 | info.type = info.BOOL; 59 | info.description = "Mixer LO PLL locking indication"; 60 | return info; 61 | } 62 | return info; 63 | } 64 | 65 | //======================================================== 66 | std::string Cariboulite::readSensor(const int direction, const size_t channel, const std::string &key) const 67 | { 68 | return std::to_string(readSensor(direction, channel, key)); 69 | } 70 | 71 | //======================================================== 72 | template 73 | Type Cariboulite::readSensor(const int direction, const size_t channel, const std::string &key) const 74 | { 75 | if (direction == SOAPY_SDR_RX) 76 | { 77 | if (key == "RSSI") 78 | { 79 | float rssi = 0.0f; 80 | cariboulite_radio_get_rssi((cariboulite_radio_state_st*)radio, &rssi); 81 | return rssi; 82 | } 83 | if (key == "ENERGY") 84 | { 85 | float energy = 0.0f; 86 | cariboulite_radio_get_energy_det((cariboulite_radio_state_st*)radio, &energy); 87 | return energy; 88 | } 89 | } 90 | 91 | if (key == "PLL_LOCK_MODEM") 92 | { 93 | return radio->modem_pll_locked; 94 | } 95 | 96 | if (channel == cariboulite_channel_hif && key == "PLL_LOCK_MIXER") 97 | { 98 | return radio->lo_pll_locked; 99 | } 100 | return 0; 101 | } -------------------------------------------------------------------------------- /software/libcariboulite/src/caribou_smi/caribou_smi.h: -------------------------------------------------------------------------------- 1 | #ifndef __CARIBOU_SMI_H__ 2 | #define __CARIBOU_SMI_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | #include "kernel/bcm2835_smi.h" 19 | #include "kernel/smi_stream_dev.h" 20 | 21 | // DEBUG Information 22 | typedef enum 23 | { 24 | caribou_smi_none = 0, 25 | caribou_smi_lfsr = 1, 26 | caribou_smi_push = 2, 27 | caribou_smi_pull = 3, 28 | } caribou_smi_debug_mode_en; 29 | 30 | typedef struct 31 | { 32 | uint32_t error_accum_counter; 33 | uint32_t cur_err_cnt; 34 | uint8_t last_correct_byte; 35 | double error_rate; 36 | uint32_t cnt; 37 | double bitrate; 38 | struct timeval last_time; 39 | } caribou_smi_debug_data_st; 40 | 41 | #define CARIBOU_SMI_DEBUG_WORD (0xABCDEF01) 42 | #define CARIBOU_SMI_BYTES_PER_SAMPLE (4) 43 | #define CARIBOU_SMI_SAMPLE_RATE (4000000) 44 | 45 | typedef enum 46 | { 47 | caribou_smi_channel_900 = smi_stream_channel_0, 48 | caribou_smi_channel_2400 = smi_stream_channel_1, 49 | } caribou_smi_channel_en; 50 | 51 | 52 | // Data container 53 | #pragma pack(1) 54 | // associated with CS16 - total 4 bytes / element 55 | typedef struct 56 | { 57 | int16_t i; // LSB 58 | int16_t q; // MSB 59 | } caribou_smi_sample_complex_int16; 60 | 61 | typedef struct 62 | { 63 | uint8_t sync; 64 | } caribou_smi_sample_meta; 65 | #pragma pack() 66 | 67 | typedef struct 68 | { 69 | int initialized; 70 | int filedesc; 71 | size_t native_batch_len; 72 | uint32_t sample_rate; 73 | smi_stream_state_en state; 74 | 75 | uint8_t *read_temp_buffer; 76 | uint8_t *write_temp_buffer; 77 | 78 | bool invert_iq; 79 | 80 | // debugging 81 | caribou_smi_debug_mode_en debug_mode; 82 | caribou_smi_debug_data_st debug_data; 83 | } caribou_smi_st; 84 | 85 | int caribou_smi_init(caribou_smi_st* dev, 86 | void* context); 87 | int caribou_smi_close (caribou_smi_st* dev); 88 | int caribou_smi_check_modules(bool reload); 89 | 90 | void caribou_smi_invert_iq(caribou_smi_st* dev, bool invert); 91 | 92 | void caribou_smi_set_debug_mode(caribou_smi_st* dev, caribou_smi_debug_mode_en mode); 93 | int caribou_smi_set_driver_streaming_state(caribou_smi_st* dev, smi_stream_state_en state); 94 | smi_stream_state_en caribou_smi_get_driver_streaming_state(caribou_smi_st* dev); 95 | 96 | int caribou_smi_read(caribou_smi_st* dev, caribou_smi_channel_en channel, 97 | caribou_smi_sample_complex_int16* buffer, caribou_smi_sample_meta* metadata, size_t length_samples); 98 | 99 | int caribou_smi_write(caribou_smi_st* dev, caribou_smi_channel_en channel, 100 | caribou_smi_sample_complex_int16* buffer, size_t length_samples); 101 | 102 | size_t caribou_smi_get_native_batch_samples(caribou_smi_st* dev); 103 | 104 | void caribou_smi_setup_ios(caribou_smi_st* dev); 105 | void caribou_smi_set_sample_rate(caribou_smi_st* dev, uint32_t sample_rate); 106 | int caribou_smi_flush_fifo(caribou_smi_st* dev); 107 | 108 | #ifdef __cplusplus 109 | } 110 | #endif 111 | 112 | #endif // __CARIBOU_SMI_H__ -------------------------------------------------------------------------------- /software/libcariboulite/src/cariboulite_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef __CARIBOULITE_INT_H__ 2 | #define __CARIBOULITE_INT_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "cariboulite_config_default.h" 9 | 10 | #include 11 | #include // for file system path max length 12 | 13 | #include "hat/hat.h" 14 | #include "io_utils/io_utils.h" 15 | #include "io_utils/io_utils_spi.h" 16 | #include "io_utils/io_utils_sys_info.h" 17 | #include "rffc507x/rffc507x.h" 18 | #include "at86rf215/at86rf215.h" 19 | 20 | #include "caribou_programming/caribou_prog.h" 21 | #include "caribou_fpga/caribou_fpga.h" 22 | #include "caribou_smi/caribou_smi.h" 23 | 24 | #include "cariboulite_radio.h" 25 | 26 | // GENERAL SETTINGS 27 | struct sys_st_t; 28 | 29 | typedef void (*signal_handler)( struct sys_st_t *sys, // the current cariboulite low-level management struct 30 | void* context, // custom context - can be a higher level app class 31 | int signal_number, // the signal number 32 | siginfo_t *si); 33 | 34 | typedef enum 35 | { 36 | signal_handler_op_last = 0, // The curtom sighandler operates (if present) after the default sig handler 37 | signal_handler_op_first = 1, // The curtom sighandler operates (if present) before the default sig handler 38 | signal_handler_op_override = 2, // The curtom sighandler operates (if present) instead of the default sig handler 39 | } signal_handler_operation_en; 40 | 41 | typedef enum 42 | { 43 | system_type_unknown = 0, 44 | system_type_cariboulite_full = 1, 45 | system_type_cariboulite_ism = 2, 46 | } system_type_en; 47 | 48 | typedef enum 49 | { 50 | cariboulite_ext_ref_src_modem = 0, 51 | cariboulite_ext_ref_src_connector = 1, 52 | cariboulite_ext_ref_src_txco = 2, 53 | cariboulite_ext_ref_src_na = 3, // not applicable 54 | } cariboulite_ext_ref_src_en; 55 | 56 | typedef enum 57 | { 58 | sys_status_unintialized = 0, 59 | sys_status_minimal_init = 1, 60 | sys_status_full_init = 2, 61 | } sys_status_en; 62 | 63 | typedef struct 64 | { 65 | cariboulite_ext_ref_src_en src; 66 | double freq_hz; 67 | } cariboulite_ext_ref_settings_st; 68 | 69 | typedef struct sys_st_t 70 | { 71 | // board information 72 | hat_board_info_st board_info; 73 | system_type_en sys_type; 74 | 75 | // SoC level 76 | io_utils_spi_st spi_dev; 77 | caribou_smi_st smi; 78 | //ustimer_t timer; 79 | 80 | // Peripheral chips 81 | caribou_fpga_st fpga; 82 | at86rf215_st modem; 83 | cariboulite_ext_ref_settings_st ext_ref_settings; 84 | rffc507x_st mixer; 85 | 86 | // Configuration 87 | int reset_fpga_on_startup; 88 | int force_fpga_reprogramming; 89 | int fpga_config_resistor_state; 90 | char firmware_path_operational[PATH_MAX]; 91 | char firmware_path_testing[PATH_MAX]; 92 | 93 | // Radios 94 | cariboulite_radio_state_st radio_low; 95 | cariboulite_radio_state_st radio_high; 96 | 97 | // Signals 98 | signal_handler signal_cb; 99 | void* singal_cb_context; 100 | signal_handler_operation_en sig_op; 101 | 102 | // Management 103 | caribou_fpga_versions_st fpga_versions; 104 | uint8_t fpga_error_status; 105 | int fpga_config_res_state; 106 | // Initialization 107 | sys_status_en system_status; 108 | } sys_st; 109 | 110 | #ifdef __cplusplus 111 | } 112 | #endif 113 | 114 | 115 | #endif // __CARIBOULITE_INT_H__ 116 | -------------------------------------------------------------------------------- /software/libcariboulite/src/io_utils/rpi/rpi.h: -------------------------------------------------------------------------------- 1 | /** 2 | * rpi.h 3 | * 4 | * Copyright (c) 2017 Ed Alegrid 5 | * GNU General Public License v3.0 6 | * 7 | */ 8 | 9 | /* Defines for RPI */ 10 | #ifndef RPI_H 11 | #define RPI_H 12 | 13 | #include 14 | 15 | #define RPI_VERSION 100 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | 22 | /* Initialize RPI library */ 23 | extern void rpi_init(int access); 24 | 25 | /* Close RPI library */ 26 | extern uint8_t rpi_close(); 27 | 28 | /** 29 | * Time Delays 30 | */ 31 | void nswait(uint64_t ns); //nanosecond time delay 32 | 33 | void uswait(uint32_t us); //microsecond time delay 34 | 35 | void mswait(uint32_t ms); //millisecond time delay 36 | 37 | /** 38 | * GPIO 39 | */ 40 | void gpio_config(uint8_t pin, uint8_t mode); 41 | 42 | uint8_t get_gpio_config(uint8_t pin); 43 | 44 | void gpio_input(uint8_t pin); 45 | 46 | void gpio_output(uint8_t pin); 47 | 48 | uint8_t gpio_read(uint8_t pin); 49 | 50 | uint8_t gpio_write(uint8_t pin, uint8_t bit); 51 | 52 | void gpio_on(uint8_t pin); 53 | 54 | void gpio_off(uint8_t pin); 55 | 56 | void gpio_pulse(uint8_t pin, int td); 57 | 58 | void gpio_reset_all_events(uint8_t pin); 59 | 60 | void gpio_enable_high_event(uint8_t pin, uint8_t bit); 61 | 62 | void gpio_enable_low_event(uint8_t pin, uint8_t bit); 63 | 64 | void gpio_enable_rising_event(uint8_t pin, uint8_t bit); 65 | 66 | void gpio_enable_falling_event(uint8_t pin, uint8_t bit); 67 | 68 | void gpio_enable_async_rising_event(uint8_t pin, uint8_t bit); 69 | 70 | void gpio_enable_async_falling_event(uint8_t pin, uint8_t bit); 71 | 72 | uint8_t gpio_detect_input_event(uint8_t pin); 73 | 74 | void gpio_reset_event(uint8_t pin); 75 | 76 | void gpio_enable_pud(uint8_t pin, uint8_t value); 77 | 78 | void get_pads(uint8_t group, uint8_t *slew_fast, uint8_t *hyst_enabled, uint8_t *drive_strength); 79 | void set_pads(uint8_t group, uint8_t slew_fast, uint8_t hyst_enabled, uint8_t drive_strength); 80 | /** 81 | * PWM 82 | */ 83 | void pwm_set_pin(uint8_t pin); 84 | 85 | void pwm_reset_pin(uint8_t pin); 86 | 87 | void pwm_reset_all_pins(); 88 | 89 | uint8_t pwm_set_clock_freq(uint32_t divider); 90 | 91 | uint8_t pwm_clk_status(); 92 | 93 | void pwm_enable(uint8_t pin, uint8_t n); 94 | 95 | void pwm_set_mode(uint8_t pin, uint8_t n); 96 | 97 | void pwm_set_pola(uint8_t pin, uint8_t n); 98 | 99 | void pwm_set_data(uint8_t pin, uint32_t data); 100 | 101 | void pwm_set_range(uint8_t pin, uint32_t range); 102 | 103 | /** 104 | * I2C 105 | */ 106 | int i2c_start(); 107 | 108 | int i2c_init(uint8_t value); 109 | 110 | void i2c_stop(); 111 | 112 | void i2c_select_slave(uint8_t addr); 113 | 114 | void i2c_set_clock_freq(uint16_t divider); 115 | 116 | void i2c_data_transfer_speed(uint32_t baud); 117 | 118 | uint8_t i2c_write(const char * wbuf, uint8_t len); 119 | 120 | uint8_t i2c_read(char * rbuf, uint8_t len); 121 | 122 | uint8_t i2c_byte_read(); 123 | 124 | /** 125 | * SPI 126 | */ 127 | int spi_start(); 128 | 129 | void spi_stop(); 130 | 131 | void spi_set_clock_freq(uint16_t divider); 132 | 133 | void spi_set_data_mode(uint8_t mode); 134 | 135 | void spi_set_chip_select_polarity(uint8_t cs, uint8_t active); 136 | 137 | void spi_chip_select(uint8_t cs); 138 | 139 | void spi_data_transfer(char* wbuf, char* rbuf, uint8_t len); 140 | 141 | void _spi_write(char* wbuf, uint8_t len); 142 | 143 | void _spi_read(char* rbuf, uint8_t len); 144 | 145 | 146 | #ifdef __cplusplus 147 | } 148 | #endif 149 | 150 | #endif /* RPI_H */ -------------------------------------------------------------------------------- /firmware/complex_fifo.v: -------------------------------------------------------------------------------- 1 | module complex_fifo #( 2 | parameter ADDR_WIDTH = 10, 3 | parameter DATA_WIDTH = 16 4 | ) 5 | ( 6 | input wire wr_rst_b_i, 7 | input wire wr_clk_i, 8 | input wire wr_en_i, 9 | input wire [2*DATA_WIDTH-1:0] wr_data_i, 10 | 11 | input wire rd_rst_b_i, 12 | input wire rd_clk_i, 13 | input wire rd_en_i, 14 | output reg [2*DATA_WIDTH-1:0] rd_data_o, 15 | 16 | output reg full_o, 17 | output reg empty_o, 18 | 19 | input wire debug_pull, 20 | input wire debug_push, 21 | ); 22 | 23 | reg [ADDR_WIDTH-1:0] wr_addr; 24 | reg [ADDR_WIDTH-1:0] wr_addr_gray; 25 | reg [ADDR_WIDTH-1:0] wr_addr_gray_rd; 26 | reg [ADDR_WIDTH-1:0] wr_addr_gray_rd_r; 27 | reg [ADDR_WIDTH-1:0] rd_addr; 28 | reg [ADDR_WIDTH-1:0] rd_addr_gray; 29 | reg [ADDR_WIDTH-1:0] rd_addr_gray_wr; 30 | reg [ADDR_WIDTH-1:0] rd_addr_gray_wr_r; 31 | 32 | reg [2*DATA_WIDTH-1:0] debug_buffer; 33 | 34 | function [ADDR_WIDTH-1:0] gray_conv; 35 | input [ADDR_WIDTH-1:0] in; 36 | begin 37 | gray_conv = {in[ADDR_WIDTH-1], in[ADDR_WIDTH-2:0] ^ in[ADDR_WIDTH-1:1]}; 38 | end 39 | endfunction 40 | 41 | always @(posedge wr_clk_i) begin 42 | if (wr_rst_b_i == 1'b0) begin 43 | wr_addr <= 0; 44 | wr_addr_gray <= 0; 45 | end else if (wr_en_i) begin 46 | wr_addr <= wr_addr + 1'b1; 47 | wr_addr_gray <= gray_conv(wr_addr + 1'b1); 48 | end 49 | end 50 | 51 | // synchronize read address to write clock domain 52 | always @(posedge wr_clk_i) begin 53 | rd_addr_gray_wr <= rd_addr_gray; 54 | rd_addr_gray_wr_r <= rd_addr_gray_wr; 55 | end 56 | 57 | always @(posedge wr_clk_i) begin 58 | if (wr_rst_b_i == 1'b0) begin 59 | full_o <= 0; 60 | end else if (wr_en_i) begin 61 | full_o <= gray_conv(wr_addr + 2) == rd_addr_gray_wr_r; 62 | end else begin 63 | full_o <= full_o & (gray_conv(wr_addr + 1'b1) == rd_addr_gray_wr_r); 64 | end 65 | end 66 | 67 | always @(posedge rd_clk_i) begin 68 | if (rd_rst_b_i == 1'b0) begin 69 | rd_addr <= 0; 70 | rd_addr_gray <= 0; 71 | debug_buffer <= 32'hABCDEF01; 72 | end else if (rd_en_i) begin 73 | rd_addr <= rd_addr + 1'b1; 74 | rd_addr_gray <= gray_conv(rd_addr + 1'b1); 75 | end 76 | end 77 | 78 | // synchronize write address to read clock domain 79 | always @(posedge rd_clk_i) begin 80 | wr_addr_gray_rd <= wr_addr_gray; 81 | wr_addr_gray_rd_r <= wr_addr_gray_rd; 82 | end 83 | 84 | always @(posedge rd_clk_i) begin 85 | if (rd_rst_b_i == 1'b0) begin 86 | empty_o <= 1'b1; 87 | end else if (rd_en_i) begin 88 | empty_o <= gray_conv(rd_addr + 1) == wr_addr_gray_rd_r; 89 | end else begin 90 | empty_o <= empty_o & (gray_conv(rd_addr) == wr_addr_gray_rd_r); 91 | end 92 | end 93 | 94 | always @(posedge rd_clk_i) begin 95 | if (rd_en_i) begin 96 | if (debug_pull) begin 97 | rd_data_o <= debug_buffer; 98 | end else begin 99 | rd_data_o[15:0] <= mem_q[rd_addr][15:0]; 100 | rd_data_o[31:16] <= mem_i[rd_addr][15:0]; 101 | end 102 | end 103 | end 104 | 105 | always @(posedge wr_clk_i) begin 106 | if (wr_en_i) begin 107 | if (debug_push) begin 108 | mem_q[wr_addr] <= debug_buffer[15:0]; 109 | mem_i[wr_addr] <= debug_buffer[31:16]; 110 | end else begin 111 | mem_q[wr_addr] <= wr_data_i[15:0]; 112 | mem_i[wr_addr] <= wr_data_i[31:16]; 113 | end 114 | end 115 | end 116 | 117 | reg [DATA_WIDTH-1:0] mem_i[(1< 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define MODE_S_ICAO_CACHE_LEN 1024 // Power of two required 23 | #define MODE_S_LONG_MSG_BYTES (112/8) 24 | #define MODE_S_UNIT_FEET 0 25 | #define MODE_S_UNIT_METERS 1 26 | 27 | // Program state 28 | typedef struct 29 | { 30 | // Internal state - recently seen ICAO addresses cache 31 | uint32_t icao_cache[sizeof(uint32_t)*MODE_S_ICAO_CACHE_LEN*2]; 32 | 33 | // Configuration 34 | int fix_errors; // Single bit error correction if true 35 | int aggressive; // Aggressive detection algorithm 36 | int check_crc; // Only display messages with good CRC 37 | } mode_s_t; 38 | 39 | // The struct we use to store information about a decoded message 40 | struct mode_s_msg 41 | { 42 | // ------ Generic fields ------------ 43 | unsigned char msg[MODE_S_LONG_MSG_BYTES]; // Binary message 44 | int msgbits; // Number of bits in message 45 | int msgtype; // Downlink format # 46 | int crcok; // True if CRC was valid 47 | uint32_t crc; // Message CRC 48 | int errorbit; // Bit corrected. -1 if no bit corrected. 49 | int aa1, aa2, aa3; // ICAO Address bytes 1 2 and 3 50 | int phase_corrected; // True if phase correction was applied. 51 | 52 | // ------ DF 11 --------------------- 53 | int ca; // Responder capabilities. 54 | 55 | // ------ DF 17 --------------------- 56 | int metype; // Extended squitter message type. 57 | int mesub; // Extended squitter message subtype. 58 | int heading_is_valid; 59 | int heading; 60 | int aircraft_type; 61 | int fflag; // 1 = Odd, 0 = Even CPR message. 62 | int tflag; // UTC synchronized? 63 | int raw_latitude; // Non decoded latitude 64 | int raw_longitude; // Non decoded longitude 65 | char flight[9]; // 8 chars flight number. 66 | int ew_dir; // 0 = East, 1 = West. 67 | int ew_velocity; // E/W velocity. 68 | int ns_dir; // 0 = North, 1 = South. 69 | int ns_velocity; // N/S velocity. 70 | int vert_rate_source; // Vertical rate source. 71 | int vert_rate_sign; // Vertical rate sign. 72 | int vert_rate; // Vertical rate. 73 | int velocity; // Computed from EW and NS velocity. 74 | 75 | // ------ DF4, DF5, DF20, DF21 ------- 76 | int fs; // Flight status for DF4,5,20,21 77 | int dr; // Request extraction of downlink request. 78 | int um; // Request extraction of downlink request. 79 | int identity; // 13 bits identity (Squawk). 80 | 81 | // Fields used by multiple message types. 82 | int altitude, unit; 83 | }; 84 | 85 | typedef void (*mode_s_callback_t)(mode_s_t *self, struct mode_s_msg *mm); 86 | 87 | void mode_s_init(mode_s_t *self); 88 | void mode_s_detect(mode_s_t *self, uint16_t *mag, uint32_t maglen, mode_s_callback_t); 89 | void mode_s_decode(mode_s_t *self, struct mode_s_msg *mm, unsigned char *msg); 90 | void mode_s_display_message(struct mode_s_msg *mm); 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | 96 | 97 | #endif -------------------------------------------------------------------------------- /software/libcariboulite/src/rffc507x/test_rffc507x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "rffc507x.h" 3 | #include "io_utils/io_utils.h" 4 | #include "io_utils/io_utils_spi.h" 5 | 6 | #define CARIBOULITE_MOSI 20 7 | #define CARIBOULITE_SCK 21 8 | #define CARIBOULITE_MISO 19 9 | 10 | #define FPGA_RESET 26 11 | #define ICE40_CS 18 12 | #define CARIBOULITE_MXR_SS 16 13 | #define CARIBOULITE_MXR_RESET 5 14 | 15 | io_utils_spi_st io_spi_dev = 16 | { 17 | .miso = CARIBOULITE_MISO, 18 | .mosi = CARIBOULITE_MOSI, 19 | .sck = CARIBOULITE_SCK, 20 | }; 21 | 22 | rffc507x_st dev = 23 | { 24 | .cs_pin = CARIBOULITE_MXR_SS, 25 | .reset_pin = CARIBOULITE_MXR_RESET, 26 | .ref_freq_hz = 32e6, 27 | }; 28 | 29 | int main () 30 | { 31 | io_utils_setup(NULL); 32 | io_utils_set_gpio_mode(FPGA_RESET, io_utils_alt_gpio_out); 33 | io_utils_set_gpio_mode(ICE40_CS, io_utils_alt_gpio_out); 34 | io_utils_setup_gpio(CARIBOULITE_MXR_RESET, io_utils_dir_output, io_utils_pull_up); 35 | 36 | //io_utils_write_gpio(FPGA_RESET, 0); 37 | //io_utils_write_gpio(ICE40_CS, 0); 38 | 39 | io_utils_write_gpio(CARIBOULITE_MXR_RESET, 0); 40 | printf("RFFC5072 is reset, press enter to release...\n"); 41 | getchar(); 42 | io_utils_write_gpio(CARIBOULITE_MXR_RESET, 1); 43 | printf("RFFC5072 is not reset.\n"); 44 | 45 | io_utils_spi_init(&io_spi_dev); 46 | io_utils_set_gpio_mode(19, io_utils_alt_gpio_in); 47 | rffc507x_init(&dev, &io_spi_dev); 48 | 49 | printf("RFFC507X Registers:\n"); 50 | for (int i = 0; i < RFFC507X_NUM_REGS; i ++) 51 | { 52 | uint16_t reg_val = rffc507x_reg_read(&dev, i); 53 | printf("REG #%d => %04X\n", i, reg_val); 54 | } 55 | 56 | rffc507x_device_id_st dev_id; 57 | rffc507x_device_status_st stat; 58 | rffc507x_readback_status(&dev, &dev_id, &stat); 59 | rffc507x_print_dev_id(&dev_id); 60 | rffc507x_print_stat(&stat); 61 | 62 | rffc507x_set_frequency(&dev, 85e6); 63 | 64 | for (int i = 0; i<5; i++) 65 | { 66 | io_utils_usleep(10000); 67 | rffc507x_readback_status(&dev, NULL, &stat); 68 | rffc507x_print_stat(&stat); 69 | } 70 | 71 | 72 | 73 | rffc507x_set_frequency(&dev, 314159265); 74 | 75 | for (int i = 0; i<5; i++) 76 | { 77 | io_utils_usleep(10000); 78 | rffc507x_readback_status(&dev, NULL, &stat); 79 | rffc507x_print_stat(&stat); 80 | } 81 | 82 | 83 | rffc507x_set_frequency(&dev, 915e6); 84 | 85 | for (int i = 0; i<5; i++) 86 | { 87 | io_utils_usleep(10000); 88 | rffc507x_readback_status(&dev, NULL, &stat); 89 | rffc507x_print_stat(&stat); 90 | } 91 | 92 | rffc507x_set_frequency(&dev, 1200e6); 93 | 94 | for (int i = 0; i<5; i++) 95 | { 96 | io_utils_usleep(10000); 97 | rffc507x_readback_status(&dev, NULL, &stat); 98 | rffc507x_print_stat(&stat); 99 | } 100 | 101 | 102 | rffc507x_set_frequency(&dev, 4600e6); 103 | 104 | for (int i = 0; i<5; i++) 105 | { 106 | io_utils_usleep(10000); 107 | rffc507x_readback_status(&dev, NULL, &stat); 108 | rffc507x_print_stat(&stat); 109 | } 110 | 111 | 112 | rffc507x_set_frequency(&dev, 5600e6); 113 | 114 | for (int i = 0; i<5; i++) 115 | { 116 | io_utils_usleep(10000); 117 | rffc507x_readback_status(&dev, NULL, &stat); 118 | rffc507x_print_stat(&stat); 119 | } 120 | 121 | rffc507x_release(&dev); 122 | io_utils_spi_close(&io_spi_dev); 123 | io_utils_cleanup(); 124 | 125 | /*rffc507x_setup(); 126 | rffc507x_tx(0); 127 | rffc507x_set_frequency(500, 0); 128 | rffc507x_set_frequency(525, 0); 129 | rffc507x_set_frequency(550, 0); 130 | rffc507x_set_frequency(1500, 0); 131 | rffc507x_set_frequency(1525, 0); 132 | rffc507x_set_frequency(1550, 0); 133 | rffc507x_disable(); 134 | rffc507x_rx(0); 135 | rffc507x_disable(); 136 | rffc507x_rxtx(); 137 | rffc507x_disable();*/ 138 | return 0; 139 | } 140 | -------------------------------------------------------------------------------- /firmware/sys_ctrl.v: -------------------------------------------------------------------------------- 1 | module sys_ctrl 2 | ( 3 | input i_rst_b, 4 | input i_sys_clk, // FPGA Clock 5 | 6 | input [4:0] i_ioc, 7 | input [7:0] i_data_in, 8 | output reg [7:0] o_data_out, 9 | input i_cs, 10 | input i_fetch_cmd, 11 | input i_load_cmd, 12 | 13 | // controls output 14 | output o_debug_fifo_push, 15 | output o_debug_fifo_pull, 16 | output o_debug_smi_test, 17 | output o_debug_loopback_tx, 18 | output [3:0] o_tx_sample_gap, 19 | ); 20 | 21 | // MODULE SPECIFIC IOC LIST 22 | // ------------------------ 23 | localparam 24 | ioc_module_version = 5'b00000, // read only 25 | ioc_system_version = 5'b00001, // read only 26 | ioc_manu_id = 5'b00010, // read only 27 | ioc_error_state = 5'b00011, // read only 28 | ioc_debug_modes = 5'b00101, // write only 29 | ioc_tx_sample_gap = 5'b00110; // read / write 30 | 31 | // MODULE SPECIFIC PARAMS 32 | // ---------------------- 33 | localparam 34 | module_version = 8'b00000001, 35 | system_version = 8'b00000001, 36 | manu_id = 8'b00000001; 37 | 38 | // MODULE INTERNAL SIGNALS 39 | // ----------------------- 40 | reg debug_fifo_push; 41 | reg debug_fifo_pull; 42 | reg debug_smi_test; 43 | reg debug_loopback_tx; 44 | reg [3:0] tx_sample_gap; 45 | 46 | assign o_debug_fifo_push = debug_fifo_push; 47 | assign o_debug_fifo_pull = debug_fifo_pull; 48 | assign o_debug_smi_test = debug_smi_test; 49 | 50 | // MODULE MAIN PROCESS 51 | // ------------------- 52 | always @(posedge i_sys_clk or negedge i_rst_b) 53 | begin 54 | if (i_rst_b == 1'b0) begin 55 | o_data_out <= 8'b00000000; 56 | debug_fifo_push <= 1'b0; 57 | debug_fifo_pull <= 1'b0; 58 | debug_smi_test <= 1'b0; 59 | debug_loopback_tx <= 1'b0; 60 | tx_sample_gap <= 4'd0; 61 | end else if (i_cs == 1'b1) begin 62 | //============================================= 63 | // READ OPERATIONS 64 | //============================================= 65 | if (i_fetch_cmd == 1'b1) begin 66 | case (i_ioc) 67 | ioc_module_version: o_data_out <= module_version; 68 | ioc_system_version: o_data_out <= system_version; 69 | ioc_manu_id: o_data_out <= manu_id; 70 | //---------------------------------------------- 71 | ioc_tx_sample_gap: begin 72 | o_data_out[3:0] <= tx_sample_gap; 73 | o_data_out[7:4] <= 4'd0; 74 | end 75 | endcase 76 | end 77 | //============================================= 78 | // WRITE OPERATIONS 79 | //============================================= 80 | else if (i_load_cmd == 1'b1) begin 81 | case (i_ioc) 82 | //---------------------------------------------- 83 | ioc_debug_modes: begin 84 | debug_fifo_push <= i_data_in[0]; 85 | debug_fifo_pull <= i_data_in[1]; 86 | debug_smi_test <= i_data_in[2]; 87 | debug_loopback_tx <= i_data_in[3]; 88 | end 89 | //---------------------------------------------- 90 | ioc_tx_sample_gap: begin 91 | tx_sample_gap <= i_data_in[3:0]; 92 | end 93 | endcase 94 | end 95 | end 96 | end 97 | 98 | endmodule // sys_ctrl --------------------------------------------------------------------------------