♻️ Refactor HAL as singleton (#23357, #23871, #23897)

This commit is contained in:
Scott Lahteine
2022-02-17 18:50:31 -06:00
committed by Scott Lahteine
parent 428b67db31
commit 56cec9690a
81 changed files with 1976 additions and 1418 deletions

View File

@ -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;

View File

@ -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]
*/
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
// 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]
*/
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);
};

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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