diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b088f28f4d4a6a8cd810433089afa1c1a8686d9c..fe3796b257422291f987f66aab73530f5daa60d3 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -35,25 +35,16 @@ jobs:
     runs-on: ${{ matrix.os }}
     steps:
     - uses: actions/checkout@v3
-    - name: Cache pip
-      uses: actions/cache@v3
+    - uses: actions/cache@v3
       with:
-        path: ~/.cache/pip
-        key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
-        restore-keys: |
-          ${{ runner.os }}-pip-
-    - name: Cache PlatformIO
-      uses: actions/cache@v3
+        path: |
+          ~/.cache/pip
+          ~/.platformio/.cache
+        key: ${{ runner.os }}-pio
+    - uses: actions/setup-python@v4
       with:
-        path: ~/.platformio
-        key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
-    - name: Set up Python
-      uses: actions/setup-python@v4
-      with:
-        python-version: "3.9"
-    - name: Install PlatformIO
-      run: |
-        python -m pip install --upgrade pip
-        pip install --upgrade platformio
-    - name: Run PlatformIO
-      run: pio run
+        python-version: '3.9'
+    - name: Install PlatformIO Core
+      run: pip install --upgrade platformio
+    - name: Build PlatformIO Project
+      run: pio run
\ No newline at end of file
diff --git a/.github/workflows/minichlink.yml b/.github/workflows/minichlink.yml
new file mode 100644
index 0000000000000000000000000000000000000000..517382fe584f8cc7c3385e2e08762c0226eb1636
--- /dev/null
+++ b/.github/workflows/minichlink.yml
@@ -0,0 +1,69 @@
+name: Build minichlink
+
+on: [push, pull_request]
+#    push:
+#        paths:
+#            - minichlink/**
+#    pull_request:
+#        paths:
+#            - minichlink/**
+jobs:
+  build-minichlink:
+    strategy:
+        fail-fast: false
+        matrix:
+            os: [ubuntu-latest, macos-12, macos-11]
+    runs-on: ${{matrix.os}}
+    steps:
+    - uses: actions/checkout@v3
+    - name: Install Dependencies (Linux)
+      if: ${{ matrix.os == 'ubuntu-latest' }}
+      run: sudo apt-get update && sudo apt-get install -y build-essential make libusb-1.0-0-dev libudev-dev mingw-w64-x86-64-dev gcc-mingw-w64-x86-64
+    # we don't need to brew install libusb on Mac, actually preinstalled on the runner! :)
+    - name: Build (Linux, Mac)
+      run: |
+       cd minichlink
+       make clean
+       make V=1 -j3
+    # we cross-compile the Windows binaries from Linux 
+    - name: Build (for Windows)
+      if: ${{ matrix.os == 'ubuntu-latest' }}
+      run: |
+        cd minichlink
+        OS=Windows_NT make clean
+        OS=Windows_NT make V=1 -j3 minichlink.exe
+
+    - name: "Pack (Linux)"
+      if: ${{ matrix.os == 'ubuntu-latest' }}
+      run: tar czf minichlink.tar.gz -C minichlink minichlink minichlink.so 99-minichlink.rules
+    - name: "Pack (Mac)"
+      if: ${{ matrix.os == 'macos-12' || matrix.os == 'macos-11' }}
+      run: tar czf minichlink.tar.gz -C minichlink minichlink
+    # no packing needed for Windows as it's .exe only
+
+    - name: "Upload minichlink (Linux)"
+      if: ${{ matrix.os == 'ubuntu-latest' }}
+      uses: actions/upload-artifact@v3
+      with:
+        name: minichlink (Linux)
+        path: minichlink.tar.gz
+    - name: "Upload minichlink (MacOs 11)"
+      if: ${{ matrix.os == 'macos-11' }}
+      uses: actions/upload-artifact@v3
+      with:
+        name: minichlink (MacOS 11)
+        path: minichlink.tar.gz  
+    - name: "Upload minichlink (MacOs 12)"
+      if: ${{ matrix.os == 'macos-12' }}
+      uses: actions/upload-artifact@v3
+      with:
+        name: minichlink (MacOS 12)
+        path: minichlink.tar.gz  
+    - name: "Upload minichlink (Windows)"
+      if: ${{ matrix.os == 'ubuntu-latest' }}
+      uses: actions/upload-artifact@v3
+      with:
+        name: minichlink (Windows)
+        path: | 
+          minichlink/minichlink.exe
+          minichlink/libusb-1.0.dll
diff --git a/.gitignore b/.gitignore
index b56264024e9f393f86ba06d2418e24078af823ac..f79293a9c0b686f0cb5fcd5f5760dfcea671c309 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 .pio
 .vscode
+.idea
 *.elf
 *.hex
 *.lst
@@ -7,3 +8,6 @@
 *.map
 minichlink/minichlink
 minichlink/minichlink.so
