diff --git a/README.md b/README.md index f6fbc4cdd9..d29d01b69c 100644 --- a/README.md +++ b/README.md @@ -85,9 +85,10 @@ Only the TFTs listed below are currently supported. Trying to install the firmwa **MKS TFT** MKS_TFT28_V3.0 and V4.0 + MKS_TFT28_NEW_GENIUS MKS_TFT32_V1.3 and V1.4 - MKS_TFT32L_V3_0 - MKS_TFT35_V1_0 + MKS_TFT32L_V3.0 + MKS_TFT35_V1.0 **MKS TFT with GigaDevice MCUs** @@ -457,23 +458,39 @@ Please, see [Customization Guides](https://github.com/bigtreetech/BIGTREETECH-To
platformio.ini
and change the default_envs
to one that matches your TFT model and version:
-;BIGTREE_TFT35_V1_0 +;BIGTREE_TFT24_V1_1 +;BIGTREE_TFT28_V1_0 +;BIGTREE_TFT28_V3_0 +;BIGTREE_TFT35_V1_0 ;BIGTREE_TFT35_V1_1 ;BIGTREE_TFT35_V1_2 ;BIGTREE_TFT35_V2_0 ;BIGTREE_TFT35_V3_0 ;BIGTREE_TFT35_E3_V3_0 -;BIGTREE_TFT28_V1_0 -;BIGTREE_TFT28_V3_0 -;BIGTREE_TFT24_V1_1 -;MKS_TFT32_V1_3 -;MKS_TFT32_V1_4 -;MKS_TFT32_V1_4_NOBL +;BIGTREE_TFT35_B1_V3_0 +;BIGTREE_TFT43_V3_0 +;BIGTREE_TFT50_V3_0 +;BIGTREE_TFT70_V3_0 + +;BIGTREE_GD_TFT24_V1_1 +;BIGTREE_GD_TFT35_V2_0 +;BIGTREE_GD_TFT35_V3_0 +;BIGTREE_GD_TFT35_E3_V3_0 +;BIGTREE_GD_TFT35_B1_V3_0 +;BIGTREE_GD_TFT43_V3_0 +;BIGTREE_GD_TFT50_V3_0 +;BIGTREE_GD_TFT70_V3_0 + ;MKS_TFT28_V3_0 ;MKS_TFT28_V4_0 ;MKS_TFT28_NEW_GENIUS +;MKS_TFT32_V1_3 +;MKS_TFT32_V1_4 +;MKS_TFT32_V1_4_NOBL +;MKS_TFT32L_V3_0 ;MKS_TFT35_V1_0 ;MKS_GD_TFT28_V1_2-4 + [platformio] src_dir = TFT boards_dir = buildroot/boards diff --git a/TFT/src/User/API/AddonHardware.c b/TFT/src/User/API/AddonHardware.c index f393d5c8ac..027003550e 100644 --- a/TFT/src/User/API/AddonHardware.c +++ b/TFT/src/User/API/AddonHardware.c @@ -3,25 +3,22 @@ #include "GPIO_Init.h" // -// Power Supply +// power supply // #ifdef PS_ON_PIN -// Power Supply Control pins Initialization void PS_ON_Init(void) { GPIO_InitSet(PS_ON_PIN, MGPIO_MODE_OUT_PP, 0); GPIO_SetLevel(PS_ON_PIN, infoSettings.ps_active_high); } -// Power Supply Control turn on, M80 void PS_ON_On(void) { GPIO_SetLevel(PS_ON_PIN, infoSettings.ps_active_high); } -// Power Supply Control turn off, M81 void PS_ON_Off(void) { GPIO_SetLevel(PS_ON_PIN, !infoSettings.ps_active_high); @@ -30,20 +27,23 @@ void PS_ON_Off(void) #endif // PS_ON_PIN // -// Filament runout detection +// filament runout detection // #ifdef FIL_RUNOUT_PIN +#define FIL_POS_E_REFRESH_TIME 2000 +#define FIL_ALARM_REMINDER_TIME 10000 + enum { FILAMENT_SENSOR_NORMAL, FILAMENT_SENSOR_SMART, }; -static uint32_t nextUpdateTime = FIL_ALARM_REMINDER_TIME; // Give TFT time to connect to mainboard first before polling for runout -static bool posE_updateWaiting = false; -static bool sfs_alive = false; // Use an encoder disc to toggles the runout. Suitable for BigTreeTech Smart Filament Sensor +static uint32_t posE_nextUpdateTime = FIL_ALARM_REMINDER_TIME; // give TFT time to connect to mainboard first before polling for runout +static bool posE_sendingWaiting = false; +static bool sfs_alive = false; // use an encoder disc to toggles the runout. Suitable for BigTreeTech Smart Filament Sensor void FIL_Runout_Init(void) { @@ -73,15 +73,9 @@ void FIL_Runout_Init(void) #endif } -static inline void FIL_SetNextUpdateTime(uint32_t timeInterval) -{ - nextUpdateTime = OS_GetTimeMs() + timeInterval; -} - -// Set whether we need to query the current position -void FIL_PosE_SetUpdateWaiting(bool waiting) +void FIL_PosE_ClearSendingWaiting(void) { - posE_updateWaiting = waiting; + posE_sendingWaiting = false; } void FIL_SFS_SetAlive(bool alive) @@ -93,14 +87,9 @@ bool FIL_NormalRunoutDetect(void) { static bool runout = false; static int32_t trigBalance = 0; + static uint32_t nextUpdateTime = 0; - if (OS_GetTimeMs() > nextUpdateTime) - { - runout = (trigBalance > 0); - trigBalance = 0; - FIL_SetNextUpdateTime(infoSettings.runout_noise); - } - else + if (OS_GetTimeMs() < nextUpdateTime) { bool pinState = false; uint8_t toolNum = heatGetToolIndex(); @@ -116,34 +105,47 @@ bool FIL_NormalRunoutDetect(void) pinState = GPIO_GetLevel(FIL_RUNOUT_PIN_1); break; #endif + #ifdef FIL_RUNOUT_PIN_2 case 2: pinState = GPIO_GetLevel(FIL_RUNOUT_PIN_2); break; #endif + #ifdef FIL_RUNOUT_PIN_3 case 3: pinState = GPIO_GetLevel(FIL_RUNOUT_PIN_3); break; #endif + #ifdef FIL_RUNOUT_PIN_4 case 4: pinState = GPIO_GetLevel(FIL_RUNOUT_PIN_4); break; #endif + #ifdef FIL_RUNOUT_PIN_5 case 5: pinState = GPIO_GetLevel(FIL_RUNOUT_PIN_5); break; #endif + default: pinState = GPIO_GetLevel(FIL_RUNOUT_PIN); break; } trigBalance += (pinState == GET_BIT(infoSettings.runout, RUNOUT_INVERTED)) ? 1: -1; // if triggered add 1 else substract 1 + + return runout; } + // if OS_GetTimeMs() >= nextUpdateTime + + runout = (trigBalance > 0); + trigBalance = 0; + nextUpdateTime = OS_GetTimeMs() + infoSettings.runout_noise; + return runout; } @@ -156,34 +158,23 @@ static inline bool FIL_SmartRunoutDetect(void) bool runout = FIL_NormalRunoutDetect(); do - { - // Send M114 E to query extrude position continuously - if (posE_updateWaiting == true) - { - FIL_SetNextUpdateTime(FIL_POS_E_UPDATE_TIME); - break; - } + { // send M114 E to query extrude position continuously - if (OS_GetTimeMs() < nextUpdateTime) + if (OS_GetTimeMs() < posE_nextUpdateTime) // if next check time not yet elapsed, do nothing break; - if (requestCommandInfoIsRunning()) // To avoid collision in gcode response processing - break; + posE_nextUpdateTime = OS_GetTimeMs() + FIL_POS_E_REFRESH_TIME; // extend next check time - if (!storeCmd("M114 E\n")) + // if M114 previously enqueued and not yet sent or pending command + // (to avoid collision in gcode response processing), do nothing + if (posE_sendingWaiting || requestCommandInfoIsRunning()) break; - FIL_SetNextUpdateTime(FIL_POS_E_UPDATE_TIME); - posE_updateWaiting = true; + posE_sendingWaiting = storeCmd("M114 E\n"); } while (0); - if (sfs_alive == false) - { - if (lastRunout != runout) - { - sfs_alive = true; - } - } + if (!sfs_alive && lastRunout != runout) + sfs_alive = true; if (ABS(posE - lastPosE) >= infoSettings.runout_distance) { @@ -220,10 +211,10 @@ static inline bool FIL_IsRunout(void) void FIL_BE_CheckRunout(void) { - if (!GET_BIT(infoSettings.runout, RUNOUT_ENABLED)) // Filament runout turned off + if (!GET_BIT(infoSettings.runout, RUNOUT_ENABLED)) // filament runout turned off return; - setPrintRunout(FIL_IsRunout()); // Need constant scanning to filter interference + setPrintRunout(FIL_IsRunout()); // need constant scanning to filter interference } void FIL_FE_CheckRunout(void) @@ -233,13 +224,13 @@ void FIL_FE_CheckRunout(void) if (!getPrintRunout() && !getRunoutAlarm()) return; - if (pausePrint(true, PAUSE_NORMAL) && !getRunoutAlarm()) // If not printing, pausePrint() function will always fail + if (pausePrint(true, PAUSE_NORMAL) && !getRunoutAlarm()) // if not printing, pausePrint() function will always fail { // so no useless error message is displayed setRunoutAlarmTrue(); popupDialog(DIALOG_TYPE_ALERT, LABEL_WARNING, LABEL_FILAMENT_RUNOUT, LABEL_CONFIRM, LABEL_NULL, setRunoutAlarmFalse, NULL, NULL); } - if ((OS_GetTimeMs() > nextReminderTime) && (getRunoutAlarm() == true)) + if (OS_GetTimeMs() >= nextReminderTime && getRunoutAlarm()) { BUZZER_PLAY(SOUND_ERROR); nextReminderTime = OS_GetTimeMs() + FIL_ALARM_REMINDER_TIME; diff --git a/TFT/src/User/API/AddonHardware.h b/TFT/src/User/API/AddonHardware.h index 1023ea6f58..063d7a767b 100644 --- a/TFT/src/User/API/AddonHardware.h +++ b/TFT/src/User/API/AddonHardware.h @@ -8,23 +8,20 @@ extern "C" { #include#include "variants.h" // for PS_ON_PIN, FIL_RUNOUT_PIN etc. -// Power Supply +// power supply #ifdef PS_ON_PIN - void PS_ON_Init(void); - void PS_ON_On(void); - void PS_ON_Off(void); + void PS_ON_Init(void); // power supply control pins initialization + void PS_ON_On(void); // power supply control turn on, M80 + void PS_ON_Off(void); // power supply control turn off, M81 #endif -// Filament runout detection +// filament runout detection #ifdef FIL_RUNOUT_PIN - #define FIL_POS_E_UPDATE_TIME 2000 - #define FIL_ALARM_REMINDER_TIME 10000 - void FIL_Runout_Init(void); - void FIL_PosE_SetUpdateWaiting(bool waiting); + void FIL_PosE_ClearSendingWaiting(void); // clear sending waiting for position query void FIL_SFS_SetAlive(bool alive); - void FIL_BE_CheckRunout(void); - void FIL_FE_CheckRunout(void); + void FIL_BE_CheckRunout(void); // called in loopBackEnd() + void FIL_FE_CheckRunout(void); // called in loopFrontEnd() #endif #ifdef __cplusplus diff --git a/TFT/src/User/API/FanControl.c b/TFT/src/User/API/FanControl.c index 776d9b7c71..107de2447e 100644 --- a/TFT/src/User/API/FanControl.c +++ b/TFT/src/User/API/FanControl.c @@ -1,17 +1,16 @@ #include "FanControl.h" #include "includes.h" -#define NEXT_FAN_WAIT 500 // 1 second is 1000 +#define FAN_REFRESH_TIME 500 // 1 second is 1000 -const char* fanID[MAX_FAN_COUNT] = FAN_DISPLAY_ID; -const char* fanCmd[MAX_FAN_COUNT] = FAN_CMD; +const char * fanID[MAX_FAN_COUNT] = FAN_DISPLAY_ID; +const char * fanCmd[MAX_FAN_COUNT] = FAN_CMD; static uint8_t setFanSpeed[MAX_FAN_COUNT] = {0}; static uint8_t curFanSpeed[MAX_FAN_COUNT] = {0}; static uint8_t needSetFanSpeed = 0; -static bool ctrlFanQueryWait = false; -static uint32_t nextCtrlFanTime = 0; +static bool ctrlFanSendingWaiting = false; void fanResetSpeed(void) { @@ -20,7 +19,6 @@ void fanResetSpeed(void) memset(curFanSpeed, 0, sizeof(curFanSpeed)); } -// Check whether the index is a valid fan index. bool fanIsValid(const uint8_t index) { if (index >= infoSettings.fan_count && index < MAX_COOLING_FAN_COUNT) // invalid cooling fan index @@ -74,32 +72,32 @@ uint8_t fanGetCurPercent(const uint8_t i) return (curFanSpeed[i] * 100.0f) / infoSettings.fan_max[i] + 0.5f; } -void loopFan(void) +void loopCheckFan(void) { + static uint32_t nextUpdateTime = 0; + + if (OS_GetTimeMs() < nextUpdateTime) // avoid rapid fire, clogging the queue + return; + + nextUpdateTime = OS_GetTimeMs() + FAN_REFRESH_TIME; // extend next check time + for (uint8_t i = 0; i < MAX_FAN_COUNT; i++) { - if (GET_BIT(needSetFanSpeed, i) && (OS_GetTimeMs() > nextCtrlFanTime)) + if (GET_BIT(needSetFanSpeed, i)) { if (storeCmd(fanCmd[i], setFanSpeed[i])) - { SET_BIT_OFF(needSetFanSpeed, i); - } - - nextCtrlFanTime = OS_GetTimeMs() + NEXT_FAN_WAIT; // avoid rapid fire, clogging the queue } } } -void ctrlFanQuerySetWait(const bool wait) +void ctrlFanQueryClearSendingWaiting(void) { - ctrlFanQueryWait = wait; + ctrlFanSendingWaiting = false; } -// query for controller fan only void ctrlFanQuery(void) { // following conditions ordered by importance - if (!ctrlFanQueryWait && infoHost.tx_slots != 0 && infoHost.connected && infoSettings.ctrl_fan_en) - { - ctrlFanQueryWait = storeCmd("M710\n"); - } + if (infoSettings.ctrl_fan_en && !ctrlFanSendingWaiting && infoHost.tx_slots != 0 && infoHost.connected) + ctrlFanSendingWaiting = storeCmd("M710\n"); } diff --git a/TFT/src/User/API/FanControl.h b/TFT/src/User/API/FanControl.h index 9eac89130f..a3ca822e38 100644 --- a/TFT/src/User/API/FanControl.h +++ b/TFT/src/User/API/FanControl.h @@ -9,27 +9,28 @@ extern "C" { #include #include "Settings.h" -#define FAN_TYPE_F 0 // Default cooling fan -#define FAN_TYPE_CTRL_S 1 // Controller FAN on Stepper/Bed On (Check - Marlin M710) -#define FAN_TYPE_CTRL_I 2 // Controller FAN on Idle (Check - Marlin M710) -#define FAN_TYPE_UNKNOWN 8 // Unknown / Not defined! +#define FAN_TYPE_F 0 // default cooling fan +#define FAN_TYPE_CTRL_S 1 // controller FAN on stepper/bed on (check - Marlin M710) +#define FAN_TYPE_CTRL_I 2 // controller FAN on idle (check - Marlin M710) +#define FAN_TYPE_UNKNOWN 8 // unknown / not defined! -extern const char* fanID[MAX_FAN_COUNT]; -extern const char* fanCmd[MAX_FAN_COUNT]; +extern const char * fanID[MAX_FAN_COUNT]; +extern const char * fanCmd[MAX_FAN_COUNT]; void fanResetSpeed(void); -bool fanIsValid(const uint8_t index); +bool fanIsValid(const uint8_t index); // check whether the index is a valid fan index void fanSetSpeed(const uint8_t i, const uint8_t speed); uint8_t fanGetSetSpeed(const uint8_t i); void fanSetPercent(const uint8_t i, const uint8_t percent); uint8_t fanGetSetPercent(const uint8_t i); void fanSetCurSpeed(const uint8_t i, const uint8_t speed); uint8_t fanGetCurSpeed(const uint8_t i); -void fanSetCurPercent(const uint8_t i, const uint8_t percent); -uint8_t fanGetCurPercent(const uint8_t i); -void loopFan(void); -void ctrlFanQuerySetWait(const bool wait); -void ctrlFanQuery(void); +void fanSetCurPercent(const uint8_t i, const uint8_t percent); // set current fan percent +uint8_t fanGetCurPercent(const uint8_t i); // get current fan percent + +void loopCheckFan(void); // called in loopBackEnd(). Loop for check on fan +void ctrlFanQueryClearSendingWaiting(void); // called in sendQueueCmd(). Clear sending waiting for controller fan query +void ctrlFanQuery(void); // query for controller fan only #ifdef __cplusplus } diff --git a/TFT/src/User/API/FlashStore.c b/TFT/src/User/API/FlashStore.c index 83346883b6..59e222b84b 100644 --- a/TFT/src/User/API/FlashStore.c +++ b/TFT/src/User/API/FlashStore.c @@ -9,7 +9,7 @@ #endif #define TSC_SIGN 0x20200512 // (YYYYMMDD) DO NOT MODIFY (Touch Screem Calibration sign) -#define PARA_SIGN 0x20220321 // (YYYYMMDD) if a new setting parameter is added, modify here and +#define PARA_SIGN 0x20240203 // (YYYYMMDD) if a new setting parameter is added, modify here and // initialize the initial value in the "initSettings()" function enum { diff --git a/TFT/src/User/API/Gcode/gcode.c b/TFT/src/User/API/Gcode/gcode.c index 9dbf5e824e..1b8b9cb062 100644 --- a/TFT/src/User/API/Gcode/gcode.c +++ b/TFT/src/User/API/Gcode/gcode.c @@ -1,9 +1,10 @@ #include "gcode.h" #include "includes.h" +#include "RRFStatusControl.h" REQUEST_COMMAND_INFO requestCommandInfo = {0}; -void waitForResponse(void) +static void waitForResponse(void) { TASK_LOOP_WHILE(!requestCommandInfo.done); } @@ -22,6 +23,14 @@ void clearRequestCommandInfo(void) } } +void abortRequestCommandInfo(void) +{ + requestCommandInfo.inWaitResponse = false; + requestCommandInfo.inResponse = false; + requestCommandInfo.done = true; + requestCommandInfo.inError = true; +} + static void resetRequestCommandInfo( const char * string_start, // The magic to identify the start const char * string_stop, // The magic to identify the stop @@ -34,8 +43,9 @@ static void resetRequestCommandInfo( requestCommandInfo.cmd_rev_buf = malloc(CMD_MAX_REV); - while (!requestCommandInfo.cmd_rev_buf) - ; // malloc failed + while (!requestCommandInfo.cmd_rev_buf) // if malloc failed, block the TFT + { + } memset(requestCommandInfo.cmd_rev_buf, 0, CMD_MAX_REV); requestCommandInfo.startMagic = string_start; @@ -187,7 +197,7 @@ long request_M23_M36(const char * filename) const char * sizeTag; char * strPtr; - if (infoMachineSettings.firmwareType != FW_REPRAPFW) // all other firmwares except reprap firmware + if (infoMachineSettings.firmwareType != FW_REPRAPFW) // all other firmwares except RepRap firmware { resetRequestCommandInfo("File opened", // The magic to identify the start "File selected", // The magic to identify the stop @@ -200,7 +210,7 @@ long request_M23_M36(const char * filename) sizeTag = "Size:"; } - else // reprap firmware + else // RepRap firmware { resetRequestCommandInfo("{\"err\"", // The magic to identify the start "}", // The magic to identify the stop @@ -210,7 +220,7 @@ long request_M23_M36(const char * filename) mustStoreCmd("M36 /%s\n", filename); - sizeTag = "size\":"; // reprap firmware reports size JSON + sizeTag = "size\":"; // RepRap firmware reports size JSON } waitForResponse(); // wait for response @@ -223,7 +233,7 @@ long request_M23_M36(const char * filename) } if (infoMachineSettings.firmwareType == FW_REPRAPFW) - mustStoreCmd("M23 /%s\n", filename); // send M23 for reprap firmware + mustStoreCmd("M23 /%s\n", filename); // send M23 for RepRap firmware // Find file size and report it strPtr = strstr(requestCommandInfo.cmd_rev_buf, sizeTag); @@ -278,7 +288,7 @@ void request_M125(void) } /** - * Stop or Unconditional stop in reprap firmware + * Stop or Unconditional stop in RepRap firmware */ void request_M0(void) { diff --git a/TFT/src/User/API/Gcode/gcode.h b/TFT/src/User/API/Gcode/gcode.h index 10d5955e9a..5c2c9186cb 100644 --- a/TFT/src/User/API/Gcode/gcode.h +++ b/TFT/src/User/API/Gcode/gcode.h @@ -34,6 +34,7 @@ extern REQUEST_COMMAND_INFO requestCommandInfo; bool requestCommandInfoIsRunning(void); void clearRequestCommandInfo(void); +void abortRequestCommandInfo(void); void detectAdvancedOk(void); bool request_M21(void); diff --git a/TFT/src/User/API/HW_Init.c b/TFT/src/User/API/HW_Init.c index 29ecba7fb4..f7c649af74 100644 --- a/TFT/src/User/API/HW_Init.c +++ b/TFT/src/User/API/HW_Init.c @@ -7,11 +7,11 @@ void HW_GetClocksFreq(CLOCKS *clk) { -#if defined GD32F2XX || defined GD32F3XX - RCU_GetClocksFreq(&clk->rccClocks); -#else - RCC_GetClocksFreq(&clk->rccClocks); -#endif + #if defined GD32F2XX || defined GD32F3XX + RCU_GetClocksFreq(&clk->rccClocks); + #else + RCC_GetClocksFreq(&clk->rccClocks); + #endif if (clk->rccClocks.PCLK1_Frequency < clk->rccClocks.HCLK_Frequency) // if (APBx presc = 1) x1 else x2 clk->PCLK1_Timer_Frequency = clk->rccClocks.PCLK1_Frequency * 2; @@ -27,11 +27,13 @@ void HW_GetClocksFreq(CLOCKS *clk) void HW_Init(void) { HW_GetClocksFreq(&mcuClocks); -#if defined GD32F2XX || defined GD32F3XX - nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); -#else - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); -#endif + + #if defined GD32F2XX || defined GD32F3XX + nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); + #else + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); + #endif + Delay_init(); #ifdef DISABLE_JTAG @@ -42,7 +44,7 @@ void HW_Init(void) DISABLE_DEBUG(); // disable JTAG & SWD #endif - #if defined(MKS_TFT) && !defined (MKS_TFT35_V1_0) // not used by MKS_TFT35_V1_0 + #if defined(MKS_TFT) && !defined(MKS_TFT35_V1_0) // not used by MKS_TFT35_V1_0 #if defined (GD32F3XX) rcu_periph_clock_enable(RCU_AF); gpio_pin_remap_config(GPIO_USART1_REMAP, ENABLE); diff --git a/TFT/src/User/API/LCD_Dimming.c b/TFT/src/User/API/LCD_Dimming.c index 3716b9f89e..ca89d2a77f 100644 --- a/TFT/src/User/API/LCD_Dimming.c +++ b/TFT/src/User/API/LCD_Dimming.c @@ -43,7 +43,7 @@ const LABEL lcd_idle_time_names[LCD_IDLE_TIME_COUNT] = { typedef struct { - uint32_t idle_ms; + uint32_t next_idle_time; bool dimmed; bool locked; } LCD_AUTO_DIM; @@ -62,10 +62,9 @@ bool LCD_IsBlocked(void) void LCD_Wake(void) { - if (infoSettings.lcd_idle_time != IDLE_TIME_OFF) + if (infoSettings.lcd_idle_time != IDLE_TIME_OFF) // if LCD dim function is activated { - // the LCD dim function is activated. First check if it's dimmed - if (lcd_dim.dimmed) + if (lcd_dim.dimmed) // if LCD is dimmed { lcd_dim.locked = false; lcd_dim.dimmed = false; @@ -79,8 +78,8 @@ void LCD_Wake(void) #endif } - // set a new idle_ms time - lcd_dim.idle_ms = OS_GetTimeMs(); + // always set next idle time + lcd_dim.next_idle_time = OS_GetTimeMs() + SEC_TO_MS(lcd_idle_times[infoSettings.lcd_idle_time]); } } @@ -89,49 +88,51 @@ void LCD_CheckDimming(void) if (infoSettings.lcd_idle_time == IDLE_TIME_OFF) return; - if (TS_IsPressed() + if (!TS_IsPressed() #if LCD_ENCODER_SUPPORT - || LCD_Enc_CheckState() + && !LCD_Enc_CheckState() #endif - ) + ) // if touch screen not pressed and rotary encoder neither pressed nor rotated { - if (lcd_dim.dimmed) - { - if (infoSettings.lcd_lock_on_idle && TS_IsPressed()) // if touch is blocked on idle and pressing on the LCD (not on the encoder), - lcd_dim.locked = true; // the first touch will be skipped preventing to trigger any undesired action + if (lcd_dim.dimmed || OS_GetTimeMs() < lcd_dim.next_idle_time) + return; - lcd_dim.dimmed = false; - LCD_SET_BRIGHTNESS(lcd_brightness[infoSettings.lcd_brightness]); + lcd_dim.locked = false; + lcd_dim.dimmed = true; + LCD_SET_BRIGHTNESS(lcd_brightness[infoSettings.lcd_idle_brightness]); - #ifdef KNOB_LED_COLOR_PIN - if (infoSettings.knob_led_idle) - { - Knob_LED_SetColor(knob_led_colors[infoSettings.knob_led_color], infoSettings.neopixel_pixels); - } - #endif - } + #ifdef KNOB_LED_COLOR_PIN + if (infoSettings.knob_led_idle) + { + Knob_LED_SetColor(knob_led_colors[KNOB_LED_OFF], infoSettings.neopixel_pixels); + } + #endif - lcd_dim.idle_ms = OS_GetTimeMs(); + return; } - else - { - if (OS_GetTimeMs() - lcd_dim.idle_ms < SEC_TO_MS(lcd_idle_times[infoSettings.lcd_idle_time])) - return; - if (!lcd_dim.dimmed) - { - lcd_dim.locked = false; - lcd_dim.dimmed = true; - LCD_SET_BRIGHTNESS(lcd_brightness[infoSettings.lcd_idle_brightness]); + // touch screen pressed and/or rotary encoder pressed or rotated - #ifdef KNOB_LED_COLOR_PIN - if (infoSettings.knob_led_idle) - { - Knob_LED_SetColor(knob_led_colors[KNOB_LED_OFF], infoSettings.neopixel_pixels); - } - #endif + // always set next idle time + lcd_dim.next_idle_time = OS_GetTimeMs() + SEC_TO_MS(lcd_idle_times[infoSettings.lcd_idle_time]); + + if (!lcd_dim.dimmed) + return; + + // if touch is blocked on idle and pressing on the LCD (not on the rotary encoder), + // the first touch will be skipped preventing to trigger any undesired action + if (infoSettings.lcd_lock_on_idle && TS_IsPressed()) + lcd_dim.locked = true; + + lcd_dim.dimmed = false; + LCD_SET_BRIGHTNESS(lcd_brightness[infoSettings.lcd_brightness]); + + #ifdef KNOB_LED_COLOR_PIN + if (infoSettings.knob_led_idle) + { + Knob_LED_SetColor(knob_led_colors[infoSettings.knob_led_color], infoSettings.neopixel_pixels); } - } + #endif } #ifdef KNOB_LED_COLOR_PIN diff --git a/TFT/src/User/API/LED_Event.c b/TFT/src/User/API/LED_Event.c index 779db0cc27..b98b78c0f4 100644 --- a/TFT/src/User/API/LED_Event.c +++ b/TFT/src/User/API/LED_Event.c @@ -1,19 +1,14 @@ #include "LED_Event.h" #include "includes.h" -#define UPDATE_TIME 2000 // 1 seconds is 1000 - -uint32_t lastUpdateTime = 0; -uint8_t prevLedValue = 0; -bool heatingDone = false; -bool printingDone = false; +#define LED_REFRESH_TIME 2000 // 1 seconds is 1000 //#define ROOM_TEMPERATURE #ifdef ROOM_TEMPERATURE #define MAX_COLD_TEMP 50 #define DEFAULT_COLD_TEMP 25 - uint16_t coldTemperature = 0; + static uint16_t coldTemperature = 0; #define COLD_TEMPERATURE coldTemperature #else @@ -22,16 +17,14 @@ bool printingDone = false; inline static bool nextUpdate(void) { - uint32_t curTime = OS_GetTimeMs(); + static uint32_t lastUpdateTime = 0; - if (curTime > (lastUpdateTime + UPDATE_TIME)) - { - lastUpdateTime = curTime; + if (OS_GetTimeMs() - lastUpdateTime < LED_REFRESH_TIME) + return false; - return true; - } + lastUpdateTime = OS_GetTimeMs(); - return false; + return true; } #ifdef ROOM_TEMPERATURE @@ -67,6 +60,10 @@ void getColdTemperature(void) void LED_CheckEvent(void) { + static uint8_t prevLedValue = 0; + static bool heatingDone = false; + static bool printingDone = false; + #ifdef ROOM_TEMPERATURE getColdTemperature(); #endif diff --git a/TFT/src/User/API/Language/Language.inc b/TFT/src/User/API/Language/Language.inc index 020575869d..6ff4efc2ea 100644 --- a/TFT/src/User/API/Language/Language.inc +++ b/TFT/src/User/API/Language/Language.inc @@ -11,6 +11,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings X_WORD (LANGUAGE) X_WORD (ADVANCED_OK) +X_WORD (COMMAND_CHECKSUM) X_WORD (EMULATED_M600) X_WORD (EMULATED_M109_M190) X_WORD (EVENT_LED) diff --git a/TFT/src/User/API/Language/language_am.h b/TFT/src/User/API/Language/language_am.h index f9b91998ff..cbc48d8c6a 100644 --- a/TFT/src/User/API/Language/language_am.h +++ b/TFT/src/User/API/Language/language_am.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Հայերեն" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_br.h b/TFT/src/User/API/Language/language_br.h index 160602c349..c9f3dd679a 100644 --- a/TFT/src/User/API/Language/language_br.h +++ b/TFT/src/User/API/Language/language_br.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Português BRASIL" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "M600 emulado" #define STRING_EMULATED_M109_M190 "M109 / M190 emulado" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_ca.h b/TFT/src/User/API/Language/language_ca.h index a8c293c163..510433c065 100644 --- a/TFT/src/User/API/Language/language_ca.h +++ b/TFT/src/User/API/Language/language_ca.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Català" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_cn.h b/TFT/src/User/API/Language/language_cn.h index d48f8b7257..dba6a6d7db 100644 --- a/TFT/src/User/API/Language/language_cn.h +++ b/TFT/src/User/API/Language/language_cn.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "简体中文" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "模拟M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_cz.h b/TFT/src/User/API/Language/language_cz.h index 633d6c22a4..b3a30f9ee1 100644 --- a/TFT/src/User/API/Language/language_cz.h +++ b/TFT/src/User/API/Language/language_cz.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Čeština" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulace M600" #define STRING_EMULATED_M109_M190 "Emulace M109 / M190" #define STRING_EVENT_LED "LED události" diff --git a/TFT/src/User/API/Language/language_de.h b/TFT/src/User/API/Language/language_de.h index 92aa2db4db..d041bee0c2 100644 --- a/TFT/src/User/API/Language/language_de.h +++ b/TFT/src/User/API/Language/language_de.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Deutsch" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emuliere M600" #define STRING_EMULATED_M109_M190 "Emuliere M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_en.h b/TFT/src/User/API/Language/language_en.h index 91f2714c67..94c0cb34fd 100644 --- a/TFT/src/User/API/Language/language_en.h +++ b/TFT/src/User/API/Language/language_en.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "English" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_es.h b/TFT/src/User/API/Language/language_es.h index 967dd70d76..6828c34f92 100644 --- a/TFT/src/User/API/Language/language_es.h +++ b/TFT/src/User/API/Language/language_es.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Español" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_fr.h b/TFT/src/User/API/Language/language_fr.h index 56dacfa83f..da7a776b87 100644 --- a/TFT/src/User/API/Language/language_fr.h +++ b/TFT/src/User/API/Language/language_fr.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Français" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emuler M600" #define STRING_EMULATED_M109_M190 "Emuler M109 / M190" #define STRING_EVENT_LED "LED Neopixel" diff --git a/TFT/src/User/API/Language/language_gr.h b/TFT/src/User/API/Language/language_gr.h index c3f2415460..17786dde70 100644 --- a/TFT/src/User/API/Language/language_gr.h +++ b/TFT/src/User/API/Language/language_gr.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Ελληνικά" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_hr.h b/TFT/src/User/API/Language/language_hr.h index b49500d542..b4795a7c70 100644 --- a/TFT/src/User/API/Language/language_hr.h +++ b/TFT/src/User/API/Language/language_hr.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Hrvatski" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emuliraj M600" #define STRING_EMULATED_M109_M190 "Emuliraj M109 / M190" #define STRING_EVENT_LED "LED event" diff --git a/TFT/src/User/API/Language/language_hu.h b/TFT/src/User/API/Language/language_hu.h index 742bfb1d11..342ae898da 100644 --- a/TFT/src/User/API/Language/language_hu.h +++ b/TFT/src/User/API/Language/language_hu.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Magyar" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulált M600" #define STRING_EMULATED_M109_M190 "Emulált M109 / M190" #define STRING_EVENT_LED "Esemény LED" diff --git a/TFT/src/User/API/Language/language_it.h b/TFT/src/User/API/Language/language_it.h index 796a89969f..ac2ecc161e 100644 --- a/TFT/src/User/API/Language/language_it.h +++ b/TFT/src/User/API/Language/language_it.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Italiano" #define STRING_ADVANCED_OK "OK avanzato" + #define STRING_COMMAND_CHECKSUM "Checksum comando" #define STRING_EMULATED_M600 "M600 emulato" #define STRING_EMULATED_M109_M190 "M109 / M190 emulati" #define STRING_EVENT_LED "LED evento" diff --git a/TFT/src/User/API/Language/language_jp.h b/TFT/src/User/API/Language/language_jp.h index 795495b790..1ec81a993a 100644 --- a/TFT/src/User/API/Language/language_jp.h +++ b/TFT/src/User/API/Language/language_jp.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "日本語" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_keywords.h b/TFT/src/User/API/Language/language_keywords.h index 4cfe967642..bd585b5619 100644 --- a/TFT/src/User/API/Language/language_keywords.h +++ b/TFT/src/User/API/Language/language_keywords.h @@ -11,6 +11,7 @@ extern "C" { // config.ini Parameter Settings - Screen Settings and Feature Settings #define LANG_KEY_LANGUAGE "label_language:" #define LANG_KEY_ADVANCED_OK "label_advanced_ok:" +#define LANG_KEY_COMMAND_CHECKSUM "label_command_checksum:" #define LANG_KEY_EMULATED_M600 "label_emulated_m600:" #define LANG_KEY_EMULATED_M109_M190 "label_emulated_m109_m190:" #define LANG_KEY_EVENT_LED "label_event_led:" diff --git a/TFT/src/User/API/Language/language_nl.h b/TFT/src/User/API/Language/language_nl.h index 4a55305626..93a8ecee1b 100644 --- a/TFT/src/User/API/Language/language_nl.h +++ b/TFT/src/User/API/Language/language_nl.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Dutch" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_pl.h b/TFT/src/User/API/Language/language_pl.h index 55dba591c9..a949debcef 100644 --- a/TFT/src/User/API/Language/language_pl.h +++ b/TFT/src/User/API/Language/language_pl.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Polski" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulowane M600" #define STRING_EMULATED_M109_M190 "Emulowane M109 / M190" #define STRING_EVENT_LED "Sygn. zdarzenia diodą LED" diff --git a/TFT/src/User/API/Language/language_pt.h b/TFT/src/User/API/Language/language_pt.h index 3a5635e385..b3a4e339fa 100644 --- a/TFT/src/User/API/Language/language_pt.h +++ b/TFT/src/User/API/Language/language_pt.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Portugues" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_ru.h b/TFT/src/User/API/Language/language_ru.h index 17d7f9b976..d843efa38b 100644 --- a/TFT/src/User/API/Language/language_ru.h +++ b/TFT/src/User/API/Language/language_ru.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Русский" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Эмуляция M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_sk.h b/TFT/src/User/API/Language/language_sk.h index 45d6295b17..41a47dd221 100644 --- a/TFT/src/User/API/Language/language_sk.h +++ b/TFT/src/User/API/Language/language_sk.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Slovensky" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_sl.h b/TFT/src/User/API/Language/language_sl.h index eda325177f..8e0628641d 100644 --- a/TFT/src/User/API/Language/language_sl.h +++ b/TFT/src/User/API/Language/language_sl.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Slovenski" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_tc.h b/TFT/src/User/API/Language/language_tc.h index 18074e7d1d..fcbe2609c9 100644 --- a/TFT/src/User/API/Language/language_tc.h +++ b/TFT/src/User/API/Language/language_tc.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "正體中文" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_tr.h b/TFT/src/User/API/Language/language_tr.h index 3bd1dbec58..8b4b352e71 100644 --- a/TFT/src/User/API/Language/language_tr.h +++ b/TFT/src/User/API/Language/language_tr.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Türkçe" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/Language/language_uk.h b/TFT/src/User/API/Language/language_uk.h index 65a4657d7e..98fc67df35 100644 --- a/TFT/src/User/API/Language/language_uk.h +++ b/TFT/src/User/API/Language/language_uk.h @@ -4,6 +4,7 @@ // config.ini Parameter Settings - Screen Settings and Feature Settings #define STRING_LANGUAGE "Українська" #define STRING_ADVANCED_OK "Advanced OK" + #define STRING_COMMAND_CHECKSUM "Command checksum" #define STRING_EMULATED_M600 "Emulated M600" #define STRING_EMULATED_M109_M190 "Emulated M109 / M190" #define STRING_EVENT_LED "Event LED" diff --git a/TFT/src/User/API/parseACK.c b/TFT/src/User/API/Mainboard_AckHandler.c similarity index 94% rename from TFT/src/User/API/parseACK.c rename to TFT/src/User/API/Mainboard_AckHandler.c index 233153ecf2..1ff03b1089 100644 --- a/TFT/src/User/API/parseACK.c +++ b/TFT/src/User/API/Mainboard_AckHandler.c @@ -1,6 +1,6 @@ -#include "parseACK.h" +#include "Mainboard_AckHandler.h" #include "includes.h" -#include "RRFParseACK.hpp" +#include "RRFAckHandler.hpp" typedef enum // popup message types available to display an echo message { @@ -21,9 +21,6 @@ const ECHO knownEcho[] = { {ECHO_NOTIFY_NONE, "busy: processing"}, {ECHO_NOTIFY_NONE, "Now fresh file:"}, {ECHO_NOTIFY_NONE, "Now doing file:"}, - //{ECHO_NOTIFY_NONE, "Probe Offset"}, - //{ECHO_NOTIFY_NONE, "enqueueing \"M117\""}, - {ECHO_NOTIFY_NONE, "Flow:"}, {ECHO_NOTIFY_NONE, "echo:;"}, // M503 {ECHO_NOTIFY_NONE, "echo: G"}, // M503 {ECHO_NOTIFY_NONE, "echo: M"}, // M503 @@ -357,9 +354,9 @@ static inline void hostActionCommands(void) } } -void parseACK(void) +void parseAck(void) { - while (Serial_NewDataAvailable(SERIAL_PORT) && (ack_len = Serial_Get(SERIAL_PORT, ack_cache, ACK_CACHE_SIZE)) != 0) // if some data have been retrieved + while (Serial_DataAvailableRX(SERIAL_PORT) && (ack_len = Serial_Get(SERIAL_PORT, ack_cache, ACK_CACHE_SIZE)) != 0) // if some data have been retrieved { UPD_RX_KPIS(ack_len); // debug monitoring KPI @@ -369,6 +366,8 @@ void parseACK(void) Serial_Put(SERIAL_DEBUG_PORT, ack_cache); #endif + InfoHost_UpdateAckTimestamp(); // update last received ACK message timestamp + bool avoid_terminal = false; //---------------------------------------- @@ -401,13 +400,12 @@ void parseACK(void) if (ack_seen(heaterID[CHAMBER])) infoSettings.chamber_en = ENABLED; - updateNextHeatCheckTime(); + heatSetNextUpdateTime(); // set next temperature query time or timeout if (!ack_seen("@")) // it's RepRapFirmware { storeCmd("M92\n"); storeCmd("M115\n"); // as last command to identify the FW type! - coordinateQuerySetWait(true); } else if (infoMachineSettings.firmwareType == FW_NOT_DETECTED) // if never connected to the printer since boot { @@ -420,7 +418,7 @@ void parseACK(void) // 1) store on command queue the above gcodes to detect printer info // 2) re-initialize infoHost when connected to avoid this code branch is executed again - // 3) set requestCommandInfo.inJson to "false" and detect the presence of Marlin ADVANCED_OK + // 3) set requestCommandInfo.inJson to "false" and detect the presence of Marlin "ADVANCED_OK" // feature (if any) and its command queue size // 4) finally, set listening mode flag according to its last state stored in flash // @@ -515,7 +513,7 @@ void parseACK(void) // proceed with generic OK response handling to update infoHost.tx_slots and infoHost.tx_count // if (infoMachineSettings.firmwareType == FW_REPRAPFW || ack_starts_with("ok")) - InfoHost_HandleOkAck(HOST_SLOTS_GENERIC_OK); + InfoHost_HandleAckOk(HOST_SLOTS_GENERIC_OK); } goto parse_end; @@ -526,7 +524,7 @@ void parseACK(void) //---------------------------------------- // check for a possible json response and eventually parse and process it - else if (!requestCommandInfo.inWaitResponse && infoMachineSettings.firmwareType == FW_REPRAPFW) + else if (infoMachineSettings.firmwareType == FW_REPRAPFW && !requestCommandInfo.inWaitResponse) { if (strchr(ack_cache, '{') != NULL) requestCommandInfo.inJson = true; @@ -537,10 +535,10 @@ void parseACK(void) if (ack_seen(magic_warning)) ackPopupInfo(magic_warning); else - rrfParseACK(ack_cache); + rrfParseAck(ack_cache); // proceed with generic OK response handling to update infoHost.tx_slots and infoHost.tx_count - InfoHost_HandleOkAck(HOST_SLOTS_GENERIC_OK); + InfoHost_HandleAckOk(HOST_SLOTS_GENERIC_OK); goto parse_end; } @@ -555,7 +553,7 @@ void parseACK(void) // if regular OK response ("ok\n") if (ack_cache[ack_index] == '\n') { - InfoHost_HandleOkAck(infoSettings.tx_slots); + InfoHost_HandleAckOk(infoSettings.tx_slots); goto parse_end; // nothing else to do } @@ -563,15 +561,15 @@ void parseACK(void) // if ADVANCED_OK response (e.g. "ok N10 P15 B3\n"). Required "ADVANCED_OK" in Marlin if (ack_continue_seen("P") && ack_continue_seen("B")) { - InfoHost_HandleOkAck(ack_value()); + InfoHost_HandleAckOk(ack_value()); goto parse_end; // nothing else to do } - // if here, it is a temperature response (e.g. "ok T:16.13 /0.00 B:16.64 /0.00 @:0 B@:0\n"). + // if here, it is an M105 temperature response (e.g. "ok T:16.13 /0.00 B:16.64 /0.00 @:0 B@:0\n"). // Proceed with generic OK response handling to update infoHost.tx_slots and infoHost.tx_count // and then continue applying the next matching patterns to handle the temperature response - InfoHost_HandleOkAck(HOST_SLOTS_GENERIC_OK); + InfoHost_HandleAckOk(HOST_SLOTS_GENERIC_OK); } //---------------------------------------- @@ -588,7 +586,9 @@ void parseACK(void) // Pushed / polled / on printing parsed responses //---------------------------------------- - // parse and store temperatures (e.g. "ok T:16.13 /0.00 B:16.64 /0.00 @:0 B@:0\n") + // parse and store M105 or auto reported (M155) temperature response, + // e.g. "ok T:16.13 /0.00 B:16.64 /0.00 @:0 B@:0\n" for M105, + // e.g. "T:16.13 /0.00 B:16.64 /0.00 @:0 B@:0\n" for auto reported (M155) else if ((ack_seen("@") && ack_seen("T:")) || ack_seen("T0:")) { uint8_t heaterIndex = NOZZLE0; @@ -612,7 +612,12 @@ void parseACK(void) } avoid_terminal = !infoSettings.terminal_ack; - updateNextHeatCheckTime(); + heatSetNextUpdateTime(); // set next temperature query time or timeout + } + // parse and store M114 E, extruder position. Required "M114_DETAIL" in Marlin + else if (ack_seen("Count E:")) + { + coordinateSetExtruderActualSteps(ack_value()); } // parse and store M114, current position else if (ack_starts_with("X:") || ack_seen("C: X:")) // Smoothieware axis position starts with "C: X:" @@ -631,37 +636,16 @@ void parseACK(void) coordinateSetAxisActual(E_AXIS, ack_value()); } } - - coordinateQuerySetWait(false); - } - // parse and store M114 E, extruder position. Required "M114_DETAIL" in Marlin - else if (ack_seen("Count E:")) - { - coordinateSetExtruderActualSteps(ack_value()); } // parse and store feed rate percentage - else if (ack_seen("FR:")) + else if (ack_seen("FR:") || (infoMachineSettings.firmwareType == FW_SMOOTHIEWARE && ack_seen("Speed factor at "))) { speedSetCurPercent(0, ack_value()); - speedQuerySetWait(false); } // parse and store flow rate percentage - else if (ack_seen("Flow:")) - { - speedSetCurPercent(1, ack_value()); - speedQuerySetWait(false); - } - // parse and store feed rate percentage in case of Smoothieware - else if ((infoMachineSettings.firmwareType == FW_SMOOTHIEWARE) && ack_seen("Speed factor at ")) - { - speedSetCurPercent(0, ack_value()); - speedQuerySetWait(false); - } - // parse and store flow rate percentage in case of Smoothieware - else if ((infoMachineSettings.firmwareType == FW_SMOOTHIEWARE) && ack_seen("Flow rate at ")) + else if (ack_seen("Flow:") || (infoMachineSettings.firmwareType == FW_SMOOTHIEWARE && ack_seen("Flow rate at "))) { speedSetCurPercent(1, ack_value()); - speedQuerySetWait(false); } // parse and store M106, fan speed else if (ack_starts_with("M106")) @@ -676,8 +660,6 @@ void parseACK(void) if (ack_seen("I")) fanSetCurSpeed(MAX_COOLING_FAN_COUNT + 1, ack_value()); - - ctrlFanQuerySetWait(false); } // parse pause message else if (!infoMachineSettings.promptSupport && ack_seen("paused for user")) @@ -759,6 +741,8 @@ void parseACK(void) setPrintAbort(); } } + + printSetNextUpdateTime(); // set next printing query time or timeout } // parse and store M73 else @@ -782,6 +766,11 @@ void parseACK(void) } } } + // "Resend:" response handling. Required COMMAND_CHECKSUM feature enabled in TFT or managed by remote host + else if (ack_starts_with("Resend:")) + { + handleCmdLineNumberMismatch((uint32_t)ack_value()); + } //---------------------------------------- // Tuning parsed responses @@ -1356,7 +1345,21 @@ void parseACK(void) // parse error messages else if (ack_seen(magic_error)) { - ackPopupInfo(magic_error); + // command line number mismatch or checksum mismatch. + // Required COMMAND_CHECKSUM feature enabled in TFT or managed by remote host + if (ack_continue_seen("Last Line:")) + { + if (getCmdLineNumberOk() != (uint32_t)ack_value()) // if error message not already displayed for the same line number + { + setCmdLineNumberOk((uint32_t)ack_value()); + ack_seen(magic_error); // just to reset ack_index to the beginning of the full error message to display + ackPopupInfo(magic_error); // display error message + } + } + else + { + ackPopupInfo(magic_error); + } } // parse echo messages else if (ack_starts_with(magic_echo)) @@ -1410,16 +1413,14 @@ void parseACK(void) { if (ack_seen("External") || ack_seen("Software") || ack_seen("Watchdog") || ack_seen("Brown out")) { - // proceed to reset the command queue, host status, fan speeds and load default machine settings. + // proceed to reset the host status (it includes also command queue, pending queries and info queries) + // and load default machine settings. // These functions will also trigger the query of temperatures which together with the resets // done will also trigger the query of the motherboard capabilities and settings. It is necessary // to do so because after the motherboard reset things might have changed (ex. FW update by M997) - clearCmdQueue(); InfoHost_Init(false); initMachineSettings(); - fanResetSpeed(); - coordinateSetKnown(false); } } @@ -1442,7 +1443,7 @@ void parseACK(void) Serial_Forward(ack_port_index, ack_cache); // if no pending gcode (all "ok" have been received), reset ACK port index to avoid wrong relaying (in case no - // more commands will be sent by interfaceCmd) of any successive spontaneous ACK message + // more commands will be sent by Mainboard_CmdHandler.c) of any successive spontaneous ACK message if (infoHost.tx_count == 0) ack_port_index = PORT_1; } diff --git a/TFT/src/User/API/parseACK.h b/TFT/src/User/API/Mainboard_AckHandler.h similarity index 73% rename from TFT/src/User/API/parseACK.h rename to TFT/src/User/API/Mainboard_AckHandler.h index d8c44ac6cb..588d6075fd 100644 --- a/TFT/src/User/API/parseACK.h +++ b/TFT/src/User/API/Mainboard_AckHandler.h @@ -1,5 +1,5 @@ -#ifndef _PARSE_ACK_H_ -#define _PARSE_ACK_H_ +#ifndef _MAINBOARD_ACK_HANDLER_H_ +#define _MAINBOARD_ACK_HANDLER_H_ #ifdef __cplusplus extern "C" { @@ -11,7 +11,7 @@ extern "C" { void setHostDialog(bool isHostDialog); bool getHostDialog(void); void setCurrentAckSrc(SERIAL_PORT_INDEX portIndex); -void parseACK(void); +void parseAck(void); #ifdef __cplusplus } diff --git a/TFT/src/User/API/Mainboard_CmdControl.c b/TFT/src/User/API/Mainboard_CmdControl.c new file mode 100644 index 0000000000..b85b48eb57 --- /dev/null +++ b/TFT/src/User/API/Mainboard_CmdControl.c @@ -0,0 +1,167 @@ +#include +#include + +// line number of last command properly processed by mainboard, +// base line number and line number of last command sent by TFT respectively. +// Required COMMAND_CHECKSUM feature enabled in TFT +static uint32_t cmd_line_number_ok = NO_LINE_NUMBER; +static uint32_t cmd_line_number_base = 0; +static uint32_t cmd_line_number = 0; + +uint32_t getCmdLineNumberOk(void) +{ + return cmd_line_number_ok; +} + +void setCmdLineNumberOk(const uint32_t lineNumber) +{ + cmd_line_number_ok = lineNumber; +} + +uint32_t getCmdLineNumberBase(void) +{ + return cmd_line_number_base; +} + +void setCmdLineNumberBase(const uint32_t lineNumber) +{ + cmd_line_number_base = cmd_line_number = lineNumber; +} + +uint32_t getCmdLineNumber(void) +{ + return cmd_line_number; +} + +uint32_t addCmdLineNumberAndChecksum(CMD cmd, uint8_t cmdIndex, uint8_t * cmdLen) +{ + CMD plainCmd; // plain command (with no line number and checksum, if any) + + strcpy(plainCmd, &cmd[cmdIndex]); // e.g. "N1 G28*18\n" -> "G28*18\n" + stripCmdChecksum(plainCmd); // e.g. "G28*18\n" -> "G28" + + if (strlen(plainCmd) + 16 > CMD_MAX_SIZE) // we consider extra bytes for line number, checksum, "\n" and "\0" + { + addNotification(DIALOG_TYPE_ERROR, "Cmd too long", cmd, true); + + return NO_LINE_NUMBER; + } + + cmd_line_number++; // next command line number to be used + + sprintf(cmd, "N%lu %s", cmd_line_number, plainCmd); // e.g. "G28" -> "N2 G28" + sprintf(strchr(cmd, '\0'), "*%u\n", getCmdChecksum(cmd)); // e.g. "N2 G28" -> "N2 G28*17\n" + + *cmdLen = strlen(cmd); + + return cmd_line_number; +} + +const char * stripCmdHead(const CMD cmd) +{ + // example: ": /test/cap2.gcode\n" -> "test/cap2.gcode\n" + + while (*cmd == ' ' || *cmd == '/' || *cmd == ':') + { + cmd++; + } + + return cmd; +} + +void stripCmdChecksum(CMD cmd) +{ + // examples: + // + // "/test/cap2.gcode *18\n\0" -> "/test/cap2.gcode" + // "/test/cap2.gcode \n\0" -> "/test/cap2.gcode" + + char * cmdPtr = strrchr(cmd, '*'); // e.g. "/test/cap2.gcode *18\n\0" -> "*18\n\0" + + if (cmdPtr == NULL) + cmdPtr = cmd + strlen(cmd); // e.g. "/test/cap2.gcode \n\0" -> "\0" + + while (cmdPtr != cmd) + { + // e.g. "*18\n\0" -> " *18\n\0" + // e.g. "\0" -> "\n\0" + // + --cmdPtr; + + if (*cmdPtr != ' ' && *cmdPtr != '\t' && *cmdPtr != '\n' && *cmdPtr != '\r') + { + cmdPtr++; // next char has to be set to "\0" + break; + } + } + + // e.g. " *18\n\0" -> "\0 *18\n\0" + // e.g. " \n\0" -> "\0 \n\0" + // + *cmdPtr = '\0'; +} + +uint8_t getCmdChecksum(const CMD cmd) +{ + uint8_t checksum = 0; + + while (*cmd != '\0') + { + checksum ^= *(cmd++); + } + + return checksum; +} + +bool validateCmdChecksum(const CMD cmd) +{ + char * cmdPtr = strrchr(cmd, '*'); // e.g. "N1 G28*18\n\0" -> "*18\n\0" + + if (cmdPtr == NULL) + return false; + + uint8_t checksum = 0; + uint8_t value = strtol(&cmdPtr[1], NULL, 10); + + while (cmdPtr != cmd) + { + checksum ^= *(--cmdPtr); + } + + return (checksum == value ? true : false); +} + +const char * parseM118(CMD cmd, bool * hasE, bool * hasA) +{ + stripCmdChecksum((char *) stripCmdHead(cmd)); + + *hasE = false; + *hasA = false; + + for (uint8_t i = 3; i--;) + { + // A1, E1 and Pn are always parsed out + if (!(((cmd[0] == 'A' || cmd[0] == 'E') && cmd[1] == '1') || (cmd[0] == 'P' && NUMERIC(cmd[1])))) + break; + + switch (cmd[0]) + { + case 'A': + *hasA = true; + break; + + case 'E': + *hasE = true; + break; + } + + cmd += 2; + + while (*cmd == ' ') + { + ++cmd; + } + } + + return cmd; +} diff --git a/TFT/src/User/API/Mainboard_CmdControl.h b/TFT/src/User/API/Mainboard_CmdControl.h new file mode 100644 index 0000000000..9d7ab3e685 --- /dev/null +++ b/TFT/src/User/API/Mainboard_CmdControl.h @@ -0,0 +1,35 @@ +#ifndef _MAINBOARD_CMD_CONTROL_ +#define _MAINBOARD_CMD_CONTROL_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include // for CMD + +#define NO_LINE_NUMBER 0xFFFFFFFF; // no processed line number + +uint32_t getCmdLineNumberOk(void); // get line number of last command properly processed by mainboard +void setCmdLineNumberOk(const uint32_t lineNumber); // set line number of last command properly processed by mainboard +uint32_t getCmdLineNumberBase(void); // get base line number +void setCmdLineNumberBase(const uint32_t lineNumber); // set base line number +uint32_t getCmdLineNumber(void); // get line number of last command sent by TFT + +// add line number and checksum to the provided command (cmd and cmdLen are properly set) +// and return the used line number +uint32_t addCmdLineNumberAndChecksum(CMD cmd, uint8_t cmdIndex, uint8_t * cmdLen); + +const char * stripCmdHead(const CMD cmd); // strip out any leading " ", "/" or ":" character that might be in the command +void stripCmdChecksum(CMD cmd); // strip out any trailing checksum that might be in the command +uint8_t getCmdChecksum(const CMD cmd); // return checksum for the provided command +bool validateCmdChecksum(const CMD cmd); // validate checksum for the provided command + +const char * parseM118(CMD cmd, bool * hasE, bool * hasA); // parse M118 gcode + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/TFT/src/User/API/interfaceCmd.c b/TFT/src/User/API/Mainboard_CmdHandler.c similarity index 86% rename from TFT/src/User/API/interfaceCmd.c rename to TFT/src/User/API/Mainboard_CmdHandler.c index 1846afa17c..f9eeaf2c85 100644 --- a/TFT/src/User/API/interfaceCmd.c +++ b/TFT/src/User/API/Mainboard_CmdHandler.c @@ -1,8 +1,9 @@ -#include "interfaceCmd.h" +#include "Mainboard_CmdHandler.h" #include "includes.h" -#include "RRFSendCmd.h" +#include "RRFStatusControl.h" -#define CMD_QUEUE_SIZE 20 +#define CMD_QUEUE_SIZE 20 +#define CMD_RETRY_COUNT 3 typedef struct { @@ -18,6 +19,14 @@ typedef struct uint8_t count; // count of commands in the queue } GCODE_QUEUE; +typedef struct +{ + uint32_t line_number; // line number used as matching key with value reported by mainboard on "Resend: " ACK message + bool retry; // flag set to "true" to trigger a command resend. Initially set to "false" (no need to resend) + int8_t retry_attempts; // remaining retry attempts. Initially set to default max value CMD_RETRY_COUNT + GCODE_INFO gcode_info; // command to resend +} GCODE_RETRY_INFO; + typedef enum { NO_WRITING = 0, @@ -25,13 +34,15 @@ typedef enum ONBOARD_WRITING } WRITING_MODE; -GCODE_QUEUE cmdQueue; // command queue where commands to be sent are stored +GCODE_QUEUE cmdQueue; // command queue where commands to be sent are stored +GCODE_RETRY_INFO cmdRetryInfo = {0}; // command retry info. Required COMMAND_CHECKSUM feature enabled in TFT + char * cmd_ptr; uint8_t cmd_len; -SERIAL_PORT_INDEX cmd_port_index; // index of serial port originating the gcode -uint8_t cmd_base_index; // base index in case the gcode has checksum ("Nxxx " is present at the beginning of gcode) +SERIAL_PORT_INDEX cmd_port_index; // index of serial port originating the gcode +uint8_t cmd_base_index; // base index in case the gcode has checksum ("Nxx " is present at the beginning of gcode) uint8_t cmd_index; -WRITING_MODE writing_mode = NO_WRITING; +WRITING_MODE writing_mode = NO_WRITING; // writing mode. Used by M28 and M29 FIL file; uint8_t getQueueCount(void) @@ -182,25 +193,20 @@ void clearCmdQueue(void) // Strip out any leading space from the passed command. // Furthermore, skip any N[-0-9] (line number) and return a pointer to the beginning of the command. -char * stripCmd(char ** cmdPtr) +char * stripCmd(char * cmdPtr) { - char * strPtr = *cmdPtr; - // skip leading spaces - while (*strPtr == ' ') strPtr++; // e.g. " N1 G28*46\n" -> "N1 G28*46\n" - - // save pointer to skipped spaces - *cmdPtr = strPtr; // e.g. " N1 G28*46\n" -> "N1 G28*46\n" + while (*cmdPtr == ' ') cmdPtr++; // e.g. " N1 G28*18\n" -> "N1 G28*18\n" // skip N[-0-9] (line number) if included in the command line - if (*strPtr == 'N' && NUMERIC(strPtr[1])) // e.g. "N1 G28*46\n" -> "G28*46\n" + if (*cmdPtr == 'N' && NUMERIC(cmdPtr[1])) // e.g. "N1 G28*18\n" -> "G28*18\n" { - strPtr += 2; // skip N[-0-9] - while (NUMERIC(*strPtr)) strPtr++; // skip [0-9]* - while (*strPtr == ' ') strPtr++; // skip [ ]* + cmdPtr += 2; // skip N[-0-9] + while (NUMERIC(*cmdPtr)) cmdPtr++; // skip [0-9]* + while (*cmdPtr == ' ') cmdPtr++; // skip [ ]* } - return strPtr; + return cmdPtr; } // Get the data of the next to be sent command in cmdQueue @@ -215,16 +221,33 @@ static inline bool getCmd(void) // // set cmd_base_index with index of gcode command // - cmd_base_index = stripCmd(&cmd_ptr) - cmd_ptr; // e.g. "N1 G28*46\n" -> "G28*46\n" + cmd_base_index = stripCmd(cmd_ptr) - cmd_ptr; // e.g. "N1 G28*18\n" -> "G28*18\n" // set cmd_index with index of gcode value - cmd_index = cmd_base_index + 1; // e.g. "G28*46\n" -> "28*46\n" + cmd_index = cmd_base_index + 1; // e.g. "G28*18\n" -> "28*18\n" cmd_len = strlen(cmd_ptr); // length of gcode return (cmd_port_index == PORT_1); // if gcode is originated by TFT (SERIAL_PORT), return "true" } +static inline void getCmdFromCmdRetryInfo(void) +{ + cmd_ptr = cmdRetryInfo.gcode_info.gcode; + cmd_port_index = cmdRetryInfo.gcode_info.port_index; + cmd_len = strlen(cmd_ptr); +} + +void setCmdRetryInfo(uint32_t lineNumber) +{ + cmdRetryInfo.line_number = lineNumber; // set line number to the provided value + cmdRetryInfo.retry = false; // set retry flag to "false" (no need to resend) + cmdRetryInfo.retry_attempts = CMD_RETRY_COUNT; // set retry attempts to default max value CMD_RETRY_COUNT + + strncpy_no_pad(cmdRetryInfo.gcode_info.gcode, cmd_ptr, CMD_MAX_SIZE); // copy command + cmdRetryInfo.gcode_info.port_index = cmd_port_index; // copy port index +} + // Purge gcode cmd or send it to the printer and then remove it from cmdQueue queue. bool sendCmd(bool purge, bool avoidTerminal) { @@ -238,24 +261,40 @@ bool sendCmd(bool purge, bool avoidTerminal) // dump serial data sent to debug port Serial_Put(SERIAL_DEBUG_PORT, serialPort[cmd_port_index].id); // serial port ID (e.g. "2" for SERIAL_PORT_2) Serial_Put(SERIAL_DEBUG_PORT, ">>"); - - if (purge) - Serial_Put(SERIAL_DEBUG_PORT, purgeStr); - - Serial_Put(SERIAL_DEBUG_PORT, cmd_ptr); #endif if (!purge) // if command is not purged, send it to printer { + if (!cmdRetryInfo.retry) // if there is no pending command to resend + { + if (GET_BIT(infoSettings.general_settings, INDEX_COMMAND_CHECKSUM) == 1) + setCmdRetryInfo(addCmdLineNumberAndChecksum(cmd_ptr, cmd_base_index, &cmd_len)); // cmd_ptr and cmd_len are updated + + cmdQueue.count--; + cmdQueue.index_r = (cmdQueue.index_r + 1) % CMD_QUEUE_SIZE; + } + else // if there is a pending command to resend + { + cmdRetryInfo.retry = false; // disable command resend flag + cmdRetryInfo.retry_attempts--; // update remaining retry attempts + } + + // send or resend command + UPD_TX_KPIS(cmd_len); // debug monitoring KPI - if (infoMachineSettings.firmwareType != FW_REPRAPFW) - Serial_Put(SERIAL_PORT, cmd_ptr); - else - rrfSendCmd(cmd_ptr); + Serial_Put(SERIAL_PORT, cmd_ptr); setCurrentAckSrc(cmd_port_index); } + #if defined(SERIAL_DEBUG_PORT) && defined(DEBUG_SERIAL_COMM) + else // if command is purged + { + Serial_Put(SERIAL_DEBUG_PORT, purgeStr); + } + + Serial_Put(SERIAL_DEBUG_PORT, cmd_ptr); + #endif if (!avoidTerminal && MENU_IS(menuTerminal)) { @@ -265,9 +304,6 @@ bool sendCmd(bool purge, bool avoidTerminal) terminalCache(cmd_ptr, cmd_len, cmd_port_index, SRC_TERMINAL_GCODE); } - cmdQueue.count--; - cmdQueue.index_r = (cmdQueue.index_r + 1) % CMD_QUEUE_SIZE; - return !purge; // return "true" if command was sent. Otherwise, return "false" } @@ -334,12 +370,12 @@ bool initRemoteTFT() { // examples: // - // "cmd_ptr" = "N1 M23 SD:/test/cap2.gcode*36\n" - // "cmd_ptr" = "N1 M23 S /test/cap2.gcode*36\n" + // "cmd_ptr" = "N1 M23 SD:/test/cap2.gcode*12\n" + // "cmd_ptr" = "N1 M23 S /test/cap2.gcode*82\n" // // "infoFile.path" = "SD:/test/cap2.gcode" - // e.g. "N1 M23 SD:/test/cap2.gcode*36\n" -> "SD:/test/cap2.gcode*36\n" + // e.g. "N1 M23 SD:/test/cap2.gcode*12\n" -> "SD:/test/cap2.gcode*12\n" // if (cmd_seen_from(cmd_base_index, "SD:") || cmd_seen_from(cmd_base_index, "S ")) infoFile.source = FS_TFT_SD; // set source first @@ -354,11 +390,11 @@ bool initRemoteTFT() CMD path; // temporary working buffer (cmd_ptr buffer must always remain unchanged) // cmd_index was set by cmd_seen_from() function - strcpy(path, &cmd_ptr[cmd_index]); // e.g. "N1 M23 SD:/test/cap2.gcode*36\n" -> "/test/cap2.gcode*36\n" - stripChecksum(path); // e.g. "/test/cap2.gcode*36\n" -> /test/cap2.gcode" + strcpy(path, &cmd_ptr[cmd_index]); // e.g. "N1 M23 SD:/test/cap2.gcode*12\n" -> "/test/cap2.gcode*12\n" + stripCmdChecksum(path); // e.g. "/test/cap2.gcode*12\n" -> /test/cap2.gcode" - resetInfoFile(); // then reset infoFile (source is restored) - enterFolder(stripHead(path)); // set path as last + resetInfoFile(); // then reset infoFile (source is restored) + enterFolder(stripCmdHead(path)); // set path as last return true; } @@ -419,12 +455,12 @@ static inline void writeRemoteTFT() { // examples: // - // "cmd_ptr" = "N1 G28*46\n" - // "cmd_ptr" = "N2 G29*56\n" - // "cmd_ptr" = "N3 M29*66\n" + // "cmd_ptr" = "N1 G28*18\n" + // "cmd_ptr" = "N2 G29*16\n" + // "cmd_ptr" = "N3 M29*27\n" // if M29, stop writing mode. cmd_index (used by cmd_value() function) was set by sendQueueCmd() function - if (cmd_ptr[cmd_base_index] == 'M' && cmd_value() == 29) // e.g. "N3 M29*66\n" -> "M29*66\n" + if (cmd_ptr[cmd_base_index] == 'M' && cmd_value() == 29) // e.g. "N3 M29*27\n" -> "M29*27\n" { f_close(&file); @@ -437,12 +473,13 @@ static inline void writeRemoteTFT() UINT br; CMD cmd; // temporary working buffer (cmd_ptr buffer must always remain unchanged) - strcpy(cmd, &cmd_ptr[cmd_base_index]); // e.g. "N1 G28*46\n" -> "G28*46\n" - stripChecksum(cmd); // e.g. "G28*46\n" -> "G28" + strcpy(cmd, &cmd_ptr[cmd_base_index]); // e.g. "N1 G28*18\n" -> "G28*18\n" + stripCmdChecksum(cmd); // e.g. "G28*18\n" -> "G28" f_write(&file, cmd, strlen(cmd), &br); - // "\n" is always removed by stripChecksum() function even if there is no checksum, so we need to write it on file separately + // "\n" is always removed by stripCmdChecksum() function even if there is no checksum, + // so we need to write it on file separately f_write(&file, "\n", 1, &br); f_sync(&file); } @@ -476,6 +513,37 @@ void syncTargetTemp(uint8_t index) } } +void handleCmdLineNumberMismatch(const uint32_t lineNumber) +{ + // if no buffered command with the requested line number is found or it is found but the maximum number of retry + // attempts is reached, reset the line number with M110 just to try to avoid further retransmission requests for + // the same line number or for any out of synch command already sent to the mainboard (e.g. in case ADVANCED_OK + // feature is enabled in TFT) + if (cmdRetryInfo.line_number != lineNumber || cmdRetryInfo.retry_attempts == 0) + { + if (getCmdLineNumberBase() != lineNumber) // if notification not already displayed for the same line number + { + char msgText[MAX_MSG_LENGTH]; + + snprintf(msgText, MAX_MSG_LENGTH, "line: cur=%lu, exp=%lu", cmdRetryInfo.line_number, lineNumber); + + addNotification(DIALOG_TYPE_ERROR, "Cmd not found", msgText, false); + } + + setCmdLineNumberBase(lineNumber); // set base line number of next command sent by the TFT to the requested line number + + CMD cmd; + + sprintf(cmd, "M110 N%lu", lineNumber); + + sendEmergencyCmd(cmd); // immediately send M110 command to set new base line number on mainboard + } + else // if a command with the requested line number is present on the buffer and + { // not already resent for the maximum retry attempts, mark it as to be sent + cmdRetryInfo.retry = true; + } +} + // Check if the received gcode is an emergency command or not // (M108, M112, M410, M524, M876) and parse it accordingly. // Otherwise, store the gcode on command queue. @@ -484,13 +552,13 @@ void handleCmd(CMD cmd, const SERIAL_PORT_INDEX portIndex) // strip out any leading space from the passed command. // Furthermore, skip any N[-0-9] (line number) and return a pointer to the beginning of the command // - char * strPtr = stripCmd(&cmd); // e.g. " N1 G28*46\n" -> "G28*46\n" + char * cmdPtr = stripCmd(cmd); // e.g. " N1 G28*18\n" -> "G28*18\n" // check if the received gcode is an emergency command and parse it accordingly - if (strPtr[0] == 'M') + if (cmdPtr[0] == 'M') { - switch (strtol(&strPtr[1], NULL, 10)) + switch (strtol(&cmdPtr[1], NULL, 10)) { case 108: // M108 case 112: // M112 @@ -529,23 +597,32 @@ void sendEmergencyCmd(const CMD emergencyCmd, const SERIAL_PORT_INDEX portIndex) Serial_Put(SERIAL_DEBUG_PORT, emergencyCmd); #endif - if (infoMachineSettings.firmwareType != FW_REPRAPFW) - Serial_Put(SERIAL_PORT, emergencyCmd); - else - rrfSendCmd(emergencyCmd); + uint8_t cmdLen = strlen(emergencyCmd); + + UPD_TX_KPIS(cmdLen); // debug monitoring KPI + + Serial_Put(SERIAL_PORT, emergencyCmd); setCurrentAckSrc(portIndex); if (MENU_IS(menuTerminal)) - terminalCache(emergencyCmd, strlen(emergencyCmd), portIndex, SRC_TERMINAL_GCODE); + terminalCache(emergencyCmd, cmdLen, portIndex, SRC_TERMINAL_GCODE); } // Parse and send gcode cmd in cmdQueue queue. void sendQueueCmd(void) { - if (infoHost.tx_slots == 0 || cmdQueue.count == 0) return; + if (infoHost.tx_slots == 0 || (cmdQueue.count == 0 && !cmdRetryInfo.retry)) return; bool avoid_terminal = false; + + if (cmdRetryInfo.retry) // if there is a pending command to resend + { + getCmdFromCmdRetryInfo(); // retrieve gcode from cmdRetryInfo + + goto send_cmd; // send the command + } + bool fromTFT = getCmd(); // retrieve leading gcode in the queue and check if it is originated by TFT or other hosts if (writing_mode != NO_WRITING) // if writing mode (previously triggered by M28) @@ -653,8 +730,8 @@ void sendQueueCmd(void) if (!fromTFT) { // NOTE: If the file was selected (with M23) from onboard media, infoFile.source will be set to - // FS_ONBOARD_MEDIA_REMOTE by the startPrintingFromRemoteHost() function called in parseAck.c - // during M23 ACK parsing + // FS_ONBOARD_MEDIA_REMOTE by the startPrintingFromRemoteHost() function called in + // Mainboard_AckHandler.c during M23 ACK parsing if (infoFile.source < FS_ONBOARD_MEDIA) // if a file was selected from TFT media with M23 { @@ -725,7 +802,7 @@ void sendQueueCmd(void) } else { - setPrintUpdateWaiting(false); + printClearSendingWaiting(); } break; @@ -838,7 +915,7 @@ void sendQueueCmd(void) #else // not SERIAL_PORT_2 case 27: // M27 - setPrintUpdateWaiting(false); + printClearSendingWaiting(); break; #endif // SERIAL_PORT_2 @@ -865,17 +942,15 @@ void sendQueueCmd(void) } break; - case 80: // M80 - #ifdef PS_ON_PIN + #ifdef PS_ON_PIN + case 80: // M80 PS_ON_On(); - #endif - break; + break; - case 81: // M81 - #ifdef PS_ON_PIN + case 81: // M81 PS_ON_Off(); - #endif - break; + break; + #endif case 82: // M82 eSetRelative(false); @@ -895,7 +970,7 @@ void sendQueueCmd(void) if (fromTFT) { - heatSetUpdateWaiting(false); + heatClearSendingWaiting(); if (cmd_value() == 105) // if M105 { @@ -934,11 +1009,20 @@ void sendQueueCmd(void) } break; + case 110: // M110 + setCmdLineNumberBase(cmd_seen('N') ? (uint32_t)cmd_value() : 0); + break; + case 114: // M114 - #ifdef FIL_RUNOUT_PIN - if (fromTFT) - FIL_PosE_SetUpdateWaiting(false); - #endif + if (fromTFT) + { + if (!cmd_seen('E')) + coordinateQueryClearSendingWaiting(); + #ifdef FIL_RUNOUT_PIN + else + FIL_PosE_ClearSendingWaiting(); + #endif + } break; case 117: // M117 @@ -968,8 +1052,8 @@ void sendQueueCmd(void) strncpy_no_pad(rawMsg, &cmd_ptr[cmd_base_index + 4], CMD_MAX_SIZE); // retrieve message text - stripChecksum(rawMsg); - msgText = stripHead(rawMsg); + stripCmdChecksum(rawMsg); + msgText = stripCmdHead(rawMsg); statusSetMsg((uint8_t *)"M117", (uint8_t *)msgText); @@ -1104,11 +1188,17 @@ void sendQueueCmd(void) case 220: // M220 if (cmd_seen('S')) speedSetCurPercent(0, cmd_value()); + + if (fromTFT) + speedQueryClearSendingWaiting(); break; case 221: // M221 if (cmd_seen('S')) speedSetCurPercent(1, cmd_value()); + + if (fromTFT) + speedQueryClearSendingWaiting(); break; #ifdef BUZZER_PIN @@ -1157,7 +1247,7 @@ void sendQueueCmd(void) caseLightSetPercent(cmd_value()); break; - case 376: // M376 (Reprap FW) + case 376: // M376 (RepRap firmware) if (infoMachineSettings.firmwareType == FW_REPRAPFW && cmd_seen('H')) setParameter(P_ABL_STATE, 1, cmd_float()); break; @@ -1287,6 +1377,9 @@ void sendQueueCmd(void) if (cmd_seen('I')) fanSetCurSpeed(MAX_COOLING_FAN_COUNT + 1, cmd_value()); + + if (fromTFT) + ctrlFanQueryClearSendingWaiting(); break; case 900: // M900 linear advance factor diff --git a/TFT/src/User/API/interfaceCmd.h b/TFT/src/User/API/Mainboard_CmdHandler.h similarity index 90% rename from TFT/src/User/API/interfaceCmd.h rename to TFT/src/User/API/Mainboard_CmdHandler.h index 79995c0937..193d89da73 100644 --- a/TFT/src/User/API/interfaceCmd.h +++ b/TFT/src/User/API/Mainboard_CmdHandler.h @@ -1,5 +1,5 @@ -#ifndef _INTERFACE_CMD_H_ -#define _INTERFACE_CMD_H_ +#ifndef _MAINBOARD_CMD_HANDLER_H_ +#define _MAINBOARD_CMD_HANDLER_H_ #ifdef __cplusplus extern "C" { @@ -33,6 +33,7 @@ void mustStoreCmd(const char * format, ...); void mustStoreScript(const char * format, ...); bool storeCmdFromUART(const CMD cmd, const SERIAL_PORT_INDEX portIndex); void clearCmdQueue(void); +void handleCmdLineNumberMismatch(const uint32_t lineNumber); void handleCmd(CMD cmd, const SERIAL_PORT_INDEX portIndex); void sendEmergencyCmd(const CMD emergencyCmd, const SERIAL_PORT_INDEX portIndex); void sendQueueCmd(void); diff --git a/TFT/src/User/API/Mainboard_FlowControl.c b/TFT/src/User/API/Mainboard_FlowControl.c new file mode 100644 index 0000000000..c48a50fb48 --- /dev/null +++ b/TFT/src/User/API/Mainboard_FlowControl.c @@ -0,0 +1,287 @@ +#include "Mainboard_FlowControl.h" +#include "includes.h" +#include "RRFStatusControl.h" + +CLOCKS mcuClocks; +PRIORITY_COUNTER priorityCounter; +HOST infoHost; +MENU infoMenu; + +void resetInfoQueries(void) +{ + fanResetSpeed(); + coordinateSetKnown(false); + setRunoutAlarmFalse(); +} + +void resetPendingQueries(void) +{ + abortRequestCommandInfo(); // abort pending command query + + ctrlFanQueryClearSendingWaiting(); // clear sending waiting for controller fan query + speedQueryClearSendingWaiting(); // clear sending waiting for speed query + coordinateQueryClearSendingWaiting(); // clear sending waiting for coordinate query + + heatClearSendingWaiting(); // clear sending waiting for temperature query + printClearSendingWaiting(); // clear sending waiting for printing query + + #ifdef FIL_RUNOUT_PIN + FIL_PosE_ClearSendingWaiting(); // clear sending waiting for position query + #endif +} + +// non-UI background loop tasks +void loopBackEnd(void) +{ + UPD_SCAN_RATE(); // debug monitoring KPI + + // handle a print from TFT media, if any + loopPrintFromTFT(); + + // parse and send gcode commands in the queue + sendQueueCmd(); + + // parse the received slave response information + parseAck(); + + // retrieve and store (in command queue) the gcodes received from other UART, such as ESP3D etc... + #ifdef SERIAL_PORT_2 + Serial_GetFromUART(); + #endif + + // handle USB communication + #ifdef USB_FLASH_DRIVE_SUPPORT + USB_LoopProcess(); + #endif + + if ((priorityCounter.be++ % BE_PRIORITY_DIVIDER) != 0) // a divider value of 16 -> run 6% of the time only + return; + + // handle ACK message timeout + if (InfoHost_HandleAckTimeout()) // if ACK message timeout, unlock any pending query waiting for an update + resetPendingQueries(); + + // fan speed monitor + loopCheckFan(); + + // speed & flow monitor + loopCheckSpeed(); + + if (infoMachineSettings.firmwareType != FW_REPRAPFW) + loopCheckHeater(); // temperature monitor + else + rrfStatusQuery(); // query RRF status + + // handle a print from (remote) onboard media, if any + if (infoMachineSettings.onboardSD == ENABLED) + loopPrintFromOnboard(); + + // Buzzer handling + #ifdef BUZZER_PIN + loopBuzzer(); + #endif + + // check filament runout status + #ifdef FIL_RUNOUT_PIN + FIL_BE_CheckRunout(); + #endif + + // check changes in encoder steps + #if LCD_ENCODER_SUPPORT + #ifdef HAS_EMULATOR + if (MENU_IS_NOT(menuMarlinMode)) + #endif + { + LCD_Enc_CheckSteps(); + } + #endif + + // check mode switching + #ifdef HAS_EMULATOR + Mode_CheckSwitching(); + #endif + + // handle screenshot capture + #ifdef SCREEN_SHOT_TO_SD + loopScreenShot(); + #endif + + // check if Back is pressed and held + #ifdef SMART_HOME + loopCheckBackPress(); + #endif + + // check LCD screen dimming + #ifdef LCD_LED_PWM_CHANNEL + LCD_CheckDimming(); + #endif + + // check LED Event + if (GET_BIT(infoSettings.general_settings, INDEX_EVENT_LED) == 1) + LED_CheckEvent(); +} + +// UI-related background loop tasks +void loopFrontEnd(void) +{ + // check if volume source (SD/USB) insert + loopVolumeSource(); + + // loop to check and run toast messages + loopToast(); + + // if there is a message in the status bar, timed clear + loopReminderManage(); + + // busy Indicator clear + loopBusySignClear(); + + // check update temperature status + loopTemperatureStatus(); + + // loop for filament runout detection + #ifdef FIL_RUNOUT_PIN + FIL_FE_CheckRunout(); + #endif + + // loop for popup menu + loopPopup(); +} + +void loopProcess(void) +{ + loopBackEnd(); + + if ((priorityCounter.fe++ % FE_PRIORITY_DIVIDER) != 0) // a divider value of 16 -> run 6% of the time only + return; + + loopFrontEnd(); +} + +void menuDummy(void) +{ + CLOSE_MENU(); +} + +void loopProcessAndGUI(void) +{ + uint8_t curMenu = infoMenu.cur; + + loopProcess(); + + if (infoMenu.cur != curMenu) // if a user interaction is needed (e.g. dialog box), handle it + { + (*infoMenu.menu[infoMenu.cur])(); // handle user interaction + + if (MENU_IS_NOT(menuDummy)) // avoid to nest menuDummy menu type + OPEN_MENU(menuDummy); // load a dummy menu just to force the redraw of the underlying menu (caller menu) + } +} + +void InfoHost_Init(bool isConnected) +{ + infoHost.target_tx_slots = infoSettings.tx_slots; + infoHost.tx_slots = 1; // set to 1 just to allow a soft start + infoHost.tx_count = 0; + infoHost.rx_timestamp = OS_GetTimeMs(); + infoHost.connected = isConnected; + infoHost.listening_mode = false; // temporary disable listening mode. It will be later set by InfoHost_UpdateListeningMode() + infoHost.status = HOST_STATUS_IDLE; + + if (!isConnected) + { + clearCmdQueue(); + resetPendingQueries(); + resetInfoQueries(); + + setReminderMsg(LABEL_UNCONNECTED, SYS_STATUS_DISCONNECTED); // set the no printer attached reminder + } +} + +void InfoHost_HandleAckOk(int16_t target_tx_slots) +{ + // the following check should always be matched unless: + // - an ACK message not related to a gcode originated by the TFT is received + // - an ACK message for an out of band gcode (e.g. emergency gcode) is received + // + if (infoHost.tx_count > 0) + infoHost.tx_count--; + + // NOTE: the following code always allows to align infoHost.tx_slots even in case of switching ON/OFF + // the ADVANCED_OK feature in TFT and/or in case infoHost.tx_slots is beeing also managed by + // Marlin (if ADVANCED_OK is enabled in Marlin firmware) + // + + // if ADVANCED_OK is disabled in TFT + // + if (GET_BIT(infoSettings.general_settings, INDEX_ADVANCED_OK) == 0) + { + infoHost.tx_slots = 1; + } + // + // if ADVANCED_OK is enabled in TFT or Marlin + // + else if (target_tx_slots >= 0) + { + // UPPER LIMITER + // + // the following check is matched in case: + // - ADVANCED_OK is enabled in TFT. infoSettings.tx_slots for static ADVANCED_OK configured in TFT is used + // - ADVANCED_OK is enabled in Marlin but the mainboard reply (target_tx_slots) is out of sync (above) with the current + // pending gcodes (it happens sometimes). infoSettings.tx_slots for Marlin ADVANCED_OK detected at TFT boot is used + // + if (target_tx_slots + infoHost.tx_count >= infoSettings.tx_slots) + infoHost.tx_slots = infoSettings.tx_slots - infoHost.tx_count; + // + // LOWER LIMITER (only for Marlin ADVANCED_OK) + // + // if printing from onboard media target_tx_slots is always reported as 0 by Marlin even if there are no pending gcodes + // so just set infoHost.tx_slots to 1 to allow the transmission of one gcode per time avoiding a possible TFT freeze + // + else if (target_tx_slots != 0 || infoHost.tx_count != 0) // if not printing from onboard media + infoHost.tx_slots = target_tx_slots; + else // if printing from onboard media + infoHost.tx_slots = 1; + + infoHost.target_tx_slots = infoHost.tx_slots; // set new current target + } + // + // if generic OK response handling (e.g. temperature response), increment the current value up to current target + // + else + { + // UPPER AND LOWER LIMITER + // + // limit the current value up to current target or to 1 if current target was set to 0 and there are no more pending gcodes + // + if (infoHost.tx_slots < infoHost.target_tx_slots || (infoHost.tx_slots == 0 && infoHost.tx_count == 0)) + infoHost.tx_slots++; + } +} + +bool InfoHost_HandleAckTimeout(void) +{ + if (OS_GetTimeMs() - infoHost.rx_timestamp < ACK_TIMEOUT || infoHost.tx_count == 0) // if no timeout or no pending gcode + return false; + + infoHost.rx_timestamp = OS_GetTimeMs(); // update timestamp + + InfoHost_HandleAckOk(HOST_SLOTS_GENERIC_OK); // release pending gcode + + //addNotification(DIALOG_TYPE_ERROR, "ACK timed out", "Pending gcode released", true); + + return true; +} + +void InfoHost_UpdateAckTimestamp(void) +{ + infoHost.rx_timestamp = OS_GetTimeMs(); +} + +void InfoHost_UpdateListeningMode(void) +{ + infoHost.listening_mode = (GET_BIT(infoSettings.general_settings, INDEX_LISTENING_MODE) == 1); + + if (infoHost.listening_mode) + setReminderMsg(LABEL_LISTENING, SYS_STATUS_LISTENING); // if TFT in listening mode, display a reminder message +} diff --git a/TFT/src/User/API/Mainboard_FlowControl.h b/TFT/src/User/API/Mainboard_FlowControl.h new file mode 100644 index 0000000000..f643c7f690 --- /dev/null +++ b/TFT/src/User/API/Mainboard_FlowControl.h @@ -0,0 +1,97 @@ +#ifndef _MAINBOARD_FLOW_CONTROL_H_ +#define _MAINBOARD_FLOW_CONTROL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "variants.h" // for RCC_ClocksTypeDef + +#define BE_PRIORITY_DIVIDER 16 // a divider value of 16 -> run 6% of the time only. Use a power of 2 for performance reasons! +#define FE_PRIORITY_DIVIDER 16 // a divider value of 16 -> run 6% of the time only. Use a power of 2 for performance reasons! +#define ACK_TIMEOUT 15000 // 15 seconds (1 sec is 1000) +#define MAX_MENU_DEPTH 10 // max sub menu depth + +// menu macros +#define OPEN_MENU(x) infoMenu.menu[++infoMenu.cur] = x +#define REPLACE_MENU(x) infoMenu.menu[infoMenu.cur] = x +#define CLOSE_MENU() infoMenu.cur-- +#define MENU_IS(x) infoMenu.menu[infoMenu.cur] == x +#define MENU_IS_NOT(x) infoMenu.menu[infoMenu.cur] != x + +typedef struct +{ + RCC_ClocksTypeDef rccClocks; + uint32_t PCLK1_Timer_Frequency; + uint32_t PCLK2_Timer_Frequency; +} CLOCKS; + +typedef struct +{ + uint32_t be; // back end + uint32_t fe; // front end +} PRIORITY_COUNTER; + +typedef enum +{ + HOST_STATUS_IDLE = 0, + HOST_STATUS_PRINTING, + HOST_STATUS_RESUMING, + HOST_STATUS_PAUSED, + HOST_STATUS_PAUSING +} HOST_STATUS; + +typedef enum +{ + HOST_SLOTS_GENERIC_OK = -1, +} HOST_SLOTS; + +typedef struct +{ + uint8_t target_tx_slots; // keep track of target gcode tx slots (e.g. if ADVANCED_OK feature is enabled on both mainboard and TFT) + uint8_t tx_slots; // keep track of available gcode tx slots (e.g. if ADVANCED_OK feature is enabled on both mainboard and TFT) + uint8_t tx_count; // keep track of pending gcode tx count + uint32_t rx_timestamp; // keep track of last received ACK message timestamp + bool connected; // TFT is connected to Marlin + bool listening_mode; // TFT is in listening mode from Marlin + HOST_STATUS status; // host is busy in printing execution. (USB serial printing and gcode print from onboard) +} HOST; + +typedef void (* FP_MENU)(void); + +typedef struct +{ + FP_MENU menu[MAX_MENU_DEPTH]; // menu function buffer + uint8_t cur; // current menu index in buffer +} MENU; + +extern CLOCKS mcuClocks; // system clocks: SYSCLK, AHB, APB1, APB2, APB1_Timer, APB2_Timer2 +extern PRIORITY_COUNTER priorityCounter; // priority counter +extern HOST infoHost; // information interaction with Marlin +extern MENU infoMenu; // menu structure + +void resetPendingQueries(void); +void loopBackEnd(void); +void loopFrontEnd(void); +void loopProcess(void); +void loopProcessAndGUI(void); + +void InfoHost_Init(bool isConnected); + +// handle ACK message OK response: +// - tx_slots (used/effective only in case "advanced_ok" configuration setting is also enabled in TFT): +// - < 0 (HOST_SLOTS_GENERIC_OK): to increase infoHost.tx_slots up to current target and decrease infoHost.tx_count by 1 +// - >= 0: to handle static ADVANCED_OK and Marlin ADVANCED_OK +void InfoHost_HandleAckOk(int16_t tx_slots); + +bool InfoHost_HandleAckTimeout(void); // handle ACK message timeout, if any. Return "true" if ACK message timed out +void InfoHost_UpdateAckTimestamp(void); // update last received ACK message timestamp +void InfoHost_UpdateListeningMode(void); // update listening mode + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/TFT/src/User/API/ModeSwitching.c b/TFT/src/User/API/ModeSwitching.c index 4e8850c117..29269b95ff 100644 --- a/TFT/src/User/API/ModeSwitching.c +++ b/TFT/src/User/API/ModeSwitching.c @@ -31,9 +31,9 @@ void Mode_Switch(void) { uint32_t startUpTime = OS_GetTimeMs(); - heatSetUpdateSeconds(TEMPERATURE_QUERY_FAST_SECONDS); LOGO_ReadDisplay(); - updateNextHeatCheckTime(); // send "M105" after a delay, because of mega2560 will be hanged when received data at startup + heatSetUpdateSeconds(TEMPERATURE_QUERY_FAST_SECONDS); + heatSetNextUpdateTime(); // send "M105" after a delay, because of mega2560 will be hanged when received data at startup TASK_LOOP_WHILE(OS_GetTimeMs() - startUpTime < BTT_BOOTSCREEN_TIME); // display logo BTT_BOOTSCREEN_TIME ms @@ -46,7 +46,7 @@ void Mode_Switch(void) case MODE_MARLIN: #ifdef HAS_EMULATOR if (infoSettings.serial_always_on == ENABLED) - updateNextHeatCheckTime(); // send "M105" after a delay, because of mega2560 will be hanged when received data at startup + heatSetNextUpdateTime(); // send "M105" after a delay, because of mega2560 will be hanged when received data at startup REPLACE_MENU(menuMarlinMode); #endif diff --git a/TFT/src/User/API/Notification.c b/TFT/src/User/API/Notification.c index b16c61c9a3..8b5c09e19c 100644 --- a/TFT/src/User/API/Notification.c +++ b/TFT/src/User/API/Notification.c @@ -14,17 +14,17 @@ typedef struct } TOAST; // toast notification variables -static TOAST toastlist[TOAST_MSG_COUNT]; - -static uint8_t nextToastIndex = 0; // next index to store new toast -static uint8_t curToastDisplay = 0; // current toast notification being displayed -static uint32_t nextToastTime = 0; // time to change to next notification - -static NOTIFICATION msglist[MAX_MSG_COUNT]; -static uint8_t nextMsgIndex = 0; // next index to store new message -static void (*notificationHandler)() = NULL; - -bool _toastRunning = false; +static TOAST toastlist[TOAST_MSG_COUNT]; // toast notification array +static bool _toastRunning = false; // "true" when a toast notification is currently displayed +static bool _toastAvailable = false; // "true" when a new toast is added. "false" when no more toasts to display are available +static uint8_t nextToastIndex = 0; // next index to store new toast +static uint8_t curToastDisplay = 0; // current toast notification being displayed +static uint32_t nextToastTime = 0; // time to change to next toast notification + +// message notification variables +static NOTIFICATION msglist[MAX_MSG_COUNT]; // message notification array +static uint8_t nextMsgIndex = 0; // next index to store new message +static void (* notificationHandler)() = NULL; // message notification handler // add new message to toast notification queue void addToast(DIALOG_TYPE style, char * text) @@ -34,24 +34,9 @@ void addToast(DIALOG_TYPE style, char * text) strncpy_no_pad(toastlist[nextToastIndex].text, text, TOAST_MSG_LENGTH); toastlist[nextToastIndex].style = style; toastlist[nextToastIndex].isNew = true; - nextToastIndex = (nextToastIndex + 1) % TOAST_MSG_COUNT; -} -// check if notification is currently displayed -bool toastRunning(void) -{ - return _toastRunning; -} - -// check if any new notification is available -static inline bool toastAvailable(void) -{ - for (int i = 0; i < TOAST_MSG_COUNT; i++) - { - if (toastlist[i].isNew == true) - return true; - } - return false; + _toastAvailable = true; + nextToastIndex = (nextToastIndex + 1) % TOAST_MSG_COUNT; } // show next notification @@ -66,33 +51,33 @@ void drawToast(bool redraw) _toastRunning = true; // draw icon - uint8_t *icon; - SOUND cursound; + uint8_t * icon; + SOUND curSound; switch (toastlist[curToastDisplay].style) { case DIALOG_TYPE_ERROR: GUI_SetColor(NOTIF_ICON_ERROR_BG_COLOR); icon = IconCharSelect(CHARICON_ERROR); - cursound = SOUND_ERROR; + curSound = SOUND_ERROR; break; case DIALOG_TYPE_SUCCESS: GUI_SetColor(NOTIF_ICON_SUCCESS_BG_COLOR); icon = IconCharSelect(CHARICON_OK_ROUND); - cursound = SOUND_SUCCESS; + curSound = SOUND_SUCCESS; break; default: GUI_SetColor(NOTIF_ICON_INFO_BG_COLOR); icon = IconCharSelect(CHARICON_INFO); - cursound = SOUND_TOAST; + curSound = SOUND_TOAST; break; } if (!redraw) // if notification is new { - BUZZER_PLAY(cursound); // play sound + BUZZER_PLAY(curSound); // play sound nextToastTime = OS_GetTimeMs() + SEC_TO_MS(TOAST_DURATION); // set new timer } @@ -114,22 +99,42 @@ void drawToast(bool redraw) } } +// check if notification is currently displayed +bool toastRunning(void) +{ + return _toastRunning; +} + +// check if any new notification is available +static inline bool toastAvailable(void) +{ + for (int i = 0; i < TOAST_MSG_COUNT; i++) + { + if (toastlist[i].isNew == true) + return true; + } + + return false; +} + // check and control toast notification display void loopToast(void) { - if (getMenuType() != MENU_TYPE_FULLSCREEN && OS_GetTimeMs() > nextToastTime) + // if no new toast is available or it is not yet expired on screen or in case a full screen menu is displayed, do nothing + if (_toastAvailable == false || OS_GetTimeMs() < nextToastTime || getMenuType() == MENU_TYPE_FULLSCREEN) + return; + + if (toastAvailable()) { - if (toastAvailable()) - { - drawToast(false); - } - else if (_toastRunning == true) - { - _toastRunning = false; - GUI_ClearPrect(&toastIconRect); - GUI_ClearPrect(&toastRect); - menuDrawTitle(); - } + drawToast(false); + } + else if (_toastRunning == true) + { + _toastRunning = false; + _toastAvailable = false; + GUI_ClearPrect(&toastIconRect); + GUI_ClearPrect(&toastRect); + menuDrawTitle(); } } @@ -145,6 +150,7 @@ void addNotification(DIALOG_TYPE style, char * title, char * text, bool drawDial { memcpy(&msglist[i], &msglist[i + 1], sizeof(NOTIFICATION)); } + nextMsgIndex = MAX_MSG_COUNT - 1; } @@ -173,7 +179,7 @@ void replayNotification(uint8_t index) } // retrieve a stored notification -NOTIFICATION *getNotification(uint8_t index) +NOTIFICATION * getNotification(uint8_t index) { if (msglist[index].title[0] != '\0' && msglist[index].text[0] != '\0') return &msglist[index]; @@ -189,28 +195,28 @@ bool hasNotification(void) void clearNotification(void) { nextMsgIndex = 0; + for (int i = 0; i < MAX_MSG_COUNT; i++) { msglist[i].text[0] = '\0'; msglist[i].title[0] = '\0'; } + notificationDot(); statusSetReady(); } +void setNotificationHandler(void (* handler)()) +{ + notificationHandler = handler; +} + // check if pressed on titlebar area void titleBarPress(void) { if (getMenuType() == MENU_TYPE_ICON || getMenuType() == MENU_TYPE_LISTVIEW) { if (MENU_IS_NOT(menuNotification)) - { OPEN_MENU(menuNotification); - } } } - -void setNotificationHandler(void (*handler)()) -{ - notificationHandler = handler; -} diff --git a/TFT/src/User/API/Notification.h b/TFT/src/User/API/Notification.h index 29ce457c90..7771cdf0bd 100644 --- a/TFT/src/User/API/Notification.h +++ b/TFT/src/User/API/Notification.h @@ -12,11 +12,11 @@ extern "C" { #define TOAST_X_PAD START_X #define TOAST_Y_PAD 3 -#define TOAST_MSG_COUNT 3 +#define TOAST_MSG_COUNT 5 #define TOAST_MSG_LENGTH 35 #define TOAST_DISPLAY_LENGTH TOAST_MSG_LENGTH -#define MAX_MSG_COUNT 3 +#define MAX_MSG_COUNT 5 #define MAX_MSG_TITLE_LENGTH 15 #define MAX_MSG_LENGTH 70 @@ -27,17 +27,18 @@ typedef struct char text[MAX_MSG_LENGTH]; } NOTIFICATION; -bool toastRunning(void); void addToast(DIALOG_TYPE style, char * text); void drawToast(bool redraw); +bool toastRunning(void); void loopToast(void); + void addNotification(DIALOG_TYPE style, char * title, char * text, bool drawDialog); void replayNotification(uint8_t index); NOTIFICATION * getNotification(uint8_t index); bool hasNotification(void); -void titleBarPress(void); void clearNotification(void); -void setNotificationHandler(void (*handler)()); +void setNotificationHandler(void (* handler)()); +void titleBarPress(void); #ifdef __cplusplus } diff --git a/TFT/src/User/API/PowerFailed.c b/TFT/src/User/API/PowerFailed.c index 39b57ccd71..f1ab46cb45 100644 --- a/TFT/src/User/API/PowerFailed.c +++ b/TFT/src/User/API/PowerFailed.c @@ -203,9 +203,7 @@ void powerFailedCreate(char *path) if (f_write(&fpPowerFailed, &infoBreakPoint, sizeof(infoBreakPoint), &br) == FR_OK) { if (f_sync(&fpPowerFailed) == FR_OK) - { create_ok = true; - } } } } diff --git a/TFT/src/User/API/Printing.c b/TFT/src/User/API/Printing.c index ac5ff3f05f..e3b2e72b1f 100644 --- a/TFT/src/User/API/Printing.c +++ b/TFT/src/User/API/Printing.c @@ -24,11 +24,13 @@ typedef struct PRINTING infoPrinting = {0}; PRINT_SUMMARY infoPrintSummary = {.name[0] = '\0', 0, 0, 0, 0, false}; -static bool updateM27Waiting = false; static bool extrusionDuringPause = false; // flag for extrusion during Print -> Pause static bool filamentRunoutAlarm = false; static float lastEPos = 0; // used only to update stats in infoPrintSummary +static uint32_t nextUpdateTime = 0; +static bool sendingWaiting = false; + void setExtrusionDuringPause(bool extruded) { extrusionDuringPause = extruded; @@ -52,9 +54,8 @@ bool getRunoutAlarm(void) void clearQueueAndMore(void) { clearCmdQueue(); + resetPendingQueries(); setRunoutAlarmFalse(); - heatSetUpdateWaiting(false); - setPrintUpdateWaiting(false); } void breakAndContinue(void) @@ -345,11 +346,6 @@ void sendPrintCodes(uint8_t index) } } -void setPrintUpdateWaiting(bool isWaiting) -{ - updateM27Waiting = isWaiting; -} - void updatePrintUsedFilament(void) { float ePos = coordinateGetAxis(E_AXIS); @@ -424,7 +420,7 @@ bool startPrintFromRemoteHost(const char * filename) { infoFile.source = FS_ONBOARD_MEDIA_REMOTE; // set source first resetInfoFile(); // then reset infoFile (source is restored) - enterFolder(stripHead(filename)); // set path as last + enterFolder(stripCmdHead(filename)); // set path as last request_M27(infoSettings.m27_refresh_time); // use gcode M27 in case of a print running from remote onboard media } @@ -502,7 +498,7 @@ bool startPrint(void) if (infoFile.source == FS_ONBOARD_MEDIA) { - // let setPrintResume() (that will be called in parseAck.c by parsing ACK message for M24 or M27) + // let setPrintResume() (that will be called in Mainboard_AckHandler.c by parsing ACK message for M24 or M27) // notify the print as started (infoHost.status set to "HOST_STATUS_PRINTING") infoHost.status = HOST_STATUS_RESUMING; @@ -578,7 +574,7 @@ void abortPrint(void) case FS_REMOTE_HOST: // - forward a print cancel notification to all hosts (so also the one handling the print) asking to cancel the print // - the host handling the print should respond to this notification with "M118 P0 A1 action:cancel" that will - // trigger setPrintAbort() in parseACK() once the following loop does its job (stopping all blocking operations) + // trigger setPrintAbort() in parseAck() once the following loop does its job (stopping all blocking operations) // mustStoreCmd("M118 P0 A1 action:notification remote cancel\n"); waitForAbort(); @@ -588,9 +584,10 @@ void abortPrint(void) } // - forward a print cancel action to all hosts (also TFT) to notify the print cancelation - // - the print cancel action received by the TFT always guarantees the invokation of setPrintAbort() in parseAck.c - // (e.g. to finalize the print (e.g. stats) in case the ACK messages "Not SD printing" and/or "//action:cancel" - // are not received from Marlin) once the following loop does its job (stopping all blocking operations) + // - the print cancel action received by the TFT always guarantees the invokation of setPrintAbort() + // in Mainboard_AckHandler.c (e.g. to finalize the print (e.g. stats) in case the ACK messages + // "Not SD printing" and/or "//action:cancel" are not received from Marlin) once the following + // loop does its job (stopping all blocking operations) // mustStoreCmd("M118 P0 A1 action:cancel\n"); waitForAbort(); @@ -919,6 +916,16 @@ void loopPrintFromTFT(void) } } +void printSetNextUpdateTime(void) +{ + nextUpdateTime = OS_GetTimeMs() + SEC_TO_MS(infoSettings.m27_refresh_time); +} + +void printClearSendingWaiting(void) +{ + sendingWaiting = false; +} + void loopPrintFromOnboard(void) { #ifdef HAS_EMULATOR @@ -931,24 +938,18 @@ void loopPrintFromOnboard(void) if (!infoSettings.m27_active) return; if (MENU_IS(menuTerminal)) return; - static uint32_t nextCheckPrintTime = 0; - uint32_t update_M27_time = SEC_TO_MS(infoSettings.m27_refresh_time); - do - { // WAIT FOR M27 - if (updateM27Waiting == true) - { - nextCheckPrintTime = OS_GetTimeMs() + update_M27_time; - break; - } + { // send M27 to query SD print status continuously - if (OS_GetTimeMs() < nextCheckPrintTime) + if (OS_GetTimeMs() < nextUpdateTime) // if next check time not yet elapsed, do nothing break; - if (storeCmd("M27\n") == false) + printSetNextUpdateTime(); // extend next check time + + // if M27 previously enqueued and not yet sent, do nothing + if (sendingWaiting) break; - nextCheckPrintTime = OS_GetTimeMs() + update_M27_time; - updateM27Waiting = true; + sendingWaiting = storeCmd("M27\n"); } while (0); } diff --git a/TFT/src/User/API/Printing.h b/TFT/src/User/API/Printing.h index 5b532e1e71..ba382b87b0 100644 --- a/TFT/src/User/API/Printing.h +++ b/TFT/src/User/API/Printing.h @@ -7,8 +7,8 @@ extern "C" { #include #include -#include "variants.h" // for RAPID_SERIAL_COMM -#include "main.h" // for HOST_STATUS +#include "variants.h" // for RAPID_SERIAL_COMM +#include "Mainboard_FlowControl.h" // for HOST_STATUS #ifdef RAPID_SERIAL_COMM #define RAPID_SERIAL_LOOP() loopBackEnd() @@ -111,9 +111,8 @@ bool getPrintRunout(void); //void preparePrintSummary(void); //void sendPrintCodes(uint8_t index); -void setPrintUpdateWaiting(bool isWaiting); // called in interfaceCmd.c -void updatePrintUsedFilament(void); // called in PrintingMenu.c -void clearInfoPrint(void); // called in PrintingMenu.c +void updatePrintUsedFilament(void); // called in PrintingMenu.c +void clearInfoPrint(void); // called in PrintingMenu.c // // commented because NOT externally invoked @@ -147,8 +146,11 @@ void setPrintAbort(void); void setPrintPause(HOST_STATUS hostStatus, PAUSE_TYPE pauseType); void setPrintResume(HOST_STATUS hostStatus); -void loopPrintFromTFT(void); // called in loopBackEnd(). It handles a print from TFT media, if any -void loopPrintFromOnboard(void); // called in loopBackEnd(). It handles a print from (remote) onboard media, if any +void loopPrintFromTFT(void); // called in loopBackEnd(). It handles a print from TFT media, if any + +void printSetNextUpdateTime(void); // called in parseAck(). Set next printing query time or timeout +void printClearSendingWaiting(void); // called in sendQueueCmd(). Clear sending waiting for printing query +void loopPrintFromOnboard(void); // called in loopBackEnd(). It handles a print from (remote) onboard media, if any #ifdef __cplusplus } diff --git a/TFT/src/User/API/ProbeHeightControl.c b/TFT/src/User/API/ProbeHeightControl.c index 4d6349a84f..b7e58322ef 100644 --- a/TFT/src/User/API/ProbeHeightControl.c +++ b/TFT/src/User/API/ProbeHeightControl.c @@ -5,9 +5,8 @@ #define ENDSTOP_CMD_RRF "M564 S%d H%d\n" // for RRF #define MOVE_Z_CMD "G1 Z%.2f F%d\n" -#define PROBE_UPDATE_DELAY 200 // 1 seconds is 1000 +#define PROBE_REFRESH_TIME 200 // 1 seconds is 1000 -static uint32_t nextQueryTime = 0; static uint8_t origEndstopsState = DISABLED; static float origAblState = DISABLED; @@ -20,10 +19,10 @@ void probeHeightEnable(void) if (origEndstopsState == ENABLED) // if software endstops is enabled, disable it temporary { - if (infoMachineSettings.firmwareType == FW_REPRAPFW) - mustStoreCmd(ENDSTOP_CMD_RRF, 0, 0); - else + if (infoMachineSettings.firmwareType != FW_REPRAPFW) mustStoreCmd(ENDSTOP_CMD, 0); // disable software endstops to move nozzle lower than Z0 if necessary + else + mustStoreCmd(ENDSTOP_CMD_RRF, 0, 0); } } @@ -33,10 +32,10 @@ void probeHeightDisable(void) { if (origEndstopsState == ENABLED) // if software endstops was originally enabled, enable it again { - if (infoMachineSettings.firmwareType == FW_REPRAPFW) - mustStoreCmd(ENDSTOP_CMD_RRF, 1, 1); - else + if (infoMachineSettings.firmwareType != FW_REPRAPFW) mustStoreCmd(ENDSTOP_CMD, 1); // enable software endstops + else + mustStoreCmd(ENDSTOP_CMD_RRF, 1, 1); } if (origAblState == ENABLED) // if ABL was originally enabled, enable it again @@ -110,9 +109,12 @@ void probeHeightMove(float unit) // Query for new coordinates void probeHeightQueryCoord(void) { - if (OS_GetTimeMs() > nextQueryTime) - { - coordinateQuery(0); // query position manually for delay less than 1 second - nextQueryTime = OS_GetTimeMs() + PROBE_UPDATE_DELAY; - } + static uint32_t nextUpdateTime = 0; + + if (OS_GetTimeMs() < nextUpdateTime) + return; + + nextUpdateTime = OS_GetTimeMs() + PROBE_REFRESH_TIME; + + coordinateQuery(0); // query position manually for delay less than 1 second } diff --git a/TFT/src/User/API/RRFParseACK.cpp b/TFT/src/User/API/RRFAckHandler.cpp similarity index 93% rename from TFT/src/User/API/RRFParseACK.cpp rename to TFT/src/User/API/RRFAckHandler.cpp index 0cfa7ad6d2..fa2e0ec177 100644 --- a/TFT/src/User/API/RRFParseACK.cpp +++ b/TFT/src/User/API/RRFAckHandler.cpp @@ -1,5 +1,6 @@ -#include "RRFParseACK.hpp" +#include "RRFAckHandler.hpp" #include "includes.h" +#include "RRFStatusControl.h" /* * Parses structures like follows: @@ -43,26 +44,33 @@ static uint32_t expire_time = 0; static void m291_confirm(void) { - if (m291_mode >= 1) mustStoreCmd("M292 P0\n"); + if (m291_mode >= 1) + mustStoreCmd("M292 P0\n"); + if (rrfStatusIsMacroBusy()) rrfShowRunningMacro(); } static void m291_cancel(void) { - if (m291_mode > 2) mustStoreCmd("M292 P1\n"); - if (m291_mode == 2) mustStoreCmd("M292 P0\n"); + if (m291_mode > 2) + mustStoreCmd("M292 P1\n"); + + if (m291_mode == 2) + mustStoreCmd("M292 P0\n"); + if (rrfStatusIsMacroBusy()) rrfShowRunningMacro(); } static void m291_loop(void) { - if (m291_mode == -1 || (expire_time > 0 && OS_GetTimeMs() > expire_time)) + if (m291_mode == -1 || (expire_time > 0 && OS_GetTimeMs() >= expire_time)) { - CLOSE_MENU(); if (rrfStatusIsMacroBusy()) rrfShowRunningMacro(); + + CLOSE_MENU(); } } @@ -73,6 +81,7 @@ void ParseACKJsonParser::endDocument() if (show_m291 && m291_msg != NULL) { char M291[] = "M291"; + // _Generic is not available in C++ //setDialogText(m291_title, m291_msg, LABEL_CONFIRM, LABEL_CANCEL); _setDialogTitleStr((uint8_t *)(m291_title == NULL ? M291 : m291_title)); @@ -80,8 +89,10 @@ void ParseACKJsonParser::endDocument() _setDialogOkTextLabel(LABEL_CONFIRM); _setDialogCancelTextLabel(m291_mode > 2 ? LABEL_CANCEL : LABEL_NULL); expire_time = m291_timeo > 0 ? OS_GetTimeMs() + m291_timeo : 0; + showDialog(m291_mode > 2 ? DIALOG_TYPE_QUESTION : DIALOG_TYPE_INFO, m291_confirm, - m291_mode > 2 ? m291_cancel : NULL, m291_loop); + m291_mode > 2 ? m291_cancel : NULL, m291_loop); + BUZZER_PLAY(SOUND_NOTIFY); show_m291 = false; } @@ -97,6 +108,7 @@ void ParseACKJsonParser::endDocument() free(m291_title); m291_title = NULL; } + need_parser_reset = true; } @@ -105,98 +117,103 @@ void ParseACKJsonParser::value(const char *value) uint32_t seq; char *string_end; char *string_start; + switch (state) { case status: rrfStatusSet(value[0]); break; + case heaters: if (index == 0) - { heatSetCurrentTemp(BED, strtod((char *)value, NULL) + 0.5f); - } else if (index <= INVALID_HEATER) - { heatSetCurrentTemp(index - 1, strtod((char *)value, NULL) + 0.5f); - } break; + case active: if (index == 0) - { heatSetTargetTemp(BED, strtod((char *)value, NULL) + 0.5f, FROM_HOST); - } else if (index <= INVALID_HEATER) - { heatSetTargetTemp(index - 1, strtod((char *)value, NULL) + 0.5f, FROM_HOST); - } break; + case standby: break; + case hstat: if (strtod((char *)value, NULL) == 3) { if (index == 0) - { heatSetTargetTemp(BED, 0, FROM_HOST); - } else if (index <= INVALID_HEATER) - { heatSetTargetTemp(index - 1, 0, FROM_HOST); - } } break; + case pos: coordinateSetAxisActual((AXIS)index, strtod((char *)value, NULL)); break; + case sfactor: speedSetCurPercent(0, strtod((char *)value, NULL)); break; + case efactor: if (index == heatGetToolIndex()) - { speedSetCurPercent(1, strtod((char *)value, NULL)); - } break; + case baby_step: babystepSetValue(strtod((char *)value, NULL)); break; + case tool: break; + case probe: break; + case fan_percent: if (index != 0 && index <= infoSettings.fan_count) // index 0 is an alias for default tool fan - { fanSetPercent(index - 1, strtod((char *)value, NULL) + 0.5f); - } break; + case fanRPM: break; + case fraction_printed: if (getPrintProgressSource() < PROG_RRF) setPrintProgressSource(PROG_RRF); + if (getPrintProgressSource() == PROG_RRF) setPrintProgressPercentage((value[0] - '0') * 100 + (value[2] - '0') * 10 + (value[3] - '0')); break; + case mbox_seq: seq = strtod((char *)value, NULL); show_m291 = seq != m291_seq; m291_seq = seq; break; + case mbox_mode: m291_mode = strtod((char *)value, NULL); break; + case mbox_msg: m291_msg = (char*)malloc(strlen(value) + 1); strcpy(m291_msg, value); break; + case mbox_title: m291_title = (char*)malloc(strlen(value) + 1); strcpy(m291_title, value); break; + case mbox_timeo: m291_timeo = SEC_TO_MS(strtod((char *)value, NULL)); break; + case resp: if (strstr(value, (char *)"Steps/")) // parse M92 { @@ -237,8 +254,8 @@ void ParseACKJsonParser::value(const char *value) { pidUpdateStatus(PID_FAILED); } - break; + case result: if (starting_print) { @@ -246,22 +263,26 @@ void ParseACKJsonParser::value(const char *value) starting_print = false; } break; + case none: break; } + if (in_array) ++index; } -void rrfParseACK(const char *data) +void rrfParseAck(const char *data) { static ParseACKJsonParser handler; jsonStreamingParser.setListener(&handler); + while (*data != 0) { jsonStreamingParser.parse(*data++); } + if (handler.need_parser_reset) { jsonStreamingParser.reset(); diff --git a/TFT/src/User/API/RRFParseACK.hpp b/TFT/src/User/API/RRFAckHandler.hpp similarity index 96% rename from TFT/src/User/API/RRFParseACK.hpp rename to TFT/src/User/API/RRFAckHandler.hpp index bd8de8c7c4..030e550904 100644 --- a/TFT/src/User/API/RRFParseACK.hpp +++ b/TFT/src/User/API/RRFAckHandler.hpp @@ -1,11 +1,11 @@ -#ifndef _PARSE_ACK_JSON_H_ -#define _PARSE_ACK_JSON_H_ +#ifndef _RRF_ACK_HANDLER_JSON_H_ +#define _RRF_ACK_HANDLER_JSON_H_ #ifdef __cplusplus extern "C" { #endif - void rrfParseACK(const char *data); + void rrfParseAck(const char *data); #ifdef __cplusplus } #endif @@ -79,11 +79,13 @@ class ParseACKJsonParser : public JsonListener inline void endObject() {} inline void whitespace(char c) {} virtual void endDocument(); + inline void startArray() { in_array = true; index = 0; } + inline void endArray() { in_array = false; @@ -164,6 +166,7 @@ class ParseACKJsonParser : public JsonListener state = none; } } + virtual void value(const char *value); }; #endif diff --git a/TFT/src/User/API/RRFM20Parser.cpp b/TFT/src/User/API/RRFM20Parser.cpp index eb18a290a0..1b4f3c7cbb 100644 --- a/TFT/src/User/API/RRFM20Parser.cpp +++ b/TFT/src/User/API/RRFM20Parser.cpp @@ -36,6 +36,7 @@ "next": 0 } */ + const TCHAR *skip_number(const TCHAR *value) { if (isdigit(*value)) @@ -44,6 +45,7 @@ const TCHAR *skip_number(const TCHAR *value) { ++value; } while (isdigit(*value)); + return (*value == '_') ? value + 1 : value; } @@ -53,6 +55,7 @@ const TCHAR *skip_number(const TCHAR *value) int compare_items(void *arg, const void *a, const void *b) { bool macro_sort = *(bool *)arg; + if (macro_sort) return strcasecmp(((M20_LIST_ITEM *)a)->file_name, ((M20_LIST_ITEM *)b)->file_name); @@ -61,13 +64,17 @@ int compare_items(void *arg, const void *a, const void *b) // if M20 S3 ever works, we can make use of this case SORT_DATE_NEW_FIRST: return ((M20_LIST_ITEM *)b)->timestamp - ((M20_LIST_ITEM *)a)->timestamp; + case SORT_DATE_OLD_FIRST: return ((M20_LIST_ITEM *)a)->timestamp - ((M20_LIST_ITEM *)b)->timestamp; + case SORT_NAME_ASCENDING: return strcasecmp(((M20_LIST_ITEM *)a)->file_name, ((M20_LIST_ITEM *)b)->file_name); + case SORT_NAME_DESCENDING: return strcasecmp(((M20_LIST_ITEM *)b)->file_name, ((M20_LIST_ITEM *)a)->file_name); } + return strcmp(((M20_LIST_ITEM *)a)->file_name, ((M20_LIST_ITEM *)b)->file_name); } @@ -79,6 +86,7 @@ void RRFM20Parser::startObject() void RRFM20Parser::endObject() { in_object = false; + if (in_files && fileCount < FILE_NUM) ++fileCount; } @@ -86,7 +94,9 @@ void RRFM20Parser::endObject() void RRFM20Parser::endDocument() { if (macro_sort) + { qsort_r(fileList, fileCount, sizeof(M20_LIST_ITEM), ¯o_sort, compare_items); + } else { switch (infoSettings.files_sort_by) @@ -95,6 +105,7 @@ void RRFM20Parser::endDocument() // TODO use this implicit sort until M20 S3 works // M20 appears to be sorted oldest first, implicitly, reverse it. int i, j; + for (i = 0, j = fileCount - 1; i < j; ++i, --j) { M20_LIST_ITEM tmp; @@ -103,9 +114,10 @@ void RRFM20Parser::endDocument() fileList[j] = tmp; } break; + case SORT_NAME_ASCENDING: case SORT_NAME_DESCENDING: - qsort_r(fileList, fileCount, sizeof(M20_LIST_ITEM), ¯o_sort, compare_items); + qsort_r(fileList, fileCount, sizeof(M20_LIST_ITEM), ¯o_sort, compare_items); break; } } @@ -124,6 +136,7 @@ void RRFM20Parser::endDocument() infoFile.file[infoFile.fileCount++] = fileList[i].display_name; } } + need_reset = true; } @@ -132,6 +145,7 @@ void RRFM20Parser::endDocument() void RRFM20Parser::key(const char *key) { state = none; + if (!in_array) in_files = strcmp(FILES, key) == 0; @@ -168,16 +182,14 @@ void RRFM20Parser::value(const char *value) { if ((fileList[fileCount].file_name = (TCHAR *)malloc(len)) != NULL) strcpy(fileList[fileCount].file_name, value); + const char *skipped = macro_sort ? skip_number(value) : value; len = strlen(skipped) + 1; + if (macro_sort && value != skipped && (fileList[fileCount].display_name = (TCHAR *)malloc(len)) != NULL) - { strcpy(fileList[fileCount].display_name, skipped); - } else - { fileList[fileCount].display_name = fileList[fileCount].file_name; - } break; } @@ -191,6 +203,7 @@ void RRFM20Parser::value(const char *value) uint8_t hour = strtol(out + 1, &out, 10); uint8_t mins = strtol(out + 1, &out, 10); uint8_t secs = strtol(out + 1, NULL, 10); + // uint32_t will allow about up until year 2098, 31 days in a month because I'm lazy fileList[fileCount].timestamp = secs + (mins * 60) + (hour * 60 * 60) + (date * 60 * 60 * 24) + (mnth * 31 * 60 * 60 * 24) + (year * 12 * 31 * 60 * 60 * 24); @@ -200,18 +213,19 @@ void RRFM20Parser::value(const char *value) case none: break; } + state = none; } else { uint16_t current = fileCount++; + if (current >= FILE_NUM) return; if ((fileList[current].is_directory = (*value == '*'))) - { ++value; - } + uint16_t len = strlen(value) + 1; if ((fileList[current].file_name = (TCHAR *)malloc(len)) != NULL) @@ -219,6 +233,7 @@ void RRFM20Parser::value(const char *value) value = macro_sort ? skip_number(value) : value; len = strlen(value) + 1; + if ((fileList[current].display_name = (TCHAR *)malloc(len)) != NULL) strcpy(fileList[current].display_name, value); } @@ -229,12 +244,11 @@ void parseM20Response(const char *data, bool macro_sorting) static RRFM20Parser *handler = NULL; if (handler == NULL) - { handler = new RRFM20Parser; - } handler->macro_sort = macro_sorting; jsonStreamingParser.setListener(handler); + while (*data != 0) { jsonStreamingParser.parse(*data++); diff --git a/TFT/src/User/API/RRFM20Parser.hpp b/TFT/src/User/API/RRFM20Parser.hpp index 15563fb899..e0709f5754 100644 --- a/TFT/src/User/API/RRFM20Parser.hpp +++ b/TFT/src/User/API/RRFM20Parser.hpp @@ -18,6 +18,7 @@ extern "C" TCHAR *file_name; uint32_t timestamp; } M20_LIST_ITEM; + void parseJobListResponse(const char *data); void parseMacroListResponse(const char *data); #ifdef __cplusplus @@ -32,6 +33,7 @@ extern "C" #define FILES_TYPE "type" #define FILES_NAME "name" #define FILES_DATE "date" + enum RRFM20ParserState { none, type, name, date }; class RRFM20Parser : public JsonListener @@ -72,6 +74,7 @@ class RRFM20Parser : public JsonListener { in_array = in_files; } + inline void endArray() { in_array = false; diff --git a/TFT/src/User/API/RRFSendCmd.c b/TFT/src/User/API/RRFSendCmd.c deleted file mode 100644 index 0f824888a3..0000000000 --- a/TFT/src/User/API/RRFSendCmd.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "RRFM20Parser.hpp" -#include "includes.h" - -static uint32_t line_number = 0; - -void rrfSendCmd(const char * cmd_ptr) -{ - char rrfCmd[CMD_MAX_SIZE]; - char * rrfCmd_ptr = rrfCmd; - uint8_t checksum = 0; - - sprintf(rrfCmd, "N%lu %s", line_number++, cmd_ptr); - - // calculate checksum - while (*rrfCmd_ptr != '\n') - { - checksum ^= *rrfCmd_ptr++; - } - - // add checksum and finalize formatting the RRF command - sprintf(rrfCmd_ptr, "*%u\n", checksum); - - // send the command to the serial port - Serial_Put(SERIAL_PORT, rrfCmd); -} diff --git a/TFT/src/User/API/RRFSendCmd.h b/TFT/src/User/API/RRFSendCmd.h deleted file mode 100644 index 88250753ea..0000000000 --- a/TFT/src/User/API/RRFSendCmd.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _RRF_SEND_CMD_H_ -#define _RRF_SEND_CMD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void rrfSendCmd(const char* cmd_ptr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/TFT/src/User/API/RRFStatusControl.c b/TFT/src/User/API/RRFStatusControl.c index afeed2eee8..8313b2d3ac 100644 --- a/TFT/src/User/API/RRFStatusControl.c +++ b/TFT/src/User/API/RRFStatusControl.c @@ -2,7 +2,7 @@ #include "includes.h" #define RRF_NORMAL_STATUS_QUERY_MS 1000 -#define RRF_FAST_STATUS_QUERY_MS 500 +#define RRF_FAST_STATUS_QUERY_MS 500 // available status: status: // I=idle, P=printing from SD card, S=stopped (i.e. needs a reset), C=running config file (i.e starting up), @@ -29,8 +29,9 @@ void rrfStatusSet(char status) setHostDialog(false); setPrintResume(HOST_STATUS_RESUMING); break; + case 'I': - // RRFParseACK will take care of going to the print screen + // rrfParseAck will take care of going to the print screen mustStoreCmd("M409 K\"job.file.fileName\"\n"); starting_print = true; break; @@ -77,21 +78,21 @@ void rrfStatusSet(char status) break; } } + rrf_status = status; + if (status != 'B') - { macro_busy = false; - } } -inline void rrfStatusSetBusy(void) +inline bool rrfStatusIsBusy(void) { - rrf_status = 'B'; + return rrf_status == 'B'; } -inline bool rrfStatusIsBusy(void) +inline void rrfStatusSetBusy(void) { - return rrf_status == 'B'; + rrf_status = 'B'; } inline bool rrfStatusIsMacroBusy(void) @@ -116,16 +117,20 @@ inline void rrfStatusQueryNormal(void) } void rrfStatusQuery(void) -{ // following conditions ordered by importance - if (infoMachineSettings.firmwareType == FW_REPRAPFW && infoHost.connected) +{ + if (infoHost.connected) { static uint32_t rrf_next_query_time = 0; + if (OS_GetTimeMs() < rrf_next_query_time) + return; + + rrf_next_query_time = OS_GetTimeMs() + rrf_query_interval; + // don't send status queries while in the terminal menu to avoid flooding the console - if (OS_GetTimeMs() > rrf_next_query_time && MENU_IS_NOT(menuTerminal)) - { - rrf_next_query_time = OS_GetTimeMs() + rrf_query_interval; - storeCmd("M408 S0\n"); - } + if (MENU_IS(menuTerminal)) + return; + + storeCmd("M408 S0\n"); } } diff --git a/TFT/src/User/API/RRFStatusControl.h b/TFT/src/User/API/RRFStatusControl.h index 94e0ae35a2..9dc50bdc19 100644 --- a/TFT/src/User/API/RRFStatusControl.h +++ b/TFT/src/User/API/RRFStatusControl.h @@ -6,16 +6,17 @@ extern "C" { #endif #include + extern bool starting_print; -void rrfStatusQuery(void); -void rrfStatusQueryFast(void); -void rrfStatusQueryNormal(void); void rrfStatusSet(char status); bool rrfStatusIsBusy(void); void rrfStatusSetBusy(void); bool rrfStatusIsMacroBusy(void); void rrfStatusSetMacroBusy(void); +void rrfStatusQueryFast(void); +void rrfStatusQueryNormal(void); +void rrfStatusQuery(void); #ifdef __cplusplus } diff --git a/TFT/src/User/API/SerialConnection.c b/TFT/src/User/API/SerialConnection.c index 840816a9ab..9e435c9430 100644 --- a/TFT/src/User/API/SerialConnection.c +++ b/TFT/src/User/API/SerialConnection.c @@ -38,7 +38,6 @@ void Serial_Init(SERIAL_PORT_INDEX portIndex) if (portIndex == PORT_1 || portIndex == ALL_PORTS) // if primary or all serial ports, initialize the primary serial port first { InfoHost_Init(false); // initialize infoHost when disconnected - coordinateSetKnown(false); Serial_Config(serialPort[PORT_1].port, serialPort[PORT_1].cacheSizeRX, serialPort[PORT_1].cacheSizeTX, baudrateValues[infoSettings.serial_port[PORT_1]]); } @@ -113,7 +112,7 @@ void Serial_Forward(SERIAL_PORT_INDEX portIndex, const char * msg) } } -bool Serial_NewDataAvailable(uint8_t port) +bool Serial_DataAvailableRX(uint8_t port) { // NOTE: used 32 bit variables for performance reasons @@ -214,7 +213,7 @@ void Serial_GetFromUART(void) #endif ) { - while (Serial_NewDataAvailable(serialPort[portIndex].port) && Serial_Get(serialPort[portIndex].port, cmd, CMD_MAX_SIZE) != 0) + while (Serial_DataAvailableRX(serialPort[portIndex].port) && Serial_Get(serialPort[portIndex].port, cmd, CMD_MAX_SIZE) != 0) { handleCmd(cmd, portIndex); } diff --git a/TFT/src/User/API/SerialConnection.h b/TFT/src/User/API/SerialConnection.h index 5c71575613..69104da579 100644 --- a/TFT/src/User/API/SerialConnection.h +++ b/TFT/src/User/API/SerialConnection.h @@ -8,6 +8,7 @@ extern "C" { #include #include #include "variants.h" // for SERIAL_PORT_2 etc. +#include "Serial.h" // for dmaL1DataTX etc. #include "uart.h" // for _UART_CNT etc. #define BAUDRATE_COUNT 12 @@ -64,11 +65,20 @@ void Serial_DeInit(SERIAL_PORT_INDEX portIndex); // - msg: message to send void Serial_Forward(SERIAL_PORT_INDEX portIndex, const char * msg); -// test if a new message is available in the message queue of the provided physical serial port: +// test if a message is available in the RX message queue of the provided physical serial port: // - port: physical serial port where data availability is tested // // - return value: "true" if a new message is available. "false" otherwise -bool Serial_NewDataAvailable(uint8_t port); +bool Serial_DataAvailableRX(uint8_t port); + +// test if a message is available in the TX message queue of the provided physical serial port: +// - port: physical serial port where data availability is tested +// +// - return value: "true" if a message is available. "false" otherwise +static inline bool Serial_DataAvailableTX(uint8_t port) +{ + return (dmaL1DataTX[port].wIndex != dmaL1DataTX[port].rIndex); // is more data available? +} // retrieve a message from the provided physical serial port: // - port: physical serial port where data are read from @@ -80,7 +90,7 @@ uint16_t Serial_Get(uint8_t port, char * buf, uint16_t bufSize); #ifdef SERIAL_PORT_2 // retrieve messages from all the enabled supplementary ports storing them - // in the command queue (in interfaceCmd.c) for further processing + // in the command queue (in Mainboard_CmdHandler.c) for further processing void Serial_GetFromUART(void); #endif diff --git a/TFT/src/User/API/Settings.c b/TFT/src/User/API/Settings.c index 3c4ba19a14..6d01eb4dea 100644 --- a/TFT/src/User/API/Settings.c +++ b/TFT/src/User/API/Settings.c @@ -26,6 +26,7 @@ void initSettings(void) infoSettings.tx_slots = TX_SLOTS; infoSettings.general_settings = ((0 << INDEX_LISTENING_MODE) | (ADVANCED_OK << INDEX_ADVANCED_OK) | + (COMMAND_CHECKSUM << INDEX_COMMAND_CHECKSUM) | (EMULATED_M600 << INDEX_EMULATED_M600) | (EMULATED_M109_M190 << INDEX_EMULATED_M109_M190) | (EVENT_LED << INDEX_EVENT_LED) | @@ -173,12 +174,12 @@ void initSettings(void) infoSettings.pause_feedrate[i] = default_pause_speed[i]; // XY, Z, E } - for (int i = 0; i < FEEDRATE_COUNT - 1 ; i++) // xy, z + for (int i = 0; i < FEEDRATE_COUNT - 1; i++) // xy, z { infoSettings.level_feedrate[i] = default_level_speed[i]; } - for (int i = 0; i < LED_COLOR_COMPONENT_COUNT - 1 ; i++) + for (int i = 0; i < LED_COLOR_COMPONENT_COUNT - 1; i++) { infoSettings.led_color[i] = default_led_color[i]; } @@ -226,10 +227,6 @@ void initMachineSettings(void) infoMachineSettings.babyStepping = DISABLED; infoMachineSettings.buildPercent = DISABLED; infoMachineSettings.softwareEndstops = ENABLED; - - // reset the state to restart the temperature polling process - // needed by parseAck() function to establish the connection - heatSetUpdateWaiting(false); } void setupMachine(FW_TYPE fwType) @@ -354,5 +351,6 @@ bool getFlashSignStatus(int index) uint32_t len = sizeof(flash_sign); W25Qxx_ReadBuffer((uint8_t*)&cur_flash_sign, addr, len); + return (flash_sign[index] == cur_flash_sign[index]); } diff --git a/TFT/src/User/API/Settings.h b/TFT/src/User/API/Settings.h index ad56be1b3b..d6393e57ed 100644 --- a/TFT/src/User/API/Settings.h +++ b/TFT/src/User/API/Settings.h @@ -11,10 +11,10 @@ extern "C" { #include "coordinate.h" // for TOTAL_AXIS #include "LED_Colors.h" // for LED_COLOR_COMPONENT_COUNT -#define CONFIG_SUPPPORT 20231119 // (YYYYMMDD) change if any keyword(s) is Configuration.h is added, removed or changed. +#define CONFIG_SUPPPORT 20240203 // (YYYYMMDD) change if any keyword(s) in Configuration.h is added, removed or changed. // This number should match CONFIGURATION_H_VERSION in Configuration.h -#define CONFIG_FLASH_SIGN 20230929 // (YYYYMMDD) change if any keyword(s) in config.ini is added or removed -#define LANGUAGE_FLASH_SIGN 20230821 // (YYYYMMDD) change if any keyword(s) in language pack is added or removed +#define CONFIG_FLASH_SIGN 20240203 // (YYYYMMDD) change if any keyword(s) in config.ini is added or removed +#define LANGUAGE_FLASH_SIGN 20240203 // (YYYYMMDD) change if any keyword(s) in language pack is added or removed #define ICON_FLASH_SIGN 20230821 // (YYYYMMDD) change if any icon(s) is added or removed #define FONT_FLASH_SIGN 20230821 // (YYYYMMDD) change if fonts require updating @@ -69,6 +69,7 @@ typedef enum { INDEX_LISTENING_MODE = 0, INDEX_ADVANCED_OK, + INDEX_COMMAND_CHECKSUM, INDEX_EMULATED_M600, INDEX_EMULATED_M109_M190, INDEX_EVENT_LED, diff --git a/TFT/src/User/API/SpeedControl.c b/TFT/src/User/API/SpeedControl.c index eb820aa440..d5727c495c 100644 --- a/TFT/src/User/API/SpeedControl.c +++ b/TFT/src/User/API/SpeedControl.c @@ -1,75 +1,73 @@ #include "SpeedControl.h" #include "includes.h" -#define NEXT_SPEED_WAIT 500 // 1 second is 1000 +#define SPEED_REFRESH_TIME 500 // 1 second is 1000 -const char *const speedCmd[SPEED_NUM] = {"M220", "M221"}; +const char * const speedCmd[SPEED_NUM] = {"M220", "M221"}; static uint16_t setPercent[SPEED_NUM] = {100, 100}; static uint16_t curPercent[SPEED_NUM] = {100, 100}; -static uint8_t needSetPercent = 0; +static uint8_t needSetPercent = 0; -static bool speedQueryWait = false; -static uint32_t nextSpeedTime = 0; +static bool speedSendingWaiting = false; -void speedSetPercent(uint8_t tool, uint16_t per) +void speedSetPercent(const uint8_t tool, const uint16_t per) { uint16_t value = NOBEYOND(SPEED_MIN, per, SPEED_MAX); + SET_BIT_VALUE(needSetPercent, tool, value != curPercent[tool]); setPercent[tool] = value; } -uint16_t speedGetSetPercent(uint8_t tool) +uint16_t speedGetSetPercent(const uint8_t tool) { return setPercent[tool]; } -void speedSetCurPercent(uint8_t tool, uint16_t per) +void speedSetCurPercent(const uint8_t tool, const uint16_t per) { curPercent[tool] = per; } -uint16_t speedGetCurPercent(uint8_t tool) +uint16_t speedGetCurPercent(const uint8_t tool) { return curPercent[tool]; } -void loopSpeed(void) +void loopCheckSpeed(void) { + static uint32_t nextUpdateTime = 0; + + if (OS_GetTimeMs() < nextUpdateTime) // avoid rapid fire, clogging the queue + return; + + nextUpdateTime = OS_GetTimeMs() + SPEED_REFRESH_TIME; // extend next check time + for (uint8_t i = 0; i < SPEED_NUM; i++) { - if (infoSettings.ext_count == 0 && i > 0) - { - // Don't poll M221 if there are no extruders + if (infoSettings.ext_count == 0 && i > 0) // don't poll M221 if there are no extruders continue; - } - if (GET_BIT(needSetPercent, i) && (OS_GetTimeMs() > nextSpeedTime)) + if (GET_BIT(needSetPercent, i)) { if (storeCmd("%s S%d D%d\n", speedCmd[i], setPercent[i], heatGetToolIndex())) - { SET_BIT_OFF(needSetPercent, i); - } - - nextSpeedTime = OS_GetTimeMs() + NEXT_SPEED_WAIT; // avoid rapid fire, clogging the queue } } } -void speedQuerySetWait(bool wait) +void speedQueryClearSendingWaiting(void) { - speedQueryWait = wait; + speedSendingWaiting = false; } void speedQuery(void) { // following conditions ordered by importance - if (!speedQueryWait && infoHost.tx_slots != 0 && infoHost.connected && infoMachineSettings.firmwareType != FW_REPRAPFW) + if (!speedSendingWaiting && infoHost.tx_slots != 0 && infoHost.connected && infoMachineSettings.firmwareType != FW_REPRAPFW) { - speedQueryWait = storeCmd("M220\n"); + speedSendingWaiting = storeCmd("M220\n"); if (infoSettings.ext_count > 0) - { - speedQueryWait |= storeCmd("M221\n"); // speedQueryWait set to "true" if at least one command will be sent - } + speedSendingWaiting |= storeCmd("M221\n"); // speedSendingWaiting set to "true" if at least one command will be sent } } diff --git a/TFT/src/User/API/SpeedControl.h b/TFT/src/User/API/SpeedControl.h index 12eb46367c..8f3fc2df6c 100644 --- a/TFT/src/User/API/SpeedControl.h +++ b/TFT/src/User/API/SpeedControl.h @@ -12,13 +12,14 @@ extern "C" { #define SPEED_MIN 10 #define SPEED_MAX 999 -void speedSetPercent(uint8_t tool, uint16_t per); -uint16_t speedGetSetPercent(uint8_t tool); -void speedSetCurPercent(uint8_t tool, uint16_t per); -uint16_t speedGetCurPercent(uint8_t tool); -void loopSpeed(void); -void speedQuerySetWait(bool wait); -void speedQuery(void); +void speedSetPercent(const uint8_t tool, const uint16_t per); +uint16_t speedGetSetPercent(const uint8_t tool); +void speedSetCurPercent(const uint8_t tool, const uint16_t per); +uint16_t speedGetCurPercent(const uint8_t tool); + +void loopCheckSpeed(void); // called in loopBackEnd(). Loop for check on speed +void speedQueryClearSendingWaiting(void); // called in sendQueueCmd(). Clear sending waiting for speed query +void speedQuery(void); // query for speed #ifdef __cplusplus } diff --git a/TFT/src/User/API/Temperature.c b/TFT/src/User/API/Temperature.c index b46d98f627..dad45a8371 100644 --- a/TFT/src/User/API/Temperature.c +++ b/TFT/src/User/API/Temperature.c @@ -9,36 +9,35 @@ const char * const heatWaitCmd[MAX_HEATER_COUNT] = HEAT_WAIT_CMD; const char * const extruderDisplayID[] = EXTRUDER_ID; const char * const toolChange[] = TOOL_CHANGE; -static HEATER heater = {{}, NOZZLE0}; -static uint8_t heat_update_seconds = TEMPERATURE_QUERY_SLOW_SECONDS; -static bool heat_update_waiting = false; -static uint8_t heat_send_waiting = 0; -static uint8_t heat_feedback_waiting = 0; +static HEATER heater = {{}, NOZZLE0}; +static uint8_t heat_send_waiting = 0; +static uint8_t heat_feedback_waiting = 0; -uint32_t nextHeatCheckTime = 0; +static uint8_t heat_update_seconds = TEMPERATURE_QUERY_SLOW_SECONDS; +static uint32_t heat_next_update_time = 0; +static bool heat_sending_waiting = false; -#define AUTOREPORT_TIMEOUT (nextHeatCheckTime + 3000) // update interval + 3 second grace period +#define AUTOREPORT_TIMEOUT 3000 // 3 second grace period // verify that the heater index is valid, and fix the index of multiple in and 1 out tool nozzles static uint8_t heaterIndexFix(uint8_t index) { - if (index == BED && infoSettings.bed_en) // Bed + if (index == BED && infoSettings.bed_en) // bed return index; - if (index == CHAMBER && infoSettings.chamber_en) // Chamber + if (index == CHAMBER && infoSettings.chamber_en) // chamber return index; - if (index < infoSettings.hotend_count) // Vaild tool nozzle + if (index < infoSettings.hotend_count) // vaild tool nozzle return index; - if (index < infoSettings.ext_count && infoSettings.hotend_count == 1) // "multi-extruder" that shares a single nozzle. + if (index < infoSettings.ext_count && infoSettings.hotend_count == 1) // "multi-extruder" that shares a single nozzle return NOZZLE0; - return INVALID_HEATER; // Invalid heater + return INVALID_HEATER; // invalid heater } -// set target temperature -void heatSetTargetTemp(uint8_t index, int16_t temp, TEMP_SOURCE tempSource) +void heatSetTargetTemp(uint8_t index, const int16_t temp, const TEMP_SOURCE tempSource) { index = heaterIndexFix(index); @@ -74,7 +73,6 @@ void heatSetTargetTemp(uint8_t index, int16_t temp, TEMP_SOURCE tempSource) } } -// get target temperature uint16_t heatGetTargetTemp(uint8_t index) { index = heaterIndexFix(index); @@ -85,8 +83,7 @@ uint16_t heatGetTargetTemp(uint8_t index) return heater.T[index].target; } -// set current temperature -void heatSetCurrentTemp(uint8_t index, int16_t temp) +void heatSetCurrentTemp(uint8_t index, const int16_t temp) { index = heaterIndexFix(index); @@ -96,10 +93,9 @@ void heatSetCurrentTemp(uint8_t index, int16_t temp) heater.T[index].current = NOBEYOND(-99, temp, 999); if (infoMachineSettings.autoReportTemp) - updateNextHeatCheckTime(); // set next timeout for temperature auto-report + heatSetNextUpdateTime(); // set next timeout for temperature auto-report } -// get current temperature int16_t heatGetCurrentTemp(uint8_t index) { index = heaterIndexFix(index); @@ -110,7 +106,6 @@ int16_t heatGetCurrentTemp(uint8_t index) return heater.T[index].current; } -// disable all heaters/hotends void heatCoolDown(void) { for (uint8_t i = 0; i < MAX_HEATER_COUNT; i++) @@ -119,13 +114,11 @@ void heatCoolDown(void) } } -// is heating waiting to heat up -bool heatGetIsWaiting(uint8_t index) +bool heatGetIsWaiting(const uint8_t index) { return (heater.T[index].waiting == true); } -// check all heater if there is a heater waiting to be waited bool heatHasWaiting(void) { for (uint8_t i = 0; i < MAX_HEATER_COUNT; i++) @@ -137,8 +130,7 @@ bool heatHasWaiting(void) return false; } -// set heater waiting status -void heatSetIsWaiting(uint8_t index, bool isWaiting) +void heatSetIsWaiting(uint8_t index, const bool isWaiting) { index = heaterIndexFix(index); @@ -163,8 +155,6 @@ void heatClearIsWaiting(void) heatSetUpdateSeconds(TEMPERATURE_QUERY_SLOW_SECONDS); } -// set current tool (extruder) -// used when tool change command is from TFT bool heatSetTool(const uint8_t toolIndex) { if (storeCmd("%s\n", toolChange[toolIndex])) @@ -181,20 +171,17 @@ void heatSetToolIndex(const uint8_t toolIndex) heater.toolIndex = toolIndex; } -// get current Tool (extruder) uint8_t heatGetToolIndex(void) { return heater.toolIndex; } -// get current hotend index in arry T[] uint8_t heatGetCurrentHotend(void) { return (infoSettings.hotend_count == 1) ? NOZZLE0 : heater.toolIndex; } -// check whether the index is a valid heater index. -bool heaterDisplayIsValid(uint8_t index) +bool heaterDisplayIsValid(const uint8_t index) { if (index >= infoSettings.hotend_count && index < MAX_HOTEND_COUNT) return false; @@ -208,78 +195,59 @@ bool heaterDisplayIsValid(uint8_t index) return true; } -// set temperature update time interval -void heatSetUpdateSeconds(uint8_t seconds) +void heatSetUpdateSeconds(const uint8_t seconds) { if (heat_update_seconds == seconds) return; heat_update_seconds = seconds; - if (infoMachineSettings.autoReportTemp && !heat_update_waiting) - heat_update_waiting = storeCmd("M155 S%u\n", heatGetUpdateSeconds()); + if (infoMachineSettings.autoReportTemp && !heat_sending_waiting) + heat_sending_waiting = storeCmd("M155 S%u\n", heat_update_seconds); } -// get query temperature seconds uint8_t heatGetUpdateSeconds(void) { return heat_update_seconds; } -// set query temperature seconds -void heatSyncUpdateSeconds(uint8_t seconds) +void heatSyncUpdateSeconds(const uint8_t seconds) { heat_update_seconds = seconds; } -// set whether we need to query the current temperature -void heatSetUpdateWaiting(bool isWaiting) +void heatSetNextUpdateTime(void) { - heat_update_waiting = isWaiting; + heat_next_update_time = OS_GetTimeMs() + SEC_TO_MS(heat_update_seconds); + + if (infoMachineSettings.autoReportTemp) + heat_next_update_time += AUTOREPORT_TIMEOUT; } -void updateNextHeatCheckTime(void) +void heatClearSendingWaiting(void) { - nextHeatCheckTime = OS_GetTimeMs() + SEC_TO_MS(heat_update_seconds); + heat_sending_waiting = false; } void loopCheckHeater(void) { - // Send M105 to query the temperatures, if motherboard does not supports M155 (AUTO_REPORT_TEMPERATURES) feature - // to automatically report the temperatures. - if (!infoMachineSettings.autoReportTemp) - { - do - { - // Send M105 query temperature continuously - if (heat_update_waiting == true) - { - updateNextHeatCheckTime(); - break; - } + do + { // periodically send M105 to query the temperatures, if motherboard does not supports M155 (AUTO_REPORT_TEMPERATURES) + // feature to automatically report the temperatures or (if M155 is supported) check temperature auto-report timeout + // and resend M155 command in case of timeout expired - if (OS_GetTimeMs() < nextHeatCheckTime) - break; + if (OS_GetTimeMs() < heat_next_update_time) // if next check time not yet elapsed, do nothing + break; - if (requestCommandInfoIsRunning()) // To avoid collision in gcode response processing - break; + heatSetNextUpdateTime(); // extend next check time - if ((infoMachineSettings.firmwareType != FW_REPRAPFW) && !storeCmd("M105\n")) - break; + // if M105/M155 previously enqueued and not yet sent or pending command + // (to avoid collision in gcode response processing), do nothing + if (heat_sending_waiting || requestCommandInfoIsRunning()) + break; - updateNextHeatCheckTime(); - heat_update_waiting = true; - } while (0); - } - else // check temperature auto-report timout and resend M155 command - { - if (OS_GetTimeMs() > AUTOREPORT_TIMEOUT && !heat_update_waiting) - { - heat_update_waiting = storeCmd("M155 S%u\n", heatGetUpdateSeconds()); - if (heat_update_waiting) - updateNextHeatCheckTime(); // set next timeout for temperature auto-report - } - } + heat_sending_waiting = !infoMachineSettings.autoReportTemp ? storeCmd("M105\n") : storeCmd("M155 S%u\n", heat_update_seconds); + } while (0); for (uint8_t i = 0; i < MAX_HEATER_COUNT; i++) { diff --git a/TFT/src/User/API/Temperature.h b/TFT/src/User/API/Temperature.h index 8646694642..c65e9e73dd 100644 --- a/TFT/src/User/API/Temperature.h +++ b/TFT/src/User/API/Temperature.h @@ -23,7 +23,7 @@ typedef enum typedef enum { - FROM_HOST = 0, // temperature status (actual/requested) from host (Marlin, Reprap, etc.) + FROM_HOST = 0, // temperature status (actual/requested) from host (Marlin, RepRap, etc.) FROM_GUI, // temperature requested from the TFT's GUI FROM_CMD, // temperature requested in the command queue (from gcode or external source connected to the TFT) } TEMP_SOURCE; @@ -73,30 +73,30 @@ extern const char * const heatWaitCmd[]; extern const char * const extruderDisplayID[]; extern const char * const toolChange[]; -void heatSetTargetTemp(uint8_t index, int16_t temp, TEMP_SOURCE tempSource); -uint16_t heatGetTargetTemp(uint8_t index); -void heatSetCurrentTemp(uint8_t index, int16_t temp); -int16_t heatGetCurrentTemp(uint8_t index); -void heatCoolDown(void); +void heatSetTargetTemp(uint8_t index, const int16_t temp, const TEMP_SOURCE tempSource); // set target temperature +uint16_t heatGetTargetTemp(uint8_t index); // get target temperature +void heatSetCurrentTemp(uint8_t index, const int16_t temp); // set current temperature +int16_t heatGetCurrentTemp(uint8_t index); // get current temperature +void heatCoolDown(void); // disable all heaters/hotends -bool heatGetIsWaiting(uint8_t index); -bool heatHasWaiting(void); -void heatSetIsWaiting(uint8_t index, bool isWaiting); +bool heatGetIsWaiting(const uint8_t index); // is heating waiting to heat up +bool heatHasWaiting(void); // check all heater if there is a heater waiting to be waited +void heatSetIsWaiting(uint8_t index, const bool isWaiting); // set heater waiting status void heatClearIsWaiting(void); -bool heatSetTool(const uint8_t tool); -void heatSetToolIndex(const uint8_t toolIndex); -uint8_t heatGetToolIndex(void); -uint8_t heatGetCurrentHotend(void); -bool heaterDisplayIsValid(uint8_t index); +bool heatSetTool(const uint8_t tool); // set current tool (extruder). Used when tool change command is from TFT +void heatSetToolIndex(const uint8_t toolIndex); // set current Tool (extruder) +uint8_t heatGetToolIndex(void); // get current Tool (extruder) +uint8_t heatGetCurrentHotend(void); // get current hotend index in arry T[] +bool heaterDisplayIsValid(const uint8_t index); // check whether the index is a valid heater index -void heatSetUpdateSeconds(uint8_t seconds); -uint8_t heatGetUpdateSeconds(void); -void heatSyncUpdateSeconds(uint8_t seconds); -void heatSetUpdateWaiting(bool isWaiting); +void heatSetUpdateSeconds(const uint8_t seconds); // set temperature query update time interval +uint8_t heatGetUpdateSeconds(void); // get temperature query seconds +void heatSyncUpdateSeconds(const uint8_t seconds); // set temperature query seconds -void updateNextHeatCheckTime(void); -void loopCheckHeater(void); +void heatSetNextUpdateTime(void); // called in parseAck(). Set next temperature query time or timeout +void heatClearSendingWaiting(void); // called in sendQueueCmd(). Clear sending waiting for temperature query +void loopCheckHeater(void); // called in loopBackEnd(). Loop for check on Heater #ifdef __cplusplus } diff --git a/TFT/src/User/API/Touch_Encoder.c b/TFT/src/User/API/Touch_Encoder.c index 44e1e14841..722c59aa7e 100644 --- a/TFT/src/User/API/Touch_Encoder.c +++ b/TFT/src/User/API/Touch_Encoder.c @@ -1,25 +1,25 @@ #include "Touch_Encoder.h" #include "includes.h" -bool Touch_Enc_ReadPen(uint16_t interval) +bool Touch_Enc_ReadPen(uint16_t duration) { - static uint32_t nowTime = 0; + static uint32_t lastTime = 0; - if (!XPT2046_Read_Pen()) + if (XPT2046_Read_Pen()) // if touch screen not pressed { - if (OS_GetTimeMs() - nowTime >= interval) - { - nowTime = OS_GetTimeMs(); + lastTime = OS_GetTimeMs(); - return true; - } - } - else - { - nowTime = OS_GetTimeMs(); + return false; } - return false; + if (OS_GetTimeMs() - lastTime < duration) // if touch screen held pressed but provided duration not yet reached + return false; + + // touch screen held pressed for the provided duration + + lastTime = OS_GetTimeMs(); + + return true; } #if LCD_ENCODER_SUPPORT @@ -27,79 +27,83 @@ bool Touch_Enc_ReadPen(uint16_t interval) #define LCD_FREE_WIDTH (LCD_WIDTH - LCD_WIDTH / 5) #define LCD_FREE_HEIGHT (LCD_HEIGHT / 5) -bool Touch_Enc_ReadBtn(uint16_t interval) +bool Touch_Enc_ReadBtn(uint16_t duration) { - static uint32_t nowTime = 0; - uint16_t tx, ty; + static uint32_t lastTime = 0; - if (!XPT2046_Read_Pen()) + if (XPT2046_Read_Pen()) // if touch screen not pressed { - TS_GetCoordinates(&tx, &ty); + lastTime = OS_GetTimeMs(); - if (OS_GetTimeMs() - nowTime >= interval) - { - if (tx > LCD_FREE_WIDTH && ty < LCD_FREE_HEIGHT) - return true; - } - } - else - { - nowTime = OS_GetTimeMs(); + return false; } + if (OS_GetTimeMs() - lastTime < duration) // if touch screen held pressed but provided duration not yet reached + return false; + + // touch screen held pressed for the provided duration + + uint16_t tx, ty; + + TS_GetCoordinates(&tx, &ty); + + if (tx > LCD_FREE_WIDTH && ty < LCD_FREE_HEIGHT) + return true; + return false; } uint8_t Touch_Enc_ReadPos(void) { static bool move = false; - static uint16_t sy; + static uint16_t sy = 0; + + if (XPT2046_Read_Pen()) // if touch screen not pressed + { + move = false; + sy = 0; + modeSwitching = false; // resume mode switching + + return 0; + } + uint16_t ex, ey; ex = ey = 0; - if (!XPT2046_Read_Pen()) - { - TS_GetCoordinates(&ex, &ey); + TS_GetCoordinates(&ex, &ey); - if (!move) - sy = ey; + if (!move) + sy = ey; - move = true; + move = true; - if (ex > LCD_FREE_WIDTH) // if touched navigation area, stop mode switching - modeSwitching = true; - else - modeSwitching = false; + if (ex > LCD_FREE_WIDTH) // if touched navigation area, stop mode switching + modeSwitching = true; + else + modeSwitching = false; - if (ex > LCD_FREE_WIDTH) + if (ex > LCD_FREE_WIDTH) + { + if (sy > ey && ey != 0) { - if (sy > ey && ey != 0) + if (sy - ey > LCD_HEIGHT / 9 && sy - ey < LCD_HEIGHT / 7) // 7 - 5 { - if (sy - ey > LCD_HEIGHT / 9 && sy - ey < LCD_HEIGHT / 7) // 7 - 5 - { - sy = ey; + sy = ey; - return 2; - } + return 2; } - else + } + else + { + if (ey - sy > LCD_HEIGHT / 9 && ey - sy < LCD_HEIGHT / 7) { - if (ey - sy > LCD_HEIGHT / 9 && ey - sy < LCD_HEIGHT / 7) - { - sy = ey; + sy = ey; - return 3; - } + return 3; } } } - else - { - move = false; - sy = ey = 0; - modeSwitching = false; // resume mode switching - } return 0; } diff --git a/TFT/src/User/API/Touch_Encoder.h b/TFT/src/User/API/Touch_Encoder.h index 31e774e8c1..b4123ef9fa 100644 --- a/TFT/src/User/API/Touch_Encoder.h +++ b/TFT/src/User/API/Touch_Encoder.h @@ -9,10 +9,10 @@ extern "C" { #include #include "variants.h" // for LCD_ENCODER_SUPPORT -bool Touch_Enc_ReadPen(uint16_t interval); // return the button press state resetting internal timer when reached. Interval is in milli seconds - +bool Touch_Enc_ReadPen(uint16_t duration); // return the button press state resetting internal timer when reached. + // Duration is in milli seconds #if LCD_ENCODER_SUPPORT - bool Touch_Enc_ReadBtn(uint16_t interval); // return the button press state to send to encoder. Interval is in milli seconds + bool Touch_Enc_ReadBtn(uint16_t duration); // return the button press state to send to encoder. Duration is in milli seconds uint8_t Touch_Enc_ReadPos(void); // return the position to send to encoder #endif diff --git a/TFT/src/User/API/UI/GUI.c b/TFT/src/User/API/UI/GUI.c index ca9c3a7947..0509d5fb87 100644 --- a/TFT/src/User/API/UI/GUI.c +++ b/TFT/src/User/API/UI/GUI.c @@ -87,7 +87,7 @@ void GUI_DrawPixel(int16_t x, int16_t y, uint16_t color) ||x >= pixel_limit_rect.x1 ||y < pixel_limit_rect.y0 ||y >= pixel_limit_rect.y1)) - return ; + return; LCD_SetWindow(x, y, x, y); LCD_WR_16BITS_DATA(color); @@ -1132,7 +1132,7 @@ void Scroll_DispString(SCROLL * para, uint8_t align) if (para->text == NULL) return; if (para->totalPixelWidth > para->maxPixelWidth) { - if (OS_GetTimeMs() > para->time) + if (OS_GetTimeMs() >= para->time) { para->time = OS_GetTimeMs() + 50; // 50ms GUI_SetRange(para->rect.x0, para->rect.y0, para->rect.x1, para->rect.y1); diff --git a/TFT/src/User/API/UI/HD44780_Emulator.c b/TFT/src/User/API/UI/HD44780_Emulator.c index 2cd12e9cf1..5d356e5c8d 100644 --- a/TFT/src/User/API/UI/HD44780_Emulator.c +++ b/TFT/src/User/API/UI/HD44780_Emulator.c @@ -176,7 +176,7 @@ void HD44780_DispDDRAM(uint8_t data) temp |= font[i++]; } - for (y = HD44780.y * BYTE_HEIGHT; y < ey ;y++) + for (y = HD44780.y * BYTE_HEIGHT; y < ey; y++) { HD44780_DrawPixel(x, y, temp & (1 << (BYTE_HEIGHT - 1)), 1); temp <<= 1; diff --git a/TFT/src/User/API/UI/Numpad.c b/TFT/src/User/API/UI/Numpad.c index 6dfeca2d4d..2f631e6b96 100644 --- a/TFT/src/User/API/UI/Numpad.c +++ b/TFT/src/User/API/UI/Numpad.c @@ -162,7 +162,7 @@ void Draw_keyboard(uint8_t * title, bool numberOnly, bool negative) setFontSize(FONT_SIZE_LARGE); - for (uint8_t i = 0; i < KEY_COUNT ;i++) + for (uint8_t i = 0; i < KEY_COUNT; i++) { if (!(i == NUM_KEY_DEC || i == NUM_KEY_MINUS || (i % 4) == 3)) // || i == NUM_KEY_DEL || i == NUM_KEY_EXIT || i == NUM_KEY_RESET)) GUI_DispStringInPrect(&rect_of_numkey[i], (uint8_t *)numPadKeyChar[i]); diff --git a/TFT/src/User/API/Vfs/vfs.c b/TFT/src/User/API/Vfs/vfs.c index 6df3ec9076..986f5cbd57 100644 --- a/TFT/src/User/API/Vfs/vfs.c +++ b/TFT/src/User/API/Vfs/vfs.c @@ -26,7 +26,7 @@ TCHAR * getFS(void) case FS_ONBOARD_MEDIA: case FS_ONBOARD_MEDIA_REMOTE: - return infoMachineSettings.firmwareType == FW_REPRAPFW ? "gcodes" : "oMD:"; + return infoMachineSettings.firmwareType != FW_REPRAPFW ? "oMD:" : "gcodes"; case FS_REMOTE_HOST: return "Remote printing..."; diff --git a/TFT/src/User/API/config.c b/TFT/src/User/API/config.c index a5a845fe9e..d592763620 100644 --- a/TFT/src/User/API/config.c +++ b/TFT/src/User/API/config.c @@ -7,6 +7,7 @@ #define CONFIG_SERIAL_PORT "serial_port:" #define CONFIG_TX_SLOTS "tx_slots:" #define CONFIG_ADVANCED_OK "advanced_ok:" +#define CONFIG_COMMAND_CHECKSUM "command_checksum:" #define CONFIG_EMULATED_M600 "emulated_m600:" #define CONFIG_EMULATED_M109_M190 "emulated_m109_m190:" #define CONFIG_EVENT_LED "event_led:" @@ -428,10 +429,11 @@ void parseConfigKey(uint16_t index) break; case C_INDEX_TX_SLOTS: - SET_VALID_INT_VALUE(infoSettings.tx_slots, 2, 16); + SET_VALID_INT_VALUE(infoSettings.tx_slots, MIN_TX_SLOTS, MAX_TX_SLOTS); break; case C_INDEX_ADVANCED_OK: + case C_INDEX_COMMAND_CHECKSUM: case C_INDEX_EMULATED_M600: case C_INDEX_EMULATED_M109_M190: case C_INDEX_EVENT_LED: diff --git a/TFT/src/User/API/config.h b/TFT/src/User/API/config.h index 54ad0c02ea..88fa2d72af 100644 --- a/TFT/src/User/API/config.h +++ b/TFT/src/User/API/config.h @@ -11,6 +11,7 @@ extern "C" { #define LINE_MAX_CHAR 200 //-----------------------------Limits +#define MAX_TX_SLOTS 16 // tx slots over this will not be parsed #define MAX_SIZE_LIMIT 2000 // machine size over this will not be parsed #define MAX_EXT_SPEED_LIMIT 5000 // Extruder speed over this will not be parsed #define MAX_TOOL_TEMP 1000 // extruder temp over this will not be parsed @@ -25,6 +26,7 @@ extern "C" { #define MAX_LED_COLOR_COMP 255 // (neopixel) LED color component over this will not be parsed #define MAX_NEOPIXEL_PIXELS 200 // neopixel pixels over this will not be parsed +#define MIN_TX_SLOTS 2 // tx slots less than this will not be parsed #define MIN_SIZE_LIMIT -2000 // machine size less than this will not be parsed #define NAME_MIN_LENGTH 3 // minimum name length #define GCODE_MIN_LENGTH 3 // gcode length less than this will not be parsed diff --git a/TFT/src/User/API/config.inc b/TFT/src/User/API/config.inc index 35b9f35f65..2b0d84e5ca 100644 --- a/TFT/src/User/API/config.inc +++ b/TFT/src/User/API/config.inc @@ -12,6 +12,7 @@ X_CONFIG (SERIAL_PORT) X_CONFIG (TX_SLOTS) X_CONFIG (ADVANCED_OK) +X_CONFIG (COMMAND_CHECKSUM) X_CONFIG (EMULATED_M600) X_CONFIG (EMULATED_M109_M190) X_CONFIG (EVENT_LED) diff --git a/TFT/src/User/API/coordinate.c b/TFT/src/User/API/coordinate.c index 943f74aeb3..1ad3f37d0a 100644 --- a/TFT/src/User/API/coordinate.c +++ b/TFT/src/User/API/coordinate.c @@ -18,8 +18,9 @@ static bool relative_e = false; // false means current position is unknown // false after M18/M84 disable stepper or power up, true after G28 static bool position_known = false; -static bool coordinateQueryWait = false; -static uint8_t curQuerySeconds = 0; + +static uint8_t coordUpdateSeconds = 0; +static bool coordSendingWaiting = false; bool coorGetRelative(void) { @@ -108,9 +109,17 @@ void coordinateGetAllActual(COORDINATE *tmp) memcpy(tmp, &curPosition, sizeof(curPosition)); } -void coordinateQuerySetWait(bool wait) +float coordinateGetAxis(AXIS axis) +{ + if (infoFile.source >= FS_ONBOARD_MEDIA) + return coordinateGetAxisActual(axis); + else + return coordinateGetAxisTarget(axis); +} + +void coordinateQueryClearSendingWaiting(void) { - coordinateQueryWait = wait; + coordSendingWaiting = false; } /** @@ -120,41 +129,33 @@ void coordinateQuerySetWait(bool wait) */ void coordinateQuery(uint8_t seconds) { // following conditions ordered by importance - if (!coordinateQueryWait && infoHost.tx_slots != 0 && infoHost.connected) + if (!coordSendingWaiting && infoHost.tx_slots != 0 && infoHost.connected && infoMachineSettings.firmwareType != FW_REPRAPFW) { if (infoMachineSettings.autoReportPos == 1) // if auto report is enabled { if (seconds == 0) // if manual querying is requested (if query interval is 0) - coordinateQueryWait = storeCmd("M114\n"); + coordSendingWaiting = storeCmd("M114\n"); - if (seconds != curQuerySeconds) // if query interval is changed + if (seconds != coordUpdateSeconds) // if query interval is changed { if (storeCmd("M154 S%d\n", seconds)) // turn on or off (if query interval is 0) auto report - curQuerySeconds = seconds; // if gcode will be sent, avoid to enable auto report again on next + coordUpdateSeconds = seconds; // if gcode will be sent, avoid to enable auto report again on next } // function call if already enabled for that query interval } else // if auto report is disabled { - coordinateQueryWait = storeCmd("M114\n"); + coordSendingWaiting = storeCmd("M114\n"); } } } void coordinateQueryTurnOff(void) { - coordinateQueryWait = false; + coordSendingWaiting = false; if (infoMachineSettings.autoReportPos == 1) // if auto report is enabled, turn it off { storeCmd("M154 S0\n"); - curQuerySeconds = 0; + coordUpdateSeconds = 0; } } - -float coordinateGetAxis(AXIS axis) -{ - if (infoFile.source >= FS_ONBOARD_MEDIA) - return coordinateGetAxisActual(axis); - else - return coordinateGetAxisTarget(axis); -} diff --git a/TFT/src/User/API/coordinate.h b/TFT/src/User/API/coordinate.h index 3d4c5302a3..0e9c5d01ec 100644 --- a/TFT/src/User/API/coordinate.h +++ b/TFT/src/User/API/coordinate.h @@ -50,11 +50,12 @@ void coordinateSetExtruderActualSteps(float steps); float coordinateGetAxisActual(AXIS axis); void coordinateSetAxisActual(AXIS axis, float position); void coordinateGetAllActual(COORDINATE *tmp); -void coordinateQuerySetWait(bool wait); -void coordinateQuery(uint8_t delay); -void coordinateQueryTurnOff(void); float coordinateGetAxis(AXIS axis); +void coordinateQueryClearSendingWaiting(void); // called in sendQueueCmd(). Clear sending waiting for coordinate query +void coordinateQuery(uint8_t delay); // query for coordinate +void coordinateQueryTurnOff(void); + #ifdef __cplusplus } #endif diff --git a/TFT/src/User/API/menu.c b/TFT/src/User/API/menu.c index 625e0c95b9..892cbc1251 100644 --- a/TFT/src/User/API/menu.c +++ b/TFT/src/User/API/menu.c @@ -536,15 +536,6 @@ void menuClearGaps(void) #endif } -void GUI_RestoreColorDefault(void) -{ - GUI_SetBkColor(infoSettings.bg_color); - GUI_SetColor(infoSettings.font_color); - GUI_SetTextMode(GUI_TEXTMODE_NORMAL); - GUI_SetNumMode(GUI_NUMMODE_SPACE); - setFontSize(FONT_SIZE_NORMAL); -} - static const MENUITEMS *curMenuItems = NULL; // current menu static const LISTITEMS *curListItems = NULL; // current listmenu @@ -568,105 +559,6 @@ static struct { uint16_t x; uint32_t time; } busySign = {LCD_WIDTH - 3, 3, 3, SYS_STATUS_BUSY, 0}; -MENUITEMS *getCurMenuItems(void) -{ - return (MENUITEMS *)curMenuItems; -} - -LISTITEMS *getCurListItems(void) -{ - return (LISTITEMS *)curListItems; -} - -// Get the top left point of the corresponding icon position) -GUI_POINT getIconStartPoint(int index) -{ - GUI_POINT p = {curRect[index].x0, curRect[index].y0}; - return p; -} - -uint8_t *labelGetAddress(const LABEL *label) -{ - if (label == NULL || label->index == LABEL_NULL) // No content in label - return NULL; - if (label->index < LABEL_NUM) // Index of language - return textSelect(label->index); - else // Address of string - return label->address; -} - -void menuDrawItem(const ITEM *item, uint8_t position) -{ - menuDrawIconOnly(item, position); - menuDrawIconText(item, position); -} - -void menuDrawIconOnly(const ITEM *item, uint8_t position) -{ - const GUI_RECT *rect = curRect + position; - if (item->icon != ICON_NULL) - ICON_ReadDisplay(rect->x0, rect->y0, item->icon); - else - GUI_ClearPrect(rect); -} - -void menuDrawIconText(const ITEM *item, uint8_t position) -{ - uint8_t *content = labelGetAddress(&item->label); - const GUI_RECT *rect = curRect + ITEM_PER_PAGE + position; - GUI_ClearPrect(rect); - if (content) - GUI_DispStringInPrect(rect, content); -} - -void menuDrawListItem(const LISTITEM *item, uint8_t position) -{ - const GUI_RECT *rect = rect_of_keyListView + position; - if (item->icon == CHARICON_NULL) - { - GUI_ClearPrect(rect); - } - else - { - ListItem_Display(rect, position, item, false); - } -} - -void menuRefreshListPage(void) -{ - for (uint8_t i = 0; i < ITEM_PER_PAGE; i++) - { - RAPID_PRINTING_COMM() // perform backend printing loop between drawing icons to avoid printer idling - menuDrawListItem(&curListItems->items[i], i); - } -} - -void setMenuType(MENU_TYPE type) -{ - menuType = type; -} - -MENU_TYPE getMenuType(void) -{ - return menuType; -} - -void setMenu(MENU_TYPE menu_type, LABEL * title, uint16_t rectCount, const GUI_RECT * menuRect, - void (*action_redraw)(uint8_t position, uint8_t is_press), - void (*menu_redraw)(void)) -{ - menuType = menu_type; - curRect = menuRect; - curRectCount = rectCount; - curTitle = title; - curMenuRedrawHandle = menu_redraw; - TS_ReDrawIcon = action_redraw; - - #if LCD_ENCODER_SUPPORT - encoderPosition = 0; - #endif -} - SYS_STATUS getReminderStatus(void) { return reminder.status; @@ -775,6 +667,114 @@ void notificationDot(void) GUI_RestoreColorDefault(); } +void GUI_RestoreColorDefault(void) +{ + GUI_SetBkColor(infoSettings.bg_color); + GUI_SetColor(infoSettings.font_color); + GUI_SetTextMode(GUI_TEXTMODE_NORMAL); + GUI_SetNumMode(GUI_NUMMODE_SPACE); + setFontSize(FONT_SIZE_NORMAL); +} + +MENUITEMS *getCurMenuItems(void) +{ + return (MENUITEMS *)curMenuItems; +} + +LISTITEMS *getCurListItems(void) +{ + return (LISTITEMS *)curListItems; +} + +// Get the top left point of the corresponding icon position) +GUI_POINT getIconStartPoint(int index) +{ + GUI_POINT p = {curRect[index].x0, curRect[index].y0}; + return p; +} + +uint8_t *labelGetAddress(const LABEL *label) +{ + if (label == NULL || label->index == LABEL_NULL) // No content in label + return NULL; + if (label->index < LABEL_NUM) // Index of language + return textSelect(label->index); + else // Address of string + return label->address; +} + +void menuDrawItem(const ITEM *item, uint8_t position) +{ + menuDrawIconOnly(item, position); + menuDrawIconText(item, position); +} + +void menuDrawIconOnly(const ITEM *item, uint8_t position) +{ + const GUI_RECT *rect = curRect + position; + if (item->icon != ICON_NULL) + ICON_ReadDisplay(rect->x0, rect->y0, item->icon); + else + GUI_ClearPrect(rect); +} + +void menuDrawIconText(const ITEM *item, uint8_t position) +{ + uint8_t *content = labelGetAddress(&item->label); + const GUI_RECT *rect = curRect + ITEM_PER_PAGE + position; + GUI_ClearPrect(rect); + if (content) + GUI_DispStringInPrect(rect, content); +} + +void menuDrawListItem(const LISTITEM *item, uint8_t position) +{ + const GUI_RECT *rect = rect_of_keyListView + position; + if (item->icon == CHARICON_NULL) + { + GUI_ClearPrect(rect); + } + else + { + ListItem_Display(rect, position, item, false); + } +} + +void menuRefreshListPage(void) +{ + for (uint8_t i = 0; i < ITEM_PER_PAGE; i++) + { + RAPID_PRINTING_COMM() // perform backend printing loop between drawing icons to avoid printer idling + menuDrawListItem(&curListItems->items[i], i); + } +} + +void setMenuType(MENU_TYPE type) +{ + menuType = type; +} + +MENU_TYPE getMenuType(void) +{ + return menuType; +} + +void setMenu(MENU_TYPE menu_type, LABEL * title, uint16_t rectCount, const GUI_RECT * menuRect, + void (*action_redraw)(uint8_t position, uint8_t is_press), + void (*menu_redraw)(void)) +{ + menuType = menu_type; + curRect = menuRect; + curRectCount = rectCount; + curTitle = title; + curMenuRedrawHandle = menu_redraw; + TS_ReDrawIcon = action_redraw; + + #if LCD_ENCODER_SUPPORT + encoderPosition = 0; + #endif +} + void menuSetTitle(const LABEL *title) { curTitle = title; @@ -1023,7 +1023,7 @@ void showLiveInfo(uint8_t index, const LIVE_INFO * liveicon, bool redrawIcon) } GUI_RestoreColorDefault(); -} // showLiveInfo +} // showLiveInfo void displayExhibitHeader(const char * titleStr, const char * unitStr) { @@ -1137,7 +1137,7 @@ KEY_VALUES menuKeyGetValue(void) // Smart home (long press on back button to go to status screen) #ifdef SMART_HOME -static inline void loopCheckBackPress(void) +void loopCheckBackPress(void) { static bool longPress = false; @@ -1207,148 +1207,3 @@ static inline void loopCheckBackPress(void) } #endif // SMART_HOME - -// Non-UI background loop tasks -void loopBackEnd(void) -{ - UPD_SCAN_RATE(); // debug monitoring KPI - - // Handle a print from TFT media, if any - loopPrintFromTFT(); - - // Parse and send gcode commands in the queue - sendQueueCmd(); - - // Parse the received slave response information - parseACK(); - - // Retrieve and store (in command queue) the gcodes received from other UART, such as ESP3D etc... - #ifdef SERIAL_PORT_2 - Serial_GetFromUART(); - #endif - - // Handle USB communication - #ifdef USB_FLASH_DRIVE_SUPPORT - USB_LoopProcess(); - #endif - - if ((priorityCounter.be++ % BE_PRIORITY_DIVIDER) != 0) // a divider value of 16 -> run 6% of the time only - return; - - // Temperature monitor - loopCheckHeater(); - - // Fan speed monitor - loopFan(); - - // Speed & flow monitor - loopSpeed(); - - // Buzzer handling - #ifdef BUZZER_PIN - loopBuzzer(); - #endif - - // Handle a print from (remote) onboard media, if any - if (infoMachineSettings.onboardSD == ENABLED) - loopPrintFromOnboard(); - - // Check filament runout status - #ifdef FIL_RUNOUT_PIN - FIL_BE_CheckRunout(); - #endif - - // Check changes in encoder steps - #if LCD_ENCODER_SUPPORT - #ifdef HAS_EMULATOR - if (MENU_IS_NOT(menuMarlinMode)) - #endif - { - LCD_Enc_CheckSteps(); - } - #endif - - // Check mode switching - #ifdef HAS_EMULATOR - Mode_CheckSwitching(); - #endif - - // Handle screenshot capture - #ifdef SCREEN_SHOT_TO_SD - loopScreenShot(); - #endif - - // Check if Back is pressed and held - #ifdef SMART_HOME - loopCheckBackPress(); - #endif - - // Check LCD screen dimming - #ifdef LCD_LED_PWM_CHANNEL - LCD_CheckDimming(); - #endif - - // Check LED Event - if (GET_BIT(infoSettings.general_settings, INDEX_EVENT_LED) == 1) - LED_CheckEvent(); - - // Query RRF status - rrfStatusQuery(); -} - -// UI-related background loop tasks -void loopFrontEnd(void) -{ - // Check if volume source (SD/USB) insert - loopVolumeSource(); - - // Loop to check and run toast messages - loopToast(); - - // If there is a message in the status bar, timed clear - loopReminderManage(); - - // Busy Indicator clear - loopBusySignClear(); - - // Check update temperature status - loopTemperatureStatus(); - - // Loop for filament runout detection - #ifdef FIL_RUNOUT_PIN - FIL_FE_CheckRunout(); - #endif - - // Loop for popup menu - loopPopup(); -} - -void loopProcess(void) -{ - loopBackEnd(); - - if ((priorityCounter.fe++ % FE_PRIORITY_DIVIDER) != 0) // a divider value of 16 -> run 6% of the time only - return; - - loopFrontEnd(); -} - -void menuDummy(void) -{ - CLOSE_MENU(); -} - -void loopProcessAndGUI(void) -{ - uint8_t curMenu = infoMenu.cur; - - loopProcess(); - - if (infoMenu.cur != curMenu) // if a user interaction is needed (e.g. dialog box), handle it - { - (*infoMenu.menu[infoMenu.cur])(); // handle user interaction - - if (MENU_IS_NOT(menuDummy)) // avoid to nest menuDummy menu type - OPEN_MENU(menuDummy); // load a dummy menu just to force the redraw of the underlying menu (caller menu) - } -} diff --git a/TFT/src/User/API/menu.h b/TFT/src/User/API/menu.h index 32e5beb66a..0d78934cd9 100644 --- a/TFT/src/User/API/menu.h +++ b/TFT/src/User/API/menu.h @@ -106,15 +106,6 @@ typedef struct ITEM items[ITEM_PER_PAGE]; } MENUITEMS; -typedef enum -{ - SYS_STATUS_IDLE = 0, - SYS_STATUS_BUSY, - SYS_STATUS_DISCONNECTED, - SYS_STATUS_LISTENING, - SYS_STATUS_VOL_CHANGE -} SYS_STATUS; - typedef enum { LIST_LABEL = 0, @@ -158,7 +149,14 @@ typedef struct LIVE_DATA lines[LIVEICON_LINES]; } LIVE_INFO; -typedef bool (* CONDITION_CALLBACK)(void); +typedef enum +{ + SYS_STATUS_IDLE = 0, + SYS_STATUS_BUSY, + SYS_STATUS_DISCONNECTED, + SYS_STATUS_LISTENING, + SYS_STATUS_VOL_CHANGE +} SYS_STATUS; extern const GUI_RECT exhibitRect; extern const GUI_RECT rect_of_key[MENU_RECT_COUNT]; @@ -166,32 +164,32 @@ extern const GUI_RECT rect_of_keySS[SS_RECT_COUNT]; extern const GUI_RECT rect_of_keyPS[]; extern const GUI_RECT rect_of_keyPS_end[]; extern const GUI_RECT rect_of_keyPS_draw[]; // used to draw VERTICAL GUI Printing menu - extern const GUI_RECT rect_of_titleBar[1]; -void setMenuType(MENU_TYPE type); -MENU_TYPE getMenuType(void); - SYS_STATUS getReminderStatus(void); void setReminderMsg(int16_t inf, SYS_STATUS status); -void notificationDot(void); +void loopReminderManage(void); void drawBusySign(void); +void loopBusySignClear(void); +void notificationDot(void); +void GUI_RestoreColorDefault(void); MENUITEMS *getCurMenuItems(void); LISTITEMS *getCurListItems(void); GUI_POINT getIconStartPoint(int index); - -void GUI_RestoreColorDefault(void); uint8_t *labelGetAddress(const LABEL * label); -void setMenu(MENU_TYPE menu_type, LABEL * title, uint16_t rectCount, const GUI_RECT * menuRect, - void (*action_redraw)(uint8_t position, uint8_t is_press), - void (*menu_redraw)(void)); void menuDrawItem (const ITEM * menuItem, uint8_t position); void menuDrawIconOnly(const ITEM *item, uint8_t position); void menuDrawIconText(const ITEM *item, uint8_t position); void menuDrawListItem(const LISTITEM *item, uint8_t position); void menuRefreshListPage(void); + +void setMenuType(MENU_TYPE type); +MENU_TYPE getMenuType(void); +void setMenu(MENU_TYPE menu_type, LABEL * title, uint16_t rectCount, const GUI_RECT * menuRect, + void (*action_redraw)(uint8_t position, uint8_t is_press), + void (*menu_redraw)(void)); void menuSetTitle(const LABEL *title); void menuDrawTitle(void); void menuDrawPage(const MENUITEMS * menuItems); @@ -203,16 +201,12 @@ void displayExhibitValue(const char * valueStr); KEY_VALUES menuKeyGetValue(void); -// Smart home +// smart home #ifdef SMART_HOME #define LONG_TOUCH (MODE_SWITCHING_INTERVAL / 3) // keep it lower than MODE_SWITCHING_INTERVAL -#endif -void menuDummy(void); -void loopBackEnd(void); -void loopFrontEnd(void); -void loopProcess(void); -void loopProcessAndGUI(void); + void loopCheckBackPress(void); +#endif #ifdef __cplusplus } diff --git a/TFT/src/User/Configuration.h b/TFT/src/User/Configuration.h index 171f7b7f19..8fb168dfe7 100644 --- a/TFT/src/User/Configuration.h +++ b/TFT/src/User/Configuration.h @@ -1,7 +1,7 @@ #ifndef _CONFIGURATION_H_ #define _CONFIGURATION_H_ -#define CONFIG_VERSION 20231119 +#define CONFIG_VERSION 20240203 //==================================================================================================== //=============================== Settings Configurable On config.ini ================================ @@ -74,12 +74,50 @@ * support the transmission of G-codes according to the configured "TX_SLOTS" setting. * If disabled, the TFT will provide the standard transmission logic based on one G-code per time. * - * NOTE: Disable it in case no ADVANCED_OK feature is requested/needed by the user. + * NOTE: Disable it in case: + * - no ADVANCED_OK feature is requested/needed by the user. + * - ADVANCED_OK feature is not providing good printing results or if the mainboard notifies + * frequent error ACK messages (e.g. unknown command) to the TFT during printing. + * - COMMAND_CHECKSUM feature (see description of next setting "COMMAND_CHECKSUM") is + * requested/needed by the user. * * Options: [disable: 0, enable: 1] */ #define ADVANCED_OK 0 // Default: 0 +/** + * Command Checksum + * The TFT enriches each G-code to be sent to the mainboard adding a leading sequential line number + * and a trailing checksum appended after an "*" character used as separator. + * The checksum is based on algorithm "CheckSum8 Xor" and it is calculated on the G-code with the + * applied line number. E.g. "G28" is firstly enriched with a line number (e.g. "N1 G28") and finally + * a checksum calculated on that enriched G-code is appended (e.g. "N1 G28*18"). + * A data integrity check (sequential line number check and checksum check) will be performed on the + * mainboard. In case of data mismatch (e.g. data corruption due to EMI on communication serial line): + * - the mainboard will send to the TFT an error ACK message followed by a "Resend: " ACK message to + * ask TFT to resend the G-code with the requested line number. + * - the TFT will check the presence on an internal buffer of the G-code with the requested line number: + * - if found, the G-code is resent for a maximum of 3 attempts. + * - if not found or the maximum number of attempts has been reached, the TFT will reset the line + * number with an "M110" G-code (immediately sent bypassing any other enqueued G-code) to the + * requested line number just to try to avoid further retransmission requests for the same line + * number or for any out of synch command already sent to the mainboard (e.g. in case ADVANCED_OK + * feature is enabled in TFT). + * + * NOTE: Disable it in case: + * - printing is controlled by a remote host (e.g. ESP3D, OctoPrint etc.) and a COMMAND_CHECKSUM + * feature is enabled and managed by the remote host. Otherwise (COMMAND_CHECKSUM feature also + * enabled in TFT), the TFT's COMMAND_CHECKSUM feature will always replace the one provided by + * the remote host causing conflicts in case data mismatch will be notified by the mainboard. + * - ADVANCED_OK feature is enabled in TFT. Otherwise, any out of synch command already sent to + * the mainboard will be discarded by the mainboard and not resent by the TFT due the current + * implementation of COMMAND_CHECKSUM feature on the TFT buffers only the last sent command + * and not all the pending commands. + * + * Options: [disable: 0, enable: 1] + */ +#define COMMAND_CHECKSUM 1 // Default: 1 + /** * Emulated M600 * The TFT intercepts the M600 G-code (filament change) and emulates the handling logic @@ -209,7 +247,7 @@ * Options: [OFF: 0, POPUP: 1, TOAST: 2] * OFF: No notification. The message is ignored. * POPUP: Display a popup window for user confirmation. - * TOAST: A non-blocking Toast notification is displayed for few seconds. No user interaction is needed. + * TOAST: A non-blocking toast notification is displayed for few seconds. No user interaction is needed. */ #define ACK_NOTIFICATION 1 // Default: 1 @@ -802,6 +840,10 @@ /** * Filament Runout Sensor * Select the type of filament runout sensor and its default enabled/disabled state. + * + * NOTE: Smart Filament Sensor (SFS) (value 2 or 3) is a sensor based on an encoder disc that + * toggles runout pin as filament moves (e.g. the BigTreeTech SFS). + * * Options: [Normal Disabled: 0, Normal Enabled: 1, Smart Disabled: 2, Smart Enabled: 3] */ #define FIL_RUNOUT 0 // Default: 0 @@ -834,6 +876,10 @@ * Smart Filament Runout Detection * Used in conjunction with an SFS (Smart Filament Sensor) based on an encoder disc that * toggles runout pin as filament moves. + * + * NOTE: This setting is taken into account by the TFT only in case "FIL_RUNOUT" setting is + * set to 2 or 3 (an SFS is used). + * * Unit: [distance in mm] * Value range: [min: 1, max: 50] */ diff --git a/TFT/src/User/Hal/HD44780.c b/TFT/src/User/Hal/HD44780.c index 9ed1f63b59..933decb9c5 100644 --- a/TFT/src/User/Hal/HD44780.c +++ b/TFT/src/User/Hal/HD44780.c @@ -112,7 +112,7 @@ bool HD44780_writeData(void) uint8_t temp = ((LCD_D7_PORT->IDR & LCD_D7_PIN) >> 3 ) + // D7 ((LCD_D6_PORT->IDR & LCD_D6_PIN) >> 5 ) + // D6 ((LCD_D5_PORT->IDR & LCD_D5_PIN) >> 13) + // D5 - ((LCD_D4_PORT->IDR & LCD_D4_PIN) >> 13) ; // D4 + ((LCD_D4_PORT->IDR & LCD_D4_PIN) >> 13); // D4 if ((GPIOB->IDR & (1 << 12)) == 0) { //Command received diff --git a/TFT/src/User/Hal/LCD_Encoder.c b/TFT/src/User/Hal/LCD_Encoder.c index 5b33b47d94..09cef9aea8 100644 --- a/TFT/src/User/Hal/LCD_Encoder.c +++ b/TFT/src/User/Hal/LCD_Encoder.c @@ -48,21 +48,23 @@ void LCD_Enc_Init(void) encoderLastState = encoderLastSteps = LCD_Enc_ReadPos(); } -bool LCD_Enc_ReadBtn(uint16_t interval) +bool LCD_Enc_ReadBtn(uint16_t duration) { - static uint32_t nowTime = 0; + static uint32_t lastTime = 0; - if (!GPIO_GetLevel(LCD_BTN_PIN)) + if (GPIO_GetLevel(LCD_BTN_PIN)) // if rotary encoder button not pressed { - if (OS_GetTimeMs() - nowTime >= interval) - return true; - } - else - { - nowTime = OS_GetTimeMs(); + lastTime = OS_GetTimeMs(); + + return false; } - return false; + if (OS_GetTimeMs() - lastTime < duration) // if rotary encoder button held pressed but provided duration not yet reached + return false; + + // rotary encoder button held pressed for the provided duration + + return true; } uint8_t LCD_Enc_ReadPos(void) @@ -158,8 +160,12 @@ void LCD_Enc_CheckSteps(void) #define encrot3 1 // manage encoder rotation - #define ENCODER_SPIN(_E1, _E2) switch (encoderLastSteps) { case _E1: encoderDiff += encoderDirection; break; \ - case _E2: encoderDiff -= encoderDirection; } + #define ENCODER_SPIN(_E1, _E2) \ + switch (encoderLastSteps) \ + { \ + case _E1: encoderDiff += encoderDirection; break; \ + case _E2: encoderDiff -= encoderDirection; break; \ + } if (pos != encoderLastSteps) { @@ -190,7 +196,9 @@ KEY_VALUES LCD_Enc_KeyValue(void) else { int16_t encPosTemp = encoderPosition; + encoderPosition = 0; + return (encPosTemp > 0) ? KEY_INCREASE : KEY_DECREASE; } } diff --git a/TFT/src/User/Hal/LCD_Encoder.h b/TFT/src/User/Hal/LCD_Encoder.h index 94f7812e43..3415f94c34 100644 --- a/TFT/src/User/Hal/LCD_Encoder.h +++ b/TFT/src/User/Hal/LCD_Encoder.h @@ -19,7 +19,7 @@ extern "C" { extern int16_t encoderPosition; // make it available for reading the current rotation value void LCD_Enc_Init(void); - bool LCD_Enc_ReadBtn(uint16_t interval); // return the button press state. Interval is in milli seconds + bool LCD_Enc_ReadBtn(uint16_t duration); // return the button press state. Duration is in milli seconds uint8_t LCD_Enc_ReadPos(void); // return the position pins state void LCD_Enc_SendPulse(uint8_t num); // send a pulse to the encoder bool LCD_Enc_CheckState(void); diff --git a/TFT/src/User/Hal/gd32f20x/Serial.h b/TFT/src/User/Hal/gd32f20x/Serial.h index d66960ba5a..43041be815 100644 --- a/TFT/src/User/Hal/gd32f20x/Serial.h +++ b/TFT/src/User/Hal/gd32f20x/Serial.h @@ -30,6 +30,7 @@ typedef struct } SERIAL_CFG; extern DMA_CIRCULAR_BUFFER dmaL1DataRX[_UART_CNT]; +extern DMA_CIRCULAR_BUFFER dmaL1DataTX[_UART_CNT]; extern const SERIAL_CFG Serial[_UART_CNT]; void Serial_Config(uint8_t port, uint32_t cacheSizeRX, uint32_t cacheSizeTX, uint32_t baudrate); diff --git a/TFT/src/User/Hal/gd32f20x/lcd.c b/TFT/src/User/Hal/gd32f20x/lcd.c index 5afacb4cc7..4091bdf230 100644 --- a/TFT/src/User/Hal/gd32f20x/lcd.c +++ b/TFT/src/User/Hal/gd32f20x/lcd.c @@ -59,8 +59,8 @@ void LCD_GPIO_Config(void) void LCD_EXMC_Config(void) { - exmc_norsram_parameter_struct EXMC_NORSRAMInitStructure; - exmc_norsram_timing_parameter_struct readWriteTiming,writeTiming; ; + exmc_norsram_parameter_struct EXMC_NORSRAMInitStructure; + exmc_norsram_timing_parameter_struct readWriteTiming,writeTiming; /* EXMC configuration */ readWriteTiming.asyn_address_setuptime = 1U; diff --git a/TFT/src/User/Hal/stm32f10x/Serial.h b/TFT/src/User/Hal/stm32f10x/Serial.h index bd51bf52a0..7d5fd491a3 100644 --- a/TFT/src/User/Hal/stm32f10x/Serial.h +++ b/TFT/src/User/Hal/stm32f10x/Serial.h @@ -30,6 +30,7 @@ typedef struct } SERIAL_CFG; extern DMA_CIRCULAR_BUFFER dmaL1DataRX[_UART_CNT]; +extern DMA_CIRCULAR_BUFFER dmaL1DataTX[_UART_CNT]; extern const SERIAL_CFG Serial[_UART_CNT]; void Serial_Config(uint8_t port, uint32_t cacheSizeRX, uint32_t cacheSizeTX, uint32_t baudrate); diff --git a/TFT/src/User/Hal/stm32f2_f4xx/Serial.h b/TFT/src/User/Hal/stm32f2_f4xx/Serial.h index a1bdbdc6c8..e7b9a2fd33 100644 --- a/TFT/src/User/Hal/stm32f2_f4xx/Serial.h +++ b/TFT/src/User/Hal/stm32f2_f4xx/Serial.h @@ -30,6 +30,7 @@ typedef struct } SERIAL_CFG; extern DMA_CIRCULAR_BUFFER dmaL1DataRX[_UART_CNT]; +extern DMA_CIRCULAR_BUFFER dmaL1DataTX[_UART_CNT]; extern const SERIAL_CFG Serial[_UART_CNT]; void Serial_Config(uint8_t port, uint32_t cacheSizeRX, uint32_t cacheSizeTX, uint32_t baudrate); diff --git a/TFT/src/User/Hal/stm32f2_f4xx/sdio_sdcard.c b/TFT/src/User/Hal/stm32f2_f4xx/sdio_sdcard.c index cbb110bb81..294a51c1ed 100644 --- a/TFT/src/User/Hal/stm32f2_f4xx/sdio_sdcard.c +++ b/TFT/src/User/Hal/stm32f2_f4xx/sdio_sdcard.c @@ -1126,7 +1126,7 @@ SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo) tmp = (uint8_t)((CSD_Tab[2] & 0x0000FF00) >> 8); cardinfo->SD_csd.DeviceSizeMul |= (tmp & 0x80) >> 7; - cardinfo->CardCapacity = (cardinfo->SD_csd.DeviceSize + 1) ; + cardinfo->CardCapacity = (cardinfo->SD_csd.DeviceSize + 1); cardinfo->CardCapacity *= (1 << (cardinfo->SD_csd.DeviceSizeMul + 2)); cardinfo->CardBlockSize = 1 << (cardinfo->SD_csd.RdBlockLen); cardinfo->CardCapacity *= cardinfo->CardBlockSize; diff --git a/TFT/src/User/Menu/BLTouch.c b/TFT/src/User/Menu/BLTouch.c index 431ee3e438..12f5f2df44 100644 --- a/TFT/src/User/Menu/BLTouch.c +++ b/TFT/src/User/Menu/BLTouch.c @@ -33,7 +33,7 @@ void menuBLTouch(void) if (infoMachineSettings.firmwareType == FW_MARLIN) { - mustStoreCmd("M401 H\n"); // get BLTouch HS Mode state (bltHSmode will be updated in parseACK()) + mustStoreCmd("M401 H\n"); // get BLTouch HS Mode state (bltHSmode will be updated in parseAck()) mustStoreCmd(SERVO_GCODE, 90); // if "M401 H" is not supported the probe will be deployed so it needs to be stowed back } @@ -67,7 +67,7 @@ void menuBLTouch(void) case KEY_ICON_5: if (bltHSmode != HS_DISABLED) - storeCmd("M401 S%u\n", HS_ON - bltHSmode); // switch BLTouch HS Mode state (bltHSmode will be updated in parseACK()) + storeCmd("M401 S%u\n", HS_ON - bltHSmode); // switch BLTouch HS Mode state (bltHSmode will be updated in parseAck()) break; case KEY_ICON_7: diff --git a/TFT/src/User/Menu/BedLeveling.c b/TFT/src/User/Menu/BedLeveling.c index 3f69099e07..e6b830c7fb 100644 --- a/TFT/src/User/Menu/BedLeveling.c +++ b/TFT/src/User/Menu/BedLeveling.c @@ -168,7 +168,7 @@ void menuBedLeveling(void) break; } - if (levelStateNew != UNDEFINED) // it's Marlin or Reprap FW + if (levelStateNew != UNDEFINED) // it's Marlin or RepRap firmware { levelStateNew = getParameter(P_ABL_STATE, 0); diff --git a/TFT/src/User/Menu/CaseLight.c b/TFT/src/User/Menu/CaseLight.c index 93d9f3de82..587c9006b3 100644 --- a/TFT/src/User/Menu/CaseLight.c +++ b/TFT/src/User/Menu/CaseLight.c @@ -1,8 +1,6 @@ #include "CaseLight.h" #include "includes.h" -#define CASE_LIGHT_UPDATE_TIME 1000 // 1 seconds is 1000 - static uint8_t caseLightPercent = 0; static bool caseLightState; @@ -87,8 +85,8 @@ void menuCaseLight(void) case KEY_ICON_3: case KEY_INCREASE: requestedCLpercent = (key_num == KEY_ICON_3 || key_num == KEY_INCREASE) ? - NOBEYOND(0, requestedCLpercent + percentSteps[percent_index], 100) : - NOBEYOND(0, requestedCLpercent - percentSteps[percent_index], 100); + NOBEYOND(0, requestedCLpercent + percentSteps[percent_index], 100) : + NOBEYOND(0, requestedCLpercent - percentSteps[percent_index], 100); sendingNeeded |= DO_SEND_PERCENT; break; diff --git a/TFT/src/User/Menu/FeatureSettings.c b/TFT/src/User/Menu/FeatureSettings.c index 8388fc35be..95f0d18882 100644 --- a/TFT/src/User/Menu/FeatureSettings.c +++ b/TFT/src/User/Menu/FeatureSettings.c @@ -24,6 +24,7 @@ const LABEL itemToggleSmart[ITEM_TOGGLE_SMART_NUM] = typedef enum { SKEY_ADVANCED_OK = 0, + SKEY_COMMAND_CHECKSUM, SKEY_EMULATED_M600, SKEY_EMULATED_M109_M190, SKEY_EVENT_LED, @@ -65,6 +66,7 @@ static inline void updateFeatureSettings(uint8_t item_index) switch (item_index) { case SKEY_ADVANCED_OK: + case SKEY_COMMAND_CHECKSUM: case SKEY_EMULATED_M600: case SKEY_EMULATED_M109_M190: case SKEY_EVENT_LED: @@ -139,6 +141,7 @@ void loadFeatureSettings(LISTITEM * item, uint16_t item_index, uint8_t itemPos) switch (item_index) { case SKEY_ADVANCED_OK: + case SKEY_COMMAND_CHECKSUM: case SKEY_EMULATED_M600: case SKEY_EMULATED_M109_M190: case SKEY_EVENT_LED: @@ -176,7 +179,7 @@ void loadFeatureSettings(LISTITEM * item, uint16_t item_index, uint8_t itemPos) case SKEY_FIL_RUNOUT: { LABEL sensorLabel = itemToggleSmart[GET_BIT(infoSettings.runout, 1)]; - item->valueLabel.index = (GET_BIT(infoSettings.runout, 0)) ? sensorLabel.index : LABEL_OFF ; + item->valueLabel.index = (GET_BIT(infoSettings.runout, 0)) ? sensorLabel.index : LABEL_OFF; break; } #endif @@ -215,6 +218,7 @@ void menuFeatureSettings(void) // set item types LISTITEM settingPage[SKEY_COUNT] = { {CHARICON_TOGGLE_ON, LIST_TOGGLE, LABEL_ADVANCED_OK, LABEL_NULL}, + {CHARICON_TOGGLE_ON, LIST_TOGGLE, LABEL_COMMAND_CHECKSUM, LABEL_NULL}, {CHARICON_TOGGLE_ON, LIST_TOGGLE, LABEL_EMULATED_M600, LABEL_NULL}, {CHARICON_TOGGLE_ON, LIST_TOGGLE, LABEL_EMULATED_M109_M190, LABEL_NULL}, {CHARICON_TOGGLE_ON, LIST_TOGGLE, LABEL_EVENT_LED, LABEL_NULL}, diff --git a/TFT/src/User/Menu/LEDColor.c b/TFT/src/User/Menu/LEDColor.c index 41399cd92a..55bea976f9 100644 --- a/TFT/src/User/Menu/LEDColor.c +++ b/TFT/src/User/Menu/LEDColor.c @@ -2,9 +2,9 @@ #include "includes.h" // value ranges -#define LED_UPDATE_TIME 1000 // 1 seconds is 1000 -#define LED_MIN_VALUE 0 -#define LED_MAX_VALUE 255 +#define LED_REFRESH_TIME 1000 // 1 seconds is 1000 +#define LED_MIN_VALUE 0 +#define LED_MAX_VALUE 255 // key button enumeration typedef enum @@ -444,7 +444,7 @@ void menuLEDColorCustom(void) sendingNeeded = true; } - if ((sendingNeeded && nextScreenUpdate(LED_UPDATE_TIME)) || updateForced) + if ((sendingNeeded && nextScreenUpdate(LED_REFRESH_TIME)) || updateForced) { LED_SendColor(&ledColor); diff --git a/TFT/src/User/Menu/LevelCorner.c b/TFT/src/User/Menu/LevelCorner.c index f3c1f17a89..f0f4071d66 100644 --- a/TFT/src/User/Menu/LevelCorner.c +++ b/TFT/src/User/Menu/LevelCorner.c @@ -11,7 +11,7 @@ int16_t origLevelEdge = -1; uint8_t getLevelEdgeMin(void) { - // min edge limit for the probe with probe offset set in parseACK.c + // min edge limit for the probe with probe offset set in Mainboard_AckHandler.c int16_t maxXedge = getParameter(P_PROBE_OFFSET, AXIS_INDEX_X) + getParameter(P_HOME_OFFSET, AXIS_INDEX_X); int16_t maxYedge = getParameter(P_PROBE_OFFSET, AXIS_INDEX_Y) + getParameter(P_HOME_OFFSET, AXIS_INDEX_Y); diff --git a/TFT/src/User/Menu/MainPage.c b/TFT/src/User/Menu/MainPage.c index d12405c7b5..189d2074eb 100644 --- a/TFT/src/User/Menu/MainPage.c +++ b/TFT/src/User/Menu/MainPage.c @@ -27,9 +27,7 @@ void menuMain(void) KEY_VALUES key_num = KEY_IDLE; if (infoMachineSettings.firmwareType == FW_REPRAPFW) - { mainPageItems.items[5].label.index = LABEL_MACROS; - } if (infoSettings.status_screen != 1) { @@ -72,14 +70,14 @@ void menuMain(void) break; case KEY_ICON_5: - if (infoMachineSettings.firmwareType == FW_REPRAPFW) + if (infoMachineSettings.firmwareType != FW_REPRAPFW) { - strcpy(infoFile.path, "Macros"); - OPEN_MENU(menuCallMacro); + OPEN_MENU(menuCustom); } else { - OPEN_MENU(menuCustom); + strcpy(infoFile.path, "Macros"); + OPEN_MENU(menuCallMacro); } break; diff --git a/TFT/src/User/Menu/Move.c b/TFT/src/User/Menu/Move.c index 31a9055678..1f62ff034f 100644 --- a/TFT/src/User/Menu/Move.c +++ b/TFT/src/User/Menu/Move.c @@ -105,7 +105,7 @@ void menuMove(void) | X-(4) | Y+(5) | X+(6) | back(7) | *-------*-------*-------*---------* |X+ X- |Y+ Y- |Z+ Z- */ - {{6, 4}, {5, 1}, {2, 0}} + {{6, 4}, {5, 1}, {2, 0}}; #else /*-------*-------*-------*---------* | X+(0) | Y+(1) | Z+(2) | unit(3) | @@ -113,9 +113,8 @@ void menuMove(void) | X-(4) | Y-(5) | Z-(6) | back(7) | *-------*-------*-------*---------* |X+ X- |Y+ Y- |Z+ Z- */ - {{0, 4}, {1, 5}, {2, 6}} + {{0, 4}, {1, 5}, {2, 6}}; #endif - ; if (!GET_BIT(infoSettings.inverted_axis, X_AXIS)) LOAD_XYZ_LABEL_INDEX(table[X_AXIS][0], INC, table[X_AXIS][1], DEC, X); // table[0] <--> INC(+) table[1] <--> DEC(+) if not inverted diff --git a/TFT/src/User/Menu/NotificationMenu.c b/TFT/src/User/Menu/NotificationMenu.c index 77f6694873..d1c9549ec6 100644 --- a/TFT/src/User/Menu/NotificationMenu.c +++ b/TFT/src/User/Menu/NotificationMenu.c @@ -72,6 +72,8 @@ void menuNotification(void) case KEY_ICON_0: case KEY_ICON_1: case KEY_ICON_2: + case KEY_ICON_3: + case KEY_ICON_4: replayNotification(key_num); break; diff --git a/TFT/src/User/Menu/Pid.c b/TFT/src/User/Menu/Pid.c index d7ac99394c..902196c096 100644 --- a/TFT/src/User/Menu/Pid.c +++ b/TFT/src/User/Menu/Pid.c @@ -42,7 +42,7 @@ void pidRun(void) if (tool < MAX_HEATER_PID_COUNT) { - mustStoreCmd("%s S%d\n", (infoMachineSettings.firmwareType == FW_REPRAPFW) ? pidCmdRRF[tool] : pidCmdMarlin[tool], (int)pidHeaterTarget[tool]); // start PID autotune + mustStoreCmd("%s S%d\n", (infoMachineSettings.firmwareType != FW_REPRAPFW) ? pidCmdMarlin[tool] : pidCmdRRF[tool], (int)pidHeaterTarget[tool]); // start PID autotune pidStatus = PID_RUNNING; } } @@ -235,7 +235,7 @@ void menuPid(void) if (getMenuType() != MENU_TYPE_SPLASH) popupSplash(DIALOG_TYPE_INFO, LABEL_SCREEN_INFO, LABEL_BUSY); - if (OS_GetTimeMs() > pidTimeout) + if (OS_GetTimeMs() >= pidTimeout) pidUpdateStatus(PID_TIMEOUT); if (pidStatus != PID_RUNNING) diff --git a/TFT/src/User/Menu/SelectMode.c b/TFT/src/User/Menu/SelectMode.c index fa1ec5ee77..32a9d5571a 100644 --- a/TFT/src/User/Menu/SelectMode.c +++ b/TFT/src/User/Menu/SelectMode.c @@ -66,11 +66,13 @@ void menuMode(void) drawSelectedMode(nowMode); #if LCD_ENCODER_SUPPORT - while (!XPT2046_Read_Pen() || LCD_Enc_ReadBtn(LCD_ENC_BUTTON_INTERVAL)) - ; // wait for button release + while (!XPT2046_Read_Pen() || LCD_Enc_ReadBtn(LCD_ENC_BUTTON_INTERVAL)) // wait for button release + { + } #else - while (!XPT2046_Read_Pen()) - ; // wait for touch release + while (!XPT2046_Read_Pen()) // wait for touch release + { + } #endif while (MENU_IS(menuMode)) diff --git a/TFT/src/User/Menu/StatusScreen.c b/TFT/src/User/Menu/StatusScreen.c index a0c0d17436..c96e7f0280 100644 --- a/TFT/src/User/Menu/StatusScreen.c +++ b/TFT/src/User/Menu/StatusScreen.c @@ -12,7 +12,7 @@ #define SET_SPEEDMENUINDEX(x) #endif -#define UPDATE_TOOL_TIME 2000 // 1 seconds is 1000 +#define TOOL_TOGGLE_TIME 2000 // 1 seconds is 1000 #ifdef PORTRAIT_MODE #define XYZ_STATUS "X:%.2f Y:%.2f Z:%.2f" @@ -251,7 +251,7 @@ static inline void statusScrollMsg(void) static inline void statusToggleTool(void) { - if (nextScreenUpdate(UPDATE_TOOL_TIME)) + if (nextScreenUpdate(TOOL_TOGGLE_TIME)) { // increment hotend index if (infoSettings.hotend_count > 1) @@ -275,7 +275,7 @@ static inline void statusToggleTool(void) statusDraw(); // gcode queries must be call after drawStatus - coordinateQuery(MS_TO_SEC(UPDATE_TOOL_TIME)); + coordinateQuery(MS_TO_SEC(TOOL_TOGGLE_TIME)); speedQuery(); ctrlFanQuery(); } diff --git a/TFT/src/User/Menu/common.c b/TFT/src/User/Menu/common.c index babf2c3e8a..66365665e3 100644 --- a/TFT/src/User/Menu/common.c +++ b/TFT/src/User/Menu/common.c @@ -102,20 +102,16 @@ const uint16_t iconToggle[ITEM_TOGGLE_NUM] = // Check time elapsed against the time specified in milliseconds for displaying/updating info on screen // Use this for timed screen updates in menu loops only -bool nextScreenUpdate(uint32_t duration) +bool nextScreenUpdate(uint32_t refreshTime) { static uint32_t lastTime = 0; - uint32_t curTime = OS_GetTimeMs(); - if (curTime > (lastTime + duration)) - { - lastTime = curTime; - return true; - } - else - { + if (OS_GetTimeMs() - lastTime < refreshTime) return false; - } + + lastTime = OS_GetTimeMs(); + + return true; } #ifdef FRIENDLY_Z_OFFSET_LANGUAGE diff --git a/TFT/src/User/Menu/common.h b/TFT/src/User/Menu/common.h index 7f7cac4b61..09bdfb5308 100644 --- a/TFT/src/User/Menu/common.h +++ b/TFT/src/User/Menu/common.h @@ -58,7 +58,7 @@ extern const LABEL itemToggle[ITEM_TOGGLE_NUM]; extern const uint16_t iconToggle[ITEM_TOGGLE_NUM]; // Check if next screen update is due -bool nextScreenUpdate(uint32_t duration); +bool nextScreenUpdate(uint32_t refreshTime); #ifdef FRIENDLY_Z_OFFSET_LANGUAGE void invertZAxisIcons(MENUITEMS * menuItems); diff --git a/TFT/src/User/Variants/pin_GD_TFT35_V3_0.h b/TFT/src/User/Variants/pin_GD_TFT35_V3_0.h index 91f9659dd0..fae81c57c7 100644 --- a/TFT/src/User/Variants/pin_GD_TFT35_V3_0.h +++ b/TFT/src/User/Variants/pin_GD_TFT35_V3_0.h @@ -1,7 +1,7 @@ #ifndef _PIN_GD_TFT35_V3_0_H_ // modify to actual filename !!! #define _PIN_GD_TFT35_V3_0_H_ // modify to actual filename !!! -// MCU type (STM32F10x, STM32F2xx, STM32F4xx) +// MCU type (STM32F10x, STM32F2xx, STM32F4xx, gd32f20x, gd32f30x) #ifndef MCU_TYPE #define MCU_TYPE #include "gd32f20x.h" diff --git a/TFT/src/User/Variants/pin_MKS_TFT32_V1_4.h b/TFT/src/User/Variants/pin_MKS_TFT32_V1_4.h index 980c24ce2e..7cb637f435 100644 --- a/TFT/src/User/Variants/pin_MKS_TFT32_V1_4.h +++ b/TFT/src/User/Variants/pin_MKS_TFT32_V1_4.h @@ -1,7 +1,7 @@ #ifndef _PIN_MKS_TFT32_V1_4_H_ // modify to actual filename !!! #define _PIN_MKS_TFT32_V1_4_H_ // modify to actual filename !!! -// MCU type (STM32F10x, STM32F2xx, STM32F4xx) +// MCU type (STM32F10x, STM32F2xx, STM32F4xx, GD32F20x, GD32F30x) #ifndef MCU_TYPE #define MCU_TYPE #include "stm32f10x.h" diff --git a/TFT/src/User/Variants/pin_MKS_TFT35_V1_0.h b/TFT/src/User/Variants/pin_MKS_TFT35_V1_0.h index bae8e37a02..6076080a5a 100644 --- a/TFT/src/User/Variants/pin_MKS_TFT35_V1_0.h +++ b/TFT/src/User/Variants/pin_MKS_TFT35_V1_0.h @@ -1,8 +1,11 @@ #ifndef _PIN_TFT35_V1_0_H_ // modify to actual filename !!! #define _PIN_TFT35_V1_0_H_ // modify to actual filename !!! -// MCU type (STM32F10x, STM32F2xx, STM32F4xx) -#include "stm32f4xx.h" +// MCU type (STM32F10x, STM32F2xx, STM32F4xx, gd32f20x, gd32f30x) +#ifndef MCU_TYPE + #define MCU_TYPE + #include "stm32f4xx.h" +#endif // Portrait Mode support // Comment the following line in case the TFT variant supports Portrait Mode diff --git a/TFT/src/User/Variants/pin_TFT24_V1_1.h b/TFT/src/User/Variants/pin_TFT24_V1_1.h index 19f26d962f..279f614f0d 100644 --- a/TFT/src/User/Variants/pin_TFT24_V1_1.h +++ b/TFT/src/User/Variants/pin_TFT24_V1_1.h @@ -1,8 +1,11 @@ #ifndef _PIN_TFT24_V1_1_H_ // modify to actual filename !!! #define _PIN_TFT24_V1_1_H_ // modify to actual filename !!! -// MCU type (STM32F10x, STM32F2xx, STM32F4xx) -#include "stm32f10x.h" +// MCU type (STM32F10x, STM32F2xx, STM32F4xx, gd32f20x, gd32f30x) +#ifndef MCU_TYPE + #define MCU_TYPE + #include "stm32f10x.h" +#endif // Portrait Mode support // Comment the following line in case the TFT variant supports Portrait Mode diff --git a/TFT/src/User/Variants/pin_TFT35_V1_0.h b/TFT/src/User/Variants/pin_TFT35_V1_0.h index 96ea757d1a..f678d6ed0e 100644 --- a/TFT/src/User/Variants/pin_TFT35_V1_0.h +++ b/TFT/src/User/Variants/pin_TFT35_V1_0.h @@ -1,8 +1,11 @@ #ifndef _PIN_TFT35_V1_0_H_ // modify to actual filename !!! #define _PIN_TFT35_V1_0_H_ // modify to actual filename !!! -// MCU type (STM32F10x, STM32F2xx, STM32F4xx) -#include "stm32f10x.h" +// MCU type (STM32F10x, STM32F2xx, STM32F4xx, gd32f20x, gd32f30x) +#ifndef MCU_TYPE + #define MCU_TYPE + #include "stm32f10x.h" +#endif // Portrait Mode support // Comment the following line in case the TFT variant supports Portrait Mode diff --git a/TFT/src/User/Variants/pin_TFT35_V2_0.h b/TFT/src/User/Variants/pin_TFT35_V2_0.h index 00d8d69dd2..0f8a668c3e 100644 --- a/TFT/src/User/Variants/pin_TFT35_V2_0.h +++ b/TFT/src/User/Variants/pin_TFT35_V2_0.h @@ -1,8 +1,11 @@ #ifndef _PIN_TFT35_V2_0_H_ // modify to actual filename !!! #define _PIN_TFT35_V2_0_H_ // modify to actual filename !!! -// MCU type (STM32F10x, STM32F2xx, STM32F4xx) -#include "stm32f10x.h" +// MCU type (STM32F10x, STM32F2xx, STM32F4xx, gd32f20x, gd32f30x) +#ifndef MCU_TYPE + #define MCU_TYPE + #include "stm32f10x.h" +#endif // Portrait Mode support // Comment the following line in case the TFT variant supports Portrait Mode diff --git a/TFT/src/User/Variants/pin_TFT35_V3_0.h b/TFT/src/User/Variants/pin_TFT35_V3_0.h index 186f94b962..025a1d2cc0 100644 --- a/TFT/src/User/Variants/pin_TFT35_V3_0.h +++ b/TFT/src/User/Variants/pin_TFT35_V3_0.h @@ -1,7 +1,7 @@ #ifndef _PIN_TFT35_V3_0_H_ // modify to actual filename !!! #define _PIN_TFT35_V3_0_H_ // modify to actual filename !!! -// MCU type (STM32F10x, STM32F2xx, STM32F4xx) +// MCU type (STM32F10x, STM32F2xx, STM32F4xx, gd32f20x, gd32f30x) #ifndef MCU_TYPE #define MCU_TYPE #include "stm32f2xx.h" diff --git a/TFT/src/User/Variants/pin_TFT70_V3_0.h b/TFT/src/User/Variants/pin_TFT70_V3_0.h index 365f6be1ec..c8b2bd4140 100644 --- a/TFT/src/User/Variants/pin_TFT70_V3_0.h +++ b/TFT/src/User/Variants/pin_TFT70_V3_0.h @@ -1,8 +1,11 @@ #ifndef _PIN_TFT70_V3_0_H_ // modify to actual filename !!! #define _PIN_TFT70_V3_0_H_ // modify to actual filename !!! -// MCU type (STM32F10x, STM32F2xx, STM32F4xx) -#include "stm32f4xx.h" +// MCU type (STM32F10x, STM32F2xx, STM32F4xx, gd32f20x, gd32f30x) +#ifndef MCU_TYPE + #define MCU_TYPE + #include "stm32f4xx.h" +#endif // Portrait Mode support // Comment the following line in case the TFT variant supports Portrait Mode diff --git a/TFT/src/User/Variants/pin_Template.h b/TFT/src/User/Variants/pin_Template.h index e11e59f81d..a4f95ed102 100644 --- a/TFT/src/User/Variants/pin_Template.h +++ b/TFT/src/User/Variants/pin_Template.h @@ -1,8 +1,11 @@ #ifndef _PIN_TEMPLATE_H_ // modify to actual filename !!! #define _PIN_TEMPLATE_H_ // modify to actual filename !!! -// MCU type (STM32F10x, STM32F2xx, STM32F4xx) -//#include "stm32fxxx.h" +// MCU type (STM32F10x, STM32F2xx, STM32F4xx, gd32f20x, gd32f30x) +#ifndef MCU_TYPE + #define MCU_TYPE + //#include "stm32fxxx.h" +#endif // Portrait Mode support // Comment the following line in case the TFT variant supports Portrait Mode diff --git a/TFT/src/User/config.ini b/TFT/src/User/config.ini index 3e6c94bd00..02b6ebd4e6 100644 --- a/TFT/src/User/config.ini +++ b/TFT/src/User/config.ini @@ -142,11 +142,47 @@ tx_slots:2 # support the transmission of G-codes according to the configured "tx_slots" setting. # If disabled, the TFT will provide the standard transmission logic based on one G-code per time. # -# NOTE: Disable it in case no ADVANCED_OK feature is requested/needed by the user. +# NOTE: Disable it in case: +# - no ADVANCED_OK feature is requested/needed by the user. +# - ADVANCED_OK feature is not providing good printing results or if the mainboard notifies +# frequent error ACK messages (e.g. unknown command) to the TFT during printing. +# - COMMAND_CHECKSUM feature (see description of next setting "command_checksum") is +# requested/needed by the user. # # Options: [disable: 0, enable: 1] advanced_ok:0 +#### Command Checksum +# The TFT enriches each G-code to be sent to the mainboard adding a leading sequential line number +# and a trailing checksum appended after an "*" character used as separator. +# The checksum is based on algorithm "CheckSum8 Xor" and it is calculated on the G-code with the +# applied line number. E.g. "G28" is firstly enriched with a line number (e.g. "N1 G28") and finally +# a checksum calculated on that enriched G-code is appended (e.g. "N1 G28*18"). +# A data integrity check (sequential line number check and checksum check) will be performed on the +# mainboard. In case of data mismatch (e.g. data corruption due to EMI on communication serial line): +# - the mainboard will send to the TFT an error ACK message followed by a "Resend: " ACK message to +# ask TFT to resend the G-code with the requested line number. +# - the TFT will check the presence on an internal buffer of the G-code with the requested line number: +# - if found, the G-code is resent for a maximum of 3 attempts. +# - if not found or the maximum number of attempts has been reached, the TFT will reset the line +# number with an "M110" G-code (immediately sent bypassing any other enqueued G-code) to the +# requested line number just to try to avoid further retransmission requests for the same line +# number or for any out of synch command already sent to the mainboard (e.g. in case ADVANCED_OK +# feature is enabled in TFT). +# +# NOTE: Disable it in case: +# - printing is controlled by a remote host (e.g. ESP3D, OctoPrint etc.) and a COMMAND_CHECKSUM +# feature is enabled and managed by the remote host. Otherwise (COMMAND_CHECKSUM feature also +# enabled in TFT), the TFT's COMMAND_CHECKSUM feature will always replace the one provided by +# the remote host causing conflicts in case data mismatch will be notified by the mainboard. +# - ADVANCED_OK feature is enabled in TFT. Otherwise, any out of synch command already sent to +# the mainboard will be discarded by the mainboard and not resent by the TFT due the current +# implementation of COMMAND_CHECKSUM feature on the TFT buffers only the last sent command +# and not all the pending commands. +# +# Options: [disable: 0, enable: 1] +command_checksum:1 + #### Emulated M600 # The TFT intercepts the M600 G-code (filament change) and emulates the handling logic # otherwise provided by Marlin firmware. @@ -275,7 +311,7 @@ terminal_color_scheme:0 # Options: [OFF: 0, POPUP: 1, TOAST: 2] # OFF: No notification. The message is ignored. # POPUP: Display a popup window for user confirmation. -# TOAST: A non-blocking Toast notification is displayed for few seconds. No user interaction is needed. +# TOAST: A non-blocking toast notification is displayed for few seconds. No user interaction is needed. ack_notification:1 #### Files Sorting @@ -763,6 +799,10 @@ ps_auto_shutdown_temp:50 #### Filament Runout Sensor # Select the type of filament runout sensor and its default enabled/disabled state. +# +# NOTE: Smart Filament Sensor (SFS) (value 2 or 3) is a sensor based on an encoder disc that +# toggles runout pin as filament moves (e.g. the BigTreeTech SFS). +# # Options: [Normal Disabled: 0, Normal Enabled: 1, Smart Disabled: 2, Smart Enabled: 3] fil_runout:0 @@ -787,6 +827,10 @@ fil_runout_noise_threshold:100 #### Smart Filament Runout Detection # Used in conjunction with an SFS (Smart Filament Sensor) based on an encoder disc that # toggles runout pin as filament moves. +# +# NOTE: This setting is taken into account by the TFT only in case "fil_runout" setting is +# set to 2 or 3 (an SFS is used). +# # Unit: [distance in mm] # Value range: [min: 1, max: 50] fil_runout_distance:7 diff --git a/TFT/src/User/config_rrf.ini b/TFT/src/User/config_rrf.ini index f51b3f96b2..8fe12cfe07 100644 --- a/TFT/src/User/config_rrf.ini +++ b/TFT/src/User/config_rrf.ini @@ -105,11 +105,47 @@ tx_slots:2 # support the transmission of G-codes according to the configured "tx_slots" setting. # If disabled, the TFT will provide the standard transmission logic based on one G-code per time. # -# NOTE: Disable it in case no ADVANCED_OK feature is requested/needed by the user. +# NOTE: Disable it in case: +# - no ADVANCED_OK feature is requested/needed by the user. +# - ADVANCED_OK feature is not providing good printing results or if the mainboard notifies +# frequent error ACK messages (e.g. unknown command) to the TFT during printing. +# - COMMAND_CHECKSUM feature (see description of next setting "command_checksum") is +# requested/needed by the user. # # Options: [disable: 0, enable: 1] advanced_ok:0 +#### Command Checksum +# The TFT enriches each G-code to be sent to the mainboard adding a leading sequential line number +# and a trailing checksum appended after an "*" character used as separator. +# The checksum is based on algorithm "CheckSum8 Xor" and it is calculated on the G-code with the +# applied line number. E.g. "G28" is firstly enriched with a line number (e.g. "N1 G28") and finally +# a checksum calculated on that enriched G-code is appended (e.g. "N1 G28*18"). +# A data integrity check (sequential line number check and checksum check) will be performed on the +# mainboard. In case of data mismatch (e.g. data corruption due to EMI on communication serial line): +# - the mainboard will send to the TFT an error ACK message followed by a "Resend: " ACK message to +# ask TFT to resend the G-code with the requested line number. +# - the TFT will check the presence on an internal buffer of the G-code with the requested line number: +# - if found, the G-code is resent for a maximum of 3 attempts. +# - if not found or the maximum number of attempts has been reached, the TFT will reset the line +# number with an "M110" G-code (immediately sent bypassing any other enqueued G-code) to the +# requested line number just to try to avoid further retransmission requests for the same line +# number or for any out of synch command already sent to the mainboard (e.g. in case ADVANCED_OK +# feature is enabled in TFT). +# +# NOTE: Disable it in case: +# - printing is controlled by a remote host (e.g. ESP3D, OctoPrint etc.) and a COMMAND_CHECKSUM +# feature is enabled and managed by the remote host. Otherwise (COMMAND_CHECKSUM feature also +# enabled in TFT), the TFT's COMMAND_CHECKSUM feature will always replace the one provided by +# the remote host causing conflicts in case data mismatch will be notified by the mainboard. +# - ADVANCED_OK feature is enabled in TFT. Otherwise, any out of synch command already sent to +# the mainboard will be discarded by the mainboard and not resent by the TFT due the current +# implementation of COMMAND_CHECKSUM feature on the TFT buffers only the last sent command +# and not all the pending commands. +# +# Options: [disable: 0, enable: 1] +command_checksum:1 + #### Emulated M600 # The TFT intercepts the M600 G-code (filament change) and emulates the handling logic # otherwise provided by Marlin firmware. @@ -238,7 +274,7 @@ terminal_color_scheme:0 # Options: [OFF: 0, POPUP: 1, TOAST: 2] # OFF: No notification. The message is ignored. # POPUP: Display a popup window for user confirmation. -# TOAST: A non-blocking Toast notification is displayed for few seconds. No user interaction is needed. +# TOAST: A non-blocking toast notification is displayed for few seconds. No user interaction is needed. ack_notification:1 #### Files Sorting diff --git a/TFT/src/User/includes.h b/TFT/src/User/includes.h index 64852508b2..36f33b407e 100644 --- a/TFT/src/User/includes.h +++ b/TFT/src/User/includes.h @@ -79,22 +79,23 @@ #include "FlashStore.h" #include "HomeOffsetControl.h" #include "HW_Init.h" -#include "interfaceCmd.h" #include "LCD_Colors.h" #include "LCD_Dimming.h" #include "LED_Colors.h" #include "LED_Event.h" #include "LevelingControl.h" #include "MachineParameters.h" +#include "Mainboard_AckHandler.h" +#include "Mainboard_CmdControl.h" +#include "Mainboard_CmdHandler.h" +#include "Mainboard_FlowControl.h" #include "menu.h" #include "ModeSwitching.h" #include "Notification.h" -#include "parseACK.h" #include "PowerFailed.h" #include "Printing.h" #include "ProbeHeightControl.h" #include "ProbeOffsetControl.h" -#include "RRFStatusControl.h" #include "ScreenShot.h" #include "SerialConnection.h" #include "Settings.h" diff --git a/TFT/src/User/main.c b/TFT/src/User/main.c index c7778b415e..1e397debb7 100644 --- a/TFT/src/User/main.c +++ b/TFT/src/User/main.c @@ -1,93 +1,6 @@ #include "main.h" #include "includes.h" -MENU infoMenu; -HOST infoHost; -CLOCKS mcuClocks; -PRIORITY_COUNTER priorityCounter; - -void InfoHost_Init(bool isConnected) -{ - infoHost.target_tx_slots = infoSettings.tx_slots; - infoHost.tx_slots = 1; // set to 1 just to allow a soft start - infoHost.tx_count = 0; - infoHost.connected = isConnected; - infoHost.listening_mode = false; // temporary disable listening mode. It will be later set by InfoHost_UpdateListeningMode() - infoHost.status = HOST_STATUS_IDLE; - - if (!isConnected) - setReminderMsg(LABEL_UNCONNECTED, SYS_STATUS_DISCONNECTED); // set the no printer attached reminder -} - -void InfoHost_UpdateListeningMode(void) -{ - infoHost.listening_mode = (GET_BIT(infoSettings.general_settings, INDEX_LISTENING_MODE) == 1); - - if (infoHost.listening_mode) - setReminderMsg(LABEL_LISTENING, SYS_STATUS_LISTENING); // if TFT in listening mode, display a reminder message -} - -void InfoHost_HandleOkAck(int16_t target_tx_slots) -{ - // the following check should always be matched unless: - // - an ACK message not related to a gcode originated by the TFT is received - // - an ACK message for an out of band gcode (e.g. emergency gcode) is received - // - if (infoHost.tx_count > 0) - infoHost.tx_count--; - - // NOTE: the following code always allows to align infoHost.tx_slots even in case of switching ON/OFF - // the ADVANCED_OK feature in TFT and/or in case infoHost.tx_slots is beeing also managed by - // Marlin (if ADVANCED_OK is enabled in Marlin firmware) - // - - // if ADVANCED_OK is disabled in TFT - // - if (GET_BIT(infoSettings.general_settings, INDEX_ADVANCED_OK) == 0) - { - infoHost.tx_slots = 1; - } - // - // if ADVANCED_OK is enabled in TFT or Marlin - // - else if (target_tx_slots >= 0) - { - // UPPER LIMITER - // - // the following check is matched in case: - // - ADVANCED_OK is enabled in TFT. infoSettings.tx_slots for static ADVANCED_OK configured in TFT is used - // - ADVANCED_OK is enabled in Marlin but the mainboard reply (target_tx_slots) is out of sync (above) with the current - // pending gcodes (it happens sometimes). infoSettings.tx_slots for Marlin ADVANCED_OK detected at TFT boot is used - // - if (target_tx_slots + infoHost.tx_count >= infoSettings.tx_slots) - infoHost.tx_slots = infoSettings.tx_slots - infoHost.tx_count; - // - // LOWER LIMITER (only for Marlin ADVANCED_OK) - // - // if printing from onboard media target_tx_slots is always reported as 0 by Marlin even if there are no pending gcodes - // so just set infoHost.tx_slots to 1 to allow the transmission of one gcode per time avoiding a possible TFT freeze - // - else if (target_tx_slots != 0 || infoHost.tx_count != 0) // if not printing from onboard media - infoHost.tx_slots = target_tx_slots; - else // if printing from onboard media - infoHost.tx_slots = 1; - - infoHost.target_tx_slots = infoHost.tx_slots; // set new current target - } - // - // if generic OK response handling (e.g. temperature response), increment the current value up to current target - // - else - { - // UPPER AND LOWER LIMITER - // - // limit the current value up to current target or to 1 if current target was set to 0 and there are no more pending gcodes - // - if (infoHost.tx_slots < infoHost.target_tx_slots || (infoHost.tx_slots == 0 && infoHost.tx_count == 0)) - infoHost.tx_slots++; - } -} - int main(void) { #if defined GD32F3XX @@ -95,7 +8,7 @@ int main(void) __enable_irq(); #endif - SystemClockInit(); + SystemClockInit(); // it depends on "variants.h" included in "includes.h" SCB->VTOR = VECT_TAB_FLASH; diff --git a/TFT/src/User/main.h b/TFT/src/User/main.h index 0a2f831d58..391cea7165 100644 --- a/TFT/src/User/main.h +++ b/TFT/src/User/main.h @@ -5,73 +5,7 @@ extern "C" { #endif -#include -#include -#include "variants.h" // for RCC_ClocksTypeDef -#include "uart.h" // for _UART_CNT - -#define MAX_MENU_DEPTH 10 // max sub menu depth -#define BE_PRIORITY_DIVIDER 16 // a divider value of 16 -> run 6% of the time only. Use a power of 2 for performance reasons! -#define FE_PRIORITY_DIVIDER 16 // a divider value of 16 -> run 6% of the time only. Use a power of 2 for performance reasons! - -typedef void (* FP_MENU)(void); - -typedef struct -{ - FP_MENU menu[MAX_MENU_DEPTH]; // menu function buffer - uint8_t cur; // current menu index in buffer -} MENU; - -typedef enum -{ - HOST_STATUS_IDLE = 0, - HOST_STATUS_PRINTING, - HOST_STATUS_RESUMING, - HOST_STATUS_PAUSED, - HOST_STATUS_PAUSING -} HOST_STATUS; - -typedef enum -{ - HOST_SLOTS_GENERIC_OK = -1, -} HOST_SLOTS; - -typedef struct -{ - uint8_t target_tx_slots; // keep track of target gcode tx slots (e.g. if ADVANCED_OK feature is enabled on both mainboard and TFT) - uint8_t tx_slots; // keep track of available gcode tx slots (e.g. if ADVANCED_OK feature is enabled on both mainboard and TFT) - uint8_t tx_count; // keep track of pending gcode tx count - bool connected; // TFT is connected to Marlin - bool listening_mode; // TFT is in listening mode from Marlin - HOST_STATUS status; // host is busy in printing execution. (USB serial printing and gcode print from onboard) -} HOST; - -typedef struct -{ - RCC_ClocksTypeDef rccClocks; - uint32_t PCLK1_Timer_Frequency; - uint32_t PCLK2_Timer_Frequency; -} CLOCKS; - -typedef struct -{ - uint32_t be; // back end - uint32_t fe; // front end -} PRIORITY_COUNTER; - -extern MENU infoMenu; // menu structure -extern HOST infoHost; // information interaction with Marlin -extern CLOCKS mcuClocks; // system clocks: SYSCLK, AHB, APB1, APB2, APB1_Timer, APB2_Timer2 -extern PRIORITY_COUNTER priorityCounter; // priority counter - -void InfoHost_Init(bool isConnected); -void InfoHost_UpdateListeningMode(void); - -// handle OK response: -// - tx_slots (used/effective only in case "advanced_ok" configuration setting is also enabled in TFT): -// - < 0 (HOST_SLOTS_GENERIC_OK): to increase infoHost.tx_slots up to current target and decrease infoHost.tx_count by 1 -// - >= 0: to handle static ADVANCED_OK and Marlin ADVANCED_OK -void InfoHost_HandleOkAck(int16_t tx_slots); +int main(void); #ifdef __cplusplus } diff --git a/TFT/src/User/my_misc.c b/TFT/src/User/my_misc.c index 3aa686c38e..0aa7d580e1 100644 --- a/TFT/src/User/my_misc.c +++ b/TFT/src/User/my_misc.c @@ -24,21 +24,20 @@ uint32_t calculateCRC16(const uint8_t *data, uint32_t length) { uint16_t crc = 0xFFFF; uint32_t i; + for (i = 0; i < length; i++) { crc = (crc ^ data[i]) & 0xFFFF; + for (uint8_t j = 0; j < 8; j++) { if (crc & 1) - { crc = (crc >> 1) ^ CRC_POLY; - } else - { crc = crc >> 1; - } } } + return crc; } @@ -213,115 +212,3 @@ void strncpy_no_pad(char *dest, const char *src, size_t n) if (n != 0) // safe in case value 0 was passed for "n" *dest = '\0'; } - -// strip out any leading " ", "/" or ":" character that might be in the string -const char *stripHead(const char *str) -{ - // example: ": /test/cap2.gcode\n" -> "test/cap2.gcode\n" - - while (*str == ' ' || *str == '/' || *str == ':') - { - str++; - } - - return str; -} - -// strip out any trailing checksum that might be in the string -void stripChecksum(char *str) -{ - // examples: - // - // "/test/cap2.gcode *36\n\0" -> "/test/cap2.gcode" - // "/test/cap2.gcode \n\0" -> "/test/cap2.gcode" - - char *strPtr = strrchr(str, '*'); // e.g. "/test/cap2.gcode *36\n\0" -> "*36\n\0" - - if (strPtr == NULL) - strPtr = str + strlen(str); // e.g. "/test/cap2.gcode \n\0" -> "\0" - - while (strPtr != str) - { - // e.g. "*36\n\0" -> " *36\n\0" - // e.g. "\0" -> "\n\0" - // - --strPtr; - - if (*strPtr != ' ' && *strPtr != '\t' && *strPtr != '\n' && *strPtr != '\r') - { - strPtr++; // next char has to be set to "\0" - break; - } - } - - // e.g. " *36\n\0" -> "\0 *36\n\0" - // e.g. " \n\0" -> "\0 \n\0" - // - *strPtr = '\0'; -} - -uint8_t getChecksum(char *str) -{ - uint8_t checksum = 0; - - while (*str != '\0') - { - checksum ^= *(str++); - } - - return checksum; -} - -bool validateChecksum(char *str) -{ - char *strPtr = strrchr(str, '*'); // e.g. "N1 G28*18\n\0" -> "*18\n\0" - - if (strPtr == NULL) - return false; - - uint8_t checksum = 0; - uint8_t value = strtol(&strPtr[1], NULL, 10); - - while (strPtr != str) - { - checksum ^= *(--strPtr); - } - - return (checksum == value ? true : false); -} - -const char *parseM118(char *str, bool *hasE, bool *hasA) -{ - stripChecksum(str); - str = (char *) stripHead(str); - - *hasE = false; - *hasA = false; - - for (uint8_t i = 3; i--;) - { - // A1, E1 and Pn are always parsed out - if (!(((str[0] == 'A' || str[0] == 'E') && str[1] == '1') || (str[0] == 'P' && NUMERIC(str[1])))) - break; - - switch (str[0]) - { - case 'A': - *hasA = true; - break; - - case 'E': - *hasE = true; - break; - } - - str += 2; - - while (*str == ' ') - { - ++str; - } - } - - return str; -} diff --git a/TFT/src/User/my_misc.h b/TFT/src/User/my_misc.h index 2ce0a59e49..f60d5cdfff 100644 --- a/TFT/src/User/my_misc.h +++ b/TFT/src/User/my_misc.h @@ -9,13 +9,6 @@ extern "C" { #include #include // for size_t -// Menu Macros -#define OPEN_MENU(x) infoMenu.menu[++infoMenu.cur] = x -#define REPLACE_MENU(x) infoMenu.menu[infoMenu.cur] = x -#define CLOSE_MENU() infoMenu.cur-- -#define MENU_IS(x) infoMenu.menu[infoMenu.cur] == x -#define MENU_IS_NOT(x) infoMenu.menu[infoMenu.cur] != x - // Macros to make a string from a macro #define STRINGIFY_(M) #M #define STRINGIFY(M) STRINGIFY_(M) @@ -91,13 +84,6 @@ double strtod_ligth(char *str, char **endptr); // light weight str void strncpy_pad(char *dest, const char *src, size_t n); // light weight and safe strncpy() function with padding void strncpy_no_pad(char *dest, const char *src, size_t n); // light weight and safe strncpy() function without padding -const char *stripHead(const char *str); // strip out any leading " ", "/" or ":" character that might be in the string -void stripChecksum(char *str); // strip out any trailing checksum that might be in the string -uint8_t getChecksum(char *str); -bool validateChecksum(char *str); - -const char *parseM118(char *str, bool *hasE, bool *hasA); - #ifdef __cplusplus } #endif diff --git a/TFT/src/User/os_timer.c b/TFT/src/User/os_timer.c index d3aaa1f28b..6a60b4125b 100644 --- a/TFT/src/User/os_timer.c +++ b/TFT/src/User/os_timer.c @@ -1,13 +1,7 @@ #include "os_timer.h" #include "includes.h" -typedef struct -{ - uint32_t ms; // milliseconds - uint16_t sec; // seconds -} OS_COUNTER; - -volatile static OS_COUNTER os_counter = {0, 0}; +OS_COUNTER os_counter = {0, 0}; void OS_InitTimerMs(void) { @@ -84,12 +78,6 @@ void TIM7_IRQHandler(void) } #endif -// 1 ms -uint32_t OS_GetTimeMs(void) -{ - return os_counter.ms; -} - // task: task structure to be filled // time_ms: // diff --git a/TFT/src/User/os_timer.h b/TFT/src/User/os_timer.h index 570c994fc6..e1bd01d9c6 100644 --- a/TFT/src/User/os_timer.h +++ b/TFT/src/User/os_timer.h @@ -7,6 +7,13 @@ extern "C" { #include +// NOTE: not needed to define "ms" attribute as "volatile" +typedef struct +{ + uint32_t ms; // milliseconds + uint16_t sec; // seconds +} OS_COUNTER; + typedef void (*FP_TASK)(void *); typedef struct @@ -19,8 +26,14 @@ typedef struct uint8_t is_repeat; } OS_TASK; +extern OS_COUNTER os_counter; + void OS_InitTimerMs(void); -uint32_t OS_GetTimeMs(void); + +static inline uint32_t OS_GetTimeMs(void) +{ + return os_counter.ms; +} void OS_TaskInit(OS_TASK *task, uint32_t time_ms, FP_TASK function, void *para); void OS_TaskLoop(OS_TASK *task); diff --git a/platformio.ini b/platformio.ini index 10627f8b82..6a1820306e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -186,6 +186,12 @@ platform_packages = framework-spl-gd32@https://github.com/bigtreetech/gd32-pio-s framework = spl upload_protocol = cmsis-dap + + +# +# BIGTREE-TECH STM32 Series +# + # # BIGTREE TFT24 V1.1 # @@ -390,7 +396,10 @@ build_flags = ${stm32f4xx.build_flags} ${base64_png.build_flags} -# GD32 Series +# +# BIGTREE-TECH GD32 Series +# + # # BIGTREE TFT24 V1.1 # @@ -522,7 +531,9 @@ build_flags = ${stm32f4xx.build_flags} ${base64_png.build_flags} # -# MKS Series, Maintained by open source contributors +# MKS STM32 Series. Maintained by open source contributors +# + # # MKS TFT28 V3.0 #