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.
This commit is contained in:
victorpv 2017-12-20 16:16:36 -06:00 committed by Scott Lahteine
parent 913d9e9a59
commit 2ec4113cb2
8 changed files with 129 additions and 99 deletions

View file

@ -88,16 +88,30 @@ uint8 adc_pins[] = {
}; };
enum TEMP_PINS { enum TEMP_PINS {
#if HAS_TEMP_0
TEMP_0, TEMP_0,
#endif
#if HAS_TEMP_1
TEMP_1, TEMP_1,
#endif
#if HAS_TEMP_2
TEMP_2, TEMP_2,
#endif
#if HAS_TEMP_3
TEMP_3, TEMP_3,
#endif
#if HAS_TEMP_4
TEMP_4, TEMP_4,
#endif
#if HAS_TEMP_BED
TEMP_BED, TEMP_BED,
FILWIDTH #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]; 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) { void HAL_adc_start_conversion(const uint8_t adc_pin) {
TEMP_PINS pin_index; TEMP_PINS pin_index;
switch (adc_pin) { switch (adc_pin) {
default: #if HAS_TEMP_0
case TEMP_0_PIN: pin_index = TEMP_0; break; case TEMP_0_PIN: pin_index = TEMP_0; break;
#endif
#if HAS_TEMP_1
case TEMP_1_PIN: pin_index = TEMP_1; break; case TEMP_1_PIN: pin_index = TEMP_1; break;
#endif
#if HAS_TEMP_2
case TEMP_2_PIN: pin_index = TEMP_2; break; case TEMP_2_PIN: pin_index = TEMP_2; break;
#endif
#if HAS_TEMP_3
case TEMP_3_PIN: pin_index = TEMP_3; break; case TEMP_3_PIN: pin_index = TEMP_3; break;
#endif
#if HAS_TEMP_4
case TEMP_4_PIN: pin_index = TEMP_4; break; case TEMP_4_PIN: pin_index = TEMP_4; break;
#endif
#if HAS_TEMP_BED
case TEMP_BED_PIN: pin_index = TEMP_BED; break; case TEMP_BED_PIN: pin_index = TEMP_BED; break;
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR) #if ENABLED(FILAMENT_WIDTH_SENSOR)
case FILWIDTH_PIN: pin_index = FILWIDTH; break; case FILWIDTH_PIN: pin_index = FILWIDTH; break;
#endif #endif

View file

@ -79,8 +79,8 @@ void spiBegin() {
#if !PIN_EXISTS(SS) #if !PIN_EXISTS(SS)
#error "SS_PIN not defined!" #error "SS_PIN not defined!"
#endif #endif
SET_OUTPUT(SS_PIN);
WRITE(SS_PIN, HIGH); WRITE(SS_PIN, HIGH);
SET_OUTPUT(SS_PIN);
} }
/** /**

View file

@ -82,11 +82,11 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
// Public functions // Public functions
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
/* /**
Timer_clock1: Prescaler 2 -> 42MHz * Timer_clock1: Prescaler 2 -> 36 MHz
Timer_clock2: Prescaler 8 -> 10.5MHz * Timer_clock2: Prescaler 8 -> 9 MHz
Timer_clock3: Prescaler 32 -> 2.625MHz * Timer_clock3: Prescaler 32 -> 2.25 MHz
Timer_clock4: Prescaler 128 -> 656.25kHz * Timer_clock4: Prescaler 128 -> 562.5 kHz
*/ */
/** /**
@ -94,6 +94,23 @@ Timer_clock4: Prescaler 128 -> 656.25kHz
*/ */
void HAL_timer_start(uint8_t timer_num, uint32_t frequency) { 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) { switch (timer_num) {
case STEP_TIMER_NUM: case STEP_TIMER_NUM:
timer_pause(STEP_TIMER_DEV); timer_pause(STEP_TIMER_DEV);

View file

@ -46,7 +46,7 @@
typedef uint16_t hal_timer_t; typedef uint16_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFF #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 #define STEP_TIMER_NUM 4 // For C8/CB boards, use timer 4
#else #else
#define STEP_TIMER_NUM 5 // for other boards, five is fine. #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_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 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 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_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 #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 PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz #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 ENABLE_STEPPER_DRIVER_INTERRUPT() timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM) #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) #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 // 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) { 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) { switch (timer_num) {
case STEP_TIMER_NUM: case STEP_TIMER_NUM:
StepperTimer.pause(); timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, count);
StepperTimer.setCompare(STEP_TIMER_CHAN, count); return;
StepperTimer.refresh();
StepperTimer.resume();
break;
case TEMP_TIMER_NUM: case TEMP_TIMER_NUM:
TempTimer.pause(); timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, count);
TempTimer.setCompare(TEMP_TIMER_CHAN, count); return;
TempTimer.refresh();
TempTimer.resume();
break;
default: default:
break; return;
} }
} }
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
hal_timer_t temp;
switch (timer_num) { switch (timer_num) {
case STEP_TIMER_NUM: case STEP_TIMER_NUM:
temp = StepperTimer.getCompare(STEP_TIMER_CHAN); return timer_get_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN);
break;
case TEMP_TIMER_NUM: case TEMP_TIMER_NUM:
temp = TempTimer.getCompare(TEMP_TIMER_CHAN); return timer_get_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN);
break;
default: default:
temp = 0; return 0;
break;
}
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) { FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
switch (timer_num) { switch (timer_num) {
case STEP_TIMER_NUM: case STEP_TIMER_NUM:
StepperTimer.pause(); timer_set_count(STEP_TIMER_DEV, 0);
StepperTimer.setCount(0); timer_generate_update(STEP_TIMER_DEV);
StepperTimer.refresh(); return;
StepperTimer.resume();
break;
case TEMP_TIMER_NUM: case TEMP_TIMER_NUM:
TempTimer.pause(); timer_set_count(TEMP_TIMER_DEV, 0);
TempTimer.setCount(0); timer_generate_update(TEMP_TIMER_DEV);
TempTimer.refresh(); return;
TempTimer.resume();
break;
default: default:
break; return;
} }
} }