+compile_commands.json
+.clangd
+.cache
diff --git a/README.md b/README.md
index 59599c9385d8b74709a27d39525e522ffdfe8512..0b66a4cbdc0013a89bf11c8b607de4e762c0fca1 100644
--- a/README.md
+++ b/README.md
@@ -10,23 +10,21 @@ ch32v003fun contains:
   * An STM32F042 Programmer, the NHC-Link042
   * An ESP32S2 Programmer, the [esp32s2-funprog](https://github.com/cnlohr/esp32s2-cookbook/tree/master/ch32v003programmer)
   * The official WCH Link-E Programmer.
+  * Supports gdbserver-style-debugging for use with Visual Studio.
+  * Supports printf-over-single-wire. (At about 400kBaud)
 3. An extra copy of libgcc so you can use unusual risc-v build chains, located in the `misc/libgcc.a`.
 4. A folder named "ch32v003fun" containing a single self-contained source file and header file for compling apps for the ch32v003.
 5. On some systems ability to "printf" back through
 6. A demo bootloader.
 
 In Progress:
-1. Other programmer support (ESP32-S2 works, currently)
-2. OpenOCD-compatible build for `minichlink`.
-3. Full-chip-write for faster flash.
-4. Support for `NHC-Link042`
-5. Write more demos.
+1. Write more demos.
 
-## Features
+## Features!
 
-### A fast "printf" debug over the programming interface.
+###  A fast "printf" debug over the programming interface.
 
-And by fast I mean very fast. Typically around 36kBytes/sec. 
+And by fast I mean very fast. Typically around 36kBytes/sec.
 
 ```
 ./minichlink -T | pv > /dev/null
@@ -34,20 +32,18 @@ Found ESP32S2 Programmer
  536KiB 0:00:15 [36.7KiB/s] [        <=>                     ]
 ```
 
-You can just try out the `debugprintf` project, or call `SetupDebugPrintf();` and `printf()` away.
+You can just try out the debugprintf project, or call SetupDebugPrintf(); and printf() away.
 
-### todo;;
+### Debugging support!
 
+Via gdbserver built into minichlink!  It works with `gdb-multiarch` as well as in Visual Studio Code 
 
-## System Prep
-
-On WSL or Debian based OSes `apt-get install build-essential libnewlib-dev gcc-riscv64-unknown-elf libusb-1.0-0-dev libudev-dev`
+### TODO
 
-On Arch/Manjaro, `sudo pacman -S base-devel libusb`, then from AUR install `riscv64-unknown-elf-gcc, riscv64-unknown-elf-binutils, riscv64-unknown-elf-newlib` (will compile for a long time).
+## System Prep
 
-On Windows, download and install (to system) this copy of GCC10. https://gnutoolchains.com/risc-v/
+For installation instructions, see the [wiki page here](https://github.com/cnlohr/ch32v003fun/wiki/Installation)
 
-On macOS install the RISC-V toolchain with homebrew following the instructions at https://github.com/riscv-software-src/homebrew-riscv
 
 You can use the pre-compiled minichlink or go to minichlink dir and `make` it.
 
@@ -112,15 +108,20 @@ To use the WCH-Link in WSL, it is required to "attach" the USB hardware on the W
 9. For unknown reasons, you must run make under root access in order to connect to the programmer with minichlink.  Recommend running `sudo make` when building and programming projects using WSL. This may work too (to be confirmed):
 
 ### non-root access on linux
-Unlike serial interfaces, by default, the USB device is owned by root, has group set to root and everyone else may only read.
-1. Get the vendor:device ID of the WCH-Link from `lsusb`.
-2. Create a udev rule with `sudo nano /etc/udev/rules.d/80-USB_WCH-Link.rules`, paste (CTRL+SHIFT+V) `SUBSYSTEM=="usb", ATTR{idVendor}=="1a86", ATTR{idProduct}=="8010", MODE="0666"` and save, replacing the idVendor and idProduct if what you got previously was different.
-3. Reboot or reload the udev rules with `sudo udevadm control --reload-rules && sudo udevadm trigger` 
-4. ???
-5. profit
-Now anyone on your PC has access to the WCH-Link device, so you can stop using sudo for make.  
-I don't think there are any security risks here.
-You may also tie this to the WCH-Link serial number or some other attribute from `udevadm info -a -n /dev/bus/usb/busid/deviceid` with the bus id and device id you got from lsusb earlier.
+Unlike serial interfaces, by default, the USB device is owned by root, has group set to root and everyone else may only read by default.
+The way to allow non-root users/groups to be able to access devices is via udev rules.
+
+minichlink provides a list of udev rules that allows any user in the plugdev group to be able to interact with the programmers it supports.
+
+You can install and load the required udev rules for minichlink by executing the following commands in the root of this Git repository:
+```
+sudo cp minichlink/99-minichlink.rules /etc/udev/rules.d/
+sudo udevadm control --reload-rules && sudo udevadm trigger
+```
+
+If you add support for another programmer in minichlink, you will need to add more rules here.
+
+**Note:** This readme used to recommend manually making these rules under `80-USB_WCH-Link.rules`. If you wish to use the new rules file shipped in this repo, you may want to remove the old rules file.
 
 
 ## minichlink
@@ -139,6 +140,12 @@ This project can also be built, uploaded and debugged with VSCode and the Platfo
 
 See [here](https://github.com/Community-PIO-CH32V/platform-ch32v) for further details.
 
+## clangd
+
+If the C/C++ language server clangd is unable to find `ch32v003fun.h`, the example will have to be wiped `make clean` and built once with `bear -- make build`, which will generate a `compile_commands.json`, which clangd uses to find the include paths specified in the makefiles.  
+`make clangd` does this in one step.
+`build_all_clangd.sh` does in `build scripts` does this for all examples.
+
 ## Quick Reference
  * Needed for programming/debugging: `SWIO` is on `PD1`
  * Optional (not needed, can be configured as output if fuse set): `NRST` is on `PD7`
@@ -154,3 +161,5 @@ You can open a github ticket or join my Discord in the #ch32v003fun channel. htt
  * http://www.wch-ic.com/downloads/QingKeV2_Processor_Manual_PDF.html Processor Manual
  * http://www.wch-ic.com/downloads/CH32V003RM_PDF.html Technical Reference Manual
  * http://www.wch-ic.com/downloads/CH32V003DS0_PDF.html Datasheet
+ * https://github.com/CaiB/CH32V003-Architecture-Exploration/blob/main/InstructionTypes.md Details for the compressed ISA on this chip.
+ * The CH32V003 has xv extensions, you can use this customized version of rvcodec.js to work with its opcodes: https://xw.macyler.moe/
diff --git a/NHC-Link042/LibUSB/LibUSB.c b/attic/NHC-Link042/LibUSB/LibUSB.c
similarity index 100%
rename from NHC-Link042/LibUSB/LibUSB.c
rename to attic/NHC-Link042/LibUSB/LibUSB.c
diff --git a/NHC-Link042/LibUSB/LibUSB.h b/attic/NHC-Link042/LibUSB/LibUSB.h
similarity index 100%
rename from NHC-Link042/LibUSB/LibUSB.h
rename to attic/NHC-Link042/LibUSB/LibUSB.h
diff --git a/NHC-Link042/NHC-Link042.uvprojx b/attic/NHC-Link042/NHC-Link042.uvprojx
similarity index 100%
rename from NHC-Link042/NHC-Link042.uvprojx
rename to attic/NHC-Link042/NHC-Link042.uvprojx
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Release_Notes.html b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Release_Notes.html
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Release_Notes.html
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Release_Notes.html
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f030.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f030.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f030.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f030.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f031.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f031.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f031.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f031.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f042.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f042.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f042.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f042.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f051.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f051.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f051.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f051.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f072.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f072.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f072.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f072.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f0xx.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f0xx.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f0xx.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f0xx.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f0xx_ld.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f0xx_ld.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f0xx_ld.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f0xx_ld.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f030.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f030.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f030.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f030.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f031.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f031.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f031.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f031.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f042.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f042.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f042.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f042.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f051.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f051.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f051.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f051.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f072.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f072.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f072.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f072.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f0xx.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f0xx.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f0xx.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f0xx.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f0xx_ld.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f0xx_ld.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f0xx_ld.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/arm/startup_stm32f0xx_ld.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f030.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f030.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f030.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f030.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f031.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f031.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f031.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f031.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f042.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f042.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f042.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f042.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f051.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f051.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f051.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f051.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f072.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f072.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f072.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f072.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f0xx.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f0xx.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f0xx.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc_ride7/startup_stm32f0xx.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f030.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f030.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f030.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f030.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f031.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f031.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f031.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f031.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f042.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f042.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f042.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f042.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f051.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f051.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f051.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f051.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f072.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f072.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f072.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f072.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f0xx.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f0xx.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f0xx.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f0xx.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f0xx_ld.s b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f0xx_ld.s
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f0xx_ld.s
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/iar/startup_stm32f0xx_ld.s
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_common_tables.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_common_tables.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_common_tables.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_common_tables.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_const_structs.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_const_structs.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_const_structs.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_const_structs.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_math.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_math.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_math.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/arm_math.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm0.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm0.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm0.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm0.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm0plus.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm0plus.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm0plus.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm0plus.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm3.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm3.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm3.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm3.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm4.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm4.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm4.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm4.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm4_simd.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm4_simd.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm4_simd.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cm4_simd.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cmFunc.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cmFunc.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cmFunc.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cmFunc.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cmInstr.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cmInstr.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cmInstr.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_cmInstr.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_sc000.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_sc000.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_sc000.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_sc000.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_sc300.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_sc300.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_sc300.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/CMSIS/Include/core_sc300.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_adc.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_adc.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_adc.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_adc.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_can.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_can.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_can.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_can.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_cec.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_cec.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_cec.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_cec.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_comp.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_comp.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_comp.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_comp.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_crc.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_crc.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_crc.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_crc.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_crs.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_crs.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_crs.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_crs.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dac.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dac.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dac.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dac.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dbgmcu.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dbgmcu.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dbgmcu.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dbgmcu.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dma.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dma.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dma.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_dma.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_exti.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_exti.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_exti.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_exti.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_flash.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_flash.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_flash.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_flash.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_gpio.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_gpio.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_gpio.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_gpio.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_i2c.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_i2c.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_i2c.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_i2c.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_iwdg.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_iwdg.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_iwdg.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_iwdg.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_misc.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_misc.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_misc.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_misc.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_pwr.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_pwr.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_pwr.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_pwr.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_rcc.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_rcc.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_rcc.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_rcc.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_rtc.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_rtc.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_rtc.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_rtc.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_spi.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_spi.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_spi.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_spi.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_syscfg.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_syscfg.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_syscfg.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_syscfg.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_tim.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_tim.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_tim.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_tim.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_usart.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_usart.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_usart.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_usart.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_wwdg.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_wwdg.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_wwdg.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/inc/stm32f0xx_wwdg.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_adc.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_adc.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_adc.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_adc.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_can.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_can.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_can.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_can.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_cec.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_cec.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_cec.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_cec.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_comp.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_comp.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_comp.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_comp.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_crc.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_crc.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_crc.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_crc.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_crs.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_crs.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_crs.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_crs.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dac.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dac.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dac.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dac.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dbgmcu.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dbgmcu.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dbgmcu.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dbgmcu.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dma.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dma.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dma.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dma.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_exti.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_exti.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_exti.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_exti.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_flash.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_flash.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_flash.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_flash.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_gpio.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_gpio.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_gpio.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_gpio.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_i2c.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_i2c.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_i2c.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_i2c.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_iwdg.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_iwdg.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_iwdg.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_iwdg.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_misc.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_misc.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_misc.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_misc.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_pwr.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_pwr.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_pwr.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_pwr.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_rcc.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_rcc.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_rcc.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_rcc.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_rtc.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_rtc.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_rtc.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_rtc.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_spi.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_spi.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_spi.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_spi.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_tim.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_tim.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_tim.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_tim.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_wwdg.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_wwdg.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_wwdg.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_wwdg.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_bsp.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_bsp.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_bsp.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_bsp.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_conf_template.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_conf_template.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_conf_template.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_conf_template.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_core.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_core.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_core.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_core.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_dcd.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_dcd.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_dcd.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_dcd.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_dcd_int.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_dcd_int.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_dcd_int.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_dcd_int.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_regs.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_regs.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_regs.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/inc/usb_regs.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_bsp_template.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_bsp_template.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_bsp_template.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_bsp_template.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_core.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_core.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_core.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_core.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_dcd.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_dcd.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_dcd.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_dcd.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_dcd_int.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_dcd_int.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_dcd_int.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Driver/src/usb_dcd_int.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_cmd.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_cmd.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_cmd.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_cmd.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_core.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_core.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_core.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_core.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_if.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_if.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_if.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/inc/usbd_ccid_if.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_cmd.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_cmd.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_cmd.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_cmd.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_core.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_core.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_core.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_core.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_if.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_if.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_if.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/ccid/src/usbd_ccid_if.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_custom_hid_core.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_custom_hid_core.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_custom_hid_core.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_custom_hid_core.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/src/usbd_custom_hid_core.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/src/usbd_custom_hid_core.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/src/usbd_custom_hid_core.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/src/usbd_custom_hid_core.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_cdc_wrapper/inc/usbd_hid_cdc_wrapper.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_cdc_wrapper/inc/usbd_hid_cdc_wrapper.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_cdc_wrapper/inc/usbd_hid_cdc_wrapper.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_cdc_wrapper/inc/usbd_hid_cdc_wrapper.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_cdc_wrapper/src/usbd_hid_cdc_wrapper.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_cdc_wrapper/src/usbd_hid_cdc_wrapper.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_cdc_wrapper/src/usbd_hid_cdc_wrapper.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_cdc_wrapper/src/usbd_hid_cdc_wrapper.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_msc_wrapper/inc/usbd_hid_msc_wrapper.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_msc_wrapper/inc/usbd_hid_msc_wrapper.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_msc_wrapper/inc/usbd_hid_msc_wrapper.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_msc_wrapper/inc/usbd_hid_msc_wrapper.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_msc_wrapper/src/usbd_hid_msc_wrapper.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_msc_wrapper/src/usbd_hid_msc_wrapper.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_msc_wrapper/src/usbd_hid_msc_wrapper.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/hid_msc_wrapper/src/usbd_hid_msc_wrapper.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_core.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_core.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_core.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_core.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_pwr.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_pwr.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_pwr.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_pwr.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_usr.h b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_usr.h
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_usr.h
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_usr.h
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_core.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_core.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_core.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_core.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_ioreq.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_ioreq.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_ioreq.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_ioreq.c
diff --git a/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_req.c b/attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_req.c
similarity index 100%
rename from NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_req.c
rename to attic/NHC-Link042/STM32F0x2_USB-FS-Device_Lib V1.0.0/Libraries/STM32_USB_Device_Library/Core/src/usbd_req.c
diff --git a/NHC-Link042/User/NHC_WCH_SDI.c b/attic/NHC-Link042/User/NHC_WCH_SDI.c
similarity index 100%
rename from NHC-Link042/User/NHC_WCH_SDI.c
rename to attic/NHC-Link042/User/NHC_WCH_SDI.c
diff --git a/NHC-Link042/User/NHC_WCH_SDI.h b/attic/NHC-Link042/User/NHC_WCH_SDI.h
similarity index 100%
rename from NHC-Link042/User/NHC_WCH_SDI.h
rename to attic/NHC-Link042/User/NHC_WCH_SDI.h
diff --git a/NHC-Link042/User/config.h b/attic/NHC-Link042/User/config.h
similarity index 100%
rename from NHC-Link042/User/config.h
rename to attic/NHC-Link042/User/config.h
diff --git a/NHC-Link042/User/it.c b/attic/NHC-Link042/User/it.c
similarity index 100%
rename from NHC-Link042/User/it.c
rename to attic/NHC-Link042/User/it.c
diff --git a/NHC-Link042/User/main.c b/attic/NHC-Link042/User/main.c
similarity index 100%
rename from NHC-Link042/User/main.c
rename to attic/NHC-Link042/User/main.c
diff --git a/NHC-Link042/User/stm32_it.c b/attic/NHC-Link042/User/stm32_it.c
similarity index 100%
rename from NHC-Link042/User/stm32_it.c
rename to attic/NHC-Link042/User/stm32_it.c
diff --git a/NHC-Link042/User/stm32_it.h b/attic/NHC-Link042/User/stm32_it.h
similarity index 100%
rename from NHC-Link042/User/stm32_it.h
rename to attic/NHC-Link042/User/stm32_it.h
diff --git a/NHC-Link042/User/stm32f0xx_conf.h b/attic/NHC-Link042/User/stm32f0xx_conf.h
similarity index 100%
rename from NHC-Link042/User/stm32f0xx_conf.h
rename to attic/NHC-Link042/User/stm32f0xx_conf.h
diff --git a/NHC-Link042/User/system_stm32f0xx.c b/attic/NHC-Link042/User/system_stm32f0xx.c
similarity index 100%
rename from NHC-Link042/User/system_stm32f0xx.c
rename to attic/NHC-Link042/User/system_stm32f0xx.c
diff --git a/NHC-Link042/User/usb_bsp.c b/attic/NHC-Link042/User/usb_bsp.c
similarity index 100%
rename from NHC-Link042/User/usb_bsp.c
rename to attic/NHC-Link042/User/usb_bsp.c
diff --git a/NHC-Link042/User/usb_conf.h b/attic/NHC-Link042/User/usb_conf.h
similarity index 100%
rename from NHC-Link042/User/usb_conf.h
rename to attic/NHC-Link042/User/usb_conf.h
diff --git a/NHC-Link042/User/usbd_conf.h b/attic/NHC-Link042/User/usbd_conf.h
similarity index 100%
rename from NHC-Link042/User/usbd_conf.h
rename to attic/NHC-Link042/User/usbd_conf.h
diff --git a/NHC-Link042/User/usbd_desc.c b/attic/NHC-Link042/User/usbd_desc.c
similarity index 100%
rename from NHC-Link042/User/usbd_desc.c
rename to attic/NHC-Link042/User/usbd_desc.c
diff --git a/NHC-Link042/User/usbd_desc.h b/attic/NHC-Link042/User/usbd_desc.h
similarity index 100%
rename from NHC-Link042/User/usbd_desc.h
rename to attic/NHC-Link042/User/usbd_desc.h
diff --git a/NHC-Link042/User/usbd_pwr.c b/attic/NHC-Link042/User/usbd_pwr.c
similarity index 100%
rename from NHC-Link042/User/usbd_pwr.c
rename to attic/NHC-Link042/User/usbd_pwr.c
diff --git a/NHC-Link042/User/usbd_usr.c b/attic/NHC-Link042/User/usbd_usr.c
similarity index 100%
rename from NHC-Link042/User/usbd_usr.c
rename to attic/NHC-Link042/User/usbd_usr.c
diff --git a/build_scripts/README.md b/build_scripts/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c3da4c4607d8dc3d8b215f49dd53b2d6f41005bc
--- /dev/null
+++ b/build_scripts/README.md
@@ -0,0 +1,3 @@
+Scripts serve to build / clean all examples at once.  
+
+`build_all_clangd.sh` uses bear to additionally generate a `compile_commands.yaml` for each example so the C/C++ language server clangd can be aware of the paths in the makefiles.
diff --git a/examples/build_all.cmd b/build_scripts/build_all.cmd
similarity index 75%
rename from examples/build_all.cmd
rename to build_scripts/build_all.cmd
index aa685db2007d798187a916c262ec93c5c999a263..8621190973cef4bdba3811fb6691f3c61f1ae92e 100644
--- a/examples/build_all.cmd
+++ b/build_scripts/build_all.cmd
@@ -4,4 +4,8 @@ setlocal
 set TARGET=%1
 if [%1]==[] set TARGET=build
 
+cd ..\examples
+
 for /d %%i in (*) do make --directory=%%i %TARGET%
+
+cd ..\build_scripts
diff --git a/build_scripts/build_all.sh b/build_scripts/build_all.sh
new file mode 100755
index 0000000000000000000000000000000000000000..982db503b6d59774ea085eddff9ff6d947fd1797
--- /dev/null
+++ b/build_scripts/build_all.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+echo "this will build all examples"
+sleep 2
+
+cd ../examples
+
+for dir in */; do
+	if [ -f "${dir}Makefile" ]; then
+		echo "running 'make build' in ${dir}"
+		(cd "${dir}" && make build)
+	else
+		echo "no Makefile in ${dir}"
+	fi
+done
+
+cd ../build_scripts
diff --git a/build_scripts/build_all_clangd.sh b/build_scripts/build_all_clangd.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1331381f4dcac697583183f0267819275e799f90
--- /dev/null
+++ b/build_scripts/build_all_clangd.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+echo "this will build all examples with 'bear' to generate 'compile_commands.json'"
+echo "'clangd' relies on these files to find the include paths"
+sleep 2
+
+cd ../examples
+
+if ! command -v bear --help &> /dev/null
+then
+	echo "'bear' could not be found"
+	echo "please install it from your package manager"
+	exit
+fi
+
+for dir in */; do
+	if [ -f "${dir}Makefile" ]; then
+		echo "running 'bear -- make' in ${dir}"
+		(cd "${dir}" && make clean && make clangd_clean && make clangd)
+	else
+		echo "no Makefile in ${dir}"
+	fi
+done
+
+cd ../build_scripts
diff --git a/build_scripts/clean_all.sh b/build_scripts/clean_all.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d0bd5a72949e3605e3560ff76ea46bcf0ca184f9
--- /dev/null
+++ b/build_scripts/clean_all.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+echo "this will clean all examples"
+sleep 2
+
+cd ../examples
+
+for dir in */; do
+	if [ -f "${dir}Makefile" ]; then
+		echo "running 'make clean' in ${dir}"
+		(cd "${dir}" && make clean)
+	else
+		echo "no Makefile in ${dir}"
+	fi
+done
+
+cd ../build_scripts
diff --git a/build_scripts/clean_all_clangd.sh b/build_scripts/clean_all_clangd.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4a507edad6a91c68997f29cff85181127fabad73
--- /dev/null
+++ b/build_scripts/clean_all_clangd.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+echo "this will clean all examples and their 'compile_commands.json'"
+echo "'clangd' relies on these files to find the include paths"
+sleep 2
+
+cd ../examples
+
+for dir in */; do
+	if [ -f "${dir}Makefile" ]; then
+		echo "running 'make clean' and 'make clangd_clean' in ${dir}"
+		(cd "${dir}" && make clean && make clangd_clean)
+	else
+		echo "no Makefile in ${dir}"
+	fi
+done
+
+cd ../build_scripts
diff --git a/ch32v003fun/ch32v003fun.c b/ch32v003fun/ch32v003fun.c
index 056f3cddb529d41ed8d86ad9cfc01d3c7542e1c8..6e6e60d4cd857cfa262c115b104370d6eef845c1 100644
--- a/ch32v003fun/ch32v003fun.c
+++ b/ch32v003fun/ch32v003fun.c
@@ -660,6 +660,10 @@ mini_pprintf(int (*puts)(char*s, int len, void* buf), void* buf, const char *fmt
 	Copyright 2023 Charles Lohr, under the MIT-x11 or NewBSD licenses, you choose.
 */
 
+#ifdef CPLUSPLUS
+// Method to call the C++ constructors
+void __libc_init_array(void);
+#endif
 
 int main() __attribute__((used));
 void SystemInit( void ) __attribute__((used));
@@ -716,6 +720,7 @@ void InterruptVectorDefault()
 {
 	asm volatile( "\n\
 	.align  2\n\
+	.option   push;\n\
 	.option   norvc;\n\
 	j handle_reset\n\
 	.word   0\n\
@@ -756,7 +761,8 @@ void InterruptVectorDefault()
 	.word   TIM1_UP_IRQHandler        /* TIM1 Update */                    \n\
 	.word   TIM1_TRG_COM_IRQHandler   /* TIM1 Trigger and Commutation */   \n\
 	.word   TIM1_CC_IRQHandler        /* TIM1 Capture Compare */           \n\
-	.word   TIM2_IRQHandler           /* TIM2 */                           \n");
+	.word   TIM2_IRQHandler           /* TIM2 */                           \n\
+	.option   pop;\n");
 }
 
 void handle_reset()
@@ -774,10 +780,10 @@ void handle_reset()
 "	li a0, 0x80\n\
 	csrw mstatus, a0\n\
 	li a3, 0x3\n\
-	csrw 0x804, a3\n\
 	la a0, InterruptVector\n\
 	or a0, a0, a3\n\
-	csrw mtvec, a0\n" );
+	csrw mtvec, a0\n" 
+	: : : "a0", "a3", "memory");
 
 	// Careful: Use registers to prevent overwriting of self-data.
 	// This clears out BSS.
@@ -800,7 +806,16 @@ asm volatile(
 	addi a0, a0, 4\n\
 	addi a1, a1, 4\n\
 	bne a1, a2, 1b\n\
-2:\n" );
+2:\n"
+#ifdef CPLUSPLUS
+	// Call __libc_init_array function
+"	call %0 \n\t"
+: : "i" (__libc_init_array)
+#else
+: :
+#endif
+: "a0", "a1", "a2", "a3", "memory"
+);
 
 	SETUP_SYSTICK_HCLK
 
@@ -973,3 +988,29 @@ void DelaySysTick( uint32_t n )
 	while( ((int32_t)( SysTick->CNT - targend )) < 0 );
 }
 
+// C++ Support
+
+#ifdef CPLUSPLUS
+// This is required to allow pure virtual functions to be defined.
+extern void __cxa_pure_virtual() { while (1); }
+
+// These magic symbols are provided by the linker.
+extern void (*__preinit_array_start[]) (void) __attribute__((weak));
+extern void (*__preinit_array_end[]) (void) __attribute__((weak));
+extern void (*__init_array_start[]) (void) __attribute__((weak));
+extern void (*__init_array_end[]) (void) __attribute__((weak));
+
+void __libc_init_array(void)
+{
+	size_t count;
+	size_t i;
+
+	count = __preinit_array_end - __preinit_array_start;
+	for (i = 0; i < count; i++)
+		__preinit_array_start[i]();
+
+	count = __init_array_end - __init_array_start;
+	for (i = 0; i < count; i++)
+		__init_array_start[i]();
+}
+#endif
diff --git a/ch32v003fun/ch32v003fun.h b/ch32v003fun/ch32v003fun.h
index 8a47047cd84b5e5072b89df6c89112c09e5b802f..1634bcb8e1d59b10b564fba9e94370168f4dddee 100644
--- a/ch32v003fun/ch32v003fun.h
+++ b/ch32v003fun/ch32v003fun.h
@@ -60,7 +60,7 @@ extern "C" {
     #define HSITRIM 0x10
 #endif
 
-#ifndef ASSEMBLER
+#ifndef __ASSEMBLER__
 
 /* Interrupt Number Definition, according to the selected device */
 typedef enum IRQn
@@ -108,7 +108,7 @@ typedef enum IRQn
 #define HSE_Value             HSE_VALUE
 #define HSEStartUp_TimeOut    HSE_STARTUP_TIMEOUT
 
-#ifndef ASSEMBLER
+#ifndef __ASSEMBLER__
 /* Analog to Digital Converter */
 typedef struct
 {
@@ -196,17 +196,133 @@ typedef struct
 } OB_TypeDef;
 
 /* General Purpose I/O */
+typedef enum
+{
+	GPIO_CFGLR_IN_ANALOG = 0,
+	GPIO_CFGLR_IN_FLOAT = 4,
+	GPIO_CFGLR_IN_PUPD = 8,
+	GPIO_CFGLR_OUT_10Mhz_PP = 1,
+	GPIO_CFGLR_OUT_2Mhz_PP = 2,
+	GPIO_CFGLR_OUT_50Mhz_PP = 3,
+	GPIO_CFGLR_OUT_10Mhz_OD = 5,
+	GPIO_CFGLR_OUT_2Mhz_OD = 6,
+	GPIO_CFGLR_OUT_50Mhz_OD = 7,
+	GPIO_CFGLR_OUT_10Mhz_AF_PP = 9,
+	GPIO_CFGLR_OUT_2Mhz_AF_PP = 10,
+	GPIO_CFGLR_OUT_50Mhz_AF_PP = 11,
+	GPIO_CFGLR_OUT_10Mhz_AF_OD = 13,
+	GPIO_CFGLR_OUT_2Mhz_AF_OD = 14,
+	GPIO_CFGLR_OUT_50Mhz_AF_OD = 15,
+} GPIO_CFGLR_PIN_MODE_Typedef;
+
+typedef union {
+	uint32_t __FULL;
+	struct {
+		GPIO_CFGLR_PIN_MODE_Typedef PIN0 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN1 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN2 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN3 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN4 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN5 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN6 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN7 :4;
+	};
+} GPIO_CFGLR_t;
+typedef union {
+	uint32_t __FULL;
+	const struct {
+		uint32_t IDR0 :1;
+		uint32_t IDR1 :1;
+		uint32_t IDR2 :1;
+		uint32_t IDR3 :1;
+		uint32_t IDR4 :1;
+		uint32_t IDR5 :1;
+		uint32_t IDR6 :1;
+		uint32_t IDR7 :1;
+		uint32_t :24;
+	};
+} GPIO_INDR_t;
+typedef union {
+	uint32_t __FULL;
+	struct {
+		uint32_t ODR0 :1;
+		uint32_t ODR1 :1;
+		uint32_t ODR2 :1;
+		uint32_t ODR3 :1;
+		uint32_t ODR4 :1;
+		uint32_t ODR5 :1;
+		uint32_t ODR6 :1;
+		uint32_t ODR7 :1;
+		uint32_t :24;
+	};
+} GPIO_OUTDR_t;
+typedef union {
+	uint32_t __FULL;
+	struct {
+		uint32_t BS0 :1;
+		uint32_t BS1 :1;
+		uint32_t BS2 :1;
+		uint32_t BS3 :1;
+		uint32_t BS4 :1;
+		uint32_t BS5 :1;
+		uint32_t BS6 :1;
+		uint32_t BS7 :1;
+		uint32_t :8;
+		uint32_t BR0 :1;
+		uint32_t BR1 :1;
+		uint32_t BR2 :1;
+		uint32_t BR3 :1;
+		uint32_t BR4 :1;
+		uint32_t BR5 :1;
+		uint32_t BR6 :1;
+		uint32_t BR7 :1;
+		uint32_t :8;
+	};
+} GPIO_BSHR_t;
+typedef union {
+	uint32_t __FULL;
+	struct {
+		uint32_t BR0 :1;
+		uint32_t BR1 :1;
+		uint32_t BR2 :1;
+		uint32_t BR3 :1;
+		uint32_t BR4 :1;
+		uint32_t BR5 :1;
+		uint32_t BR6 :1;
+		uint32_t BR7 :1;
+		uint32_t :24;
+	};
+} GPIO_BCR_t;
+typedef union {
+	uint32_t __FULL;
+	struct {
+		uint32_t LCK0 :1;
+		uint32_t LCK1 :1;
+		uint32_t LCK2 :1;
+		uint32_t LCK3 :1;
+		uint32_t LCK4 :1;
+		uint32_t LCK5 :1;
+		uint32_t LCK6 :1;
+		uint32_t LCK7 :1;
+		uint32_t LCKK :1;
+		uint32_t :23;
+	};
+} GPIO_LCKR_t;
 typedef struct
 {
-    __IO uint32_t CFGLR;
-    __IO uint32_t CFGHR;
-    __IO uint32_t INDR;
-    __IO uint32_t OUTDR;
-    __IO uint32_t BSHR;
-    __IO uint32_t BCR;
-    __IO uint32_t LCKR;
+	__IO uint32_t CFGLR;
+	__IO uint32_t CFGHR;
+	__I  uint32_t INDR;
+	__IO uint32_t OUTDR;
+	__IO uint32_t BSHR;
+	__IO uint32_t BCR;
+	__IO uint32_t LCKR;
 } GPIO_TypeDef;
 
+#define DYN_GPIO_READ(gpio, field) ((GPIO_##field##_t) { .__FULL = gpio->field })
+#define DYN_GPIO_WRITE(gpio, field, ...) gpio->field = ((const GPIO_##field##_t) __VA_ARGS__).__FULL
+#define DYN_GPIO_MOD(gpio, field, reg, val) {GPIO_##field##_t tmp; tmp.__FULL = gpio->field; tmp.reg = val; gpio->field = tmp.__FULL;}
+
 /* Alternate Function I/O */
 typedef struct
 {
@@ -370,7 +486,7 @@ typedef struct
 #endif
 
 /* Peripheral memory map */
-#ifdef ASSEMBLER
+#ifdef __ASSEMBLER__
 #define FLASH_BASE                              (0x08000000) /* FLASH base address in the alias region */
 #define SRAM_BASE                               (0x20000000) /* SRAM base address in the alias region */
 #define PERIPH_BASE                             (0x40000000) /* Peripheral base address in the alias region */
@@ -2811,7 +2927,7 @@ extern "C" {
 /* BDCTLR register base address */
 #define BDCTLR_ADDRESS             (PERIPH_BASE + BDCTLR_OFFSET)
 
-#ifndef ASSEMBLER
+#ifndef __ASSEMBLER__
 static __I uint8_t APBAHBPrescTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8};
 static __I uint8_t ADCPrescTable[20] = {2, 4, 6, 8, 4, 8, 12, 16, 8, 16, 24, 32, 16, 32, 48, 64, 32, 64, 96, 128};
 #endif
@@ -3111,7 +3227,7 @@ static __I uint8_t ADCPrescTable[20] = {2, 4, 6, 8, 4, 8, 12, 16, 8, 16, 24, 32,
 
 /* ch32v00x_exti.h -----------------------------------------------------------*/
 
-#ifndef ASSEMBLER
+#ifndef __ASSEMBLER__
 
 /* EXTI mode enumeration */
 typedef enum
@@ -3146,7 +3262,7 @@ typedef enum
 /* ch32v00x_flash.h ----------------------------------------------------------*/
 
 
-#ifndef ASSEMBLER
+#ifndef __ASSEMBLER__
 /* FLASH Status */
 typedef enum
 {
@@ -3224,7 +3340,7 @@ typedef enum
 
 /* ch32v00x_gpio.h ------------------------------------------------------------*/
 
-#ifndef ASSEMBLER
+#ifndef __ASSEMBLER__
 
 /* Output Maximum frequency selection */
 typedef enum
@@ -3261,7 +3377,7 @@ typedef enum
 } GPIOMode_TypeDef;
 */
 
-#ifndef ASSEMBLER
+#ifndef __ASSEMBLER__
 
 /* Bit_SET and Bit_RESET enumeration */
 typedef enum
@@ -3594,7 +3710,7 @@ typedef enum
 /* ch32v00x_opa.h ------------------------------------------------------------*/
 
 /* Editor's note: I don't know if this is actually useful */
-#ifndef ASSEMBLER
+#ifndef __ASSEMBLER__
 
 /* OPA PSEL enumeration */
 typedef enum
@@ -4254,7 +4370,7 @@ typedef struct
  extern "C" {
 #endif
 	
-#ifndef ASSEMBLER
+#ifndef __ASSEMBLER__
 
 /* Standard Peripheral Library old types (maintained for legacy purpose) */
 typedef __I uint32_t vuc32;  /* Read Only */
@@ -4345,7 +4461,7 @@ typedef struct
 
 #define SysTick         ((SysTick_Type *) 0xE000F000)
 
-#ifndef ASSEMBLER
+#ifndef __ASSEMBLER__
 
 /*********************************************************************
  * @fn      __enable_irq
@@ -4358,7 +4474,11 @@ RV_STATIC_INLINE void __enable_irq()
 {
   uint32_t result;
 
-  __asm volatile("csrr %0," "mstatus": "=r"(result));
+    __asm volatile(
+#if __GNUC__ > 10
+		".option arch, +zicsr\n"
+#endif
+		"csrr %0," "mstatus": "=r"(result));
   result |= 0x88;
   __asm volatile ("csrw mstatus, %0" : : "r" (result) );
 }
@@ -4374,7 +4494,11 @@ RV_STATIC_INLINE void __disable_irq()
 {
   uint32_t result;
 
-  __asm volatile("csrr %0," "mstatus": "=r"(result));
+    __asm volatile(
+#if __GNUC__ > 10
+		".option arch, +zicsr\n"
+#endif
+		"csrr %0," "mstatus": "=r"(result));
   result &= ~0x88;
   __asm volatile ("csrw mstatus, %0" : : "r" (result) );
 }
@@ -4509,6 +4633,47 @@ RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority)
   NVIC->IPRIOR[(uint32_t)(IRQn)] = priority;
 }
 
+/*********************************************************************
+ * SUSPEND ALL INTERRUPTS EXCEPT
+ * The following 3 functions serve to suspend all interrupts, except for the one you momentarily need.
+ * The purpose of this is to not disturb the one interrupt of interest and let it run unimpeded.
+ * procedure:
+ * 1. save the enabled IRQs: uint32_t IRQ_backup = NVIC_get_enabled_IRQs();
+ * 2. disable all IRQs: NVIC_clear_all_IRQs_except(IRQ_of_interest);
+ * 3. restore the previously enabled IRQs: NVIC_restore_IRQs(IRQ_backup);
+ * 
+ * bit layout of the IRQ backup
+ * bit		0 | 1 | 2  |  3  | 4  |  5  | 6  .. 22 | 23 .. 28
+ * IRQn		2 | 3 | 12 | res | 14 | res | 16 .. 31 | 32 .. 38
+ * IRQn 2 and 3 aren't actually user-settable (see RM).
+ * 
+ * Specifying an invalid IRQn_to_keep like 0 will disable all interrupts.
+ */
+
+RV_STATIC_INLINE uint32_t NVIC_get_enabled_IRQs()
+{
+	return ( ((NVIC->ISR[0] >> 2) & 0b11) | ((NVIC->ISR[0] >> 12) << 2) | ((NVIC->ISR[1] & 0b1111111) << 23) );
+}
+
+RV_STATIC_INLINE void NVIC_clear_all_IRQs_except(uint8_t IRQn_to_keep)
+{
+	if (!(IRQn_to_keep >> 5)) {		// IRQn_to_keep < 32
+		NVIC->IRER[0] = (~0) & (~(1 << IRQn_to_keep));
+		NVIC->IRER[1] = (~0);
+	}
+	else {
+		IRQn_to_keep = IRQn_to_keep >> 5;
+		NVIC->IRER[0] = (~0);
+		NVIC->IRER[1] = (~0) & (~(1 << IRQn_to_keep));
+	}
+}
+
+RV_STATIC_INLINE void NVIC_restore_IRQs(uint32_t old_state)
+{
+	NVIC->IENR[0] = (old_state >> 2) << 12;
+	NVIC->IENR[1] = old_state >> 23;
+}
+
 /*********************************************************************
  * @fn       __WFI
  *
@@ -4842,9 +5007,11 @@ static inline uint32_t __get_SP(void)
 extern "C" {
 #endif
 
-// You can use SYSTICK_USE_HCLK, if you do, you will have a high-resolution
-// however it will limit your max delay to 44 seconds before it will wrap
-// around.  You must also call SETUP_SYSTICK_HCLK.
+/* SYSTICK info
+ * time on the ch32v003 is kept by the SysTick counter (32bit)
+ * by default, it will operate at (SYSTEM_CORE_CLOCK / 8) = 6MHz
+ * more info at https://github.com/cnlohr/ch32v003fun/wiki/Time
+*/
 
 #ifdef SYSTICK_USE_HCLK
 #define DELAY_US_TIME ((SYSTEM_CORE_CLOCK)/1000000)
@@ -4856,11 +5023,19 @@ extern "C" {
 #define SETUP_SYSTICK_HCLK SysTick->CTLR = 1;
 #endif
 
+#define Delay_Us(n) DelaySysTick( (n) * DELAY_US_TIME )
+#define Delay_Ms(n) DelaySysTick( (n) * DELAY_MS_TIME )
+
+#define Ticks_from_Us(n)	(n * DELAY_US_TIME)
+#define Ticks_from_Ms(n)	(n * DELAY_MS_TIME)
+
+
+
 #if defined(__riscv) || defined(__riscv__) || defined( CH32V003FUN_BASE )
 
 // Stuff that can only be compiled on device (not for the programmer, or other host programs)
 
-#ifndef ASSEMBLER
+#ifndef __ASSEMBLER__
 void handle_reset()            __attribute__((naked)) __attribute((section(".text.handle_reset"))) __attribute__((used));
 void DefaultIRQHandler( void ) __attribute__((section(".text.vector_handler"))) __attribute__((naked)) __attribute__((used));
 #endif
@@ -4871,10 +5046,9 @@ void DefaultIRQHandler( void ) __attribute__((section(".text.vector_handler")))
 
 #endif
 
-#define Delay_Us(n) DelaySysTick( (n) * DELAY_US_TIME )
-#define Delay_Ms(n) DelaySysTick( (n) * DELAY_MS_TIME )
 
-#ifndef ASSEMBLER
+
+#ifndef __ASSEMBLER__
 
 void DelaySysTick( uint32_t n );
 
diff --git a/ch32v003fun/ch32v003fun.mk b/ch32v003fun/ch32v003fun.mk
index 8d39c567534b7f7dc045a8ca3b72f069d749aa08..278b7361d74b728961d7fe4678ce8931aca58ee3 100644
--- a/ch32v003fun/ch32v003fun.mk
+++ b/ch32v003fun/ch32v003fun.mk
@@ -10,15 +10,20 @@ CFLAGS+= \
 	-march=rv32ec \
 	-mabi=ilp32e \
 	-I/usr/include/newlib \
+	-I$(CH32V003FUN)/../extralibs \
 	-I$(CH32V003FUN) \
 	-nostdlib \
-	-I. -Wall
+	-I. -Wall $(EXTRA_CFLAGS)
 
-LDFLAGS+=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections -L$(CH32V003FUN)/../misc -lgcc
+LINKER_SCRIPT?=$(CH32V003FUN)/ch32v003fun.ld
 
-SYSTEM_C:=$(CH32V003FUN)/ch32v003fun.c
+LDFLAGS+=-T $(LINKER_SCRIPT) -Wl,--gc-sections -L$(CH32V003FUN)/../misc -lgcc
 
-$(TARGET).elf : $(SYSTEM_C) $(TARGET).c $(ADDITIONAL_C_FILES)
+WRITE_SECTION?=flash
+SYSTEM_C?=$(CH32V003FUN)/ch32v003fun.c
+TARGET_EXT?=c
+
+$(TARGET).elf : $(SYSTEM_C) $(TARGET).$(TARGET_EXT) $(ADDITIONAL_C_FILES)
 	$(PREFIX)-gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)
 
 $(TARGET).bin : $(TARGET).elf
@@ -44,9 +49,21 @@ monitor :
 gdbserver : 
 	-$(MINICHLINK)/minichlink -baG
 
+clangd :
+	make clean
+	bear -- make build
+	@echo "CompileFlags:" > .clangd
+	@echo "  Remove: [-march=*, -mabi=*]" >> .clangd
+
+clangd_clean :
+	rm -f compile_commands.json .clangd
+	rm -rf .cache
+
+FLASH_COMMAND?=$(MINICHLINK)/minichlink -w $< $(WRITE_SECTION) -b
+
 cv_flash : $(TARGET).bin
 	make -C $(MINICHLINK) all
-	$(MINICHLINK)/minichlink -w $< flash -b
+	$(FLASH_COMMAND)
 
 cv_clean :
 	rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).lst $(TARGET).map $(TARGET).hex || true
diff --git a/ch32v003fun/xw_ext.inc b/ch32v003fun/xw_ext.inc
new file mode 100644
index 0000000000000000000000000000000000000000..ca210702fc69d9d31b87d9f69ddaf004c17e0b0c
--- /dev/null
+++ b/ch32v003fun/xw_ext.inc
@@ -0,0 +1,57 @@
+/*
+Encoder for some of the proprietary 'XW' RISC-V instructions present on the QingKe RV32 processor.
+Examples:
+	XW_C_LBU(a3, a1, 27); // c.xw.lbu a3, 27(a1)
+	XW_C_SB(a0, s0, 13);  // c.xw.sb a0, 13(s0)
+
+	XW_C_LHU(a5, a5, 38); // c.xw.lhu a5, 38(a5)
+	XW_C_SH(a2, s1, 14);  // c.xw.sh a2, 14(s1)
+*/
+
+// Let us do some compile-time error checking.
+#define ASM_ASSERT(COND) .if (!(COND)); .err; .endif
+
+// Integer encodings of the possible compressed registers.
+#define C_s0 0
+#define C_s1 1
+#define C_a0 2
+#define C_a1 3
+#define C_a2 4
+#define C_a3 5
+#define C_a4 6
+#define C_a5 7
+
+// register to encoding
+#define REG2I(X) (C_ ## X)
+
+// XW opcodes
+#define XW_OP_LBUSP 0b1000000000000000
+#define XW_OP_STSP  0b1000000001000000
+
+#define XW_OP_LHUSP 0b1000000000100000
+#define XW_OP_SHSP  0b1000000001100000
+
+#define XW_OP_LBU   0b0010000000000000
+#define XW_OP_SB    0b1010000000000000
+
+#define XW_OP_LHU   0b0010000000000010
+#define XW_OP_SH    0b1010000000000010
+
+// The two different XW encodings supported at the moment.
+#define XW_ENCODE1(OP, R1, R2, IMM) ASM_ASSERT((IMM) >= 0 && (IMM) < 32); .2byte ((OP) | (REG2I(R1) << 2) | (REG2I(R2) << 7) | \
+	(((IMM) & 0b1) << 12) | (((IMM) & 0b110) << (5 - 1)) | (((IMM) & 0b11000) << (10 - 3)))
+
+#define XW_ENCODE2(OP, R1, R2, IMM) ASM_ASSERT((IMM) >= 0 && (IMM) < 32); .2byte ((OP) | (REG2I(R1) << 2) | (REG2I(R2) << 7) | \
+	(((IMM) & 0b11) << 5) | (((IMM) & 0b11100) << (10 - 2))
+
+// Compressed load byte, zero-extend result
+#define XW_C_LBU(RD, RS, IMM) XW_ENCODE1(XW_OP_LBU, RD, RS, IMM)
+
+// Compressed store byte
+#define XW_C_SB(RS1, RS2, IMM) XW_ENCODE1(XW_OP_SB, RS1, RS2, IMM)
+
+// Compressed load half, zero-extend result
+#define XW_C_LHU(RD, RS, IMM) ASM_ASSERT(((IMM) & 1) == 0); XW_ENCODE2(XW_OP_LHU, RD, RS, ((IMM) >> 1)))
+
+// Compressed store half
+#define XW_C_SH(RS1, RS2, IMM)  ASM_ASSERT(((IMM) & 1) == 0); XW_ENCODE2(XW_OP_SH, RS1, RS2, ((IMM) >> 1)))
diff --git a/examples/GPIO/GPIO.c b/examples/GPIO/GPIO.c
index 148aa0198a1710d1b298fbf2f6c038201a90b6e6..a761850c339f8e445fc38585064b58a92c73a6ec 100644
--- a/examples/GPIO/GPIO.c
+++ b/examples/GPIO/GPIO.c
@@ -1,47 +1,199 @@
-// blink, but with arduino-like HAL
-// Could be defined here, or in the processor defines.
+// 2023-06-07 recallmenot
+
+#define DEMO_GPIO_blink					1
+#define DEMO_GPIO_out					0
+#define DEMO_GPIO_in_btn				0
+#define DEMO_ADC_bragraph				0
+#define DEMO_PWM_dayrider				0
+
+#if ((DEMO_GPIO_blink + DEMO_GPIO_out + DEMO_GPIO_in_btn + DEMO_ADC_bragraph + DEMO_PWM_dayrider) > 1 \
+  || (DEMO_GPIO_blink + DEMO_GPIO_out + DEMO_GPIO_in_btn + DEMO_ADC_bragraph + DEMO_PWM_dayrider) < 1)
+#error "please enable ONE of the demos by setting it to 1 and the others to 0"
+#endif
+
+
 #define SYSTEM_CORE_CLOCK 48000000
+#define APB_CLOCK SYSTEM_CORE_CLOCK
 
 #include "ch32v003fun.h"
-#include "wiring.h"
+
+#include "ch32v003_GPIO_branchless.h"
+
 #include <stdio.h>
 
-#define APB_CLOCK SYSTEM_CORE_CLOCK
 
-uint32_t count;
 
 int main() {
 	SystemInit48HSI();
 
-	// Enable GPIO ports
-	portEnable(port_C);
-	portEnable(port_D);
-
-	for (int i = pin_C0; i <= pin_C7; i++) {
-		pinMode(i, pinMode_O_pushPull);
+#if DEMO_GPIO_blink == 1
+	GPIO_portEnable(GPIO_port_C);
+	GPIO_portEnable(GPIO_port_D);
+	// GPIO D0 Push-Pull
+	GPIO_pinMode(GPIO_port_D, 0, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
+	// GPIO D4 Push-Pull
+	GPIO_pinMode(GPIO_port_D, 4, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
+	// GPIO C0 Push-Pull
+	GPIO_pinMode(GPIO_port_C, 0, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
+#elif DEMO_GPIO_out == 1
+	GPIO_portEnable(GPIO_port_C);
+	GPIO_portEnable(GPIO_port_D);
+	// GPIO D4 Push-Pull
+	GPIO_pinMode(GPIO_port_D, 4, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
+	// GPIO C0 - C7 Push-Pull
+	for (int i = 0; i <= 7; i++) {
+		GPIO_pinMode(GPIO_port_C, i, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
 	}
-
+#elif DEMO_GPIO_in_btn == 1
+	GPIO_portEnable(GPIO_port_C);
+	GPIO_portEnable(GPIO_port_D);
+	// GPIO D4 Push-Pull
+	GPIO_pinMode(GPIO_port_D, 3, GPIO_pinMode_I_pullUp, GPIO_SPEED_IN);
+	// GPIO C0 - C7 Push-Pull
+	for (int i = 0; i <= 7; i++) {
+		GPIO_pinMode(GPIO_port_C, i, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
+	}
+#elif DEMO_ADC_bragraph == 1
+	GPIO_portEnable(GPIO_port_C);
+	GPIO_portEnable(GPIO_port_D);
 	// GPIO D4 Push-Pull
-	pinMode(pin_D4, pinMode_O_pushPull);
+	GPIO_pinMode(GPIO_port_D, 4, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
+	// GPIO D6 analog in
+	GPIO_pinMode(GPIO_port_D, 6, GPIO_pinMode_I_analog, GPIO_SPEED_IN);
+	// GPIO C0 - C7 Push-Pull
+	for (int i = 0; i<= 7; i++) {
+		GPIO_pinMode(GPIO_port_C, i, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
+	}
+	GPIO_ADCinit();
+#elif DEMO_PWM_dayrider == 1
+	//SetupUART( UART_BRR );
+	GPIO_portEnable(GPIO_port_C);
+	GPIO_portEnable(GPIO_port_D);
+	// GPIO D4 Push-Pull
+	GPIO_pinMode(GPIO_port_D, 4, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
+	// GPIO D6 analog in
+	GPIO_pinMode(GPIO_port_D, 6, GPIO_pinMode_I_analog, GPIO_SPEED_IN);
+	// GPIO C0 - C7 Push-Pull
+	for (int i = 0; i<= 7; i++) {
+		GPIO_pinMode(GPIO_port_C, i, GPIO_pinMode_O_pushPullMux, GPIO_Speed_50MHz);
+	}
+	GPIO_tim2_map(GPIO_tim2_output_set_1__C5_C2_D2_C1);
+	GPIO_tim2_init();
+	GPIO_tim2_enableCH(4);
+	GPIO_tim2_enableCH(2);
+	GPIO_tim2_enableCH(1);
+	GPIO_tim1_map(GPIO_tim1_output_set_0__D2_A1_C3_C4__D0_A2_D1);
+	GPIO_tim1_init();
+	GPIO_tim1_enableCH(3);
+	GPIO_tim1_enableCH(4);
+#endif
+	
+
 
 	while (1) {
-		// Turn on pins
-		digitalWrite(pin_C0, high);
-		digitalWrite(pin_D4, high);
+#if DEMO_GPIO_blink == 1
+		GPIO_digitalWrite(GPIO_port_D, 0, high);
+		GPIO_digitalWrite(GPIO_port_D, 4, high);
+		GPIO_digitalWrite(GPIO_port_C, 0, high);
+		Delay_Ms( 250 );
+		GPIO_digitalWrite(GPIO_port_D, 0, low);
+		GPIO_digitalWrite(GPIO_port_D, 4, low);
+		GPIO_digitalWrite(GPIO_port_C, 0, low);
+		Delay_Ms( 250 );
+#elif DEMO_GPIO_out == 1
+		GPIO_digitalWrite(GPIO_port_D, 4, low);
+		Delay_Ms(1000);
+		GPIO_digitalWrite(GPIO_port_D, 4, high);
 		Delay_Ms(250);
-		// Turn off pins
-		digitalWrite(pin_C0, low);
-		digitalWrite(pin_D4, low);
-		Delay_Ms(250);
-		for (int i = pin_C0; i <= pin_C7; i++) {
-			digitalWrite(i, high);
+		for (int i = 0; i <= 7; i++) {
+			GPIO_digitalWrite_hi(GPIO_port_C, i);
 			Delay_Ms(50);
 		}
-		for (int i = pin_C7; i >= pin_C0; i--) {
-			digitalWrite(i, low);
+		for (int i = 7; i >= 0; i--) {
+			GPIO_digitalWrite_lo(GPIO_port_C, i);
 			Delay_Ms(50);
 		}
-		Delay_Ms(250);
-		count++;
+#elif DEMO_GPIO_in_btn == 1
+		uint8_t button_is_pressed = !GPIO_digitalRead(GPIO_port_D, 3);
+		static uint8_t leds_to_turn_on;
+		if (button_is_pressed && leds_to_turn_on < 8) {
+			leds_to_turn_on++;
+		}
+		else if (!button_is_pressed && leds_to_turn_on > 0) {
+			leds_to_turn_on--;
+		}
+		uint8_t led_i = 0;
+		for (int i = 0; i<= 7; i++) {
+			if (led_i < leds_to_turn_on) {
+				GPIO_digitalWrite_hi(GPIO_port_C, i);
+			}
+			else {
+				GPIO_digitalWrite_lo(GPIO_port_C, i);
+			}
+			led_i++;
+		}
+		Delay_Ms(50);
+#elif DEMO_ADC_bragraph == 1
+		GPIO_digitalWrite(GPIO_port_D, 4, high);
+		uint16_t analog_result = GPIO_analogRead(GPIO_Ain6_D6);
+		analog_result = analog_result > 10 ?
+				(analog_result < ((1 << 10) - 42) ? analog_result + 42 : (1 << 10))
+			: 0;
+		uint8_t leds_to_turn_on = analog_result >> 7;
+		uint8_t led_i = 0;
+		for (int i = 0; i<= 7; i++) {
+			if (led_i < leds_to_turn_on) {
+				GPIO_digitalWrite_hi(GPIO_port_C, i);
+			}
+			else {
+				GPIO_digitalWrite_lo(GPIO_port_C, i);
+			}
+			led_i++;
+		}
+		GPIO_digitalWrite(GPIO_port_D, 4, low);
+		Delay_Ms(50);
+#elif DEMO_PWM_dayrider == 1
+		#define NUMLEDS		5
+		#define TICKS_NEXT	149			// lower = faster scanning
+		#define TICK_i		2143			// lower = faster fade-out
+		GPIO_digitalWrite(GPIO_port_D, 4, high);
+		static uint8_t led_focus = 0;
+		static uint8_t direction = 0;
+
+		static uint16_t led_PW[NUMLEDS];
+
+		static uint32_t tick;
+
+		for (uint8_t i = 0; i < NUMLEDS; i++) {
+			if ((i == led_focus) && ((tick % TICKS_NEXT) == 0)) {
+				led_PW[i] = 1023;
+				//printf("focus %u, tick %u, direction %u\r\n", led_focus, tick, direction);
+				if (direction == 0) {
+					led_focus++;
+					if (led_focus >= (NUMLEDS - 1)) {
+						direction = 1;
+					}
+				}
+				else {
+					led_focus--;
+					if (led_focus == 0) {
+						direction = 0;
+					}
+				}
+				tick++;
+			}
+			else {
+				led_PW[i] = (led_PW[i] > 2) ? (led_PW[i] - 3) : 0;
+			}
+		}
+		GPIO_tim2_analogWrite(4, led_PW[0]);
+		GPIO_tim2_analogWrite(2, led_PW[1]);
+		GPIO_tim1_analogWrite(3, led_PW[2]);
+		GPIO_tim1_analogWrite(4, led_PW[3]);
+		GPIO_tim2_analogWrite(1, led_PW[4]);
+		GPIO_digitalWrite(GPIO_port_D, 4, low);
+		tick++;
+		Delay_Us(TICK_i);
+#endif
 	}
 }
diff --git a/examples/GPIO/Makefile b/examples/GPIO/Makefile
index 399d16eba5d704e10e1ce2a4c0455daf5b06477c..7e60f814bb33181340eca2ad204cee695088fcc8 100644
--- a/examples/GPIO/Makefile
+++ b/examples/GPIO/Makefile
@@ -3,7 +3,7 @@ all : flash
 TARGET:=GPIO
 
 CFLAGS+=-DTINYVECTOR
-ADDITIONAL_C_FILES+=wiring.c
+CFLAGS+=-DSTDOUT_UART
 
 include ../../ch32v003fun/ch32v003fun.mk
 
diff --git a/examples/GPIO/README.md b/examples/GPIO/README.md
index a6c23799ff7e6df932b10774273f86094daac8b3..33ac22d79daecb0e64c0c96c8df2f0d50450934a 100644
--- a/examples/GPIO/README.md
+++ b/examples/GPIO/README.md
@@ -1,14 +1,22 @@
-# GPIO Libaray
-On the shoulders of the Blink example, this Arduino-like GPIO library stands.
+# one GPIO libaray to rule them all
 
-All pins are adressable as outputs, inputs, with pull-up, etc.
-The pins are in an enum, so you can call them by their name and iterate over them.
+This Arduino-like GPIO library offers
+ * digital IO
+ * analog-to-digital
+ * digital-to-analog (PWM)
 
-It's your responsibility to not blow up a pin.
-Only use one pin for one thing and you should be fine.
+Great care has been taken to make the resulting code as fast and tiny as possible. Let the compiler suffer!  
+Hand-written blink compiles to 500 bytes, blink using this library compiles to 504 bytes!  
 
 # GPIO Example
-Connect LED + 1k resistor to each pin (C0 to C7 and D4) and GND.
-Marvel at the colorful glory.
 
-https://user-images.githubusercontent.com/104343143/231585338-725f1197-dfa0-484d-8707-f0824af80b7e.mp4
+Connect LED + 1k resistor to each LED pin (C0 to C7 and D4) and GND.  
+Connect a button to GND and D3.  
+Connect a 10k pot between GND and VCC, wiper to D6.  
+
+The desired demo may be selected in GPIO.c by setting it to 1 and the others to 0.  
+Marvel at the colorful glory.  
+
+
+
+https://github.com/recallmenot/ch32v003fun/assets/104343143/afb4027d-a609-467a-96c5-0cc3283366a4
diff --git a/examples/GPIO/wiring.c b/examples/GPIO/wiring.c
deleted file mode 100644
index ce706a3f257aa41496036d72ce41ba00bd1b59f9..0000000000000000000000000000000000000000
--- a/examples/GPIO/wiring.c
+++ /dev/null
@@ -1,251 +0,0 @@
-//#include <stdio.h>
-
-#include "wiring.h"
-#include <stdint.h>
-
-
-
-enum GPIOports getPort (enum GPIOpins pin) {
-	if (pin <= pin_A2) {
-		return port_A;
-	}
-	else if (pin <= pin_C7) {
-		return port_C;
-	}
-	else if (pin <= pin_D7) {
-		return port_D;
-	}
-	return port_none;
-}
-
-
-
-void portEnable(enum GPIOports port) {
-	// Enable GPIOs
-	switch (port) {
-		case port_A:
-			RCC->APB2PCENR |= RCC_APB2Periph_GPIOA;
-			break;
-		case port_C:
-			RCC->APB2PCENR |= RCC_APB2Periph_GPIOC;
-			break;
-		case port_D:
-			RCC->APB2PCENR |= RCC_APB2Periph_GPIOD;
-			break;
-		case port_none:
-			break;
-	}
-}
-
-
-
-void pinMode(enum GPIOpins pin, enum GPIOpinMode mode) {
-	GPIO_TypeDef * GPIOx;
-	uint16_t PinOffset = 4;
-	
-	if (pin <= pin_A2) {
-		GPIOx = GPIOA;
-		PinOffset *= pin;
-	}
-	else if (pin <= pin_C7) {
-		GPIOx = GPIOC;
-		PinOffset *= (pin - 2);
-	}
-	else if (pin <= pin_D7) {
-		GPIOx = GPIOD;
-		PinOffset *= (pin - 10);
-	}
-	else {
-		return;
-	}
-
-	GPIOx->CFGLR &= ~(0b1111<<PinOffset);							// zero the 4 configuration bits
-	
-	uint8_t target_pin_state = pinState_nochange;					// by default, pin shall retain its state
-
-	uint8_t modeMask = 0;												// configuration mask
-
-	switch (mode) {
-		case pinMode_I_floating:
-			modeMask = GPIO_CNF_IN_FLOATING;
-			break;
-		case pinMode_I_pullUp:
-			modeMask = GPIO_CNF_IN_PUPD;
-			target_pin_state = pinState_high;
-			break;
-		case pinMode_I_pullDown:
-			modeMask = GPIO_CNF_IN_PUPD;
-			target_pin_state = pinState_low;
-			break;
-		case pinMode_I_analog:
-			modeMask = GPIO_CNF_IN_ANALOG;
-			break;
-		case pinMode_O_pushPull:
-			modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_PP;
-			break;
-		case pinMode_O_openDrain:
-			modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_OD;
-			break;
-		case pinMode_O_pushPullMux:
-			modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF;
-			break;
-		case pinMode_O_openDrainMux:
-			modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_OD_AF;
-			break;
-	}
-
-	// wirte mask to CFGR
-	GPIOx->CFGLR |= modeMask<<PinOffset;
-
-	// set pin state
-	if (target_pin_state > pinState_nochange) {
-		digitalWrite(pin, target_pin_state - 1);
-	}
-}
-
-
-
-void digitalWrite(enum GPIOpins pin, uint8_t value) {
-	// no checks given whether pin is currently being toggled by timer! your output trannys are in your hands! beware the magic smoke!
-	GPIO_TypeDef * GPIOx;
-	uint16_t PinOffset = 0;
-	
-	if (pin <= pin_A2) {
-		GPIOx = GPIOA;
-		PinOffset = pin;
-	}
-	else if (pin <= pin_C7) {
-		GPIOx = GPIOC;
-		PinOffset = (pin - 2);
-	}
-	else if (pin <= pin_D7) {
-		GPIOx = GPIOD;
-		PinOffset = (pin - 10);
-	}
-	else {
-		return;
-	}
-
-	if (value) {
-		GPIOx-> BSHR |= 1 << PinOffset;
-	}
-	else {
-		GPIOx-> BSHR |= 1 << (16 + PinOffset);
-	}
-}
-
-
-
-uint8_t digitalRead(uint8_t pin) {
-	GPIO_TypeDef * GPIOx;
-	uint16_t PinOffset = 0;
-	
-	if (pin <= pin_A2) {
-		GPIOx = GPIOA;
-		PinOffset = pin;
-	}
-	else if (pin <= pin_C7) {
-		GPIOx = GPIOC;
-		PinOffset = (pin - 2);
-	}
-	else if (pin <= pin_D7) {
-		GPIOx = GPIOD;
-		PinOffset = (pin - 10);
-	}
-	else {
-		return 0;
-	}
-
-	int8_t result = (GPIOx->INDR >> PinOffset) & 1;
-	return result;
-}
-
-
-
-
-
-void ADCinit() {
-	// select ADC clock source
-	// ADCCLK = 24 MHz => RCC_ADCPRE = 0: divide by 2
-	RCC->CFGR0 &= ~(0x1F<<11);
-
-	// enable clock to the ADC
-	RCC->APB2PCENR |= RCC_APB2Periph_ADC1;
-
-	// Reset the ADC to init all regs
-	RCC->APB2PRSTR |= RCC_APB2Periph_ADC1;
-	RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1;
-
-	// set sampling time for all inputs to 241 cycles
-	for (uint8_t i = Ain0_A2; i <= AinVcal; i++) {
-		ADCsetSampletime(i, Ast_241cy_default);
-	}
-
-	// set trigger to software
-	ADC1->CTLR2 |= ADC_EXTSEL;
-
-	// pre-clear conversion queue
-	ADC1->RSQR1 = 0;
-	ADC1->RSQR2 = 0;
-	ADC1->RSQR3 = 0;
-
-	// power the ADC
-	ADCsetPower(1);
-}
-
-
-
-void ADCsetSampletime(enum ANALOGinputs input, enum ANALOGsampletimes time) {
-	// clear
-	ADC1->SAMPTR2 &= ~(0b111)<<(3*input);
-	// set
-	ADC1->SAMPTR2 |= time<<(3*input);	// 0:7 => 3/9/15/30/43/57/73/241 cycles
-}
-
-
-
-void ADCsetPower(uint8_t enable) {
-	if (enable) {
-		ADC1->CTLR2 |= ADC_ADON;
-		if (enable == 1) {
-			// auto-cal each time after turning on the ADC
-			// can be overridden by calling with enable > 1.
-			ADCcalibrate();					
-		}
-	}
-	else {
-		ADC1->CTLR2 &= ~(ADC_ADON);
-	}
-}
-
-
-
-void ADCcalibrate() {
-	// reset calibration
-	ADC1->CTLR2 |= ADC_RSTCAL;
-	while(ADC1->CTLR2 & ADC_RSTCAL);
-	
-	// calibrate
-	ADC1->CTLR2 |= ADC_CAL;
-	while(ADC1->CTLR2 & ADC_CAL);
-}
-
-
-
-// inspired by arduinos analogRead()
-uint16_t analogRead(enum ANALOGinputs input) {
-	// set mux to selected input
-	ADC1->RSQR3 = input;
-
-	// may need a delay right here for the mux to actually finish switching??
-	// Arduino inserts a full ms delay right here!
-	
-	// start sw conversion (auto clears)
-	ADC1->CTLR2 |= ADC_SWSTART;
-	
-	// wait for conversion complete
-	while(!(ADC1->STATR & ADC_EOC));
-	
-	// get result
-	return ADC1->RDATAR;
-}
diff --git a/examples/GPIO/wiring.h b/examples/GPIO/wiring.h
deleted file mode 100644
index 5b822036cc1fad1314fc0b249ee1ae6bb8c6293b..0000000000000000000000000000000000000000
--- a/examples/GPIO/wiring.h
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef WIRING_H
-#define WIRING_H
-
-#include "../../ch32v003fun/ch32v003fun.h"
-
-
-
-enum lowhigh {
-	low,
-	high,
-};
-
-
-
-enum GPIOports{
-	port_A,
-	port_C,
-	port_D,
-	port_none,
-};
-
-enum GPIOpins{
-	pin_A1,
-	pin_A2,
-	pin_C0,
-	pin_C1,
-	pin_C2,
-	pin_C3,
-	pin_C4,
-	pin_C5,
-	pin_C6,
-	pin_C7,
-	pin_D0,
-	pin_D1,
-	pin_D2,
-	pin_D3,
-	pin_D4,
-	pin_D5,
-	pin_D6,
-	pin_D7,
-	pin_none,
-};
-
-enum GPIOpinMode {
-	pinMode_I_floating,
-	pinMode_I_pullUp,			//pull-mode + ODR(1)
-	pinMode_I_pullDown,			//pull-mode + ODR(0)
-	pinMode_I_analog,
-	pinMode_O_pushPull,
-	pinMode_O_openDrain,
-	pinMode_O_pushPullMux,
-	pinMode_O_openDrainMux,
-};
-
-enum GPIOpinState {
-	pinState_nochange,
-	pinState_low,
-	pinState_high,
-};
-
-enum ANALOGinputs {
-	Ain0_A2,
-	Ain1_A1,
-	Ain2_C4,
-	Ain3_D2,
-	Ain4_D3,
-	Ain5_D5,
-	Ain6_D6,
-	Ain7_D4,
-	AinVref,
-	AinVcal,
-};
-
-enum ANALOGsampletimes {
-	Ast_3cy,
-	Ast_9cy,
-	Ast_15cy,
-	Ast_30cy,
-	Ast_43cy,
-	Ast_57cy,
-	Ast_73cy,
-	Ast_241cy_default,
-};
-
-
-enum GPIOports getPort (enum GPIOpins pin);
-
-void portEnable(enum GPIOports port);
-void pinMode(enum GPIOpins pin, enum GPIOpinMode mode);
-void digitalWrite(enum GPIOpins pin, uint8_t value);
-uint8_t digitalRead(uint8_t pin);
-
-void ADCinit();
-void ADCsetPower(uint8_t enable);
-void ADCsetSampletime(enum ANALOGinputs input, enum ANALOGsampletimes time);
-void ADCcalibrate();
-uint16_t analogRead(enum ANALOGinputs input);
-
-#endif					// WIRING_H
diff --git a/examples/GPIO_analogRead/GPIO_analogRead.c b/examples/GPIO_analogRead/GPIO_analogRead.c
deleted file mode 100644
index 76df1facacafbbf45260486402d91266f1f93d7a..0000000000000000000000000000000000000000
--- a/examples/GPIO_analogRead/GPIO_analogRead.c
+++ /dev/null
@@ -1,47 +0,0 @@
-// blink, but with arduino-like HAL
-// Could be defined here, or in the processor defines.
-#define SYSTEM_CORE_CLOCK 48000000
-
-#include "ch32v003fun.h"
-#include "wiring.h"
-#include <stdio.h>
-
-#define APB_CLOCK SYSTEM_CORE_CLOCK
-
-uint32_t count;
-
-int main() {
-	SystemInit48HSI();
-
-	// Enable GPIO ports
-	portEnable(port_C);
-	portEnable(port_D);
-
-	for (int i = pin_C0; i <= pin_C7; i++) {
-		pinMode(i, pinMode_O_pushPull);
-	}
-
-	// GPIO D4 Push-Pull
-	pinMode(pin_D4, pinMode_O_pushPull);
-
-	pinMode(pin_D6, pinMode_I_analog);
-	ADCinit();
-
-	while (1) {
-		digitalWrite(pin_D4, high);
-		uint8_t leds_to_turn_on = (uint8_t)(((float)(analogRead(Ain6_D6)) / 1024.f) * 8.f * 1.2 - 1.f);
-		uint8_t led_i = 0;
-		for (int i = pin_C0; i <= pin_C7; i++) {
-			if (led_i < leds_to_turn_on) {
-				digitalWrite(i, high);
-			}
-			else {
-				digitalWrite(i, low);
-			}
-			led_i++;
-		}
-		digitalWrite(pin_D4, low);
-		Delay_Ms(250);
-		count++;
-	}
-}
diff --git a/examples/GPIO_analogRead/README.md b/examples/GPIO_analogRead/README.md
deleted file mode 100644
index 3b9e1b6ca6799c77987e830cf7ea868d095601b5..0000000000000000000000000000000000000000
--- a/examples/GPIO_analogRead/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# GPIO Libaray
-On the shoulders of the Blink and the adc_polled example, this Arduino-like GPIO + ADC library stands.
-
-All pins are adressable as outputs, inputs, with pull-up, etc. but now you can also read the eight muxed inputs.
-The pins are in an enum, so you can call them by their name and iterate over them.
-
-It has been extended by an arduino-like analogRead function.
-
-It's your responsibility to not blow up a pin.
-Only use one pin for one thing and you should be fine.
-
-# GPIO Example
-Connect LED + 1k resistor to each pin (C0 to C7 and D4) and GND.
-Connect a 10k pot between GND and VCC, wiper to D6.
-Marvel at the colorful glory.
-
-https://user-images.githubusercontent.com/104343143/231814680-d41ae68f-dc7b-4c9c-a3c7-0b88cc82e541.mp4
diff --git a/examples/GPIO_analogRead/wiring.c b/examples/GPIO_analogRead/wiring.c
deleted file mode 100644
index ce706a3f257aa41496036d72ce41ba00bd1b59f9..0000000000000000000000000000000000000000
--- a/examples/GPIO_analogRead/wiring.c
+++ /dev/null
@@ -1,251 +0,0 @@
-//#include <stdio.h>
-
-#include "wiring.h"
-#include <stdint.h>
-
-
-
-enum GPIOports getPort (enum GPIOpins pin) {
-	if (pin <= pin_A2) {
-		return port_A;
-	}
-	else if (pin <= pin_C7) {
-		return port_C;
-	}
-	else if (pin <= pin_D7) {
-		return port_D;
-	}
-	return port_none;
-}
-
-
-
-void portEnable(enum GPIOports port) {
-	// Enable GPIOs
-	switch (port) {
-		case port_A:
-			RCC->APB2PCENR |= RCC_APB2Periph_GPIOA;
-			break;
-		case port_C:
-			RCC->APB2PCENR |= RCC_APB2Periph_GPIOC;
-			break;
-		case port_D:
-			RCC->APB2PCENR |= RCC_APB2Periph_GPIOD;
-			break;
-		case port_none:
-			break;
-	}
-}
-
-
-
-void pinMode(enum GPIOpins pin, enum GPIOpinMode mode) {
-	GPIO_TypeDef * GPIOx;
-	uint16_t PinOffset = 4;
-	
-	if (pin <= pin_A2) {
-		GPIOx = GPIOA;
-		PinOffset *= pin;
-	}
-	else if (pin <= pin_C7) {
-		GPIOx = GPIOC;
-		PinOffset *= (pin - 2);
-	}
-	else if (pin <= pin_D7) {
-		GPIOx = GPIOD;
-		PinOffset *= (pin - 10);
-	}
-	else {
-		return;
-	}
-
-	GPIOx->CFGLR &= ~(0b1111<<PinOffset);							// zero the 4 configuration bits
-	
-	uint8_t target_pin_state = pinState_nochange;					// by default, pin shall retain its state
-
-	uint8_t modeMask = 0;												// configuration mask
-
-	switch (mode) {
-		case pinMode_I_floating:
-			modeMask = GPIO_CNF_IN_FLOATING;
-			break;
-		case pinMode_I_pullUp:
-			modeMask = GPIO_CNF_IN_PUPD;
-			target_pin_state = pinState_high;
-			break;
-		case pinMode_I_pullDown:
-			modeMask = GPIO_CNF_IN_PUPD;
-			target_pin_state = pinState_low;
-			break;
-		case pinMode_I_analog:
-			modeMask = GPIO_CNF_IN_ANALOG;
-			break;
-		case pinMode_O_pushPull:
-			modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_PP;
-			break;
-		case pinMode_O_openDrain:
-			modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_OD;
-			break;
-		case pinMode_O_pushPullMux:
-			modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF;
-			break;
-		case pinMode_O_openDrainMux:
-			modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_OD_AF;
-			break;
-	}
-
-	// wirte mask to CFGR
-	GPIOx->CFGLR |= modeMask<<PinOffset;
-
-	// set pin state
-	if (target_pin_state > pinState_nochange) {
-		digitalWrite(pin, target_pin_state - 1);
-	}
-}
-
-
-
-void digitalWrite(enum GPIOpins pin, uint8_t value) {
-	// no checks given whether pin is currently being toggled by timer! your output trannys are in your hands! beware the magic smoke!
-	GPIO_TypeDef * GPIOx;
-	uint16_t PinOffset = 0;
-	
-	if (pin <= pin_A2) {
-		GPIOx = GPIOA;
-		PinOffset = pin;
-	}
-	else if (pin <= pin_C7) {
-		GPIOx = GPIOC;
-		PinOffset = (pin - 2);
-	}
-	else if (pin <= pin_D7) {
-		GPIOx = GPIOD;
-		PinOffset = (pin - 10);
-	}
-	else {
-		return;
-	}
-
-	if (value) {
-		GPIOx-> BSHR |= 1 << PinOffset;
-	}
-	else {
-		GPIOx-> BSHR |= 1 << (16 + PinOffset);
-	}
-}
-
-
-
-uint8_t digitalRead(uint8_t pin) {
-	GPIO_TypeDef * GPIOx;
-	uint16_t PinOffset = 0;
-	
-	if (pin <= pin_A2) {
-		GPIOx = GPIOA;
-		PinOffset = pin;
-	}
-	else if (pin <= pin_C7) {
-		GPIOx = GPIOC;
-		PinOffset = (pin - 2);
-	}
-	else if (pin <= pin_D7) {
-		GPIOx = GPIOD;
-		PinOffset = (pin - 10);
-	}
-	else {
-		return 0;
-	}
-
-	int8_t result = (GPIOx->INDR >> PinOffset) & 1;
-	return result;
-}
-
-
-
-
-
-void ADCinit() {
-	// select ADC clock source
-	// ADCCLK = 24 MHz => RCC_ADCPRE = 0: divide by 2
-	RCC->CFGR0 &= ~(0x1F<<11);
-
-	// enable clock to the ADC
-	RCC->APB2PCENR |= RCC_APB2Periph_ADC1;
-
-	// Reset the ADC to init all regs
-	RCC->APB2PRSTR |= RCC_APB2Periph_ADC1;
-	RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1;
-
-	// set sampling time for all inputs to 241 cycles
-	for (uint8_t i = Ain0_A2; i <= AinVcal; i++) {
-		ADCsetSampletime(i, Ast_241cy_default);
-	}
-
-	// set trigger to software
-	ADC1->CTLR2 |= ADC_EXTSEL;
-
-	// pre-clear conversion queue
-	ADC1->RSQR1 = 0;
-	ADC1->RSQR2 = 0;
-	ADC1->RSQR3 = 0;
-
-	// power the ADC
-	ADCsetPower(1);
-}
-
-
-
-void ADCsetSampletime(enum ANALOGinputs input, enum ANALOGsampletimes time) {
-	// clear
-	ADC1->SAMPTR2 &= ~(0b111)<<(3*input);
-	// set
-	ADC1->SAMPTR2 |= time<<(3*input);	// 0:7 => 3/9/15/30/43/57/73/241 cycles
-}
-
-
-
-void ADCsetPower(uint8_t enable) {
-	if (enable) {
-		ADC1->CTLR2 |= ADC_ADON;
-		if (enable == 1) {
-			// auto-cal each time after turning on the ADC
-			// can be overridden by calling with enable > 1.
-			ADCcalibrate();					
-		}
-	}
-	else {
-		ADC1->CTLR2 &= ~(ADC_ADON);
-	}
-}
-
-
-
-void ADCcalibrate() {
-	// reset calibration
-	ADC1->CTLR2 |= ADC_RSTCAL;
-	while(ADC1->CTLR2 & ADC_RSTCAL);
-	
-	// calibrate
-	ADC1->CTLR2 |= ADC_CAL;
-	while(ADC1->CTLR2 & ADC_CAL);
-}
-
-
-
-// inspired by arduinos analogRead()
-uint16_t analogRead(enum ANALOGinputs input) {
-	// set mux to selected input
-	ADC1->RSQR3 = input;
-
-	// may need a delay right here for the mux to actually finish switching??
-	// Arduino inserts a full ms delay right here!
-	
-	// start sw conversion (auto clears)
-	ADC1->CTLR2 |= ADC_SWSTART;
-	
-	// wait for conversion complete
-	while(!(ADC1->STATR & ADC_EOC));
-	
-	// get result
-	return ADC1->RDATAR;
-}
diff --git a/examples/GPIO_analogRead/wiring.h b/examples/GPIO_analogRead/wiring.h
deleted file mode 100644
index 5b822036cc1fad1314fc0b249ee1ae6bb8c6293b..0000000000000000000000000000000000000000
--- a/examples/GPIO_analogRead/wiring.h
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef WIRING_H
-#define WIRING_H
-
-#include "../../ch32v003fun/ch32v003fun.h"
-
-
-
-enum lowhigh {
-	low,
-	high,
-};
-
-
-
-enum GPIOports{
-	port_A,
-	port_C,
-	port_D,
-	port_none,
-};
-
-enum GPIOpins{
-	pin_A1,
-	pin_A2,
-	pin_C0,
-	pin_C1,
-	pin_C2,
-	pin_C3,
-	pin_C4,
-	pin_C5,
-	pin_C6,
-	pin_C7,
-	pin_D0,
-	pin_D1,
-	pin_D2,
-	pin_D3,
-	pin_D4,
-	pin_D5,
-	pin_D6,
-	pin_D7,
-	pin_none,
-};
-
-enum GPIOpinMode {
-	pinMode_I_floating,
-	pinMode_I_pullUp,			//pull-mode + ODR(1)
-	pinMode_I_pullDown,			//pull-mode + ODR(0)
-	pinMode_I_analog,
-	pinMode_O_pushPull,
-	pinMode_O_openDrain,
-	pinMode_O_pushPullMux,
-	pinMode_O_openDrainMux,
-};
-
-enum GPIOpinState {
-	pinState_nochange,
-	pinState_low,
-	pinState_high,
-};
-
-enum ANALOGinputs {
-	Ain0_A2,
-	Ain1_A1,
-	Ain2_C4,
-	Ain3_D2,
-	Ain4_D3,
-	Ain5_D5,
-	Ain6_D6,
-	Ain7_D4,
-	AinVref,
-	AinVcal,
-};
-
-enum ANALOGsampletimes {
-	Ast_3cy,
-	Ast_9cy,
-	Ast_15cy,
-	Ast_30cy,
-	Ast_43cy,
-	Ast_57cy,
-	Ast_73cy,
-	Ast_241cy_default,
-};
-
-
-enum GPIOports getPort (enum GPIOpins pin);
-
-void portEnable(enum GPIOports port);
-void pinMode(enum GPIOpins pin, enum GPIOpinMode mode);
-void digitalWrite(enum GPIOpins pin, uint8_t value);
-uint8_t digitalRead(uint8_t pin);
-
-void ADCinit();
-void ADCsetPower(uint8_t enable);
-void ADCsetSampletime(enum ANALOGinputs input, enum ANALOGsampletimes time);
-void ADCcalibrate();
-uint16_t analogRead(enum ANALOGinputs input);
-
-#endif					// WIRING_H
diff --git a/examples/blink/blink.bin b/examples/blink/blink.bin
index eb40bbd2f9458454bc76c9c2604a2d1fa3e077a5..b2c6174d1dac1759b26f345f4dde42f709e0e59e 100755
Binary files a/examples/blink/blink.bin and b/examples/blink/blink.bin differ
diff --git a/examples/bootload/Makefile b/examples/bootload/Makefile
index dc85199fa0bbfef6e06393db5dc3213810bc88e5..b9b810c429d4f063e22a81da2c367d2a3abbddf2 100644
--- a/examples/bootload/Makefile
+++ b/examples/bootload/Makefile
@@ -1,6 +1,9 @@
 all : flash
 
 TARGET:=bootload
+LINKER_SCRIPT:=../../ch32v003fun/ch32v003fun-bootloader.ld
+WRITE_SECTION:=bootloader
+FLASH_COMMAND:=../../minichlink/minichlink -a -U -w $(TARGET).bin $(WRITE_SECTION) -B
 
 include ../../ch32v003fun/ch32v003fun.mk
 
diff --git a/examples/bootload/bootload.c b/examples/bootload/bootload.c
index a5975940f73027cf267f591b70fca7ff582b05f0..67847cfb6486c83be5a87f0fd220cb6895afb2e9 100644
--- a/examples/bootload/bootload.c
+++ b/examples/bootload/bootload.c
@@ -14,8 +14,10 @@ void InterruptVector()
 {
 	asm volatile( "\n\
 	.align  2\n\
+	.option   push;\n\
 	.option   norvc;\n\
-	j handle_reset");
+	j handle_reset\n\
+	.option pop");
 }
 
 uint32_t count;
@@ -40,7 +42,7 @@ int main()
 
 	// GPIO C0 Push-Pull, 10MHz Output
 	GPIOC->CFGLR &= ~(0xf<<(4*0));
-	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
+	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);
 
 	static const uint32_t marker[] = { 0xaaaaaaaa };
 	count = marker[0];
@@ -56,7 +58,7 @@ int main()
 		GPIOC->BSHR = 1<<16;                     // Turn off GPIOC0
 	}
 
-	for( i = 0; i < 5; i++ )
+	for( i = 0; i < 3; i++ )
 	{
 		GPIOD->BSHR = 1 | (1<<4);
 		GPIOC->BSHR = 1;
diff --git a/examples/cpp_virtual_methods/Makefile b/examples/cpp_virtual_methods/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..749b3b594dc1d8623b2309ce03d26a0a28b4a39b
--- /dev/null
+++ b/examples/cpp_virtual_methods/Makefile
@@ -0,0 +1,26 @@
+all : flash
+
+TARGET:=cpp_virtual_methods
+TARGET_EXT:=cpp
+
+ADDITIONAL_C_FILES+=example.cpp
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+# Removing compiler optimization to small file size
+# because it optimizes the virtual functions out
+# which are tested here.
+CFLAGS:= \
+	-g -flto -ffunction-sections \
+	-static-libgcc \
+	-march=rv32ec \
+	-mabi=ilp32e \
+	-I/usr/include/newlib \
+	-I$(CH32V003FUN) \
+	-nostdlib \
+	-I. -Wall
+
+CFLAGS+=-fno-rtti -DSTDOUT_UART -DCPLUSPLUS
+
+flash : cv_flash
+clean : cv_clean
\ No newline at end of file
diff --git a/examples/cpp_virtual_methods/README.md b/examples/cpp_virtual_methods/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..d4ff847d1aba891d7849a945f07739ba6cc8ed4b
--- /dev/null
+++ b/examples/cpp_virtual_methods/README.md
@@ -0,0 +1,29 @@
+# C++ Virtual Methods Example
+
+This example tests the usage of classes with virtual methods in C++.
+
+Without the usage of `__libc_init_array`, the virtual table of the class instance `Example` is not initialized correctly:
+
+```
+vtable for 'ExampleClass' @ 0x0 (subobject @ 0x20000004):
+[0]: 0x11e0006f
+[1]: 0x0 <InterruptVectorDefault()>
+```
+
+In this case, a call to a virtual method will result to an invalid call
+and the program won't work as expected.
+Here, the program will only print out `Begin example`, but does not print any values.
+It seems like the MCU resets here.
+
+In other environments like with the Arduino Core, the hard fault handler is called
+and the program gets into an infinite loop.
+
+With the macro `CPLUSPLUS`, an implemention auf `__libc_init_array` is called on startup.
+
+Then the virtual table is initialized correctly and new values are printed as expected:
+
+```
+vtable for 'ExampleClass' @ 0x212c (subobject @ 0x20000004):
+[0]: 0x1fb0 <ExampleClass::doNewLine()>
+[1]: 0x1fda <ExampleClass::printValue(int)>
+```
\ No newline at end of file
diff --git a/examples/cpp_virtual_methods/cpp_virtual_methods.cpp b/examples/cpp_virtual_methods/cpp_virtual_methods.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e2c1d69153af63b6c03fb9cea9b0792ec7fddbf4
--- /dev/null
+++ b/examples/cpp_virtual_methods/cpp_virtual_methods.cpp
@@ -0,0 +1,30 @@
+/*
+ * Example for using virtual methods in C++
+ * 05/21/2023 A. Mandera
+ */
+
+// Could be defined here, or in the processor defines.
+#define SYSTEM_CORE_CLOCK 48000000
+#define APB_CLOCK SYSTEM_CORE_CLOCK
+
+#include "ch32v003fun.h"
+#include "example.h"
+#include <stdio.h>
+
+int main() {
+	SystemInit48HSI();
+
+	// Setup UART @ 115200 baud
+	SetupUART(UART_BRR);
+	Delay_Ms(100);
+
+	printf("Begin example\n");
+
+	// Initialize variable in example class
+	Example.begin();
+
+	while (true) {
+		Example.doPrint(10);
+		Delay_Ms(1000);
+	}
+}
\ No newline at end of file
diff --git a/examples/cpp_virtual_methods/example.cpp b/examples/cpp_virtual_methods/example.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bc43c6799795e608e9668a85a563e7c0303be593
--- /dev/null
+++ b/examples/cpp_virtual_methods/example.cpp
@@ -0,0 +1,30 @@
+/*
+ * Example for using virtual methods in C++
+ * 05/21/2023 A. Mandera
+ */
+
+#include "example.h"
+#include "stdio.h"
+
+ExampleClass Example;
+
+void Print::doPrint(int i) {
+	printValue(i);
+	doNewLine();
+}
+
+void ExampleClass::begin() {
+	this->_value = 1;
+}
+
+int ExampleClass::value() {
+	return this->_value++;
+}
+
+void ExampleClass::doNewLine() {
+	printf("\n");
+}
+
+void ExampleClass::printValue(int i) {
+	printf("Value: %d", this->value() + i);
+};
\ No newline at end of file
diff --git a/examples/cpp_virtual_methods/example.h b/examples/cpp_virtual_methods/example.h
new file mode 100644
index 0000000000000000000000000000000000000000..d510d8e5fbcc04de9011d932f0fa5409466f3f64
--- /dev/null
+++ b/examples/cpp_virtual_methods/example.h
@@ -0,0 +1,26 @@
+/*
+ * Example for using virtual methods in C++
+ * 05/21/2023 A. Mandera
+ */
+
+#pragma once
+
+class Print {
+public:
+	void doPrint(int);
+	virtual void doNewLine(void) = 0;
+	virtual void printValue(int) = 0;
+};
+
+class ExampleClass : public Print {
+public:
+	void begin();
+	int value();
+	void doNewLine(void) override;
+	void printValue(int) override;
+
+private:
+	int _value;
+};
+
+extern ExampleClass Example;
\ No newline at end of file
diff --git a/examples/i2c_oled/bomb.h b/examples/i2c_oled/bomb.h
new file mode 100644
index 0000000000000000000000000000000000000000..208d602109a3e8be6caf75f299b32375c834def7
--- /dev/null
+++ b/examples/i2c_oled/bomb.h
@@ -0,0 +1,17 @@
+/*
+The bomb illustration has been drawn and provided by [DoubleWaffleCakes](https://www.reddit.com/user/DoubleWaffleCakes/).  
+*/
+const unsigned char bomb_i_stripped[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
+  0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x48, 0x00,
+  0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x03, 0xfe, 0x00,
+  0x00, 0x0f, 0xff, 0x80, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x1f, 0xff, 0xc0,
+  0x00, 0x3f, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x73, 0x9f, 0xf0,
+  0x00, 0x73, 0x9f, 0xf0, 0x00, 0x73, 0x9f, 0xf0, 0x00, 0x73, 0x9f, 0xf0,
+  0x00, 0x73, 0x9f, 0xf0, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xe0,
+  0x00, 0x1f, 0xff, 0xc0, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0x80,
+  0x00, 0x13, 0xe0, 0x40, 0x00, 0x20, 0xc0, 0x20, 0x00, 0x7f, 0xff, 0xe0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+const unsigned int bomb_i_stripped_len = 128;
diff --git a/examples/i2c_oled/i2c_oled.c b/examples/i2c_oled/i2c_oled.c
index 94e6ce6390af94aa88c6d4020f01e71d1016b563..fd7a3bc3a2f88cf0dcd895d57a5469b1ea65bb7e 100644
--- a/examples/i2c_oled/i2c_oled.c
+++ b/examples/i2c_oled/i2c_oled.c
@@ -17,6 +17,8 @@
 #include "ssd1306_i2c.h"
 #include "ssd1306.h"
 
+#include "bomb.h"
+
 int main()
 {
 	// 48MHz internal clock
@@ -42,7 +44,7 @@ int main()
 		printf("Looping on test modes...");
 		while(1)
 		{
-			for(uint8_t mode=0;mode<(SSD1306_H>32?8:7);mode++)
+			for(uint8_t mode=0;mode<(SSD1306_H>32?9:8);mode++)
 			{
 				// clear buffer for next mode
 				ssd1306_setbuf(0);
@@ -85,8 +87,11 @@ int main()
 							else
 								ssd1306_fillCircle(x, SSD1306_H/2, 15, 1);
 						break;
-					
 					case 4:
+						printf("Image\n\r");
+						ssd1306_drawImage(0, 0, bomb_i_stripped, 32, 32, 0);
+						break;
+					case 5:
 						printf("Unscaled Text\n\r");
 						ssd1306_drawstr(0,0, "This is a test", 1);
 						ssd1306_drawstr(0,8, "of the emergency", 1);
@@ -102,19 +107,19 @@ int main()
 						ssd1306_xorrect(SSD1306_W/2, 0, SSD1306_W/2, SSD1306_W);
 						break;
 						
-					case 5:
+					case 6:
 						printf("Scaled Text 1, 2\n\r");
 						ssd1306_drawstr_sz(0,0, "sz 8x8", 1, fontsize_8x8);
 						ssd1306_drawstr_sz(0,16, "16x16", 1, fontsize_16x16);
 						break;
 					
-					case 6:
+					case 7:
 						printf("Scaled Text 4\n\r");
 						ssd1306_drawstr_sz(0,0, "32x32", 1, fontsize_32x32);
 						break;
 					
 					
-					case 7:
+					case 8:
 						printf("Scaled Text 8\n\r");
 						ssd1306_drawstr_sz(0,0, "64", 1, fontsize_64x64);
 						break;
diff --git a/examples/i2c_oled/ssd1306.h b/examples/i2c_oled/ssd1306.h
index 19ea88db1053ad211038656b1dbe1452f8f6e2bb..ea985d8d8a0108004beb495107b3c95570eb5b13 100644
--- a/examples/i2c_oled/ssd1306.h
+++ b/examples/i2c_oled/ssd1306.h
@@ -240,6 +240,77 @@ void ssd1306_xorPixel(uint8_t x, uint8_t y)
 	ssd1306_buffer[addr] ^= (1<<(y&7));
 }
 
+/*
+ * draw a an image from an array, directly into to the display buffer
+ * the color modes allow for overwriting and even layering (sprites!)
+ */
+void ssd1306_drawImage(uint8_t x, uint8_t y, const unsigned char* input, uint8_t width, uint8_t height, uint8_t color_mode) {
+	uint8_t x_absolute;
+	uint8_t y_absolute;
+	uint8_t pixel;
+	uint8_t bytes_to_draw = width / 8;
+	uint16_t buffer_addr;
+
+	for (uint8_t line = 0; line < height; line++) {
+		y_absolute = y + line;
+		if (y_absolute >= SSD1306_H) {
+			break;
+		}
+
+		// SSD1306 is in vertical mode, yet we want to draw horizontally, which necessitates assembling the output bytes from the input data
+		// bitmask for current pixel in vertical (output) byte
+		uint8_t v_mask = 1 << (y_absolute & 7);
+
+		for (uint8_t byte = 0; byte < bytes_to_draw; byte++) {
+			uint8_t input_byte = input[byte + line * bytes_to_draw];
+
+			for (pixel = 0; pixel < 8; pixel++) {
+				x_absolute = x + 8 * (bytes_to_draw - byte) + pixel;
+				if (x_absolute >= SSD1306_W) {
+					break;
+				}
+				// looking at the horizontal display, we're drawing bytes bottom to top, not left to right, hence y / 8
+				buffer_addr = x_absolute + SSD1306_W * (y_absolute / 8);
+				// state of current pixel
+				uint8_t input_pixel = input_byte & (1 << pixel);
+
+				switch (color_mode) {
+					case 0:
+						// write pixels as they are
+						ssd1306_buffer[buffer_addr] = (ssd1306_buffer[buffer_addr] & ~v_mask) | (input_pixel ? v_mask : 0);
+						break;
+					case 1:
+						// write pixels after inversion
+						ssd1306_buffer[buffer_addr] = (ssd1306_buffer[buffer_addr] & ~v_mask) | (!input_pixel ? v_mask : 0);
+						break;
+					case 2:
+						// 0 clears pixel
+						ssd1306_buffer[buffer_addr] &= input_pixel ? 0xFF : ~v_mask;
+						break;
+					case 3:
+						// 1 sets pixel
+						ssd1306_buffer[buffer_addr] |= input_pixel ? v_mask : 0;
+						break;
+					case 4:
+						// 0 sets pixel
+						ssd1306_buffer[buffer_addr] |= !input_pixel ? v_mask : 0;
+						break;
+					case 5:
+						// 1 clears pixel
+						ssd1306_buffer[buffer_addr] &= input_pixel ? ~v_mask : 0xFF;
+						break;
+				}
+			}
+			#if SSD1306_LOG_IMAGE == 1
+			printf("%02x ", input_byte);
+			#endif
+		}
+		#if SSD1306_LOG_IMAGE == 1
+		printf("\n\r");
+		#endif
+	}
+}
+
 /*
  *  fast vert line
  */
diff --git a/examples/i2c_slave/Makefile b/examples/i2c_slave/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..49b91ce536597c14d0d8273010cba332c68baef1
--- /dev/null
+++ b/examples/i2c_slave/Makefile
@@ -0,0 +1,9 @@
+all : flash
+
+TARGET:=i2c_slave
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
diff --git a/examples/i2c_slave/README.md b/examples/i2c_slave/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..cfdbd1b46fb2f58e9bea2c7b4ce8d2aa0e4ee367
--- /dev/null
+++ b/examples/i2c_slave/README.md
@@ -0,0 +1,9 @@
+# I2C peripheral in slave mode
+
+This library and example show how to use the I2C peripheral in slave mode.
+
+The library uses a one-byte address, allowing for up to 256 registers to be defined.
+
+The first byte written to the device within a transaction determines the offset for following reads and writes, emulating a simple EEPROM.
+
+The example will turn on a LED connected to PD0 when the LSB of register 0 is set to 1 and off when it's set to 0.
diff --git a/examples/i2c_slave/i2c_slave.c b/examples/i2c_slave/i2c_slave.c
new file mode 100644
index 0000000000000000000000000000000000000000..dbfaf80ec8448a67b4f5ab3e5ece38b1bb6c02d3
--- /dev/null
+++ b/examples/i2c_slave/i2c_slave.c
@@ -0,0 +1,30 @@
+#define SYSTEM_CORE_CLOCK 48000000
+
+#include "ch32v003fun.h"
+#include "i2c_slave.h"
+#include <stdio.h>
+
+// The I2C slave library uses a one byte address so you can extend the size of this array up to 256 registers
+// note that the register set is modified by interrupts, to prevent the compiler from accidently optimizing stuff
+// away make sure to declare the register array volatile
+
+volatile uint8_t i2c_registers[32] = {0x00};
+
+int main() {
+    SystemInit48HSI();
+    SetupDebugPrintf();
+    SetupI2CSlave(0x9, i2c_registers, sizeof(i2c_registers));
+
+    // Enable GPIOD and set pin 0 to output
+    RCC->APB2PCENR |= RCC_APB2Periph_GPIOD;
+    GPIOD->CFGLR &= ~(0xf<<(4*0));
+    GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);
+
+    while (1) {
+        if (i2c_registers[0] & 1) { // Turn on LED (PD0) if bit 1 of register 0 is set
+            GPIOD-> BSHR |= 1 << 16;
+        } else {
+            GPIOD-> BSHR |= 1;
+        }
+    }
+}
diff --git a/examples/i2c_slave/i2c_slave.h b/examples/i2c_slave/i2c_slave.h
new file mode 100644
index 0000000000000000000000000000000000000000..a488eaf8ea046d5ca80e395a2715650d9213dbeb
--- /dev/null
+++ b/examples/i2c_slave/i2c_slave.h
@@ -0,0 +1,150 @@
+/*
+ * Single-File-Header for using the I2C peripheral in slave mode
+ *
+ * MIT License
+ *
+ * Copyright (c) 2023 Renze Nicolai
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __I2C_SLAVE_H
+#define __I2C_SLAVE_H
+
+#include <stdint.h>
+
+#define APB_CLOCK SYSTEM_CORE_CLOCK
+
+struct _i2c_slave_state {
+    uint8_t first_write;
+    uint8_t offset;
+    uint8_t position;
+    volatile uint8_t* volatile registers;
+    uint8_t size;
+} i2c_slave_state;
+
+void SetupI2CSlave(uint8_t address, volatile uint8_t* registers, uint8_t size) {
+    i2c_slave_state.first_write = 1;
+    i2c_slave_state.offset = 0;
+    i2c_slave_state.position = 0;
+    i2c_slave_state.registers = registers;
+    i2c_slave_state.size = size;
+
+    // Enable GPIOC and I2C
+    RCC->APB2PCENR |= RCC_APB2Periph_GPIOC;
+    RCC->APB1PCENR |= RCC_APB1Periph_I2C1;
+
+    // PC1 is SDA, 10MHz Output, alt func, open-drain
+    GPIOC->CFGLR &= ~(0xf<<(4*1));
+    GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_OD_AF)<<(4*1);
+
+    // PC2 is SCL, 10MHz Output, alt func, open-drain
+    GPIOC->CFGLR &= ~(0xf<<(4*2));
+    GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_OD_AF)<<(4*2);
+
+    // Reset I2C1 to init all regs
+    RCC->APB1PRSTR |= RCC_APB1Periph_I2C1;
+    RCC->APB1PRSTR &= ~RCC_APB1Periph_I2C1;
+
+    I2C1->CTLR1 |= I2C_CTLR1_SWRST;
+    I2C1->CTLR1 &= ~I2C_CTLR1_SWRST;
+
+    // Set module clock frequency
+    uint32_t prerate = 2000000; // I2C Logic clock rate, must be higher than the bus clock rate
+    I2C1->CTLR2 |= (APB_CLOCK/prerate) & I2C_CTLR2_FREQ;
+
+    // Enable interrupts
+    I2C1->CTLR2 |= I2C_CTLR2_ITBUFEN;
+    I2C1->CTLR2 |= I2C_CTLR2_ITEVTEN; // Event interrupt
+    I2C1->CTLR2 |= I2C_CTLR2_ITERREN; // Error interrupt
+
+    NVIC_EnableIRQ(I2C1_EV_IRQn); // Event interrupt
+    NVIC_SetPriority(I2C1_EV_IRQn, 2 << 4);
+    NVIC_EnableIRQ(I2C1_ER_IRQn); // Error interrupt
+
+    // Set clock configuration
+    uint32_t clockrate = 1000000; // I2C Bus clock rate, must be lower than the logic clock rate
+    I2C1->CKCFGR = ((APB_CLOCK/(3*clockrate))&I2C_CKCFGR_CCR) | I2C_CKCFGR_FS; // Fast mode 33% duty cycle
+    //I2C1->CKCFGR = ((APB_CLOCK/(25*clockrate))&I2C_CKCFGR_CCR) | I2C_CKCFGR_DUTY | I2C_CKCFGR_FS; // Fast mode 36% duty cycle
+    //I2C1->CKCFGR = (APB_CLOCK/(2*clockrate))&I2C_CKCFGR_CCR; // Standard mode good to 100kHz
+
+    // Set I2C address
+    I2C1->OADDR1 = address << 1;
+
+    // Enable I2C
+    I2C1->CTLR1 |= I2C_CTLR1_PE;
+
+    // Acknowledge the first address match event when it happens
+    I2C1->CTLR1 |= I2C_CTLR1_ACK;
+}
+
+void I2C1_EV_IRQHandler(void) __attribute__((interrupt));
+void I2C1_EV_IRQHandler(void) {
+    uint16_t STAR1, STAR2 __attribute__((unused));
+    STAR1 = I2C1->STAR1;
+    STAR2 = I2C1->STAR2;
+
+    I2C1->CTLR1 |= I2C_CTLR1_ACK;
+
+    if (STAR1 & I2C_STAR1_ADDR) { // Start event
+        i2c_slave_state.first_write = 1; // Next write will be the offset
+        i2c_slave_state.position = i2c_slave_state.offset; // Reset position
+    }
+
+    if (STAR1 & I2C_STAR1_RXNE) { // Write event
+        if (i2c_slave_state.first_write) { // First byte written, set the offset
+            i2c_slave_state.offset = I2C1->DATAR;
+            i2c_slave_state.position = i2c_slave_state.offset;
+            i2c_slave_state.first_write = 0;
+        } else { // Normal register write
+            if (i2c_slave_state.position < i2c_slave_state.size) {
+                i2c_slave_state.registers[i2c_slave_state.position] = I2C1->DATAR;
+                i2c_slave_state.position++;
+            }
+        }
+    }
+
+    if (STAR1 & I2C_STAR1_TXE) { // Read event
+        if (i2c_slave_state.position < i2c_slave_state.size) {
+            I2C1->DATAR = i2c_slave_state.registers[i2c_slave_state.position];
+            i2c_slave_state.position++;
+        } else {
+            I2C1->DATAR = 0x00;
+        }
+    }
+}
+
+void I2C1_ER_IRQHandler(void) __attribute__((interrupt));
+void I2C1_ER_IRQHandler(void) {
+    uint16_t STAR1 = I2C1->STAR1;
+
+    if (STAR1 & I2C_STAR1_BERR) { // Bus error
+        I2C1->STAR1 &= ~(I2C_STAR1_BERR); // Clear error
+    }
+
+    if (STAR1 & I2C_STAR1_ARLO) { // Arbitration lost error
+        I2C1->STAR1 &= ~(I2C_STAR1_ARLO); // Clear error
+    }
+
+    if (STAR1 & I2C_STAR1_AF) { // Acknowledge failure
+        I2C1->STAR1 &= ~(I2C_STAR1_AF); // Clear error
+    }
+}
+
+#endif
diff --git a/examples/GPIO_analogRead/Makefile b/examples/input_capture/Makefile
similarity index 55%
rename from examples/GPIO_analogRead/Makefile
rename to examples/input_capture/Makefile
index e47191ea6a2a9efea0eb37aa371f0c276ec5f817..e656f94faa92ed98d446d57a76a59a4efefb53e9 100644
--- a/examples/GPIO_analogRead/Makefile
+++ b/examples/input_capture/Makefile
@@ -1,12 +1,10 @@
 all : flash
 
-TARGET:=GPIO_analogRead
-
-CFLAGS+=-DTINYVECTOR
-ADDITIONAL_C_FILES+=wiring.c
+TARGET:=input_capture
 
 include ../../ch32v003fun/ch32v003fun.mk
 
 flash : cv_flash
 clean : cv_clean
 
+
diff --git a/examples/input_capture/input_capture.c b/examples/input_capture/input_capture.c
new file mode 100644
index 0000000000000000000000000000000000000000..ed3b92bbd40450be5a41e4b23a0d9b04a3bfce2b
--- /dev/null
+++ b/examples/input_capture/input_capture.c
@@ -0,0 +1,109 @@
+/* Small example showing how to capture timer values on gpio edges */
+
+#define SYSTEM_CORE_CLOCK 48000000
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+
+#define APB_CLOCK SYSTEM_CORE_CLOCK
+
+#define queuelen 16
+volatile uint32_t captureVals[queuelen];
+volatile size_t read = 0;
+volatile size_t write = 0;
+
+void TIM1_CC_IRQHandler(void) __attribute__((interrupt));
+void TIM1_CC_IRQHandler(void)
+{
+	// capture
+	if(TIM1->INTFR & TIM_CC1IF)
+	{
+		// get capture
+		captureVals[write++] = 0x00010000 | TIM1->CH1CVR; // capture valur
+		if (write == queuelen)
+		{
+			write = 0;
+		}
+		// overflow
+		if(TIM1->INTFR & TIM_CC1OF)
+		{
+			// clear
+			TIM1->INTFR = ~(TIM_CC1OF); // cleard by writing 0
+			printf("OF1\n");
+		}
+	}
+	else if (TIM1->INTFR & TIM_CC2IF)
+	{
+		// get capture
+		captureVals[write++] = TIM1->CH2CVR; // capture valur
+		if (write == queuelen)
+		{
+			write = 0;
+		}
+		// overflow
+		if(TIM1->INTFR & TIM_CC2OF)
+		{
+			// clear
+			TIM1->INTFR = ~(TIM_CC2OF); // cleard by writing 0
+			printf("OF0\n");
+		}
+	}
+	else
+	{
+		printf("badtrigger\n");
+	}
+}
+
+int main()
+{
+	SystemInit48HSI();
+	SetupDebugPrintf();
+
+	Delay_Ms(100);
+
+	printf("UP\n");
+
+	// Enable peripherals
+	RCC->APB2PCENR = RCC_IOPDEN | RCC_TIM1EN;
+	RCC->APB2PRSTR = RCC_TIM1RST;
+	RCC->APB2PRSTR = 0;
+
+	// GPIO D0, D4 Push-Pull LEDs, D1/SWIO floating, D2 Capture Input(T1CH1), default analog input
+	GPIOD->CFGLR = ((GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * 0)) | 
+				   ((GPIO_SPEED_IN | GPIO_CNF_IN_FLOATING) << (4 * 1)) | 
+				   ((GPIO_SPEED_IN | GPIO_CNF_IN_FLOATING) << (4 * 2)) | 
+				   ((GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * 4));
+
+	TIM1->ATRLR = 0xffff;
+	TIM1->PSC = 47; // 48MHz/(47+1) -> 1µs resolution
+
+	TIM1->CHCTLR1 = TIM_CC1S_0 | TIM_CC2S_1;
+
+	TIM1->CCER = TIM_CC1E|TIM_CC2E|TIM_CC2P;
+
+	TIM1->CTLR1 = TIM_CEN;
+
+	NVIC_EnableIRQ(TIM1_CC_IRQn);
+	TIM1->DMAINTENR = TIM_CC1IE|TIM_CC2IE;
+
+	while (1)
+	{
+		if (read != write)
+		{
+			uint32_t val = captureVals[read++];
+			printf("capture %ld %lu\n", val >> 16, val & 0xFFFF);
+			if (read == queuelen)
+			{
+				read = 0;
+			}
+		}
+
+		// Turn D0 on and D4 off at the same time
+		GPIOD->BSHR = 1 | 1<<(16+4);
+		Delay_Ms(1);
+
+		// Turn D0 off and D4 on at the same time
+		GPIOD->BSHR = 1<<16 | 1<<4;
+		Delay_Ms(1);
+	}
+}
\ No newline at end of file
diff --git a/examples/iwdg/Makefile b/examples/iwdg/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0d17f3d3669e18df049b73815420d5a4c11f55f9
--- /dev/null
+++ b/examples/iwdg/Makefile
@@ -0,0 +1,10 @@
+all : flash
+
+TARGET:=iwdg
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
+
diff --git a/examples/iwdg/iwdg.c b/examples/iwdg/iwdg.c
new file mode 100644
index 0000000000000000000000000000000000000000..886f2778eedfa6d29a06c33b9ea204e2c8769554
--- /dev/null
+++ b/examples/iwdg/iwdg.c
@@ -0,0 +1,73 @@
+// Could be defined here, or in the processor defines.
+#define SYSTEM_CORE_CLOCK 48000000
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+
+static void iwdg_setup(uint16_t reload_val, uint8_t prescaler) {
+	IWDG->CTLR = 0x5555;
+	IWDG->PSCR = prescaler;
+
+	IWDG->CTLR = 0x5555;
+	IWDG->RLDR = reload_val & 0xfff;
+
+	IWDG->CTLR = 0xCCCC;
+}
+
+static void iwdg_feed() {
+	IWDG->CTLR = 0xAAAA;
+}
+
+static void gpios_on() {
+	GPIOD->BSHR = 1 | (1<<4);
+	GPIOC->BSHR = 1;
+}
+
+static void gpios_off() {
+	GPIOD->BSHR = (1<<16) | (1<<(16+4));
+	GPIOC->BSHR = (1<<16);
+}
+
+int main()
+{
+	SystemInit48HSI();
+
+	// Enable GPIOs
+	RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC;
+
+	// GPIO D0 Push-Pull
+	GPIOD->CFGLR &= ~(0xf<<(4*0));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);
+
+	// GPIO D4 Push-Pull
+	GPIOD->CFGLR &= ~(0xf<<(4*4));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
+
+	// GPIO C0 Push-Pull
+	GPIOC->CFGLR &= ~(0xf<<(4*0));
+	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);
+
+	gpios_on();
+	Delay_Ms( 1500 );
+	gpios_off();
+	Delay_Ms( 1000 );
+
+	// set up watchdog to about 4 s
+	iwdg_setup(0xfff, IWDG_Prescaler_128);
+
+	gpios_on();
+	Delay_Ms( 3000 );
+	gpios_off();
+
+	// feed the watch dog. Now there should be about 8 blinks
+	iwdg_feed();
+
+	while(1)
+	{
+		gpios_on();
+		Delay_Ms( 250 );
+		gpios_off();
+		Delay_Ms( 250 );
+	}
+}
+
diff --git a/examples/optiondata/Makefile b/examples/optiondata/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..5ad2b8e5ed62673531a142e2a44fa1e7ebf78b08
--- /dev/null
+++ b/examples/optiondata/Makefile
@@ -0,0 +1,8 @@
+all : flash
+
+TARGET:=optiondata
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
diff --git a/examples/optiondata/README.md b/examples/optiondata/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..840aee6057895eb3696b9e18407e37190a9f87cf
--- /dev/null
+++ b/examples/optiondata/README.md
@@ -0,0 +1,11 @@
+# Write to the user fields in the Option Data flash
+
+This is a simple example code for writing to the two 8-bit data0/data1 bytes that are a part of the Flash "User-selected words" (aka Option bytes).
+
+To reduce the code footpint no timeouts are implemented in the code. It simply waits for the busy-flag to be cleaed. The two wait-loops could be replaced with a Delay_Ms(10) if speed is not an issue.
+
+The two bytes could be used for remembering user settings between power-offs.
+
+After flashing you can test it with the command
+`../../minichlink/minichlink -a -b -T` 
+that will Halt, Reboot and enter Terminal mode. For each run the count will increment by one.
diff --git a/examples/optiondata/optiondata.c b/examples/optiondata/optiondata.c
new file mode 100644
index 0000000000000000000000000000000000000000..a3c8f273c0a07d9416ff30963cacea91651b6b17
--- /dev/null
+++ b/examples/optiondata/optiondata.c
@@ -0,0 +1,74 @@
+//
+// Example code for writing to the two 8-bit data0/data1 bytes that are
+// a part of the Flash "User-selected words" (aka Option bytes).
+// To reduce the code footpint no timeouts are implemented in the code. It simply
+// waits for the busy-flag to be cleaed. The two wait-loops could be replaced 
+// with a Delay_Ms(10) if speed is not an issue.
+//
+// June 13, 2023 Mats Engstrom (github.com/mengstr)
+//
+
+#define SYSTEM_CORE_CLOCK 48000000
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+void FlashOptionData(uint8_t data0, uint8_t data1) {
+	volatile uint16_t hold[6]; 		// array to hold current values while erasing
+
+	// The entire 64 byte data block of the "User-selected words" will be erased
+	// so we need to keep a copy of the content for re-writing after erase.
+	// Save a few (20) bytes code space by moving 32 bits at a time.
+	// 			hold[0]=OB->RDPR;
+	// 			hold[1]=OB->USER;
+	// 			hold[2]=data0;
+	// 			hold[3]=data1;
+	// 			hold[4]=OB->WRPR0;
+	// 			hold[5]=OB->WRPR1;
+	uint32_t *hold32p=(uint32_t *)hold;
+	uint32_t *ob32p=(uint32_t *)OB_BASE;
+	hold32p[0]=ob32p[0]; 			// Copy RDPR and USER
+	hold32p[1]=data0+(data1<<16);	// Copy in the two Data values to be written
+	hold32p[2]=ob32p[2];			// Copy WRPR0 and WEPR1
+
+	// Unlock both the general Flash and the User-selected words
+	FLASH->KEYR = FLASH_KEY1;
+	FLASH->KEYR = FLASH_KEY2;
+	FLASH->OBKEYR = FLASH_KEY1;
+	FLASH->OBKEYR = FLASH_KEY2;
+
+	FLASH->CTLR |= CR_OPTER_Set;			// OBER RW Perform user-selected word erasure	
+	FLASH->CTLR |= CR_STRT_Set;    			// STRT RW1 Start. Set 1 to start an erase action,hw automatically clears to 0
+	while (FLASH->STATR & FLASH_BUSY);		// Wait for flash operation to be done
+	FLASH->CTLR &= CR_OPTER_Reset; 			// Disable erasure mode	
+
+	// Write the held values back one-by-one
+	FLASH->CTLR |= CR_OPTPG_Set;   			// OBG  RW Perform user-selected word programming
+	uint16_t *ob16p=(uint16_t *)OB_BASE;
+	for (int i=0;i<sizeof(hold)/sizeof(hold[0]); i++) {
+		ob16p[i]=hold[i];
+		while (FLASH->STATR & FLASH_BUSY);	// Wait for flash operation to be done
+	}
+	FLASH->CTLR &= CR_OPTPG_Reset;			// Disable programming mode
+
+	FLASH->CTLR|=CR_LOCK_Set;				// Lock flash memories again
+
+	return;
+}
+
+
+
+//
+//
+//
+int main() {
+	SystemInit48HSI();
+	SetupDebugPrintf();
+	Delay_Ms(250);
+	
+	uint8_t bootcnt=OB->Data0;
+	bootcnt++;
+	FlashOptionData(bootcnt,0);
+	printf("Boot count is %d\n",bootcnt);
+
+	for(;;);
+}
diff --git a/examples/spi_24L01_rx/nrf24l01_low_level.c b/examples/spi_24L01_rx/nrf24l01_low_level.c
index 3d5c21b9e2aa09a314612d864a04c82127f18384..a69547b35744247efa3c956aba07bc7dc1b0ce26 100644
--- a/examples/spi_24L01_rx/nrf24l01_low_level.c
+++ b/examples/spi_24L01_rx/nrf24l01_low_level.c
@@ -1,6 +1,6 @@
 #define SYSTEM_CORE_CLOCK 48000000
 #define APB_CLOCK SYSTEM_CORE_CLOCK
-#include "../../ch32v003fun/ch32v003fun.h"
+#include "ch32v003fun.h"
 
 
 #define CH32V003_SPI_SPEED_HZ 1000000
diff --git a/examples/spi_24L01_rx/spi_24L01_rx.c b/examples/spi_24L01_rx/spi_24L01_rx.c
index 0b20192b71d7272843f9ab316fbfed82b1f9d9d7..f7c81499f04447821be5d236ab141d88fb89f757 100644
--- a/examples/spi_24L01_rx/spi_24L01_rx.c
+++ b/examples/spi_24L01_rx/spi_24L01_rx.c
@@ -6,7 +6,7 @@
 #define SYSTEM_CORE_CLOCK 48000000
 #define APB_CLOCK SYSTEM_CORE_CLOCK
 
-#include "../../ch32v003fun/ch32v003fun.h"
+#include "ch32v003fun.h"
 #include <stdio.h>
 #include "nrf24l01.h"
 
diff --git a/examples/spi_24L01_tx/nrf24l01_low_level.c b/examples/spi_24L01_tx/nrf24l01_low_level.c
index 3d5c21b9e2aa09a314612d864a04c82127f18384..a69547b35744247efa3c956aba07bc7dc1b0ce26 100644
--- a/examples/spi_24L01_tx/nrf24l01_low_level.c
+++ b/examples/spi_24L01_tx/nrf24l01_low_level.c
@@ -1,6 +1,6 @@
 #define SYSTEM_CORE_CLOCK 48000000
 #define APB_CLOCK SYSTEM_CORE_CLOCK
-#include "../../ch32v003fun/ch32v003fun.h"
+#include "ch32v003fun.h"
 
 
 #define CH32V003_SPI_SPEED_HZ 1000000
diff --git a/examples/spi_24L01_tx/spi_24L01_tx.c b/examples/spi_24L01_tx/spi_24L01_tx.c
index 46c5f519431ebfe6d690b4a313e15088dd8b8ecf..16a1c7ee4c73aa698446d48a20cdab072113a58d 100644
--- a/examples/spi_24L01_tx/spi_24L01_tx.c
+++ b/examples/spi_24L01_tx/spi_24L01_tx.c
@@ -6,7 +6,7 @@
 #define SYSTEM_CORE_CLOCK 48000000
 #define APB_CLOCK SYSTEM_CORE_CLOCK
 
-#include "../../ch32v003fun/ch32v003fun.h"
+#include "ch32v003fun.h"
 #include <stdio.h>
 #include "nrf24l01.h"
 
diff --git a/examples/standby_autowake/Makefile b/examples/standby_autowake/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..782271405d709df21ca8a06b9250d2bdf4328c10
--- /dev/null
+++ b/examples/standby_autowake/Makefile
@@ -0,0 +1,11 @@
+all : flash
+
+TARGET:=standby_autowake
+
+CFLAGS+=-DSTDOUT_UART
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
diff --git a/examples/standby_autowake/README.md b/examples/standby_autowake/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..205a20afd4985de0e516aefff821d97d109e04d1
--- /dev/null
+++ b/examples/standby_autowake/README.md
@@ -0,0 +1,19 @@
+# the deepest slumber
+
+This example serves to show how to put the CH32V003 into its lowest power state (standby) and have it wake periodically.  
+
+Power consumption should be around 10uA.  
+
+The MCU only toggles the LED and prints a message, then it goes to sleep.  
+The LED staying on demonstrates that GPIO keeps its state even when the rest of the mcu is in a coma.  
+
+Based on the groundwork of Marek M.  
+
+## time calculations
+
+The autowakeup delay can be calculated by:
+
+`t = AWUWR / (fLSI / AWUPSC)`  
+
+Where AWUWR can be 1 to 63, fLSI is always 128000 and AWUPSC, for practical purposes is 2048, 4096, 10240 or 61440, though lower values are possible.  
+The maximum autowakeup delay is 30s.
diff --git a/examples/standby_autowake/standby_autowake.c b/examples/standby_autowake/standby_autowake.c
new file mode 100644
index 0000000000000000000000000000000000000000..cc0fe4295b82faadc151d4331f38cc43bbea3959
--- /dev/null
+++ b/examples/standby_autowake/standby_autowake.c
@@ -0,0 +1,71 @@
+// based on https://paste.sr.ht/blob/b9b4fb45cbc70f2db7e31a77a6ef7dd2a7f220fb
+// Could be defined here, or in the processor defines.
+#define SYSTEM_CORE_CLOCK 48000000
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+
+#define APB_CLOCK SYSTEM_CORE_CLOCK
+
+/* somehow this ISR won't get called??
+void AWU_IRQHandler( void ) __attribute__((interrupt));
+void AWU_IRQHandler( void ) {
+	GPIOD->OUTDR ^= (1 << 4);
+}
+*/
+
+int main()
+{
+	SystemInit48HSI();
+	SetupUART( UART_BRR );
+
+	printf("\r\n\r\nlow power example\r\n\r\n");
+
+	RCC->APB2PCENR |= RCC_APB2Periph_GPIOD;
+	// GPIO D4 Push-Pull
+	GPIOD->CFGLR &= ~(0xf<<(4*4));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
+	GPIOD->OUTDR |= (1 << 4);
+
+	// give the user time to open the terminal connection
+	//Delay_Ms(5000);
+	printf("5000ms wait over\r\n");
+	
+	// enable power interface module clock
+	RCC->APB1PCENR |= RCC_APB1Periph_PWR;
+
+	// enable low speed oscillator (LSI)
+	RCC->RSTSCKR |= RCC_LSION;
+	while ((RCC->RSTSCKR & RCC_LSIRDY) == 0) {}
+
+	// enable AutoWakeUp event
+	EXTI->EVENR |= EXTI_Line9;
+	EXTI->FTENR |= EXTI_Line9;
+
+	// configure AWU prescaler
+	PWR->AWUPSC |= PWR_AWU_Prescaler_4096;
+
+	// configure AWU window comparison value
+	PWR->AWUWR &= ~0x3f;
+	PWR->AWUWR |= 63;
+
+	// enable AWU
+	PWR->AWUCSR |= (1 << 1);
+
+	// select standby on power-down
+	PWR->CTLR |= PWR_CTLR_PDDS;
+
+	// peripheral interrupt controller send to deep sleep
+	PFIC->SCTLR |= (1 << 2);
+
+	uint16_t counter = 0;
+	printf("entering sleep loop\r\n");
+
+	for (;;) {
+		__WFE();
+		// restore clock to full speed
+		SystemInit48HSI();
+		printf("\r\nawake, %u\r\n", counter++);
+		GPIOD->OUTDR ^= (1 << 4);
+	}
+}
diff --git a/examples/standby_btn/Makefile b/examples/standby_btn/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..36f69f6e37bcf583949d8bbf90a118f928c7a70d
--- /dev/null
+++ b/examples/standby_btn/Makefile
@@ -0,0 +1,11 @@
+all : flash
+
+TARGET:=standby_btn
+
+CFLAGS+=-DSTDOUT_UART
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
diff --git a/examples/standby_btn/README.md b/examples/standby_btn/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..794e8b4ccc30b278904c12658a303c200170b380
--- /dev/null
+++ b/examples/standby_btn/README.md
@@ -0,0 +1,15 @@
+# the deepest slumber
+
+This example serves to show how to put the CH32V003 into its lowest power state (standby) and have it wake with a button press.  
+
+Power consumption should be around 10uA.  
+
+The MCU only toggles the LED and prints a message, then it goes back to sleep.  
+The LED staying on demonstrates that GPIO keeps its state even when the rest of the mcu is in a coma.  
+
+Based on the groundwork of Marek M.  
+
+## circuit
+
+Connect LED to PD4 (with resistor), connect button to GND and PD2.  
+There is no debouncing but it should suffice for waking the chip.
diff --git a/examples/standby_btn/standby_btn.c b/examples/standby_btn/standby_btn.c
new file mode 100644
index 0000000000000000000000000000000000000000..3a6cd7252127df5407fc5ac4ed54cfd9494de913
--- /dev/null
+++ b/examples/standby_btn/standby_btn.c
@@ -0,0 +1,65 @@
+// based on https://paste.sr.ht/blob/b9b4fb45cbc70f2db7e31a77a6ef7dd2a7f220fb
+// Could be defined here, or in the processor defines.
+#define SYSTEM_CORE_CLOCK 48000000
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+
+#define APB_CLOCK SYSTEM_CORE_CLOCK
+
+void EXTI7_0_IRQHandler( void ) __attribute__((interrupt));
+void EXTI7_0_IRQHandler( void ) {
+	//GPIOD->OUTDR ^= (1 << 4);
+}
+
+
+
+int main()
+{
+	SystemInit48HSI();
+	SetupUART( UART_BRR );
+
+	printf("\r\n\r\nlow power example\r\n\r\n");
+
+	RCC->APB2PCENR |= RCC_APB2Periph_GPIOD;
+	// GPIO D4 Push-Pull
+	GPIOD->CFGLR &= ~(0xf<<(4*4));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
+	GPIOD->OUTDR |= (1 << 4);
+
+	// give the user time to open the terminal connection
+	//Delay_Ms(5000);
+	//printf("5000ms wait over\r\n");
+	
+	// enable alternate IO function module clock
+	RCC->APB2PCENR |= RCC_AFIOEN;
+
+	// configure button on PD2 as input, pullup
+	GPIOD->CFGLR &= ~(0xf<<(2*4));
+	GPIOD->CFGLR |= (GPIO_CNF_IN_PUPD)<<(2*4);
+	GPIOD->BSHR = (1 << 2);
+
+	// assign pin 2 interrupt from portD (0b11) to EXTI channel 2
+	AFIO->EXTICR |= (uint32_t)(0b11 << (2 * 2));
+
+	// enable line2 interrupt event
+	EXTI->EVENR |= EXTI_Line2;
+	EXTI->FTENR |= EXTI_Line2;
+
+	// select standby on power-down
+	PWR->CTLR |= PWR_CTLR_PDDS;
+
+	// peripheral interrupt controller send to deep sleep
+	PFIC->SCTLR |= (1 << 2);
+
+	uint16_t counter = 0;
+	printf("entering sleep loop\r\n");
+
+	for (;;) {
+		__WFE();
+		// restore clock to full speed
+		SystemInit48HSI();
+		printf("\r\nawake, %u\r\n", counter++);
+		GPIOD->OUTDR ^= (1 << 4);
+	}
+}
diff --git a/examples/struct_direct_gpio/Makefile b/examples/struct_direct_gpio/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..85f20cd0d48a32047732d23715b103a600daa699
--- /dev/null
+++ b/examples/struct_direct_gpio/Makefile
@@ -0,0 +1,9 @@
+all : flash
+
+TARGET:=struct_direct_gpio
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
diff --git a/examples/struct_direct_gpio/struct_direct_gpio.c b/examples/struct_direct_gpio/struct_direct_gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..9c05c6bf3b6460bd9cb21581870125e53ef913a3
--- /dev/null
+++ b/examples/struct_direct_gpio/struct_direct_gpio.c
@@ -0,0 +1,55 @@
+// This tries to generates exacly the same assambly as direct_gpio but using structs as much as possible
+
+// Could be defined here, or in the processor defines.
+#define SYSTEM_CORE_CLOCK 48000000
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+
+#define APB_CLOCK SYSTEM_CORE_CLOCK
+
+uint32_t count;
+
+int main()
+{
+	SystemInit48HSI();
+
+	// Enable GPIOs
+	RCC->APB2PCENR |= RCC_APB2Periph_GPIOC;
+
+	// this code modifies two fields at the same time
+
+	// GPIO C1 Push-Pull
+	GPIOC->CFGLR &= ~(0xf<<(4*1));
+	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*1);
+	// GPIO C2 Push-Pull
+	GPIOC->CFGLR &= ~(0xf<<(4*2));
+	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*2);
+	// GPIO C4 Push-Pull
+	GPIOC->CFGLR &= ~(0xf<<(4*4));
+	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
+
+	while(1)
+	{
+		// Use low bits of BSHR to SET output
+		DYN_GPIO_WRITE(GPIOC, BSHR, (GPIO_BSHR_t) {.BS1 = 1});
+		DYN_GPIO_WRITE(GPIOC, BSHR, (GPIO_BSHR_t) {.BS2 = 1});
+
+		// Modify the OUTDR register directly to SET output
+		DYN_GPIO_MOD(GPIOC, OUTDR, ODR4, 1);
+		Delay_Ms( 950 );
+
+		// Use upper bits of BSHR to RESET output
+		DYN_GPIO_WRITE(GPIOC, BSHR, (GPIO_BSHR_t) {.BR1 = 1});
+
+		// Use BCR to RESET output
+		DYN_GPIO_WRITE(GPIOC, BCR, (GPIO_BCR_t) {.BR2 = 1});
+
+		// Modify the OUTDR register directly to CLEAR output
+		DYN_GPIO_MOD(GPIOC, OUTDR, ODR4, 0);
+
+		Delay_Ms( 50 );
+		count++;
+	}
+}
+
diff --git a/examples/struct_gpio/Makefile b/examples/struct_gpio/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..82e0f6d0ee54c0fa4c8662f4a5248797d37d031c
--- /dev/null
+++ b/examples/struct_gpio/Makefile
@@ -0,0 +1,9 @@
+all : flash
+
+TARGET:=struct_gpio
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
diff --git a/examples/struct_gpio/struct_gpio.c b/examples/struct_gpio/struct_gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..dee26554c964e1505a474aad4adc34cf35daa53f
--- /dev/null
+++ b/examples/struct_gpio/struct_gpio.c
@@ -0,0 +1,59 @@
+/* Small example showing how to use structs for controling GPIO pins */
+
+#define SYSTEM_CORE_CLOCK 48000000
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+
+#define APB_CLOCK SYSTEM_CORE_CLOCK
+
+uint32_t count;
+
+int main()
+{
+	SystemInit48HSI();
+	SetupDebugPrintf();
+
+	// Enable GPIOs
+	RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC;
+
+	Delay_Ms( 100 );
+
+	// all floating inputs before
+	printf("CFGLR: %lX\n", GPIOD->CFGLR); // -> CFGLR: 44444444
+
+    // GPIO D0, D4 Push-Pull, D1/SWIO floating, default analog input
+	DYN_GPIO_WRITE(GPIOD, CFGLR, (GPIO_CFGLR_t) { // (GPIO_CFGLR_t) is optional but helps vscode with completion
+		.PIN0 = GPIO_CFGLR_OUT_10Mhz_PP,
+		.PIN1 = GPIO_CFGLR_IN_FLOAT,
+		.PIN4 = GPIO_CFGLR_OUT_10Mhz_PP,
+	});
+
+	// all unconfigured pins are now 0b0000, aka analog inputs with TTL Schmitttrigger disabled
+	printf("CFGLR: %lX\n", GPIOD->CFGLR); // -> CFGLR: 10041
+
+	// GPIO C0 Push-Pull
+	// read modify write
+	GPIO_CFGLR_t ioc = DYN_GPIO_READ(GPIOC, CFGLR);
+	ioc.PIN0 = GPIO_CFGLR_OUT_10Mhz_PP,
+	ioc.PIN1 = GPIO_CFGLR_IN_ANALOG;
+	DYN_GPIO_WRITE(GPIOC, CFGLR, ioc);
+
+	while(1)
+	{
+		// Turn D0 on and D4 off at the same time
+		DYN_GPIO_WRITE(GPIOD, BSHR, (GPIO_BSHR_t) {.BS0 = 1, .BR4 = 1});
+
+		// implicit read->modify->write
+		DYN_GPIO_MOD(GPIOC, OUTDR, ODR0, 1);
+		Delay_Ms( 100 );
+
+		// Turn D0 off and D4 on at the same time
+		DYN_GPIO_WRITE(GPIOD, BSHR, (GPIO_BSHR_t) {.BR0 = 1, .BS4 = 1});
+
+		// implicit read->modify->write
+		DYN_GPIO_MOD(GPIOC, OUTDR, ODR0, 0);
+		Delay_Ms( 100 );
+	}
+}
+
diff --git a/examples/tim2_pwm/.gdbinit b/examples/tim2_pwm/.gdbinit
new file mode 100644
index 0000000000000000000000000000000000000000..427595ae0e4d2332e7e580facfd2c4327e8441c6
--- /dev/null
+++ b/examples/tim2_pwm/.gdbinit
@@ -0,0 +1,2 @@
+file tim1_pwm.elf
+target extended-remote localhost:3333
diff --git a/examples/tim2_pwm/Makefile b/examples/tim2_pwm/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..7b3d0c031265e2b750553f45da8dfce649a99c68
--- /dev/null
+++ b/examples/tim2_pwm/Makefile
@@ -0,0 +1,11 @@
+all : flash
+
+TARGET:=tim2_pwm
+
+CFLAGS+=-DSTDOUT_UART
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
diff --git a/examples/tim2_pwm/README.md b/examples/tim2_pwm/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..36c81a1f41d8414c953a7060f43aaeb94e3282ce
--- /dev/null
+++ b/examples/tim2_pwm/README.md
@@ -0,0 +1,6 @@
+# Demonstration of PWM using Timer 2
+This example shows how to set up Timer 2 (the General Purpose Timer) to generate Pulse-Width Modulation (PWM) on two output pins.
+PWM is frequently used to do variable brightness on LEDs or for digital-to-analog conversion when combined with a suitable lowpass filter.
+
+## Use
+Connect GPIO pins PD04 and PD3 to LEDs (with appropriate current limiting) and observe that they fade at the same speed, but phase-rotatd by 180°.
diff --git a/examples/tim2_pwm/debug.sh b/examples/tim2_pwm/debug.sh
new file mode 100755
index 0000000000000000000000000000000000000000..bb05a9465959cb153fad95bba4b2175667830528
--- /dev/null
+++ b/examples/tim2_pwm/debug.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# before running this you should start OOCD server
+#../../../MRS_Toolchain_Linux_x64_V1.70/OpenOCD/bin/openocd -f ../../../MRS_Toolchain_Linux_x64_V1.70/OpenOCD/bin/wch-riscv.cfg
+ 
+../../../MRS_Toolchain_Linux_x64_V1.70/RISC-V\ Embedded\ GCC/bin/riscv-none-embed-gdb
diff --git a/examples/tim2_pwm/tim2_pwm.c b/examples/tim2_pwm/tim2_pwm.c
new file mode 100644
index 0000000000000000000000000000000000000000..37e949d727dfd01883b1271ff9bb9e41bac54b36
--- /dev/null
+++ b/examples/tim2_pwm/tim2_pwm.c
@@ -0,0 +1,131 @@
+/*
+ * Example for using Advanced Control Timer (TIM2) for PWM generation
+ * 03-28-2023 E. Brombaugh
+ * 05-29-2023 recallmenot adapted from Timer1 to Timer2
+ */
+
+/*
+Timer 2 pin mappings by AFIO->PCFR1
+	00 (default)
+		D4		T2CH1ETR
+		D3		T2CH2
+		C0		T2CH3
+		D7		T2CH4
+	01
+		C5		T2CH1ETR_
+		C2		T2CH2_
+		D2		T2CH3_
+		C1		T2CH4_
+	10
+		C1		T2CH1ETR_
+		D3		T2CH2
+		C0		T2CH3
+		D7		T2CH4
+	11
+		C1		T2CH1ETR_
+		C7		T2CH2_
+		D6		T2CH3_
+		D5		T2CH4_
+*/
+
+// Could be defined here, or in the processor defines.
+#define SYSTEM_CORE_CLOCK 48000000
+#define APB_CLOCK SYSTEM_CORE_CLOCK
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+
+/*
+ * initialize TIM2 for PWM
+ */
+void t2pwm_init( void )
+{
+	// Enable GPIOD and TIM2
+	RCC->APB2PCENR |= RCC_APB2Periph_GPIOD;
+	RCC->APB1PCENR |= RCC_APB1Periph_TIM2;
+
+	// PD4 is T2CH1, 10MHz Output alt func, push-pull
+	GPIOD->CFGLR &= ~(0xf<<(4*4));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*4);
+	
+	// PD3 is T2CH2, 10MHz Output alt func, push-pull
+	GPIOD->CFGLR &= ~(0xf<<(4*3));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*3);
+		
+	// Reset TIM2 to init all regs
+	RCC->APB1PRSTR |= RCC_APB1Periph_TIM2;
+	RCC->APB1PRSTR &= ~RCC_APB1Periph_TIM2;
+	
+	// SMCFGR: default clk input is CK_INT
+	// set TIM2 clock prescaler divider 
+	TIM2->PSC = 0x0000;
+	// set PWM total cycle width
+	TIM2->ATRLR = 255;
+	
+	// for channel 1 and 2, let CCxS stay 00 (output), set OCxM to 110 (PWM I)
+	// enabling preload causes the new pulse width in compare capture register only to come into effect when UG bit in SWEVGR is set (= initiate update) (auto-clears)
+	TIM2->CHCTLR1 |= TIM_OC1M_2 | TIM_OC1M_1 | TIM_OC1PE | TIM_OC2M_2 | TIM_OC2M_1 | TIM_OC2PE;
+
+	// CTLR1: default is up, events generated, edge align
+	// enable auto-reload of preload
+	TIM2->CTLR1 |= TIM_ARPE;
+
+	// Enable CH1 output, positive pol
+	TIM2->CCER |= TIM_CC1E | TIM_CC1P;
+	// Enable CH2 output, positive pol
+	TIM2->CCER |= TIM_CC2E | TIM_CC2P;
+
+	// initialize counter
+	TIM2->SWEVGR |= TIM_UG;
+
+	// Enable TIM2
+	TIM2->CTLR1 |= TIM_CEN;
+}
+
+
+/*
+ * set timer channel PW
+ */
+void t2pwm_setpw(uint8_t chl, uint16_t width)
+{
+	switch(chl&3)
+	{
+		case 0: TIM2->CH1CVR = width; break;
+		case 1: TIM2->CH2CVR = width; break;
+		case 2: TIM2->CH3CVR = width; break;
+		case 3: TIM2->CH4CVR = width; break;
+	}
+	TIM2->SWEVGR |= TIM_UG; // load new value in compare capture register
+}
+
+
+
+/*
+ * entry
+ */
+int main()
+{
+	uint32_t count = 0;
+	
+	SystemInit48HSI();
+
+	// start serial @ default 115200bps
+	SetupUART( UART_BRR );
+	Delay_Ms( 100 );
+	printf("\r\r\n\ntim2_pwm example\n\r");
+
+	// init TIM2 for PWM
+	printf("initializing tim2...");
+	t2pwm_init();
+	printf("done.\n\r");
+		
+	printf("looping...\n\r");
+	while(1)
+	{
+		t2pwm_setpw(0, count);			// Chl 1
+		t2pwm_setpw(1, (count + 128)&255);	// Chl 2 180° out-of-phase
+		count++;
+		count &= 255;
+		Delay_Ms( 5 );
+	}
+}
diff --git a/examples/tim2_pwm_remap/Makefile b/examples/tim2_pwm_remap/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..36df10e860825f2e0d005debbe3cbcb791b2b591
--- /dev/null
+++ b/examples/tim2_pwm_remap/Makefile
@@ -0,0 +1,10 @@
+all : flash
+
+TARGET:=tim2_pwm_remap
+
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
diff --git a/examples/tim2_pwm_remap/tim2_pwm_remap.c b/examples/tim2_pwm_remap/tim2_pwm_remap.c
new file mode 100644
index 0000000000000000000000000000000000000000..1d2c4bbfa43fab930c8ccdbd69b776b7e84e33dd
--- /dev/null
+++ b/examples/tim2_pwm_remap/tim2_pwm_remap.c
@@ -0,0 +1,175 @@
+/*
+ * Example for using AFIO to remap peripheral outputs to alternate configuration
+ * 06-01-2023 B. Roy, based on previous work by:
+ * 03-28-2023 E. Brombaugh
+ * 05-29-2023 recallmenot adapted from Timer1 to Timer2
+ *
+ * Usage: 
+ * Connect LEDs between PD3 and GND, PD4 and GND, PC1 and GND, and PC7 and GND
+ * Observe activity on PD3 and PD4, then activity on PC1 and PC7, and back
+ *
+ * Nutshell:
+ * 1. Ensure you're providing a clock to the AFIO peripheral! Save yourself an 
+ * 	hour of troubleshooting!
+ *	RCC->APB2PCENR |= RCC_APB2Periph_AFIO
+ * 2. Apply the remapping configuration bits to the AFIO register:
+ * 	AFIO->PCFR1 |= AFIO_PCFR1_TIM2_REMAP_FULLREMAP
+ * 3. Go on about your business.
+ *
+ * /
+
+
+Timer 2 pin mappings by AFIO->PCFR1
+	00	AFIO_PCFR1_TIM2_REMAP_NOREMAP
+		D4		T2CH1ETR
+		D3		T2CH2
+		C0		T2CH3
+		D7		T2CH4  --note: requires disabling nRST in opt
+	01	AFIO_PCFR1_TIM2_REMAP_PARTIALREMAP1
+		C5		T2CH1ETR_
+		C2		T2CH2_
+		D2		T2CH3_
+		C1		T2CH4_
+	10	AFIO_PCFR1_TIM2_REMAP_PARTIALREMAP2
+		C1		T2CH1ETR_
+		D3		T2CH2
+		C0		T2CH3
+		D7		T2CH4  --note: requires disabling nRST in opt
+	11	AFIO_PCFR1_TIM2_REMAP_FULLREMAP
+		C1		T2CH1ETR_
+		C7		T2CH2_
+		D6		T2CH3_
+		D5		T2CH4_
+*/
+
+// Could be defined here, or in the processor defines.
+#define SYSTEM_CORE_CLOCK 48000000
+#define APB_CLOCK SYSTEM_CORE_CLOCK
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+
+/******************************************************************************************
+ * initialize TIM2 for PWM
+ ******************************************************************************************/
+void t2pwm_init( void )
+{
+	// Enable GPIOC, GPIOD, TIM2, and AFIO *very important!*
+	RCC->APB2PCENR |= RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC;
+	RCC->APB1PCENR |= RCC_APB1Periph_TIM2;
+
+	// PD4 is T2CH1, 10MHz Output alt func, push-pull (also works in oepn drain OD_AF)
+	GPIOD->CFGLR &= ~(0xf<<(4*4));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*4);
+
+	// PD3 is T2CH2, 10MHz Output alt func, push-pull (also works in oepn drain OD_AF)
+	GPIOD->CFGLR &= ~(0xf<<(4*3));
+	GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*3);
+
+	// PC1 is T2CH1_, 10MHz Output alt func, push-pull (also works in oepn drain OD_AF)
+	GPIOC->CFGLR &= ~(0xf<<(4*1));
+	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*1);
+
+	// PC7 is T2CH2_, 10MHz Output alt func, push-pull (also works in oepn drain OD_AF)
+	GPIOC->CFGLR &= ~(0xf<<(4*7));
+	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*7);
+	
+	// Reset TIM2 to init all regs
+	RCC->APB1PRSTR |= RCC_APB1Periph_TIM2;
+	RCC->APB1PRSTR &= ~RCC_APB1Periph_TIM2;
+	
+	// SMCFGR: default clk input is CK_INT
+	// set TIM2 clock prescaler divider 
+	TIM2->PSC = 0x0000;
+	// set PWM total cycle width
+	TIM2->ATRLR = 255;
+	
+	// for channel 1 and 2, let CCxS stay 00 (output), set OCxM to 110 (PWM I)
+	// enabling preload causes the new pulse width in compare capture register only to come into effect when UG bit in SWEVGR is set (= initiate update) (auto-clears)
+	TIM2->CHCTLR1 |= TIM_OC1M_2 | TIM_OC1M_1 | TIM_OC1PE;
+	TIM2->CHCTLR1 |= TIM_OC2M_2 | TIM_OC2M_1 | TIM_OC2PE;
+
+	// CTLR1: default is up, events generated, edge align
+	// enable auto-reload of preload
+	TIM2->CTLR1 |= TIM_ARPE;
+
+	// Enable CH1 output, positive pol
+	TIM2->CCER |= TIM_CC1E | TIM_CC1P;
+	// Enable CH2 output, positive pol
+	TIM2->CCER |= TIM_CC2E | TIM_CC2P;
+
+	// initialize counter
+	TIM2->SWEVGR |= TIM_UG;
+
+	// Enable TIM2
+	TIM2->CTLR1 |= TIM_CEN;
+}
+
+/*****************************************************************************************
+ * set timer channel PW
+ *****************************************************************************************/
+void t2pwm_setpw(uint8_t chl, uint16_t width)
+{
+	switch(chl&3)
+	{
+		case 0: TIM2->CH1CVR = width; break;
+		case 1: TIM2->CH2CVR = width; break;
+		case 2: TIM2->CH3CVR = width; break;
+		case 3: TIM2->CH4CVR = width; break;
+	}
+	TIM2->SWEVGR |= TIM_UG; // load new value in compare capture register
+}
+
+/*****************************************************************************************
+ * Remap T1CH1/T1CH2 from PD4/PD3 to PC1/PC7
+ *
+ * Can remap on-the fly; no need to re-initialize timers, reset GPIO mode/config, etc.
+ *
+ * Leaves the previous pins configured as 'alternate function' mode - i.e. disconnected
+ * from the GPIO peripheral, and floating.
+ *
+ *****************************************************************************************/
+void ToggleRemap(void) {
+	if(AFIO->PCFR1 & AFIO_PCFR1_TIM2_REMAP_FULLREMAP) {
+		AFIO->PCFR1 &= AFIO_PCFR1_TIM2_REMAP_NOREMAP;   //clear remapping bits
+		printf("Standard Mapping!\r\n");
+	}
+	else {
+		AFIO->PCFR1 |= AFIO_PCFR1_TIM2_REMAP_FULLREMAP; //set fullremap mode
+		printf("Full Remapping!\r\n");
+	}
+};
+
+/*****************************************************************************************
+ * entry
+ *****************************************************************************************/
+int main()
+{
+	uint32_t count = 0;
+	
+	SystemInit48HSI();
+
+	// start serial @ default 115200bps
+	SetupDebugPrintf();
+
+	Delay_Ms( 100 );
+	printf("\r\r\n\ntim2_pwm example, with remap\n\r");
+
+	// init TIM2 for PWM
+	printf("initializing tim2...");
+	t2pwm_init();
+	printf("done.\n\r");
+		
+	printf("looping...\n\r");
+	
+	while(1)
+	{
+		for(;count<255;count++){
+			t2pwm_setpw(0, count);		// Chl 1
+			t2pwm_setpw(1, 255-count);	// Chl 2 180° out-of-phase
+			Delay_Ms( 5 );
+		}
+		count = 0;
+		ToggleRemap();
+	}
+}
diff --git a/examples/ws2812bdemo/ws2812bdemo.c b/examples/ws2812bdemo/ws2812bdemo.c
index 985c20b8b1d88bb5e70982dfbb8d20f18bb41db2..2f462d0f1cbddba7e7a399299c752c58d45c98f8 100644
--- a/examples/ws2812bdemo/ws2812bdemo.c
+++ b/examples/ws2812bdemo/ws2812bdemo.c
@@ -2,12 +2,15 @@
 #define SYSTEM_CORE_CLOCK 48000000
 #define APB_CLOCK SYSTEM_CORE_CLOCK
 
+// NOTE: CONNECT WS2812's to PC6
+
 #include "ch32v003fun.h"
 #include <stdio.h>
 #include <string.h>
 
 #define WS2812DMA_IMPLEMENTATION
-#define WSRBG //For WS2816C's.
+//#define WSRBG //For WS2816C's.
+#define WSGRB // For SK6805-EC15
 #define NR_LEDS 191
 
 #include "ws2812b_dma_spi_led_driver.h"
diff --git a/extralibs/ch32v003_GPIO_branchless.h b/extralibs/ch32v003_GPIO_branchless.h
new file mode 100644
index 0000000000000000000000000000000000000000..728ee001044175d82084a7c25c478f5723630345
--- /dev/null
+++ b/extralibs/ch32v003_GPIO_branchless.h
@@ -0,0 +1,476 @@
+// 2023-06-07 recallmenot
+
+//######## necessities
+
+// include guards
+#ifndef CH32V003_GPIO_BR_H
+#define CH32V003_GPIO_BR_H
+
+// includes
+#include <stdint.h>								//uintN_t support
+#include "../ch32v003fun/ch32v003fun.h"
+
+
+
+/*######## library description
+This is a speedy and light GPIO library due to
+	static inlining of most functions
+	compile-time abstraction
+	branchless where it counts
+*/
+
+
+
+/*######## library usage and configuration
+
+first, enable the desired port.
+
+digital usage is quite Arduino-like:
+pinMode
+digitalWrite
+digitalWrite_lo
+digitalWrite_hi
+digitalRead
+
+
+
+analog-to-digital usage is almost Arduino-like:
+pinMode
+ADCinit
+analogRead
+
+By default, this library inserts a delay of 300 µs between configuration of the ADC input mux and the time the conversion starts.
+This serves to counteract the high input impedance of the ADC, especially if it is increased by external resistors.
+The input impedance of port A appears to be especially large.
+You may modify it to your liking using the following define before including this library.
+#define GPIO_ADC_MUX_DELAY 1200
+
+GPIO_ADC_sampletime controls the time each conversion is granted, by default it is GPIO_ADC_sampletime_241cy_default, all options originate from the GPIO_ADC_sampletimes enum.
+To alter it, you have 3 options:
+ * `#define GPIO_ADC_sampletime GPIO_ADC_sampletime_43cy` before including this library
+ * call the GPIO_ADC_set_sampletime function-like macro to momentarrily set it for one channel
+ * call the GPIO_ADC_set_sampletimes_all function-like macro to to momentarrily set it for all channels
+
+You may also disable the ADC to save power between infrequent measurements.
+
+
+
+digital-to-analog (PWM) usage is quite different:
+pinMode
+GPIO_timX_map
+GPIO_timX_init
+GPIO_timX_enableCH
+GPIO_timX_analogWrite
+
+This is due to the fact that the CH32V003 has 2 timers, which each can be connected to 4 pre-defined sets (mappings) of pins.
+Then you address the 4 channels of the timers, instead of the pins.
+
+By default, the timers will be configured to count up to 2^10, which is 10 bits or 1024 discrete steps.
+You may alter this to suit your needs, for example to an 8 bit resolution (256 discrete steps).
+Insert this before including this library:
+#define GPIO_timer_resolution (1 << 8)
+
+By default, the timers will operate with a clock prescaler of 2 but you may choose 1 or 4 if you wish to alter the speed.
+Insert this before including this library:
+#define GPIO_timer_prescaler TIM_CKD_DIV1;		// APB_CLOCK / 1024 / 1 = 46.9kHz
+
+You may calculate the base frequency of the timer (the rate of repetition of your signal) like follows:
+fpwm = APB_CLOCK / resolution / prescaler
+This puts the defaults at an inaudible 23.4kHz.
+The higher the frequency, the greater the EMI radiation will be.
+With low frequencies, say below 1000Hz, LEDs may exhibit perceivable flicker.
+
+Since this library enables compare capture preload (OCxPE of CHCTLRy), writing a value into the compare register using analogWrite will automatically apply it (=load into shadow register) when the timer starts its next cycle.
+This avoids a bug whereby writing a compare value lower than the current counter value, the output will glitch high for the next cycle, resulting in flickery updates.
+Writing `TIMx->SWEVGR |= TIM_UG` will immediately update the shadow register and cause the same issue.
+
+*/
+
+
+
+//######## ports, pins and states: use these for the functions below!
+
+enum GPIO_port_n {
+	GPIO_port_A = 0b00,
+	GPIO_port_C = 0b10,
+	GPIO_port_D = 0b11,
+};
+
+enum GPIO_pinModes {
+	GPIO_pinMode_I_floating,
+	GPIO_pinMode_I_pullUp,
+	GPIO_pinMode_I_pullDown,
+	GPIO_pinMode_I_analog,
+	GPIO_pinMode_O_pushPull,
+	GPIO_pinMode_O_openDrain,
+	GPIO_pinMode_O_pushPullMux,
+	GPIO_pinMode_O_openDrainMux,
+};
+
+enum lowhigh {
+	low,
+	high,
+};
+
+// analog inputs
+enum GPIO_analog_inputs {
+	GPIO_Ain0_A2,
+	GPIO_Ain1_A1,
+	GPIO_Ain2_C4,
+	GPIO_Ain3_D2,
+	GPIO_Ain4_D3,
+	GPIO_Ain5_D5,
+	GPIO_Ain6_D6,
+	GPIO_Ain7_D4,
+	GPIO_AinVref,
+	GPIO_AinVcal,
+};
+
+// how many cycles the ADC shall sample the input for (speed vs precision)
+enum GPIO_ADC_sampletimes {
+	GPIO_ADC_sampletime_3cy,
+	GPIO_ADC_sampletime_9cy,
+	GPIO_ADC_sampletime_15cy,
+	GPIO_ADC_sampletime_30cy,
+	GPIO_ADC_sampletime_43cy,
+	GPIO_ADC_sampletime_57cy,
+	GPIO_ADC_sampletime_73cy,
+	GPIO_ADC_sampletime_241cy_default,
+};
+
+enum GPIO_tim1_output_sets {
+	GPIO_tim1_output_set_0__D2_A1_C3_C4__D0_A2_D1,
+	GPIO_tim1_output_set_1__C6_C7_C0_D3__C3_C4_D1,
+	GPIO_tim1_output_set_2__D2_A1_C3_C4__D0_A2_D1,
+	GPIO_tim1_output_set_3__C4_C7_C5_D4__C3_D2_C6,
+};
+
+enum GPIO_tim2_output_sets {
+	GPIO_tim2_output_set_0__D4_D3_C0_D7,
+	GPIO_tim2_output_set_1__C5_C2_D2_C1,
+	GPIO_tim2_output_set_2__C1_D3_C0_D7,
+	GPIO_tim2_output_set_3__C1_C7_D6_D5,
+};
+
+
+
+//######## interface function overview: use these!
+// most functions have been reduced to function-like macros, actual definitions downstairs
+
+// setup
+#define GPIO_portEnable(GPIO_port_n)
+#define GPIO_pinMode(GPIO_port_n, pin, pinMode, GPIO_Speed)
+
+// digital
+#define GPIO_digitalWrite_hi(GPIO_port_n, pin)
+#define GPIO_digitalWrite_lo(GPIO_port_n, pin)
+#define GPIO_digitalWrite(GPIO_port_n, pin, lowhigh)
+#define GPIO_digitalWrite_branching(GPIO_port_n, pin, lowhigh)
+#define GPIO_digitalRead(GPIO_port_n, pin)
+
+// analog to digital
+static inline void GPIO_ADCinit();
+#define GPIO_ADC_set_sampletime(GPIO_analog_input, GPIO_ADC_sampletime)
+#define GPIO_ADC_set_sampletimes_all(GPIO_ADC_sampletime)
+#define GPIO_ADC_set_power(enable)
+#define GPIO_ADC_calibrate()
+static inline uint16_t GPIO_analogRead(enum GPIO_analog_inputs input);
+
+// digital to analog (PWM)
+#define GPIO_tim1_map(GPIO_tim1_output_set)
+#define GPIO_tim2_map(GPIO_tim2_output_set)
+static inline void GPIO_tim1_init();
+static inline void GPIO_tim2_init();
+#define GPIO_tim1_enableCH(channel)
+#define GPIO_tim2_enableCH(channel)
+#define GPIO_tim1_analogWrite(channel, value)
+#define GPIO_tim2_analogWrite(channel, value)
+
+
+
+//######## internal function declarations
+
+
+
+//######## internal variables
+
+
+
+//######## preprocessor macros
+
+#define CONCAT(a, b) a ## b
+#define CONCAT_INDIRECT(a, b) CONCAT(a, b)
+
+#define GPIOx_to_port_n2(GPIOx)				GPIOx_to_port_n_##GPIOx
+#define GPIOx_to_port_n(GPIOx)				GPIOx_to_port_n2(GPIOx)
+#define GPIOx_to_port_n_GPIO_port_A			0b00
+#define GPIOx_to_port_n_GPIO_port_C			0b10
+#define GPIOx_to_port_n_GPIO_port_D			0b11
+
+#define GPIO_port_n_to_GPIOx2(GPIO_port_n)		GPIO_port_n_to_GPIOx_##GPIO_port_n
+#define GPIO_port_n_to_GPIOx(GPIO_port_n)		GPIO_port_n_to_GPIOx2(GPIO_port_n)
+#define GPIO_port_n_to_GPIOx_GPIO_port_A		GPIOA
+#define GPIO_port_n_to_GPIOx_GPIO_port_C		GPIOC
+#define GPIO_port_n_to_GPIOx_GPIO_port_D		GPIOD
+
+#define GPIO_port_n_to_RCC_APB2Periph2(GPIO_port_n)	GPIO_port_n_to_RCC_APB2Periph_##GPIO_port_n
+#define GPIO_port_n_to_RCC_APB2Periph(GPIO_port_n)	GPIO_port_n_to_RCC_APB2Periph2(GPIO_port_n)
+#define GPIO_port_n_to_RCC_APB2Periph_GPIO_port_A	RCC_APB2Periph_GPIOA
+#define GPIO_port_n_to_RCC_APB2Periph_GPIO_port_C	RCC_APB2Periph_GPIOC
+#define GPIO_port_n_to_RCC_APB2Periph_GPIO_port_D	RCC_APB2Periph_GPIOD
+
+#define GPIO_pinMode_to_CFG2(GPIO_pinMode, GPIO_Speed)				GPIO_pinMode_to_CFG_##GPIO_pinMode(GPIO_Speed)
+#define GPIO_pinMode_to_CFG(GPIO_pinMode, GPIO_Speed)				GPIO_pinMode_to_CFG2(GPIO_pinMode, GPIO_Speed)
+#define GPIO_pinMode_to_CFG_GPIO_pinMode_I_floating(GPIO_Speed)			(GPIO_SPEED_IN	| GPIO_CNF_IN_FLOATING)
+#define GPIO_pinMode_to_CFG_GPIO_pinMode_I_pullUp(GPIO_Speed)			(GPIO_SPEED_IN	| GPIO_CNF_IN_PUPD)
+#define GPIO_pinMode_to_CFG_GPIO_pinMode_I_pullDown(GPIO_Speed)			(GPIO_SPEED_IN	| GPIO_CNF_IN_PUPD)
+#define GPIO_pinMode_to_CFG_GPIO_pinMode_I_analog(GPIO_Speed)			(GPIO_SPEED_IN	| GPIO_CNF_IN_ANALOG)
+#define GPIO_pinMode_to_CFG_GPIO_pinMode_O_pushPull(GPIO_Speed)			(GPIO_Speed	| GPIO_CNF_OUT_PP)
+#define GPIO_pinMode_to_CFG_GPIO_pinMode_O_openDrain(GPIO_Speed)		(GPIO_Speed	| GPIO_CNF_OUT_OD)
+#define GPIO_pinMode_to_CFG_GPIO_pinMode_O_pushPullMux(GPIO_Speed)		(GPIO_Speed	| GPIO_CNF_OUT_PP_AF)
+#define GPIO_pinMode_to_CFG_GPIO_pinMode_O_openDrainMux(GPIO_Speed)		(GPIO_Speed	| GPIO_CNF_IN_ANALOG)
+
+#define GPIO_pinMode_set_PUPD2(GPIO_pinMode, GPIO_port_n, pin)			GPIO_pinMode_set_PUPD_##GPIO_pinMode(GPIO_port_n, pin)
+#define GPIO_pinMode_set_PUPD(GPIO_pinMode, GPIO_port_n, pin)			GPIO_pinMode_set_PUPD2(GPIO_pinMode, GPIO_port_n, pin)
+#define GPIO_pinMode_set_PUPD_GPIO_pinMode_I_floating(GPIO_port_n, pin)
+#define GPIO_pinMode_set_PUPD_GPIO_pinMode_I_pullUp(GPIO_port_n, pin)		GPIO_port_n_to_GPIOx(GPIO_port_n)->BSHR = (1 << pin)
+#define GPIO_pinMode_set_PUPD_GPIO_pinMode_I_pullDown(GPIO_port_n, pin)		GPIO_port_n_to_GPIOx(GPIO_port_n)->BSHR = (1 << (pin + 16))
+#define GPIO_pinMode_set_PUPD_GPIO_pinMode_I_analog(GPIO_port_n, pin)
+#define GPIO_pinMode_set_PUPD_GPIO_pinMode_O_pushPull(GPIO_port_n, pin)
+#define GPIO_pinMode_set_PUPD_GPIO_pinMode_O_openDrain(GPIO_port_n, pin)
+#define GPIO_pinMode_set_PUPD_GPIO_pinMode_O_pushPullMux(GPIO_port_n, pin)
+#define GPIO_pinMode_set_PUPD_GPIO_pinMode_O_openDrainMux(GPIO_port_n, pin)
+
+#if !defined(GPIO_ADC_MUX_DELAY)
+#define GPIO_ADC_MUX_DELAY 200
+#endif
+
+#if !defined(GPIO_ADC_sampletime)
+#define GPIO_ADC_sampletime GPIO_ADC_sampletime_241cy_default
+#endif
+
+#if !defined(GPIO_timer_resolution)
+#define GPIO_timer_resolution (1 << 10)
+#endif
+
+#if !defined(GPIO_timer_prescaler)
+#define GPIO_timer_prescaler TIM_CKD_DIV2		// APB_CLOCK / 1024 / 2 = 23.4kHz
+#endif
+
+// maintenance define
+#if !defined(SYSTEM_CORE_CLOCK)
+#define SYSTEM_CORE_CLOCK 48000000
+#define APB_CLOCK SYSTEM_CORE_CLOCK
+#endif
+
+
+
+//######## define requirements / maintenance defines
+
+
+
+//######## small function definitions, static inline
+
+
+#undef GPIO_portEnable
+#define GPIO_portEnable(GPIO_port_n) RCC->APB2PCENR |= GPIO_port_n_to_RCC_APB2Periph(GPIO_port_n);
+
+#undef GPIO_pinMode
+#define GPIO_pinMode(GPIO_port_n, pin, pinMode, GPIO_Speed) ({							\
+	GPIO_port_n_to_GPIOx(GPIO_port_n)->CFGLR &= ~(0b1111 << (4 * pin));					\
+	GPIO_port_n_to_GPIOx(GPIO_port_n)->CFGLR |= (GPIO_pinMode_to_CFG(pinMode, GPIO_Speed) << (4 * pin));	\
+	GPIO_pinMode_set_PUPD(pinMode, GPIO_port_n, pin);							\
+})
+
+#undef GPIO_digitalWrite_hi
+#define GPIO_digitalWrite_hi(GPIO_port_n, pin)		GPIO_port_n_to_GPIOx(GPIO_port_n)->BSHR = (1 << pin)
+#undef GPIO_digitalWrite_lo
+#define GPIO_digitalWrite_lo(GPIO_port_n, pin)		GPIO_port_n_to_GPIOx(GPIO_port_n)->BSHR = (1 << (pin + 16))
+
+#undef GPIO_digitalWrite
+#define GPIO_digitalWrite2(GPIO_port_n, pin, lowhigh)	GPIO_digitalWrite_##lowhigh(GPIO_port_n, pin)
+#define GPIO_digitalWrite(GPIO_port_n, pin, lowhigh)	GPIO_digitalWrite2(GPIO_port_n, pin, lowhigh)
+#define GPIO_digitalWrite_low(GPIO_port_n, pin)		GPIO_digitalWrite_lo(GPIO_port_n, pin)
+#define GPIO_digitalWrite_0(GPIO_port_n, pin)		GPIO_digitalWrite_lo(GPIO_port_n, pin)
+#define GPIO_digitalWrite_high(GPIO_port_n, pin)	GPIO_digitalWrite_hi(GPIO_port_n, pin)
+#define GPIO_digitalWrite_1(GPIO_port_n, pin)		GPIO_digitalWrite_hi(GPIO_port_n, pin)
+
+#undef GPIO_digitalWrite_branching
+#define GPIO_digitalWrite_branching(GPIO_port_n, pin, lowhigh)		(lowhigh ? GPIO_digitalWrite_hi(GPIO_port_n, pin) : GPIO_digitalWrite_lo(GPIO_port_n, pin))
+
+#undef GPIO_digitalRead
+#define GPIO_digitalRead(GPIO_port_n, pin)	 	((GPIO_port_n_to_GPIOx(GPIO_port_n)->INDR >> pin) & 0b1)
+
+
+#undef GPIO_ADC_set_sampletime
+// 0:7 => 3/9/15/30/43/57/73/241 cycles
+#define GPIO_ADC_set_sampletime(GPIO_analog_input, GPIO_ADC_sampletime) ({	\
+	ADC1->SAMPTR2 &= ~(0b111) << (3 * GPIO_analog_input);			\
+	ADC1->SAMPTR2 |= GPIO_ADC_sampletime << (3 * GPIO_analog_input);	\
+})
+
+#undef GPIO_ADC_set_sampletimes_all
+#define GPIO_ADC_set_sampletimes_all(GPIO_ADC_sampletime) ({	\
+	ADC1->SAMPTR2 &= 0;					\
+	ADC1->SAMPTR2 |=					\
+			GPIO_ADC_sampletime << (0 * 3)		\
+		|	GPIO_ADC_sampletime << (1 * 3)		\
+		|	GPIO_ADC_sampletime << (2 * 3)		\
+		|	GPIO_ADC_sampletime << (3 * 3)		\
+		|	GPIO_ADC_sampletime << (4 * 3)		\
+		|	GPIO_ADC_sampletime << (5 * 3)		\
+		|	GPIO_ADC_sampletime << (6 * 3)		\
+		|	GPIO_ADC_sampletime << (7 * 3)		\
+		|	GPIO_ADC_sampletime << (8 * 3)		\
+		|	GPIO_ADC_sampletime << (9 * 3);		\
+	ADC1->SAMPTR1 &= 0;					\
+	ADC1->SAMPTR1 |=					\
+			GPIO_ADC_sampletime << (0 * 3)		\
+		|	GPIO_ADC_sampletime << (1 * 3)		\
+		|	GPIO_ADC_sampletime << (2 * 3)		\
+		|	GPIO_ADC_sampletime << (3 * 3)		\
+		|	GPIO_ADC_sampletime << (4 * 3)		\
+		|	GPIO_ADC_sampletime << (5 * 3);		\
+})
+
+#undef GPIO_ADC_set_power
+#define GPIO_ADC_set_power2(enable) GPIO_ADC_set_power_##enable
+#define GPIO_ADC_set_power(enable) GPIO_ADC_set_power2(enable)
+#define GPIO_ADC_set_power_1 ADC1->CTLR2 |= ADC_ADON
+#define GPIO_ADC_set_power_0 ADC1->CTLR2 &= ~(ADC_ADON)
+
+#undef GPIO_ADC_calibrate
+#define GPIO_ADC_calibrate() ({			\
+	ADC1->CTLR2 |= ADC_RSTCAL;		\
+	while(ADC1->CTLR2 & ADC_RSTCAL);	\
+	ADC1->CTLR2 |= ADC_CAL;			\
+	while(ADC1->CTLR2 & ADC_CAL);		\
+})
+
+// large but will likely only ever be called once
+static inline void GPIO_ADCinit() {
+	// select ADC clock source
+	// ADCCLK = 24 MHz => RCC_ADCPRE = 0: divide by 2
+	RCC->CFGR0 &= ~(0x1F<<11);
+
+	// enable clock to the ADC
+	RCC->APB2PCENR |= RCC_APB2Periph_ADC1;
+
+	// Reset the ADC to init all regs
+	RCC->APB2PRSTR |= RCC_APB2Periph_ADC1;
+	RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1;
+
+	// set sampling time for all inputs to 241 cycles
+	GPIO_ADC_set_sampletimes_all(GPIO_ADC_sampletime);
+
+	// set trigger to software
+	ADC1->CTLR2 |= ADC_EXTSEL;
+
+	// pre-clear conversion queue
+	ADC1->RSQR1 = 0;
+	ADC1->RSQR2 = 0;
+	ADC1->RSQR3 = 0;
+
+	// power the ADC
+	GPIO_ADC_set_power(1);
+	GPIO_ADC_calibrate();
+}
+
+static inline uint16_t GPIO_analogRead(enum GPIO_analog_inputs input) {
+	// set mux to selected input
+	ADC1->RSQR3 = input;
+	// allow everything to precharge
+	Delay_Us(GPIO_ADC_MUX_DELAY);
+	// start sw conversion (auto clears)
+	ADC1->CTLR2 |= ADC_SWSTART;
+	// wait for conversion complete
+	while(!(ADC1->STATR & ADC_EOC)) {}
+	// get result
+	return ADC1->RDATAR;
+}
+
+
+
+#undef GPIO_tim1_map
+#define GPIO_tim1_map(GPIO_tim1_output_set) ({					\
+	RCC->APB2PCENR |= RCC_APB2Periph_AFIO;					\
+	AFIO->PCFR1 |= ((GPIO_tim1_output_set & 0b11) << 6);			\
+})
+
+#undef GPIO_tim2_map
+#define GPIO_tim2_map(GPIO_tim2_output_set) ({					\
+	RCC->APB2PCENR |= RCC_APB2Periph_AFIO;					\
+	AFIO->PCFR1 |= ((GPIO_tim2_output_set & 0b11) << 8);			\
+})
+
+static inline void GPIO_tim1_init() {
+	// enable TIM1
+	RCC->APB2PCENR |= RCC_APB2Periph_TIM1;
+	// reset TIM1 to init all regs
+	RCC->APB2PRSTR |= RCC_APB2Periph_TIM1;
+	RCC->APB2PRSTR &= ~RCC_APB2Periph_TIM1;
+	// SMCFGR: default clk input is CK_INT
+	// set clock prescaler divider 
+	TIM1->PSC = GPIO_timer_prescaler;
+	// set PWM total cycle width
+	TIM1->ATRLR = GPIO_timer_resolution;
+	// CTLR1: default is up, events generated, edge align
+	// enable auto-reload of preload
+	TIM1->CTLR1 |= TIM_ARPE;
+	// initialize counter
+	TIM1->SWEVGR |= TIM_UG;
+	// disengage brake
+	TIM1->BDTR |= TIM_MOE;
+	// Enable TIM1
+	TIM1->CTLR1 |= TIM_CEN;
+}
+static inline void GPIO_tim2_init() {
+	// enable TIM2
+	RCC->APB1PCENR |= RCC_APB1Periph_TIM2;
+	// reset TIM2 to init all regs
+	RCC->APB1PRSTR |= RCC_APB1Periph_TIM2;
+	RCC->APB1PRSTR &= ~RCC_APB1Periph_TIM2;
+	// SMCFGR: default clk input is CK_INT
+	// set clock prescaler divider 
+	TIM2->PSC = GPIO_timer_prescaler;
+	// set PWM total cycle width
+	TIM2->ATRLR = GPIO_timer_resolution;
+	// CTLR1: default is up, events generated, edge align
+	// enable auto-reload of preload
+	TIM2->CTLR1 |= TIM_ARPE;
+	// initialize counter
+	TIM2->SWEVGR |= TIM_UG;
+	// Enable TIM2
+	TIM2->CTLR1 |= TIM_CEN;
+}
+
+#define GPIO_timer_channel_set2(timer, channel)		GPIO_timer_channel_set_##channel(timer)
+#define GPIO_timer_channel_set(timer, channel)		GPIO_timer_channel_set2(timer, channel)
+#define GPIO_timer_channel_set_1(timer)			timer->CHCTLR1 |=  (TIM_OCMode_PWM1 | TIM_OCPreload_Enable)
+#define GPIO_timer_channel_set_2(timer)			timer->CHCTLR1 |= ((TIM_OCMode_PWM1 | TIM_OCPreload_Enable) << 8)
+#define GPIO_timer_channel_set_3(timer)			timer->CHCTLR2 |=  (TIM_OCMode_PWM1 | TIM_OCPreload_Enable)
+#define GPIO_timer_channel_set_4(timer)			timer->CHCTLR2 |= ((TIM_OCMode_PWM1 | TIM_OCPreload_Enable) << 8)
+
+#undef GPIO_tim1_enableCH
+#define GPIO_tim1_enableCH(channel) ({						\
+	GPIO_timer_channel_set(TIM1, channel);					\
+	TIM1->CCER |= (TIM_OutputState_Enable) << (4 * (channel - 1));		\
+})
+#undef GPIO_tim2_enableCH
+#define GPIO_tim2_enableCH(channel) ({						\
+	GPIO_timer_channel_set(TIM2, channel);					\
+	TIM2->CCER |= (TIM_OutputState_Enable ) << (4 * (channel - 1));		\
+})
+
+#define GPIO_timer_CVR(channel)		CONCAT_INDIRECT(CH, CONCAT_INDIRECT(channel, CVR))
+
+#undef GPIO_tim1_analogWrite
+#define GPIO_tim1_analogWrite(channel, value) ({				\
+	TIM1->GPIO_timer_CVR(channel) = value;					\
+})
+#undef GPIO_tim2_analogWrite
+#define GPIO_tim2_analogWrite(channel, value) ({				\
+	TIM2->GPIO_timer_CVR(channel) = value;					\
+})
+
+#endif // CH32V003_GPIO_BR_H
diff --git a/examples/ws2812bdemo/ws2812b_dma_spi_led_driver.h b/extralibs/ws2812b_dma_spi_led_driver.h
similarity index 95%
rename from examples/ws2812bdemo/ws2812b_dma_spi_led_driver.h
rename to extralibs/ws2812b_dma_spi_led_driver.h
index 15a62d391aeff540d781992b68eae629fa9b0d66..4968d7017dd9140742c2bed7e5645394a7d91f9f 100644
--- a/examples/ws2812bdemo/ws2812b_dma_spi_led_driver.h
+++ b/extralibs/ws2812b_dma_spi_led_driver.h
@@ -106,6 +106,13 @@ static void WS2812FillBuffSec( uint16_t * ptr, int numhalfwords, int tce )
 		ptr[3] = bitquartets[(ledval24bit>>16)&0xf];
 		ptr[4] = bitquartets[(ledval24bit>>4)&0xf];
 		ptr[5] = bitquartets[(ledval24bit>>0)&0xf];
