From 1b6db4c482c8edaaf11a7c0f73f8a6a483bec83f Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Fri, 8 May 2020 21:56:32 -0700 Subject: [PATCH] Update to arduinostm32 4.10800. Update timer usage accordingly. --- Marlin/src/HAL/STM32/SoftwareSerial.cpp | 14 +++- Marlin/src/HAL/STM32/SoftwareSerial.h | 1 - Marlin/src/HAL/STM32/timers.cpp | 48 ++++++------ Marlin/src/HAL/STM32/timers.h | 2 - .../share/PlatformIO/boards/malyanM200v2.json | 2 +- platformio.ini | 76 ++++++++++--------- 6 files changed, 76 insertions(+), 67 deletions(-) diff --git a/Marlin/src/HAL/STM32/SoftwareSerial.cpp b/Marlin/src/HAL/STM32/SoftwareSerial.cpp index 60f355e08e96..dd2b83255706 100644 --- a/Marlin/src/HAL/STM32/SoftwareSerial.cpp +++ b/Marlin/src/HAL/STM32/SoftwareSerial.cpp @@ -100,7 +100,6 @@ // HardwareTimer SoftwareSerial::timer(TIMER_SERIAL); const IRQn_Type SoftwareSerial::timer_interrupt_number = static_cast(getTimerUpIrq(TIMER_SERIAL)); -uint32_t SoftwareSerial::timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TIM_IRQ_PRIO, TIM_IRQ_SUBPRIO); SoftwareSerial *SoftwareSerial::active_listener = nullptr; SoftwareSerial *volatile SoftwareSerial::active_out = nullptr; SoftwareSerial *volatile SoftwareSerial::active_in = nullptr; @@ -113,7 +112,13 @@ int32_t SoftwareSerial::rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start uint32_t SoftwareSerial::cur_speed = 0; void SoftwareSerial::setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority) { - timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority); + timer.setInterruptPriority(preemptPriority, subPriority); + + // Arduino_Core_STM32 1.8 does not apply the interrupt priority until the + // timer is completely re-initialized, which may not even be possible + // through the HardwareTimer interface. Work around this until it is + // fixed by setting directly to the STM32 HAL. + NVIC_SetPriority(timer_interrupt_number, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority)); } // @@ -137,12 +142,15 @@ void SoftwareSerial::setSpeed(uint32_t speed) { pre *= 2; } } while (cmp_value >= UINT16_MAX); + // Arduino_Core_STM32 1.8 requires setMode to be called on a channel to start the timer. + // This is fixed in the following PR, which has not yet been released. + // https://github.com/stm32duino/Arduino_Core_STM32/pull/849 + timer.setMode(1, TIMER_OUTPUT_COMPARE, NC); timer.setPrescaleFactor(pre); timer.setOverflow(cmp_value); timer.setCount(0); timer.attachInterrupt(&handleInterrupt); timer.resume(); - NVIC_SetPriority(timer_interrupt_number, timer_interrupt_priority); } else timer.detachInterrupt(); diff --git a/Marlin/src/HAL/STM32/SoftwareSerial.h b/Marlin/src/HAL/STM32/SoftwareSerial.h index 504bd6979b2c..aaea92fbb075 100644 --- a/Marlin/src/HAL/STM32/SoftwareSerial.h +++ b/Marlin/src/HAL/STM32/SoftwareSerial.h @@ -64,7 +64,6 @@ class SoftwareSerial : public Stream { // static data static HardwareTimer timer; static const IRQn_Type timer_interrupt_number; - static uint32_t timer_interrupt_priority; static SoftwareSerial *active_listener; static SoftwareSerial *volatile active_out; static SoftwareSerial *volatile active_in; diff --git a/Marlin/src/HAL/STM32/timers.cpp b/Marlin/src/HAL/STM32/timers.cpp index 0871fbc7d7e6..bd0f16c49d81 100644 --- a/Marlin/src/HAL/STM32/timers.cpp +++ b/Marlin/src/HAL/STM32/timers.cpp @@ -85,7 +85,6 @@ // ------------------------ HardwareTimer *timer_instance[NUM_HARDWARE_TIMERS] = { NULL }; -bool timer_enabled[NUM_HARDWARE_TIMERS] = { false }; // ------------------------ // Public functions @@ -110,11 +109,21 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { * which changes the prescaler when an IRQ frequency change is needed * (for example when steppers are turned on) */ + + // Arduino_Core_STM32 1.8 requires setMode to be called on a channel to start the timer. + // This is fixed in the following PR, which has not yet been released. + // https://github.com/stm32duino/Arduino_Core_STM32/pull/849 + timer_instance[timer_num]->setMode(1, TIMER_OUTPUT_COMPARE, NC); timer_instance[timer_num]->setPrescaleFactor(STEPPER_TIMER_PRESCALE); //the -1 is done internally timer_instance[timer_num]->setOverflow(_MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* /frequency */), TICK_FORMAT); break; case TEMP_TIMER_NUM: // TEMP TIMER - any available 16bit timer timer_instance[timer_num] = new HardwareTimer(TEMP_TIMER_DEV); + + // Arduino_Core_STM32 1.8 requires setMode to be called on a channel to start the timer. + // This is fixed in the following PR, which has not yet been released. + // https://github.com/stm32duino/Arduino_Core_STM32/pull/849 + timer_instance[timer_num]->setMode(1, TIMER_OUTPUT_COMPARE, NC); // The prescale factor is computed automatically for HERTZ_FORMAT timer_instance[timer_num]->setOverflow(frequency, HERTZ_FORMAT); break; @@ -122,13 +131,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { HAL_timer_enable_interrupt(timer_num); - /* - * Initializes (and unfortunately starts) the timer. - * This is needed to set correct IRQ priority at the moment but causes - * no harm since every call to HAL_timer_start() is actually followed by - * a call to HAL_timer_enable_interrupt() which means that there isn't - * a case in which you want the timer to run without a callback. - */ + // Start the timer. timer_instance[timer_num]->resume(); // First call to resume() MUST follow the attachInterrupt() // This is fixed in Arduino_Core_STM32 1.8. @@ -136,9 +139,19 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { // timer_instance[timer_num]->setInterruptPriority switch (timer_num) { case STEP_TIMER_NUM: + timer_instance[timer_num]->setInterruptPriority(STEP_TIMER_IRQ_PRIO, 0); + + // Arduino_Core_STM32 1.8 does not apply the interrupt priority until the + // timer is completely re-initialized, which never happens in this code. + // Explicitly set the interrupt priority until fixed in a future Arduino_Core_STM32. HAL_NVIC_SetPriority(STEP_TIMER_IRQ_NAME, STEP_TIMER_IRQ_PRIO, 0); break; case TEMP_TIMER_NUM: + timer_instance[timer_num]->setInterruptPriority(TEMP_TIMER_IRQ_PRIO, 0); + + // Arduino_Core_STM32 1.8 does not apply the interrupt priority until the + // timer is completely re-initialized, which never happens in this code. + // Explicitly set the interrupt priority until fixed in a future Arduino_Core_STM32. HAL_NVIC_SetPriority(TEMP_TIMER_IRQ_NAME, TEMP_TIMER_IRQ_PRIO, 0); break; } @@ -146,8 +159,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { } void HAL_timer_enable_interrupt(const uint8_t timer_num) { - if (HAL_timer_initialized(timer_num) && !timer_enabled[timer_num]) { - timer_enabled[timer_num] = true; + if (HAL_timer_initialized(timer_num) && !timer_instance[timer_num]->hasInterrupt()) { switch (timer_num) { case STEP_TIMER_NUM: timer_instance[timer_num]->attachInterrupt(Step_Handler); @@ -160,23 +172,11 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num) { } void HAL_timer_disable_interrupt(const uint8_t timer_num) { - if (HAL_timer_interrupt_enabled(timer_num)) { - timer_instance[timer_num]->detachInterrupt(); - timer_enabled[timer_num] = false; - } + if (HAL_timer_initialized(timer_num)) timer_instance[timer_num]->detachInterrupt(); } bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - return HAL_timer_initialized(timer_num) && timer_enabled[timer_num]; -} - -// Only for use within the HAL -TIM_TypeDef * HAL_timer_device(const uint8_t timer_num) { - switch (timer_num) { - case STEP_TIMER_NUM: return STEP_TIMER_DEV; - case TEMP_TIMER_NUM: return TEMP_TIMER_DEV; - } - return nullptr; + return HAL_timer_initialized(timer_num) && timer_instance[timer_num]->hasInterrupt(); } void SetSoftwareSerialTimerInterruptPriority() { diff --git a/Marlin/src/HAL/STM32/timers.h b/Marlin/src/HAL/STM32/timers.h index 60d3b3aaf3fc..ff656acda082 100644 --- a/Marlin/src/HAL/STM32/timers.h +++ b/Marlin/src/HAL/STM32/timers.h @@ -78,8 +78,6 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num); // Exposed here to allow all timer priority information to reside in timers.cpp void SetSoftwareSerialTimerInterruptPriority(); -//TIM_TypeDef* HAL_timer_device(const uint8_t timer_num); no need to be public for now. not public = not used externally - // FORCE_INLINE because these are used in performance-critical situations FORCE_INLINE bool HAL_timer_initialized(const uint8_t timer_num) { return timer_instance[timer_num] != NULL; diff --git a/buildroot/share/PlatformIO/boards/malyanM200v2.json b/buildroot/share/PlatformIO/boards/malyanM200v2.json index 9e301ee79f31..765a0c0a0006 100644 --- a/buildroot/share/PlatformIO/boards/malyanM200v2.json +++ b/buildroot/share/PlatformIO/boards/malyanM200v2.json @@ -4,7 +4,7 @@ "extra_flags": "-DSTM32F070xB", "f_cpu": "48000000L", "mcu": "stm32f070rbt6", - "variant": "MALYANM200_F070CB", + "variant": "MALYANMx00_F070CB", "vec_tab_addr": "0x8002000" }, "debug": { diff --git a/platformio.ini b/platformio.ini index 413b5201dae7..7c8076cbdef5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -21,7 +21,6 @@ boards_dir = buildroot/share/PlatformIO/boards default_envs = mega2560 [common] -arduinoststm32_ver = >=4.10700,<4.10800 default_src_filter = + - - + extra_scripts = pre:buildroot/share/PlatformIO/scripts/common-cxxflags.py build_flags = -fmax-errors=5 -g -D__MARLIN_FIRMWARE__ -fmerge-all-constants @@ -36,6 +35,10 @@ lib_deps = SailfishLCD=https://github.com/mikeshub/SailfishLCD/archive/master.zip SlowSoftI2CMaster=https://github.com/mikeshub/SlowSoftI2CMaster/archive/master.zip +[common_stm32] +arduinoststm32_ver = >=4.10800 +ststm32_ver = >=6.1 + # Globally defined properties # inherited by all environments [env] @@ -470,8 +473,8 @@ src_filter = ${common.default_src_filter} + -=6.1.0 +platform = ststm32@${common_stm32.ststm32_ver} +platform_packages = framework-arduinoststm32@${common_stm32.arduinoststm32_ver} board = malyanm300_f070cb build_flags = ${common.build_flags} -DUSBCON -DUSBD_VID=0x0483 "-DUSB_MANUFACTURER=\"Unknown\"" "-DUSB_PRODUCT=\"MALYAN_M300\"" @@ -679,8 +683,8 @@ lib_ignore = Adafruit NeoPixel # 'STEVAL-3DP001V1' STM32F401VE board - https://www.st.com/en/evaluation-tools/steval-3dp001v1.html # [env:STM32F401VE_STEVAL] -platform = ststm32 -platform_packages = framework-arduinoststm32@${common.arduinoststm32_ver} +platform = ststm32@${common_stm32.ststm32_ver} +platform_packages = framework-arduinoststm32@${common_stm32.arduinoststm32_ver} board = STEVAL_STM32F401VE build_flags = ${common.build_flags} -DTARGET_STM32F4 -DARDUINO_STEVAL -DSTM32F401xE @@ -697,8 +701,8 @@ src_filter = ${common.default_src_filter} + # FLYF407ZG # [env:FLYF407ZG] -platform = ststm32 -platform_packages = framework-arduinoststm32@${common.arduinoststm32_ver} +platform = ststm32@${common_stm32.ststm32_ver} +platform_packages = framework-arduinoststm32@${common_stm32.arduinoststm32_ver} board = FLYF407ZG build_flags = ${common.build_flags} -DSTM32F4 -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483 -DUSB_PRODUCT=\"STM32F407ZG\" @@ -714,10 +718,10 @@ src_filter = ${common.default_src_filter} + # FYSETC S6 (STM32F446VET6 ARM Cortex-M4) # [env:FYSETC_S6] -platform = ststm32 +platform = ststm32@${common_stm32.ststm32_ver} platform_packages = - tool-stm32duino - framework-arduinoststm32@${common.arduinoststm32_ver} + framework-arduinoststm32@${common_stm32.arduinoststm32_ver} + tool-stm32duino board = fysetc_s6 build_flags = ${common.build_flags} -DTARGET_STM32F4 -std=gnu++14 @@ -738,8 +742,8 @@ upload_command = dfu-util -a 0 -s 0x08010000:leave -D "$SOURCE" # Shield - https://github.com/jmz52/Hardware # [env:STM32F407VE_black] -platform = ststm32 -platform_packages = framework-arduinoststm32@${common.arduinoststm32_ver} +platform = ststm32@${common_stm32.ststm32_ver} +platform_packages = framework-arduinoststm32@${common_stm32.arduinoststm32_ver} board = blackSTM32F407VET6 build_flags = ${common.build_flags} -DTARGET_STM32F4 -DARDUINO_BLACK_F407VE @@ -755,8 +759,8 @@ src_filter = ${common.default_src_filter} + # BigTreeTech SKR Pro (STM32F407ZGT6 ARM Cortex-M4) # [env:BIGTREE_SKR_PRO] -platform = ststm32 -platform_packages = framework-arduinoststm32@${common.arduinoststm32_ver} +platform = ststm32@${common_stm32.ststm32_ver} +platform_packages = framework-arduinoststm32@${common_stm32.arduinoststm32_ver} board = BigTree_SKR_Pro build_flags = ${common.build_flags} -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483 -DUSB_PRODUCT=\"STM32F407ZG\" @@ -775,8 +779,8 @@ debug_init_break = # Bigtreetech GTR V1.0 (STM32F407IGT6 ARM Cortex-M4) # [env:BIGTREE_GTR_V1_0] -platform = ststm32@>=5.7.0 -platform_packages = framework-arduinoststm32@${common.arduinoststm32_ver} +platform = ststm32@${common_stm32.ststm32_ver} +platform_packages = framework-arduinoststm32@${common_stm32.arduinoststm32_ver} board = BigTree_GTR_v1 extra_scripts = pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py build_flags = ${common.build_flags} @@ -797,8 +801,8 @@ src_filter = ${common.default_src_filter} + # BigTreeTech BTT002 V1.0 (STM32F407VGT6 ARM Cortex-M4) # [env:BIGTREE_BTT002] -platform = ststm32@5.6.0 -platform_packages = framework-arduinoststm32@${common.arduinoststm32_ver} +platform = ststm32@${common_stm32.ststm32_ver} +platform_packages = framework-arduinoststm32@${common_stm32.arduinoststm32_ver} board = BigTree_Btt002 build_flags = ${common.build_flags} -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483 -DUSB_PRODUCT=\"STM32F407VG\" @@ -886,10 +890,10 @@ debug_tool = jlink # RUMBA32 # [env:rumba32_f446ve] -platform = ststm32 -platform_packages = framework-arduinoststm32@${common.arduinoststm32_ver} -board = rumba32_f446ve -build_flags = ${common.build_flags} +platform = ststm32@${common_stm32.ststm32_ver} +platform_packages = framework-arduinoststm32@${common_stm32.arduinoststm32_ver} +board = rumba32_f446ve +build_flags = ${common.build_flags} -DSTM32F4xx -DARDUINO_RUMBA32_F446VE -DARDUINO_ARCH_STM32 @@ -905,19 +909,19 @@ build_flags = ${common.build_flags} -DHAL_UART_MODULE_ENABLED -Os -IMarlin/src/HAL/STM32 -lib_ignore = Adafruit NeoPixel, SoftwareSerial -src_filter = ${common.default_src_filter} + -monitor_speed = 500000 -upload_protocol = dfu +lib_ignore = Adafruit NeoPixel, SoftwareSerial +src_filter = ${common.default_src_filter} + +monitor_speed = 500000 +upload_protocol = dfu # # MKS RUMBA32 (adds TMC2208/2209 UART interface and AUX-1) # [env:rumba32_mks] -platform = ststm32 -platform_packages = framework-arduinoststm32@${common.arduinoststm32_ver} -board = rumba32_f446ve -build_flags = ${common.build_flags} +platform = ststm32@${common_stm32.ststm32_ver} +platform_packages = framework-arduinoststm32@${common_stm32.arduinoststm32_ver} +board = rumba32_f446ve +build_flags = ${common.build_flags} -DSTM32F4xx -DARDUINO_RUMBA32_F446VE -DARDUINO_ARCH_STM32 "-DBOARD_NAME=\"RUMBA32_F446VE\"" -DSTM32F446xx -DUSBCON -DUSBD_VID=0x8000 "-DUSB_MANUFACTURER=\"Unknown\"" @@ -928,9 +932,9 @@ build_flags = ${common.build_flags} -DHAL_UART_MODULE_ENABLED -Os -IMarlin/src/HAL/STM32 -lib_ignore = Adafruit NeoPixel, SoftwareSerial -src_filter = ${common.default_src_filter} + -upload_protocol = dfu +lib_ignore = Adafruit NeoPixel, SoftwareSerial +src_filter = ${common.default_src_filter} + +upload_protocol = dfu # # Just print the dependency tree