diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 56060f0a4801..e0ee13af0778 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,7 +1,7 @@ name: 🪲 Report a bug description: Create a bug report to help improve Marlin Firmware title: "[BUG] (bug summary)" -labels: 'Bug: Potential ?' +labels: ["Bug: Potential ?"] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index b64383cd48b2..2e8607142ca8 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,7 +1,7 @@ name: ✨ Request a feature description: Request a new Marlin Firmware feature title: "[FR] (feature summary)" -labels: 'T: Feature Request' +labels: ["T: Feature Request"] body: - type: markdown attributes: diff --git a/.github/workflows/auto-label.yml b/.github/workflows/auto-label.yml index f3a752da3d45..c69e6c4fade9 100644 --- a/.github/workflows/auto-label.yml +++ b/.github/workflows/auto-label.yml @@ -4,6 +4,8 @@ # - Apply the label "Bug: Potential ?" to these issues. # +name: Label Old Bugs + on: schedule: - cron: "30 8 * * *" @@ -15,24 +17,21 @@ jobs: runs-on: ubuntu-latest steps: - name: Auto Label for [BUG] - uses: actions/github-script@v5 + uses: actions/github-script@v7 with: script: | - # Get all open issues in this repository + // Get all open issues in this repository const issueList = await github.rest.issues.listForRepo({ owner: context.repo.owner, repo: context.repo.repo, state: 'open' }); - # Filter the list of issues to only those that don't have any labels - # and have a title that contains '[BUG]'. Only the first 50 issues. + // Filter issues without labels that have a title containing '[BUG]'. const matchingIssues = issueList.data.filter( issue => issue.title.includes('[BUG]') && issue.labels.length === 0 ); - # Process the first 50 + // Process the first 50 for (const issue of matchingIssues.slice(0, 50)) { - // Run the desired action on the issue - // For example, to add a label: await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index abb0d44706d3..2b15067f5156 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -12,7 +12,6 @@ on: - 1.0.x - 1.1.x - 2.0.x - - 2.1.x jobs: bad_target: diff --git a/.github/workflows/test-builds.yml b/.github/workflows/test-builds.yml index 057fa8b75f19..7c62b5af6c54 100644 --- a/.github/workflows/test-builds.yml +++ b/.github/workflows/test-builds.yml @@ -9,6 +9,7 @@ on: pull_request: branches: - bugfix-2.1.x + - 2.1.x paths-ignore: - config/** - data/** @@ -17,6 +18,7 @@ on: push: branches: - bugfix-2.1.x + - 2.1.x paths-ignore: - config/** - data/** diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index b72f7d8da11b..5871c99a215f 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1579,6 +1579,10 @@ //#define SOUND_MENU_ITEM // Add a mute option to the LCD menu #define SOUND_ON_DEFAULT // Buzzer/speaker default enabled state + #if HAS_WIRED_LCD + //#define DOUBLE_LCD_FRAMERATE // Not recommended for slow boards. + #endif + // The timeout to return to the status screen from sub-menus //#define LCD_TIMEOUT_TO_STATUS 15000 // (ms) diff --git a/Marlin/Version.h b/Marlin/Version.h index 07815b01d6fe..4b493f35ab72 100644 --- a/Marlin/Version.h +++ b/Marlin/Version.h @@ -41,7 +41,7 @@ * here we define this default string as the date where the latest release * version was tagged. */ -//#define STRING_DISTRIBUTION_DATE "2023-11-30" +//#define STRING_DISTRIBUTION_DATE "2023-12-09" /** * Defines a generic printer name to be output to the LCD after booting Marlin. diff --git a/Marlin/src/HAL/ESP32/HAL.cpp b/Marlin/src/HAL/ESP32/HAL.cpp index 27f6516f9ae8..4890972b0193 100644 --- a/Marlin/src/HAL/ESP32/HAL.cpp +++ b/Marlin/src/HAL/ESP32/HAL.cpp @@ -175,7 +175,7 @@ uint8_t MarlinHAL::get_reset_source() { return rtc_get_reset_reason(1); } void MarlinHAL::reboot() { ESP.restart(); } -void _delay_ms(int delay_ms) { delay(delay_ms); } +void _delay_ms(const int ms) { delay(ms); } // return free memory between end of heap (or end bss) and whatever is current int MarlinHAL::freeMemory() { return ESP.getFreeHeap(); } diff --git a/Marlin/src/HAL/LINUX/include/Arduino.h b/Marlin/src/HAL/LINUX/include/Arduino.h index f05aaed88083..6e9c80ee07dc 100644 --- a/Marlin/src/HAL/LINUX/include/Arduino.h +++ b/Marlin/src/HAL/LINUX/include/Arduino.h @@ -28,6 +28,9 @@ #include +#define strlcpy(A, B, C) strncpy(A, B, (C) - 1) +#define strlcpy_P(A, B, C) strncpy_P(A, B, (C) - 1) + #define HIGH 0x01 #define LOW 0x00 diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp index 6c00a4cae0b2..a737266c6811 100644 --- a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp +++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp @@ -78,7 +78,7 @@ bool XPT2046::getRawPoint(int16_t * const x, int16_t * const y) { if (isBusy() || !isTouched()) return false; *x = getRawData(XPT2046_X); *y = getRawData(XPT2046_Y); - return true; + return isTouched(); } uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { diff --git a/Marlin/src/HAL/SAMD51/HAL.cpp b/Marlin/src/HAL/SAMD51/HAL.cpp index beace8126cbf..a3c871ce516a 100644 --- a/Marlin/src/HAL/SAMD51/HAL.cpp +++ b/Marlin/src/HAL/SAMD51/HAL.cpp @@ -47,27 +47,27 @@ #endif #endif -#define GET_TEMP_0_ADC() TERN(HAS_TEMP_ADC_0, PIN_TO_ADC(TEMP_0_PIN), -1) -#define GET_TEMP_1_ADC() TERN(HAS_TEMP_ADC_1, PIN_TO_ADC(TEMP_1_PIN), -1) -#define GET_TEMP_2_ADC() TERN(HAS_TEMP_ADC_2, PIN_TO_ADC(TEMP_2_PIN), -1) -#define GET_TEMP_3_ADC() TERN(HAS_TEMP_ADC_3, PIN_TO_ADC(TEMP_3_PIN), -1) -#define GET_TEMP_4_ADC() TERN(HAS_TEMP_ADC_4, PIN_TO_ADC(TEMP_4_PIN), -1) -#define GET_TEMP_5_ADC() TERN(HAS_TEMP_ADC_5, PIN_TO_ADC(TEMP_5_PIN), -1) -#define GET_TEMP_6_ADC() TERN(HAS_TEMP_ADC_6, PIN_TO_ADC(TEMP_6_PIN), -1) -#define GET_TEMP_7_ADC() TERN(HAS_TEMP_ADC_7, PIN_TO_ADC(TEMP_7_PIN), -1) -#define GET_BED_ADC() TERN(HAS_TEMP_ADC_BED, PIN_TO_ADC(TEMP_BED_PIN), -1) -#define GET_CHAMBER_ADC() TERN(HAS_TEMP_ADC_CHAMBER, PIN_TO_ADC(TEMP_CHAMBER_PIN), -1) -#define GET_PROBE_ADC() TERN(HAS_TEMP_ADC_PROBE, PIN_TO_ADC(TEMP_PROBE_PIN), -1) -#define GET_COOLER_ADC() TERN(HAS_TEMP_ADC_COOLER, PIN_TO_ADC(TEMP_COOLER_PIN), -1) -#define GET_BOARD_ADC() TERN(HAS_TEMP_ADC_BOARD, PIN_TO_ADC(TEMP_BOARD_PIN), -1) -#define GET_SOC_ADC() TERN(HAS_TEMP_ADC_SOC, PIN_TO_ADC(TEMP_SOC_PIN), -1) -#define GET_FILAMENT_WIDTH_ADC() TERN(FILAMENT_WIDTH_SENSOR, PIN_TO_ADC(FILWIDTH_PIN), -1) -#define GET_BUTTONS_ADC() TERN(HAS_ADC_BUTTONS, PIN_TO_ADC(ADC_KEYPAD_PIN), -1) -#define GET_JOY_ADC_X() TERN(HAS_JOY_ADC_X, PIN_TO_ADC(JOY_X_PIN), -1) -#define GET_JOY_ADC_Y() TERN(HAS_JOY_ADC_Y, PIN_TO_ADC(JOY_Y_PIN), -1) -#define GET_JOY_ADC_Z() TERN(HAS_JOY_ADC_Z, PIN_TO_ADC(JOY_Z_PIN), -1) -#define GET_POWERMON_ADC_CURRENT() TERN(POWER_MONITOR_CURRENT, PIN_TO_ADC(POWER_MONITOR_CURRENT_PIN), -1) -#define GET_POWERMON_ADC_VOLTS() TERN(POWER_MONITOR_VOLTAGE, PIN_TO_ADC(POWER_MONITOR_VOLTAGE_PIN), -1) +#define GET_TEMP_0_ADC() TERN(HAS_TEMP_ADC_0, PIN_TO_ADC(TEMP_0_PIN), -1) +#define GET_TEMP_1_ADC() TERN(HAS_TEMP_ADC_1, PIN_TO_ADC(TEMP_1_PIN), -1) +#define GET_TEMP_2_ADC() TERN(HAS_TEMP_ADC_2, PIN_TO_ADC(TEMP_2_PIN), -1) +#define GET_TEMP_3_ADC() TERN(HAS_TEMP_ADC_3, PIN_TO_ADC(TEMP_3_PIN), -1) +#define GET_TEMP_4_ADC() TERN(HAS_TEMP_ADC_4, PIN_TO_ADC(TEMP_4_PIN), -1) +#define GET_TEMP_5_ADC() TERN(HAS_TEMP_ADC_5, PIN_TO_ADC(TEMP_5_PIN), -1) +#define GET_TEMP_6_ADC() TERN(HAS_TEMP_ADC_6, PIN_TO_ADC(TEMP_6_PIN), -1) +#define GET_TEMP_7_ADC() TERN(HAS_TEMP_ADC_7, PIN_TO_ADC(TEMP_7_PIN), -1) +#define GET_BED_ADC() TERN(HAS_TEMP_ADC_BED, PIN_TO_ADC(TEMP_BED_PIN), -1) +#define GET_CHAMBER_ADC() TERN(HAS_TEMP_ADC_CHAMBER, PIN_TO_ADC(TEMP_CHAMBER_PIN), -1) +#define GET_PROBE_ADC() TERN(HAS_TEMP_ADC_PROBE, PIN_TO_ADC(TEMP_PROBE_PIN), -1) +#define GET_COOLER_ADC() TERN(HAS_TEMP_ADC_COOLER, PIN_TO_ADC(TEMP_COOLER_PIN), -1) +#define GET_BOARD_ADC() TERN(HAS_TEMP_ADC_BOARD, PIN_TO_ADC(TEMP_BOARD_PIN), -1) +#define GET_SOC_ADC() TERN(HAS_TEMP_ADC_BOARD, PIN_TO_ADC(TEMP_BOARD_PIN), -1) +#define GET_FILAMENT_WIDTH_ADC() TERN(FILAMENT_WIDTH_SENSOR, PIN_TO_ADC(FILWIDTH_PIN), -1) +#define GET_BUTTONS_ADC() TERN(HAS_ADC_BUTTONS, PIN_TO_ADC(ADC_KEYPAD_PIN), -1) +#define GET_JOY_ADC_X() TERN(HAS_JOY_ADC_X, PIN_TO_ADC(JOY_X_PIN), -1) +#define GET_JOY_ADC_Y() TERN(HAS_JOY_ADC_Y, PIN_TO_ADC(JOY_Y_PIN), -1) +#define GET_JOY_ADC_Z() TERN(HAS_JOY_ADC_Z, PIN_TO_ADC(JOY_Z_PIN), -1) +#define GET_POWERMON_ADC_CURRENT() TERN(POWER_MONITOR_CURRENT, PIN_TO_ADC(POWER_MONITOR_CURRENT_PIN), -1) +#define GET_POWERMON_ADC_VOLTS() TERN(POWER_MONITOR_VOLTAGE, PIN_TO_ADC(POWER_MONITOR_VOLTAGE_PIN), -1) #define IS_ADC_REQUIRED(n) ( \ GET_TEMP_0_ADC() == n || GET_TEMP_1_ADC() == n || GET_TEMP_2_ADC() == n || GET_TEMP_3_ADC() == n \ @@ -162,10 +162,10 @@ enum ADCIndex { POWERMON_CURRENT, #endif #if GET_POWERMON_ADC_VOLTS() == 0 - POWERMON_VOLTS, + POWERMON_VOLTAGE, #endif - // Use later indexes for ADC index 1 + // Indexes for ADC1 after those for ADC0 #if GET_TEMP_0_ADC() == 1 TEMP_0, @@ -228,9 +228,8 @@ enum ADCIndex { POWERMON_CURRENT, #endif #if GET_POWERMON_ADC_VOLTS() == 1 - POWERMON_VOLTS, + POWERMON_VOLTAGE, #endif - ADC_COUNT }; @@ -351,10 +350,10 @@ enum ADCIndex { POWER_MONITOR_CURRENT_PIN, #endif #if GET_POWERMON_ADC_VOLTS() == 0 - POWER_MONITOR_VOLTS_PIN, + POWER_MONITOR_VOLTAGE_PIN, #endif - // ADC1 pins + // Pins for ADC1 after ADC0 #if GET_TEMP_0_ADC() == 1 TEMP_0_PIN, @@ -417,7 +416,7 @@ enum ADCIndex { POWER_MONITOR_CURRENT_PIN, #endif #if GET_POWERMON_ADC_VOLTS() == 1 - POWER_MONITOR_VOLTS_PIN, + POWER_MONITOR_VOLTAGE_PIN, #endif }; @@ -488,7 +487,7 @@ enum ADCIndex { { PIN_TO_INPUTCTRL(POWER_MONITOR_CURRENT_PIN) }, #endif #if GET_POWERMON_ADC_VOLTS() == 0 - { PIN_TO_INPUTCTRL(POWER_MONITOR_VOLTS_PIN) }, + { PIN_TO_INPUTCTRL(POWER_MONITOR_VOLTAGE_PIN) }, #endif }; @@ -560,7 +559,7 @@ enum ADCIndex { { PIN_TO_INPUTCTRL(POWER_MONITOR_CURRENT_PIN) }, #endif #if GET_POWERMON_ADC_VOLTS() == 1 - { PIN_TO_INPUTCTRL(POWER_MONITOR_VOLTS_PIN) }, + { PIN_TO_INPUTCTRL(POWER_MONITOR_VOLTAGE_PIN) }, #endif }; diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h index b3430f333987..276f031685fe 100644 --- a/Marlin/src/HAL/STM32/HAL.h +++ b/Marlin/src/HAL/STM32/HAL.h @@ -138,11 +138,7 @@ typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs. -#if defined(STM32G0B1xx) || defined(STM32H7xx) - typedef int32_t pin_t; -#else - typedef int16_t pin_t; -#endif +typedef int32_t pin_t; // Parity with platform/ststm32 class libServo; typedef libServo hal_servo_t; diff --git a/Marlin/src/HAL/STM32/tft/xpt2046.cpp b/Marlin/src/HAL/STM32/tft/xpt2046.cpp index 57c50653c9ce..c5645ad79c4a 100644 --- a/Marlin/src/HAL/STM32/tft/xpt2046.cpp +++ b/Marlin/src/HAL/STM32/tft/xpt2046.cpp @@ -123,7 +123,7 @@ bool XPT2046::getRawPoint(int16_t * const x, int16_t * const y) { if (isBusy() || !isTouched()) return false; *x = getRawData(XPT2046_X); *y = getRawData(XPT2046_Y); - return true; + return isTouched(); } uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { diff --git a/Marlin/src/HAL/STM32F1/HAL.cpp b/Marlin/src/HAL/STM32F1/HAL.cpp index a83c3a23bf7d..e6cbb9fc0605 100644 --- a/Marlin/src/HAL/STM32F1/HAL.cpp +++ b/Marlin/src/HAL/STM32F1/HAL.cpp @@ -29,53 +29,8 @@ #include "../../inc/MarlinConfig.h" #include "HAL.h" -#include - -// ------------------------ -// Types -// ------------------------ - -#define __I -#define __IO volatile - typedef struct { - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5]; - __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ - } SCB_Type; - -// ------------------------ -// Local defines -// ------------------------ - -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ +#include "adc.h" +uint16_t adc_results[ADC_COUNT]; // ------------------------ // Serial ports @@ -171,153 +126,9 @@ void analogWrite(const pin_t pin, int pwm_val8) { uint16_t MarlinHAL::adc_result; -// ------------------------ -// Private functions -// ------------------------ - -static void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); // only values 0..7 are used - - reg_value = SCB->AIRCR; // read old register configuration - reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); // clear bits to change - reg_value = (reg_value | - ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8)); // Insert write key & priority group - SCB->AIRCR = reg_value; -} - -// ------------------------ -// Public functions -// ------------------------ - -void flashFirmware(const int16_t) { hal.reboot(); } - -// -// Leave PA11/PA12 intact if USBSerial is not used -// -#if SERIAL_USB - namespace wirish { namespace priv { - #if SERIAL_PORT > 0 - #if SERIAL_PORT2 - #if SERIAL_PORT2 > 0 - void board_setup_usb() {} - #endif - #else - void board_setup_usb() {} - #endif - #endif - } } -#endif - -TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial()); - -// ------------------------ -// MarlinHAL class -// ------------------------ - -void MarlinHAL::init() { - NVIC_SetPriorityGrouping(0x3); - #if PIN_EXISTS(LED) - OUT_WRITE(LED_PIN, LOW); - #endif - #if HAS_SD_HOST_DRIVE - MSC_SD_init(); - #elif ALL(SERIAL_USB, EMERGENCY_PARSER) - usb_cdcacm_set_hooks(USB_CDCACM_HOOK_RX, my_rx_callback); - #endif - #if PIN_EXISTS(USB_CONNECT) - OUT_WRITE(USB_CONNECT_PIN, !USB_CONNECT_INVERTING); // USB clear connection - delay(1000); // Give OS time to notice - WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING); - #endif - TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the minimal serial handler -} - -// HAL idle task -void MarlinHAL::idletask() { - #if HAS_SHARED_MEDIA - // If Marlin is using the SD card we need to lock it to prevent access from - // a PC via USB. - // Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but - // this will not reliably detect delete operations. To be safe we will lock - // the disk if Marlin has it mounted. Unfortunately there is currently no way - // to unmount the disk from the LCD menu. - // if (IS_SD_PRINTING() || IS_SD_FILE_OPEN()) - /* copy from lpc1768 framework, should be fixed later for process HAS_SD_HOST_DRIVE*/ - // process USB mass storage device class loop - MarlinMSC.loop(); - #endif -} - -void MarlinHAL::reboot() { nvic_sys_reset(); } +#ifndef VOXELAB_N32 -// ------------------------ -// Free Memory Accessor -// ------------------------ - -extern "C" { - extern unsigned int _ebss; // end of bss section -} - -/** - * TODO: Change this to correct it for libmaple - */ - -// return free memory between end of heap (or end bss) and whatever is current - -/* -#include -//extern caddr_t _sbrk(int incr); -#ifndef CONFIG_HEAP_END -extern char _lm_heap_end; -#define CONFIG_HEAP_END ((caddr_t)&_lm_heap_end) -#endif - -extern "C" { - static int freeMemory() { - char top = 't'; - return &top - reinterpret_cast(sbrk(0)); - } - int freeMemory() { - int free_memory; - int heap_end = (int)_sbrk(0); - free_memory = ((int)&free_memory) - ((int)heap_end); - return free_memory; - } -} -*/ - -// ------------------------ -// ADC -// ------------------------ - -enum ADCIndex : uint8_t { - OPTITEM(HAS_TEMP_ADC_0, TEMP_0) - OPTITEM(HAS_TEMP_ADC_1, TEMP_1) - OPTITEM(HAS_TEMP_ADC_2, TEMP_2) - OPTITEM(HAS_TEMP_ADC_3, TEMP_3) - OPTITEM(HAS_TEMP_ADC_4, TEMP_4) - OPTITEM(HAS_TEMP_ADC_5, TEMP_5) - OPTITEM(HAS_TEMP_ADC_6, TEMP_6) - OPTITEM(HAS_TEMP_ADC_7, TEMP_7) - OPTITEM(HAS_HEATED_BED, TEMP_BED) - OPTITEM(HAS_TEMP_CHAMBER, TEMP_CHAMBER) - OPTITEM(HAS_TEMP_ADC_PROBE, TEMP_PROBE) - OPTITEM(HAS_TEMP_COOLER, TEMP_COOLER) - OPTITEM(HAS_TEMP_BOARD, TEMP_BOARD) - OPTITEM(HAS_TEMP_SOC, TEMP_SOC) - OPTITEM(FILAMENT_WIDTH_SENSOR, FILWIDTH) - OPTITEM(HAS_ADC_BUTTONS, ADC_KEY) - OPTITEM(HAS_JOY_ADC_X, JOY_X) - OPTITEM(HAS_JOY_ADC_Y, JOY_Y) - OPTITEM(HAS_JOY_ADC_Z, JOY_Z) - OPTITEM(POWER_MONITOR_CURRENT, POWERMON_CURRENT) - OPTITEM(POWER_MONITOR_VOLTAGE, POWERMON_VOLTS) - ADC_COUNT -}; - -static uint16_t adc_results[ADC_COUNT]; +#include // Init the AD in continuous capture mode void MarlinHAL::adc_init() { @@ -345,7 +156,7 @@ void MarlinHAL::adc_init() { OPTITEM(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN) }; static STM32ADC adc(ADC1); - // configure the ADC + // Configure the ADC adc.calibrate(); adc.setSampleRate((F_CPU > 72000000) ? ADC_SMPR_71_5 : ADC_SMPR_41_5); // 71.5 or 41.5 ADC cycles adc.setPins((uint8_t *)adc_pins, ADC_COUNT); @@ -355,6 +166,8 @@ void MarlinHAL::adc_init() { adc.startConversion(); } +#endif // !VOXELAB_N32 + void MarlinHAL::adc_start(const pin_t pin) { #define __TCASE(N,I) case N: pin_index = I; break; #define _TCASE(C,N,I) TERN_(C, __TCASE(N, I)) @@ -381,9 +194,87 @@ void MarlinHAL::adc_start(const pin_t pin) { _TCASE(FILAMENT_WIDTH_SENSOR, FILWIDTH_PIN, FILWIDTH) _TCASE(HAS_ADC_BUTTONS, ADC_KEYPAD_PIN, ADC_KEY) _TCASE(POWER_MONITOR_CURRENT, POWER_MONITOR_CURRENT_PIN, POWERMON_CURRENT) - _TCASE(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN, POWERMON_VOLTS) + _TCASE(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN, POWERMON_VOLTAGE) } adc_result = (adc_results[(int)pin_index] & 0xFFF) >> (12 - HAL_ADC_RESOLUTION); // shift out unused bits } +// ------------------------ +// Public functions +// ------------------------ + +void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); // only values 0..7 are used + + reg_value = SCB->AIRCR; // read old register configuration + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); // clear bits to change + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); // Insert write key & priority group + SCB->AIRCR = reg_value; +} + +void flashFirmware(const int16_t) { hal.reboot(); } + +// +// Leave PA11/PA12 intact if USBSerial is not used +// +#if SERIAL_USB + namespace wirish { namespace priv { + #if SERIAL_PORT > 0 + #if SERIAL_PORT2 + #if SERIAL_PORT2 > 0 + void board_setup_usb() {} + #endif + #else + void board_setup_usb() {} + #endif + #endif + } } +#endif + +TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial()); + +// ------------------------ +// MarlinHAL class +// ------------------------ + +void MarlinHAL::init() { + NVIC_SetPriorityGrouping(0x3); + #if PIN_EXISTS(LED) + OUT_WRITE(LED_PIN, LOW); + #endif + #if HAS_SD_HOST_DRIVE + MSC_SD_init(); + #elif ALL(SERIAL_USB, EMERGENCY_PARSER) + usb_cdcacm_set_hooks(USB_CDCACM_HOOK_RX, my_rx_callback); + #endif + #if PIN_EXISTS(USB_CONNECT) + OUT_WRITE(USB_CONNECT_PIN, !USB_CONNECT_INVERTING); // USB clear connection + delay(1000); // Give OS time to notice + WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING); + #endif + TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the minimal serial handler +} + +// HAL idle task +void MarlinHAL::idletask() { + #if HAS_SHARED_MEDIA + /** + * When Marlin is using the SD card it should be locked to prevent it being + * accessed from a PC over USB. + * Other HALs use (IS_SD_PRINTING() || IS_SD_FILE_OPEN()) to check for access + * but this won't reliably detect other file operations. To be safe we just lock + * the drive whenever Marlin has it mounted. LCDs should include an Unmount + * command so drives can be released as needed. + */ + /* Copied from LPC1768 framework. Should be fixed later to process HAS_SD_HOST_DRIVE */ + //if (!drive_locked()) // TODO + MarlinMSC.loop(); // Process USB mass storage device class loop + #endif +} + +void MarlinHAL::reboot() { nvic_sys_reset(); } + #endif // __STM32F1__ diff --git a/Marlin/src/HAL/STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h index c4b90db68a19..41c91e200f89 100644 --- a/Marlin/src/HAL/STM32F1/HAL.h +++ b/Marlin/src/HAL/STM32F1/HAL.h @@ -221,10 +221,10 @@ void flashFirmware(const int16_t); // Memory related #define __bss_end __bss_end__ -void _delay_ms(const int ms); - extern "C" char* _sbrk(int incr); +void NVIC_SetPriorityGrouping(uint32_t PriorityGroup); + #pragma GCC diagnostic push #if GCC_VERSION <= 50000 #pragma GCC diagnostic ignored "-Wunused-function" @@ -308,3 +308,49 @@ class MarlinHAL { static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); }; + +// ------------------------ +// Types +// ------------------------ + +#define __I +#define __IO volatile + typedef struct { + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + } SCB_Type; + +// ------------------------ +// System Control Space +// ------------------------ + +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ diff --git a/Marlin/src/HAL/STM32F1/HAL_N32.cpp b/Marlin/src/HAL/STM32F1/HAL_N32.cpp new file mode 100644 index 000000000000..971a344f210d --- /dev/null +++ b/Marlin/src/HAL/STM32F1/HAL_N32.cpp @@ -0,0 +1,641 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * HAL for stm32duino.com based on Libmaple and compatible (STM32F1) + * Specifically for VOXELAB_N32. TODO: Rework for generic N32 MCU. + */ + +#if defined(__STM32F1__) && defined(VOXELAB_N32) + +#include "../../inc/MarlinConfig.h" +#include "HAL_N32.h" +#include "HAL.h" + +#include "adc.h" + +void ADC_Init(ADC_Module* NS_ADCx, ADC_InitType* ADC_InitStruct) { + uint32_t tmpreg1 = 0; + uint8_t tmpreg2 = 0; + + /*---------------------------- ADCx CTRL1 Configuration -----------------*/ + /* Get the ADCx CTRL1 value */ + tmpreg1 = NS_ADCx->CTRL1; + /* Clear DUALMOD and SCAN bits */ + tmpreg1 &= CTRL1_CLR_MASK; + /* Configure ADCx: Dual mode and scan conversion mode */ + /* Set DUALMOD bits according to WorkMode value */ + /* Set SCAN bit according to MultiChEn value */ + tmpreg1 |= (uint32_t)(ADC_InitStruct->WorkMode | ((uint32_t)ADC_InitStruct->MultiChEn << 8)); + /* Write to ADCx CTRL1 */ + NS_ADCx->CTRL1 = tmpreg1; + + /*---------------------------- ADCx CTRL2 Configuration -----------------*/ + /* Get the ADCx CTRL2 value */ + tmpreg1 = NS_ADCx->CTRL2; + /* Clear CONT, ALIGN and EXTSEL bits */ + tmpreg1 &= CTRL2_CLR_MASK; + /* Configure ADCx: external trigger event and continuous conversion mode */ + /* Set ALIGN bit according to DatAlign value */ + /* Set EXTSEL bits according to ExtTrigSelect value */ + /* Set CONT bit according to ContinueConvEn value */ + tmpreg1 |= (uint32_t)(ADC_InitStruct->DatAlign | ADC_InitStruct->ExtTrigSelect + | ((uint32_t)ADC_InitStruct->ContinueConvEn << 1)); + /* Write to ADCx CTRL2 */ + NS_ADCx->CTRL2 = tmpreg1; + + /*---------------------------- ADCx RSEQ1 Configuration -----------------*/ + /* Get the ADCx RSEQ1 value */ + tmpreg1 = NS_ADCx->RSEQ1; + /* Clear L bits */ + tmpreg1 &= RSEQ1_CLR_MASK; + /* Configure ADCx: regular channel sequence length */ + /* Set L bits according to ChsNumber value */ + tmpreg2 |= (uint8_t)(ADC_InitStruct->ChsNumber - (uint8_t)1); + tmpreg1 |= (uint32_t)tmpreg2 << 20; + /* Write to ADCx RSEQ1 */ + NS_ADCx->RSEQ1 = tmpreg1; +} + +/**================================================================ + * ADC reset + ================================================================*/ +void ADC_DeInit(ADC_Module* NS_ADCx) { + uint32_t reg_temp; + + if (NS_ADCx == NS_ADC1) { + /* Enable ADC1 reset state */ + reg_temp = ADC_RCC_AHBPRST; + reg_temp |= RCC_AHB_PERIPH_ADC1; + ADC_RCC_AHBPRST = reg_temp; // ADC module reunion position + ADC_RCC_AHBPRST = 0x00000000; // ADC module reset and clear + } + else if (NS_ADCx == NS_ADC2) { + /* Enable ADC2 reset state */ + reg_temp = ADC_RCC_AHBPRST; + reg_temp |= RCC_AHB_PERIPH_ADC2; + ADC_RCC_AHBPRST = reg_temp; // ADC module reunion position + ADC_RCC_AHBPRST = 0x00000000; // ADC module reset and clear + } + else if (NS_ADCx == NS_ADC3) { + /* Enable ADC2 reset state */ + reg_temp = ADC_RCC_AHBPRST; + reg_temp |= RCC_AHB_PERIPH_ADC3; + ADC_RCC_AHBPRST = reg_temp; // ADC module reunion position + ADC_RCC_AHBPRST = 0x00000000; // ADC module reset and clear + } + else if (NS_ADCx == NS_ADC4) { + /* Enable ADC3 reset state */ + reg_temp = ADC_RCC_AHBPRST; + reg_temp |= RCC_AHB_PERIPH_ADC4; + ADC_RCC_AHBPRST = reg_temp; // ADC module reunion position + ADC_RCC_AHBPRST = 0x00000000; // ADC module reset and clear + } +} + +/**================================================================ + * ADC module enable + ================================================================*/ +void ADC_Enable(ADC_Module* NS_ADCx, uint32_t Cmd) { + if (Cmd) + /* Set the AD_ON bit to wake up the ADC from power down mode */ + NS_ADCx->CTRL2 |= CTRL2_AD_ON_SET; + else + /* Disable the selected ADC peripheral */ + NS_ADCx->CTRL2 &= CTRL2_AD_ON_RESET; +} + +/**================================================================ + * Get the ADC status logo bit + ================================================================*/ +uint32_t ADC_GetFlagStatusNew(ADC_Module* NS_ADCx, uint8_t ADC_FLAG_NEW) { + uint32_t bitstatus = 0; + + /* Check the status of the specified ADC flag */ + if ((NS_ADCx->CTRL3 & ADC_FLAG_NEW) != (uint8_t)0) + /* ADC_FLAG_NEW is set */ + bitstatus = 1; + else + /* ADC_FLAG_NEW is reset */ + bitstatus = 0; + /* Return the ADC_FLAG_NEW status */ + return bitstatus; +} + +/**================================================================ + * Open ADC calibration + ================================================================*/ +void ADC_StartCalibration(ADC_Module* NS_ADCx) { + /* Enable the selected ADC calibration process */ + if (NS_ADCx->CALFACT == 0) + NS_ADCx->CTRL2 |= CTRL2_CAL_SET; +} + +/**================================================================ + * Enable ADC DMA + ================================================================*/ +void ADC_EnableDMA(ADC_Module* NS_ADCx, uint32_t Cmd) { + if (Cmd != 0) + /* Enable the selected ADC DMA request */ + NS_ADCx->CTRL2 |= CTRL2_DMA_SET; + else + /* Disable the selected ADC DMA request */ + NS_ADCx->CTRL2 &= CTRL2_DMA_RESET; +} + +/**================================================================ + * Configure ADC interrupt enable enable + ================================================================*/ +void ADC_ConfigInt(ADC_Module* NS_ADCx, uint16_t ADC_IT, uint32_t Cmd) { + uint8_t itmask = 0; + + /* Get the ADC IT index */ + itmask = (uint8_t)ADC_IT; + if (Cmd != 0) + /* Enable the selected ADC interrupts */ + NS_ADCx->CTRL1 |= itmask; + else + /* Disable the selected ADC interrupts */ + NS_ADCx->CTRL1 &= (~(uint32_t)itmask); +} + +/**================================================================ + * Get ADC calibration status + ================================================================*/ +uint32_t ADC_GetCalibrationStatus(ADC_Module* NS_ADCx) { + uint32_t bitstatus = 0; + + /* Check the status of CAL bit */ + if ((NS_ADCx->CTRL2 & CTRL2_CAL_SET) != (uint32_t)0) + /* CAL bit is set: calibration on going */ + bitstatus = 1; + else + /* CAL bit is reset: end of calibration */ + bitstatus = 0; + + if (NS_ADCx->CALFACT != 0) + bitstatus = 0; + /* Return the CAL bit status */ + return bitstatus; +} + +/**================================================================ + * Configure the ADC channel + ================================================================*/ +void ADC_ConfigRegularChannel(ADC_Module* NS_ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) { + uint32_t tmpreg1 = 0, tmpreg2 = 0; + + if (ADC_Channel == ADC_CH_18) { + tmpreg1 = NS_ADCx->SAMPT3; + tmpreg1 &= (~0x00000007); + tmpreg1 |= ADC_SampleTime; + NS_ADCx->SAMPT3 = tmpreg1; + } + else if (ADC_Channel > ADC_CH_9) { /* if ADC_CH_10 ... ADC_CH_17 is selected */ + /* Get the old register value */ + tmpreg1 = NS_ADCx->SAMPT1; + /* Calculate the mask to clear */ + tmpreg2 = SAMPT1_SMP_SET << (3 * (ADC_Channel - 10)); + /* Clear the old channel sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10)); + /* Set the new channel sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + NS_ADCx->SAMPT1 = tmpreg1; + } + else { /* ADC_Channel include in ADC_Channel_[0..9] */ + /* Get the old register value */ + tmpreg1 = NS_ADCx->SAMPT2; + /* Calculate the mask to clear */ + tmpreg2 = SAMPT2_SMP_SET << (3 * ADC_Channel); + /* Clear the old channel sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); + /* Set the new channel sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + NS_ADCx->SAMPT2 = tmpreg1; + } + /* For Rank 1 to 6 */ + if (Rank < 7) { + /* Get the old register value */ + tmpreg1 = NS_ADCx->RSEQ3; + /* Calculate the mask to clear */ + tmpreg2 = SQR3_SEQ_SET << (5 * (Rank - 1)); + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 1)); + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + NS_ADCx->RSEQ3 = tmpreg1; + } + /* For Rank 7 to 12 */ + else if (Rank < 13) { + /* Get the old register value */ + tmpreg1 = NS_ADCx->RSEQ2; + /* Calculate the mask to clear */ + tmpreg2 = SQR2_SEQ_SET << (5 * (Rank - 7)); + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 7)); + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + NS_ADCx->RSEQ2 = tmpreg1; + } + /* For Rank 13 to 16 */ + else { + /* Get the old register value */ + tmpreg1 = NS_ADCx->RSEQ1; + /* Calculate the mask to clear */ + tmpreg2 = SQR1_SEQ_SET << (5 * (Rank - 13)); + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 13)); + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + NS_ADCx->RSEQ1 = tmpreg1; + } +} + +/**================================================================ + * Start ADC conversion + ================================================================*/ +void ADC_EnableSoftwareStartConv(ADC_Module* NS_ADCx, uint32_t Cmd) { + if (Cmd != 0) + /* Enable the selected ADC conversion on external event and start the selected + ADC conversion */ + NS_ADCx->CTRL2 |= CTRL2_EXT_TRIG_SWSTART_SET; + else + /* Disable the selected ADC conversion on external event and stop the selected + ADC conversion */ + NS_ADCx->CTRL2 &= CTRL2_EXT_TRIG_SWSTART_RESET; +} + +/**================================================================ + * Get the ADC status logo bit + ================================================================*/ +uint32_t ADC_GetFlagStatus(ADC_Module* NS_ADCx, uint8_t ADC_FLAG) { + uint32_t bitstatus = 0; + + /* Check the status of the specified ADC flag */ + if ((NS_ADCx->STS & ADC_FLAG) != (uint8_t)0) + /* ADC_FLAG is set */ + bitstatus = 1; + else + /* ADC_FLAG is reset */ + bitstatus = 0; + /* Return the ADC_FLAG status */ + return bitstatus; +} + +/**================================================================ + * Clear status logo bit + ================================================================*/ +void ADC_ClearFlag(ADC_Module* NS_ADCx, uint8_t ADC_FLAG) { + /* Clear the selected ADC flags */ + NS_ADCx->STS &= ~(uint32_t)ADC_FLAG; +} + +/**================================================================ + * Get ADC sampling value + ================================================================*/ +uint16_t ADC_GetDat(ADC_Module* NS_ADCx) { + /* Return the selected ADC conversion value */ + return (uint16_t)NS_ADCx->DAT; +} + +/**================================================================ + * Initialize ADC clock + ================================================================*/ + +void enable_adc_clk(uint8_t cmd) { + uint32_t reg_temp; + if (cmd) { + /** Make PWR clock */ + reg_temp = ADC_RCC_APB1PCLKEN; + reg_temp |= RCC_APB1Periph_PWR; + ADC_RCC_APB1PCLKEN = reg_temp; + + /** Enable expansion mode */ + reg_temp = NS_PWR_CR3; + reg_temp |= 0x00000001; + NS_PWR_CR3 = reg_temp; + + /** Make ADC clock */ + reg_temp = ADC_RCC_AHBPCLKEN; + reg_temp |= ( RCC_AHB_PERIPH_ADC1 | + RCC_AHB_PERIPH_ADC2 | + RCC_AHB_PERIPH_ADC3 | + RCC_AHB_PERIPH_ADC4 ); + ADC_RCC_AHBPCLKEN = reg_temp; + + /** Reset */ + reg_temp = ADC_RCC_AHBPRST; + reg_temp |= ( RCC_AHB_PERIPH_ADC1 | + RCC_AHB_PERIPH_ADC2 | + RCC_AHB_PERIPH_ADC3 | + RCC_AHB_PERIPH_ADC4 ); + ADC_RCC_AHBPRST = reg_temp; // ADC module reunion position + ADC_RCC_AHBPRST &= ~reg_temp; // ADC module reset and clear + + /** Set ADC 1M clock */ + reg_temp = ADC_RCC_CFG2; + reg_temp &= CFG2_ADC1MSEL_RESET_MASK; // HSI as an ADC 1M clock + reg_temp &= CFG2_ADC1MPRES_RESET_MASK; + reg_temp |= 7 << 11; // Adc1m 8m / 8 = 1m + + /** Set the ADC PLL frequency split coefficient */ + reg_temp &= CFG2_ADCPLLPRES_RESET_MASK; + reg_temp |= RCC_ADCPLLCLK_DIV4; // ADC PLL frequency split coefficient + + /** Set the ADC HCLK frequency frequency coefficient */ + reg_temp &= CFG2_ADCHPRES_RESET_MASK; + reg_temp |= RCC_ADCHCLK_DIV4; // ADC HCLK frequency split coefficient + ADC_RCC_CFG2 = reg_temp; // Write to register + } + else { + /** Turn off the ADC clock */ + reg_temp = ADC_RCC_AHBPCLKEN; + reg_temp &= ~( RCC_AHB_PERIPH_ADC1 | + RCC_AHB_PERIPH_ADC2 | + RCC_AHB_PERIPH_ADC3 | + RCC_AHB_PERIPH_ADC4 ); + ADC_RCC_AHBPCLKEN = reg_temp; + } + +} + +/**================================================================ + * Initialize ADC peripheral parameters + ================================================================*/ +void ADC_Initial(ADC_Module* NS_ADCx) { + ADC_InitType ADC_InitStructure; + + /* ADC configuration ------------------------------------------------------*/ + ADC_InitStructure.WorkMode = ADC_WORKMODE_INDEPENDENT; // Independent mode + ADC_InitStructure.MultiChEn = 1; // Multi-channel enable + ADC_InitStructure.ContinueConvEn = 1; // Continuous enable + ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_NONE; // Non-trigger + ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R; // Right alignment + ADC_InitStructure.ChsNumber = 2; // Scan channel number + ADC_Init(NS_ADCx, &ADC_InitStructure); + + /* ADC regular channel14 configuration */ + ADC_ConfigRegularChannel(NS_ADCx, ADC2_Channel_05_PC4, 2, ADC_SAMP_TIME_55CYCLES5); + ADC_ConfigRegularChannel(NS_ADCx, ADC2_Channel_12_PC5, 1, ADC_SAMP_TIME_55CYCLES5); + + /** 使能ADC DMA */ + ADC_EnableDMA(NS_ADCx, 1); + + /* Enable ADC */ + ADC_Enable(NS_ADCx, 1); + while(ADC_GetFlagStatusNew(NS_ADCx, ADC_FLAG_RDY) == 0); + + /* Start ADC calibration */ + ADC_StartCalibration(NS_ADCx); + while (ADC_GetCalibrationStatus(NS_ADCx)); + + /* Start ADC Software Conversion */ + ADC_EnableSoftwareStartConv(NS_ADCx, 1); +} + +/**================================================================ + * Single independent sampling + ================================================================*/ +uint16_t ADC_GetData(ADC_Module* NS_ADCx, uint8_t ADC_Channel) { + uint16_t dat; + + /** Set channel parameters */ + ADC_ConfigRegularChannel(NS_ADCx, ADC_Channel, 1, ADC_SAMP_TIME_239CYCLES5); + + /* Start ADC Software Conversion */ + ADC_EnableSoftwareStartConv(NS_ADCx, 1); + while(ADC_GetFlagStatus(NS_ADCx, ADC_FLAG_ENDC) == 0); + + ADC_ClearFlag(NS_ADCx, ADC_FLAG_ENDC); + ADC_ClearFlag(NS_ADCx, ADC_FLAG_STR); + dat = ADC_GetDat(NS_ADCx); + return dat; +} + +void DMA_DeInit(DMA_ChannelType* DMAyChx) { + + /* Disable the selected DMAy Channelx */ + DMAyChx->CHCFG &= (uint16_t)(~DMA_CHCFG1_CHEN); + + /* Reset DMAy Channelx control register */ + DMAyChx->CHCFG = 0; + + /* Reset DMAy Channelx remaining bytes register */ + DMAyChx->TXNUM = 0; + + /* Reset DMAy Channelx peripheral address register */ + DMAyChx->PADDR = 0; + + /* Reset DMAy Channelx memory address register */ + DMAyChx->MADDR = 0; + + if (DMAyChx == DMA1_CH1) { + /* Reset interrupt pending bits for DMA1 Channel1 */ + DMA1->INTCLR |= DMA1_CH1_INT_MASK; + } + else if (DMAyChx == DMA1_CH2) { + /* Reset interrupt pending bits for DMA1 Channel2 */ + DMA1->INTCLR |= DMA1_CH2_INT_MASK; + } + else if (DMAyChx == DMA1_CH3) { + /* Reset interrupt pending bits for DMA1 Channel3 */ + DMA1->INTCLR |= DMA1_CH3_INT_MASK; + } + else if (DMAyChx == DMA1_CH4) { + /* Reset interrupt pending bits for DMA1 Channel4 */ + DMA1->INTCLR |= DMA1_CH4_INT_MASK; + } + else if (DMAyChx == DMA1_CH5) { + /* Reset interrupt pending bits for DMA1 Channel5 */ + DMA1->INTCLR |= DMA1_CH5_INT_MASK; + } + else if (DMAyChx == DMA1_CH6) { + /* Reset interrupt pending bits for DMA1 Channel6 */ + DMA1->INTCLR |= DMA1_CH6_INT_MASK; + } + else if (DMAyChx == DMA1_CH7) { + /* Reset interrupt pending bits for DMA1 Channel7 */ + DMA1->INTCLR |= DMA1_CH7_INT_MASK; + } + else if (DMAyChx == DMA1_CH8) { + /* Reset interrupt pending bits for DMA1 Channel8 */ + DMA1->INTCLR |= DMA1_CH8_INT_MASK; + } + else if (DMAyChx == DMA2_CH1) { + /* Reset interrupt pending bits for DMA2 Channel1 */ + DMA2->INTCLR |= DMA2_CH1_INT_MASK; + } + else if (DMAyChx == DMA2_CH2) { + /* Reset interrupt pending bits for DMA2 Channel2 */ + DMA2->INTCLR |= DMA2_CH2_INT_MASK; + } + else if (DMAyChx == DMA2_CH3) { + /* Reset interrupt pending bits for DMA2 Channel3 */ + DMA2->INTCLR |= DMA2_CH3_INT_MASK; + } + else if (DMAyChx == DMA2_CH4) { + /* Reset interrupt pending bits for DMA2 Channel4 */ + DMA2->INTCLR |= DMA2_CH4_INT_MASK; + } + else if (DMAyChx == DMA2_CH5) { + /* Reset interrupt pending bits for DMA2 Channel5 */ + DMA2->INTCLR |= DMA2_CH5_INT_MASK; + } + else if (DMAyChx == DMA2_CH6) { + /* Reset interrupt pending bits for DMA2 Channel6 */ + DMA2->INTCLR |= DMA2_CH6_INT_MASK; + } + else if (DMAyChx == DMA2_CH7) { + /* Reset interrupt pending bits for DMA2 Channel7 */ + DMA2->INTCLR |= DMA2_CH7_INT_MASK; + } + else if (DMAyChx == DMA2_CH8) + /* Reset interrupt pending bits for DMA2 Channel8 */ + DMA2->INTCLR |= DMA2_CH8_INT_MASK; +} + +void DMA_Init(DMA_ChannelType* DMAyChx, DMA_InitType* DMA_InitParam) { + uint32_t tmpregister = 0; + + /*--------------------------- DMAy Channelx CHCFG Configuration --------------*/ + /* Get the DMAyChx CHCFG value */ + tmpregister = DMAyChx->CHCFG; + /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */ + tmpregister &= CCR_CLEAR_Mask; + /* Configure DMAy Channelx: data transfer, data size, priority level and mode */ + /* Set DIR bit according to Direction value */ + /* Set CIRC bit according to CircularMode value */ + /* Set PINC bit according to PeriphInc value */ + /* Set MINC bit according to DMA_MemoryInc value */ + /* Set PSIZE bits according to PeriphDataSize value */ + /* Set MSIZE bits according to MemDataSize value */ + /* Set PL bits according to Priority value */ + /* Set the MEM2MEM bit according to Mem2Mem value */ + tmpregister |= DMA_InitParam->Direction | DMA_InitParam->CircularMode | DMA_InitParam->PeriphInc + | DMA_InitParam->DMA_MemoryInc | DMA_InitParam->PeriphDataSize | DMA_InitParam->MemDataSize + | DMA_InitParam->Priority | DMA_InitParam->Mem2Mem; + + /* Write to DMAy Channelx CHCFG */ + DMAyChx->CHCFG = tmpregister; + + /*--------------------------- DMAy Channelx TXNUM Configuration --------------*/ + /* Write to DMAy Channelx TXNUM */ + DMAyChx->TXNUM = DMA_InitParam->BufSize; + + /*--------------------------- DMAy Channelx PADDR Configuration --------------*/ + /* Write to DMAy Channelx PADDR */ + DMAyChx->PADDR = DMA_InitParam->PeriphAddr; + + /*--------------------------- DMAy Channelx MADDR Configuration --------------*/ + /* Write to DMAy Channelx MADDR */ + DMAyChx->MADDR = DMA_InitParam->MemAddr; +} + +void DMA_EnableChannel(DMA_ChannelType* DMAyChx, uint32_t Cmd) { + if (Cmd != 0) { + /* Enable the selected DMAy Channelx */ + DMAyChx->CHCFG |= DMA_CHCFG1_CHEN; + } + else { + /* Disable the selected DMAy Channelx */ + DMAyChx->CHCFG &= (uint16_t)(~DMA_CHCFG1_CHEN); + } +} + +/**================================================================ + * Initialize the DMA of ADC + ================================================================*/ +void ADC_DMA_init() { + DMA_InitType DMA_InitStructure; + uint32_t reg_temp; + + /** Make DMA clock */ + reg_temp = ADC_RCC_AHBPCLKEN; + reg_temp |= ( RCC_AHB_PERIPH_DMA1 | + RCC_AHB_PERIPH_DMA2 ); + ADC_RCC_AHBPCLKEN = reg_temp; + + /* DMA channel configuration*/ + DMA_DeInit(USE_DMA_CH); + DMA_InitStructure.PeriphAddr = (uint32_t)&USE_ADC->DAT; + DMA_InitStructure.MemAddr = (uint32_t)adc_results; + DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC; // Peripheral-> memory + DMA_InitStructure.BufSize = 2; + DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE; + DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE; // Memory ++ + DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD; + DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_HalfWord; + DMA_InitStructure.CircularMode = DMA_MODE_CIRCULAR; + DMA_InitStructure.Priority = DMA_PRIORITY_HIGH; + DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE; + DMA_Init(USE_DMA_CH, &DMA_InitStructure); + + /* Enable DMA channel1 */ + DMA_EnableChannel(USE_DMA_CH, 1); +} + +/**============================================================================= + * n32g452 - end + ==============================================================================*/ + +#define NS_PINRT(V...) do{ SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(V); }while(0) + +// Init the AD in continuous capture mode +void MarlinHAL::adc_init() { + uint32_t reg_temp; + + //SERIAL_ECHO_MSG("\r\n n32g45x HAL_adc_init\r\n"); + + // GPIO settings + reg_temp = ADC_RCC_APB2PCLKEN; + reg_temp |= 0x0f; // Make PORT mouth clock + ADC_RCC_APB2PCLKEN = reg_temp; + + //reg_temp = NS_GPIOC_PL_CFG; + //reg_temp &= 0XFF00FFFF; + //NS_GPIOC_PL_CFG = reg_temp; // PC4/5 analog input + + enable_adc_clk(1); // Make ADC clock + ADC_DMA_init(); // DMA initialization + ADC_Initial(NS_ADC2); // ADC initialization + + delay(2); + //NS_PINRT("get adc1 = ", adc_results[0], "\r\n"); + //NS_PINRT("get adc2 = ", adc_results[1], "\r\n"); +} + +#endif // __STM32F1__ && VOXELAB_N32 diff --git a/Marlin/src/HAL/STM32F1/HAL_N32.h b/Marlin/src/HAL/STM32F1/HAL_N32.h new file mode 100644 index 000000000000..46ec7ba6db9c --- /dev/null +++ b/Marlin/src/HAL/STM32F1/HAL_N32.h @@ -0,0 +1,892 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * HAL for stm32duino.com based on Libmaple and compatible (STM32F1) + * Specifically for VOXELAB_N32 (N32G452). TODO: Rework for generic N32 MCU. + */ + +#include + +typedef struct { + uint32_t WorkMode; + uint32_t MultiChEn; + uint32_t ContinueConvEn; + uint32_t ExtTrigSelect; + uint32_t DatAlign; + uint8_t ChsNumber; +} ADC_InitType; + +typedef struct { + __IO uint32_t STS; + __IO uint32_t CTRL1; + __IO uint32_t CTRL2; + __IO uint32_t SAMPT1; + __IO uint32_t SAMPT2; + __IO uint32_t JOFFSET1; + __IO uint32_t JOFFSET2; + __IO uint32_t JOFFSET3; + __IO uint32_t JOFFSET4; + __IO uint32_t WDGHIGH; + __IO uint32_t WDGLOW; + __IO uint32_t RSEQ1; + __IO uint32_t RSEQ2; + __IO uint32_t RSEQ3; + __IO uint32_t JSEQ; + __IO uint32_t JDAT1; + __IO uint32_t JDAT2; + __IO uint32_t JDAT3; + __IO uint32_t JDAT4; + __IO uint32_t DAT; + __IO uint32_t DIFSEL; + __IO uint32_t CALFACT; + __IO uint32_t CTRL3; + __IO uint32_t SAMPT3; +} ADC_Module; + +#define NS_ADC1_BASE ((uint32_t)0x40020800) +#define NS_ADC2_BASE ((uint32_t)0x40020c00) +#define NS_ADC3_BASE ((uint32_t)0x40021800) +#define NS_ADC4_BASE ((uint32_t)0x40021c00) + +#define NS_ADC1 ((ADC_Module*)NS_ADC1_BASE) +#define NS_ADC2 ((ADC_Module*)NS_ADC2_BASE) +#define NS_ADC3 ((ADC_Module*)NS_ADC3_BASE) +#define NS_ADC4 ((ADC_Module*)NS_ADC4_BASE) + +#define ADC1_Channel_01_PA0 ((uint8_t)0x01) +#define ADC1_Channel_02_PA1 ((uint8_t)0x02) +#define ADC1_Channel_03_PA6 ((uint8_t)0x03) +#define ADC1_Channel_04_PA3 ((uint8_t)0x04) +#define ADC1_Channel_05_PF4 ((uint8_t)0x05) +#define ADC1_Channel_06_PC0 ((uint8_t)0x06) +#define ADC1_Channel_07_PC1 ((uint8_t)0x07) +#define ADC1_Channel_08_PC2 ((uint8_t)0x08) +#define ADC1_Channel_09_PC3 ((uint8_t)0x09) +#define ADC1_Channel_10_PF2 ((uint8_t)0x0A) +#define ADC1_Channel_11_PA2 ((uint8_t)0x0B) + +#define ADC2_Channel_01_PA4 ((uint8_t)0x01) +#define ADC2_Channel_02_PA5 ((uint8_t)0x02) +#define ADC2_Channel_03_PB1 ((uint8_t)0x03) +#define ADC2_Channel_04_PA7 ((uint8_t)0x04) +#define ADC2_Channel_05_PC4 ((uint8_t)0x05) +#define ADC2_Channel_06_PC0 ((uint8_t)0x06) +#define ADC2_Channel_07_PC1 ((uint8_t)0x07) +#define ADC2_Channel_08_PC2 ((uint8_t)0x08) +#define ADC2_Channel_09_PC3 ((uint8_t)0x09) +#define ADC2_Channel_10_PF2 ((uint8_t)0x0A) +#define ADC2_Channel_11_PA2 ((uint8_t)0x0B) +#define ADC2_Channel_12_PC5 ((uint8_t)0x0C) +#define ADC2_Channel_13_PB2 ((uint8_t)0x0D) + +#define ADC3_Channel_01_PB11 ((uint8_t)0x01) +#define ADC3_Channel_02_PE9 ((uint8_t)0x02) +#define ADC3_Channel_03_PE13 ((uint8_t)0x03) +#define ADC3_Channel_04_PE12 ((uint8_t)0x04) +#define ADC3_Channel_05_PB13 ((uint8_t)0x05) +#define ADC3_Channel_06_PE8 ((uint8_t)0x06) +#define ADC3_Channel_07_PD10 ((uint8_t)0x07) +#define ADC3_Channel_08_PD11 ((uint8_t)0x08) +#define ADC3_Channel_09_PD12 ((uint8_t)0x09) +#define ADC3_Channel_10_PD13 ((uint8_t)0x0A) +#define ADC3_Channel_11_PD14 ((uint8_t)0x0B) +#define ADC3_Channel_12_PB0 ((uint8_t)0x0C) +#define ADC3_Channel_13_PE7 ((uint8_t)0x0D) +#define ADC3_Channel_14_PE10 ((uint8_t)0x0E) +#define ADC3_Channel_15_PE11 ((uint8_t)0x0F) + +#define ADC4_Channel_01_PE14 ((uint8_t)0x01) +#define ADC4_Channel_02_PE15 ((uint8_t)0x02) +#define ADC4_Channel_03_PB12 ((uint8_t)0x03) +#define ADC4_Channel_04_PB14 ((uint8_t)0x04) +#define ADC4_Channel_05_PB15 ((uint8_t)0x05) +#define ADC4_Channel_06_PE8 ((uint8_t)0x06) +#define ADC4_Channel_07_PD10 ((uint8_t)0x07) +#define ADC4_Channel_08_PD11 ((uint8_t)0x08) +#define ADC4_Channel_09_PD12 ((uint8_t)0x09) +#define ADC4_Channel_10_PD13 ((uint8_t)0x0A) +#define ADC4_Channel_11_PD14 ((uint8_t)0x0B) +#define ADC4_Channel_12_PD8 ((uint8_t)0x0C) +#define ADC4_Channel_13_PD9 ((uint8_t)0x0D) + +#define ADC_RCC_BASE ((uint32_t)0x40021000) +#define ADC_RCC_CTRL *((uint32_t*)(ADC_RCC_BASE + 0x00)) +#define ADC_RCC_CFG *((uint32_t*)(ADC_RCC_BASE + 0x04)) +#define ADC_RCC_CLKINT *((uint32_t*)(ADC_RCC_BASE + 0x08)) +#define ADC_RCC_APB2PRST *((uint32_t*)(ADC_RCC_BASE + 0x0c)) +#define ADC_RCC_APB1PRST *((uint32_t*)(ADC_RCC_BASE + 0x10)) +#define ADC_RCC_AHBPCLKEN *((uint32_t*)(ADC_RCC_BASE + 0x14)) +#define ADC_RCC_APB2PCLKEN *((uint32_t*)(ADC_RCC_BASE + 0x18)) +#define ADC_RCC_APB1PCLKEN *((uint32_t*)(ADC_RCC_BASE + 0x1c)) +#define ADC_RCC_BDCTRL *((uint32_t*)(ADC_RCC_BASE + 0x20)) +#define ADC_RCC_CTRLSTS *((uint32_t*)(ADC_RCC_BASE + 0x24)) +#define ADC_RCC_AHBPRST *((uint32_t*)(ADC_RCC_BASE + 0x28)) +#define ADC_RCC_CFG2 *((uint32_t*)(ADC_RCC_BASE + 0x2c)) +#define ADC_RCC_CFG3 *((uint32_t*)(ADC_RCC_BASE + 0x30)) + +#define NS_PWR_CR3 *((uint32_t*)(0x40007000 + 0x0C)) +#define RCC_APB1Periph_PWR ((uint32_t)0x10000000) + +/////////////////////////////// +#define NS_GPIOA_BASE ((uint32_t)0x40010800) +#define NS_GPIOA_PL_CFG *((uint32_t*)(NS_GPIOA_BASE + 0x00)) +#define NS_GPIOA_PH_CFG *((uint32_t*)(NS_GPIOA_BASE + 0x04)) + +#define NS_GPIOC_BASE ((uint32_t)0x40011000) +#define NS_GPIOC_PL_CFG *((uint32_t*)(NS_GPIOC_BASE + 0x00)) +#define NS_GPIOC_PH_CFG *((uint32_t*)(NS_GPIOC_BASE + 0x04)) + +/* CFG2 register bit mask */ +#define CFG2_TIM18CLKSEL_SET_MASK ((uint32_t)0x20000000) +#define CFG2_TIM18CLKSEL_RESET_MASK ((uint32_t)0xDFFFFFFF) +#define CFG2_RNGCPRES_SET_MASK ((uint32_t)0x1F000000) +#define CFG2_RNGCPRES_RESET_MASK ((uint32_t)0xE0FFFFFF) +#define CFG2_ADC1MSEL_SET_MASK ((uint32_t)0x00000400) +#define CFG2_ADC1MSEL_RESET_MASK ((uint32_t)0xFFFFFBFF) +#define CFG2_ADC1MPRES_SET_MASK ((uint32_t)0x0000F800) +#define CFG2_ADC1MPRES_RESET_MASK ((uint32_t)0xFFFF07FF) +#define CFG2_ADCPLLPRES_SET_MASK ((uint32_t)0x000001F0) +#define CFG2_ADCPLLPRES_RESET_MASK ((uint32_t)0xFFFFFE0F) +#define CFG2_ADCHPRES_SET_MASK ((uint32_t)0x0000000F) +#define CFG2_ADCHPRES_RESET_MASK ((uint32_t)0xFFFFFFF0) + +#define RCC_ADCPLLCLK_DISABLE ((uint32_t)0xFFFFFEFF) +#define RCC_ADCPLLCLK_DIV1 ((uint32_t)0x00000100) +#define RCC_ADCPLLCLK_DIV2 ((uint32_t)0x00000110) +#define RCC_ADCPLLCLK_DIV4 ((uint32_t)0x00000120) +#define RCC_ADCPLLCLK_DIV6 ((uint32_t)0x00000130) +#define RCC_ADCPLLCLK_DIV8 ((uint32_t)0x00000140) +#define RCC_ADCPLLCLK_DIV10 ((uint32_t)0x00000150) +#define RCC_ADCPLLCLK_DIV12 ((uint32_t)0x00000160) +#define RCC_ADCPLLCLK_DIV16 ((uint32_t)0x00000170) +#define RCC_ADCPLLCLK_DIV32 ((uint32_t)0x00000180) +#define RCC_ADCPLLCLK_DIV64 ((uint32_t)0x00000190) +#define RCC_ADCPLLCLK_DIV128 ((uint32_t)0x000001A0) +#define RCC_ADCPLLCLK_DIV256 ((uint32_t)0x000001B0) +#define RCC_ADCPLLCLK_DIV_OTHERS ((uint32_t)0x000001C0) + +#define RCC_ADCHCLK_DIV1 ((uint32_t)0x00000000) +#define RCC_ADCHCLK_DIV2 ((uint32_t)0x00000001) +#define RCC_ADCHCLK_DIV4 ((uint32_t)0x00000002) +#define RCC_ADCHCLK_DIV6 ((uint32_t)0x00000003) +#define RCC_ADCHCLK_DIV8 ((uint32_t)0x00000004) +#define RCC_ADCHCLK_DIV10 ((uint32_t)0x00000005) +#define RCC_ADCHCLK_DIV12 ((uint32_t)0x00000006) +#define RCC_ADCHCLK_DIV16 ((uint32_t)0x00000007) +#define RCC_ADCHCLK_DIV32 ((uint32_t)0x00000008) +#define RCC_ADCHCLK_DIV_OTHERS ((uint32_t)0x00000008) + +#define SAMPT1_SMP_SET ((uint32_t)0x00000007) +#define SAMPT2_SMP_SET ((uint32_t)0x00000007) + +#define SQR4_SEQ_SET ((uint32_t)0x0000001F) +#define SQR3_SEQ_SET ((uint32_t)0x0000001F) +#define SQR2_SEQ_SET ((uint32_t)0x0000001F) +#define SQR1_SEQ_SET ((uint32_t)0x0000001F) + +#define CTRL1_CLR_MASK ((uint32_t)0xFFF0FEFF) +#define RSEQ1_CLR_MASK ((uint32_t)0xFF0FFFFF) +#define CTRL2_CLR_MASK ((uint32_t)0xFFF1F7FD) + +#define ADC_CH_0 ((uint8_t)0x00) +#define ADC_CH_1 ((uint8_t)0x01) +#define ADC_CH_2 ((uint8_t)0x02) +#define ADC_CH_3 ((uint8_t)0x03) +#define ADC_CH_4 ((uint8_t)0x04) +#define ADC_CH_5 ((uint8_t)0x05) +#define ADC_CH_6 ((uint8_t)0x06) +#define ADC_CH_7 ((uint8_t)0x07) +#define ADC_CH_8 ((uint8_t)0x08) +#define ADC_CH_9 ((uint8_t)0x09) +#define ADC_CH_10 ((uint8_t)0x0A) +#define ADC_CH_11 ((uint8_t)0x0B) +#define ADC_CH_12 ((uint8_t)0x0C) +#define ADC_CH_13 ((uint8_t)0x0D) +#define ADC_CH_14 ((uint8_t)0x0E) +#define ADC_CH_15 ((uint8_t)0x0F) +#define ADC_CH_16 ((uint8_t)0x10) +#define ADC_CH_17 ((uint8_t)0x11) +#define ADC_CH_18 ((uint8_t)0x12) + +#define ADC_WORKMODE_INDEPENDENT ((uint32_t)0x00000000) +#define ADC_WORKMODE_REG_INJECT_SIMULT ((uint32_t)0x00010000) +#define ADC_WORKMODE_REG_SIMULT_ALTER_TRIG ((uint32_t)0x00020000) +#define ADC_WORKMODE_INJ_SIMULT_FAST_INTERL ((uint32_t)0x00030000) +#define ADC_WORKMODE_INJ_SIMULT_SLOW_INTERL ((uint32_t)0x00040000) +#define ADC_WORKMODE_INJ_SIMULT ((uint32_t)0x00050000) +#define ADC_WORKMODE_REG_SIMULT ((uint32_t)0x00060000) +#define ADC_WORKMODE_FAST_INTERL ((uint32_t)0x00070000) +#define ADC_WORKMODE_SLOW_INTERL ((uint32_t)0x00080000) +#define ADC_WORKMODE_ALTER_TRIG ((uint32_t)0x00090000) + +#define ADC_EXT_TRIGCONV_T1_CC3 ((uint32_t)0x00040000) //!< For ADC1, ADC2 , ADC3 and ADC4 +#define ADC_EXT_TRIGCONV_NONE ((uint32_t)0x000E0000) //!< For ADC1, ADC2 , ADC3 and ADC4 + +#define ADC_DAT_ALIGN_R ((uint32_t)0x00000000) +#define ADC_DAT_ALIGN_L ((uint32_t)0x00000800) + +#define ADC_FLAG_RDY ((uint8_t)0x20) +#define ADC_FLAG_PD_RDY ((uint8_t)0x40) + +#define CTRL2_AD_ON_SET ((uint32_t)0x00000001) +#define CTRL2_AD_ON_RESET ((uint32_t)0xFFFFFFFE) + +#define CTRL2_CAL_SET ((uint32_t)0x00000004) + +/* ADC Software start mask */ +#define CTRL2_EXT_TRIG_SWSTART_SET ((uint32_t)0x00500000) +#define CTRL2_EXT_TRIG_SWSTART_RESET ((uint32_t)0xFFAFFFFF) + +#define ADC_SAMP_TIME_1CYCLES5 ((uint8_t)0x00) +#define ADC_SAMP_TIME_7CYCLES5 ((uint8_t)0x01) +#define ADC_SAMP_TIME_13CYCLES5 ((uint8_t)0x02) +#define ADC_SAMP_TIME_28CYCLES5 ((uint8_t)0x03) +#define ADC_SAMP_TIME_41CYCLES5 ((uint8_t)0x04) +#define ADC_SAMP_TIME_55CYCLES5 ((uint8_t)0x05) +#define ADC_SAMP_TIME_71CYCLES5 ((uint8_t)0x06) +#define ADC_SAMP_TIME_239CYCLES5 ((uint8_t)0x07) + +#define ADC_FLAG_AWDG ((uint8_t)0x01) +#define ADC_FLAG_ENDC ((uint8_t)0x02) +#define ADC_FLAG_JENDC ((uint8_t)0x04) +#define ADC_FLAG_JSTR ((uint8_t)0x08) +#define ADC_FLAG_STR ((uint8_t)0x10) +#define ADC_FLAG_EOC_ANY ((uint8_t)0x20) +#define ADC_FLAG_JEOC_ANY ((uint8_t)0x40) + +/* ADC DMA mask */ +#define CTRL2_DMA_SET ((uint32_t)0x00000100) +#define CTRL2_DMA_RESET ((uint32_t)0xFFFFFEFF) + +typedef struct { + uint32_t PeriphAddr; + uint32_t MemAddr; + uint32_t Direction; + uint32_t BufSize; + uint32_t PeriphInc; + uint32_t DMA_MemoryInc; + uint32_t PeriphDataSize; + uint32_t MemDataSize; + uint32_t CircularMode; + uint32_t Priority; + uint32_t Mem2Mem; +} DMA_InitType; + +typedef struct { + __IO uint32_t CHCFG; + __IO uint32_t TXNUM; + __IO uint32_t PADDR; + __IO uint32_t MADDR; + __IO uint32_t CHSEL; +} DMA_ChannelType; + +#define DMA_DIR_PERIPH_DST ((uint32_t)0x00000010) +#define DMA_DIR_PERIPH_SRC ((uint32_t)0x00000000) + +#define DMA_PERIPH_INC_ENABLE ((uint32_t)0x00000040) +#define DMA_PERIPH_INC_DISABLE ((uint32_t)0x00000000) + +#define DMA_MEM_INC_ENABLE ((uint32_t)0x00000080) +#define DMA_MEM_INC_DISABLE ((uint32_t)0x00000000) + +#define DMA_PERIPH_DATA_SIZE_BYTE ((uint32_t)0x00000000) +#define DMA_PERIPH_DATA_SIZE_HALFWORD ((uint32_t)0x00000100) +#define DMA_PERIPH_DATA_SIZE_WORD ((uint32_t)0x00000200) + +#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000) +#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00000400) +#define DMA_MemoryDataSize_Word ((uint32_t)0x00000800) + +#define DMA_MODE_CIRCULAR ((uint32_t)0x00000020) +#define DMA_MODE_NORMAL ((uint32_t)0x00000000) + +#define DMA_M2M_ENABLE ((uint32_t)0x00004000) +#define DMA_M2M_DISABLE ((uint32_t)0x00000000) + +#define RCC_AHB_PERIPH_DMA1 ((uint32_t)0x00000001) +#define RCC_AHB_PERIPH_DMA2 ((uint32_t)0x00000002) + +/******************* Bit definition for DMA_CHCFG1 register *******************/ +#define DMA_CHCFG1_CHEN ((uint16_t)0x0001) //!< Channel enable +#define DMA_CHCFG1_TXCIE ((uint16_t)0x0002) //!< Transfer complete interrupt enable +#define DMA_CHCFG1_HTXIE ((uint16_t)0x0004) //!< Half Transfer interrupt enable +#define DMA_CHCFG1_ERRIE ((uint16_t)0x0008) //!< Transfer error interrupt enable +#define DMA_CHCFG1_DIR ((uint16_t)0x0010) //!< Data transfer direction +#define DMA_CHCFG1_CIRC ((uint16_t)0x0020) //!< Circular mode +#define DMA_CHCFG1_PINC ((uint16_t)0x0040) //!< Peripheral increment mode +#define DMA_CHCFG1_MINC ((uint16_t)0x0080) //!< Memory increment mode + +#define NS_DMA1_BASE (0x40020000) +#define DMA1_CH1_BASE (NS_DMA1_BASE + 0x0008) +#define DMA1_CH2_BASE (NS_DMA1_BASE + 0x001C) +#define DMA1_CH3_BASE (NS_DMA1_BASE + 0x0030) +#define DMA1_CH4_BASE (NS_DMA1_BASE + 0x0044) +#define DMA1_CH5_BASE (NS_DMA1_BASE + 0x0058) +#define DMA1_CH6_BASE (NS_DMA1_BASE + 0x006C) +#define DMA1_CH7_BASE (NS_DMA1_BASE + 0x0080) +#define DMA1_CH8_BASE (NS_DMA1_BASE + 0x0094) + +#define NS_DMA2_BASE (0x40020400) +#define DMA2_CH1_BASE (NS_DMA2_BASE + 0x008) +#define DMA2_CH2_BASE (NS_DMA2_BASE + 0x01C) +#define DMA2_CH3_BASE (NS_DMA2_BASE + 0x0030) +#define DMA2_CH4_BASE (NS_DMA2_BASE + 0x0044) +#define DMA2_CH5_BASE (NS_DMA2_BASE + 0x0058) +#define DMA2_CH6_BASE (NS_DMA2_BASE + 0x006C) +#define DMA2_CH7_BASE (NS_DMA2_BASE + 0x0080) +#define DMA2_CH8_BASE (NS_DMA2_BASE + 0x0094) + +#define DMA1 ((DMA_Module*)NS_DMA1_BASE) +#define DMA2 ((DMA_Module*)NS_DMA2_BASE) +#define DMA1_CH1 ((DMA_ChannelType*)DMA1_CH1_BASE) +#define DMA1_CH2 ((DMA_ChannelType*)DMA1_CH2_BASE) +#define DMA1_CH3 ((DMA_ChannelType*)DMA1_CH3_BASE) +#define DMA1_CH4 ((DMA_ChannelType*)DMA1_CH4_BASE) +#define DMA1_CH5 ((DMA_ChannelType*)DMA1_CH5_BASE) +#define DMA1_CH6 ((DMA_ChannelType*)DMA1_CH6_BASE) +#define DMA1_CH7 ((DMA_ChannelType*)DMA1_CH7_BASE) +#define DMA1_CH8 ((DMA_ChannelType*)DMA1_CH8_BASE) +#define DMA2_CH1 ((DMA_ChannelType*)DMA2_CH1_BASE) +#define DMA2_CH2 ((DMA_ChannelType*)DMA2_CH2_BASE) +#define DMA2_CH3 ((DMA_ChannelType*)DMA2_CH3_BASE) +#define DMA2_CH4 ((DMA_ChannelType*)DMA2_CH4_BASE) +#define DMA2_CH5 ((DMA_ChannelType*)DMA2_CH5_BASE) +#define DMA2_CH6 ((DMA_ChannelType*)DMA2_CH6_BASE) +#define DMA2_CH7 ((DMA_ChannelType*)DMA2_CH7_BASE) +#define DMA2_CH8 ((DMA_ChannelType*)DMA2_CH8_BASE) + +/******************************************************************************/ +/* */ +/* DMA Controller */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for DMA_INTSTS register ********************/ +#define DMA_INTSTS_GLBF1 ((uint32_t)0x00000001) //!< Channel 1 Global interrupt flag +#define DMA_INTSTS_TXCF1 ((uint32_t)0x00000002) //!< Channel 1 Transfer Complete flag +#define DMA_INTSTS_HTXF1 ((uint32_t)0x00000004) //!< Channel 1 Half Transfer flag +#define DMA_INTSTS_ERRF1 ((uint32_t)0x00000008) //!< Channel 1 Transfer Error flag +#define DMA_INTSTS_GLBF2 ((uint32_t)0x00000010) //!< Channel 2 Global interrupt flag +#define DMA_INTSTS_TXCF2 ((uint32_t)0x00000020) //!< Channel 2 Transfer Complete flag +#define DMA_INTSTS_HTXF2 ((uint32_t)0x00000040) //!< Channel 2 Half Transfer flag +#define DMA_INTSTS_ERRF2 ((uint32_t)0x00000080) //!< Channel 2 Transfer Error flag +#define DMA_INTSTS_GLBF3 ((uint32_t)0x00000100) //!< Channel 3 Global interrupt flag +#define DMA_INTSTS_TXCF3 ((uint32_t)0x00000200) //!< Channel 3 Transfer Complete flag +#define DMA_INTSTS_HTXF3 ((uint32_t)0x00000400) //!< Channel 3 Half Transfer flag +#define DMA_INTSTS_ERRF3 ((uint32_t)0x00000800) //!< Channel 3 Transfer Error flag +#define DMA_INTSTS_GLBF4 ((uint32_t)0x00001000) //!< Channel 4 Global interrupt flag +#define DMA_INTSTS_TXCF4 ((uint32_t)0x00002000) //!< Channel 4 Transfer Complete flag +#define DMA_INTSTS_HTXF4 ((uint32_t)0x00004000) //!< Channel 4 Half Transfer flag +#define DMA_INTSTS_ERRF4 ((uint32_t)0x00008000) //!< Channel 4 Transfer Error flag +#define DMA_INTSTS_GLBF5 ((uint32_t)0x00010000) //!< Channel 5 Global interrupt flag +#define DMA_INTSTS_TXCF5 ((uint32_t)0x00020000) //!< Channel 5 Transfer Complete flag +#define DMA_INTSTS_HTXF5 ((uint32_t)0x00040000) //!< Channel 5 Half Transfer flag +#define DMA_INTSTS_ERRF5 ((uint32_t)0x00080000) //!< Channel 5 Transfer Error flag +#define DMA_INTSTS_GLBF6 ((uint32_t)0x00100000) //!< Channel 6 Global interrupt flag +#define DMA_INTSTS_TXCF6 ((uint32_t)0x00200000) //!< Channel 6 Transfer Complete flag +#define DMA_INTSTS_HTXF6 ((uint32_t)0x00400000) //!< Channel 6 Half Transfer flag +#define DMA_INTSTS_ERRF6 ((uint32_t)0x00800000) //!< Channel 6 Transfer Error flag +#define DMA_INTSTS_GLBF7 ((uint32_t)0x01000000) //!< Channel 7 Global interrupt flag +#define DMA_INTSTS_TXCF7 ((uint32_t)0x02000000) //!< Channel 7 Transfer Complete flag +#define DMA_INTSTS_HTXF7 ((uint32_t)0x04000000) //!< Channel 7 Half Transfer flag +#define DMA_INTSTS_ERRF7 ((uint32_t)0x08000000) //!< Channel 7 Transfer Error flag +#define DMA_INTSTS_GLBF8 ((uint32_t)0x10000000) //!< Channel 7 Global interrupt flag +#define DMA_INTSTS_TXCF8 ((uint32_t)0x20000000) //!< Channel 7 Transfer Complete flag +#define DMA_INTSTS_HTXF8 ((uint32_t)0x40000000) //!< Channel 7 Half Transfer flag +#define DMA_INTSTS_ERRF8 ((uint32_t)0x80000000) //!< Channel 7 Transfer Error flag + +/******************* Bit definition for DMA_INTCLR register *******************/ +#define DMA_INTCLR_CGLBF1 ((uint32_t)0x00000001) //!< Channel 1 Global interrupt clear +#define DMA_INTCLR_CTXCF1 ((uint32_t)0x00000002) //!< Channel 1 Transfer Complete clear +#define DMA_INTCLR_CHTXF1 ((uint32_t)0x00000004) //!< Channel 1 Half Transfer clear +#define DMA_INTCLR_CERRF1 ((uint32_t)0x00000008) //!< Channel 1 Transfer Error clear +#define DMA_INTCLR_CGLBF2 ((uint32_t)0x00000010) //!< Channel 2 Global interrupt clear +#define DMA_INTCLR_CTXCF2 ((uint32_t)0x00000020) //!< Channel 2 Transfer Complete clear +#define DMA_INTCLR_CHTXF2 ((uint32_t)0x00000040) //!< Channel 2 Half Transfer clear +#define DMA_INTCLR_CERRF2 ((uint32_t)0x00000080) //!< Channel 2 Transfer Error clear +#define DMA_INTCLR_CGLBF3 ((uint32_t)0x00000100) //!< Channel 3 Global interrupt clear +#define DMA_INTCLR_CTXCF3 ((uint32_t)0x00000200) //!< Channel 3 Transfer Complete clear +#define DMA_INTCLR_CHTXF3 ((uint32_t)0x00000400) //!< Channel 3 Half Transfer clear +#define DMA_INTCLR_CERRF3 ((uint32_t)0x00000800) //!< Channel 3 Transfer Error clear +#define DMA_INTCLR_CGLBF4 ((uint32_t)0x00001000) //!< Channel 4 Global interrupt clear +#define DMA_INTCLR_CTXCF4 ((uint32_t)0x00002000) //!< Channel 4 Transfer Complete clear +#define DMA_INTCLR_CHTXF4 ((uint32_t)0x00004000) //!< Channel 4 Half Transfer clear +#define DMA_INTCLR_CERRF4 ((uint32_t)0x00008000) //!< Channel 4 Transfer Error clear +#define DMA_INTCLR_CGLBF5 ((uint32_t)0x00010000) //!< Channel 5 Global interrupt clear +#define DMA_INTCLR_CTXCF5 ((uint32_t)0x00020000) //!< Channel 5 Transfer Complete clear +#define DMA_INTCLR_CHTXF5 ((uint32_t)0x00040000) //!< Channel 5 Half Transfer clear +#define DMA_INTCLR_CERRF5 ((uint32_t)0x00080000) //!< Channel 5 Transfer Error clear +#define DMA_INTCLR_CGLBF6 ((uint32_t)0x00100000) //!< Channel 6 Global interrupt clear +#define DMA_INTCLR_CTXCF6 ((uint32_t)0x00200000) //!< Channel 6 Transfer Complete clear +#define DMA_INTCLR_CHTXF6 ((uint32_t)0x00400000) //!< Channel 6 Half Transfer clear +#define DMA_INTCLR_CERRF6 ((uint32_t)0x00800000) //!< Channel 6 Transfer Error clear +#define DMA_INTCLR_CGLBF7 ((uint32_t)0x01000000) //!< Channel 7 Global interrupt clear +#define DMA_INTCLR_CTXCF7 ((uint32_t)0x02000000) //!< Channel 7 Transfer Complete clear +#define DMA_INTCLR_CHTXF7 ((uint32_t)0x04000000) //!< Channel 7 Half Transfer clear +#define DMA_INTCLR_CERRF7 ((uint32_t)0x08000000) //!< Channel 7 Transfer Error clear +#define DMA_INTCLR_CGLBF8 ((uint32_t)0x10000000) //!< Channel 7 Global interrupt clear +#define DMA_INTCLR_CTXCF8 ((uint32_t)0x20000000) //!< Channel 7 Transfer Complete clear +#define DMA_INTCLR_CHTXF8 ((uint32_t)0x40000000) //!< Channel 7 Half Transfer clear +#define DMA_INTCLR_CERRF8 ((uint32_t)0x80000000) //!< Channel 7 Transfer Error clear + +/******************* Bit definition for DMA_CHCFG1 register *******************/ +#define DMA_CHCFG1_CHEN ((uint16_t)0x0001) //!< Channel enable +#define DMA_CHCFG1_TXCIE ((uint16_t)0x0002) //!< Transfer complete interrupt enable +#define DMA_CHCFG1_HTXIE ((uint16_t)0x0004) //!< Half Transfer interrupt enable +#define DMA_CHCFG1_ERRIE ((uint16_t)0x0008) //!< Transfer error interrupt enable +#define DMA_CHCFG1_DIR ((uint16_t)0x0010) //!< Data transfer direction +#define DMA_CHCFG1_CIRC ((uint16_t)0x0020) //!< Circular mode +#define DMA_CHCFG1_PINC ((uint16_t)0x0040) //!< Peripheral increment mode +#define DMA_CHCFG1_MINC ((uint16_t)0x0080) //!< Memory increment mode + +#define DMA_CHCFG1_PSIZE ((uint16_t)0x0300) //!< PSIZE[1:0] bits (Peripheral size) +#define DMA_CHCFG1_PSIZE_0 ((uint16_t)0x0100) //!< Bit 0 +#define DMA_CHCFG1_PSIZE_1 ((uint16_t)0x0200) //!< Bit 1 + +#define DMA_CHCFG1_MSIZE ((uint16_t)0x0C00) //!< MSIZE[1:0] bits (Memory size) +#define DMA_CHCFG1_MSIZE_0 ((uint16_t)0x0400) //!< Bit 0 +#define DMA_CHCFG1_MSIZE_1 ((uint16_t)0x0800) //!< Bit 1 + +#define DMA_CHCFG1_PRIOLVL ((uint16_t)0x3000) //!< PL[1:0] bits(Channel Priority level) +#define DMA_CHCFG1_PRIOLVL_0 ((uint16_t)0x1000) //!< Bit 0 +#define DMA_CHCFG1_PRIOLVL_1 ((uint16_t)0x2000) //!< Bit 1 + +#define DMA_CHCFG1_MEM2MEM ((uint16_t)0x4000) //!< Memory to memory mode + +/******************* Bit definition for DMA_CHCFG2 register *******************/ +#define DMA_CHCFG2_CHEN ((uint16_t)0x0001) //!< Channel enable +#define DMA_CHCFG2_TXCIE ((uint16_t)0x0002) //!< Transfer complete interrupt enable +#define DMA_CHCFG2_HTXIE ((uint16_t)0x0004) //!< Half Transfer interrupt enable +#define DMA_CHCFG2_ERRIE ((uint16_t)0x0008) //!< Transfer error interrupt enable +#define DMA_CHCFG2_DIR ((uint16_t)0x0010) //!< Data transfer direction +#define DMA_CHCFG2_CIRC ((uint16_t)0x0020) //!< Circular mode +#define DMA_CHCFG2_PINC ((uint16_t)0x0040) //!< Peripheral increment mode +#define DMA_CHCFG2_MINC ((uint16_t)0x0080) //!< Memory increment mode + +#define DMA_CHCFG2_PSIZE ((uint16_t)0x0300) //!< PSIZE[1:0] bits (Peripheral size) +#define DMA_CHCFG2_PSIZE_0 ((uint16_t)0x0100) //!< Bit 0 +#define DMA_CHCFG2_PSIZE_1 ((uint16_t)0x0200) //!< Bit 1 + +#define DMA_CHCFG2_MSIZE ((uint16_t)0x0C00) //!< MSIZE[1:0] bits (Memory size) +#define DMA_CHCFG2_MSIZE_0 ((uint16_t)0x0400) //!< Bit 0 +#define DMA_CHCFG2_MSIZE_1 ((uint16_t)0x0800) //!< Bit 1 + +#define DMA_CHCFG2_PRIOLVL ((uint16_t)0x3000) //!< PL[1:0] bits (Channel Priority level) +#define DMA_CHCFG2_PRIOLVL_0 ((uint16_t)0x1000) //!< Bit 0 +#define DMA_CHCFG2_PRIOLVL_1 ((uint16_t)0x2000) //!< Bit 1 + +#define DMA_CHCFG2_MEM2MEM ((uint16_t)0x4000) //!< Memory to memory mode + +/******************* Bit definition for DMA_CHCFG3 register *******************/ +#define DMA_CHCFG3_CHEN ((uint16_t)0x0001) //!< Channel enable +#define DMA_CHCFG3_TXCIE ((uint16_t)0x0002) //!< Transfer complete interrupt enable +#define DMA_CHCFG3_HTXIE ((uint16_t)0x0004) //!< Half Transfer interrupt enable +#define DMA_CHCFG3_ERRIE ((uint16_t)0x0008) //!< Transfer error interrupt enable +#define DMA_CHCFG3_DIR ((uint16_t)0x0010) //!< Data transfer direction +#define DMA_CHCFG3_CIRC ((uint16_t)0x0020) //!< Circular mode +#define DMA_CHCFG3_PINC ((uint16_t)0x0040) //!< Peripheral increment mode +#define DMA_CHCFG3_MINC ((uint16_t)0x0080) //!< Memory increment mode + +#define DMA_CHCFG3_PSIZE ((uint16_t)0x0300) //!< PSIZE[1:0] bits (Peripheral size) +#define DMA_CHCFG3_PSIZE_0 ((uint16_t)0x0100) //!< Bit 0 +#define DMA_CHCFG3_PSIZE_1 ((uint16_t)0x0200) //!< Bit 1 + +#define DMA_CHCFG3_MSIZE ((uint16_t)0x0C00) //!< MSIZE[1:0] bits (Memory size) +#define DMA_CHCFG3_MSIZE_0 ((uint16_t)0x0400) //!< Bit 0 +#define DMA_CHCFG3_MSIZE_1 ((uint16_t)0x0800) //!< Bit 1 + +#define DMA_CHCFG3_PRIOLVL ((uint16_t)0x3000) //!< PL[1:0] bits (Channel Priority level) +#define DMA_CHCFG3_PRIOLVL_0 ((uint16_t)0x1000) //!< Bit 0 +#define DMA_CHCFG3_PRIOLVL_1 ((uint16_t)0x2000) //!< Bit 1 + +#define DMA_CHCFG3_MEM2MEM ((uint16_t)0x4000) //!< Memory to memory mode + +/*!<****************** Bit definition for DMA_CHCFG4 register *******************/ +#define DMA_CHCFG4_CHEN ((uint16_t)0x0001) //!< Channel enable +#define DMA_CHCFG4_TXCIE ((uint16_t)0x0002) //!< Transfer complete interrupt enable +#define DMA_CHCFG4_HTXIE ((uint16_t)0x0004) //!< Half Transfer interrupt enable +#define DMA_CHCFG4_ERRIE ((uint16_t)0x0008) //!< Transfer error interrupt enable +#define DMA_CHCFG4_DIR ((uint16_t)0x0010) //!< Data transfer direction +#define DMA_CHCFG4_CIRC ((uint16_t)0x0020) //!< Circular mode +#define DMA_CHCFG4_PINC ((uint16_t)0x0040) //!< Peripheral increment mode +#define DMA_CHCFG4_MINC ((uint16_t)0x0080) //!< Memory increment mode + +#define DMA_CHCFG4_PSIZE ((uint16_t)0x0300) //!< PSIZE[1:0] bits (Peripheral size) +#define DMA_CHCFG4_PSIZE_0 ((uint16_t)0x0100) //!< Bit 0 +#define DMA_CHCFG4_PSIZE_1 ((uint16_t)0x0200) //!< Bit 1 + +#define DMA_CHCFG4_MSIZE ((uint16_t)0x0C00) //!< MSIZE[1:0] bits (Memory size) +#define DMA_CHCFG4_MSIZE_0 ((uint16_t)0x0400) //!< Bit 0 +#define DMA_CHCFG4_MSIZE_1 ((uint16_t)0x0800) //!< Bit 1 + +#define DMA_CHCFG4_PRIOLVL ((uint16_t)0x3000) //!< PL[1:0] bits (Channel Priority level) +#define DMA_CHCFG4_PRIOLVL_0 ((uint16_t)0x1000) //!< Bit 0 +#define DMA_CHCFG4_PRIOLVL_1 ((uint16_t)0x2000) //!< Bit 1 + +#define DMA_CHCFG4_MEM2MEM ((uint16_t)0x4000) //!< Memory to memory mode + +/****************** Bit definition for DMA_CHCFG5 register *******************/ +#define DMA_CHCFG5_CHEN ((uint16_t)0x0001) //!< Channel enable +#define DMA_CHCFG5_TXCIE ((uint16_t)0x0002) //!< Transfer complete interrupt enable +#define DMA_CHCFG5_HTXIE ((uint16_t)0x0004) //!< Half Transfer interrupt enable +#define DMA_CHCFG5_ERRIE ((uint16_t)0x0008) //!< Transfer error interrupt enable +#define DMA_CHCFG5_DIR ((uint16_t)0x0010) //!< Data transfer direction +#define DMA_CHCFG5_CIRC ((uint16_t)0x0020) //!< Circular mode +#define DMA_CHCFG5_PINC ((uint16_t)0x0040) //!< Peripheral increment mode +#define DMA_CHCFG5_MINC ((uint16_t)0x0080) //!< Memory increment mode + +#define DMA_CHCFG5_PSIZE ((uint16_t)0x0300) //!< PSIZE[1:0] bits (Peripheral size) +#define DMA_CHCFG5_PSIZE_0 ((uint16_t)0x0100) //!< Bit 0 +#define DMA_CHCFG5_PSIZE_1 ((uint16_t)0x0200) //!< Bit 1 + +#define DMA_CHCFG5_MSIZE ((uint16_t)0x0C00) //!< MSIZE[1:0] bits (Memory size) +#define DMA_CHCFG5_MSIZE_0 ((uint16_t)0x0400) //!< Bit 0 +#define DMA_CHCFG5_MSIZE_1 ((uint16_t)0x0800) //!< Bit 1 + +#define DMA_CHCFG5_PRIOLVL ((uint16_t)0x3000) //!< PL[1:0] bits (Channel Priority level) +#define DMA_CHCFG5_PRIOLVL_0 ((uint16_t)0x1000) //!< Bit 0 +#define DMA_CHCFG5_PRIOLVL_1 ((uint16_t)0x2000) //!< Bit 1 + +#define DMA_CHCFG5_MEM2MEM ((uint16_t)0x4000) //!< Memory to memory mode enable + +/******************* Bit definition for DMA_CHCFG6 register *******************/ +#define DMA_CHCFG6_CHEN ((uint16_t)0x0001) //!< Channel enable +#define DMA_CHCFG6_TXCIE ((uint16_t)0x0002) //!< Transfer complete interrupt enable +#define DMA_CHCFG6_HTXIE ((uint16_t)0x0004) //!< Half Transfer interrupt enable +#define DMA_CHCFG6_ERRIE ((uint16_t)0x0008) //!< Transfer error interrupt enable +#define DMA_CHCFG6_DIR ((uint16_t)0x0010) //!< Data transfer direction +#define DMA_CHCFG6_CIRC ((uint16_t)0x0020) //!< Circular mode +#define DMA_CHCFG6_PINC ((uint16_t)0x0040) //!< Peripheral increment mode +#define DMA_CHCFG6_MINC ((uint16_t)0x0080) //!< Memory increment mode + +#define DMA_CHCFG6_PSIZE ((uint16_t)0x0300) //!< PSIZE[1:0] bits (Peripheral size) +#define DMA_CHCFG6_PSIZE_0 ((uint16_t)0x0100) //!< Bit 0 +#define DMA_CHCFG6_PSIZE_1 ((uint16_t)0x0200) //!< Bit 1 + +#define DMA_CHCFG6_MSIZE ((uint16_t)0x0C00) //!< MSIZE[1:0] bits (Memory size) +#define DMA_CHCFG6_MSIZE_0 ((uint16_t)0x0400) //!< Bit 0 +#define DMA_CHCFG6_MSIZE_1 ((uint16_t)0x0800) //!< Bit 1 + +#define DMA_CHCFG6_PRIOLVL ((uint16_t)0x3000) //!< PL[1:0] bits (Channel Priority level) +#define DMA_CHCFG6_PRIOLVL_0 ((uint16_t)0x1000) //!< Bit 0 +#define DMA_CHCFG6_PRIOLVL_1 ((uint16_t)0x2000) //!< Bit 1 + +#define DMA_CHCFG6_MEM2MEM ((uint16_t)0x4000) //!< Memory to memory mode + +/******************* Bit definition for DMA_CHCFG7 register *******************/ +#define DMA_CHCFG7_CHEN ((uint16_t)0x0001) //!< Channel enable +#define DMA_CHCFG7_TXCIE ((uint16_t)0x0002) //!< Transfer complete interrupt enable +#define DMA_CHCFG7_HTXIE ((uint16_t)0x0004) //!< Half Transfer interrupt enable +#define DMA_CHCFG7_ERRIE ((uint16_t)0x0008) //!< Transfer error interrupt enable +#define DMA_CHCFG7_DIR ((uint16_t)0x0010) //!< Data transfer direction +#define DMA_CHCFG7_CIRC ((uint16_t)0x0020) //!< Circular mode +#define DMA_CHCFG7_PINC ((uint16_t)0x0040) //!< Peripheral increment mode +#define DMA_CHCFG7_MINC ((uint16_t)0x0080) //!< Memory increment mode + +#define DMA_CHCFG7_PSIZE , ((uint16_t)0x0300) //!< PSIZE[1:0] bits (Peripheral size) +#define DMA_CHCFG7_PSIZE_0 ((uint16_t)0x0100) //!< Bit 0 +#define DMA_CHCFG7_PSIZE_1 ((uint16_t)0x0200) //!< Bit 1 + +#define DMA_CHCFG7_MSIZE ((uint16_t)0x0C00) //!< MSIZE[1:0] bits (Memory size) +#define DMA_CHCFG7_MSIZE_0 ((uint16_t)0x0400) //!< Bit 0 +#define DMA_CHCFG7_MSIZE_1 ((uint16_t)0x0800) //!< Bit 1 + +#define DMA_CHCFG7_PRIOLVL ((uint16_t)0x3000) //!< PL[1:0] bits (Channel Priority level) +#define DMA_CHCFG7_PRIOLVL_0 ((uint16_t)0x1000) //!< Bit 0 +#define DMA_CHCFG7_PRIOLVL_1 ((uint16_t)0x2000) //!< Bit 1 + +#define DMA_CHCFG7_MEM2MEM ((uint16_t)0x4000) //!< Memory to memory mode enable + +/******************* Bit definition for DMA_CHCFG8 register *******************/ +#define DMA_CHCFG8_CHEN ((uint16_t)0x0001) //!< Channel enable +#define DMA_CHCFG8_TXCIE ((uint16_t)0x0002) //!< Transfer complete interrupt enable +#define DMA_CHCFG8_HTXIE ((uint16_t)0x0004) //!< Half Transfer interrupt enable +#define DMA_CHCFG8_ERRIE ((uint16_t)0x0008) //!< Transfer error interrupt enable +#define DMA_CHCFG8_DIR ((uint16_t)0x0010) //!< Data transfer direction +#define DMA_CHCFG8_CIRC ((uint16_t)0x0020) //!< Circular mode +#define DMA_CHCFG8_PINC ((uint16_t)0x0040) //!< Peripheral increment mode +#define DMA_CHCFG8_MINC ((uint16_t)0x0080) //!< Memory increment mode + +#define DMA_CHCFG8_PSIZE , ((uint16_t)0x0300) //!< PSIZE[1:0] bits (Peripheral size) +#define DMA_CHCFG8_PSIZE_0 ((uint16_t)0x0100) //!< Bit 0 +#define DMA_CHCFG8_PSIZE_1 ((uint16_t)0x0200) //!< Bit 1 + +#define DMA_CHCFG8_MSIZE ((uint16_t)0x0C00) //!< MSIZE[1:0] bits (Memory size) +#define DMA_CHCFG8_MSIZE_0 ((uint16_t)0x0400) //!< Bit 0 +#define DMA_CHCFG8_MSIZE_1 ((uint16_t)0x0800) //!< Bit 1 + +#define DMA_CHCFG8_PRIOLVL ((uint16_t)0x3000) //!< PL[1:0] bits (Channel Priority level) +#define DMA_CHCFG8_PRIOLVL_0 ((uint16_t)0x1000) //!< Bit 0 +#define DMA_CHCFG8_PRIOLVL_1 ((uint16_t)0x2000) //!< Bit 1 + +#define DMA_CHCFG8_MEM2MEM ((uint16_t)0x4000) //!< Memory to memory mode enable + +/****************** Bit definition for DMA_TXNUM1 register ******************/ +#define DMA_TXNUM1_NDTX ((uint16_t)0xFFFF) //!< Number of data to Transfer + +/****************** Bit definition for DMA_TXNUM2 register ******************/ +#define DMA_TXNUM2_NDTX ((uint16_t)0xFFFF) //!< Number of data to Transfer + +/****************** Bit definition for DMA_TXNUM3 register ******************/ +#define DMA_TXNUM3_NDTX ((uint16_t)0xFFFF) //!< Number of data to Transfer + +/****************** Bit definition for DMA_TXNUM4 register ******************/ +#define DMA_TXNUM4_NDTX ((uint16_t)0xFFFF) //!< Number of data to Transfer + +/****************** Bit definition for DMA_TXNUM5 register ******************/ +#define DMA_TXNUM5_NDTX ((uint16_t)0xFFFF) //!< Number of data to Transfer + +/****************** Bit definition for DMA_TXNUM6 register ******************/ +#define DMA_TXNUM6_NDTX ((uint16_t)0xFFFF) //!< Number of data to Transfer + +/****************** Bit definition for DMA_TXNUM7 register ******************/ +#define DMA_TXNUM7_NDTX ((uint16_t)0xFFFF) //!< Number of data to Transfer + +/****************** Bit definition for DMA_TXNUM8 register ******************/ +#define DMA_TXNUM8_NDTX ((uint16_t)0xFFFF) //!< Number of data to Transfer + +/****************** Bit definition for DMA_PADDR1 register *******************/ +#define DMA_PADDR1_ADDR ((uint32_t)0xFFFFFFFF) //!< Peripheral Address + +/****************** Bit definition for DMA_PADDR2 register *******************/ +#define DMA_PADDR2_ADDR ((uint32_t)0xFFFFFFFF) //!< Peripheral Address + +/****************** Bit definition for DMA_PADDR3 register *******************/ +#define DMA_PADDR3_ADDR ((uint32_t)0xFFFFFFFF) //!< Peripheral Address + +/****************** Bit definition for DMA_PADDR4 register *******************/ +#define DMA_PADDR4_ADDR ((uint32_t)0xFFFFFFFF) //!< Peripheral Address + +/****************** Bit definition for DMA_PADDR5 register *******************/ +#define DMA_PADDR5_ADDR ((uint32_t)0xFFFFFFFF) //!< Peripheral Address + +/****************** Bit definition for DMA_PADDR6 register *******************/ +#define DMA_PADDR6_ADDR ((uint32_t)0xFFFFFFFF) //!< Peripheral Address + +/****************** Bit definition for DMA_PADDR7 register *******************/ +#define DMA_PADDR7_ADDR ((uint32_t)0xFFFFFFFF) //!< Peripheral Address + +/****************** Bit definition for DMA_PADDR8 register *******************/ +#define DMA_PADDR8_ADDR ((uint32_t)0xFFFFFFFF) //!< Peripheral Address + +/****************** Bit definition for DMA_MADDR1 register *******************/ +#define DMA_MADDR1_ADDR ((uint32_t)0xFFFFFFFF) //!< Memory Address + +/****************** Bit definition for DMA_MADDR2 register *******************/ +#define DMA_MADDR2_ADDR ((uint32_t)0xFFFFFFFF) //!< Memory Address + +/****************** Bit definition for DMA_MADDR3 register *******************/ +#define DMA_MADDR3_ADDR ((uint32_t)0xFFFFFFFF) //!< Memory Address + +/****************** Bit definition for DMA_MADDR4 register *******************/ +#define DMA_MADDR4_ADDR ((uint32_t)0xFFFFFFFF) //!< Memory Address + +/****************** Bit definition for DMA_MADDR5 register *******************/ +#define DMA_MADDR5_ADDR ((uint32_t)0xFFFFFFFF) //!< Memory Address + +/****************** Bit definition for DMA_MADDR6 register *******************/ +#define DMA_MADDR6_ADDR ((uint32_t)0xFFFFFFFF) //!< Memory Address + +/****************** Bit definition for DMA_MADDR7 register *******************/ +#define DMA_MADDR7_ADDR ((uint32_t)0xFFFFFFFF) //!< Memory Address + +/****************** Bit definition for DMA_MADDR8 register *******************/ +#define DMA_MADDR8_ADDR ((uint32_t)0xFFFFFFFF) //!< Memory Address + +/****************** Bit definition for DMA_CHSEL1 register *******************/ +#define DMA_CHSEL1_CH_SEL ((uint32_t)0x0000003F) //!< Channel Select + +/****************** Bit definition for DMA_CHSEL2 register *******************/ +#define DMA_CHSEL2_CH_SEL ((uint32_t)0x0000003F) //!< Channel Select + +/****************** Bit definition for DMA_CHSEL3 register *******************/ +#define DMA_CHSEL3_CH_SEL ((uint32_t)0x0000003F) //!< Channel Select + +/****************** Bit definition for DMA_CHSEL4 register *******************/ +#define DMA_CHSEL4_CH_SEL ((uint32_t)0x0000003F) //!< Channel Select + +/****************** Bit definition for DMA_CHSEL5 register *******************/ +#define DMA_CHSEL5_CH_SEL ((uint32_t)0x0000003F) //!< Channel Select + +/****************** Bit definition for DMA_CHSEL6 register *******************/ +#define DMA_CHSEL6_CH_SEL ((uint32_t)0x0000003F) //!< Channel Select + +/****************** Bit definition for DMA_CHSEL7 register *******************/ +#define DMA_CHSEL7_CH_SEL ((uint32_t)0x0000003F) //!< Channel Select + +/****************** Bit definition for DMA_CHSEL8 register *******************/ +#define DMA_CHSEL8_CH_SEL ((uint32_t)0x0000003F) //!< Channel Select + +/****************** Bit definition for DMA_CHMAPEN register *******************/ +#define DMA_CHMAPEN_MAP_EN ((uint32_t)0x00000001) //!< Channel Map Enable + +/* DMA1 Channelx interrupt pending bit masks */ +#define DMA1_CH1_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF1 | DMA_INTSTS_TXCF1 | DMA_INTSTS_HTXF1 | DMA_INTSTS_ERRF1)) +#define DMA1_CH2_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF2 | DMA_INTSTS_TXCF2 | DMA_INTSTS_HTXF2 | DMA_INTSTS_ERRF2)) +#define DMA1_CH3_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF3 | DMA_INTSTS_TXCF3 | DMA_INTSTS_HTXF3 | DMA_INTSTS_ERRF3)) +#define DMA1_CH4_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF4 | DMA_INTSTS_TXCF4 | DMA_INTSTS_HTXF4 | DMA_INTSTS_ERRF4)) +#define DMA1_CH5_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF5 | DMA_INTSTS_TXCF5 | DMA_INTSTS_HTXF5 | DMA_INTSTS_ERRF5)) +#define DMA1_CH6_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF6 | DMA_INTSTS_TXCF6 | DMA_INTSTS_HTXF6 | DMA_INTSTS_ERRF6)) +#define DMA1_CH7_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF7 | DMA_INTSTS_TXCF7 | DMA_INTSTS_HTXF7 | DMA_INTSTS_ERRF7)) +#define DMA1_CH8_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF8 | DMA_INTSTS_TXCF8 | DMA_INTSTS_HTXF8 | DMA_INTSTS_ERRF8)) + +/* DMA2 Channelx interrupt pending bit masks */ +#define DMA2_CH1_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF1 | DMA_INTSTS_TXCF1 | DMA_INTSTS_HTXF1 | DMA_INTSTS_ERRF1)) +#define DMA2_CH2_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF2 | DMA_INTSTS_TXCF2 | DMA_INTSTS_HTXF2 | DMA_INTSTS_ERRF2)) +#define DMA2_CH3_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF3 | DMA_INTSTS_TXCF3 | DMA_INTSTS_HTXF3 | DMA_INTSTS_ERRF3)) +#define DMA2_CH4_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF4 | DMA_INTSTS_TXCF4 | DMA_INTSTS_HTXF4 | DMA_INTSTS_ERRF4)) +#define DMA2_CH5_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF5 | DMA_INTSTS_TXCF5 | DMA_INTSTS_HTXF5 | DMA_INTSTS_ERRF5)) +#define DMA2_CH6_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF6 | DMA_INTSTS_TXCF6 | DMA_INTSTS_HTXF6 | DMA_INTSTS_ERRF6)) +#define DMA2_CH7_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF7 | DMA_INTSTS_TXCF7 | DMA_INTSTS_HTXF7 | DMA_INTSTS_ERRF7)) +#define DMA2_CH8_INT_MASK ((uint32_t)(DMA_INTSTS_GLBF8 | DMA_INTSTS_TXCF8 | DMA_INTSTS_HTXF8 | DMA_INTSTS_ERRF8)) + +typedef struct { + __IO uint32_t INTSTS; + __IO uint32_t INTCLR; + __IO DMA_ChannelType DMA_Channel[8]; + __IO uint32_t CHMAPEN; +} DMA_Module; + +#define RCC_AHB_PERIPH_ADC1 ((uint32_t)0x00001000) +#define RCC_AHB_PERIPH_ADC2 ((uint32_t)0x00002000) +#define RCC_AHB_PERIPH_ADC3 ((uint32_t)0x00004000) +#define RCC_AHB_PERIPH_ADC4 ((uint32_t)0x00008000) + +void ADC_Init(ADC_Module* NS_ADCx, ADC_InitType* ADC_InitStruct); + +/**================================================================ + * ADC reset + ================================================================*/ +void ADC_DeInit(ADC_Module* NS_ADCx); + +/**================================================================ + * ADC module enable + ================================================================*/ +void ADC_Enable(ADC_Module* NS_ADCx, uint32_t Cmd); + +/**================================================================ + * Get the ADC status logo bit + ================================================================*/ +uint32_t ADC_GetFlagStatusNew(ADC_Module* NS_ADCx, uint8_t ADC_FLAG_NEW); + +/**================================================================ + * Open ADC calibration + ================================================================*/ +void ADC_StartCalibration(ADC_Module* NS_ADCx); + +/**================================================================ + * Enable ADC DMA + ================================================================*/ +void ADC_EnableDMA(ADC_Module* NS_ADCx, uint32_t Cmd); + +/**================================================================ + * Configure ADC interrupt enable enable + ================================================================*/ +void ADC_ConfigInt(ADC_Module* NS_ADCx, uint16_t ADC_IT, uint32_t Cmd); + +/**================================================================ + * Get ADC calibration status + ================================================================*/ +uint32_t ADC_GetCalibrationStatus(ADC_Module* NS_ADCx); + +/**================================================================ + * Configure the ADC channel + ================================================================*/ +void ADC_ConfigRegularChannel(ADC_Module* NS_ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); + +/**================================================================ + * Start ADC conversion + ================================================================*/ +void ADC_EnableSoftwareStartConv(ADC_Module* NS_ADCx, uint32_t Cmd); + +/**================================================================ + * Get the ADC status logo bit + ================================================================*/ +uint32_t ADC_GetFlagStatus(ADC_Module* NS_ADCx, uint8_t ADC_FLAG); + +/**================================================================ + * Clear status logo bit + ================================================================*/ +void ADC_ClearFlag(ADC_Module* NS_ADCx, uint8_t ADC_FLAG); + +/**================================================================ + * Get ADC sampling value + ================================================================*/ +uint16_t ADC_GetDat(ADC_Module* NS_ADCx); + +//////////////////////////////////////////////////////////////////////////////// + +typedef struct { + __IO uint32_t CR; /* Completely compatible */ + __IO uint32_t CFGR; /* Not compatible: ADC frequency is not set here */ + __IO uint32_t CIR; /* Completely compatible */ + + __IO uint32_t APB2RSTR; /* Completely compatible */ + __IO uint32_t APB1RSTR; /* Completely compatible */ + + __IO uint32_t AHBENR; /* Not compatible: ADC clock enables settings here */ + __IO uint32_t APB2ENR; /* Not compatible: ADC clock enables to be here */ + __IO uint32_t APB1ENR; /* compatible */ + __IO uint32_t BDCR; /* compatible */ + __IO uint32_t CSR; /* compatible */ + + + __IO uint32_t AHBRSTR; /* Not compatible, ADC reset here settings */ + __IO uint32_t CFGR2; /* Not compatible, ADC clock settings here */ + __IO uint32_t CFGR3; /* Not compatible, add a new register */ + +} RCC_TypeDef; + +#define RCC ((RCC_TypeDef *) ADC_RCC_BASE) + +/**================================================================ + * Initialize ADC clock + ================================================================*/ + +void enable_adc_clk(uint8_t cmd); + +/**================================================================ + * Initialize ADC peripheral parameters + ================================================================*/ +void ADC_Initial(ADC_Module* NS_ADCx); + +/**================================================================ + * Single independent sampling + ================================================================*/ +uint16_t ADC_GetData(ADC_Module* NS_ADCx, uint8_t ADC_Channel); + +void DMA_DeInit(DMA_ChannelType* DMAyChx); + +#define CCR_CLEAR_Mask ((uint32_t)0xFFFF800F) + +void DMA_Init(DMA_ChannelType* DMAyChx, DMA_InitType* DMA_InitParam); + +void DMA_EnableChannel(DMA_ChannelType* DMAyChx, uint32_t Cmd); + +#define USE_ADC NS_ADC2 +#define USE_DMA_CH DMA1_CH8 + +/**================================================================ + * Initialize the DMA of ADC + ================================================================*/ +void ADC_DMA_init(); diff --git a/Marlin/src/HAL/STM32F1/MarlinSerial.cpp b/Marlin/src/HAL/STM32F1/MarlinSerial.cpp index 8c468e9609f8..3b26b630df22 100644 --- a/Marlin/src/HAL/STM32F1/MarlinSerial.cpp +++ b/Marlin/src/HAL/STM32F1/MarlinSerial.cpp @@ -28,7 +28,7 @@ // Copied from ~/.platformio/packages/framework-arduinoststm32-maple/STM32F1/system/libmaple/usart_private.h // Changed to handle Emergency Parser -static __always_inline void my_usart_irq(ring_buffer *rb, ring_buffer *wb, usart_reg_map *regs, MSerialT &serial) { +FORCE_INLINE void my_usart_irq(ring_buffer *rb, ring_buffer *wb, usart_reg_map *regs, MSerialT &serial) { /* Handle RXNEIE and TXEIE interrupts. * RXNE signifies availability of a byte in DR. * diff --git a/Marlin/src/HAL/STM32F1/adc.h b/Marlin/src/HAL/STM32F1/adc.h new file mode 100644 index 000000000000..25f4a7ce16d1 --- /dev/null +++ b/Marlin/src/HAL/STM32F1/adc.h @@ -0,0 +1,57 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * HAL for stm32duino.com based on Libmaple and compatible (STM32F1) + * + * adc.h - Define enumerated indices for enabled ADC Features + */ + +#include "../../inc/MarlinConfig.h" + +enum ADCIndex : uint8_t { + OPTITEM(HAS_TEMP_ADC_0, TEMP_0 ) + OPTITEM(HAS_TEMP_ADC_1, TEMP_1 ) + OPTITEM(HAS_TEMP_ADC_2, TEMP_2 ) + OPTITEM(HAS_TEMP_ADC_3, TEMP_3 ) + OPTITEM(HAS_TEMP_ADC_4, TEMP_4 ) + OPTITEM(HAS_TEMP_ADC_5, TEMP_5 ) + OPTITEM(HAS_TEMP_ADC_6, TEMP_6 ) + OPTITEM(HAS_TEMP_ADC_7, TEMP_7 ) + OPTITEM(HAS_TEMP_ADC_BED, TEMP_BED ) + OPTITEM(HAS_TEMP_ADC_CHAMBER, TEMP_CHAMBER ) + OPTITEM(HAS_TEMP_ADC_PROBE, TEMP_PROBE ) + OPTITEM(HAS_TEMP_ADC_COOLER, TEMP_COOLER ) + OPTITEM(HAS_TEMP_ADC_BOARD, TEMP_BOARD ) + OPTITEM(HAS_TEMP_ADC_SOC, TEMP_SOC ) + OPTITEM(FILAMENT_WIDTH_SENSOR, FILWIDTH ) + OPTITEM(HAS_ADC_BUTTONS, ADC_KEY ) + OPTITEM(HAS_JOY_ADC_X, JOY_X ) + OPTITEM(HAS_JOY_ADC_Y, JOY_Y ) + OPTITEM(HAS_JOY_ADC_Z, JOY_Z ) + OPTITEM(POWER_MONITOR_CURRENT, POWERMON_CURRENT ) + OPTITEM(POWER_MONITOR_VOLTAGE, POWERMON_VOLTAGE ) + ADC_COUNT +}; + +extern uint16_t adc_results[ADC_COUNT]; diff --git a/Marlin/src/HAL/STM32F1/onboard_sd.cpp b/Marlin/src/HAL/STM32F1/onboard_sd.cpp index df5549217d98..a3d8dcb2d57e 100644 --- a/Marlin/src/HAL/STM32F1/onboard_sd.cpp +++ b/Marlin/src/HAL/STM32F1/onboard_sd.cpp @@ -5,9 +5,6 @@ * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] * Copyright (C) 2015, ChaN, all right reserved. * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * * This software is a free software and there is NO WARRANTY. * No restriction on use. You can use, modify and redistribute it for * personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. diff --git a/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp b/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp index 3428110c127e..475290de45b2 100644 --- a/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp +++ b/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp @@ -90,7 +90,7 @@ bool XPT2046::getRawPoint(int16_t * const x, int16_t * const y) { if (isBusy() || !isTouched()) return false; *x = getRawData(XPT2046_X); *y = getRawData(XPT2046_Y); - return true; + return isTouched(); } uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { diff --git a/Marlin/src/HAL/STM32F1/timers.h b/Marlin/src/HAL/STM32F1/timers.h index f92c32c2a3ef..89a609c2c39d 100644 --- a/Marlin/src/HAL/STM32F1/timers.h +++ b/Marlin/src/HAL/STM32F1/timers.h @@ -80,7 +80,7 @@ typedef uint16_t hal_timer_t; //#define MF_TIMER_TEMP 4 // 2->4, Timer 2 for Stepper Current PWM #endif -#if MB(BTT_SKR_MINI_E3_V1_0, BTT_SKR_E3_DIP, BTT_SKR_MINI_E3_V1_2, MKS_ROBIN_LITE, MKS_ROBIN_E3D, MKS_ROBIN_E3) +#if MB(BTT_SKR_MINI_E3_V1_0, BTT_SKR_E3_DIP, BTT_SKR_MINI_E3_V1_2, MKS_ROBIN_LITE, MKS_ROBIN_E3D, MKS_ROBIN_E3, VOXELAB_AQUILA) // SKR Mini E3 boards use PA8 as FAN0_PIN, so TIMER 1 is used for Fan PWM. #ifdef STM32_HIGH_DENSITY #define MF_TIMER_SERVO0 8 // tone.cpp uses Timer 4 diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h index 0c685460bf08..c55035e8f075 100644 --- a/Marlin/src/core/boards.h +++ b/Marlin/src/core/boards.h @@ -400,6 +400,7 @@ #define BOARD_TRIGORILLA_V006 5068 // Trigorilla V0.0.6 (GD32F103RE) #define BOARD_KEDI_CONTROLLER_V1_2 5069 // EDUTRONICS Kedi Controller V1.2 (STM32F103RC) #define BOARD_MD_D301 5070 // Mingda D2 DZ301 V1.0 (STM32F103ZE) +#define BOARD_VOXELAB_AQUILA 5071 // Voxelab Aquila V1.0.0/V1.0.1 (GD32F103RC / N32G455RE / STM32F103RE) // // ARM Cortex-M4F @@ -514,7 +515,7 @@ // // HC32 ARM Cortex-M4 // -#define BOARD_AQUILA_V101 7200 // Aquila V1.0.1 as found in the Voxelab Aquila X2 +#define BOARD_AQUILA_V101 7200 // Voxelab Aquila V1.0.0/V1.0.1/V1.0.2/V1.0.3 as found in the Voxelab Aquila X2 and C2 // // Custom board diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h index bc0df357ca22..beb6bfe3e9a5 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -218,12 +218,16 @@ #define _OPTCODE(A) A; #define OPTCODE(O,A) TERN_(O,DEFER4(_OPTCODE)(A)) -// Macros to avoid 'f + 0.0' which is not always optimized away. Minus included for symmetry. +// Macros to avoid operations that aren't always optimized away (e.g., 'f + 0.0' and 'f * 1.0'). // Compiler flags -fno-signed-zeros -ffinite-math-only also cover 'f * 1.0', 'f - f', etc. #define PLUS_TERN0(O,A) _TERN(_ENA_1(O),,+ (A)) // OPTION ? '+ (A)' : '' #define MINUS_TERN0(O,A) _TERN(_ENA_1(O),,- (A)) // OPTION ? '- (A)' : '' +#define MUL_TERN1(O,A) _TERN(_ENA_1(O),,* (A)) // OPTION ? '* (A)' : '' +#define DIV_TERN1(O,A) _TERN(_ENA_1(O),,/ (A)) // OPTION ? '/ (A)' : '' #define SUM_TERN(O,B,A) ((B) PLUS_TERN0(O,A)) // ((B) (OPTION ? '+ (A)' : '')) #define DIFF_TERN(O,B,A) ((B) MINUS_TERN0(O,A)) // ((B) (OPTION ? '- (A)' : '')) +#define MUL_TERN(O,B,A) ((B) MUL_TERN1(O,A)) // ((B) (OPTION ? '* (A)' : '')) +#define DIV_TERN(O,B,A) ((B) DIV_TERN1(O,A)) // ((B) (OPTION ? '/ (A)' : '')) // Macros to support pins/buttons exist testing #define PIN_EXISTS(PN) (defined(PN##_PIN) && PN##_PIN >= 0) diff --git a/Marlin/src/core/mstring.h b/Marlin/src/core/mstring.h index 9606fa22af10..0ea53fef1b48 100644 --- a/Marlin/src/core/mstring.h +++ b/Marlin/src/core/mstring.h @@ -48,7 +48,7 @@ #define DEFAULT_MSTRING_SIZE 20 #endif -//#define UNSAFE_MSTRING // Don't initialize the string and don't terminate strncpy +//#define UNSAFE_MSTRING // Don't initialize the string to "" or set a terminating nul //#define USE_SPRINTF // Use sprintf instead of snprintf //#define DJB2_HASH // 32-bit hash with Djb2 algorithm //#define MSTRING_DEBUG // Debug string operations to diagnose memory leaks @@ -98,13 +98,7 @@ class MString { void debug(FSTR_P const f) { #if ENABLED(MSTRING_DEBUG) - SERIAL_ECHO(FTOP(f)); - SERIAL_CHAR(':'); - SERIAL_ECHO(uintptr_t(str)); - SERIAL_CHAR(' '); - SERIAL_ECHO(length()); - SERIAL_CHAR(' '); - SERIAL_ECHOLN(str); + SERIAL_ECHOLN(f, ':', uintptr_t(str), ' ', length(), ' ', str); #endif } @@ -112,12 +106,12 @@ class MString { // Chainable String Setters MString& set() { str[0] = '\0'; debug(F("clear")); return *this; } - MString& set(char *s) { strncpy(str, s, SIZE); debug(F("string")); return *this; } + MString& set(char *s) { strlcpy(str, s, SIZE + 1); debug(F("string")); return *this; } MString& set(const char *s) { return set(const_cast(s)); } - MString& set_P(PGM_P const s) { strncpy_P(str, s, SIZE); debug(F("pstring")); return *this; } + MString& set_P(PGM_P const s) { strlcpy_P(str, s, SIZE + 1); debug(F("pstring")); return *this; } MString& set(FSTR_P const f) { return set_P(FTOP(f)); } MString& set(const bool &b) { return set(b ? F("true") : F("false")); } - MString& set(const char c) { str[0] = c; if (1 < SIZE) str[1] = '\0'; debug(F("char")); return *this; } + MString& set(const char c) { str[0] = c; str[1] = '\0'; debug(F("char")); return *this; } MString& set(const int8_t &i) { SNPRINTF_P(str, SIZE, PSTR("%d"), i); debug(F("int8_t")); return *this; } MString& set(const short &i) { SNPRINTF_P(str, SIZE, PSTR("%d"), i); debug(F("short")); return *this; } MString& set(const int &i) { SNPRINTF_P(str, SIZE, PSTR("%d"), i); debug(F("int")); return *this; } @@ -134,11 +128,11 @@ class MString { MString& set(const xyze_pos_t &v) { set(); return append(v); } template - MString& set(const MString &m) { strncpy(str, &m, SIZE); debug(F("MString")); return *this; } + MString& set(const MString &m) { strlcpy(str, &m, SIZE + 1); debug(F("MString")); return *this; } - MString& setn(char *s, int len) { int c = _MIN(len, SIZE); strncpy(str, s, c); str[c] = '\0'; debug(F("string")); return *this; } + MString& setn(char *s, int len) { int c = _MIN(len, SIZE); strlcpy(str, s, c + 1); debug(F("string")); return *this; } MString& setn(const char *s, int len) { return setn(const_cast(s), len); } - MString& setn_P(PGM_P const s, int len) { int c = _MIN(len, SIZE); strncpy_P(str, s, c); str[c] = '\0'; debug(F("pstring")); return *this; } + MString& setn_P(PGM_P const s, int len) { int c = _MIN(len, SIZE); strlcpy_P(str, s, c + 1); debug(F("pstring")); return *this; } MString& setn(FSTR_P const f, int len) { return setn_P(FTOP(f), len); } // set(repchr_t('-', 10)) @@ -159,9 +153,9 @@ class MString { // Chainable String appenders MString& append() { debug(F("nil")); return *this; } // for macros that might emit no output - MString& append(char *s) { int sz = length(); if (sz < SIZE) strncpy(str + sz, s, SIZE - sz); debug(F("string")); return *this; } + MString& append(char *s) { int sz = length(); if (sz < SIZE) strlcpy(str + sz, s, SIZE - sz + 1); debug(F("string")); return *this; } MString& append(const char *s) { return append(const_cast(s)); } - MString& append_P(PGM_P const s) { int sz = length(); if (sz < SIZE) strncpy_P(str + sz, s, SIZE - sz); debug(F("pstring")); return *this; } + MString& append_P(PGM_P const s) { int sz = length(); if (sz < SIZE) strlcpy_P(str + sz, s, SIZE - sz + 1); debug(F("pstring")); return *this; } MString& append(FSTR_P const f) { return append_P(FTOP(f)); } MString& append(const bool &b) { return append(b ? F("true") : F("false")); } MString& append(const char c) { int sz = length(); if (sz < SIZE) { str[sz] = c; if (sz < SIZE - 1) str[sz + 1] = '\0'; } return *this; } @@ -195,15 +189,15 @@ class MString { MString& append(const MString &m) { return append(&m); } // Append only if the given space is available - MString& appendn(char *s, int len) { int sz = length(), c = _MIN(len, SIZE - sz); if (c > 0) { strncpy(str + sz, s, c); str[sz + c] = '\0'; } debug(F("string")); return *this; } + MString& appendn(char *s, int len) { int sz = length(), c = _MIN(len, SIZE - sz); if (c > 0) { strlcpy(str + sz, s, c + 1); } debug(F("string")); return *this; } MString& appendn(const char *s, int len) { return appendn(const_cast(s), len); } - MString& appendn_P(PGM_P const s, int len) { int sz = length(), c = _MIN(len, SIZE - sz); if (c > 0) { strncpy_P(str + sz, s, c); str[sz + c] = '\0'; } debug(F("pstring")); return *this; } + MString& appendn_P(PGM_P const s, int len) { int sz = length(), c = _MIN(len, SIZE - sz); if (c > 0) { strlcpy_P(str + sz, s, c + 1); } debug(F("pstring")); return *this; } MString& appendn(FSTR_P const f, int len) { return appendn_P(FTOP(f), len); } // append(repchr_t('-', 10)) MString& append(const repchr_t &s) { const int sz = length(), c = _MIN(s.count, SIZE - sz); - if (c > 0) { memset(str + sz, s.asc, c); safety(sz + c); } + if (c > 0) { memset(str + sz, s.asc, c); str[sz + c] = '\0'; } debug(F("repchr")); return *this; } @@ -299,7 +293,7 @@ class MString { } void copyto(char * const dst) const { strcpy(dst, str); } - void copyto(char * const dst, int len) const { strncpy(dst, str, len); } + void copyto(char * const dst, int len) const { strlcpy(dst, str, len + 1); } MString& clear() { return set(); } MString& eol() { return append('\n'); } @@ -318,6 +312,7 @@ class MString { #pragma GCC diagnostic pop +// Temporary inline string typically used to compose a G-code command #ifndef TS_SIZE #define TS_SIZE 63 #endif diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp index 7496c9e9b5e1..d136f0000d8c 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp @@ -1790,8 +1790,8 @@ void unified_bed_leveling::smart_fill_mesh() { SERIAL_ECHOLNPGM("Meshes go from ", hex_address((void*)settings.meshes_start_index()), " to ", hex_address((void*)settings.meshes_end_index())); serial_delay(50); - SERIAL_ECHOLNPGM("sizeof(ubl) : ", sizeof(ubl)); SERIAL_EOL(); - SERIAL_ECHOLNPGM("z_value[][] size: ", sizeof(z_values)); SERIAL_EOL(); + SERIAL_ECHOLNPGM("sizeof(unified_bed_leveling) : ", sizeof(unified_bed_leveling)); + SERIAL_ECHOLNPGM("z_value[][] size: ", sizeof(z_values)); serial_delay(25); SERIAL_ECHOLNPGM("EEPROM free for UBL: ", hex_address((void*)(settings.meshes_end_index() - settings.meshes_start_index()))); diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index ba16c7bbd7e2..dbdbdc5affee 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -263,7 +263,7 @@ void GcodeSuite::G28() { #if ENABLED(DEBUG_LEVELING_FEATURE) auto debug_current = [](FSTR_P const s, const int16_t a, const int16_t b) { - if (DEBUGGING(LEVELING)) { DEBUG_ECHOF(s); DEBUG_ECHOLNPGM(" current: ", a, " -> ", b); } + if (DEBUGGING(LEVELING)) { DEBUG_ECHOLN(s, F(" current: "), a, F(" -> "), b); } }; #else #define debug_current(...) diff --git a/Marlin/src/gcode/queue.h b/Marlin/src/gcode/queue.h index aa7ef99f479e..91cad1f08d94 100644 --- a/Marlin/src/gcode/queue.h +++ b/Marlin/src/gcode/queue.h @@ -134,7 +134,7 @@ class GCodeQueue { * Aborts the current SRAM queue so only use for one or two commands. */ static void inject(const char * const gcode) { - strncpy(injected_commands, gcode, sizeof(injected_commands) - 1); + strlcpy(injected_commands, gcode, sizeof(injected_commands)); } /** diff --git a/Marlin/src/gcode/stats/M31.cpp b/Marlin/src/gcode/stats/M31.cpp index a76ec7ee4def..ad48eae8663f 100644 --- a/Marlin/src/gcode/stats/M31.cpp +++ b/Marlin/src/gcode/stats/M31.cpp @@ -33,7 +33,7 @@ void GcodeSuite::M31() { char buffer[22]; duration_t(print_job_timer.duration()).toString(buffer); - ui.set_status(buffer, ENABLED(DWIN_LCD_PROUI)); // No expire on ProUI + ui.set_status_no_expire(buffer); SERIAL_ECHO_MSG("Print time: ", buffer); } diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 634652c9bf99..ba074e256088 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -852,7 +852,11 @@ #define HAS_MEDIA_SUBCALLS 1 #endif -#if ANY(SHOW_PROGRESS_PERCENT, SHOW_ELAPSED_TIME, SHOW_REMAINING_TIME, SHOW_INTERACTION_TIME) && !HAS_GRAPHICAL_TFT +#if ANY(SHOW_ELAPSED_TIME, SHOW_REMAINING_TIME, SHOW_INTERACTION_TIME) + #define HAS_TIME_DISPLAY 1 +#endif + +#if ANY(SHOW_PROGRESS_PERCENT, HAS_TIME_DISPLAY) && !HAS_GRAPHICAL_TFT #define HAS_EXTRA_PROGRESS 1 #endif @@ -1256,7 +1260,7 @@ * currently HAL.h must be included ahead of pins.h. */ #if LCD_IS_SERIAL_HOST && !defined(LCD_SERIAL_PORT) - #if MB(BTT_SKR_MINI_E3_V1_0, BTT_SKR_MINI_E3_V1_2, BTT_SKR_MINI_E3_V2_0, BTT_SKR_MINI_E3_V3_0, BTT_SKR_E3_TURBO, BTT_OCTOPUS_V1_1, AQUILA_V101) + #if MB(BTT_SKR_MINI_E3_V1_0, BTT_SKR_MINI_E3_V1_2, BTT_SKR_MINI_E3_V2_0, BTT_SKR_MINI_E3_V3_0, BTT_SKR_MINI_E3_V3_0_1, BTT_SKR_E3_TURBO, BTT_OCTOPUS_V1_1, AQUILA_V101) #define LCD_SERIAL_PORT 1 #elif MB(CREALITY_V24S1_301, CREALITY_V24S1_301F4, CREALITY_F401RE, CREALITY_V423, MKS_ROBIN, PANOWIN_CUTLASS, KODAMA_BARDO) #define LCD_SERIAL_PORT 2 diff --git a/Marlin/src/inc/Version.h b/Marlin/src/inc/Version.h index 3d192cb4740a..02525afb5437 100644 --- a/Marlin/src/inc/Version.h +++ b/Marlin/src/inc/Version.h @@ -42,7 +42,7 @@ * version was tagged. */ #ifndef STRING_DISTRIBUTION_DATE - #define STRING_DISTRIBUTION_DATE "2023-11-30" + #define STRING_DISTRIBUTION_DATE "2023-12-09" #endif /** diff --git a/Marlin/src/inc/Warnings.cpp b/Marlin/src/inc/Warnings.cpp index 26ecfbf533a5..3efbb67a0cd5 100644 --- a/Marlin/src/inc/Warnings.cpp +++ b/Marlin/src/inc/Warnings.cpp @@ -33,6 +33,13 @@ #if ENABLED(MARLIN_DEV_MODE) #warning "WARNING! Disable MARLIN_DEV_MODE for the final build!" + #ifdef __LONG_MAX__ + #if __LONG_MAX__ > __INT_MAX__ + #warning "The 'long' type is larger than the 'int' type on this platform." + #else + #warning "The 'long' type is the same as the 'int' type on this platform." + #endif + #endif #endif #if ENABLED(LA_DEBUG) @@ -707,7 +714,7 @@ /** * Maple environment */ -#ifdef __STM32F1__ +#if defined(__STM32F1__) && DISABLED(NO_MAPLE_WARNING) #warning "Maple build environments are deprecated. Please use a non-Maple build environment. Report issues to the Marlin Firmware project." #endif @@ -777,6 +784,13 @@ #warning "Place the firmware bin file in a folder named 'STM32F4_UPDATE' on the SD card. Install with 'M936 V2'." #endif +/** + * Voxelab N32 bootloader + */ +#ifdef SDCARD_FLASH_LIMIT_256K + #warning "This board has 512K but the bootloader can only flash firmware.bin <= 256K. ICSP required for full 512K capacity." +#endif + /** * ProUI Boot Screen Duration */ diff --git a/Marlin/src/lcd/dogm/fontdata/fontdata_6x9_marlin.h b/Marlin/src/lcd/dogm/fontdata/fontdata_6x9_marlin.h index 524ff18778dc..c81c63f2ed8f 100644 --- a/Marlin/src/lcd/dogm/fontdata/fontdata_6x9_marlin.h +++ b/Marlin/src/lcd/dogm/fontdata/fontdata_6x9_marlin.h @@ -22,15 +22,15 @@ #pragma once /** - Fontname: -Misc-Fixed-Medium-R-Normal--9-90-75-75-C-60-ISO10646-1 - Copyright: Public domain font. Share and enjoy. - Capital A Height: 6, '1' Height: 6 - Calculated Max Values w= 6 h= 9 x= 5 y= 5 dx= 6 dy= 0 ascent= 7 len= 9 - Font Bounding box w= 6 h= 9 x= 0 y=-2 - Calculated Min Values x= 0 y=-2 dx= 0 dy= 0 - Pure Font ascent = 6 descent=-2 - X Font ascent = 6 descent=-2 - Max Font ascent = 7 descent=-2 + * Fontname: -Misc-Fixed-Medium-R-Normal--9-90-75-75-C-60-ISO10646-1 + * Copyright: Public domain font. Share and enjoy. + * Capital A Height: 6, '1' Height: 6 + * Calculated Max Values w= 6 h= 9 x= 5 y= 5 dx= 6 dy= 0 ascent= 7 len= 9 + * Font Bounding box w= 6 h= 9 x= 0 y=-2 + * Calculated Min Values x= 0 y=-2 dx= 0 dy= 0 + * Pure Font ascent = 6 descent=-2 + * X Font ascent = 6 descent=-2 + * Max Font ascent = 7 descent=-2 */ #include const u8g_fntpgm_uint8_t u8g_font_6x9[2434] U8G_FONT_SECTION(".progmem.u8g_font_6x9") = { @@ -186,4 +186,5 @@ const u8g_fntpgm_uint8_t u8g_font_6x9[2434] U8G_FONT_SECTION(".progmem.u8g_font_ 0x00,0x50,0x00,0x90,0x90,0x90,0x70,0x04,0x09,0x09,0x06,0x01,0xFE,0x20,0x40,0x00, 0x90,0x90,0x90,0x70,0x90,0x60,0x04,0x08,0x08,0x06,0x01,0xFE,0x80,0x80,0xE0,0x90, 0x90,0xE0,0x80,0x80,0x04,0x08,0x08,0x06,0x01,0xFE,0x50,0x00,0x90,0x90,0x90,0x70, - 0x90,0x60}; + 0x90,0x60 +}; diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp index d38d28c8cd3b..ad9e38266162 100644 --- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp +++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp @@ -91,6 +91,18 @@ #define EXTRAS_BASELINE (40 + INFO_FONT_ASCENT) #define STATUS_BASELINE (LCD_PIXEL_HEIGHT - INFO_FONT_DESCENT) +#define PCENTERED // Center percent value over progress bar, else right-align +#define PROGRESS_BAR_X TERN(PCENTERED, 54, 40) +#define PROGRESS_BAR_Y (EXTRAS_BASELINE + TERN(PCENTERED, 1, -3)) +#define PCT_X TERN(PCENTERED, PROGRESS_BAR_X, LCD_PIXEL_WIDTH - TERN(PRINT_PROGRESS_SHOW_DECIMALS, 5, 4) * INFO_FONT_WIDTH) +#define PCT_Y (EXTRAS_BASELINE + TERN(PCENTERED, 0, 3)) +#define PROGRESS_BAR_WIDTH TERN(PCENTERED, LCD_PIXEL_WIDTH - PROGRESS_BAR_X, PCT_X - PROGRESS_BAR_X - 1) +#define PROGRESS_BAR_HEIGHT TERN(PCENTERED, 4, 5) + +#if DISABLED(PCENTERED) && HAS_TIME_DISPLAY + #error "PCENTERED is required for extra progress display options." +#endif + #if ANIM_HBCC enum HeatBits : uint8_t { DRAWBIT_HOTEND, @@ -188,10 +200,6 @@ } #endif -#define PROGRESS_BAR_X 54 -#define PROGRESS_BAR_Y (EXTRAS_BASELINE + 1) -#define PROGRESS_BAR_WIDTH (LCD_PIXEL_WIDTH - PROGRESS_BAR_X) - FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, const uint8_t ty) { const char *str; uint8_t len; @@ -471,46 +479,44 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const // Prepare strings for progress display #if ANY(HAS_EXTRA_PROGRESS, HAS_PRINT_PROGRESS) static MarlinUI::progress_t progress = 0; - static char bufferc[13]; + static MString<12> progressString; #endif #if HAS_EXTRA_PROGRESS - static void prepare_time_string(const duration_t &time, char prefix) { - char str[13]; - memset(&bufferc[2], 0x20, 5); // partialy fill with spaces to avoid artifacts and terminator - bufferc[0] = prefix; - bufferc[1] = ':'; - int str_length = time.toDigital(str, time.value >= 60*60*24L); - strcpy(&bufferc[sizeof(bufferc) - str_length - 1], str); - } - + #if HAS_TIME_DISPLAY + static void prepare_time_string(const duration_t &time, char prefix) { + char str[10]; + const uint8_t time_len = time.toDigital(str, time.value >= 60*60*24L); // 5 to 8 chars + progressString.set(prefix, ':', spaces_t(10 - time_len), str); // 2 to 5 spaces + } + #endif #if ENABLED(SHOW_PROGRESS_PERCENT) void MarlinUI::drawPercent() { - if (progress != 0) { - #define PCENTERED 1 // center percent value over progress bar, else align to the right - #define PPOS TERN(PCENTERED, 4, 0) - #define PLEN TERN(PRINT_PROGRESS_SHOW_DECIMALS, 4, 3) - memset(&bufferc, 0x20, 12); - memcpy(&bufferc[PPOS], TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(progress), ui8tostr3rj(progress / (PROGRESS_SCALE))), PLEN); - bufferc[PPOS+PLEN] = '%'; - } + if (progress == 0) return; + progressString.set( + OPTITEM(PCENTERED, spaces_t(4)) + TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(progress), ui8tostr3rj(progress / (PROGRESS_SCALE))), '%' + ); } #endif #if ENABLED(SHOW_REMAINING_TIME) void MarlinUI::drawRemain() { if (printJobOngoing() && get_remaining_time() != 0) - prepare_time_string(get_remaining_time(), 'R'); } + prepare_time_string(get_remaining_time(), 'R'); + } #endif #if ENABLED(SHOW_INTERACTION_TIME) void MarlinUI::drawInter() { if (printingIsActive() && interaction_time) - prepare_time_string(interaction_time, 'C'); } + prepare_time_string(interaction_time, 'C'); + } #endif #if ENABLED(SHOW_ELAPSED_TIME) void MarlinUI::drawElapsed() { if (printJobOngoing()) - prepare_time_string(print_job_timer.duration(), 'E'); } + prepare_time_string(print_job_timer.duration(), 'E'); + } #endif #endif // HAS_EXTRA_PROGRESS @@ -779,17 +785,17 @@ void MarlinUI::draw_status_screen() { #if HAS_PRINT_PROGRESS // Progress bar frame - if (PAGE_CONTAINS(PROGRESS_BAR_Y, PROGRESS_BAR_Y + 3)) - u8g.drawFrame(PROGRESS_BAR_X, PROGRESS_BAR_Y, PROGRESS_BAR_WIDTH, 4); + if (PAGE_CONTAINS(PROGRESS_BAR_Y, PROGRESS_BAR_Y + PROGRESS_BAR_HEIGHT - 1)) + u8g.drawFrame(PROGRESS_BAR_X, PROGRESS_BAR_Y, PROGRESS_BAR_WIDTH, PROGRESS_BAR_HEIGHT); // Progress bar solid part - if (PAGE_CONTAINS(PROGRESS_BAR_Y + 1, PROGRESS_BAR_Y + 2)) - u8g.drawBox(PROGRESS_BAR_X + 1, PROGRESS_BAR_Y + 1, progress_bar_solid_width, 2); + if (PAGE_CONTAINS(PROGRESS_BAR_Y + 1, PROGRESS_BAR_Y + PROGRESS_BAR_HEIGHT - 3)) + u8g.drawBox(PROGRESS_BAR_X + 1, PROGRESS_BAR_Y + 1, progress_bar_solid_width, PROGRESS_BAR_HEIGHT - 2); // Progress strings - if (PAGE_CONTAINS(EXTRAS_BASELINE - INFO_FONT_ASCENT, EXTRAS_BASELINE - 1)) { + if (PAGE_CONTAINS(PCT_Y - INFO_FONT_ASCENT, PCT_Y - 1)) { ui.rotate_progress(); - lcd_put_u8str(PROGRESS_BAR_X, EXTRAS_BASELINE, bufferc); + lcd_put_u8str(PCT_X, PCT_Y, progressString); } #endif diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp index a6e942b7066e..2039d9963581 100644 --- a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp +++ b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp @@ -664,15 +664,17 @@ bool ST7920_Lite_Status_Screen::indicators_changed() { #if HAS_PRINT_PROGRESS static char screenstr[8]; - char * ST7920_Lite_Status_Screen::prepare_time_string(const duration_t &time, char prefix) { - static char str[6]; - memset(&screenstr, 0x20, 8); // fill with spaces to avoid artifacts, not doing right-justification to save cycles - screenstr[0] = prefix; - TERN_(HOTENDS == 1, screenstr[1] = 0x07;) // add bullet • separator when there is space - int str_length = time.toDigital(str); - memcpy(&screenstr[TERN(HOTENDS == 1, 2, 1)], str, str_length); //memcpy because we can't have terminator - return screenstr; - } + #if HAS_TIME_DISPLAY + char * ST7920_Lite_Status_Screen::prepare_time_string(const duration_t &time, char prefix) { + static char str[6]; + memset(&screenstr, ' ', 8); // fill with spaces to avoid artifacts, not doing right-justification to save cycles + screenstr[0] = prefix; + TERN_(HOTENDS == 1, screenstr[1] = 0x07;) // add bullet • separator when there is space + int str_length = time.toDigital(str); + memcpy(&screenstr[TERN(HOTENDS == 1, 2, 1)], str, str_length); //memcpy because we can't have terminator + return screenstr; + } + #endif void ST7920_Lite_Status_Screen::draw_progress_string(uint8_t addr, const char *str) { set_ddram_address(addr); @@ -687,7 +689,7 @@ bool ST7920_Lite_Status_Screen::indicators_changed() { void ST7920_Lite_Status_Screen::drawPercent() { #define LSHIFT TERN(HOTENDS == 1, 0, 1) const uint8_t progress = ui.get_progress_percent(); - memset(&screenstr, 0x20, 8); // fill with spaces to avoid artifacts + memset(&screenstr, ' ', 8); // fill with spaces to avoid artifacts if (progress){ memcpy(&screenstr[2 - LSHIFT], \ TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(ui.get_progress_permyriad()), ui8tostr3rj(progress)), \ diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h index d838ee1a3a68..e096825f8adc 100644 --- a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h +++ b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h @@ -83,8 +83,10 @@ class ST7920_Lite_Status_Screen { static void draw_bed_temp(const int16_t temp, const int16_t target, bool forceUpdate=false); static void draw_fan_speed(const uint8_t value); #if HAS_PRINT_PROGRESS + #if HAS_TIME_DISPLAY + static char* prepare_time_string(const duration_t &time, char prefix=' '); + #endif static void draw_progress_bar(const uint8_t value); - static char* prepare_time_string(const duration_t &time, char prefix=' '); static void draw_progress_string(uint8_t addr, const char *str); static void update_progress(const bool forceUpdate); #endif diff --git a/Marlin/src/lcd/e3v2/common/encoder.h b/Marlin/src/lcd/e3v2/common/encoder.h index 72d37108dcf2..ce431c9811b1 100644 --- a/Marlin/src/lcd/e3v2/common/encoder.h +++ b/Marlin/src/lcd/e3v2/common/encoder.h @@ -45,7 +45,7 @@ typedef enum { ENCODER_DIFF_ENTER = 3 // click } EncoderState; -#define ENCODER_WAIT_MS 20 +#define ENCODER_WAIT_MS TERN(DWIN_LCD_PROUI, 10, 20) // Encoder initialization void encoderConfiguration(); diff --git a/Marlin/src/lcd/e3v2/creality/dwin.cpp b/Marlin/src/lcd/e3v2/creality/dwin.cpp index f3935f39dd5e..274390189107 100644 --- a/Marlin/src/lcd/e3v2/creality/dwin.cpp +++ b/Marlin/src/lcd/e3v2/creality/dwin.cpp @@ -103,7 +103,6 @@ #define UNITFDIGITS 1 #define MINUNITMULT pow(10, UNITFDIGITS) -#define ENCODER_WAIT_MS 20 #define DWIN_VAR_UPDATE_INTERVAL 1024 #define DWIN_SCROLL_UPDATE_INTERVAL SEC_TO_MS(2) #define DWIN_REMAIN_TIME_UPDATE_INTERVAL SEC_TO_MS(20) diff --git a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp index 6e7898a389f9..be8605e3bba0 100644 --- a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp @@ -389,9 +389,9 @@ class TextScroller { // Draw value text on if (viewer_print_value) { - xy_uint_t offset { 0, cell_height_px / 2 - 6 }; + const int8_t offset_y = cell_height_px / 2 - 6; if (isnan(bedlevel.z_values[x][y])) { // undefined - dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + cell_width_px / 2 - 5, start_y_px + offset.y, F("X")); + dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + cell_width_px / 2 - 5, start_y_px + offset_y, F("X")); } else { // has value MString<12> msg; @@ -399,10 +399,10 @@ class TextScroller { msg.set(p_float_t(abs(bedlevel.z_values[x][y]), 2)); else msg.setf(F("%02i"), uint16_t(abs(bedlevel.z_values[x][y] - int16_t(bedlevel.z_values[x][y])) * 100)); - offset.x = cell_width_px / 2 - 3 * msg.length() - 2; + const int8_t offset_x = cell_width_px / 2 - 3 * msg.length() - 2; if (GRID_MAX_POINTS_X >= 10) - dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px - 2 + offset.x, start_y_px + offset.y /*+ square / 2 - 6*/, F(".")); - dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + 1 + offset.x, start_y_px + offset.y /*+ square / 2 - 6*/, msg); + dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px - 2 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, F(".")); + dwinDrawString(false, font6x12, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + 1 + offset_x, start_y_px + offset_y /*+ square / 2 - 6*/, msg); } safe_delay(10); LCD_SERIAL.flushTX(); diff --git a/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp b/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp index f2fe008667c6..64d145c95dfd 100644 --- a/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp +++ b/Marlin/src/lcd/e3v2/proui/bedlevel_tools.cpp @@ -247,9 +247,9 @@ bool BedLevelTools::meshValidate() { // Draw value text on const uint8_t fs = DWINUI::fontWidth(meshfont); if (viewer_print_value) { - xy_uint_t offset { 0, cell_height_px / 2 - fs }; + const int8_t offset_y = cell_height_px / 2 - fs; if (isnan(bedlevel.z_values[x][y])) { // undefined - dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + cell_width_px / 2 - 5, start_y_px + offset.y, F("X")); + dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + cell_width_px / 2 - 5, start_y_px + offset_y, F("X")); } else { // has value MString<12> msg; @@ -257,10 +257,10 @@ bool BedLevelTools::meshValidate() { msg.set(p_float_t(abs(bedlevel.z_values[x][y]), 2)); else msg.setf(F("%02i"), uint16_t(abs(bedlevel.z_values[x][y] - int16_t(bedlevel.z_values[x][y])) * 100)); - offset.x = cell_width_px / 2 - (fs / 2) * msg.length() - 2; + const int8_t offset_x = cell_width_px / 2 - (fs / 2) * msg.length() - 2; if ((GRID_MAX_POINTS_X) >= TERN(TJC_DISPLAY, 8, 10)) - dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px - 2 + offset.x, start_y_px + offset.y, F(".")); - dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + 1 + offset.x, start_y_px + offset.y, msg); + dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px - 2 + offset_x, start_y_px + offset_y, F(".")); + dwinDrawString(false, meshfont, COLOR_WHITE, COLOR_BG_BLUE, start_x_px + 1 + offset_x, start_y_px + offset_y, msg); } safe_delay(10); LCD_SERIAL.flushTX(); diff --git a/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp b/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp index 853da8532e12..7c71b8fc5974 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp +++ b/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp @@ -127,7 +127,7 @@ void dwinWriteToMem(uint8_t mem, uint16_t addr, uint16_t length, uint8_t *data) dwinWord(i, addr + indx); // start address of the data block ++i; for (uint8_t j = 0; j < i; ++j) { LCD_SERIAL.write(dwinSendBuf[j]); delayMicroseconds(1); } // Buf header - for (uint16_t j = indx; j <= indx + to_send - 1; j++) LCD_SERIAL.write(*(data + j)); delayMicroseconds(1); // write block of data + for (uint16_t j = indx; j <= indx + to_send - 1; j++) { LCD_SERIAL.write(*(data + j)); delayMicroseconds(1); } // write block of data for (uint8_t j = 0; j < 4; ++j) { LCD_SERIAL.write(dwinBufTail[j]); delayMicroseconds(1); } block++; pending -= to_send; diff --git a/Marlin/src/lcd/e3v2/proui/dwinui.cpp b/Marlin/src/lcd/e3v2/proui/dwinui.cpp index 7e94fc3e5633..23cd1736fdf4 100644 --- a/Marlin/src/lcd/e3v2/proui/dwinui.cpp +++ b/Marlin/src/lcd/e3v2/proui/dwinui.cpp @@ -181,7 +181,7 @@ void DWINUI::drawString(uint16_t color, const char * const string, uint16_t rlim // iNum: Number of digits // x/y: Upper-left coordinate // value: Integer value -void DWINUI::drawInt(uint8_t bShow, bool signedMode, fontid_t fid, uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, int32_t value) { +void DWINUI::drawInt(uint8_t bShow, bool signedMode, fontid_t fid, uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) { char nstr[10]; sprintf_P(nstr, PSTR("%*li"), (signedMode ? iNum + 1 : iNum), value); dwinDrawString(bShow, fid, color, bColor, x, y, nstr); diff --git a/Marlin/src/lcd/e3v2/proui/dwinui.h b/Marlin/src/lcd/e3v2/proui/dwinui.h index 015e66c8cb71..636b4fbbad72 100644 --- a/Marlin/src/lcd/e3v2/proui/dwinui.h +++ b/Marlin/src/lcd/e3v2/proui/dwinui.h @@ -338,7 +338,7 @@ namespace DWINUI { // iNum: Number of digits // x/y: Upper-left coordinate // value: Integer value - void drawInt(uint8_t bShow, bool signedMode, fontid_t fid, uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, int32_t value); + void drawInt(uint8_t bShow, bool signedMode, fontid_t fid, uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value); // Draw a positive integer inline void drawInt(uint8_t bShow, fontid_t fid, uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) { diff --git a/Marlin/src/lcd/e3v2/proui/menus.cpp b/Marlin/src/lcd/e3v2/proui/menus.cpp index d537bc5ae663..9f48ff03b748 100644 --- a/Marlin/src/lcd/e3v2/proui/menus.cpp +++ b/Marlin/src/lcd/e3v2/proui/menus.cpp @@ -107,7 +107,7 @@ void onDrawMenuItem(MenuItem* menuitem, int8_t line) { if (menuitem->icon) DWINUI::drawIcon(menuitem->icon, ICOX, MBASE(line) - 3); if (menuitem->frameid) dwinFrameAreaCopy(menuitem->frameid, menuitem->frame.left, menuitem->frame.top, menuitem->frame.right, menuitem->frame.bottom, LBLX, MBASE(line)); - else if (menuitem->caption) + else DWINUI::drawString(LBLX, MBASE(line) - 1, menuitem->caption); dwinDrawHLine(hmiData.colorSplitLine, 16, MYPOS(line + 1), 240); } diff --git a/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp b/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp index df0c4df30dfd..63b1ef9c195c 100644 --- a/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp +++ b/Marlin/src/lcd/extui/anycubic_chiron/chiron_tft.cpp @@ -433,12 +433,12 @@ void ChironTFT::sendFileList(int8_t startindex) { } void ChironTFT::selectFile() { - const size_t namelen = command_len - 4 + (panel_type <= AC_panel_new); - strncpy(selectedfile, panel_command + 4, namelen); - selectedfile[namelen] = '\0'; + const size_t fnlen = command_len - 4 + (panel_type <= AC_panel_new); + strlcpy(selectedfile, panel_command + 4, fnlen + 1); #if ACDEBUG(AC_FILE) DEBUG_ECHOLNPGM(" Selected File: ", selectedfile); #endif + switch (selectedfile[0]) { case '/': // Valid file selected tftSendLn(AC_msg_sd_file_open_success); @@ -449,10 +449,9 @@ void ChironTFT::selectFile() { tftSendLn(AC_msg_sd_file_open_failed); sendFileList( 0 ); break; - default: // enter sub folder - // for new panel remove the '.GCO' tag that was added to the end of the path - if (panel_type <= AC_panel_new) - selectedfile[strlen(selectedfile) - 4] = '\0'; + default: // enter subfolder + // For new panel remove the '.GCO' tag that was added to the end of the path + if (panel_type <= AC_panel_new) selectedfile[fnlen - 4] = '\0'; filenavigator.changeDIR(selectedfile); tftSendLn(AC_msg_sd_file_open_failed); sendFileList( 0 ); diff --git a/Marlin/src/lcd/extui/anycubic_vyper/dgus_tft.cpp b/Marlin/src/lcd/extui/anycubic_vyper/dgus_tft.cpp index 4726cba3786a..3209aa76f248 100644 --- a/Marlin/src/lcd/extui/anycubic_vyper/dgus_tft.cpp +++ b/Marlin/src/lcd/extui/anycubic_vyper/dgus_tft.cpp @@ -971,8 +971,7 @@ namespace Anycubic { } void DgusTFT::selectFile() { - strncpy(selectedfile, panel_command + 4, command_len - 4); - selectedfile[command_len - 5] = '\0'; + strlcpy(selectedfile, panel_command + 4, command_len - 3); #if ACDEBUG(AC_FILE) DEBUG_ECHOLNPGM(" Selected File: ", selectedfile); #endif @@ -1293,8 +1292,7 @@ namespace Anycubic { TERN_(CASE_LIGHT_ENABLE, setCaseLightState(true)); char str_buf[20]; - strncpy_P(str_buf, filenavigator.filelist.longFilename(), 17); - str_buf[17] = '\0'; + strlcpy_P(str_buf, filenavigator.filelist.longFilename(), 18); sendTxtToTFT(str_buf, TXT_PRINT_NAME); #if ENABLED(POWER_LOSS_RECOVERY) @@ -1332,8 +1330,7 @@ namespace Anycubic { printFile(filenavigator.filelist.shortFilename()); char str_buf[20]; - strncpy_P(str_buf, filenavigator.filelist.longFilename(), 17); - str_buf[17] = '\0'; + strlcpy_P(str_buf, filenavigator.filelist.longFilename(), 18); sendTxtToTFT(str_buf, TXT_PRINT_NAME); sprintf(str_buf, "%5.2f", getFeedrate_percent()); diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSTxHandler.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSTxHandler.cpp index 0dd12b1612c0..3a9ca9c76288 100644 --- a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSTxHandler.cpp +++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSTxHandler.cpp @@ -105,7 +105,7 @@ void DGUSTxHandler::sdCardInsertionStatus(DGUS_VP &vp) { } #endif // PIDTEMPBED -static duration_t _PrintRemainingDurationEstimate() { +static duration_t _printRemainingDurationEstimate() { duration_t remainingDuration = 0; if (ExtUI::isPrinting()) { @@ -120,12 +120,12 @@ static duration_t _PrintRemainingDurationEstimate() { } void DGUSTxHandler::printRemainingHours(DGUS_VP &vp) { - const int16_t data = _PrintRemainingDurationEstimate().hour(); + const int16_t data = _printRemainingDurationEstimate().hour(); dgus.write((uint16_t)vp.addr, Endianness::toBE(data)); } void DGUSTxHandler::printRemainingMinutes(DGUS_VP &vp) { - const int16_t data = _PrintRemainingDurationEstimate().minute() % 60; + const int16_t data = _printRemainingDurationEstimate().minute() % 60; dgus.write((uint16_t)vp.addr, Endianness::toBE(data)); } diff --git a/Marlin/src/lcd/extui/dgus_reloaded/dgus_reloaded_extui.cpp b/Marlin/src/lcd/extui/dgus_reloaded/dgus_reloaded_extui.cpp index 3434bdf8c366..68e405776e9d 100644 --- a/Marlin/src/lcd/extui/dgus_reloaded/dgus_reloaded_extui.cpp +++ b/Marlin/src/lcd/extui/dgus_reloaded/dgus_reloaded_extui.cpp @@ -21,7 +21,7 @@ */ /** - * lcd/extui/dgus_e3s1pro/dgus_e3s1pro_extui.cpp + * lcd/extui/dgus_reloaded/dgus_reloaded_extui.cpp */ #include "../../../inc/MarlinConfigPre.h" diff --git a/Marlin/src/lcd/extui/mks_ui/draw_keyboard.cpp b/Marlin/src/lcd/extui/mks_ui/draw_keyboard.cpp index 90b181d6b548..ec7e549c4160 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_keyboard.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_keyboard.cpp @@ -155,7 +155,7 @@ static void lv_kb_event_cb(lv_obj_t *kb, lv_event_t event) { #endif // MKS_WIFI_MODULE case autoLevelGcodeCommand: uint8_t buf[100]; - strncpy((char *)buf, ret_ta_txt, sizeof(buf)); + strlcpy((char *)buf, ret_ta_txt, sizeof(buf)); update_gcode_command(AUTO_LEVELING_COMMAND_ADDR, buf); goto_previous_ui(); break; diff --git a/Marlin/src/lcd/extui/mks_ui/draw_print_file.cpp b/Marlin/src/lcd/extui/mks_ui/draw_print_file.cpp index da79cb617495..7732d5d2a4b3 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_print_file.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_print_file.cpp @@ -474,7 +474,7 @@ void cutFileName(char *path, int len, int bytePerLine, char *outStr) { wcscpy(outStr, beginIndex); #else if ((int)strlen(beginIndex) > len) - strncpy(outStr, beginIndex, len); + strlcpy(outStr, beginIndex, len + 1); else strcpy(outStr, beginIndex); #endif @@ -485,17 +485,17 @@ void cutFileName(char *path, int len, int bytePerLine, char *outStr) { wcsncpy(outStr, (const WCHAR *)beginIndex, len - 3); wcscat(outStr, (const WCHAR *)gFileTail); #else - //strncpy(outStr, beginIndex, len - 3); - strncpy(outStr, beginIndex, len - 4); + strlcpy(outStr, beginIndex, len - 3); strcat_P(outStr, PSTR("~.g")); #endif } else { + const size_t strsize = strIndex2 - beginIndex + 1; #if _LFN_UNICODE - wcsncpy(outStr, (const WCHAR *)beginIndex, strIndex2 - beginIndex + 1); + wcsncpy(outStr, (const WCHAR *)beginIndex, strsize); wcscat(outStr, (const WCHAR *)&gFileTail[3]); #else - strncpy(outStr, beginIndex, strIndex2 - beginIndex + 1); + strlcpy(outStr, beginIndex, strsize + 1); strcat_P(outStr, PSTR("g")); #endif } diff --git a/Marlin/src/lcd/extui/mks_ui/mks_hardware.cpp b/Marlin/src/lcd/extui/mks_ui/mks_hardware.cpp index a759f8677e6f..eb9cac641ad8 100644 --- a/Marlin/src/lcd/extui/mks_ui/mks_hardware.cpp +++ b/Marlin/src/lcd/extui/mks_ui/mks_hardware.cpp @@ -727,8 +727,7 @@ void disp_assets_update_progress(FSTR_P const fmsg) { static constexpr int buflen = 30; char buf[buflen]; memset(buf, ' ', buflen); - strncpy_P(buf, FTOP(fmsg), buflen - 1); - buf[buflen - 1] = '\0'; + strlcpy_P(buf, FTOP(fmsg), buflen); disp_string(100, 165, buf, 0xFFFF, 0x0000); #else disp_string(100, 165, FTOP(fmsg), 0xFFFF, 0x0000); diff --git a/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp b/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp index 7adce94c2fa6..be6394514360 100644 --- a/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp +++ b/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp @@ -237,11 +237,11 @@ void tft_lvgl_init() { uiCfg.print_state = REPRINTING; #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - strncpy(public_buf_m, recovery.info.sd_filename, sizeof(public_buf_m)); + strlcpy(public_buf_m, recovery.info.sd_filename, sizeof(public_buf_m)); card.printLongPath(public_buf_m); - strncpy(list_file.long_name[sel_id], card.longFilename, sizeof(list_file.long_name[0])); + strlcpy(list_file.long_name[sel_id], card.longFilename, sizeof(list_file.long_name[0])); #else - strncpy(list_file.long_name[sel_id], recovery.info.sd_filename, sizeof(list_file.long_name[0])); + strlcpy(list_file.long_name[sel_id], recovery.info.sd_filename, sizeof(list_file.long_name[0])); #endif lv_draw_printing(); } @@ -305,35 +305,28 @@ uint16_t getTickDiff(const uint16_t curTick, const uint16_t lastTick) { return (TICK_CYCLE) * (lastTick <= curTick ? (curTick - lastTick) : (0xFFFFFFFF - lastTick + curTick)); } -static bool get_point(xy_int_t &point) { - if (!touch.getRawPoint(&point.x, &point.y)) return false; +static bool get_point(int16_t * const x, int16_t * const y) { + if (!touch.getRawPoint(x, y)) return false; #if ENABLED(TOUCH_SCREEN_CALIBRATION) const calibrationState state = touch_calibration.get_calibration_state(); if (WITHIN(state, CALIBRATION_TOP_LEFT, CALIBRATION_BOTTOM_LEFT)) { - if (touch_calibration.handleTouch(point)) lv_update_touch_calibration_screen(); + if (touch_calibration.handleTouch(*x, *y)) lv_update_touch_calibration_screen(); return false; } #endif - point.x = int16_t((int32_t(point.x) * _TOUCH_CALIBRATION_X) >> 16) + _TOUCH_OFFSET_X; - point.y = int16_t((int32_t(point.y) * _TOUCH_CALIBRATION_Y) >> 16) + _TOUCH_OFFSET_Y; + *x = int16_t((int32_t(*x) * _TOUCH_CALIBRATION_X) >> 16) + _TOUCH_OFFSET_X; + *y = int16_t((int32_t(*y) * _TOUCH_CALIBRATION_Y) >> 16) + _TOUCH_OFFSET_Y; return true; } bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) { static xy_int_t last { 0, 0 }; - if (get_point(last)) { - data->point.x = (TFT_ROTATION == TFT_ROTATE_180) ? TFT_WIDTH - last.x : last.x; - data->point.y = (TFT_ROTATION == TFT_ROTATE_180) ? TFT_HEIGHT - last.y : last.y; - data->state = LV_INDEV_STATE_PR; - } - else { - data->point.x = (TFT_ROTATION == TFT_ROTATE_180) ? TFT_WIDTH - last.x : last.x; - data->point.y = (TFT_ROTATION == TFT_ROTATE_180) ? TFT_HEIGHT - last.y : last.y; - data->state = LV_INDEV_STATE_REL; - } + data->state = get_point(&last.x, &last.y) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + data->point.x = (TFT_ROTATION == TFT_ROTATE_180) ? TFT_WIDTH - last.x : last.x; + data->point.y = (TFT_ROTATION == TFT_ROTATE_180) ? TFT_HEIGHT - last.y : last.y; return false; // Return `false` since no data is buffering or left to read } diff --git a/Marlin/src/lcd/extui/nextion/nextion_tft.cpp b/Marlin/src/lcd/extui/nextion/nextion_tft.cpp index 87a6544e5ef5..4833ab96ab77 100644 --- a/Marlin/src/lcd/extui/nextion/nextion_tft.cpp +++ b/Marlin/src/lcd/extui/nextion/nextion_tft.cpp @@ -158,8 +158,7 @@ void NextionTFT::sendFileList(int8_t startindex) { } void NextionTFT::selectFile() { - strncpy(selectedfile, nextion_command + 4, command_len - 4); - selectedfile[command_len - 5] = '\0'; + strlcpy(selectedfile, nextion_command + 4, command_len - 3); #if NEXDEBUG(N_FILE) DEBUG_ECHOLNPGM(" Selected File: ", selectedfile); #endif diff --git a/Marlin/src/lcd/lcdprint.cpp b/Marlin/src/lcd/lcdprint.cpp index f559272f7ed2..ea833f53a1df 100644 --- a/Marlin/src/lcd/lcdprint.cpp +++ b/Marlin/src/lcd/lcdprint.cpp @@ -67,24 +67,24 @@ lcd_uint_t expand_u8str_P(char * const outstr, PGM_P const ptpl, const int8_t in } else { PGM_P const b = ind == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED); - strncpy_P(o, b, n); + strlcpy_P(o, b, n + 1); n -= utf8_strlen(o); o += strlen(o); } if (n > 0) { - strncpy_P(o, (PGM_P)p, n); + strlcpy_P(o, (PGM_P)p, n + 1); n -= utf8_strlen(o); o += strlen(o); break; } } else if (wc == '$' && fstr) { - strncpy_P(o, FTOP(fstr), n); - n -= utf8_strlen_P(FTOP(fstr)); + strlcpy_P(o, FTOP(fstr), n + 1); + n -= utf8_strlen(o); o += strlen(o); } else if (wc == '$' && cstr) { - strncpy(o, cstr, n); + strlcpy(o, cstr, n + 1); n -= utf8_strlen(o); o += strlen(o); } diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index 178f0b74ecc5..4eb58f52aedf 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -67,6 +67,8 @@ MarlinUI ui; constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; +#define BLOCK_CLICK_AFTER_MOVEMENT_MS 100 + #if HAS_STATUS_MESSAGE #if ENABLED(STATUS_MESSAGE_SCROLLING) && ANY(HAS_WIRED_LCD, DWIN_LCD_PROUI) uint8_t MarlinUI::status_scroll_offset; // = 0 @@ -880,8 +882,8 @@ void MarlinUI::init() { void MarlinUI::external_encoder() { if (external_control && encoderDiff) { bedlevel.encoder_diff += encoderDiff; // Encoder for UBL G29 mesh editing - encoderDiff = 0; // Hide encoder events from the screen handler - refresh(LCDVIEW_REDRAW_NOW); // ...but keep the refresh. + encoderDiff = 0; // Hide encoder events from the screen handler + refresh(LCDVIEW_REDRAW_NOW); // ...but keep the refresh. } } @@ -932,7 +934,8 @@ void MarlinUI::init() { void MarlinUI::update() { static uint16_t max_display_update_time = 0; - millis_t ms = millis(); + static millis_t next_encoder_enable_ms = 0; + const millis_t ms = millis(); #if LED_POWEROFF_TIMEOUT > 0 leds.update_timeout(powerManager.psu_on); @@ -982,7 +985,12 @@ void MarlinUI::init() { if (!touch_buttons) { // Integrated LCD click handling via button_pressed if (!external_control && button_pressed()) { - if (!wait_for_unclick) do_click(); // Handle the click + if (!wait_for_unclick) { + if (ELAPSED(ms, next_encoder_enable_ms)) + do_click(); // Handle the click + else + wait_for_unclick = true; + } } else wait_for_unclick = false; @@ -1019,68 +1027,69 @@ void MarlinUI::init() { uint8_t abs_diff = ABS(encoderDiff); #if ENCODER_PULSES_PER_STEP > 1 - // When reversing the encoder direction, a movement step can be missed because - // encoderDiff has a non-zero residual value, making the controller unresponsive. - // The fix clears the residual value when the encoder is idle. - // Also check if past half the threshold to compensate for missed single steps. static int8_t lastEncoderDiff; - - // Timeout? No decoder change since last check. 10 or 20 times per second. - if (encoderDiff == lastEncoderDiff && abs_diff <= epps / 2) // Same direction & size but not over a half-step? - encoderDiff = 0; // Clear residual pulses. - else if (WITHIN(abs_diff, epps / 2 + 1, epps - 1)) { // Past half of threshold? - abs_diff = epps; // Treat as a full step size - encoderDiff = (encoderDiff < 0 ? -1 : 1) * abs_diff; // ...in the spin direction. - } TERN_(HAS_TOUCH_SLEEP, if (lastEncoderDiff != encoderDiff) wakeup_screen()); lastEncoderDiff = encoderDiff; #endif const bool encoderPastThreshold = (abs_diff >= epps); - if (encoderPastThreshold || lcd_clicked) { - if (encoderPastThreshold && TERN1(IS_TFTGLCD_PANEL, !external_control)) { + if (encoderPastThreshold && TERN1(IS_TFTGLCD_PANEL, !external_control)) { - #if ALL(HAS_MARLINUI_MENU, ENCODER_RATE_MULTIPLIER) + #if ALL(HAS_MARLINUI_MENU, ENCODER_RATE_MULTIPLIER) - int32_t encoderMultiplier = 1; + int32_t encoderMultiplier = 1; - if (encoderRateMultiplierEnabled) { + if (encoderRateMultiplierEnabled) { + if (lastEncoderMovementMillis) { const float encoderMovementSteps = float(abs_diff) / epps; + // Note that the rate is always calculated between two passes through the + // loop and that the abs of the encoderDiff value is tracked. + const float encoderStepRate = encoderMovementSteps / float(ms - lastEncoderMovementMillis) * 1000; + + if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100; + else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10; + + // Enable to output the encoder steps per second value + //#define ENCODER_RATE_MULTIPLIER_DEBUG + #if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG) + SERIAL_ECHO_START(); + SERIAL_ECHOPGM("Enc Step Rate: ", encoderStepRate); + SERIAL_ECHOPGM(" Multiplier: ", encoderMultiplier); + SERIAL_ECHOPGM(" ENCODER_10X_STEPS_PER_SEC: ", ENCODER_10X_STEPS_PER_SEC); + SERIAL_ECHOPGM(" ENCODER_100X_STEPS_PER_SEC: ", ENCODER_100X_STEPS_PER_SEC); + SERIAL_EOL(); + #endif + } - if (lastEncoderMovementMillis) { - // Note that the rate is always calculated between two passes through the - // loop and that the abs of the encoderDiff value is tracked. - const float encoderStepRate = encoderMovementSteps / float(ms - lastEncoderMovementMillis) * 1000; - - if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100; - else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10; - - // Enable to output the encoder steps per second value - //#define ENCODER_RATE_MULTIPLIER_DEBUG - #if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG) - SERIAL_ECHO_START(); - SERIAL_ECHOPGM("Enc Step Rate: ", encoderStepRate); - SERIAL_ECHOPGM(" Multiplier: ", encoderMultiplier); - SERIAL_ECHOPGM(" ENCODER_10X_STEPS_PER_SEC: ", ENCODER_10X_STEPS_PER_SEC); - SERIAL_ECHOPGM(" ENCODER_100X_STEPS_PER_SEC: ", ENCODER_100X_STEPS_PER_SEC); - SERIAL_EOL(); - #endif - } + lastEncoderMovementMillis = ms; + } // encoderRateMultiplierEnabled - lastEncoderMovementMillis = ms; - } // encoderRateMultiplierEnabled + #else - #else + constexpr int32_t encoderMultiplier = 1; - constexpr int32_t encoderMultiplier = 1; + #endif // ENCODER_RATE_MULTIPLIER - #endif // ENCODER_RATE_MULTIPLIER + int8_t fullSteps = encoderDiff / epps; + if (fullSteps != 0) { - if (can_encode()) encoderPosition += (encoderDiff * encoderMultiplier) / epps; + #if ENABLED(ENCODER_RATE_MULTIPLIER) + static bool lastFwd; + const bool fwd = fullSteps > 0; + if (encoderMultiplier != 1 && fwd != lastFwd) + fullSteps *= -1; // Fast move and direction changed? Assume glitch. + else + lastFwd = fwd; // Slow move or lastFwd==fwd already. Remember dir. + #endif - encoderDiff = 0; + next_encoder_enable_ms = ms + BLOCK_CLICK_AFTER_MOVEMENT_MS; + encoderDiff -= fullSteps * epps; + if (can_encode() && !lcd_clicked) + encoderPosition += (fullSteps * encoderMultiplier); } + } + if (encoderPastThreshold || lcd_clicked) { reset_status_timeout(ms); #if LCD_BACKLIGHT_TIMEOUT_MINS @@ -1094,7 +1103,7 @@ void MarlinUI::init() { #if LED_POWEROFF_TIMEOUT > 0 if (!powerManager.psu_on) leds.reset_timeout(ms); #endif - } // encoder activity + } #endif // HAS_ENCODER_ACTION @@ -1393,9 +1402,10 @@ void MarlinUI::init() { #if HAS_ENCODER_WHEEL static uint8_t lastEncoderBits; + bool ignore = false; // Manage encoder rotation - #define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: encoderDiff += encoderDirection; break; case _E2: encoderDiff -= encoderDirection; } + #define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: encoderDiff += encoderDirection; break; case _E2: encoderDiff -= encoderDirection; break; default: ignore = true; } uint8_t enc = 0; if (buttons & EN_A) enc |= B01; @@ -1410,7 +1420,7 @@ void MarlinUI::init() { #if ALL(HAS_MARLINUI_MENU, AUTO_BED_LEVELING_UBL) external_encoder(); #endif - lastEncoderBits = enc; + if (!ignore) lastEncoderBits = enc; } #endif // HAS_ENCODER_WHEEL diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index 7dd5b6b2d83d..595b89b6e00f 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -88,7 +88,7 @@ typedef bool (*statusResetFunc_t)(); #if ANY(HAS_WIRED_LCD, DWIN_CREALITY_LCD_JYERSUI) #define LCD_WITH_BLINK 1 - #define LCD_UPDATE_INTERVAL TERN(HAS_TOUCH_BUTTONS, 50, 100) + #define LCD_UPDATE_INTERVAL DIV_TERN(DOUBLE_LCD_FRAMERATE, TERN(HAS_TOUCH_BUTTONS, 50, 100), 2) #endif #if HAS_MARLINUI_U8GLIB diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp index 90a37ed5199c..51fb55c9a471 100644 --- a/Marlin/src/lcd/menu/menu_advanced.cpp +++ b/Marlin/src/lcd/menu/menu_advanced.cpp @@ -371,8 +371,8 @@ void menu_backlash(); #define _MPC_EDIT_ITEMS(N) \ MPC_t &mpc = thermalManager.temp_hotend[MenuItemBase::itemIndex].mpc; \ - EDIT_ITEM_FAST_N(float31sign, N, MSG_MPC_POWER_E, &mpc.heater_power, 1, 200); \ - EDIT_ITEM_FAST_N(float31sign, N, MSG_MPC_BLOCK_HEAT_CAPACITY_E, &mpc.block_heat_capacity, 0, 40); \ + EDIT_ITEM_FAST_N(float41, N, MSG_MPC_POWER_E, &mpc.heater_power, 1, 200); \ + EDIT_ITEM_FAST_N(float31, N, MSG_MPC_BLOCK_HEAT_CAPACITY_E, &mpc.block_heat_capacity, 0, 40); \ EDIT_ITEM_FAST_N(float43, N, MSG_SENSOR_RESPONSIVENESS_E, &mpc.sensor_responsiveness, 0, 1); \ EDIT_ITEM_FAST_N(float43, N, MSG_MPC_AMBIENT_XFER_COEFF_E, &mpc.ambient_xfer_coeff_fan0, 0, 1) @@ -562,24 +562,24 @@ void menu_backlash(); #if ENABLED(INPUT_SHAPING_X) editable.decimal = stepper.get_shaping_frequency(X_AXIS); if (editable.decimal) { - ACTION_ITEM_N(X_AXIS, MSG_SHAPING_DISABLE, []{ stepper.set_shaping_frequency(X_AXIS, 0.0f); }); - EDIT_ITEM_FAST_N(float61, X_AXIS, MSG_SHAPING_FREQ, &editable.decimal, min_frequency, 200.0f, []{ stepper.set_shaping_frequency(X_AXIS, editable.decimal); }); + ACTION_ITEM_N(X_AXIS, MSG_SHAPING_DISABLE, []{ stepper.set_shaping_frequency(X_AXIS, 0.0f); ui.refresh(LCDVIEW_CLEAR_CALL_REDRAW); }); + EDIT_ITEM_FAST_N(float41, X_AXIS, MSG_SHAPING_FREQ, &editable.decimal, min_frequency, 200.0f, []{ stepper.set_shaping_frequency(X_AXIS, editable.decimal); }); editable.decimal = stepper.get_shaping_damping_ratio(X_AXIS); EDIT_ITEM_FAST_N(float42_52, X_AXIS, MSG_SHAPING_ZETA, &editable.decimal, 0.0f, 1.0f, []{ stepper.set_shaping_damping_ratio(X_AXIS, editable.decimal); }); } else - ACTION_ITEM_N(X_AXIS, MSG_SHAPING_ENABLE, []{ stepper.set_shaping_frequency(X_AXIS, (SHAPING_FREQ_X) ?: (SHAPING_MIN_FREQ)); }); + ACTION_ITEM_N(X_AXIS, MSG_SHAPING_ENABLE, []{ stepper.set_shaping_frequency(X_AXIS, (SHAPING_FREQ_X) ?: (SHAPING_MIN_FREQ)); ui.refresh(LCDVIEW_CLEAR_CALL_REDRAW); }); #endif #if ENABLED(INPUT_SHAPING_Y) editable.decimal = stepper.get_shaping_frequency(Y_AXIS); if (editable.decimal) { - ACTION_ITEM_N(Y_AXIS, MSG_SHAPING_DISABLE, []{ stepper.set_shaping_frequency(Y_AXIS, 0.0f); }); - EDIT_ITEM_FAST_N(float61, Y_AXIS, MSG_SHAPING_FREQ, &editable.decimal, min_frequency, 200.0f, []{ stepper.set_shaping_frequency(Y_AXIS, editable.decimal); }); + ACTION_ITEM_N(Y_AXIS, MSG_SHAPING_DISABLE, []{ stepper.set_shaping_frequency(Y_AXIS, 0.0f); ui.refresh(LCDVIEW_CLEAR_CALL_REDRAW); }); + EDIT_ITEM_FAST_N(float41, Y_AXIS, MSG_SHAPING_FREQ, &editable.decimal, min_frequency, 200.0f, []{ stepper.set_shaping_frequency(Y_AXIS, editable.decimal); }); editable.decimal = stepper.get_shaping_damping_ratio(Y_AXIS); EDIT_ITEM_FAST_N(float42_52, Y_AXIS, MSG_SHAPING_ZETA, &editable.decimal, 0.0f, 1.0f, []{ stepper.set_shaping_damping_ratio(Y_AXIS, editable.decimal); }); } else - ACTION_ITEM_N(Y_AXIS, MSG_SHAPING_ENABLE, []{ stepper.set_shaping_frequency(Y_AXIS, (SHAPING_FREQ_Y) ?: (SHAPING_MIN_FREQ)); }); + ACTION_ITEM_N(Y_AXIS, MSG_SHAPING_ENABLE, []{ stepper.set_shaping_frequency(Y_AXIS, (SHAPING_FREQ_Y) ?: (SHAPING_MIN_FREQ)); ui.refresh(LCDVIEW_CLEAR_CALL_REDRAW); }); #endif END_MENU(); diff --git a/Marlin/src/lcd/menu/menu_bed_leveling.cpp b/Marlin/src/lcd/menu/menu_bed_leveling.cpp index f4d5a269af69..9fb9813ee504 100644 --- a/Marlin/src/lcd/menu/menu_bed_leveling.cpp +++ b/Marlin/src/lcd/menu/menu_bed_leveling.cpp @@ -138,7 +138,7 @@ // void _lcd_level_bed_moving() { if (ui.should_draw()) { - MString<9> msg; + MString<10> msg; msg.setf(F(" %i / %u"), int(manual_probe_index + 1), total_probe_points); MenuItem_static::draw(LCD_HEIGHT / 2, GET_TEXT_F(MSG_LEVEL_BED_NEXT_POINT), SS_CENTER, msg); } diff --git a/Marlin/src/lcd/menu/menu_item.h b/Marlin/src/lcd/menu/menu_item.h index 4d3e33db4c5a..823d2a4a25e7 100644 --- a/Marlin/src/lcd/menu/menu_item.h +++ b/Marlin/src/lcd/menu/menu_item.h @@ -150,10 +150,19 @@ DEFINE_MENU_EDIT_ITEM_TYPE(uint16_5 ,uint16_t ,ui16tostr5rj , 0.01f DEFINE_MENU_EDIT_ITEM_TYPE(float3 ,float ,ftostr3rj , 1 ); // 123 right-justified DEFINE_MENU_EDIT_ITEM_TYPE(float42_52 ,float ,ftostr42_52 , 100 , + 0.001f ); // _2.34, 12.34, -2.34 or 123.45, -23.45 DEFINE_MENU_EDIT_ITEM_TYPE(float43 ,float ,ftostr43sign ,1000 , + 0.0001f); // -1.234, _1.234, +1.234 +DEFINE_MENU_EDIT_ITEM_TYPE(float53 ,float ,ftostr53sign ,1000 , + 0.0001f); // -12.345, _2.345, +2.345 +DEFINE_MENU_EDIT_ITEM_TYPE(float54 ,float ,ftostr54sign ,10000 , + 0.00001f); // -1.2345, _1.2345, +1.2345 DEFINE_MENU_EDIT_ITEM_TYPE(float4 ,float ,ftostr4sign , 1 ); // 1234 right-justified DEFINE_MENU_EDIT_ITEM_TYPE(float5 ,float ,ftostr5rj , 1 ); // 12345 right-justified DEFINE_MENU_EDIT_ITEM_TYPE(float5_25 ,float ,ftostr5rj , 0.04f ); // 12345 right-justified (25 increment) +DEFINE_MENU_EDIT_ITEM_TYPE(float31 ,float ,ftostr31rj , 10 , + 0.01f ); // 45.6 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(float41 ,float ,ftostr41rj , 10 , + 0.01f ); // 345.6 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(float51 ,float ,ftostr51rj , 10 , + 0.01f ); // 1234.5 right-justified DEFINE_MENU_EDIT_ITEM_TYPE(float61 ,float ,ftostr61rj , 10 , + 0.01f ); // 12345.6 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(float32 ,float ,ftostr32rj , 100 , + 0.001f ); // 1.23 +DEFINE_MENU_EDIT_ITEM_TYPE(float42 ,float ,ftostr42rj , 100 , + 0.001f ); // 12.34 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(float52 ,float ,ftostr52rj , 100 , + 0.001f ); // 123.45 right-justified +DEFINE_MENU_EDIT_ITEM_TYPE(float62 ,float ,ftostr62rj , 100 , + 0.001f ); // 1234.56 right-justified DEFINE_MENU_EDIT_ITEM_TYPE(float72 ,float ,ftostr72rj , 100 , + 0.001f ); // 12345.67 right-justified DEFINE_MENU_EDIT_ITEM_TYPE(float31sign ,float ,ftostr31sign , 10 , + 0.01f ); // +12.3 DEFINE_MENU_EDIT_ITEM_TYPE(float41sign ,float ,ftostr41sign , 10 , + 0.01f ); // +123.4 @@ -377,11 +386,11 @@ class MenuItem_bool : public MenuEditItemBase { #define PSTRING_ITEM_F_P(FLABEL, PVAL, STYL) do{ \ constexpr int m = 20; \ - char msg[m+1]; \ + char msg[m + 1]; \ if (_menuLineNr == _thisItemNr) { \ msg[0] = ':'; msg[1] = ' '; \ - strncpy_P(msg+2, PVAL, m-2); \ - if (msg[m-1] & 0x80) msg[m-1] = '\0'; \ + strlcpy_P(msg + 2, PVAL, m - 1); \ + if (msg[m - 1] & 0x80) msg[m - 1] = '\0'; \ } \ STATIC_ITEM_F(FLABEL, STYL, msg); \ }while(0) diff --git a/Marlin/src/lcd/menu/menu_main.cpp b/Marlin/src/lcd/menu/menu_main.cpp index 1bf380e3608c..3daeb285a17a 100644 --- a/Marlin/src/lcd/menu/menu_main.cpp +++ b/Marlin/src/lcd/menu/menu_main.cpp @@ -296,7 +296,7 @@ void menu_main() { #if ENABLED(TFT_COLOR_UI) // Menu display issue on item removal with multi language selection menu if (encoderTopLine > 0) encoderTopLine--; - ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); + ui.refresh(LCDVIEW_CLEAR_CALL_REDRAW); #endif }); #endif @@ -413,7 +413,7 @@ void menu_main() { #if ENABLED(TFT_COLOR_UI) // Menu display issue on item removal with multi language selection menu if (encoderTopLine > 0) encoderTopLine--; - ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); + ui.refresh(LCDVIEW_CLEAR_CALL_REDRAW); #endif }); #endif diff --git a/Marlin/src/lcd/tft/touch.cpp b/Marlin/src/lcd/tft/touch.cpp index 8e79e397adea..3c0b21ba8fd3 100644 --- a/Marlin/src/lcd/tft/touch.cpp +++ b/Marlin/src/lcd/tft/touch.cpp @@ -39,7 +39,7 @@ #include "tft.h" bool Touch::enabled = true; -xy_int_t Touch::point; +int16_t Touch::x, Touch::y; touch_control_t Touch::controls[]; touch_control_t *Touch::current_control; uint16_t Touch::controls_count; @@ -67,13 +67,17 @@ void Touch::add_control(TouchControlType type, uint16_t x, uint16_t y, uint16_t if (controls_count == MAX_CONTROLS) return; controls[controls_count].type = type; - controls[controls_count].pos.set(x, y); - controls[controls_count].size.set(width, height); + controls[controls_count].x = x; + controls[controls_count].y = y; + controls[controls_count].width = width; + controls[controls_count].height = height; controls[controls_count].data = data; controls_count++; } void Touch::idle() { + int16_t _x, _y; + if (!enabled) return; // Return if Touch::idle is called within the same millisecond @@ -81,8 +85,7 @@ void Touch::idle() { if (now <= next_touch_ms) return; next_touch_ms = now; - xy_int_t got_point; - if (get_point(got_point)) { + if (get_point(&_x, &_y)) { #if HAS_RESUME_CONTINUE // UI is waiting for a click anywhere? if (wait_for_user) { @@ -106,13 +109,11 @@ void Touch::idle() { if (time_to_hold == 0) time_to_hold = now + MINIMUM_HOLD_TIME; if (PENDING(now, time_to_hold)) return; - if (bool(point)) { + if (x != 0 && y != 0) { if (current_control) { - if ( WITHIN(point.x, current_control->pos.x - FREE_MOVE_RANGE, current_control->pos.x + current_control->size.x + FREE_MOVE_RANGE) - && WITHIN(point.y, current_control->pos.y - FREE_MOVE_RANGE, current_control->pos.y + current_control->size.y + FREE_MOVE_RANGE) - ) { - LIMIT(point.x, current_control->pos.x, current_control->pos.x + current_control->size.x); - LIMIT(point.y, current_control->pos.y, current_control->pos.y + current_control->size.y); + if (WITHIN(x, current_control->x - FREE_MOVE_RANGE, current_control->x + current_control->width + FREE_MOVE_RANGE) && WITHIN(y, current_control->y - FREE_MOVE_RANGE, current_control->y + current_control->height + FREE_MOVE_RANGE)) { + LIMIT(x, current_control->x, current_control->x + current_control->width); + LIMIT(y, current_control->y, current_control->y + current_control->height); touch(current_control); } else @@ -120,10 +121,7 @@ void Touch::idle() { } else { for (uint16_t i = 0; i < controls_count; i++) { - if (TERN0(TOUCH_SCREEN_CALIBRATION, controls[i].type == CALIBRATE) - || ( WITHIN(point.x, controls[i].pos.x, controls[i].pos.x + controls[i].size.x) - && WITHIN(point.y, controls[i].pos.y, controls[i].pos.y + controls[i].size.y)) - ) { + if ((WITHIN(x, controls[i].x, controls[i].x + controls[i].width) && WITHIN(y, controls[i].y, controls[i].y + controls[i].height)) || (TERN(TOUCH_SCREEN_CALIBRATION, controls[i].type == CALIBRATE, false))) { touch_control_type = controls[i].type; touch(&controls[i]); break; @@ -134,10 +132,11 @@ void Touch::idle() { if (!current_control) touch_time = now; } - point = got_point; + x = _x; + y = _y; } else { - point.reset(); + x = y = 0; current_control = nullptr; touch_time = 0; touch_control_type = NONE; @@ -150,7 +149,7 @@ void Touch::touch(touch_control_t *control) { switch (control->type) { #if ENABLED(TOUCH_SCREEN_CALIBRATION) case CALIBRATE: - if (touch_calibration.handleTouch(point)) ui.refresh(); + if (touch_calibration.handleTouch(x, y)) ui.refresh(); break; #endif @@ -177,7 +176,7 @@ void Touch::touch(touch_control_t *control) { ui.encoderPosition = ui.encoderPosition + LCD_HEIGHT < (uint32_t)screen_items ? ui.encoderPosition + LCD_HEIGHT : screen_items; ui.refresh(); break; - case SLIDER: hold(control); ui.encoderPosition = (point.x - control->pos.x) * control->data / control->size.x; break; + case SLIDER: hold(control); ui.encoderPosition = (x - control->x) * control->data / control->width; break; case INCREASE: hold(control, repeat_delay - 5); TERN(AUTO_BED_LEVELING_UBL, ui.external_control ? bedlevel.encoder_diff++ : ui.encoderPosition++, ui.encoderPosition++); break; case DECREASE: hold(control, repeat_delay - 5); TERN(AUTO_BED_LEVELING_UBL, ui.external_control ? bedlevel.encoder_diff-- : ui.encoderPosition--, ui.encoderPosition--); break; case HEATER: @@ -263,16 +262,19 @@ void Touch::hold(touch_control_t *control, millis_t delay) { ui.refresh(); } -bool Touch::get_point(xy_int_t &point) { - bool is_touched = false; +bool Touch::get_point(int16_t * const x, int16_t * const y) { #if ANY(TFT_TOUCH_DEVICE_XPT2046, TFT_TOUCH_DEVICE_GT911) - is_touched = (TOUCH_ORIENTATION_NONE != _TOUCH_ORIENTATION) - && (TOUCH_PORTRAIT == _TOUCH_ORIENTATION - ? io.getRawPoint(&point.y, &point.x) - : io.getRawPoint(&point.x, &point.y)); - #if ENABLED(TFT_TOUCH_DEVICE_XPT2046) - point.x = uint16_t((uint32_t(point.x) * _TOUCH_CALIBRATION_X) >> 16) + _TOUCH_OFFSET_X; - point.y = uint16_t((uint32_t(point.y) * _TOUCH_CALIBRATION_Y) >> 16) + _TOUCH_OFFSET_Y; + const bool is_touched = TOUCH_PORTRAIT == _TOUCH_ORIENTATION ? io.getRawPoint(y, x) : io.getRawPoint(x, y); + #endif + #if ENABLED(TFT_TOUCH_DEVICE_XPT2046) + #if ENABLED(TOUCH_SCREEN_CALIBRATION) + if (is_touched && TOUCH_ORIENTATION_NONE != _TOUCH_ORIENTATION) { + *x = int16_t((int32_t(*x) * _TOUCH_CALIBRATION_X) >> 16) + _TOUCH_OFFSET_X; + *y = int16_t((int32_t(*y) * _TOUCH_CALIBRATION_Y) >> 16) + _TOUCH_OFFSET_Y; + } + #else + *x = uint16_t((uint32_t(*x) * _TOUCH_CALIBRATION_X) >> 16) + _TOUCH_OFFSET_X; + *y = uint16_t((uint32_t(*y) * _TOUCH_CALIBRATION_Y) >> 16) + _TOUCH_OFFSET_Y; #endif #endif diff --git a/Marlin/src/lcd/tft/touch.h b/Marlin/src/lcd/tft/touch.h index 6c0ff88f4674..93f9327a15b3 100644 --- a/Marlin/src/lcd/tft/touch.h +++ b/Marlin/src/lcd/tft/touch.h @@ -57,8 +57,10 @@ enum TouchControlType : uint16_t { typedef struct __attribute__((__packed__)) { TouchControlType type; - xy_uint_t pos; - xy_uint_t size; + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; intptr_t data; } touch_control_t; @@ -75,7 +77,7 @@ typedef struct __attribute__((__packed__)) { class Touch { private: static TOUCH_DRIVER_CLASS io; - static xy_int_t point; + static int16_t x, y; static bool enabled; static touch_control_t controls[MAX_CONTROLS]; @@ -85,7 +87,7 @@ class Touch { static millis_t next_touch_ms, time_to_hold, repeat_delay, touch_time; static TouchControlType touch_control_type; - static bool get_point(xy_int_t &point); + static bool get_point(int16_t * const x, int16_t * const y); static void touch(touch_control_t *control); static void hold(touch_control_t *control, millis_t delay=0); diff --git a/Marlin/src/lcd/tft_io/touch_calibration.cpp b/Marlin/src/lcd/tft_io/touch_calibration.cpp index b1cdfe6cda94..f76c29eb49f2 100644 --- a/Marlin/src/lcd/tft_io/touch_calibration.cpp +++ b/Marlin/src/lcd/tft_io/touch_calibration.cpp @@ -58,18 +58,18 @@ void TouchCalibration::validate_calibration() { #define CP(N) calibration_points[CALIBRATION_##N] if (landscape) { calibration_state = CALIBRATION_SUCCESS; - calibration.x = ((CP(TOP_RIGHT).x - CP(TOP_LEFT).x) << 17) / (CP(BOTTOM_RIGHT).raw.x + CP(TOP_RIGHT).raw.x - CP(BOTTOM_LEFT).raw.x - CP(TOP_LEFT).raw.x); - calibration.y = ((CP(BOTTOM_LEFT).y - CP(TOP_LEFT).y) << 17) / (CP(BOTTOM_RIGHT).raw.y - CP(TOP_RIGHT).raw.y + CP(BOTTOM_LEFT).raw.y - CP(TOP_LEFT).raw.y); - calibration.offset.x = CP(TOP_LEFT).x - int16_t(((CP(TOP_LEFT).raw.x + CP(BOTTOM_LEFT).raw.x) * calibration.x) >> 17); - calibration.offset.y = CP(TOP_LEFT).y - int16_t(((CP(TOP_LEFT).raw.y + CP(TOP_RIGHT).raw.y) * calibration.y) >> 17); + calibration.x = ((CP(TOP_RIGHT).x - CP(TOP_LEFT).x) << 17) / (CP(BOTTOM_RIGHT).raw_x + CP(TOP_RIGHT).raw_x - CP(BOTTOM_LEFT).raw_x - CP(TOP_LEFT).raw_x); + calibration.y = ((CP(BOTTOM_LEFT).y - CP(TOP_LEFT).y) << 17) / (CP(BOTTOM_RIGHT).raw_y - CP(TOP_RIGHT).raw_y + CP(BOTTOM_LEFT).raw_y - CP(TOP_LEFT).raw_y); + calibration.offset_x = CP(TOP_LEFT).x - int16_t(((CP(TOP_LEFT).raw_x + CP(BOTTOM_LEFT).raw_x) * calibration.x) >> 17); + calibration.offset_y = CP(TOP_LEFT).y - int16_t(((CP(TOP_LEFT).raw_y + CP(TOP_RIGHT).raw_y) * calibration.y) >> 17); calibration.orientation = TOUCH_LANDSCAPE; } else if (portrait) { calibration_state = CALIBRATION_SUCCESS; - calibration.x = ((CP(TOP_RIGHT).x - CP(TOP_LEFT).x) << 17) / (CP(BOTTOM_RIGHT).raw.y + CP(TOP_RIGHT).raw.y - CP(BOTTOM_LEFT).raw.y - CP(TOP_LEFT).raw.y); - calibration.y = ((CP(BOTTOM_LEFT).y - CP(TOP_LEFT).y) << 17) / (CP(BOTTOM_RIGHT).raw.x - CP(TOP_RIGHT).raw.x + CP(BOTTOM_LEFT).raw.x - CP(TOP_LEFT).raw.x); - calibration.offset.x = CP(TOP_LEFT).x - int16_t(((CP(TOP_LEFT).raw.y + CP(BOTTOM_LEFT).raw.y) * calibration.x) >> 17); - calibration.offset.y = CP(TOP_LEFT).y - int16_t(((CP(TOP_LEFT).raw.x + CP(TOP_RIGHT).raw.x) * calibration.y) >> 17); + calibration.x = ((CP(TOP_RIGHT).x - CP(TOP_LEFT).x) << 17) / (CP(BOTTOM_RIGHT).raw_y + CP(TOP_RIGHT).raw_y - CP(BOTTOM_LEFT).raw_y - CP(TOP_LEFT).raw_y); + calibration.y = ((CP(BOTTOM_LEFT).y - CP(TOP_LEFT).y) << 17) / (CP(BOTTOM_RIGHT).raw_x - CP(TOP_RIGHT).raw_x + CP(BOTTOM_LEFT).raw_x - CP(TOP_LEFT).raw_x); + calibration.offset_x = CP(TOP_LEFT).x - int16_t(((CP(TOP_LEFT).raw_y + CP(BOTTOM_LEFT).raw_y) * calibration.x) >> 17); + calibration.offset_y = CP(TOP_LEFT).y - int16_t(((CP(TOP_LEFT).raw_x + CP(TOP_RIGHT).raw_x) * calibration.y) >> 17); calibration.orientation = TOUCH_PORTRAIT; } else { @@ -83,23 +83,23 @@ void TouchCalibration::validate_calibration() { SERIAL_ECHOLNPGM("Touch screen calibration completed"); SERIAL_ECHOLN(F("#define TOUCH_"), F("CALIBRATION_X "), calibration.x); SERIAL_ECHOLN(F("#define TOUCH_"), F("CALIBRATION_Y "), calibration.y); - SERIAL_ECHOLN(F("#define TOUCH_"), F("OFFSET_X "), calibration.offset.x); - SERIAL_ECHOLN(F("#define TOUCH_"), F("OFFSET_Y "), calibration.offset.y); + SERIAL_ECHOLN(F("#define TOUCH_"), F("OFFSET_X "), calibration.offset_x); + SERIAL_ECHOLN(F("#define TOUCH_"), F("OFFSET_Y "), calibration.offset_y); SERIAL_ECHO(F("#define TOUCH_")); SERIAL_ECHO_TERNARY(calibration.orientation == TOUCH_LANDSCAPE, "ORIENTATION ", "TOUCH_LANDSCAPE", "TOUCH_PORTRAIT", "\n"); TERN_(TOUCH_CALIBRATION_AUTO_SAVE, settings.save()); } } -bool TouchCalibration::handleTouch(const xy_int_t &point) { +bool TouchCalibration::handleTouch(const uint16_t x, const uint16_t y) { const millis_t now = millis(); + if (next_touch_update_ms && PENDING(now, next_touch_update_ms)) return false; next_touch_update_ms = now + BUTTON_DELAY_MENU; if (calibration_state < CALIBRATION_SUCCESS) { - calibration_points[calibration_state].raw = point; - DEBUG_ECHOLNPGM("TouchCalibration - State: ", calibration_state, - ", x: ", calibration_points[calibration_state].x, ", raw.x: ", point.x, - ", y: ", calibration_points[calibration_state].y, ", raw.y: ", point.y); + calibration_points[calibration_state].raw_x = x; + calibration_points[calibration_state].raw_y = y; + DEBUG_ECHOLNPGM("TouchCalibration - State: ", calibration_state, ", x: ", calibration_points[calibration_state].x, ", raw_x: ", x, ", y: ", calibration_points[calibration_state].y, ", raw_y: ", y); } switch (calibration_state) { diff --git a/Marlin/src/lcd/tft_io/touch_calibration.h b/Marlin/src/lcd/tft_io/touch_calibration.h index be226db224cc..5e15f85cb570 100644 --- a/Marlin/src/lcd/tft_io/touch_calibration.h +++ b/Marlin/src/lcd/tft_io/touch_calibration.h @@ -27,8 +27,8 @@ #define _TOUCH_CALIBRATION_X touch_calibration.calibration.x #define _TOUCH_CALIBRATION_Y touch_calibration.calibration.y -#define _TOUCH_OFFSET_X touch_calibration.calibration.offset.x -#define _TOUCH_OFFSET_Y touch_calibration.calibration.offset.y +#define _TOUCH_OFFSET_X touch_calibration.calibration.offset_x +#define _TOUCH_OFFSET_Y touch_calibration.calibration.offset_y #define _TOUCH_ORIENTATION touch_calibration.calibration.orientation #ifndef TOUCH_SCREEN_CALIBRATION_PRECISION @@ -38,22 +38,15 @@ #define TOUCH_SCREEN_HOLD_TO_CALIBRATE_MS 2500 #endif -typedef struct __attribute__((__packed__)) TouchCal : xy_long_t { - xy_int_t offset; +typedef struct __attribute__((__packed__)) { + int32_t x, y; + int16_t offset_x, offset_y; uint8_t orientation; - TouchCal() { set(xy_long_t({ 0, 0 }), xy_int_t({ 0, 0 }), TOUCH_ORIENTATION_NONE); } - void set(const xy_long_t &xy, const xy_int_t &hv, const uint8_t o) { - xy_long_t::set(xy); offset = hv; orientation = o; - } - void reset() { - set(xy_long_t({ TOUCH_CALIBRATION_X, TOUCH_CALIBRATION_Y }), - xy_int_t({ TOUCH_OFFSET_X, TOUCH_OFFSET_Y }), - TOUCH_ORIENTATION); - } } touch_calibration_t; -typedef struct __attribute__((__packed__)) : xy_uint_t { - xy_int_t raw; +typedef struct __attribute__((__packed__)) { + uint16_t x, y; + int16_t raw_x, raw_y; } touch_calibration_point_t; enum calibrationState : uint8_t { @@ -72,24 +65,28 @@ class TouchCalibration { static touch_calibration_point_t calibration_points[4]; static millis_t next_touch_update_ms; - static bool validate_precision(int32_t a, int32_t b) { return (a > b ? (100 * b) / a : (100 * a) / b) > (TOUCH_SCREEN_CALIBRATION_PRECISION); } - static bool validate_precision_x(uint8_t a, uint8_t b) { return validate_precision(calibration_points[a].raw.x, calibration_points[b].raw.x); } - static bool validate_precision_y(uint8_t a, uint8_t b) { return validate_precision(calibration_points[a].raw.y, calibration_points[b].raw.y); } + static bool validate_precision(int32_t a, int32_t b) { return (a > b ? (100 * b) / a : (100 * a) / b) > TOUCH_SCREEN_CALIBRATION_PRECISION; } + static bool validate_precision_x(uint8_t a, uint8_t b) { return validate_precision(calibration_points[a].raw_x, calibration_points[b].raw_x); } + static bool validate_precision_y(uint8_t a, uint8_t b) { return validate_precision(calibration_points[a].raw_y, calibration_points[b].raw_y); } static void validate_calibration(); static touch_calibration_t calibration; static uint8_t failed_count; - static void calibration_reset() { calibration.set(xy_long_t({ TOUCH_CALIBRATION_X, TOUCH_CALIBRATION_Y }), xy_int_t({ TOUCH_OFFSET_X, TOUCH_OFFSET_Y }), TOUCH_ORIENTATION); } - static bool need_calibration() { return !(calibration.offset.x || calibration.offset.y || calibration.x || calibration.y); } + static void calibration_reset() { calibration = { TOUCH_CALIBRATION_X, TOUCH_CALIBRATION_Y, TOUCH_OFFSET_X, TOUCH_OFFSET_Y, TOUCH_ORIENTATION }; } + static bool need_calibration() { return !calibration.offset_x && !calibration.offset_y && !calibration.x && !calibration.y; } static calibrationState calibration_start() { next_touch_update_ms = millis() + 750UL; - calibration.reset(); + calibration = { 0, 0, 0, 0, TOUCH_ORIENTATION_NONE }; calibration_state = CALIBRATION_TOP_LEFT; - calibration_points[CALIBRATION_TOP_LEFT].set(30, 30); - calibration_points[CALIBRATION_TOP_RIGHT].set(TFT_WIDTH - 31, 30); - calibration_points[CALIBRATION_BOTTOM_RIGHT].set(TFT_WIDTH - 31, TFT_HEIGHT - 31); - calibration_points[CALIBRATION_BOTTOM_LEFT].set(30, TFT_HEIGHT - 31); + calibration_points[CALIBRATION_TOP_LEFT].x = 30; + calibration_points[CALIBRATION_TOP_LEFT].y = 30; + calibration_points[CALIBRATION_TOP_RIGHT].x = TFT_WIDTH - 31; + calibration_points[CALIBRATION_TOP_RIGHT].y = 30; + calibration_points[CALIBRATION_BOTTOM_RIGHT].x = TFT_WIDTH - 31; + calibration_points[CALIBRATION_BOTTOM_RIGHT].y = TFT_HEIGHT - 31; + calibration_points[CALIBRATION_BOTTOM_LEFT].x = 30; + calibration_points[CALIBRATION_BOTTOM_LEFT].y = TFT_HEIGHT - 31; failed_count = 0; return calibration_state; } @@ -100,12 +97,12 @@ class TouchCalibration { return !need_calibration(); } - static bool handleTouch(const xy_int_t &point); + static bool handleTouch(const uint16_t x, const uint16_t y); }; extern TouchCalibration touch_calibration; -#else // TOUCH_SCREEN_CALIBRATION +#else // !TOUCH_SCREEN_CALIBRATION #define _TOUCH_CALIBRATION_X (TOUCH_CALIBRATION_X) #define _TOUCH_CALIBRATION_Y (TOUCH_CALIBRATION_Y) diff --git a/Marlin/src/lcd/touch/touch_buttons.cpp b/Marlin/src/lcd/touch/touch_buttons.cpp index 636a31dafa41..7d31b21c04a6 100644 --- a/Marlin/src/lcd/touch/touch_buttons.cpp +++ b/Marlin/src/lcd/touch/touch_buttons.cpp @@ -66,6 +66,7 @@ uint8_t TouchButtons::read_buttons() { int16_t x, y; #if ENABLED(TFT_TOUCH_DEVICE_XPT2046) + const bool is_touched = TOUCH_PORTRAIT == _TOUCH_ORIENTATION ? touchIO.getRawPoint(&y, &x) : touchIO.getRawPoint(&x, &y); @@ -88,13 +89,16 @@ uint8_t TouchButtons::read_buttons() { #if ENABLED(TOUCH_SCREEN_CALIBRATION) const calibrationState state = touch_calibration.get_calibration_state(); if (WITHIN(state, CALIBRATION_TOP_LEFT, CALIBRATION_BOTTOM_LEFT)) { - if (!no_touch && touch_calibration.handleTouch(xy_int_t({x, y}))) ui.refresh(); + if (!no_touch && touch_calibration.handleTouch(x, y)) ui.refresh(); no_touch = true; return 0; } + x = int16_t((int32_t(x) * _TOUCH_CALIBRATION_X) >> 16) + _TOUCH_OFFSET_X; + y = int16_t((int32_t(y) * _TOUCH_CALIBRATION_Y) >> 16) + _TOUCH_OFFSET_Y; + #else + x = uint16_t((uint32_t(x) * _TOUCH_CALIBRATION_X) >> 16) + _TOUCH_OFFSET_X; + y = uint16_t((uint32_t(y) * _TOUCH_CALIBRATION_Y) >> 16) + _TOUCH_OFFSET_Y; #endif - x = uint16_t((uint32_t(x) * _TOUCH_CALIBRATION_X) >> 16) + _TOUCH_OFFSET_X; - y = uint16_t((uint32_t(y) * _TOUCH_CALIBRATION_Y) >> 16) + _TOUCH_OFFSET_Y; #elif ENABLED(TFT_TOUCH_DEVICE_GT911) diff --git a/Marlin/src/libs/numtostr.cpp b/Marlin/src/libs/numtostr.cpp index e27373263556..6f4e4a480bfb 100644 --- a/Marlin/src/libs/numtostr.cpp +++ b/Marlin/src/libs/numtostr.cpp @@ -45,7 +45,7 @@ constexpr long UINTFLOAT(const float V, const int N) { char conv[9] = { 0 }; -// Format uint8_t (0-100) as rj string with 123% / _12% / __1% format +// Format uint8_t (0-100) as rj string with __3% / _23% / 123% format const char* pcttostrpctrj(const uint8_t i) { conv[4] = RJDIGIT(i, 100); conv[5] = RJDIGIT(i, 10); @@ -59,7 +59,7 @@ const char* ui8tostr4pctrj(const uint8_t i) { return pcttostrpctrj(ui8_to_percent(i)); } -// Convert unsigned 8bit int to string 123 format +// Convert unsigned 8bit int to string with __3 / _23 / 123 format const char* ui8tostr3rj(const uint8_t i) { conv[5] = RJDIGIT(i, 100); conv[6] = RJDIGIT(i, 10); @@ -74,7 +74,7 @@ const char* ui8tostr2(const uint8_t i) { return &conv[6]; } -// Convert signed 8bit int to rj string with 123 or -12 format +// Convert signed 8bit int to rj string with __3 / _23 / 123 / -_3 / -23 format const char* i8tostr3rj(const int8_t x) { int xx = x; conv[5] = MINUSOR(xx, RJDIGIT(xx, 100)); @@ -105,32 +105,26 @@ const char* i8tostr3rj(const int8_t x) { } #endif -// Convert unsigned 16bit int to string 12345 format -const char* ui16tostr5rj(const uint16_t xx) { - conv[3] = RJDIGIT(xx, 10000); - conv[4] = RJDIGIT(xx, 1000); - conv[5] = RJDIGIT(xx, 100); - conv[6] = RJDIGIT(xx, 10); +// Convert unsigned 16bit int to right-justified string +inline const char* ui16tostrXrj(const uint16_t xx, const int index) { + switch (index) { + case 0 ... 3: conv[3] = RJDIGIT(xx, 10000); + case 4: conv[4] = RJDIGIT(xx, 1000); + case 5: conv[5] = RJDIGIT(xx, 100); + case 6: conv[6] = RJDIGIT(xx, 10); + } conv[7] = DIGIMOD(xx, 1); - return &conv[3]; + return &conv[index]; } -// Convert unsigned 16bit int to string 1234 format -const char* ui16tostr4rj(const uint16_t xx) { - conv[4] = RJDIGIT(xx, 1000); - conv[5] = RJDIGIT(xx, 100); - conv[6] = RJDIGIT(xx, 10); - conv[7] = DIGIMOD(xx, 1); - return &conv[4]; -} +// Convert unsigned 16bit int to string with 12345 format +const char* ui16tostr5rj(const uint16_t xx) { return ui16tostrXrj(xx, 8 - 5); } -// Convert unsigned 16bit int to string 123 format -const char* ui16tostr3rj(const uint16_t xx) { - conv[5] = RJDIGIT(xx, 100); - conv[6] = RJDIGIT(xx, 10); - conv[7] = DIGIMOD(xx, 1); - return &conv[5]; -} +// Convert unsigned 16bit int to string with 1234 format +const char* ui16tostr4rj(const uint16_t xx) { return ui16tostrXrj(xx, 8 - 4); } + +// Convert unsigned 16bit int to string with 123 format +const char* ui16tostr3rj(const uint16_t xx) { return ui16tostrXrj(xx, 8 - 3); } // Convert signed 16bit int to rj string with 123 or -12 format const char* i16tostr3rj(const int16_t x) { @@ -222,7 +216,7 @@ const char* ftostr41ns(const_float_t f) { return &conv[3]; } -// Convert signed float to fixed-length string with 12.34 / _2.34 / -2.34 or -23.45 / 123.45 format +// Convert float to fixed-length string with 12.34 / _2.34 / -2.34 or -23.45 / 123.45 format const char* ftostr42_52(const_float_t f) { if (f <= -10 || f >= 100) return ftostr52(f); // -23.45 / 123.45 long i = INTFLOAT(f, 2); @@ -234,7 +228,7 @@ const char* ftostr42_52(const_float_t f) { return &conv[3]; } -// Convert signed float to fixed-length string with 023.45 / -23.45 format +// Convert float to fixed-length string with 023.45 / -23.45 format const char* ftostr52(const_float_t f) { long i = INTFLOAT(f, 2); conv[2] = MINUSOR(i, DIGIMOD(i, 10000)); @@ -246,7 +240,7 @@ const char* ftostr52(const_float_t f) { return &conv[2]; } -// Convert signed float to fixed-length string with 12.345 / _2.345 / -2.345 or -23.45 / 123.45 format +// Convert float to fixed-length string with 12.345 / _2.345 / -2.345 or -23.45 / 123.45 format const char* ftostr53_63(const_float_t f) { if (f <= -10 || f >= 100) return ftostr63(f); // -23.456 / 123.456 long i = INTFLOAT(f, 3); @@ -259,7 +253,7 @@ const char* ftostr53_63(const_float_t f) { return &conv[2]; } -// Convert signed float to fixed-length string with 023.456 / -23.456 format +// Convert float to fixed-length string with 023.456 / -23.456 format const char* ftostr63(const_float_t f) { long i = INTFLOAT(f, 3); conv[1] = MINUSOR(i, DIGIMOD(i, 100000)); @@ -289,42 +283,58 @@ const char* ftostr63(const_float_t f) { #endif -// Convert float to fixed-length string with +12.3 / -12.3 format -const char* ftostr31sign(const_float_t f) { - int i = INTFLOAT(f, 1); - conv[3] = MINUSOR(i, '+'); - conv[4] = DIGIMOD(i, 100); +// +// Convert float to fixed-length string with +/- and a single decimal place +// +inline const char* ftostrX1sign(const_float_t f, const int index) { + long i = INTFLOAT(f, 1); + conv[index] = MINUSOR(i, '+'); + switch (index + 1) { + case 1: conv[1] = DIGIMOD(i, 100000); + case 2: conv[2] = DIGIMOD(i, 10000); + case 3: conv[3] = DIGIMOD(i, 1000); + case 4: conv[4] = DIGIMOD(i, 100); + } conv[5] = DIGIMOD(i, 10); conv[6] = '.'; conv[7] = DIGIMOD(i, 1); - return &conv[3]; + return &conv[index]; } +// Convert float to fixed-length string with +12.3 / -12.3 format +const char* ftostr31sign(const_float_t f) { return ftostrX1sign(f, 3); } + // Convert float to fixed-length string with +123.4 / -123.4 format -const char* ftostr41sign(const_float_t f) { - int i = INTFLOAT(f, 1); - conv[2] = MINUSOR(i, '+'); - conv[3] = DIGIMOD(i, 1000); - conv[4] = DIGIMOD(i, 100); - conv[5] = DIGIMOD(i, 10); - conv[6] = '.'; - conv[7] = DIGIMOD(i, 1); - return &conv[2]; -} +const char* ftostr41sign(const_float_t f) { return ftostrX1sign(f, 2); } -// Convert signed float to string (6 digit) with -1.234 / _0.000 / +1.234 format -const char* ftostr43sign(const_float_t f, char plus/*=' '*/) { +// Convert float to fixed-length string with +1234.5 / +1234.5 format +const char* ftostr51sign(const_float_t f) { return ftostrX1sign(f, 1); } + +// +// Convert float to string with +/ /- and 3 decimal places +// +inline const char* ftostrX3sign(const_float_t f, const int index, char plus/*=' '*/) { long i = INTFLOAT(f, 3); - conv[2] = i ? MINUSOR(i, plus) : ' '; + conv[index] = i ? MINUSOR(i, plus) : ' '; + switch (index + 1) { + case 1: conv[1] = DIGIMOD(i, 100000); + case 2: conv[2] = DIGIMOD(i, 10000); + } conv[3] = DIGIMOD(i, 1000); conv[4] = '.'; conv[5] = DIGIMOD(i, 100); conv[6] = DIGIMOD(i, 10); conv[7] = DIGIMOD(i, 1); - return &conv[2]; + return &conv[index]; } -// Convert signed float to string (5 digit) with -1.2345 / _0.0000 / +1.2345 format +// Convert float to string (6 chars) with -1.234 / _0.000 / +1.234 format +const char* ftostr43sign(const_float_t f, char plus/*=' '*/) { return ftostrX3sign(f, 2, plus); } + +// Convert float to string (7 chars) with -12.345 / _00.000 / +12.345 format +const char* ftostr53sign(const_float_t f, char plus/*=' '*/) { return ftostrX3sign(f, 1, plus); } + +// Convert float to string (7 chars) with -1.2345 / _0.0000 / +1.2345 format const char* ftostr54sign(const_float_t f, char plus/*=' '*/) { long i = INTFLOAT(f, 4); conv[1] = i ? MINUSOR(i, plus) : ' '; @@ -343,19 +353,6 @@ const char* ftostr5rj(const_float_t f) { return ui16tostr5rj(i); } -// Convert signed float to string with +1234.5 format -const char* ftostr51sign(const_float_t f) { - long i = INTFLOAT(f, 1); - conv[1] = MINUSOR(i, '+'); - conv[2] = DIGIMOD(i, 10000); - conv[3] = DIGIMOD(i, 1000); - conv[4] = DIGIMOD(i, 100); - conv[5] = DIGIMOD(i, 10); - conv[6] = '.'; - conv[7] = DIGIMOD(i, 1); - return &conv[1]; -} - // Convert signed float to string with +123.45 format const char* ftostr52sign(const_float_t f) { long i = INTFLOAT(f, 2); @@ -369,47 +366,66 @@ const char* ftostr52sign(const_float_t f) { return &conv[1]; } -// Convert signed float to string with +12.345 format -const char* ftostr53sign(const_float_t f) { - long i = INTFLOAT(f, 3); - conv[1] = MINUSOR(i, '+'); - conv[2] = DIGIMOD(i, 10000); - conv[3] = DIGIMOD(i, 1000); - conv[4] = '.'; - conv[5] = DIGIMOD(i, 100); - conv[6] = DIGIMOD(i, 10); - conv[7] = DIGIMOD(i, 1); - return &conv[1]; -} - -// Convert unsigned float to string with ____5.6, ___45.6, __345.6, _2345.6, 12345.6 format -const char* ftostr61rj(const_float_t f) { +// Convert unsigned float to string with a single digit precision +inline const char* ftostrX1rj(const_float_t f, const int index=1) { const long i = UINTFLOAT(f, 1); - conv[1] = RJDIGIT(i, 100000); - conv[2] = RJDIGIT(i, 10000); - conv[3] = RJDIGIT(i, 1000); - conv[4] = RJDIGIT(i, 100); + switch (index) { + case 0: conv[0] = RJDIGIT(i, 1000000); + case 1: conv[1] = RJDIGIT(i, 100000); + case 2: conv[2] = RJDIGIT(i, 10000); + case 3: conv[3] = RJDIGIT(i, 1000); + case 4: conv[4] = RJDIGIT(i, 100); + } conv[5] = DIGIMOD(i, 10); conv[6] = '.'; conv[7] = DIGIMOD(i, 1); - return &conv[1]; + return &conv[index]; } -// Convert unsigned float to string with ____5.67, ___45.67, __345.67, _2345.67, 12345.67 format -const char* ftostr72rj(const_float_t f) { +// Convert unsigned float to string with _2.3 / 12.3 format +const char* ftostr31rj(const_float_t f) { return ftostrX1rj(f, 7 - 3); } + +// Convert unsigned float to string with __3.4 / _23.4 / 123.4 format +const char* ftostr41rj(const_float_t f) { return ftostrX1rj(f, 7 - 4); } + +// Convert unsigned float to string with ___4.5 / __34.5 / _234.5 / 1234.5 format +const char* ftostr51rj(const_float_t f) { return ftostrX1rj(f, 7 - 5); } + +// Convert unsigned float to string with ____5.6 / ___45.6 / __345.6 / _2345.6 / 12345.6 format +const char* ftostr61rj(const_float_t f) { return ftostrX1rj(f, 7 - 6); } + +// Convert unsigned float to string with two digit precision +inline const char* ftostrX2rj(const_float_t f, const int index=1) { const long i = UINTFLOAT(f, 2); - conv[0] = RJDIGIT(i, 1000000); - conv[1] = RJDIGIT(i, 100000); - conv[2] = RJDIGIT(i, 10000); - conv[3] = RJDIGIT(i, 1000); - conv[4] = DIGIMOD(i, 100); + switch (index) { + case 0: conv[0] = RJDIGIT(i, 1000000); + case 1: conv[1] = RJDIGIT(i, 100000); + case 2: conv[2] = RJDIGIT(i, 10000); + case 3: conv[3] = RJDIGIT(i, 1000); + case 4: conv[4] = RJDIGIT(i, 100); + } conv[5] = '.'; conv[6] = DIGIMOD(i, 10); conv[7] = DIGIMOD(i, 1); - return conv; + return &conv[index]; } -// Convert signed float to space-padded string with -_23.4_ format +// Convert unsigned float to string with 1.23 format +const char* ftostr32rj(const_float_t f) { return ftostrX2rj(f, 4); } + +// Convert unsigned float to string with _2.34, 12.34 format +const char* ftostr42rj(const_float_t f) { return ftostrX2rj(f, 3); } + +// Convert unsigned float to string with __3.45, _23.45, 123.45 format +const char* ftostr52rj(const_float_t f) { return ftostrX2rj(f, 2); } + +// Convert unsigned float to string with ___4.56, __34.56, _234.56, 1234.56 format +const char* ftostr62rj(const_float_t f) { return ftostrX2rj(f, 1); } + +// Convert unsigned float to string with ____5.67, ___45.67, __345.67, _2345.67, 12345.67 format +const char* ftostr72rj(const_float_t f) { return ftostrX2rj(f, 0); } + +// Convert float to space-padded string with -_23.4_ format const char* ftostr52sp(const_float_t f) { long i = INTFLOAT(f, 2); uint8_t dig; @@ -418,17 +434,17 @@ const char* ftostr52sp(const_float_t f) { conv[3] = RJDIGIT(i, 1000); conv[4] = DIGIMOD(i, 100); - if ((dig = i % 10)) { // second digit after decimal point? + if ((dig = i % 10)) { // Second digit after decimal point? conv[5] = '.'; conv[6] = DIGIMOD(i, 10); conv[7] = DIGIT(dig); } else { - if ((dig = (i / 10) % 10)) { // first digit after decimal point? + if ((dig = (i / 10) % 10)) { // First digit after decimal point? conv[5] = '.'; conv[6] = DIGIT(dig); } - else // nothing after decimal point + else // Nothing after decimal point conv[5] = conv[6] = ' '; conv[7] = ' '; } @@ -440,7 +456,7 @@ const char* utostr3(const uint16_t x) { return i16tostr3left(_MIN(x, 999U)); } -// Convert signed float to space-padded string with 1.23, 12.34, 123.45 format +// Convert float to space-padded string with 1.23, 12.34, 123.45 format const char* ftostr52sprj(const_float_t f) { long i = INTFLOAT(f, 2); LIMIT(i, -99999, 99999); // cap to -999.99 - 999.99 range diff --git a/Marlin/src/libs/numtostr.h b/Marlin/src/libs/numtostr.h index f8af09ebeeca..fde07e836846 100644 --- a/Marlin/src/libs/numtostr.h +++ b/Marlin/src/libs/numtostr.h @@ -40,7 +40,7 @@ const char* ui8tostr3rj(const uint8_t i); const char* i8tostr3rj(const int8_t x); #if HAS_PRINT_PROGRESS_PERMYRIAD - // Convert 16-bit unsigned permyriad value to percent: 100 / 23 / 23.4 / 3.45 + // Convert 16-bit unsigned permyriad value to percent: _100 / __23 / 23.4 / 3.45 const char* permyriadtostr4(const uint16_t xx); #endif @@ -86,22 +86,34 @@ const char* ftostr53_63(const_float_t x); // Convert signed float to fixed-length string with 023.456 / -23.456 format const char* ftostr63(const_float_t x); -// Convert float to fixed-length string with +12.3 / -12.3 format +// Convert signed float to fixed-length string with +12.3 / -12.3 format const char* ftostr31sign(const_float_t x); -// Convert float to fixed-length string with +123.4 / -123.4 format +// Convert signed float to fixed-length string with +123.4 / -123.4 format const char* ftostr41sign(const_float_t x); +// Convert signed float to fixed-length string with +1234.5 / +1234.5 format +const char* ftostr51sign(const_float_t x); + // Convert signed float to string (6 digit) with -1.234 / _0.000 / +1.234 format const char* ftostr43sign(const_float_t x, char plus=' '); +// Convert signed float to string (7 chars) with -12.345 / _00.000 / +12.345 format +const char* ftostr53sign(const_float_t x, char plus=' '); + // Convert signed float to string (5 digit) with -1.2345 / _0.0000 / +1.2345 format const char* ftostr54sign(const_float_t x, char plus=' '); // Convert unsigned float to rj string with 12345 format const char* ftostr5rj(const_float_t x); -// Convert signed float to string with +1234.5 format +// Convert signed float to fixed-length string with +12.3 / -12.3 format +const char* ftostr31sign(const_float_t x); + +// Convert signed float to fixed-length string with +123.4 / -123.4 format +const char* ftostr41sign(const_float_t x); + +// Convert signed float to fixed-length string with +1234.5 format const char* ftostr51sign(const_float_t x); // Convert signed float to space-padded string with -_23.4_ format @@ -110,23 +122,41 @@ const char* ftostr52sp(const_float_t x); // Convert signed float to string with +123.45 format const char* ftostr52sign(const_float_t x); -// Convert signed float to string with +12.345 format -const char* ftostr53sign(const_float_t f); +// Convert unsigned float to string with _2.3 / 12.3 format +const char* ftostr31rj(const_float_t x); -// Convert unsigned float to string with 12345.6 format omitting trailing zeros +// Convert unsigned float to string with __3.4 / _23.4 / 123.4 format +const char* ftostr41rj(const_float_t x); + +// Convert unsigned float to string with ___4.5 / __34.5 / _234.5 / 1234.5 format +const char* ftostr51rj(const_float_t x); + +// Convert unsigned float to string with ____5.6 / ___45.6 / __345.6 / _2345.6 / 12345.6 format const char* ftostr61rj(const_float_t x); -// Convert unsigned float to string with 12345.67 format omitting trailing zeros +// Convert unsigned float to string with 1.23 format +const char* ftostr32rj(const_float_t f); + +// Convert unsigned float to string with _2.34, 12.34 format +const char* ftostr42rj(const_float_t f); + +// Convert unsigned float to string with __3.45, _23.45, 123.45 format +const char* ftostr52rj(const_float_t f); + +// Convert unsigned float to string with ___4.56, __34.56, _234.56, 1234.56 format +const char* ftostr62rj(const_float_t f); + +// Convert unsigned float to string with ____5.67, ___45.67, __345.67, _2345.67, 12345.67 format const char* ftostr72rj(const_float_t x); -// Convert float to rj string with 123 or -12 format +// Convert signed float to rj string with 123 or -12 format FORCE_INLINE const char* ftostr3rj(const_float_t x) { return i16tostr3rj(int16_t(x + (x < 0 ? -0.5f : 0.5f))); } #if ENABLED(LCD_DECIMAL_SMALL_XY) - // Convert float to rj string with 1234, _123, 12.3, _1.2, -123, _-12, or -1.2 format + // Convert signed float to rj string with 1234, _123, 12.3, _1.2, -123, _-12, or -1.2 format const char* ftostr4sign(const_float_t fx); #else - // Convert float to rj string with 1234, _123, -123, __12, _-12, ___1, or __-1 format + // Convert signed float to rj string with 1234, _123, -123, __12, _-12, ___1, or __-1 format FORCE_INLINE const char* ftostr4sign(const_float_t x) { return i16tostr4signrj(int16_t(x + (x < 0 ? -0.5f : 0.5f))); } #endif diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index 0f060f572048..9c6a3c011cca 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -1360,7 +1360,7 @@ void Endstops::update() { #if ENABLED(DEBUG_LEVELING_FEATURE) auto debug_current = [](FSTR_P const s, const int16_t a, const int16_t b) { - if (DEBUGGING(LEVELING)) { DEBUG_ECHOF(s); DEBUG_ECHOLNPGM(" current: ", a, " -> ", b); } + if (DEBUGGING(LEVELING)) { DEBUG_ECHOLN(s, F(" current: "), a, F(" -> "), b); } }; #else #define debug_current(...) diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp index deeb53942ba3..0bd83bc3ac10 100644 --- a/Marlin/src/module/probe.cpp +++ b/Marlin/src/module/probe.cpp @@ -596,11 +596,15 @@ bool Probe::probe_down_to_z(const_float_t z, const_feedRate_t fr_mm_s) { thermalManager.wait_for_hotend_heating(active_extruder); #endif - // Ensure the BLTouch is deployed. Does nothing if already deployed. - if (TERN0(BLTOUCH, bltouch.deploy())) return true; + #if ENABLED(BLTOUCH) + // Ensure the BLTouch is deployed. (Does nothing if already deployed.) + // Don't deploy with high_speed_mode enabled. The probe already re-deploys itself. + if (TERN(MEASURE_BACKLASH_WHEN_PROBING, true, !bltouch.high_speed_mode) && bltouch.deploy()) + return true; + #endif #if HAS_Z_SERVO_PROBE && (ENABLED(Z_SERVO_INTERMEDIATE_STOW) || defined(Z_SERVO_MEASURE_ANGLE)) - probe_specific_action(true); // Always re-deploy in this case + probe_specific_action(true); // Always re-deploy in this case #endif // Disable stealthChop if used. Enable diag1 pin on driver. diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index 6f7c4b1ebca5..f636b985e1be 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -2042,7 +2042,7 @@ void MarlinSettings::postprocess() { if (grid_max_x == (GRID_MAX_POINTS_X) && grid_max_y == (GRID_MAX_POINTS_Y)) { if (!validating) set_bed_leveling_enabled(false); bedlevel.set_grid(spacing, start); - EEPROM_READ(bedlevel.z_values); // 9 to 256 floats + EEPROM_READ(bedlevel.z_values); // 9 to 256 floats } else if (grid_max_x > (GRID_MAX_POINTS_X) || grid_max_y > (GRID_MAX_POINTS_Y)) { eeprom_error = ERR_EEPROM_CORRUPT; diff --git a/Marlin/src/module/thermistor/thermistor_14.h b/Marlin/src/module/thermistor/thermistor_14.h index f0bc6f606ee8..0d432f3d65ce 100644 --- a/Marlin/src/module/thermistor/thermistor_14.h +++ b/Marlin/src/module/thermistor/thermistor_14.h @@ -22,7 +22,7 @@ #pragma once // R25 = 100 kOhm, beta25 = 4092 K, 4.7 kOhm pull-up, bed thermistor -const temp_entry_t temptable_14[] PROGMEM = { +constexpr temp_entry_t temptable_14[] PROGMEM = { { OV( 23), 275 }, { OV( 25), 270 }, { OV( 27), 265 }, diff --git a/Marlin/src/module/thermistor/thermistor_68.h b/Marlin/src/module/thermistor/thermistor_68.h index 270456dcb59c..f8b0f625e72b 100644 --- a/Marlin/src/module/thermistor/thermistor_68.h +++ b/Marlin/src/module/thermistor/thermistor_68.h @@ -24,7 +24,7 @@ #define REVERSE_TEMP_SENSOR_RANGE_68 1 // PT100 amplifier board from Dyze Design -const temp_entry_t temptable_68[] PROGMEM = { +constexpr temp_entry_t temptable_68[] PROGMEM = { { OV(273), 0 }, { OV(294), 20 }, { OV(315), 40 }, diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 22982fa91a44..373dcf314221 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -1028,7 +1028,7 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0. if (!too_cold(active_extruder)) { destination = current_position; // Remember the old position - const bool ok = TERN1(TOOLCHANGE_PARK, all_axes_homed() && toolchange_settings.enable_park); + const bool ok = TERN0(TOOLCHANGE_PARK, all_axes_homed() && toolchange_settings.enable_park); #if HAS_FAN && TOOLCHANGE_FS_FAN >= 0 // Store and stop fan. Restored on any exit. @@ -1080,7 +1080,20 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0. } #endif + // Clone previous position extruder_cutting_recover(destination.e); // Cutting recover + + // Retract if previously retracted + #if ENABLED(FWRETRACT) + if (fwretract.retracted[active_extruder]) + unscaled_e_move(-fwretract.settings.retract_length, fwretract.settings.retract_feedrate_mm_s); + #endif + + // If resume_position is negative + if (current_position.e < 0) unscaled_e_move(current_position.e, MMM_TO_MMS(toolchange_settings.retract_speed)); + + planner.synchronize(); + planner.set_e_position_mm(current_position.e); // Extruder primed and ready } } @@ -1597,6 +1610,9 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { unscaled_e_move(-fwretract.settings.retract_length, fwretract.settings.retract_feedrate_mm_s); #endif + // If resume_position is negative + if (resume_current_e < 0) unscaled_e_move(resume_current_e, MMM_TO_MMS(toolchange_settings.retract_speed)); + // If no available extruder if (EXTRUDERS < 2 || active_extruder >= EXTRUDERS - 2 || active_extruder == migration.last) migration.automode = false; diff --git a/Marlin/src/pins/gd32f1/pins_VOXELAB_AQUILA.h b/Marlin/src/pins/gd32f1/pins_VOXELAB_AQUILA.h new file mode 100644 index 000000000000..2f3998b45fcf --- /dev/null +++ b/Marlin/src/pins/gd32f1/pins_VOXELAB_AQUILA.h @@ -0,0 +1,39 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * FFP0173_Aquila_Main_Board_V1.0.1 (GD32F103RC / N32G455RE) + * + * Uses CREALITY V4 (STM32F103RE / STM32F103RC) board pin assignments + */ + +#define BOARD_INFO_NAME "Aquila v1.0.1" +#ifndef DEFAULT_MACHINE_NAME + #define DEFAULT_MACHINE_NAME "Aquila" +#endif + +#define INLINE_USART_IRQ + +#define NO_MAPLE_WARNING // Disable warning when compiling with Maple env + +#include "../stm32f1/pins_CREALITY_V4.h" diff --git a/Marlin/src/pins/hc32f4/env_validate.h b/Marlin/src/pins/hc32f4/env_validate.h index 7883bc03c743..9bbc999fd6ee 100644 --- a/Marlin/src/pins/hc32f4/env_validate.h +++ b/Marlin/src/pins/hc32f4/env_validate.h @@ -19,8 +19,11 @@ * along with this program. If not, see . * */ -#pragma once +#ifndef ENV_VALIDATE_H +#define ENV_VALIDATE_H #ifndef ARDUINO_ARCH_HC32 #error "Oops! Select an HC32F460 board in 'Tools > Board.'" #endif + +#endif diff --git a/Marlin/src/pins/hc32f4/pins_AQUILA_101.h b/Marlin/src/pins/hc32f4/pins_AQUILA_101.h index a9dfb9b0f9b8..32268f4cf84e 100644 --- a/Marlin/src/pins/hc32f4/pins_AQUILA_101.h +++ b/Marlin/src/pins/hc32f4/pins_AQUILA_101.h @@ -22,7 +22,7 @@ #pragma once // -// Voxelab Aquila V1.0.1 and V1.0.2 (HC32F460) as found in the Voxelab Aquila X2 +// Voxelab Aquila V1.0.0/V1.0.1/V1.0.2/V1.0.3 (HC32F460) as found in the Voxelab Aquila X2 and C2 // #include "env_validate.h" @@ -152,7 +152,23 @@ #define EXP1_07_PIN PB12 // EN2 #define EXP1_08_PIN PB15 // EN1 -#if ANY(HAS_DWIN_E3V2, IS_DWIN_MARLINUI) +#if ENABLED(CR10_STOCKDISPLAY) // LCD used for C2 +#undef LCD_SERIAL_PORT +#define LCD_SERIAL_PORT 1 + + #define LCD_PINS_RS EXP1_07_PIN + #define LCD_PINS_EN EXP1_08_PIN + #define LCD_PINS_D4 EXP1_06_PIN + + #define BTN_ENC EXP1_02_PIN + #define BTN_EN1 EXP1_03_PIN + #define BTN_EN2 EXP1_05_PIN + + #ifndef HAS_PIN_27_BOARD + #define BEEPER_PIN EXP1_01_PIN + #endif + +#elif ANY(HAS_DWIN_E3V2, IS_DWIN_MARLINUI) // LCD used for X2 /** * Display pinout (display side, so RX/TX are swapped) * diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index 1618078f45f6..28ae5e8d42f8 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -700,6 +700,8 @@ #include "stm32f1/pins_KEDI_CONTROLLER_V1_2.h" // STM32F1 env:STM32F103RC_btt env:STM32F103RC_btt_USB env:STM32F103RC_btt_maple env:STM32F103RC_btt_USB_maple #elif MB(MD_D301) #include "stm32f1/pins_MD_D301.h" // STM32F1 env:mingda_d301 env:mingda_d301_maple +#elif MB(VOXELAB_AQUILA) + #include "gd32f1/pins_VOXELAB_AQUILA.h" // GD32F1, N32G4, STM32F1 env:GD32F103RC_voxelab_maple env:N32G455RE_voxelab_maple env:STM32F103RE_creality_maple env:STM32F103RE_creality // // ARM Cortex-M4F diff --git a/Marlin/src/pins/stm32f1/pins_CREALITY_V521.h b/Marlin/src/pins/stm32f1/pins_CREALITY_V521.h index d555c0aaa12d..2660b6e50518 100644 --- a/Marlin/src/pins/stm32f1/pins_CREALITY_V521.h +++ b/Marlin/src/pins/stm32f1/pins_CREALITY_V521.h @@ -135,7 +135,7 @@ #define FAN0_PIN PB14 // FAN #define FAN1_PIN PB12 // FAN -#define FAN_SOFT_PWM +#define FAN_SOFT_PWM_REQUIRED // // SD Card diff --git a/Marlin/src/pins/stm32f4/pins_MKS_MONSTER8_V2.h b/Marlin/src/pins/stm32f4/pins_MKS_MONSTER8_V2.h index d70e935f0a29..772a93605ae6 100644 --- a/Marlin/src/pins/stm32f4/pins_MKS_MONSTER8_V2.h +++ b/Marlin/src/pins/stm32f4/pins_MKS_MONSTER8_V2.h @@ -58,6 +58,9 @@ #define WIFI_RESET_PIN PD14 // MKS ESP WIFI RESET PIN #endif -#define NEOPIXEL_PIN PC5 +// The FYSETC_MINI_12864_2_1 uses one of the EXP pins +#if DISABLED(FYSETC_MINI_12864_2_1) && !defined(NEOPIXEL_PIN) + #define NEOPIXEL_PIN PC5 +#endif #include "pins_MKS_MONSTER8_common.h" diff --git a/Marlin/src/pins/stm32f4/pins_TRONXY_V10.h b/Marlin/src/pins/stm32f4/pins_TRONXY_V10.h index e9e069583afe..97580bf618f9 100644 --- a/Marlin/src/pins/stm32f4/pins_TRONXY_V10.h +++ b/Marlin/src/pins/stm32f4/pins_TRONXY_V10.h @@ -157,7 +157,7 @@ #define FAN2_PIN PG9 // FAN2 #define FAN3_PIN PF10 // FAN3 #define CONTROLLER_FAN_PIN PD7 // BOARD FAN -#define FAN_SOFT_PWM +#define FAN_SOFT_PWM_REQUIRED // // Laser / Spindle diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 9b9b3509d6e0..175e4e5c05bc 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -446,8 +446,7 @@ void CardReader::ls(const uint8_t lsflags/*=0*/) { diveDir.close(); if (longFilename[0]) { - strncpy_P(pathLong, longFilename, 63); - pathLong[63] = '\0'; + strlcpy_P(pathLong, longFilename, 64); break; } } @@ -1075,8 +1074,7 @@ const char* CardReader::diveToFile(const bool update_cwd, MediaFile* &inDirPtr, // Isolate the next subitem name const uint8_t len = name_end - atom_ptr; char dosSubdirname[len + 1]; - strncpy(dosSubdirname, atom_ptr, len); - dosSubdirname[len] = 0; + strlcpy(dosSubdirname, atom_ptr, len + 1); if (echo) SERIAL_ECHOLN(dosSubdirname); @@ -1181,7 +1179,7 @@ void CardReader::cdroot() { #endif #else // Copy filenames into the static array - #define _SET_SORTNAME(I) strncpy(sortnames[I], longest_filename(), SORTED_LONGNAME_MAXLEN) + #define _SET_SORTNAME(I) strlcpy(sortnames[I], longest_filename(), sizeof(sortnames[I])) #if SORTED_LONGNAME_MAXLEN == LONG_FILENAME_LENGTH // Short name sorting always use LONG_FILENAME_LENGTH with no trailing nul #define SET_SORTNAME(I) _SET_SORTNAME(I) diff --git a/buildroot/share/sublime/MarlinFirmware.sublime-project b/buildroot/share/sublime/MarlinFirmware.sublime-project index 11808dd45df0..62607ac0c6d1 100644 --- a/buildroot/share/sublime/MarlinFirmware.sublime-project +++ b/buildroot/share/sublime/MarlinFirmware.sublime-project @@ -30,6 +30,7 @@ "ensure_newline_at_eof_on_save": true, "tab_size": 2, "translate_tabs_to_spaces": true, - "trim_trailing_white_space_on_save": true + "trim_trailing_white_space_on_save": true, + "uncrustify_config" : "${project_dir}/../extras/uncrustify.cfg" } } diff --git a/buildroot/tests/mega2560 b/buildroot/tests/mega2560 index d647a6ddb16c..1fbdd6b58b20 100755 --- a/buildroot/tests/mega2560 +++ b/buildroot/tests/mega2560 @@ -33,6 +33,7 @@ opt_enable AUTO_BED_LEVELING_UBL AVOID_OBSTACLES RESTORE_LEVELING_AFTER_G28 DEBU EMERGENCY_PARSER MULTI_NOZZLE_DUPLICATION CLASSIC_JERK LIN_ADVANCE ADVANCE_K_EXTRA QUICK_HOME \ SET_PROGRESS_MANUALLY SET_PROGRESS_PERCENT PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME \ ENCODER_NOISE_FILTER BABYSTEPPING BABYSTEP_XY NANODLP_Z_SYNC I2C_POSITION_ENCODERS M114_DETAIL +opt_disable ENCODER_RATE_MULTIPLIER exec_test $1 $2 "Azteeg X3 Pro | EXTRUDERS 5 | RRDFGSC | UBL | LIN_ADVANCE ..." "$3" # diff --git a/ini/hc32.ini b/ini/hc32.ini index 676f9e19b6e5..d25ef4e7be07 100644 --- a/ini/hc32.ini +++ b/ini/hc32.ini @@ -27,7 +27,7 @@ # Base Environment for all HC32F460 variants # [HC32F460_base] -platform = https://github.com/shadow578/platform-hc32f46x/archive/main.zip +platform = https://github.com/shadow578/platform-hc32f46x/archive/1.0.0.zip board = generic_hc32f460 build_src_filter = ${common.default_src_filter} + + build_type = release @@ -50,7 +50,6 @@ build_flags = -D __PANIC_SHORT_FILENAMES # Use short filenames in core panic output -D __OMIT_PANIC_MESSAGE # Omit panic messages in core panic output - # Drivers and Middleware required by the HC32 HAL board_build.ddl.ots = true board_build.ddl.sdioc = true @@ -80,7 +79,7 @@ extends = HC32F460_base board_build.ld_args.flash_size = 512K # -# Aquila V1.0.1 Mainboard, as found in the Voxelab Aquila X2 +# Voxelab Aquila V1.0.0/V1.0.1/V1.0.2/V1.0.3 as found in the Voxelab Aquila X2 & C2 # [env:HC32F460C_aquila_101] extends = HC32F460C_base diff --git a/ini/stm32f1-maple.ini b/ini/stm32f1-maple.ini index 34025a8a38b2..a113d1a7b154 100644 --- a/ini/stm32f1-maple.ini +++ b/ini/stm32f1-maple.ini @@ -142,6 +142,29 @@ extends = env:STM32F103RE_creality_maple board_build.address = 0x08010000 board_build.ldscript = crealityPro.ld +# +# Voxelab Aquila V1.0.1 +# +# GD32F103RC_voxelab_maple ........ GD32F103RCT6 with 256K +# N32G455RE_voxelab_maple ......... N32G455REL7 - Requires ICSP to flash over 256K +# +[env:GD32F103RC_voxelab_maple] +extends = env:STM32F103RC_maple +build_flags = ${env:STM32F103RC_maple.build_flags} -DTEMP_TIMER_CHAN=4 +board_build.address = 0x08007000 +board_build.ldscript = creality256k.ld +debug_tool = jlink +upload_protocol = jlink + +[env:N32G455RE_voxelab_maple] +extends = env:STM32F103RE_maple +build_flags = ${env:STM32F103RE_maple.build_flags} -DTEMP_TIMER_CHAN=4 + -DVOXELAB_N32 -DSDCARD_FLASH_LIMIT_256K +board_build.address = 0x08007000 +board_build.ldscript = creality.ld +debug_tool = jlink +upload_protocol = jlink + # # BigTreeTech SKR Mini E3 V2.0 & DIP / SKR CR6 (STM32F103RET6 ARM Cortex-M3) # @@ -399,8 +422,6 @@ build_flags = ${STM32F1_maple.build_flags} -DTEMP_TIMER_CHAN=4 board_build.address = 0x08007000 board_build.ldscript = sovol.ld board_build.rename = firmware-{date}-{time}.bin -extra_scripts = ${STM32F1_maple.extra_scripts} - buildroot/share/PlatformIO/scripts/custom_board.py debug_tool = jlink upload_protocol = jlink diff --git a/ini/stm32f4.ini b/ini/stm32f4.ini index 0ba6b66c3fed..60ccee94d89b 100644 --- a/ini/stm32f4.ini +++ b/ini/stm32f4.ini @@ -743,7 +743,7 @@ upload_protocol = stlink [env:STM32F401RC_btt] extends = stm32_variant platform = ststm32@~14.1.0 -platform_packages = framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32/archive/2.6.0.zip +platform_packages = framework-arduinoststm32@~4.20600.231001 toolchain-gccarmnoneeabi@1.100301.220327 board = marlin_STM32F401RC board_build.offset = 0x4000 diff --git a/ini/stm32g0.ini b/ini/stm32g0.ini index 109200bb0c43..cf36541f3f50 100644 --- a/ini/stm32g0.ini +++ b/ini/stm32g0.ini @@ -32,7 +32,7 @@ build_flags = -DPIN_WIRE_SCL=PB3 -DPIN_WIRE_SDA=PB4 [env:BTT_EBB42_V1_1_filament_extruder] extends = stm32_variant platform = ststm32@~14.1.0 -platform_packages = framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32/archive/2.6.0.zip +platform_packages = framework-arduinoststm32@~4.20600.231001 toolchain-gccarmnoneeabi@1.100301.220327 board = marlin_BTT_EBB42_V1_1 board_build.offset = 0x0000 @@ -48,7 +48,7 @@ upload_command = dfu-util -a 0 -s 0x08000000:leave -D "$SOURCE" [env:STM32G0B1RE_btt] extends = stm32_variant platform = ststm32@~14.1.0 -platform_packages = framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32/archive/2.6.0.zip +platform_packages = framework-arduinoststm32@~4.20600.231001 toolchain-gccarmnoneeabi@1.100301.220327 board = marlin_STM32G0B1RE board_build.offset = 0x2000 @@ -105,7 +105,7 @@ upload_protocol = custom [env:STM32G0B1VE_btt] extends = stm32_variant platform = ststm32@~14.1.0 -platform_packages = framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32/archive/2.6.0.zip +platform_packages = framework-arduinoststm32@~4.20600.231001 toolchain-gccarmnoneeabi@1.100301.220327 board = marlin_STM32G0B1VE board_build.offset = 0x2000