+#elif defined( WSGRB )
+		ptr[0] = bitquartets[(ledval24bit>>12)&0xf];
+		ptr[1] = bitquartets[(ledval24bit>>8)&0xf];
+		ptr[2] = bitquartets[(ledval24bit>>4)&0xf];
+		ptr[3] = bitquartets[(ledval24bit>>0)&0xf];
+		ptr[4] = bitquartets[(ledval24bit>>20)&0xf];
+		ptr[5] = bitquartets[(ledval24bit>>16)&0xf];
 #else
 		ptr[0] = bitquartets[(ledval24bit>>20)&0xf];
 		ptr[1] = bitquartets[(ledval24bit>>16)&0xf];
diff --git a/minichlink/99-WCH-LinkE.rules b/minichlink/99-WCH-LinkE.rules
deleted file mode 100644
index ff1d7332da3f9d86b89c097d582109ea31bbb836..0000000000000000000000000000000000000000
--- a/minichlink/99-WCH-LinkE.rules
+++ /dev/null
@@ -1 +0,0 @@
-SUBSYSTEMS=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="8010", GROUP="plugdev", MODE="0666"
diff --git a/minichlink/99-minichlink.rules b/minichlink/99-minichlink.rules
new file mode 100644
index 0000000000000000000000000000000000000000..8cca6989adad49aceff2f035b04e8024dc76446e
--- /dev/null
+++ b/minichlink/99-minichlink.rules
@@ -0,0 +1,4 @@
+SUBSYSTEM=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="8010", GROUP="plugdev", MODE="0660"
+SUBSYSTEM=="usb", ATTRS{idVendor}=="303a", ATTRS{idProduct}=="4004", GROUP="plugdev", MODE="0660"
+KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="303a", ATTRS{idProduct}=="4004", GROUP="plugdev", MODE="0660"
+
diff --git a/minichlink/Makefile b/minichlink/Makefile
index e3f1b3809bbbcbadb4b6b83e8c44e6a7a18052d6..dc6c8cc949c0dbbe024a5b31ccadd512d70b9455 100644
--- a/minichlink/Makefile
+++ b/minichlink/Makefile
@@ -9,7 +9,7 @@ C_S:=minichlink.c pgm-wch-linke.c pgm-esp32s2-ch32xx.c nhc-link042.c minichgdb.c
 
 ifeq ($(OS),Windows_NT)
 	LDFLAGS:=-L. -lpthread -lusb-1.0 -lsetupapi -lws2_32
