diff --git a/Marlin/src/HAL/HAL_STM32/HAL_SPI.cpp b/Marlin/src/HAL/HAL_STM32/HAL_SPI.cpp
index 82cae9b75cbdbede8a98fa2fa68d06866798cfdd..de45c8948e130d2516e2948b919b5cdaf62f9504 100644
--- a/Marlin/src/HAL/HAL_STM32/HAL_SPI.cpp
+++ b/Marlin/src/HAL/HAL_STM32/HAL_SPI.cpp
@@ -37,121 +37,193 @@ static SPISettings spiConfig;
// ------------------------
#if ENABLED(SOFTWARE_SPI)
+
// ------------------------
// Software SPI
// ------------------------
- #error "Software SPI not supported for STM32. Use Hardware SPI."
-#else
+ #include "../shared/Delay.h"
-// ------------------------
-// Hardware SPI
-// ------------------------
+ void spiBegin(void) {
+ OUT_WRITE(SS_PIN, HIGH);
+ OUT_WRITE(SCK_PIN, HIGH);
+ SET_INPUT(MISO_PIN);
+ OUT_WRITE(MOSI_PIN, HIGH);
+ }
-/**
- * VGPV SPI speed start and PCLK2/2, by default 108/2 = 54Mhz
- */
+ static uint16_t delay_STM32_soft_spi;
+
+ void spiInit(uint8_t spiRate) {
+ // Use datarates Marlin uses
+ switch (spiRate) {
+ case SPI_FULL_SPEED: delay_STM32_soft_spi = 125; break; // desired: 8,000,000 actual: ~1.1M
+ case SPI_HALF_SPEED: delay_STM32_soft_spi = 125; break; // desired: 4,000,000 actual: ~1.1M
+ case SPI_QUARTER_SPEED:delay_STM32_soft_spi = 250; break; // desired: 2,000,000 actual: ~890K
+ case SPI_EIGHTH_SPEED: delay_STM32_soft_spi = 500; break; // desired: 1,000,000 actual: ~590K
+ case SPI_SPEED_5: delay_STM32_soft_spi = 1000; break; // desired: 500,000 actual: ~360K
+ case SPI_SPEED_6: delay_STM32_soft_spi = 2000; break; // desired: 250,000 actual: ~210K
+ default: delay_STM32_soft_spi = 4000; break; // desired: 125,000 actual: ~123K
+ }
+ SPI.begin();
+ }
-/**
- * @brief Begin SPI port setup
- *
- * @return Nothing
- *
- * @details Only configures SS pin since stm32duino creates and initialize the SPI object
- */
-void spiBegin() {
- #if !PIN_EXISTS(SS)
- #error "SS_PIN not defined!"
- #endif
-
- OUT_WRITE(SS_PIN, HIGH);
-}
-
-/** Configure SPI for specified SPI speed */
-void spiInit(uint8_t spiRate) {
- // Use datarates Marlin uses
- uint32_t clock;
- switch (spiRate) {
- case SPI_FULL_SPEED: clock = 20000000; break; // 13.9mhz=20000000 6.75mhz=10000000 3.38mhz=5000000 .833mhz=1000000
- case SPI_HALF_SPEED: clock = 5000000; break;
- case SPI_QUARTER_SPEED: clock = 2500000; break;
- case SPI_EIGHTH_SPEED: clock = 1250000; break;
- case SPI_SPEED_5: clock = 625000; break;
- case SPI_SPEED_6: clock = 300000; break;
- default:
- clock = 4000000; // Default from the SPI library
+ // Begin SPI transaction, set clock, bit order, data mode
+ void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { /* do nothing */ }
+
+ uint8_t HAL_SPI_STM32_SpiTransfer_Mode_3(uint8_t b) { // using Mode 3
+ for (uint8_t bits = 8; bits--;) {
+ WRITE(SCK_PIN, LOW);
+ WRITE(MOSI_PIN, b & 0x80);
+
+ DELAY_NS(delay_STM32_soft_spi);
+ WRITE(SCK_PIN, HIGH);
+ DELAY_NS(delay_STM32_soft_spi);
+
+ b <<= 1; // little setup time
+ b |= (READ(MISO_PIN) != 0);
+ }
+ DELAY_NS(125);
+ return b;
}
- spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
- #if ENABLED(CUSTOM_SPI_PINS)
- SPI.setMISO(MISO_PIN);
- SPI.setMOSI(MOSI_PIN);
- SPI.setSCLK(SCK_PIN);
- SPI.setSSEL(SS_PIN);
- #endif
+ // Soft SPI receive byte
+ uint8_t spiRec() {
+ DISABLE_ISRS(); // No interrupts during byte receive
+ const uint8_t data = HAL_SPI_STM32_SpiTransfer_Mode_3(0xFF);
+ ENABLE_ISRS(); // Enable interrupts
+ return data;
+ }
- SPI.begin();
-}
+ // Soft SPI read data
+ void spiRead(uint8_t *buf, uint16_t nbyte) {
+ for (uint16_t i = 0; i < nbyte; i++)
+ buf[i] = spiRec();
+ }
-/**
- * @brief Receives a single byte from the SPI port.
- *
- * @return Byte received
- *
- * @details
- */
-uint8_t spiRec() {
- SPI.beginTransaction(spiConfig);
- uint8_t returnByte = SPI.transfer(0xFF);
- SPI.endTransaction();
- return returnByte;
-}
+ // Soft SPI send byte
+ void spiSend(uint8_t data) {
+ DISABLE_ISRS(); // No interrupts during byte send
+ HAL_SPI_STM32_SpiTransfer_Mode_3(data); // Don't care what is received
+ ENABLE_ISRS(); // Enable interrupts
+ }
-/**
- * @brief Receives a number of bytes from the SPI port to a buffer
- *
- * @param buf Pointer to starting address of buffer to write to.
- * @param nbyte Number of bytes to receive.
- * @return Nothing
- *
- * @details Uses DMA
- */
-void spiRead(uint8_t* buf, uint16_t nbyte) {
- if (nbyte == 0) return;
- memset(buf, 0xFF, nbyte);
- SPI.beginTransaction(spiConfig);
- SPI.transfer(buf, nbyte);
- SPI.endTransaction();
-}
+ // Soft SPI send block
+ void spiSendBlock(uint8_t token, const uint8_t *buf) {
+ spiSend(token);
+ for (uint16_t i = 0; i < 512; i++)
+ spiSend(buf[i]);
+ }
-/**
- * @brief Sends a single byte on SPI port
- *
- * @param b Byte to send
- *
- * @details
- */
-void spiSend(uint8_t b) {
- SPI.beginTransaction(spiConfig);
- SPI.transfer(b);
- SPI.endTransaction();
-}
+#else
-/**
- * @brief Write token and then write from 512 byte buffer to SPI (for SD card)
- *
- * @param buf Pointer with buffer start address
- * @return Nothing
- *
- * @details Use DMA
- */
-void spiSendBlock(uint8_t token, const uint8_t* buf) {
- uint8_t rxBuf[512];
- SPI.beginTransaction(spiConfig);
- SPI.transfer(token);
- SPI.transfer((uint8_t*)buf, &rxBuf, 512);
- SPI.endTransaction();
-}
+ // ------------------------
+ // Hardware SPI
+ // ------------------------
+
+ /**
+ * VGPV SPI speed start and PCLK2/2, by default 108/2 = 54Mhz
+ */
+
+ /**
+ * @brief Begin SPI port setup
+ *
+ * @return Nothing
+ *
+ * @details Only configures SS pin since stm32duino creates and initialize the SPI object
+ */
+ void spiBegin() {
+ #if !PIN_EXISTS(SS)
+ #error "SS_PIN not defined!"
+ #endif
+
+ OUT_WRITE(SS_PIN, HIGH);
+ }
+
+ // Configure SPI for specified SPI speed
+ void spiInit(uint8_t spiRate) {
+ // Use datarates Marlin uses
+ uint32_t clock;
+ switch (spiRate) {
+ case SPI_FULL_SPEED: clock = 20000000; break; // 13.9mhz=20000000 6.75mhz=10000000 3.38mhz=5000000 .833mhz=1000000
+ case SPI_HALF_SPEED: clock = 5000000; break;
+ case SPI_QUARTER_SPEED: clock = 2500000; break;
+ case SPI_EIGHTH_SPEED: clock = 1250000; break;
+ case SPI_SPEED_5: clock = 625000; break;
+ case SPI_SPEED_6: clock = 300000; break;
+ default:
+ clock = 4000000; // Default from the SPI library
+ }
+ spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
+
+ #if ENABLED(CUSTOM_SPI_PINS)
+ SPI.setMISO(MISO_PIN);
+ SPI.setMOSI(MOSI_PIN);
+ SPI.setSCLK(SCK_PIN);
+ SPI.setSSEL(SS_PIN);
+ #endif
+
+ SPI.begin();
+ }
+
+ /**
+ * @brief Receives a single byte from the SPI port.
+ *
+ * @return Byte received
+ *
+ * @details
+ */
+ uint8_t spiRec() {
+ SPI.beginTransaction(spiConfig);
+ uint8_t returnByte = SPI.transfer(0xFF);
+ SPI.endTransaction();
+ return returnByte;
+ }
+
+ /**
+ * @brief Receive a number of bytes from the SPI port to a buffer
+ *
+ * @param buf Pointer to starting address of buffer to write to.
+ * @param nbyte Number of bytes to receive.
+ * @return Nothing
+ *
+ * @details Uses DMA
+ */
+ void spiRead(uint8_t* buf, uint16_t nbyte) {
+ if (nbyte == 0) return;
+ memset(buf, 0xFF, nbyte);
+ SPI.beginTransaction(spiConfig);
+ SPI.transfer(buf, nbyte);
+ SPI.endTransaction();
+ }
+
+ /**
+ * @brief Send a single byte on SPI port
+ *
+ * @param b Byte to send
+ *
+ * @details
+ */
+ void spiSend(uint8_t b) {
+ SPI.beginTransaction(spiConfig);
+ SPI.transfer(b);
+ SPI.endTransaction();
+ }
+
+ /**
+ * @brief Write token and then write from 512 byte buffer to SPI (for SD card)
+ *
+ * @param buf Pointer with buffer start address
+ * @return Nothing
+ *
+ * @details Use DMA
+ */
+ void spiSendBlock(uint8_t token, const uint8_t* buf) {
+ uint8_t rxBuf[512];
+ SPI.beginTransaction(spiConfig);
+ SPI.transfer(token);
+ SPI.transfer((uint8_t*)buf, &rxBuf, 512);
+ SPI.endTransaction();
+ }
#endif // SOFTWARE_SPI
diff --git a/Marlin/src/gcode/feature/L6470/M906.cpp b/Marlin/src/gcode/feature/L6470/M906.cpp
index d6bf8a53c94522bf7728cc9e5a841082478c2a4b..5b4157b0b21d837875d400a29338b6f9a0a28233 100644
--- a/Marlin/src/gcode/feature/L6470/M906.cpp
+++ b/Marlin/src/gcode/feature/L6470/M906.cpp
@@ -39,22 +39,16 @@
*
* On L6474 this sets the TVAL register (same address).
*
- * J - select which driver(s) to monitor on multi-driver axis
- * 0 - (default) monitor all drivers on the axis or E0
+ * I - select which driver(s) to change on multi-driver axis
+ * 0 - (default) all drivers on the axis or E0
* 1 - monitor only X, Y, Z or E1
* 2 - monitor only X2, Y2, Z2 or E2
* 3 - monitor only Z3 or E3
* 4 - monitor only E4
* 5 - monitor only E5
- * Xxxx, Yxxx, Zxxx, Exxx - axis to be monitored with displacement
- * xxx (1-255) is distance moved on either side of current position
- *
- * I - over current threshold
- * optional - will report current value from driver if not specified
- *
- * K - value for KVAL_HOLD (0 - 255) (optional)
- * optional - will report current value from driver if not specified
- *
+ * Xxxx, Yxxx, Zxxx, Exxx - axis to change (optional)
+ * L6474 - current in mA (4A max)
+ * All others - 0-255
*/
/**
@@ -202,10 +196,12 @@ void L6470_report_current(L64XX &motor, const L64XX_axis_t axis) {
const uint16_t MicroSteps = _BV(motor.GetParam(L6470_STEP_MODE) & 0x07); //NOMORE(MicroSteps, 16);
SERIAL_ECHOLNPAIR("...MicroSteps: ", MicroSteps,
- " ADC_OUT: ", L6470_ADC_out);
+ " ADC_OUT: ", L6470_ADC_out,
+ " Vs_compensation: NA");
+
+ SERIAL_EOL();
- SERIAL_ECHOLNPGM(" Vs_compensation: NA\n"
- "...KVAL_HOLD: NA"
+ SERIAL_ECHOLNPGM("...KVAL_HOLD: NA"
" KVAL_RUN : NA"
" KVAL_ACC: NA"
" KVAL_DEC: NA"
@@ -232,7 +228,7 @@ void GcodeSuite::M906() {
L64xxManager.pause_monitor(true); // Keep monitor_driver() from stealing status
- #define L6470_SET_KVAL_HOLD(Q) stepper##Q.SetParam(L6470_KVAL_HOLD, value)
+ #define L6470_SET_KVAL_HOLD(Q) (AXIS_IS_L64XX(Q) ? stepper##Q.setTVALCurrent(value) : stepper##Q.SetParam(L6470_KVAL_HOLD, uint8_t(value)))
DEBUG_ECHOLNPGM("M906");
@@ -242,7 +238,7 @@ void GcodeSuite::M906() {
const uint8_t index = parser.byteval('I');
#endif
- LOOP_XYZE(i) if (uint8_t value = parser.byteval(axis_codes[i])) {
+ LOOP_XYZE(i) if (uint16_t value = parser.intval(axis_codes[i])) {
report_current = false;
diff --git a/Marlin/src/pins/stm32/pins_STEVAL_3DP001V1.h b/Marlin/src/pins/stm32/pins_STEVAL_3DP001V1.h
index fc600fd450e37fb0fbd53c6d5e8ec50ebb7aea77..3ec5c4c0ecee5a69a1245518c83627f226416002 100644
--- a/Marlin/src/pins/stm32/pins_STEVAL_3DP001V1.h
+++ b/Marlin/src/pins/stm32/pins_STEVAL_3DP001V1.h
@@ -68,18 +68,10 @@
// #define Z_MIN_PROBE_PIN 16 // PA4
//#endif
-#define SCK_PIN 13 // PB13 SPI_S
-#define MISO_PIN 12 // PB14 SPI_M
-#define MOSI_PIN 11 // PB15 SPI_M
-
-#define L6470_CHAIN_SCK_PIN 17 // PA5
-#define L6470_CHAIN_MISO_PIN 18 // PA6
-#define L6470_CHAIN_MOSI_PIN 19 // PA7
-#define L6470_CHAIN_SS_PIN 16 // PA4
-
-//#define SCK_PIN L6470_CHAIN_SCK_PIN
-//#define MISO_PIN L6470_CHAIN_MISO_PIN
-//#define MOSI_PIN L6470_CHAIN_MOSI_PIN
+//
+// Filament runout
+//
+//#define FIL_RUNOUT_PIN 53 // PA3 BED_THE
//
// Steppers
@@ -124,19 +116,34 @@
#define E4_CS_PIN 16 // PA4 SPI_CS
#define E5_CS_PIN 16 // PA4 SPI_CS
+#if HAS_L64XX
+ #define L6470_CHAIN_SCK_PIN 17 // PA5
+ #define L6470_CHAIN_MISO_PIN 18 // PA6
+ #define L6470_CHAIN_MOSI_PIN 19 // PA7
+ #define L6470_CHAIN_SS_PIN 16 // PA4
+
+ //#define SCK_PIN L6470_CHAIN_SCK_PIN
+ //#define MISO_PIN L6470_CHAIN_MISO_PIN
+ //#define MOSI_PIN L6470_CHAIN_MOSI_PIN
+#else
+ //#define SCK_PIN 13 // PB13 SPI_S
+ //#define MISO_PIN 12 // PB14 SPI_M
+ //#define MOSI_PIN 11 // PB15 SPI_M
+#endif
+
/**
- * macro to reset/enable L6474 chips
+ * Macro to reset/enable L6474 stepper drivers
*
- * IMPORTANT - to disable (bypass) a L6474, install the corresponding
- * resistor (R11 - R17) and change the "V" to zero for the
- * corresponding pin.
+ * IMPORTANT - To disable (bypass) L6474s, install the corresponding
+ * resistors (R11 - R17) and change the "V" to "0" for the
+ * corresponding pins here:
*/
-#define ENABLE_RESET_L64XX_CHIPS(V) do{OUT_WRITE(X_ENABLE_PIN, V);\
- OUT_WRITE(Y_ENABLE_PIN, V);\
- OUT_WRITE(Z_ENABLE_PIN, V);\
- OUT_WRITE(E0_ENABLE_PIN,V);\
- OUT_WRITE(E1_ENABLE_PIN,V);\
- OUT_WRITE(E2_ENABLE_PIN,V);\
+#define ENABLE_RESET_L64XX_CHIPS(V) do{ OUT_WRITE(X_ENABLE_PIN, V); \
+ OUT_WRITE(Y_ENABLE_PIN, V); \
+ OUT_WRITE(Z_ENABLE_PIN, V); \
+ OUT_WRITE(E0_ENABLE_PIN,V); \
+ OUT_WRITE(E1_ENABLE_PIN,V); \
+ OUT_WRITE(E2_ENABLE_PIN,V); \
}while(0)
//
@@ -146,7 +153,7 @@
#define TEMP_1_PIN 4 // Analog input 4, digital pin 55 PA1 E2_THERMISTOR
#define TEMP_2_PIN 5 // Analog input 5, digital pin 56 PA2 E3_THERMISTOR
#define TEMP_BED_PIN 0 // Analog input 0, digital pin 51 PC2 BED_THERMISTOR_1
-#define TEMP_BED_1_PIN 1` // Analog input 1, digital pin 52 PC3 BED_THERMISTOR_2
+#define TEMP_BED_1_PIN 1 // Analog input 1, digital pin 52 PC3 BED_THERMISTOR_2
#define TEMP_BED_2_PIN 2 // Analog input 2, digital pin 53 PA3 BED_THERMISTOR_3
//
@@ -171,7 +178,7 @@
#define LED_PIN -1 // 9 // PE1 green LED Heart beat
#define PS_ON_PIN -1
#define KILL_PIN -1
-#define PWR_LOSS -1 // Power loss / nAC_FAULT
+#define POWER_LOSS_PIN -1 // PWR_LOSS / nAC_FAULT
//
// LCD / Controller
@@ -188,11 +195,6 @@
//#define BTN_EN2 58 // PC5 E2_FAN
//#define BTN_ENC 52 // PC3 BED_THE
-//
-// Filament runout
-//
-//#define FIL_RUNOUT_PIN 53 // PA3 BED_THE
-
//
// Extension pins
//
@@ -225,7 +227,10 @@
// 21 // PA14 JTAG_TCK/SWCLK
// 22 // PB3 JTAG_TDO/SWO
-// SDCARD
+//
+// SD support
+//
+//#define SDIO_SUPPORT
// 23 // PC8 SDIO_D0
// 24 // PC9 SDIO_D1
// 25 // PA15 SD_CARD_DETECT
@@ -234,6 +239,12 @@
// 28 // PC12 SDIO_CK
// 29 // PD2 SDIO_CMD
+#define SOFTWARE_SPI // Use soft SPI for onboard SD
+#define SDSS 27 // PC11 SDIO_D3
+#define SCK_PIN 28 // PC12 SDIO_CK
+#define MISO_PIN 23 // PC8 SDIO_D0
+#define MOSI_PIN 29 // PD2 SDIO_CMD
+
// OTG
// 30 // PA11 OTG_DM
// 31 // PA12 OTG_DP
diff --git a/buildroot/share/PlatformIO/variants/STEVAL_F401VE/hal_conf_custom.h b/buildroot/share/PlatformIO/variants/STEVAL_F401VE/hal_conf_custom.h
index 40046334289e12ab64dcf12ac8a59a5b524b6702..0c7781997fef87fbb874cbadf28ae7d47648193a 100644
--- a/buildroot/share/PlatformIO/variants/STEVAL_F401VE/hal_conf_custom.h
+++ b/buildroot/share/PlatformIO/variants/STEVAL_F401VE/hal_conf_custom.h
@@ -55,7 +55,7 @@ extern "C" {
#define HAL_I2C_MODULE_ENABLED
/* #define HAL_SMBUS_MODULE_ENABLED */
/* #define HAL_I2S_MODULE_ENABLED */
-/* #define HAL_IWDG_MODULE_ENABLED */
+#define HAL_IWDG_MODULE_ENABLED
/* #define HAL_LTDC_MODULE_ENABLED */
/* #define HAL_DSI_MODULE_ENABLED */
#define HAL_PWR_MODULE_ENABLED
diff --git a/buildroot/share/PlatformIO/variants/STEVAL_F401VE/variant.cpp b/buildroot/share/PlatformIO/variants/STEVAL_F401VE/variant.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a53a92c48c29fcaddd39d787c522917d5655fdd6
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/STEVAL_F401VE/variant.cpp
@@ -0,0 +1,310 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2017, STMicroelectronics
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *******************************************************************************
+ */
+
+#include "pins_arduino.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(ARDUINO_STEVAL)
+// Pin number
+// This array allows to wrap Arduino pin number(Dx or x)
+// to STM32 PinName (PX_n)
+const PinName digitalPin[] = {
+ PA_9, // TX
+ PA_10, // RX
+
+ // WIFI
+ PD_3, // CTS
+ PD_4, // RTS
+ PD_5, // TX
+ PD_6, // RX
+ PB_5, // WIFI_WAKEUP
+ PE_11, // WIFI_RESET
+ PE_12, // WIFI_BOOT
+
+ // STATUS_LED
+ PE_1, //STATUS_LED
+
+ // SPI USER
+ PB_12, // SPI_CS
+ PB_15, // SPI_MOSI
+ PB_14, // SPI_MISO
+ PB_13, // SPI_SCK
+
+ // I2C USER
+ PB_7, // SDA
+ PB_6, // SCL
+
+ // SPI
+ PA_4, // SPI_CS
+ PA_5, // SPI_SCK
+ PA_6, // SPI_MISO
+ PA_7, // SPI_MOSI
+
+ // JTAG
+ PA_13, // JTAG_TMS/SWDIO
+ PA_14, // JTAG_TCK/SWCLK
+ PB_3, // JTAG_TDO/SWO
+
+ // SDCARD
+ PC_8, // SDIO_D0
+ PC_9, // SDIO_D1
+ PA_15, // SD_CARD_DETECT
+ PC_10, // SDIO_D2
+ PC_11, // SDIO_D3
+ PC_12, // SDIO_CK
+ PD_2, // SDIO_CMD
+
+ // OTG
+ PA_11, // OTG_DM
+ PA_12, // OTG_DP
+
+ // IR/PROBE
+ PD_1, // IR_OUT
+ PC_1, // IR_ON
+
+ // USER_PINS
+ PD_7, // USER3
+ PB_9, // USER1
+ PE_0, // USER2
+ PB_4, // USER4
+
+ // USERKET
+ PE_7, // USER_BUTTON
+
+ // ENDSTOPS
+ PD_8, // X_STOP
+ PD_9, // Y_STOP
+ PD_10, // Z_STOP
+ PD_11, // U_STOP
+ PA_8, // V_STOP
+ PD_0, // W_STOP
+
+ // HEATERS
+ PD_13, // BED_HEAT_2
+ PD_14, // BED_HEAT_1
+ PD_15, // BED_HEAT_3
+ PC_7, // E1_HEAT_PWM
+ PB_0, // E2_HEAT_PWM
+ PB_1, // E3_HEAT_PWM
+
+ // THERMISTOR
+ PC_2, // BED_THERMISTOR_1
+ PC_3, // BED_THERMISTOR_2
+ PA_3, // BED_THERMISTOR_3
+ PA_0, // E1_THERMISTOR
+ PA_1, // E2_THERMISTOR
+ PA_2, // E3_THERMISTOR
+
+ // FANS
+ PC_4, // E1_FAN
+ PC_5, // E2_FAN
+ PE_8, // E3_FAN
+
+ // X_MOTOR
+ PE_13, // X_RESET
+ PE_14, // X_PWM
+ PE_15, // X_DIR
+
+ // Y_MOTOR
+ PE_10, // Y_RESET
+ PB_10, // Y_PWM
+ PE_9, // Y_DIR
+
+ // Z_MOTOR
+ PC_15, // Z_RESET
+ PC_6, // Z_PWM
+ PC_0, // Z_DIR
+
+ // E1_MOTOR
+ PC_14, // E1_RESET
+ PC_13, // E1_DIR
+ PD_12, // E1_PWM
+
+ // E2_MOTOR
+ PE_4, // E2_RESET
+ PE_5, // E2_PWM
+ PE_6, // E2_DIR
+
+ // E3_MOTOR
+ PE_3, // E3_RESET
+ PE_2, // E3_DIR
+ PB_8 // E3_PWM
+};
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+// ----------------------------------------------------------------------------
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @brief System Clock Configuration
+ * The system Clock is configured as follow :
+ * System Clock source = PLL (HSI)
+ * SYSCLK(Hz) = 84000000
+ * HCLK(Hz) = 84000000
+ * AHB Prescaler = 1
+ * APB1 Prescaler = 2
+ * APB2 Prescaler = 1
+ * HSI Frequency(Hz) = 16000000
+ * PLL_M = 16
+ * PLL_N = 336
+ * PLL_P = 4
+ * PLL_Q = 7
+ * VDD(V) = 3.3
+ * Main regulator output voltage = Scale2 mode
+ * Flash Latency(WS) = 2
+ * @param None
+ * @retval None
+ */
+WEAK void SystemClock_Config(void)
+{
+ RCC_OscInitTypeDef RCC_OscInitStruct = {};
+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
+
+ /* Configure the main internal regulator output voltage */
+ __HAL_RCC_PWR_CLK_ENABLE();
+ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
+
+ /* Initializes the CPU, AHB and APB busses clocks */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+ RCC_OscInitStruct.PLL.PLLM = 15;
+ RCC_OscInitStruct.PLL.PLLN = 144;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
+ RCC_OscInitStruct.PLL.PLLQ = 5;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
+ Error_Handler();
+ }
+ /* Initializes the CPU, AHB and APB busses clocks */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
+ | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
+ Error_Handler();
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+// PA_0 54 // E1_THERMISTOR
+// PA_1 55 // E2_THERMISTOR
+// PA_2 56 // E3_THERMISTOR
+// PA_3 53 // BED_THERMISTOR_3
+// PA_4 16 // SPI_CS
+// PA_5 17 // SPI_SCK
+// PA_6 18 // SPI_MISO
+// PA_7 19 // SPI_MOSI
+// PA_8 43 // V_STOP
+// PA_9 0 //TX
+// PA_10 1 //RX
+// PA_11 30 //OTG_DM
+// PA_12 31 //OTG_DP
+// PA_13 20 // JTAG_TMS/SWDIO
+// PA_14 21 // JTAG_TCK/SWCLK
+// PA_15 25 // SD_CARD_DETECT
+// PB_0 49 // E2_HEAT_PWM
+// PB_1 50 // E3_HEAT_PWM
+// PB_3 22 // JTAG_TDO/SWO
+// PB_4 37 // USER4
+// PB_5 6 // WIFI_WAKEUP
+// PB_6 15 // SCL
+// PB_7 14 // SDA
+// PB_8 77 // E3_PWM
+// PB_9 35 // USER1
+// PB_10 64 // Y_PWM
+// PB_12 10 // SPI_CS
+// PB_13 13 // SPI_SCK
+// PB_14 12 // SPI_MISO
+// PB_15 11 // SPI_MOSI
+// PC_0 68 // Z_DIR
+// PC_1 33 //IR_ON
+// PC_2 51 // BED_THERMISTOR_1
+// PC_3 52 // BED_THERMISTOR_2
+// PC_4 57 // E1_FAN
+// PC_5 58 // E2_FAN
+// PC_6 67 // Z_PWM
+// PC_7 48 // E1_HEAT_PWM
+// PC_8 23 // SDIO_D0
+// PC_9 24 // SDIO_D1
+// PC_10 26 // SDIO_D2
+// PC_11 27 // SDIO_D3
+// PC_12 28 // SDIO_CK
+// PC_13 70 // E1_DIR
+// PC_14 69 // E1_RESET
+// PC_15 66 // Z_RESET
+// PD_0 44 // W_STOP
+// PD_1 32 //IR_OUT
+// PD_2 29 // SDIO_CMD
+// PD_3 2 // CTS
+// PD_4 3 // RTS
+// PD_5 4 // TX
+// PD_6 5 // RX
+// PD_7 34 // USER3
+// PD_8 39 // X_STOP
+// PD_9 40 // Y_STOP
+// PD_10 41 // Z_STOP
+// PD_11 42 // U_STOP
+// PD_12 71 // E1_PWM
+// PD_13 45 // BED_HEAT_2
+// PD_14 46 // BED_HEAT_1
+// PD_15 47 // BED_HEAT_3
+// PE_0 36 // USER2
+// PE_1 9 // STATUS_LED
+// PE_2 76 // E3_DIR
+// PE_3 75 // E3_RESET
+// PE_4 72 // E2_RESET
+// PE_5 73 // E2_PWM
+// PE_6 74 // E2_DIR
+// PE_7 38 // USER_BUTTON
+// PE_8 59 // E3_FAN
+// PE_9 65 // Y_DIR
+// PE_10 63 // Y_RESET
+// PE_11 7 // WIFI_RESET
+// PE_12 8 // WIFI_BOOT
+// PE_13 60 // X_RESET
+// PE_14 61 // X_PWM
+// PE_15 62 // X_DIR