diff --git a/.github/workflows/CI_build.yml b/.github/workflows/CI_build.yml
new file mode 100644
index 00000000..7b11d888
--- /dev/null
+++ b/.github/workflows/CI_build.yml
@@ -0,0 +1,25 @@
+name: CI Build Linux
+
+on: [push, pull_request]
+
+jobs:
+  build:
+    runs-on: 'ubuntu-latest'
+
+    steps:
+      - uses: actions/checkout@v4
+        with:
+          submodules: 'recursive'
+
+      - name: Build CI
+        run: |
+          make arm_sdk_install
+          make -j8
+
+      - name: Archive build
+        uses: actions/upload-artifact@v3
+        with:
+          name: AM32-binaries
+          path: |
+            obj/*.hex
+          retention-days: 7
diff --git a/.github/workflows/CI_build_windows.yml b/.github/workflows/CI_build_windows.yml
new file mode 100644
index 00000000..ecfd63de
--- /dev/null
+++ b/.github/workflows/CI_build_windows.yml
@@ -0,0 +1,25 @@
+name: CI Build Windows
+
+on: [push, pull_request]
+
+jobs:
+  build:
+    runs-on: 'windows-latest'
+
+    steps:
+      - uses: actions/checkout@v4
+        with:
+          submodules: 'recursive'
+
+      - name: Build CI
+        run: |
+          make arm_sdk_install
+          tools/windows/make/bin/make
+
+      - name: Archive build
+        uses: actions/upload-artifact@v3
+        with:
+          name: AM32-binaries
+          path: |
+            obj/*.hex
+          retention-days: 7
diff --git a/.gitignore b/.gitignore
index f0f28382..39542a56 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,9 @@ Keil_Projects/*.uvguix.*
 Keil_Projects/Objects
 Keil_Projects/RTE/*
 Keil_Projects/Listings
+*.bin
+*.elf
+*.d
+*.hex
+*.log
+*~
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 00000000..67fb7a9c
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,49 @@
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+      // STLink configuration
+      {
+        "name": "AM32 STLink",
+        "cwd": "${workspaceFolder}",
+        "executable": "${workspaceFolder}/obj/debug.elf",
+        "liveWatch": {
+            "enabled": true,
+            "samplesPerSecond": 4,
+        },
+        "request": "launch",
+        "type": "cortex-debug",
+        "servertype": "openocd",
+	      "configFiles": [
+	    "${workspaceFolder}/obj/openocd.cfg",
+        ],
+	      "showDevDebugOutput": "none",
+
+      	"serverpath": "${workspaceFolder}${/}tools${/}${config:OS}${/}openocd${/}bin${/}openocd",
+	      "armToolchainPath": "${workspaceRoot}/tools/${config:OS}/xpack-arm-none-eabi-gcc-10.3.1-2.3/bin",
+      },
+
+      // JLink configuration
+      {
+        "type": "cortex-debug",
+        "request": "launch",
+        "name": "AM32 JLink",
+        "cwd": "${workspaceRoot}",
+	      "device" : "-AT32F421K8U7",
+	      "gdbPath": "${workspaceRoot}/tools/${config:OS}/xpack-arm-none-eabi-gcc-10.3.1-2.3/bin/arm-none-eabi-gdb",
+        "executable": "${workspaceRoot}/obj/debug.elf",
+	      "showDevDebugOutput": "raw",
+        "servertype" : "jlink",
+        "swoConfig": {
+          "enabled": false,
+        },
+        "serialNumber": "", 
+        "liveWatch": {
+          "enabled": true,
+          "samplesPerSecond": 4
+        }
+      }
+    ]
+  }
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..031335b4
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,27 @@
+{
+    "OS": "windows",
+    "makefile.makePath": "tools/windows/make/bin/make.exe",
+
+    //"OS": "linux",
+    //"makefile.makePath": "/usr/bin/make",
+
+    "makefile.configurations": [
+        {
+            "name": "MakeSingle",
+            "makeArgs": [
+                "-j1"
+            ]
+	},
+        {
+            "name": "MakeParallel-8",
+            "makeArgs": [
+                "-j8"
+            ]
+	},
+        {
+	    "name": "MakeParallel-MAX",
+            "makeArgs": [
+		"-j"
+            ]
+	}
+}
diff --git a/Inc/targets.h b/Inc/targets.h
index 2ae0fe54..8ee6f1fd 100644
--- a/Inc/targets.h
+++ b/Inc/targets.h
@@ -327,7 +327,7 @@
 #endif
 /****************************************Generic********************************************/
 
-#ifdef AT32F421_PB4_054
+#ifdef AT32PB4_054_F421
 #define FIRMWARE_NAME "AT32PB4_054 "
 #define FILE_NAME "AT32PB4_054_F421"
 #define DEAD_TIME 80
@@ -336,7 +336,7 @@
 #define USE_SERIAL_TELEMETRY
 #endif
 
-#ifdef AT32F421_PB4_405
+#ifdef AT32PB4_405_F421
 #define FIRMWARE_NAME "AT32PB4_405 "
 #define FILE_NAME "AT32PB4_405_F421"
 #define DEAD_TIME 80
@@ -345,7 +345,7 @@
 #define USE_SERIAL_TELEMETRY
 #endif
 
-#ifdef AT32F421_PB4_540
+#ifdef AT32PB4_540_F421
 #define FIRMWARE_NAME "AT32PB4_540 "
 #define FILE_NAME "AT32PB4_540_F421"
 #define DEAD_TIME 80
@@ -406,7 +406,7 @@
 #define ADC_CHANNEL_TEMP ADC_CHANNEL_6
 #endif
 
-#ifdef FLYROTOR_150A_F421
+#ifdef FLYROTOR_F421
 #define FIRMWARE_NAME "FLYROTOR_150"
 #define FILE_NAME "FLYROTOR_F421"
 #define DEAD_TIME 100
@@ -513,12 +513,13 @@
 #define FILE_NAME "AT32DEV_F415"
 #define DEAD_TIME 100
 #define HARDWARE_GROUP_AT_D
+#define HARDWARE_GROUP_AT_045
 #define USE_SERIAL_TELEMETRY
 #endif
 
 #ifdef DAKEFPV_35A_F415
 #define FIRMWARE_NAME "DakeFPV 35A "
-#define FILE_NAME "DAKEFPV_35A_F415"
+#define FILE_NAME "DAKEFPV_35A_F415" // DISABLE_BUILD
 #define DEAD_TIME 20
 #define HARDWARE_GROUP_AT_D
 #define USE_SERIAL_TELEMETRY
@@ -535,7 +536,7 @@
 
 #ifdef SPEEDYBEE_F421
 #define FIRMWARE_NAME "SpeedyBee F4"