-	CFLAGS:=-Os -s -Wall
+	CFLAGS:=-Os -s -Wall -D_WIN32_WINNT=0x0600
 	TOOLS:=minichlink.exe
 else
 	OS_NAME := $(shell uname -s | tr A-Z a-z)
@@ -19,8 +19,8 @@ else
 	ifeq ($(OS_NAME),darwin)
 		LDFLAGS:=-lpthread -lusb-1.0 -framework CoreFoundation -framework IOKit
 		CFLAGS:=-O0 -Wall -Wno-asm-operand-widths -Wno-deprecated-declarations -Wno-deprecated-non-prototype -D__MACOSX__
-		INCLUDES:=-I /opt/homebrew/Cellar/libusb/1.0.26/include/libusb-1.0
-		LIBINCLUDES:=-L /opt/homebrew/Cellar/libusb/1.0.26/lib 
+		INCLUDES:=$(shell pkg-config --cflags-only-I libusb-1.0)
+		LIBINCLUDES:=$(shell pkg-config --libs-only-L libusb-1.0)
 		INCS:=$(INCLUDES) $(LIBINCLUDES)
 	endif
 endif
diff --git a/minichlink/microgdbstub.h b/minichlink/microgdbstub.h
index 3d802f55bdfb690121ef300dcf0b0d0b2a465a66..da9246f835ff697825a706f14ffb6111982df523 100644
--- a/minichlink/microgdbstub.h
+++ b/minichlink/microgdbstub.h
@@ -72,12 +72,15 @@ int WSAAPI WSAPoll(struct pollfd * fdArray, ULONG       fds, INT         timeout
 #include <arpa/inet.h>
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <linux/in.h>
 #include <unistd.h>
 #include <poll.h>
 #endif
 #endif
 
+#ifdef __linux__
+#include <linux/in.h>
+#endif
+
 char gdbbuffer[65536];
 uint8_t gdbchecksum = 0;
 int gdbbufferplace = 0;
diff --git a/minichlink/minichlink.c b/minichlink/minichlink.c
index 1c5c335be26b2e028f39f90a9a64bd08794a73ce..471e8237893adde7f7cb9c511fb8e9b662c950c6 100644
--- a/minichlink/minichlink.c
+++ b/minichlink/minichlink.c
@@ -11,9 +11,17 @@
 #include "minichlink.h"
 #include "../ch32v003fun/ch32v003fun.h"
 
+#if defined(WINDOWS) || defined(WIN32) || defined(_WIN32)
+void Sleep(uint32_t dwMilliseconds);
+#else
+#include <unistd.h>
+#endif
+
+
 static int64_t StringToMemoryAddress( const char * number ) __attribute__((used));
 static void StaticUpdatePROGBUFRegs( void * dev ) __attribute__((used));
 static int InternalUnlockBootloader( void * dev ) __attribute__((used));
+int DefaultReadBinaryBlob( void * dev, uint32_t address_to_read_from, uint32_t read_size, uint8_t * blob );
 
 void TestFunction(void * v );
 struct MiniChlinkFunctions MCF;
@@ -164,6 +172,10 @@ keep_going:
 				if( !MCF.HaltMode || MCF.HaltMode( dev, 0 ) )
 					goto unimplemented;
 				break;
+			case 'A':  // Halt without reboot
+				if( !MCF.HaltMode || MCF.HaltMode( dev, 5 ) )
+					goto unimplemented;
+				break;
 
 			// disable NRST pin (turn it into a GPIO)
 			case 'd':  // see "RSTMODE" in datasheet
@@ -180,6 +192,20 @@ keep_going:
 				else
 					goto unimplemented;
 				break;
+			case 'p': 
+				if( MCF.HaltMode ) MCF.HaltMode( dev, 0 );
+				if( MCF.ConfigureReadProtection )
+					MCF.ConfigureReadProtection( dev, 0 );
+				else
+					goto unimplemented;
+				break;
+			case 'P':
+				if( MCF.HaltMode ) MCF.HaltMode( dev, 0 );
+				if( MCF.ConfigureReadProtection )
+					MCF.ConfigureReadProtection( dev, 1 );
+				else
+					goto unimplemented;
+				break;
 			case 'G':
 			case 'T':
 			{
@@ -198,8 +224,7 @@ keep_going:
 				else
 				{
 					// In case we aren't running already.
-					MCF.HaltMode( dev, 2 );
-
+					//MCF.HaltMode( dev, 2 );
 					//XXX TODO: Why do some programmers start automatically, and others don't? 
 				}
 
@@ -295,7 +320,7 @@ keep_going:
 					goto unimplemented;
 				break;
 			}
-			case 'p':
+			case 'i':
 			{
 				if( MCF.PrintChipInfo )
 					MCF.PrintChipInfo( dev ); 
@@ -318,7 +343,7 @@ keep_going:
 			}
 			case 'r':
 			{
-				if( MCF.HaltMode ) MCF.HaltMode( dev, 0 );
+				if( MCF.HaltMode ) MCF.HaltMode( dev, 5 ); //No need to reboot.
 
 				if( argchar[2] != 0 )
 				{
@@ -398,8 +423,6 @@ keep_going:
 			}
 			case 'w':
 			{
-				if( MCF.HaltMode ) MCF.HaltMode( dev, 0 );
-
 				if( argchar[2] != 0 ) goto help;
 				iarg++;
 				argchar = 0; // Stop advancing
@@ -456,6 +479,11 @@ keep_going:
 				else
 				{
 					FILE * f = fopen( fname, "rb" );
+					if( !f )
+					{
+						fprintf( stderr, "Error: Could not open %s\n", fname );
+						return -55;
+					}
 					fseek( f, 0, SEEK_END );
 					len = ftell( f );
 					fseek( f, 0, SEEK_SET );
@@ -481,6 +509,8 @@ keep_going:
 					exit( -9 );
 				}
 
+				int is_flash = ( offset & 0xff000000 ) == 0x08000000 || ( offset & 0x1FFFF800 ) == 0x1FFFF000;
+				if( MCF.HaltMode ) MCF.HaltMode( dev, is_flash?0:5 );
 
 				if( MCF.WriteBinaryBlob )
 				{
@@ -524,15 +554,17 @@ help:
 	fprintf( stderr, " -u Clear all code flash - by power off (also can unbrick)\n" );
 	fprintf( stderr, " -b Reboot out of Halt\n" );
 	fprintf( stderr, " -e Resume from halt\n" );
-	fprintf( stderr, " -a Place into Halt\n" );
+	fprintf( stderr, " -a Reboot into Halt\n" );
+	fprintf( stderr, " -A Go into Halt without reboot\n" );
 	fprintf( stderr, " -D Configure NRST as GPIO\n" );
 	fprintf( stderr, " -d Configure NRST as NRST\n" );
+	fprintf( stderr, " -i Show chip info\n" );
 	fprintf( stderr, " -s [debug register] [value]\n" );
 	fprintf( stderr, " -m [debug register]\n" );
 	fprintf( stderr, " -T Terminal Only\n" );
 	fprintf( stderr, " -G Terminal + GDB\n" );
-//	fprintf( stderr, " -P Enable Read Protection (UNTESTED)\n" );
-//	fprintf( stderr, " -p Disable Read Protection (UNTESTED)\n" );
+	fprintf( stderr, " -P Enable Read Protection\n" );
+	fprintf( stderr, " -p Disable Read Protection\n" );
 	fprintf( stderr, " -w [binary image to write] [address, decimal or 0x, try0x08000000]\n" );
 	fprintf( stderr, " -r [output binary image] [memory address, decimal or 0x, try 0x08000000] [size, decimal or 0x, try 16384]\n" );
 	fprintf( stderr, "   Note: for memory addresses, you can use 'flash' 'launcher' 'bootloader' 'option' 'ram' and say \"ram+0x10\" for instance\n" );
@@ -941,7 +973,6 @@ static int DefaultWriteWord( void * dev, uint32_t address_to_write, uint32_t dat
 	return ret;
 }
 
-
 int DefaultWriteBinaryBlob( void * dev, uint32_t address_to_write, uint32_t blob_size, uint8_t * blob )
 {
 	// NOTE IF YOU FIX SOMETHING IN THIS FUNCTION PLEASE ALSO UPDATE THE PROGRAMMERS.
@@ -968,7 +999,7 @@ int DefaultWriteBinaryBlob( void * dev, uint32_t address_to_write, uint32_t blob
 			int r = MCF.BlockWrite64( dev, address_to_write + i, blob + i );
 			if( r )
 			{
-				fprintf( stderr, "Error writing block at memory %08x\n", address_to_write );
+				fprintf( stderr, "Error writing block at memory %08x / Error: %d\n", address_to_write, r );
 				return r;
 			}
 		}
@@ -1004,7 +1035,7 @@ int DefaultWriteBinaryBlob( void * dev, uint32_t address_to_write, uint32_t blob
 				rsofar += 64;
 				if( r )
 				{
-					fprintf( stderr, "Error writing block at memory %08x\n", base );
+					fprintf( stderr, "Error writing block at memory %08x (error = %d)\n", base, r );
 					return r;
 				}
 			}
@@ -1041,23 +1072,31 @@ int DefaultWriteBinaryBlob( void * dev, uint32_t address_to_write, uint32_t blob
 			{
 				MCF.ReadBinaryBlob( dev, base, 64, tempblock );
 
-				MCF.Erase( dev, base, 64, 0 );
-				MCF.WriteWord( dev, 0x40022010, CR_PAGE_PG ); // THIS IS REQUIRED, (intptr_t)&FLASH->CTLR = 0x40022010
-				MCF.WriteWord( dev, 0x40022010, CR_BUF_RST | CR_PAGE_PG );  // (intptr_t)&FLASH->CTLR = 0x40022010
-
 				// Permute tempblock
 				int tocopy = end_o_plus_one_in_block - offset_in_block;
 				memcpy( tempblock + offset_in_block, blob + rsofar, tocopy );
 				rsofar += tocopy;
 
-				int j;
-				for( j = 0; j < 16; j++ )
+				if( MCF.BlockWrite64 ) 
 				{
-					MCF.WriteWord( dev, j*4+base, *(uint32_t*)(tempblock + j * 4) );
-					rsofar += 4;
+					int r = MCF.BlockWrite64( dev, base, tempblock );
+					if( r ) return r;
+				}
+				else
+				{
+					MCF.Erase( dev, base, 64, 0 );
+					MCF.WriteWord( dev, 0x40022010, CR_PAGE_PG ); // THIS IS REQUIRED, (intptr_t)&FLASH->CTLR = 0x40022010
+					MCF.WriteWord( dev, 0x40022010, CR_BUF_RST | CR_PAGE_PG );  // (intptr_t)&FLASH->CTLR = 0x40022010
+
+					int j;
+					for( j = 0; j < 16; j++ )
+					{
+						MCF.WriteWord( dev, j*4+base, *(uint32_t*)(tempblock + j * 4) );
+						rsofar += 4;
+					}
+					MCF.WriteWord( dev, 0x40022014, base );  //0x40022014 -> FLASH->ADDR
+					MCF.WriteWord( dev, 0x40022010, CR_PAGE_PG|CR_STRT_Set ); // 0x40022010 -> FLASH->CTLR
 				}
-				MCF.WriteWord( dev, 0x40022014, base );  //0x40022014 -> FLASH->ADDR
-				MCF.WriteWord( dev, 0x40022010, CR_PAGE_PG|CR_STRT_Set ); // 0x40022010 -> FLASH->CTLR
 				if( MCF.WaitForFlash && MCF.WaitForFlash( dev ) ) goto timedout;
 			}
 			else
@@ -1106,7 +1145,25 @@ int DefaultWriteBinaryBlob( void * dev, uint32_t address_to_write, uint32_t blob
 	}
 
 	MCF.FlushLLCommands( dev );
-	if(MCF.DelayUS) MCF.DelayUS( dev, 100 ); // Why do we need this?
+
+#if 0
+	{
+		uint8_t scratch[blob_size];
+		int rrr = DefaultReadBinaryBlob( dev, address_to_write, blob_size, scratch );
+		int i;
+		printf( "Read op: %d\n", rrr );
+		for( i = 0; i < blob_size; i++ )
+		{
+			if( scratch[i] != blob[i] )
+			{
+				printf( "DISAGREE: %04x\n", i );
+				i = (i & ~0x3f) + 0x40-1;
+			}
+		}
+	}
+#endif
+
+	if(MCF.DelayUS) MCF.DelayUS( dev, 100 ); // Why do we need this? (We seem to need this on the WCH programmers?)
 	return 0;
 timedout:
 	fprintf( stderr, "Timed out\n" );
@@ -1418,13 +1475,16 @@ static int DefaultHaltMode( void * dev, int mode )
 	struct InternalState * iss = (struct InternalState*)(((struct ProgrammerStructBase*)dev)->internal);
 	switch ( mode )
 	{
+	case 5: // Don't reboot.
 	case 0:
 		MCF.WriteReg32( dev, DMSHDWCFGR, 0x5aa50000 | (1<<10) ); // Shadow Config Reg
 		MCF.WriteReg32( dev, DMCFGR, 0x5aa50000 | (1<<10) ); // CFGR (1<<10 == Allow output from slave)
 		MCF.WriteReg32( dev, DMCFGR, 0x5aa50000 | (1<<10) ); // Bug in silicon?  If coming out of cold boot, and we don't do our little "song and dance" this has to be called.
 
 		MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Make the debug module work properly.
-		MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Initiate a halt request.
+		if( mode == 0 ) MCF.WriteReg32( dev, DMCONTROL, 0x80000003 ); // Reboot.
+		MCF.WriteReg32( dev, DMCONTROL, 0x80000001 ); // Re-initiate a halt request.
+
 //		MCF.WriteReg32( dev, DMCONTROL, 0x00000001 ); // Clear Halt Request.  This is recommended, but not doing it seems more stable.
 		// Sometimes, even if the processor is halted but the MSB is clear, it will spuriously start?
 		MCF.FlushLLCommands( dev );
@@ -1459,6 +1519,8 @@ static int DefaultHaltMode( void * dev, int mode )
 		MCF.WriteReg32( dev, DMCONTROL, 0x40000001 ); // resumereq
 		MCF.FlushLLCommands( dev );
 		break;
+	default:
+		fprintf( stderr, "Error: Unknown halt mode %d\n", mode );
 	}
 #if 0
 	int i;
@@ -1564,9 +1626,21 @@ int DefaultUnbrick( void * dev )
 
 //  Many times we would clear the halt request, but in this case, we want to just leave it here, to prevent it from booting.
 //  TODO: Experiment and see if this is needed/wanted in cases.  NOTE: If you don't clear halt request, progarmmers can get stuck.
-	MCF.WriteReg32( dev, DMCONTROL, 0x00000001 ); // Clear Halt Request.
+//	MCF.WriteReg32( dev, DMCONTROL, 0x00000001 ); // Clear Halt Request.
+
+	// After more experimentation, it appaers to work best by not clearing the halt request.
 
 	MCF.FlushLLCommands( dev );
+	if( MCF.DelayUS )
+		MCF.DelayUS( dev, 20000 );
+	else
+	{
+#if defined(WINDOWS) || defined(WIN32) || defined(_WIN32)
+		Sleep(20);
+#else
+		usleep(20000);
+#endif
+	}
 
 	if( timeout == max_timeout ) 
 	{
@@ -1716,19 +1790,25 @@ int DefaultConfigureNRSTAsGPIO( void * dev, int one_if_yes_gpio  )
 #endif
 }
 
+int DefaultConfigureReadProtection( void * dev, int one_if_yes_protect  )
+{
+	fprintf( stderr, "Error: DefaultConfigureReadProtection does not work via the programmer here.  Please see the demo \"optionbytes\"\n" );
+	return -5;
+}
+
 int DefaultPrintChipInfo( void * dev )
 {
 	uint32_t reg;
-	MCF.HaltMode( dev, 0 );
+	MCF.HaltMode( dev, 5 );
 
 	if( MCF.ReadWord( dev, 0x1FFFF800, &reg ) ) goto fail;	
-	printf( "USER/RDPR: %08x\n", reg );
-/*	if( MCF.ReadWord( dev, 0x1FFFF804, &reg ) ) goto fail;	
-	printf( "NDATA: %08x\n", reg );
+	printf( "USER/RDPR  : %04x/%04x\n", reg>>16, reg&0xFFFF );
+	if( MCF.ReadWord( dev, 0x1FFFF804, &reg ) ) goto fail;	
+	printf( "DATA1/DATA0: %04x/%04x\n", reg>>16, reg&0xFFFF );
 	if( MCF.ReadWord( dev, 0x1FFFF808, &reg ) ) goto fail;	
-	printf( "WRPR01: %08x\n", reg );
+	printf( "WRPR1/WRPR0: %04x/%04x\n", reg>>16, reg&0xFFFF );
 	if( MCF.ReadWord( dev, 0x1FFFF80c, &reg ) ) goto fail;	
-	printf( "WRPR23: %08x\n", reg );*/
+	printf( "WRPR3/WRPR2: %04x/%04x\n", reg>>16, reg&0xFFFF );
 	if( MCF.ReadWord( dev, 0x1FFFF7E0, &reg ) ) goto fail;
 	printf( "Flash Size: %d kB\n", (reg&0xffff) );
 	if( MCF.ReadWord( dev, 0x1FFFF7E8, &reg ) ) goto fail;	
diff --git a/minichlink/minichlink.h b/minichlink/minichlink.h
index 0462984284cef827728f2e2631ce0745fef5280e..131a433c4183202c4ac8787c30ae89f13b79ea20 100644
--- a/minichlink/minichlink.h
+++ b/minichlink/minichlink.h
@@ -23,6 +23,7 @@ struct MiniChlinkFunctions
 
 	int (*HaltMode)( void * dev, int mode ); //0 for halt, 1 for reset, 2 for resume
 	int (*ConfigureNRSTAsGPIO)( void * dev, int one_if_yes_gpio );
+	int (*ConfigureReadProtection)( void * dev, int one_if_yes_protect );
 
 	// No boundary or limit rules.  Must support any combination of alignment and size.
 	int (*WriteBinaryBlob)( void * dev, uint32_t address_to_write, uint32_t blob_size, uint8_t * blob );
diff --git a/minichlink/pgm-esp32s2-ch32xx.c b/minichlink/pgm-esp32s2-ch32xx.c
index 11d0048daee958797d8e837009331b330fe63365..ef8a721e7c3cbfbaf335c47bb353c666c2156d39 100644
--- a/minichlink/pgm-esp32s2-ch32xx.c
+++ b/minichlink/pgm-esp32s2-ch32xx.c
@@ -100,6 +100,17 @@ int ESPFlushLLCommands( void * dev )
 
 	eps->commandbuffer[0] = 0xad; // Key report ID
 	eps->commandbuffer[eps->commandplace] = 0xff;
+
+#if 0
+	int i;
+	for( i = 0; i < eps->commandplace; i++ )
+	{
+		if( ( i & 0xff ) == 0 ) printf( "\n" );
+		printf( "%02x ", eps->commandbuffer[i] );
+	}
+	printf("\n" );
+#endif
+
 	r = hid_send_feature_report( eps->hd, eps->commandbuffer, 255 );
 	eps->commandplace = 1;
 	if( r < 0 )
@@ -226,21 +237,40 @@ int ESPExit( void * dev )
 
 int ESPBlockWrite64( void * dev, uint32_t address_to_write, uint8_t * data )
 {
+	int writeretry = 0;
 	struct ESP32ProgrammerStruct * eps = (struct ESP32ProgrammerStruct *)dev;
 	ESPFlushLLCommands( dev );
+
+retry:
+
 	Write2LE( eps, 0x0bfe );
 	Write4LE( eps, address_to_write );
 	int i;
+	int timeout = 0;
 	for( i = 0; i < 64; i++ ) Write1( eps, data[i] );
+
 	do
 	{
 		ESPFlushLLCommands( dev );
+		timeout++;
+		if( timeout > 1000 )
+		{
+			fprintf( stderr, "Error: Timed out block-writing 64\n" );
+			return -49;
+		}
 	} while( eps->replylen < 2 );
-	
-	// Not sure why this is needed.
-	ESPWaitForDoneOp( dev, 0 );
 
-	return eps->reply[1];
+	if( eps->reply[1] )
+	{
+		fprintf( stderr, "Error: Got code %d from ESP write algo. %d [%02x %02x %02x]\n", (char)eps->reply[1], eps->replylen, eps->reply[0], eps->reply[1], eps->reply[2] );
+		if( writeretry < 10 )
+		{
+			writeretry++;
+			goto retry;
+		}
+	}
+
+	return (char)eps->reply[1];
 }
 
 int ESPPerformSongAndDance( void * dev )
@@ -342,7 +372,8 @@ int ESPPollTerminal( void * dev, uint8_t * buffer, int maxlen, uint32_t leavefla
 	int rlen = eps->reply[0];
 	if( rlen < 1 ) return -8;
 
-/*
+
+#if 0
 	int i;
 
 	printf( "RESP (ML %d): %d\n", maxlen,eps->reply[0] );
@@ -353,7 +384,8 @@ int ESPPollTerminal( void * dev, uint8_t * buffer, int maxlen, uint32_t leavefla
 		if( (i % 16) == 15 ) printf( "\n" );
 	}
 	printf( "\n" );
-*/
+#endif
+
 	int errc = eps->reply[1];
 	if( errc > 7 ) return -7;
 
diff --git a/minichlink/pgm-wch-linke.c b/minichlink/pgm-wch-linke.c
index e314875464e5545833cd1d8dab7092c723f31f42..70c43eba8571425820b95f1c484f6f02ba1fefd1 100644
--- a/minichlink/pgm-wch-linke.c
+++ b/minichlink/pgm-wch-linke.c
@@ -309,6 +309,21 @@ static int LEConfigureNRSTAsGPIO( void * d, int one_if_yes_gpio )
 	return 0;
 }
 
+static int LEConfigureReadProtection( void * d, int one_if_yes_protect )
+{
+	libusb_device_handle * dev = ((struct LinkEProgrammerStruct*)d)->devh;
+
+	if( one_if_yes_protect )
+	{
+		wch_link_multicommands( (libusb_device_handle *)dev, 2, 11, "\x81\x06\x08\x03\xf7\xff\xff\xff\xff\xff\xff", 4, "\x81\x0b\x01\x01" );
+	}
+	else
+	{
+		wch_link_multicommands( (libusb_device_handle *)dev, 2, 11, "\x81\x06\x08\x02\xf7\xff\xff\xff\xff\xff\xff", 4, "\x81\x0b\x01\x01" );
+	}
+	return 0;
+}
+
 int LEExit( void * d )
 {
 	libusb_device_handle * dev = ((struct LinkEProgrammerStruct*)d)->devh;
@@ -337,6 +352,7 @@ void * TryInit_WCHLinkE()
 	MCF.Control5v = LEControl5v;
 	MCF.Unbrick = LEUnbrick;
 	MCF.ConfigureNRSTAsGPIO = LEConfigureNRSTAsGPIO;
+	MCF.ConfigureReadProtection = LEConfigureReadProtection;
 
 	MCF.Exit = LEExit;
 	return ret;
diff --git a/platformio.ini b/platformio.ini
index 7ab6a396ed2f437fc242993fcbcd52a33c93b782..3edc591904e025923f2883664a83269f1e1840eb 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -15,9 +15,15 @@ extends = fun_base
 ; for examples that use ch32v003fun as their base
 [fun_base]
 board_build.ldscript = ch32v003fun/ch32v003fun.ld
-build_flags = -flto -Ich32v003fun -I/usr/include/newlib -DTINYVECTOR -lgcc
+build_flags = -flto -Ich32v003fun -I/usr/include/newlib -DTINYVECTOR -lgcc -Iextralibs
 build_src_filter = +<ch32v003fun>
+extra_libs_srcs = +<extralibs>
 
+; If creating a new example:
+; 1. Add new [env:name]
+; 2. Add build_src_filter with fun base files + example folder (+ extra libraries if used) for source files
+; 3. Add additional build flags as needed (see uartdemo)
+; 4. Switch to new environment in VSCode bottom taskbar (https://docs.platformio.org/en/latest/integration/ide/vscode.html#project-tasks)
 [env:blink]
 build_src_filter = ${fun_base.build_src_filter} +<examples/blink>
 
@@ -30,6 +36,9 @@ build_src_filter = ${fun_base.build_src_filter} +<examples/debugprintfdemo>
 [env:external_crystal]
 build_src_filter = ${fun_base.build_src_filter} +<examples/external_crystal>
 
+[env:GPIO]
+build_src_filter = ${fun_base.build_src_filter} ${fun_base.extra_libs_srcs} +<examples/GPIO>
+
 [env:optionbytes]
 build_src_filter = ${fun_base.build_src_filter} +<examples/optionbytes>