View file

@ -35,12 +35,10 @@
#elif ENABLED(SPINDLE_LASER_PWM) && PIN_EXISTS(SPINDLE_LASER_PWM) #elif ENABLED(SPINDLE_LASER_PWM) && PIN_EXISTS(SPINDLE_LASER_PWM)
#if !PWM_PIN(SPINDLE_LASER_PWM_PIN) #if !PWM_PIN(SPINDLE_LASER_PWM_PIN)
#error "SPINDLE_LASER_PWM_PIN not assigned to a 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) #elif SPINDLE_LASER_POWERUP_DELAY < 0
#error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" #error "SPINDLE_LASER_POWERUP_DELAY must be positive"
#elif SPINDLE_LASER_POWERUP_DELAY < 1 #elif SPINDLE_LASER_POWERDOWN_DELAY < 0
#error "SPINDLE_LASER_POWERUP_DELAY must be greater than 0." #error "SPINDLE_LASER_POWERDOWN_DELAY must be positive"
#elif SPINDLE_LASER_POWERDOWN_DELAY < 1
#error "SPINDLE_LASER_POWERDOWN_DELAY must be greater than 0."
#elif !defined(SPINDLE_LASER_PWM_INVERT) #elif !defined(SPINDLE_LASER_PWM_INVERT)
#error "SPINDLE_LASER_PWM_INVERT missing." #error "SPINDLE_LASER_PWM_INVERT missing."
#elif !defined(SPEED_POWER_SLOPE) || !defined(SPEED_POWER_INTERCEPT) || !defined(SPEED_POWER_MIN) || !defined(SPEED_POWER_MAX) #elif !defined(SPEED_POWER_SLOPE) || !defined(SPEED_POWER_INTERCEPT) || !defined(SPEED_POWER_MIN) || !defined(SPEED_POWER_MAX)

View file

@ -49,5 +49,9 @@
#define GET_TIMER(IO) (PIN_MAP[IO].timer_device != NULL) #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 */ #endif /* _FASTIO_STM32F1_H */

View file

@ -27,7 +27,7 @@
/** /**
* Define SPI Pins: SCK, MISO, MOSI, SS * 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 SCK_PIN PA5
#define MISO_PIN PA6 #define MISO_PIN PA6

View file

@ -30,6 +30,12 @@
#include <libmaple/iwdg.h> #include <libmaple/iwdg.h>
#include "../../../src/inc/MarlinConfig.h" #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 #define STM32F1_WD_RELOAD 625
// Arduino STM32F1 core now has watchdog support // 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 // Reset watchdog. MUST be called at least every 4 seconds after the
// first watchdog_init or STM32F1 will reset. // 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 #endif // WATCHDOG_STM32F1_H