-#define FILE_NAME "SpeedyBee_F421"
+#define FILE_NAME "SPEEDYBEE_F421"
 #define DEAD_TIME 100
 #define HARDWARE_GROUP_AT_C
 #define HARDWARE_GROUP_AT_540
@@ -867,7 +868,7 @@
 #endif
 
 #ifdef ARIA_RAMP_F051
-#define FILE_NAME "FLYCOLOR_F051"
+#define FILE_NAME "ARIA_RAMP_F051"
 #define FIRMWARE_NAME "Aria Slow  "
 #define DEAD_TIME 45
 #define HARDWARE_GROUP_F0_A
@@ -1134,7 +1135,7 @@
 #endif
 
 #ifdef IFLIGHT_12S_SINGLE_N_G071
-#define FILE_NAME "IFLIGHT_12S_G071"
+#define FILE_NAME "IFLIGHT_12S_SINGLE_N_G071"
 #define FIRMWARE_NAME "12s G071N "
 #define DEAD_TIME 100
 #define MILLIVOLT_PER_AMP 67
@@ -1390,7 +1391,10 @@
 #define VOLTAGE_ADC_CHANNEL LL_ADC_CHANNEL_7
 #endif
 
-
+#ifndef FIRMWARE_NAME
+/* if you get this then you have forgotten to add the section for your target above */
+#error "Missing defines for target"
+#endif
 
 /********************************** defaults if not set
  * ***************************/
