From 2ec4113cb26f1a3b70a9f513f7344e57c7ef1e45 Mon Sep 17 00:00:00 2001 From: victorpv Date: Wed, 20 Dec 2017 16:16:36 -0600 Subject: [PATCH] Changes to STM32F1 HAL (#8833) Some to correct missing files from previous PR to completely avoid HardwareTimer Class (reduce overhead). Some changes to formatting. Changes to DMA ADC to work correctly. Change to F1 sanity check. --- Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.cpp | 55 ++++++++--- .../src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp | 14 +-- .../HAL/HAL_STM32F1/HAL_timers_Stm32f1.cpp | 29 ++++-- .../src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.h | 99 +++++++------------ .../src/HAL/HAL_STM32F1/SanityCheck_Stm32f1.h | 10 +- Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h | 6 +- Marlin/src/HAL/HAL_STM32F1/spi_pins.h | 2 +- Marlin/src/HAL/HAL_STM32F1/watchdog_Stm32f1.h | 13 ++- 8 files changed, 129 insertions(+), 99 deletions(-) diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.cpp index 8bc88f009..163e28a3e 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.cpp @@ -88,16 +88,30 @@ uint8 adc_pins[] = { }; enum TEMP_PINS { - TEMP_0, - TEMP_1, - TEMP_2, - TEMP_3, - TEMP_4, - TEMP_BED, - FILWIDTH + #if HAS_TEMP_0 + TEMP_0, + #endif + #if HAS_TEMP_1 + TEMP_1, + #endif + #if HAS_TEMP_2 + TEMP_2, + #endif + #if HAS_TEMP_3 + TEMP_3, + #endif + #if HAS_TEMP_4 + TEMP_4, + #endif + #if HAS_TEMP_BED + TEMP_BED, + #endif + #if ENABLED(FILAMENT_WIDTH_SENSOR) + FILWIDTH, + #endif + ADC_PIN_COUNT }; -#define ADC_PIN_COUNT (sizeof(adc_pins)/sizeof(adc_pins[0])) uint16_t HAL_adc_results[ADC_PIN_COUNT]; @@ -181,13 +195,24 @@ void HAL_adc_init(void) { void HAL_adc_start_conversion(const uint8_t adc_pin) { TEMP_PINS pin_index; switch (adc_pin) { - default: - case TEMP_0_PIN: pin_index = TEMP_0; break; - case TEMP_1_PIN: pin_index = TEMP_1; break; - case TEMP_2_PIN: pin_index = TEMP_2; break; - case TEMP_3_PIN: pin_index = TEMP_3; break; - case TEMP_4_PIN: pin_index = TEMP_4; break; - case TEMP_BED_PIN: pin_index = TEMP_BED; break; + #if HAS_TEMP_0 + case TEMP_0_PIN: pin_index = TEMP_0; break; + #endif + #if HAS_TEMP_1 + case TEMP_1_PIN: pin_index = TEMP_1; break; + #endif + #if HAS_TEMP_2 + case TEMP_2_PIN: pin_index = TEMP_2; break; + #endif + #if HAS_TEMP_3 + case TEMP_3_PIN: pin_index = TEMP_3; break; + #endif + #if HAS_TEMP_4 + case TEMP_4_PIN: pin_index = TEMP_4; break; + #endif + #if HAS_TEMP_BED + case TEMP_BED_PIN: pin_index = TEMP_BED; break; + #endif #if ENABLED(FILAMENT_WIDTH_SENSOR) case FILWIDTH_PIN: pin_index = FILWIDTH; break; #endif diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp index 5ddbfc0d9..87169c5a5 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp @@ -79,8 +79,8 @@ void spiBegin() { #if !PIN_EXISTS(SS) #error "SS_PIN not defined!" #endif - SET_OUTPUT(SS_PIN); WRITE(SS_PIN, HIGH); + SET_OUTPUT(SS_PIN); } /** @@ -94,12 +94,12 @@ void spiBegin() { void spiInit(uint8_t spiRate) { uint8_t clock; switch (spiRate) { - case SPI_FULL_SPEED: clock = SPI_CLOCK_DIV2 ; break; - case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4 ; break; - case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8 ; break; - case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break; - case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break; - case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; + case SPI_FULL_SPEED: clock = SPI_CLOCK_DIV2 ; break; + case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4 ; break; + case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8 ; break; + case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break; + case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break; + case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; default: clock = SPI_CLOCK_DIV2; // Default from the SPI library } diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.cpp index b515c6625..45ed20df1 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.cpp @@ -82,18 +82,35 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = { // Public functions // -------------------------------------------------------------------------- -/* -Timer_clock1: Prescaler 2 -> 42MHz -Timer_clock2: Prescaler 8 -> 10.5MHz -Timer_clock3: Prescaler 32 -> 2.625MHz -Timer_clock4: Prescaler 128 -> 656.25kHz -*/ +/** + * Timer_clock1: Prescaler 2 -> 36 MHz + * Timer_clock2: Prescaler 8 -> 9 MHz + * Timer_clock3: Prescaler 32 -> 2.25 MHz + * Timer_clock4: Prescaler 128 -> 562.5 kHz + */ /** * TODO: Calculate Timer prescale value, so we get the 32bit to adjust */ void HAL_timer_start(uint8_t timer_num, uint32_t frequency) { + nvic_irq_num irq_num; + switch (timer_num) { + case 1: irq_num = NVIC_TIMER1_CC; break; + case 2: irq_num = NVIC_TIMER2; break; + case 3: irq_num = NVIC_TIMER3; break; + case 4: irq_num = NVIC_TIMER4; break; + case 5: irq_num = NVIC_TIMER5; break; + default: + /** + * We should not get here, add Sanitycheck for timer number. Should be a general timer + * since basic timers do not have CC channels. + * Advanced timers should be skipped if possible too, and are not listed above. + */ + break; + } + nvic_irq_set_priority(irq_num, 0xF); // this is the lowest settable priority, but should still be over USB + switch (timer_num) { case STEP_TIMER_NUM: timer_pause(STEP_TIMER_DEV); diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.h b/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.h index 0b4c9050e..bdc083e2a 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.h +++ b/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.h @@ -46,7 +46,7 @@ typedef uint16_t hal_timer_t; #define HAL_TIMER_TYPE_MAX 0xFFFF -#ifdef MCU_STM32F103CB || defined(MCU_STM32F103C8) +#if defined MCU_STM32F103CB || defined(MCU_STM32F103C8) #define STEP_TIMER_NUM 4 // For C8/CB boards, use timer 4 #else #define STEP_TIMER_NUM 5 // for other boards, five is fine. @@ -56,8 +56,18 @@ typedef uint16_t hal_timer_t; #define TEMP_TIMER_NUM 2 // index of timer to use for temperature #define TEMP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts +#define CAT(a, ...) a ## __VA_ARGS__ +#define TIMER_DEV(num) CAT (&timer, num) + +#define STEP_TIMER_DEV TIMER_DEV(STEP_TIMER_NUM) +#define TEMP_TIMER_DEV TIMER_DEV(TEMP_TIMER_NUM) + + + +//STM32_HAVE_TIMER(n); + #define HAL_TIMER_RATE (F_CPU) // frequency of timers peripherals -#define STEPPER_TIMER_PRESCALE 36 // prescaler for setting stepper timer, 2Mhz +#define STEPPER_TIMER_PRESCALE 18 // prescaler for setting stepper timer, 4Mhz #define HAL_STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) #define HAL_TICKS_PER_US ((HAL_STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per us @@ -65,13 +75,17 @@ typedef uint16_t hal_timer_t; #define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE #define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency +#define TEMP_TIMER_FREQUENCY 100 // temperature interrupt frequency -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM) +#define ENABLE_STEPPER_DRIVER_INTERRUPT() timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) + +#define ENABLE_TEMPERATURE_INTERRUPT() timer_enable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN) +#define DISABLE_TEMPERATURE_INTERRUPT() timer_disable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN) + +#define HAL_timer_get_current_count(timer_num) timer_get_count(TIMER_DEV(timer_num)) +#define HAL_timer_set_current_count(timer_num, count) timer_set_count(TIMER_DEV(timer_num, (uint16)count)) -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) #define HAL_ENABLE_ISRs() do { if (thermalManager.in_temp_isr)DISABLE_TEMPERATURE_INTERRUPT(); else ENABLE_TEMPERATURE_INTERRUPT(); ENABLE_STEPPER_DRIVER_INTERRUPT(); } while(0) // TODO change this @@ -115,81 +129,42 @@ void HAL_timer_disable_interrupt(uint8_t timer_num); */ FORCE_INLINE static void HAL_timer_set_count(const uint8_t timer_num, const hal_timer_t count) { + //count = min(count, HAL_TIMER_TYPE_MAX); switch (timer_num) { case STEP_TIMER_NUM: - StepperTimer.pause(); - StepperTimer.setCompare(STEP_TIMER_CHAN, count); - StepperTimer.refresh(); - StepperTimer.resume(); - break; + timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, count); + return; case TEMP_TIMER_NUM: - TempTimer.pause(); - TempTimer.setCompare(TEMP_TIMER_CHAN, count); - TempTimer.refresh(); - TempTimer.resume(); - break; + timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, count); + return; default: - break; + return; } } FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { - hal_timer_t temp; switch (timer_num) { case STEP_TIMER_NUM: - temp = StepperTimer.getCompare(STEP_TIMER_CHAN); - break; + return timer_get_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN); case TEMP_TIMER_NUM: - temp = TempTimer.getCompare(TEMP_TIMER_CHAN); - break; + return timer_get_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN); default: - temp = 0; - break; + return 0; } - return temp; } -FORCE_INLINE static void HAL_timer_set_current_count(const uint8_t timer_num, const hal_timer_t count) { - switch (timer_num) { - case STEP_TIMER_NUM: StepperTimer.setCount(count); break; - case TEMP_TIMER_NUM: TempTimer.setCount(count); break; - } -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_current_count(const uint8_t timer_num) { - hal_timer_t temp; - switch (timer_num) { - case STEP_TIMER_NUM: - temp = StepperTimer.getCount(); - break; - case TEMP_TIMER_NUM: - temp = TempTimer.getCount(); - break; - default: - temp = 0; - break; - } - return temp; -} - -//void HAL_timer_isr_prologue (const uint8_t timer_num); - FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { switch (timer_num) { case STEP_TIMER_NUM: - StepperTimer.pause(); - StepperTimer.setCount(0); - StepperTimer.refresh(); - StepperTimer.resume(); - break; + timer_set_count(STEP_TIMER_DEV, 0); + timer_generate_update(STEP_TIMER_DEV); + return; case TEMP_TIMER_NUM: - TempTimer.pause(); - TempTimer.setCount(0); - TempTimer.refresh(); - TempTimer.resume(); - break; + timer_set_count(TEMP_TIMER_DEV, 0); + timer_generate_update(TEMP_TIMER_DEV); + return; default: - break; + return; } } diff --git a/Marlin/src/HAL/HAL_STM32F1/SanityCheck_Stm32f1.h b/Marlin/src/HAL/HAL_STM32F1/SanityCheck_Stm32f1.h index eec7e4d23..19127efdf 100644 --- a/Marlin/src/HAL/HAL_STM32F1/SanityCheck_Stm32f1.h +++ b/Marlin/src/HAL/HAL_STM32F1/SanityCheck_Stm32f1.h @@ -35,12 +35,10 @@ #elif ENABLED(SPINDLE_LASER_PWM) && PIN_EXISTS(SPINDLE_LASER_PWM) #if !PWM_PIN(SPINDLE_LASER_PWM_PIN) #error "SPINDLE_LASER_PWM_PIN not assigned to a PWM pin." - #elif !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11) - #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" - #elif SPINDLE_LASER_POWERUP_DELAY < 1 - #error "SPINDLE_LASER_POWERUP_DELAY must be greater than 0." - #elif SPINDLE_LASER_POWERDOWN_DELAY < 1 - #error "SPINDLE_LASER_POWERDOWN_DELAY must be greater than 0." + #elif SPINDLE_LASER_POWERUP_DELAY < 0 + #error "SPINDLE_LASER_POWERUP_DELAY must be positive" + #elif SPINDLE_LASER_POWERDOWN_DELAY < 0 + #error "SPINDLE_LASER_POWERDOWN_DELAY must be positive" #elif !defined(SPINDLE_LASER_PWM_INVERT) #error "SPINDLE_LASER_PWM_INVERT missing." #elif !defined(SPEED_POWER_SLOPE) || !defined(SPEED_POWER_INTERCEPT) || !defined(SPEED_POWER_MIN) || !defined(SPEED_POWER_MAX) diff --git a/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h b/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h index 01964916a..4519a4fe4 100644 --- a/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h +++ b/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h @@ -48,6 +48,10 @@ #define GET_OUTPUT(IO) (_GET_MODE(IO) == GPIO_OUTPUT_PP) #define GET_TIMER(IO) (PIN_MAP[IO].timer_device != NULL) -#define OUT_WRITE(IO, v) { _SET_OUTPUT(IO); WRITE(IO, v); } +#define OUT_WRITE(IO, v) { _SET_OUTPUT(IO); WRITE(IO, v); } +/* + * TODO: Write a macro to test if PIN is PWM or not. + */ +#define PWM_PIN(p) true #endif /* _FASTIO_STM32F1_H */ diff --git a/Marlin/src/HAL/HAL_STM32F1/spi_pins.h b/Marlin/src/HAL/HAL_STM32F1/spi_pins.h index 26a69080a..f834cea3c 100644 --- a/Marlin/src/HAL/HAL_STM32F1/spi_pins.h +++ b/Marlin/src/HAL/HAL_STM32F1/spi_pins.h @@ -27,7 +27,7 @@ /** * Define SPI Pins: SCK, MISO, MOSI, SS * - * Available chip select pins for HW SPI are 4 10 52 77 + * Any PIN can be used for Chip Select (SS) */ #define SCK_PIN PA5 #define MISO_PIN PA6 diff --git a/Marlin/src/HAL/HAL_STM32F1/watchdog_Stm32f1.h b/Marlin/src/HAL/HAL_STM32F1/watchdog_Stm32f1.h index 5add9e5ef..535d7b2b7 100644 --- a/Marlin/src/HAL/HAL_STM32F1/watchdog_Stm32f1.h +++ b/Marlin/src/HAL/HAL_STM32F1/watchdog_Stm32f1.h @@ -30,6 +30,12 @@ #include #include "../../../src/inc/MarlinConfig.h" + +/** + * The watchdog clock is 40Khz. We need a 4 seconds interval, so use a /256 preescaler and + * 625 reload value (counts down to 0) + * use 1250 for 8 seconds + */ #define STM32F1_WD_RELOAD 625 // Arduino STM32F1 core now has watchdog support @@ -39,6 +45,11 @@ void watchdog_init(); // Reset watchdog. MUST be called at least every 4 seconds after the // first watchdog_init or STM32F1 will reset. -inline void watchdog_reset() { iwdg_feed(); } +inline void watchdog_reset() { + #if PIN_EXISTS(LED) + TOGGLE(LED_PIN); // heart beat indicator + #endif + iwdg_feed(); +} #endif // WATCHDOG_STM32F1_H