From 6aa536c08f444daaf7e3aad125ab9ff225515e2b Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Wed, 19 Oct 2022 00:33:17 +0000 Subject: [PATCH 01/24] [cron] Bump distribution date (2022-10-19) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index f8efc0c0e8..794d5def4c 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2022-10-18" +//#define STRING_DISTRIBUTION_DATE "2022-10-19" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index ae9c65955e..b348d0cfac 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2022-10-18" + #define STRING_DISTRIBUTION_DATE "2022-10-19" #endif /** From e49c3dc0889f1a6b597701ceb69624bdf4365445 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 19 Oct 2022 00:45:35 -0500 Subject: [PATCH 02/24] =?UTF-8?q?=F0=9F=A9=B9=20Polargraph=20followup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix issue from #24847 --- Marlin/src/module/settings.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index 95836a5f3a..cb8fe217e9 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -319,7 +319,7 @@ typedef struct SettingsDataStruct { #endif // - // Kinematic Settings + // Kinematic Settings (Delta, SCARA, TPARA, Polargraph...) // #if IS_KINEMATIC float segments_per_second; // M665 S @@ -992,7 +992,7 @@ void MarlinSettings::postprocess() { } // - // Kinematic Settings + // Kinematic Settings (Delta, SCARA, TPARA, Polargraph...) // #if IS_KINEMATIC { @@ -1444,14 +1444,6 @@ void MarlinSettings::postprocess() { _FIELD_TEST(planner_skew_factor); EEPROM_WRITE(planner.skew_factor); - // - // POLARGRAPH - // - #if ENABLED(POLARGRAPH) - _FIELD_TEST(polargraph_max_belt_len); - EEPROM_WRITE(polargraph_max_belt_len); - #endif - // // Advanced Pause filament load & unload lengths // @@ -1940,7 +1932,7 @@ void MarlinSettings::postprocess() { } // - // Kinematic Segments-per-second + // Kinematic Settings (Delta, SCARA, TPARA, Polargraph...) // #if IS_KINEMATIC { @@ -3001,7 +2993,7 @@ void MarlinSettings::reset() { #endif // - // Kinematic settings + // Kinematic Settings (Delta, SCARA, TPARA, Polargraph...) // #if IS_KINEMATIC From 4b279ac3008b35e8cfb257ba3d7dcdbe05a9d38d Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Thu, 20 Oct 2022 00:30:52 +0000 Subject: [PATCH 03/24] [cron] Bump distribution date (2022-10-20) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 794d5def4c..5b0f010226 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2022-10-19" +//#define STRING_DISTRIBUTION_DATE "2022-10-20" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index b348d0cfac..2d776134d6 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2022-10-19" + #define STRING_DISTRIBUTION_DATE "2022-10-20" #endif /** From 437cc484707cba8f8da5898bf7274e2254989cbe Mon Sep 17 00:00:00 2001 From: ellensp <530024+ellensp@users.noreply.github.com> Date: Thu, 20 Oct 2022 14:29:15 +1300 Subject: [PATCH 04/24] =?UTF-8?q?=F0=9F=94=A7=20No=20Native=20USB=20on=20A?= =?UTF-8?q?VR=20(#24906)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/HAL/AVR/HAL.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h index 1491867721..d458790979 100644 --- a/Marlin/src/HAL/AVR/HAL.h +++ b/Marlin/src/HAL/AVR/HAL.h @@ -32,6 +32,7 @@ #include #else #include "MarlinSerial.h" + #define BOARD_NO_NATIVE_USB #endif #include @@ -106,36 +107,36 @@ typedef Servo hal_servo_t; #define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0) #else - #if !WITHIN(SERIAL_PORT, -1, 3) - #error "SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." + #if !WITHIN(SERIAL_PORT, 0, 3) + #error "SERIAL_PORT must be from 0 to 3." #endif #define MYSERIAL1 customizedSerial1 #ifdef SERIAL_PORT_2 - #if !WITHIN(SERIAL_PORT_2, -1, 3) - #error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial." + #if !WITHIN(SERIAL_PORT_2, 0, 3) + #error "SERIAL_PORT_2 must be from 0 to 3." #endif #define MYSERIAL2 customizedSerial2 #endif #ifdef SERIAL_PORT_3 - #if !WITHIN(SERIAL_PORT_3, -1, 3) - #error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial." + #if !WITHIN(SERIAL_PORT_3, 0, 3) + #error "SERIAL_PORT_3 must be from 0 to 3." #endif #define MYSERIAL3 customizedSerial3 #endif #endif #ifdef MMU2_SERIAL_PORT - #if !WITHIN(MMU2_SERIAL_PORT, -1, 3) - #error "MMU2_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." + #if !WITHIN(MMU2_SERIAL_PORT, 0, 3) + #error "MMU2_SERIAL_PORT must be from 0 to 3" #endif #define MMU2_SERIAL mmuSerial #endif #ifdef LCD_SERIAL_PORT - #if !WITHIN(LCD_SERIAL_PORT, -1, 3) - #error "LCD_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." + #if !WITHIN(LCD_SERIAL_PORT, 0, 3) + #error "LCD_SERIAL_PORT must be from 0 to 3." #endif #define LCD_SERIAL lcdSerial #if HAS_DGUS_LCD From 7e25ef945676f148b54ed0fa159e858ec5b958ec Mon Sep 17 00:00:00 2001 From: Keith Bennett <13375512+thisiskeithb@users.noreply.github.com> Date: Wed, 19 Oct 2022 18:32:12 -0700 Subject: [PATCH 05/24] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Fix=20a=20label=20(#?= =?UTF-8?q?24903)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Followup to e298266eff --- Marlin/src/HAL/STM32/eeprom_flash.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/HAL/STM32/eeprom_flash.cpp b/Marlin/src/HAL/STM32/eeprom_flash.cpp index 78db07c6c0..6bd519877d 100644 --- a/Marlin/src/HAL/STM32/eeprom_flash.cpp +++ b/Marlin/src/HAL/STM32/eeprom_flash.cpp @@ -221,7 +221,7 @@ bool PersistentStore::access_finish() { return success; - #else !FLASH_EEPROM_LEVELING + #else // !FLASH_EEPROM_LEVELING // The following was written for the STM32F4 but may work with other MCUs as well. // Most STM32F4 flash does not allow reading from flash during erase operations. From b244785141f518202060467bf39717192728c65d Mon Sep 17 00:00:00 2001 From: InsanityAutomation <38436470+InsanityAutomation@users.noreply.github.com> Date: Wed, 19 Oct 2022 21:36:39 -0400 Subject: [PATCH 06/24] =?UTF-8?q?=F0=9F=90=9B=20Fix=20Print=20Timer=20stop?= =?UTF-8?q?=20with=20MarlinUI=20abort=20(#24902)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/lcd/marlinui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index b1827534b5..c885e83845 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -1630,7 +1630,7 @@ void MarlinUI::init() { #ifdef ACTION_ON_CANCEL hostui.cancel(); #endif - IF_DISABLED(SDSUPPORT, print_job_timer.stop()); + print_job_timer.stop(); TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_open(PROMPT_INFO, F("UI Aborted"), FPSTR(DISMISS_STR))); LCD_MESSAGE(MSG_PRINT_ABORTED); TERN_(HAS_MARLINUI_MENU, return_to_status()); From 9be1554faf486cec71742e82e1312d233162e31e Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 19 Oct 2022 21:00:14 -0500 Subject: [PATCH 07/24] =?UTF-8?q?=F0=9F=8E=A8=20Misc.=20variant=20cleanup,?= =?UTF-8?q?=20translation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Followup to #24787 --- .../MARLIN_F446Zx_TRONXY/hal_conf_custom.h | 2 +- .../variants/MARLIN_F446Zx_TRONXY/variant.cpp | 102 +++++++++--------- .../variants/MARLIN_F446Zx_TRONXY/variant.h | 5 +- .../MARLIN_MKS_SKIPR_V1/PeripheralPins.c | 4 +- .../variants/MARLIN_MKS_SKIPR_V1/variant.h | 2 +- 5 files changed, 57 insertions(+), 58 deletions(-) diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/hal_conf_custom.h b/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/hal_conf_custom.h index e077592245..c23d30ce88 100644 --- a/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/hal_conf_custom.h +++ b/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/hal_conf_custom.h @@ -411,7 +411,7 @@ in voltage and temperature. */ #endif /* HAL_SPI_MODULE_ENABLED */ #ifdef HAL_TIM_MODULE_ENABLED -#include "stm32f4xx_hal_tim.h" +#include "stm32f4xx_hal_tim.h" #endif /* HAL_TIM_MODULE_ENABLED */ #ifdef HAL_UART_MODULE_ENABLED diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/variant.cpp b/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/variant.cpp index 807b9392eb..2d94ee763a 100644 --- a/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/variant.cpp +++ b/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/variant.cpp @@ -170,69 +170,69 @@ extern "C" { #endif uint32_t myvar[] = {1,2,3,4,5,6,7,8}; -void myshow(int fre,int times)//YSZ-WORK +void myshow(int fre, int times) // YSZ-WORK { uint32_t index = 10; - RCC->AHB1ENR |= 1 << 6;//端口G时钟 - GPIOG->MODER &= ~(3UL << 2 * index);//清除旧模式 - GPIOG->MODER |= 1 << 2 * index;//模式为输出 - GPIOG->OSPEEDR &= ~(3UL << 2 * index); //清除旧输出速度 - GPIOG->OSPEEDR |= 2 << 2 * index;//设置输出速度 - GPIOG->OTYPER &= ~(1UL << index);//清除旧输出方式 - GPIOG->OTYPER |= 0 << index;//设置输出方式为推挽 - GPIOG->PUPDR &= ~(3 << 2 * index);//先清除原来的设置 - GPIOG->PUPDR |= 1 << 2 * index;//设置新的上下拉 - while(times != 0) { + RCC->AHB1ENR |= 1 << 6; // port G clock + GPIOG->MODER &= ~(3UL << 2 * index); // clear old mode + GPIOG->MODER |= 1 << 2 * index; // mode is output + GPIOG->OSPEEDR &= ~(3UL << 2 * index) // Clear old output speed + GPIOG->OSPEEDR |= 2 << 2 * index; // Set output speed + GPIOG->OTYPER &= ~(1UL << index) // clear old output + GPIOG->OTYPER |= 0 << index; // Set the output mode to push-pull + GPIOG->PUPDR &= ~(3 << 2 * index) // Clear the original settings first + GPIOG->PUPDR |= 1 << 2 * index; // Set new up and down + while (times != 0) { GPIOG->BSRR = 1UL << index; - for(int i = 0;i < fre; i++) - for(int j = 0; j < 1000000; j++)__NOP(); + for (int i = 0; i < fre; i++) + for (int j = 0; j < 1000000; j++) __NOP(); GPIOG->BSRR = 1UL << (index + 16); - for(int i = 0;i < fre; i++) - for(int j = 0; j < 1000000; j++)__NOP(); - if(times > 0)times--; + for (int i = 0; i < fre; i++) + for (int j = 0; j < 1000000; j++) __NOP(); + if (times > 0) times--; } } HAL_StatusTypeDef SDMMC_IsProgramming(SDIO_TypeDef *SDIOx,uint32_t RCA) { HAL_SD_CardStateTypeDef CardState; - volatile uint32_t respR1 = 0, status = 0; - SDIO_CmdInitTypeDef sdmmc_cmdinit; + volatile uint32_t respR1 = 0, status = 0; + SDIO_CmdInitTypeDef sdmmc_cmdinit; do { sdmmc_cmdinit.Argument = RCA << 16; sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_STATUS; sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT; sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO; sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE; - SDIO_SendCommand(SDIOx,&sdmmc_cmdinit);//发送CMD13 + SDIO_SendCommand(SDIOx,&sdmmc_cmdinit); // send CMD13 do status = SDIOx->STA; - while(!(status & ((1 << 0) | (1 << 6) | (1 << 2))));//等待操作完成 - if(status & (1 << 0)) //CRC检测失败 - { - SDIOx->ICR |= 1 << 0; //清除错误标记 + while (!(status & ((1 << 0) | (1 << 6) | (1 << 2)))); // wait for the operation to complete + if (status & (1 << 0)) { // CRC check failed + SDIOx->ICR |= 1 << 0; // clear error flag return HAL_ERROR; } - if(status & (1 << 2)) //命令超时 - { - SDIOx->ICR |= 1 << 2; //清除错误标记 + if (status & (1 << 2)) { // command timed out + SDIOx->ICR |= 1 << 2; // clear error flag return HAL_ERROR; } - if(SDIOx->RESPCMD != SDMMC_CMD_SEND_STATUS)return HAL_ERROR; - SDIOx->ICR = 0X5FF; //清除所有标记 + if (SDIOx->RESPCMD != SDMMC_CMD_SEND_STATUS) return HAL_ERROR; + SDIOx->ICR = 0X5FF; // clear all tags respR1 = SDIOx->RESP1; CardState = (respR1 >> 9) & 0x0000000F; - }while((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING) || (CardState == HAL_SD_CARD_PROGRAMMING)); + } while ((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING) || (CardState == HAL_SD_CARD_PROGRAMMING)); return HAL_OK; } -void debugStr(const char*str) { - while(*str) { - while((USART1->SR & 0x40) == 0); - USART1->DR = *str++; - } + +void debugStr(const char *str) { + while (*str) { + while ((USART1->SR & 0x40) == 0); + USART1->DR = *str++; + } } + /** * @brief System Clock Configuration - * The system Clock is configured as follow : + * The system Clock is configured as follows: * System Clock source = PLL (HSE) * SYSCLK(Hz) = 168000000/120000000/180000000 * HCLK(Hz) = 168000000/120000000/180000000 @@ -265,8 +265,8 @@ WEAK void SystemClock_Config(void) /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); - /* The voltage scaling allows optimizing the power consumption when the device is - clocked below the maximum system frequency, to update the voltage scaling value + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); @@ -281,42 +281,40 @@ WEAK void SystemClock_Config(void) RCC_OscInitStruct.PLL.PLLQ = 7; RCC_OscInitStruct.PLL.PLLR = 2; ret = HAL_RCC_OscConfig(&RCC_OscInitStruct); - - if(ret != HAL_OK)myshow(10,-1); + + if (ret != HAL_OK) myshow(10,-1); HAL_PWREx_EnableOverDrive(); - + /* Select PLLSAI output as USB clock source */ PeriphClkInitStruct.PLLSAI.PLLSAIM = 8; PeriphClkInitStruct.PLLSAI.PLLSAIN = 192; PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV4; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDIO; PeriphClkInitStruct.Clk48ClockSelection = RCC_CK48CLKSOURCE_PLLSAIP; - PeriphClkInitStruct.SdioClockSelection = RCC_SDIOCLKSOURCE_CLK48;//SDIO Clock Mux + PeriphClkInitStruct.SdioClockSelection = RCC_SDIOCLKSOURCE_CLK48; // SDIO Clock Mux HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); - /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 - clocks dividers */ + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); - if(ret != HAL_OK)myshow(10,-1); + if (ret != HAL_OK) myshow(10,-1); - SystemCoreClockUpdate();//更新系统时钟SystemCoreClock - /**Configure the Systick interrupt time - */ + SystemCoreClockUpdate(); + /* Configure the Systick interrupt time */ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000); - /**Configure the Systick - */ + /* Configure the Systick */ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); - __enable_irq();//打开中断,因为在bootloader中关闭了,所以这里要打开 + __enable_irq(); // Turn on the interrupt here because it is turned off in the bootloader } + #ifdef __cplusplus } #endif diff --git a/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/variant.h b/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/variant.h index 29649de938..082be9403e 100644 --- a/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/variant.h +++ b/buildroot/share/PlatformIO/variants/MARLIN_F446Zx_TRONXY/variant.h @@ -24,8 +24,9 @@ extern "C" { #endif // __cplusplus extern unsigned long myvar[]; -void myshow(int fre,int times); -void debugStr(const char*str); +void myshow(int fre, int times); +void debugStr(const char *str); + /*---------------------------------------------------------------------------- * Pins *----------------------------------------------------------------------------*/ diff --git a/buildroot/share/PlatformIO/variants/MARLIN_MKS_SKIPR_V1/PeripheralPins.c b/buildroot/share/PlatformIO/variants/MARLIN_MKS_SKIPR_V1/PeripheralPins.c index 640fbdbe13..11f5cc5afc 100644 --- a/buildroot/share/PlatformIO/variants/MARLIN_MKS_SKIPR_V1/PeripheralPins.c +++ b/buildroot/share/PlatformIO/variants/MARLIN_MKS_SKIPR_V1/PeripheralPins.c @@ -76,8 +76,8 @@ WEAK const PinMap PinMap_PWM[] = { {PA_0, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1 Fan2 {PA_1, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2 Fan1 {PA_2, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 3, 0)}, // TIM5_CH3 Fan0 - {PA_3, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 4, 0)}, // TIM5_CH4 HE2 - {PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 Servo + {PA_3, TIM5, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 4, 0)}, // TIM5_CH4 HE2 + {PA_8, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1 Servo {PB_0, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N HE1 {PB_1, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N HE0 {PB_2, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 BEEPER diff --git a/buildroot/share/PlatformIO/variants/MARLIN_MKS_SKIPR_V1/variant.h b/buildroot/share/PlatformIO/variants/MARLIN_MKS_SKIPR_V1/variant.h index dcc8c49395..51a9e92286 100644 --- a/buildroot/share/PlatformIO/variants/MARLIN_MKS_SKIPR_V1/variant.h +++ b/buildroot/share/PlatformIO/variants/MARLIN_MKS_SKIPR_V1/variant.h @@ -32,7 +32,7 @@ #ifdef __cplusplus extern "C" { #endif // __cplusplus -// +// /*---------------------------------------------------------------------------- * Pins *----------------------------------------------------------------------------*/ From 42d30ed102308f0c5cb04b70dc55f9f37012a157 Mon Sep 17 00:00:00 2001 From: ellensp <530024+ellensp@users.noreply.github.com> Date: Thu, 20 Oct 2022 15:23:22 +1300 Subject: [PATCH 08/24] =?UTF-8?q?=F0=9F=94=A7=20Some=20STM32=20UART=20Sani?= =?UTF-8?q?ty=20Checks=20(#24795)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/Configuration_adv.h | 2 +- Marlin/src/HAL/AVR/inc/SanityCheck.h | 16 +++-- Marlin/src/HAL/STM32/inc/SanityCheck.h | 59 +++++++++++++++++ Marlin/src/inc/Conditionals_post.h | 10 +-- Marlin/src/pins/pinsDebug_list.h | 74 ++++++++++++++++++++++ Marlin/src/pins/stm32f1/pins_CREALITY_V4.h | 55 +++++++++++----- 6 files changed, 187 insertions(+), 29 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 4a60ec6139..47b42aa8dd 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1152,7 +1152,7 @@ #endif /** - * Automatic backlash, position and hotend offset calibration + * Automatic backlash, position, and hotend offset calibration * * Enable G425 to run automatic calibration using an electrically- * conductive cube, bolt, or washer mounted on the bed. diff --git a/Marlin/src/HAL/AVR/inc/SanityCheck.h b/Marlin/src/HAL/AVR/inc/SanityCheck.h index 411b0198f1..ff1610f741 100644 --- a/Marlin/src/HAL/AVR/inc/SanityCheck.h +++ b/Marlin/src/HAL/AVR/inc/SanityCheck.h @@ -40,13 +40,15 @@ #if SERIAL_IN_USE(0) // D0-D1. No known conflicts. #endif -#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__) - #if SERIAL_IN_USE(1) && (CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19)) - #error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board." - #endif -#else - #if SERIAL_IN_USE(1) && (CHECK_SERIAL_PIN(10) || CHECK_SERIAL_PIN(11)) - #error "Serial Port 1 pin D10 and/or D11 conflicts with another pin on the board." +#if SERIAL_IN_USE(1) + #if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__) + #if CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19) + #error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board." + #endif + #else + #if CHECK_SERIAL_PIN(10) || CHECK_SERIAL_PIN(11) + #error "Serial Port 1 pin D10 and/or D11 conflicts with another pin on the board." + #endif #endif #endif #if SERIAL_IN_USE(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17)) diff --git a/Marlin/src/HAL/STM32/inc/SanityCheck.h b/Marlin/src/HAL/STM32/inc/SanityCheck.h index a440695a06..e8ddfa1720 100644 --- a/Marlin/src/HAL/STM32/inc/SanityCheck.h +++ b/Marlin/src/HAL/STM32/inc/SanityCheck.h @@ -50,3 +50,62 @@ #if ANY(TFT_COLOR_UI, TFT_LVGL_UI, TFT_CLASSIC_UI) && NOT_TARGET(STM32H7xx, STM32F4xx, STM32F1xx) #error "TFT_COLOR_UI, TFT_LVGL_UI and TFT_CLASSIC_UI are currently only supported on STM32H7, STM32F4 and STM32F1 hardware." #endif + +/** + * Check for common serial pin conflicts + */ +#define _CHECK_SERIAL_PIN(N) (( \ + BTN_EN1 == N || DOGLCD_CS == N || HEATER_BED_PIN == N || FAN_PIN == N || \ + SDIO_D2_PIN == N || SDIO_D3_PIN == N || SDIO_CK_PIN == N || SDIO_CMD_PIN == N \ + )) +#define CHECK_SERIAL_PIN(T,N) defined(UART##N##_##T##_PIN) && _CHECK_SERIAL_PIN(UART##N##_##T##_PIN) +#if SERIAL_IN_USE(1) + #if CHECK_SERIAL_PIN(TX,1) + #error "Serial Port 1 TX IO pins conflict with another pin on the board." + #endif + #if CHECK_SERIAL_PIN(RX,1) + #error "Serial Port 1 RX IO pins conflict with another pin on the board." + #endif +#endif +#if SERIAL_IN_USE(2) + #if CHECK_SERIAL_PIN(TX,2) + #error "Serial Port 2 TX IO pins conflict with another pin on the board." + #endif + #if CHECK_SERIAL_PIN(RX,2) + #error "Serial Port 2 RX IO pins conflict with another pin on the board." + #endif +#endif +#if SERIAL_IN_USE(3) + #if CHECK_SERIAL_PIN(TX,3) + #error "Serial Port 3 TX IO pins conflict with another pin on the board." + #endif + #if CHECK_SERIAL_PIN(RX,3) + #error "Serial Port 3 RX IO pins conflict with another pin on the board." + #endif +#endif +#if SERIAL_IN_USE(4) + #if CHECK_SERIAL_PIN(TX,4) + #error "Serial Port 4 TX IO pins conflict with another pin on the board." + #endif + #if CHECK_SERIAL_PIN(RX,4) + #error "Serial Port 4 RX IO pins conflict with another pin on the board." + #endif +#endif +#if SERIAL_IN_USE(5) + #if CHECK_SERIAL_PIN(TX,5) + #error "Serial Port 5 TX IO pins conflict with another pin on the board." + #endif + #if CHECK_SERIAL_PIN(RX,5) + #error "Serial Port 5 RX IO pins conflict with another pin on the board." + #endif +#endif +#if SERIAL_IN_USE(6) + #if CHECK_SERIAL_PIN(TX,6) + #error "Serial Port 6 TX IO pins conflict with another pin on the board." + #endif + #if CHECK_SERIAL_PIN(RX,6) + #error "Serial Port 6 RX IO pins conflict with another pin on the board." + #endif +#endif +#undef CHECK_SERIAL_PIN +#undef _CHECK_SERIAL_PIN diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index bb9a1ac640..417ce4479a 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2446,11 +2446,11 @@ // // Flag the indexed hardware serial ports in use -#define SERIAL_IN_USE(N) ( (defined(SERIAL_PORT) && SERIAL_PORT == N) \ - || (defined(SERIAL_PORT_2) && SERIAL_PORT_2 == N) \ - || (defined(SERIAL_PORT_3) && SERIAL_PORT_3 == N) \ - || (defined(MMU2_SERIAL_PORT) && MMU2_SERIAL_PORT == N) \ - || (defined(LCD_SERIAL_PORT) && LCD_SERIAL_PORT == N) ) +#define SERIAL_IN_USE(N) ( (defined(SERIAL_PORT) && N == SERIAL_PORT) \ + || (defined(SERIAL_PORT_2) && N == SERIAL_PORT_2) \ + || (defined(SERIAL_PORT_3) && N == SERIAL_PORT_3) \ + || (defined(MMU2_SERIAL_PORT) && N == MMU2_SERIAL_PORT) \ + || (defined(LCD_SERIAL_PORT) && N == LCD_SERIAL_PORT) ) // Flag the named hardware serial ports in use #define TMC_UART_IS(A,N) (defined(A##_HARDWARE_SERIAL) && (CAT(HW_,A##_HARDWARE_SERIAL) == HW_Serial##N || CAT(HW_,A##_HARDWARE_SERIAL) == HW_MSerial##N)) diff --git a/Marlin/src/pins/pinsDebug_list.h b/Marlin/src/pins/pinsDebug_list.h index 2cd54ecf18..077c94a60f 100644 --- a/Marlin/src/pins/pinsDebug_list.h +++ b/Marlin/src/pins/pinsDebug_list.h @@ -2231,6 +2231,80 @@ REPORT_NAME_DIGITAL(__LINE__, TFT_RESET_PIN) #endif +// +// Hardware UART +// +#if SERIAL_IN_USE(1) + #if PIN_EXISTS(UART1_TX) + REPORT_NAME_DIGITAL(__LINE__, UART1_TX_PIN) + #endif + #if PIN_EXISTS(UART1_RX) + REPORT_NAME_DIGITAL(__LINE__, UART1_RX_PIN) + #endif +#endif +#if SERIAL_IN_USE(2) + #if PIN_EXISTS(UART2_TX) + REPORT_NAME_DIGITAL(__LINE__, UART2_TX_PIN) + #endif + #if PIN_EXISTS(UART2_RX) + REPORT_NAME_DIGITAL(__LINE__, UART2_RX_PIN) + #endif +#endif +#if SERIAL_IN_USE(3) + #if PIN_EXISTS(UART3_TX) + REPORT_NAME_DIGITAL(__LINE__, UART3_TX_PIN) + #endif + #if PIN_EXISTS(UART3_RX) + REPORT_NAME_DIGITAL(__LINE__, UART3_RX_PIN) + #endif +#endif +#if SERIAL_IN_USE(4) + #if PIN_EXISTS(UART4_TX) + REPORT_NAME_DIGITAL(__LINE__, UART4_TX_PIN) + #endif + #if PIN_EXISTS(UART4_RX) + REPORT_NAME_DIGITAL(__LINE__, UART4_RX_PIN) + #endif +#endif +#if SERIAL_IN_USE(5) + #if PIN_EXISTS(UART5_TX) + REPORT_NAME_DIGITAL(__LINE__, UART5_TX_PIN) + #endif + #if PIN_EXISTS(UART5_RX) + REPORT_NAME_DIGITAL(__LINE__, UART5_RX_PIN) + #endif +#endif +#if SERIAL_IN_USE(6) + #if PIN_EXISTS(UART6_TX) + REPORT_NAME_DIGITAL(__LINE__, UART6_TX_PIN) + #endif + #if PIN_EXISTS(UART6_RX) + REPORT_NAME_DIGITAL(__LINE__, UART6_RX_PIN) + #endif +#endif + +// +// SDIO +// +#if PIN_EXISTS(SDIO_D0) + REPORT_NAME_DIGITAL(__LINE__, SDIO_D0_PIN) +#endif +#if PIN_EXISTS(SDIO_D1) + REPORT_NAME_DIGITAL(__LINE__, SDIO_D1_PIN) +#endif +#if PIN_EXISTS(SDIO_D2) + REPORT_NAME_DIGITAL(__LINE__, SDIO_D2_PIN) +#endif +#if PIN_EXISTS(SDIO_D3) + REPORT_NAME_DIGITAL(__LINE__, SDIO_D3_PIN) +#endif +#if PIN_EXISTS(SDIO_CK) + REPORT_NAME_DIGITAL(__LINE__, SDIO_CK_PIN) +#endif +#if PIN_EXISTS(SDIO_CMD) + REPORT_NAME_DIGITAL(__LINE__, SDIO_CMD_PIN) +#endif + // // Miscellaneous // diff --git a/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h b/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h index 11384799a3..f633ee0983 100644 --- a/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h +++ b/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h @@ -173,14 +173,14 @@ * GND | 9 10 | 5V * ------ */ - #define EXP3_01_PIN PC6 - #define EXP3_02_PIN PB2 - #define EXP3_03_PIN PB10 - #define EXP3_04_PIN PB11 - #define EXP3_05_PIN PB14 - #define EXP3_06_PIN PB13 - #define EXP3_07_PIN PB12 - #define EXP3_08_PIN PB15 + #define EXP3_01_PIN PC6 + #define EXP3_02_PIN PB2 + #define EXP3_03_PIN PB10 + #define EXP3_04_PIN PB11 + #define EXP3_05_PIN PB14 + #define EXP3_06_PIN PB13 + #define EXP3_07_PIN PB12 + #define EXP3_08_PIN PB15 #elif EITHER(VET6_12864_LCD, DWIN_VET6_CREALITY_LCD) @@ -194,14 +194,14 @@ * GND | 9 10 | 5V * ------ */ - #define EXP3_01_PIN -1 - #define EXP3_02_PIN PC5 - #define EXP3_03_PIN PB10 - #define EXP3_04_PIN -1 - #define EXP3_05_PIN PA6 - #define EXP3_06_PIN PA5 - #define EXP3_07_PIN PA4 - #define EXP3_08_PIN PA7 + #define EXP3_01_PIN -1 + #define EXP3_02_PIN PC5 + #define EXP3_03_PIN PB10 + #define EXP3_04_PIN -1 + #define EXP3_05_PIN PA6 + #define EXP3_06_PIN PA5 + #define EXP3_07_PIN PA4 + #define EXP3_08_PIN PA7 #elif EITHER(CR10_STOCKDISPLAY, FYSETC_MINI_12864_2_1) #error "Define RET6_12864_LCD or VET6_12864_LCD to select pins for the LCD with the Creality V4 controller." @@ -283,3 +283,26 @@ #define NEOPIXEL_PIN PA13 #endif + +// Pins for documentation and sanity checks only. +// Changing these will not change the pin they are on. + +// Hardware UART pins +#define UART1_TX_PIN PA9 // default uses CH340 RX +#define UART1_RX_PIN PA10 // default uses CH340 TX +#define UART2_TX_PIN PA2 // default uses HEATER_BED_PIN +#define UART2_RX_PIN PA3 // not connected +#define UART3_TX_PIN PB10 // default uses LCD connector +#define UART3_RX_PIN PB11 // default uses LCD connector +#define UART4_TX_PIN PC10 // default uses sdcard SDIO_D2 +#define UART4_RX_PIN PC11 // default uses sdcard SDIO_D3 +#define UART5_TX_PIN PC12 // default uses sdcard SDIO_CK +#define UART5_RX_PIN PD2 // default uses sdcard SDIO_CMD + +// SDIO pins +#define SDIO_D0_PIN PC8 +#define SDIO_D1_PIN PC9 +#define SDIO_D2_PIN PC10 +#define SDIO_D3_PIN PC11 +#define SDIO_CK_PIN PC12 +#define SDIO_CMD_PIN PD2 From 70b3166715903aebc015362c7a96ac52cee4f2ed Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Fri, 21 Oct 2022 00:28:49 +0000 Subject: [PATCH 09/24] [cron] Bump distribution date (2022-10-21) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 5b0f010226..dae6ae3368 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2022-10-20" +//#define STRING_DISTRIBUTION_DATE "2022-10-21" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 2d776134d6..510641cf1d 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2022-10-20" + #define STRING_DISTRIBUTION_DATE "2022-10-21" #endif /** From 86aac677ac8f90536d895b3d33effa4ab65495be Mon Sep 17 00:00:00 2001 From: silycr <32662182+silycr@users.noreply.github.com> Date: Sat, 22 Oct 2022 04:31:46 +1030 Subject: [PATCH 10/24] =?UTF-8?q?=F0=9F=9A=B8=20Probe=20pins=20for=20Chitu?= =?UTF-8?q?=20V5=20(#24910)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h b/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h index 53b6797e91..f4cecc21c2 100644 --- a/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h +++ b/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h @@ -23,6 +23,14 @@ #define BOARD_INFO_NAME "Chitu3D V5" -#define Z_STOP_PIN PA14 +// +// Servos +// +#define SERVO0_PIN PA13 // Z+ (behind FILAMENT) Pinout [+5v|G|S] + +// +// Limit Switches +// +#define Z_STOP_PIN PA14 // Pinout [+12/24v|G|S] #include "pins_CHITU3D_common.h" From 02c43f44c73b76c8d8d1e48b8e595ced62da2459 Mon Sep 17 00:00:00 2001 From: InsanityAutomation <38436470+InsanityAutomation@users.noreply.github.com> Date: Fri, 21 Oct 2022 14:03:38 -0400 Subject: [PATCH 11/24] =?UTF-8?q?=E2=9C=A8=20Controllerfan=20PWM=20scaling?= =?UTF-8?q?,=20kickstart=20(#24873)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/Configuration_adv.h | 12 ++++++++---- Marlin/src/feature/controllerfan.cpp | 16 ++++++++++++++++ Marlin/src/inc/Conditionals_adv.h | 11 +++++++++++ Marlin/src/inc/SanityCheck.h | 5 +++++ Marlin/src/module/planner.cpp | 16 +++++----------- Marlin/src/module/temperature.cpp | 14 +++++++------- Marlin/src/module/tool_change.cpp | 2 +- 7 files changed, 53 insertions(+), 23 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 47b42aa8dd..085c5379a9 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -552,10 +552,14 @@ #endif #endif -// When first starting the main fan, run it at full speed for the -// given number of milliseconds. This gets the fan spinning reliably -// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) -//#define FAN_KICKSTART_TIME 100 +/** + * Fan Kickstart + * When part cooling or controller fans first start, run at a speed that + * gets it spinning reliably for a short time before setting the requested speed. + * (Does not work on Sanguinololu with FAN_SOFT_PWM.) + */ +//#define FAN_KICKSTART_TIME 100 // (ms) +//#define FAN_KICKSTART_POWER 180 // 64-255 // Some coolers may require a non-zero "off" state. //#define FAN_OFF_PWM 1 diff --git a/Marlin/src/feature/controllerfan.cpp b/Marlin/src/feature/controllerfan.cpp index f42bf52ae4..2f25832cdc 100644 --- a/Marlin/src/feature/controllerfan.cpp +++ b/Marlin/src/feature/controllerfan.cpp @@ -72,6 +72,22 @@ void ControllerFan::update() { ? settings.active_speed : settings.idle_speed ); + speed = CALC_FAN_SPEED(speed); + + #if FAN_KICKSTART_TIME + static millis_t fan_kick_end = 0; + if (speed > FAN_OFF_PWM) { + if (!fan_kick_end) { + fan_kick_end = ms + FAN_KICKSTART_TIME; // May be longer based on slow update interval for controller fn check. Sets minimum + speed = FAN_KICKSTART_POWER; + } + else if (PENDING(ms, fan_kick_end)) + speed = FAN_KICKSTART_POWER; + } + else + fan_kick_end = 0; + #endif + #if ENABLED(FAN_SOFT_PWM) thermalManager.soft_pwm_controller_speed = speed; #else diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index ba8c3587fe..27185400f9 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -1074,3 +1074,14 @@ #if ANY(DISABLE_INACTIVE_X, DISABLE_INACTIVE_Y, DISABLE_INACTIVE_Z, DISABLE_INACTIVE_I, DISABLE_INACTIVE_J, DISABLE_INACTIVE_K, DISABLE_INACTIVE_U, DISABLE_INACTIVE_V, DISABLE_INACTIVE_W, DISABLE_INACTIVE_E) #define HAS_DISABLE_INACTIVE_AXIS 1 #endif + +// Fan Kickstart +#if FAN_KICKSTART_TIME && !defined(FAN_KICKSTART_POWER) + #define FAN_KICKSTART_POWER 180 +#endif + +#if FAN_MIN_PWM == 0 && FAN_MAX_PWM == 255 + #define CALC_FAN_SPEED(f) (f ?: FAN_OFF_PWM) +#else + #define CALC_FAN_SPEED(f) (f ? map(f, 1, 255, FAN_MIN_PWM, FAN_MAX_PWM) : FAN_OFF_PWM) +#endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 02d798543c..679463798a 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -1513,6 +1513,11 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "To use BED_LIMIT_SWITCHING you must disable PIDTEMPBED." #endif +// Fan Kickstart +#if FAN_KICKSTART_TIME && defined(FAN_KICKSTART_POWER) && !WITHIN(FAN_KICKSTART_POWER, 64, 255) + #error "FAN_KICKSTART_POWER must be an integer from 64 to 255." +#endif + /** * Synchronous M106/M107 checks */ diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index 91a994470a..3263e7660a 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -1282,16 +1282,10 @@ void Planner::recalculate(TERN_(HINTS_SAFE_EXIT_SPEED, const_float_t safe_exit_s void Planner::sync_fan_speeds(uint8_t (&fan_speed)[FAN_COUNT]) { - #if FAN_MIN_PWM != 0 || FAN_MAX_PWM != 255 - #define CALC_FAN_SPEED(f) (fan_speed[f] ? map(fan_speed[f], 1, 255, FAN_MIN_PWM, FAN_MAX_PWM) : FAN_OFF_PWM) - #else - #define CALC_FAN_SPEED(f) (fan_speed[f] ?: FAN_OFF_PWM) - #endif - #if ENABLED(FAN_SOFT_PWM) - #define _FAN_SET(F) thermalManager.soft_pwm_amount_fan[F] = CALC_FAN_SPEED(F); + #define _FAN_SET(F) thermalManager.soft_pwm_amount_fan[F] = CALC_FAN_SPEED(fan_speed[F]); #else - #define _FAN_SET(F) hal.set_pwm_duty(pin_t(FAN##F##_PIN), CALC_FAN_SPEED(F)); + #define _FAN_SET(F) hal.set_pwm_duty(pin_t(FAN##F##_PIN), CALC_FAN_SPEED(fan_speed[F])); #endif #define FAN_SET(F) do{ kickstart_fan(fan_speed, ms, F); _FAN_SET(F); }while(0) @@ -1306,13 +1300,13 @@ void Planner::recalculate(TERN_(HINTS_SAFE_EXIT_SPEED, const_float_t safe_exit_s void Planner::kickstart_fan(uint8_t (&fan_speed)[FAN_COUNT], const millis_t &ms, const uint8_t f) { static millis_t fan_kick_end[FAN_COUNT] = { 0 }; - if (fan_speed[f]) { + if (fan_speed[f] > FAN_OFF_PWM) { if (fan_kick_end[f] == 0) { fan_kick_end[f] = ms + FAN_KICKSTART_TIME; - fan_speed[f] = 255; + fan_speed[f] = FAN_KICKSTART_POWER; } else if (PENDING(ms, fan_kick_end[f])) - fan_speed[f] = 255; + fan_speed[f] = FAN_KICKSTART_POWER; } else fan_kick_end[f] = 0; diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 349264606a..7515396fbe 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -306,19 +306,19 @@ PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED); #endif #if EITHER(AUTO_POWER_E_FANS, HAS_FANCHECK) - uint8_t Temperature::autofan_speed[HOTENDS]; // = { 0 } + uint8_t Temperature::autofan_speed[HOTENDS] = ARRAY_N_1(HOTENDS, FAN_OFF_PWM); #endif #if ENABLED(AUTO_POWER_CHAMBER_FAN) - uint8_t Temperature::chamberfan_speed; // = 0 + uint8_t Temperature::chamberfan_speed = FAN_OFF_PWM; #endif #if ENABLED(AUTO_POWER_COOLER_FAN) - uint8_t Temperature::coolerfan_speed; // = 0 + uint8_t Temperature::coolerfan_speed = FAN_OFF_PWM; #endif #if BOTH(FAN_SOFT_PWM, USE_CONTROLLER_FAN) - uint8_t Temperature::soft_pwm_controller_speed; + uint8_t Temperature::soft_pwm_controller_speed = FAN_OFF_PWM; #endif // Init fans according to whether they're native PWM or Software PWM @@ -342,11 +342,11 @@ PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED); // HAS_FAN does not include CONTROLLER_FAN #if HAS_FAN - uint8_t Temperature::fan_speed[FAN_COUNT]; // = { 0 } + uint8_t Temperature::fan_speed[FAN_COUNT] = ARRAY_N_1(FAN_COUNT, FAN_OFF_PWM); #if ENABLED(EXTRA_FAN_SPEED) - Temperature::extra_fan_t Temperature::extra_fan_speed[FAN_COUNT]; + Temperature::extra_fan_t Temperature::extra_fan_speed[FAN_COUNT] = ARRAY_N_1(FAN_COUNT, FAN_OFF_PWM); /** * Handle the M106 P T command: @@ -373,7 +373,7 @@ PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED); #if EITHER(PROBING_FANS_OFF, ADVANCED_PAUSE_FANS_PAUSE) bool Temperature::fans_paused; // = false; - uint8_t Temperature::saved_fan_speed[FAN_COUNT]; // = { 0 } + uint8_t Temperature::saved_fan_speed[FAN_COUNT] = ARRAY_N_1(FAN_COUNT, FAN_OFF_PWM); #endif #if ENABLED(ADAPTIVE_FAN_SLOWING) diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 4eb72a5b7d..80aedd3bdd 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -917,7 +917,7 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0. #if HAS_FAN && TOOLCHANGE_FS_FAN >= 0 thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = toolchange_settings.fan_speed; gcode.dwell(SEC_TO_MS(toolchange_settings.fan_time)); - thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = 0; + thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = FAN_OFF_PWM; #endif } From f8d7090e30ca679c5bce6a16c1350b15b52ba50b Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 21 Oct 2022 15:41:51 -0500 Subject: [PATCH 12/24] =?UTF-8?q?=F0=9F=94=A8=20gcc-12=20for=20macOS=20nat?= =?UTF-8?q?ive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ini/native.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ini/native.ini b/ini/native.ini index 1905559fd0..15a4d36af8 100644 --- a/ini/native.ini +++ b/ini/native.ini @@ -66,11 +66,11 @@ build_flags = ${simulator_linux.build_flags} ${simulator_linux.release_flags} # # MacPorts: -# sudo port install gcc11 glm libsdl2 libsdl2_net +# sudo port install gcc12 glm libsdl2 libsdl2_net # # cd /opt/local/bin # sudo rm -f gcc g++ cc -# sudo ln -s gcc-mp-11 gcc ; sudo ln -s g++-mp-11 g++ ; sudo ln -s g++ cc +# sudo ln -s gcc-mp-12 gcc ; sudo ln -s g++-mp-12 g++ ; sudo ln -s g++ cc # cd - # rehash # From a460b01c876ff39901fe55a4b66b2c62737ef46c Mon Sep 17 00:00:00 2001 From: tombrazier <68918209+tombrazier@users.noreply.github.com> Date: Fri, 21 Oct 2022 22:34:22 +0100 Subject: [PATCH 13/24] =?UTF-8?q?=F0=9F=9A=80=20ZV=20Input=20Shaping=20(#2?= =?UTF-8?q?4797)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/Configuration_adv.h | 29 ++ .../src/gcode/feature/input_shaping/M593.cpp | 83 ++++++ Marlin/src/gcode/gcode.cpp | 4 + Marlin/src/gcode/gcode.h | 6 + Marlin/src/inc/Conditionals_adv.h | 14 + Marlin/src/inc/SanityCheck.h | 35 ++- Marlin/src/lcd/language/language_en.h | 5 + Marlin/src/lcd/menu/menu_advanced.cpp | 41 ++- Marlin/src/module/planner.cpp | 8 + Marlin/src/module/settings.cpp | 66 +++++ Marlin/src/module/stepper.cpp | 269 +++++++++++++++--- Marlin/src/module/stepper.h | 135 ++++++++- buildroot/tests/mega2560 | 2 +- ini/features.ini | 1 + platformio.ini | 1 + 15 files changed, 657 insertions(+), 42 deletions(-) create mode 100644 Marlin/src/gcode/feature/input_shaping/M593.cpp diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 085c5379a9..01a2bd85c5 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1055,6 +1055,35 @@ // @section motion +/** + * Input Shaping -- EXPERIMENTAL + * + * Zero Vibration (ZV) Input Shaping for X and/or Y movements. + * + * This option uses a lot of SRAM for the step buffer, which is proportional + * to the largest step rate possible for any axis. If the build fails due to + * low SRAM the buffer size may be reduced by setting smaller values for + * DEFAULT_AXIS_STEPS_PER_UNIT and/or DEFAULT_MAX_FEEDRATE. Runtime editing + * of max feedrate (M203) or resonant frequency (M593) may result feedrate + * being capped to prevent buffer overruns. + * + * Tune with M593 D F: + * + * D Set the zeta/damping factor. If axes (X, Y, etc.) are not specified, set for all axes. + * F Set the frequency. If axes (X, Y, etc.) are not specified, set for all axes. + * T[map] Input Shaping type, 0:ZV, 1:EI, 2:2H EI (not implemented yet) + * X<1> Set the given parameters only for the X axis. + * Y<1> Set the given parameters only for the Y axis. + */ +//#define INPUT_SHAPING +#if ENABLED(INPUT_SHAPING) + #define SHAPING_FREQ_X 40 // (Hz) The dominant resonant frequency of the X axis. + #define SHAPING_FREQ_Y 40 // (Hz) The dominant resonant frequency of the Y axis. + #define SHAPING_ZETA_X 0.3f // Damping ratio of the X axis (range: 0.0 = no damping to 1.0 = critical damping). + #define SHAPING_ZETA_Y 0.3f // Damping ratio of the Y axis (range: 0.0 = no damping to 1.0 = critical damping). + //#define SHAPING_MENU // Add a menu to the LCD to set shaping parameters. +#endif + #define AXIS_RELATIVE_MODES { false, false, false, false } // Add a Duplicate option for well-separated conjoined nozzles diff --git a/Marlin/src/gcode/feature/input_shaping/M593.cpp b/Marlin/src/gcode/feature/input_shaping/M593.cpp new file mode 100644 index 0000000000..84301963cb --- /dev/null +++ b/Marlin/src/gcode/feature/input_shaping/M593.cpp @@ -0,0 +1,83 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2022 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 . + * + */ + +#include "../../../inc/MarlinConfig.h" + +#if ENABLED(INPUT_SHAPING) + +#include "../../gcode.h" +#include "../../../module/stepper.h" + +void GcodeSuite::M593_report(const bool forReplay/*=true*/) { + report_heading_etc(forReplay, F("Input Shaping")); + #if HAS_SHAPING_X + SERIAL_ECHO_MSG("M593 X" + " F", stepper.get_shaping_frequency(X_AXIS), + " D", stepper.get_shaping_damping_ratio(X_AXIS) + ); + #endif + #if HAS_SHAPING_Y + SERIAL_ECHO_MSG("M593 Y" + " F", stepper.get_shaping_frequency(Y_AXIS), + " D", stepper.get_shaping_damping_ratio(Y_AXIS) + ); + #endif +} + +/** + * M593: Get or Set Input Shaping Parameters + * D Set the zeta/damping factor. If axes (X, Y, etc.) are not specified, set for all axes. + * F Set the frequency. If axes (X, Y, etc.) are not specified, set for all axes. + * T[map] Input Shaping type, 0:ZV, 1:EI, 2:2H EI (not implemented yet) + * X<1> Set the given parameters only for the X axis. + * Y<1> Set the given parameters only for the Y axis. + */ +void GcodeSuite::M593() { + if (!parser.seen_any()) return M593_report(); + + const bool seen_X = TERN0(HAS_SHAPING_X, parser.seen_test('X')), + seen_Y = TERN0(HAS_SHAPING_Y, parser.seen_test('Y')), + for_X = seen_X || TERN0(HAS_SHAPING_X, (!seen_X && !seen_Y)), + for_Y = seen_Y || TERN0(HAS_SHAPING_Y, (!seen_X && !seen_Y)); + + if (parser.seen('D')) { + const float zeta = parser.value_float(); + if (WITHIN(zeta, 0, 1)) { + if (for_X) stepper.set_shaping_damping_ratio(X_AXIS, zeta); + if (for_Y) stepper.set_shaping_damping_ratio(Y_AXIS, zeta); + } + else + SERIAL_ECHO_MSG("?Zeta (D) value out of range (0-1)"); + } + + if (parser.seen('F')) { + const float freq = parser.value_float(); + if (freq > 0) { + if (for_X) stepper.set_shaping_frequency(X_AXIS, freq); + if (for_Y) stepper.set_shaping_frequency(Y_AXIS, freq); + } + else + SERIAL_ECHO_MSG("?Frequency (F) must be greater than 0"); + } +} + +#endif diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 0667ef0b7b..ff066ed678 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -933,6 +933,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 575: M575(); break; // M575: Set serial baudrate #endif + #if ENABLED(INPUT_SHAPING) + case 593: M593(); break; // M593: Set Input Shaping parameters + #endif + #if ENABLED(ADVANCED_PAUSE_FEATURE) case 600: M600(); break; // M600: Pause for Filament Change case 603: M603(); break; // M603: Configure Filament Change diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index e2506e4ed9..0ce8ab3902 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -259,6 +259,7 @@ * M554 - Get or set IP gateway. (Requires enabled Ethernet port) * M569 - Enable stealthChop on an axis. (Requires at least one _DRIVER_TYPE to be TMC2130/2160/2208/2209/5130/5160) * M575 - Change the serial baud rate. (Requires BAUD_RATE_GCODE) + * M593 - Get or set input shaping parameters. (Requires INPUT_SHAPING) * M600 - Pause for filament change: "M600 X Y Z E L". (Requires ADVANCED_PAUSE_FEATURE) * M603 - Configure filament change: "M603 T U L". (Requires ADVANCED_PAUSE_FEATURE) * M605 - Set Dual X-Carriage movement mode: "M605 S [X] [R]". (Requires DUAL_X_CARRIAGE) @@ -1080,6 +1081,11 @@ private: static void M575(); #endif + #if ENABLED(INPUT_SHAPING) + static void M593(); + static void M593_report(const bool forReplay=true); + #endif + #if ENABLED(ADVANCED_PAUSE_FEATURE) static void M600(); static void M603(); diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 27185400f9..1f8f0ddfb6 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -1085,3 +1085,17 @@ #else #define CALC_FAN_SPEED(f) (f ? map(f, 1, 255, FAN_MIN_PWM, FAN_MAX_PWM) : FAN_OFF_PWM) #endif + +// Input shaping +#if ENABLED(INPUT_SHAPING) + #if !HAS_Y_AXIS + #undef SHAPING_FREQ_Y + #undef SHAPING_BUFFER_Y + #endif + #ifdef SHAPING_FREQ_X + #define HAS_SHAPING_X 1 + #endif + #ifdef SHAPING_FREQ_Y + #define HAS_SHAPING_Y 1 + #endif +#endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 679463798a..06b8f32946 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -4238,11 +4238,6 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive."); #endif #endif -// Misc. Cleanup -#undef _TEST_PWM -#undef _NUM_AXES_STR -#undef _LOGICAL_AXES_STR - // JTAG support in the HAL #if ENABLED(DISABLE_DEBUG) && !defined(JTAGSWD_DISABLE) #error "DISABLE_DEBUG is not supported for the selected MCU/Board." @@ -4254,3 +4249,33 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive."); #if ENABLED(XFER_BUILD) && !BOTH(BINARY_FILE_TRANSFER, CUSTOM_FIRMWARE_UPLOAD) #error "BINARY_FILE_TRANSFER and CUSTOM_FIRMWARE_UPLOAD are required for custom upload." #endif + +// Check requirements for Input Shaping +#if ENABLED(INPUT_SHAPING) && defined(__AVR__) + #if HAS_SHAPING_X + #if F_CPU > 16000000 + static_assert((SHAPING_FREQ_X) * 2 * 0x10000 >= (STEPPER_TIMER_RATE), "SHAPING_FREQ_X is below the minimum (20) for AVR 20MHz."); + #else + static_assert((SHAPING_FREQ_X) * 2 * 0x10000 >= (STEPPER_TIMER_RATE), "SHAPING_FREQ_X is below the minimum (16) for AVR 16MHz."); + #endif + #elif HAS_SHAPING_Y + #if F_CPU > 16000000 + static_assert((SHAPING_FREQ_Y) * 2 * 0x10000 >= (STEPPER_TIMER_RATE), "SHAPING_FREQ_Y is below the minimum (20) for AVR 20MHz."); + #else + static_assert((SHAPING_FREQ_Y) * 2 * 0x10000 >= (STEPPER_TIMER_RATE), "SHAPING_FREQ_Y is below the minimum (16) for AVR 16MHz."); + #endif + #endif +#endif + +#if ENABLED(INPUT_SHAPING) + #if ENABLED(DIRECT_STEPPING) + #error "INPUT_SHAPING cannot currently be used with DIRECT_STEPPING." + #elif ENABLED(LASER_FEATURE) + #error "INPUT_SHAPING cannot currently be used with LASER_FEATURE." + #endif +#endif + +// Misc. Cleanup +#undef _TEST_PWM +#undef _NUM_AXES_STR +#undef _LOGICAL_AXES_STR diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index e4f8ef8fb7..c888207ed1 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -399,6 +399,11 @@ namespace Language_en { LSTR MSG_AMAX_EN = _UxGT("Max * Accel"); LSTR MSG_A_RETRACT = _UxGT("Retract Accel"); LSTR MSG_A_TRAVEL = _UxGT("Travel Accel"); + LSTR MSG_INPUT_SHAPING = _UxGT("Input Shaping"); + LSTR MSG_SHAPING_X_FREQ = STR_X _UxGT(" frequency"); + LSTR MSG_SHAPING_Y_FREQ = STR_Y _UxGT(" frequency"); + LSTR MSG_SHAPING_X_ZETA = STR_X _UxGT(" damping"); + LSTR MSG_SHAPING_Y_ZETA = STR_Y _UxGT(" damping"); LSTR MSG_XY_FREQUENCY_LIMIT = _UxGT("XY Freq Limit"); LSTR MSG_XY_FREQUENCY_FEEDRATE = _UxGT("Min FR Factor"); LSTR MSG_STEPS_PER_MM = _UxGT("Steps/mm"); diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp index 5978a8ec1a..9d6d79efd7 100644 --- a/Marlin/src/lcd/menu/menu_advanced.cpp +++ b/Marlin/src/lcd/menu/menu_advanced.cpp @@ -31,6 +31,7 @@ #include "menu_item.h" #include "../../MarlinCore.h" #include "../../module/planner.h" +#include "../../module/stepper.h" #if DISABLED(NO_VOLUMETRICS) #include "../../gcode/parser.h" @@ -80,8 +81,6 @@ void menu_backlash(); #if HAS_MOTOR_CURRENT_PWM - #include "../../module/stepper.h" - void menu_pwm() { START_MENU(); BACK_ITEM(MSG_ADVANCED_SETTINGS); @@ -538,6 +537,39 @@ void menu_backlash(); END_MENU(); } + #if ENABLED(SHAPING_MENU) + + void menu_advanced_input_shaping() { + constexpr float min_frequency = TERN(__AVR__, float(STEPPER_TIMER_RATE) / 2 / 0x10000, 1.0f); + + START_MENU(); + BACK_ITEM(MSG_ADVANCED_SETTINGS); + + // M593 F Frequency + #if HAS_SHAPING_X + editable.decimal = stepper.get_shaping_frequency(X_AXIS); + EDIT_ITEM_FAST(float61, MSG_SHAPING_X_FREQ, &editable.decimal, min_frequency, 200.0f, []{ stepper.set_shaping_frequency(X_AXIS, editable.decimal); }); + #endif + #if HAS_SHAPING_Y + editable.decimal = stepper.get_shaping_frequency(Y_AXIS); + EDIT_ITEM_FAST(float61, MSG_SHAPING_Y_FREQ, &editable.decimal, min_frequency, 200.0f, []{ stepper.set_shaping_frequency(Y_AXIS, editable.decimal); }); + #endif + + // M593 D Damping ratio + #if HAS_SHAPING_X + editable.decimal = stepper.get_shaping_damping_ratio(X_AXIS); + EDIT_ITEM_FAST(float42_52, MSG_SHAPING_X_ZETA, &editable.decimal, 0.0f, 1.0f, []{ stepper.set_shaping_damping_ratio(X_AXIS, editable.decimal); }); + #endif + #if HAS_SHAPING_Y + editable.decimal = stepper.get_shaping_damping_ratio(Y_AXIS); + EDIT_ITEM_FAST(float42_52, MSG_SHAPING_Y_ZETA, &editable.decimal, 0.0f, 1.0f, []{ stepper.set_shaping_damping_ratio(Y_AXIS, editable.decimal); }); + #endif + + END_MENU(); + } + + #endif + #if HAS_CLASSIC_JERK void menu_advanced_jerk() { @@ -657,6 +689,11 @@ void menu_advanced_settings() { // M201 - Acceleration items SUBMENU(MSG_ACCELERATION, menu_advanced_acceleration); + // M593 - Acceleration items + #if ENABLED(SHAPING_MENU) + SUBMENU(MSG_INPUT_SHAPING, menu_advanced_input_shaping); + #endif + #if HAS_CLASSIC_JERK // M205 - Max Jerk SUBMENU(MSG_JERK, menu_advanced_jerk); diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index 3263e7660a..dce9160664 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -2483,6 +2483,14 @@ bool Planner::_populate_block( #endif // XY_FREQUENCY_LIMIT + #if ENABLED(INPUT_SHAPING) + const float top_freq = _MIN(float(0x7FFFFFFFL) + OPTARG(HAS_SHAPING_X, stepper.get_shaping_frequency(X_AXIS)) + OPTARG(HAS_SHAPING_Y, stepper.get_shaping_frequency(Y_AXIS))), + max_factor = (top_freq * float(shaping_dividends - 3) * 2.0f) / block->nominal_rate; + NOMORE(speed_factor, max_factor); + #endif + // Correct the speed if (speed_factor < 1.0f) { current_speed *= speed_factor; diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index cb8fe217e9..f76b5afe74 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -577,6 +577,18 @@ typedef struct SettingsDataStruct { MPC_t mpc_constants[HOTENDS]; // M306 #endif + // + // Input Shaping + // + #if HAS_SHAPING_X + float shaping_x_frequency, // M593 X F + shaping_x_zeta; // M593 X D + #endif + #if HAS_SHAPING_Y + float shaping_y_frequency, // M593 Y F + shaping_y_zeta; // M593 Y D + #endif + } SettingsData; //static_assert(sizeof(SettingsData) <= MARLIN_EEPROM_SIZE, "EEPROM too small to contain SettingsData!"); @@ -1602,6 +1614,20 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(thermalManager.temp_hotend[e].constants); #endif + // + // Input Shaping + /// + #if ENABLED(INPUT_SHAPING) + #if HAS_SHAPING_X + EEPROM_WRITE(stepper.get_shaping_frequency(X_AXIS)); + EEPROM_WRITE(stepper.get_shaping_damping_ratio(X_AXIS)); + #endif + #if HAS_SHAPING_Y + EEPROM_WRITE(stepper.get_shaping_frequency(Y_AXIS)); + EEPROM_WRITE(stepper.get_shaping_damping_ratio(Y_AXIS)); + #endif + #endif + // // Report final CRC and Data Size // @@ -2573,6 +2599,27 @@ void MarlinSettings::postprocess() { } #endif + // + // Input Shaping + // + #if HAS_SHAPING_X + { + float _data[2]; + EEPROM_READ(_data); + stepper.set_shaping_frequency(X_AXIS, _data[0]); + stepper.set_shaping_damping_ratio(X_AXIS, _data[1]); + } + #endif + + #if HAS_SHAPING_Y + { + float _data[2]; + EEPROM_READ(_data); + stepper.set_shaping_frequency(Y_AXIS, _data[0]); + stepper.set_shaping_damping_ratio(Y_AXIS, _data[1]); + } + #endif + // // Validate Final Size and CRC // @@ -3343,6 +3390,20 @@ void MarlinSettings::reset() { } #endif + // + // Input Shaping + // + #if ENABLED(INPUT_SHAPING) + #if HAS_SHAPING_X + stepper.set_shaping_frequency(X_AXIS, SHAPING_FREQ_X); + stepper.set_shaping_damping_ratio(X_AXIS, SHAPING_ZETA_X); + #endif + #if HAS_SHAPING_Y + stepper.set_shaping_frequency(Y_AXIS, SHAPING_FREQ_Y); + stepper.set_shaping_damping_ratio(Y_AXIS, SHAPING_ZETA_Y); + #endif + #endif + postprocess(); #if EITHER(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE) @@ -3590,6 +3651,11 @@ void MarlinSettings::reset() { // TERN_(HAS_STEALTHCHOP, gcode.M569_report(forReplay)); + // + // Input Shaping + // + TERN_(INPUT_SHAPING, gcode.M593_report(forReplay)); + // // Linear Advance // diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 4ee4c1d1a7..6cc40ccece 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -199,7 +199,7 @@ IF_DISABLED(ADAPTIVE_STEP_SMOOTHING, constexpr) uint8_t Stepper::oversampling_fa xyze_long_t Stepper::delta_error{0}; -xyze_ulong_t Stepper::advance_dividend{0}; +xyze_long_t Stepper::advance_dividend{0}; uint32_t Stepper::advance_divisor = 0, Stepper::step_events_completed = 0, // The number of step events executed in the current block Stepper::accelerate_until, // The count at which to stop accelerating @@ -232,6 +232,20 @@ uint32_t Stepper::advance_divisor = 0, Stepper::la_advance_steps = 0; #endif +#if ENABLED(INPUT_SHAPING) + shaping_time_t DelayTimeManager::now = 0; + ParamDelayQueue Stepper::shaping_dividend_queue; + DelayQueue Stepper::shaping_queue; + #if HAS_SHAPING_X + shaping_time_t DelayTimeManager::delay_x; + ShapeParams Stepper::shaping_x; + #endif + #if HAS_SHAPING_Y + shaping_time_t DelayTimeManager::delay_y; + ShapeParams Stepper::shaping_y; + #endif +#endif + #if ENABLED(INTEGRATED_BABYSTEPPING) uint32_t Stepper::nextBabystepISR = BABYSTEP_NEVER; #endif @@ -458,12 +472,10 @@ xyze_int8_t Stepper::count_direction{0}; #define PULSE_LOW_TICK_COUNT hal_timer_t(NS_TO_PULSE_TIMER_TICKS(_MIN_PULSE_LOW_NS - _MIN(_MIN_PULSE_LOW_NS, TIMER_SETUP_NS))) #define USING_TIMED_PULSE() hal_timer_t start_pulse_count = 0 -#define START_TIMED_PULSE(DIR) (start_pulse_count = HAL_timer_get_count(MF_TIMER_PULSE)) -#define AWAIT_TIMED_PULSE(DIR) while (PULSE_##DIR##_TICK_COUNT > HAL_timer_get_count(MF_TIMER_PULSE) - start_pulse_count) { } -#define START_HIGH_PULSE() START_TIMED_PULSE(HIGH) -#define AWAIT_HIGH_PULSE() AWAIT_TIMED_PULSE(HIGH) -#define START_LOW_PULSE() START_TIMED_PULSE(LOW) -#define AWAIT_LOW_PULSE() AWAIT_TIMED_PULSE(LOW) +#define START_TIMED_PULSE() (start_pulse_count = HAL_timer_get_count(MF_TIMER_PULSE)) +#define AWAIT_TIMED_PULSE(DIR) while (PULSE_##DIR##_TICK_COUNT > HAL_timer_get_count(MF_TIMER_PULSE) - start_pulse_count) { /* nada */ } +#define AWAIT_HIGH_PULSE() AWAIT_TIMED_PULSE(HIGH) +#define AWAIT_LOW_PULSE() AWAIT_TIMED_PULSE(LOW) #if MINIMUM_STEPPER_PRE_DIR_DELAY > 0 #define DIR_WAIT_BEFORE() DELAY_NS(MINIMUM_STEPPER_PRE_DIR_DELAY) @@ -559,6 +571,16 @@ void Stepper::disable_all_steppers() { TERN_(EXTENSIBLE_UI, ExtUI::onSteppersDisabled()); } +#define SET_STEP_DIR(A) \ + if (motor_direction(_AXIS(A))) { \ + A##_APPLY_DIR(INVERT_##A##_DIR, false); \ + count_direction[_AXIS(A)] = -1; \ + } \ + else { \ + A##_APPLY_DIR(!INVERT_##A##_DIR, false); \ + count_direction[_AXIS(A)] = 1; \ + } + /** * Set the stepper direction of each axis * @@ -570,16 +592,6 @@ void Stepper::set_directions() { DIR_WAIT_BEFORE(); - #define SET_STEP_DIR(A) \ - if (motor_direction(_AXIS(A))) { \ - A##_APPLY_DIR(INVERT_##A##_DIR, false); \ - count_direction[_AXIS(A)] = -1; \ - } \ - else { \ - A##_APPLY_DIR(!INVERT_##A##_DIR, false); \ - count_direction[_AXIS(A)] = 1; \ - } - TERN_(HAS_X_DIR, SET_STEP_DIR(X)); // A TERN_(HAS_Y_DIR, SET_STEP_DIR(Y)); // B TERN_(HAS_Z_DIR, SET_STEP_DIR(Z)); // C @@ -1467,8 +1479,20 @@ void Stepper::isr() { // Enable ISRs to reduce USART processing latency hal.isr_on(); + #if ENABLED(INPUT_SHAPING) + // Speed limiting should ensure the buffers never get full. But if somehow they do, stutter rather than overflow. + if (!nextMainISR) { + TERN_(HAS_SHAPING_X, if (shaping_dividend_queue.free_count_x() == 0) nextMainISR = shaping_dividend_queue.peek_x() + 1); + TERN_(HAS_SHAPING_Y, if (shaping_dividend_queue.free_count_y() == 0) NOLESS(nextMainISR, shaping_dividend_queue.peek_y() + 1)); + TERN_(HAS_SHAPING_X, if (shaping_queue.free_count_x() < steps_per_isr) NOLESS(nextMainISR, shaping_queue.peek_x() + 1)); + TERN_(HAS_SHAPING_Y, if (shaping_queue.free_count_y() < steps_per_isr) NOLESS(nextMainISR, shaping_queue.peek_y() + 1)); + } + #endif + if (!nextMainISR) pulse_phase_isr(); // 0 = Do coordinated axes Stepper pulses + TERN_(INPUT_SHAPING, shaping_isr()); // Do Shaper stepping, if needed + #if ENABLED(LIN_ADVANCE) if (!nextAdvanceISR) { // 0 = Do Linear Advance E Stepper pulses advance_isr(); @@ -1497,10 +1521,14 @@ void Stepper::isr() { // Get the interval to the next ISR call const uint32_t interval = _MIN( - uint32_t(HAL_TIMER_TYPE_MAX), // Come back in a very long time - nextMainISR // Time until the next Pulse / Block phase - OPTARG(LIN_ADVANCE, nextAdvanceISR) // Come back early for Linear Advance? - OPTARG(INTEGRATED_BABYSTEPPING, nextBabystepISR) // Come back early for Babystepping? + uint32_t(HAL_TIMER_TYPE_MAX), // Come back in a very long time + nextMainISR // Time until the next Pulse / Block phase + OPTARG(HAS_SHAPING_X, shaping_dividend_queue.peek_x()) // Time until next input shaping dividend change for X + OPTARG(HAS_SHAPING_Y, shaping_dividend_queue.peek_y()) // Time until next input shaping dividend change for Y + OPTARG(HAS_SHAPING_X, shaping_queue.peek_x()) // Time until next input shaping echo for X + OPTARG(HAS_SHAPING_Y, shaping_queue.peek_y()) // Time until next input shaping echo for Y + OPTARG(LIN_ADVANCE, nextAdvanceISR) // Come back early for Linear Advance? + OPTARG(INTEGRATED_BABYSTEPPING, nextBabystepISR) // Come back early for Babystepping? ); // @@ -1512,6 +1540,8 @@ void Stepper::isr() { nextMainISR -= interval; + TERN_(INPUT_SHAPING, DelayTimeManager::decrement_delays(interval)); + #if ENABLED(LIN_ADVANCE) if (nextAdvanceISR != LA_ADV_NEVER) nextAdvanceISR -= interval; #endif @@ -1604,11 +1634,19 @@ void Stepper::pulse_phase_isr() { // If we must abort the current block, do so! if (abort_current_block) { abort_current_block = false; - if (current_block) discard_current_block(); + if (current_block) { + discard_current_block(); + #if ENABLED(INPUT_SHAPING) + shaping_dividend_queue.purge(); + shaping_queue.purge(); + TERN_(HAS_SHAPING_X, delta_error.x = 0); + TERN_(HAS_SHAPING_Y, delta_error.y = 0); + #endif + } } // If there is no current block, do nothing - if (!current_block) return; + if (!current_block || step_events_completed >= step_event_count) return; // Skipping step processing causes motion to freeze if (TERN0(FREEZE_FEATURE, frozen)) return; @@ -1627,6 +1665,9 @@ void Stepper::pulse_phase_isr() { #endif xyze_bool_t step_needed{0}; + // Direct Stepping page? + const bool is_page = current_block->is_page(); + do { #define _APPLY_STEP(AXIS, INV, ALWAYS) AXIS ##_APPLY_STEP(INV, ALWAYS) #define _INVERT_STEP_PIN(AXIS) INVERT_## AXIS ##_STEP_PIN @@ -1641,6 +1682,22 @@ void Stepper::pulse_phase_isr() { } \ }while(0) + #define PULSE_PREP_SHAPING(AXIS, DIVIDEND) do{ \ + delta_error[_AXIS(AXIS)] += (DIVIDEND); \ + if ((MAXDIR(AXIS) && delta_error[_AXIS(AXIS)] <= -0x30000000L) || (MINDIR(AXIS) && delta_error[_AXIS(AXIS)] >= 0x30000000L)) { \ + TBI(last_direction_bits, _AXIS(AXIS)); \ + DIR_WAIT_BEFORE(); \ + SET_STEP_DIR(AXIS); \ + DIR_WAIT_AFTER(); \ + } \ + step_needed[_AXIS(AXIS)] = (MAXDIR(AXIS) && delta_error[_AXIS(AXIS)] >= 0x10000000L) || \ + (MINDIR(AXIS) && delta_error[_AXIS(AXIS)] <= -0x10000000L); \ + if (step_needed[_AXIS(AXIS)]) { \ + count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \ + delta_error[_AXIS(AXIS)] += MAXDIR(AXIS) ? -0x20000000L : 0x20000000L; \ + } \ + }while(0) + // Start an active pulse if needed #define PULSE_START(AXIS) do{ \ if (step_needed[_AXIS(AXIS)]) { \ @@ -1655,9 +1712,6 @@ void Stepper::pulse_phase_isr() { } \ }while(0) - // Direct Stepping page? - const bool is_page = current_block->is_page(); - #if ENABLED(DIRECT_STEPPING) // Direct stepping is currently not ready for HAS_I_AXIS if (is_page) { @@ -1765,12 +1819,22 @@ void Stepper::pulse_phase_isr() { #endif // DIRECT_STEPPING if (!is_page) { + TERN_(INPUT_SHAPING, shaping_queue.enqueue()); + // Determine if pulses are needed #if HAS_X_STEP - PULSE_PREP(X); + #if HAS_SHAPING_X + PULSE_PREP_SHAPING(X, advance_dividend.x); + #else + PULSE_PREP(X); + #endif #endif #if HAS_Y_STEP - PULSE_PREP(Y); + #if HAS_SHAPING_Y + PULSE_PREP_SHAPING(Y, advance_dividend.y); + #else + PULSE_PREP(Y); + #endif #endif #if HAS_Z_STEP PULSE_PREP(Z); @@ -1855,7 +1919,7 @@ void Stepper::pulse_phase_isr() { // TODO: need to deal with MINIMUM_STEPPER_PULSE over i2s #if ISR_MULTI_STEPS - START_HIGH_PULSE(); + START_TIMED_PULSE(); AWAIT_HIGH_PULSE(); #endif @@ -1895,12 +1959,62 @@ void Stepper::pulse_phase_isr() { #endif #if ISR_MULTI_STEPS - if (events_to_do) START_LOW_PULSE(); + if (events_to_do) START_TIMED_PULSE(); #endif } while (--events_to_do); } +#if ENABLED(INPUT_SHAPING) + + void Stepper::shaping_isr() { + xyze_bool_t step_needed{0}; + + const bool shapex = TERN0(HAS_SHAPING_X, !shaping_queue.peek_x()), + shapey = TERN0(HAS_SHAPING_Y, !shaping_queue.peek_y()); + + #if HAS_SHAPING_X + if (!shaping_dividend_queue.peek_x()) shaping_x.dividend = shaping_dividend_queue.dequeue_x(); + #endif + #if HAS_SHAPING_Y + if (!shaping_dividend_queue.peek_y()) shaping_y.dividend = shaping_dividend_queue.dequeue_y(); + #endif + + #if HAS_SHAPING_X + if (shapex) { + shaping_queue.dequeue_x(); + PULSE_PREP_SHAPING(X, shaping_x.dividend); + PULSE_START(X); + } + #endif + + #if HAS_SHAPING_Y + if (shapey) { + shaping_queue.dequeue_y(); + PULSE_PREP_SHAPING(Y, shaping_y.dividend); + PULSE_START(Y); + } + #endif + + TERN_(I2S_STEPPER_STREAM, i2s_push_sample()); + + if (shapex || shapey) { + #if ISR_MULTI_STEPS + USING_TIMED_PULSE(); + START_TIMED_PULSE(); + AWAIT_HIGH_PULSE(); + #endif + #if HAS_SHAPING_X + if (shapex) PULSE_STOP(X); + #endif + #if HAS_SHAPING_Y + if (shapey) PULSE_STOP(Y); + #endif + } + } + +#endif // INPUT_SHAPING + // Calculate timer interval, with all limits applied. uint32_t Stepper::calc_timer_interval(uint32_t step_rate) { #ifdef CPU_32_BIT @@ -2365,12 +2479,56 @@ uint32_t Stepper::block_phase_isr() { step_event_count = current_block->step_event_count << oversampling; // Initialize Bresenham delta errors to 1/2 + #if HAS_SHAPING_X + const int32_t old_delta_error_x = delta_error.x; + #endif + #if HAS_SHAPING_Y + const int32_t old_delta_error_y = delta_error.y; + #endif delta_error = TERN_(LIN_ADVANCE, la_delta_error =) -int32_t(step_event_count); // Calculate Bresenham dividends and divisors - advance_dividend = current_block->steps << 1; + advance_dividend = (current_block->steps << 1).asLong(); advance_divisor = step_event_count << 1; + // for input shaped axes, advance_divisor is replaced with 0x40000000 + // and steps are repeated twice so dividends have to be scaled and halved + // and the dividend is directional, i.e. signed + TERN_(HAS_SHAPING_X, advance_dividend.x = (uint64_t(current_block->steps.x) << 29) / step_event_count); + TERN_(HAS_SHAPING_X, if (TEST(current_block->direction_bits, X_AXIS)) advance_dividend.x *= -1); + TERN_(HAS_SHAPING_X, if (!shaping_queue.empty_x()) SET_BIT_TO(current_block->direction_bits, X_AXIS, TEST(last_direction_bits, X_AXIS))); + TERN_(HAS_SHAPING_Y, advance_dividend.y = (uint64_t(current_block->steps.y) << 29) / step_event_count); + TERN_(HAS_SHAPING_Y, if (TEST(current_block->direction_bits, Y_AXIS)) advance_dividend.y *= -1); + TERN_(HAS_SHAPING_Y, if (!shaping_queue.empty_y()) SET_BIT_TO(current_block->direction_bits, Y_AXIS, TEST(last_direction_bits, Y_AXIS))); + + // The scaling operation above introduces rounding errors which must now be removed. + // For this segment, there will be step_event_count calls to the Bresenham logic and the same number of echoes. + // For each pair of calls to the Bresenham logic, delta_error will increase by advance_dividend modulo 0x20000000 + // so (e.g. for x) delta_error.x will end up changing by (advance_dividend.x * step_event_count) % 0x20000000. + // For a divisor which is a power of 2, modulo is the same as as a bitmask, i.e. + // (advance_dividend.x * step_event_count) & 0x1FFFFFFF. + // This segment's final change in delta_error should actually be zero so we need to increase delta_error by + // 0 - ((advance_dividend.x * step_event_count) & 0x1FFFFFFF) + // And this needs to be adjusted to the range -0x10000000 to 0x10000000. + // Adding and subtracting 0x10000000 inside the outside the modulo achieves this. + TERN_(HAS_SHAPING_X, delta_error.x = old_delta_error_x + 0x10000000L - ((0x10000000L + advance_dividend.x * step_event_count) & 0x1FFFFFFFUL)); + TERN_(HAS_SHAPING_Y, delta_error.y = old_delta_error_y + 0x10000000L - ((0x10000000L + advance_dividend.y * step_event_count) & 0x1FFFFFFFUL)); + + // when there is damping, the signal and its echo have different amplitudes + #if ENABLED(HAS_SHAPING_X) + const int32_t echo_x = shaping_x.factor * (advance_dividend.x >> 7); + #endif + #if ENABLED(HAS_SHAPING_Y) + const int32_t echo_y = shaping_y.factor * (advance_dividend.y >> 7); + #endif + + // plan the change of values for advance_dividend for the input shaping echoes + TERN_(INPUT_SHAPING, shaping_dividend_queue.enqueue(TERN0(HAS_SHAPING_X, echo_x), TERN0(HAS_SHAPING_Y, echo_y))); + + // apply the adjustment to the primary signal + TERN_(HAS_SHAPING_X, advance_dividend.x -= echo_x); + TERN_(HAS_SHAPING_Y, advance_dividend.y -= echo_y); + // No step events completed so far step_events_completed = 0; @@ -2485,7 +2643,7 @@ uint32_t Stepper::block_phase_isr() { // Enforce a minimum duration for STEP pulse ON #if ISR_PULSE_CONTROL USING_TIMED_PULSE(); - START_HIGH_PULSE(); + START_TIMED_PULSE(); AWAIT_HIGH_PULSE(); #endif @@ -2816,6 +2974,51 @@ void Stepper::init() { #endif } +#if ENABLED(INPUT_SHAPING) + /** + * Calculate a fixed point factor to apply to the signal and its echo + * when shaping an axis. + */ + void Stepper::set_shaping_damping_ratio(const AxisEnum axis, const float zeta) { + // from the damping ratio, get a factor that can be applied to advance_dividend for fixed point maths + // for ZV, we use amplitudes 1/(1+K) and K/(1+K) where K = exp(-zeta * M_PI / sqrt(1.0f - zeta * zeta)) + // which can be converted to 1:7 fixed point with an excellent fit with a 3rd order polynomial + float shaping_factor; + if (zeta <= 0.0f) shaping_factor = 64.0f; + else if (zeta >= 1.0f) shaping_factor = 0.0f; + else { + shaping_factor = 64.44056192 + -99.02008832 * zeta; + const float zeta2 = zeta * zeta; + shaping_factor += -7.58095488 * zeta2; + const float zeta3 = zeta2 * zeta; + shaping_factor += 43.073216 * zeta3; + } + + const bool was_on = hal.isr_state(); + hal.isr_off(); + TERN_(HAS_SHAPING_X, if (axis == X_AXIS) { shaping_x.factor = floor(shaping_factor); shaping_x.zeta = zeta; }) + TERN_(HAS_SHAPING_Y, if (axis == Y_AXIS) { shaping_y.factor = floor(shaping_factor); shaping_y.zeta = zeta; }) + if (was_on) hal.isr_on(); + } + + float Stepper::get_shaping_damping_ratio(const AxisEnum axis) { + TERN_(HAS_SHAPING_X, if (axis == X_AXIS) return shaping_x.zeta); + TERN_(HAS_SHAPING_Y, if (axis == Y_AXIS) return shaping_y.zeta); + return -1; + } + + void Stepper::set_shaping_frequency(const AxisEnum axis, const float freq) { + TERN_(HAS_SHAPING_X, if (axis == X_AXIS) { DelayTimeManager::set_delay(axis, float(uint32_t(STEPPER_TIMER_RATE) / 2) / freq); shaping_x.frequency = freq; }) + TERN_(HAS_SHAPING_Y, if (axis == Y_AXIS) { DelayTimeManager::set_delay(axis, float(uint32_t(STEPPER_TIMER_RATE) / 2) / freq); shaping_y.frequency = freq; }) + } + + float Stepper::get_shaping_frequency(const AxisEnum axis) { + TERN_(HAS_SHAPING_X, if (axis == X_AXIS) return shaping_x.frequency); + TERN_(HAS_SHAPING_Y, if (axis == Y_AXIS) return shaping_y.frequency); + return -1; + } +#endif + /** * Set the stepper positions directly in steps * @@ -3021,7 +3224,7 @@ void Stepper::report_positions() { #if EXTRA_CYCLES_BABYSTEP > 20 #define _SAVE_START() const hal_timer_t pulse_start = HAL_timer_get_count(MF_TIMER_PULSE) - #define _PULSE_WAIT() while (EXTRA_CYCLES_BABYSTEP > (uint32_t)(HAL_timer_get_count(MF_TIMER_PULSE) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ } + #define _PULSE_WAIT() while (EXTRA_CYCLES_BABYSTEP > uint32_t(HAL_timer_get_count(MF_TIMER_PULSE) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ } #else #define _SAVE_START() NOOP #if EXTRA_CYCLES_BABYSTEP > 0 diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 729ab83266..5b634c52e4 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -312,6 +312,117 @@ constexpr ena_mask_t enable_overlap[] = { //static_assert(!any_enable_overlap(), "There is some overlap."); +#if ENABLED(INPUT_SHAPING) + + typedef IF::type shaping_time_t; + + // These constexpr are used to calculate the shaping queue buffer sizes + constexpr xyze_float_t max_feedrate = DEFAULT_MAX_FEEDRATE; + constexpr xyze_float_t steps_per_unit = DEFAULT_AXIS_STEPS_PER_UNIT; + constexpr float max_steprate = _MAX(LOGICAL_AXIS_LIST( + max_feedrate.e * steps_per_unit.e, + max_feedrate.x * steps_per_unit.x, + max_feedrate.y * steps_per_unit.y, + max_feedrate.z * steps_per_unit.z, + max_feedrate.i * steps_per_unit.i, + max_feedrate.j * steps_per_unit.j, + max_feedrate.k * steps_per_unit.k, + max_feedrate.u * steps_per_unit.u, + max_feedrate.v * steps_per_unit.v, + max_feedrate.w * steps_per_unit.w + )); + constexpr uint16_t shaping_dividends = max_steprate / _MIN(0x7FFFFFFFL OPTARG(HAS_SHAPING_X, SHAPING_FREQ_X) OPTARG(HAS_SHAPING_Y, SHAPING_FREQ_Y)) / 2 + 3; + constexpr uint16_t shaping_segments = max_steprate / (MIN_STEPS_PER_SEGMENT) / _MIN(0x7FFFFFFFL OPTARG(HAS_SHAPING_X, SHAPING_FREQ_X) OPTARG(HAS_SHAPING_Y, SHAPING_FREQ_Y)) / 2 + 3; + + class DelayTimeManager { + private: + static shaping_time_t now; + #ifdef HAS_SHAPING_X + static shaping_time_t delay_x; + #endif + #ifdef HAS_SHAPING_Y + static shaping_time_t delay_y; + #endif + public: + static void decrement_delays(const shaping_time_t interval) { now += interval; } + static void set_delay(const AxisEnum axis, const shaping_time_t delay) { + TERN_(HAS_SHAPING_X, if (axis == X_AXIS) delay_x = delay); + TERN_(HAS_SHAPING_Y, if (axis == Y_AXIS) delay_y = delay); + } + }; + + template + class DelayQueue : public DelayTimeManager { + protected: + shaping_time_t times[SIZE]; + uint16_t tail = 0 OPTARG(HAS_SHAPING_X, head_x = 0) OPTARG(HAS_SHAPING_Y, head_y = 0); + + public: + void enqueue() { + times[tail] = now; + if (++tail == SIZE) tail = 0; + } + #ifdef HAS_SHAPING_X + shaping_time_t peek_x() { + if (head_x != tail) return times[head_x] + delay_x - now; + else return shaping_time_t(-1); + } + void dequeue_x() { if (++head_x == SIZE) head_x = 0; } + bool empty_x() { return head_x == tail; } + uint16_t free_count_x() { return head_x > tail ? head_x - tail - 1 : head_x + SIZE - tail - 1; } + #endif + #ifdef HAS_SHAPING_Y + shaping_time_t peek_y() { + if (head_y != tail) return times[head_y] + delay_y - now; + else return shaping_time_t(-1); + } + void dequeue_y() { if (++head_y == SIZE) head_y = 0; } + bool empty_y() { return head_y == tail; } + uint16_t free_count_y() { return head_y > tail ? head_y - tail - 1 : head_y + SIZE - tail - 1; } + #endif + void purge() { auto temp = TERN_(HAS_SHAPING_X, head_x) = TERN_(HAS_SHAPING_Y, head_y) = tail; UNUSED(temp);} + }; + + class ParamDelayQueue : public DelayQueue { + private: + #ifdef HAS_SHAPING_X + int32_t params_x[shaping_segments]; + #endif + #ifdef HAS_SHAPING_Y + int32_t params_y[shaping_segments]; + #endif + + public: + void enqueue(const int32_t param_x, const int32_t param_y) { + TERN(HAS_SHAPING_X, params_x[DelayQueue::tail] = param_x, UNUSED(param_x)); + TERN(HAS_SHAPING_Y, params_y[DelayQueue::tail] = param_y, UNUSED(param_y)); + DelayQueue::enqueue(); + } + #ifdef HAS_SHAPING_X + const int32_t dequeue_x() { + const int32_t result = params_x[DelayQueue::head_x]; + DelayQueue::dequeue_x(); + return result; + } + #endif + #ifdef HAS_SHAPING_Y + const int32_t dequeue_y() { + const int32_t result = params_y[DelayQueue::head_y]; + DelayQueue::dequeue_y(); + return result; + } + #endif + }; + + struct ShapeParams { + float frequency; + float zeta; + uint8_t factor; + int32_t dividend; + }; + +#endif // INPUT_SHAPING + // // Stepper class definition // @@ -391,7 +502,7 @@ class Stepper { // Delta error variables for the Bresenham line tracer static xyze_long_t delta_error; - static xyze_ulong_t advance_dividend; + static xyze_long_t advance_dividend; static uint32_t advance_divisor, step_events_completed, // The number of step events executed in the current block accelerate_until, // The point from where we need to stop acceleration @@ -416,6 +527,17 @@ class Stepper { static bool bezier_2nd_half; // If Bézier curve has been initialized or not #endif + #if ENABLED(INPUT_SHAPING) + static ParamDelayQueue shaping_dividend_queue; + static DelayQueue shaping_queue; + #if HAS_SHAPING_X + static ShapeParams shaping_x; + #endif + #if HAS_SHAPING_Y + static ShapeParams shaping_y; + #endif + #endif + #if ENABLED(LIN_ADVANCE) static constexpr uint32_t LA_ADV_NEVER = 0xFFFFFFFF; static uint32_t nextAdvanceISR, @@ -475,6 +597,10 @@ class Stepper { // The stepper block processing ISR phase static uint32_t block_phase_isr(); + #if ENABLED(INPUT_SHAPING) + static void shaping_isr(); + #endif + #if ENABLED(LIN_ADVANCE) // The Linear advance ISR phase static void advance_isr(); @@ -628,6 +754,13 @@ class Stepper { set_directions(); } + #if ENABLED(INPUT_SHAPING) + static void set_shaping_damping_ratio(const AxisEnum axis, const float zeta); + static float get_shaping_damping_ratio(const AxisEnum axis); + static void set_shaping_frequency(const AxisEnum axis, const float freq); + static float get_shaping_frequency(const AxisEnum axis); + #endif + private: // Set the current position in steps diff --git a/buildroot/tests/mega2560 b/buildroot/tests/mega2560 index 86b2779032..333be2f0fa 100755 --- a/buildroot/tests/mega2560 +++ b/buildroot/tests/mega2560 @@ -80,7 +80,7 @@ opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO MIXING_STEPPERS 5 LCD_LANGUAGE ru \ FIL_RUNOUT2_PIN 16 FIL_RUNOUT3_PIN 17 FIL_RUNOUT4_PIN 4 FIL_RUNOUT5_PIN 5 opt_enable MIXING_EXTRUDER GRADIENT_MIX GRADIENT_VTOOL CR10_STOCKDISPLAY \ USE_CONTROLLER_FAN CONTROLLER_FAN_EDITABLE CONTROLLER_FAN_IGNORE_Z \ - FILAMENT_RUNOUT_SENSOR ADVANCED_PAUSE_FEATURE NOZZLE_PARK_FEATURE + FILAMENT_RUNOUT_SENSOR ADVANCED_PAUSE_FEATURE NOZZLE_PARK_FEATURE INPUT_SHAPING opt_disable DISABLE_INACTIVE_EXTRUDER exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Greek" "$3" diff --git a/ini/features.ini b/ini/features.ini index 5f30db8a2f..7c8fd2fd8f 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -187,6 +187,7 @@ HAS_DUPLICATION_MODE = src_filter=+ PHOTO_GCODE = src_filter=+ CONTROLLER_FAN_EDITABLE = src_filter=+ +INPUT_SHAPING = src_filter=+ GCODE_MACROS = src_filter=+ GRADIENT_MIX = src_filter=+ HAS_SAVED_POSITIONS = src_filter=+ + diff --git a/platformio.ini b/platformio.ini index 751543c8a3..613f2c963a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -192,6 +192,7 @@ default_src_filter = + - - + - - - + - - - - From ed1252642f43ccebfb329e74d46b745f8d3aa00f Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Sat, 22 Oct 2022 00:33:26 +0000 Subject: [PATCH 14/24] [cron] Bump distribution date (2022-10-22) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index dae6ae3368..5b21d2209e 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2022-10-21" +//#define STRING_DISTRIBUTION_DATE "2022-10-22" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 510641cf1d..05776b4a80 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2022-10-21" + #define STRING_DISTRIBUTION_DATE "2022-10-22" #endif /** From fd0c6fa153246e0ffa3a5b39b617c75f66857162 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 21 Oct 2022 19:45:20 -0500 Subject: [PATCH 15/24] =?UTF-8?q?=F0=9F=94=A7=20Clean=20up=20unused=20ESP?= =?UTF-8?q?=5FWIFI=20pins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/inc/Conditionals_post.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 417ce4479a..21f0eed622 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2543,6 +2543,21 @@ #undef TMC_UART_IS #undef ANY_SERIAL_IS +// Clean up unused ESP_WIFI pins +#ifdef ESP_WIFI_MODULE_COM + #if !SERIAL_IN_USE(ESP_WIFI_MODULE_COM) + #undef ESP_WIFI_MODULE_COM + #undef ESP_WIFI_MODULE_BAUDRATE + #undef ESP_WIFI_MODULE_RESET_PIN + #undef ESP_WIFI_MODULE_ENABLE_PIN + #undef ESP_WIFI_MODULE_TXD_PIN + #undef ESP_WIFI_MODULE_RXD_PIN + #undef ESP_WIFI_MODULE_GPIO0_PIN + #undef ESP_WIFI_MODULE_GPIO2_PIN + #undef ESP_WIFI_MODULE_GPIO4_PIN + #endif +#endif + // // Endstops and bed probe // From 1b31a7cf2c1b5cc1f7b58041604fa8b8ebb3ffe7 Mon Sep 17 00:00:00 2001 From: kurtis-potier-geofabrica <77456752+kurtis-potier-geofabrica@users.noreply.github.com> Date: Sat, 22 Oct 2022 00:13:56 -0400 Subject: [PATCH 16/24] =?UTF-8?q?=F0=9F=9A=B8=20Up=20to=203=20MAX=20Thermo?= =?UTF-8?q?couples=20(#24898)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/Configuration.h | 4 + Marlin/Configuration_adv.h | 2 + Marlin/src/inc/Conditionals_adv.h | 100 ++++++++++++++++-------- Marlin/src/inc/Conditionals_post.h | 85 ++++++++++++++++++-- Marlin/src/inc/SanityCheck.h | 23 ++++-- Marlin/src/module/temperature.cpp | 121 +++++++++++++++++++++++------ 6 files changed, 261 insertions(+), 74 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 83c1c541e3..87a98298a5 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -564,6 +564,10 @@ #define MAX31865_SENSOR_OHMS_1 100 #define MAX31865_CALIBRATION_OHMS_1 430 #endif +#if TEMP_SENSOR_IS_MAX_TC(2) + #define MAX31865_SENSOR_OHMS_2 100 + #define MAX31865_CALIBRATION_OHMS_2 430 +#endif #if HAS_E_TEMP_SENSOR #define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109 diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 01a2bd85c5..9a54b10b82 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -175,6 +175,7 @@ //#define TEMP_SENSOR_FORCE_HW_SPI // Ignore SCK/MOSI/MISO pins; use CS and the default SPI bus. //#define MAX31865_SENSOR_WIRES_0 2 // (2-4) Number of wires for the probe connected to a MAX31865 board. //#define MAX31865_SENSOR_WIRES_1 2 +//#define MAX31865_SENSOR_WIRES_2 2 //#define MAX31865_50HZ_FILTER // Use a 50Hz filter instead of the default 60Hz. //#define MAX31865_USE_READ_ERROR_DETECTION // Treat value spikes (20°C delta in under 1s) as read errors. @@ -185,6 +186,7 @@ //#define MAX31865_WIRE_OHMS_0 0.95f // For 2-wire, set the wire resistances for more accurate readings. //#define MAX31865_WIRE_OHMS_1 0.0f +//#define MAX31865_WIRE_OHMS_2 0.0f /** * Hephestos 2 24V heated bed upgrade kit. diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 1f8f0ddfb6..dd69e61c92 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -262,26 +262,72 @@ #undef HEATER_1_MAXTEMP #endif +#if TEMP_SENSOR_IS_MAX_TC(2) + #if TEMP_SENSOR_2 == -5 + #define TEMP_SENSOR_2_IS_MAX31865 1 + #define TEMP_SENSOR_2_MAX_TC_TMIN 0 + #define TEMP_SENSOR_2_MAX_TC_TMAX 1024 + #ifndef MAX31865_SENSOR_WIRES_2 + #define MAX31865_SENSOR_WIRES_2 2 + #endif + #ifndef MAX31865_WIRE_OHMS_2 + #define MAX31865_WIRE_OHMS_2 0.0f + #endif + #elif TEMP_SENSOR_2 == -3 + #define TEMP_SENSOR_2_IS_MAX31855 1 + #define TEMP_SENSOR_2_MAX_TC_TMIN -270 + #define TEMP_SENSOR_2_MAX_TC_TMAX 1800 + #elif TEMP_SENSOR_2 == -2 + #define TEMP_SENSOR_2_IS_MAX6675 1 + #define TEMP_SENSOR_2_MAX_TC_TMIN 0 + #define TEMP_SENSOR_2_MAX_TC_TMAX 1024 + #endif + + #if TEMP_SENSOR_2 != TEMP_SENSOR_0 + #if TEMP_SENSOR_2 == -5 + #error "If MAX31865 Thermocouple (-5) is used for TEMP_SENSOR_2 then TEMP_SENSOR_0 must match." + #elif TEMP_SENSOR_2 == -3 + #error "If MAX31855 Thermocouple (-3) is used for TEMP_SENSOR_2 then TEMP_SENSOR_0 must match." + #elif TEMP_SENSOR_2 == -2 + #error "If MAX6675 Thermocouple (-2) is used for TEMP_SENSOR_2 then TEMP_SENSOR_0 must match." + #endif + #endif +#elif TEMP_SENSOR_2 == -4 + #define TEMP_SENSOR_2_IS_AD8495 1 +#elif TEMP_SENSOR_2 == -1 + #define TEMP_SENSOR_2_IS_AD595 1 +#elif TEMP_SENSOR_2 > 0 + #define TEMP_SENSOR_2_IS_THERMISTOR 1 + #if TEMP_SENSOR_2 == 1000 + #define TEMP_SENSOR_2_IS_CUSTOM 1 + #elif TEMP_SENSOR_2 == 998 || TEMP_SENSOR_2 == 999 + #define TEMP_SENSOR_2_IS_DUMMY 1 + #endif +#else + #undef HEATER_2_MINTEMP + #undef HEATER_2_MAXTEMP +#endif + #if TEMP_SENSOR_IS_MAX_TC(REDUNDANT) #if TEMP_SENSOR_REDUNDANT == -5 - #if !REDUNDANT_TEMP_MATCH(SOURCE, E0) && !REDUNDANT_TEMP_MATCH(SOURCE, E1) - #error "MAX31865 Thermocouples (-5) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1 (0/1)." + #if !REDUNDANT_TEMP_MATCH(SOURCE, E0) && !REDUNDANT_TEMP_MATCH(SOURCE, E1) && !REDUNDANT_TEMP_MATCH(SOURCE, E2) + #error "MAX31865 Thermocouples (-5) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1/TEMP_SENSOR_2 (0/1/2)." #endif #define TEMP_SENSOR_REDUNDANT_IS_MAX31865 1 #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN 0 #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX 1024 #elif TEMP_SENSOR_REDUNDANT == -3 - #if !REDUNDANT_TEMP_MATCH(SOURCE, E0) && !REDUNDANT_TEMP_MATCH(SOURCE, E1) - #error "MAX31855 Thermocouples (-3) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1 (0/1)." + #if !REDUNDANT_TEMP_MATCH(SOURCE, E0) && !REDUNDANT_TEMP_MATCH(SOURCE, E1) && !REDUNDANT_TEMP_MATCH(SOURCE, E2) + #error "MAX31855 Thermocouples (-3) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1/TEMP_SENSOR_2 (0/1/2)." #endif #define TEMP_SENSOR_REDUNDANT_IS_MAX31855 1 #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN -270 #define TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX 1800 #elif TEMP_SENSOR_REDUNDANT == -2 - #if !REDUNDANT_TEMP_MATCH(SOURCE, E0) && !REDUNDANT_TEMP_MATCH(SOURCE, E1) - #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1 (0/1)." + #if !REDUNDANT_TEMP_MATCH(SOURCE, E0) && !REDUNDANT_TEMP_MATCH(SOURCE, E1) && !REDUNDANT_TEMP_MATCH(SOURCE, E2) + #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_REDUNDANT_SOURCE other than TEMP_SENSOR_0/TEMP_SENSOR_1/TEMP_SENSOR_2 (0/1/2)." #endif #define TEMP_SENSOR_REDUNDANT_IS_MAX6675 1 @@ -302,15 +348,21 @@ #ifndef MAX31865_SENSOR_WIRES_1 #define MAX31865_SENSOR_WIRES_1 2 #endif + #elif REDUNDANT_TEMP_MATCH(SOURCE, E2) + #define TEMP_SENSOR_2_MAX_TC_TMIN TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN + #define TEMP_SENSOR_2_MAX_TC_TMAX TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX + #ifndef MAX31865_SENSOR_WIRES_2 + #define MAX31865_SENSOR_WIRES_2 2 + #endif #endif - #if (TEMP_SENSOR_IS_MAX_TC(0) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_0) || (TEMP_SENSOR_IS_MAX_TC(1) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_1) + #if (TEMP_SENSOR_IS_MAX_TC(0) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_0) || (TEMP_SENSOR_IS_MAX_TC(1) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_1) || (TEMP_SENSOR_IS_MAX_TC(2) && TEMP_SENSOR_REDUNDANT != TEMP_SENSOR_2) #if TEMP_SENSOR_REDUNDANT == -5 - #error "If MAX31865 Thermocouple (-5) is used for TEMP_SENSOR_0/TEMP_SENSOR_1 then TEMP_SENSOR_REDUNDANT must match." + #error "If MAX31865 Thermocouple (-5) is used for TEMP_SENSOR_0/TEMP_SENSOR_1/TEMP_SENSOR_2 then TEMP_SENSOR_REDUNDANT must match." #elif TEMP_SENSOR_REDUNDANT == -3 - #error "If MAX31855 Thermocouple (-3) is used for TEMP_SENSOR_0/TEMP_SENSOR_1 then TEMP_SENSOR_REDUNDANT must match." + #error "If MAX31855 Thermocouple (-3) is used for TEMP_SENSOR_0/TEMP_SENSOR_1/TEMP_SENSOR_2 then TEMP_SENSOR_REDUNDANT must match." #elif TEMP_SENSOR_REDUNDANT == -2 - #error "If MAX6675 Thermocouple (-2) is used for TEMP_SENSOR_0/TEMP_SENSOR_1 then TEMP_SENSOR_REDUNDANT must match." + #error "If MAX6675 Thermocouple (-2) is used for TEMP_SENSOR_0/TEMP_SENSOR_1/TEMP_SENSOR_2 then TEMP_SENSOR_REDUNDANT must match." #endif #endif #elif TEMP_SENSOR_REDUNDANT == -4 @@ -326,39 +378,19 @@ #endif #endif -#if TEMP_SENSOR_IS_MAX_TC(0) || TEMP_SENSOR_IS_MAX_TC(1) || TEMP_SENSOR_IS_MAX_TC(REDUNDANT) +#if TEMP_SENSOR_IS_MAX_TC(0) || TEMP_SENSOR_IS_MAX_TC(1) || TEMP_SENSOR_IS_MAX_TC(2) || TEMP_SENSOR_IS_MAX_TC(REDUNDANT) #define HAS_MAX_TC 1 #endif -#if TEMP_SENSOR_0_IS_MAX6675 || TEMP_SENSOR_1_IS_MAX6675 || TEMP_SENSOR_REDUNDANT_IS_MAX6675 +#if TEMP_SENSOR_0_IS_MAX6675 || TEMP_SENSOR_1_IS_MAX6675 || TEMP_SENSOR_2_IS_MAX6675 || TEMP_SENSOR_REDUNDANT_IS_MAX6675 #define HAS_MAX6675 1 #endif -#if TEMP_SENSOR_0_IS_MAX31855 || TEMP_SENSOR_1_IS_MAX31855 || TEMP_SENSOR_REDUNDANT_IS_MAX31855 +#if TEMP_SENSOR_0_IS_MAX31855 || TEMP_SENSOR_1_IS_MAX31855 || TEMP_SENSOR_2_IS_MAX31855 || TEMP_SENSOR_REDUNDANT_IS_MAX31855 #define HAS_MAX31855 1 #endif -#if TEMP_SENSOR_0_IS_MAX31865 || TEMP_SENSOR_1_IS_MAX31865 || TEMP_SENSOR_REDUNDANT_IS_MAX31865 +#if TEMP_SENSOR_0_IS_MAX31865 || TEMP_SENSOR_1_IS_MAX31865 || TEMP_SENSOR_2_IS_MAX31865 || TEMP_SENSOR_REDUNDANT_IS_MAX31865 #define HAS_MAX31865 1 #endif -#if TEMP_SENSOR_2 == -4 - #define TEMP_SENSOR_2_IS_AD8495 1 -#elif TEMP_SENSOR_2 == -3 - #error "MAX31855 Thermocouples (-3) not supported for TEMP_SENSOR_2." -#elif TEMP_SENSOR_2 == -2 - #error "MAX6675 Thermocouples (-2) not supported for TEMP_SENSOR_2." -#elif TEMP_SENSOR_2 == -1 - #define TEMP_SENSOR_2_IS_AD595 1 -#elif TEMP_SENSOR_2 > 0 - #define TEMP_SENSOR_2_IS_THERMISTOR 1 - #if TEMP_SENSOR_2 == 1000 - #define TEMP_SENSOR_2_IS_CUSTOM 1 - #elif TEMP_SENSOR_2 == 998 || TEMP_SENSOR_2 == 999 - #define TEMP_SENSOR_2_IS_DUMMY 1 - #endif -#else - #undef HEATER_2_MINTEMP - #undef HEATER_2_MAXTEMP -#endif - #if TEMP_SENSOR_3 == -4 #define TEMP_SENSOR_3_IS_AD8495 1 #elif TEMP_SENSOR_3 == -3 diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 21f0eed622..5f54039392 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -723,19 +723,19 @@ #define TEMP_0_SCK_PIN MAX31855_SCK_PIN #endif - #elif TEMP_SENSOR_1_IS_MAX31865 - #if !PIN_EXISTS(TEMP_1_MISO) // DO + #elif TEMP_SENSOR_0_IS_MAX31865 + #if !PIN_EXISTS(TEMP_0_MISO) // DO #if PIN_EXISTS(MAX31865_MISO) - #define TEMP_1_MISO_PIN MAX31865_MISO_PIN + #define TEMP_0_MISO_PIN MAX31865_MISO_PIN #elif PIN_EXISTS(MAX31865_DO) - #define TEMP_1_MISO_PIN MAX31865_DO_PIN + #define TEMP_0_MISO_PIN MAX31865_DO_PIN #endif #endif - #if !PIN_EXISTS(TEMP_1_SCK) && PIN_EXISTS(MAX31865_SCK) - #define TEMP_1_SCK_PIN MAX31865_SCK_PIN + #if !PIN_EXISTS(TEMP_0_SCK) && PIN_EXISTS(MAX31865_SCK) + #define TEMP_0_SCK_PIN MAX31865_SCK_PIN #endif - #if !PIN_EXISTS(TEMP_1_MOSI) && PIN_EXISTS(MAX31865_MOSI) // MOSI for '65 only - #define TEMP_1_MOSI_PIN MAX31865_MOSI_PIN + #if !PIN_EXISTS(TEMP_0_MOSI) && PIN_EXISTS(MAX31865_MOSI) // MOSI for '65 only + #define TEMP_0_MOSI_PIN MAX31865_MOSI_PIN #endif #endif @@ -819,6 +819,75 @@ #endif // TEMP_SENSOR_IS_MAX_TC(1) + #if TEMP_SENSOR_IS_MAX_TC(2) || (TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E2)) + + #if !PIN_EXISTS(TEMP_2_CS) // SS3, CS3 + #if PIN_EXISTS(MAX6675_SS3) + #define TEMP_2_CS_PIN MAX6675_SS3_PIN + #elif PIN_EXISTS(MAX6675_CS) + #define TEMP_2_CS_PIN MAX6675_CS3_PIN + #elif PIN_EXISTS(MAX31855_SS3) + #define TEMP_2_CS_PIN MAX31855_SS3_PIN + #elif PIN_EXISTS(MAX31855_CS3) + #define TEMP_2_CS_PIN MAX31855_CS3_PIN + #elif PIN_EXISTS(MAX31865_SS3) + #define TEMP_2_CS_PIN MAX31865_SS3_PIN + #elif PIN_EXISTS(MAX31865_CS3) + #define TEMP_2_CS_PIN MAX31865_CS3_PIN + #endif + #endif + + #if TEMP_SENSOR_2_IS_MAX6675 + #if !PIN_EXISTS(TEMP_2_MISO) // DO + #if PIN_EXISTS(MAX6675_MISO) + #define TEMP_2_MISO_PIN MAX6675_MISO_PIN + #elif PIN_EXISTS(MAX6675_DO) + #define TEMP_2_MISO_PIN MAX6675_DO_PIN + #endif + #endif + #if !PIN_EXISTS(TEMP_2_SCK) && PIN_EXISTS(MAX6675_SCK) + #define TEMP_2_SCK_PIN MAX6675_SCK_PIN + #endif + + #elif TEMP_SENSOR_2_IS_MAX31855 + #if !PIN_EXISTS(TEMP_2_MISO) // DO + #if PIN_EXISTS(MAX31855_MISO) + #define TEMP_2_MISO_PIN MAX31855_MISO_PIN + #elif PIN_EXISTS(MAX31855_DO) + #define TEMP_2_MISO_PIN MAX31855_DO_PIN + #endif + #endif + #if !PIN_EXISTS(TEMP_2_SCK) && PIN_EXISTS(MAX31855_SCK) + #define TEMP_2_SCK_PIN MAX31855_SCK_PIN + #endif + + #elif TEMP_SENSOR_2_IS_MAX31865 + #if !PIN_EXISTS(TEMP_2_MISO) // DO + #if PIN_EXISTS(MAX31865_MISO) + #define TEMP_2_MISO_PIN MAX31865_MISO_PIN + #elif PIN_EXISTS(MAX31865_DO) + #define TEMP_2_MISO_PIN MAX31865_DO_PIN + #endif + #endif + #if !PIN_EXISTS(TEMP_2_SCK) && PIN_EXISTS(MAX31865_SCK) + #define TEMP_2_SCK_PIN MAX31865_SCK_PIN + #endif + #if !PIN_EXISTS(TEMP_2_MOSI) && PIN_EXISTS(MAX31865_MOSI) // MOSI for '65 only + #define TEMP_2_MOSI_PIN MAX31865_MOSI_PIN + #endif + #endif + + // Software SPI - enable if MISO/SCK are defined. + #if PIN_EXISTS(TEMP_2_MISO) && PIN_EXISTS(TEMP_2_SCK) && DISABLED(TEMP_SENSOR_2_FORCE_HW_SPI) + #if TEMP_SENSOR_2_IS_MAX31865 && !PIN_EXISTS(TEMP_2_MOSI) + #error "TEMP_SENSOR_2 MAX31865 requires TEMP_2_MOSI_PIN defined for Software SPI. To use Hardware SPI instead, undefine MISO/SCK or enable TEMP_SENSOR_2_FORCE_HW_SPI." + #else + #define TEMP_SENSOR_2_HAS_SPI_PINS 1 + #endif + #endif + + #endif // TEMP_SENSOR_IS_MAX_TC(2) + // // User-defined thermocouple libraries // diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 06b8f32946..744e68a5bb 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -416,17 +416,17 @@ #elif defined(CHDK) #error "CHDK is now CHDK_PIN." #elif ANY_PIN( \ - MAX6675_SS, MAX6675_SS2, MAX6675_CS, MAX6675_CS2, \ - MAX31855_SS, MAX31855_SS2, MAX31855_CS, MAX31855_CS2, \ - MAX31865_SS, MAX31865_SS2, MAX31865_CS, MAX31865_CS2) - #warning "MAX*_SS_PIN, MAX*_SS2_PIN, MAX*_CS_PIN, and MAX*_CS2_PIN are deprecated and will be removed in a future version. Please use TEMP_0_CS_PIN/TEMP_1_CS_PIN instead." + MAX6675_SS, MAX6675_SS2, MAX6675_SS3, MAX6675_CS, MAX6675_CS2, MAX6675_CS3,\ + MAX31855_SS, MAX31855_SS2, MAX31855_SS3, MAX31855_CS, MAX31855_CS2, MAX31855_CS3, \ + MAX31865_SS, MAX31865_SS2, MAX31865_SS3, MAX31865_CS, MAX31865_CS2, MAX31865_CS3) + #warning "MAX*_SS_PIN, MAX*_SS2_PIN, MAX*_SS3_PIN, MAX*_CS_PIN, MAX*_CS2_PIN, and MAX*_CS3_PIN, are deprecated and will be removed in a future version. Please use TEMP_0_CS_PIN/TEMP_1_CS_PIN/TEMP_2_CS_PIN instead." #elif ANY_PIN(MAX6675_SCK, MAX31855_SCK, MAX31865_SCK) - #warning "MAX*_SCK_PIN is deprecated and will be removed in a future version. Please use TEMP_0_SCK_PIN/TEMP_1_SCK_PIN instead." + #warning "MAX*_SCK_PIN is deprecated and will be removed in a future version. Please use TEMP_0_SCK_PIN/TEMP_1_SCK_PIN/TEMP_2_SCK_PIN instead." #elif ANY_PIN(MAX6675_MISO, MAX6675_DO, MAX31855_MISO, MAX31855_DO, MAX31865_MISO, MAX31865_DO) - #warning "MAX*_MISO_PIN and MAX*_DO_PIN are deprecated and will be removed in a future version. Please use TEMP_0_MISO_PIN/TEMP_1_MISO_PIN instead." + #warning "MAX*_MISO_PIN and MAX*_DO_PIN are deprecated and will be removed in a future version. Please use TEMP_0_MISO_PIN/TEMP_1_MISO_PIN/TEMP_2_MISO_PIN instead." #elif PIN_EXISTS(MAX31865_MOSI) - #warning "MAX31865_MOSI_PIN is deprecated and will be removed in a future version. Please use TEMP_0_MOSI_PIN/TEMP_1_MOSI_PIN instead." -#elif ANY_PIN(THERMO_CS1_PIN, THERMO_CS2_PIN, THERMO_DO_PIN, THERMO_SCK_PIN) + #warning "MAX31865_MOSI_PIN is deprecated and will be removed in a future version. Please use TEMP_0_MOSI_PIN/TEMP_1_MOSI_PIN/TEMP_2_MOSI_PIN instead." +#elif ANY_PIN(THERMO_CS1_PIN, THERMO_CS2_PIN, THERMO_CS3_PIN, THERMO_DO_PIN, THERMO_SCK_PIN) #error "THERMO_*_PIN is now TEMP_n_CS_PIN, TEMP_n_SCK_PIN, TEMP_n_MOSI_PIN, TEMP_n_MISO_PIN." #elif defined(MAX31865_SENSOR_OHMS) #error "MAX31865_SENSOR_OHMS is now MAX31865_SENSOR_OHMS_0." @@ -2340,6 +2340,13 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "MAX31865_SENSOR_OHMS_1 and MAX31865_CALIBRATION_OHMS_1 must be set if TEMP_SENSOR_1/TEMP_SENSOR_REDUNDANT is MAX31865." #endif #endif +#if TEMP_SENSOR_2_IS_MAX31865 || (TEMP_SENSOR_REDUNDANT_IS_MAX31865 && REDUNDANT_TEMP_MATCH(SOURCE, E2)) + #if !defined(MAX31865_SENSOR_WIRES_2) || !WITHIN(MAX31865_SENSOR_WIRES_2, 2, 4) + #error "MAX31865_SENSOR_WIRES_2 must be defined as an integer between 2 and 4." + #elif !defined(MAX31865_SENSOR_OHMS_2) || !defined(MAX31865_CALIBRATION_OHMS_2) + #error "MAX31865_SENSOR_OHMS_2 and MAX31865_CALIBRATION_OHMS_2 must be set if TEMP_SENSOR_2/TEMP_SENSOR_REDUNDANT is MAX31865." + #endif +#endif /** * Redundant temperature sensor config diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 7515396fbe..8843582f4e 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -113,13 +113,16 @@ // 3. CS, MISO, and SCK pins w/ FORCE_HW_SPI: Hardware SPI on the default bus, ignoring MISO, SCK. // #if TEMP_SENSOR_IS_ANY_MAX_TC(0) && TEMP_SENSOR_0_HAS_SPI_PINS && DISABLED(TEMP_SENSOR_FORCE_HW_SPI) - #define TEMP_SENSOR_0_USES_SW_SPI 1 + #define TEMP_SENSOR_0_USES_SW_SPI 1 #endif #if TEMP_SENSOR_IS_ANY_MAX_TC(1) && TEMP_SENSOR_1_HAS_SPI_PINS && DISABLED(TEMP_SENSOR_FORCE_HW_SPI) - #define TEMP_SENSOR_1_USES_SW_SPI 1 + #define TEMP_SENSOR_1_USES_SW_SPI 1 +#endif +#if TEMP_SENSOR_IS_ANY_MAX_TC(2) && TEMP_SENSOR_2_HAS_SPI_PINS && DISABLED(TEMP_SENSOR_FORCE_HW_SPI) + #define TEMP_SENSOR_2_USES_SW_SPI 1 #endif -#if (TEMP_SENSOR_0_USES_SW_SPI || TEMP_SENSOR_1_USES_SW_SPI) && !HAS_MAXTC_LIBRARIES +#if (TEMP_SENSOR_0_USES_SW_SPI || TEMP_SENSOR_1_USES_SW_SPI || TEMP_SENSOR_2_USES_SW_SPI) && !HAS_MAXTC_LIBRARIES #include "../libs/private_spi.h" #define HAS_MAXTC_SW_SPI 1 @@ -130,12 +133,18 @@ #if PIN_EXISTS(TEMP_0_MOSI) #define SW_SPI_MOSI_PIN TEMP_0_MOSI_PIN #endif - #else + #elif TEMP_SENSOR_1_USES_SW_SPI #define SW_SPI_SCK_PIN TEMP_1_SCK_PIN #define SW_SPI_MISO_PIN TEMP_1_MISO_PIN #if PIN_EXISTS(TEMP_1_MOSI) #define SW_SPI_MOSI_PIN TEMP_1_MOSI_PIN #endif + #elif TEMP_SENSOR_2_USES_SW_SPI + #define SW_SPI_SCK_PIN TEMP_2_SCK_PIN + #define SW_SPI_MISO_PIN TEMP_2_MISO_PIN + #if PIN_EXISTS(TEMP_2_MOSI) + #define SW_SPI_MOSI_PIN TEMP_2_MOSI_PIN + #endif #endif #ifndef SW_SPI_MOSI_PIN #define SW_SPI_MOSI_PIN SD_MOSI_PIN @@ -256,6 +265,9 @@ PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED); #if TEMP_SENSOR_IS_MAX(1, 6675) MAXTC_INIT(1, 6675); #endif + #if TEMP_SENSOR_IS_MAX(2, 6675) + MAXTC_INIT(2, 6675); + #endif #endif #if HAS_MAX31855_LIBRARY @@ -265,12 +277,16 @@ PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED); #if TEMP_SENSOR_IS_MAX(1, 31855) MAXTC_INIT(1, 31855); #endif + #if TEMP_SENSOR_IS_MAX(2, 31855) + MAXTC_INIT(2, 31855); + #endif #endif // MAX31865 always uses a library, unlike '55 & 6675 #if HAS_MAX31865 #define _MAX31865_0_SW TEMP_SENSOR_0_USES_SW_SPI #define _MAX31865_1_SW TEMP_SENSOR_1_USES_SW_SPI + #define _MAX31865_2_SW TEMP_SENSOR_2_USES_SW_SPI #if TEMP_SENSOR_IS_MAX(0, 31865) MAXTC_INIT(0, 31865); @@ -278,9 +294,13 @@ PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED); #if TEMP_SENSOR_IS_MAX(1, 31865) MAXTC_INIT(1, 31865); #endif + #if TEMP_SENSOR_IS_MAX(2, 31865) + MAXTC_INIT(2, 31865); + #endif #undef _MAX31865_0_SW #undef _MAX31865_1_SW + #undef _MAX31865_2_SW #endif #undef MAXTC_INIT @@ -541,6 +561,7 @@ volatile bool Temperature::raw_temps_ready = false; #endif #if MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED > 1 + #define MULTI_MAX_CONSECUTIVE_LOW_TEMP_ERR 1 uint8_t Temperature::consecutive_low_temperature_error[HOTENDS] = { 0 }; #endif @@ -1866,6 +1887,10 @@ void Temperature::task() { if (degHotend(1) > _MIN(HEATER_1_MAXTEMP, TEMP_SENSOR_1_MAX_TC_TMAX - 1.0)) max_temp_error(H_E1); if (degHotend(1) < _MAX(HEATER_1_MINTEMP, TEMP_SENSOR_1_MAX_TC_TMIN + .01)) min_temp_error(H_E1); #endif + #if TEMP_SENSOR_IS_MAX_TC(2) + if (degHotend(2) > _MIN(HEATER_2_MAXTEMP, TEMP_SENSOR_2_MAX_TC_TMAX - 1.0)) max_temp_error(H_E2); + if (degHotend(2) < _MAX(HEATER_2_MINTEMP, TEMP_SENSOR_2_MAX_TC_TMIN + .01)) min_temp_error(H_E2); + #endif #if TEMP_SENSOR_IS_MAX_TC(REDUNDANT) if (degRedundant() > TEMP_SENSOR_REDUNDANT_MAX_TC_TMAX - 1.0) max_temp_error(H_REDUNDANT); if (degRedundant() < TEMP_SENSOR_REDUNDANT_MAX_TC_TMIN + .01) min_temp_error(H_REDUNDANT); @@ -2112,6 +2137,15 @@ void Temperature::task() { case 2: #if TEMP_SENSOR_2_IS_CUSTOM return user_thermistor_to_deg_c(CTI_HOTEND_2, raw); + #elif TEMP_SENSOR_IS_MAX_TC(2) + #if TEMP_SENSOR_0_IS_MAX31865 + return TERN(LIB_INTERNAL_MAX31865, + max31865_2.temperature(raw), + max31865_2.temperature(MAX31865_SENSOR_OHMS_2, MAX31865_CALIBRATION_OHMS_2) + ); + #else + return (int16_t)raw * 0.25; + #endif #elif TEMP_SENSOR_2_IS_AD595 return TEMP_AD595(raw); #elif TEMP_SENSOR_2_IS_AD8495 @@ -2281,6 +2315,8 @@ void Temperature::task() { return TERN(TEMP_SENSOR_REDUNDANT_IS_MAX31865, max31865_0.temperature(raw), (int16_t)raw * 0.25); #elif TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E1) return TERN(TEMP_SENSOR_REDUNDANT_IS_MAX31865, max31865_1.temperature(raw), (int16_t)raw * 0.25); + #elif TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E2) + return TERN(TEMP_SENSOR_REDUNDANT_IS_MAX31865, max31865_2.temperature(raw), (int16_t)raw * 0.25); #elif TEMP_SENSOR_REDUNDANT_IS_THERMISTOR SCAN_THERMISTOR_TABLE(TEMPTABLE_REDUNDANT, TEMPTABLE_REDUNDANT_LEN); #elif TEMP_SENSOR_REDUNDANT_IS_AD595 @@ -2316,6 +2352,9 @@ void Temperature::updateTemperaturesFromRawValues() { #if TEMP_SENSOR_IS_MAX_TC(1) temp_hotend[1].setraw(READ_MAX_TC(1)); #endif + #if TEMP_SENSOR_IS_MAX_TC(2) + temp_hotend[2].setraw(READ_MAX_TC(2)); + #endif #if TEMP_SENSOR_IS_MAX_TC(REDUNDANT) temp_redundant.setraw(READ_MAX_TC(HEATER_ID(TEMP_SENSOR_REDUNDANT_SOURCE))); #endif @@ -2347,9 +2386,14 @@ void Temperature::updateTemperaturesFromRawValues() { #else , TEMPDIR(1) #endif - #if HOTENDS > 2 + #if TEMP_SENSOR_IS_ANY_MAX_TC(2) + , 0 + #else + , TEMPDIR(2) + #endif + #if HOTENDS > 3 #define _TEMPDIR(N) , TEMPDIR(N) - REPEAT_S(2, HOTENDS, _TEMPDIR) + REPEAT_S(3, HOTENDS, _TEMPDIR) #endif #endif }; @@ -2362,15 +2406,12 @@ void Temperature::updateTemperaturesFromRawValues() { const bool heater_on = temp_hotend[e].target > 0; if (heater_on && ((neg && r > temp_range[e].raw_min) || (pos && r < temp_range[e].raw_min))) { - #if MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED > 1 - if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) - #endif - min_temp_error((heater_id_t)e); + if (TERN1(MULTI_MAX_CONSECUTIVE_LOW_TEMP_ERR, ++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED)) + min_temp_error((heater_id_t)e); + } + else { + TERN_(MULTI_MAX_CONSECUTIVE_LOW_TEMP_ERR, consecutive_low_temperature_error[e] = 0); } - #if MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED > 1 - else - consecutive_low_temperature_error[e] = 0; - #endif } #endif // HAS_HOTEND @@ -2432,6 +2473,9 @@ void Temperature::init() { #if TEMP_SENSOR_IS_ANY_MAX_TC(1) && PIN_EXISTS(TEMP_1_CS) OUT_WRITE(TEMP_1_CS_PIN, HIGH); #endif + #if TEMP_SENSOR_IS_ANY_MAX_TC(2) && PIN_EXISTS(TEMP_2_CS) + OUT_WRITE(TEMP_2_CS_PIN, HIGH); + #endif // Setup objects for library-based polling of MAX TCs #if HAS_MAXTC_LIBRARIES @@ -2459,6 +2503,18 @@ void Temperature::init() { OPTARG(LIB_INTERNAL_MAX31865, MAX31865_SENSOR_OHMS_1, MAX31865_CALIBRATION_OHMS_1, MAX31865_WIRE_OHMS_1) ); #endif + + #if TEMP_SENSOR_IS_MAX(2, 6675) && HAS_MAX6675_LIBRARY + max6675_2.begin(); + #elif TEMP_SENSOR_IS_MAX(2, 31855) && HAS_MAX31855_LIBRARY + max31855_2.begin(); + #elif TEMP_SENSOR_IS_MAX(2, 31865) + max31865_2.begin( + MAX31865_WIRES(MAX31865_SENSOR_WIRES_2) // MAX31865_2WIRE, MAX31865_3WIRE, MAX31865_4WIRE + OPTARG(LIB_INTERNAL_MAX31865, MAX31865_SENSOR_OHMS_2, MAX31865_CALIBRATION_OHMS_2, MAX31865_WIRE_OHMS_2) + ); + #endif + #undef MAX31865_WIRES #undef _MAX31865_WIRES #endif @@ -2491,6 +2547,15 @@ void Temperature::init() { #endif )); #endif + #if PIN_EXISTS(TEMP_2_TR_ENABLE) + OUT_WRITE(TEMP_2_TR_ENABLE_PIN, ( + #if TEMP_SENSOR_IS_ANY_MAX_TC(2) + HIGH + #else + LOW + #endif + )); + #endif #if ENABLED(MPCTEMP) HOTEND_LOOP() temp_hotend[e].modeled_block_temp = NAN; @@ -3009,25 +3074,29 @@ void Temperature::disable_all_heaters() { // Needed to return the correct temp when this is called between readings static raw_adc_t max_tc_temp_previous[MAX_TC_COUNT] = { 0 }; #define THERMO_TEMP(I) max_tc_temp_previous[I] - #define THERMO_SEL(A,B) (hindex ? (B) : (A)) - #define MAXTC_CS_WRITE(V) do{ switch (hindex) { case 1: WRITE(TEMP_1_CS_PIN, V); break; default: WRITE(TEMP_0_CS_PIN, V); } }while(0) + #define THERMO_SEL(A,B,C) (hindex > 1 ? (C) : hindex == 1 ? (B) : (A)) + #define MAXTC_CS_WRITE(V) do{ switch (hindex) { case 1: WRITE(TEMP_1_CS_PIN, V); break; case 2: WRITE(TEMP_2_CS_PIN, V); break; default: WRITE(TEMP_0_CS_PIN, V); } }while(0) #else // When we have only 1 max tc, THERMO_SEL will pick the appropriate sensor // variable, and MAXTC_*() macros will be hardcoded to the correct CS pin. constexpr uint8_t hindex = 0; #define THERMO_TEMP(I) max_tc_temp #if TEMP_SENSOR_IS_ANY_MAX_TC(0) - #define THERMO_SEL(A,B) A + #define THERMO_SEL(A,B,C) A #define MAXTC_CS_WRITE(V) WRITE(TEMP_0_CS_PIN, V) - #else - #define THERMO_SEL(A,B) B + #elif TEMP_SENSOR_IS_ANY_MAX_TC(1) + #define THERMO_SEL(A,B,C) B #define MAXTC_CS_WRITE(V) WRITE(TEMP_1_CS_PIN, V) + #elif TEMP_SENSOR_IS_ANY_MAX_TC(2) + #define THERMO_SEL(A,B,C) C + #define MAXTC_CS_WRITE(V) WRITE(TEMP_2_CS_PIN, V) #endif #endif static TERN(HAS_MAX31855, uint32_t, uint16_t) max_tc_temp = THERMO_SEL( TEMP_SENSOR_0_MAX_TC_TMAX, - TEMP_SENSOR_1_MAX_TC_TMAX + TEMP_SENSOR_1_MAX_TC_TMAX, + TEMP_SENSOR_2_MAX_TC_TMAX ); static uint8_t max_tc_errors[MAX_TC_COUNT] = { 0 }; @@ -3062,17 +3131,17 @@ void Temperature::disable_all_heaters() { MAXTC_CS_WRITE(HIGH); // Disable MAXTC #else #if HAS_MAX6675_LIBRARY - MAX6675 &max6675ref = THERMO_SEL(max6675_0, max6675_1); + MAX6675 &max6675ref = THERMO_SEL(max6675_0, max6675_1, max6675_2); max_tc_temp = max6675ref.readRaw16(); #endif #if HAS_MAX31855_LIBRARY - MAX31855 &max855ref = THERMO_SEL(max31855_0, max31855_1); + MAX31855 &max855ref = THERMO_SEL(max31855_0, max31855_1, max31855_2); max_tc_temp = max855ref.readRaw32(); #endif #if HAS_MAX31865 - MAX31865 &max865ref = THERMO_SEL(max31865_0, max31865_1); + MAX31865 &max865ref = THERMO_SEL(max31865_0, max31865_1, max31865_2); max_tc_temp = TERN(LIB_INTERNAL_MAX31865, max865ref.readRaw(), max865ref.readRTD_with_Fault()); #endif #endif @@ -3117,7 +3186,7 @@ void Temperature::disable_all_heaters() { #endif // Set thermocouple above max temperature (TMAX) - max_tc_temp = THERMO_SEL(TEMP_SENSOR_0_MAX_TC_TMAX, TEMP_SENSOR_1_MAX_TC_TMAX) << (MAX_TC_DISCARD_BITS + 1); + max_tc_temp = THERMO_SEL(TEMP_SENSOR_0_MAX_TC_TMAX, TEMP_SENSOR_1_MAX_TC_TMAX, TEMP_SENSOR_2_MAX_TC_TMAX) << (MAX_TC_DISCARD_BITS + 1); } } else { @@ -3155,6 +3224,10 @@ void Temperature::update_raw_temperatures() { temp_hotend[1].update(); #endif + #if HAS_TEMP_ADC_2 && !TEMP_SENSOR_IS_MAX_TC(2) + temp_hotend[2].update(); + #endif + #if HAS_TEMP_ADC_REDUNDANT && !TEMP_SENSOR_IS_MAX_TC(REDUNDANT) temp_redundant.update(); #endif From 2cad4420fdd0bbc10da521cc6cdf8e65c5a021fb Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Sun, 23 Oct 2022 00:34:38 +0000 Subject: [PATCH 17/24] [cron] Bump distribution date (2022-10-23) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 5b21d2209e..87c29ae7ea 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2022-10-22" +//#define STRING_DISTRIBUTION_DATE "2022-10-23" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 05776b4a80..a96140bbc1 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2022-10-22" + #define STRING_DISTRIBUTION_DATE "2022-10-23" #endif /** From aaf34fa96bf3da9cf7c95a41ccb7e5bc441dbd20 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 22 Oct 2022 23:35:31 -0500 Subject: [PATCH 18/24] =?UTF-8?q?=F0=9F=A9=B9=20Fix=20M593=20report?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/gcode/feature/input_shaping/M593.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Marlin/src/gcode/feature/input_shaping/M593.cpp b/Marlin/src/gcode/feature/input_shaping/M593.cpp index 84301963cb..e1e99ca51b 100644 --- a/Marlin/src/gcode/feature/input_shaping/M593.cpp +++ b/Marlin/src/gcode/feature/input_shaping/M593.cpp @@ -30,13 +30,14 @@ void GcodeSuite::M593_report(const bool forReplay/*=true*/) { report_heading_etc(forReplay, F("Input Shaping")); #if HAS_SHAPING_X - SERIAL_ECHO_MSG("M593 X" + SERIAL_ECHOLNPGM(" M593 X" " F", stepper.get_shaping_frequency(X_AXIS), " D", stepper.get_shaping_damping_ratio(X_AXIS) ); #endif #if HAS_SHAPING_Y - SERIAL_ECHO_MSG("M593 Y" + TERN_(HAS_SHAPING_X, report_echo_start(forReplay)); + SERIAL_ECHOLNPGM(" M593 Y" " F", stepper.get_shaping_frequency(Y_AXIS), " D", stepper.get_shaping_damping_ratio(Y_AXIS) ); From 248236b1a763b02f7f15ec8cb6f39bd301aaa956 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Mon, 24 Oct 2022 00:36:39 +0000 Subject: [PATCH 19/24] [cron] Bump distribution date (2022-10-24) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 87c29ae7ea..1738b263d6 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2022-10-23" +//#define STRING_DISTRIBUTION_DATE "2022-10-24" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index a96140bbc1..0fefc64297 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2022-10-23" + #define STRING_DISTRIBUTION_DATE "2022-10-24" #endif /** From cf2311f768b939940a1846c3930c95bb7119eb46 Mon Sep 17 00:00:00 2001 From: Manuel McLure Date: Mon, 24 Oct 2022 14:25:47 -0700 Subject: [PATCH 20/24] =?UTF-8?q?=F0=9F=A9=B9=20Fix=20spurious=20"bad=20co?= =?UTF-8?q?mmand"=20(#24923)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/feature/bedlevel/ubl/ubl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.cpp b/Marlin/src/feature/bedlevel/ubl/ubl.cpp index 2aa50be34d..f2af1445b1 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl.cpp @@ -260,7 +260,7 @@ bool unified_bed_leveling::sanity_check() { */ void GcodeSuite::M1004() { - #define ALIGN_GCODE TERN(Z_STEPPER_AUTO_ALIGN, "G34", "") + #define ALIGN_GCODE TERN(Z_STEPPER_AUTO_ALIGN, "G34\n", "") #define PROBE_GCODE TERN(HAS_BED_PROBE, "G29P1\nG29P3", "G29P4R") #if HAS_HOTEND @@ -280,7 +280,7 @@ bool unified_bed_leveling::sanity_check() { #endif process_subcommands_now(FPSTR(G28_STR)); // Home - process_subcommands_now(F(ALIGN_GCODE "\n" // Align multi z axis if available + process_subcommands_now(F(ALIGN_GCODE // Align multi z axis if available PROBE_GCODE "\n" // Build mesh with available hardware "G29P3\nG29P3")); // Ensure mesh is complete by running smart fill twice From 81f88fefdc1d32fade897ddd0daff604c92b5da0 Mon Sep 17 00:00:00 2001 From: InsanityAutomation <38436470+InsanityAutomation@users.noreply.github.com> Date: Mon, 24 Oct 2022 17:44:52 -0400 Subject: [PATCH 21/24] =?UTF-8?q?=F0=9F=90=9B=20Fix=20FTDUI=20Status=20Scr?= =?UTF-8?q?een=20Timeout=20(#24899)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/inc/Conditionals_post.h | 4 ++-- .../ftdi_eve_touch_ui/generic/base_screen.cpp | 18 +++++++++++------- .../ftdi_eve_touch_ui/generic/base_screen.h | 2 +- Marlin/src/lcd/marlinui.cpp | 4 ++-- Marlin/src/lcd/marlinui.h | 8 ++++---- Marlin/src/lcd/menu/menu.cpp | 6 +++--- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 5f54039392..9f41390db9 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -3689,13 +3689,13 @@ #endif #endif -#if HAS_MARLINUI_MENU +#if EITHER(HAS_MARLINUI_MENU, TOUCH_UI_FTDI_EVE) // LCD timeout to status screen default is 15s #ifndef LCD_TIMEOUT_TO_STATUS #define LCD_TIMEOUT_TO_STATUS 15000 #endif #if LCD_TIMEOUT_TO_STATUS - #define SCREENS_CAN_TIME_OUT 1 + #define HAS_SCREEN_TIMEOUT 1 #endif #endif diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.cpp index 0a8bebea3c..4e5a3fec2f 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.cpp @@ -45,15 +45,16 @@ bool BaseScreen::buttonStyleCallback(CommandProcessor &cmd, uint8_t tag, uint8_t return false; } - #if SCREENS_CAN_TIME_OUT + #if HAS_SCREEN_TIMEOUT if (EventLoop::get_pressed_tag() != 0) { + #if ENABLED(TOUCH_UI_DEBUG) + SERIAL_ECHO_MSG("buttonStyleCallback, resetting timeout"); + #endif reset_menu_timeout(); } #endif - if (buttonIsPressed(tag)) { - options = OPT_FLAT; - } + if (buttonIsPressed(tag)) options = OPT_FLAT; if (style & cmd.STYLE_DISABLED) { cmd.tag(0); @@ -65,7 +66,10 @@ bool BaseScreen::buttonStyleCallback(CommandProcessor &cmd, uint8_t tag, uint8_t } void BaseScreen::onIdle() { - #if SCREENS_CAN_TIME_OUT + #if HAS_SCREEN_TIMEOUT + if (EventLoop::get_pressed_tag() != 0) + reset_menu_timeout(); + if ((millis() - last_interaction) > LCD_TIMEOUT_TO_STATUS) { reset_menu_timeout(); #if ENABLED(TOUCH_UI_DEBUG) @@ -77,10 +81,10 @@ void BaseScreen::onIdle() { } void BaseScreen::reset_menu_timeout() { - TERN_(SCREENS_CAN_TIME_OUT, last_interaction = millis()); + TERN_(HAS_SCREEN_TIMEOUT, last_interaction = millis()); } -#if SCREENS_CAN_TIME_OUT +#if HAS_SCREEN_TIMEOUT uint32_t BaseScreen::last_interaction; #endif diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.h index 030fa51a2a..4b29bf1e41 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.h @@ -27,7 +27,7 @@ class BaseScreen : public UIScreen { protected: - #if SCREENS_CAN_TIME_OUT + #if HAS_SCREEN_TIMEOUT static uint32_t last_interaction; #endif diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index c885e83845..0dfe60d8e4 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -316,7 +316,7 @@ void MarlinUI::init() { #endif #endif - #if SCREENS_CAN_TIME_OUT + #if HAS_SCREEN_TIMEOUT bool MarlinUI::defer_return_to_status; millis_t MarlinUI::return_to_status_ms = 0; #endif @@ -1171,7 +1171,7 @@ void MarlinUI::init() { NOLESS(max_display_update_time, millis() - ms); } - #if SCREENS_CAN_TIME_OUT + #if HAS_SCREEN_TIMEOUT // Return to Status Screen after a timeout if (on_status_screen() || defer_return_to_status) reset_status_timeout(ms); diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index b1a98248bb..ec19f8bd34 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -545,7 +545,7 @@ public: #endif static void reset_status_timeout(const millis_t ms) { - TERN(SCREENS_CAN_TIME_OUT, return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS, UNUSED(ms)); + TERN(HAS_SCREEN_TIMEOUT, return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS, UNUSED(ms)); } #if HAS_MARLINUI_MENU @@ -596,11 +596,11 @@ public: #endif FORCE_INLINE static bool screen_is_sticky() { - return TERN1(SCREENS_CAN_TIME_OUT, defer_return_to_status); + return TERN1(HAS_SCREEN_TIMEOUT, defer_return_to_status); } FORCE_INLINE static void defer_status_screen(const bool defer=true) { - TERN(SCREENS_CAN_TIME_OUT, defer_return_to_status = defer, UNUSED(defer)); + TERN(HAS_SCREEN_TIMEOUT, defer_return_to_status = defer, UNUSED(defer)); } static void goto_previous_screen_no_defer() { @@ -778,7 +778,7 @@ public: private: - #if SCREENS_CAN_TIME_OUT + #if HAS_SCREEN_TIMEOUT static millis_t return_to_status_ms; static bool defer_return_to_status; #else diff --git a/Marlin/src/lcd/menu/menu.cpp b/Marlin/src/lcd/menu/menu.cpp index 7ae1078f4d..6389383d28 100644 --- a/Marlin/src/lcd/menu/menu.cpp +++ b/Marlin/src/lcd/menu/menu.cpp @@ -61,7 +61,7 @@ typedef struct { screenFunc_t menu_function; // The screen's function uint32_t encoder_position; // The position of the encoder int8_t top_line, items; // The amount of scroll, and the number of items - #if SCREENS_CAN_TIME_OUT + #if HAS_SCREEN_TIMEOUT bool sticky; // The screen is sticky #endif } menuPosition; @@ -89,7 +89,7 @@ void MarlinUI::return_to_status() { goto_screen(status_screen); } void MarlinUI::push_current_screen() { if (screen_history_depth < COUNT(screen_history)) - screen_history[screen_history_depth++] = { currentScreen, encoderPosition, encoderTopLine, screen_items OPTARG(SCREENS_CAN_TIME_OUT, screen_is_sticky()) }; + screen_history[screen_history_depth++] = { currentScreen, encoderPosition, encoderTopLine, screen_items OPTARG(HAS_SCREEN_TIMEOUT, screen_is_sticky()) }; } void MarlinUI::_goto_previous_screen(TERN_(TURBO_BACK_MENU_ITEM, const bool is_back/*=false*/)) { @@ -102,7 +102,7 @@ void MarlinUI::_goto_previous_screen(TERN_(TURBO_BACK_MENU_ITEM, const bool is_b is_back ? 0 : sh.top_line, sh.items ); - defer_status_screen(TERN_(SCREENS_CAN_TIME_OUT, sh.sticky)); + defer_status_screen(TERN_(HAS_SCREEN_TIMEOUT, sh.sticky)); } else return_to_status(); From f4dc9d572be3b9858539a5115f275e4b6e626f8e Mon Sep 17 00:00:00 2001 From: ellensp <530024+ellensp@users.noreply.github.com> Date: Tue, 25 Oct 2022 10:47:23 +1300 Subject: [PATCH 22/24] =?UTF-8?q?=F0=9F=90=9B=20Fix=20move=5Fextruder=5Fse?= =?UTF-8?q?rvo=20(#24908)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/module/tool_change.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 80aedd3bdd..cd18462be3 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -115,7 +115,7 @@ void move_extruder_servo(const uint8_t e) { planner.synchronize(); - if ((EXTRUDERS & 1) && e < EXTRUDERS - 1) { + if (e < EXTRUDERS) { servo[_SERVO_NR(e)].move(servo_angles[_SERVO_NR(e)][e & 1]); safe_delay(500); } From 6e1f0be215235c96113c74a6fda345e11626ce28 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 24 Oct 2022 17:04:55 -0500 Subject: [PATCH 23/24] =?UTF-8?q?=F0=9F=A9=B9=20Allow=20for=20last=20non-s?= =?UTF-8?q?ervo=20extruder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/module/tool_change.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index cd18462be3..a0939d155a 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -115,7 +115,8 @@ void move_extruder_servo(const uint8_t e) { planner.synchronize(); - if (e < EXTRUDERS) { + constexpr bool evenExtruders = !(EXTRUDERS & 1); + if (evenExtruders || e < EXTRUDERS - 1) { servo[_SERVO_NR(e)].move(servo_angles[_SERVO_NR(e)][e & 1]); safe_delay(500); } From 6b4d7b9151d260d3109ca857d084e3ca0cd8b048 Mon Sep 17 00:00:00 2001 From: thinkyhead Date: Tue, 25 Oct 2022 00:37:23 +0000 Subject: [PATCH 24/24] [cron] Bump distribution date (2022-10-25) --- Marlin/Version.h | 2 +- Marlin/src/inc/Version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Version.h b/Marlin/Version.h index 1738b263d6..91f86174d3 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2022-10-24" +//#define STRING_DISTRIBUTION_DATE "2022-10-25" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 0fefc64297..32bb738d24 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2022-10-24" + #define STRING_DISTRIBUTION_DATE "2022-10-25" #endif /**