diff --git a/Inc/version.h b/Inc/version.h
new file mode 100644
index 00000000..19554e01
--- /dev/null
+++ b/Inc/version.h
@@ -0,0 +1,5 @@
+/*
+  update this file for new releases
+ */
+#define VERSION_MAJOR 2
+#define VERSION_MINOR 16
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..b85da356
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,143 @@
+
+QUIET = @
+
+# tools
+CC = $(ARM_SDK_PREFIX)gcc
+OBJCOPY = $(ARM_SDK_PREFIX)objcopy
+ECHO = echo
+
+# common variables
+IDENTIFIER := AM32
+
+# Folders
+HAL_FOLDER := Mcu
+MAIN_SRC_DIR := Src
+MAIN_INC_DIR := Inc
+
+SRC_DIRS_COMMON := $(MAIN_SRC_DIR)
+
+# Working directories
+ROOT := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
+
+# include the rules for OS independence
+include $(ROOT)/make/tools.mk
+
+# Include processor specific makefiles
+include f051makefile.mk
+include g071makefile.mk
+include f031makefile.mk
+include f421makefile.mk
+include e230makefile.mk
+include f415makefile.mk
+include gd32makefile.mk
+
+# Default MCU type to F051
+MCU_TYPE ?= F051
+
+# additional libs
+LIBS := -lnosys
+
+# extract version from Inc/version.h
+VERSION_MAJOR := $(shell $(FGREP) "define VERSION_MAJOR" $(MAIN_INC_DIR)/version.h | $(CUT) -d" " -f3 )
+VERSION_MINOR := $(shell $(FGREP) "define VERSION_MINOR" $(MAIN_INC_DIR)/version.h | $(CUT) -d" " -f3 )
+
+FIRMWARE_VERSION := $(VERSION_MAJOR).$(VERSION_MINOR)
+
+# Compiler options
+CFLAGS_COMMON := -DUSE_MAKE -fsingle-precision-constant -fomit-frame-pointer -ffast-math
+CFLAGS_COMMON += -I$(MAIN_INC_DIR) -g -O3 -Wall -ffunction-sections
+CFLAGS_COMMON += -D$(TARGET)
+
+# Linker options
+LDFLAGS_COMMON := -specs=nano.specs $(LIBS) -Wl,--gc-sections -Wl,--print-memory-usage
+
+# Search source files
+SRC_COMMON := $(foreach dir,$(SRC_DIRS_COMMON),$(wildcard $(dir)/*.[cs]))
+
+TARGET_FNAME = $(IDENTIFIER)_$(TARGET)_$(FIRMWARE_VERSION)
+TARGET_BASENAME = $(BIN_DIR)/$(TARGET_FNAME)
+
+# configure some directories that are relative to wherever ROOT_DIR is located
+OBJ := obj
+BIN_DIR := $(ROOT)/$(OBJ)
+
+TOOLS_DIR ?= $(ROOT)/tools
+DL_DIR := $(ROOT)/downloads
+
+.PHONY : clean all binary f051 g071 f031 e230 f421 f415
+ALL_TARGETS := $(TARGETS_F051) $(TARGETS_G071) $(TARGETS_F031) $(TARGETS_E230) $(TARGETS_F421) $(TARGETS_F415)
+all : $(ALL_TARGETS)
+f051 : $(TARGETS_F051)
+g071 : $(TARGETS_G071)
+f031 : $(TARGETS_F031)
+e230 : $(TARGETS_E230)
+f421 : $(TARGETS_F421)
+f415 : $(TARGETS_F415)
+
+clean :
+	@echo Removing $(OBJ) directory
+	@$(RM) -rf $(OBJ)
+
+# lowercase version of MCU_TYPE
+MCU_LOWER = $(call lc,$(MCU_TYPE))
+
+binary : $(TARGET_BASENAME).bin
+# we copy debug.elf to give us a constant debug target for vscode
+# this means the debug button will always debug the last target built
+	@$(CP) -f $(OBJ)$(DSEP)$(TARGET_FNAME).elf $(OBJ)$(DSEP)debug.elf > $(NUL)
+# also copy the openocd.cfg from the MCU directory to obj/openocd.cfg for auto config of Cortex-Debug
+# in vscode
+	@$(CP) -f Mcu$(DSEP)$(MCU_LOWER)$(DSEP)openocd.cfg $(OBJ)$(DSEP)openocd.cfg > $(NUL)
+	@$(ECHO) done $(TARGET)
+
+$(TARGETS_F051) :
+	@$(MAKE) -s MCU_TYPE=F051 TARGET=$@ binary
+
+$(TARGETS_G071) :
+	@$(MAKE) -s MCU_TYPE=G071 TARGET=$@ binary
+
+$(TARGETS_F031) :
+	@$(MAKE) -s MCU_TYPE=F031 TARGET=$@ binary
+
+$(TARGETS_E230) :
+	@$(MAKE) -s MCU_TYPE=E230 TARGET=$@ binary
+
+$(TARGETS_F421) :
+	@$(MAKE) -s MCU_TYPE=F421 TARGET=$@ binary	
+
+$(TARGETS_F415) :
+	@$(MAKE) -s MCU_TYPE=F415 TARGET=$@ binary		
+
+# Compile target
+$(TARGET_BASENAME).elf: CFLAGS := $(MCU_$(MCU_TYPE)) $(CFLAGS_$(MCU_TYPE)) $(CFLAGS_COMMON)
+$(TARGET_BASENAME).elf: LDFLAGS := $(LDFLAGS_COMMON) $(LDFLAGS_$(MCU_TYPE)) -T$(LDSCRIPT_$(MCU_TYPE))
+$(TARGET_BASENAME).elf: $(SRC_COMMON) $(SRC_$(MCU_TYPE))
+	@$(ECHO) Compiling $(notdir $@)
+	$(QUIRT)$(MKDIR) -p $(OBJ)
+	$(QUIET)$(CC) $(CFLAGS) $(LDFLAGS) -MMD -MP -MF $(@:.elf=.d) -o $(@) $(SRC_COMMON) $(SRC_$(MCU_TYPE))
+
+# Generate bin and hex files
+$(TARGET_BASENAME).bin: $(TARGET_BASENAME).elf
+	@$(ECHO) Generating $(notdir $@)
+	$(QUIET)$(OBJCOPY) -O binary $(<) $@
+	$(QUIET)$(OBJCOPY) $(<) -O ihex $(@:.bin=.hex)
+
+# mkdirs
+$(DL_DIR):
+	$(QUIET)$(MKDIR) -p $@
+
+$(TOOLS_DIR):
+	$(QUIET)$(MKDIR) -p $@
+
+# include the targets for installing tools
+include $(ROOT)/make/tools_install.mk
+
+targets:
+	$(QUIET)echo Targets for each MCU. To build a target use 'make TARGETNAME'
+	$(QUIET)echo F051 Targets:  $(TARGETS_F051)
+	$(QUIET)echo G071 Targets: $(TARGETS_G071)
+	$(QUIET)echo F031 Targets: $(TARGETS_F031)
+	$(QUIET)echo E230 Targets: $(TARGETS_E230)
+	$(QUIET)echo F421 Targets: $(TARGETS_F421)
+	$(QUIET)echo F415 Targets: $(TARGETS_F415)
+	$(QUIET)echo GD32 Targets: $(TARGETS_GD32)
diff --git a/Mcu/e230/openocd.cfg b/Mcu/e230/openocd.cfg
new file mode 100644
index 00000000..1674ddf5
--- /dev/null
+++ b/Mcu/e230/openocd.cfg
@@ -0,0 +1,7 @@
+# config for openocd for GD32E230 MCUs
+source [find interface/stlink.cfg]
+source [find target/gd32e23x.cfg]
+
+# use -gdb-max-connections to allow for live watch in vscode
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -gdb-max-connections 4
+init
diff --git a/Mcu/f031/openocd.cfg b/Mcu/f031/openocd.cfg
new file mode 100644
index 00000000..4fe89ee4
--- /dev/null
+++ b/Mcu/f031/openocd.cfg
@@ -0,0 +1,7 @@
+# config for openocd for STM32F031 MCUs
+source [find interface/stlink.cfg]
+source [find target/stm32f0x.cfg]
+
+# use -gdb-max-connections to allow for live watch in vscode
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -gdb-max-connections 4
+init
diff --git a/Mcu/f051/openocd.cfg b/Mcu/f051/openocd.cfg
new file mode 100644
index 00000000..17c6d87b
--- /dev/null
+++ b/Mcu/f051/openocd.cfg
@@ -0,0 +1,7 @@
+# config for openocd for STM32F051 MCUs
+source [find interface/stlink.cfg]
+source [find target/stm32f0x.cfg]
+
+# use -gdb-max-connections to allow for live watch in vscode
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -gdb-max-connections 4
+init
diff --git a/Mcu/f415/Inc/functions.h b/Mcu/f415/Inc/functions.h
index 2670d806..77d984c8 100644
--- a/Mcu/f415/Inc/functions.h
+++ b/Mcu/f415/Inc/functions.h
@@ -11,8 +11,8 @@
 #endif /* FUNCTIONS_H_ */
 
 #include "main.h"
-void gpio_mode_QUICK(gpio_type* gpio_periph, uint16_t mode,
-    uint16_t pull_up_down, uint32_t pin);
+void gpio_mode_QUICK(gpio_type* gpio_periph, uint32_t mode,
+    uint32_t pull_up_down, uint32_t pin);
 void gpio_mode_set(uint32_t mode, uint32_t pull_up_down, uint32_t pin);
 int getAbsDif(int number1, int number2);
 void delayMicros(uint32_t micros);
diff --git a/Mcu/f415/openocd.cfg b/Mcu/f415/openocd.cfg
new file mode 100644
index 00000000..6bec3574
--- /dev/null
+++ b/Mcu/f415/openocd.cfg
@@ -0,0 +1,7 @@
+# config for openocd for AT32F415 MCUs
+source [find interface/stlink.cfg]
+source [find target/at32f415xx.cfg]
+
+# use -gdb-max-connections to allow for live watch in vscode
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -gdb-max-connections 4
+init
diff --git a/Mcu/f421/Src/at32f421_it.c b/Mcu/f421/Src/at32f421_it.c
index 59f5c2f7..c9268d65 100644
--- a/Mcu/f421/Src/at32f421_it.c
+++ b/Mcu/f421/Src/at32f421_it.c
@@ -2,7 +2,7 @@
  * ------------------------------------------------------------------*/
 #include "at32f421_it.h"
 
-#include "adc.h"
+#include "ADC.h"
 #include "main.h"
 #include "targets.h"
 extern void transfercomplete();
diff --git a/Mcu/f421/openocd.cfg b/Mcu/f421/openocd.cfg
new file mode 100644
index 00000000..dfb5745c
--- /dev/null
+++ b/Mcu/f421/openocd.cfg
@@ -0,0 +1,7 @@
+# config for openocd for AT32F421 MCUs
+source [find interface/stlink.cfg]
+source [find target/at32f421xx.cfg]
+
+# use -gdb-max-connections to allow for live watch in vscode
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -gdb-max-connections 4
+init
diff --git a/Mcu/g071/openocd.cfg b/Mcu/g071/openocd.cfg
new file mode 100644
index 00000000..8740af23
--- /dev/null
+++ b/Mcu/g071/openocd.cfg
@@ -0,0 +1,7 @@
+# config for openocd for STM32G071 MCUs
+source [find interface/stlink.cfg]
+source [find target/stm32g0x.cfg]
+
+# use -gdb-max-connections to allow for live watch in vscode
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -gdb-max-connections 4
+init
diff --git a/Mcu/g431/openocd.cfg b/Mcu/g431/openocd.cfg
new file mode 100644
index 00000000..6b5611d0
--- /dev/null
+++ b/Mcu/g431/openocd.cfg
@@ -0,0 +1,7 @@
+# config for openocd for STM32G431 MCUs
+source [find interface/stlink.cfg]
+source [find target/stm32g4x.cfg]
+
+# use -gdb-max-connections to allow for live watch in vscode
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -gdb-max-connections 4
+init
diff --git a/Src/main.c b/Src/main.c
index 8e4a4510..902cba84 100644
--- a/Src/main.c
+++ b/Src/main.c
@@ -238,8 +238,7 @@ an settings option)
 #include "crsf.h"
 #endif
 
-#define VERSION_MAJOR 2
-#define VERSION_MINOR 16
+#include <version.h>
 
 void zcfoundroutine(void);
 
@@ -2284,4 +2283,4 @@ void assert_failed(uint8_t* file, uint32_t line)
        line) */
     /* USER CODE END 6 */
 }
