diff --git a/README.md b/README.md index efda26d62..a40bcbc27 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -## Meta Module +# Meta Module [![Build Simulator](https://github.com/4ms/metamodule/actions/workflows/build_simulator.yml/badge.svg)](https://github.com/4ms/metamodule/actions/workflows/build_simulator.yml) [![Build VCV Rack Plugin](https://github.com/4ms/metamodule/actions/workflows/build_vcv_plugin.yml/badge.svg)](https://github.com/4ms/metamodule/actions/workflows/build_vcv_plugin.yml) [![Run VCV unit tests](https://github.com/4ms/metamodule/actions/workflows/run_vcv_tests.yml/badge.svg)](https://github.com/4ms/metamodule/actions/workflows/run_vcv_tests.yml) [![Build Firmware](https://github.com/4ms/metamodule/actions/workflows/build_test_firmware.yml/badge.svg)](https://github.com/4ms/metamodule/actions/workflows/build_test_firmware.yml) -### Start +## Start First, clone this repo and `cd` into the new directory. @@ -28,21 +28,23 @@ git submodule update --init --recursive Next, setup your development environment by [following the instructions on this page](./docs/Setup.md). -### Next Steps +## Next Steps The Meta Module environment is built using three separate components: The VCV Rack Plugin (which includes the Meta Module patch exporter module), the Firmware for the Meta Module hardware, and the Firmware Simulator that allows you to run the firmware locally to test changes. -To build these components, please follow the separate build guides: +For information about building and using these components, please follow the separate guides: + - [VCV Rack Plugin](./vcv/README.md) -- [Simulator](./simulator/Building.md) +- [Simulator](./simulator/README.md) - [Firmware](./firmware/README.md) -### Usage +## Usage - [Creating Meta Module Patches With VCV](./docs/BasicVCVPatching.md) +- [Updating Firmware](./docs/user-firmware-update.md) -### Contributing +## Contributing If you would like to port your own VCV modules to the Meta Module platform, please see the [Porting Guide](./docs/Porting.md). diff --git a/docs/Firmware-Boot.md b/docs/Firmware-Boot.md new file mode 100644 index 000000000..5b7d817f5 --- /dev/null +++ b/docs/Firmware-Boot.md @@ -0,0 +1,47 @@ +# Firmware Boot Procedure + +The chip's ROM code reads the `BOOT0_2` DIP switch and then: + +- either halts (if it's set to `Debug`) +- or attempts to load a bootloader from the SD Card (if it's set to `SD`) +- or attempts to load a bootloader from the QSPI NOR Flash chip (if it's set to + `Flash`) + +and then starts executing the bootloader. + +The bootloader (which is `mp1-boot`) initializes the DDR RAM and various system +peripherals (security, MMU, clocks). After that it halts if Pin 2 and 4 of the +"Control Expander" (`J102`) are shortened with a jumper. + +Otherwise (no jumper detected), it will check if the rotary encoder is pressed. +If so, it loads an alternative firmware image from whatever media it booted +from (SD or Flash). On the Flash chip, USB-DFU "second-stage bootloader" (SSBL) +is preloaded. The SD card could also have an alternative firmware but this is +not used yet. + +Otherwise (no jumper and rotary not pressed) it loads the firmware image from the +default location on the selected boot media and then starts execution. + +### Secondary A7 core startup + +Both A7 cores startup at the same time, but Core 2 (aka secondary core) will go to +sleep immediately. The first core (primary, aka Core 1) +will proceed with the procedure descrived above. + +The MetaModule firmware awakens the secondary core and tells it to start executing from +the `aux_core_start` assembly code in 'firmware/lib/mdrivlib/target/stm32mp1_ca7/boot/startup_ca7.s` +which does some basic stack setup and then jumps to +the `aux_core_main()` function in `firmware/src/core_a7/aux_core_main.cc`. Here, the +secondary core handles the screen updates and runs the LVGL tasks. It also gets interrupted +by the primary core to help with audio processing. + + +### M4 startup + +The M4 firmware is bundled inside the A7 firmware. After power-on there is no +M4 firmware running (there is no internal flash to store the M4 firmware), so +the M4 core is just sitting idle. The A7 core does some early init and then +loads the M4 firmware and starts that core. + +The M4 firmware is responsible for reading all controls and the gate jacks. It also +handles all USB and SD Card transactions. diff --git a/docs/Porting.md b/docs/Porting.md index afdba992d..26ea17f7f 100644 --- a/docs/Porting.md +++ b/docs/Porting.md @@ -1,9 +1,92 @@ -If you would like to port your VCV-compatible modules to the Meta Module platform, you will need to follow a few steps for exporting artwork and ensuring binary compatibility. +### Instructions for adding a new module (WIP) -### Converting assets +1) First step is add the module code as a git submodule: -(TODO) +```bash +git submodule https://github.com// firmware/vcv_ports/ +``` + +2) Create artwork folders: + +```bash +mkdir -p firmware/src/gui/images//modules/ +mkdir -p firmware/src/gui/images//components/ +``` + +3) Create a modules.cmake file: `firmware/vcv_ports/glue//modules.cmake` +Look at other brands examples and copy what's done there. + +`modules.cmake` must do a few things: + +- Create a list of module names call `Modules`. + These names should be the VCV Rack module slugs. Ideally, these names are + also the names of the SVG faceplate files (without the .svg extension) and + also the names of the C++ source files (without the .cpp or .cc extension), + but if that's not the case you will just need to manually specify the SVGs + and source file names manually. + +- Invoke the module list filtering function on the list, like this: + ```cmake + include(${CMAKE_CURRENT_LIST_DIR}/../filter.cmake) + limit_modules_built("" Modules) + ``` + This allows developers to speed up build times and reduce binary sizes by specifying a white-list of + modules to include in the build. + +- Set a list called `_FACEPLATE_SVGS` ( is all caps), which + contains full paths to the faceplate .svg files. This is used when + (re-)generating all artwork files (convering SVG files to PNG and LVGL + format). + + +4) Create a brand CMakeLists.txt file: `firmware/vcv_ports/glue//CMakeLists.txt` +This file tells CMake how to build your modules. + +- Typically at the top of the CMakeLists file, you will `include()` the + `modules.cmake` file, and use the list of module names to generate the + list of source files needed to compile, but that's not a strict requirement. + +- The CMakeLists.txt must create a CMake target OBJECT library named Library, like this: + ```cmake + add_library( + Library OBJECT + ${BRAND_SOURCE_PATHS} + ${OTHER_SOURCES} + more_source_files.cpp + ) + ``` + You can then use normal CMake commands like `target_include_directories`, + `target_compile_options`, etc to specify how your modules should be built. + + +5) Add the brand name to `firmware/vcv_ports/brands.cmake` + +```cmake +# List of brands +set(brands + ... + +) +``` + + +5) Add the plugin to the VCV whitelist (see `vcv/src/mapping/module_directory.hh`). + +6) Generate faceplate artwork. + You can now run `make faceplate-image` to generate the faceplate artwork. This will + also re-generate all other brands artwork, so it's recommend that you a + limit file (see [Firmware README.md](../firmware/README.md) ) to just + specify your brands' modules, or perhaps even a subset of them just to + start. This works by reading the cmake list you created `BRAND_FACEPLATE_SVGS` + +7) Generate component artwork. + Put all SVG files for components into a folder (from the repo root) `graphics//components/`. + Then run `make comp-images` to generate the component images. This will regenerate all brand's component images. + (TODO: allow limiting this). Please only commit actually changed images. + +8) Connect VCV Widgets to MetaModule Elements and LVGL images. +(TODO). For an example, see [this commit](https://github.com/4ms/metamodule/pull/135/commits/3d5a721e7c9beea818e58401e82ba4faf5d52321) +Also, see issue #47 + -To create the artwork files from the SVGs, you must have Inkscape installed an on your PATH -...To Be Continued... \ No newline at end of file diff --git a/docs/firmware-building.md b/docs/firmware-building.md new file mode 100644 index 000000000..26e82d804 --- /dev/null +++ b/docs/firmware-building.md @@ -0,0 +1,166 @@ +## Building Firmware + +This requires `arm-none-eabi-gcc` version 12.2 or later installed on your PATH. +Please see the [setup guide](../docs/Setup.md) for some important notes about this. + +Make sure you are in the right branch and you already updated the submodules. + +To prepare the build system: (only needs to be run once) + +``` +make configure +``` + +To compile, run: + +``` +make all +``` + +The `make configure` command is a shortcut for running: + +``` +# MacOS, Linux: +cmake --fresh --preset base -GNinja + +# MinGW: +cmake --fresh --preset base -G"Unix Makefiles" +``` + +(The work-around for MinGW is documented with [issue #78](https://github.com/4ms/metamodule/issues/78)) + +The `make all` command is a shortcut for running: + +``` +cmake --build --preset base +``` + +### Limiting the modules built + +You also can limit the modules built to substantially reduce the compilation +and link times, as well as binary size. Create a text file with the modules +you want built, one per line. Each line should contain an +entry in the form `Brand:Module`. For example: + +``` +echo "4ms:EnOsc" >> quickbuild.txt +echo "Befaco:EvenVCO" >> quickbuild.txt +echo "hetrickcv:PhasorGen" >> quickbuild.txt + +make limit quickbuild.txt +``` + +This would tell CMake to re-configure the project and just build those three modules. +You can still open patches containing other modules, but their artwork won't be shown +and you can't play them. + + +### Using an SD Card + +*Optional*: If you plan to flash firmware to an SD Card, then you can specify the +path the SD Card device to save time. If you don't do this, then the system +will prompt you whenever you run one of the SD Card flashing scripts. The +device path should be to the entire SD Card device (not just one partition). +``` +cmake --preset base -DSD_DISK_DEV=/dev/disk4 + +# Alternatively, set an environment variable: +export SD_DISK_DEV=/dev/disk4 +``` + +The firmware is built as `firmware/build/mp1corea7/medium/main.elf` and `main.uimg` +in the same directory. The .elf file is used when debugging, and the .uimg file +is used when copying firmware to NOR Flash or an SD card. + + +### Specifying the toolchain + +*Optional*: if you have multiple versions of the gcc arm toolchain installed and don't want to +change your PATH for this project, you can set the METAMODULE_ARM_NONE_EABI_PATH var like this: + +``` +# Put in your bashrc/zshrc for convenience: +# Note the trailing slash (required) +export METAMODULE_ARM_NONE_EABI_PATH=/path/to/arm-gnu-toolchain-12.x-relX/bin/ +``` + + +### Automatically generated materials + +Several files are automatically generated using python scripts, e.g. faceplate +LVGL code. These generated files are already committed for a few reasons: 1) +the conversion process uses some specific external programs (inkscape CLI, and +a particular version of node); 2) generating all the assets takes a long time; +3) the assets don't change very often (if ever) and are completely orthogonal +to the code. Also conversion from SVG to PNG can generate a file that is +visually the same but has a different binary representation, causing lots of +noise in the git diffs. However if you wish to (re)-generate these files, the +following commands can be run: + +``` +# Generating LVGL image files for components +make comp-images + +# Generating LVGL image files for faceplates +make faceplate-images + +# Updating/creating 4ms VCV artwork SVGs files from *_info.svg files +make vcv-images + +# Updating/creating CoreModule *_info.hh files from *_info.svg +make module-infos + +# All of the above +make regenerate-all +``` + +If you just want to re-generate one image (that is, convert one SVG to a PNG and LVGL format), then you can invoke the python script directly. + +Here are some examples. These commands can be run from anywhere, but for these examples we'll show it from the firmware dir: + +``` +cd firmware/ +``` + + +Make sure the output directories exist first: + +``` +mkdir -p src/gui/images/BRANDNAME/components/ +mkdir -p src/gui/images/BRANDNAME/modules/ +``` + +Convert a component SVG: +(The DPI will be automatically detected and the output will be rescaled properly) + +``` +../shared/svgextract/svgextract.py convertSvgToLvgl \ + path/to/newcomponent.svg \ + src/gui/images/BRANDNAME/components/newcomponent.c +``` + +Convert a faceplate SVG: +This is the same as converting a component SVG, except for Alpha blending is disabled, and the height is fixed at 240px. + +``` +../shared/svgextract/svgextract.py createLvglFaceplate \ + path/to/newfaceplate.svg \ + src/gui/images/BRANDNAME/modules/newfaceplate.c +``` + +Optionally, you can only export one layer from a faceplate SVG file by specifying the layer name as a 3rd argument: + +``` +../shared/svgextract/svgextract.py createLvglFaceplate \ + path/to/newfaceplate.svg \ + src/gui/images/BRANDNAME/modules/newfaceplate.c \ + artworklayer +``` + +The svgextract script can do more, to see its help and view available commands: + +``` +../shared/svgextract/svgextract.py +``` + + diff --git a/docs/firmware-debugging.md b/docs/firmware-debugging.md new file mode 100644 index 000000000..139a1487c --- /dev/null +++ b/docs/firmware-debugging.md @@ -0,0 +1,92 @@ + +## Debugging with gdb and OpenOCD or JLinkGDBServer + + +Connecct an ST-LINK or J-Link programmer to the 10-pin JTAG/SWD header on the PCB. + +If you want to use OpenOCD, run this: + +``` +openocd -f board/stm32mp15x_dk2.cfg +``` + +Alternatively, you can run JLinkGDBServer and then select the STM32MP15x Core A7 as the target. + +``` +TODO: command? +``` + + +In another terminal window, run this command (from the project directory): + +``` +arm-none-eabi-gdb -f build/mp1corea7/medium/main.elf +``` + +From the gdb prompt, type: + +``` +target extended-remote localhost:3333 +load +``` + +The port number (3333) may be different for you, check the output of openocd or JLinkGDBServer +to see what port it's listening on. There may be a different port for each core. + +Remember, any file you load using a debugger will only get loaded into RAM. As +soon as you power down, it will be lost. + +## Debugging with Segger Ozone (OSD32 board only) + + +This requires a J-Link debugger. Within Ozone, create a new project for the +STM32MP15xx Core A7, and load the elf file `build/mp1corea7/medium/main.elf`. + +Make sure the Control Expander "freeze" jumper is installed, as described in +[firmware-loading](firmware-loading.md) + +After re-compiling, power cycle before loading the new .elf file. The Freeze jumper +makes this possible. + +## GPIO pin debugging (pin flipping) + +You can toggle some GPIO pins to indicate states from firmware with minimal impact on firmware timing. +Typically you would read the pins using an oscilloscope or logic probe. + +There are 6 header pins and two SMD pads on the PCB dedicated to this. They can be used like this: + +``` +#include "debug.hh" // Found in firmware/src/medium/ + +Debug::Pin0::high(); +Debug::Pin0::low(); +Debug::Pin1::set(true); //same as ::high() +Debug::Pin1::set(false); //same as ::low() +``` + +The pins and pads are located on the PCB as shown here: +![PCB header locations](./images/pcb-headers.png) + + +## Console output (printf debugging) + +You can view the console output by connecting a USB-UART cable to the TX pin of +the debug header (next to the SWD header). The TX pin is labeled (upper-right +pin). The bottom four pins are all GND. Settings are 115200, 8N1. See image above. + +Use `pr_dbg()`, `pr_warn()`, `pr_err()`, and `pr_trace()` for debug output. These +require the `console/pr_dbg.hh` header. + + +## Using VSCode + +VSCode can be used to debug, using OpenOCD and gdb. + + +Some configuration files (for the mp1 bootloader, so they will need to be adapted to MetaModule): +[here](https://github.com/danngreen/stm32mp1-baremetal/tree/vscode/bootloaders/mp1-boot/.vscode) +and [here](https://github.com/kamejoko80/stm32mp1-baremetal-1/tree/vscode/bootloaders/mp1-boot/.vscode) + +And also [some discussion:](https://github.com/4ms/stm32mp1-baremetal/issues/20) + +TODO: Adapt this to MetaModule. diff --git a/docs/firmware-loading.md b/docs/firmware-loading.md new file mode 100644 index 000000000..ea58549cd --- /dev/null +++ b/docs/firmware-loading.md @@ -0,0 +1,170 @@ +## Loading firmware onto the MetaModule + +You have several choices for how to load the firmware applcation. Each one is covered +in a section below: + +1) Load in RAM over SWD/JTAG + +2) Load into NOR Flash over DFU-USB + +3) Boot from SD Card + + +### Load in RAM over SWD/JTAG + +![PCB header locations](./images/pcb-headers.png) + +This is the preferred method for active firmware development. It requires a +JTAG programmer. + +Attach a JTAG debugger to the 10-pin connector at the top of the module labeled +"SWD". The protocol is actually JTAG, despite the header's name, though SWD may +work since the only difference is the tRST pin instead of NRST. + +If you are already running the application and just need to debug, you can just +attach without loading. + +If you need to load new firmware, then do this: + +1) Install a "Freeze jumper" on `Control Expander` header that bridges the top-left pin +and the pin just to the right of it. Make sure you use the right header, it's +the one above the Wifi header, near the `y` and `z` pots. The jumper should be +horizontal, not vertical, on the top row of pins all the way to the left: + +``` + Control + Expander + [====] o o + o o o o +``` + +See image above for reference. + +2) Power off and back on (full power-cycle is required). + +The console will show: + +``` +Freeze pin detected active, freezing. +Ready to load firmware to DDR RAM via SWD/JTAG. +``` + +Use Jflash, TRACE32, Ozone, openOCD/arm-none-eabi-gdb, etc to load the main.elf file. +If you have a JLink connected, you can program with this; + +``` +make jprog +``` + +This should take 15-30 seconds. + +For other methods, just load the .elf file and then start executing from 0xC0200040. + +Note: If you are familiar with flashing Cortex-M series MCUs, you will notice +some differences. One is that Flash is on an external chip. Another difference is +that the main RAM (DDR RAM) is not available until software initializes it. The +on-board NOR Flash chip has a bootloader installed +([MP1-Boot](https://github.com/4ms/mp1-boot), which is the FSBL). This is +loaded by the BOOTROM on power-up. The MP1-Boot bootloader is responsible for +initializing the DDR RAM peripheral. Obviously, this must be done before +loading the firmware into DDR RAM. So, unlike a Cortex-M chip, you must run a +bootloader before programming the device. However, one of the first things an +application does when it starts running is to enable the MMU and setup various +memory regions, some of which are not writable. Thus, the only time in which +it's possible to load firmware to RAM is after the bootloader has initialized +RAM but before the application has started. To handle this, MP1-Boot has a +"Freeze pin" option. When this pin is detected low (jumper is installed), then +MP1-Boot will halt execution (freeze) after initializing RAM. + +### Load into NOR Flash over DFU-USB + +Loading onto NOR Flash will flash the firmware into the on-board FLASH chip so +you can boot normally without a computer connected. It takes a minute or two, +so this is a good way to flash firmware infrequently, for example, flashing the +latest stable firwmare version. This is not recommended if you're doing active +firmware development since it's slow (use SWD/JTAG in that case). + +Power cycle the module while holding down the rotary encoder button. This +forces an alt firmware to be loaded from NOR Flash (which is a USB-DFU +bootloader). Make sure the jumper mentioned in the SWD/JTAG section is not installed. +If you are using the UART console, then you'll see this in the console: + +``` +USB DFU Loader Starting... +QSPI is initialized. +Connect a USB cable to the computer. +Run `dfu-util --list` in a terminal and you should see this device. +``` + +The button will be flashing green when in USB-DFU bootloader mode. + +Connect a USB cable from a computer to the module. + +You can use a web-based loader [such as this +one](https://devanlai.github.io/webdfu/dfu-util/). Click Connect, and then +select "STM Device in DFU Mode". Then click "Choose File" and select the uimg +file you just built at `build/mp1corea7/medium/main.uimg`. Then click +"Download". There may be an error `DFU GETSTATUS failed: ControlTransferIn +failed: NetworkError: Failed to execute 'controlTransferIn' on 'USBDevice': A +transfer error has occurred.` This is normal, and is not an error. It's safe to +ignore this. + + +Or use the command line (you must have [dfu-util](https://dfu-util.sourceforge.net/) installed): + +``` +make flash-dfu +``` + + +This command loads the main.uimg file to the default address (0x70080000). +It calls `dfu-util -a 0 -s 0x70080000 -D build/mp1corea7/medium/main.uimg` + +This will take between 60 and 120 seconds. +When it's done, unplug the USB cable, power-cycle, and the new code will start up. + + +### Boot from SD Card + +You need a dedicated SD Card, all contents will be erased. A 16GB card is common and works fine, +but smaller or larger should work too. + +You first need to format, partition, and install the bootloader on the card. This only needs +to happen once when you use a new SD Card. + +``` +make format-sd +``` + +This will ask you for the device path (/dev/disk4, for example). Make sure you get it right, because the +script will run `mkfs` or `diskutil eraseDisk`. + +After running this, you will need to eject and re-insert the SD Card because the volumes have changed. + +Then do: + +``` +make flash-bootloader-sd +``` + +This will build the bootloader (mp1-boot) and use `dd` to load it onto the first two partitions of the SD Card. +You will again be asked for the drive name. + +You now have a bootable SD Card. You shouldn't need to repeat the above steps unless you get a new SD Card. + +To flash the application, do this: + +``` +make flash-app-sd +``` + +This will build the application as normal, and then use `dd` to copy it to the fourth partition. + +Eject the card and insert it into the Meta Module. + +To tell the Meta Module to boot using the SD Card, you need to change the BOOT DIP switches. +These are located on the back of the PCB, under the screen near the rotary encoder. +They are labeled "BOOT0_2". There are two switches. Look at the diagram printed on the PCB. +To boot with the SD, both switches should be pushed to the left. +If you want to back to booting from Flash (internal Flash chip), then flip the bottom switch to the right. + diff --git a/docs/images/pcb-headers.jpg b/docs/images/pcb-headers.jpg new file mode 100644 index 000000000..ead735ad4 Binary files /dev/null and b/docs/images/pcb-headers.jpg differ diff --git a/docs/images/pcb-headers.png b/docs/images/pcb-headers.png new file mode 100644 index 000000000..f7848dcf4 Binary files /dev/null and b/docs/images/pcb-headers.png differ diff --git a/simulator/Building.md b/docs/simulator-building.md similarity index 55% rename from simulator/Building.md rename to docs/simulator-building.md index b5bc4b269..c69bf7331 100644 --- a/simulator/Building.md +++ b/docs/simulator-building.md @@ -1,11 +1,7 @@ -For information on how to use the firmware simulator, please see [README.md](./README.md). - ### Building the Simulator The simulator uses SDL2, which must be installed on your host machine. It -simulates graphics and audio output. The window can be re-sized in order to -examine precise pixel alignment. - +simulates graphics and audio output. Install the requirements as described in [Setup](../docs/Setup.md) Make sure you are in the right branch and you already updated the submodules. @@ -37,7 +33,7 @@ build/simulator build/simulator --help ``` -See the simulator [README.md](./README.md) for arguments details. +See the [Simulator Usage guide](simulator-usage.md) for arguments details. When adding/removing assets, sometimes you need to clean the build: @@ -60,3 +56,23 @@ make clean ``` Note that `make run` doesn't allow you to pass arguments. + +### Limiting the modules built + +You also can limit the modules built to substantially reduce the compilation +and link times. Create a text file with the modules +you want built, one per line. Each line should contain an +entry in the form `Brand:Module`. For example: + +``` +echo "4ms:EnOsc" >> quickbuild.txt +echo "Befaco:EvenVCO" >> quickbuild.txt +echo "hetrickcv:PhasorGen" >> quickbuild.txt + +make limit quickbuild.txt +``` + +This would tell CMake to re-configure the project and just build those three modules. +You can still open patches containing other modules, but their artwork won't be shown +and you can't play them. + diff --git a/docs/simulator-usage.md b/docs/simulator-usage.md new file mode 100644 index 000000000..7844484c8 --- /dev/null +++ b/docs/simulator-usage.md @@ -0,0 +1,130 @@ +# MetaModule Simulator Usage + +## Keyboard Control + +The simulator simulates the hardware's rotary encoder, button, knobs, and jacks +(patching/unpatching) using the host computer's keyboard. + +### Navigation + +- `Left Arrow`: Turn encoder counter-clockwise +- `Right Arrow`: Turn encoder clockwise +- `Down Arrow`: Press the encoder +- `Up Arrow`: Press the button (typically goes to the previous page) + +### Knobs + +The knobs on the Metamodule are labeled with letters (A-F, and u-z). These can be turned with the keyboard +by first pressing a letter to select the knob you want to turn, and then pressing ] or [ to increment/decrement the knob; + +- `a`: select knob A +- `b`: select knob B +- `c`: select knob C +- `d`: select knob D +- `e`: select knob E +- `f`: select knob F +- `u`: select knob u +- `v`: select knob v +- `w`: select knob w +- `x`: select knob x +- `y`: select knob y +- `z`: select knob z + +- `[`: turn the selected knob down 5% +- `]`: turn the selected knob up 5% + +TODO: make `{` and `}` inc/dec by small amounts + +The console will report the knob that was turned and its present value. + +### Audio Routing +By default, Audio Out 1 and Audio Out 2 are patched to the soundcard's left and right outputs, respectively. +Pressing a number button will change the routing: + +- `1`: Audio Out 1 -> Left, Audio Out 2 -> Right (default) +- `2`: Audio Out 2 -> Left, Audio Out 3 -> Right +- `3`: Audio Out 3 -> Left, Audio Out 4 -> Right +- `4`: Audio Out 4 -> Left, Audio Out 5 -> Right +- `5`: Audio Out 5 -> Left, Audio Out 6 -> Right +- `6`: Audio Out 6 -> Left, Audio Out 7 -> Right +- `7`: Audio Out 7 -> Left, Audio Out 8 -> Right +- `8`: Audio Out 8 -> Left, Audio Out 1 -> Right + +For now, the only way to test the inputs of a virtual module is to create a patch that runs signals +from a virtual module into the virtual module to be tested. +Future features include: +- Route a .wav file on the host computer to an input jack and play it on startup, and/or when a key is pressed. +- Route an audio interface's input jacks to input jacks. + +### Window + +The window can be re-sized in order to +examine precise pixel alignment. Drag the bottom-right corner of the window. To maintain the aspect ratio, hold shift while dragging. + +You also can specify a zoom level in the command-line arguments, see below. + + +------------------------ + +## Command-line Arguments + +Command-line arguments can be passed to the executable. To see the valid arguments, run: + +``` +build/simulator --help +``` + +Or you can type `-h` instead of `--help` + +Currently these are the options: + +### Audio Output Device + +`-a #`: specify the audio device index to use for output. Run the simulator and look at the console log to see what devices +are available. For example, you might see: + +``` +SDL: 3 audio devices found +0: DELL P2415Q (selected) +1: Studio Display Speakers +2: Mac Studio Speakers +``` + +Device 0 is chosen if the option is not specificed. If you were to do: + +``` +build/simulator -a 1 +``` + +then the Studio Display Speakers would be chosen. + + +### Zoom level + +`-z ###`: specify the initial zoom amount, as a percentage. Default is 100 (1 hardware pixel = 1 simulator pixel). + +A zoom of 300 or more is useful for inspecting pixel alignment. + +You can also change the zoom while the simulator is running by re-sizing the window with the mouse. + +### Patch file directory + +There are two mock "volumes" containing patch files. The `Internal` volume is +the list of factory default patches. This is always loaded. This list is found in +`firmware/src/patch_file/patches_default.hh`. + +Patches are also loaded from a local host computer directory, and appear in the `SD Card` volume. + +`-p path/to/patchfiles/`: The directory to search for patch files (.yml files) + +``` +build/simulator -p ~/MyPatchFiles/ +``` + +If no path is specified, `patches/` will be used (which is a directory in the simulator/ dir). + +If a directory is specified but it contains no valid patch files (or is an +invalid path), the simulator will print an error and ignore it. + + + diff --git a/docs/user-firmware-update.md b/docs/user-firmware-update.md new file mode 100644 index 000000000..1b78ef5e4 --- /dev/null +++ b/docs/user-firmware-update.md @@ -0,0 +1,28 @@ +## MetaModule Users Guide: + +### How to upgrade firmware + +1) Download the latest firmware release from the [MetaModule Github releases](https://github.com/4ms/metamodule/releases). You only need the main.uimg file, the other files are just for doing debugging. + +2) Connect a USB cable from a computer to the module. + +3) Power cycle the module while holding down the rotary encoder. + +4) The button will be flashing green, this tells you that you are in USB-DFU bootloader mode + +5) Open [this web-based DFU loader](https://devanlai.github.io/webdfu/dfu-util/) + +6) Click Connect, and then select "STM Device in DFU Mode". + +7) Then click "Choose File" and select the main.uimg file you just downloaded. + +8) Click "Download". + +9) Wait a couple minutes... it takes a while. There may be this error message: + +`DFU GETSTATUS failed: ControlTransferIn failed: NetworkError: Failed to execute 'controlTransferIn' on 'USBDevice': A transfer error has occurred.` + +This is normal, and is not a problem. It's safe to ignore this. + +10) When the web page says it's done, then unplug the USB cable and power cycle the module + diff --git a/firmware/README.md b/firmware/README.md index bb30233d8..902053e62 100644 --- a/firmware/README.md +++ b/firmware/README.md @@ -1,289 +1,18 @@ -### Building Firmware +## MetaModule Firmware -This requires `arm-none-eabi-gcc` version 12.2 or later installed on your PATH. -Please see the [setup guide](../docs/Setup.md) for some important notes about this. +The MetaModule firmware is built on a host computer using the arm-none-eabi +toolchain, and then loaded onto the MetaModule. -Make sure you are in the right branch and you already updated the submodules. +The following guides are available: -To prepare the build system: (only needs to be run once) +- [Setting up your environment](../docs/Setup.md): required software for your host computer. -``` -make configure -``` +- [Building firmware](../docs/firmware-building.md) -To compile, run: +- [Loading firmware](../docs/firmware-loading.md) -``` -make all -``` +- [User instructions to upgrading firmware](../docs/user-firmware-update.md) -The `make configure` command is a shortcut for running: +- [Debugging](../docs/firmware-debugging.md) -``` -# MacOS, Linux: -cmake --fresh --preset base -GNinja - -# MinGW: -cmake --fresh --preset base -G"Unix Makefiles" -``` - -(The work-around for MinGW is documented with [issue #78](https://github.com/4ms/metamodule/issues/78)) - -The `make all` command is a shortcut for running: - -``` -cmake --build --preset base -``` - -*Optional*: If you plan to flash firmware to an SD Card, then you can specify the -path the SD Card device to save time. If you don't do this, then the system -will prompt you whenever you run one of the SD Card flashing scripts. The -device path should be to the entire SD Card device (not just one partition). -``` -cmake --preset base -DSD_DISK_DEV=/dev/disk4 - -# Alternatively, set an environment variable: -export SD_DISK_DEV=/dev/disk4 -``` - -The firmware is built as `firmware/build/mp1corea7/medium/main.elf` and `main.uimg` -in the same directory. The .elf file is used when debugging, and the .uimg file -is used when copying firmware to NOR Flash or an SD card. - -*Optional*: if you have multiple versions of the gcc arm toolchain installed and don't want to -change your PATH for this project, you can set the METAMODULE_ARM_NONE_EABI_PATH var like this: - -``` -# Put in your bashrc/zshrc for convenience: -# Note the trailing slash (required) -export METAMODULE_ARM_NONE_EABI_PATH=/path/to/arm-gnu-toolchain-12.x-relX/bin/ -``` - -### Console output - -You can view the console output by connecting a USB-UART cable to the TX pin of -the debug header (next to the SWD header). The TX pin is labeled (upper-right -pin). The bottom four pins are all GND. Settings are 115200, 8N1. - - -### Loading firmware onto the device - -You have several choices for how to load the firmware applcation. Each one is covered -in a section below: - -1) Load in RAM over SWD/JTAG - -2) Load into NOR Flash over DFU-USB - -3) Boot from SD Card - - -#### Load in RAM over SWD/JTAG - -This is the preferred method for active firmware development. It requires a -JTAG programmer. - -Attach a JTAG debugger to the 10-pin connector at the top of the module labeled -"SWD". The protocol is actually JTAG, despite the header's name, though SWD may -work since the only difference is the tRST pin instead of NRST. - -If you are already running the application and just need to debug, you can just -attach without loading. - -If you need to load new firmware, then do this: - -1) Install a jumper on `Control Expander` header that bridges the top-left pin -and the pin just to the right of it. Make sure you use the right header, it's -the one above the Wifi header, near the `y` and `z` pots. The jumper should be -horizontal, not vertical, on the top row of pins all the way to the left: - -``` - Control - Expander - [====] o o - o o o o -``` - -2) Power off and back on (full power-cycle is required). - -The console will show: - -``` -Freeze pin detected active, freezing. -Ready to load firmware to DDR RAM via SWD/JTAG. -``` - -Use Jflash, TRACE32, Ozone, openOCD/arm-none-eabi-gdb, etc to load the main.elf file. -If you have a JLink connected, you can program with this; - -``` -make jprog -``` - -This should take 15-30 seconds. - -For other methods, just load the .elf file and then start executing from 0xC0200040. - -Note: If you are familiar with flashing Cortex-M series MCUs, you will notice -some differences. One is that Flash is on an external chip. Another difference is -that the main RAM (DDR RAM) is not available until software initializes it. The -on-board NOR Flash chip has a bootloader installed -([MP1-Boot](https://github.com/4ms/mp1-boot), which is the FSBL). This is -loaded by the BOOTROM on power-up. The MP1-Boot bootloader is responsible for -initializing the DDR RAM peripheral. Obviously, this must be done before -loading the firmware into DDR RAM. So, unlike a Cortex-M chip, you must run a -bootloader before programming the device. However, one of the first things an -application does when it starts running is to enable the MMU and setup various -memory regions, some of which are not writable. Thus, the only time in which -it's possible to load firmware to RAM is after the bootloader has initialized -RAM but before the application has started. To handle this, MP1-Boot has a -"Freeze pin" option. When this pin is detected low (jumper is installed), then -MP1-Boot will halt execution (freeze) after initializing RAM. - -#### Load into NOR Flash over DFU-USB - -Loading onto NOR Flash will flash the firmware into the on-board FLASH chip so -you can boot normally without a computer connected. It takes a minute or two, -so this is a good way to flash firmware infrequently, for example, flashing the -latest stable firwmare version. This is not recommended if you're doing active -firmware development since it's slow (use SWD/JTAG in that case). - -Power cycle the module while holding down the rotary encoder button. This -forces an alt firmware to be loaded from NOR Flash (which is a USB-DFU -bootloader). Make sure the jumper mentioned in the SWD/JTAG section is not installed. -If you are using the UART console, then you'll see this in the console: - -``` -USB DFU Loader Starting... -QSPI is initialized. -Connect a USB cable to the computer. -Run `dfu-util --list` in a terminal and you should see this device. -``` - -The button will be flashing green when in USB-DFU bootloader mode. - -Connect a USB cable from a computer to the module. - -You can use a web-based loader [such as this -one](https://devanlai.github.io/webdfu/dfu-util/). Click Connect, and then -select "STM Device in DFU Mode". Then click "Choose File" and select the uimg -file you just built at `build/mp1corea7/medium/main.uimg`. Then click -"Download". There may be an error `DFU GETSTATUS failed: ControlTransferIn -failed: NetworkError: Failed to execute 'controlTransferIn' on 'USBDevice': A -transfer error has occurred.` This is normal, and is not an error. It's safe to -ignore this. - - -Or use the command line (you must have [dfu-util](https://dfu-util.sourceforge.net/) installed): - -``` -make flash-dfu -``` - - -This command loads the main.uimg file to the default address (0x70080000). -It calls `dfu-util -a 0 -s 0x70080000 -D build/mp1corea7/medium/main.uimg` - -This will take between 60 and 120 seconds. -When it's done, unplug the USB cable, power-cycle, and the new code will start up. - - -#### Boot from SD Card - -You need a dedicated SD Card, all contents will be erased. A 16GB card is common and works fine, -but smaller or larger should work too. - -You first need to format, partition, and install the bootloader on the card. This only needs -to happen once when you use a new SD Card. - -``` -make format-sd -``` - -This will ask you for the device path (/dev/disk4, for example). Make sure you get it right, because the -script will run `mkfs` or `diskutil eraseDisk`. - -After running this, you will need to eject and re-insert the SD Card because the volumes have changed. - -Then do: - -``` -make flash-bootloader-sd -``` - -This will build the bootloader (mp1-boot) and use `dd` to load it onto the first two partitions of the SD Card. -You will again be asked for the drive name. - -You now have a bootable SD Card. You shouldn't need to repeat the above steps unless you get a new SD Card. - -To flash the application, do this: - -``` -make flash-app-sd -``` - -This will build the application as normal, and then use `dd` to copy it to the fourth partition. - -Eject the card and insert it into the Meta Module. - -To tell the Meta Module to boot using the SD Card, you need to change the BOOT DIP switches. -These are located on the back of the PCB, under the screen near the rotary encoder. -They are labeled "BOOT0_2". There are two switches. Look at the diagram printed on the PCB. -To boot with the SD, both switches should be pushed to the left. -If you want to back to booting from Flash (internal Flash chip), then flip the bottom switch to the right. - -### Automatically generated materials - -Several files are automatically generated using python scripts, e.g. faceplate LVGL code. These generated files are already committed for a few reasons: 1) the conversion process uses some specific external programs (inkscape CLI, and a particular version of node); 2) generating all the assets takes a long time; 3) the assets don't change very often (if ever) and are completely orthogonal to the code. Also conversion from SVG to PNG can generate a file that is visually the same but has a different binary representation, causing lots of noise in the git diffs. However if you wish to (re)-generate these files, the following commands can be run: - -``` -# Generating LVGL image files for components -make comp-images - -# Generating LVGL image files for faceplates -make faceplate-images - -# Update image_list.hh -make image-list - -# Updating/creating 4ms VCV artwork SVGs files from *_info.svg files -make vcv-images - -# Updating/creating CoreModule *_info.hh files from *_info.svg -make module-infos - -# All of the above -make regenerate-all -``` - -### Instructions for adding a new module (WIP) - -First step is add the module code as a git submodule: - -``` -git submodule https://github.com// firmware/vcv_ports/ -``` - -Create folder: - -``` -firmware/src/gui/images//modules/ -``` - -TODO which glue files to make/how, currently too complicated: - -* `firmware/vcv_ports/glue//modules.cmake` - list of modules mainly + list of svgs -* `firmware/vcv_ports/glue//CMakeLists.txt` - creates library, include directories, compile arguments - - -Add the following to `firmware\CMakeLists.txt`: - -``` -# List of brands -set(brands - - ... -) -``` - -You will also need to add the plugin to the Hub whitelist (see `vcv/src/mapping/module_directory.hh`). +- [Firmware Boot Process](../docs/Firmware-Boot.md) diff --git a/simulator/README.md b/simulator/README.md index 018cfea7f..b687be7fc 100644 --- a/simulator/README.md +++ b/simulator/README.md @@ -1,125 +1,12 @@ -## Meta Module Simulator +## MetaModule Simulator -This simulates the screen and the audio outputs. The pixels should be identical to the actual hardware's pixels. +The simulator runs on a host computer and simulates the screen and the audio +outputs. The pixels should be identical to the actual hardware's pixels. The audio should be the same as in hardware (though, your sound card might be AC-coupled, vs. the hardware is DC-coupled). -For information on building the simulator, please see [Building.md](./Building.md). +The following guides are available: -### Keyboard Control +- [Simulator Usage](../docs/simulator-usage.md) +- [Compiling the Simulator](../docs/simulator-building.md) -The simulator simulates the hardware's rotary encoder, button, knobs, and jacks -(patching/unpatching) using the host computer's keyboard. - -#### Navigation - -- `Left Arrow`: Turn encoder counter-clockwise -- `Right Arrow`: Turn encoder clockwise -- `Down Arrow`: Press the encoder -- `Up Arrow`: Press the button (typically goes to the previous page) - -#### Knobs - -The knobs on the Metamodule are labeled with letters (A-F, and u-z). These can be turned with the keyboard -by first pressing a letter to select the knob you want to turn, and then pressing ] or [ to increment/decrement the knob; - -- `a`: select knob A -- `b`: select knob B -- `c`: select knob C -- `d`: select knob D -- `e`: select knob E -- `f`: select knob F -- `u`: select knob u -- `v`: select knob v -- `w`: select knob w -- `x`: select knob x -- `y`: select knob y -- `z`: select knob z - -- `[`: turn the selected knob down 5% -- `]`: turn the selected knob up 5% - -TODO: make `{` and `}` inc/dec by small amounts - -The console will report the knob that was turned and its present value. - -#### Audio Routing -By default, Audio Out 1 and Audio Out 2 are patched to the soundcard's left and right outputs, respectively. -Pressing a number button will change the routing: - -- `1`: Audio Out 1 -> Left, Audio Out 2 -> Right (default) -- `2`: Audio Out 2 -> Left, Audio Out 3 -> Right -- `3`: Audio Out 3 -> Left, Audio Out 4 -> Right -- `4`: Audio Out 4 -> Left, Audio Out 5 -> Right -- `5`: Audio Out 5 -> Left, Audio Out 6 -> Right -- `6`: Audio Out 6 -> Left, Audio Out 7 -> Right -- `7`: Audio Out 7 -> Left, Audio Out 8 -> Right -- `8`: Audio Out 8 -> Left, Audio Out 1 -> Right - -For now, the only way to test the inputs of a virtual module is to create a patch that runs signals -from a virtual module into the virtual module to be tested. -Future features include: -- Route a .wav file on the host computer to an input jack and play it on startup, and/or when a key is pressed. -- Route an audio interface's input jacks to input jacks. - -### Arguments - -Command-line arguments can be passed to the executable. To see the valid arguments, run: - -``` -build/simulator --help -``` - -Or you can type `-h` instead of `--help` - -Currently these are the options: - -#### Audio Output Device - -`-a #`: specify the audio device index to use for output. Run the simulator and look at the console log to see what devices -are available. For example, you might see: - -``` -SDL: 3 audio devices found -0: DELL P2415Q (selected) -1: Studio Display Speakers -2: Mac Studio Speakers -``` - -Device 0 is chosen if the option is not specificed. If you were to do: - -``` -build/simulator -a 1 -``` - -then the Studio Display Speakers would be chosen. - - -#### Zoom level - -`-z ###`: specify the initial zoom amount, as a percentage. Default is 100 (1 hardware pixel = 1 simulator pixel). - -A zoom of 300 or more is useful for inspecting pixel alignment. - -You can also change the zoom while the simulator is running by re-sizing the window with the mouse. - -#### Patch files - -There are two mock "volumes" containing patch files. The `Internal` volume is -the list of factory default patches. This is always loaded. This list is found in -`firmware/src/patch_file/patches_default.hh`. - -Patches are also loaded from a local host computer directory, and appear in the `SD Card` volume. - -`-p path/to/patchfiles/`: The directory to search for patch files (.yml files) - -``` -build/simulator -p ~/MyPatchFiles/ -``` - -If no path is specified, `patches/` will be used (which is a directory in the simulator/ dir). - -If a directory is specified but it contains no valid patch files (or is an -invalid path), the simulator will print an error and ignore it. - - diff --git a/vcv/CHANGELOG.md b/vcv/CHANGELOG.md deleted file mode 100644 index 4d2f2a3d6..000000000 --- a/vcv/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -## 4ms VCV Changelog - - -### 2.0.0 -- Initial release \ No newline at end of file diff --git a/vcv/Dockerfile b/vcv/Dockerfile deleted file mode 100644 index cbd057241..000000000 --- a/vcv/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM debian:stretch - -LABEL "com.github.actions.name"="VCVRackPluginBuilder-Windows" -LABEL "com.github.actions.description"="Builds a VCV Rack plugin for Windows" -LABEL "com.github.actions.icon"="headphones" -LABEL "com.github.actions.color"="purple" - -LABEL "repository"="TBD" -LABEL "homepage"="TBD" -LABEL "maintainer"="dewb" - -RUN apt-get update -RUN apt-get install -y build-essential cmake curl gcc g++ git make tar unzip zip libgl1-mesa-dev libglu1-mesa-dev jq g++-mingw-w64-x86-64 - -ADD entrypoint.sh /entrypoint.sh -RUN chmod a+x /entrypoint.sh - -ENTRYPOINT ["/entrypoint.sh"] diff --git a/vcv/README.md b/vcv/README.md index 909c9c97f..a92baf551 100644 --- a/vcv/README.md +++ b/vcv/README.md @@ -4,7 +4,7 @@ Make sure to install all prerequisites as described on the [Setup guide](../docs ### Building VCV Rack Plugin -You must have the Rack-SDK on your computer already. Version 2.2.3 is known to +You must have the Rack-SDK on your computer already. Version 2.4.1 is known to work. Set the environment variable `RACK_DIR` equal to the path to the location of Rack-SDK. For instance, add this to your .bashrc or .zshrc: diff --git a/vcv/docker_build.sh b/vcv/docker_build.sh deleted file mode 100644 index 6295c4001..000000000 --- a/vcv/docker_build.sh +++ /dev/null @@ -1 +0,0 @@ -docker build -t test . diff --git a/vcv/docker_run.sh b/vcv/docker_run.sh deleted file mode 100644 index b7ed624a6..000000000 --- a/vcv/docker_run.sh +++ /dev/null @@ -1,2 +0,0 @@ -docker run -v /Users/dann/4ms/stm32/meta-module:/plugin test - diff --git a/vcv/entrypoint.sh b/vcv/entrypoint.sh deleted file mode 100755 index 257837e62..000000000 --- a/vcv/entrypoint.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -set -eu - -export RACK_DIR=$(PWD)/Rack-SDK -#export RACK_USER_DIR=./ -export RACK_SDK_VERSION=1.1.6 - -curl -L https://vcvrack.com/downloads/Rack-SDK-${RACK_SDK_VERSION}.zip -o rack-sdk.zip -unzip -o rack-sdk.zip -rm rack-sdk.zip - -#export CC=x86_64-w64-mingw32-gcc-posix -#export CXX=x86_64-w64-mingw32-g++-posix -export CC=x86_64-w64-mingw32-gcc -export CXX=x86_64-w64-mingw32-g++ -export STRIP=x86_64-w64-mingw32-strip - -cd /plugin -cd vcv -make clean -make dist - diff --git a/vcv/plugin-minimal.json b/vcv/plugin-minimal.json deleted file mode 100644 index 1cedc5e15..000000000 --- a/vcv/plugin-minimal.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "slug": "4msCompany", - "name": "4msCompany", - "version": "2.0.0", - "license": "proprietary", - "brand": "4msCompany", - "author": "", - "authorEmail": "", - "authorUrl": "", - "pluginUrl": "", - "manualUrl": "", - "sourceUrl": "", - "donateUrl": "", - "changelogUrl": "", - "modules": [ - { - "slug": "HubMedium", - "name": "MetaModule", - "description": "MetaModule", - "tags": [] - }, - { - "slug": "ENVVCA", - "name": "ENVVCA", - "description": "ENVVCA", - "tags": [] - }, - { - "slug": "Freeverb", - "name": "Freeverb", - "description": "Freeverb", - "tags": [] - }, - { - "slug": "SMR", - "name": "SMR", - "description": "Spectral Multiband Resonator", - "tags": [] - } - ] -} diff --git a/vcv/plugins-unused.json b/vcv/plugins-unused.json deleted file mode 100644 index ed59c87d8..000000000 --- a/vcv/plugins-unused.json +++ /dev/null @@ -1,373 +0,0 @@ - { - "slug": "VCA", - "name": "VCA", - "description": "VCA", - "tags": [] - }, - { - "slug": "Send", - "name": "Send", - "description": "Send", - "tags": [] - }, - - { - "slug": "Logic", - "name": "Logic", - "description": "Logic", - "tags": [] - }, - { - "slug": "LFO", - "name": "LFO", - "description": "LFO", - "tags": [] - }, - { - "slug": "FadeDelay", - "name": "FadeDelay", - "description": "FadeDelay", - "tags": [] - }, - - { - "slug": "Att", - "name": "Att", - "description": "Att", - "tags": [] - }, - - - - - { - "slug": "dual_opener", - "name": "Dual Opener", - "description": "", - "tags": [] - }, - { - "slug": "dspTemplate", - "name": "dspTemplate", - "description": "", - "tags": [] - }, - { - "slug": "adjTest", - "name": "adjTest", - "description": "", - "tags": [] - }, - - { - "slug": "PANEL_8", - "name": "MetaModuleMini", - "description": "MetaModule 16HP 8 knobs, stereo Audio In, 4-channel audio out, 4 CV inputs, 2 gate in, clock in/out, two RGB buttons", - "tags": [] - }, - { - "slug": "PANEL_MED", - "name": "PanelMedium", - "description": "Panel Medium 26HP", - "tags": [] - }, -{ - "slug": "INFOSC64", - "name": "Infosc-64bit-phase", - "description": "infinite-oscillator-64bit-Phase", - "tags": [] -}, -{ - "slug": "INFOSC01", - "name": "Infosc01", - "description": "infinite-oscillator-01", - "tags": [] -}, -{ - "slug": "DJEMBE", - "name": "Djembe", - "description": "Djembe", - "tags": [] -}, -{ - "slug": "BIPOLARSOURCE", - "name": "Bipolarsource", - "description": "Bipolar Voltage Source", - "tags": [] -}, -{ - "slug": "MULTILFO", - "name": "Multilfo", - "description": "Multi Output LFO", - "tags": [] -}, -{ - "slug": "ENVELOPEFOLLOWER", - "name": "Envelopefollower", - "description": "Envelope Follower", - "tags": [] -}, -{ - "slug": "VOLTAGESOURCE", - "name": "Voltagesource", - "description": "Voltage Source", - "tags": [] -}, -{ - "slug": "NOISE", - "name": "Noise", - "description": "Noise", - "tags": [] -}, -{ - "slug": "SAMPLEPLAYER", - "name": "Sampleplayer", - "description": "Sample Player", - "tags": [] -}, -{ - "slug": "SLEWLIMITER", - "name": "Slewlimiter", - "description": "Slew Limiter", - "tags": [] -}, -{ - "slug": "BANDPASSFILTER", - "name": "Bandpassfilter", - "description": "Bandpass Filter", - "tags": [] -}, -{ - "slug": "HIGHPASSFILTER", - "name": "Highpassfilter", - "description": "Highpass Filter", - "tags": [] -}, -{ - "slug": "REVERB", - "name": "Reverb", - "description": "Reverb", - "tags": [] -}, -{ - "slug": "KARPLUS", - "name": "Karplus", - "description": "Karplus", - "tags": [] -}, -{ - "slug": "GATESEQ16", - "name": "Gateseq16", - "description": "16 Step Gate Sequencer", - "tags": [] -}, -{ - "slug": "GATESEQ8", - "name": "Gateseq8", - "description": "8 Step Gate Sequencer", - "tags": [] -}, -{ - "slug": "OCTAVE", - "name": "Octave", - "description": "Octave", - "tags": [] -}, -{ - "slug": "MINMAX", - "name": "Minmax", - "description": "Minimum/Maximum", - "tags": [] -}, -{ - "slug": "DRUM", - "name": "Drum", - "description": "Drum", - "tags": [] -}, -{ - "slug": "COMPLEXENVELOPE", - "name": "Complexenvelope", - "description": "Complex Envelope", - "tags": [] -}, -{ - "slug": "FMOSC", - "name": "Fmosc", - "description": "FM Oscillator", - "tags": [] -}, -{ - "slug": "STEREOMIXER", - "name": "Stereomixer", - "description": "Stereo Mixer", - "tags": [] -}, -{ - "slug": "PANNER", - "name": "Panner", - "description": "Panner", - "tags": [] -}, -{ - "slug": "GATECONVERTER", - "name": "Gateconverter", - "description": "Gate Converter", - "tags": [] -}, -{ - "slug": "DETUNE", - "name": "Detune", - "description": "Detune", - "tags": [] -}, -{ - "slug": "PITCHSHIFT", - "name": "Pitchshift", - "description": "Pitch Shifter", - "tags": [] -}, -{ - "slug": "SWITCH4TO1", - "name": "Switch4to1", - "description": "4 to 1 Switch", - "tags": [] -}, -{ - "slug": "SWITCH1TO4", - "name": "Switch1to4", - "description": "1 to 4 Switch", - "tags": [] -}, - { - "slug": "EIGHTSTEPPROB", - "name": "Eightstepprob", - "description": "8 Step Probability Sequencer", - "tags": [] - }, - { - "slug": "QUANTIZER", - "name": "Quantizer", - "description": "Quantizer", - "tags": [] - }, - { - "slug": "FOURSTEP", - "name": "Fourstep", - "description": "4 Step Sequencer", - "tags": [] - }, - { - "slug": "EIGHTSTEP", - "name": "Eightstep", - "description": "8 Step Sequencer", - "tags": [] - }, - { - "slug": "BITCRUSH", - "name": "Bitcrush", - "description": "Bit Crusher", - "tags": [] - }, - { - "slug": "PHASER", - "name": "Phaser", - "description": "Phaser", - "tags": [] - }, - { - "slug": "FREQSHIFT", - "name": "Freqshift", - "description": "Frequency Shifter", - "tags": [] - }, - { - "slug": "LOWPASSFILTER", - "name": "Lowpassfilter", - "description": "Low Pass Filter", - "tags": [] - }, - { - "slug": "LOWPASSGATE", - "name": "Lowpassgate", - "description": "Low Pass Gate", - "tags": [] - }, - { - "slug": "CLKMULTIPLIER", - "name": "Clkmultiplier", - "description": "clock multiplier", - "tags": [] - }, - { - "slug": "CLKDIVIDER", - "name": "Clkdivider", - "description": "clock divider", - "tags": [] - }, - { - "slug": "comparator", - "name": "Comparator", - "description": "", - "tags": [] - }, - { - "slug": "send", - "name": "Send", - "description": "", - "tags": [] - }, - { - "slug": "lfo", - "name": "lfo", - "description": "", - "tags": [] - }, - { - "slug": "ad_envelope", - "name": "AD envelope", - "description": "", - "tags": [] - }, - { - "slug": "crossfade", - "name": "crossfade", - "description": "", - "tags": [] - }, - { - "slug": "mixer4", - "name": "mixer4", - "description": "", - "tags": [] - }, - { - "slug": "logic", - "name": "logic", - "description": "", - "tags": [] - }, - { - "slug": "samplehold", - "name": "samplehold", - "description": "", - "tags": [] - }, - { - "slug": "attenuvert", - "name": "attenuvert", - "description": "", - "tags": [] - }, - { - "slug": "fadedelay", - "name": "fadedelay", - "description": "", - "tags": [] - }, - { - "slug": "vca", - "name": "vca", - "description": "", - "tags": [] - } diff --git a/vcv/res/12hptemplate.svg b/vcv/res/12hptemplate.svg deleted file mode 100644 index 371cbc8af..000000000 --- a/vcv/res/12hptemplate.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/vcv/res/16hptemplate.svg b/vcv/res/16hptemplate.svg deleted file mode 100644 index 8f7c5b715..000000000 --- a/vcv/res/16hptemplate.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/vcv/res/4hptemplate.svg b/vcv/res/4hptemplate.svg deleted file mode 100644 index d93520f0a..000000000 --- a/vcv/res/4hptemplate.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/vcv/res/8hptemplate.svg b/vcv/res/8hptemplate.svg deleted file mode 100644 index 38b74b8be..000000000 --- a/vcv/res/8hptemplate.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/vcv/res/meta-module-medium-p8.svg b/vcv/res/meta-module-medium-p8.svg deleted file mode 100644 index 330a3adfe..000000000 --- a/vcv/res/meta-module-medium-p8.svg +++ /dev/null @@ -1,381 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vcv/res/meta-module-medium.svg b/vcv/res/meta-module-medium.svg deleted file mode 100644 index d4a475ba0..000000000 --- a/vcv/res/meta-module-medium.svg +++ /dev/null @@ -1,360 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vcv/res/meta-module-mini.svg b/vcv/res/meta-module-mini.svg deleted file mode 100644 index 2e8d5107f..000000000 --- a/vcv/res/meta-module-mini.svg +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -