committed by
					
						
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							428b67db31
						
					
				
				
					commit
					56cec9690a
				
			@@ -36,7 +36,7 @@
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
// Don't initialize/override variable (which would happen in .init4)
 | 
			
		||||
uint8_t reset_reason __attribute__((section(".noinit")));
 | 
			
		||||
uint8_t MarlinHAL::reset_reason __attribute__((section(".noinit")));
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public functions
 | 
			
		||||
@@ -45,22 +45,22 @@ uint8_t reset_reason __attribute__((section(".noinit")));
 | 
			
		||||
__attribute__((naked))             // Don't output function pro- and epilogue
 | 
			
		||||
__attribute__((used))              // Output the function, even if "not used"
 | 
			
		||||
__attribute__((section(".init3"))) // Put in an early user definable section
 | 
			
		||||
void HAL_save_reset_reason() {
 | 
			
		||||
void save_reset_reason() {
 | 
			
		||||
  #if ENABLED(OPTIBOOT_RESET_REASON)
 | 
			
		||||
    __asm__ __volatile__(
 | 
			
		||||
      A("STS %0, r2")
 | 
			
		||||
      : "=m"(reset_reason)
 | 
			
		||||
      : "=m"(hal.reset_reason)
 | 
			
		||||
    );
 | 
			
		||||
  #else
 | 
			
		||||
    reset_reason = MCUSR;
 | 
			
		||||
    hal.reset_reason = MCUSR;
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  // Clear within 16ms since WDRF bit enables a 16ms watchdog timer -> Boot loop
 | 
			
		||||
  MCUSR = 0;
 | 
			
		||||
  hal.clear_reset_source();
 | 
			
		||||
  wdt_disable();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_init() {
 | 
			
		||||
void MarlinHAL::init() {
 | 
			
		||||
  // Init Servo Pins
 | 
			
		||||
  #define INIT_SERVO(N) OUT_WRITE(SERVO##N##_PIN, LOW)
 | 
			
		||||
  #if HAS_SERVO_0
 | 
			
		||||
@@ -79,7 +79,7 @@ void HAL_init() {
 | 
			
		||||
  init_pwm_timers();   // Init user timers to default frequency - 1000HZ
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_reboot() {
 | 
			
		||||
void MarlinHAL::reboot() {
 | 
			
		||||
  #if ENABLED(USE_WATCHDOG)
 | 
			
		||||
    while (1) { /* run out the watchdog */ }
 | 
			
		||||
  #else
 | 
			
		||||
@@ -95,7 +95,7 @@ void HAL_reboot() {
 | 
			
		||||
 | 
			
		||||
#else // !SDSUPPORT
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
  extern "C" {
 | 
			
		||||
    extern char __bss_end;
 | 
			
		||||
    extern char __heap_start;
 | 
			
		||||
    extern void* __brkval;
 | 
			
		||||
@@ -108,7 +108,7 @@ extern "C" {
 | 
			
		||||
        free_memory = ((int)&free_memory) - ((int)__brkval);
 | 
			
		||||
      return free_memory;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#endif // !SDSUPPORT
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -74,9 +74,9 @@
 | 
			
		||||
  #define CRITICAL_SECTION_START()  unsigned char _sreg = SREG; cli()
 | 
			
		||||
  #define CRITICAL_SECTION_END()    SREG = _sreg
 | 
			
		||||
#endif
 | 
			
		||||
#define ISRS_ENABLED() TEST(SREG, SREG_I)
 | 
			
		||||
#define ENABLE_ISRS()  sei()
 | 
			
		||||
#define DISABLE_ISRS() cli()
 | 
			
		||||
 | 
			
		||||
#define HAL_CAN_SET_PWM_FREQ   // This HAL supports PWM Frequency adjustment
 | 
			
		||||
#define PWM_FREQUENCY 1000     // Default PWM frequency when set_pwm_duty() is called without set_pwm_frequency()
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Types
 | 
			
		||||
@@ -84,16 +84,15 @@
 | 
			
		||||
 | 
			
		||||
typedef int8_t pin_t;
 | 
			
		||||
 | 
			
		||||
#define SHARED_SERVOS HAS_SERVOS
 | 
			
		||||
#define HAL_SERVO_LIB Servo
 | 
			
		||||
#define SHARED_SERVOS HAS_SERVOS  // Use shared/servos.cpp
 | 
			
		||||
 | 
			
		||||
class Servo;
 | 
			
		||||
typedef Servo hal_servo_t;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public Variables
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
extern uint8_t reset_reason;
 | 
			
		||||
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#ifdef USBCON
 | 
			
		||||
  #include "../../core/serial_hook.h"
 | 
			
		||||
  typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
 | 
			
		||||
@@ -142,57 +141,15 @@ extern uint8_t reset_reason;
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public functions
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void HAL_init();
 | 
			
		||||
 | 
			
		||||
//void cli();
 | 
			
		||||
 | 
			
		||||
//void _delay_ms(const int delay);
 | 
			
		||||
 | 
			
		||||
inline void HAL_clear_reset_source() { }
 | 
			
		||||
inline uint8_t HAL_get_reset_source() { return reset_reason; }
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
extern "C" int freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// ADC
 | 
			
		||||
#ifdef DIDR2
 | 
			
		||||
  #define HAL_ANALOG_SELECT(ind) do{ if (ind < 8) SBI(DIDR0, ind); else SBI(DIDR2, ind & 0x07); }while(0)
 | 
			
		||||
#else
 | 
			
		||||
  #define HAL_ANALOG_SELECT(ind) SBI(DIDR0, ind);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
inline void HAL_adc_init() {
 | 
			
		||||
  ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
 | 
			
		||||
  DIDR0 = 0;
 | 
			
		||||
  #ifdef DIDR2
 | 
			
		||||
    DIDR2 = 0;
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define SET_ADMUX_ADCSRA(ch) ADMUX = _BV(REFS0) | (ch & 0x07); SBI(ADCSRA, ADSC)
 | 
			
		||||
#ifdef MUX5
 | 
			
		||||
  #define HAL_START_ADC(ch) if (ch > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
 | 
			
		||||
#else
 | 
			
		||||
  #define HAL_START_ADC(ch) ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
#define HAL_ADC_VREF        5.0
 | 
			
		||||
#define HAL_ADC_RESOLUTION 10
 | 
			
		||||
#define HAL_READ_ADC()  ADC
 | 
			
		||||
#define HAL_ADC_READY() !TEST(ADCSRA, ADSC)
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Pin Mapping for M42, M43, M226
 | 
			
		||||
//
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
 | 
			
		||||
@@ -206,30 +163,109 @@ inline void HAL_adc_init() {
 | 
			
		||||
// AVR compatibility
 | 
			
		||||
#define strtof strtod
 | 
			
		||||
 | 
			
		||||
#define HAL_CAN_SET_PWM_FREQ   // This HAL supports PWM Frequency adjustment
 | 
			
		||||
#define PWM_FREQUENCY 1000     // Default PWM frequency when set_pwm_duty() is called without set_pwm_frequency()
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  set_pwm_frequency
 | 
			
		||||
 *  Sets the frequency of the timer corresponding to the provided pin
 | 
			
		||||
 *  as close as possible to the provided desired frequency. Internally
 | 
			
		||||
 *  calculates the required waveform generation mode, prescaler and
 | 
			
		||||
 *  resolution values required and sets the timer registers accordingly.
 | 
			
		||||
 *  NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B)
 | 
			
		||||
 *  NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings)
 | 
			
		||||
 */
 | 
			
		||||
void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * set_pwm_duty
 | 
			
		||||
 *  Set the PWM duty cycle of the provided pin to the provided value
 | 
			
		||||
 *  Optionally allows inverting the duty cycle [default = false]
 | 
			
		||||
 *  Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
 */
 | 
			
		||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
 | 
			
		||||
extern "C" int freeMemory();
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
  static void init();          // Called early in setup()
 | 
			
		||||
  static void init_board() {}  // Called less early in setup()
 | 
			
		||||
  static void reboot();        // Restart the firmware from 0x0
 | 
			
		||||
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static bool isr_state() { return TEST(SREG, SREG_I); }
 | 
			
		||||
  static void isr_on()  { sei(); }
 | 
			
		||||
  static void isr_off() { cli(); }
 | 
			
		||||
 | 
			
		||||
  static void delay_ms(const int ms) { _delay_ms(ms); }
 | 
			
		||||
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask() {}
 | 
			
		||||
 | 
			
		||||
  // Reset
 | 
			
		||||
  static uint8_t reset_reason;
 | 
			
		||||
  static uint8_t get_reset_source() { return reset_reason; }
 | 
			
		||||
  static void clear_reset_source() { MCUSR = 0; }
 | 
			
		||||
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory() { return ::freeMemory(); }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init() {
 | 
			
		||||
    ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
 | 
			
		||||
    DIDR0 = 0;
 | 
			
		||||
    #ifdef DIDR2
 | 
			
		||||
      DIDR2 = 0;
 | 
			
		||||
    #endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const uint8_t ch) {
 | 
			
		||||
    #ifdef DIDR2
 | 
			
		||||
      if (ch > 7) { SBI(DIDR2, ch & 0x07); return; }
 | 
			
		||||
    #endif
 | 
			
		||||
    SBI(DIDR0, ch);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given channel
 | 
			
		||||
  static void adc_start(const uint8_t ch) {
 | 
			
		||||
    #ifdef MUX5
 | 
			
		||||
      ADCSRB = ch > 7 ? _BV(MUX5) : 0;
 | 
			
		||||
    #else
 | 
			
		||||
      ADCSRB = 0;
 | 
			
		||||
    #endif
 | 
			
		||||
    ADMUX = _BV(REFS0) | (ch & 0x07);
 | 
			
		||||
    SBI(ADCSRA, ADSC);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready() { return !TEST(ADCSRA, ADSC); }
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static __typeof__(ADC) adc_value() { return ADC; }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * init_pwm_timers
 | 
			
		||||
 * sets the default frequency for timers 2-5 to 1000HZ
 | 
			
		||||
   * Set the default frequency for timers 2-5 to 1000HZ
 | 
			
		||||
   */
 | 
			
		||||
void init_pwm_timers();
 | 
			
		||||
  static void init_pwm_timers();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * Optionally invert the duty cycle [default = false]
 | 
			
		||||
   * Optionally change the scale of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the frequency of the timer for the given pin as close as
 | 
			
		||||
   * possible to the provided desired frequency. Internally calculate
 | 
			
		||||
   * the required waveform generation mode, prescaler, and resolution
 | 
			
		||||
   * values and set timer registers accordingly.
 | 
			
		||||
   * NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B)
 | 
			
		||||
   * NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST_PWM_FAN Settings)
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -486,7 +486,7 @@ void MarlinSerial<Cfg>::write(const uint8_t c) {
 | 
			
		||||
    const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
 | 
			
		||||
 | 
			
		||||
    // If global interrupts are disabled (as the result of being called from an ISR)...
 | 
			
		||||
    if (!ISRS_ENABLED()) {
 | 
			
		||||
    if (!hal.isr_state()) {
 | 
			
		||||
 | 
			
		||||
      // Make room by polling if it is possible to transmit, and do so!
 | 
			
		||||
      while (i == tx_buffer.tail) {
 | 
			
		||||
@@ -534,7 +534,7 @@ void MarlinSerial<Cfg>::flushTX() {
 | 
			
		||||
    if (!_written) return;
 | 
			
		||||
 | 
			
		||||
    // If global interrupts are disabled (as the result of being called from an ISR)...
 | 
			
		||||
    if (!ISRS_ENABLED()) {
 | 
			
		||||
    if (!hal.isr_state()) {
 | 
			
		||||
 | 
			
		||||
      // Wait until everything was transmitted - We must do polling, as interrupts are disabled
 | 
			
		||||
      while (tx_buffer.head != tx_buffer.tail || !B_TXC) {
 | 
			
		||||
 
 | 
			
		||||
@@ -191,13 +191,13 @@
 | 
			
		||||
                   rx_framing_errors;
 | 
			
		||||
    static ring_buffer_pos_t rx_max_enqueued;
 | 
			
		||||
 | 
			
		||||
    static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_head();
 | 
			
		||||
    FORCE_INLINE static ring_buffer_pos_t atomic_read_rx_head();
 | 
			
		||||
 | 
			
		||||
    static volatile bool rx_tail_value_not_stable;
 | 
			
		||||
    static volatile uint16_t rx_tail_value_backup;
 | 
			
		||||
 | 
			
		||||
    static FORCE_INLINE void atomic_set_rx_tail(ring_buffer_pos_t value);
 | 
			
		||||
    static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_tail();
 | 
			
		||||
    FORCE_INLINE static void atomic_set_rx_tail(ring_buffer_pos_t value);
 | 
			
		||||
    FORCE_INLINE static ring_buffer_pos_t atomic_read_rx_tail();
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
    FORCE_INLINE static void store_rxd_char();
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,7 @@ const Timer get_pwm_timer(const pin_t pin) {
 | 
			
		||||
  return Timer();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
 | 
			
		||||
void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
 | 
			
		||||
  const Timer timer = get_pwm_timer(pin);
 | 
			
		||||
  if (timer.isProtected || !timer.isPWM) return; // Don't proceed if protected timer or not recognized
 | 
			
		||||
 | 
			
		||||
@@ -176,7 +176,7 @@ void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
 | 
			
		||||
    _SET_ICRn(timer, res);                              // Set ICRn value (TOP) = res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
 | 
			
		||||
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
 | 
			
		||||
  // If v is 0 or v_size (max), digitalWrite to LOW or HIGH.
 | 
			
		||||
  // Note that digitalWrite also disables PWM output for us (sets COM bit to 0)
 | 
			
		||||
  if (v == 0)
 | 
			
		||||
@@ -201,7 +201,7 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_pwm_timers() {
 | 
			
		||||
void MarlinHAL::init_pwm_timers() {
 | 
			
		||||
  // Init some timer frequencies to a default 1KHz
 | 
			
		||||
  const pin_t pwm_pin[] = {
 | 
			
		||||
    #ifdef __AVR_ATmega2560__
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
// C B A is longIn1
 | 
			
		||||
// D C B A is longIn2
 | 
			
		||||
//
 | 
			
		||||
static FORCE_INLINE uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2) {
 | 
			
		||||
FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2) {
 | 
			
		||||
  uint8_t tmp1;
 | 
			
		||||
  uint8_t tmp2;
 | 
			
		||||
  uint16_t intRes;
 | 
			
		||||
@@ -89,7 +89,7 @@ static FORCE_INLINE uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2
 | 
			
		||||
// uses:
 | 
			
		||||
// r26 to store 0
 | 
			
		||||
// r27 to store the byte 1 of the 24 bit result
 | 
			
		||||
static FORCE_INLINE uint16_t MultiU16X8toH16(uint8_t charIn1, uint16_t intIn2) {
 | 
			
		||||
FORCE_INLINE static uint16_t MultiU16X8toH16(uint8_t charIn1, uint16_t intIn2) {
 | 
			
		||||
  uint8_t tmp;
 | 
			
		||||
  uint16_t intRes;
 | 
			
		||||
  __asm__ __volatile__ (
 | 
			
		||||
 
 | 
			
		||||
@@ -109,12 +109,12 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
 | 
			
		||||
 * (otherwise, characters will be lost due to UART overflow).
 | 
			
		||||
 * Then: Stepper, Endstops, Temperature, and -finally- all others.
 | 
			
		||||
 */
 | 
			
		||||
#define HAL_timer_isr_prologue(T)
 | 
			
		||||
#define HAL_timer_isr_epilogue(T)
 | 
			
		||||
#define HAL_timer_isr_prologue(T) NOOP
 | 
			
		||||
#define HAL_timer_isr_epilogue(T) NOOP
 | 
			
		||||
 | 
			
		||||
/* 18 cycles maximum latency */
 | 
			
		||||
#ifndef HAL_STEP_TIMER_ISR
 | 
			
		||||
 | 
			
		||||
/* 18 cycles maximum latency */
 | 
			
		||||
#define HAL_STEP_TIMER_ISR() \
 | 
			
		||||
extern "C" void TIMER1_COMPA_vect() __attribute__ ((signal, naked, used, externally_visible)); \
 | 
			
		||||
extern "C" void TIMER1_COMPA_vect_bottom() asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@
 | 
			
		||||
// Public Variables
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_result;
 | 
			
		||||
uint16_t MarlinHAL::adc_result;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public functions
 | 
			
		||||
@@ -42,8 +42,7 @@ uint16_t HAL_adc_result;
 | 
			
		||||
 | 
			
		||||
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
 | 
			
		||||
 | 
			
		||||
// HAL initialization task
 | 
			
		||||
void HAL_init() {
 | 
			
		||||
void MarlinHAL::init() {
 | 
			
		||||
  // Initialize the USB stack
 | 
			
		||||
  #if ENABLED(SDSUPPORT)
 | 
			
		||||
    OUT_WRITE(SDSS, HIGH);  // Try to set SDSS inactive before any other SPI users start up
 | 
			
		||||
@@ -52,21 +51,15 @@ void HAL_init() {
 | 
			
		||||
  TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HAL idle task
 | 
			
		||||
void HAL_idletask() {
 | 
			
		||||
  // Perform USB stack housekeeping
 | 
			
		||||
  usb_task_idle();
 | 
			
		||||
void MarlinHAL::init_board() {
 | 
			
		||||
  #ifdef BOARD_INIT
 | 
			
		||||
    BOARD_INIT();
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Disable interrupts
 | 
			
		||||
void cli() { noInterrupts(); }
 | 
			
		||||
void MarlinHAL::idletask() { usb_task_idle(); } // Perform USB stack housekeeping
 | 
			
		||||
 | 
			
		||||
// Enable interrupts
 | 
			
		||||
void sei() { interrupts(); }
 | 
			
		||||
 | 
			
		||||
void HAL_clear_reset_source() { }
 | 
			
		||||
 | 
			
		||||
uint8_t HAL_get_reset_source() {
 | 
			
		||||
uint8_t MarlinHAL::get_reset_source() {
 | 
			
		||||
  switch ((RSTC->RSTC_SR >> 8) & 0x07) {
 | 
			
		||||
    case 0: return RST_POWER_ON;
 | 
			
		||||
    case 1: return RST_BACKUP;
 | 
			
		||||
@@ -77,12 +70,7 @@ uint8_t HAL_get_reset_source() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_reboot() { rstc_start_software_reset(RSTC); }
 | 
			
		||||
 | 
			
		||||
void _delay_ms(const int delay_ms) {
 | 
			
		||||
  // Todo: port for Due?
 | 
			
		||||
  delay(delay_ms);
 | 
			
		||||
}
 | 
			
		||||
void MarlinHAL::reboot() { rstc_start_software_reset(RSTC); }
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
  extern unsigned int _ebss; // end of bss section
 | 
			
		||||
@@ -94,19 +82,6 @@ int freeMemory() {
 | 
			
		||||
  return (int)&free_memory - (heap_end ?: (int)&_ebss);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t ch) {
 | 
			
		||||
  HAL_adc_result = analogRead(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_get_result() {
 | 
			
		||||
  // nop
 | 
			
		||||
  return HAL_adc_result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Forward the default serial ports
 | 
			
		||||
#if USING_HW_SERIAL0
 | 
			
		||||
  DefaultSerial1 MSerial0(false, Serial);
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,10 @@
 | 
			
		||||
 | 
			
		||||
#include "../../core/serial_hook.h"
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
 | 
			
		||||
typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
 | 
			
		||||
typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
 | 
			
		||||
@@ -97,60 +101,38 @@ extern DefaultSerial4 MSerial3;
 | 
			
		||||
#include "MarlinSerial.h"
 | 
			
		||||
#include "MarlinSerialUSB.h"
 | 
			
		||||
 | 
			
		||||
// On AVR this is in math.h?
 | 
			
		||||
#define square(x) ((x)*(x))
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Types
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
typedef int8_t pin_t;
 | 
			
		||||
 | 
			
		||||
#define SHARED_SERVOS HAS_SERVOS
 | 
			
		||||
#define HAL_SERVO_LIB Servo
 | 
			
		||||
#define SHARED_SERVOS HAS_SERVOS  // Use shared/servos.cpp
 | 
			
		||||
 | 
			
		||||
class Servo;
 | 
			
		||||
typedef Servo hal_servo_t;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Interrupts
 | 
			
		||||
//
 | 
			
		||||
#define CRITICAL_SECTION_START()  uint32_t primask = __get_PRIMASK(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (!primask) __enable_irq()
 | 
			
		||||
#define ISRS_ENABLED() (!__get_PRIMASK())
 | 
			
		||||
#define ENABLE_ISRS()  __enable_irq()
 | 
			
		||||
#define DISABLE_ISRS() __disable_irq()
 | 
			
		||||
#define sei() noInterrupts()
 | 
			
		||||
#define cli() interrupts()
 | 
			
		||||
 | 
			
		||||
void cli();                     // Disable interrupts
 | 
			
		||||
void sei();                     // Enable interrupts
 | 
			
		||||
 | 
			
		||||
void HAL_clear_reset_source();  // clear reset reason
 | 
			
		||||
uint8_t HAL_get_reset_source(); // get reset reason
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
#define CRITICAL_SECTION_START()  const bool _irqon = hal.isr_state(); hal.isr_off()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (_irqon) hal.isr_on()
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// ADC
 | 
			
		||||
//
 | 
			
		||||
extern uint16_t HAL_adc_result;     // result of last ADC conversion
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_ADC_RESOLUTION  10
 | 
			
		||||
 | 
			
		||||
#ifndef analogInputToDigitalPin
 | 
			
		||||
  #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define HAL_ANALOG_SELECT(ch)
 | 
			
		||||
 | 
			
		||||
inline void HAL_adc_init() {}//todo
 | 
			
		||||
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_ADC_RESOLUTION  10
 | 
			
		||||
#define HAL_START_ADC(ch)   HAL_adc_start_conversion(ch)
 | 
			
		||||
#define HAL_READ_ADC()      HAL_adc_result
 | 
			
		||||
#define HAL_ADC_READY()     true
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t ch);
 | 
			
		||||
uint16_t HAL_adc_get_result();
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// PWM
 | 
			
		||||
//
 | 
			
		||||
inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Pin Map
 | 
			
		||||
// Pin Mapping for M42, M43, M226
 | 
			
		||||
//
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
@@ -159,27 +141,18 @@ inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255,
 | 
			
		||||
//
 | 
			
		||||
// Tone
 | 
			
		||||
//
 | 
			
		||||
void toneInit();
 | 
			
		||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
 | 
			
		||||
void noTone(const pin_t _pin);
 | 
			
		||||
 | 
			
		||||
// Enable hooks into idle and setup for HAL
 | 
			
		||||
#define HAL_IDLETASK 1
 | 
			
		||||
void HAL_idletask();
 | 
			
		||||
void HAL_init();
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Utility functions
 | 
			
		||||
//
 | 
			
		||||
void _delay_ms(const int delay);
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
@@ -189,3 +162,69 @@ char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Return free RAM between end of heap (or end bss) and whatever is current
 | 
			
		||||
int freeMemory();
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
  static void init();       // Called early in setup()
 | 
			
		||||
  static void init_board(); // Called less early in setup()
 | 
			
		||||
  static void reboot();     // Software reset
 | 
			
		||||
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static bool isr_state() { return !__get_PRIMASK(); }
 | 
			
		||||
  static void isr_on()  { __enable_irq(); }
 | 
			
		||||
  static void isr_off() { __disable_irq(); }
 | 
			
		||||
 | 
			
		||||
  static void delay_ms(const int ms) { delay(ms); }
 | 
			
		||||
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask();
 | 
			
		||||
 | 
			
		||||
  // Reset
 | 
			
		||||
  static uint8_t get_reset_source();
 | 
			
		||||
  static void clear_reset_source() {}
 | 
			
		||||
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory() { return ::freeMemory(); }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  static uint16_t adc_result;
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init() {}
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const uint8_t ch) {}
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given channel
 | 
			
		||||
  static void adc_start(const uint8_t ch) { adc_result = analogRead(ch); }
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready() { return true; }
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static uint16_t adc_value() { return adc_result; }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * No inverting the duty cycle in this HAL.
 | 
			
		||||
   * No changing the maximum size of the provided value to enable finer PWM duty control in this HAL.
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
 | 
			
		||||
    analogWrite(pin, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -406,7 +406,7 @@ size_t MarlinSerial<Cfg>::write(const uint8_t c) {
 | 
			
		||||
    const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
 | 
			
		||||
 | 
			
		||||
    // If global interrupts are disabled (as the result of being called from an ISR)...
 | 
			
		||||
    if (!ISRS_ENABLED()) {
 | 
			
		||||
    if (!hal.isr_state()) {
 | 
			
		||||
 | 
			
		||||
      // Make room by polling if it is possible to transmit, and do so!
 | 
			
		||||
      while (i == tx_buffer.tail) {
 | 
			
		||||
@@ -454,7 +454,7 @@ void MarlinSerial<Cfg>::flushTX() {
 | 
			
		||||
    if (!_written) return;
 | 
			
		||||
 | 
			
		||||
    // If global interrupts are disabled (as the result of being called from an ISR)...
 | 
			
		||||
    if (!ISRS_ENABLED()) {
 | 
			
		||||
    if (!hal.isr_state()) {
 | 
			
		||||
 | 
			
		||||
      // Wait until everything was transmitted - We must do polling, as interrupts are disabled
 | 
			
		||||
      while (tx_buffer.head != tx_buffer.tail || !(HWUART->UART_SR & UART_SR_TXEMPTY)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
static pin_t tone_pin;
 | 
			
		||||
volatile static int32_t toggles;
 | 
			
		||||
 | 
			
		||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
 | 
			
		||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration/*=0*/) {
 | 
			
		||||
  tone_pin = _pin;
 | 
			
		||||
  toggles = 2 * frequency * duration / 1000;
 | 
			
		||||
  HAL_timer_start(MF_TIMER_TONE, 2 * frequency);
 | 
			
		||||
 
 | 
			
		||||
@@ -125,4 +125,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
 | 
			
		||||
  pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define HAL_timer_isr_epilogue(T)
 | 
			
		||||
#define HAL_timer_isr_epilogue(T) NOOP
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,7 @@
 | 
			
		||||
// Externs
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
 | 
			
		||||
portMUX_TYPE MarlinHAL::spinlock = portMUX_INITIALIZER_UNLOCKED;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Local defines
 | 
			
		||||
@@ -64,7 +64,7 @@ portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
 | 
			
		||||
// Public Variables
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_result;
 | 
			
		||||
uint16_t MarlinHAL::adc_result;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Private Variables
 | 
			
		||||
@@ -95,20 +95,22 @@ volatile int numPWMUsed = 0,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLED(USE_ESP32_EXIO)
 | 
			
		||||
 | 
			
		||||
  HardwareSerial YSerial2(2);
 | 
			
		||||
 | 
			
		||||
  void Write_EXIO(uint8_t IO, uint8_t v) {
 | 
			
		||||
    if (ISRS_ENABLED()) {
 | 
			
		||||
      DISABLE_ISRS();
 | 
			
		||||
    if (hal.isr_state()) {
 | 
			
		||||
      hal.isr_off();
 | 
			
		||||
      YSerial2.write(0x80 | (((char)v) << 5) | (IO - 100));
 | 
			
		||||
      ENABLE_ISRS();
 | 
			
		||||
      hal.isr_on();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      YSerial2.write(0x80 | (((char)v) << 5) | (IO - 100));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void HAL_init_board() {
 | 
			
		||||
void MarlinHAL::init_board() {
 | 
			
		||||
  #if ENABLED(USE_ESP32_TASK_WDT)
 | 
			
		||||
    esp_task_wdt_init(10, true);
 | 
			
		||||
  #endif
 | 
			
		||||
@@ -154,27 +156,24 @@ void HAL_init_board() {
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_idletask() {
 | 
			
		||||
void MarlinHAL::idletask() {
 | 
			
		||||
  #if BOTH(WIFISUPPORT, OTASUPPORT)
 | 
			
		||||
    OTA_handle();
 | 
			
		||||
  #endif
 | 
			
		||||
  TERN_(ESP3D_WIFISUPPORT, esp3dlib.idletask());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_clear_reset_source() { }
 | 
			
		||||
uint8_t MarlinHAL::get_reset_source() { return rtc_get_reset_reason(1); }
 | 
			
		||||
 | 
			
		||||
uint8_t HAL_get_reset_source() { return rtc_get_reset_reason(1); }
 | 
			
		||||
 | 
			
		||||
void HAL_reboot() { ESP.restart(); }
 | 
			
		||||
 | 
			
		||||
void _delay_ms(int delay_ms) { delay(delay_ms); }
 | 
			
		||||
void MarlinHAL::reboot() { ESP.restart(); }
 | 
			
		||||
 | 
			
		||||
// return free memory between end of heap (or end bss) and whatever is current
 | 
			
		||||
int freeMemory() { return ESP.getFreeHeap(); }
 | 
			
		||||
int MarlinHAL::freeMemory() { return ESP.getFreeHeap(); }
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define ADC1_CHANNEL(pin) ADC1_GPIO ## pin ## _CHANNEL
 | 
			
		||||
 | 
			
		||||
adc1_channel_t get_channel(int pin) {
 | 
			
		||||
@@ -196,7 +195,7 @@ void adc1_set_attenuation(adc1_channel_t chan, adc_atten_t atten) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init() {
 | 
			
		||||
void MarlinHAL::adc_init() {
 | 
			
		||||
  // Configure ADC
 | 
			
		||||
  adc1_config_width(ADC_WIDTH_12Bit);
 | 
			
		||||
 | 
			
		||||
@@ -228,11 +227,11 @@ void HAL_adc_init() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin) {
 | 
			
		||||
  const adc1_channel_t chan = get_channel(adc_pin);
 | 
			
		||||
void MarlinHAL::adc_start(const pin_t pin) {
 | 
			
		||||
  const adc1_channel_t chan = get_channel(pin);
 | 
			
		||||
  uint32_t mv;
 | 
			
		||||
  esp_adc_cal_get_voltage((adc_channel_t)chan, &characteristics[attenuations[chan]], &mv);
 | 
			
		||||
  HAL_adc_result = mv * 1023.0 / 3300.0;
 | 
			
		||||
  adc_result = mv * 1023.0 / 3300.0;
 | 
			
		||||
 | 
			
		||||
  // Change the attenuation level based on the new reading
 | 
			
		||||
  adc_atten_t atten;
 | 
			
		||||
 
 | 
			
		||||
@@ -49,8 +49,6 @@
 | 
			
		||||
// Defines
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
extern portMUX_TYPE spinlock;
 | 
			
		||||
 | 
			
		||||
#define MYSERIAL1 flushableSerial
 | 
			
		||||
 | 
			
		||||
#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT)
 | 
			
		||||
@@ -65,9 +63,6 @@ extern portMUX_TYPE spinlock;
 | 
			
		||||
 | 
			
		||||
#define CRITICAL_SECTION_START() portENTER_CRITICAL(&spinlock)
 | 
			
		||||
#define CRITICAL_SECTION_END()   portEXIT_CRITICAL(&spinlock)
 | 
			
		||||
#define ISRS_ENABLED() (spinlock.owner == portMUX_FREE_VAL)
 | 
			
		||||
#define ENABLE_ISRS()  if (spinlock.owner != portMUX_FREE_VAL) portEXIT_CRITICAL(&spinlock)
 | 
			
		||||
#define DISABLE_ISRS() portENTER_CRITICAL(&spinlock)
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Types
 | 
			
		||||
@@ -75,14 +70,8 @@ extern portMUX_TYPE spinlock;
 | 
			
		||||
 | 
			
		||||
typedef int16_t pin_t;
 | 
			
		||||
 | 
			
		||||
#define HAL_SERVO_LIB Servo
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public Variables
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
/** result of last ADC conversion */
 | 
			
		||||
extern uint16_t HAL_adc_result;
 | 
			
		||||
class Servo;
 | 
			
		||||
typedef Servo hal_servo_t;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public functions
 | 
			
		||||
@@ -91,59 +80,18 @@ extern uint16_t HAL_adc_result;
 | 
			
		||||
//
 | 
			
		||||
// Tone
 | 
			
		||||
//
 | 
			
		||||
void toneInit();
 | 
			
		||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
 | 
			
		||||
void noTone(const pin_t _pin);
 | 
			
		||||
 | 
			
		||||
// clear reset reason
 | 
			
		||||
void HAL_clear_reset_source();
 | 
			
		||||
 | 
			
		||||
// reset reason
 | 
			
		||||
uint8_t HAL_get_reset_source();
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
 | 
			
		||||
void _delay_ms(int delay);
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
void analogWrite(pin_t pin, int value);
 | 
			
		||||
 | 
			
		||||
// ADC
 | 
			
		||||
#define HAL_ANALOG_SELECT(pin)
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init();
 | 
			
		||||
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_ADC_RESOLUTION  10
 | 
			
		||||
#define HAL_START_ADC(pin)  HAL_adc_start_conversion(pin)
 | 
			
		||||
#define HAL_READ_ADC()      HAL_adc_result
 | 
			
		||||
#define HAL_ADC_READY()     true
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin);
 | 
			
		||||
 | 
			
		||||
// PWM
 | 
			
		||||
inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
 | 
			
		||||
 | 
			
		||||
// Pin Map
 | 
			
		||||
//
 | 
			
		||||
// Pin Mapping for M42, M43, M226
 | 
			
		||||
//
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
 | 
			
		||||
 | 
			
		||||
// Enable hooks into idle and setup for HAL
 | 
			
		||||
#define HAL_IDLETASK 1
 | 
			
		||||
#define BOARD_INIT() HAL_init_board();
 | 
			
		||||
void HAL_idletask();
 | 
			
		||||
inline void HAL_init() {}
 | 
			
		||||
void HAL_init_board();
 | 
			
		||||
 | 
			
		||||
#if ENABLED(USE_ESP32_EXIO)
 | 
			
		||||
  void Write_EXIO(uint8_t IO, uint8_t v);
 | 
			
		||||
#endif
 | 
			
		||||
@@ -188,3 +136,85 @@ FORCE_INLINE static void DELAY_CYCLES(uint32_t x) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
void _delay_ms(const int ms);
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_ADC_RESOLUTION  10
 | 
			
		||||
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
  static void init() {}  // Called early in setup()
 | 
			
		||||
  static void init_board();     // Called less early in setup()
 | 
			
		||||
  static void reboot();         // Restart the firmware
 | 
			
		||||
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static portMUX_TYPE spinlock;
 | 
			
		||||
  static bool isr_state() { return spinlock.owner == portMUX_FREE_VAL; }
 | 
			
		||||
  static void isr_on()  { if (spinlock.owner != portMUX_FREE_VAL) portEXIT_CRITICAL(&spinlock); }
 | 
			
		||||
  static void isr_off() { portENTER_CRITICAL(&spinlock); }
 | 
			
		||||
 | 
			
		||||
  static void delay_ms(const int ms) { _delay_ms(ms); }
 | 
			
		||||
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask();
 | 
			
		||||
 | 
			
		||||
  // Reset
 | 
			
		||||
  static uint8_t get_reset_source();
 | 
			
		||||
  static void clear_reset_source() {}
 | 
			
		||||
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory();
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  static uint16_t adc_result;
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init();
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const pin_t pin) {}
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given channel
 | 
			
		||||
  static void adc_start(const pin_t pin);
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready() { return true; }
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static uint16_t adc_value() { return adc_result; }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * No inverting the duty cycle in this HAL.
 | 
			
		||||
   * No changing the maximum size of the provided value to enable finer PWM duty control in this HAL.
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
 | 
			
		||||
    analogWrite(pin, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
static pin_t tone_pin;
 | 
			
		||||
volatile static int32_t toggles;
 | 
			
		||||
 | 
			
		||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
 | 
			
		||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration/*=0*/) {
 | 
			
		||||
  tone_pin = _pin;
 | 
			
		||||
  toggles = 2 * frequency * duration / 1000;
 | 
			
		||||
  HAL_timer_start(MF_TIMER_TONE, 2 * frequency);
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,7 @@ void IRAM_ATTR timer_isr(void *para) {
 | 
			
		||||
 * @param timer_num timer number to initialize
 | 
			
		||||
 * @param frequency frequency of the timer
 | 
			
		||||
 */
 | 
			
		||||
void HAL_timer_start(const uint8_t timer_num, uint32_t frequency) {
 | 
			
		||||
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
 | 
			
		||||
  const tTimerConfig timer = timer_config[timer_num];
 | 
			
		||||
 | 
			
		||||
  timer_config_t config;
 | 
			
		||||
 
 | 
			
		||||
@@ -127,7 +127,7 @@ extern const tTimerConfig timer_config[];
 | 
			
		||||
// Public functions
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void HAL_timer_start (const uint8_t timer_num, uint32_t frequency);
 | 
			
		||||
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
 | 
			
		||||
void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t count);
 | 
			
		||||
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num);
 | 
			
		||||
hal_timer_t HAL_timer_get_count(const uint8_t timer_num);
 | 
			
		||||
@@ -136,5 +136,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num);
 | 
			
		||||
void HAL_timer_disable_interrupt(const uint8_t timer_num);
 | 
			
		||||
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
 | 
			
		||||
 | 
			
		||||
#define HAL_timer_isr_prologue(T)
 | 
			
		||||
#define HAL_timer_isr_epilogue(T)
 | 
			
		||||
#define HAL_timer_isr_prologue(T) NOOP
 | 
			
		||||
#define HAL_timer_isr_epilogue(T) NOOP
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,10 @@
 | 
			
		||||
#include "../../inc/MarlinConfig.h"
 | 
			
		||||
#include "../shared/Delay.h"
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
MSerialT usb_serial(TERN0(EMERGENCY_PARSER, true));
 | 
			
		||||
 | 
			
		||||
// U8glib required functions
 | 
			
		||||
@@ -37,42 +41,21 @@ extern "C" {
 | 
			
		||||
//************************//
 | 
			
		||||
 | 
			
		||||
// return free heap space
 | 
			
		||||
int freeMemory() {
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
int freeMemory() { return 0; }
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init() {
 | 
			
		||||
uint8_t MarlinHAL::active_ch = 0;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_adc_enable_channel(const uint8_t ch) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t active_ch = 0;
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t ch) {
 | 
			
		||||
  active_ch = ch;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool HAL_adc_finished() {
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_get_result() {
 | 
			
		||||
  pin_t pin = analogInputToDigitalPin(active_ch);
 | 
			
		||||
uint16_t MarlinHAL::adc_value() {
 | 
			
		||||
  const pin_t pin = analogInputToDigitalPin(active_ch);
 | 
			
		||||
  if (!VALID_PIN(pin)) return 0;
 | 
			
		||||
  uint16_t data = ((Gpio::get(pin) >> 2) & 0x3FF);
 | 
			
		||||
  const uint16_t data = ((Gpio::get(pin) >> 2) & 0x3FF);
 | 
			
		||||
  return data;    // return 10bit value as Marlin expects
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_pwm_init() {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_reboot() { /* Reset the application state and GPIO */ }
 | 
			
		||||
void MarlinHAL::reboot() { /* Reset the application state and GPIO */ }
 | 
			
		||||
 | 
			
		||||
#endif // __PLAT_LINUX__
 | 
			
		||||
 
 | 
			
		||||
@@ -21,34 +21,13 @@
 | 
			
		||||
 */
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define CPU_32_BIT
 | 
			
		||||
 | 
			
		||||
#define F_CPU 100000000UL
 | 
			
		||||
#define SystemCoreClock F_CPU
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
#undef min
 | 
			
		||||
#undef max
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
void _printf (const  char *format, ...);
 | 
			
		||||
void _putc(uint8_t c);
 | 
			
		||||
uint8_t _getc();
 | 
			
		||||
 | 
			
		||||
//extern "C" volatile uint32_t _millis;
 | 
			
		||||
 | 
			
		||||
//arduino: Print.h
 | 
			
		||||
#define DEC 10
 | 
			
		||||
#define HEX 16
 | 
			
		||||
#define OCT  8
 | 
			
		||||
#define BIN  2
 | 
			
		||||
//arduino: binary.h (weird defines)
 | 
			
		||||
#define B01 1
 | 
			
		||||
#define B10 2
 | 
			
		||||
 | 
			
		||||
#include "hardware/Clock.h"
 | 
			
		||||
 | 
			
		||||
#include "../shared/Marduino.h"
 | 
			
		||||
@@ -58,27 +37,56 @@ uint8_t _getc();
 | 
			
		||||
#include "watchdog.h"
 | 
			
		||||
#include "serial.h"
 | 
			
		||||
 | 
			
		||||
#define SHARED_SERVOS HAS_SERVOS
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Defines
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
extern MSerialT usb_serial;
 | 
			
		||||
#define MYSERIAL1 usb_serial
 | 
			
		||||
#define CPU_32_BIT
 | 
			
		||||
#define SHARED_SERVOS HAS_SERVOS  // Use shared/servos.cpp
 | 
			
		||||
 | 
			
		||||
#define F_CPU 100000000UL
 | 
			
		||||
#define SystemCoreClock F_CPU
 | 
			
		||||
 | 
			
		||||
#define DELAY_CYCLES(x) Clock::delayCycles(x)
 | 
			
		||||
 | 
			
		||||
#define CPU_ST7920_DELAY_1 600
 | 
			
		||||
#define CPU_ST7920_DELAY_2 750
 | 
			
		||||
#define CPU_ST7920_DELAY_3 750
 | 
			
		||||
 | 
			
		||||
void _printf(const  char *format, ...);
 | 
			
		||||
void _putc(uint8_t c);
 | 
			
		||||
uint8_t _getc();
 | 
			
		||||
 | 
			
		||||
//arduino: Print.h
 | 
			
		||||
#define DEC 10
 | 
			
		||||
#define HEX 16
 | 
			
		||||
#define OCT  8
 | 
			
		||||
#define BIN  2
 | 
			
		||||
//arduino: binary.h (weird defines)
 | 
			
		||||
#define B01 1
 | 
			
		||||
#define B10 2
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
extern MSerialT usb_serial;
 | 
			
		||||
#define MYSERIAL1 usb_serial
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Interrupts
 | 
			
		||||
//
 | 
			
		||||
#define CRITICAL_SECTION_START()
 | 
			
		||||
#define CRITICAL_SECTION_END()
 | 
			
		||||
#define ISRS_ENABLED()
 | 
			
		||||
#define ENABLE_ISRS()
 | 
			
		||||
#define DISABLE_ISRS()
 | 
			
		||||
 | 
			
		||||
inline void HAL_init() {}
 | 
			
		||||
// ADC
 | 
			
		||||
#define HAL_ADC_VREF           5.0
 | 
			
		||||
#define HAL_ADC_RESOLUTION    10
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
// Utility functions
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
@@ -88,29 +96,66 @@ int freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
// ADC
 | 
			
		||||
#define HAL_ADC_VREF           5.0
 | 
			
		||||
#define HAL_ADC_RESOLUTION    10
 | 
			
		||||
#define HAL_ANALOG_SELECT(ch) HAL_adc_enable_channel(ch)
 | 
			
		||||
#define HAL_START_ADC(ch)     HAL_adc_start_conversion(ch)
 | 
			
		||||
#define HAL_READ_ADC()        HAL_adc_get_result()
 | 
			
		||||
#define HAL_ADC_READY()       true
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init();
 | 
			
		||||
void HAL_adc_enable_channel(const uint8_t ch);
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t ch);
 | 
			
		||||
uint16_t HAL_adc_get_result();
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
// PWM
 | 
			
		||||
inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
// Reset source
 | 
			
		||||
inline void HAL_clear_reset_source(void) {}
 | 
			
		||||
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
 | 
			
		||||
  static void init() {}        // Called early in setup()
 | 
			
		||||
  static void init_board() {}  // Called less early in setup()
 | 
			
		||||
  static void reboot();               // Reset the application state and GPIO
 | 
			
		||||
 | 
			
		||||
void HAL_reboot(); // Reset the application state and GPIO
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static bool isr_state() { return true; }
 | 
			
		||||
  static void isr_on()  {}
 | 
			
		||||
  static void isr_off() {}
 | 
			
		||||
 | 
			
		||||
/* ---------------- Delay in cycles */
 | 
			
		||||
FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {
 | 
			
		||||
  Clock::delayCycles(x);
 | 
			
		||||
}
 | 
			
		||||
  static void delay_ms(const int ms) { _delay_ms(ms); }
 | 
			
		||||
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask() {}
 | 
			
		||||
 | 
			
		||||
  // Reset
 | 
			
		||||
  static constexpr uint8_t reset_reason = RST_POWER_ON;
 | 
			
		||||
  static uint8_t get_reset_source() { return reset_reason; }
 | 
			
		||||
  static void clear_reset_source() {}
 | 
			
		||||
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory() { return ::freeMemory(); }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  static uint8_t active_ch;
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init() {}
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const uint8_t) {}
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given channel
 | 
			
		||||
  static void adc_start(const uint8_t ch) { active_ch = ch; }
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready() { return true; }
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static uint16_t adc_value();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * No option to change the resolution or invert the duty cycle.
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
 | 
			
		||||
    analogWrite(pin, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static void set_pwm_frequency(const pin_t, int) {}
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -31,9 +31,7 @@ void cli() { } // Disable
 | 
			
		||||
void sei() { } // Enable
 | 
			
		||||
 | 
			
		||||
// Time functions
 | 
			
		||||
void _delay_ms(const int delay_ms) {
 | 
			
		||||
  delay(delay_ms);
 | 
			
		||||
}
 | 
			
		||||
void _delay_ms(const int ms) { delay(ms); }
 | 
			
		||||
 | 
			
		||||
uint32_t millis() {
 | 
			
		||||
  return (uint32_t)Clock::millis();
 | 
			
		||||
 
 | 
			
		||||
@@ -59,10 +59,9 @@ typedef uint8_t byte;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define sq(v) ((v) * (v))
 | 
			
		||||
#define square(v) sq(v)
 | 
			
		||||
#define constrain(value, arg_min, arg_max) ((value) < (arg_min) ? (arg_min) :((value) > (arg_max) ? (arg_max) : (value)))
 | 
			
		||||
 | 
			
		||||
//Interrupts
 | 
			
		||||
// Interrupts
 | 
			
		||||
void cli(); // Disable
 | 
			
		||||
void sei(); // Enable
 | 
			
		||||
void attachInterrupt(uint32_t pin, void (*callback)(), uint32_t mode);
 | 
			
		||||
@@ -74,8 +73,8 @@ extern "C" {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Time functions
 | 
			
		||||
extern "C" void delay(const int milis);
 | 
			
		||||
void _delay_ms(const int delay);
 | 
			
		||||
extern "C" void delay(const int ms);
 | 
			
		||||
void _delay_ms(const int ms);
 | 
			
		||||
void delayMicroseconds(unsigned long);
 | 
			
		||||
uint32_t millis();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -92,5 +92,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num);
 | 
			
		||||
void HAL_timer_disable_interrupt(const uint8_t timer_num);
 | 
			
		||||
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
 | 
			
		||||
 | 
			
		||||
#define HAL_timer_isr_prologue(T)
 | 
			
		||||
#define HAL_timer_isr_epilogue(T)
 | 
			
		||||
#define HAL_timer_isr_prologue(T) NOOP
 | 
			
		||||
#define HAL_timer_isr_epilogue(T) NOOP
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
 | 
			
		||||
DefaultSerial1 USBSerial(false, UsbSerial);
 | 
			
		||||
 | 
			
		||||
uint32_t HAL_adc_reading = 0;
 | 
			
		||||
uint32_t MarlinHAL::adc_result = 0;
 | 
			
		||||
 | 
			
		||||
// U8glib required functions
 | 
			
		||||
extern "C" {
 | 
			
		||||
@@ -41,8 +41,6 @@ extern "C" {
 | 
			
		||||
  void u8g_Delay(uint16_t val)       { delay(val); }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//************************//
 | 
			
		||||
 | 
			
		||||
// return free heap space
 | 
			
		||||
int freeMemory() {
 | 
			
		||||
  char stack_end;
 | 
			
		||||
@@ -54,7 +52,27 @@ int freeMemory() {
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// scan command line for code
 | 
			
		||||
void MarlinHAL::reboot() { NVIC_SystemReset(); }
 | 
			
		||||
 | 
			
		||||
uint8_t MarlinHAL::get_reset_source() {
 | 
			
		||||
  #if ENABLED(USE_WATCHDOG)
 | 
			
		||||
    if (watchdog_timed_out()) return RST_WATCHDOG;
 | 
			
		||||
  #endif
 | 
			
		||||
  return RST_POWER_ON;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::clear_reset_source() {
 | 
			
		||||
  TERN_(USE_WATCHDOG, watchdog_clear_timeout_flag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void flashFirmware(const int16_t) {
 | 
			
		||||
  delay(500);          // Give OS time to disconnect
 | 
			
		||||
  USB_Connect(false);  // USB clear connection
 | 
			
		||||
  delay(1000);         // Give OS time to notice
 | 
			
		||||
  hal.reboot();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// For M42/M43, scan command line for pin code
 | 
			
		||||
//   return index into pin map array if found and the pin is valid.
 | 
			
		||||
//   return dval if not found or not a valid pin.
 | 
			
		||||
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
 | 
			
		||||
@@ -63,24 +81,4 @@ int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
 | 
			
		||||
  return ind > -1 ? ind : dval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void flashFirmware(const int16_t) {
 | 
			
		||||
  delay(500);          // Give OS time to disconnect
 | 
			
		||||
  USB_Connect(false);  // USB clear connection
 | 
			
		||||
  delay(1000);         // Give OS time to notice
 | 
			
		||||
  HAL_reboot();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_clear_reset_source(void) {
 | 
			
		||||
  TERN_(USE_WATCHDOG, watchdog_clear_timeout_flag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t HAL_get_reset_source(void) {
 | 
			
		||||
  #if ENABLED(USE_WATCHDOG)
 | 
			
		||||
    if (watchdog_timed_out()) return RST_WATCHDOG;
 | 
			
		||||
  #endif
 | 
			
		||||
  return RST_POWER_ON;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_reboot() { NVIC_SystemReset(); }
 | 
			
		||||
 | 
			
		||||
#endif // TARGET_LPC1768
 | 
			
		||||
 
 | 
			
		||||
@@ -28,8 +28,6 @@
 | 
			
		||||
 | 
			
		||||
#define CPU_32_BIT
 | 
			
		||||
 | 
			
		||||
void HAL_init();
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
@@ -47,12 +45,9 @@ extern "C" volatile uint32_t _millis;
 | 
			
		||||
#include <pinmapping.h>
 | 
			
		||||
#include <CDCSerial.h>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Default graphical display delays
 | 
			
		||||
//
 | 
			
		||||
#define CPU_ST7920_DELAY_1 600
 | 
			
		||||
#define CPU_ST7920_DELAY_2 750
 | 
			
		||||
#define CPU_ST7920_DELAY_3 750
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
typedef ForwardSerial1Class< decltype(UsbSerial) > DefaultSerial1;
 | 
			
		||||
extern DefaultSerial1 USBSerial;
 | 
			
		||||
@@ -114,26 +109,12 @@ extern DefaultSerial1 USBSerial;
 | 
			
		||||
//
 | 
			
		||||
// Interrupts
 | 
			
		||||
//
 | 
			
		||||
#define CRITICAL_SECTION_START()  uint32_t primask = __get_PRIMASK(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (!primask) __enable_irq()
 | 
			
		||||
#define ISRS_ENABLED() (!__get_PRIMASK())
 | 
			
		||||
#define ENABLE_ISRS()  __enable_irq()
 | 
			
		||||
#define DISABLE_ISRS() __disable_irq()
 | 
			
		||||
 | 
			
		||||
#define CRITICAL_SECTION_START()  const bool irqon = !__get_PRIMASK(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (irqon) __enable_irq()
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Utility functions
 | 
			
		||||
//
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// ADC API
 | 
			
		||||
// ADC
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#define ADC_MEDIAN_FILTER_SIZE (23) // Higher values increase step delay (phase shift),
 | 
			
		||||
@@ -152,20 +133,9 @@ int freeMemory();
 | 
			
		||||
#define HAL_ADC_RESOLUTION     12   // 15 bit maximum, raw temperature is stored as int16_t
 | 
			
		||||
#define HAL_ADC_FILTERED            // Disable oversampling done in Marlin as ADC values already filtered in HAL
 | 
			
		||||
 | 
			
		||||
using FilteredADC = LPC176x::ADC<ADC_LOWPASS_K_VALUE, ADC_MEDIAN_FILTER_SIZE>;
 | 
			
		||||
extern uint32_t HAL_adc_reading;
 | 
			
		||||
[[gnu::always_inline]] inline void HAL_adc_start_conversion(const pin_t pin) {
 | 
			
		||||
  HAL_adc_reading = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
 | 
			
		||||
}
 | 
			
		||||
[[gnu::always_inline]] inline uint16_t HAL_adc_get_result() {
 | 
			
		||||
  return HAL_adc_reading;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define HAL_adc_init()
 | 
			
		||||
#define HAL_ANALOG_SELECT(pin) FilteredADC::enable_channel(pin)
 | 
			
		||||
#define HAL_START_ADC(pin)     HAL_adc_start_conversion(pin)
 | 
			
		||||
#define HAL_READ_ADC()         HAL_adc_get_result()
 | 
			
		||||
#define HAL_ADC_READY()        (true)
 | 
			
		||||
//
 | 
			
		||||
// Pin Mapping for M42, M43, M226
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Test whether the pin is valid
 | 
			
		||||
constexpr bool VALID_PIN(const pin_t pin) {
 | 
			
		||||
@@ -192,32 +162,101 @@ int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
 | 
			
		||||
// P0.6 thru P0.9 are for the onboard SD card
 | 
			
		||||
#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09,
 | 
			
		||||
 | 
			
		||||
#define HAL_IDLETASK 1
 | 
			
		||||
void HAL_idletask();
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Defines
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define PLATFORM_M997_SUPPORT
 | 
			
		||||
void flashFirmware(const int16_t);
 | 
			
		||||
 | 
			
		||||
#define HAL_CAN_SET_PWM_FREQ   // This HAL supports PWM Frequency adjustment
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * set_pwm_frequency
 | 
			
		||||
// Default graphical display delays
 | 
			
		||||
#define CPU_ST7920_DELAY_1 600
 | 
			
		||||
#define CPU_ST7920_DELAY_2 750
 | 
			
		||||
#define CPU_ST7920_DELAY_3 750
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
  static void init();                 // Called early in setup()
 | 
			
		||||
  static void init_board() {}  // Called less early in setup()
 | 
			
		||||
  static void reboot();               // Restart the firmware from 0x0
 | 
			
		||||
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static bool isr_state() { return !__get_PRIMASK(); }
 | 
			
		||||
  static void isr_on()  { __enable_irq(); }
 | 
			
		||||
  static void isr_off() { __disable_irq(); }
 | 
			
		||||
 | 
			
		||||
  static void delay_ms(const int ms) { _delay_ms(ms); }
 | 
			
		||||
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask();
 | 
			
		||||
 | 
			
		||||
  // Reset
 | 
			
		||||
  static uint8_t get_reset_source();
 | 
			
		||||
  static void clear_reset_source();
 | 
			
		||||
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory() { return ::freeMemory(); }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  using FilteredADC = LPC176x::ADC<ADC_LOWPASS_K_VALUE, ADC_MEDIAN_FILTER_SIZE>;
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init() {}
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const pin_t pin) {
 | 
			
		||||
    FilteredADC::enable_channel(pin);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given pin
 | 
			
		||||
  static uint32_t adc_result;
 | 
			
		||||
  static void adc_start(const pin_t pin) {
 | 
			
		||||
    adc_result = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready() { return true; }
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static uint16_t adc_value() { return uint16_t(adc_result); }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * Optionally invert the duty cycle [default = false]
 | 
			
		||||
   * Optionally change the scale of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the frequency of the timer corresponding to the provided pin
 | 
			
		||||
 *  All Hardware PWM pins run at the same frequency and all
 | 
			
		||||
 *  Software PWM pins run at the same frequency
 | 
			
		||||
   * All Hardware PWM pins will run at the same frequency and
 | 
			
		||||
   * All Software PWM pins will run at the same frequency
 | 
			
		||||
   */
 | 
			
		||||
void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * set_pwm_duty
 | 
			
		||||
 *  Set the PWM duty cycle of the provided pin to the provided value
 | 
			
		||||
 *  Optionally allows inverting the duty cycle [default = false]
 | 
			
		||||
 *  Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
 */
 | 
			
		||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
 | 
			
		||||
 | 
			
		||||
// Reset source
 | 
			
		||||
void HAL_clear_reset_source(void);
 | 
			
		||||
uint8_t HAL_get_reset_source(void);
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
  static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -65,4 +65,5 @@ class libServo: public Servo {
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define HAL_SERVO_LIB libServo
 | 
			
		||||
class libServo;
 | 
			
		||||
typedef libServo hal_servo_t;
 | 
			
		||||
 
 | 
			
		||||
@@ -21,16 +21,16 @@
 | 
			
		||||
 */
 | 
			
		||||
#ifdef TARGET_LPC1768
 | 
			
		||||
 | 
			
		||||
#include "../../inc/MarlinConfigPre.h"
 | 
			
		||||
#include "../../inc/MarlinConfig.h"
 | 
			
		||||
#include <pwm.h>
 | 
			
		||||
 | 
			
		||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
 | 
			
		||||
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
 | 
			
		||||
  if (!LPC176x::pin_is_valid(pin)) return;
 | 
			
		||||
  if (LPC176x::pwm_attach_pin(pin))
 | 
			
		||||
    LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);  // map 1-254 onto PWM range
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
 | 
			
		||||
void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
 | 
			
		||||
  LPC176x::pwm_set_frequency(pin, f_desired);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@ void SysTick_Callback() { disk_timerproc(); }
 | 
			
		||||
 | 
			
		||||
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
 | 
			
		||||
 | 
			
		||||
void HAL_init() {
 | 
			
		||||
void MarlinHAL::init() {
 | 
			
		||||
 | 
			
		||||
  // Init LEDs
 | 
			
		||||
  #if PIN_EXISTS(LED)
 | 
			
		||||
@@ -130,7 +130,7 @@ void HAL_init() {
 | 
			
		||||
  const millis_t usb_timeout = millis() + 2000;
 | 
			
		||||
  while (!USB_Configuration && PENDING(millis(), usb_timeout)) {
 | 
			
		||||
    delay(50);
 | 
			
		||||
    HAL_idletask();
 | 
			
		||||
    idletask();
 | 
			
		||||
    #if PIN_EXISTS(LED)
 | 
			
		||||
      TOGGLE(LED_PIN);     // Flash quickly during USB initialization
 | 
			
		||||
    #endif
 | 
			
		||||
@@ -142,7 +142,7 @@ void HAL_init() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HAL idle task
 | 
			
		||||
void HAL_idletask() {
 | 
			
		||||
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.
 | 
			
		||||
 
 | 
			
		||||
@@ -170,4 +170,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define HAL_timer_isr_epilogue(T)
 | 
			
		||||
#define HAL_timer_isr_epilogue(T) NOOP
 | 
			
		||||
 
 | 
			
		||||
@@ -21,18 +21,10 @@
 | 
			
		||||
 */
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define CPU_32_BIT
 | 
			
		||||
#define HAL_IDLETASK
 | 
			
		||||
void HAL_idletask();
 | 
			
		||||
 | 
			
		||||
#define F_CPU 100000000
 | 
			
		||||
#define SystemCoreClock F_CPU
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
#undef min
 | 
			
		||||
#undef max
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include "pinmapping.h"
 | 
			
		||||
 | 
			
		||||
@@ -40,8 +32,6 @@ void _printf (const  char *format, ...);
 | 
			
		||||
void _putc(uint8_t c);
 | 
			
		||||
uint8_t _getc();
 | 
			
		||||
 | 
			
		||||
//extern "C" volatile uint32_t _millis;
 | 
			
		||||
 | 
			
		||||
//arduino: Print.h
 | 
			
		||||
#define DEC 10
 | 
			
		||||
#define HEX 16
 | 
			
		||||
@@ -58,7 +48,23 @@ uint8_t _getc();
 | 
			
		||||
#include "watchdog.h"
 | 
			
		||||
#include "serial.h"
 | 
			
		||||
 | 
			
		||||
#define SHARED_SERVOS HAS_SERVOS
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Defines
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define CPU_32_BIT
 | 
			
		||||
#define SHARED_SERVOS HAS_SERVOS  // Use shared/servos.cpp
 | 
			
		||||
 | 
			
		||||
#define F_CPU 100000000
 | 
			
		||||
#define SystemCoreClock F_CPU
 | 
			
		||||
 | 
			
		||||
#define CPU_ST7920_DELAY_1 600
 | 
			
		||||
#define CPU_ST7920_DELAY_2 750
 | 
			
		||||
#define CPU_ST7920_DELAY_3 750
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
extern MSerialT serial_stream_0;
 | 
			
		||||
extern MSerialT serial_stream_1;
 | 
			
		||||
@@ -98,49 +104,19 @@ extern MSerialT serial_stream_3;
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define CPU_ST7920_DELAY_1 600
 | 
			
		||||
#define CPU_ST7920_DELAY_2 750
 | 
			
		||||
#define CPU_ST7920_DELAY_3 750
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Interrupts
 | 
			
		||||
//
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define CRITICAL_SECTION_START()
 | 
			
		||||
#define CRITICAL_SECTION_END()
 | 
			
		||||
#define ISRS_ENABLED()
 | 
			
		||||
#define ENABLE_ISRS()
 | 
			
		||||
#define DISABLE_ISRS()
 | 
			
		||||
 | 
			
		||||
inline void HAL_init() {}
 | 
			
		||||
 | 
			
		||||
// Utility functions
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
int freeMemory();
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define HAL_ADC_VREF           5.0
 | 
			
		||||
#define HAL_ADC_RESOLUTION    10
 | 
			
		||||
#define HAL_ANALOG_SELECT(ch) HAL_adc_enable_channel(ch)
 | 
			
		||||
#define HAL_START_ADC(ch)     HAL_adc_start_conversion(ch)
 | 
			
		||||
#define HAL_READ_ADC()        HAL_adc_get_result()
 | 
			
		||||
#define HAL_ADC_READY()       true
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init();
 | 
			
		||||
void HAL_adc_enable_channel(const uint8_t ch);
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t ch);
 | 
			
		||||
uint16_t HAL_adc_get_result();
 | 
			
		||||
 | 
			
		||||
// PWM
 | 
			
		||||
inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
 | 
			
		||||
 | 
			
		||||
// Reset source
 | 
			
		||||
inline void HAL_clear_reset_source(void) {}
 | 
			
		||||
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
 | 
			
		||||
/* ---------------- Delay in cycles */
 | 
			
		||||
 | 
			
		||||
@@ -159,29 +135,22 @@ constexpr inline std::size_t strlen_constexpr(const char* str) {
 | 
			
		||||
  // https://github.com/gcc-mirror/gcc/blob/5c7634a0e5f202935aa6c11b6ea953b8bf80a00a/libstdc%2B%2B-v3/include/bits/char_traits.h#L329
 | 
			
		||||
  if (str != nullptr) {
 | 
			
		||||
    std::size_t i = 0;
 | 
			
		||||
    while (str[i] != '\0') {
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (str[i] != '\0') ++i;
 | 
			
		||||
    return i;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr inline int strncmp_constexpr(const char* lhs, const char* rhs, std::size_t count) {
 | 
			
		||||
  // https://github.com/gcc-mirror/gcc/blob/13b9cbfc32fe3ac4c81c4dd9c42d141c8fb95db4/libstdc%2B%2B-v3/include/bits/char_traits.h#L655
 | 
			
		||||
  if (lhs == nullptr || rhs == nullptr) {
 | 
			
		||||
  if (lhs == nullptr || rhs == nullptr)
 | 
			
		||||
    return rhs != nullptr ? -1 : 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (std::size_t i = 0; i < count; ++i) {
 | 
			
		||||
    if (lhs[i] != rhs[i]) {
 | 
			
		||||
  for (std::size_t i = 0; i < count; ++i)
 | 
			
		||||
    if (lhs[i] != rhs[i])
 | 
			
		||||
      return lhs[i] < rhs[i] ? -1 : 1;
 | 
			
		||||
    } else if (lhs[i] == '\0') {
 | 
			
		||||
    else if (lhs[i] == '\0')
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -193,14 +162,11 @@ constexpr inline const char* strstr_constexpr(const char* str, const char* targe
 | 
			
		||||
    do {
 | 
			
		||||
      char sc = {};
 | 
			
		||||
      do {
 | 
			
		||||
        if ((sc = *str++) == '\0') {
 | 
			
		||||
          return nullptr;
 | 
			
		||||
        }
 | 
			
		||||
        if ((sc = *str++) == '\0') return nullptr;
 | 
			
		||||
      } while (sc != c);
 | 
			
		||||
    } while (strncmp_constexpr(str, target, len) != 0);
 | 
			
		||||
    --str;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -211,12 +177,87 @@ constexpr inline char* strstr_constexpr(char* str, const char* target) {
 | 
			
		||||
    do {
 | 
			
		||||
      char sc = {};
 | 
			
		||||
      do {
 | 
			
		||||
        if ((sc = *str++) == '\0') {
 | 
			
		||||
          return nullptr;
 | 
			
		||||
        }
 | 
			
		||||
        if ((sc = *str++) == '\0') return nullptr;
 | 
			
		||||
      } while (sc != c);
 | 
			
		||||
    } while (strncmp_constexpr(str, target, len) != 0);
 | 
			
		||||
    --str;
 | 
			
		||||
  }
 | 
			
		||||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
  static void init() {}        // Called early in setup()
 | 
			
		||||
  static void init_board() {}  // Called less early in setup()
 | 
			
		||||
  static void reboot();        // Restart the firmware from 0x0
 | 
			
		||||
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static bool isr_state() { return true; }
 | 
			
		||||
  static void isr_on()  {}
 | 
			
		||||
  static void isr_off() {}
 | 
			
		||||
 | 
			
		||||
  static void delay_ms(const int ms) { _delay_ms(ms); }
 | 
			
		||||
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask();
 | 
			
		||||
 | 
			
		||||
  // Reset
 | 
			
		||||
  static constexpr uint8_t reset_reason = RST_POWER_ON;
 | 
			
		||||
  static uint8_t get_reset_source() { return reset_reason; }
 | 
			
		||||
  static void clear_reset_source() {}
 | 
			
		||||
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory() { return ::freeMemory(); }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  static uint8_t active_ch;
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init();
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const uint8_t ch);
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given channel
 | 
			
		||||
  static void adc_start(const uint8_t ch);
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready();
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static uint16_t adc_value();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * No option to invert the duty cycle [default = false]
 | 
			
		||||
   * No option to change the scale of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
 | 
			
		||||
    analogWrite(pin, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -87,5 +87,5 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num);
 | 
			
		||||
void HAL_timer_disable_interrupt(const uint8_t timer_num);
 | 
			
		||||
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
 | 
			
		||||
 | 
			
		||||
#define HAL_timer_isr_prologue(T)
 | 
			
		||||
#define HAL_timer_isr_epilogue(T)
 | 
			
		||||
#define HAL_timer_isr_prologue(T) NOOP
 | 
			
		||||
#define HAL_timer_isr_epilogue(T) NOOP
 | 
			
		||||
 
 | 
			
		||||
@@ -42,10 +42,6 @@
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Local defines
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#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)
 | 
			
		||||
@@ -61,6 +57,9 @@
 | 
			
		||||
#define GET_BOARD_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 IS_ADC_REQUIRED(n) ( \
 | 
			
		||||
     GET_TEMP_0_ADC() == n || GET_TEMP_1_ADC() == n || GET_TEMP_2_ADC() == n || GET_TEMP_3_ADC() == n \
 | 
			
		||||
@@ -72,6 +71,7 @@
 | 
			
		||||
  || GET_BOARD_ADC() == n \
 | 
			
		||||
  || GET_FILAMENT_WIDTH_ADC() == n \
 | 
			
		||||
  || GET_BUTTONS_ADC() == n \
 | 
			
		||||
  || GET_JOY_ADC_X() == n || GET_JOY_ADC_Y() == n || GET_JOY_ADC_Z() == n \
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
#if IS_ADC_REQUIRED(0)
 | 
			
		||||
@@ -91,6 +91,118 @@
 | 
			
		||||
  #define DMA_IS_REQUIRED 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum ADCIndex {
 | 
			
		||||
  #if GET_TEMP_0_ADC() == 0
 | 
			
		||||
    TEMP_0,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_1_ADC() == 0
 | 
			
		||||
    TEMP_1,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_2_ADC() == 0
 | 
			
		||||
    TEMP_2,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_3_ADC() == 0
 | 
			
		||||
    TEMP_3,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_4_ADC() == 0
 | 
			
		||||
    TEMP_4,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_5_ADC() == 0
 | 
			
		||||
    TEMP_5,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_6_ADC() == 0
 | 
			
		||||
    TEMP_6,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_7_ADC() == 0
 | 
			
		||||
    TEMP_7,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_BED_ADC() == 0
 | 
			
		||||
    TEMP_BED,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_CHAMBER_ADC() == 0
 | 
			
		||||
    TEMP_CHAMBER,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_PROBE_ADC() == 0
 | 
			
		||||
    TEMP_PROBE,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_COOLER_ADC() == 0
 | 
			
		||||
    TEMP_COOLER,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_BOARD_ADC() == 0
 | 
			
		||||
    TEMP_BOARD,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_FILAMENT_WIDTH_ADC() == 0
 | 
			
		||||
    FILWIDTH,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_BUTTONS_ADC() == 0
 | 
			
		||||
    ADC_KEY,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_JOY_ADC_X() == 0
 | 
			
		||||
    JOY_X,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_JOY_ADC_Y() == 0
 | 
			
		||||
    JOY_Y,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_JOY_ADC_Z() == 0
 | 
			
		||||
    JOY_Z,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_0_ADC() == 1
 | 
			
		||||
    TEMP_0,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_1_ADC() == 1
 | 
			
		||||
    TEMP_1,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_2_ADC() == 1
 | 
			
		||||
    TEMP_2,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_3_ADC() == 1
 | 
			
		||||
    TEMP_3,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_4_ADC() == 1
 | 
			
		||||
    TEMP_4,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_5_ADC() == 1
 | 
			
		||||
    TEMP_5,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_6_ADC() == 1
 | 
			
		||||
    TEMP_6,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_TEMP_7_ADC() == 1
 | 
			
		||||
    TEMP_7,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_BED_ADC() == 1
 | 
			
		||||
    TEMP_BED,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_CHAMBER_ADC() == 1
 | 
			
		||||
    TEMP_CHAMBER,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_PROBE_ADC() == 1
 | 
			
		||||
    TEMP_PROBE,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_COOLER_ADC() == 1
 | 
			
		||||
    TEMP_COOLER,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_BOARD_ADC() == 1
 | 
			
		||||
    TEMP_BOARD,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_FILAMENT_WIDTH_ADC() == 1
 | 
			
		||||
    FILWIDTH,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_BUTTONS_ADC() == 1
 | 
			
		||||
    ADC_KEY,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_JOY_ADC_X() == 1
 | 
			
		||||
    JOY_X,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_JOY_ADC_Y() == 1
 | 
			
		||||
    JOY_Y,
 | 
			
		||||
  #endif
 | 
			
		||||
  #if GET_JOY_ADC_Z() == 1
 | 
			
		||||
    JOY_Z,
 | 
			
		||||
  #endif
 | 
			
		||||
  ADC_COUNT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Types
 | 
			
		||||
// ------------------------
 | 
			
		||||
@@ -108,12 +220,10 @@
 | 
			
		||||
// Private Variables
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_result;
 | 
			
		||||
 | 
			
		||||
#if ADC_IS_REQUIRED
 | 
			
		||||
 | 
			
		||||
  // Pins used by ADC inputs. Order must be ADC0 inputs first then ADC1
 | 
			
		||||
  const uint8_t adc_pins[] = {
 | 
			
		||||
  static constexpr uint8_t adc_pins[ADC_COUNT] = {
 | 
			
		||||
    // ADC0 pins
 | 
			
		||||
    #if GET_TEMP_0_ADC() == 0
 | 
			
		||||
      TEMP_0_PIN,
 | 
			
		||||
@@ -160,6 +270,15 @@ uint16_t HAL_adc_result;
 | 
			
		||||
    #if GET_BUTTONS_ADC() == 0
 | 
			
		||||
      ADC_KEYPAD_PIN,
 | 
			
		||||
    #endif
 | 
			
		||||
    #if GET_JOY_ADC_X() == 0
 | 
			
		||||
      JOY_X_PIN,
 | 
			
		||||
    #endif
 | 
			
		||||
    #if GET_JOY_ADC_Y() == 0
 | 
			
		||||
      JOY_Y_PIN,
 | 
			
		||||
    #endif
 | 
			
		||||
    #if GET_JOY_ADC_Z() == 0
 | 
			
		||||
      JOY_Z_PIN,
 | 
			
		||||
    #endif
 | 
			
		||||
    // ADC1 pins
 | 
			
		||||
    #if GET_TEMP_0_ADC() == 1
 | 
			
		||||
      TEMP_0_PIN,
 | 
			
		||||
@@ -206,15 +325,23 @@ uint16_t HAL_adc_result;
 | 
			
		||||
    #if GET_BUTTONS_ADC() == 1
 | 
			
		||||
      ADC_KEYPAD_PIN,
 | 
			
		||||
    #endif
 | 
			
		||||
    #if GET_JOY_ADC_X() == 1
 | 
			
		||||
      JOY_X_PIN,
 | 
			
		||||
    #endif
 | 
			
		||||
    #if GET_JOY_ADC_Y() == 1
 | 
			
		||||
      JOY_Y_PIN,
 | 
			
		||||
    #endif
 | 
			
		||||
    #if GET_JOY_ADC_Z() == 1
 | 
			
		||||
      JOY_Z_PIN,
 | 
			
		||||
    #endif
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  uint16_t HAL_adc_results[COUNT(adc_pins)];
 | 
			
		||||
  static uint16_t adc_results[ADC_COUNT];
 | 
			
		||||
 | 
			
		||||
  #if ADC0_IS_REQUIRED
 | 
			
		||||
    Adafruit_ZeroDMA adc0DMAProgram,
 | 
			
		||||
                     adc0DMARead;
 | 
			
		||||
    Adafruit_ZeroDMA adc0DMAProgram, adc0DMARead;
 | 
			
		||||
 | 
			
		||||
    const HAL_DMA_DAC_Registers adc0_dma_regs_list[] = {
 | 
			
		||||
    static constexpr HAL_DMA_DAC_Registers adc0_dma_regs_list[ADC_COUNT] = {
 | 
			
		||||
      #if GET_TEMP_0_ADC() == 0
 | 
			
		||||
        { PIN_TO_INPUTCTRL(TEMP_0_PIN) },
 | 
			
		||||
      #endif
 | 
			
		||||
@@ -260,16 +387,24 @@ uint16_t HAL_adc_result;
 | 
			
		||||
      #if GET_BUTTONS_ADC() == 0
 | 
			
		||||
        { PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) },
 | 
			
		||||
      #endif
 | 
			
		||||
      #if GET_JOY_ADC_X() == 0
 | 
			
		||||
        { PIN_TO_INPUTCTRL(JOY_X_PIN) },
 | 
			
		||||
      #endif
 | 
			
		||||
      #if GET_JOY_ADC_Y() == 0
 | 
			
		||||
        { PIN_TO_INPUTCTRL(JOY_Y_PIN) },
 | 
			
		||||
      #endif
 | 
			
		||||
      #if GET_JOY_ADC_Z() == 0
 | 
			
		||||
        { PIN_TO_INPUTCTRL(JOY_Z_PIN) },
 | 
			
		||||
      #endif
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    #define ADC0_AINCOUNT   COUNT(adc0_dma_regs_list)
 | 
			
		||||
  #endif // ADC0_IS_REQUIRED
 | 
			
		||||
 | 
			
		||||
  #if ADC1_IS_REQUIRED
 | 
			
		||||
    Adafruit_ZeroDMA adc1DMAProgram,
 | 
			
		||||
                     adc1DMARead;
 | 
			
		||||
    Adafruit_ZeroDMA adc1DMAProgram, adc1DMARead;
 | 
			
		||||
 | 
			
		||||
    const HAL_DMA_DAC_Registers adc1_dma_regs_list[] = {
 | 
			
		||||
    static constexpr HAL_DMA_DAC_Registers adc1_dma_regs_list[ADC_COUNT] = {
 | 
			
		||||
      #if GET_TEMP_0_ADC() == 1
 | 
			
		||||
        { PIN_TO_INPUTCTRL(TEMP_0_PIN) },
 | 
			
		||||
      #endif
 | 
			
		||||
@@ -315,6 +450,15 @@ uint16_t HAL_adc_result;
 | 
			
		||||
      #if GET_BUTTONS_ADC() == 1
 | 
			
		||||
        { PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) },
 | 
			
		||||
      #endif
 | 
			
		||||
      #if GET_JOY_ADC_X() == 1
 | 
			
		||||
        { PIN_TO_INPUTCTRL(JOY_X_PIN) },
 | 
			
		||||
      #endif
 | 
			
		||||
      #if GET_JOY_ADC_Y() == 1
 | 
			
		||||
        { PIN_TO_INPUTCTRL(JOY_Y_PIN) },
 | 
			
		||||
      #endif
 | 
			
		||||
      #if GET_JOY_ADC_Z() == 1
 | 
			
		||||
        { PIN_TO_INPUTCTRL(JOY_Z_PIN) },
 | 
			
		||||
      #endif
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    #define ADC1_AINCOUNT   COUNT(adc1_dma_regs_list)
 | 
			
		||||
@@ -326,9 +470,10 @@ uint16_t HAL_adc_result;
 | 
			
		||||
// Private functions
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#if DMA_IS_REQUIRED
 | 
			
		||||
void MarlinHAL::dma_init() {
 | 
			
		||||
 | 
			
		||||
  #if DMA_IS_REQUIRED
 | 
			
		||||
 | 
			
		||||
  void dma_init() {
 | 
			
		||||
    DmacDescriptor *descriptor;
 | 
			
		||||
 | 
			
		||||
    #if ADC0_IS_REQUIRED
 | 
			
		||||
@@ -357,7 +502,7 @@ uint16_t HAL_adc_result;
 | 
			
		||||
      if (adc0DMARead.allocate() == DMA_STATUS_OK) {
 | 
			
		||||
        adc0DMARead.addDescriptor(
 | 
			
		||||
          (void *)&ADC0->RESULT.reg,          // SRC
 | 
			
		||||
          &HAL_adc_results,                   // DEST
 | 
			
		||||
          &adc_results,                       // DEST
 | 
			
		||||
          ADC0_AINCOUNT,                      // CNT
 | 
			
		||||
          DMA_BEAT_SIZE_HWORD,
 | 
			
		||||
          false,                              // SRCINC
 | 
			
		||||
@@ -394,7 +539,7 @@ uint16_t HAL_adc_result;
 | 
			
		||||
      if (adc1DMARead.allocate() == DMA_STATUS_OK) {
 | 
			
		||||
        adc1DMARead.addDescriptor(
 | 
			
		||||
          (void *)&ADC1->RESULT.reg,          // SRC
 | 
			
		||||
          &HAL_adc_results[ADC0_AINCOUNT],    // DEST
 | 
			
		||||
          &adc_results[ADC0_AINCOUNT],        // DEST
 | 
			
		||||
          ADC1_AINCOUNT,                      // CNT
 | 
			
		||||
          DMA_BEAT_SIZE_HWORD,
 | 
			
		||||
          false,                              // SRCINC
 | 
			
		||||
@@ -407,16 +552,16 @@ uint16_t HAL_adc_result;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    DMAC->PRICTRL0.bit.RRLVLEN0 = true;                         // Activate round robin for DMA channels required by ADCs
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#endif // DMA_IS_REQUIRED
 | 
			
		||||
  #endif // DMA_IS_REQUIRED
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public functions
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
// HAL initialization task
 | 
			
		||||
void HAL_init() {
 | 
			
		||||
void MarlinHAL::init() {
 | 
			
		||||
  TERN_(DMA_IS_REQUIRED, dma_init());
 | 
			
		||||
  #if ENABLED(SDSUPPORT)
 | 
			
		||||
    #if SD_CONNECTION_IS(ONBOARD) && PIN_EXISTS(SD_DETECT)
 | 
			
		||||
@@ -426,17 +571,9 @@ void HAL_init() {
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HAL idle task
 | 
			
		||||
/*
 | 
			
		||||
void HAL_idletask() {
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
void HAL_clear_reset_source() { }
 | 
			
		||||
 | 
			
		||||
#pragma push_macro("WDT")
 | 
			
		||||
#undef WDT    // Required to be able to use '.bit.WDT'. Compiler wrongly replace struct field with WDT define
 | 
			
		||||
uint8_t HAL_get_reset_source() {
 | 
			
		||||
uint8_t MarlinHAL::get_reset_source() {
 | 
			
		||||
  RSTC_RCAUSE_Type resetCause;
 | 
			
		||||
 | 
			
		||||
  resetCause.reg = REG_RSTC_RCAUSE;
 | 
			
		||||
@@ -450,7 +587,7 @@ uint8_t HAL_get_reset_source() {
 | 
			
		||||
}
 | 
			
		||||
#pragma pop_macro("WDT")
 | 
			
		||||
 | 
			
		||||
void HAL_reboot() { NVIC_SystemReset(); }
 | 
			
		||||
void MarlinHAL::reboot() { NVIC_SystemReset(); }
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
  void * _sbrk(int incr);
 | 
			
		||||
@@ -468,9 +605,11 @@ int freeMemory() {
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init() {
 | 
			
		||||
uint16_t MarlinHAL::adc_result;
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::adc_init() {
 | 
			
		||||
  #if ADC_IS_REQUIRED
 | 
			
		||||
    memset(HAL_adc_results, 0xFF, sizeof(HAL_adc_results));                 // Fill result with invalid values
 | 
			
		||||
    memset(adc_results, 0xFF, sizeof(adc_results));                         // Fill result with invalid values
 | 
			
		||||
 | 
			
		||||
    LOOP_L_N(pi, COUNT(adc_pins))
 | 
			
		||||
      pinPeripheral(adc_pins[pi], PIO_ANALOG);
 | 
			
		||||
@@ -505,17 +644,13 @@ void HAL_adc_init() {
 | 
			
		||||
  #endif // ADC_IS_REQUIRED
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin) {
 | 
			
		||||
void MarlinHAL::adc_start(const pin_t pin) {
 | 
			
		||||
  #if ADC_IS_REQUIRED
 | 
			
		||||
    LOOP_L_N(pi, COUNT(adc_pins)) {
 | 
			
		||||
      if (adc_pin == adc_pins[pi]) {
 | 
			
		||||
        HAL_adc_result = HAL_adc_results[pi];
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    LOOP_L_N(pi, COUNT(adc_pins))
 | 
			
		||||
      if (pin == adc_pins[pi]) { adc_result = adc_results[pi]; return; }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  HAL_adc_result = 0xFFFF;
 | 
			
		||||
  adc_result = 0xFFFF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // __SAMD51__
 | 
			
		||||
 
 | 
			
		||||
@@ -89,51 +89,30 @@
 | 
			
		||||
 | 
			
		||||
typedef int8_t pin_t;
 | 
			
		||||
 | 
			
		||||
#define SHARED_SERVOS HAS_SERVOS
 | 
			
		||||
#define HAL_SERVO_LIB Servo
 | 
			
		||||
#define SHARED_SERVOS HAS_SERVOS  // Use shared/servos.cpp
 | 
			
		||||
 | 
			
		||||
class Servo;
 | 
			
		||||
typedef Servo hal_servo_t;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Interrupts
 | 
			
		||||
//
 | 
			
		||||
#define CRITICAL_SECTION_START()  uint32_t primask = __get_PRIMASK(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (!primask) __enable_irq()
 | 
			
		||||
#define ISRS_ENABLED() (!__get_PRIMASK())
 | 
			
		||||
#define ENABLE_ISRS()  __enable_irq()
 | 
			
		||||
#define DISABLE_ISRS() __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_START()  const bool irqon = !__get_PRIMASK(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (irqon) __enable_irq()
 | 
			
		||||
 | 
			
		||||
#define cli() __disable_irq() // Disable interrupts
 | 
			
		||||
#define sei() __enable_irq()  // Enable interrupts
 | 
			
		||||
 | 
			
		||||
void HAL_clear_reset_source();  // clear reset reason
 | 
			
		||||
uint8_t HAL_get_reset_source(); // get reset reason
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// ADC
 | 
			
		||||
//
 | 
			
		||||
extern uint16_t HAL_adc_result;     // Most recent ADC conversion
 | 
			
		||||
 | 
			
		||||
#define HAL_ANALOG_SELECT(pin)
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init();
 | 
			
		||||
 | 
			
		||||
//#define HAL_ADC_FILTERED          // Disable Marlin's oversampling. The HAL filters ADC values.
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_ADC_RESOLUTION  10      // ... 12
 | 
			
		||||
#define HAL_START_ADC(pin)  HAL_adc_start_conversion(pin)
 | 
			
		||||
#define HAL_READ_ADC()      HAL_adc_result
 | 
			
		||||
#define HAL_ADC_READY()     true
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin);
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// PWM
 | 
			
		||||
//
 | 
			
		||||
inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Pin Map
 | 
			
		||||
// Pin Mapping for M42, M43, M226
 | 
			
		||||
//
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
@@ -142,35 +121,93 @@ inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255,
 | 
			
		||||
//
 | 
			
		||||
// Tone
 | 
			
		||||
//
 | 
			
		||||
void toneInit();
 | 
			
		||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
 | 
			
		||||
void noTone(const pin_t _pin);
 | 
			
		||||
 | 
			
		||||
// Enable hooks into idle and setup for HAL
 | 
			
		||||
void HAL_init();
 | 
			
		||||
/*
 | 
			
		||||
#define HAL_IDLETASK 1
 | 
			
		||||
void HAL_idletask();
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Utility functions
 | 
			
		||||
//
 | 
			
		||||
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
  extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s);
 | 
			
		||||
 | 
			
		||||
extern "C" int freeMemory();
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
  static void init();          // Called early in setup()
 | 
			
		||||
  static void init_board() {}  // Called less early in setup()
 | 
			
		||||
  static void reboot();        // Restart the firmware from 0x0
 | 
			
		||||
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static bool isr_state() { return !__get_PRIMASK(); }
 | 
			
		||||
  static void isr_on()  { sei(); }
 | 
			
		||||
  static void isr_off() { cli(); }
 | 
			
		||||
 | 
			
		||||
  static void delay_ms(const int ms) { delay(ms); }
 | 
			
		||||
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask() {}
 | 
			
		||||
 | 
			
		||||
  // Reset
 | 
			
		||||
  static uint8_t get_reset_source();
 | 
			
		||||
  static void clear_reset_source() {}
 | 
			
		||||
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory() { return ::freeMemory(); }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  static uint16_t adc_result;
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init();
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const uint8_t ch) {}
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given channel
 | 
			
		||||
  static void adc_start(const pin_t pin);
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready() { return true; }
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static uint16_t adc_value() { return adc_result; }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * No option to invert the duty cycle [default = false]
 | 
			
		||||
   * No option to change the scale of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
 | 
			
		||||
    analogWrite(pin, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  static void dma_init();
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -53,16 +53,18 @@
 | 
			
		||||
// Public Variables
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_result;
 | 
			
		||||
uint16_t MarlinHAL::adc_result;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public functions
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
 | 
			
		||||
#if ENABLED(POSTMORTEM_DEBUGGING)
 | 
			
		||||
  extern void install_min_serial();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// HAL initialization task
 | 
			
		||||
void HAL_init() {
 | 
			
		||||
void MarlinHAL::init() {
 | 
			
		||||
  // Ensure F_CPU is a constant expression.
 | 
			
		||||
  // If the compiler breaks here, it means that delay code that should compute at compile time will not work.
 | 
			
		||||
  // So better safe than sorry here.
 | 
			
		||||
@@ -103,7 +105,7 @@ void HAL_init() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HAL idle task
 | 
			
		||||
void HAL_idletask() {
 | 
			
		||||
void MarlinHAL::idletask() {
 | 
			
		||||
  #if HAS_SHARED_MEDIA
 | 
			
		||||
    // Stm32duino currently doesn't have a "loop/idle" method
 | 
			
		||||
    CDC_resume_receive();
 | 
			
		||||
@@ -111,9 +113,9 @@ void HAL_idletask() {
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }
 | 
			
		||||
void MarlinHAL::reboot() { NVIC_SystemReset(); }
 | 
			
		||||
 | 
			
		||||
uint8_t HAL_get_reset_source() {
 | 
			
		||||
uint8_t MarlinHAL::get_reset_source() {
 | 
			
		||||
  return
 | 
			
		||||
    #ifdef RCC_FLAG_IWDGRST // Some sources may not exist...
 | 
			
		||||
      RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST)  ? RST_WATCHDOG :
 | 
			
		||||
@@ -137,24 +139,14 @@ uint8_t HAL_get_reset_source() {
 | 
			
		||||
  ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_reboot() { NVIC_SystemReset(); }
 | 
			
		||||
 | 
			
		||||
void _delay_ms(const int delay_ms) { delay(delay_ms); }
 | 
			
		||||
void MarlinHAL::clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
  extern unsigned int _ebss; // end of bss section
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
// TODO: Make sure this doesn't cause any delay
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRead(adc_pin); }
 | 
			
		||||
uint16_t HAL_adc_get_result() { return HAL_adc_result; }
 | 
			
		||||
 | 
			
		||||
// Reset the system to initiate a firmware flash
 | 
			
		||||
WEAK void flashFirmware(const int16_t) { HAL_reboot(); }
 | 
			
		||||
WEAK void flashFirmware(const int16_t) { hal.reboot(); }
 | 
			
		||||
 | 
			
		||||
// Maple Compatibility
 | 
			
		||||
volatile uint32_t systick_uptime_millis = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -44,9 +44,9 @@
 | 
			
		||||
#define CPU_ST7920_DELAY_2  40
 | 
			
		||||
#define CPU_ST7920_DELAY_3 340
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Serial Ports
 | 
			
		||||
//
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
#ifdef USBCON
 | 
			
		||||
  #include <USBSerial.h>
 | 
			
		||||
  #include "../../core/serial_hook.h"
 | 
			
		||||
@@ -115,17 +115,14 @@
 | 
			
		||||
  #define analogInputToDigitalPin(p) (p)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CRITICAL_SECTION_START()  uint32_t primask = __get_PRIMASK(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (!primask) __enable_irq()
 | 
			
		||||
#define ISRS_ENABLED() (!__get_PRIMASK())
 | 
			
		||||
#define ENABLE_ISRS()  __enable_irq()
 | 
			
		||||
#define DISABLE_ISRS() __disable_irq()
 | 
			
		||||
//
 | 
			
		||||
// Interrupts
 | 
			
		||||
//
 | 
			
		||||
#define CRITICAL_SECTION_START()  const bool irqon = !__get_PRIMASK(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (irqon) __enable_irq()
 | 
			
		||||
#define cli() __disable_irq()
 | 
			
		||||
#define sei() __enable_irq()
 | 
			
		||||
 | 
			
		||||
// On AVR this is in math.h?
 | 
			
		||||
#define square(x) ((x)*(x))
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Types
 | 
			
		||||
// ------------------------
 | 
			
		||||
@@ -136,56 +133,14 @@
 | 
			
		||||
  typedef int16_t pin_t;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define HAL_SERVO_LIB libServo
 | 
			
		||||
class libServo;
 | 
			
		||||
typedef libServo hal_servo_t;
 | 
			
		||||
#define PAUSE_SERVO_OUTPUT() libServo::pause_all_servos()
 | 
			
		||||
#define RESUME_SERVO_OUTPUT() libServo::resume_all_servos()
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public Variables
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
// result of last ADC conversion
 | 
			
		||||
extern uint16_t HAL_adc_result;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public functions
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
// Memory related
 | 
			
		||||
#define __bss_end __bss_end__
 | 
			
		||||
 | 
			
		||||
// Enable hooks into  setup for HAL
 | 
			
		||||
void HAL_init();
 | 
			
		||||
#define HAL_IDLETASK 1
 | 
			
		||||
void HAL_idletask();
 | 
			
		||||
 | 
			
		||||
// Clear reset reason
 | 
			
		||||
void HAL_clear_reset_source();
 | 
			
		||||
 | 
			
		||||
// Reset reason
 | 
			
		||||
uint8_t HAL_get_reset_source();
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
 | 
			
		||||
void _delay_ms(const int delay);
 | 
			
		||||
 | 
			
		||||
extern "C" char* _sbrk(int incr);
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
 | 
			
		||||
static inline int freeMemory() {
 | 
			
		||||
  volatile char top;
 | 
			
		||||
  return &top - reinterpret_cast<char*>(_sbrk(0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// ADC
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#ifdef ADC_RESOLUTION
 | 
			
		||||
  #define HAL_ADC_RESOLUTION ADC_RESOLUTION
 | 
			
		||||
@@ -194,16 +149,10 @@ static inline int freeMemory() {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_START_ADC(pin)  HAL_adc_start_conversion(pin)
 | 
			
		||||
#define HAL_READ_ADC()      HAL_adc_result
 | 
			
		||||
#define HAL_ADC_READY()     true
 | 
			
		||||
 | 
			
		||||
inline void HAL_adc_init() { analogReadResolution(HAL_ADC_RESOLUTION); }
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin);
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_get_result();
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Pin Mapping for M42, M43, M226
 | 
			
		||||
//
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
 | 
			
		||||
@@ -226,17 +175,92 @@ extern volatile uint32_t systick_uptime_millis;
 | 
			
		||||
 | 
			
		||||
#define HAL_CAN_SET_PWM_FREQ   // This HAL supports PWM Frequency adjustment
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * set_pwm_frequency
 | 
			
		||||
 *  Set the frequency of the timer corresponding to the provided pin
 | 
			
		||||
 *  All Timer PWM pins run at the same frequency
 | 
			
		||||
 */
 | 
			
		||||
void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * set_pwm_duty
 | 
			
		||||
 *  Set the PWM duty cycle of the provided pin to the provided value
 | 
			
		||||
 *  Optionally allows inverting the duty cycle [default = false]
 | 
			
		||||
 *  Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
// Memory related
 | 
			
		||||
#define __bss_end __bss_end__
 | 
			
		||||
 | 
			
		||||
extern "C" char* _sbrk(int incr);
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static inline int freeMemory() {
 | 
			
		||||
  volatile char top;
 | 
			
		||||
  return &top - reinterpret_cast<char*>(_sbrk(0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
  static void init();                 // Called early in setup()
 | 
			
		||||
  static void init_board() {}  // Called less early in setup()
 | 
			
		||||
  static void reboot();               // Restart the firmware from 0x0
 | 
			
		||||
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static bool isr_state() { return !__get_PRIMASK(); }
 | 
			
		||||
  static void isr_on()  { sei(); }
 | 
			
		||||
  static void isr_off() { cli(); }
 | 
			
		||||
 | 
			
		||||
  static void delay_ms(const int ms) { delay(ms); }
 | 
			
		||||
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask();
 | 
			
		||||
 | 
			
		||||
  // Reset
 | 
			
		||||
  static uint8_t get_reset_source();
 | 
			
		||||
  static void clear_reset_source();
 | 
			
		||||
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory() { return ::freeMemory(); }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  static uint16_t adc_result;
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init() {
 | 
			
		||||
    analogReadResolution(HAL_ADC_RESOLUTION);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const pin_t pin) { pinMode(pin, INPUT); }
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given channel
 | 
			
		||||
  static void adc_start(const pin_t pin) { adc_result = analogRead(pin); }
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready() { return true; }
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static uint16_t adc_value() { return adc_result; }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * Optionally invert the duty cycle [default = false]
 | 
			
		||||
   * Optionally change the maximum size of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
   */
 | 
			
		||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the frequency of the timer for the given pin.
 | 
			
		||||
   * All Timer PWM pins run at the same frequency.
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -102,9 +102,9 @@ static SPISettings spiConfig;
 | 
			
		||||
 | 
			
		||||
  // Soft SPI receive byte
 | 
			
		||||
  uint8_t spiRec() {
 | 
			
		||||
    DISABLE_ISRS();                                               // No interrupts during byte receive
 | 
			
		||||
    hal.isr_off();                                                // No interrupts during byte receive
 | 
			
		||||
    const uint8_t data = HAL_SPI_STM32_SpiTransfer_Mode_3(0xFF);
 | 
			
		||||
    ENABLE_ISRS();                                                // Enable interrupts
 | 
			
		||||
    hal.isr_on();                                                 // Enable interrupts
 | 
			
		||||
    return data;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -116,9 +116,9 @@ static SPISettings spiConfig;
 | 
			
		||||
 | 
			
		||||
  // Soft SPI send byte
 | 
			
		||||
  void spiSend(uint8_t data) {
 | 
			
		||||
    DISABLE_ISRS();                         // No interrupts during byte send
 | 
			
		||||
    hal.isr_off();                          // No interrupts during byte send
 | 
			
		||||
    HAL_SPI_STM32_SpiTransfer_Mode_3(data); // Don't care what is received
 | 
			
		||||
    ENABLE_ISRS();                          // Enable interrupts
 | 
			
		||||
    hal.isr_on();                           // Enable interrupts
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Soft SPI send block
 | 
			
		||||
 
 | 
			
		||||
@@ -174,9 +174,9 @@ bool PersistentStore::access_finish() {
 | 
			
		||||
        UNLOCK_FLASH();
 | 
			
		||||
 | 
			
		||||
        TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT());
 | 
			
		||||
        DISABLE_ISRS();
 | 
			
		||||
        hal.isr_off();
 | 
			
		||||
        status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
 | 
			
		||||
        ENABLE_ISRS();
 | 
			
		||||
        hal.isr_on();
 | 
			
		||||
        TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT());
 | 
			
		||||
        if (status != HAL_OK) {
 | 
			
		||||
          DEBUG_ECHOLNPGM("HAL_FLASHEx_Erase=", status);
 | 
			
		||||
@@ -229,9 +229,9 @@ bool PersistentStore::access_finish() {
 | 
			
		||||
      // output. Servo output still glitches with interrupts disabled, but recovers after the
 | 
			
		||||
      // erase.
 | 
			
		||||
      TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT());
 | 
			
		||||
      DISABLE_ISRS();
 | 
			
		||||
      hal.isr_off();
 | 
			
		||||
      eeprom_buffer_flush();
 | 
			
		||||
      ENABLE_ISRS();
 | 
			
		||||
      hal.isr_on();
 | 
			
		||||
      TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT());
 | 
			
		||||
 | 
			
		||||
      eeprom_data_written = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@
 | 
			
		||||
// Array to support sticky frequency sets per timer
 | 
			
		||||
static uint16_t timer_freq[TIMER_NUM];
 | 
			
		||||
 | 
			
		||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
 | 
			
		||||
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
 | 
			
		||||
  const uint16_t duty = invert ? v_size - v : v;
 | 
			
		||||
  if (PWM_PIN(pin)) {
 | 
			
		||||
    const PinName pin_name = digitalPinToPinName(pin);
 | 
			
		||||
@@ -61,7 +61,7 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
 | 
			
		||||
void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
 | 
			
		||||
  if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer
 | 
			
		||||
  const PinName pin_name = digitalPinToPinName(pin);
 | 
			
		||||
  TIM_TypeDef * const Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); // Get HAL timer instance
 | 
			
		||||
 
 | 
			
		||||
@@ -115,7 +115,6 @@ const XrefInfo pin_xref[] PROGMEM = {
 | 
			
		||||
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d)  "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
 | 
			
		||||
#define PRINT_PORT(ANUM) port_print(ANUM)
 | 
			
		||||
#define DIGITAL_PIN_TO_ANALOG_PIN(ANUM) -1  // will report analog pin number in the print port routine
 | 
			
		||||
#define GET_PIN_MAP_PIN_M43(Index) pin_xref[Index].Ard_num
 | 
			
		||||
 | 
			
		||||
// x is a variable used to search pin_array
 | 
			
		||||
#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital)
 | 
			
		||||
@@ -123,6 +122,11 @@ const XrefInfo pin_xref[] PROGMEM = {
 | 
			
		||||
#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
 | 
			
		||||
#define MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Pin Mapping for M43
 | 
			
		||||
//
 | 
			
		||||
#define GET_PIN_MAP_PIN_M43(Index) pin_xref[Index].Ard_num
 | 
			
		||||
 | 
			
		||||
#ifndef M43_NEVER_TOUCH
 | 
			
		||||
  #define _M43_NEVER_TOUCH(Index) (Index >= 9 && Index <= 12) // SERIAL/USB pins: PA9(TX) PA10(RX) PA11(USB_DM) PA12(USB_DP)
 | 
			
		||||
  #ifdef KILL_PIN
 | 
			
		||||
 
 | 
			
		||||
@@ -116,5 +116,5 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const ha
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define HAL_timer_isr_prologue(T)
 | 
			
		||||
#define HAL_timer_isr_epilogue(T)
 | 
			
		||||
#define HAL_timer_isr_prologue(T) NOOP
 | 
			
		||||
#define HAL_timer_isr_epilogue(T) NOOP
 | 
			
		||||
 
 | 
			
		||||
@@ -79,7 +79,7 @@
 | 
			
		||||
#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public Variables
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#if defined(SERIAL_USB) && !HAS_SD_HOST_DRIVE
 | 
			
		||||
@@ -112,74 +112,37 @@
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_result;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Private Variables
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
STM32ADC adc(ADC1);
 | 
			
		||||
 | 
			
		||||
const uint8_t adc_pins[] = {
 | 
			
		||||
  OPTITEM(HAS_TEMP_ADC_0, TEMP_0_PIN)
 | 
			
		||||
  OPTITEM(HAS_TEMP_ADC_1, TEMP_1_PIN)
 | 
			
		||||
  OPTITEM(HAS_TEMP_ADC_2, TEMP_2_PIN)
 | 
			
		||||
  OPTITEM(HAS_TEMP_ADC_3, TEMP_3_PIN)
 | 
			
		||||
  OPTITEM(HAS_TEMP_ADC_4, TEMP_4_PIN)
 | 
			
		||||
  OPTITEM(HAS_TEMP_ADC_5, TEMP_5_PIN)
 | 
			
		||||
  OPTITEM(HAS_TEMP_ADC_6, TEMP_6_PIN)
 | 
			
		||||
  OPTITEM(HAS_TEMP_ADC_7, TEMP_7_PIN)
 | 
			
		||||
  OPTITEM(HAS_HEATED_BED, TEMP_BED_PIN)
 | 
			
		||||
  OPTITEM(HAS_TEMP_CHAMBER, TEMP_CHAMBER_PIN)
 | 
			
		||||
  OPTITEM(HAS_TEMP_ADC_PROBE, TEMP_PROBE_PIN)
 | 
			
		||||
  OPTITEM(HAS_TEMP_COOLER, TEMP_COOLER_PIN)
 | 
			
		||||
  OPTITEM(HAS_TEMP_BOARD, TEMP_BOARD_PIN)
 | 
			
		||||
  OPTITEM(FILAMENT_WIDTH_SENSOR, FILWIDTH_PIN)
 | 
			
		||||
  OPTITEM(HAS_ADC_BUTTONS, ADC_KEYPAD_PIN)
 | 
			
		||||
  OPTITEM(HAS_JOY_ADC_X, JOY_X_PIN)
 | 
			
		||||
  OPTITEM(HAS_JOY_ADC_Y, JOY_Y_PIN)
 | 
			
		||||
  OPTITEM(HAS_JOY_ADC_Z, JOY_Z_PIN)
 | 
			
		||||
  OPTITEM(POWER_MONITOR_CURRENT, POWER_MONITOR_CURRENT_PIN)
 | 
			
		||||
  OPTITEM(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN)
 | 
			
		||||
};
 | 
			
		||||
// Watch out for recursion here! Our pin_t is signed, so pass through to Arduino -> analogRead(uint8_t)
 | 
			
		||||
 | 
			
		||||
enum TempPinIndex : char {
 | 
			
		||||
  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(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_PIN_COUNT
 | 
			
		||||
};
 | 
			
		||||
uint16_t analogRead(const pin_t pin) {
 | 
			
		||||
  const bool is_analog = _GET_MODE(pin) == GPIO_INPUT_ANALOG;
 | 
			
		||||
  return is_analog ? analogRead(uint8_t(pin)) : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_results[ADC_PIN_COUNT];
 | 
			
		||||
// Wrapper to maple unprotected analogWrite
 | 
			
		||||
void analogWrite(const pin_t pin, int pwm_val8) {
 | 
			
		||||
  if (PWM_PIN(pin)) analogWrite(uint8_t(pin), 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          */
 | 
			
		||||
  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  =  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  */
 | 
			
		||||
                (PriorityGroupTmp << 8));                                     // Insert write key & priority group
 | 
			
		||||
  SCB->AIRCR =  reg_value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -187,6 +150,8 @@ static void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) {
 | 
			
		||||
// Public functions
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void flashFirmware(const int16_t) { hal.reboot(); }
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Leave PA11/PA12 intact if USBSerial is not used
 | 
			
		||||
//
 | 
			
		||||
@@ -206,7 +171,11 @@ static void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) {
 | 
			
		||||
 | 
			
		||||
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
 | 
			
		||||
 | 
			
		||||
void HAL_init() {
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::init() {
 | 
			
		||||
  NVIC_SetPriorityGrouping(0x3);
 | 
			
		||||
  #if PIN_EXISTS(LED)
 | 
			
		||||
    OUT_WRITE(LED_PIN, LOW);
 | 
			
		||||
@@ -225,7 +194,7 @@ void HAL_init() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HAL idle task
 | 
			
		||||
void HAL_idletask() {
 | 
			
		||||
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.
 | 
			
		||||
@@ -240,14 +209,7 @@ void HAL_idletask() {
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_clear_reset_source() { }
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * TODO: Check this and change or remove.
 | 
			
		||||
 */
 | 
			
		||||
uint8_t HAL_get_reset_source() { return RST_POWER_ON; }
 | 
			
		||||
 | 
			
		||||
void _delay_ms(const int delay_ms) { delay(delay_ms); }
 | 
			
		||||
void MarlinHAL::reboot() { nvic_sys_reset(); }
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
  extern unsigned int _ebss; // end of bss section
 | 
			
		||||
@@ -281,31 +243,76 @@ extern "C" {
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
//
 | 
			
		||||
// 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(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];
 | 
			
		||||
 | 
			
		||||
// Init the AD in continuous capture mode
 | 
			
		||||
void HAL_adc_init() {
 | 
			
		||||
void MarlinHAL::adc_init() {
 | 
			
		||||
  static const uint8_t adc_pins[] = {
 | 
			
		||||
    OPTITEM(HAS_TEMP_ADC_0, TEMP_0_PIN)
 | 
			
		||||
    OPTITEM(HAS_TEMP_ADC_1, TEMP_1_PIN)
 | 
			
		||||
    OPTITEM(HAS_TEMP_ADC_2, TEMP_2_PIN)
 | 
			
		||||
    OPTITEM(HAS_TEMP_ADC_3, TEMP_3_PIN)
 | 
			
		||||
    OPTITEM(HAS_TEMP_ADC_4, TEMP_4_PIN)
 | 
			
		||||
    OPTITEM(HAS_TEMP_ADC_5, TEMP_5_PIN)
 | 
			
		||||
    OPTITEM(HAS_TEMP_ADC_6, TEMP_6_PIN)
 | 
			
		||||
    OPTITEM(HAS_TEMP_ADC_7, TEMP_7_PIN)
 | 
			
		||||
    OPTITEM(HAS_HEATED_BED, TEMP_BED_PIN)
 | 
			
		||||
    OPTITEM(HAS_TEMP_CHAMBER, TEMP_CHAMBER_PIN)
 | 
			
		||||
    OPTITEM(HAS_TEMP_ADC_PROBE, TEMP_PROBE_PIN)
 | 
			
		||||
    OPTITEM(HAS_TEMP_COOLER, TEMP_COOLER_PIN)
 | 
			
		||||
    OPTITEM(HAS_TEMP_BOARD, TEMP_BOARD_PIN)
 | 
			
		||||
    OPTITEM(FILAMENT_WIDTH_SENSOR, FILWIDTH_PIN)
 | 
			
		||||
    OPTITEM(HAS_ADC_BUTTONS, ADC_KEYPAD_PIN)
 | 
			
		||||
    OPTITEM(HAS_JOY_ADC_X, JOY_X_PIN)
 | 
			
		||||
    OPTITEM(HAS_JOY_ADC_Y, JOY_Y_PIN)
 | 
			
		||||
    OPTITEM(HAS_JOY_ADC_Z, JOY_Z_PIN)
 | 
			
		||||
    OPTITEM(POWER_MONITOR_CURRENT, POWER_MONITOR_CURRENT_PIN)
 | 
			
		||||
    OPTITEM(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN)
 | 
			
		||||
  };
 | 
			
		||||
  static STM32ADC adc(ADC1);
 | 
			
		||||
  // configure the ADC
 | 
			
		||||
  adc.calibrate();
 | 
			
		||||
  #if F_CPU > 72000000
 | 
			
		||||
    adc.setSampleRate(ADC_SMPR_71_5); // 71.5 ADC cycles
 | 
			
		||||
  #else
 | 
			
		||||
    adc.setSampleRate(ADC_SMPR_41_5); // 41.5 ADC cycles
 | 
			
		||||
  #endif
 | 
			
		||||
  adc.setPins((uint8_t *)adc_pins, ADC_PIN_COUNT);
 | 
			
		||||
  adc.setDMA(HAL_adc_results, (uint16_t)ADC_PIN_COUNT, (uint32_t)(DMA_MINC_MODE | DMA_CIRC_MODE), nullptr);
 | 
			
		||||
  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);
 | 
			
		||||
  adc.setDMA(adc_results, uint16_t(ADC_COUNT), uint32_t(DMA_MINC_MODE | DMA_CIRC_MODE), nullptr);
 | 
			
		||||
  adc.setScanMode();
 | 
			
		||||
  adc.setContinuous();
 | 
			
		||||
  adc.startConversion();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin) {
 | 
			
		||||
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))
 | 
			
		||||
  //TEMP_PINS pin_index;
 | 
			
		||||
  TempPinIndex pin_index;
 | 
			
		||||
  switch (adc_pin) {
 | 
			
		||||
  ADCIndex pin_index;
 | 
			
		||||
  switch (pin) {
 | 
			
		||||
    default: return;
 | 
			
		||||
    _TCASE(HAS_TEMP_ADC_0,        TEMP_0_PIN,                TEMP_0)
 | 
			
		||||
    _TCASE(HAS_TEMP_ADC_1,        TEMP_1_PIN,                TEMP_1)
 | 
			
		||||
@@ -328,23 +335,7 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
 | 
			
		||||
    _TCASE(POWER_MONITOR_CURRENT, POWER_MONITOR_CURRENT_PIN, POWERMON_CURRENT)
 | 
			
		||||
    _TCASE(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN, POWERMON_VOLTS)
 | 
			
		||||
  }
 | 
			
		||||
  HAL_adc_result = HAL_adc_results[(int)pin_index] >> (12 - HAL_ADC_RESOLUTION); // shift out unused bits
 | 
			
		||||
  adc_result = (adc_results[(int)pin_index] & 0xFFF) >> (12 - HAL_ADC_RESOLUTION); // shift out unused bits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_get_result() { return HAL_adc_result; }
 | 
			
		||||
 | 
			
		||||
uint16_t analogRead(pin_t pin) {
 | 
			
		||||
  const bool is_analog = _GET_MODE(pin) == GPIO_INPUT_ANALOG;
 | 
			
		||||
  return is_analog ? analogRead(uint8_t(pin)) : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Wrapper to maple unprotected analogWrite
 | 
			
		||||
void analogWrite(pin_t pin, int pwm_val8) {
 | 
			
		||||
  if (PWM_PIN(pin)) analogWrite(uint8_t(pin), pwm_val8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_reboot() { nvic_sys_reset(); }
 | 
			
		||||
 | 
			
		||||
void flashFirmware(const int16_t) { HAL_reboot(); }
 | 
			
		||||
 | 
			
		||||
#endif // __STM32F1__
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,10 @@
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#ifdef SERIAL_USB
 | 
			
		||||
  typedef ForwardSerial1Class< USBSerial > DefaultSerial1;
 | 
			
		||||
  extern DefaultSerial1 MSerial0;
 | 
			
		||||
@@ -141,11 +145,6 @@
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Set interrupt grouping for this MCU
 | 
			
		||||
void HAL_init();
 | 
			
		||||
#define HAL_IDLETASK 1
 | 
			
		||||
void HAL_idletask();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * TODO: review this to return 1 for pins that are not analog input
 | 
			
		||||
 */
 | 
			
		||||
@@ -158,15 +157,7 @@ void HAL_idletask();
 | 
			
		||||
  #define NO_COMPILE_TIME_PWM
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CRITICAL_SECTION_START()  uint32_t primask = __get_primask(); (void)__iCliRetVal()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (!primask) (void)__iSeiRetVal()
 | 
			
		||||
#define ISRS_ENABLED() (!__get_primask())
 | 
			
		||||
#define ENABLE_ISRS()  ((void)__iSeiRetVal())
 | 
			
		||||
#define DISABLE_ISRS() ((void)__iCliRetVal())
 | 
			
		||||
 | 
			
		||||
// On AVR this is in math.h?
 | 
			
		||||
#define square(x) ((x)*(x))
 | 
			
		||||
 | 
			
		||||
// Reset Reason
 | 
			
		||||
#define RST_POWER_ON   1
 | 
			
		||||
#define RST_EXTERNAL   2
 | 
			
		||||
#define RST_BROWN_OUT  4
 | 
			
		||||
@@ -182,60 +173,17 @@ void HAL_idletask();
 | 
			
		||||
typedef int8_t pin_t;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public Variables
 | 
			
		||||
// Interrupts
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
// Result of last ADC conversion
 | 
			
		||||
extern uint16_t HAL_adc_result;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Public functions
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
// Disable interrupts
 | 
			
		||||
#define CRITICAL_SECTION_START()  const bool irqon = !__get_primask(); (void)__iCliRetVal()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (!irqon) (void)__iSeiRetVal()
 | 
			
		||||
#define cli() noInterrupts()
 | 
			
		||||
 | 
			
		||||
// Enable interrupts
 | 
			
		||||
#define sei() interrupts()
 | 
			
		||||
 | 
			
		||||
// Memory related
 | 
			
		||||
#define __bss_end __bss_end__
 | 
			
		||||
 | 
			
		||||
// Clear reset reason
 | 
			
		||||
void HAL_clear_reset_source();
 | 
			
		||||
 | 
			
		||||
// Reset reason
 | 
			
		||||
uint8_t HAL_get_reset_source();
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
 | 
			
		||||
void _delay_ms(const int delay);
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
extern "C" {
 | 
			
		||||
  int freeMemory();
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
extern "C" char* _sbrk(int incr);
 | 
			
		||||
 | 
			
		||||
static inline int freeMemory() {
 | 
			
		||||
  volatile char top;
 | 
			
		||||
  return &top - _sbrk(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// ------------------------
 | 
			
		||||
// ADC
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT_ANALOG);
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init();
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#ifdef ADC_RESOLUTION
 | 
			
		||||
  #define HAL_ADC_RESOLUTION ADC_RESOLUTION
 | 
			
		||||
@@ -244,16 +192,13 @@ void HAL_adc_init();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_START_ADC(pin)  HAL_adc_start_conversion(pin)
 | 
			
		||||
#define HAL_READ_ADC()      HAL_adc_result
 | 
			
		||||
#define HAL_ADC_READY()     true
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin);
 | 
			
		||||
uint16_t HAL_adc_get_result();
 | 
			
		||||
 | 
			
		||||
uint16_t analogRead(pin_t pin); // need HAL_ANALOG_SELECT() first
 | 
			
		||||
void analogWrite(pin_t pin, int pwm_val8); // PWM only! mul by 257 in maple!?
 | 
			
		||||
uint16_t analogRead(const pin_t pin); // need hal.adc_enable() first
 | 
			
		||||
void analogWrite(const pin_t pin, int pwm_val8); // PWM only! mul by 257 in maple!?
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Pin Mapping for M42, M43, M226
 | 
			
		||||
//
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
 | 
			
		||||
@@ -264,23 +209,98 @@ void analogWrite(pin_t pin, int pwm_val8); // PWM only! mul by 257 in maple!?
 | 
			
		||||
#define PLATFORM_M997_SUPPORT
 | 
			
		||||
void flashFirmware(const int16_t);
 | 
			
		||||
 | 
			
		||||
#define HAL_CAN_SET_PWM_FREQ      // This HAL supports PWM Frequency adjustment
 | 
			
		||||
#ifndef PWM_FREQUENCY
 | 
			
		||||
  #define PWM_FREQUENCY      1000 // Default PWM Frequency
 | 
			
		||||
#endif
 | 
			
		||||
#define HAL_CAN_SET_PWM_FREQ      // This HAL supports PWM Frequency adjustment
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * set_pwm_frequency
 | 
			
		||||
 *  Set the frequency of the timer corresponding to the provided pin
 | 
			
		||||
 *  All Timer PWM pins run at the same frequency
 | 
			
		||||
 */
 | 
			
		||||
void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * set_pwm_duty
 | 
			
		||||
 *  Set the PWM duty cycle of the provided pin to the provided value
 | 
			
		||||
 *  Optionally allows inverting the duty cycle [default = false]
 | 
			
		||||
 *  Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
// Memory related
 | 
			
		||||
#define __bss_end __bss_end__
 | 
			
		||||
 | 
			
		||||
void _delay_ms(const int ms);
 | 
			
		||||
 | 
			
		||||
extern "C" char* _sbrk(int incr);
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
  #pragma GCC diagnostic ignored "-Wunused-function"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static inline int freeMemory() {
 | 
			
		||||
  volatile char top;
 | 
			
		||||
  return &top - _sbrk(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
  static void init();          // Called early in setup()
 | 
			
		||||
  static void init_board() {}  // Called less early in setup()
 | 
			
		||||
  static void reboot();        // Restart the firmware from 0x0
 | 
			
		||||
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static bool isr_state() { return !__get_primask(); }
 | 
			
		||||
  static void isr_on()  { ((void)__iSeiRetVal()); }
 | 
			
		||||
  static void isr_off() { ((void)__iCliRetVal()); }
 | 
			
		||||
 | 
			
		||||
  static void delay_ms(const int ms) { delay(ms); }
 | 
			
		||||
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask();
 | 
			
		||||
 | 
			
		||||
  // Reset
 | 
			
		||||
  static uint8_t get_reset_source() { return RST_POWER_ON; }
 | 
			
		||||
  static void clear_reset_source() {}
 | 
			
		||||
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory() { return ::freeMemory(); }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  static uint16_t adc_result;
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init();
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const pin_t pin) { pinMode(pin, INPUT_ANALOG); }
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given channel
 | 
			
		||||
  static void adc_start(const pin_t pin);
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready() { return true; }
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static uint16_t adc_value() { return adc_result; }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * Optionally invert the duty cycle [default = false]
 | 
			
		||||
   * Optionally change the maximum size of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
   * The timer must be pre-configured with set_pwm_frequency() if the default frequency is not desired.
 | 
			
		||||
   */
 | 
			
		||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the frequency of the timer for the given pin.
 | 
			
		||||
   * All Timer PWM pins run at the same frequency.
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,14 @@ static const spi_pins board_spi_pins[] __FLASH__ = {
 | 
			
		||||
  static void *_spi3_this;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset.
 | 
			
		||||
 */
 | 
			
		||||
static inline void waitSpiTxEnd(spi_dev *spi_d) {
 | 
			
		||||
  while (spi_is_tx_empty(spi_d) == 0) { /* nada */ } // wait until TXE=1
 | 
			
		||||
  while (spi_is_busy(spi_d) != 0) { /* nada */ }     // wait until BSY=0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Constructor
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -414,12 +414,4 @@ private:
 | 
			
		||||
  */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset.
 | 
			
		||||
 */
 | 
			
		||||
static void waitSpiTxEnd(spi_dev *spi_d) {
 | 
			
		||||
  while (spi_is_tx_empty(spi_d) == 0) { /* nada */ } // wait until TXE=1
 | 
			
		||||
  while (spi_is_busy(spi_d) != 0) { /* nada */ }     // wait until BSY=0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern SPIClass SPI;
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,8 @@
 | 
			
		||||
#define SERVO_DEFAULT_MIN_ANGLE         0
 | 
			
		||||
#define SERVO_DEFAULT_MAX_ANGLE         180
 | 
			
		||||
 | 
			
		||||
#define HAL_SERVO_LIB libServo
 | 
			
		||||
class libServo;
 | 
			
		||||
typedef libServo hal_servo_t;
 | 
			
		||||
 | 
			
		||||
class libServo {
 | 
			
		||||
  public:
 | 
			
		||||
 
 | 
			
		||||
@@ -21,11 +21,9 @@
 | 
			
		||||
 */
 | 
			
		||||
#ifdef __STM32F1__
 | 
			
		||||
 | 
			
		||||
#include "../../inc/MarlinConfigPre.h"
 | 
			
		||||
#include "../../inc/MarlinConfig.h"
 | 
			
		||||
 | 
			
		||||
#include <pwm.h>
 | 
			
		||||
#include "HAL.h"
 | 
			
		||||
#include "timers.h"
 | 
			
		||||
 | 
			
		||||
#define NR_TIMERS TERN(STM32_XL_DENSITY, 14, 8) // Maple timers, 14 for STM32_XL_DENSITY (F/G chips), 8 for HIGH density (C D E)
 | 
			
		||||
 | 
			
		||||
@@ -38,7 +36,7 @@ inline uint8_t timer_and_index_for_pin(const pin_t pin, timer_dev **timer_ptr) {
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
 | 
			
		||||
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
 | 
			
		||||
  const uint16_t duty = invert ? v_size - v : v;
 | 
			
		||||
  if (PWM_PIN(pin)) {
 | 
			
		||||
    timer_dev *timer; UNUSED(timer);
 | 
			
		||||
@@ -54,7 +52,7 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
 | 
			
		||||
void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
 | 
			
		||||
  if (!PWM_PIN(pin)) return;                    // Don't proceed if no hardware timer
 | 
			
		||||
 | 
			
		||||
  timer_dev *timer; UNUSED(timer);
 | 
			
		||||
 
 | 
			
		||||
@@ -188,7 +188,7 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define HAL_timer_isr_epilogue(T)
 | 
			
		||||
#define HAL_timer_isr_epilogue(T) NOOP
 | 
			
		||||
 | 
			
		||||
// No command is available in framework to turn off ARPE bit, which is turned on by default in libmaple.
 | 
			
		||||
// Needed here to reset ARPE=0 for stepper timer
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,10 @@
 | 
			
		||||
 | 
			
		||||
#include <Wire.h>
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
 | 
			
		||||
#define IMPLEMENT_SERIAL(X)  _IMPLEMENT_SERIAL(X)
 | 
			
		||||
#if WITHIN(SERIAL_PORT, 0, 3)
 | 
			
		||||
@@ -40,45 +44,9 @@
 | 
			
		||||
#endif
 | 
			
		||||
USBSerialType USBSerial(false, SerialUSB);
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_result;
 | 
			
		||||
 | 
			
		||||
static const uint8_t pin2sc1a[] = {
 | 
			
		||||
    5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 0, 19, 3, 31, // 0-13, we treat them as A0-A13
 | 
			
		||||
    5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 (A0-A9)
 | 
			
		||||
    31, 31, 31, 31, 31, 31, 31, 31, 31, 31, // 24-33
 | 
			
		||||
    0+64, 19+64, 3+64, 31+64, // 34-37 (A10-A13)
 | 
			
		||||
    26, 22, 23, 27, 29, 30 // 38-43: temp. sensor, VREF_OUT, A14, bandgap, VREFH, VREFL. A14 isn't connected to anything in Teensy 3.0.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  // disable interrupts
 | 
			
		||||
  void cli() { noInterrupts(); }
 | 
			
		||||
 | 
			
		||||
  // enable interrupts
 | 
			
		||||
  void sei() { interrupts(); }
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init() {
 | 
			
		||||
  analog_init();
 | 
			
		||||
  while (ADC0_SC3 & ADC_SC3_CAL) {}; // Wait for calibration to finish
 | 
			
		||||
  NVIC_ENABLE_IRQ(IRQ_FTM1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_clear_reset_source() { }
 | 
			
		||||
 | 
			
		||||
uint8_t HAL_get_reset_source() {
 | 
			
		||||
  switch (RCM_SRS0) {
 | 
			
		||||
    case 128: return RST_POWER_ON; break;
 | 
			
		||||
    case 64: return RST_EXTERNAL; break;
 | 
			
		||||
    case 32: return RST_WATCHDOG; break;
 | 
			
		||||
    // case 8: return RST_LOSS_OF_LOCK; break;
 | 
			
		||||
    // case 4: return RST_LOSS_OF_CLOCK; break;
 | 
			
		||||
    // case 2: return RST_LOW_VOLTAGE; break;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_reboot() { _reboot_Teensyduino_(); }
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
  extern char __bss_end;
 | 
			
		||||
@@ -95,8 +63,43 @@ extern "C" {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin) { ADC0_SC1A = pin2sc1a[adc_pin]; }
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_get_result() { return ADC0_RA; }
 | 
			
		||||
void MarlinHAL::reboot() { _reboot_Teensyduino_(); }
 | 
			
		||||
 | 
			
		||||
uint8_t MarlinHAL::get_reset_source() {
 | 
			
		||||
  switch (RCM_SRS0) {
 | 
			
		||||
    case 128: return RST_POWER_ON; break;
 | 
			
		||||
    case 64: return RST_EXTERNAL; break;
 | 
			
		||||
    case 32: return RST_WATCHDOG; break;
 | 
			
		||||
    // case 8: return RST_LOSS_OF_LOCK; break;
 | 
			
		||||
    // case 4: return RST_LOSS_OF_CLOCK; break;
 | 
			
		||||
    // case 2: return RST_LOW_VOLTAGE; break;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ADC
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::adc_init() {
 | 
			
		||||
  analog_init();
 | 
			
		||||
  while (ADC0_SC3 & ADC_SC3_CAL) {}; // Wait for calibration to finish
 | 
			
		||||
  NVIC_ENABLE_IRQ(IRQ_FTM1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::adc_start(const pin_t pin) {
 | 
			
		||||
  static const uint8_t pin2sc1a[] = {
 | 
			
		||||
      5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 0, 19, 3, 31, // 0-13, we treat them as A0-A13
 | 
			
		||||
      5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 (A0-A9)
 | 
			
		||||
      31, 31, 31, 31, 31, 31, 31, 31, 31, 31, // 24-33
 | 
			
		||||
      0+64, 19+64, 3+64, 31+64, // 34-37 (A10-A13)
 | 
			
		||||
      26, 22, 23, 27, 29, 30 // 38-43: temp. sensor, VREF_OUT, A14, bandgap, VREFH, VREFL. A14 isn't connected to anything in Teensy 3.0.
 | 
			
		||||
  };
 | 
			
		||||
  ADC0_SC1A = pin2sc1a[pin];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t MarlinHAL::adc_value() { return ADC0_RA; }
 | 
			
		||||
 | 
			
		||||
#endif // __MK20DX256__
 | 
			
		||||
 
 | 
			
		||||
@@ -36,12 +36,9 @@
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#define CPU_ST7920_DELAY_1 600
 | 
			
		||||
#define CPU_ST7920_DELAY_2 750
 | 
			
		||||
#define CPU_ST7920_DELAY_3 750
 | 
			
		||||
 | 
			
		||||
//#undef MOTHERBOARD
 | 
			
		||||
//#define MOTHERBOARD BOARD_TEENSY31_32
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Defines
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define IS_32BIT_TEENSY 1
 | 
			
		||||
#define IS_TEENSY_31_32 1
 | 
			
		||||
@@ -49,6 +46,14 @@
 | 
			
		||||
  #define IS_TEENSY32 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CPU_ST7920_DELAY_1 600
 | 
			
		||||
#define CPU_ST7920_DELAY_2 750
 | 
			
		||||
#define CPU_ST7920_DELAY_3 750
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#include "../../core/serial_hook.h"
 | 
			
		||||
 | 
			
		||||
#define Serial0 Serial
 | 
			
		||||
@@ -72,31 +77,44 @@ extern USBSerialType USBSerial;
 | 
			
		||||
  #error "The required SERIAL_PORT must be from 0 to 3, or -1 for Native USB."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define HAL_SERVO_LIB libServo
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Types
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
class libServo;
 | 
			
		||||
typedef libServo hal_servo_t;
 | 
			
		||||
 | 
			
		||||
typedef int8_t pin_t;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Interrupts
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
uint32_t __get_PRIMASK(void); // CMSIS
 | 
			
		||||
#define CRITICAL_SECTION_START()  const bool irqon = !__get_PRIMASK(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (irqon) __enable_irq()
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#ifndef analogInputToDigitalPin
 | 
			
		||||
  #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CRITICAL_SECTION_START()  uint32_t primask = __get_PRIMASK(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (!primask) __enable_irq()
 | 
			
		||||
#define ISRS_ENABLED() (!__get_PRIMASK())
 | 
			
		||||
#define ENABLE_ISRS()  __enable_irq()
 | 
			
		||||
#define DISABLE_ISRS() __disable_irq()
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_ADC_RESOLUTION  10
 | 
			
		||||
 | 
			
		||||
inline void HAL_init() {}
 | 
			
		||||
//
 | 
			
		||||
// Pin Mapping for M42, M43, M226
 | 
			
		||||
//
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
 | 
			
		||||
 | 
			
		||||
// Clear the reset reason
 | 
			
		||||
void HAL_clear_reset_source();
 | 
			
		||||
 | 
			
		||||
// Get the reason for the reset
 | 
			
		||||
uint8_t HAL_get_reset_source();
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
 | 
			
		||||
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
@@ -107,27 +125,63 @@ extern "C" int freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init();
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_ADC_RESOLUTION  10
 | 
			
		||||
#define HAL_START_ADC(pin)  HAL_adc_start_conversion(pin)
 | 
			
		||||
#define HAL_READ_ADC()      HAL_adc_get_result()
 | 
			
		||||
#define HAL_ADC_READY()     true
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
#define HAL_ANALOG_SELECT(pin)
 | 
			
		||||
  static void init() {}        // Called early in setup()
 | 
			
		||||
  static void init_board() {}  // Called less early in setup()
 | 
			
		||||
  static void reboot();        // Restart the firmware from 0x0
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin);
 | 
			
		||||
uint16_t HAL_adc_get_result();
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static bool isr_state() { return !__get_PRIMASK(); }
 | 
			
		||||
  static void isr_on()  { __enable_irq(); }
 | 
			
		||||
  static void isr_off() { __disable_irq(); }
 | 
			
		||||
 | 
			
		||||
// PWM
 | 
			
		||||
  static void delay_ms(const int ms) { delay(ms); }
 | 
			
		||||
 | 
			
		||||
inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask() {}
 | 
			
		||||
 | 
			
		||||
// Pin Map
 | 
			
		||||
  // Reset
 | 
			
		||||
  static uint8_t get_reset_source();
 | 
			
		||||
  static void clear_reset_source() {}
 | 
			
		||||
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory() { return ::freeMemory(); }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init();
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const pin_t ch) {}
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given channel
 | 
			
		||||
  static void adc_start(const pin_t ch);
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready() { return true; }
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static uint16_t adc_value();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * No option to invert the duty cycle [default = false]
 | 
			
		||||
   * No option to change the scale of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
 | 
			
		||||
    analogWrite(pin, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -110,4 +110,4 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
 | 
			
		||||
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
 | 
			
		||||
 | 
			
		||||
void HAL_timer_isr_prologue(const uint8_t timer_num);
 | 
			
		||||
#define HAL_timer_isr_epilogue(T)
 | 
			
		||||
#define HAL_timer_isr_epilogue(T) NOOP
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,10 @@
 | 
			
		||||
 | 
			
		||||
#include <Wire.h>
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
 | 
			
		||||
#define IMPLEMENT_SERIAL(X)  _IMPLEMENT_SERIAL(X)
 | 
			
		||||
#if WITHIN(SERIAL_PORT, 0, 3)
 | 
			
		||||
@@ -39,54 +43,9 @@
 | 
			
		||||
 | 
			
		||||
USBSerialType USBSerial(false, SerialUSB);
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_result, HAL_adc_select;
 | 
			
		||||
 | 
			
		||||
static const uint8_t pin2sc1a[] = {
 | 
			
		||||
  5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 3, 19+128, 14+128, 15+128, // 0-13 -> A0-A13
 | 
			
		||||
  5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 are A0-A9
 | 
			
		||||
  255, 255, 255, 255, 255, 255, 255, // 24-30 are digital only
 | 
			
		||||
  14+128, 15+128, 17, 18, 4+128, 5+128, 6+128, 7+128, 17+128,  // 31-39 are A12-A20
 | 
			
		||||
  255, 255, 255, 255, 255, 255, 255, 255, 255,  // 40-48 are digital only
 | 
			
		||||
  10+128, 11+128, // 49-50 are A23-A24
 | 
			
		||||
  255, 255, 255, 255, 255, 255, 255, // 51-57 are digital only
 | 
			
		||||
  255, 255, 255, 255, 255, 255, // 58-63 (sd card pins) are digital only
 | 
			
		||||
  3, 19+128, // 64-65 are A10-A11
 | 
			
		||||
  23, 23+128,// 66-67 are A21-A22 (DAC pins)
 | 
			
		||||
  1, 1+128,  // 68-69 are A25-A26 (unused USB host port on Teensy 3.5)
 | 
			
		||||
  26,        // 70 is Temperature Sensor
 | 
			
		||||
  18+128     // 71 is Vref
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  // disable interrupts
 | 
			
		||||
  void cli() { noInterrupts(); }
 | 
			
		||||
 | 
			
		||||
  // enable interrupts
 | 
			
		||||
  void sei() { interrupts(); }
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init() {
 | 
			
		||||
  analog_init();
 | 
			
		||||
  while (ADC0_SC3 & ADC_SC3_CAL) {}; // Wait for calibration to finish
 | 
			
		||||
  while (ADC1_SC3 & ADC_SC3_CAL) {}; // Wait for calibration to finish
 | 
			
		||||
  NVIC_ENABLE_IRQ(IRQ_FTM1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_clear_reset_source() { }
 | 
			
		||||
 | 
			
		||||
uint8_t HAL_get_reset_source() {
 | 
			
		||||
  switch (RCM_SRS0) {
 | 
			
		||||
    case 128: return RST_POWER_ON; break;
 | 
			
		||||
    case 64: return RST_EXTERNAL; break;
 | 
			
		||||
    case 32: return RST_WATCHDOG; break;
 | 
			
		||||
    // case 8: return RST_LOSS_OF_LOCK; break;
 | 
			
		||||
    // case 4: return RST_LOSS_OF_CLOCK; break;
 | 
			
		||||
    // case 2: return RST_LOW_VOLTAGE; break;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_reboot() { _reboot_Teensyduino_(); }
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
  extern char __bss_end;
 | 
			
		||||
@@ -103,24 +62,69 @@ extern "C" {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin) {
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::reboot() { _reboot_Teensyduino_(); }
 | 
			
		||||
 | 
			
		||||
// Reset
 | 
			
		||||
 | 
			
		||||
uint8_t MarlinHAL::get_reset_source() {
 | 
			
		||||
  switch (RCM_SRS0) {
 | 
			
		||||
    case 128: return RST_POWER_ON; break;
 | 
			
		||||
    case 64: return RST_EXTERNAL; break;
 | 
			
		||||
    case 32: return RST_WATCHDOG; break;
 | 
			
		||||
    // case 8: return RST_LOSS_OF_LOCK; break;
 | 
			
		||||
    // case 4: return RST_LOSS_OF_CLOCK; break;
 | 
			
		||||
    // case 2: return RST_LOW_VOLTAGE; break;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ADC
 | 
			
		||||
 | 
			
		||||
int8_t MarlinHAL::adc_select;
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::adc_init() {
 | 
			
		||||
  analog_init();
 | 
			
		||||
  while (ADC0_SC3 & ADC_SC3_CAL) { /* Wait for calibration to finish */ }
 | 
			
		||||
  while (ADC1_SC3 & ADC_SC3_CAL) { /* Wait for calibration to finish */ }
 | 
			
		||||
  NVIC_ENABLE_IRQ(IRQ_FTM1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::adc_start(const pin_t adc_pin) {
 | 
			
		||||
  static const uint8_t pin2sc1a[] = {
 | 
			
		||||
    5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 3, 19+128, 14+128, 15+128, // 0-13 -> A0-A13
 | 
			
		||||
    5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 are A0-A9
 | 
			
		||||
    255, 255, 255, 255, 255, 255, 255, // 24-30 are digital only
 | 
			
		||||
    14+128, 15+128, 17, 18, 4+128, 5+128, 6+128, 7+128, 17+128,  // 31-39 are A12-A20
 | 
			
		||||
    255, 255, 255, 255, 255, 255, 255, 255, 255,  // 40-48 are digital only
 | 
			
		||||
    10+128, 11+128, // 49-50 are A23-A24
 | 
			
		||||
    255, 255, 255, 255, 255, 255, 255, // 51-57 are digital only
 | 
			
		||||
    255, 255, 255, 255, 255, 255, // 58-63 (sd card pins) are digital only
 | 
			
		||||
    3, 19+128, // 64-65 are A10-A11
 | 
			
		||||
    23, 23+128,// 66-67 are A21-A22 (DAC pins)
 | 
			
		||||
    1, 1+128,  // 68-69 are A25-A26 (unused USB host port on Teensy 3.5)
 | 
			
		||||
    26,        // 70 is Temperature Sensor
 | 
			
		||||
    18+128     // 71 is Vref
 | 
			
		||||
  };
 | 
			
		||||
  const uint16_t pin = pin2sc1a[adc_pin];
 | 
			
		||||
  if (pin == 0xFF) {
 | 
			
		||||
    // Digital only
 | 
			
		||||
    HAL_adc_select = -1;
 | 
			
		||||
    adc_select = -1;    // Digital only
 | 
			
		||||
  }
 | 
			
		||||
  else if (pin & 0x80) {
 | 
			
		||||
    HAL_adc_select = 1;
 | 
			
		||||
    adc_select = 1;
 | 
			
		||||
    ADC1_SC1A = pin & 0x7F;
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    HAL_adc_select = 0;
 | 
			
		||||
    adc_select = 0;
 | 
			
		||||
    ADC0_SC1A = pin;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_get_result() {
 | 
			
		||||
  switch (HAL_adc_select) {
 | 
			
		||||
uint16_t MarlinHAL::adc_value() {
 | 
			
		||||
  switch (adc_select) {
 | 
			
		||||
    case 0: return ADC0_RA;
 | 
			
		||||
    case 1: return ADC1_RA;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -37,10 +37,6 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <util/atomic.h>
 | 
			
		||||
 | 
			
		||||
#define CPU_ST7920_DELAY_1 600
 | 
			
		||||
#define CPU_ST7920_DELAY_2 750
 | 
			
		||||
#define CPU_ST7920_DELAY_3 750
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Defines
 | 
			
		||||
// ------------------------
 | 
			
		||||
@@ -53,6 +49,17 @@
 | 
			
		||||
  #define IS_TEENSY35 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CPU_ST7920_DELAY_1 600
 | 
			
		||||
#define CPU_ST7920_DELAY_2 750
 | 
			
		||||
#define CPU_ST7920_DELAY_3 750
 | 
			
		||||
 | 
			
		||||
#undef sq
 | 
			
		||||
#define sq(x) ((x)*(x))
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#include "../../core/serial_hook.h"
 | 
			
		||||
 | 
			
		||||
#define Serial0 Serial
 | 
			
		||||
@@ -76,34 +83,43 @@ extern USBSerialType USBSerial;
 | 
			
		||||
  #error "SERIAL_PORT must be from 0 to 3, or -1 for Native USB."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define HAL_SERVO_LIB libServo
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Types
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
class libServo;
 | 
			
		||||
typedef libServo hal_servo_t;
 | 
			
		||||
 | 
			
		||||
typedef int8_t pin_t;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Interrupts
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define CRITICAL_SECTION_START()  const bool irqon = !__get_primask(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (irqon) __enable_irq()
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#ifndef analogInputToDigitalPin
 | 
			
		||||
  #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CRITICAL_SECTION_START()  uint32_t primask = __get_primask(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (!primask) __enable_irq()
 | 
			
		||||
#define ISRS_ENABLED() (!__get_primask())
 | 
			
		||||
#define ENABLE_ISRS()  __enable_irq()
 | 
			
		||||
#define DISABLE_ISRS() __disable_irq()
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_ADC_RESOLUTION  10
 | 
			
		||||
 | 
			
		||||
#undef sq
 | 
			
		||||
#define sq(x) ((x)*(x))
 | 
			
		||||
//
 | 
			
		||||
// Pin Mapping for M42, M43, M226
 | 
			
		||||
//
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
 | 
			
		||||
 | 
			
		||||
inline void HAL_init() {}
 | 
			
		||||
 | 
			
		||||
// Clear reset reason
 | 
			
		||||
void HAL_clear_reset_source();
 | 
			
		||||
 | 
			
		||||
// Reset reason
 | 
			
		||||
uint8_t HAL_get_reset_source();
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
 | 
			
		||||
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
@@ -114,27 +130,65 @@ extern "C" int freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init();
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_ADC_RESOLUTION  10
 | 
			
		||||
#define HAL_START_ADC(pin)  HAL_adc_start_conversion(pin)
 | 
			
		||||
#define HAL_READ_ADC()      HAL_adc_get_result()
 | 
			
		||||
#define HAL_ADC_READY()     true
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
#define HAL_ANALOG_SELECT(pin)
 | 
			
		||||
  static void init() {}        // Called early in setup()
 | 
			
		||||
  static void init_board() {}  // Called less early in setup()
 | 
			
		||||
  static void reboot();        // Restart the firmware from 0x0
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin);
 | 
			
		||||
uint16_t HAL_adc_get_result();
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static bool isr_state() { return true; }
 | 
			
		||||
  static void isr_on()  { __enable_irq(); }
 | 
			
		||||
  static void isr_off() { __disable_irq(); }
 | 
			
		||||
 | 
			
		||||
// PWM
 | 
			
		||||
  static void delay_ms(const int ms) { delay(ms); }
 | 
			
		||||
 | 
			
		||||
inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask() {}
 | 
			
		||||
 | 
			
		||||
// Pin Map
 | 
			
		||||
  // Reset
 | 
			
		||||
  static uint8_t get_reset_source();
 | 
			
		||||
  static void clear_reset_source() {}
 | 
			
		||||
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory() { return ::freeMemory(); }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  static int8_t adc_select;
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init();
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const pin_t) {}
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given channel
 | 
			
		||||
  static void adc_start(const pin_t pin);
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready() { return true; }
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static uint16_t adc_value();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * No option to invert the duty cycle [default = false]
 | 
			
		||||
   * No option to change the scale of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
 | 
			
		||||
    analogWrite(pin, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -109,4 +109,4 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
 | 
			
		||||
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
 | 
			
		||||
 | 
			
		||||
void HAL_timer_isr_prologue(const uint8_t timer_num);
 | 
			
		||||
#define HAL_timer_isr_epilogue(T)
 | 
			
		||||
#define HAL_timer_isr_epilogue(T) NOOP
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,10 @@
 | 
			
		||||
#include "timers.h"
 | 
			
		||||
#include <Wire.h>
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
 | 
			
		||||
#define IMPLEMENT_SERIAL(X)  _IMPLEMENT_SERIAL(X)
 | 
			
		||||
#if WITHIN(SERIAL_PORT, 0, 3)
 | 
			
		||||
@@ -40,9 +44,71 @@
 | 
			
		||||
#endif
 | 
			
		||||
USBSerialType USBSerial(false, SerialUSB);
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_result, HAL_adc_select;
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
static const uint8_t pin2sc1a[] = {
 | 
			
		||||
#define __bss_end _ebss
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
  extern char __bss_end;
 | 
			
		||||
  extern char __heap_start;
 | 
			
		||||
  extern void* __brkval;
 | 
			
		||||
 | 
			
		||||
  // Doesn't work on Teensy 4.x
 | 
			
		||||
  uint32_t freeMemory() {
 | 
			
		||||
    uint32_t free_memory;
 | 
			
		||||
    free_memory = ((uint32_t)&free_memory) - (((uint32_t)__brkval) ?: ((uint32_t)&__bss_end));
 | 
			
		||||
    return free_memory;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// FastIO
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
bool is_output(pin_t pin) {
 | 
			
		||||
  const struct digital_pin_bitband_and_config_table_struct *p;
 | 
			
		||||
  p = digital_pin_to_info_PGM + pin;
 | 
			
		||||
  return (*(p->reg + 1) & p->mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::reboot() { _reboot_Teensyduino_(); }
 | 
			
		||||
 | 
			
		||||
uint8_t MarlinHAL::get_reset_source() {
 | 
			
		||||
  switch (SRC_SRSR & 0xFF) {
 | 
			
		||||
    case 1: return RST_POWER_ON; break;
 | 
			
		||||
    case 2: return RST_SOFTWARE; break;
 | 
			
		||||
    case 4: return RST_EXTERNAL; break;
 | 
			
		||||
    //case 8: return RST_BROWN_OUT; break;
 | 
			
		||||
    case 16: return RST_WATCHDOG; break;
 | 
			
		||||
    case 64: return RST_JTAG; break;
 | 
			
		||||
    //case 128: return RST_OVERTEMP; break;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::clear_reset_source() {
 | 
			
		||||
  uint32_t reset_source = SRC_SRSR;
 | 
			
		||||
  SRC_SRSR = reset_source;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ADC
 | 
			
		||||
 | 
			
		||||
int8_t MarlinHAL::adc_select;
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::adc_init() {
 | 
			
		||||
  analog_init();
 | 
			
		||||
  while (ADC1_GC & ADC_GC_CAL) { /* wait */ }
 | 
			
		||||
  while (ADC2_GC & ADC_GC_CAL) { /* wait */ }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MarlinHAL::adc_start(const pin_t adc_pin) {
 | 
			
		||||
  static const uint8_t pin2sc1a[] = {
 | 
			
		||||
    0x07,  // 0/A0  AD_B1_02
 | 
			
		||||
    0x08,  // 1/A1  AD_B1_03
 | 
			
		||||
    0x0C,  // 2/A2  AD_B1_07
 | 
			
		||||
@@ -87,91 +153,31 @@ static const uint8_t pin2sc1a[] = {
 | 
			
		||||
      0x09,  // 40/A16 AD_B1_04
 | 
			
		||||
      0x0A,  // 41/A17 AD_B1_05
 | 
			
		||||
    #endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
// disable interrupts
 | 
			
		||||
void cli() { noInterrupts(); }
 | 
			
		||||
 | 
			
		||||
// enable interrupts
 | 
			
		||||
void sei() { interrupts(); }
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init() {
 | 
			
		||||
  analog_init();
 | 
			
		||||
  while (ADC1_GC & ADC_GC_CAL) ;
 | 
			
		||||
  while (ADC2_GC & ADC_GC_CAL) ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_clear_reset_source() {
 | 
			
		||||
  uint32_t reset_source = SRC_SRSR;
 | 
			
		||||
  SRC_SRSR = reset_source;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t HAL_get_reset_source() {
 | 
			
		||||
  switch (SRC_SRSR & 0xFF) {
 | 
			
		||||
    case 1: return RST_POWER_ON; break;
 | 
			
		||||
    case 2: return RST_SOFTWARE; break;
 | 
			
		||||
    case 4: return RST_EXTERNAL; break;
 | 
			
		||||
    //case 8: return RST_BROWN_OUT; break;
 | 
			
		||||
    case 16: return RST_WATCHDOG; break;
 | 
			
		||||
    case 64: return RST_JTAG; break;
 | 
			
		||||
    //case 128: return RST_OVERTEMP; break;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_reboot() { _reboot_Teensyduino_(); }
 | 
			
		||||
 | 
			
		||||
#define __bss_end _ebss
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
  extern char __bss_end;
 | 
			
		||||
  extern char __heap_start;
 | 
			
		||||
  extern void* __brkval;
 | 
			
		||||
 | 
			
		||||
  // Doesn't work on Teensy 4.x
 | 
			
		||||
  uint32_t freeMemory() {
 | 
			
		||||
    uint32_t free_memory;
 | 
			
		||||
    if ((uint32_t)__brkval == 0)
 | 
			
		||||
      free_memory = ((uint32_t)&free_memory) - ((uint32_t)&__bss_end);
 | 
			
		||||
    else
 | 
			
		||||
      free_memory = ((uint32_t)&free_memory) - ((uint32_t)__brkval);
 | 
			
		||||
    return free_memory;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin) {
 | 
			
		||||
  };
 | 
			
		||||
  const uint16_t pin = pin2sc1a[adc_pin];
 | 
			
		||||
  if (pin == 0xFF) {
 | 
			
		||||
    HAL_adc_select = -1; // Digital only
 | 
			
		||||
    adc_select = -1; // Digital only
 | 
			
		||||
  }
 | 
			
		||||
  else if (pin & 0x80) {
 | 
			
		||||
    HAL_adc_select = 1;
 | 
			
		||||
    adc_select = 1;
 | 
			
		||||
    ADC2_HC0 = pin & 0x7F;
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    HAL_adc_select = 0;
 | 
			
		||||
    adc_select = 0;
 | 
			
		||||
    ADC1_HC0 = pin;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t HAL_adc_get_result() {
 | 
			
		||||
  switch (HAL_adc_select) {
 | 
			
		||||
uint16_t MarlinHAL::adc_value() {
 | 
			
		||||
  switch (adc_select) {
 | 
			
		||||
    case 0:
 | 
			
		||||
      while (!(ADC1_HS & ADC_HS_COCO0)) ; // wait
 | 
			
		||||
      while (!(ADC1_HS & ADC_HS_COCO0)) { /* wait */ }
 | 
			
		||||
      return ADC1_R0;
 | 
			
		||||
    case 1:
 | 
			
		||||
      while (!(ADC2_HS & ADC_HS_COCO0)) ; // wait
 | 
			
		||||
      while (!(ADC2_HS & ADC_HS_COCO0)) { /* wait */ }
 | 
			
		||||
      return ADC2_R0;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool is_output(pin_t pin) {
 | 
			
		||||
  const struct digital_pin_bitband_and_config_table_struct *p;
 | 
			
		||||
  p = digital_pin_to_info_PGM + pin;
 | 
			
		||||
  return (*(p->reg + 1) & p->mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // __IMXRT1062__
 | 
			
		||||
 
 | 
			
		||||
@@ -41,10 +41,6 @@
 | 
			
		||||
  #include "../../feature/ethernet.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CPU_ST7920_DELAY_1 600
 | 
			
		||||
#define CPU_ST7920_DELAY_2 750
 | 
			
		||||
#define CPU_ST7920_DELAY_3 750
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Defines
 | 
			
		||||
// ------------------------
 | 
			
		||||
@@ -55,7 +51,23 @@
 | 
			
		||||
  #define IS_TEENSY41 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CPU_ST7920_DELAY_1 600
 | 
			
		||||
#define CPU_ST7920_DELAY_2 750
 | 
			
		||||
#define CPU_ST7920_DELAY_3 750
 | 
			
		||||
 | 
			
		||||
#undef sq
 | 
			
		||||
#define sq(x) ((x)*(x))
 | 
			
		||||
 | 
			
		||||
// Don't place string constants in PROGMEM
 | 
			
		||||
#undef PSTR
 | 
			
		||||
#define PSTR(str) ({static const char *data = (str); &data[0];})
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Serial ports
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#include "../../core/serial_hook.h"
 | 
			
		||||
 | 
			
		||||
#define Serial0 Serial
 | 
			
		||||
#define _DECLARE_SERIAL(X) \
 | 
			
		||||
  typedef ForwardSerial1Class<decltype(Serial##X)> DefaultSerial##X; \
 | 
			
		||||
@@ -89,41 +101,47 @@ extern USBSerialType USBSerial;
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define HAL_SERVO_LIB libServo
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Types
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
class libServo;
 | 
			
		||||
typedef libServo hal_servo_t;
 | 
			
		||||
 | 
			
		||||
typedef int8_t pin_t;
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Interrupts
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#define CRITICAL_SECTION_START()  const bool irqon = !__get_primask(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (irqon) __enable_irq()
 | 
			
		||||
 | 
			
		||||
// ------------------------
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#ifndef analogInputToDigitalPin
 | 
			
		||||
  #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CRITICAL_SECTION_START()  uint32_t primask = __get_primask(); __disable_irq()
 | 
			
		||||
#define CRITICAL_SECTION_END()    if (!primask) __enable_irq()
 | 
			
		||||
#define ISRS_ENABLED() (!__get_primask())
 | 
			
		||||
#define ENABLE_ISRS()  __enable_irq()
 | 
			
		||||
#define DISABLE_ISRS() __disable_irq()
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_ADC_RESOLUTION  10
 | 
			
		||||
#define HAL_ADC_FILTERED      // turn off ADC oversampling
 | 
			
		||||
 | 
			
		||||
#undef sq
 | 
			
		||||
#define sq(x) ((x)*(x))
 | 
			
		||||
//
 | 
			
		||||
// Pin Mapping for M42, M43, M226
 | 
			
		||||
//
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
 | 
			
		||||
 | 
			
		||||
// Don't place string constants in PROGMEM
 | 
			
		||||
#undef PSTR
 | 
			
		||||
#define PSTR(str) ({static const char *data = (str); &data[0];})
 | 
			
		||||
// FastIO
 | 
			
		||||
bool is_output(pin_t pin);
 | 
			
		||||
 | 
			
		||||
// Enable hooks into idle and setup for HAL
 | 
			
		||||
#define HAL_IDLETASK 1
 | 
			
		||||
FORCE_INLINE void HAL_idletask() {}
 | 
			
		||||
FORCE_INLINE void HAL_init() {}
 | 
			
		||||
 | 
			
		||||
// Clear reset reason
 | 
			
		||||
void HAL_clear_reset_source();
 | 
			
		||||
 | 
			
		||||
// Reset reason
 | 
			
		||||
uint8_t HAL_get_reset_source();
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
 | 
			
		||||
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
 | 
			
		||||
// ------------------------
 | 
			
		||||
// Class Utilities
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#if GCC_VERSION <= 50000
 | 
			
		||||
@@ -134,30 +152,65 @@ extern "C" uint32_t freeMemory();
 | 
			
		||||
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
// ADC
 | 
			
		||||
// ------------------------
 | 
			
		||||
// MarlinHAL Class
 | 
			
		||||
// ------------------------
 | 
			
		||||
 | 
			
		||||
void HAL_adc_init();
 | 
			
		||||
class MarlinHAL {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
#define HAL_ADC_VREF         3.3
 | 
			
		||||
#define HAL_ADC_RESOLUTION  10
 | 
			
		||||
#define HAL_ADC_FILTERED      // turn off ADC oversampling
 | 
			
		||||
#define HAL_START_ADC(pin)  HAL_adc_start_conversion(pin)
 | 
			
		||||
#define HAL_READ_ADC()      HAL_adc_get_result()
 | 
			
		||||
#define HAL_ADC_READY()     true
 | 
			
		||||
  // Earliest possible init, before setup()
 | 
			
		||||
  MarlinHAL() {}
 | 
			
		||||
 | 
			
		||||
#define HAL_ANALOG_SELECT(pin)
 | 
			
		||||
  static void init() {}        // Called early in setup()
 | 
			
		||||
  static void init_board() {}  // Called less early in setup()
 | 
			
		||||
  static void reboot();        // Restart the firmware from 0x0
 | 
			
		||||
 | 
			
		||||
void HAL_adc_start_conversion(const uint8_t adc_pin);
 | 
			
		||||
uint16_t HAL_adc_get_result();
 | 
			
		||||
  // Interrupts
 | 
			
		||||
  static bool isr_state() { return !__get_primask(); }
 | 
			
		||||
  static void isr_on()  { __enable_irq(); }
 | 
			
		||||
  static void isr_off() { __disable_irq(); }
 | 
			
		||||
 | 
			
		||||
// PWM
 | 
			
		||||
  static void delay_ms(const int ms) { delay(ms); }
 | 
			
		||||
 | 
			
		||||
inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
 | 
			
		||||
  // Tasks, called from idle()
 | 
			
		||||
  static void idletask() {}
 | 
			
		||||
 | 
			
		||||
// Pin Map
 | 
			
		||||
  // Reset
 | 
			
		||||
  static uint8_t get_reset_source();
 | 
			
		||||
  static void clear_reset_source();
 | 
			
		||||
 | 
			
		||||
#define GET_PIN_MAP_PIN(index) index
 | 
			
		||||
#define GET_PIN_MAP_INDEX(pin) pin
 | 
			
		||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
 | 
			
		||||
  // Free SRAM
 | 
			
		||||
  static int freeMemory() { return ::freeMemory(); }
 | 
			
		||||
 | 
			
		||||
bool is_output(pin_t pin);
 | 
			
		||||
  //
 | 
			
		||||
  // ADC Methods
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  static int8_t adc_select;
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init once at startup
 | 
			
		||||
  static void adc_init();
 | 
			
		||||
 | 
			
		||||
  // Called by Temperature::init for each sensor at startup
 | 
			
		||||
  static void adc_enable(const pin_t pin) {}
 | 
			
		||||
 | 
			
		||||
  // Begin ADC sampling on the given channel
 | 
			
		||||
  static void adc_start(const pin_t pin);
 | 
			
		||||
 | 
			
		||||
  // Is the ADC ready for reading?
 | 
			
		||||
  static bool adc_ready() { return true; }
 | 
			
		||||
 | 
			
		||||
  // The current value of the ADC register
 | 
			
		||||
  static uint16_t adc_value();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the PWM duty cycle for the pin to the given value.
 | 
			
		||||
   * No option to invert the duty cycle [default = false]
 | 
			
		||||
   * No option to change the scale of the provided value to enable finer PWM duty control [default = 255]
 | 
			
		||||
   */
 | 
			
		||||
  static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
 | 
			
		||||
    analogWrite(pin, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -114,4 +114,4 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
 | 
			
		||||
 | 
			
		||||
void HAL_timer_isr_prologue(const uint8_t timer_num);
 | 
			
		||||
//void HAL_timer_isr_epilogue(const uint8_t timer_num) {}
 | 
			
		||||
#define HAL_timer_isr_epilogue(T)
 | 
			
		||||
#define HAL_timer_isr_epilogue(T) NOOP
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								Marlin/src/HAL/shared/HAL.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Marlin/src/HAL/shared/HAL.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Marlin 3D Printer Firmware
 | 
			
		||||
 * Copyright (c) 2022 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 <https://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * HAL/shared/HAL.cpp
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "../../inc/MarlinConfig.h"
 | 
			
		||||
 | 
			
		||||
MarlinHAL hal;
 | 
			
		||||
 | 
			
		||||
#if ENABLED(SOFT_RESET_VIA_SERIAL)
 | 
			
		||||
 | 
			
		||||
  // Global for use by e_parser.h
 | 
			
		||||
  void HAL_reboot() { hal.reboot(); }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -92,9 +92,9 @@ uint8_t L64XX_Marlin::transfer_single(uint8_t data, int16_t ss_pin) {
 | 
			
		||||
  // First device in chain has data sent last
 | 
			
		||||
  extDigitalWrite(ss_pin, LOW);
 | 
			
		||||
 | 
			
		||||
  DISABLE_ISRS(); // Disable interrupts during SPI transfer (can't allow partial command to chips)
 | 
			
		||||
  hal.isr_off();  // Disable interrupts during SPI transfer (can't allow partial command to chips)
 | 
			
		||||
  const uint8_t data_out = L6470_SpiTransfer_Mode_3(data);
 | 
			
		||||
  ENABLE_ISRS();  // Enable interrupts
 | 
			
		||||
  hal.isr_on();   // Enable interrupts
 | 
			
		||||
 | 
			
		||||
  extDigitalWrite(ss_pin, HIGH);
 | 
			
		||||
  return data_out;
 | 
			
		||||
@@ -107,9 +107,9 @@ uint8_t L64XX_Marlin::transfer_chain(uint8_t data, int16_t ss_pin, uint8_t chain
 | 
			
		||||
  extDigitalWrite(ss_pin, LOW);
 | 
			
		||||
 | 
			
		||||
  for (uint8_t i = L64XX::chain[0]; !L64xxManager.spi_abort && i >= 1; i--) {   // Send data unless aborted
 | 
			
		||||
    DISABLE_ISRS();   // Disable interrupts during SPI transfer (can't allow partial command to chips)
 | 
			
		||||
    hal.isr_off();    // Disable interrupts during SPI transfer (can't allow partial command to chips)
 | 
			
		||||
    const uint8_t temp = L6470_SpiTransfer_Mode_3(uint8_t(i == chain_position ? data : dSPIN_NOP));
 | 
			
		||||
    ENABLE_ISRS();    // Enable interrupts
 | 
			
		||||
    hal.isr_on();     // Enable interrupts
 | 
			
		||||
    if (i == chain_position) data_out = temp;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,6 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Math helper functions for 32 bit CPUs
 | 
			
		||||
 */
 | 
			
		||||
static FORCE_INLINE uint32_t MultiU32X24toH32(uint32_t longIn1, uint32_t longIn2) {
 | 
			
		||||
FORCE_INLINE static uint32_t MultiU32X24toH32(uint32_t longIn1, uint32_t longIn2) {
 | 
			
		||||
  return ((uint64_t)longIn1 * longIn2 + 0x00800000) >> 24;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -790,7 +790,7 @@ void idle(bool no_stepper_sleep/*=false*/) {
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  // Run HAL idle tasks
 | 
			
		||||
  TERN_(HAL_IDLETASK, HAL_idletask());
 | 
			
		||||
  hal.idletask();
 | 
			
		||||
 | 
			
		||||
  // Check network connection
 | 
			
		||||
  TERN_(HAS_ETHERNET, ethernet.check());
 | 
			
		||||
@@ -929,7 +929,7 @@ void minkill(const bool steppers_off/*=false*/) {
 | 
			
		||||
      watchdog_refresh();
 | 
			
		||||
 | 
			
		||||
    // Reboot the board
 | 
			
		||||
    HAL_reboot();
 | 
			
		||||
    hal.reboot();
 | 
			
		||||
 | 
			
		||||
  #else
 | 
			
		||||
 | 
			
		||||
@@ -1041,7 +1041,7 @@ inline void tmc_standby_setup() {
 | 
			
		||||
 *    • L64XX Stepper Drivers (SPI)
 | 
			
		||||
 *    • Stepper Driver Reset: DISABLE
 | 
			
		||||
 *    • TMC Stepper Drivers (SPI)
 | 
			
		||||
 *    • Run BOARD_INIT if defined
 | 
			
		||||
 *    • Run hal.init_board() for additional pins setup
 | 
			
		||||
 *    • ESP WiFi
 | 
			
		||||
 *  - Get the Reset Reason and report it
 | 
			
		||||
 *  - Print startup messages and diagnostics
 | 
			
		||||
@@ -1119,8 +1119,8 @@ void setup() {
 | 
			
		||||
  tmc_standby_setup();  // TMC Low Power Standby pins must be set early or they're not usable
 | 
			
		||||
 | 
			
		||||
  // Check startup - does nothing if bootloader sets MCUSR to 0
 | 
			
		||||
  const byte mcu = HAL_get_reset_source();
 | 
			
		||||
  HAL_clear_reset_source();
 | 
			
		||||
  const byte mcu = hal.get_reset_source();
 | 
			
		||||
  hal.clear_reset_source();
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(MARLIN_DEV_MODE)
 | 
			
		||||
    auto log_current_ms = [&](PGM_P const msg) {
 | 
			
		||||
@@ -1181,23 +1181,20 @@ void setup() {
 | 
			
		||||
    JTAGSWD_RESET();
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if EITHER(DISABLE_DEBUG, DISABLE_JTAG)
 | 
			
		||||
    delay(10);
 | 
			
		||||
  // Disable any hardware debug to free up pins for IO
 | 
			
		||||
  #if ENABLED(DISABLE_DEBUG) && defined(JTAGSWD_DISABLE)
 | 
			
		||||
    delay(10);
 | 
			
		||||
    SETUP_LOG("JTAGSWD_DISABLE");
 | 
			
		||||
    JTAGSWD_DISABLE();
 | 
			
		||||
    #elif defined(JTAG_DISABLE)
 | 
			
		||||
  #elif ENABLED(DISABLE_JTAG) && defined(JTAG_DISABLE)
 | 
			
		||||
    delay(10);
 | 
			
		||||
    SETUP_LOG("JTAG_DISABLE");
 | 
			
		||||
    JTAG_DISABLE();
 | 
			
		||||
    #else
 | 
			
		||||
      #error "DISABLE_(DEBUG|JTAG) is not supported for the selected MCU/Board."
 | 
			
		||||
    #endif
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  TERN_(DYNAMIC_VECTORTABLE, hook_cpu_exceptions()); // If supported, install Marlin exception handlers at runtime
 | 
			
		||||
 | 
			
		||||
  SETUP_RUN(HAL_init());
 | 
			
		||||
  SETUP_RUN(hal.init());
 | 
			
		||||
 | 
			
		||||
  // Init and disable SPI thermocouples; this is still needed
 | 
			
		||||
  #if TEMP_SENSOR_0_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E0))
 | 
			
		||||
@@ -1243,10 +1240,7 @@ void setup() {
 | 
			
		||||
    SETUP_RUN(tmc_init_cs_pins());
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #ifdef BOARD_INIT
 | 
			
		||||
    SETUP_LOG("BOARD_INIT");
 | 
			
		||||
    BOARD_INIT();
 | 
			
		||||
  #endif
 | 
			
		||||
  SETUP_RUN(hal.init_board());
 | 
			
		||||
 | 
			
		||||
  SETUP_RUN(esp_wifi_init());
 | 
			
		||||
 | 
			
		||||
@@ -1266,7 +1260,7 @@ void setup() {
 | 
			
		||||
    );
 | 
			
		||||
  #endif
 | 
			
		||||
  SERIAL_ECHO_MSG(" Compiled: " __DATE__);
 | 
			
		||||
  SERIAL_ECHO_MSG(STR_FREE_MEMORY, freeMemory(), STR_PLANNER_BUFFER_BYTES, sizeof(block_t) * (BLOCK_BUFFER_SIZE));
 | 
			
		||||
  SERIAL_ECHO_MSG(STR_FREE_MEMORY, hal.freeMemory(), STR_PLANNER_BUFFER_BYTES, sizeof(block_t) * (BLOCK_BUFFER_SIZE));
 | 
			
		||||
 | 
			
		||||
  // Some HAL need precise delay adjustment
 | 
			
		||||
  calibrate_delay_loop();
 | 
			
		||||
@@ -1542,7 +1536,7 @@ void setup() {
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(USE_WATCHDOG)
 | 
			
		||||
    SETUP_RUN(watchdog_init());       // Reinit watchdog after HAL_get_reset_source call
 | 
			
		||||
    SETUP_RUN(watchdog_init());       // Reinit watchdog after hal.get_reset_source call
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
 | 
			
		||||
 
 | 
			
		||||
@@ -79,7 +79,7 @@ void CaseLight::update(const bool sflag) {
 | 
			
		||||
 | 
			
		||||
    #if CASELIGHT_USES_BRIGHTNESS
 | 
			
		||||
      if (pin_is_pwm())
 | 
			
		||||
        set_pwm_duty(pin_t(CASE_LIGHT_PIN), (
 | 
			
		||||
        hal.set_pwm_duty(pin_t(CASE_LIGHT_PIN), (
 | 
			
		||||
          #if CASE_LIGHT_MAX_PWM == 255
 | 
			
		||||
            n10ct
 | 
			
		||||
          #else
 | 
			
		||||
 
 | 
			
		||||
@@ -76,7 +76,7 @@ void ControllerFan::update() {
 | 
			
		||||
      thermalManager.soft_pwm_controller_speed = speed;
 | 
			
		||||
    #else
 | 
			
		||||
      if (PWM_PIN(CONTROLLER_FAN_PIN))
 | 
			
		||||
        set_pwm_duty(pin_t(CONTROLLER_FAN_PIN), speed);
 | 
			
		||||
        hal.set_pwm_duty(pin_t(CONTROLLER_FAN_PIN), speed);
 | 
			
		||||
      else
 | 
			
		||||
        WRITE(CONTROLLER_FAN_PIN, speed > 0);
 | 
			
		||||
    #endif
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,9 @@ extern bool wait_for_user, wait_for_heatup;
 | 
			
		||||
  void quickresume_stepper();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void HAL_reboot();
 | 
			
		||||
#if ENABLED(SOFT_RESET_VIA_SERIAL)
 | 
			
		||||
  void HAL_reboot();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class EmergencyParser {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -131,7 +131,7 @@ void LEDLights::set_color(const LEDColor &incol
 | 
			
		||||
    // If the pins can do PWM then their intensity will be set.
 | 
			
		||||
    #define _UPDATE_RGBW(C,c) do {                     \
 | 
			
		||||
      if (PWM_PIN(RGB_LED_##C##_PIN))                  \
 | 
			
		||||
        set_pwm_duty(pin_t(RGB_LED_##C##_PIN), c); \
 | 
			
		||||
        hal.set_pwm_duty(pin_t(RGB_LED_##C##_PIN), c); \
 | 
			
		||||
      else                                             \
 | 
			
		||||
        WRITE(RGB_LED_##C##_PIN, c ? HIGH : LOW);      \
 | 
			
		||||
    }while(0)
 | 
			
		||||
 
 | 
			
		||||
@@ -66,10 +66,10 @@ void SpindleLaser::init() {
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(SPINDLE_LASER_USE_PWM)
 | 
			
		||||
    SET_PWM(SPINDLE_LASER_PWM_PIN);
 | 
			
		||||
    set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed
 | 
			
		||||
    hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY
 | 
			
		||||
    set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY);
 | 
			
		||||
    hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY);
 | 
			
		||||
    TERN_(MARLIN_DEV_MODE, frequency = SPINDLE_LASER_FREQUENCY);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(AIR_EVACUATION)
 | 
			
		||||
@@ -89,9 +89,9 @@ void SpindleLaser::init() {
 | 
			
		||||
   */
 | 
			
		||||
  void SpindleLaser::_set_ocr(const uint8_t ocr) {
 | 
			
		||||
    #if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY
 | 
			
		||||
      set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), TERN(MARLIN_DEV_MODE, frequency, SPINDLE_LASER_FREQUENCY));
 | 
			
		||||
      hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), TERN(MARLIN_DEV_MODE, frequency, SPINDLE_LASER_FREQUENCY));
 | 
			
		||||
    #endif
 | 
			
		||||
    set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
 | 
			
		||||
    hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void SpindleLaser::set_ocr(const uint8_t ocr) {
 | 
			
		||||
 
 | 
			
		||||
@@ -103,7 +103,7 @@ public:
 | 
			
		||||
  static void init();
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(MARLIN_DEV_MODE)
 | 
			
		||||
    static void refresh_frequency() { set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency); }
 | 
			
		||||
    static void refresh_frequency() { hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency); }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  // Modifying this function should update everywhere
 | 
			
		||||
 
 | 
			
		||||
@@ -126,10 +126,10 @@ void GcodeSuite::M42() {
 | 
			
		||||
  extDigitalWrite(pin, pin_status);
 | 
			
		||||
 | 
			
		||||
  #ifdef ARDUINO_ARCH_STM32
 | 
			
		||||
    // A simple I/O will be set to 0 by set_pwm_duty()
 | 
			
		||||
    // A simple I/O will be set to 0 by hal.set_pwm_duty()
 | 
			
		||||
    if (pin_status <= 1 && !PWM_PIN(pin)) return;
 | 
			
		||||
  #endif
 | 
			
		||||
  set_pwm_duty(pin, pin_status);
 | 
			
		||||
  hal.set_pwm_duty(pin, pin_status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // DIRECT_PIN_CONTROL
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@
 | 
			
		||||
#include "../sd/cardreader.h"
 | 
			
		||||
#include "../MarlinCore.h" // for kill
 | 
			
		||||
 | 
			
		||||
extern void dump_delay_accuracy_check();
 | 
			
		||||
void dump_delay_accuracy_check();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Dn: G-code for development and testing
 | 
			
		||||
@@ -54,7 +54,7 @@ void GcodeSuite::D(const int16_t dcode) {
 | 
			
		||||
      for (;;) { /* loop forever (watchdog reset) */ }
 | 
			
		||||
 | 
			
		||||
    case 0:
 | 
			
		||||
      HAL_reboot();
 | 
			
		||||
      hal.reboot();
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case 10:
 | 
			
		||||
@@ -74,7 +74,7 @@ void GcodeSuite::D(const int16_t dcode) {
 | 
			
		||||
        settings.reset();
 | 
			
		||||
        settings.save();
 | 
			
		||||
      #endif
 | 
			
		||||
      HAL_reboot();
 | 
			
		||||
      hal.reboot();
 | 
			
		||||
    } break;
 | 
			
		||||
 | 
			
		||||
    case 2: { // D2 Read / Write SRAM
 | 
			
		||||
@@ -189,12 +189,12 @@ void GcodeSuite::D(const int16_t dcode) {
 | 
			
		||||
      SERIAL_ECHOLNPGM("(USE_WATCHDOG " TERN(USE_WATCHDOG, "ENABLED", "DISABLED") ")");
 | 
			
		||||
      thermalManager.disable_all_heaters();
 | 
			
		||||
      delay(1000); // Allow time to print
 | 
			
		||||
      DISABLE_ISRS();
 | 
			
		||||
      hal.isr_off();
 | 
			
		||||
      // Use a low-level delay that does not rely on interrupts to function
 | 
			
		||||
      // Do not spin forever, to avoid thermal risks if heaters are enabled and
 | 
			
		||||
      // watchdog does not work.
 | 
			
		||||
      for (int i = 10000; i--;) DELAY_US(1000UL);
 | 
			
		||||
      ENABLE_ISRS();
 | 
			
		||||
      hal.isr_on();
 | 
			
		||||
      SERIAL_ECHOLNPGM("FAILURE: Watchdog did not trigger board reset.");
 | 
			
		||||
    } break;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@
 | 
			
		||||
 | 
			
		||||
#ifndef __MARLIN_DEPS__
 | 
			
		||||
  #include "../HAL/HAL.h"
 | 
			
		||||
  extern MarlinHAL hal;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "../pins/pins.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -3891,3 +3891,10 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
 | 
			
		||||
#undef _TEST_PWM
 | 
			
		||||
#undef _LINEAR_AXES_STR
 | 
			
		||||
#undef _LOGICAL_AXES_STR
 | 
			
		||||
 | 
			
		||||
// JTAG support in the HAL
 | 
			
		||||
#if ENABLED(DISABLE_DEBUG) && !defined(JTAGSWD_DISABLE)
 | 
			
		||||
  #error "DISABLE_DEBUG is not supported for the selected MCU/Board."
 | 
			
		||||
#elif ENABLED(DISABLE_JTAG) && !defined(JTAG_DISABLE)
 | 
			
		||||
  #error "DISABLE_JTAG is not supported for the selected MCU/Board."
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -282,9 +282,9 @@ void MarlinUI::init_lcd() {
 | 
			
		||||
  #if PIN_EXISTS(LCD_RESET)
 | 
			
		||||
    // Perform a clean hardware reset with needed delays
 | 
			
		||||
    OUT_WRITE(LCD_RESET_PIN, LOW);
 | 
			
		||||
    _delay_ms(5);
 | 
			
		||||
    hal.delay_ms(5);
 | 
			
		||||
    WRITE(LCD_RESET_PIN, HIGH);
 | 
			
		||||
    _delay_ms(5);
 | 
			
		||||
    hal.delay_ms(5);
 | 
			
		||||
    u8g.begin();
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2206,7 +2206,7 @@ void RebootPrinter() {
 | 
			
		||||
  thermalManager.disable_all_heaters();
 | 
			
		||||
  planner.finish_and_disable();
 | 
			
		||||
  DWIN_RebootScreen();
 | 
			
		||||
  HAL_reboot();
 | 
			
		||||
  hal.reboot();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Goto_Info_Menu(){
 | 
			
		||||
 
 | 
			
		||||
@@ -1348,7 +1348,7 @@ void Endstops::update() {
 | 
			
		||||
        ES_REPORT_CHANGE(K_MAX);
 | 
			
		||||
      #endif
 | 
			
		||||
      SERIAL_ECHOLNPGM("\n");
 | 
			
		||||
      set_pwm_duty(pin_t(LED_PIN), local_LED_status);
 | 
			
		||||
      hal.set_pwm_duty(pin_t(LED_PIN), local_LED_status);
 | 
			
		||||
      local_LED_status ^= 255;
 | 
			
		||||
      old_live_state_local = live_state_local;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -703,7 +703,7 @@ void Planner::init() {
 | 
			
		||||
    // All other 32-bit MPUs can easily do inverse using hardware division,
 | 
			
		||||
    // so we don't need to reduce precision or to use assembly language at all.
 | 
			
		||||
    // This routine, for all other archs, returns 0x100000000 / d ~= 0xFFFFFFFF / d
 | 
			
		||||
    static FORCE_INLINE uint32_t get_period_inverse(const uint32_t d) {
 | 
			
		||||
    FORCE_INLINE static uint32_t get_period_inverse(const uint32_t d) {
 | 
			
		||||
      return d ? 0xFFFFFFFF / d : 0xFFFFFFFF;
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
@@ -1260,7 +1260,7 @@ void Planner::recalculate() {
 | 
			
		||||
    #if ENABLED(FAN_SOFT_PWM)
 | 
			
		||||
      #define _FAN_SET(F) thermalManager.soft_pwm_amount_fan[F] = CALC_FAN_SPEED(F);
 | 
			
		||||
    #else
 | 
			
		||||
      #define _FAN_SET(F) set_pwm_duty(pin_t(FAN##F##_PIN), CALC_FAN_SPEED(F));
 | 
			
		||||
      #define _FAN_SET(F) hal.set_pwm_duty(pin_t(FAN##F##_PIN), CALC_FAN_SPEED(F));
 | 
			
		||||
    #endif
 | 
			
		||||
    #define FAN_SET(F) do{ kickstart_fan(fan_speed, ms, F); _FAN_SET(F); }while(0)
 | 
			
		||||
 | 
			
		||||
@@ -1397,8 +1397,8 @@ void Planner::check_axes_activity() {
 | 
			
		||||
  TERN_(AUTOTEMP, autotemp_task());
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(BARICUDA)
 | 
			
		||||
    TERN_(HAS_HEATER_1, set_pwm_duty(pin_t(HEATER_1_PIN), tail_valve_pressure));
 | 
			
		||||
    TERN_(HAS_HEATER_2, set_pwm_duty(pin_t(HEATER_2_PIN), tail_e_to_p_pressure));
 | 
			
		||||
    TERN_(HAS_HEATER_1, hal.set_pwm_duty(pin_t(HEATER_1_PIN), tail_valve_pressure));
 | 
			
		||||
    TERN_(HAS_HEATER_2, hal.set_pwm_duty(pin_t(HEATER_2_PIN), tail_e_to_p_pressure));
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@
 | 
			
		||||
 | 
			
		||||
#include "servo.h"
 | 
			
		||||
 | 
			
		||||
HAL_SERVO_LIB servo[NUM_SERVOS];
 | 
			
		||||
hal_servo_t servo[NUM_SERVOS];
 | 
			
		||||
 | 
			
		||||
#if ENABLED(EDITABLE_SERVO_ANGLES)
 | 
			
		||||
  uint16_t servo_angles[NUM_SERVOS][2];
 | 
			
		||||
 
 | 
			
		||||
@@ -112,5 +112,5 @@
 | 
			
		||||
#define MOVE_SERVO(I, P) servo[I].move(P)
 | 
			
		||||
#define DETACH_SERVO(I) servo[I].detach()
 | 
			
		||||
 | 
			
		||||
extern HAL_SERVO_LIB servo[NUM_SERVOS];
 | 
			
		||||
extern hal_servo_t servo[NUM_SERVOS];
 | 
			
		||||
void servo_init();
 | 
			
		||||
 
 | 
			
		||||
@@ -1474,7 +1474,7 @@ void Stepper::isr() {
 | 
			
		||||
  #ifndef __AVR__
 | 
			
		||||
    // Disable interrupts, to avoid ISR preemption while we reprogram the period
 | 
			
		||||
    // (AVR enters the ISR with global interrupts disabled, so no need to do it here)
 | 
			
		||||
    DISABLE_ISRS();
 | 
			
		||||
    hal.isr_off();
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  // Program timer compare for the maximum period, so it does NOT
 | 
			
		||||
@@ -1492,7 +1492,7 @@ void Stepper::isr() {
 | 
			
		||||
  hal_timer_t min_ticks;
 | 
			
		||||
  do {
 | 
			
		||||
    // Enable ISRs to reduce USART processing latency
 | 
			
		||||
    ENABLE_ISRS();
 | 
			
		||||
    hal.isr_on();
 | 
			
		||||
 | 
			
		||||
    if (!nextMainISR) pulse_phase_isr();                            // 0 = Do coordinated axes Stepper pulses
 | 
			
		||||
 | 
			
		||||
@@ -1576,7 +1576,7 @@ void Stepper::isr() {
 | 
			
		||||
     * is less than the current count due to something preempting between the
 | 
			
		||||
     * read and the write of the new period value).
 | 
			
		||||
     */
 | 
			
		||||
    DISABLE_ISRS();
 | 
			
		||||
    hal.isr_off();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the current tick value + margin
 | 
			
		||||
@@ -1611,7 +1611,7 @@ void Stepper::isr() {
 | 
			
		||||
  HAL_timer_set_compare(MF_TIMER_STEP, hal_timer_t(next_isr_ticks));
 | 
			
		||||
 | 
			
		||||
  // Don't forget to finally reenable interrupts
 | 
			
		||||
  ENABLE_ISRS();
 | 
			
		||||
  hal.isr_on();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if MINIMUM_STEPPER_PULSE || MAXIMUM_STEPPER_RATE
 | 
			
		||||
@@ -3260,33 +3260,33 @@ void Stepper::report_positions() {
 | 
			
		||||
 | 
			
		||||
      #elif HAS_MOTOR_CURRENT_PWM
 | 
			
		||||
 | 
			
		||||
        #define _WRITE_CURRENT_PWM_DUTY(P) set_pwm_duty(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), 255L * current / (MOTOR_CURRENT_PWM_RANGE))
 | 
			
		||||
        #define _WRITE_CURRENT_PWM(P) hal.set_pwm_duty(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), 255L * current / (MOTOR_CURRENT_PWM_RANGE))
 | 
			
		||||
        switch (driver) {
 | 
			
		||||
          case 0:
 | 
			
		||||
            #if PIN_EXISTS(MOTOR_CURRENT_PWM_X)
 | 
			
		||||
              _WRITE_CURRENT_PWM_DUTY(X);
 | 
			
		||||
              _WRITE_CURRENT_PWM(X);
 | 
			
		||||
            #endif
 | 
			
		||||
            #if PIN_EXISTS(MOTOR_CURRENT_PWM_Y)
 | 
			
		||||
              _WRITE_CURRENT_PWM_DUTY(Y);
 | 
			
		||||
              _WRITE_CURRENT_PWM(Y);
 | 
			
		||||
            #endif
 | 
			
		||||
            #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
 | 
			
		||||
              _WRITE_CURRENT_PWM_DUTY(XY);
 | 
			
		||||
              _WRITE_CURRENT_PWM(XY);
 | 
			
		||||
            #endif
 | 
			
		||||
            break;
 | 
			
		||||
          case 1:
 | 
			
		||||
            #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
 | 
			
		||||
              _WRITE_CURRENT_PWM_DUTY(Z);
 | 
			
		||||
              _WRITE_CURRENT_PWM(Z);
 | 
			
		||||
            #endif
 | 
			
		||||
            break;
 | 
			
		||||
          case 2:
 | 
			
		||||
            #if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
 | 
			
		||||
              _WRITE_CURRENT_PWM_DUTY(E);
 | 
			
		||||
              _WRITE_CURRENT_PWM(E);
 | 
			
		||||
            #endif
 | 
			
		||||
            #if PIN_EXISTS(MOTOR_CURRENT_PWM_E0)
 | 
			
		||||
              _WRITE_CURRENT_PWM_DUTY(E0);
 | 
			
		||||
              _WRITE_CURRENT_PWM(E0);
 | 
			
		||||
            #endif
 | 
			
		||||
            #if PIN_EXISTS(MOTOR_CURRENT_PWM_E1)
 | 
			
		||||
              _WRITE_CURRENT_PWM_DUTY(E1);
 | 
			
		||||
              _WRITE_CURRENT_PWM(E1);
 | 
			
		||||
            #endif
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
@@ -3308,7 +3308,7 @@ void Stepper::report_positions() {
 | 
			
		||||
        #ifdef __SAM3X8E__
 | 
			
		||||
          #define _RESET_CURRENT_PWM_FREQ(P) NOOP
 | 
			
		||||
        #else
 | 
			
		||||
          #define _RESET_CURRENT_PWM_FREQ(P) set_pwm_frequency(pin_t(P), MOTOR_CURRENT_PWM_FREQUENCY)
 | 
			
		||||
          #define _RESET_CURRENT_PWM_FREQ(P) hal.set_pwm_frequency(pin_t(P), MOTOR_CURRENT_PWM_FREQUENCY)
 | 
			
		||||
        #endif
 | 
			
		||||
        #define INIT_CURRENT_PWM(P) do{ SET_PWM(MOTOR_CURRENT_PWM_## P ##_PIN); _RESET_CURRENT_PWM_FREQ(MOTOR_CURRENT_PWM_## P ##_PIN); }while(0)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -327,7 +327,7 @@ PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED);
 | 
			
		||||
  #define _INIT_FAN_PIN(P) do{ if (PWM_PIN(P)) SET_PWM(P); else _INIT_SOFT_FAN(P); }while(0)
 | 
			
		||||
#endif
 | 
			
		||||
#if ENABLED(FAST_PWM_FAN)
 | 
			
		||||
  #define SET_FAST_PWM_FREQ(P) set_pwm_frequency(P, FAST_PWM_FAN_FREQUENCY)
 | 
			
		||||
  #define SET_FAST_PWM_FREQ(P) hal.set_pwm_frequency(pin_t(P), FAST_PWM_FAN_FREQUENCY)
 | 
			
		||||
#else
 | 
			
		||||
  #define SET_FAST_PWM_FREQ(P) NOOP
 | 
			
		||||
#endif
 | 
			
		||||
@@ -818,7 +818,7 @@ volatile bool Temperature::raw_temps_ready = false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Run HAL idle tasks
 | 
			
		||||
      TERN_(HAL_IDLETASK, HAL_idletask());
 | 
			
		||||
      hal.idletask();
 | 
			
		||||
 | 
			
		||||
      // Run UI update
 | 
			
		||||
      TERN(HAS_DWIN_E3V2_BASIC, DWIN_Update(), ui.update());
 | 
			
		||||
@@ -907,7 +907,7 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) {
 | 
			
		||||
 | 
			
		||||
    #define _UPDATE_AUTO_FAN(P,D,A) do{                   \
 | 
			
		||||
      if (PWM_PIN(P##_AUTO_FAN_PIN) && A < 255)           \
 | 
			
		||||
        set_pwm_duty(pin_t(P##_AUTO_FAN_PIN), D ? A : 0); \
 | 
			
		||||
        hal.set_pwm_duty(pin_t(P##_AUTO_FAN_PIN), D ? A : 0); \
 | 
			
		||||
      else                                                \
 | 
			
		||||
        WRITE(P##_AUTO_FAN_PIN, D);                       \
 | 
			
		||||
    }while(0)
 | 
			
		||||
@@ -2321,74 +2321,33 @@ void Temperature::init() {
 | 
			
		||||
 | 
			
		||||
  TERN_(HAS_MAXTC_SW_SPI, max_tc_spi.init());
 | 
			
		||||
 | 
			
		||||
  HAL_adc_init();
 | 
			
		||||
  hal.adc_init();
 | 
			
		||||
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_0,         hal.adc_enable(TEMP_0_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_1,         hal.adc_enable(TEMP_1_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_2,         hal.adc_enable(TEMP_2_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_3,         hal.adc_enable(TEMP_3_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_4,         hal.adc_enable(TEMP_4_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_5,         hal.adc_enable(TEMP_5_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_6,         hal.adc_enable(TEMP_6_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_7,         hal.adc_enable(TEMP_7_PIN));
 | 
			
		||||
  TERN_(HAS_JOY_ADC_X,          hal.adc_enable(JOY_X_PIN));
 | 
			
		||||
  TERN_(HAS_JOY_ADC_Y,          hal.adc_enable(JOY_Y_PIN));
 | 
			
		||||
  TERN_(HAS_JOY_ADC_Z,          hal.adc_enable(JOY_Z_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_BED,       hal.adc_enable(TEMP_BED_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_CHAMBER,   hal.adc_enable(TEMP_CHAMBER_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_PROBE,     hal.adc_enable(TEMP_PROBE_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_COOLER,    hal.adc_enable(TEMP_COOLER_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_BOARD,     hal.adc_enable(TEMP_BOARD_PIN));
 | 
			
		||||
  TERN_(HAS_TEMP_ADC_REDUNDANT, hal.adc_enable(TEMP_REDUNDANT_PIN));
 | 
			
		||||
  TERN_(FILAMENT_WIDTH_SENSOR,  hal.adc_enable(FILWIDTH_PIN));
 | 
			
		||||
  TERN_(HAS_ADC_BUTTONS,        hal.adc_enable(ADC_KEYPAD_PIN));
 | 
			
		||||
  TERN_(POWER_MONITOR_CURRENT,  hal.adc_enable(POWER_MONITOR_CURRENT_PIN));
 | 
			
		||||
  TERN_(POWER_MONITOR_VOLTAGE,  hal.adc_enable(POWER_MONITOR_VOLTAGE_PIN));
 | 
			
		||||
 | 
			
		||||
  #if HAS_TEMP_ADC_0
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_0_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_1
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_1_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_2
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_2_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_3
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_3_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_4
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_4_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_5
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_5_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_6
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_6_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_7
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_7_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_JOY_ADC_X
 | 
			
		||||
    HAL_ANALOG_SELECT(JOY_X_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_JOY_ADC_Y
 | 
			
		||||
    HAL_ANALOG_SELECT(JOY_Y_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_JOY_ADC_Z
 | 
			
		||||
    HAL_ANALOG_SELECT(JOY_Z_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_JOY_ADC_EN
 | 
			
		||||
    SET_INPUT_PULLUP(JOY_EN_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_BED
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_BED_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_CHAMBER
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_CHAMBER_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_PROBE
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_PROBE_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_COOLER
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_COOLER_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_BOARD
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_BOARD_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_TEMP_ADC_REDUNDANT
 | 
			
		||||
    HAL_ANALOG_SELECT(TEMP_REDUNDANT_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(FILAMENT_WIDTH_SENSOR)
 | 
			
		||||
    HAL_ANALOG_SELECT(FILWIDTH_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if HAS_ADC_BUTTONS
 | 
			
		||||
    HAL_ANALOG_SELECT(ADC_KEYPAD_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(POWER_MONITOR_CURRENT)
 | 
			
		||||
    HAL_ANALOG_SELECT(POWER_MONITOR_CURRENT_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
  #if ENABLED(POWER_MONITOR_VOLTAGE)
 | 
			
		||||
    HAL_ANALOG_SELECT(POWER_MONITOR_VOLTAGE_PIN);
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  HAL_timer_start(MF_TIMER_TEMP, TEMP_TIMER_FREQUENCY);
 | 
			
		||||
  ENABLE_TEMPERATURE_INTERRUPT();
 | 
			
		||||
@@ -3364,8 +3323,8 @@ void Temperature::isr() {
 | 
			
		||||
   * This gives each ADC 0.9765ms to charge up.
 | 
			
		||||
   */
 | 
			
		||||
  #define ACCUMULATE_ADC(obj) do{ \
 | 
			
		||||
    if (!HAL_ADC_READY()) next_sensor_state = adc_sensor_state; \
 | 
			
		||||
    else obj.sample(HAL_READ_ADC()); \
 | 
			
		||||
    if (!hal.adc_ready()) next_sensor_state = adc_sensor_state; \
 | 
			
		||||
    else obj.sample(hal.adc_value()); \
 | 
			
		||||
  }while(0)
 | 
			
		||||
 | 
			
		||||
  ADCSensorState next_sensor_state = adc_sensor_state < SensorsReady ? (ADCSensorState)(int(adc_sensor_state) + 1) : StartSampling;
 | 
			
		||||
@@ -3397,115 +3356,115 @@ void Temperature::isr() {
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_0
 | 
			
		||||
      case PrepareTemp_0: HAL_START_ADC(TEMP_0_PIN); break;
 | 
			
		||||
      case PrepareTemp_0: hal.adc_start(TEMP_0_PIN); break;
 | 
			
		||||
      case MeasureTemp_0: ACCUMULATE_ADC(temp_hotend[0]); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_BED
 | 
			
		||||
      case PrepareTemp_BED: HAL_START_ADC(TEMP_BED_PIN); break;
 | 
			
		||||
      case PrepareTemp_BED: hal.adc_start(TEMP_BED_PIN); break;
 | 
			
		||||
      case MeasureTemp_BED: ACCUMULATE_ADC(temp_bed); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_CHAMBER
 | 
			
		||||
      case PrepareTemp_CHAMBER: HAL_START_ADC(TEMP_CHAMBER_PIN); break;
 | 
			
		||||
      case PrepareTemp_CHAMBER: hal.adc_start(TEMP_CHAMBER_PIN); break;
 | 
			
		||||
      case MeasureTemp_CHAMBER: ACCUMULATE_ADC(temp_chamber); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_COOLER
 | 
			
		||||
      case PrepareTemp_COOLER: HAL_START_ADC(TEMP_COOLER_PIN); break;
 | 
			
		||||
      case PrepareTemp_COOLER: hal.adc_start(TEMP_COOLER_PIN); break;
 | 
			
		||||
      case MeasureTemp_COOLER: ACCUMULATE_ADC(temp_cooler); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_PROBE
 | 
			
		||||
      case PrepareTemp_PROBE: HAL_START_ADC(TEMP_PROBE_PIN); break;
 | 
			
		||||
      case PrepareTemp_PROBE: hal.adc_start(TEMP_PROBE_PIN); break;
 | 
			
		||||
      case MeasureTemp_PROBE: ACCUMULATE_ADC(temp_probe); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_BOARD
 | 
			
		||||
      case PrepareTemp_BOARD: HAL_START_ADC(TEMP_BOARD_PIN); break;
 | 
			
		||||
      case PrepareTemp_BOARD: hal.adc_start(TEMP_BOARD_PIN); break;
 | 
			
		||||
      case MeasureTemp_BOARD: ACCUMULATE_ADC(temp_board); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_REDUNDANT
 | 
			
		||||
      case PrepareTemp_REDUNDANT: HAL_START_ADC(TEMP_REDUNDANT_PIN); break;
 | 
			
		||||
      case PrepareTemp_REDUNDANT: hal.adc_start(TEMP_REDUNDANT_PIN); break;
 | 
			
		||||
      case MeasureTemp_REDUNDANT: ACCUMULATE_ADC(temp_redundant); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_1
 | 
			
		||||
      case PrepareTemp_1: HAL_START_ADC(TEMP_1_PIN); break;
 | 
			
		||||
      case PrepareTemp_1: hal.adc_start(TEMP_1_PIN); break;
 | 
			
		||||
      case MeasureTemp_1: ACCUMULATE_ADC(temp_hotend[1]); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_2
 | 
			
		||||
      case PrepareTemp_2: HAL_START_ADC(TEMP_2_PIN); break;
 | 
			
		||||
      case PrepareTemp_2: hal.adc_start(TEMP_2_PIN); break;
 | 
			
		||||
      case MeasureTemp_2: ACCUMULATE_ADC(temp_hotend[2]); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_3
 | 
			
		||||
      case PrepareTemp_3: HAL_START_ADC(TEMP_3_PIN); break;
 | 
			
		||||
      case PrepareTemp_3: hal.adc_start(TEMP_3_PIN); break;
 | 
			
		||||
      case MeasureTemp_3: ACCUMULATE_ADC(temp_hotend[3]); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_4
 | 
			
		||||
      case PrepareTemp_4: HAL_START_ADC(TEMP_4_PIN); break;
 | 
			
		||||
      case PrepareTemp_4: hal.adc_start(TEMP_4_PIN); break;
 | 
			
		||||
      case MeasureTemp_4: ACCUMULATE_ADC(temp_hotend[4]); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_5
 | 
			
		||||
      case PrepareTemp_5: HAL_START_ADC(TEMP_5_PIN); break;
 | 
			
		||||
      case PrepareTemp_5: hal.adc_start(TEMP_5_PIN); break;
 | 
			
		||||
      case MeasureTemp_5: ACCUMULATE_ADC(temp_hotend[5]); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_6
 | 
			
		||||
      case PrepareTemp_6: HAL_START_ADC(TEMP_6_PIN); break;
 | 
			
		||||
      case PrepareTemp_6: hal.adc_start(TEMP_6_PIN); break;
 | 
			
		||||
      case MeasureTemp_6: ACCUMULATE_ADC(temp_hotend[6]); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_TEMP_ADC_7
 | 
			
		||||
      case PrepareTemp_7: HAL_START_ADC(TEMP_7_PIN); break;
 | 
			
		||||
      case PrepareTemp_7: hal.adc_start(TEMP_7_PIN); break;
 | 
			
		||||
      case MeasureTemp_7: ACCUMULATE_ADC(temp_hotend[7]); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(FILAMENT_WIDTH_SENSOR)
 | 
			
		||||
      case Prepare_FILWIDTH: HAL_START_ADC(FILWIDTH_PIN); break;
 | 
			
		||||
      case Prepare_FILWIDTH: hal.adc_start(FILWIDTH_PIN); break;
 | 
			
		||||
      case Measure_FILWIDTH:
 | 
			
		||||
        if (!HAL_ADC_READY()) next_sensor_state = adc_sensor_state; // Redo this state
 | 
			
		||||
        else filwidth.accumulate(HAL_READ_ADC());
 | 
			
		||||
        if (!hal.adc_ready()) next_sensor_state = adc_sensor_state; // Redo this state
 | 
			
		||||
        else filwidth.accumulate(hal.adc_value());
 | 
			
		||||
      break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(POWER_MONITOR_CURRENT)
 | 
			
		||||
      case Prepare_POWER_MONITOR_CURRENT:
 | 
			
		||||
        HAL_START_ADC(POWER_MONITOR_CURRENT_PIN);
 | 
			
		||||
        hal.adc_start(POWER_MONITOR_CURRENT_PIN);
 | 
			
		||||
        break;
 | 
			
		||||
      case Measure_POWER_MONITOR_CURRENT:
 | 
			
		||||
        if (!HAL_ADC_READY()) next_sensor_state = adc_sensor_state; // Redo this state
 | 
			
		||||
        else power_monitor.add_current_sample(HAL_READ_ADC());
 | 
			
		||||
        if (!hal.adc_ready()) next_sensor_state = adc_sensor_state; // Redo this state
 | 
			
		||||
        else power_monitor.add_current_sample(hal.adc_value());
 | 
			
		||||
        break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(POWER_MONITOR_VOLTAGE)
 | 
			
		||||
      case Prepare_POWER_MONITOR_VOLTAGE:
 | 
			
		||||
        HAL_START_ADC(POWER_MONITOR_VOLTAGE_PIN);
 | 
			
		||||
        hal.adc_start(POWER_MONITOR_VOLTAGE_PIN);
 | 
			
		||||
        break;
 | 
			
		||||
      case Measure_POWER_MONITOR_VOLTAGE:
 | 
			
		||||
        if (!HAL_ADC_READY()) next_sensor_state = adc_sensor_state; // Redo this state
 | 
			
		||||
        else power_monitor.add_voltage_sample(HAL_READ_ADC());
 | 
			
		||||
        if (!hal.adc_ready()) next_sensor_state = adc_sensor_state; // Redo this state
 | 
			
		||||
        else power_monitor.add_voltage_sample(hal.adc_value());
 | 
			
		||||
        break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_JOY_ADC_X
 | 
			
		||||
      case PrepareJoy_X: HAL_START_ADC(JOY_X_PIN); break;
 | 
			
		||||
      case PrepareJoy_X: hal.adc_start(JOY_X_PIN); break;
 | 
			
		||||
      case MeasureJoy_X: ACCUMULATE_ADC(joystick.x); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_JOY_ADC_Y
 | 
			
		||||
      case PrepareJoy_Y: HAL_START_ADC(JOY_Y_PIN); break;
 | 
			
		||||
      case PrepareJoy_Y: hal.adc_start(JOY_Y_PIN); break;
 | 
			
		||||
      case MeasureJoy_Y: ACCUMULATE_ADC(joystick.y); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if HAS_JOY_ADC_Z
 | 
			
		||||
      case PrepareJoy_Z: HAL_START_ADC(JOY_Z_PIN); break;
 | 
			
		||||
      case PrepareJoy_Z: hal.adc_start(JOY_Z_PIN); break;
 | 
			
		||||
      case MeasureJoy_Z: ACCUMULATE_ADC(joystick.z); break;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
@@ -3513,12 +3472,12 @@ void Temperature::isr() {
 | 
			
		||||
      #ifndef ADC_BUTTON_DEBOUNCE_DELAY
 | 
			
		||||
        #define ADC_BUTTON_DEBOUNCE_DELAY 16
 | 
			
		||||
      #endif
 | 
			
		||||
      case Prepare_ADC_KEY: HAL_START_ADC(ADC_KEYPAD_PIN); break;
 | 
			
		||||
      case Prepare_ADC_KEY: hal.adc_start(ADC_KEYPAD_PIN); break;
 | 
			
		||||
      case Measure_ADC_KEY:
 | 
			
		||||
        if (!HAL_ADC_READY())
 | 
			
		||||
        if (!hal.adc_ready())
 | 
			
		||||
          next_sensor_state = adc_sensor_state; // redo this state
 | 
			
		||||
        else if (ADCKey_count < ADC_BUTTON_DEBOUNCE_DELAY) {
 | 
			
		||||
          raw_ADCKey_value = HAL_READ_ADC();
 | 
			
		||||
          raw_ADCKey_value = hal.adc_value();
 | 
			
		||||
          if (raw_ADCKey_value <= 900UL * HAL_ADC_RANGE / 1024UL) {
 | 
			
		||||
            NOMORE(current_ADCKey_raw, raw_ADCKey_value);
 | 
			
		||||
            ADCKey_count++;
 | 
			
		||||
 
 | 
			
		||||
@@ -233,7 +233,7 @@ HAS_SERVOS                             = src_filter=+<src/module/servo.cpp> +<sr
 | 
			
		||||
MORGAN_SCARA                           = src_filter=+<src/gcode/scara>
 | 
			
		||||
HAS_MICROSTEPS                         = src_filter=+<src/gcode/control/M350_M351.cpp>
 | 
			
		||||
(ESP3D_)?WIFISUPPORT                   = AsyncTCP, ESP Async WebServer
 | 
			
		||||
                                         ESP3DLib=https://github.com/luc-github/ESP3DLib/archive/master.zip
 | 
			
		||||
                                         ESP3DLib=https://github.com/luc-github/ESP3DLib/archive/master-2.0.7.zip
 | 
			
		||||
                                         arduinoWebSockets=links2004/WebSockets@2.3.4
 | 
			
		||||
                                         luc-github/ESP32SSDP@^1.1.1
 | 
			
		||||
                                         lib_ignore=ESPAsyncTCP
 | 
			
		||||
 
 | 
			
		||||
@@ -34,14 +34,14 @@ src_filter      = ${common.default_src_filter} +<src/HAL/LINUX>
 | 
			
		||||
[simulator_common]
 | 
			
		||||
platform          = native
 | 
			
		||||
framework         =
 | 
			
		||||
build_flags       = ${common.build_flags} -std=gnu++17 -D__PLAT_NATIVE_SIM__ -DU8G_HAL_LINKS -I/usr/include/SDL2 -IMarlin -IMarlin/src/HAL/NATIVE_SIM/include -IMarlin/src/HAL/NATIVE_SIM/u8g
 | 
			
		||||
build_flags       = ${common.build_flags} -std=gnu++17 -D__PLAT_NATIVE_SIM__ -DU8G_HAL_LINKS -I/usr/include/SDL2 -IMarlin -IMarlin/src/HAL/NATIVE_SIM/u8g
 | 
			
		||||
src_build_flags   = -Wall -Wno-expansion-to-defined -Wcast-align
 | 
			
		||||
release_flags     = -g0 -O3 -flto
 | 
			
		||||
debug_build_flags = -fstack-protector-strong -g -g3 -ggdb
 | 
			
		||||
lib_compat_mode   = off
 | 
			
		||||
src_filter        = ${common.default_src_filter} +<src/HAL/NATIVE_SIM>
 | 
			
		||||
lib_deps          = ${common.lib_deps}
 | 
			
		||||
  MarlinSimUI=https://github.com/p3p/MarlinSimUI/archive/master.zip
 | 
			
		||||
  MarlinSimUI=https://github.com/p3p/MarlinSimUI/archive/0.0.2.zip
 | 
			
		||||
  Adafruit NeoPixel=https://github.com/p3p/Adafruit_NeoPixel/archive/marlin_sim_native.zip
 | 
			
		||||
  LiquidCrystal=https://github.com/p3p/LiquidCrystal/archive/master.zip
 | 
			
		||||
extra_scripts = ${common.extra_scripts}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ build_flags      = ${common.build_flags}
 | 
			
		||||
                   -std=gnu++14 -DHAL_STM32
 | 
			
		||||
                   -DUSBCON -DUSBD_USE_CDC
 | 
			
		||||
                   -DTIM_IRQ_PRIO=13
 | 
			
		||||
                   -DADC_RESOLUTION=12
 | 
			
		||||
build_unflags    = -std=gnu++11
 | 
			
		||||
src_filter       = ${common.default_src_filter} +<src/HAL/STM32> +<src/HAL/shared/backtrace>
 | 
			
		||||
extra_scripts    = ${common.extra_scripts}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,6 @@ board                       = marlin_STM32G0B1RE
 | 
			
		||||
board_build.offset          = 0x2000
 | 
			
		||||
board_upload.offset_address = 0x08002000
 | 
			
		||||
build_flags                 = ${stm32_variant.build_flags}
 | 
			
		||||
                            -DADC_RESOLUTION=12
 | 
			
		||||
                            -DPIN_SERIAL4_RX=PC_11 -DPIN_SERIAL4_TX=PC_10
 | 
			
		||||
                            -DSERIAL_RX_BUFFER_SIZE=1024 -DSERIAL_TX_BUFFER_SIZE=1024
 | 
			
		||||
                            -DTIMER_SERVO=TIM3 -DTIMER_TONE=TIM4
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user