-#endif /* USE_FULL_ASSERT */
\ No newline at end of file
+#endif /* USE_FULL_ASSERT */
diff --git a/e230makefile.mk b/e230makefile.mk
index 32e8db55..87aa3b08 100644
--- a/e230makefile.mk
+++ b/e230makefile.mk
@@ -1,10 +1,9 @@
 
-TARGETS_E230 := GD32DEV_A_E230\
-	
+TARGETS_E230 := $(call get_targets,E230)
 
 HAL_FOLDER_E230 := $(HAL_FOLDER)/e230
 
-MCU_E230 := -mcpu=cortex-m23 -mthumb -fsigned-char
+MCU_E230 := -mfloat-abi=soft -mthumb -march=armv8-m.main
 LDSCRIPT_E230 := $(HAL_FOLDER_E230)/GD32E230K8_FLASH.ld
 
 SRC_DIR_E230 := \
diff --git a/f031makefile.mk b/f031makefile.mk
index 5ea76ef5..3d073340 100644
--- a/f031makefile.mk
+++ b/f031makefile.mk
@@ -1,5 +1,5 @@
 
-TARGETS_F031 := REF_F031 \
+TARGETS_F031 := $(call get_targets,F031)
 
 HAL_FOLDER_F031 := $(HAL_FOLDER)/f031
 
diff --git a/f051makefile.mk b/f051makefile.mk
index 22f65e91..2b15fda3 100644
--- a/f051makefile.mk
+++ b/f051makefile.mk
@@ -1,9 +1,5 @@
 
-TARGETS_F051 := \
-	FD6288_F051 MP6531_F051 IFLIGHT_F051 TMOTOR55_F051 TMOTOR45_F051 HGLRC_F051 SISKIN_F051 \
-	DIATONE_F051 MAMBA_F40PRO_F051 MAMBA_F50PRO_F051 MAMBA_F60PRO_F051 \
-	WRAITH32V1_F051 WRAITH32V2_F051 CRTEENSY_HILARIESC_F051 FLYCOLOR_F051 HVFLYCOLOR_F051 AIKONSINGLE_F051 \
-	SKYSTARS_F051 AM32REF_F051 BLPWR_F051 NEUTRONRC_F051 RAZOR32_F051 RHINO80A_F051
+TARGETS_F051 := $(call get_targets,F051)
 
 HAL_FOLDER_F051 := $(HAL_FOLDER)/f051
 
diff --git a/f415makefile.mk b/f415makefile.mk
index 8f0e4ebc..c3ae98c2 100644
--- a/f415makefile.mk
+++ b/f415makefile.mk
@@ -1,8 +1,7 @@
 
-TARGETS_F415 := \
-	AT32DEV_F415 TEKKO32_F415
+TARGETS_F415 := $(call get_targets,F415)
 
-HAL_FOLDER_F415 := $(HAL_FOLDER)/F415
+HAL_FOLDER_F415 := $(HAL_FOLDER)/f415
 
 MCU_F415 := -mcpu=cortex-m4 -mthumb
 LDSCRIPT_F415 := $(HAL_FOLDER_F415)/AT32F415x8_FLASH.ld
@@ -21,6 +20,6 @@ CFLAGS_F415 := \
 CFLAGS_F415 += \
 	 -DAT32F415K8U7_4 \
 	 -DUSE_STDPERIPH_DRIVER
