diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h
index 48b1a113f6..644eeee54d 100644
--- a/Marlin/src/core/boards.h
+++ b/Marlin/src/core/boards.h
@@ -305,6 +305,7 @@
#define BOARD_MKS_ROBIN_E3D 4026 // MKS Robin E3D (STM32F103RCT6)
#define BOARD_MKS_ROBIN_E3 4027 // MKS Robin E3 (STM32F103RCT6)
#define BOARD_MALYAN_M300 4028 // STM32F070-based delta
+#define BOARD_CCROBOT_MEEB_3DP 4029 // ccrobot-online.com MEEB_3DP (STM32F103RC)
//
// ARM Cortex-M4F
diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h
index 9f67781533..b8f01e5626 100644
--- a/Marlin/src/pins/pins.h
+++ b/Marlin/src/pins/pins.h
@@ -534,6 +534,8 @@
#include "stm32f1/pins_MKS_ROBIN_E3D.h" // STM32F1 env:mks_robin_e3
#elif MB(MKS_ROBIN_E3)
#include "stm32f1/pins_MKS_ROBIN_E3.h" // STM32F1 env:mks_robin_e3
+#elif MB(CCROBOT_MEEB_3DP)
+ #include "stm32f1/pins_CCROBOT_MEEB_3DP.h" // STM32F1 env:STM32F103RC_cc_meeb_3dp
//
// ARM Cortex-M4F
diff --git a/Marlin/src/pins/stm32f1/pins_CCROBOT_MEEB_3DP.h b/Marlin/src/pins/stm32f1/pins_CCROBOT_MEEB_3DP.h
new file mode 100644
index 0000000000..6cfa4e2144
--- /dev/null
+++ b/Marlin/src/pins/stm32f1/pins_CCROBOT_MEEB_3DP.h
@@ -0,0 +1,173 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#ifndef TARGET_STM32F1
+ #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
+#elif HOTENDS > 1 || E_STEPPERS > 1
+ #error "CCROBOT-ONLINE MEEB_3DP only supports 1 hotend / E-stepper. Comment out this line to continue."
+#endif
+
+// https://github.com/ccrobot-online/MEEB_3DP
+// Pin assignments for 32-bit MEEB_3DP
+#define BOARD_INFO_NAME "CCROBOT-ONLINE MEEB_3DP"
+#define DEFAULT_MACHINE_NAME "STM32F103RCT6"
+#define BOARD_WEBSITE_URL "ccrobot-online.com"
+
+//
+// Release PB4 from JTAG NRST role
+//
+#define DISABLE_JTAG
+
+//
+// EEPROM
+//
+#if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION)
+ #define FLASH_EEPROM_EMULATION
+ #define EEPROM_PAGE_SIZE 0x800U // 2KB
+ #define EEPROM_START_ADDRESS (0x8000000UL + (STM32_FLASH_SIZE) * 1024UL - (EEPROM_PAGE_SIZE) * 2UL)
+ #define MARLIN_EEPROM_SIZE 0x1000 // 4KB
+#endif
+
+//
+// Servos
+//
+#define SERVO0_PIN PA1
+
+//
+// Limit Switches
+//
+#define X_STOP_PIN PC0
+#define Y_STOP_PIN PC1
+#define Z_STOP_PIN PC2
+
+//
+// Z Probe must be this pin
+//
+#define Z_MIN_PROBE_PIN PC15 // "PROBE"
+
+//
+// TMC2208 stepper drivers
+//
+#define X_ENABLE_PIN PB4
+#define X_STEP_PIN PC12
+#define X_DIR_PIN PC11
+
+#define Y_ENABLE_PIN PC10
+#define Y_STEP_PIN PB14
+#define Y_DIR_PIN PB13
+
+#define Z_ENABLE_PIN PB12
+#define Z_STEP_PIN PB2
+#define Z_DIR_PIN PB1
+
+#define E0_ENABLE_PIN PB0
+#define E0_STEP_PIN PA6
+#define E0_DIR_PIN PA5
+
+// Stepper drivers Serial UART
+#define X_SERIAL_TX_PIN PB3
+#define X_SERIAL_RX_PIN PD2
+#define Y_SERIAL_TX_PIN PA15
+#define Y_SERIAL_RX_PIN PC6
+#define Z_SERIAL_TX_PIN PB11
+#define Z_SERIAL_RX_PIN PB10
+#define E0_SERIAL_TX_PIN PC5
+#define E0_SERIAL_RX_PIN PC4
+
+// Reduce baud rate to improve software serial reliability
+#define TMC_BAUD_RATE 19200
+
+//
+// Temperature Sensors
+//
+#define TEMP_0_PIN PA0 // TH0
+#define TEMP_BED_PIN PC3 // THB
+
+//
+// Heaters / Fans
+//
+#define HEATER_0_PIN PC8 // HEATER0
+#define HEATER_BED_PIN PC9 // HOT BED
+
+#define FAN_PIN PA7 // FAN (fan2 on board) model cool fan
+#define FAN1_PIN PA8 // FAN (fan0 on board) e0 cool fan
+#define FAN2_PIN PB9 // FAN (fan1 on board) controller cool fan
+
+// One neopixel onboard and a connector for other neopixels
+#define NEOPIXEL_PIN PC7 // The NEOPIXEL LED driving pin
+
+/**
+ * 1 _____ 2
+ * PB5 | · · | PB6
+ * PA2 | · · | RESET
+ * PA3 | · · | PB8
+ * PB7 | · · | PA4
+ * GND | · · | VCC5
+ * 9 ----- 10
+ * LCD EXP
+ */
+
+//
+// LCD / Controller
+//
+#if ENABLED(CR10_STOCKDISPLAY)
+ #define BEEPER_PIN PB5
+ #define BTN_EN1 PA2
+ #define BTN_EN2 PA3
+ #define BTN_ENC PB6
+
+ #define LCD_PINS_RS PB7 // CS -- SOFT SPI for ENDER3 LCD
+ #define LCD_PINS_D4 PB8 // SCLK
+ #define LCD_PINS_ENABLE PA4 // DATA MOSI
+#endif
+
+// Alter timing for graphical display
+#if HAS_GRAPHICAL_LCD
+ #define BOARD_ST7920_DELAY_1 DELAY_NS(125)
+ #define BOARD_ST7920_DELAY_2 DELAY_NS(125)
+ #define BOARD_ST7920_DELAY_3 DELAY_NS(125)
+#endif
+
+//
+// Camera
+//
+#define CHDK_PIN PB15
+
+#if 0
+
+//
+// SD-NAND
+//
+#if SD_CONNECTION_IS(ONBOARD)
+ #define ENABLE_SPI1
+ #define SD_DETECT_PIN -1
+ #define SCK_PIN PA5
+ #define MISO_PIN PA6
+ #define MOSI_PIN PA7
+ #define SS_PIN PA4
+#endif
+
+#define ON_BOARD_SPI_DEVICE 1 // SPI1
+#define ONBOARD_SD_CS_PIN PA4 // Chip select for SD-NAND
+
+#endif
diff --git a/buildroot/share/PlatformIO/boards/MEEB_3DP.json b/buildroot/share/PlatformIO/boards/MEEB_3DP.json
new file mode 100644
index 0000000000..870648b325
--- /dev/null
+++ b/buildroot/share/PlatformIO/boards/MEEB_3DP.json
@@ -0,0 +1,53 @@
+{
+ "build": {
+ "core": "maple",
+ "cpu": "cortex-m3",
+ "extra_flags": "-DSTM32F103xE -DSTM32F1",
+ "f_cpu": "72000000L",
+ "hwids": [
+ [
+ "0x1EAF",
+ "0x0003"
+ ],
+ [
+ "0x1EAF",
+ "0x0004"
+ ]
+ ],
+ "libopencm3": {
+ "ldscript": "stm32f103xc.ld"
+ },
+ "mcu": "stm32f103rct6",
+ "variant": "MEEB_3DP"
+ },
+ "debug": {
+ "jlink_device": "STM32F103RC",
+ "openocd_target": "stm32f1x",
+ "svd_path": "STM32F103xx.svd"
+ },
+ "frameworks": [
+ "arduino",
+ "cmsis",
+ "libopencm3",
+ "stm32cube"
+ ],
+ "name": "3D Printer control board for MEEB with 512k flash/rs422 bus/tmc2208 drivers",
+ "upload": {
+ "disable_flushing": false,
+ "maximum_ram_size": 49152,
+ "maximum_size": 524288,
+ "protocol": "dfu",
+ "protocols": [
+ "jlink",
+ "stlink",
+ "blackmagic",
+ "serial",
+ "dfu"
+ ],
+ "require_upload_port": true,
+ "use_1200bps_touch": false,
+ "wait_for_upload_port": false
+ },
+ "url": "https://github.com/ccrobot-online/MEEB_3DP",
+ "vendor": "CCROBOT-ONLINE"
+}
diff --git a/buildroot/share/PlatformIO/ldscripts/STM32F103RC_MEEB_3DP.ld b/buildroot/share/PlatformIO/ldscripts/STM32F103RC_MEEB_3DP.ld
new file mode 100644
index 0000000000..01609b9b2c
--- /dev/null
+++ b/buildroot/share/PlatformIO/ldscripts/STM32F103RC_MEEB_3DP.ld
@@ -0,0 +1,14 @@
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K - 40
+ rom (rx) : ORIGIN = 0x08002000, LENGTH = 512K - 8K - 4K
+}
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", rom);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP.py b/buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP.py
new file mode 100644
index 0000000000..9176ab3278
--- /dev/null
+++ b/buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP.py
@@ -0,0 +1,61 @@
+try:
+ import configparser
+except ImportError:
+ import ConfigParser as configparser
+
+import os
+Import("env", "projenv")
+# access to global build environment
+print(env)
+# access to project build environment (is used source files in "src" folder)
+print(projenv)
+
+config = configparser.ConfigParser()
+config.read("platformio.ini")
+
+#com_port = config.get("env:STM32F103RC_cc_meeb_3dp", "upload_port")
+#print('Use the {0:s} to reboot the board to dfu mode.'.format(com_port))
+
+#
+# Upload actions
+#
+
+def before_upload(source, target, env):
+ print("before_upload")
+ # do some actions
+ # use com_port
+ #
+ env.Execute("pwd")
+
+def after_upload(source, target, env):
+ print("after_upload")
+ # do some actions
+ #
+ #
+ env.Execute("pwd")
+
+print("Current build targets", map(str, BUILD_TARGETS))
+
+env.AddPreAction("upload", before_upload)
+env.AddPostAction("upload", after_upload)
+
+flash_size = 0
+vect_tab_addr = 0
+
+for define in env['CPPDEFINES']:
+ if define[0] == "VECT_TAB_ADDR":
+ vect_tab_addr = define[1]
+ if define[0] == "STM32_FLASH_SIZE":
+ flash_size = define[1]
+
+print('Use the {0:s} address as the marlin app entry point.'.format(vect_tab_addr))
+print('Use the {0:d}KB flash version of stm32f103rct6 chip.'.format(flash_size))
+
+custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/STM32F103RC_MEEB_3DP.ld")
+for i, flag in enumerate(env["LINKFLAGS"]):
+ if "-Wl,-T" in flag:
+ env["LINKFLAGS"][i] = "-Wl,-T" + custom_ld_script
+ elif flag == "-T":
+ env["LINKFLAGS"][i + 1] = custom_ld_script
+
+
diff --git a/buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP_create_variant.py b/buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP_create_variant.py
new file mode 100644
index 0000000000..e4f9b672d1
--- /dev/null
+++ b/buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP_create_variant.py
@@ -0,0 +1,34 @@
+import os,shutil
+from SCons.Script import DefaultEnvironment
+from platformio import util
+
+def copytree(src, dst, symlinks=False, ignore=None):
+ for item in os.listdir(src):
+ s = os.path.join(src, item)
+ d = os.path.join(dst, item)
+ if os.path.isdir(s):
+ shutil.copytree(s, d, symlinks, ignore)
+ else:
+ shutil.copy2(s, d)
+
+env = DefaultEnvironment()
+platform = env.PioPlatform()
+board = env.BoardConfig()
+
+FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoststm32-maple")
+assert os.path.isdir(FRAMEWORK_DIR)
+assert os.path.isdir("buildroot/share/PlatformIO/variants")
+
+variant = board.get("build.variant")
+variant_dir = os.path.join(FRAMEWORK_DIR, "STM32F1", "variants", variant)
+
+source_dir = os.path.join("buildroot/share/PlatformIO/variants", variant)
+assert os.path.isdir(source_dir)
+
+if os.path.isdir(variant_dir):
+ shutil.rmtree(variant_dir)
+
+if not os.path.isdir(variant_dir):
+ os.mkdir(variant_dir)
+
+copytree(source_dir, variant_dir)
\ No newline at end of file
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/board.cpp b/buildroot/share/PlatformIO/variants/MEEB_3DP/board.cpp
new file mode 100644
index 0000000000..5b602de49a
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/board.cpp
@@ -0,0 +1,162 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2011 LeafLabs, LLC.
+ *
+ * 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.
+ *****************************************************************************/
+
+/**
+ * @file wirish/boards/maple/board.cpp
+ * @author Marti Bolivar
+ * @brief Maple board file.
+ */
+
+#include // For this board's header file
+
+
+/* Roger Clark. Added next to includes for changes to Serial */
+#include
+#include
+
+#include // For stm32_pin_info and its contents
+ // (these go into PIN_MAP).
+
+#include "boards_private.h" // For PMAP_ROW(), which makes
+ // PIN_MAP easier to read.
+
+// boardInit(): nothing special to do for Maple.
+//
+// When defining your own board.cpp, you can put extra code in this
+// function if you have anything you want done on reset, before main()
+// or setup() are called.
+//
+// If there's nothing special you need done, feel free to leave this
+// function out, as we do here.
+
+void boardInit(void) {
+ // afio_remap(AFIO_REMAP_I2C1);
+}
+
+
+// Pin map: this lets the basic I/O functions (digitalWrite(),
+// analogRead(), pwmWrite()) translate from pin numbers to STM32
+// peripherals.
+//
+// PMAP_ROW() lets us specify a row (really a struct stm32_pin_info)
+// in the pin map. Its arguments are:
+//
+// - GPIO device for the pin (&gpioa, etc.)
+// - GPIO bit for the pin (0 through 15)
+// - Timer device, or NULL if none
+// - Timer channel (1 to 4, for PWM), or 0 if none
+// - ADC device, or NULL if none
+// - ADC channel, or ADCx if none
+
+extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = {
+/*
+ gpio_dev *gpio_device; GPIO device
+ timer_dev *timer_device; Pin's timer device, if any.
+ const adc_dev *adc_device; ADC device, if any.
+ uint8 gpio_bit; Pin's GPIO port bit.
+ uint8 timer_channel; Timer channel, or 0 if none.
+ uint8 adc_channel; Pin ADC channel, or ADCx if none.
+*/
+
+ {&gpioa, &timer2, &adc1, 0, 1, 0}, /* PA0 */
+ {&gpioa, &timer2, &adc1, 1, 2, 1}, /* PA1 */
+ {&gpioa, &timer2, &adc1, 2, 3, 2}, /* PA2 */
+ {&gpioa, &timer2, &adc1, 3, 4, 3}, /* PA3 */
+ {&gpioa, NULL, &adc1, 4, 0, 4}, /* PA4 */
+ {&gpioa, NULL, &adc1, 5, 0, 5}, /* PA5 */
+ {&gpioa, &timer3, &adc1, 6, 1, 6}, /* PA6 */
+ {&gpioa, &timer3, &adc1, 7, 2, 7}, /* PA7 */
+ {&gpioa, &timer1, NULL, 8, 1, ADCx}, /* PA8 */
+ {&gpioa, &timer1, NULL, 9, 2, ADCx}, /* PA9 */
+ {&gpioa, &timer1, NULL, 10, 3, ADCx}, /* PA10 */
+ {&gpioa, NULL, NULL, 11, 0, ADCx}, /* PA11 */
+ {&gpioa, NULL, NULL, 12, 0, ADCx}, /* PA12 */
+ {&gpioa, NULL, NULL, 13, 0, ADCx}, /* PA13 */
+ {&gpioa, NULL, NULL, 14, 0, ADCx}, /* PA14 */
+ {&gpioa, NULL, NULL, 15, 0, ADCx}, /* PA15 */
+
+ {&gpiob, &timer3, &adc1, 0, 3, 8}, /* PB0 */
+ {&gpiob, &timer3, &adc1, 1, 4, 9}, /* PB1 */
+ {&gpiob, NULL, NULL, 2, 0, ADCx}, /* PB2 */
+ {&gpiob, NULL, NULL, 3, 0, ADCx}, /* PB3 */
+ {&gpiob, NULL, NULL, 4, 0, ADCx}, /* PB4 */
+ {&gpiob, NULL, NULL, 5, 0, ADCx}, /* PB5 */
+ {&gpiob, &timer4, NULL, 6, 1, ADCx}, /* PB6 */
+ {&gpiob, &timer4, NULL, 7, 2, ADCx}, /* PB7 */
+ {&gpiob, &timer4, NULL, 8, 3, ADCx}, /* PB8 */
+ {&gpiob, NULL, NULL, 9, 0, ADCx}, /* PB9 */
+ {&gpiob, NULL, NULL, 10, 0, ADCx}, /* PB10 */
+ {&gpiob, NULL, NULL, 11, 0, ADCx}, /* PB11 */
+ {&gpiob, NULL, NULL, 12, 0, ADCx}, /* PB12 */
+ {&gpiob, NULL, NULL, 13, 0, ADCx}, /* PB13 */
+ {&gpiob, NULL, NULL, 14, 0, ADCx}, /* PB14 */
+ {&gpiob, NULL, NULL, 15, 0, ADCx}, /* PB15 */
+
+
+ {&gpioc, NULL, &adc1, 0, 0, 10}, /* PC0 */
+ {&gpioc, NULL, &adc1, 1, 0, 11}, /* PC1 */
+ {&gpioc, NULL, &adc1, 2, 0, 12}, /* PC2 */
+ {&gpioc, NULL, &adc1, 3, 0, 13}, /* PC3 */
+ {&gpioc, NULL, &adc1, 4, 0, 14}, /* PC4 */
+ {&gpioc, NULL, &adc1, 5, 0, 15}, /* PC5 */
+ {&gpioc, &timer8, NULL, 6, 1, ADCx}, /* PC6 */
+ {&gpioc, &timer8, NULL, 7, 2, ADCx}, /* PC7 */
+ {&gpioc, &timer8, NULL, 8, 3, ADCx}, /* PC8 */
+ {&gpioc, &timer8, NULL, 9, 4, ADCx}, /* PC9 */
+ {&gpioc, NULL, NULL, 10, 0, ADCx}, /* PC10 UART4_TX/SDIO_D2 */
+ {&gpioc, NULL, NULL, 11, 0, ADCx}, /* PC11 UART4_RX/SDIO_D3 */
+ {&gpioc, NULL, NULL, 12, 0, ADCx}, /* PC12 UART5_TX/SDIO_CK */
+ {&gpioc, NULL, NULL, 13, 0, ADCx}, /* PC13 TAMPER-RTC */
+ {&gpioc, NULL, NULL, 14, 0, ADCx}, /* PC14 OSC32_IN */
+ {&gpioc, NULL, NULL, 15, 0, ADCx}, /* PC15 OSC32_OUT */
+
+ {&gpiod, NULL, NULL, 0, 0, ADCx} , /* PD0 OSC_IN */
+ {&gpiod, NULL, NULL, 1, 0, ADCx} , /* PD1 OSC_OUT */
+ {&gpiod, NULL, NULL, 2, 0, ADCx} , /* PD2 TIM3_ETR/UART5_RX SDIO_CMD */
+};
+
+/* Basically everything that is defined as having a timer us PWM */
+extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = {
+ PA0,PA1,PA2,PA3,PA6,PA7,PA8,PA9,PA10,PB0,PB1,PB6,PB7,PB8,PB9,PC6,PC7,PC8,PC9
+};
+
+/* Basically everything that is defined having ADC */
+extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = {
+ PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PB0,PB1,PC0,PC1,PC2,PC3,PC4,PC5
+};
+
+/* not sure what this us used for */
+extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = {
+ BOARD_JTMS_SWDIO_PIN,
+ BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN
+};
+
+DEFINE_HWSERIAL(Serial1, 1);
+DEFINE_HWSERIAL(Serial2, 2);
+DEFINE_HWSERIAL(Serial3, 3);
+DEFINE_HWSERIAL_UART(Serial4, 4);
+DEFINE_HWSERIAL_UART(Serial5, 5);
+
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/board/board.h b/buildroot/share/PlatformIO/variants/MEEB_3DP/board/board.h
new file mode 100644
index 0000000000..da9ffd893f
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/board/board.h
@@ -0,0 +1,125 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2011 LeafLabs, LLC.
+ *
+ * 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.
+ *****************************************************************************/
+
+/**
+ * @file maple_RET6.h
+ * @author Marti Bolivar
+ * @brief Private include file for Maple RET6 Edition in boards.h
+ *
+ * See maple.h for more information on these definitions.
+ */
+
+#ifndef _BOARDS_GENERIC_STM32F103R_H_
+#define _BOARDS_GENERIC_STM32F103R_H_
+
+/* A few of these values will seem strange given that it's a
+ * high-density board. */
+
+#define CYCLES_PER_MICROSECOND 72
+#define SYSTICK_RELOAD_VAL (F_CPU/1000) - 1 /* takes a cycle to reload */
+
+// USARTS
+#define BOARD_NR_USARTS 5
+#define BOARD_USART1_TX_PIN PA9
+#define BOARD_USART1_RX_PIN PA10
+
+#define BOARD_USART2_TX_PIN PA2
+#define BOARD_USART2_RX_PIN PA3
+
+#define BOARD_USART3_TX_PIN PB10
+#define BOARD_USART3_RX_PIN PB11
+
+#define BOARD_USART4_TX_PIN PC10
+#define BOARD_USART4_RX_PIN PC11
+
+#define BOARD_USART5_TX_PIN PC12
+#define BOARD_USART5_RX_PIN PD2
+
+/* Note:
+ *
+ * SPI3 is unusable due to pin 43 (PB4) and NRST tie-together :(, but
+ * leave the definitions so as not to clutter things up. This is only
+ * OK since RET6 Ed. is specifically advertised as a beta board. */
+#define BOARD_NR_SPI 3
+#define BOARD_SPI1_NSS_PIN PA4
+#define BOARD_SPI1_SCK_PIN PA5
+#define BOARD_SPI1_MISO_PIN PA6
+#define BOARD_SPI1_MOSI_PIN PA7
+
+
+
+#define BOARD_SPI2_NSS_PIN PB12
+#define BOARD_SPI2_SCK_PIN PB13
+#define BOARD_SPI2_MISO_PIN PB14
+#define BOARD_SPI2_MOSI_PIN PB15
+
+
+#define BOARD_SPI3_NSS_PIN PA15
+#define BOARD_SPI3_SCK_PIN PB3
+#define BOARD_SPI3_MISO_PIN PB4
+#define BOARD_SPI3_MOSI_PIN PB5
+
+
+/* GPIO A to E = 5 * 16 - BOOT1 not used = 79*/
+#define BOARD_NR_GPIO_PINS 51
+/* Note: NOT 19. The missing one is D38 a.k.a. BOARD_BUTTON_PIN, which
+ * isn't broken out to a header and is thus unusable for PWM. */
+#define BOARD_NR_PWM_PINS 19
+#define BOARD_NR_ADC_PINS 16
+#define BOARD_NR_USED_PINS 7
+
+#define BOARD_JTMS_SWDIO_PIN 39
+#define BOARD_JTCK_SWCLK_PIN 40
+#define BOARD_JTDI_PIN 41
+#define BOARD_JTDO_PIN 42
+#define BOARD_NJTRST_PIN 43
+
+/* USB configuration. BOARD_USB_DISC_DEV is the GPIO port containing
+ * the USB_DISC pin, and BOARD_USB_DISC_BIT is that pin's bit. */
+#define BOARD_USB_DISC_DEV GPIOC
+#define BOARD_USB_DISC_BIT 12
+
+/*
+ * SDIO Pins
+ */
+#define BOARD_SDIO_D0 PC8
+#define BOARD_SDIO_D1 PC9
+#define BOARD_SDIO_D2 PC10
+#define BOARD_SDIO_D3 PC11
+#define BOARD_SDIO_CLK PC12
+#define BOARD_SDIO_CMD PD2
+
+/* Pin aliases: these give the GPIO port/bit for each pin as an
+ * enum. These are optional, but recommended. They make it easier to
+ * write code using low-level GPIO functionality. */
+enum {
+PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PA8,PA9,PA10,PA11,PA12,PA13,PA14,PA15,
+PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB11,PB12,PB13,PB14,PB15,
+PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PC8,PC9,PC10,PC11,PC12,PC13,PC14,PC15,
+PD0,PD1,PD2
+};/* Note PB2 is skipped as this is Boot1 and is not going to be much use as its likely to be pulled permanently low */
+
+#endif
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/bootloader.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/bootloader.ld
new file mode 100644
index 0000000000..ca56532fdd
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/bootloader.ld
@@ -0,0 +1,18 @@
+/*
+ * Linker script for Generic STM32F103RE boards, using the generic bootloader (which takes the lower 8k of memory)
+ */
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+ rom (rx) : ORIGIN = 0x08002000, LENGTH = 504K
+}
+
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", rom);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/common.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/common.inc
new file mode 100644
index 0000000000..e086a58bca
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/common.inc
@@ -0,0 +1,220 @@
+/*
+ * Linker script for libmaple.
+ *
+ * Original author "lanchon" from ST forums, with modifications by LeafLabs.
+ */
+
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+
+/*
+ * Configure other libraries we want in the link.
+ *
+ * libgcc, libc, and libm are common across supported toolchains.
+ * However, some toolchains require additional archives which aren't
+ * present everywhere (e.g. ARM's gcc-arm-embedded releases).
+ *
+ * To hack around this, we let the build system specify additional
+ * archives by putting the right extra_libs.inc (in a directory under
+ * toolchains/) in our search path.
+ */
+GROUP(libgcc.a libc.a libm.a)
+INCLUDE extra_libs.inc
+
+/*
+ * These force the linker to search for vector table symbols.
+ *
+ * These symbols vary by STM32 family (and also within families).
+ * It's up to the build system to configure the link's search path
+ * properly for the target MCU.
+ */
+INCLUDE vector_symbols.inc
+
+/* STM32 vector table. */
+EXTERN(__stm32_vector_table)
+
+/* C runtime initialization function. */
+EXTERN(start_c)
+
+/* main entry point */
+EXTERN(main)
+
+/* Initial stack pointer value. */
+EXTERN(__msp_init)
+PROVIDE(__msp_init = ORIGIN(ram) + LENGTH(ram));
+
+/* Reset vector and chip reset entry point */
+EXTERN(__start__)
+ENTRY(__start__)
+PROVIDE(__exc_reset = __start__);
+
+/* Heap boundaries, for libmaple */
+EXTERN(_lm_heap_start);
+EXTERN(_lm_heap_end);
+
+SECTIONS
+{
+ .text :
+ {
+ __text_start__ = .;
+ /*
+ * STM32 vector table. Leave this here. Yes, really.
+ */
+ *(.stm32.interrupt_vector)
+
+ /*
+ * Program code and vague linking
+ */
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ *(.gnu.warning)
+ *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
+
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ *(.gcc_except_table)
+ *(.eh_frame_hdr)
+ *(.eh_frame)
+
+ . = ALIGN(4);
+ KEEP(*(.init))
+
+ . = ALIGN(4);
+ __preinit_array_start = .;
+ KEEP (*(.preinit_array))
+ __preinit_array_end = .;
+
+ . = ALIGN(4);
+ __init_array_start = .;
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ __init_array_end = .;
+
+ . = ALIGN(0x4);
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+
+ . = ALIGN(4);
+ KEEP(*(.fini))
+
+ . = ALIGN(4);
+ __fini_array_start = .;
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ __fini_array_end = .;
+
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+ } > REGION_TEXT
+
+ /*
+ * End of text
+ */
+ .text.align :
+ {
+ . = ALIGN(8);
+ __text_end__ = .;
+ } > REGION_TEXT
+
+ /*
+ * .ARM.exidx exception unwinding; mandated by ARM's C++ ABI
+ */
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > REGION_RODATA
+ __exidx_end = .;
+
+ /*
+ * .data
+ */
+ .data :
+ {
+ __data_start__ = .;
+ LONG(0)
+ . = ALIGN(8);
+
+ *(.got.plt) *(.got)
+ *(.data .data.* .gnu.linkonce.d.*)
+
+ . = ALIGN(8);
+ __data_end__ = .;
+ } > REGION_DATA AT> REGION_RODATA
+
+ /*
+ * Read-only data
+ */
+ .rodata :
+ {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ /* .USER_FLASH: We allow users to allocate into Flash here */
+ *(.USER_FLASH)
+ /* ROM image configuration; for C startup */
+ . = ALIGN(4);
+ _lm_rom_img_cfgp = .;
+ LONG(LOADADDR(.data));
+ /*
+ * Heap: Linker scripts may choose a custom heap by overriding
+ * _lm_heap_start and _lm_heap_end. Otherwise, the heap is in
+ * internal SRAM, beginning after .bss, and growing towards
+ * the stack.
+ *
+ * I'm shoving these here naively; there's probably a cleaner way
+ * to go about this. [mbolivar]
+ */
+ _lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : _end;
+ _lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init;
+ } > REGION_RODATA
+
+ /*
+ * .bss
+ */
+ .bss :
+ {
+ . = ALIGN(8);
+ __bss_start__ = .;
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN (8);
+ __bss_end__ = .;
+ _end = __bss_end__;
+ } > REGION_BSS
+
+ /*
+ * Debugging sections
+ */
+ .stab 0 (NOLOAD) : { *(.stab) }
+ .stabstr 0 (NOLOAD) : { *(.stabstr) }
+ /* DWARF debug sections.
+ * Symbols in the DWARF debugging sections are relative to the beginning
+ * of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+ .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
+ /DISCARD/ : { *(.note.GNU-stack) }
+}
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/extra_libs.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/extra_libs.inc
new file mode 100644
index 0000000000..dd2c84fa45
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/extra_libs.inc
@@ -0,0 +1,7 @@
+/*
+ * Extra archives needed by ARM's GCC ARM Embedded arm-none-eabi-
+ * releases (https://launchpad.net/gcc-arm-embedded/).
+ */
+
+/* This is for the provided newlib. */
+GROUP(libnosys.a)
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/flash.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/flash.ld
new file mode 100644
index 0000000000..9e250cd747
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/flash.ld
@@ -0,0 +1,26 @@
+/*
+ * libmaple linker script for "Flash" builds.
+ *
+ * A Flash build puts .text (and .rodata) in Flash, and
+ * .data/.bss/heap (of course) in SRAM, but offsets the sections by
+ * enough space to store the Maple bootloader, which lives in low
+ * Flash and uses low memory.
+ */
+
+/*
+ * This pulls in the appropriate MEMORY declaration from the right
+ * subdirectory of stm32/mem/ (the environment must call ld with the
+ * right include directory flags to make this happen). Boards can also
+ * use this file to use any of libmaple's memory-related hooks (like
+ * where the heap should live).
+ */
+INCLUDE mem-flash.inc
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", rom);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/jtag.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/jtag.ld
new file mode 100644
index 0000000000..0612f95862
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/jtag.ld
@@ -0,0 +1,31 @@
+/*
+ * libmaple linker script for "JTAG" builds.
+ *
+ * A "JTAG" build puts .text (and .rodata) in Flash, and
+ * .data/.bss/heap (of course) in SRAM, but links starting at the
+ * Flash and SRAM starting addresses (0x08000000 and 0x20000000
+ * respectively). This will wipe out a Maple bootloader if there's one
+ * on the board, so only use this if you know what you're doing.
+ *
+ * Of course, a "JTAG" build is perfectly usable for upload over SWD,
+ * the system memory bootloader, etc. The name is just a historical
+ * artifact.
+ */
+
+/*
+ * This pulls in the appropriate MEMORY declaration from the right
+ * subdirectory of stm32/mem/ (the environment must call ld with the
+ * right include directory flags to make this happen). Boards can also
+ * use this file to use any of libmaple's memory-related hooks (like
+ * where the heap should live).
+ */
+INCLUDE mem-jtag.inc
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", rom);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-flash.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-flash.inc
new file mode 100644
index 0000000000..ddb8876fa5
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-flash.inc
@@ -0,0 +1,5 @@
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
+ rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K
+}
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-jtag.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-jtag.inc
new file mode 100644
index 0000000000..d3ed992481
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-jtag.inc
@@ -0,0 +1,5 @@
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
+}
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-ram.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-ram.inc
new file mode 100644
index 0000000000..360beafe9d
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/mem-ram.inc
@@ -0,0 +1,5 @@
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
+ rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K
+}
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/ram.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/ram.ld
new file mode 100644
index 0000000000..34b468e0a0
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/ram.ld
@@ -0,0 +1,25 @@
+/*
+ * libmaple linker script for RAM builds.
+ *
+ * A Flash build puts .text, .rodata, and .data/.bss/heap (of course)
+ * in SRAM, but offsets the sections by enough space to store the
+ * Maple bootloader, which uses low memory.
+ */
+
+/*
+ * This pulls in the appropriate MEMORY declaration from the right
+ * subdirectory of stm32/mem/ (the environment must call ld with the
+ * right include directory flags to make this happen). Boards can also
+ * use this file to use any of libmaple's memory-related hooks (like
+ * where the heap should live).
+ */
+INCLUDE mem-ram.inc
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", ram);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", ram);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb.ld
new file mode 100644
index 0000000000..9c0d19b716
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb.ld
@@ -0,0 +1,18 @@
+/*
+ * Linker script for Generic STM32F103RB boards.
+ */
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
+}
+
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", rom);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb_bootloader.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb_bootloader.ld
new file mode 100644
index 0000000000..d045db9f4b
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rb_bootloader.ld
@@ -0,0 +1,17 @@
+/*
+ * Linker script for Generic STM32F103RB boards, using the generic bootloader (which takes the lower 8k of memory)
+ */
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
+ rom (rx) : ORIGIN = 0x08002000, LENGTH = 120K
+}
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", rom);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc.ld
new file mode 100644
index 0000000000..016d59d00d
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc.ld
@@ -0,0 +1,18 @@
+/*
+ * Linker script for Generic STM32F103RC boards.
+ */
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K
+}
+
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", rom);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc_bootloader.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc_bootloader.ld
new file mode 100644
index 0000000000..00b811b0e6
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103rc_bootloader.ld
@@ -0,0 +1,18 @@
+/*
+ * Linker script for Generic STM32F103RC boards, using the generic bootloader (which takes the lower 8k of memory)
+ */
+
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
+ rom (rx) : ORIGIN = 0x08002000, LENGTH = 248K
+}
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", rom);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103re.ld b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103re.ld
new file mode 100644
index 0000000000..52abb5ad09
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/stm32f103re.ld
@@ -0,0 +1,18 @@
+/*
+ * Linker script for Generic STM32F103RE boards.
+ */
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
+}
+
+
+/* Provide memory region aliases for common.inc */
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+REGION_ALIAS("REGION_RODATA", rom);
+
+/* Let common.inc handle the real work. */
+INCLUDE common.inc
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/vector_symbols.inc b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/vector_symbols.inc
new file mode 100644
index 0000000000..f8519bba44
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/ld/vector_symbols.inc
@@ -0,0 +1,78 @@
+EXTERN(__msp_init)
+EXTERN(__exc_reset)
+EXTERN(__exc_nmi)
+EXTERN(__exc_hardfault)
+EXTERN(__exc_memmanage)
+EXTERN(__exc_busfault)
+EXTERN(__exc_usagefault)
+EXTERN(__stm32reservedexception7)
+EXTERN(__stm32reservedexception8)
+EXTERN(__stm32reservedexception9)
+EXTERN(__stm32reservedexception10)
+EXTERN(__exc_svc)
+EXTERN(__exc_debug_monitor)
+EXTERN(__stm32reservedexception13)
+EXTERN(__exc_pendsv)
+EXTERN(__exc_systick)
+
+EXTERN(__irq_wwdg)
+EXTERN(__irq_pvd)
+EXTERN(__irq_tamper)
+EXTERN(__irq_rtc)
+EXTERN(__irq_flash)
+EXTERN(__irq_rcc)
+EXTERN(__irq_exti0)
+EXTERN(__irq_exti1)
+EXTERN(__irq_exti2)
+EXTERN(__irq_exti3)
+EXTERN(__irq_exti4)
+EXTERN(__irq_dma1_channel1)
+EXTERN(__irq_dma1_channel2)
+EXTERN(__irq_dma1_channel3)
+EXTERN(__irq_dma1_channel4)
+EXTERN(__irq_dma1_channel5)
+EXTERN(__irq_dma1_channel6)
+EXTERN(__irq_dma1_channel7)
+EXTERN(__irq_adc)
+EXTERN(__irq_usb_hp_can_tx)
+EXTERN(__irq_usb_lp_can_rx0)
+EXTERN(__irq_can_rx1)
+EXTERN(__irq_can_sce)
+EXTERN(__irq_exti9_5)
+EXTERN(__irq_tim1_brk)
+EXTERN(__irq_tim1_up)
+EXTERN(__irq_tim1_trg_com)
+EXTERN(__irq_tim1_cc)
+EXTERN(__irq_tim2)
+EXTERN(__irq_tim3)
+EXTERN(__irq_tim4)
+EXTERN(__irq_i2c1_ev)
+EXTERN(__irq_i2c1_er)
+EXTERN(__irq_i2c2_ev)
+EXTERN(__irq_i2c2_er)
+EXTERN(__irq_spi1)
+EXTERN(__irq_spi2)
+EXTERN(__irq_usart1)
+EXTERN(__irq_usart2)
+EXTERN(__irq_usart3)
+EXTERN(__irq_exti15_10)
+EXTERN(__irq_rtcalarm)
+EXTERN(__irq_usbwakeup)
+
+EXTERN(__irq_tim8_brk)
+EXTERN(__irq_tim8_up)
+EXTERN(__irq_tim8_trg_com)
+EXTERN(__irq_tim8_cc)
+EXTERN(__irq_adc3)
+EXTERN(__irq_fsmc)
+EXTERN(__irq_sdio)
+EXTERN(__irq_tim5)
+EXTERN(__irq_spi3)
+EXTERN(__irq_uart4)
+EXTERN(__irq_uart5)
+EXTERN(__irq_tim6)
+EXTERN(__irq_tim7)
+EXTERN(__irq_dma2_channel1)
+EXTERN(__irq_dma2_channel2)
+EXTERN(__irq_dma2_channel3)
+EXTERN(__irq_dma2_channel4_5)
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/pins_arduino.h b/buildroot/share/PlatformIO/variants/MEEB_3DP/pins_arduino.h
new file mode 100644
index 0000000000..d5dce114d5
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/pins_arduino.h
@@ -0,0 +1,2 @@
+// API compatibility
+#include "variant.h"
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/variant.h b/buildroot/share/PlatformIO/variants/MEEB_3DP/variant.h
new file mode 100644
index 0000000000..f9a545bf6c
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/variant.h
@@ -0,0 +1,20 @@
+#ifndef _VARIANT_ARDUINO_STM32_
+#define _VARIANT_ARDUINO_STM32_
+
+#define digitalPinToPort(P) ( PIN_MAP[P].gpio_device )
+#define digitalPinToBitMask(P) ( BIT(PIN_MAP[P].gpio_bit) )
+#define portOutputRegister(port) ( &(port->regs->ODR) )
+#define portInputRegister(port) ( &(port->regs->IDR) )
+
+#define portSetRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BSRR) )
+#define portClearRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BRR) )
+
+#define portConfigRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->CRL) )
+
+static const uint8_t SS = BOARD_SPI1_NSS_PIN;
+static const uint8_t SS1 = BOARD_SPI2_NSS_PIN;
+static const uint8_t MOSI = BOARD_SPI1_MOSI_PIN;
+static const uint8_t MISO = BOARD_SPI1_MISO_PIN;
+static const uint8_t SCK = BOARD_SPI1_SCK_PIN;
+
+#endif /* _VARIANT_ARDUINO_STM32_ */
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards.cpp b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards.cpp
new file mode 100644
index 0000000000..feb287d6f3
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards.cpp
@@ -0,0 +1,225 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2010 Perry Hung.
+ * Copyright (c) 2011, 2012 LeafLabs, LLC.
+ *
+ * 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.
+ *****************************************************************************/
+
+/**
+ * @file wirish/boards.cpp
+ * @brief init() and board routines.
+ *
+ * This file is mostly interesting for the init() function, which
+ * configures Flash, the core clocks, and a variety of other available
+ * peripherals on the board so the rest of Wirish doesn't have to turn
+ * things on before using them.
+ *
+ * Prior to returning, init() calls boardInit(), which allows boards
+ * to perform any initialization they need to. This file includes a
+ * weak no-op definition of boardInit(), so boards that don't need any
+ * special initialization don't have to define their own.
+ *
+ * How init() works is chip-specific. See the boards_setup.cpp files
+ * under e.g. wirish/stm32f1/, wirish/stmf32f2 for the details, but be
+ * advised: their contents are unstable, and can/will change without
+ * notice.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "boards_private.h"
+
+static void setup_flash(void);
+static void setup_clocks(void);
+static void setup_nvic(void);
+static void setup_adcs(void);
+static void setup_timers(void);
+
+/*
+ * Exported functions
+ */
+
+void init(void) {
+ setup_flash();
+ setup_clocks();
+ setup_nvic();
+ systick_init(SYSTICK_RELOAD_VAL);
+ wirish::priv::board_setup_gpio();
+ setup_adcs();
+ setup_timers();
+ wirish::priv::board_setup_usb();
+ wirish::priv::series_init();
+ boardInit();
+}
+
+/* Provide a default no-op boardInit(). */
+__weak void boardInit(void) {
+}
+
+/* You could farm this out to the files in boards/ if e.g. it takes
+ * too long to test on boards with lots of pins. */
+bool boardUsesPin(uint8 pin) {
+ for (int i = 0; i < BOARD_NR_USED_PINS; i++) {
+ if (pin == boardUsedPins[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Auxiliary routines
+ */
+
+static void setup_flash(void) {
+ // Turn on as many Flash "go faster" features as
+ // possible. flash_enable_features() just ignores any flags it
+ // can't support.
+ flash_enable_features(FLASH_PREFETCH | FLASH_ICACHE | FLASH_DCACHE);
+ // Configure the wait states, assuming we're operating at "close
+ // enough" to 3.3V.
+ flash_set_latency(FLASH_SAFE_WAIT_STATES);
+}
+
+static void setup_clocks(void) {
+ // Turn on HSI. We'll switch to and run off of this while we're
+ // setting up the main PLL.
+ rcc_turn_on_clk(RCC_CLK_HSI);
+
+ // Turn off and reset the clock subsystems we'll be using, as well
+ // as the clock security subsystem (CSS). Note that resetting CFGR
+ // to its default value of 0 implies a switch to HSI for SYSCLK.
+ RCC_BASE->CFGR = 0x00000000;
+ rcc_disable_css();
+ rcc_turn_off_clk(RCC_CLK_PLL);
+ rcc_turn_off_clk(RCC_CLK_HSE);
+ wirish::priv::board_reset_pll();
+ // Clear clock readiness interrupt flags and turn off clock
+ // readiness interrupts.
+ RCC_BASE->CIR = 0x00000000;
+#if !USE_HSI_CLOCK
+ // Enable HSE, and wait until it's ready.
+ rcc_turn_on_clk(RCC_CLK_HSE);
+ while (!rcc_is_clk_ready(RCC_CLK_HSE))
+ ;
+#endif
+ // Configure AHBx, APBx, etc. prescalers and the main PLL.
+ wirish::priv::board_setup_clock_prescalers();
+ rcc_configure_pll(&wirish::priv::w_board_pll_cfg);
+
+ // Enable the PLL, and wait until it's ready.
+ rcc_turn_on_clk(RCC_CLK_PLL);
+ while(!rcc_is_clk_ready(RCC_CLK_PLL))
+ ;
+
+ // Finally, switch to the now-ready PLL as the main clock source.
+ rcc_switch_sysclk(RCC_CLKSRC_PLL);
+}
+
+/*
+ * These addresses are where usercode starts when a bootloader is
+ * present. If no bootloader is present, the user NVIC usually starts
+ * at the Flash base address, 0x08000000.
+ */
+#if defined(BOOTLOADER_maple)
+ #define USER_ADDR_ROM 0x08002000
+#else
+ #define USER_ADDR_ROM 0x08000000
+#endif
+#define USER_ADDR_RAM 0x20000C00
+extern char __text_start__;
+
+static void setup_nvic(void) {
+
+nvic_init((uint32)VECT_TAB_ADDR, 0);
+
+/* Roger Clark. We now control nvic vector table in boards.txt using the build.vect paramater
+#ifdef VECT_TAB_FLASH
+ nvic_init(USER_ADDR_ROM, 0);
+#elif defined VECT_TAB_RAM
+ nvic_init(USER_ADDR_RAM, 0);
+#elif defined VECT_TAB_BASE
+ nvic_init((uint32)0x08000000, 0);
+#elif defined VECT_TAB_ADDR
+ // A numerically supplied value
+ nvic_init((uint32)VECT_TAB_ADDR, 0);
+#else
+ // Use the __text_start__ value from the linker script; this
+ // should be the start of the vector table.
+ nvic_init((uint32)&__text_start__, 0);
+#endif
+
+*/
+}
+
+static void adc_default_config(adc_dev *dev) {
+ adc_enable_single_swstart(dev);
+ adc_set_sample_rate(dev, wirish::priv::w_adc_smp);
+}
+
+static void setup_adcs(void) {
+ adc_set_prescaler(wirish::priv::w_adc_pre);
+ adc_foreach(adc_default_config);
+}
+
+static void timer_default_config(timer_dev *dev) {
+ timer_adv_reg_map *regs = (dev->regs).adv;
+ const uint16 full_overflow = 0xFFFF;
+ const uint16 half_duty = 0x8FFF;
+
+ timer_init(dev);
+ timer_pause(dev);
+
+ regs->CR1 = TIMER_CR1_ARPE;
+ regs->PSC = 1;
+ regs->SR = 0;
+ regs->DIER = 0;
+ regs->EGR = TIMER_EGR_UG;
+ switch (dev->type) {
+ case TIMER_ADVANCED:
+ regs->BDTR = TIMER_BDTR_MOE | TIMER_BDTR_LOCK_OFF;
+ // fall-through
+ case TIMER_GENERAL:
+ timer_set_reload(dev, full_overflow);
+ for (uint8 channel = 1; channel <= 4; channel++) {
+ if (timer_has_cc_channel(dev, channel)) {
+ timer_set_compare(dev, channel, half_duty);
+ timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1,
+ TIMER_OC_PE);
+ }
+ }
+ // fall-through
+ case TIMER_BASIC:
+ break;
+ }
+
+ timer_generate_update(dev);
+ timer_resume(dev);
+}
+
+static void setup_timers(void) {
+ timer_foreach(timer_default_config);
+}
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards_setup.cpp b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards_setup.cpp
new file mode 100644
index 0000000000..d4e95925ac
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/boards_setup.cpp
@@ -0,0 +1,106 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2012 LeafLabs, LLC.
+ *
+ * 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.
+*****************************************************************************/
+
+/**
+ * @file wirish/stm32f1/boards_setup.cpp
+ * @author Marti Bolivar
+ * @brief STM32F1 chip setup.
+ *
+ * This file controls how init() behaves on the STM32F1. Be very
+ * careful when changing anything here. Many of these values depend
+ * upon each other.
+ */
+
+#include "boards_private.h"
+
+#include
+#include
+
+#include
+#include
+
+// Allow boards to provide a PLL multiplier. This is useful for
+// e.g. STM32F100 value line MCUs, which use slower multipliers.
+// (We're leaving the default to RCC_PLLMUL_9 for now, since that
+// works for F103 performance line MCUs, which is all that LeafLabs
+// currently officially supports).
+
+namespace wirish {
+ namespace priv {
+
+ static stm32f1_rcc_pll_data pll_data = {RCC_PLLMUL_6};
+#if !USE_HSI_CLOCK
+ __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data};
+#else
+ __weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSI_DIV_2, &pll_data};
+#endif
+ __weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6;
+ __weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5;
+
+ __weak void board_reset_pll(void) {
+ // TODO
+ }
+
+ __weak void board_setup_clock_prescalers(void) {
+ rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1);
+ rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2);
+ rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1);
+ rcc_clk_disable(RCC_USB);
+ #if F_CPU == 72000000
+ rcc_set_prescaler(RCC_PRESCALER_USB, RCC_USB_SYSCLK_DIV_1_5);
+ #elif F_CPU == 48000000
+ rcc_set_prescaler(RCC_PRESCALER_USB, RCC_USB_SYSCLK_DIV_1);
+ #endif
+ }
+
+ __weak void board_setup_gpio(void) {
+ gpio_init_all();
+ }
+
+ __weak void board_setup_usb(void) {
+#ifdef SERIAL_USB
+
+#ifdef GENERIC_BOOTLOADER
+ //Reset the USB interface on generic boards - developed by Victor PV
+ gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_OUTPUT_PP);
+ gpio_write_bit(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit,0);
+
+ for(volatile unsigned int i=0;i<512;i++);// Only small delay seems to be needed, and USB pins will get configured in Serial.begin
+ gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING);
+#endif
+
+ Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
+#endif
+ }
+
+ __weak void series_init(void) {
+ // Initialize AFIO here, too, so peripheral remaps and external
+ // interrupts work out of the box.
+ afio_init();
+ }
+
+ }
+}
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start.S b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start.S
new file mode 100644
index 0000000000..8b181aa993
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start.S
@@ -0,0 +1,57 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2011 LeafLabs, LLC.
+ *
+ * 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.
+ *****************************************************************************/
+
+/*
+ * This file is a modified version of a file obtained from
+ * CodeSourcery Inc. (now part of Mentor Graphics Corp.), in which the
+ * following text appeared:
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+ .text
+ .code 16
+ .thumb_func
+
+ .globl __start__
+ .type __start__, %function
+__start__:
+ .fnstart
+ ldr r1,=__msp_init
+ mov sp,r1
+ ldr r1,=start_c
+ bx r1
+ .pool
+ .cantunwind
+ .fnend
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start_c.c b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start_c.c
new file mode 100644
index 0000000000..655fefb884
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/start_c.c
@@ -0,0 +1,95 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2011 LeafLabs, LLC.
+ *
+ * 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.
+ *****************************************************************************/
+
+/*
+ * This file is a modified version of a file obtained from
+ * CodeSourcery Inc. (now part of Mentor Graphics Corp.), in which the
+ * following text appeared:
+ *
+ * Copyright (c) 2006, 2007 CodeSourcery Inc
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include
+
+extern void __libc_init_array(void);
+
+extern int main(int, char**, char**);
+
+extern void exit(int) __attribute__((noreturn, weak));
+
+/* The linker must ensure that these are at least 4-byte aligned. */
+extern char __data_start__, __data_end__;
+extern char __bss_start__, __bss_end__;
+
+struct rom_img_cfg {
+ int *img_start;
+};
+
+extern char _lm_rom_img_cfgp;
+
+void __attribute__((noreturn)) start_c(void) {
+ struct rom_img_cfg *img_cfg = (struct rom_img_cfg*)&_lm_rom_img_cfgp;
+ int *src = img_cfg->img_start;
+ int *dst = (int*)&__data_start__;
+ int exit_code;
+
+ /* Initialize .data, if necessary. */
+ if (src != dst) {
+ int *end = (int*)&__data_end__;
+ while (dst < end) {
+ *dst++ = *src++;
+ }
+ }
+
+ /* Zero .bss. */
+ dst = (int*)&__bss_start__;
+ while (dst < (int*)&__bss_end__) {
+ *dst++ = 0;
+ }
+
+ /* Run initializers. */
+ __libc_init_array();
+
+ /* Jump to main. */
+ exit_code = main(0, 0, 0);
+ if (exit) {
+ exit(exit_code);
+ }
+
+ /* If exit is NULL, make sure we don't return. */
+ for (;;)
+ continue;
+}
diff --git a/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/syscalls.c b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/syscalls.c
new file mode 100644
index 0000000000..d5f2d9fac3
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/MEEB_3DP/wirish/syscalls.c
@@ -0,0 +1,176 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2010 Perry Hung.
+ * Copyright (c) 2011, 2012 LeafLabs, LLC.
+ *
+ * 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.
+ *****************************************************************************/
+
+/**
+ * @file wirish/syscalls.c
+ * @brief newlib stubs
+ *
+ * Low level system routines used by newlib for basic I/O and memory
+ * allocation. You can override most of these.
+ */
+
+#include
+
+#include
+#include
+#include
+
+/* If CONFIG_HEAP_START (or CONFIG_HEAP_END) isn't defined, then
+ * assume _lm_heap_start (resp. _lm_heap_end) is appropriately set by
+ * the linker */
+#ifndef CONFIG_HEAP_START
+extern char _lm_heap_start;
+#define CONFIG_HEAP_START ((void *)&_lm_heap_start)
+#endif
+#ifndef CONFIG_HEAP_END
+extern char _lm_heap_end;
+#define CONFIG_HEAP_END ((void *)&_lm_heap_end)
+#endif
+
+/*
+ * _sbrk -- Increment the program break.
+ *
+ * Get incr bytes more RAM (for use by the heap). malloc() and
+ * friends call this function behind the scenes.
+ */
+void *_sbrk(int incr) {
+ static void * pbreak = NULL; /* current program break */
+ void * ret;
+
+ if (pbreak == NULL) {
+ pbreak = CONFIG_HEAP_START;
+ }
+
+ if ((CONFIG_HEAP_END - pbreak < incr) ||
+ (pbreak - CONFIG_HEAP_START < -incr)) {
+ errno = ENOMEM;
+ return (void *)-1;
+ }
+
+ ret = pbreak;
+ pbreak += incr;
+ return ret;
+}
+
+__weak int _open(const char *path, int flags, ...) {
+ return 1;
+}
+
+__weak int _close(int fd) {
+ return 0;
+}
+
+__weak int _fstat(int fd, struct stat *st) {
+ st->st_mode = S_IFCHR;
+ return 0;
+}
+
+__weak int _isatty(int fd) {
+ return 1;
+}
+
+__weak int isatty(int fd) {
+ return 1;
+}
+
+__weak int _lseek(int fd, off_t pos, int whence) {
+ return -1;
+}
+
+__weak unsigned char getch(void) {
+ return 0;
+}
+
+
+__weak int _read(int fd, char *buf, size_t cnt) {
+ *buf = getch();
+
+ return 1;
+}
+
+__weak void putch(unsigned char c) {
+}
+
+__weak void cgets(char *s, int bufsize) {
+ char *p;
+ int c;
+ int i;
+
+ for (i = 0; i < bufsize; i++) {
+ *(s+i) = 0;
+ }
+// memset(s, 0, bufsize);
+
+ p = s;
+
+ for (p = s; p < s + bufsize-1;) {
+ c = getch();
+ switch (c) {
+ case '\r' :
+ case '\n' :
+ putch('\r');
+ putch('\n');
+ *p = '\n';
+ return;
+
+ case '\b' :
+ if (p > s) {
+ *p-- = 0;
+ putch('\b');
+ putch(' ');
+ putch('\b');
+ }
+ break;
+
+ default :
+ putch(c);
+ *p++ = c;
+ break;
+ }
+ }
+ return;
+}
+
+__weak int _write(int fd, const char *buf, size_t cnt) {
+ int i;
+
+ for (i = 0; i < cnt; i++)
+ putch(buf[i]);
+
+ return cnt;
+}
+
+/* Override fgets() in newlib with a version that does line editing */
+__weak char *fgets(char *s, int bufsize, void *f) {
+ cgets(s, bufsize);
+ return s;
+}
+
+__weak void _exit(int exitcode) {
+ while (1)
+ ;
+}
diff --git a/buildroot/share/tests/STM32F103RC_cc_meeb_3dp-tests b/buildroot/share/tests/STM32F103RC_cc_meeb_3dp-tests
new file mode 100644
index 0000000000..74e770d3c8
--- /dev/null
+++ b/buildroot/share/tests/STM32F103RC_cc_meeb_3dp-tests
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+#
+# Build tests for STM32F103RC MEEB_3DP (ccrobot-online.com)
+#
+
+# exit on first failure
+set -e
+
+#
+# Build with the default configurations
+#
+restore_configs
+opt_set MOTHERBOARD BOARD_CCROBOT_MEEB_3DP
+opt_set SERIAL_PORT 1
+opt_set SERIAL_PORT_2 -1
+opt_set X_DRIVER_TYPE TMC2208
+opt_set Y_DRIVER_TYPE TMC2208
+opt_set Z_DRIVER_TYPE TMC2208
+opt_set E0_DRIVER_TYPE TMC2208
+exec_test $1 $2 "MEEB_3DP - Basic Config with TMC2208 SW Serial"
+
+# clean up
+restore_configs
diff --git a/platformio.ini b/platformio.ini
index aa8dd21983..fa27fb9a9a 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -45,15 +45,7 @@ src_filter = ${common.default_src_filter} +
lib_ignore =
Adafruit NeoPixel
SPI
-lib_deps =
- LiquidCrystal
- TMCStepper@>=0.6.2
- U8glib-HAL=https://github.com/MarlinFirmware/U8glib-HAL/archive/bugfix.zip
- Adafruit MAX31865 library@>=1.1,<1.2
- LiquidTWI2=https://github.com/lincomatic/LiquidTWI2/archive/master.zip
- Arduino-L6470=https://github.com/ameyer/Arduino-L6470/archive/0.8.0.zip
- SailfishLCD=https://github.com/mikeshub/SailfishLCD/archive/master.zip
- SlowSoftI2CMaster=https://github.com/mikeshub/SlowSoftI2CMaster/archive/master.zip
+lib_deps = ${common.lib_deps}
SoftwareSerialM=https://github.com/FYSETC/SoftwareSerialM/archive/master.zip
[common_avr8]
@@ -287,6 +279,31 @@ board = genericSTM32F103RC
platform_packages = tool-stm32duino
monitor_speed = 115200
+#
+# MEEB_3DP (STM32F103RCT6 with 512K)
+#
+[env:STM32F103RC_cc_meeb_3dp]
+platform = ${common_stm32f1.platform}
+extends = common_stm32f1
+board = MEEB_3DP
+platform_packages = tool-stm32duino
+build_flags = ${common_stm32f1.build_flags}
+ -DDEBUG_LEVEL=0
+ -DSS_TIMER=4
+ -DSTM32_FLASH_SIZE=512
+ -DHSE_VALUE=12000000U
+ -DUSE_USB_COMPOSITE
+ -DVECT_TAB_OFFSET=0x2000
+ -DGENERIC_BOOTLOADER
+extra_scripts = pre:buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP_create_variant.py
+ buildroot/share/PlatformIO/scripts/STM32F103RC_MEEB_3DP.py
+lib_deps = ${common.lib_deps}
+ USBComposite for STM32F1@==0.91
+ Adafruit NeoPixel=https://github.com/ccccmagicboy/Adafruit_NeoPixel#meeb_3dp_use
+lib_ignore = SPI, LiquidCrystal
+debug_tool = stlink
+upload_protocol = dfu
+
#
# STM32F103RC_fysetc
#