diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 35ca67c0f578..2cdffe5179ac 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -37,8 +37,6 @@
*/
#define CONFIGURATION_H_VERSION 02010300
-// ENABLE CAN SUPPORT HERE
-// #define CAN_MASTER
//===========================================================================
//============================= Getting Started =============================
//===========================================================================
@@ -70,7 +68,7 @@
// Choose the name from boards.h that matches your setup
#ifndef MOTHERBOARD
- #define MOTHERBOARD BOARD_MKS_MONSTER8_V2
+ #define MOTHERBOARD BOARD_RAMPS_14_EFB
#endif
// @section serial
@@ -126,6 +124,9 @@
//#define RS485_BUS_BUFFER_SIZE 128
#endif
+// Enable CAN bus support and protocol
+//#define CAN_MASTER
+
// Enable the Bluetooth serial interface on AT90USB devices
//#define BLUETOOTH
diff --git a/Marlin/src/HAL/STM32/CAN.cpp b/Marlin/src/HAL/STM32/CAN.cpp
index 52cfeca1d2d7..89292f986d3f 100644
--- a/Marlin/src/HAL/STM32/CAN.cpp
+++ b/Marlin/src/HAL/STM32/CAN.cpp
@@ -1,63 +1,85 @@
-// IRON NOTES:
-// NOTE 1: For MKS Monster 8 V1/V2 on Arduino use: Board "Generic STM32F4 series", Board part number "Generic F407VETx"
-// NOTE 2: Make sure to define "HAL_CAN_MODULE_ENABLED". In VSCode add "build_flags = -D HAL_CAN_MODULE_ENABLED" in platformio.ini.
-// For Arduino IDE include "hal_conf_extra.h" holding "#define HAL_CAN_MODULE_ENABLED"
-// NOTE 3: To accept all CAN messages, enable 1 filter (FilterBank = 0) in "FilterMode = CAN_FILTERMODE_IDMASK", mask and ID = 0 (0=don't care)
-// NOTE 4: Serial communication in ISR causes issues! Hangs etc. so avoid this!
-// NOTE 5: A FIFO storage cell is called a Mailbox in STM32F4xx, FIFO0 and FiFO1 can hold 3 CAN message each.
-// NOTE 6: The filter ID/mask numbers (LOW/HIGH) do not directly relate to the message ID numbers (See Figure 342 in RM0090)
-
-#include "../../inc/MarlinConfig.h"
-
-#ifdef CAN_MASTER
- #include "../platforms.h"
- #include "../../gcode/gcode.h"
- #include "../../module/temperature.h"
- #include "../../module/motion.h" // For current_position variable
- #include "../../module/planner.h" // For steps/mm parameters variables
- #include "../../feature/tmc_util.h"
- #include "../../module/stepper.h"
- #include "../../module/endstops.h"
- #include "../../feature/controllerfan.h" // For controllerFan settings
- #include "../../libs/numtostr.h" // For float to string conversion
-
- // #define CAN_DEBUG // Define to show gcodes send to HEAD
-
- #define CAN_EXTENDED_ID CAN_ID_EXT
- #define CAN_STANDARD_ID CAN_ID_STD
-
- #define STDID_FIFO_BIT 0b10000000000
- #define EXTID_FIFO_BIT 0x10000000
-
- #define CAN_IO_MASK 0b11111 // Masks for the 5 virtual IO bits (see below)
- #define GCODE_NUMBER_MASK 0b1111111111111
- #define PARAMETER_MASK 0b11111
- #define PARAMETER_COUNT_MASK 0b111
- #define GCODE_TYPE_MASK 0b11
- #define CAN_PROBE_MASK 1 // Virtual IO bit for probe
- #define CAN_FILAMENT_MASK 2 // Virtual IO bit for filament
- #define CAN_X_ENDSTOP_MASK 4 // Virtual IO bit for X-endstop
- #define CAN_Y_ENDSTOP_MASK 8 // Virtual IO bit for Y-endstop
- #define CAN_Z_ENDSTOP_MASK 16 // Virtual IO bit for Z-endstop
- #define CAN_STRING_MESSAGE_MASK 32 // Signals the head sent a string message
- #define CAN_REQUEST_SETUP_MASK 64 // Signals the head requests setup information
- #define CAN_TMC_OT_MASK 128 // Signals the head signals a TMC Over Temp error
- #define CAN_E0_TARGET_MASK 256 // Signals E0 or E1
- #define CAN_ERROR_MASK 512 // Signals the head encountered an error
-
- #define PARAMETER1_OFFSET 0
- #define PARAMETER2_OFFSET 5
- #define GCODE_NUMBER_OFFSET 10
- #define GCODE_TYPE_OFFSET 23
- #define PARAMETER_COUNT_OFFSET 25
-
- #define GCODE_TYPE_D 0
- #define GCODE_TYPE_G 1
- #define GCODE_TYPE_M 2
- #define GCODE_TYPE_T 3
-
-extern "C" void CAN1_RX0_IRQHandler(void); // Override weak CAN FIFO0 interrupt handler
-extern "C" void CAN1_RX1_IRQHandler(void); // Override weak CAN FIFO1 interrupt handler
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2024 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 .
+ *
+ */
+
+/**
+ * Contributor Notes:
+ * NOTE 1: For MKS Monster 8 V1/V2 on Arduino use: Board "Generic STM32F4 series", Board part number "Generic F407VETx"
+ * NOTE 2: Requires `HAL_CAN_MODULE_ENABLED`, e.g., with `-DHAL_CAN_MODULE_ENABLED`
+ * For Arduino IDE use "hal_conf_extra.h" with `#define HAL_CAN_MODULE_ENABLED`
+ * NOTE 3: To accept all CAN messages, enable 1 filter (FilterBank = 0) in "FilterMode = CAN_FILTERMODE_IDMASK", mask and ID = 0 (0=don't care)
+ * NOTE 4: Serial communication in ISR causes issues! Hangs etc. so avoid this!
+ * NOTE 5: A FIFO storage cell is called a "Mailbox" in STM32F4xx, FIFO0 and FiFO1 can hold 3 CAN messages each.
+ * NOTE 6: The filter ID/mask numbers (LOW/HIGH) do not directly relate to the message ID numbers (See Figure 342 in RM0090)
+ */
+
+#include "../../inc/MarlinConfigPre.h"
+
+#if ENABLED(CAN_MASTER)
+
+#include "../platforms.h"
+#include "../../gcode/parser.h"
+#include "../../module/temperature.h"
+#include "../../module/motion.h" // For current_position variable
+#include "../../module/planner.h" // For steps/mm parameters variables
+#include "../../feature/tmc_util.h"
+#include "../../module/endstops.h"
+#include "../../feature/controllerfan.h" // For controllerFan settings
+#include "../../libs/numtostr.h" // For float to string conversion
+
+#define CAN_EXTENDED_ID CAN_ID_EXT
+#define CAN_STANDARD_ID CAN_ID_STD
+
+#define STDID_FIFO_BIT 0b10000000000
+#define EXTID_FIFO_BIT 0x10000000
+
+#define CAN_IO_MASK 0b11111 // Masks for the 5 virtual IO bits (see below)
+#define GCODE_NUMBER_MASK 0b1111111111111
+#define PARAMETER_MASK 0b11111
+#define PARAMETER_COUNT_MASK 0b111
+#define GCODE_TYPE_MASK 0b11
+#define CAN_PROBE_MASK 1 // Virtual IO bit for probe
+#define CAN_FILAMENT_MASK 2 // Virtual IO bit for filament
+#define CAN_X_ENDSTOP_MASK 4 // Virtual IO bit for X-endstop
+#define CAN_Y_ENDSTOP_MASK 8 // Virtual IO bit for Y-endstop
+#define CAN_Z_ENDSTOP_MASK 16 // Virtual IO bit for Z-endstop
+#define CAN_STRING_MESSAGE_MASK 32 // Signals the head sent a string message
+#define CAN_REQUEST_SETUP_MASK 64 // Signals the head requests setup information
+#define CAN_TMC_OT_MASK 128 // Signals the head signals a TMC Over Temp error
+#define CAN_E0_TARGET_MASK 256 // Signals E0 or E1
+#define CAN_ERROR_MASK 512 // Signals the head encountered an error
+
+#define PARAMETER1_OFFSET 0
+#define PARAMETER2_OFFSET 5
+#define GCODE_NUMBER_OFFSET 10
+#define GCODE_TYPE_OFFSET 23
+#define PARAMETER_COUNT_OFFSET 25
+
+#define GCODE_TYPE_D 0
+#define GCODE_TYPE_G 1
+#define GCODE_TYPE_M 2
+#define GCODE_TYPE_T 3
+
+extern "C" void CAN1_RX0_IRQHandler(); // Override weak CAN FIFO0 interrupt handler
+extern "C" void CAN1_RX1_IRQHandler(); // Override weak CAN FIFO1 interrupt handler
extern "C" void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan); // Override weak CAN interrupt callback for FIFO0
extern "C" void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan); // Override weak CAN interrupt callback for FIFO1
extern "C" void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan); // Override weak CAN interrupt callback
@@ -73,71 +95,70 @@ volatile uint32_t HAL_CAN_error_code = 0; // Record a host CAN error messa
volatile bool FirstE0Error = true; // First CAN bus error, show warning only once
volatile bool string_message_complete = false; // Signals a complete string message was received
volatile uint32_t string_message_index = 0; // Index into the CAN string that is being received
-uint32_t Last_CAN_Temp_Report = 0; // Track when the last head temperature report was received
+uint32_t Next_CAN_Temp_Report = 0; // Track when the next head temperature report will be received
uint32_t Last_CAN_Error_Message = 0; // Track when the last CAN error messaget was shown
char string_message[128] = "\0"; // CAN string message buffer for incoming message, max 128 characters
-void CAN1_RX0_IRQHandler(void) // CAN FIFO0 Interrupt handler overrides standard weak CAN1_RX0_IRQHandler
-{
+void CAN1_RX0_IRQHandler() { // CAN FIFO0 Interrupt handler overrides standard weak CAN1_RX0_IRQHandler
HAL_CAN_IRQHandler(&hcan1); // Forwarded for callbacks --> HAL_CAN_RxFifo0MsgPendingCallback/HAL_CAN_ErrorCallback
-// OR
-// HAL_CAN_RxFifo0MsgPendingCallback(&hcan1); // Call the required callback directly, faster but no error reporting
+ // OR
+ //HAL_CAN_RxFifo0MsgPendingCallback(&hcan1); // Call the required callback directly, faster but no error reporting
}
-void CAN1_RX1_IRQHandler(void) // CAN FIFO1 Interrupt handler overrides standard weak CAN1_RX0_IRQHandler
-{
+void CAN1_RX1_IRQHandler() { // CAN FIFO1 Interrupt handler overrides standard weak CAN1_RX0_IRQHandler
HAL_CAN_IRQHandler(&hcan1); // Forwarded for callbacks --> HAL_CAN_RxFifo1MsgPendingCallback/HAL_CAN_ErrorCallback
-// OR
-// HAL_CAN_RxFifo1MsgPendingCallback(&hcan1); // Call the required callback directly, faster but no error reporting
+ // OR
+ //HAL_CAN_RxFifo1MsgPendingCallback(&hcan1); // Call the required callback directly, faster but no error reporting
}
// Send specified Gcode with max 2 parameters and 2 values via CAN bus
-HAL_StatusTypeDef CAN_Send_Gcode_2params(uint32_t Gcode_type, uint32_t Gcode_no, uint32_t parameter1, float value1, uint32_t parameter2, float value2)
-{
- switch (Gcode_type)
- {
- case 'D': Gcode_type = GCODE_TYPE_D;
- break;
-
- case 'G': Gcode_type = GCODE_TYPE_G;
- break;
-
- case 'M': Gcode_type = GCODE_TYPE_M;
+HAL_StatusTypeDef CAN_Send_Gcode_2params(uint32_t Gcode_type, uint32_t Gcode_no, uint32_t parameter1, float value1, uint32_t parameter2, float value2) {
+ switch (Gcode_type) {
+ case 'D':
+ Gcode_type = GCODE_TYPE_D;
+ break;
-#ifdef CAN_DEBUG
- SERIAL_ECHOPGM(">>> CAN TO HEAD: M", Gcode_no);
- if (parameter1) {
- SERIAL_CHAR(' ', parameter1);
- if (value1 == int(value1))
- SERIAL_ECHO(i16tostr3left(value1)); // Integer value
- else
- SERIAL_ECHO(p_float_t(value1, 4)); // Float with 4 digits
- }
+ case 'G':
+ Gcode_type = GCODE_TYPE_G;
+ break;
- if (parameter2) {
- SERIAL_CHAR(' ', parameter2);
- if (value2 == int(value2))
- SERIAL_ECHO(i16tostr3left(value2)); // Integer value
- else
- SERIAL_ECHO(p_float_t(value2, 4)); // Float with 4 digits
- }
- SERIAL_EOL();
-#endif
+ case 'M':
+ Gcode_type = GCODE_TYPE_M;
+
+ #ifdef CAN_DEBUG
+ SERIAL_ECHOPGM(">>> CAN TO HEAD: M", Gcode_no);
+ if (parameter1) {
+ SERIAL_CHAR(' ', parameter1);
+ if (value1 == int(value1))
+ SERIAL_ECHO(i16tostr3left(value1)); // Integer value
+ else
+ SERIAL_ECHO(p_float_t(value1, 4)); // Float with 4 digits
+ }
+
+ if (parameter2) {
+ SERIAL_CHAR(' ', parameter2);
+ if (value2 == int(value2))
+ SERIAL_ECHO(i16tostr3left(value2)); // Integer value
+ else
+ SERIAL_ECHO(p_float_t(value2, 4)); // Float with 4 digits
+ }
+ SERIAL_EOL();
+ #endif // CAN_DEBUG
+
+ break;
- break;
-
case 'T': Gcode_type = GCODE_TYPE_T;
- break;
-
+ break;
+
default: return HAL_ERROR; // UNKNOWN GCODE TYPE
}
HAL_StatusTypeDef status = HAL_OK;
- uint32_t TxMailbox; // Stores which Mailbox (0-2) is used to store the Sent TX message
+ uint32_t TxMailbox; // Stores which Mailbox (0-2) is used to store the Sent TX message
if (parameter1 > 31)
parameter1 -= 64; // Format 'A' = 1, 'B' = 2, etc.
-
+
if (parameter2 > 31)
parameter2 -= 64; // Format 'A' = 1, 'B' = 2, etc.
@@ -146,18 +167,18 @@ HAL_StatusTypeDef CAN_Send_Gcode_2params(uint32_t Gcode_type, uint32_t Gcode_no,
TxHeader.StdId = (TxHeader.StdId ^ STDID_FIFO_BIT); // Toggle FIFO bit 10, keep FIFO toggling in sync
TxHeader.ExtId = ((TxHeader.ExtId ^ EXTID_FIFO_BIT) & EXTID_FIFO_BIT) + // Toggle FIFO bit 28
((TxHeader.DLC >> 2) << PARAMETER_COUNT_OFFSET) + // Data bytes (4 or 8)
- (Gcode_type << GCODE_TYPE_OFFSET) + // G/M/T/D-code
+ (Gcode_type << GCODE_TYPE_OFFSET) + // G/M/T/D-code
((Gcode_no & GCODE_NUMBER_MASK) << GCODE_NUMBER_OFFSET) + // Gcode number
((parameter2 & PARAMETER_MASK) << PARAMETER2_OFFSET) + // First parameter
- ((parameter1 & PARAMETER_MASK) << PARAMETER1_OFFSET); // Second parameter
+ ((parameter1 & PARAMETER_MASK) << PARAMETER1_OFFSET); // Second parameter
uint8_t CAN_tx_buffer[8]; // 8 bytes CAN data TX buffer
- float * fp = (float *)CAN_tx_buffer; // Point to TX buffer
+ float * fp = (float *)CAN_tx_buffer; // Point to TX buffer
*fp++ = value1;
*fp-- = value2;
-
- uint32_t ms = millis(); // Don't send too fast!
+
+ const uint32_t ms = millis(); // Don't send too fast!
while ((HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0) && (millis() - ms < 25)) { } // BLOCKING! Wait max 25ms!
- // SERIAL_ECHOLNPGM(">>> Waited1: ", millis() - ms, " FreeTX: ", HAL_CAN_GetTxMailboxesFreeLevel(&hcan1)); // IRON, DEBUGGING
+ //SERIAL_ECHOLNPGM(">>> Waited1: ", millis() - ms, " FreeTX: ", HAL_CAN_GetTxMailboxesFreeLevel(&hcan1)); // IRON, DEBUGGING
status = HAL_CAN_AddTxMessage(&hcan1, &TxHeader, CAN_tx_buffer, &TxMailbox); // Send message
if (status == HAL_OK) // Count sent gcode messages
@@ -166,25 +187,26 @@ HAL_StatusTypeDef CAN_Send_Gcode_2params(uint32_t Gcode_type, uint32_t Gcode_no,
return status;
}
-HAL_StatusTypeDef CAN_Send_Setup() // Send setup to HEAD
-{
+HAL_StatusTypeDef CAN_Send_Setup() { // Send setup to HEAD
CAN_head_setup_request = false;
SERIAL_ECHOLNPGM(">>> CAN: SENDING CONFIG TO HEAD =====");
-// NOTE: Sending many command too fast will cause a Marlin command buffer overrun at the head, add delays if needed
-// CAN_Send_Gcode_2params('M', 104, 'S', 0, 0, 0); // M104 S0, switch off hotend heating, NOT NEEDED ANYMORE
-// CAN_Send_Gcode_2params('M', 107, 0, 0, 0, 0); // M107, switch off cooling fan, NOT NEEDED ANYMORE
-// CAN_Send_Gcode_2params('M', 18, 0, 0, 0, 0); // M18, switch off steppers, NOT NEEDED ANYMORE
-
- // M306 MPC settings (managed by host)
- MPC_t &mpc = thermalManager.temp_hotend[0].mpc;
-
- CAN_Send_Gcode_2params('M', 306, 'A', mpc.ambient_xfer_coeff_fan0, 'C', mpc.block_heat_capacity); // M306 R A
- CAN_Send_Gcode_2params('M', 306, 'F', mpc.fanCoefficient(), 'H', mpc.filament_heat_capacity_permm); // M306 F H
- CAN_Send_Gcode_2params('M', 306, 'P', mpc.heater_power, 'R', mpc.sensor_responsiveness); // M306 P C
+ // NOTE: Sending many command too fast will cause a Marlin command buffer overrun at the head, add delays if needed
+ //CAN_Send_Gcode_2params('M', 104, 'S', 0, 0, 0); // M104 S0, switch off hotend heating, NOT NEEDED ANYMORE
+ //CAN_Send_Gcode_2params('M', 107, 0, 0, 0, 0); // M107, switch off cooling fan, NOT NEEDED ANYMORE
+ //CAN_Send_Gcode_2params('M', 18, 0, 0, 0, 0); // M18, switch off steppers, NOT NEEDED ANYMORE
+
+ #if ENABLED(MPCTEMP)
+ // M306 MPC settings (managed by host)
+ MPC_t &mpc = thermalManager.temp_hotend[0].mpc;
+
+ CAN_Send_Gcode_2params('M', 306, 'A', mpc.ambient_xfer_coeff_fan0, 'C', mpc.block_heat_capacity); // M306 R A
+ CAN_Send_Gcode_2params('M', 306, 'F', mpc.fanCoefficient(), 'H', mpc.filament_heat_capacity_permm); // M306 F H
+ CAN_Send_Gcode_2params('M', 306, 'P', mpc.heater_power, 'R', mpc.sensor_responsiveness); // M306 P C
+ #endif
-// CAN_Send_Gcode_2params('M', 150, 0, 0, 0, 0); // M150, SWITCH NEOPIXEL OFF
+ //CAN_Send_Gcode_2params('M', 150, 0, 0, 0, 0); // M150, SWITCH NEOPIXEL OFF
-/*
+ /*
extern Planner planner; // M92 Steps per mm
CAN_Send_Gcode_2params('M', 92, 'X', planner.settings.axis_steps_per_mm[X_AXIS], 'Y', planner.settings.axis_steps_per_mm[Y_AXIS]);
CAN_Send_Gcode_2params('M', 92, 'Z', planner.settings.axis_steps_per_mm[Z_AXIS], 'E', planner.settings.axis_steps_per_mm[E_AXIS]);
@@ -198,7 +220,7 @@ HAL_StatusTypeDef CAN_Send_Setup() // Send setup to HEAD
// M201 Max acceleration
CAN_Send_Gcode_2params('M', 201, 'X', planner.settings.max_acceleration_mm_per_s2[X_AXIS], 'Y', planner.settings.max_acceleration_mm_per_s2[Y_AXIS]);
CAN_Send_Gcode_2params('M', 201, 'Z', planner.settings.max_acceleration_mm_per_s2[Z_AXIS], 'E', planner.settings.max_acceleration_mm_per_s2[E_AXIS]);
-
+
// M203 Max feedrate
CAN_Send_Gcode_2params('M', 203, 'X', planner.settings.max_feedrate_mm_s[X_AXIS], 'Y', planner.settings.max_feedrate_mm_s[Y_AXIS]);
CAN_Send_Gcode_2params('M', 203, 'Z', planner.settings.max_feedrate_mm_s[Z_AXIS], 'E', planner.settings.max_feedrate_mm_s[E_AXIS]);
@@ -208,16 +230,16 @@ HAL_StatusTypeDef CAN_Send_Setup() // Send setup to HEAD
CAN_Send_Gcode_2params('M', 204, 'T', planner.settings.travel_acceleration, 0, 0);
// M205
- #ifdef CLASSIC_JERK
+ #if ENABLED(CLASSIC_JERK)
CAN_Send_Gcode_2params('M', 205,'S')) planner.settings.min_feedrate_mm_s, 'T')) planner.settings.min_travel_feedrate_mm_s);
CAN_Send_Gcode_2params('M', 205, M205_MIN_SEG_TIME_PARAM, planner.settings.min_segment_time_us, 'J', planner.junction_deviation_mm);
CAN_Send_Gcode_2params('M', 205, 'X', LINEAR_UNIT(planner.max_jerk.x), 'Y', LINEAR_UNIT(planner.max_jerk.y));
CAN_Send_Gcode_2params('M', 205, 'Z', LINEAR_UNIT(planner.max_jerk.z), 'E', LINEAR_UNIT(planner.max_jerk.e));
- CAN_Send_Gcode_2params('M', 205, 'J', LINEAR_UNIT(planner.junction_deviation_mm), 0, 0);
+ CAN_Send_Gcode_2params('M', 205, 'J', LINEAR_UNIT(planner.junction_deviation_mm), 0, 0);
#endif
// M206 Home offset
- #ifndef NO_HOME_OFFSETS
+ #if DISABLED(NO_HOME_OFFSETS)
_CAN_Send_Gcode_2params('M', 206, 'X', LINEAR_UNIT(home_offset.x), 'Y', LINEAR_UNIT(home_offset.y));
CAN_Send_Gcode_2params('M', 206, 'Z', LINEAR_UNIT(home_offset.z), 0, 0);
#endif
@@ -225,14 +247,14 @@ HAL_StatusTypeDef CAN_Send_Setup() // Send setup to HEAD
// M207 Set Firmware Retraction
// M208 - Firmware Recover
// M209 - Set Auto Retract
-
+
// M220 Speed/feedrate
CAN_Send_Gcode_2params('M', 220, 'S', feedrate_percentage, 0, 0);
-
+
// M221 Flow percentage
CAN_Send_Gcode_2params('M', 221, 'T', 0, 'S', planner.flow_percentage[0]);
// CAN_Send_Gcode_2params('M', 221, 'T', 1, 'S', planner.flow_percentage[1]); // For 2nd extruder
-
+
// M302 Cold extrude settings
#if ENABLED(PREVENT_COLD_EXTRUSION)
CAN_Send_Gcode_2params('M', 302, 'P', '0' + thermalManager.allow_cold_extrude, 'S', thermalManager.extrude_min_temp); // P0 enable cold extrusion checking, P1 = disabled, S=Minimum temperature
@@ -249,31 +271,32 @@ HAL_StatusTypeDef CAN_Send_Setup() // Send setup to HEAD
// M919 TMC Chopper timing for E only
CAN_Send_Gcode_2params('M', 919, 'O', off, 'P' , Hysteresis End);
CAN_Send_Gcode_2params('M', 919, 'S', Hysteresis Start, 0, 0);
-*/
-/*
-CAN_Send_Gcode_2params('M', 710, 'E', 1, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
-CAN_Send_Gcode_2params('M', 710, 'E', 2, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
-CAN_Send_Gcode_2params('M', 710, 'E', 3, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
-CAN_Send_Gcode_2params('M', 710, 'E', 4, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
-CAN_Send_Gcode_2params('M', 710, 'E', 5, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
-CAN_Send_Gcode_2params('M', 710, 'E', 6, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
-CAN_Send_Gcode_2params('M', 710, 'E', 7, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
-CAN_Send_Gcode_2params('M', 710, 'E', 8, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
-CAN_Send_Gcode_2params('M', 710, 'E', 9, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
-CAN_Send_Gcode_2params('M', 710, 'E', 10, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
-CAN_Send_Gcode_2params('M', 710, 'E', 11, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
-*/
- // IRON, M710 SIGNALS TO THE HEAD THAT THE CAN CONFIGURATION IS COMPLETE, USE IT AS THE LAST GCODE TO SEND
- return CAN_Send_Gcode_2params('M', 710, 'E', int(controllerFan.settings.extruder_auto_fan_speed), 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ */
+ #if USE_CONTROLLER_FAN
+ /*
+ CAN_Send_Gcode_2params('M', 710, 'E', 1, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ CAN_Send_Gcode_2params('M', 710, 'E', 2, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ CAN_Send_Gcode_2params('M', 710, 'E', 3, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ CAN_Send_Gcode_2params('M', 710, 'E', 4, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ CAN_Send_Gcode_2params('M', 710, 'E', 5, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ CAN_Send_Gcode_2params('M', 710, 'E', 6, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ CAN_Send_Gcode_2params('M', 710, 'E', 7, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ CAN_Send_Gcode_2params('M', 710, 'E', 8, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ CAN_Send_Gcode_2params('M', 710, 'E', 9, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ CAN_Send_Gcode_2params('M', 710, 'E', 10, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ CAN_Send_Gcode_2params('M', 710, 'E', 11, 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ */
+ // IRON, M710 SIGNALS TO THE HEAD THAT THE CAN CONFIGURATION IS COMPLETE, USE IT AS THE LAST GCODE TO SEND
+ return CAN_Send_Gcode_2params('M', 710, 'E', int(controllerFan.settings.extruder_auto_fan_speed), 'P', int(controllerFan.settings.probing_auto_fan_speed)); // M710 E P
+ #endif
+ return HAL_OK;
}
-void CAN_Idle() // Tasks that cannot be done in the ISR
-{
+void CAN_Idle() { // Tasks that cannot be done in the ISR
if (CAN_head_setup_request) // The head requested the setup data
CAN_Send_Setup();
-
- if (string_message_complete) // Received string message is complete
- {
+
+ if (string_message_complete) { // Received string message is complete
BUZZ(1, SOUND_OK);
SERIAL_ECHOPGM(">>> CAN MSG FROM HEAD: ");
for (uint32_t i = 0; i < string_message_index; i++)
@@ -283,15 +306,13 @@ void CAN_Idle() // Tasks that cannot be done in the ISR
string_message_index = 0;
}
- if ((hcan1.ErrorCode || CAN_head_error || HAL_CAN_error_code) && (millis() - Last_CAN_Error_Message > 6000))
- {
- BUZZ(1, SOUND_ERROR); // Warn with sound
- if (CAN_head_error)
- SERIAL_ECHOLNPGM(">>> CAN ERROR REPORTED BY HEAD");
+ if ((hcan1.ErrorCode || CAN_head_error || HAL_CAN_error_code) && (millis() - Last_CAN_Error_Message > 6000)) {
+ BUZZ(1, SOUND_ERROR);
+ if (CAN_head_error) SERIAL_ECHOLNPGM(">>> CAN Error reported by head");
CAN_head_error = false; // Reset, but will be repeated by the head
if (HAL_CAN_error_code)
- SERIAL_ECHOLNPGM(">>> HAL CAN ERROR REPORTED: ", HAL_CAN_error_code);
+ SERIAL_ECHOLNPGM(">>> HAL CAN Error reported: ", HAL_CAN_error_code);
if (hcan1.ErrorCode)
SERIAL_ECHOLNPGM(">>> hcan1.ErrorCode=", hcan1.ErrorCode);
@@ -299,27 +320,25 @@ void CAN_Idle() // Tasks that cannot be done in the ISR
Last_CAN_Error_Message = millis();
}
- if ((millis() - Last_CAN_Temp_Report) > 10000) // IRON, ERROR, NO TEMP UPDATE RECEIVED IN 10 SECONDS, KILL PRINTER
- {
- Last_CAN_Temp_Report = millis();
- if (FirstE0Error) // Send error notification
- {
+ if (ELAPSED(millis(), Next_CAN_Temp_Report)) { // IRON, ERROR, NO TEMP UPDATE RECEIVED IN 10 SECONDS, KILL PRINTER
+ Next_CAN_Temp_Report = millis() + 10000;
+ if (FirstE0Error) { // Send error notification
BUZZ(1, SOUND_ERROR); // Warn with sound
- SERIAL_ECHOLNPGM("Error: NO CAN E0 TEMP UPDATES!");
+ SERIAL_ECHOLNPGM("Error: No CAN E0 temp updates!");
}
else // Send only error message
- SERIAL_ECHOLNPGM(">>> CAN ERROR, NO E0 TEMP UPDATES!");
+ SERIAL_ECHOLNPGM(">>> CAN ERROR, No E0 temp updates!");
FirstE0Error = false; // Warn only once
- #ifndef IRON_DEBUG // Only kill if not debugging
- kill(F("CAN ERROR, NO E0 TEMPERATURE UPDATES"));
- #endif
+ #ifndef CAN_DEBUG // Only kill if not debugging
+ kill(F("CAN ERROR, NO E0 TEMPERATURE UPDATES"));
+ #endif
}
}
-HAL_StatusTypeDef CAN_Send_Gcode() // Forward a Marlin Gcode via CAN (uses parser.command_letter, Gcode_no, parser.value_float())
-{ // Send a Gcode to the head with parameters and values
+HAL_StatusTypeDef CAN_Send_Gcode() { // Forward a Marlin Gcode via CAN (uses parser.command_letter, Gcode_no, parser.value_float())
+ // Send a Gcode to the head with parameters and values
// Gcode starts with extended frame which can send the Gcode with max 2 parameters and values.
// Extended frames are send to complete all parameters and values (max 2 per extended message).
// 1. Analyze Gcode command
@@ -328,25 +347,25 @@ HAL_StatusTypeDef CAN_Send_Gcode() // Forward a Marlin Gcode via CAN (uses parse
// char s[] = "G0 X123.45678 Y124.45678 Z125.45678 E126.45678 F127.45678\n";
HAL_StatusTypeDef status = HAL_OK;
- uint32_t TxMailbox; // Stores which Mailbox (0-2) is used to store the Sent TX message
-
+ uint32_t TxMailbox; // Stores which Mailbox (0-2) is used to store the Sent TX message
+
if (parser.command_letter != 'M') // Only forward Mxxx Gcode to head
return HAL_OK;
-
+
uint32_t Gcode_type = GCODE_TYPE_M; // M-code, fixed for now
uint32_t Gcode_no = parser.codenum;
if (Gcode_no == 109) // Convert M109(Hotend wait) to M104 (no wait) to keep the head responsive
Gcode_no = 104;
-
+
if ((Gcode_no == 501) || (Gcode_no == 502)) // M501=Restore settings, M502=Factory defaults
CAN_head_setup_request = true; // Also update settings for the head
if ((Gcode_no != 104) && // Set hotend target temp
(Gcode_no != 106) && // Set cooling fan speed
(Gcode_no != 107) && // Cooling fan off
- (Gcode_no != 150) && // Set NeoPixel values
-// (Gcode_no != 108) && // Break and Continue
+ (Gcode_no != 150) && // Set NeoPixel values
+ //(Gcode_no != 108) && // Break and Continue
(Gcode_no != 280) && // Servo position
(Gcode_no != 306) && // MPC settings/tuning
(Gcode_no != 710) && // Control fan PWM
@@ -414,7 +433,7 @@ HAL_StatusTypeDef CAN_Send_Gcode() // Forward a Marlin Gcode via CAN (uses parse
case 510: case 511: case 512: // No locking of the machine
case 605: // No IDEX commands
case 810: case 811: case 812: case 813: case 814: case 815: case 816: case 817: case 818: case 819:
- case 851: //
+ case 851: //
case 871: // No Probe temp config
case 876: // No handle prompt response
case 913: // No Set Hybrid Threshold Speed
@@ -424,7 +443,7 @@ HAL_StatusTypeDef CAN_Send_Gcode() // Forward a Marlin Gcode via CAN (uses parse
return HAL_OK; // NO CAM MESSAGE
}
break;
-
+
case 'T': Gcode_type = GCODE_TYPE_T;
switch (Gcode_no)
{
@@ -432,7 +451,7 @@ HAL_StatusTypeDef CAN_Send_Gcode() // Forward a Marlin Gcode via CAN (uses parse
break;
}
break;
-
+
case 'D': Gcode_type = GCODE_TYPE_D;
switch (Gcode_no)
{
@@ -442,7 +461,7 @@ HAL_StatusTypeDef CAN_Send_Gcode() // Forward a Marlin Gcode via CAN (uses parse
break;
default: return HAL_OK; // Invalid command, nothing to do
}
-*/
+ */
#ifdef CAN_DEBUG
SERIAL_ECHOPGM(">>> CAN GCODE TO HEAD: "); // IRON, DEBUGGING
@@ -451,37 +470,32 @@ HAL_StatusTypeDef CAN_Send_Gcode() // Forward a Marlin Gcode via CAN (uses parse
#endif
if (strlen(parser.command_ptr) > 4) // "M107\0", ONLY SCAN FOR PARAMETERS IF STRING IS LONG ENOUGH
- for (index = 0; index < sizeof(letters); index++) // Scan parameters
- {
- if (parser.seen(letters[index]))
- {
+ for (index = 0; index < sizeof(letters); index++) { // Scan parameters
+ if (parser.seen(letters[index])) {
parameters[parameter_counter] = letters[index] - 64; // Store parameter letter, A=1, B=2...
-
- #ifdef CAN_DEBUG
- SERIAL_CHAR(' ', letters[index]); // IRON, DEBUGGING
- #endif
- if (parser.has_value()) // Check if there is a value
- {
+ #ifdef CAN_DEBUG
+ SERIAL_CHAR(' ', letters[index]); // IRON, DEBUGGING
+ #endif
+
+ if (parser.has_value()) { // Check if there is a value
values[parameter_counter++] = parser.value_float();
- #ifdef CAN_DEBUG
- if (values[parameter_counter - 1] == int(values[parameter_counter - 1]))
- SERIAL_ECHO(i16tostr3left(values[parameter_counter - 1])); // Integer value
- else
- SERIAL_ECHO(p_float_t(values[parameter_counter - 1], 4)); // Float with 4 digits
- #endif
+ #ifdef CAN_DEBUG
+ if (values[parameter_counter - 1] == int(values[parameter_counter - 1]))
+ SERIAL_ECHO(i16tostr3left(values[parameter_counter - 1])); // Integer value
+ else
+ SERIAL_ECHO(p_float_t(values[parameter_counter - 1], 4)); // Float with 4 digits
+ #endif
}
else // No value for parameter
- values[parameter_counter++] = NAN; // Not A Number, indicates no parameter value is present
+ values[parameter_counter++] = NAN; // Not A Number, indicates no parameter value is present
}
-
- if (parameter_counter == 8)
- {
+
+ if (parameter_counter == 8) { // Max 8 parameters
parameter_counter--; // Max is 7 parameters
- SERIAL_ECHOPGM("\nError: TOO MANY PARAMETERS (> 7): ");
- SERIAL_ECHOLN_P(parser.command_ptr);
+ SERIAL_ECHOLNPGM("\nError: TOO MANY PARAMETERS (> 7): ", parser.command_ptr);
BUZZ(1, SOUND_ERROR);
break;
}
@@ -492,13 +506,13 @@ HAL_StatusTypeDef CAN_Send_Gcode() // Forward a Marlin Gcode via CAN (uses parse
parameters[parameter_counter] = 0; // Set next parameter to 0 (0=no parameter), send in pairs
index = 0;
- float * fp = (float *)CAN_tx_buffer; // Points to TX buffer
-
+ float * fp = (float *)CAN_tx_buffer; // Points to TX buffer
+
if ((Gcode_no == 710) && (parameters[0] == 3)) // "M710 C" INDICATES REQUEST FOR GCODE COUNT
SERIAL_ECHOLNPGM(">>> GCODES SENT: ", gcode_counter);
-
- gcode_counter++;
-
+
+ gcode_counter++;
+
TxHeader.IDE = CAN_EXTENDED_ID; // Start with EXTENDED_ID then send STANDARD_ID if needed
//TxHeader.ExtId &= EXTID_FIFO_BIT; // Clear ID, keep FIFO bit
TxHeader.ExtId = (TxHeader.ExtId & EXTID_FIFO_BIT) + // KEEP FIFO BIT
@@ -508,8 +522,7 @@ HAL_StatusTypeDef CAN_Send_Gcode() // Forward a Marlin Gcode via CAN (uses parse
((parameters[1] & PARAMETER_MASK) << PARAMETER2_OFFSET) + // PARAMETER2
((parameters[0] & PARAMETER_MASK) << PARAMETER1_OFFSET); // PARAMETER1
uint32_t ms = millis(); // Record message send start time
- do
- {
+ do {
TxHeader.DLC = MIN(8, (parameter_counter - index) << 2); // Maximum 8 bytes, 4 bytes if there is only 1 parameter, 8 bytes if there are 2
//TxHeader.StdId = (TxHeader.StdId ^ STDID_FIFO_BIT) & STDID_FIFO_BIT; // Toggle FIFO bit 10, clear other bits
TxHeader.StdId = ((TxHeader.StdId ^ STDID_FIFO_BIT) & STDID_FIFO_BIT) + // Toggle FIFO bit
@@ -518,32 +531,29 @@ HAL_StatusTypeDef CAN_Send_Gcode() // Forward a Marlin Gcode via CAN (uses parse
TxHeader.ExtId ^= EXTID_FIFO_BIT; // Toggle FIFO bit 28
*fp++ = values[index++]; // Copy first parameter value to data, move pointer to next 4 bytes
*fp-- = values[index++]; // Copy 2nd parameter value to data, move pointer to beginning of data array for next round
-
+
while ((HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0) && (millis() - ms < 50)) { } // BLOCKING! Wait max 50ms
status = HAL_CAN_AddTxMessage(&hcan1, &TxHeader, CAN_tx_buffer, &TxMailbox); // Send message
if (status != HAL_OK)
return status;
-
+
TxHeader.IDE = CAN_STANDARD_ID; // All following messages have standard ID for parameter values, 11 bits identifier
} while (index < parameter_counter);
-
+
return HAL_OK;
}
-void CAN_Send_Position() // Send the X, Y, Z and E position to the HEAD
-{
+void CAN_Send_Position() { // Send the X, Y, Z and E position to the HEAD
CAN_Send_Gcode_2params('G', 92, 'X', current_position.x, 'Y', current_position.y); // M92 X Y
CAN_Send_Gcode_2params('G', 92, 'Z', current_position.z, 'E', current_position.e); // M92 E Z
}
-void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle) // Called by HAL_CAN_Init
-{
+void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle) { // Called by HAL_CAN_Init
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
- if (canHandle->Instance == CAN1)
- {
+ if (canHandle->Instance == CAN1) {
RCC_PeriphCLKInitTypeDef periphClkInit = { };
HAL_RCCEx_GetPeriphCLKConfig(&periphClkInit);
periphClkInit.PeriphClockSelection |= RCC_APB1ENR_CAN1EN; // DONE IN __HAL_RCC_CAN1_CLK_ENABLE?
@@ -560,7 +570,7 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle) // Called by HAL_CAN_Init
// CAN1 GPIO Configuration
// PB8 ------> CAN1_RX
// PB9 ------> CAN1_TX
-
+
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9; // Pin PB8 and Pin PB9
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
@@ -569,21 +579,19 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle) // Called by HAL_CAN_Init
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // Port B
// CAN1 interrupt Init
- HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 1);
+ HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 1);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn); // Enable CAN FIFO1 interrupt handler
- HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 1, 1);
+ HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 1, 1);
HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn); // Enable CAN FIFO1 interrupt handler
}
}
-HAL_StatusTypeDef CAN1_Stop(void)
-{
+HAL_StatusTypeDef CAN1_Stop() {
return HAL_CAN_Stop(&hcan1);
}
-HAL_StatusTypeDef CAN1_Start(void)
-{
+HAL_StatusTypeDef CAN1_Start() {
HAL_StatusTypeDef status = HAL_OK;
// Init TxHeader with constant values
@@ -601,7 +609,7 @@ HAL_StatusTypeDef CAN1_Start(void)
hcan1.Init.AutoBusOff = DISABLE; // DISABLE: Software controlled Bus-off. ENABLE: Automatic hardware controlled (no send/receive)
hcan1.Init.AutoWakeUp = ENABLE; // ENABLE: Automatic hardware controlled bus wakeup. DISABLE: Software controlled bus wakeup.
hcan1.Init.AutoRetransmission = ENABLE; // DISABLE / ENABLE, resend if transmission failed, but locks up if communication fails/cable not connected!!!!!!!!!!!!!!!!!
- hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; // CAN_SJW_1TQ
+ hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; // CAN_SJW_1TQ
hcan1.Init.TimeSeg1 = CAN_BS1_11TQ; // CAN_BS1_11TQ
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ; // CAN_BS2_2TQ
hcan1.Init.Mode = CAN_MODE_NORMAL; // CAN_MODE_NORMAL / CAN_MODE_SILENT / CAN_MODE_LOOPBACK / CAN_MODE_SILENT_LOOPBACK
@@ -612,7 +620,7 @@ HAL_StatusTypeDef CAN1_Start(void)
status = HAL_CAN_Init(&hcan1); // Calls HAL_CAN_MspInit
if (status != HAL_OK)
return status;
-
+
CAN_FilterTypeDef sFilterConfig;
// Catch CAN messags with highest bit of StdId set in FIFO0
@@ -621,7 +629,7 @@ HAL_StatusTypeDef CAN1_Start(void)
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // CAN_FILTERSCALE_16BIT / CAN_FILTERSCALE_32BIT (See Figure 342 in RM0090)
sFilterConfig.FilterIdHigh = 0b1000000000000000; // ID MSB: (0-0xFFFF) (StdId[10-0] [ExtId17-13]) (See Figure 342 in RM0090)
sFilterConfig.FilterIdLow = 0; // ID LSB: (0-0xFFFF) ([ExtId12-0][IDE][RTR] 0) (0="don't care")
- sFilterConfig.FilterMaskIdHigh = 0b1000000000000000; // Mask MSB: (0-0xFFFF) (StdId[10-0] [ExtId17-13]) (See Figure 342 in RM0090)
+ sFilterConfig.FilterMaskIdHigh = 0b1000000000000000; // Mask MSB: (0-0xFFFF) (StdId[10-0] [ExtId17-13]) (See Figure 342 in RM0090)
sFilterConfig.FilterMaskIdLow = 0; // Mask LSB: (0-0xFFFF) ([ExtId12-0][IDE][RTR] 0) (0="don't care")
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; // Store message in FIFO1 (CAN_FILTER_FIFO0 / CAN_FILTER_FIFO1)
sFilterConfig.FilterActivation = CAN_FILTER_ENABLE; // CAN_FILTER_ENABLE / CAN_FILTER_DISABLE
@@ -634,7 +642,7 @@ HAL_StatusTypeDef CAN1_Start(void)
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // CAN_FILTERSCALE_16BIT / CAN_FILTERSCALE_32BIT (See Figure 342 in RM0090)
sFilterConfig.FilterIdHigh = 0b0000; // ID MSB: (0-0xFFFF) (StdId[10-0] [ExtId17-13]) (See Figure 342 in RM0090)
sFilterConfig.FilterIdLow = 0x0000; // ID LSB: (0-0xFFFF) ([ExtId12-0][IDE][RTR] 0) (0="don't care")
- sFilterConfig.FilterMaskIdHigh = 0b0000; // Mask MSB: (0-0xFFFF) (StdId[10-0] [ExtId17-13]) (See Figure 342 in RM0090)
+ sFilterConfig.FilterMaskIdHigh = 0b0000; // Mask MSB: (0-0xFFFF) (StdId[10-0] [ExtId17-13]) (See Figure 342 in RM0090)
sFilterConfig.FilterMaskIdLow = 0x0000; // Mask LSB: (0-0xFFFF) ([ExtId12-0][IDE][RTR] 0) (0="don't care")
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO1; // Store message in FIFO0 (CAN_FILTER_FIFO0 / CAN_FILTER_FIFO1)
sFilterConfig.FilterActivation = CAN_FILTER_ENABLE; // CAN_FILTER_ENABLE / CAN_FILTER_DISABLE
@@ -644,10 +652,10 @@ HAL_StatusTypeDef CAN1_Start(void)
// Activate RX FIFO0/FIFO1 new message interrupt
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING); // Calls CAN1_RX0_IRQHandler -> HAL_CAN_IRQHandler -> HAL_CAN_RxFifo0MsgPendingCallback
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_MSG_PENDING); // Calls CAN1_RX1_IRQHandler -> HAL_CAN_IRQHandler -> HAL_CAN_RxFifo1MsgPendingCallback
-
+
// Activate RX FIFO0/FIFO1 overrun interrupt
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_OVERRUN); // Calls CAN1_RX0_IRQHandler -> HAL_CAN_ErrorCallback
- HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_OVERRUN); // Calls CAN1_RX1_IRQHandler -> HAL_CAN_ErrorCallback
+ HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_OVERRUN); // Calls CAN1_RX1_IRQHandler -> HAL_CAN_ErrorCallback
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_ERROR); // Calls CAN1_RX0_IRQHandler -> HAL_CAN_ErrorCallback
@@ -658,39 +666,31 @@ HAL_StatusTypeDef CAN1_Start(void)
return CAN_Send_Gcode_2params('M', 997, 0, 0, 0, 0); // M997, reset head at host startup
}
-void HAL_CAN_RxFifoMsgPending(CAN_HandleTypeDef *hcan, uint32_t RxFifo) // ISR! New FIFO 0/1 message interrupt handler
-{
+void HAL_CAN_RxFifoMsgPending(CAN_HandleTypeDef *hcan, uint32_t RxFifo) { // ISR! New FIFO 0/1 message interrupt handler
CAN_RxHeaderTypeDef RxHeader; // RX Header buffer for FIFO0
uint8_t CAN_RX_buffer_Fifo[8]; // CAN MESSAGE DATA BUFFER
- if (HAL_CAN_GetRxMessage(&hcan1, RxFifo, &RxHeader, CAN_RX_buffer_Fifo) == HAL_OK) // Get message from CAN_RX_FIFO0
- {
- if ((RxHeader.StdId & CAN_IO_MASK) != CAN_io_state) // First handle time critical IO update
- {
+ if (HAL_CAN_GetRxMessage(&hcan1, RxFifo, &RxHeader, CAN_RX_buffer_Fifo) == HAL_OK) { // Get message from CAN_RX_FIFO0
+ if ((RxHeader.StdId & CAN_IO_MASK) != CAN_io_state) { // First handle time critical IO update
CAN_io_state = (RxHeader.StdId & CAN_IO_MASK);
endstops.update();
}
- if (RxHeader.StdId & CAN_STRING_MESSAGE_MASK) // Head sends a string message
- {
+ if (RxHeader.StdId & CAN_STRING_MESSAGE_MASK) { // Head sends a string message
char * CAN_RX_p = (char *)CAN_RX_buffer_Fifo;
- for (uint32_t i = 0; i < RxHeader.DLC; i++)
- {
+ for (uint32_t i = 0; i < RxHeader.DLC; i++) {
string_message[string_message_index++ % 128] = CAN_RX_p[i]; // Copy message to global buffer
-
- if (CAN_RX_p[i] == '\n')
- {
+
+ if (CAN_RX_p[i] == '\n') {
string_message_complete = true; // Print buffer
string_message[string_message_index % 128] = 0; // Close string with \0
}
}
}
- else
- if (RxHeader.DLC == 4) // FIFO0, head sent a temperature update (DLC = Data Length Code == 4 bytes)
- {
+ else if (RxHeader.DLC == 4) { // FIFO0, head sent a temperature update (DLC = Data Length Code == 4 bytes)
float * fp = (float *)CAN_RX_buffer_Fifo; // FIFO0
thermalManager.temp_hotend[0].celsius = *fp; // Set E0 hotend temperature
- Last_CAN_Temp_Report = millis();
+ Next_CAN_Temp_Report = millis() + 10000;
FirstE0Error = true; // Reset error status
}
@@ -699,18 +699,15 @@ void HAL_CAN_RxFifoMsgPending(CAN_HandleTypeDef *hcan, uint32_t RxFifo) // ISR!
}
}
-void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) // ISR! New FIFO0 message interrupt handler
-{
- HAL_CAN_RxFifoMsgPending(hcan, CAN_RX_FIFO0);
+void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { // ISR! New FIFO0 message interrupt handler
+ HAL_CAN_RxFifoMsgPending(hcan, CAN_RX_FIFO0);
}
-void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) // ISR! New FIFO1 message interrupt handler
-{
- HAL_CAN_RxFifoMsgPending(hcan, CAN_RX_FIFO1);
+void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) { // ISR! New FIFO1 message interrupt handler
+ HAL_CAN_RxFifoMsgPending(hcan, CAN_RX_FIFO1);
}
-void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) // Interrupt handler for any CAN error
-{
+void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { // Interrupt handler for any CAN error
HAL_CAN_error_code = hcan->ErrorCode; // Store the received error code
}
@@ -749,4 +746,4 @@ CAN WEAK CALLBACKS WHEN USING STANDARD WEAK CAN1_RX0_IRQHandler------------> INT
__weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) // CAN_IT_ERROR
*/
-#endif // CAN_MASTER
\ No newline at end of file
+#endif // CAN_MASTER
diff --git a/Marlin/src/HAL/STM32/CAN.h b/Marlin/src/HAL/STM32/CAN.h
deleted file mode 100644
index 32dc76a2ec21..000000000000
--- a/Marlin/src/HAL/STM32/CAN.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-
-#include "../../inc/MarlinConfig.h"
-
-#ifdef CAN_MASTER
-
- extern uint32_t CAN_io_state; // CAN virtual IO variable
-
- #define CAN_IO_MASK 0b11111 // Masks for the 5 virtual IO bits
- #define CAN_PROBE_MASK 1 // Virtual IO bit
- #define CAN_FILAMENT_MASK 2 // Virtual IO bit
- #define CAN_X_ENDSTOP_MASK 4 // Virtual IO bit
- #define CAN_Y_ENDSTOP_MASK 8 // Virtual IO bit
- #define CAN_Z_ENDSTOP_MAS 16 // Virtual IO bit
- #define CAN_STRING_MESSAGE_MASK 32 // Signals the head sends a string message
- #define CAN_REQUEST_SETUP_MASK 64 // Signals the head requests setup information
- #define CAN_TMC_OT_MASK 128 // Signals the head signals a TMC Over Temp error
- #define CAN_E0_TARGET_MASK 256 // Signals E0 or E1
- #define CAN_ERROR_MASK 512 // Signals the head encountered an error
-
- HAL_StatusTypeDef CAN1_Start(void); // FUNCTION PROTOTYPES
- HAL_StatusTypeDef CAN1_Stop(void);
- HAL_StatusTypeDef CAN_Send_Gcode(void);
- HAL_StatusTypeDef CAN_Send_Gcode_2params(uint32_t Gcode_type, uint32_t Gcode_no, uint32_t parameter1, float value1, uint32_t parameter2, float value2);
- void CAN_Send_Setup(); // Send host configuration to head
- void CAN_Idle(); // Idle CAN task
-
-#endif // CAN_MASTER
\ No newline at end of file
diff --git a/Marlin/src/HAL/STM32/Servo.cpp b/Marlin/src/HAL/STM32/Servo.cpp
index dc6888ff9d11..5ef3e62f1c6a 100644
--- a/Marlin/src/HAL/STM32/Servo.cpp
+++ b/Marlin/src/HAL/STM32/Servo.cpp
@@ -29,6 +29,10 @@
#include "Servo.h"
+#if ENABLED(CAN_MASTER)
+ #include "../shared/CAN.h"
+#endif
+
static uint_fast8_t servoCount = 0;
static libServo *servos[NUM_SERVOS] = {0};
constexpr millis_t servoDelay[] = SERVO_DELAY;
@@ -72,19 +76,16 @@ int8_t libServo::attach(const int pin, const int min, const int max) {
void libServo::move(const int value) {
-#ifdef CAN_MASTER // IRON, FORWARD UNDERWATER SERVO COMMAND TO HEAD
- int angles[2] = Z_SERVO_ANGLES;
-
- // Translate M280 S10 to M401, M280 S90 to M402
- HAL_StatusTypeDef CAN_Send_Gcode_2params(uint32_t Gcode_type, uint32_t Gcode_no, uint32_t parameter1, float value1, uint32_t parameter2, float value2); // PROTOTYPE
- if (value == angles[0]) // Deploy angle
- CAN_Send_Gcode_2params('M', 401, 0, 0, 0, 0); // IRON, send "M401" instead, enables interrupt etc.
- else
- if (value == angles[1]) // Stow angle
- CAN_Send_Gcode_2params('M', 402, 0, 0, 0, 0); // IRON, send "M401" instead, enables interrupt etc.
- else
- CAN_Send_Gcode_2params('M', 280, 'S', value, 'P', 0); // M280 S[value] P0
-#endif // IRON
+ #if ENABLED(CAN_MASTER) // Forward direct Servo command to head
+ constexpr int angles[2] = Z_SERVO_ANGLES;
+ // Translate M280 S10 to M401, M280 S90 to M402
+ if (value == angles[0])
+ CAN_Send_Gcode_2params('M', 401, 0, 0, 0, 0); // Deploy Angle: Send "M401" instead, enables interrupt etc.
+ else if (value == angles[1])
+ CAN_Send_Gcode_2params('M', 402, 0, 0, 0, 0); // Stow Angle: Send "M402" instead, enables interrupt etc.
+ else
+ CAN_Send_Gcode_2params('M', 280, 'S', value, 'P', 0); // M280 S[value] P0
+ #endif
if (attach(0) >= 0) {
stm32_servo.write(value);
diff --git a/Marlin/src/HAL/shared/CAN.h b/Marlin/src/HAL/shared/CAN.h
new file mode 100644
index 000000000000..c8e410241293
--- /dev/null
+++ b/Marlin/src/HAL/shared/CAN.h
@@ -0,0 +1,50 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2024 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
+
+#include "../../inc/MarlinConfigPre.h"
+
+//#define CAN_DEBUG // Define to show gcodes send to HEAD
+
+#define SOUND_OK 880
+#define SOUND_ERROR 40
+
+extern uint32_t CAN_io_state; // CAN virtual IO variable
+
+#define CAN_IO_MASK 0b11111 // Masks for the 5 virtual IO bits
+#define CAN_PROBE_MASK 1 // Virtual IO bit
+#define CAN_FILAMENT_MASK 2 // Virtual IO bit
+#define CAN_X_ENDSTOP_MASK 4 // Virtual IO bit
+#define CAN_Y_ENDSTOP_MASK 8 // Virtual IO bit
+#define CAN_Z_ENDSTOP_MAS 16 // Virtual IO bit
+#define CAN_STRING_MESSAGE_MASK 32 // Signals the head sends a string message
+#define CAN_REQUEST_SETUP_MASK 64 // Signals the head requests setup information
+#define CAN_TMC_OT_MASK 128 // Signals the head signals a TMC Over Temp error
+#define CAN_E0_TARGET_MASK 256 // Signals E0 or E1
+#define CAN_ERROR_MASK 512 // Signals the head encountered an error
+
+HAL_StatusTypeDef CAN1_Start(); // FUNCTION PROTOTYPES
+HAL_StatusTypeDef CAN1_Stop();
+HAL_StatusTypeDef CAN_Send_Gcode();
+HAL_StatusTypeDef CAN_Send_Gcode_2params(uint32_t Gcode_type, uint32_t Gcode_no, uint32_t parameter1, float value1, uint32_t parameter2, float value2);
+void CAN_Send_Setup(); // Send host configuration to head
+void CAN_Idle(); // Idle CAN task
diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp
index 3b73fd8b5014..d04600383323 100644
--- a/Marlin/src/MarlinCore.cpp
+++ b/Marlin/src/MarlinCore.cpp
@@ -34,8 +34,8 @@
#include "HAL/shared/esp_wifi.h"
#include "HAL/shared/cpu_exception/exception_hook.h"
-#ifdef CAN_MASTER // IRON, ADDED
- #include HAL_PATH(., CAN.h)
+#if ENABLED(CAN_MASTER)
+ #include "HAL/shared/CAN.h"
#endif
#if ENABLED(WIFISUPPORT)
@@ -1194,14 +1194,15 @@ void setup() {
while (!MYSERIAL3.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
#endif
#endif
- SERIAL_ECHOLNPGM("\nstart\n"); // IRON, ADDED \n
-#ifdef CAN_MASTER // IRON, REPORT CAN START STATUS
- if (CAN1_Start() == HAL_OK)
- SERIAL_ECHOLNPGM(">>> CAN1 Start: OK");
- else
- SERIAL_ECHOLNPGM(">>> CAN1 Start: FAILED!");
-#endif
+ SERIAL_ECHOLNPGM(TERN(CAN_MASTER, "\nstart\n", "start"));
+
+ #if ENABLED(CAN_MASTER)
+ SERIAL_ECHOLN(
+ F(">>> CAN1 Start: "),
+ CAN1_Start() == HAL_OK ? F("OK") : F("FAILED!")
+ );
+ #endif
// Set up these pins early to prevent suicide
#if HAS_KILL
diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp
index 3af6b59709e4..3589847761c5 100644
--- a/Marlin/src/feature/pause.cpp
+++ b/Marlin/src/feature/pause.cpp
@@ -225,13 +225,8 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
switch (active_extruder) {
REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_INSERTED)
}
- #else
- #ifdef CAN_MASTER // IRON, USE VIRTUAL CAN FILAMENT RUNOUT STATUS
- if ((!!(CAN_io_state & CAN_FILAMENT_MASK)) != FIL_RUNOUT_STATE)
- wait_for_user = false;
#else
if (!FILAMENT_IS_OUT()) wait_for_user = false;
- #endif // IRON
#endif
#endif
idle_no_sleep();
diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h
index 8ecb94a21b7f..8cbad8e61eb2 100644
--- a/Marlin/src/feature/runout.h
+++ b/Marlin/src/feature/runout.h
@@ -33,8 +33,8 @@
#include "pause.h" // for did_pause_print
#include "../MarlinCore.h" // for printingIsActive()
-#ifdef CAN_MASTER // IRON, ADDED
- #include HAL_PATH(.., CAN.h)
+#if ENABLED(CAN_MASTER)
+ #include "../HAL/shared/CAN.h"
#endif
#include "../inc/MarlinConfig.h"
@@ -57,6 +57,12 @@
#define FILAMENT_IS_OUT() (READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_STATE)
+#if ENABLED(CAN_MASTER)
+ #define RUNOUT_STATE(N) bool(CAN_io_state & CAN_FILAMENT_MASK) // CAN Virtual Filament Runout pin
+#else
+ #define RUNOUT_STATE(N) READ(FIL_RUNOUT##N##_PIN) // DIO Filament Runout pin
+#endif
+
typedef Flags<
#if NUM_MOTION_SENSORS > NUM_RUNOUT_SENSORS
NUM_MOTION_SENSORS
@@ -211,13 +217,7 @@ class FilamentSensorBase {
// Return a bitmask of runout pin states
static uint8_t poll_runout_pins() {
-
-#ifdef CAN_MASTER // IRON, VIRTUAL FILAMENT RUNOUT PIN
- #define _OR_RUNOUT(N) | ((CAN_io_state & CAN_FILAMENT_MASK) ? _BV((N) - 1) : 0)
-#else
- #define _OR_RUNOUT(N) | (READ(FIL_RUNOUT##N##_PIN) ? _BV((N) - 1) : 0)
-#endif // IRON
-
+ #define _OR_RUNOUT(N) | (RUNOUT_STATE(N) ? _BV((N) - 1) : 0)
return (0 REPEAT_1(NUM_RUNOUT_SENSORS, _OR_RUNOUT));
#undef _OR_RUNOUT
}
diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp
index 53d84ac27cb4..3744a384886b 100644
--- a/Marlin/src/gcode/gcode.cpp
+++ b/Marlin/src/gcode/gcode.cpp
@@ -28,10 +28,6 @@
#include "gcode.h"
GcodeSuite gcode;
-#ifdef CAN_MASTER // IRON
- #include HAL_PATH(.., CAN.h)
-#endif
-
#if ENABLED(WIFI_CUSTOM_COMMAND)
extern bool wifi_custom_command(char * const command_ptr);
#endif
@@ -73,6 +69,11 @@ GcodeSuite gcode;
#include "../feature/fancheck.h"
#endif
+#if ENABLED(CAN_MASTER)
+ #include "../HAL/shared/CAN.h"
+ #include "../libs/buzzer.h"
+#endif
+
#include "../MarlinCore.h" // for idle, kill
// Inactivity shutdown
@@ -327,16 +328,14 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
KEEPALIVE_STATE(IN_HANDLER);
-#ifdef CAN_MASTER
- if (CAN_Send_Gcode() != HAL_OK) // IRON, SEND COMMAND TO HEAD
- {
- SERIAL_ECHOPGM("Error: FAILED TO SEND GCODE CAN COMMAND TO HEAD: ");
- SERIAL_ECHOLN_P(parser.command_ptr);
- #ifndef IRON_DEBUG
- BUZZ(1, SOUND_ERROR);
+ #if ENABLED(CAN_MASTER)
+ if (CAN_Send_Gcode() != HAL_OK) { // Send command to head
+ SERIAL_ECHOLN(F("Error: CAN failed to send \""), parser.command_ptr, '"');
+ #ifndef CAN_DEBUG
+ BUZZ(1, SOUND_ERROR);
+ #endif
+ }
#endif
- }
-#endif // IRON
/**
* Block all Gcodes except M511 Unlock Printer, if printer is locked
diff --git a/Marlin/src/gcode/temp/M306.cpp b/Marlin/src/gcode/temp/M306.cpp
index 57ed2518ff9e..4b4b69c287dc 100644
--- a/Marlin/src/gcode/temp/M306.cpp
+++ b/Marlin/src/gcode/temp/M306.cpp
@@ -27,7 +27,6 @@
#include "../gcode.h"
#include "../../lcd/marlinui.h"
#include "../../module/temperature.h"
-#include "../../libs/numtostr.h" // IRON, ADDED
/**
* M306: MPC settings and autotune
@@ -59,23 +58,30 @@ void GcodeSuite::M306() {
#if ENABLED(MPC_AUTOTUNE)
if (parser.seen_test('T')) {
-#ifdef CAN_MASTER // IRON, MPC AUTOTUNE INFO
- SERIAL_ECHOLNPGM(">>> Forwarding M306 to head board");
- SERIAL_ECHOLNPGM(">>> Store MPC setup in the host Configuration.h or use M500");
- SERIAL_ECHOLNPGM(">>> MPC heater power is: ", ftostr31ns(MPC_HEATER_POWER), " Watt");
- SERIAL_ECHOLNPGM(">>> Please wait for the auto tune results...");
-#else
- Temperature::MPCTuningType tuning_type;
- const uint8_t type = parser.byteval('S', 0);
- switch (type) {
- case 1: tuning_type = Temperature::MPCTuningType::FORCE_DIFFERENTIAL; break;
- case 2: tuning_type = Temperature::MPCTuningType::FORCE_ASYMPTOTIC; break;
- default: tuning_type = Temperature::MPCTuningType::AUTO; break;
- }
- LCD_MESSAGE(MSG_MPC_AUTOTUNE);
- thermalManager.MPC_autotune(e, tuning_type);
- ui.reset_status();
-#endif // IRON
+ #if ENABLED(CAN_MASTER) // MPC Autotune info
+
+ SERIAL_ECHOLNPGM(
+ ">>> Forwarding M306 to head board\n"
+ ">>> Store MPC setup in the host Configuration.h or use M500\n"
+ ">>> MPC heater power is: ", p_float_t(MPC_HEATER_POWER, 1), " Watts\n"
+ ">>> Please wait for the auto tune results..."
+ );
+
+ #else
+
+ Temperature::MPCTuningType tuning_type;
+ const uint8_t type = parser.byteval('S', 0);
+ switch (type) {
+ case 1: tuning_type = Temperature::MPCTuningType::FORCE_DIFFERENTIAL; break;
+ case 2: tuning_type = Temperature::MPCTuningType::FORCE_ASYMPTOTIC; break;
+ default: tuning_type = Temperature::MPCTuningType::AUTO; break;
+ }
+ LCD_MESSAGE(MSG_MPC_AUTOTUNE);
+ thermalManager.MPC_autotune(e, tuning_type);
+ ui.reset_status();
+
+ #endif
+
return;
}
#endif
@@ -101,11 +107,10 @@ void GcodeSuite::M306_report(const bool forReplay/*=true*/) {
report_heading(forReplay, F("Model predictive control"));
-#ifdef CAN_MASTER // IRON, MPC AUTOTUNE INFO
- if (forReplay)
- SERIAL_ECHOLNPGM(">>> HOST M306 MPC SETTINGS:");
-#endif
-
+ #if ENABLED(CAN_MASTER) // MPC Autotune info
+ if (forReplay) SERIAL_ECHOLNPGM(">>> Host M306 MPC settings:");
+ #endif
+
HOTEND_LOOP() {
report_echo_start(forReplay);
MPC_t &mpc = thermalManager.temp_hotend[e].mpc;
diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp
index 5ce8f43b3551..dcb10c014edd 100644
--- a/Marlin/src/module/endstops.cpp
+++ b/Marlin/src/module/endstops.cpp
@@ -58,6 +58,10 @@
#include "probe.h"
#endif
+#if HAS_FILAMENT_SENSOR && !MULTI_FILAMENT_SENSOR
+ #include "../feature/runout.h"
+#endif
+
#define DEBUG_OUT ALL(USE_SENSORLESS, DEBUG_LEVELING_FEATURE)
#include "../core/debug_out.h"
@@ -77,14 +81,14 @@ Endstops::endstop_mask_t Endstops::live_state = 0;
#else
#define READ_ENDSTOP(P) READ(P)
#endif
-#else
-
-#ifdef CAN_MASTER // IRON, READ VIRTUAL CAN IO PROBE STATUS IF NEEDED
- #define READ_ENDSTOP(P) ((P == Z_MIN_PIN) ? ((CAN_io_state & CAN_PROBE_MASK)) : READ(P))
+#elif ENABLED(CAN_MASTER) // Read virtual CAN IO Probe status if needed
+ #if HAS_BED_PROBE
+ #define READ_ENDSTOP(P) ((P == Z_MIN_PIN) ? PROBE_READ() : READ(P))
+ #else
+ #define READ_ENDSTOP(P) READ(P)
+ #endif
#else
#define READ_ENDSTOP(P) READ(P)
-#endif // IRON, ADDED
-
#endif
#if ENDSTOP_NOISE_THRESHOLD
@@ -531,13 +535,10 @@ void __O2 Endstops::report_states() {
print_es_state(extDigitalRead(pin) != state);
}
#undef _CASE_RUNOUT
+
#elif HAS_FILAMENT_SENSOR
- #ifdef CAN_MASTER // IRON
- print_es_state((!!(CAN_io_state & CAN_FILAMENT_MASK)) != FIL_RUNOUT1_STATE, F(STR_FILAMENT));
- #else
- print_es_state(READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE, F(STR_FILAMENT));
- #endif // IRON
+ print_es_state(RUNOUT_STATE(1) != FIL_RUNOUT1_STATE, F(STR_FILAMENT));
#endif
diff --git a/Marlin/src/module/probe.h b/Marlin/src/module/probe.h
index e849a28324f5..41d59bb91afb 100644
--- a/Marlin/src/module/probe.h
+++ b/Marlin/src/module/probe.h
@@ -29,8 +29,8 @@
#include "motion.h"
-#ifdef CAN_MASTER // IRON
- #include HAL_PATH(.., CAN.h)
+#if ENABLED(CAN_MASTER)
+ #include "../HAL/shared/CAN.h"
#endif
#if ENABLED(BLTOUCH)
@@ -51,23 +51,13 @@
#if ENABLED(BD_SENSOR)
#define PROBE_READ() bdp_state
+#elif ENABLED(CAN_MASTER)
+ #define PROBE_READ() bool(CAN_io_state & CAN_PROBE_MASK)
#elif USE_Z_MIN_PROBE
-
- #ifdef CAN_MASTER
- #define PROBE_READ() ((CAN_io_state & CAN_PROBE_MASK)) // IRON, READ VIRTUAL IO
- #else
- #define PROBE_READ() READ(Z_MIN_PROBE_PIN)
- #endif // IRON
-
+ #define PROBE_READ() READ(Z_MIN_PROBE_PIN)
#else
-
- #ifdef CAN_MASTER // IRON, VIRTUAL IO
- #define PROBE_READ() ((CAN_io_state & CAN_PROBE_BIT)) // IRON, READ VIRTUAL IO
- #else
- #define PROBE_READ() READ(Z_MIN_PIN)
- #endif
-
-#endif // IRON
+ #define PROBE_READ() READ(Z_MIN_PIN)
+#endif
#if USE_Z_MIN_PROBE
#define PROBE_HIT_STATE Z_MIN_PROBE_ENDSTOP_HIT_STATE
diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp
index 1f78f4f9ffb5..fa984176d8a5 100644
--- a/Marlin/src/module/temperature.cpp
+++ b/Marlin/src/module/temperature.cpp
@@ -50,6 +50,10 @@
#include "motion.h"
#endif
+#if ENABLED(CAN_MASTER)
+ #include "../HAL/shared/CAN.h"
+#endif
+
#if ENABLED(DWIN_CREALITY_LCD)
#include "../lcd/e3v2/creality/dwin.h"
#elif ENABLED(SOVOL_SV06_RTS)
@@ -2734,11 +2738,9 @@ void Temperature::updateTemperaturesFromRawValues() {
temp_bed.setraw(read_max_tc_bed());
#endif
-#ifndef CAN_MASTER // IRON, NOT FOR MASTER, DON'T READ TEMPERATURE FROM SENSOR, GET IT VIA CAN BUS FROM HEAD
- #if HAS_HOTEND
+ #if HAS_HOTEND && DISABLED(CAN_MASTER) // For CAN Master we'll get temperature from CAN bus
HOTEND_LOOP() temp_hotend[e].celsius = analog_to_celsius_hotend(temp_hotend[e].getraw(), e);
#endif
-#endif // IRON
TERN_(HAS_HEATED_BED, temp_bed.celsius = analog_to_celsius_bed(temp_bed.getraw()));
TERN_(HAS_TEMP_CHAMBER, temp_chamber.celsius = analog_to_celsius_chamber(temp_chamber.getraw()));
@@ -2751,9 +2753,7 @@ void Temperature::updateTemperaturesFromRawValues() {
TERN_(FILAMENT_WIDTH_SENSOR, filwidth.update_measured_mm());
TERN_(HAS_POWER_MONITOR, power_monitor.capture_values());
- #if HAS_HOTEND
-
-#ifndef CAN_MASTER // IRON, ONLY FOR HEAD, NO TEMP SAMPLING ON MASTER
+ #if HAS_HOTEND && DISABLED(CAN_MASTER) // Only for Head, no temp sampling on Master
#define _TEMPDIR(N) TEMP_SENSOR_IS_ANY_MAX_TC(N) ? 0 : TEMPDIR(N),
static constexpr int8_t temp_dir[HOTENDS] = { REPEAT(HOTENDS, _TEMPDIR) };
@@ -2780,9 +2780,8 @@ void Temperature::updateTemperaturesFromRawValues() {
TERN_(MULTI_MAX_CONSECUTIVE_LOW_TEMP_ERR, consecutive_low_temperature_error[e] = 0);
}
}
-#endif // IRON, !CAN_MASTER
- #endif // HAS_HOTEND
+ #endif // HAS_HOTEND && !CAN_MASTER
#if ENABLED(THERMAL_PROTECTION_BED)
if (TP_CMP(BED, temp_bed.getraw(), temp_sensor_range_bed.raw_max))
@@ -3382,16 +3381,17 @@ void Temperature::disable_all_heaters() {
#if HAS_HOTEND
-#ifdef CAN_MASTER // IRON, SHUTDOWN HOTEND IN HEAD TOO
- CAN_Send_Gcode_2params('M', 104, 'S', 0, 0, 0); // IRON, M104 S0, switch off hotend heating
- CAN_Send_Gcode_2params('M', 107, 0, 0, 0, 0); // IRON, M107, switch off part cooling fan
- CAN_Send_Gcode_2params('M', 150, 'R', 255, 0, 0); // IRON, M150 R255, SET NEOPIXEL TO RED
-#endif
+ #if ENABLED(CAN_MASTER) // Shut down the hotend in the head too
+ CAN_Send_Gcode_2params('M', 104, 'S', 0, 0, 0); // M104 S0 .... Switch off hotend heating
+ CAN_Send_Gcode_2params('M', 107, 0, 0, 0, 0); // M107 ....... Switch off part cooling fan
+ CAN_Send_Gcode_2params('M', 150, 'R', 255, 0, 0); // M150 R255 .. Set NeoPixel to red
+ #endif
HOTEND_LOOP() {
setTargetHotend(0, e);
temp_hotend[e].soft_pwm_amount = 0;
}
+
#endif
#if HAS_TEMP_HOTEND
diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h
index eb26103380c1..f9b0ee25235a 100644
--- a/Marlin/src/pins/pins.h
+++ b/Marlin/src/pins/pins.h
@@ -800,7 +800,7 @@
#elif MB(MKS_MONSTER8_V1)
#include "stm32f4/pins_MKS_MONSTER8_V1.h" // STM32F4 env:mks_monster8 env:mks_monster8_usb_flash_drive env:mks_monster8_usb_flash_drive_msc
#elif MB(MKS_MONSTER8_V2)
- #include "stm32f4/pins_MKS_MONSTER8_V2.h" // STM32F4 env:mks_monster8 env:mks_monster8_usb_flash_drive env:mks_monster8_usb_flash_drive_msc
+ #include "stm32f4/pins_MKS_MONSTER8_V2.h" // STM32F4 env:mks_monster8 env:mks_monster8_usb_flash_drive env:mks_monster8_usb_flash_drive_msc env:mks_monster8_usb_flash_drive_msc_CAN
#elif MB(ANET_ET4)
#include "stm32f4/pins_ANET_ET4.h" // STM32F4 env:Anet_ET4_no_bootloader env:Anet_ET4_OpenBLT
#elif MB(ANET_ET4P)
diff --git a/Marlin/src/pins/stm32g0/pins_BTT_EBB42_V1_1.h b/Marlin/src/pins/stm32g0/pins_BTT_EBB42_V1_1.h
index 2d6cdb73f43c..fef28f3f3682 100644
--- a/Marlin/src/pins/stm32g0/pins_BTT_EBB42_V1_1.h
+++ b/Marlin/src/pins/stm32g0/pins_BTT_EBB42_V1_1.h
@@ -27,7 +27,7 @@
* This board definition is to facilitate support for a Filament Extrusion
* devices, used to convert waste plastic into 3D printable filament.
* This board is NOT a general 3D printing controller; it is NOT supported
- * as a toolboard via CANBUS (as it was originally designed) or any device
+ * as a toolboard via CAN bus (as it was originally designed) or any device
* that requires kinematics.
*/
diff --git a/ini/stm32f4.ini b/ini/stm32f4.ini
index b90b46ae7375..fbe68125092c 100644
--- a/ini/stm32f4.ini
+++ b/ini/stm32f4.ini
@@ -619,6 +619,7 @@ build_flags = ${stm_flash_drive.build_flags} ${stm32f4_I2C1_CAN.build_flag
extends = env:mks_monster8_usb_flash_drive
build_flags = ${env:mks_monster8_usb_flash_drive.build_flags}
-DUSBD_USE_CDC_MSC
+
[env:mks_monster8_usb_flash_drive_msc_CAN]
extends = env:mks_monster8_usb_flash_drive
build_flags = ${env:mks_monster8_usb_flash_drive.build_flags}
diff --git a/platformio.ini b/platformio.ini
index 88e468c49e28..ed1670dc6daf 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -13,7 +13,7 @@
[platformio]
src_dir = Marlin
boards_dir = buildroot/share/PlatformIO/boards
-default_envs = #define MOTHERBOARD BOARD_MKS_MONSTER8_V2
+default_envs = mega2560
include_dir = Marlin
extra_configs =
Marlin/config.ini