-	
+
 
 SRC_F415 := $(foreach dir,$(SRC_DIR_F415),$(wildcard $(dir)/*.[cs]))
diff --git a/f421makefile.mk b/f421makefile.mk
index 1da4aa15..26c2f8e9 100644
--- a/f421makefile.mk
+++ b/f421makefile.mk
@@ -1,9 +1,7 @@
 
-TARGETS_F421 :=  WRAITH32_F421 AIKON_SINGLE_F421 AIKON_55A_F421 FOXEER_F421 HAKRC_K_F421 \
-	             HAKRC_G_F421 TEKKO32_F421 AT32DEV_F421 DARWIN_F421 NEUTRON_F421 AT32SLOTCAR_F421\
-				 HAKRC_G23_F421 NEUTRON_MINIAIO_F421 FOXEER_F421\  
+TARGETS_F421 := $(call get_targets,F421)
 
-HAL_FOLDER_F421 := $(HAL_FOLDER)/F421
+HAL_FOLDER_F421 := $(HAL_FOLDER)/f421
 
 MCU_F421 := -mcpu=cortex-m4 -mthumb 
 LDSCRIPT_F421 := $(HAL_FOLDER_F421)/AT32F421x6_FLASH.ld
@@ -22,6 +20,6 @@ CFLAGS_F421 := \
 CFLAGS_F421 += \
 	 -DAT32F421K8U7 \
 	 -DUSE_STDPERIPH_DRIVER
-	
+
 
 SRC_F421 := $(foreach dir,$(SRC_DIR_F421),$(wildcard $(dir)/*.[cs]))
diff --git a/g071makefile.mk b/g071makefile.mk
index 99fdfbef..c4b64e4a 100644
--- a/g071makefile.mk
+++ b/g071makefile.mk
@@ -1,7 +1,5 @@
 
-TARGETS_G071 := \
-	PWM_ENABLE_G071 OPEN_DRAIN_G071 OPEN_DRAIN_B_G071 GEN_64K_G071 DT120_64K_G071 IFLIGHT_BLITZ_G071  \
-	NEUTRONRC_G071 AIKON_PRO_G071 TMOTOR_G071 
+TARGETS_F071 := $(call get_targets,G071)
 
 HAL_FOLDER_G071 := $(HAL_FOLDER)/g071
 
diff --git a/gd32makefile.mk b/gd32makefile.mk
index 5f0c1c33..33aec53b 100644
--- a/gd32makefile.mk
+++ b/gd32makefile.mk
@@ -1,6 +1,5 @@
 
-TARGETS_GD32 := \
-	GD32TEST
+TARGETS_GD32 := $(call get_targets,GD32)
 
 HAL_FOLDER_GD32 := $(HAL_FOLDER)/f350
 
diff --git a/make/system-id.mk b/make/system-id.mk
deleted file mode 100644
index 1fd42ed4..00000000
--- a/make/system-id.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-# shared.mk
-#
-# environment variables common to all operating systems supported by the make system
-
-# Make sure we know a few things about the architecture
-UNAME := $(shell uname)
-ARCH := $(shell uname -m)
-ifneq (,$(filter $(ARCH), x86_64 amd64))
-  X86-64 := 1
-  X86_64 := 1
-  AMD64 := 1
-  ARCHFAMILY := x86_64
-else
-  ARCHFAMILY := $(ARCH)
-endif
-
-# configure some variables dependent upon what type of system this is
-
-# Linux
-ifeq ($(UNAME), Linux)
-  OSFAMILY := linux
-endif
-
-# Mac OSX
-ifeq ($(UNAME), Darwin)
-  OSFAMILY := macosx
-endif
-
-# Windows using MinGW shell
-ifeq (MINGW, $(findstring MINGW,$(UNAME)))
-  OSFAMILY := windows
-  MINGW := 1
-endif
-
-# Windows using Cygwin shell
-ifeq (CYGWIN ,$(findstring CYGWIN,$(UNAME)))
-  OSFAMILY := windows
-  CYGWIN := 1
-endif
-
-# report an error if we couldn't work out what OS this is running on
-ifndef OSFAMILY
-  $(info uname reports $(UNAME))
-  $(info uname -m reports $(ARCH))
-  $(error failed to detect operating system)
-endif
diff --git a/make/tools.mk b/make/tools.mk
index 23fa8772..f267a59d 100644
--- a/make/tools.mk
+++ b/make/tools.mk
@@ -2,318 +2,34 @@
 #
 # Installers for tools
 #
-# NOTE: These are not tied to the default goals
-#       and must be invoked manually
-#
 ###############################################################
 
-##############################
-#
-# Check that environmental variables are sane
-#
-##############################
-
-# Set up ARM (STM32) SDK
-ARM_SDK_DIR ?= $(TOOLS_DIR)/gcc-arm-none-eabi-10.3-2021.10
-# Checked below, Should match the output of $(shell arm-none-eabi-gcc -dumpversion)
-GCC_REQUIRED_VERSION ?= 10.3
-
-.PHONY: arm_sdk_version
-
-arm_sdk_version:
-	$(V1) $(ARM_SDK_PREFIX)gcc --version
-
-## arm_sdk_install   : Install Arm SDK
-.PHONY: arm_sdk_install
-
-
-ARM_SDK_URL_BASE  :=https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10
-# source: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
-ifeq ($(OSFAMILY), linux)
-  ARM_SDK_URL  := $(ARM_SDK_URL_BASE)-x86_64-linux.tar.bz2
-endif
-
-ifeq ($(OSFAMILY), macosx)
-  ARM_SDK_URL  := $(ARM_SDK_URL_BASE)-mac.tar.bz2
-endif
-
-ifeq ($(OSFAMILY), windows)
-  ARM_SDK_URL  := $(ARM_SDK_URL_BASE)-win32.zip
-endif
-
-ARM_SDK_FILE := $(notdir $(ARM_SDK_URL))
 
-SDK_INSTALL_MARKER := $(ARM_SDK_DIR)/bin/arm-none-eabi-gcc-$(GCC_REQUIRED_VERSION)
-
-# order-only prereq on directory existance:
-arm_sdk_install: | $(TOOLS_DIR)
-
-arm_sdk_install: arm_sdk_download $(SDK_INSTALL_MARKER)
-
-$(SDK_INSTALL_MARKER):
-ifneq ($(OSFAMILY), windows)
-        # binary only release so just extract it
-	$(V1) tar -C $(TOOLS_DIR) -xjf "$(DL_DIR)/$(ARM_SDK_FILE)"
+ifeq ($(OS),Windows_NT)
+ARM_SDK_PREFIX:=tools/windows/xpack-arm-none-eabi-gcc-10.3.1-2.3/bin/arm-none-eabi-
+SHELL:=cmd.exe
+CP:=tools\\windows\\make\\bin\\cp
+DSEP:=\\
+NUL:=NUL
+MKDIR:=tools\\windows\\make\\bin\\mkdir
+RM:=tools\\windows\\make\\bin\\rm
+CUT:=tools\\windows\\make\\bin\\cut
+FGREP:=tools\\windows\\make\\bin\\fgrep
 else
-	$(V1) unzip -q -d $(ARM_SDK_DIR) "$(DL_DIR)/$(ARM_SDK_FILE)"
-endif
-
-.PHONY: arm_sdk_download
-arm_sdk_download: | $(DL_DIR)
-arm_sdk_download: $(DL_DIR)/$(ARM_SDK_FILE)
-$(DL_DIR)/$(ARM_SDK_FILE):
-        # download the source only if it's newer than what we already have
-	$(V1) curl -L -k -o "$(DL_DIR)/$(ARM_SDK_FILE)" -z "$(DL_DIR)/$(ARM_SDK_FILE)" "$(ARM_SDK_URL)"
-
-
-## arm_sdk_clean     : Uninstall Arm SDK
-.PHONY: arm_sdk_clean
-arm_sdk_clean:
-	$(V1) [ ! -d "$(ARM_SDK_DIR)" ] || $(RM) -r $(ARM_SDK_DIR)
-	$(V1) [ ! -d "$(DL_DIR)" ] || $(RM) -r $(DL_DIR)
-
-.PHONY: openocd_win_install
-
-openocd_win_install: | $(DL_DIR) $(TOOLS_DIR)
-openocd_win_install: OPENOCD_URL  := git://git.code.sf.net/p/openocd/code
-openocd_win_install: OPENOCD_REV  := cf1418e9a85013bbf8dbcc2d2e9985695993d9f4
-openocd_win_install: OPENOCD_OPTIONS :=
-
-ifeq ($(OPENOCD_FTDI), yes)
-openocd_win_install: OPENOCD_OPTIONS := $(OPENOCD_OPTIONS) --enable-ft2232_ftd2xx --with-ftd2xx-win32-zipdir=$(FTD2XX_DIR)
-endif
-
-openocd_win_install: openocd_win_clean libusb_win_install ftd2xx_install
-        # download the source
-	@echo " DOWNLOAD     $(OPENOCD_URL) @ $(OPENOCD_REV)"
-	$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
-	$(V1) mkdir -p "$(OPENOCD_BUILD_DIR)"
-	$(V1) git clone --no-checkout $(OPENOCD_URL) "$(DL_DIR)/openocd-build"
-	$(V1) ( \
-	  cd $(OPENOCD_BUILD_DIR) ; \
-	  git checkout -q $(OPENOCD_REV) ; \
-	)
-
-        # apply patches
-	@echo " PATCH        $(OPENOCD_BUILD_DIR)"
-	$(V1) ( \
-	  cd $(OPENOCD_BUILD_DIR) ; \
-	  git apply < $(ROOT_DIR)/flight/Project/OpenOCD/0003-freertos-cm4f-fpu-support.patch ; \
-	  git apply < $(ROOT_DIR)/flight/Project/OpenOCD/0004-st-icdi-disable.patch ; \
-	)
-
-        # build and install
-	@echo " BUILD        $(OPENOCD_WIN_DIR)"
-	$(V1) mkdir -p "$(OPENOCD_WIN_DIR)"
-	$(V1) ( \
-	  cd $(OPENOCD_BUILD_DIR) ; \
-	  ./bootstrap ; \
-	  ./configure --enable-maintainer-mode --prefix="$(OPENOCD_WIN_DIR)" \
-		--build=i686-pc-linux-gnu --host=i586-mingw32msvc \
-		CPPFLAGS=-I$(LIBUSB_WIN_DIR)/include \
-		LDFLAGS=-L$(LIBUSB_WIN_DIR)/lib/gcc \
-		$(OPENOCD_OPTIONS) \
-		--disable-werror \
-		--enable-stlink ; \
-	  $(MAKE) ; \
-	  $(MAKE) install ; \
-	)
-
-        # delete the extracted source when we're done
-	$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
-
-.PHONY: openocd_win_clean
-openocd_win_clean:
-	@echo " CLEAN        $(OPENOCD_WIN_DIR)"
-	$(V1) [ ! -d "$(OPENOCD_WIN_DIR)" ] || $(RM) -r "$(OPENOCD_WIN_DIR)"
-
-# Set up openocd tools
-OPENOCD_DIR       := $(TOOLS_DIR)/openocd
-OPENOCD_WIN_DIR   := $(TOOLS_DIR)/openocd_win
-OPENOCD_BUILD_DIR := $(DL_DIR)/openocd-build
-
-.PHONY: openocd_install
-
-openocd_install: | $(DL_DIR) $(TOOLS_DIR)
-openocd_install: OPENOCD_URL     := git://git.code.sf.net/p/openocd/code
-openocd_install: OPENOCD_TAG     := v0.9.0
-openocd_install: OPENOCD_OPTIONS := --enable-maintainer-mode --prefix="$(OPENOCD_DIR)" --enable-buspirate --enable-stlink
-
-ifeq ($(OPENOCD_FTDI), yes)
-openocd_install: OPENOCD_OPTIONS := $(OPENOCD_OPTIONS) --enable-ftdi
-endif
-
-ifeq ($(UNAME), Darwin)
-openocd_install: OPENOCD_OPTIONS := $(OPENOCD_OPTIONS) --disable-option-checking
-endif
-
-openocd_install: openocd_clean
-        # download the source
-	@echo " DOWNLOAD     $(OPENOCD_URL) @ $(OPENOCD_TAG)"
-	$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
-	$(V1) mkdir -p "$(OPENOCD_BUILD_DIR)"
-	$(V1) git clone --no-checkout $(OPENOCD_URL) "$(OPENOCD_BUILD_DIR)"
-	$(V1) ( \
-	  cd $(OPENOCD_BUILD_DIR) ; \
-	  git checkout -q tags/$(OPENOCD_TAG) ; \
-	)
-
-        # build and install
-	@echo " BUILD        $(OPENOCD_DIR)"
-	$(V1) mkdir -p "$(OPENOCD_DIR)"
-	$(V1) ( \
-	  cd $(OPENOCD_BUILD_DIR) ; \
-	  ./bootstrap ; \
-	  ./configure  $(OPENOCD_OPTIONS) ; \
-	  $(MAKE) ; \
-	  $(MAKE) install ; \
-	)
-
-        # delete the extracted source when we're done
-	$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
-
-.PHONY: openocd_clean
-openocd_clean:
-	@echo " CLEAN        $(OPENOCD_DIR)"
-	$(V1) [ ! -d "$(OPENOCD_DIR)" ] || $(RM) -r "$(OPENOCD_DIR)"
-
-STM32FLASH_DIR := $(TOOLS_DIR)/stm32flash
-
-.PHONY: stm32flash_install
-stm32flash_install: STM32FLASH_URL := http://stm32flash.googlecode.com/svn/trunk
-stm32flash_install: STM32FLASH_REV := 61
-stm32flash_install: stm32flash_clean
-        # download the source
-	@echo " DOWNLOAD     $(STM32FLASH_URL) @ r$(STM32FLASH_REV)"
-	$(V1) svn export -q -r "$(STM32FLASH_REV)" "$(STM32FLASH_URL)" "$(STM32FLASH_DIR)"
-
-        # build
-	@echo " BUILD        $(STM32FLASH_DIR)"
-	$(V1) $(MAKE) --silent -C $(STM32FLASH_DIR) all
-
-.PHONY: stm32flash_clean
-stm32flash_clean:
-	@echo " CLEAN        $(STM32FLASH_DIR)"
-	$(V1) [ ! -d "$(STM32FLASH_DIR)" ] || $(RM) -r "$(STM32FLASH_DIR)"
-
-# Set up uncrustify tools
-UNCRUSTIFY_DIR := $(TOOLS_DIR)/uncrustify-0.61
-UNCRUSTIFY_BUILD_DIR := $(DL_DIR)/uncrustify
-
-.PHONY: uncrustify_install
-uncrustify_install: | $(DL_DIR) $(TOOLS_DIR)
-uncrustify_install: UNCRUSTIFY_URL := http://downloads.sourceforge.net/project/uncrustify/uncrustify/uncrustify-0.61/uncrustify-0.61.tar.gz
-uncrustify_install: UNCRUSTIFY_FILE := uncrustify-0.61.tar.gz
-uncrustify_install: UNCRUSTIFY_OPTIONS := prefix=$(UNCRUSTIFY_DIR)
-uncrustify_install: uncrustify_clean
-ifneq ($(OSFAMILY), windows)
-	@echo " DOWNLOAD     $(UNCRUSTIFY_URL)"
-	$(V1) curl -L -k -o "$(DL_DIR)/$(UNCRUSTIFY_FILE)" "$(UNCRUSTIFY_URL)"
-endif
-        # extract the src
-	@echo " EXTRACT      $(UNCRUSTIFY_FILE)"
-	$(V1) tar -C $(TOOLS_DIR) -xf "$(DL_DIR)/$(UNCRUSTIFY_FILE)"
-
-	@echo " BUILD        $(UNCRUSTIFY_DIR)"
-	$(V1) ( \
-	  cd $(UNCRUSTIFY_DIR) ; \
-	  ./configure --prefix="$(UNCRUSTIFY_DIR)" ; \
-	  $(MAKE) ; \
-	  $(MAKE) install ; \
-	)
-	      # delete the extracted source when we're done
-	$(V1) [ ! -d "$(UNCRUSTIFY_BUILD_DIR)" ] || $(RM) -r "$(UNCRUSTIFY_BUILD_DIR)"
-
-.PHONY: uncrustify_clean
-uncrustify_clean:
-	@echo " CLEAN        $(UNCRUSTIFY_DIR)"
-	$(V1) [ ! -d "$(UNCRUSTIFY_DIR)" ] || $(RM) -r "$(UNCRUSTIFY_DIR)"
-	@echo " CLEAN        $(UNCRUSTIFY_BUILD_DIR)"
-	$(V1) [ ! -d "$(UNCRUSTIFY_BUILD_DIR)" ] || $(RM) -r "$(UNCRUSTIFY_BUILD_DIR)"
-
-# ZIP download URL
-zip_install: ZIP_URL  := http://pkgs.fedoraproject.org/repo/pkgs/zip/zip30.tar.gz/7b74551e63f8ee6aab6fbc86676c0d37/zip30.tar.gz
-
-zip_install: ZIP_FILE := $(notdir $(ZIP_URL))
-
-ZIP_DIR = $(TOOLS_DIR)/zip30
-
-# order-only prereq on directory existance:
-zip_install : | $(DL_DIR) $(TOOLS_DIR)
-zip_install: zip_clean
-	$(V1) curl -L -k -o "$(DL_DIR)/$(ZIP_FILE)" "$(ZIP_URL)"
-	$(V1) tar --force-local -C $(TOOLS_DIR) -xzf "$(DL_DIR)/$(ZIP_FILE)"
-ifneq ($(OSFAMILY), windows)
-	$(V1) cd "$(ZIP_DIR)" && $(MAKE) -f unix/Makefile generic_gcc
-else
-	$(V1) cd "$(ZIP_DIR)" && $(MAKE) -f win32/makefile.gcc
-endif
-
-.PHONY: zip_clean
-zip_clean:
-	$(V1) [ ! -d "$(ZIP_DIR)" ] || $(RM) -rf $(ZIP_DIR)
-
-##############################
-#
-# Set up paths to tools
-#
-##############################
-
-ifeq ($(shell [ -d "$(ARM_SDK_DIR)" ] && echo "exists"), exists)
-  ARM_SDK_PREFIX := $(ARM_SDK_DIR)/bin/arm-none-eabi-
-else ifeq (,$(findstring _install,$(MAKECMDGOALS)))
-  GCC_VERSION = $(shell arm-none-eabi-gcc -dumpversion)
-  ifeq ($(GCC_VERSION),)
-    $(error **ERROR** arm-none-eabi-gcc not in the PATH. Run 'make arm_sdk_install' to install automatically in the tools folder of this repo)
-  else ifneq ($(GCC_VERSION), $(GCC_REQUIRED_VERSION))
-    $(error **ERROR** your arm-none-eabi-gcc is '$(GCC_VERSION)', but '$(GCC_REQUIRED_VERSION)' is expected. Override with 'GCC_REQUIRED_VERSION' in make/local.mk or run 'make arm_sdk_install' to install the right version automatically in the tools folder of this repo)
-  endif
-
-  # ARM tookchain is in the path, and the version is what's required.
-  ARM_SDK_PREFIX ?= arm-none-eabi-
-endif
-
-ifeq ($(shell [ -d "$(ZIP_DIR)" ] && echo "exists"), exists)
-  export ZIPBIN := $(ZIP_DIR)/zip
-else
-  export ZIPBIN := zip
-endif
-
-ifeq ($(shell [ -d "$(OPENOCD_DIR)" ] && echo "exists"), exists)
-  OPENOCD := $(OPENOCD_DIR)/bin/openocd
-else
-  # not installed, hope it's in the path...
-  OPENOCD ?= openocd
-endif
-
-ifeq ($(shell [ -d "$(UNCRUSTIFY_DIR)" ] && echo "exists"), exists)
-  UNCRUSTIFY := $(UNCRUSTIFY_DIR)/bin/uncrustify
-else
-  # not installed, hope it's in the path...
-  UNCRUSTIFY ?= uncrustify
-endif
-
-# Google Breakpad
-DUMP_SYMBOLS_TOOL := $(TOOLS_DIR)/breakpad/$(OSFAMILY)-$(ARCHFAMILY)/dump_syms
-BREAKPAD_URL := http://dronin.tracer.nz/tools/breakpad.zip
-BREAKPAD_DL_FILE := $(DL_DIR)/$(notdir $(BREAKPAD_URL))
-BREAKPAD_DIR := $(TOOLS_DIR)/breakpad
-
-.PHONY: breakpad_install
-breakpad_install: | $(DL_DIR) $(TOOLS_DIR)
-breakpad_install: breakpad_clean
-	@echo " DOWNLOAD     $(BREAKPAD_URL)"
-	$(V1) $(V1) curl -L -k -z "$(BREAKPAD_DL_FILE)" -o "$(BREAKPAD_DL_FILE)" "$(BREAKPAD_URL)"
-	@echo " EXTRACT      $(notdir $(BREAKPAD_DL_FILE))"
-	$(V1) mkdir -p "$(BREAKPAD_DIR)"
-	$(V1) unzip -q -d $(BREAKPAD_DIR) "$(BREAKPAD_DL_FILE)"
-ifeq ($(OSFAMILY), windows)
-	$(V1) ln -s "$(TOOLS_DIR)/breakpad/$(OSFAMILY)-i686" "$(TOOLS_DIR)/breakpad/$(OSFAMILY)-x86_64"
-endif
-
-.PHONY: breakpad_clean
-breakpad_clean:
-	@echo " CLEAN        $(BREAKPAD_DIR)"
-	$(V1) [ ! -d "$(BREAKPAD_DIR)" ] || $(RM) -rf $(BREAKPAD_DIR)
-	@echo " CLEAN        $(BREAKPAD_DL_FILE)"
-	$(V1) $(RM) -f $(BREAKPAD_DL_FILE)
+ARM_SDK_PREFIX:=tools/linux/xpack-arm-none-eabi-gcc-10.3.1-2.3/bin/arm-none-eabi-
+CP:=cp
+DSEP:=/
+NUL:=/dev/null
+MKDIR:=mkdir
+RM:=rm
+CUT:=cut
+FGREP:=fgrep
+endif
+
+# workaround for lack of a lowercase function in GNU make
+# look away before this sends you blind ....
+lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
+
+define get_targets
+$(shell $(FGREP) "define FILE_NAME" Inc/targets.h | $(FGREP) -v DISABLE_BUILD | $(FGREP) _$(1) | $(CUT) -d\" -f2)
+endef
diff --git a/make/tools_install.mk b/make/tools_install.mk
new file mode 100644
index 00000000..9d1e4bca
--- /dev/null
+++ b/make/tools_install.mk
@@ -0,0 +1,25 @@
+# rules to download and install the tools for windows and linux
+
+# download location for tools
+WINDOWS_TOOLS=https://firmware.ardupilot.org/Tools/AM32-tools/windows-tools.zip
+LINUX_TOOLS=https://firmware.ardupilot.org/Tools/AM32-tools/linux-tools.tar.gz
+
+ifeq ($(OS),Windows_NT)
+
+arm_sdk_install:
+	@echo Installing windows tools
+	@echo downloading windows-tools.zip
+	@powershell -Command "& { (New-Object System.Net.WebClient).DownloadFile('$(WINDOWS_TOOLS)', 'windows-tools.zip') }"
+	@echo unpacking windows-tools.zip
+	@powershell -Command "Expand-Archive -Path windows-tools.zip -Force -DestinationPath ."
+	@echo windows tools install done
+
+else
+
+arm_sdk_install:
+	@echo Installing linux tools
+	@wget $(LINUX_TOOLS)
+	@tar xzf linux-tools.tar.gz
+	@echo linux tools install done
+
+endif
diff --git a/makefile b/makefile
deleted file mode 100644
index c13646fe..00000000
--- a/makefile
+++ /dev/null
@@ -1,119 +0,0 @@
-QUIET = @
-
-# tools
-CC = $(ARM_SDK_PREFIX)gcc
-CP = $(ARM_SDK_PREFIX)objcopy
-ECHO = echo
-
-# common variables
-IDENTIFIER := AM32
-
-# Folders
-HAL_FOLDER := Mcu
-MAIN_SRC_DIR := Src
-MAIN_INC_DIR := Inc
-
-SRC_DIRS_COMMON := $(MAIN_SRC_DIR)
-
-# Include processor specific makefiles
-include f051makefile.mk
-include g071makefile.mk
-include f031makefile.mk
-include f421makefile.mk
-include e230makefile.mk
-include f415makefile.mk
-
-# Default MCU type to F051
-MCU_TYPE ?= F051
-
-# additional libs
-LIBS := -lc -lm -lnosys
-
-# Compiler options
-CFLAGS_COMMON := -DUSE_MAKE
-CFLAGS_COMMON += -I$(MAIN_INC_DIR) -O3 -Wall -ffunction-sections
-CFLAGS_COMMON += -D$(TARGET)
-
-# Linker options
-LDFLAGS_COMMON := -specs=nano.specs $(LIBS) -Wl,--gc-sections -Wl,--print-memory-usage
-
-# Working directories
-ROOT := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
-
-# Search source files
-SRC_COMMON := $(foreach dir,$(SRC_DIRS_COMMON),$(wildcard $(dir)/*.[cs]))
-
-VERSION_MAJOR := $(shell grep "#define VERSION_MAJOR" $(MAIN_SRC_DIR)/main.c | awk '{print $$3}' )
-VERSION_MINOR := $(shell grep "#define VERSION_MINOR" $(MAIN_SRC_DIR)/main.c | awk '{print $$3}' )
-
-FIRMWARE_VERSION := $(VERSION_MAJOR).$(VERSION_MINOR)
-
-TARGET_BASENAME = $(BIN_DIR)/$(IDENTIFIER)_$(TARGET)_$(FIRMWARE_VERSION)
-
-# Build tools, so we all share the same versions
-# import macros common to all supported build systems
-include $(ROOT)/make/system-id.mk
-
-# configure some directories that are relative to wherever ROOT_DIR is located
-BIN_DIR := $(ROOT)/obj
-
-TOOLS_DIR ?= $(ROOT)/tools
-DL_DIR := $(ROOT)/downloads
-
-.PHONY : clean all binary f051 g071 f031 e230 f421 f415
-all : $(TARGETS_F051) $(TARGETS_G071) $(TARGETS_F031) $(TARGETS_E230) $(TARGETS_F421) $(TARGETS_F415)
-f051 : $(TARGETS_F051)
-g071 : $(TARGETS_G071)
-f031 : $(TARGETS_F031)
-e230 : $(TARGETS_E230)
-f421 : $(TARGETS_F421)
-f415 : $(TARGETS_F415)
-
-clean :
-	rm -rf $(BIN_DIR)/*
-
-binary : $(TARGET_BASENAME).bin
-	@$(ECHO) All done
-
-$(TARGETS_F051) :
-	@$(MAKE) -s MCU_TYPE=F051 TARGET=$@ binary
-
-$(TARGETS_G071) :
-	@$(MAKE) -s MCU_TYPE=G071 TARGET=$@ binary
-
-$(TARGETS_F031) :
-	@$(MAKE) -s MCU_TYPE=F031 TARGET=$@ binary
-
-$(TARGETS_E230) :
-	@$(MAKE) -s MCU_TYPE=E230 TARGET=$@ binary
-
-$(TARGETS_F421) :
-	@$(MAKE) -s MCU_TYPE=F421 TARGET=$@ binary	
-
-$(TARGETS_F415) :
-	@$(MAKE) -s MCU_TYPE=F415 TARGET=$@ binary		
-
-# Compile target
-$(TARGET_BASENAME).elf: SRC := $(SRC_COMMON) $(SRC_$(MCU_TYPE))
-$(TARGET_BASENAME).elf: CFLAGS := $(MCU_F051) $(CFLAGS_$(MCU_TYPE)) $(CFLAGS_COMMON)
-$(TARGET_BASENAME).elf: LDFLAGS := $(LDFLAGS_COMMON) $(LDFLAGS_$(MCU_TYPE)) -T$(LDSCRIPT_$(MCU_TYPE))
-$(TARGET_BASENAME).elf: $(SRC)
-	@$(ECHO) Compiling $(notdir $@)
-	$(QUIET)mkdir -p $(dir $@)
-	$(QUIET)$(CC) $(CFLAGS) $(LDFLAGS) -MMD -MP -MF $(@:.elf=.d) -o $(@) $(SRC)
-
-# Generate bin and hex files
-$(TARGET_BASENAME).bin: $(TARGET_BASENAME).elf
-	@$(ECHO) Generating $(notdir $@)
-	$(QUIET)$(CP) -O binary $(<) $@
-	$(QUIET)$(CP) $(<) -O ihex $(@:.bin=.hex)
-
-# mkdirs
-$(DL_DIR):
-	$(QUIET)mkdir -p $@
-
-$(TOOLS_DIR):
-	$(QUIET)mkdir -p $@
-
-# include the tools makefile
-include $(ROOT)/make/tools.mk
diff --git a/tools/openocd-at32f421.cfg b/tools/openocd-at32f421.cfg
new file mode 100644
index 00000000..eba041df
--- /dev/null
+++ b/tools/openocd-at32f421.cfg
@@ -0,0 +1,4 @@
+source [find interface/stlink.cfg]
+source [find target/at32f421xx.cfg]
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -gdb-max-connections 4
+init