Merge branch 'bugfix-2.0.x' into Trex_2.0.x_Devel

This commit is contained in:
InsanityAutomation
2022-03-08 17:32:43 -05:00
1050 changed files with 32220 additions and 13883 deletions
+2 -2
View File
@@ -66,7 +66,7 @@ jobs:
- mks_robin_lite_maple
- mks_robin_pro_maple
#- mks_robin_nano35_maple
#- STM32F103RET6_creality_maple
#- STM32F103RE_creality_maple
- STM32F103VE_ZM3E4V2_USB_maple
# STM32 (ST) Environments
@@ -75,7 +75,7 @@ jobs:
#- STM32F103RC_btt_USB
- STM32F103RE_btt
- STM32F103RE_btt_USB
- STM32F103RET6_creality
- STM32F103RE_creality
- STM32F103VE_longer
- STM32F407VE_black
- STM32F401VE_STEVAL
+9 -11
View File
@@ -22,12 +22,16 @@
# Generated files
_Version.h
bdf2u8g
marlin_config.json
mczip.h
*.gen
*.sublime-workspace
#
# OS
#
applet/
*.DS_Store
.DS_Store
#
# Misc
@@ -37,7 +41,6 @@ applet/
*.rej
*.bak
*.idea
*.s
*.i
*.ii
*.swp
@@ -137,20 +140,19 @@ __vm/
vc-fileutils.settings
# Visual Studio Code
.vscode
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/*.db
.vscode/*
!.vscode/extensions.json
#Simulation
imgui.ini
eeprom.dat
spi_flash.bin
#cmake
CMakeLists.txt
src/CMakeLists.txt
CMakeListsPrivate.txt
build/
# CLion
cmake-build-*
@@ -167,7 +169,3 @@ __pycache__
# IOLogger logs
*_log.csv
# Simulation / Native
eeprom.dat
imgui.ini
+11
View File
@@ -0,0 +1,11 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"marlinfirmware.auto-build",
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}
+79 -49
View File
@@ -99,7 +99,7 @@
*
* Advanced settings can be found in Configuration_adv.h
*/
#define CONFIGURATION_H_VERSION 02000902
#define CONFIGURATION_H_VERSION 02000903
//===========================================================================
//============================= Getting Started =============================
@@ -158,6 +158,17 @@
// @section machine
// Choose the name from boards.h that matches your setup
#ifndef MOTHERBOARD
#if ENABLED(SKR12Pro)
#define MOTHERBOARD BOARD_BTT_SKR_PRO_V1_2
#elif ENABLED(TREX3)
#define MOTHERBOARD BOARD_FORMBOT_TREX3
#else
#define MOTHERBOARD BOARD_FORMBOT_TREX2PLUS
#endif
#endif
/**
* Select the serial port on the board to use for communication with the host.
* This allows the connection of wireless adapters (for instance) to non-default port pins.
@@ -207,17 +218,6 @@
// Enable the Bluetooth serial interface on AT90USB devices
//#define BLUETOOTH
// Choose the name from boards.h that matches your setup
#ifndef MOTHERBOARD
#if ENABLED(SKR12Pro)
#define MOTHERBOARD BOARD_BTT_SKR_PRO_V1_2
#elif ENABLED(TREX3)
#define MOTHERBOARD BOARD_FORMBOT_TREX3
#else
#define MOTHERBOARD BOARD_FORMBOT_TREX2PLUS
#endif
#endif
// Optional custom name for your RepStrap or other custom machine
// Displayed in the LCD "Ready" message
#if ENABLED(TREX3_UPGRADE)
@@ -343,7 +343,6 @@
#define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders
#define PARKING_EXTRUDER_GRAB_DISTANCE 1 // (mm) Distance to move beyond the parking point to grab the extruder
//#define MANUAL_SOLENOID_CONTROL // Manual control of docking solenoids with M380 S / M381
#if ENABLED(PARKING_EXTRUDER)
@@ -460,8 +459,12 @@
//#define PS_OFF_SOUND // Beep 1s when power off
#define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box
//#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
//#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power
//#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
//#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power
//#define LED_POWEROFF_TIMEOUT 10000 // (ms) Turn off LEDs after power-off, with this amount of delay
//#define POWER_OFF_TIMER // Enable M81 D<seconds> to power off after a delay
//#define POWER_OFF_WAIT_FOR_COOLDOWN // Enable M81 S to power off only after cooldown
//#define PSU_POWERUP_GCODE "M355 S1" // G-code to run after power-on (e.g., case light on)
//#define PSU_POWEROFF_GCODE "M355 S0" // G-code to run before power-off (e.g., case light off)
@@ -473,12 +476,14 @@
#define AUTO_POWER_CONTROLLERFAN
#define AUTO_POWER_CHAMBER_FAN
#define AUTO_POWER_COOLER_FAN
//#define AUTO_POWER_E_TEMP 50 // (°C) Turn on PSU if any extruder is over this temperature
//#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) Turn on PSU if the chamber is over this temperature
//#define AUTO_POWER_COOLER_TEMP 26 // (°C) Turn on PSU if the cooler is over this temperature
#define POWER_TIMEOUT 30 // (s) Turn off power if the machine is idle for this duration
//#define POWER_OFF_DELAY 60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time.
#endif
#if EITHER(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN)
//#define AUTO_POWER_E_TEMP 50 // (°C) PSU on if any extruder is over this temperature
//#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) PSU on if the chamber is over this temperature
//#define AUTO_POWER_COOLER_TEMP 26 // (°C) PSU on if the cooler is over this temperature
#endif
#endif
//===========================================================================
@@ -520,6 +525,9 @@
* 5 : 100kΩ ATC Semitec 104GT-2/104NT-4-R025H42G - Used in ParCan, J-Head, and E3D, SliceEngineering 300°C
* 501 : 100kΩ Zonestar - Tronxy X3A
* 502 : 100kΩ Zonestar - used by hot bed in Zonestar Průša P802M
* 503 : 100kΩ Zonestar (Z8XM2) Heated Bed thermistor
* 504 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-B3950) Hotend Thermistor
* 505 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-3950) Bed Thermistor
* 512 : 100kΩ RPW-Ultra hotend
* 6 : 100kΩ EPCOS - Not as accurate as table #1 (created using a fluke thermocouple)
* 7 : 100kΩ Honeywell 135-104LAG-J01
@@ -539,6 +547,7 @@
* 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950
* 66 : 4.7MΩ Dyze Design High Temperature Thermistor
* 67 : 500kΩ SliceEngineering 450°C Thermistor
* 68 : PT100 amplifier board from Dyze Design
* 70 : 100kΩ bq Hephestos 2
* 75 : 100kΩ Generic Silicon Heat Pad with NTC100K MGB18-104F39050L32
* 2000 : 100kΩ Ultimachine Rambo TDK NTCG104LH104KT1 NTC100K motherboard Thermistor
@@ -875,6 +884,7 @@
//#define COREZX
//#define COREZY
//#define MARKFORGED_XY // MarkForged. See https://reprap.org/forum/read.php?152,504042
//#define MARKFORGED_YX
// Enable for a belt style printer with endless "Z" motion
//#define BELTPRINTER
@@ -1268,6 +1278,17 @@
*/
#define BLTOUCH
/**
* MagLev V4 probe by MDD
*
* This probe is deployed and activated by powering a built-in electromagnet.
*/
//#define MAGLEV4
#if ENABLED(MAGLEV4)
//#define MAGLEV_TRIGGER_PIN 11 // Set to the connected digital output
#define MAGLEV_TRIGGER_DELAY 15 // Changing this risks overheating the coil
#endif
/**
* Touch-MI Probe by hotends.fr
*
@@ -1404,6 +1425,15 @@
#endif
#endif
/**
* Probe Enable / Disable
* The probe only provides a triggered signal when enabled.
*/
//#define PROBE_ENABLE_DISABLE
#if ENABLED(PROBE_ENABLE_DISABLE)
//#define PROBE_ENABLE_PIN -1 // Override the default pin here
#endif
/**
* Multiple Probing
*
@@ -2059,6 +2089,7 @@
#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load
#if ENABLED(EEPROM_SETTINGS)
#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors.
#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build.
#endif
//
@@ -2114,8 +2145,7 @@
#if ENABLED(NOZZLE_PARK_FEATURE)
// Specify a park position as { X, Y, Z_raise }
#define NOZZLE_PARK_POINT { 150, (Y_MIN_POS + 10), 10 }
//#define NOZZLE_PARK_X_ONLY // X move only is required to park
//#define NOZZLE_PARK_Y_ONLY // Y move only is required to park
#define NOZZLE_PARK_MOVE 0 // Park motion: 0 = XY Move, 1 = X Only, 2 = Y Only, 3 = X before Y, 4 = Y before X
#define NOZZLE_PARK_Z_RAISE_MIN 2 // (mm) Always raise Z by at least this distance
#define NOZZLE_PARK_XY_FEEDRATE 100 // (mm/s) X and Y axes feedrate (also used for delta Z axis)
#define NOZZLE_PARK_Z_FEEDRATE 5 // (mm/s) Z axis feedrate (not used for delta printers)
@@ -2681,6 +2711,11 @@
//#define FYSETC_MINI_12864_2_1 // Type A/B. NeoPixel RGB Backlight
//#define FYSETC_GENERIC_12864_1_1 // Larger display with basic ON/OFF backlight.
//
// BigTreeTech Mini 12864 V1.0 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight.
//
//#define BTT_MINI_12864_V1
//
// Factory display for Creality CR-10
// https://www.aliexpress.com/item/32833148327.html
@@ -2873,32 +2908,32 @@
*/
//
// 480x320, 3.5", SPI Display From MKS
// Normally used in MKS Robin Nano V2
// 480x320, 3.5", SPI Display with Rotary Encoder from MKS
// Usually paired with MKS Robin Nano V2 & V3
//
//#define MKS_TS35_V2_0
//
// 320x240, 2.4", FSMC Display From MKS
// Normally used in MKS Robin Nano V1.2
// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT24
//
// 320x240, 2.8", FSMC Display From MKS
// Normally used in MKS Robin Nano V1.2
// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT28
//
// 320x240, 3.2", FSMC Display From MKS
// Normally used in MKS Robin Nano V1.2
// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT32
//
// 480x320, 3.5", FSMC Display From MKS
// Normally used in MKS Robin Nano V1.2
// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT35
@@ -2909,7 +2944,7 @@
//
// 320x240, 3.2", FSMC Display From MKS
// Normally used in MKS Robin
// Usually paired with MKS Robin
//
//#define MKS_ROBIN_TFT_V1_1R
@@ -2939,10 +2974,15 @@
//#define ANET_ET5_TFT35
//
// 1024x600, 7", RGB Stock Display from BIQU-BX
// 1024x600, 7", RGB Stock Display with Rotary Encoder from BIQU-BX
//
//#define BIQU_BX_TFT70
//
// 480x320, 3.5", SPI Stock Display with Rotary Encoder from BIQU B1 SE Series
//
//#define BTT_TFT35_SPI_V1_0
//
// Generic TFT with detailed options
//
@@ -2997,23 +3037,11 @@
//
// Ender-3 v2 OEM display. A DWIN display with Rotary Encoder.
//
//#define DWIN_CREALITY_LCD
//
// Ender-3 v2 OEM display, enhanced.
//
//#define DWIN_CREALITY_LCD_ENHANCED
//
// Ender-3 v2 OEM display with enhancements by Jacob Myers
//
//#define DWIN_CREALITY_LCD_JYERSUI
//
// MarlinUI for Creality's DWIN display (and others)
//
//#define DWIN_MARLINUI_PORTRAIT
//#define DWIN_MARLINUI_LANDSCAPE
//#define DWIN_CREALITY_LCD // Creality UI
//#define DWIN_CREALITY_LCD_ENHANCED // Enhanced UI
//#define DWIN_CREALITY_LCD_JYERSUI // Jyers UI by Jacob Myers
//#define DWIN_MARLINUI_PORTRAIT // MarlinUI (portrait orientation)
//#define DWIN_MARLINUI_LANDSCAPE // MarlinUI (landscape orientation)
//
// Touch Screen Settings
@@ -3023,7 +3051,7 @@
#define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
//#define TOUCH_IDLE_SLEEP 300 // (secs) Turn off the TFT backlight if set (5mn)
//#define TOUCH_IDLE_SLEEP 300 // (s) Turn off the TFT backlight if set (5mn)
#define TOUCH_SCREEN_CALIBRATION
@@ -3049,6 +3077,11 @@
//#define REPRAPWORLD_KEYPAD
//#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // (mm) Distance to move per key-press
//
// EasyThreeD ET-4000+ with button input and status LED
//
//#define EASYTHREED_UI
//=============================================================================
//=============================== Extra Features ==============================
//=============================================================================
@@ -3059,9 +3092,6 @@
// :[1,2,3,4,5,6,7,8]
//#define NUM_M106_FANS 1
// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino
//#define FAST_PWM_FAN
// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency
// which is not as annoying as with the hardware PWM. On the other hand, if this frequency
// is too low, you should also increment SOFT_PWM_SCALE.
+303 -166
View File
@@ -30,7 +30,7 @@
*
* Basic settings can be found in Configuration.h
*/
#define CONFIGURATION_ADV_H_VERSION 02000902
#define CONFIGURATION_ADV_H_VERSION 02000903
//===========================================================================
//============================= Thermal Settings ============================
@@ -138,15 +138,21 @@
#endif
/**
* Configuration options for MAX Thermocouples (-2, -3, -5).
* FORCE_HW_SPI: Ignore SCK/MOSI/MISO pins and just use the CS pin & default SPI bus.
* MAX31865_WIRES: Set the number of wires for the probe connected to a MAX31865 board, 2-4. Default: 2
* MAX31865_50HZ: Enable 50Hz filter instead of the default 60Hz.
* Thermocouple Options for MAX6675 (-2), MAX31855 (-3), and MAX31865 (-5).
*/
//#define TEMP_SENSOR_FORCE_HW_SPI
//#define MAX31865_SENSOR_WIRES_0 2
//#define TEMP_SENSOR_FORCE_HW_SPI // Ignore SCK/MOSI/MISO pins; use CS and the default SPI bus.
//#define MAX31865_SENSOR_WIRES_0 2 // (2-4) Number of wires for the probe connected to a MAX31865 board.
//#define MAX31865_SENSOR_WIRES_1 2
//#define MAX31865_50HZ_FILTER
//#define MAX31865_50HZ_FILTER // Use a 50Hz filter instead of the default 60Hz.
//#define MAX31865_USE_READ_ERROR_DETECTION // Treat value spikes (20°C delta in under 1s) as read errors.
//#define MAX31865_USE_AUTO_MODE // Read faster and more often than 1-shot; bias voltage always on; slight effect on RTD temperature.
//#define MAX31865_MIN_SAMPLING_TIME_MSEC 100 // (ms) 1-shot: minimum read interval. Reduces bias voltage effects by leaving sensor unpowered for longer intervals.
//#define MAX31865_IGNORE_INITIAL_FAULTY_READS 10 // Ignore some read faults (keeping the temperature reading) to work around a possible issue (#23439).
//#define MAX31865_WIRE_OHMS_0 0.95f // For 2-wire, set the wire resistances for more accurate readings.
//#define MAX31865_WIRE_OHMS_1 0.0f
/**
* Hephestos 2 24V heated bed upgrade kit.
@@ -186,7 +192,8 @@
//#define CHAMBER_FAN // Enable a fan on the chamber
#if ENABLED(CHAMBER_FAN)
#define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve; 3=similar to 1 but fan is always on.
//#define CHAMBER_FAN_INDEX 2 // Index of a fan to repurpose as the chamber fan. (Default: first unused fan)
#define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve; 3=similar to 1 but fan is always on.
#if CHAMBER_FAN_MODE == 0
#define CHAMBER_FAN_BASE 255 // Chamber fan PWM (0-255)
#elif CHAMBER_FAN_MODE == 1
@@ -329,14 +336,22 @@
* Thermal Protection parameters for the laser cooler.
*/
#if ENABLED(THERMAL_PROTECTION_COOLER)
#define THERMAL_PROTECTION_COOLER_PERIOD 10 // Seconds
#define THERMAL_PROTECTION_COOLER_HYSTERESIS 3 // Degrees Celsius
#define THERMAL_PROTECTION_COOLER_PERIOD 10 // Seconds
#define THERMAL_PROTECTION_COOLER_HYSTERESIS 3 // Degrees Celsius
/**
* Laser cooling watch settings (M143/M193).
*/
#define WATCH_COOLER_TEMP_PERIOD 60 // Seconds
#define WATCH_COOLER_TEMP_INCREASE 3 // Degrees Celsius
#define WATCH_COOLER_TEMP_PERIOD 60 // Seconds
#define WATCH_COOLER_TEMP_INCREASE 3 // Degrees Celsius
#endif
#if ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_CHAMBER, THERMAL_PROTECTION_COOLER)
/**
* Thermal Protection Variance Monitor - EXPERIMENTAL.
* Kill the machine on a stuck temperature sensor. Disable if you get false positives.
*/
//#define THERMAL_PROTECTION_VARIANCE_MONITOR // Detect a sensor malfunction preventing temperature updates
#endif
#if ENABLED(PIDTEMP)
@@ -414,7 +429,7 @@
*/
#define AUTOTEMP
#if ENABLED(AUTOTEMP)
#define AUTOTEMP_OLDWEIGHT 0.98
#define AUTOTEMP_OLDWEIGHT 0.98 // Factor used to weight previous readings (0.0 < value < 1.0)
// Turn on AUTOTEMP on M104/M109 by default using proportions set here
//#define AUTOTEMP_PROPORTIONAL
#if ENABLED(AUTOTEMP_PROPORTIONAL)
@@ -539,30 +554,41 @@
//#define FAN_MAX_PWM 128
/**
* FAST PWM FAN Settings
* Fan Fast PWM
*
* Use to change the FAST FAN PWM frequency (if enabled in Configuration.h)
* Combinations of PWM Modes, prescale values and TOP resolutions are used internally to produce a
* frequency as close as possible to the desired frequency.
* Combinations of PWM Modes, prescale values and TOP resolutions are used internally
* to produce a frequency as close as possible to the desired frequency.
*
* FAST_PWM_FAN_FREQUENCY [undefined by default]
* FAST_PWM_FAN_FREQUENCY
* Set this to your desired frequency.
* If left undefined this defaults to F = F_CPU/(2*255*1)
* i.e., F = 31.4kHz on 16MHz microcontrollers or F = 39.2kHz on 20MHz microcontrollers.
* These defaults are the same as with the old FAST_PWM_FAN implementation - no migration is required
* For AVR, if left undefined this defaults to F = F_CPU/(2*255*1)
* i.e., F = 31.4kHz on 16MHz microcontrollers or F = 39.2kHz on 20MHz microcontrollers.
* For non AVR, if left undefined this defaults to F = 1Khz.
* This F value is only to protect the hardware from an absence of configuration
* and not to complete it when users are not aware that the frequency must be specifically set to support the target board.
*
* NOTE: Setting very low frequencies (< 10 Hz) may result in unexpected timer behavior.
* Setting very high frequencies can damage your hardware.
*
* USE_OCR2A_AS_TOP [undefined by default]
* Boards that use TIMER2 for PWM have limitations resulting in only a few possible frequencies on TIMER2:
* 16MHz MCUs: [62.5KHz, 31.4KHz (default), 7.8KHz, 3.92KHz, 1.95KHz, 977Hz, 488Hz, 244Hz, 60Hz, 122Hz, 30Hz]
* 20MHz MCUs: [78.1KHz, 39.2KHz (default), 9.77KHz, 4.9KHz, 2.44KHz, 1.22KHz, 610Hz, 305Hz, 153Hz, 76Hz, 38Hz]
* 16MHz MCUs: [62.5kHz, 31.4kHz (default), 7.8kHz, 3.92kHz, 1.95kHz, 977Hz, 488Hz, 244Hz, 60Hz, 122Hz, 30Hz]
* 20MHz MCUs: [78.1kHz, 39.2kHz (default), 9.77kHz, 4.9kHz, 2.44kHz, 1.22kHz, 610Hz, 305Hz, 153Hz, 76Hz, 38Hz]
* A greater range can be achieved by enabling USE_OCR2A_AS_TOP. But note that this option blocks the use of
* PWM on pin OC2A. Only use this option if you don't need PWM on 0C2A. (Check your schematic.)
* USE_OCR2A_AS_TOP sacrifices duty cycle control resolution to achieve this broader range of frequencies.
*/
//#define FAST_PWM_FAN // Increase the fan PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino
#if ENABLED(FAST_PWM_FAN)
//#define FAST_PWM_FAN_FREQUENCY 31400
//#define FAST_PWM_FAN_FREQUENCY 31400 // Define here to override the defaults below
//#define USE_OCR2A_AS_TOP
#ifndef FAST_PWM_FAN_FREQUENCY
#ifdef __AVR__
#define FAST_PWM_FAN_FREQUENCY ((F_CPU) / (2 * 255 * 1))
#else
#define FAST_PWM_FAN_FREQUENCY 1000U
#endif
#endif
#endif
/**
@@ -612,6 +638,40 @@
#define COOLER_AUTO_FAN_TEMPERATURE 18
#define COOLER_AUTO_FAN_SPEED 255
/**
* Hotend Cooling Fans tachometers
*
* Define one or more tachometer pins to enable fan speed
* monitoring, and reporting of fan speeds with M123.
*
* NOTE: Only works with fans up to 7000 RPM.
*/
//#define FOURWIRES_FANS // Needed with AUTO_FAN when 4-wire PWM fans are installed
//#define E0_FAN_TACHO_PIN -1
//#define E0_FAN_TACHO_PULLUP
//#define E0_FAN_TACHO_PULLDOWN
//#define E1_FAN_TACHO_PIN -1
//#define E1_FAN_TACHO_PULLUP
//#define E1_FAN_TACHO_PULLDOWN
//#define E2_FAN_TACHO_PIN -1
//#define E2_FAN_TACHO_PULLUP
//#define E2_FAN_TACHO_PULLDOWN
//#define E3_FAN_TACHO_PIN -1
//#define E3_FAN_TACHO_PULLUP
//#define E3_FAN_TACHO_PULLDOWN
//#define E4_FAN_TACHO_PIN -1
//#define E4_FAN_TACHO_PULLUP
//#define E4_FAN_TACHO_PULLDOWN
//#define E5_FAN_TACHO_PIN -1
//#define E5_FAN_TACHO_PULLUP
//#define E5_FAN_TACHO_PULLDOWN
//#define E6_FAN_TACHO_PIN -1
//#define E6_FAN_TACHO_PULLUP
//#define E6_FAN_TACHO_PULLDOWN
//#define E7_FAN_TACHO_PIN -1
//#define E7_FAN_TACHO_PULLUP
//#define E7_FAN_TACHO_PULLDOWN
/**
* Part-Cooling Fan Multiplexer
*
@@ -868,14 +928,14 @@
//#define BLTOUCH_FORCE_MODE_SET
/**
* Use "HIGH SPEED" mode for probing.
* Enable "HIGH SPEED" option for probing.
* Danger: Disable if your probe sometimes fails. Only suitable for stable well-adjusted systems.
* This feature was designed for Deltabots with very fast Z moves; however, higher speed Cartesians
* might be able to use it. If the machine can't raise Z fast enough the BLTouch may go into ALARM.
*
* This sets the default state. Can be changed through the SCD
* Set the default state here, change with 'M401 S' or UI, use M500 to save, M502 to reset.
*/
#define BLTOUCH_HS_MODE
#define BLTOUCH_HS_MODE true
// Safety: Enable voltage mode settings in the LCD menu.
//#define BLTOUCH_LCD_VOLTAGE_MENU
@@ -918,15 +978,17 @@
//#define Z_STEPPERS_ORIENTATION 0
#endif
// Provide Z stepper positions for more rapid convergence in bed alignment.
// Requires triple stepper drivers (i.e., set NUM_Z_STEPPER_DRIVERS to 3)
//#define Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS
#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
// Define Stepper XY positions for Z1, Z2, Z3 corresponding to
// the Z screw positions in the bed carriage.
// Define one position per Z stepper in stepper driver order.
#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } }
#else
/**
* Z Stepper positions for more rapid convergence in bed alignment.
* Requires NUM_Z_STEPPER_DRIVERS to be 3 or 4.
*
* Define Stepper XY positions for Z1, Z2, Z3... corresponding to the screw
* positions in the bed carriage, with one position per Z stepper in stepper
* driver order.
*/
//#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } }
#ifndef Z_STEPPER_ALIGN_STEPPER_XY
// Amplification factor. Used to scale the correction step up or down in case
// the stepper (spindle) position is farther out than the test point.
#define Z_STEPPER_ALIGN_AMP 1.0 // Use a value > 1.0 NOTE: This may cause instability!
@@ -1225,7 +1287,7 @@
// @section lcd
#if ANY(HAS_LCD_MENU, EXTENSIBLE_UI, HAS_DWIN_E3V2)
#if HAS_MANUAL_MOVE_MENU
#define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 2*60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel
#define FINE_MANUAL_MOVE 0.025 // (mm) Smallest manual move (< 0.1mm) applying to Z on most machines
#if IS_ULTIPANEL
@@ -1248,21 +1310,41 @@
#define FEEDRATE_CHANGE_BEEP_FREQUENCY 440
#endif
#if HAS_LCD_MENU
//
// LCD Backlight Timeout
//
//#define LCD_BACKLIGHT_TIMEOUT 30 // (s) Timeout before turning off the backlight
#if HAS_BED_PROBE && EITHER(HAS_MARLINUI_MENU, HAS_TFT_LVGL_UI)
//#define PROBE_OFFSET_WIZARD // Add a Probe Z Offset calibration option to the LCD menu
#if ENABLED(PROBE_OFFSET_WIZARD)
/**
* Enable to init the Probe Z-Offset when starting the Wizard.
* Use a height slightly above the estimated nozzle-to-probe Z offset.
* For example, with an offset of -5, consider a starting height of -4.
*/
//#define PROBE_OFFSET_WIZARD_START_Z -4.0
// Set a convenient position to do the calibration (probing point and nozzle/bed-distance)
//#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER }
#endif
#endif
#if HAS_MARLINUI_MENU
// Add Probe Z Offset calibration to the Z Probe Offsets menu
#if HAS_BED_PROBE
//#define PROBE_OFFSET_WIZARD
#if ENABLED(PROBE_OFFSET_WIZARD)
//
// Enable to init the Probe Z-Offset when starting the Wizard.
// Use a height slightly above the estimated nozzle-to-probe Z offset.
// For example, with an offset of -5, consider a starting height of -4.
//
//#define PROBE_OFFSET_WIZARD_START_Z -4.0
// Set a convenient position to do the calibration (probing point and nozzle/bed-distance)
//#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER }
// Add calibration in the Probe Offsets menu to compensate for X-axis twist.
//#define X_AXIS_TWIST_COMPENSATION
#if ENABLED(X_AXIS_TWIST_COMPENSATION)
/**
* Enable to init the Probe Z-Offset when starting the Wizard.
* Use a height slightly above the estimated nozzle-to-probe Z offset.
* For example, with an offset of -5, consider a starting height of -4.
*/
#define XATC_START_Z 0.0
#define XATC_MAX_POINTS 3 // Number of points to probe in the wizard
#define XATC_Y_POSITION Y_CENTER // (mm) Y position to probe
#define XATC_Z_OFFSETS { 0, 0, 0 } // Z offsets for X axis sample points
#endif
#endif
@@ -1275,8 +1357,37 @@
// BACK menu items keep the highlight at the top
//#define TURBO_BACK_MENU_ITEM
// Add a mute option to the LCD menu
//#define SOUND_MENU_ITEM
// Insert a menu for preheating at the top level to allow for quick access
//#define PREHEAT_SHORTCUT_MENU_ITEM
#endif // HAS_MARLINUI_MENU
#if ANY(HAS_DISPLAY, DWIN_CREALITY_LCD_ENHANCED, DWIN_CREALITY_LCD_JYERSUI)
//#define SOUND_MENU_ITEM // Add a mute option to the LCD menu
#endif
#if EITHER(HAS_DISPLAY, DWIN_CREALITY_LCD_ENHANCED)
// The timeout (in ms) to return to the status screen from sub-menus
//#define LCD_TIMEOUT_TO_STATUS 15000
#if ENABLED(SHOW_BOOTSCREEN)
#define BOOTSCREEN_TIMEOUT 4000 // (ms) Total Duration to display the boot screen(s)
#if EITHER(HAS_MARLINUI_U8GLIB, TFT_COLOR_UI)
#define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash)
#endif
#endif
// Scroll a longer status message into view
//#define STATUS_MESSAGE_SCROLLING
// On the Info Screen, display XY with one decimal place when possible
//#define LCD_DECIMAL_SMALL_XY
// Add an 'M73' G-code to set the current percentage
#define LCD_SET_PROGRESS_MANUALLY
// Show the E position (filament used) during printing
//#define LCD_SHOW_E_TOTAL
/**
* LED Control Menu
@@ -1304,38 +1415,11 @@
#endif
#endif
// Insert a menu for preheating at the top level to allow for quick access
//#define PREHEAT_SHORTCUT_MENU_ITEM
#endif // HAS_LCD_MENU
#if HAS_DISPLAY
// The timeout (in ms) to return to the status screen from sub-menus
//#define LCD_TIMEOUT_TO_STATUS 15000
#if ENABLED(SHOW_BOOTSCREEN)
#define BOOTSCREEN_TIMEOUT 2000 // (ms) Total Duration to display the boot screen(s)
#if EITHER(HAS_MARLINUI_U8GLIB, TFT_COLOR_UI)
//#define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash)
#endif
#endif
// Scroll a longer status message into view
//#define STATUS_MESSAGE_SCROLLING
// On the Info Screen, display XY with one decimal place when possible
//#define LCD_DECIMAL_SMALL_XY
// Add an 'M73' G-code to set the current percentage
#define LCD_SET_PROGRESS_MANUALLY
// Show the E position (filament used) during printing
//#define LCD_SHOW_E_TOTAL
#endif
// LCD Print Progress options
#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
#if ANY(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL, IS_DWIN_MARLINUI)
#if CAN_SHOW_REMAINING_TIME
//#define SHOW_REMAINING_TIME // Display estimated time to completion
#if ENABLED(SHOW_REMAINING_TIME)
//#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation
@@ -1477,33 +1561,23 @@
// LCD's font must contain the characters. Check your selected LCD language.
//#define UTF_FILENAME_SUPPORT
// This allows hosts to request long names for files and folders with M33
#define LONG_FILENAME_HOST_SUPPORT
#define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 <dosname>' and list long filenames with 'M20 L'
//#define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol
// Enable this option to scroll long filenames in the SD card menu
#define SCROLL_LONG_FILENAMES
#define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu
// Leave the heaters on after Stop Print (not recommended!)
//#define SD_ABORT_NO_COOLDOWN
//#define SD_ABORT_NO_COOLDOWN // Leave the heaters on after Stop Print (not recommended!)
/**
* This option allows you to abort SD printing when any endstop is triggered.
* This feature must be enabled with "M540 S1" or from the LCD menu.
* To have any effect, endstops must be enabled during SD printing.
* Abort SD printing when any endstop is triggered.
* This feature is enabled with 'M540 S1' or from the LCD menu.
* Endstops must be activated for this option to work.
*/
//#define SD_ABORT_ON_ENDSTOP_HIT
/**
* This option makes it easier to print the same SD Card file again.
* On print completion the LCD Menu will open with the file selected.
* You can just click to start the print, or navigate elsewhere.
*/
//#define SD_REPRINT_LAST_SELECTED_FILE
//#define SD_REPRINT_LAST_SELECTED_FILE // On print completion open the LCD Menu and select the same file
/**
* Auto-report SdCard status with M27 S<seconds>
*/
//#define AUTO_REPORT_SD_STATUS
//#define AUTO_REPORT_SD_STATUS // Auto-report media status with 'M27 S<seconds>'
/**
* Support for USB thumb drives using an Arduino USB Host Shield or
@@ -1561,9 +1635,22 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
/**
* Enable this option if you have more than ~3K of unused flash space.
* Marlin will embed all settings in the firmware binary as compressed data.
* Use 'M503 C' to write the settings out to the SD Card as 'mc.zip'.
* See docs/ConfigEmbedding.md for details on how to use 'mc-apply.py'.
*/
//#define CONFIGURATION_EMBEDDING
// Add an optimized binary file transfer mode, initiated with 'M28 B1'
//#define BINARY_FILE_TRANSFER
#if ENABLED(BINARY_FILE_TRANSFER)
// Include extra facilities (e.g., 'M20 F') supporting firmware upload via BINARY_FILE_TRANSFER
//#define CUSTOM_FIRMWARE_UPLOAD
#endif
/**
* Set this option to one of the following (or the board's defaults apply):
*
@@ -1580,7 +1667,10 @@
// Enable if SD detect is rendered useless (e.g., by using an SD extender)
//#define NO_SD_DETECT
// Multiple volume support - EXPERIMENTAL.
/**
* Multiple volume support - EXPERIMENTAL.
* Adds 'M21 Pm' / 'M21 S' / 'M21 U' to mount SD Card / USB Drive.
*/
//#define MULTI_VOLUME
#if ENABLED(MULTI_VOLUME)
#define VOLUME_SD_ONBOARD
@@ -1666,7 +1756,7 @@
#if DISABLED(SKR12Pro)
#define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving 399 bytes of flash)
#else
#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of PROGMEM.
#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of PROGMEM.
#endif
// Frivolous Game Options
@@ -1951,6 +2041,7 @@
#define LIN_ADVANCE_K 0.0 // Unit: mm compression per 1mm/s extruder speed
//#define LA_DEBUG // If enabled, this will generate debug information output over USB.
//#define EXPERIMENTAL_SCURVE // Enable this option to permit S-Curve Acceleration
//#define ALLOW_LOW_EJERK // Allow a DEFAULT_EJERK value of <10. Recommended for direct drive hotends.
#endif
// @section leveling
@@ -2026,59 +2117,69 @@
/**
* Thermal Probe Compensation
* Probe measurements are adjusted to compensate for temperature distortion.
* Use G76 to calibrate this feature. Use M871 to set values manually.
* For a more detailed explanation of the process see G76_M871.cpp.
*
* Adjust probe measurements to compensate for distortion associated with the temperature
* of the probe, bed, and/or hotend.
* Use G76 to automatically calibrate this feature for probe and bed temperatures.
* (Extruder temperature/offset values must be calibrated manually.)
* Use M871 to set temperature/offset values manually.
* For more details see https://marlinfw.org/docs/features/probe_temp_compensation.html
*/
#if HAS_BED_PROBE && TEMP_SENSOR_PROBE && TEMP_SENSOR_BED
// Enable thermal first layer compensation using bed and probe temperatures
#define PROBE_TEMP_COMPENSATION
//#define PTC_PROBE // Compensate based on probe temperature
//#define PTC_BED // Compensate based on bed temperature
//#define PTC_HOTEND // Compensate based on hotend temperature
// Add additional compensation depending on hotend temperature
// Note: this values cannot be calibrated and have to be set manually
#if ENABLED(PROBE_TEMP_COMPENSATION)
#if ANY(PTC_PROBE, PTC_BED, PTC_HOTEND)
/**
* If the probe is outside the defined range, use linear extrapolation with the closest
* point and the point with index PTC_LINEAR_EXTRAPOLATION. e.g., If set to 4 it will use the
* linear extrapolation between data[0] and data[4] for values below PTC_PROBE_START.
*/
//#define PTC_LINEAR_EXTRAPOLATION 4
#if ENABLED(PTC_PROBE)
// Probe temperature calibration generates a table of values starting at PTC_PROBE_START
// (e.g., 30), in steps of PTC_PROBE_RES (e.g., 5) with PTC_PROBE_COUNT (e.g., 10) samples.
#define PTC_PROBE_START 30 // (°C)
#define PTC_PROBE_RES 5 // (°C)
#define PTC_PROBE_COUNT 10
#define PTC_PROBE_ZOFFS { 0 } // (µm) Z adjustments per sample
#endif
#if ENABLED(PTC_BED)
// Bed temperature calibration builds a similar table.
#define PTC_BED_START 60 // (°C)
#define PTC_BED_RES 5 // (°C)
#define PTC_BED_COUNT 10
#define PTC_BED_ZOFFS { 0 } // (µm) Z adjustments per sample
#endif
#if ENABLED(PTC_HOTEND)
// Note: There is no automatic calibration for the hotend. Use M871.
#define PTC_HOTEND_START 180 // (°C)
#define PTC_HOTEND_RES 5 // (°C)
#define PTC_HOTEND_COUNT 20
#define PTC_HOTEND_ZOFFS { 0 } // (µm) Z adjustments per sample
#endif
// G76 options
#if BOTH(PTC_PROBE, PTC_BED)
// Park position to wait for probe cooldown
#define PTC_PARK_POS { 0, 0, 100 }
// Probe position to probe and wait for probe to reach target temperature
//#define PTC_PROBE_POS { 12.0f, 7.3f } // Example: MK52 magnetic heatbed
#define PTC_PROBE_POS { 90, 100 }
// Enable additional compensation using hotend temperature
// Note: this values cannot be calibrated automatically but have to be set manually
//#define USE_TEMP_EXT_COMPENSATION
// Probe temperature calibration generates a table of values starting at PTC_SAMPLE_START
// (e.g., 30), in steps of PTC_SAMPLE_RES (e.g., 5) with PTC_SAMPLE_COUNT (e.g., 10) samples.
//#define PTC_SAMPLE_START 30 // (°C)
//#define PTC_SAMPLE_RES 5 // (°C)
//#define PTC_SAMPLE_COUNT 10
// Bed temperature calibration builds a similar table.
//#define BTC_SAMPLE_START 60 // (°C)
//#define BTC_SAMPLE_RES 5 // (°C)
//#define BTC_SAMPLE_COUNT 10
// The temperature the probe should be at while taking measurements during bed temperature
// calibration.
//#define BTC_PROBE_TEMP 30 // (°C)
// The temperature the probe should be at while taking measurements during
// bed temperature calibration.
#define PTC_PROBE_TEMP 30 // (°C)
// Height above Z=0.0 to raise the nozzle. Lowering this can help the probe to heat faster.
// Note: the Z=0.0 offset is determined by the probe offset which can be set using M851.
//#define PTC_PROBE_HEATING_OFFSET 0.5
// Height to raise the Z-probe between heating and taking the next measurement. Some probes
// may fail to untrigger if they have been triggered for a long time, which can be solved by
// increasing the height the probe is raised to.
//#define PTC_PROBE_RAISE 15
// If the probe is outside of the defined range, use linear extrapolation using the closest
// point and the PTC_LINEAR_EXTRAPOLATION'th next point. E.g. if set to 4 it will use data[0]
// and data[4] to perform linear extrapolation for values below PTC_SAMPLE_START.
//#define PTC_LINEAR_EXTRAPOLATION 4
// Note: The Z=0.0 offset is determined by the probe Z offset (e.g., as set with M851 Z).
#define PTC_PROBE_HEATING_OFFSET 0.5
#endif
#endif
#endif // PTC_PROBE || PTC_BED || PTC_HOTEND
// @section extras
@@ -2291,6 +2392,15 @@
// For serial echo, the number of digits after the decimal point
//#define SERIAL_FLOAT_PRECISION 4
/**
* Set the number of proportional font spaces required to fill up a typical character space.
* This can help to better align the output of commands like `G29 O` Mesh Output.
*
* For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0.
* Otherwise, adjust according to your client and font.
*/
#define PROPORTIONAL_FONT_RATIO 1.0
// @section extras
/**
@@ -2357,6 +2467,7 @@
*/
//#define EVENT_GCODE_TOOLCHANGE_T0 "G28 A\nG1 A0" // Extra G-code to run while executing tool-change command T0
//#define EVENT_GCODE_TOOLCHANGE_T1 "G1 A10" // Extra G-code to run while executing tool-change command T1
//#define EVENT_GCODE_TOOLCHANGE_ALWAYS_RUN // Always execute above G-code sequences. Use with caution!
/**
* Tool Sensors detect when tools have been picked up or dropped.
@@ -2372,26 +2483,26 @@
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
// Load / Unload
#define TOOLCHANGE_FS_LENGTH 4 // (mm) Load / Unload length
#define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 2 // (mm) Extra length for better restart, fine tune by LCD/Gcode)
#define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/m) (Unloading)
#define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/m) (On SINGLENOZZLE or Bowden loading must be slowed down)
#define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 2 // (mm) Extra length for better restart. Adjust with LCD or M217 B.
#define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/min) (Unloading)
#define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/min) (On SINGLENOZZLE or Bowden loading must be slowed down)
// Longer prime to clean out a SINGLENOZZLE
#define TOOLCHANGE_FS_EXTRA_PRIME 0 // (mm) Extra priming length
#define TOOLCHANGE_FS_PRIME_SPEED (4.6*60) // (mm/min) Extra priming feedrate
#define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm/min) Retract before cooling for less stringing, better wipe, etc.
#define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm) Retract before cooling for less stringing, better wipe, etc.
// Cool after prime to reduce stringing
#define TOOLCHANGE_FS_FAN -1 // Fan index or -1 to skip
#define TOOLCHANGE_FS_FAN_SPEED 255 // 0-255
#define TOOLCHANGE_FS_FAN_TIME 10 // (seconds)
// Swap uninitialized extruder with TOOLCHANGE_FS_PRIME_SPEED for all lengths (recover + prime)
// Swap uninitialized extruder (using TOOLCHANGE_FS_PRIME_SPEED feedrate)
// (May break filament if not retracted beforehand.)
//#define TOOLCHANGE_FS_INIT_BEFORE_SWAP
// Prime on the first T0 (If other, TOOLCHANGE_FS_INIT_BEFORE_SWAP applied)
// Enable it (M217 V[0/1]) before printing, to avoid unwanted priming on host connect
// Prime on the first T0 (For other tools use TOOLCHANGE_FS_INIT_BEFORE_SWAP)
// Enable with M217 V1 before printing to avoid unwanted priming on host connect
//#define TOOLCHANGE_FS_PRIME_FIRST_USED
/**
@@ -2640,6 +2751,7 @@
#define X_RSENSE 0.11
#define X_CHAIN_POS -1 // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ...
//#define X_INTERPOLATE true // Enable to override 'INTERPOLATE' for the X axis
//#define X_HOLD_MULTIPLIER 0.5 // Enable to override 'HOLD_MULTIPLIER' for the X axis
#endif
#if AXIS_IS_TMC(X2)
@@ -2649,6 +2761,7 @@
#define X2_RSENSE 0.11
#define X2_CHAIN_POS -1
//#define X2_INTERPOLATE true
//#define X2_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(Y)
@@ -2658,6 +2771,7 @@
#define Y_RSENSE 0.11
#define Y_CHAIN_POS -1
//#define Y_INTERPOLATE true
//#define Y_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(Y2)
@@ -2667,6 +2781,7 @@
#define Y2_RSENSE 0.11
#define Y2_CHAIN_POS -1
//#define Y2_INTERPOLATE true
//#define Y2_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(Z)
@@ -2676,6 +2791,7 @@
#define Z_RSENSE 0.11
#define Z_CHAIN_POS -1
//#define Z_INTERPOLATE true
//#define Z_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(Z2)
@@ -2685,6 +2801,7 @@
#define Z2_RSENSE 0.11
#define Z2_CHAIN_POS -1
//#define Z2_INTERPOLATE true
//#define Z2_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(Z3)
@@ -2694,6 +2811,7 @@
#define Z3_RSENSE 0.11
#define Z3_CHAIN_POS -1
//#define Z3_INTERPOLATE true
//#define Z3_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(Z4)
@@ -2703,6 +2821,7 @@
#define Z4_RSENSE 0.11
#define Z4_CHAIN_POS -1
//#define Z4_INTERPOLATE true
//#define Z4_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(I)
@@ -2712,6 +2831,7 @@
#define I_RSENSE 0.11
#define I_CHAIN_POS -1
//#define I_INTERPOLATE true
//#define I_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(J)
@@ -2721,6 +2841,7 @@
#define J_RSENSE 0.11
#define J_CHAIN_POS -1
//#define J_INTERPOLATE true
//#define J_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(K)
@@ -2730,6 +2851,7 @@
#define K_RSENSE 0.11
#define K_CHAIN_POS -1
//#define K_INTERPOLATE true
//#define K_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(E0)
@@ -2738,6 +2860,7 @@
#define E0_RSENSE 0.11
#define E0_CHAIN_POS -1
//#define E0_INTERPOLATE true
//#define E0_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(E1)
@@ -2746,6 +2869,7 @@
#define E1_RSENSE 0.11
#define E1_CHAIN_POS -1
//#define E1_INTERPOLATE true
//#define E1_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(E2)
@@ -2754,6 +2878,7 @@
#define E2_RSENSE 0.11
#define E2_CHAIN_POS -1
//#define E2_INTERPOLATE true
//#define E2_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(E3)
@@ -2762,6 +2887,7 @@
#define E3_RSENSE 0.11
#define E3_CHAIN_POS -1
//#define E3_INTERPOLATE true
//#define E3_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(E4)
@@ -2770,6 +2896,7 @@
#define E4_RSENSE 0.11
#define E4_CHAIN_POS -1
//#define E4_INTERPOLATE true
//#define E4_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(E5)
@@ -2778,6 +2905,7 @@
#define E5_RSENSE 0.11
#define E5_CHAIN_POS -1
//#define E5_INTERPOLATE true
//#define E5_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(E6)
@@ -2786,6 +2914,7 @@
#define E6_RSENSE 0.11
#define E6_CHAIN_POS -1
//#define E6_INTERPOLATE true
//#define E6_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(E7)
@@ -2794,6 +2923,7 @@
#define E7_RSENSE 0.11
#define E7_CHAIN_POS -1
//#define E7_INTERPOLATE true
//#define E7_HOLD_MULTIPLIER 0.5
#endif
/**
@@ -2906,6 +3036,9 @@
//#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z
//#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z
//#define CHOPPER_TIMING_Z4 CHOPPER_TIMING_Z
//#define CHOPPER_TIMING_I CHOPPER_TIMING
//#define CHOPPER_TIMING_J CHOPPER_TIMING
//#define CHOPPER_TIMING_K CHOPPER_TIMING
//#define CHOPPER_TIMING_E CHOPPER_TIMING // For Extruders (override below)
//#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E
//#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E
@@ -3143,7 +3276,7 @@
#define Z4_SLEW_RATE 1
#endif
#if AXIS_DRIVER_TYPE_I(L6470)
#if AXIS_IS_L64XX(I)
#define I_MICROSTEPS 128
#define I_OVERCURRENT 2000
#define I_STALLCURRENT 1500
@@ -3152,7 +3285,7 @@
#define I_SLEW_RATE 1
#endif
#if AXIS_DRIVER_TYPE_J(L6470)
#if AXIS_IS_L64XX(J)
#define J_MICROSTEPS 128
#define J_OVERCURRENT 2000
#define J_STALLCURRENT 1500
@@ -3161,7 +3294,7 @@
#define J_SLEW_RATE 1
#endif
#if AXIS_DRIVER_TYPE_K(L6470)
#if AXIS_IS_L64XX(K)
#define K_MICROSTEPS 128
#define K_OVERCURRENT 2000
#define K_STALLCURRENT 1500
@@ -3643,6 +3776,12 @@
*/
//#define CNC_COORDINATE_SYSTEMS
/**
* Auto-report fan speed with M123 S<seconds>
* Requires fans with tachometer pins
*/
//#define AUTO_REPORT_FANS
/**
* Auto-report temperatures with M155 S<seconds>
*/
@@ -3712,15 +3851,6 @@
//#define REPORT_FAN_CHANGE // Report the new fan speed when changed by M106 (and others)
/**
* Set the number of proportional font spaces required to fill up a typical character space.
* This can help to better align the output of commands like `G29 O` Mesh Output.
*
* For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0.
* Otherwise, adjust according to your client and font.
*/
#define PROPORTIONAL_FONT_RATIO 1.0
/**
* Spend 28 bytes of SRAM to optimize the G-code parser
*/
@@ -3826,9 +3956,13 @@
*/
#define HOST_ACTION_COMMANDS
#if ENABLED(HOST_ACTION_COMMANDS)
//#define HOST_PAUSE_M76
#define HOST_PROMPT_SUPPORT
#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start
//#define HOST_PAUSE_M76 // Tell the host to pause in response to M76
#define HOST_PROMPT_SUPPORT // Initiate host prompts to get user feedback
#if ENABLED(HOST_PROMPT_SUPPORT)
#define HOST_STATUS_NOTIFICATIONS // Send some status messages to the host as notifications
#endif
#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start
//#define HOST_SHUTDOWN_MENU_ITEM // Add a menu item that tells the host to shut down
#endif
/**
@@ -4202,3 +4336,6 @@
*/
//#define SOFT_RESET_VIA_SERIAL // 'KILL' and '^X' commands will soft-reset the controller
//#define SOFT_RESET_ON_KILL // Use a digital button to soft-reset the controller after KILL
// Report uncleaned reset reason from register r2 instead of MCUSR. Supported by Optiboot on AVR.
//#define OPTIBOOT_RESET_REASON
+158 -7
View File
@@ -191,6 +191,134 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1034)
# RAMPS Derivatives - ATmega1280, ATmega2560
#
# 3Drag Controller
else ifeq ($(HARDWARE_MOTHERBOARD),1100)
# Velleman K8200 Controller (derived from 3Drag Controller)
else ifeq ($(HARDWARE_MOTHERBOARD),1101)
# Velleman K8400 Controller (derived from 3Drag Controller)
else ifeq ($(HARDWARE_MOTHERBOARD),1102)
# Velleman K8600 Controller (Vertex Nano)
else ifeq ($(HARDWARE_MOTHERBOARD),1103)
# Velleman K8800 Controller (Vertex Delta)
else ifeq ($(HARDWARE_MOTHERBOARD),1104)
# 2PrintBeta BAM&DICE with STK drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1105)
# 2PrintBeta BAM&DICE Due with STK drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1106)
# MKS BASE v1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1107)
# MKS BASE v1.4 with Allegro A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1108)
# MKS BASE v1.5 with Allegro A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1109)
# MKS BASE v1.6 with Allegro A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1110)
# MKS BASE 1.0 with Heroic HR4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1111)
# MKS GEN v1.3 or 1.4
else ifeq ($(HARDWARE_MOTHERBOARD),1112)
# MKS GEN L
else ifeq ($(HARDWARE_MOTHERBOARD),1113)
# BigTreeTech or BIQU KFB2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1114)
# zrib V2.0 (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1115)
# zrib V5.2 (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1116)
# Felix 2.0+ Electronics Board (RAMPS like)
else ifeq ($(HARDWARE_MOTHERBOARD),1117)
# Invent-A-Part RigidBoard
else ifeq ($(HARDWARE_MOTHERBOARD),1118)
# Invent-A-Part RigidBoard V2
else ifeq ($(HARDWARE_MOTHERBOARD),1119)
# Sainsmart 2-in-1 board
else ifeq ($(HARDWARE_MOTHERBOARD),1120)
# Ultimaker
else ifeq ($(HARDWARE_MOTHERBOARD),1121)
# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
else ifeq ($(HARDWARE_MOTHERBOARD),1122)
MCU ?= atmega1280
PROG_MCU ?= m1280
# Azteeg X3
else ifeq ($(HARDWARE_MOTHERBOARD),1123)
# Azteeg X3 Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1124)
# Ultimainboard 2.x (Uses TEMP_SENSOR 20)
else ifeq ($(HARDWARE_MOTHERBOARD),1125)
# Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),1126)
# Raise3D N series Rumba derivative
else ifeq ($(HARDWARE_MOTHERBOARD),1127)
# Rapide Lite 200 (v1, low-cost RUMBA clone with drv)
else ifeq ($(HARDWARE_MOTHERBOARD),1128)
# Formbot T-Rex 2 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1129)
# Formbot T-Rex 3
else ifeq ($(HARDWARE_MOTHERBOARD),1130)
# Formbot Raptor
else ifeq ($(HARDWARE_MOTHERBOARD),1131)
# Formbot Raptor 2
else ifeq ($(HARDWARE_MOTHERBOARD),1132)
# bq ZUM Mega 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1133)
# MakeBoard Mini v2.1.2 by MicroMake
else ifeq ($(HARDWARE_MOTHERBOARD),1134)
# TriGorilla Anycubic version 1.3-based on RAMPS EFB
else ifeq ($(HARDWARE_MOTHERBOARD),1135)
# ... Ver 1.4
else ifeq ($(HARDWARE_MOTHERBOARD),1136)
# ... Rev 1.1 (new servo pin order)
else ifeq ($(HARDWARE_MOTHERBOARD),1137)
# Creality: Ender-4, CR-8
else ifeq ($(HARDWARE_MOTHERBOARD),1138)
# Creality: CR10S, CR20, CR-X
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
# Dagoma F5
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
# FYSETC F6 1.3
else ifeq ($(HARDWARE_MOTHERBOARD),1141)
# FYSETC F6 1.4
else ifeq ($(HARDWARE_MOTHERBOARD),1142)
# Wanhao Duplicator i3 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1143)
# VORON Design
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
# Tronxy TRONXY-V3-1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
# Z-Bolt X Series
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
# TT OSCAR
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
# Overlord/Overlord Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
# ADIMLab Gantry v1
else ifeq ($(HARDWARE_MOTHERBOARD),1149)
# ADIMLab Gantry v2
else ifeq ($(HARDWARE_MOTHERBOARD),1150)
# BIQU Tango V1
else ifeq ($(HARDWARE_MOTHERBOARD),1151)
# MKS GEN L V2
else ifeq ($(HARDWARE_MOTHERBOARD),1152)
# MKS GEN L V2.1
else ifeq ($(HARDWARE_MOTHERBOARD),1153)
# Copymaster 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1154)
# Ortur 4
else ifeq ($(HARDWARE_MOTHERBOARD),1155)
# Tenlog D3 Hero IDEX printer
else ifeq ($(HARDWARE_MOTHERBOARD),1156)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1157)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1158)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1159)
# Longer LK1 PRO / Alfawise U20 Pro (PRO version)
else ifeq ($(HARDWARE_MOTHERBOARD),1160)
# Longer LKx PRO / Alfawise Uxx Pro (PRO version)
else ifeq ($(HARDWARE_MOTHERBOARD),1161)
# 3Drag Controller
else ifeq ($(HARDWARE_MOTHERBOARD),1100)
# Velleman K8200 Controller (derived from 3Drag Controller)
@@ -358,20 +486,38 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1311)
else ifeq ($(HARDWARE_MOTHERBOARD),1312)
# Mega controller
else ifeq ($(HARDWARE_MOTHERBOARD),1313)
# Geeetech GT2560 Rev B for Mecreator2
# Geeetech GT2560 Rev A
else ifeq ($(HARDWARE_MOTHERBOARD),1314)
# Geeetech GT2560 Rev. A
# Geeetech GT2560 Rev A+ (with auto level probe)
else ifeq ($(HARDWARE_MOTHERBOARD),1315)
# Geeetech GT2560 Rev. A+ (with auto level probe)
# Geeetech GT2560 Rev B
else ifeq ($(HARDWARE_MOTHERBOARD),1316)
# Geeetech GT2560 Rev B for A10(M/D)
# Geeetech GT2560 Rev B for A10(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1317)
# Geeetech GT2560 Rev B for A20(M/D)
# Geeetech GT2560 Rev B for A10(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1318)
# Einstart retrofit
# Geeetech GT2560 Rev B for Mecreator2
else ifeq ($(HARDWARE_MOTHERBOARD),1319)
# Wanhao 0ne+ i3 Mini
# Geeetech GT2560 Rev B for A20(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1320)
# Einstart retrofit
else ifeq ($(HARDWARE_MOTHERBOARD),1321)
# Wanhao 0ne+ i3 Mini
else ifeq ($(HARDWARE_MOTHERBOARD),1322)
# Leapfrog Xeed 2015
else ifeq ($(HARDWARE_MOTHERBOARD),1323)
# PICA Shield (original version)
else ifeq ($(HARDWARE_MOTHERBOARD),1324)
# PICA Shield (rev C or later)
else ifeq ($(HARDWARE_MOTHERBOARD),1325)
# Intamsys 4.0 (Funmat HT)
else ifeq ($(HARDWARE_MOTHERBOARD),1326)
# Malyan M180 Mainboard Version 2 (no display function, direct gcode only)
else ifeq ($(HARDWARE_MOTHERBOARD),1327)
# Geeetech GT2560 Rev B for A20(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
# Mega controller & Protoneer CNC Shield V3.00
else ifeq ($(HARDWARE_MOTHERBOARD),1329)
#
# ATmega1281, ATmega2561
@@ -445,6 +591,11 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1510)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
# ZoneStar ZMIB V2
else ifeq ($(HARDWARE_MOTHERBOARD),1511)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
#
# Other ATmega644P, ATmega644, ATmega1284P
+1 -1
View File
@@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
#define STRING_DISTRIBUTION_DATE "2021-10-13"
#define STRING_DISTRIBUTION_DATE "2022-03-05"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
+36 -15
View File
@@ -35,13 +35,32 @@
// Public Variables
// ------------------------
//uint8_t MCUSR;
// Don't initialize/override variable (which would happen in .init4)
uint8_t MarlinHAL::reset_reason __attribute__((section(".noinit")));
// ------------------------
// Public functions
// ------------------------
void HAL_init() {
__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 save_reset_reason() {
#if ENABLED(OPTIBOOT_RESET_REASON)
__asm__ __volatile__(
A("STS %0, r2")
: "=m"(hal.reset_reason)
);
#else
hal.reset_reason = MCUSR;
#endif
// Clear within 16ms since WDRF bit enables a 16ms watchdog timer -> Boot loop
hal.clear_reset_source();
wdt_disable();
}
void MarlinHAL::init() {
// Init Servo Pins
#define INIT_SERVO(N) OUT_WRITE(SERVO##N##_PIN, LOW)
#if HAS_SERVO_0
@@ -56,9 +75,11 @@ void HAL_init() {
#if HAS_SERVO_3
INIT_SERVO(3);
#endif
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
@@ -74,20 +95,20 @@ void HAL_reboot() {
#else // !SDSUPPORT
extern "C" {
extern char __bss_end;
extern char __heap_start;
extern void* __brkval;
extern "C" {
extern char __bss_end;
extern char __heap_start;
extern void* __brkval;
int freeMemory() {
int free_memory;
if ((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
int freeMemory() {
int free_memory;
if ((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
}
}
}
#endif // !SDSUPPORT
+118 -77
View File
@@ -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 MCUSR;
// Serial ports
// ------------------------
#ifdef USBCON
#include "../../core/serial_hook.h"
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
@@ -142,59 +141,15 @@ typedef int8_t pin_t;
#endif
#endif
// ------------------------
// Public functions
// ------------------------
void HAL_init();
//void cli();
//void _delay_ms(const int delay);
inline void HAL_clear_reset_source() { MCUSR = 0; }
inline uint8_t HAL_get_reset_source() { return MCUSR; }
void HAL_reboot();
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
extern "C" int freeMemory();
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
//
// 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)
@@ -208,23 +163,109 @@ inline void HAL_adc_init() {
// AVR compatibility
#define strtof strtod
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
// ------------------------
// 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, int f_desired);
#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
/**
* set_pwm_duty
* Sets 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
* Set the default frequency for timers 2-5 to 1000HZ
*/
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);
};
+9 -11
View File
@@ -35,22 +35,20 @@
void spiBegin() {
#if PIN_EXISTS(SD_SS)
OUT_WRITE(SD_SS_PIN, HIGH);
// Do not init HIGH for boards with pin 4 used as Fans or Heaters or otherwise, not likely to have multiple SPI devices anyway.
#if defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
// SS must be in output mode even it is not chip select
SET_OUTPUT(SD_SS_PIN);
#else
// set SS high - may be chip select for another SPI device
OUT_WRITE(SD_SS_PIN, HIGH);
#endif
#endif
SET_OUTPUT(SD_SCK_PIN);
SET_INPUT(SD_MISO_PIN);
SET_OUTPUT(SD_MOSI_PIN);
#if DISABLED(SOFTWARE_SPI)
// SS must be in output mode even it is not chip select
//SET_OUTPUT(SD_SS_PIN);
// set SS high - may be chip select for another SPI device
//#if SET_SPI_SS_HIGH
//WRITE(SD_SS_PIN, HIGH);
//#endif
// set a default rate
spiInit(1);
#endif
IF_DISABLED(SOFTWARE_SPI, spiInit(SPI_HALF_SPEED));
}
#if NONE(SOFTWARE_SPI, FORCE_SOFT_SPI)
+2 -2
View File
@@ -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) {
+4 -4
View File
@@ -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();
@@ -217,7 +217,7 @@
#endif
enum { HasEmergencyParser = Cfg::EMERGENCYPARSER };
static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
static bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
+1
View File
@@ -301,5 +301,6 @@ void setup_endstop_interrupts() {
pciSetup(Z_MIN_PROBE_PIN);
#endif
#endif
// If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI.
}
+135 -195
View File
@@ -21,11 +21,7 @@
*/
#ifdef __AVR__
#include "../../inc/MarlinConfigPre.h"
#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
#include "HAL.h"
#include "../../inc/MarlinConfig.h"
struct Timer {
volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer
@@ -33,250 +29,194 @@ struct Timer {
volatile uint16_t* ICRn; // max 1 ICR register per timer
uint8_t n; // the timer number [0->5]
uint8_t q; // the timer output [0->2] (A->C)
bool isPWM; // True if pin is a "hardware timer"
bool isProtected; // True if timer is protected
};
// Macros for the Timer structure
#define _SET_WGMnQ(T, V) do{ \
*(T.TCCRnQ)[0] = (*(T.TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \
*(T.TCCRnQ)[1] = (*(T.TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \
}while(0)
// Set TCCR CS bits
#define _SET_CSn(T, V) (*(T.TCCRnQ)[1] = (*(T.TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0))
// Set TCCR COM bits
#define _SET_COMnQ(T, Q, V) (*(T.TCCRnQ)[0] = (*(T.TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q))))
// Set OCRnQ register
#define _SET_OCRnQ(T, Q, V) (*(T.OCRnQ)[Q] = int(V) & 0xFFFF)
// Set ICRn register (one per timer)
#define _SET_ICRn(T, V) (*(T.ICRn) = int(V) & 0xFFFF)
/**
* get_pwm_timer
* Get the timer information and register of the provided pin.
* Return a Timer struct containing this information.
* Used by set_pwm_frequency, set_pwm_duty
* Return a Timer struct describing a pin's timer.
*/
Timer get_pwm_timer(const pin_t pin) {
const Timer get_pwm_timer(const pin_t pin) {
uint8_t q = 0;
switch (digitalPinToTimer(pin)) {
// Protect reserved timers (TIMER0 & TIMER1)
#ifdef TCCR0A
#if !AVR_AT90USB1286_FAMILY
case TIMER0A:
#endif
case TIMER0B:
IF_DISABLED(AVR_AT90USB1286_FAMILY, case TIMER0A:)
#endif
#ifdef TCCR1A
case TIMER1A: case TIMER1B:
#endif
break;
#if defined(TCCR2) || defined(TCCR2A)
#ifdef TCCR2
case TIMER2: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2, nullptr, nullptr },
/*OCRnQ*/ { (uint16_t*)&OCR2, nullptr, nullptr },
/*ICRn*/ nullptr,
/*n, q*/ 2, 0
};
}
#elif defined(TCCR2A)
#if ENABLED(USE_OCR2A_AS_TOP)
case TIMER2A: break; // protect TIMER2A
case TIMER2B: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr },
/*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr },
/*ICRn*/ nullptr,
/*n, q*/ 2, 1
};
return timer;
}
#else
case TIMER2B: ++q;
case TIMER2A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr },
/*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr },
/*ICRn*/ nullptr,
2, q
};
return timer;
}
#endif
#endif
break; // Protect reserved timers (TIMER0 & TIMER1)
#ifdef TCCR0A
case TIMER0B: // Protected timer, but allow setting the duty cycle on OCR0B for pin D4 only
return Timer({ { &TCCR0A, nullptr, nullptr }, { (uint16_t*)&OCR0A, (uint16_t*)&OCR0B, nullptr }, nullptr, 0, 1, true, true });
#endif
#if HAS_TCCR2
case TIMER2:
return Timer({ { &TCCR2, nullptr, nullptr }, { (uint16_t*)&OCR2, nullptr, nullptr }, nullptr, 2, 0, true, false });
#elif ENABLED(USE_OCR2A_AS_TOP)
case TIMER2A: break; // Protect TIMER2A since its OCR is used by TIMER2B
case TIMER2B:
return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, 1, true, false });
#elif defined(TCCR2A)
case TIMER2B: ++q; case TIMER2A:
return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, q, true, false });
#endif
#ifdef OCR3C
case TIMER3C: ++q;
case TIMER3B: ++q;
case TIMER3A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR3A, &TCCR3B, &TCCR3C },
/*OCRnQ*/ { &OCR3A, &OCR3B, &OCR3C },
/*ICRn*/ &ICR3,
/*n, q*/ 3, q
};
return timer;
}
case TIMER3C: ++q; case TIMER3B: ++q; case TIMER3A:
return Timer({ { &TCCR3A, &TCCR3B, &TCCR3C }, { &OCR3A, &OCR3B, &OCR3C }, &ICR3, 3, q, true, false });
#elif defined(OCR3B)
case TIMER3B: ++q;
case TIMER3A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR3A, &TCCR3B, nullptr },
/*OCRnQ*/ { &OCR3A, &OCR3B, nullptr },
/*ICRn*/ &ICR3,
/*n, q*/ 3, q
};
return timer;
}
case TIMER3B: ++q; case TIMER3A:
return Timer({ { &TCCR3A, &TCCR3B, nullptr }, { &OCR3A, &OCR3B, nullptr }, &ICR3, 3, q, true, false });
#endif
#ifdef TCCR4A
case TIMER4C: ++q;
case TIMER4B: ++q;
case TIMER4A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR4A, &TCCR4B, &TCCR4C },
/*OCRnQ*/ { &OCR4A, &OCR4B, &OCR4C },
/*ICRn*/ &ICR4,
/*n, q*/ 4, q
};
return timer;
}
case TIMER4C: ++q; case TIMER4B: ++q; case TIMER4A:
return Timer({ { &TCCR4A, &TCCR4B, &TCCR4C }, { &OCR4A, &OCR4B, &OCR4C }, &ICR4, 4, q, true, false });
#endif
#ifdef TCCR5A
case TIMER5C: ++q;
case TIMER5B: ++q;
case TIMER5A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR5A, &TCCR5B, &TCCR5C },
/*OCRnQ*/ { &OCR5A, &OCR5B, &OCR5C },
/*ICRn*/ &ICR5,
/*n, q*/ 5, q
};
return timer;
}
case TIMER5C: ++q; case TIMER5B: ++q; case TIMER5A:
return Timer({ { &TCCR5A, &TCCR5B, &TCCR5C }, { &OCR5A, &OCR5B, &OCR5C }, &ICR5, 5, q, true, false });
#endif
}
Timer timer = {
/*TCCRnQ*/ { nullptr, nullptr, nullptr },
/*OCRnQ*/ { nullptr, nullptr, nullptr },
/*ICRn*/ nullptr,
0, 0
};
return timer;
return Timer();
}
void set_pwm_frequency(const pin_t pin, int f_desired) {
Timer timer = get_pwm_timer(pin);
if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
uint16_t size;
if (timer.n == 2) size = 255; else size = 65535;
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
uint16_t res = 255; // resolution (TOP value)
uint8_t j = 0; // prescaler index
uint8_t wgm = 1; // waveform generation mode
const bool is_timer2 = timer.n == 2;
const uint16_t maxtop = is_timer2 ? 0xFF : 0xFFFF;
uint16_t res = 0xFF; // resolution (TOP value)
uint8_t j = CS_NONE; // prescaler index
uint8_t wgm = WGM_PWM_PC_8; // waveform generation mode
// Calculating the prescaler and resolution to use to achieve closest frequency
if (f_desired != 0) {
int f = (F_CPU) / (2 * 1024 * size) + 1; // Initialize frequency as lowest (non-zero) achievable
uint16_t prescaler[] = { 0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 };
constexpr uint16_t prescaler[] = { 1, 8, (32), 64, (128), 256, 1024 }; // (*) are Timer 2 only
uint16_t f = (F_CPU) / (2 * 1024 * maxtop) + 1; // Start with the lowest non-zero frequency achievable (1 or 31)
// loop over prescaler values
LOOP_S_L_N(i, 1, 8) {
uint16_t res_temp_fast = 255, res_temp_phase_correct = 255;
if (timer.n == 2) {
// No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
#if ENABLED(USE_OCR2A_AS_TOP)
const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
res_temp_fast = rtf - 1;
res_temp_phase_correct = rtf / 2;
LOOP_L_N(i, COUNT(prescaler)) { // Loop through all prescaler values
const uint16_t p = prescaler[i];
uint16_t res_fast_temp, res_pc_temp;
if (is_timer2) {
#if ENABLED(USE_OCR2A_AS_TOP) // No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
const uint16_t rft = (F_CPU) / (p * f_desired);
res_fast_temp = rft - 1;
res_pc_temp = rft / 2;
#else
res_fast_temp = res_pc_temp = maxtop;
#endif
}
else {
// Skip TIMER2 specific prescalers when not TIMER2
if (i == 3 || i == 5) continue;
const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
res_temp_fast = rtf - 1;
res_temp_phase_correct = rtf / 2;
if (p == 32 || p == 128) continue; // Skip TIMER2 specific prescalers when not TIMER2
const uint16_t rft = (F_CPU) / (p * f_desired);
res_fast_temp = rft - 1;
res_pc_temp = rft / 2;
}
LIMIT(res_temp_fast, 1U, size);
LIMIT(res_temp_phase_correct, 1U, size);
LIMIT(res_fast_temp, 1U, maxtop);
LIMIT(res_pc_temp, 1U, maxtop);
// Calculate frequencies of test prescaler and resolution values
const int f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)),
f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct),
f_diff = ABS(f - f_desired),
f_fast_diff = ABS(f_temp_fast - f_desired),
f_phase_diff = ABS(f_temp_phase_correct - f_desired);
const uint32_t f_diff = _MAX(f, f_desired) - _MIN(f, f_desired),
f_fast_temp = (F_CPU) / (p * (1 + res_fast_temp)),
f_fast_diff = _MAX(f_fast_temp, f_desired) - _MIN(f_fast_temp, f_desired),
f_pc_temp = (F_CPU) / (2 * p * res_pc_temp),
f_pc_diff = _MAX(f_pc_temp, f_desired) - _MIN(f_pc_temp, f_desired);
// If FAST values are closest to desired f
if (f_fast_diff < f_diff && f_fast_diff <= f_phase_diff) {
// Remember this combination
f = f_temp_fast;
res = res_temp_fast;
j = i;
if (f_fast_diff < f_diff && f_fast_diff <= f_pc_diff) { // FAST values are closest to desired f
// Set the Wave Generation Mode to FAST PWM
if (timer.n == 2) {
wgm = (
#if ENABLED(USE_OCR2A_AS_TOP)
WGM2_FAST_PWM_OCR2A
#else
WGM2_FAST_PWM
#endif
);
}
else wgm = WGM_FAST_PWM_ICRn;
wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_FAST_PWM_ICRn);
// Remember this combination
f = f_fast_temp; res = res_fast_temp; j = i + 1;
}
// If PHASE CORRECT values are closes to desired f
else if (f_phase_diff < f_diff) {
f = f_temp_phase_correct;
res = res_temp_phase_correct;
j = i;
else if (f_pc_diff < f_diff) { // PHASE CORRECT values are closes to desired f
// Set the Wave Generation Mode to PWM PHASE CORRECT
if (timer.n == 2) {
wgm = (
#if ENABLED(USE_OCR2A_AS_TOP)
WGM2_PWM_PC_OCR2A
#else
WGM2_PWM_PC
#endif
);
}
else wgm = WGM_PWM_PC_ICRn;
wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_PWM_PC)) : uint8_t(WGM_PWM_PC_ICRn);
f = f_pc_temp; res = res_pc_temp; j = i + 1;
}
}
}
_SET_WGMnQ(timer.TCCRnQ, wgm);
_SET_CSn(timer.TCCRnQ, j);
if (timer.n == 2) {
#if ENABLED(USE_OCR2A_AS_TOP)
_SET_OCRnQ(timer.OCRnQ, 0, res); // Set OCR2A value (TOP) = res
#endif
_SET_WGMnQ(timer, wgm);
_SET_CSn(timer, j);
if (is_timer2) {
TERN_(USE_OCR2A_AS_TOP, _SET_OCRnQ(timer, 0, res)); // Set OCR2A value (TOP) = res
}
else
_SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res
_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)
// Note that digitalWrite also disables PWM output for us (sets COM bit to 0)
if (v == 0)
digitalWrite(pin, invert);
else if (v == v_size)
digitalWrite(pin, !invert);
else {
Timer timer = get_pwm_timer(pin);
if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
// Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted)
_SET_COMnQ(timer.TCCRnQ, (timer.q
#ifdef TCCR2
+ (timer.q == 2) // COM20 is on bit 4 of TCCR2, thus requires q + 1 in the macro
#endif
), COM_CLEAR_SET + invert
);
uint16_t top;
if (timer.n == 2) { // if TIMER2
top = (
#if ENABLED(USE_OCR2A_AS_TOP)
*timer.OCRnQ[0] // top = OCR2A
#else
255 // top = 0xFF (max)
#endif
);
const Timer timer = get_pwm_timer(pin);
if (timer.isPWM) {
if (timer.n == 0) {
_SET_COMnQ(timer, timer.q, COM_CLEAR_SET); // Only allow a TIMER0B select...
_SET_OCRnQ(timer, timer.q, v); // ...and OCR0B duty update. For output pin D4 no frequency changes are permitted.
}
else if (!timer.isProtected) {
const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn;
_SET_COMnQ(timer, SUM_TERN(HAS_TCCR2, timer.q, timer.q == 2), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2
_SET_OCRnQ(timer, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value
}
}
else
top = *timer.ICRn; // top = ICRn
_SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top) / float(v_size)); // Scale 8/16-bit v to top value
digitalWrite(pin, v < v_size / 2 ? LOW : HIGH);
}
}
#endif // NEEDS_HARDWARE_PWM
void MarlinHAL::init_pwm_timers() {
// Init some timer frequencies to a default 1KHz
const pin_t pwm_pin[] = {
#ifdef __AVR_ATmega2560__
10, 5, 6, 46
#elif defined(__AVR_ATmega1280__)
12, 31
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284__)
15, 6
#elif defined(__AVR_AT90USB1286__) || defined(__AVR_mega64) || defined(__AVR_mega128)
16, 24
#endif
};
LOOP_L_N(i, COUNT(pwm_pin))
set_pwm_frequency(pwm_pin[i], 1000);
}
#endif // __AVR__
+3 -3
View File
@@ -245,7 +245,7 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb
float count = 0;
if (hz > 0 && (dca || dcb || dcc)) {
count = float(F_CPU) / hz; // 1x prescaler, TOP for 16MHz base freq.
uint16_t prescaler; // Range of 30.5Hz (65535) 64.5KHz (>31)
uint16_t prescaler; // Range of 30.5Hz (65535) 64.5kHz (>31)
if (count >= 255. * 256.) { prescaler = 1024; SET_CS(5, PRESCALER_1024); }
else if (count >= 255. * 64.) { prescaler = 256; SET_CS(5, PRESCALER_256); }
@@ -257,7 +257,7 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb
const float pwm_top = round(count); // Get the rounded count
ICR5 = (uint16_t)pwm_top - 1; // Subtract 1 for TOP
OCR5A = pwm_top * ABS(dca); // Update and scale DCs
OCR5A = pwm_top * ABS(dca); // Update and scale DCs
OCR5B = pwm_top * ABS(dcb);
OCR5C = pwm_top * ABS(dcc);
_SET_COM(5, A, dca ? (dca < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL); // Set compare modes
@@ -277,7 +277,7 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb
// Restore the default for Timer 5
SET_WGM(5, PWM_PC_8); // PWM 8-bit (Phase Correct)
SET_COMS(5, NORMAL, NORMAL, NORMAL); // Do nothing
SET_CS(5, PRESCALER_64); // 16MHz / 64 = 250KHz
SET_CS(5, PRESCALER_64); // 16MHz / 64 = 250kHz
OCR5A = OCR5B = OCR5C = 0;
}
return round(count);
+21 -44
View File
@@ -118,7 +118,7 @@
*/
// Waveform Generation Modes
enum WaveGenMode : char {
enum WaveGenMode : uint8_t {
WGM_NORMAL, // 0
WGM_PWM_PC_8, // 1
WGM_PWM_PC_9, // 2
@@ -138,19 +138,19 @@ enum WaveGenMode : char {
};
// Wavefore Generation Modes (Timer 2 only)
enum WaveGenMode2 : char {
WGM2_NORMAL, // 0
WGM2_PWM_PC, // 1
WGM2_CTC_OCR2A, // 2
WGM2_FAST_PWM, // 3
WGM2_reserved_1, // 4
WGM2_PWM_PC_OCR2A, // 5
WGM2_reserved_2, // 6
WGM2_FAST_PWM_OCR2A, // 7
enum WaveGenMode2 : uint8_t {
WGM2_NORMAL, // 0
WGM2_PWM_PC, // 1
WGM2_CTC_OCR2A, // 2
WGM2_FAST_PWM, // 3
WGM2_reserved_1, // 4
WGM2_PWM_PC_OCR2A, // 5
WGM2_reserved_2, // 6
WGM2_FAST_PWM_OCR2A, // 7
};
// Compare Modes
enum CompareMode : char {
enum CompareMode : uint8_t {
COM_NORMAL, // 0
COM_TOGGLE, // 1 Non-PWM: OCnx ... Both PWM (WGM 9,11,14,15): OCnA only ... else NORMAL
COM_CLEAR_SET, // 2 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down
@@ -158,7 +158,7 @@ enum CompareMode : char {
};
// Clock Sources
enum ClockSource : char {
enum ClockSource : uint8_t {
CS_NONE, // 0
CS_PRESCALER_1, // 1
CS_PRESCALER_8, // 2
@@ -170,7 +170,7 @@ enum ClockSource : char {
};
// Clock Sources (Timer 2 only)
enum ClockSource2 : char {
enum ClockSource2 : uint8_t {
CS2_NONE, // 0
CS2_PRESCALER_1, // 1
CS2_PRESCALER_8, // 2
@@ -203,40 +203,33 @@ enum ClockSource2 : char {
TCCR##T##B = (TCCR##T##B & ~(0x3 << WGM##T##2)) | (((int(V) >> 2) & 0x3) << WGM##T##2); \
}while(0)
#define SET_WGM(T,V) _SET_WGM(T,WGM_##V)
// Runtime (see set_pwm_frequency):
#define _SET_WGMnQ(TCCRnQ, V) do{ \
*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \
*(TCCRnQ)[1] = (*(TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \
}while(0)
// Set Clock Select bits
// Ex: SET_CS3(PRESCALER_64);
#ifdef TCCR2
#define HAS_TCCR2 1
#endif
#define _SET_CS(T,V) (TCCR##T##B = (TCCR##T##B & ~(0x7 << CS##T##0)) | ((int(V) & 0x7) << CS##T##0))
#define _SET_CS0(V) _SET_CS(0,V)
#define _SET_CS1(V) _SET_CS(1,V)
#ifdef TCCR2
#define _SET_CS2(V) (TCCR2 = (TCCR2 & ~(0x7 << CS20)) | (int(V) << CS20))
#else
#define _SET_CS2(V) _SET_CS(2,V)
#endif
#define _SET_CS3(V) _SET_CS(3,V)
#define _SET_CS4(V) _SET_CS(4,V)
#define _SET_CS5(V) _SET_CS(5,V)
#define SET_CS0(V) _SET_CS0(CS_##V)
#define SET_CS1(V) _SET_CS1(CS_##V)
#ifdef TCCR2
#if HAS_TCCR2
#define _SET_CS2(V) (TCCR2 = (TCCR2 & ~(0x7 << CS20)) | (int(V) << CS20))
#define SET_CS2(V) _SET_CS2(CS2_##V)
#else
#define _SET_CS2(V) _SET_CS(2,V)
#define SET_CS2(V) _SET_CS2(CS_##V)
#endif
#define SET_CS3(V) _SET_CS3(CS_##V)
#define SET_CS4(V) _SET_CS4(CS_##V)
#define SET_CS5(V) _SET_CS5(CS_##V)
#define SET_CS(T,V) SET_CS##T(V)
// Runtime (see set_pwm_frequency)
#define _SET_CSn(TCCRnQ, V) do{ \
(*(TCCRnQ)[1] = (*(TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0)); \
}while(0)
// Set Compare Mode bits
// Ex: SET_COMS(4,CLEAR_SET,CLEAR_SET,CLEAR_SET);
@@ -246,22 +239,6 @@ enum ClockSource2 : char {
#define SET_COMB(T,V) SET_COM(T,B,V)
#define SET_COMC(T,V) SET_COM(T,C,V)
#define SET_COMS(T,V1,V2,V3) do{ SET_COMA(T,V1); SET_COMB(T,V2); SET_COMC(T,V3); }while(0)
// Runtime (see set_pwm_duty)
#define _SET_COMnQ(TCCRnQ, Q, V) do{ \
(*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q)))); \
}while(0)
// Set OCRnQ register
// Runtime (see set_pwm_duty):
#define _SET_OCRnQ(OCRnQ, Q, V) do{ \
(*(OCRnQ)[(Q)] = (0x0000) | (int(V) & 0xFFFF)); \
}while(0)
// Set ICRn register (one per timer)
// Runtime (see set_pwm_frequency)
#define _SET_ICRn(ICRn, V) do{ \
(*(ICRn) = (0x0000) | (int(V) & 0xFFFF)); \
}while(0)
// Set Noise Canceler bit
// Ex: SET_ICNC(2,1)
+11 -3
View File
@@ -28,8 +28,16 @@
/**
* Checks for FAST PWM
*/
#if ENABLED(FAST_PWM_FAN) && (ENABLED(USE_OCR2A_AS_TOP) && defined(TCCR2))
#error "USE_OCR2A_AS_TOP does not apply to devices with a single output TIMER2"
#if ALL(FAST_PWM_FAN, USE_OCR2A_AS_TOP, HAS_TCCR2)
#error "USE_OCR2A_AS_TOP does not apply to devices with a single output TIMER2."
#endif
/**
* Checks for SOFT PWM
*/
#if HAS_FAN0 && FAN_PIN == 9 && DISABLED(FAN_SOFT_PWM) && ENABLED(SPEAKER)
#error "FAN_PIN 9 Hardware PWM uses Timer 2 which conflicts with Arduino AVR Tone Timer (for SPEAKER)."
#error "Disable SPEAKER or enable FAN_SOFT_PWM."
#endif
/**
@@ -42,7 +50,7 @@
#elif NUM_SERVOS > 0 && defined(_useTimer3) && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5)
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
#endif
#elif defined(SPINDLE_LASER_FREQUENCY)
#elif SPINDLE_LASER_FREQUENCY
#error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_USE_PWM."
#endif
+2 -2
View File
@@ -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__ (
+22 -21
View File
@@ -102,7 +102,7 @@ void PRINT_ARRAY_NAME(uint8_t x) {
return true; \
} else return false
#define ABTEST(N) defined(TCCR##N##A) && defined(COM##N##A1)
/**
* Print a pin's PWM status.
@@ -113,7 +113,7 @@ static bool pwm_status(uint8_t pin) {
switch (digitalPinToTimer_DEBUG(pin)) {
#if defined(TCCR0A) && defined(COM0A1)
#if ABTEST(0)
#ifdef TIMER0A
#if !AVR_AT90USB1286_FAMILY // not available in Teensyduino type IDEs
PWM_CASE(0, A);
@@ -122,20 +122,20 @@ static bool pwm_status(uint8_t pin) {
PWM_CASE(0, B);
#endif
#if defined(TCCR1A) && defined(COM1A1)
#if ABTEST(1)
PWM_CASE(1, A);
PWM_CASE(1, B);
#if defined(COM1C1) && defined(TIMER1C)
PWM_CASE(1, C);
#endif
#if defined(COM1C1) && defined(TIMER1C)
PWM_CASE(1, C);
#endif
#endif
#if defined(TCCR2A) && defined(COM2A1)
#if ABTEST(2)
PWM_CASE(2, A);
PWM_CASE(2, B);
#endif
#if defined(TCCR3A) && defined(COM3A1)
#if ABTEST(3)
PWM_CASE(3, A);
PWM_CASE(3, B);
#ifdef COM3C1
@@ -149,7 +149,7 @@ static bool pwm_status(uint8_t pin) {
PWM_CASE(4, C);
#endif
#if defined(TCCR5A) && defined(COM5A1)
#if ABTEST(5)
PWM_CASE(5, A);
PWM_CASE(5, B);
PWM_CASE(5, C);
@@ -166,16 +166,16 @@ static bool pwm_status(uint8_t pin) {
const volatile uint8_t* const PWM_other[][3] PROGMEM = {
{ &TCCR0A, &TCCR0B, &TIMSK0 },
{ &TCCR1A, &TCCR1B, &TIMSK1 },
#if defined(TCCR2A) && defined(COM2A1)
#if ABTEST(2)
{ &TCCR2A, &TCCR2B, &TIMSK2 },
#endif
#if defined(TCCR3A) && defined(COM3A1)
#if ABTEST(3)
{ &TCCR3A, &TCCR3B, &TIMSK3 },
#endif
#ifdef TCCR4A
{ &TCCR4A, &TCCR4B, &TIMSK4 },
#endif
#if defined(TCCR5A) && defined(COM5A1)
#if ABTEST(5)
{ &TCCR5A, &TCCR5B, &TIMSK5 },
#endif
};
@@ -195,11 +195,11 @@ const volatile uint8_t* const PWM_OCR[][3] PROGMEM = {
{ (const uint8_t*)&OCR1A, (const uint8_t*)&OCR1B, 0 },
#endif
#if defined(TCCR2A) && defined(COM2A1)
#if ABTEST(2)
{ &OCR2A, &OCR2B, 0 },
#endif
#if defined(TCCR3A) && defined(COM3A1)
#if ABTEST(3)
#ifdef COM3C1
{ (const uint8_t*)&OCR3A, (const uint8_t*)&OCR3B, (const uint8_t*)&OCR3C },
#else
@@ -211,7 +211,7 @@ const volatile uint8_t* const PWM_OCR[][3] PROGMEM = {
{ (const uint8_t*)&OCR4A, (const uint8_t*)&OCR4B, (const uint8_t*)&OCR4C },
#endif
#if defined(TCCR5A) && defined(COM5A1)
#if ABTEST(5)
{ (const uint8_t*)&OCR5A, (const uint8_t*)&OCR5B, (const uint8_t*)&OCR5C },
#endif
};
@@ -281,7 +281,7 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
static void pwm_details(uint8_t pin) {
switch (digitalPinToTimer_DEBUG(pin)) {
#if defined(TCCR0A) && defined(COM0A1)
#if ABTEST(0)
#ifdef TIMER0A
#if !AVR_AT90USB1286_FAMILY // not available in Teensyduino type IDEs
case TIMER0A: timer_prefix(0, 'A', 3); break;
@@ -290,7 +290,7 @@ static void pwm_details(uint8_t pin) {
case TIMER0B: timer_prefix(0, 'B', 3); break;
#endif
#if defined(TCCR1A) && defined(COM1A1)
#if ABTEST(1)
case TIMER1A: timer_prefix(1, 'A', 4); break;
case TIMER1B: timer_prefix(1, 'B', 4); break;
#if defined(COM1C1) && defined(TIMER1C)
@@ -298,12 +298,12 @@ static void pwm_details(uint8_t pin) {
#endif
#endif
#if defined(TCCR2A) && defined(COM2A1)
#if ABTEST(2)
case TIMER2A: timer_prefix(2, 'A', 3); break;
case TIMER2B: timer_prefix(2, 'B', 3); break;
#endif
#if defined(TCCR3A) && defined(COM3A1)
#if ABTEST(3)
case TIMER3A: timer_prefix(3, 'A', 4); break;
case TIMER3B: timer_prefix(3, 'B', 4); break;
#ifdef COM3C1
@@ -317,7 +317,7 @@ static void pwm_details(uint8_t pin) {
case TIMER4C: timer_prefix(4, 'C', 4); break;
#endif
#if defined(TCCR5A) && defined(COM5A1)
#if ABTEST(5)
case TIMER5A: timer_prefix(5, 'A', 4); break;
case TIMER5B: timer_prefix(5, 'B', 4); break;
case TIMER5C: timer_prefix(5, 'C', 4); break;
@@ -351,7 +351,6 @@ static void pwm_details(uint8_t pin) {
#endif
} // pwm_details
#ifndef digitalRead_mod // Use Teensyduino's version of digitalRead - it doesn't disable the PWMs
int digitalRead_mod(const int8_t pin) { // same as digitalRead except the PWM stop section has been removed
const uint8_t port = digitalPinToPort_DEBUG(pin);
@@ -397,3 +396,5 @@ static void pwm_details(uint8_t pin) {
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
#undef ABTEST
+22 -22
View File
@@ -34,14 +34,14 @@ typedef uint16_t hal_timer_t;
#define HAL_TIMER_RATE ((F_CPU) / 8) // i.e., 2MHz or 2.5MHz
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 1
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 1
#endif
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#endif
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM 0
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP 0
#endif
#define TEMP_TIMER_FREQUENCY ((F_CPU) / 64.0 / 256.0)
@@ -58,13 +58,13 @@ typedef uint16_t hal_timer_t;
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
#define STEPPER_ISR_ENABLED() TEST(TIMSK1, OCIE1A)
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0B)
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0B)
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0B)
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0A)
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0A)
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0A)
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
switch (timer_num) {
case STEP_TIMER_NUM:
case MF_TIMER_STEP:
// waveform generation = 0100 = CTC
SET_WGM(1, CTC_OCRnA);
@@ -84,10 +84,10 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
TCNT1 = 0;
break;
case TEMP_TIMER_NUM:
case MF_TIMER_TEMP:
// Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt
OCR0B = 128;
OCR0A = 128;
break;
}
}
@@ -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(TIMER_NUM)
#define HAL_timer_isr_epilogue(TIMER_NUM)
#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)); \
@@ -180,7 +180,7 @@ void TIMER1_COMPA_vect() { \
: \
: [timsk0] "i" ((uint16_t)&TIMSK0), \
[timsk1] "i" ((uint16_t)&TIMSK1), \
[msk0] "M" ((uint8_t)(1<<OCIE0B)),\
[msk0] "M" ((uint8_t)(1<<OCIE0A)),\
[msk1] "M" ((uint8_t)(1<<OCIE1A)) \
: \
); \
@@ -193,9 +193,9 @@ void TIMER1_COMPA_vect_bottom()
/* 14 cycles maximum latency */
#define HAL_TEMP_TIMER_ISR() \
extern "C" void TIMER0_COMPB_vect() __attribute__ ((signal, naked, used, externally_visible)); \
extern "C" void TIMER0_COMPB_vect_bottom() asm ("TIMER0_COMPB_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
void TIMER0_COMPB_vect() { \
extern "C" void TIMER0_COMPA_vect() __attribute__ ((signal, naked, used, externally_visible)); \
extern "C" void TIMER0_COMPA_vect_bottom() asm ("TIMER0_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
void TIMER0_COMPA_vect() { \
__asm__ __volatile__ ( \
A("push r16") /* 2 Save R16 */ \
A("in r16, __SREG__") /* 1 Get SREG */ \
@@ -223,7 +223,7 @@ void TIMER0_COMPB_vect() { \
A("push r30") \
A("push r31") \
A("clr r1") /* C runtime expects this register to be 0 */ \
A("call TIMER0_COMPB_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
A("call TIMER0_COMPA_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
A("pop r31") \
A("pop r30") \
A("pop r27") \
@@ -251,10 +251,10 @@ void TIMER0_COMPB_vect() { \
A("reti") /* 4 Return from interrupt */ \
: \
: [timsk0] "i"((uint16_t)&TIMSK0), \
[msk0] "M" ((uint8_t)(1<<OCIE0B)) \
[msk0] "M" ((uint8_t)(1<<OCIE0A)) \
: \
); \
} \
void TIMER0_COMPB_vect_bottom()
void TIMER0_COMPA_vect_bottom()
#endif // HAL_TEMP_TIMER_ISR
+9 -34
View File
@@ -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);
+89 -47
View File
@@ -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,55 +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();
//
// Pin Map
// Pin Mapping for M42, M43, M226
//
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
@@ -154,30 +141,19 @@ uint16_t HAL_adc_get_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);
// 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 push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
#pragma GCC diagnostic pop
#ifdef __cplusplus
extern "C" {
@@ -186,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);
}
};
+2 -2
View File
@@ -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)) {
+1 -1
View File
@@ -118,7 +118,7 @@ public:
static size_t write(const uint8_t c);
static void flushTX();
static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
static bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
+1 -1
View File
@@ -41,7 +41,7 @@ extern "C" {
int udi_cdc_getc();
bool udi_cdc_is_tx_ready();
int udi_cdc_putc(int value);
};
}
// Pending character
static int pending_char = -1;
+4 -4
View File
@@ -35,20 +35,20 @@
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(TONE_TIMER_NUM, 2 * frequency);
HAL_timer_start(MF_TIMER_TONE, 2 * frequency);
}
void noTone(const pin_t _pin) {
HAL_timer_disable_interrupt(TONE_TIMER_NUM);
HAL_timer_disable_interrupt(MF_TIMER_TONE);
extDigitalWrite(_pin, LOW);
}
HAL_TONE_TIMER_ISR() {
static uint8_t pin_state = 0;
HAL_timer_isr_prologue(TONE_TIMER_NUM);
HAL_timer_isr_prologue(MF_TIMER_TONE);
if (toggles) {
toggles--;
+1 -1
View File
@@ -25,7 +25,7 @@
* is NOT used to directly toggle pins. The ISR writes to the pin assigned to
* that interrupt.
*
* All PWMs use the same repetition rate. The G2 needs about 10KHz min in order to
* All PWMs use the same repetition rate. The G2 needs about 10kHz min in order to
* not have obvious ripple on the Vref signals.
*
* The data structures are setup to minimize the computation done by the ISR which
+1 -1
View File
@@ -53,7 +53,7 @@
* The net result is that both the g_pinStatus[pin] array and the PIO_OSR register
* needs to be looked at when determining if a pin is an input or an output.
*
* b) Due has only pins 6, 7, 8 & 9 enabled for PWMs. FYI - they run at 1KHz
* b) Due has only pins 6, 7, 8 & 9 enabled for PWMs. FYI - they run at 1kHz
*
* c) NUM_DIGITAL_PINS does not include the analog pins
*
+8 -8
View File
@@ -42,7 +42,7 @@
// Private Variables
// ------------------------
const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
const tTimerConfig timer_config[NUM_HARDWARE_TIMERS] = {
{ TC0, 0, TC0_IRQn, 3}, // 0 - [servo timer5]
{ TC0, 1, TC1_IRQn, 0}, // 1
{ TC0, 2, TC2_IRQn, 2}, // 2 - stepper
@@ -66,9 +66,9 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
*/
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
Tc *tc = TimerConfig[timer_num].pTimerRegs;
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
uint32_t channel = TimerConfig[timer_num].channel;
Tc *tc = timer_config[timer_num].pTimerRegs;
IRQn_Type irq = timer_config[timer_num].IRQ_Id;
uint32_t channel = timer_config[timer_num].channel;
// Disable interrupt, just in case it was already enabled
NVIC_DisableIRQ(irq);
@@ -86,7 +86,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
NVIC_SetPriority(irq, TimerConfig [timer_num].priority);
NVIC_SetPriority(irq, timer_config[timer_num].priority);
// wave mode, reset counter on match with RC,
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
@@ -105,12 +105,12 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
IRQn_Type irq = timer_config[timer_num].IRQ_Id;
NVIC_EnableIRQ(irq);
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
IRQn_Type irq = timer_config[timer_num].IRQ_Id;
NVIC_DisableIRQ(irq);
// We NEED memory barriers to ensure Interrupts are actually disabled!
@@ -125,7 +125,7 @@ static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
IRQn_Type irq = timer_config[timer_num].IRQ_Id;
return NVIC_GetEnabledIRQ(irq);
}
+25 -25
View File
@@ -37,35 +37,35 @@ typedef uint32_t hal_timer_t;
#define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 2 // Timer Index for Stepper
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 2 // Timer Index for Stepper
#endif
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#endif
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM 4 // Timer Index for Temperature
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP 4 // Timer Index for Temperature
#endif
#ifndef TONE_TIMER_NUM
#define TONE_TIMER_NUM 6 // index of timer to use for beeper tones
#ifndef MF_TIMER_TONE
#define MF_TIMER_TONE 6 // index of timer to use for beeper tones
#endif
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() void TC2_Handler()
@@ -92,7 +92,7 @@ typedef struct {
// Public Variables
// ------------------------
extern const tTimerConfig TimerConfig[];
extern const tTimerConfig timer_config[];
// ------------------------
// Public functions
@@ -101,17 +101,17 @@ extern const tTimerConfig TimerConfig[];
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
const tTimerConfig * const pConfig = &timer_config[timer_num];
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC = compare;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
const tTimerConfig * const pConfig = &timer_config[timer_num];
return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
const tTimerConfig * const pConfig = &timer_config[timer_num];
return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_CV;
}
@@ -120,9 +120,9 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
const tTimerConfig * const pConfig = &timer_config[timer_num];
// Reading the status register clears the interrupt flag
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR;
}
#define HAL_timer_isr_epilogue(TIMER_NUM)
#define HAL_timer_isr_epilogue(T) NOOP
+10 -9
View File
@@ -4,15 +4,16 @@
# Windows: bossac.exe
# Other: leave unchanged
#
import pioutil
if pioutil.is_pio_build():
import platform
current_OS = platform.system()
import platform
current_OS = platform.system()
if current_OS == 'Windows':
if current_OS == 'Windows':
Import("env")
Import("env")
# Use bossac.exe on Windows
env.Replace(
UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE"
)
# Use bossac.exe on Windows
env.Replace(
UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE"
)
+1 -1
View File
@@ -10,7 +10,7 @@
#include "../../../sd/cardreader.h"
extern "C" {
#include "sd_mmc_spi_mem.h"
#include "sd_mmc_spi_mem.h"
}
#define SD_MMC_BLOCK_SIZE 512
+22 -19
View File
@@ -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,26 @@ 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 MarlinHAL::reboot() { ESP.restart(); }
void _delay_ms(int delay_ms) { delay(delay_ms); }
// 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 +197,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);
@@ -211,7 +212,9 @@ void HAL_adc_init() {
TERN_(HAS_TEMP_ADC_7, adc3_set_attenuation(get_channel(TEMP_7_PIN), ADC_ATTEN_11db));
TERN_(HAS_HEATED_BED, adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_CHAMBER, adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_PROBE, adc1_set_attenuation(get_channel(TEMP_PROBE_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_COOLER, adc1_set_attenuation(get_channel(TEMP_COOLER_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_BOARD, adc1_set_attenuation(get_channel(TEMP_BOARD_PIN), ADC_ATTEN_11db));
TERN_(FILAMENT_WIDTH_SENSOR, adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db));
// Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail.
@@ -226,11 +229,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;
@@ -276,7 +279,7 @@ void analogWrite(pin_t pin, int value) {
idx = numPWMUsed;
pwmPins[idx] = pin;
// Start timer on first use
if (idx == 0) HAL_timer_start(PWM_TIMER_NUM, PWM_TIMER_FREQUENCY);
if (idx == 0) HAL_timer_start(MF_TIMER_PWM, PWM_TIMER_FREQUENCY);
++numPWMUsed;
}
@@ -287,7 +290,7 @@ void analogWrite(pin_t pin, int value) {
// Handle PWM timer interrupt
HAL_PWM_TIMER_ISR() {
HAL_timer_isr_prologue(PWM_TIMER_NUM);
HAL_timer_isr_prologue(MF_TIMER_PWM);
static uint8_t count = 0;
@@ -301,7 +304,7 @@ HAL_PWM_TIMER_ISR() {
// 128 for 7 Bit resolution
count = (count + 1) & 0x7F;
HAL_timer_isr_epilogue(PWM_TIMER_NUM);
HAL_timer_isr_epilogue(MF_TIMER_PWM);
}
#endif // ARDUINO_ARCH_ESP32
+87 -55
View File
@@ -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,57 +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);
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
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);
//
// 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
@@ -186,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);
}
};
+4 -4
View File
@@ -35,19 +35,19 @@
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(TONE_TIMER_NUM, 2 * frequency);
HAL_timer_start(MF_TIMER_TONE, 2 * frequency);
}
void noTone(const pin_t _pin) {
HAL_timer_disable_interrupt(TONE_TIMER_NUM);
HAL_timer_disable_interrupt(MF_TIMER_TONE);
WRITE(_pin, LOW);
}
HAL_TONE_TIMER_ISR() {
HAL_timer_isr_prologue(TONE_TIMER_NUM);
HAL_timer_isr_prologue(MF_TIMER_TONE);
if (toggles) {
toggles--;
+14 -16
View File
@@ -64,12 +64,9 @@ uint32_t i2s_port_data = 0;
#define I2S_EXIT_CRITICAL() portEXIT_CRITICAL(&i2s_spinlock[i2s_num])
static inline void gpio_matrix_out_check(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_inv) {
//if pin = -1, do not need to configure
if (gpio != -1) {
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
gpio_set_direction((gpio_num_t)gpio, (gpio_mode_t)GPIO_MODE_DEF_OUTPUT);
gpio_matrix_out(gpio, signal_idx, out_inv, oen_inv);
}
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
gpio_set_direction((gpio_num_t)gpio, (gpio_mode_t)GPIO_MODE_DEF_OUTPUT);
gpio_matrix_out(gpio, signal_idx, out_inv, oen_inv);
}
static esp_err_t i2s_reset_fifo(i2s_port_t i2s_num) {
@@ -256,13 +253,7 @@ int i2s_init() {
I2S0.fifo_conf.dscr_en = 0;
I2S0.conf_chan.tx_chan_mod = (
#if ENABLED(I2S_STEPPER_SPLIT_STREAM)
4
#else
0
#endif
);
I2S0.conf_chan.tx_chan_mod = TERN(I2S_STEPPER_SPLIT_STREAM, 4, 0);
I2S0.fifo_conf.tx_fifo_mod = 0;
I2S0.conf.tx_mono = 0;
@@ -313,9 +304,16 @@ int i2s_init() {
xTaskCreatePinnedToCore(stepperTask, "StepperTask", 10000, nullptr, 1, nullptr, CONFIG_ARDUINO_RUNNING_CORE); // run I2S stepper task on same core as rest of Marlin
// Route the i2s pins to the appropriate GPIO
gpio_matrix_out_check(I2S_DATA, I2S0O_DATA_OUT23_IDX, 0, 0);
gpio_matrix_out_check(I2S_BCK, I2S0O_BCK_OUT_IDX, 0, 0);
gpio_matrix_out_check(I2S_WS, I2S0O_WS_OUT_IDX, 0, 0);
// If a pin is not defined, no need to configure
#if defined(I2S_DATA) && I2S_DATA >= 0
gpio_matrix_out_check(I2S_DATA, I2S0O_DATA_OUT23_IDX, 0, 0);
#endif
#if defined(I2S_BCK) && I2S_BCK >= 0
gpio_matrix_out_check(I2S_BCK, I2S0O_BCK_OUT_IDX, 0, 0);
#endif
#if defined(I2S_WS) && I2S_WS >= 0
gpio_matrix_out_check(I2S_WS, I2S0O_WS_OUT_IDX, 0, 0);
#endif
// Start the I2S peripheral
return i2s_start(I2S_NUM_0);
+10 -10
View File
@@ -41,7 +41,7 @@
static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1};
const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
const tTimerConfig timer_config[NUM_HARDWARE_TIMERS] = {
{ TIMER_GROUP_0, TIMER_0, STEPPER_TIMER_PRESCALE, stepTC_Handler }, // 0 - Stepper
{ TIMER_GROUP_0, TIMER_1, TEMP_TIMER_PRESCALE, tempTC_Handler }, // 1 - Temperature
{ TIMER_GROUP_1, TIMER_0, PWM_TIMER_PRESCALE, pwmTC_Handler }, // 2 - PWM
@@ -53,7 +53,7 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
// ------------------------
void IRAM_ATTR timer_isr(void *para) {
const tTimerConfig& timer = TimerConfig[(int)para];
const tTimerConfig& timer = timer_config[(int)para];
// Retrieve the interrupt status and the counter value
// from the timer that reported the interrupt
@@ -81,8 +81,8 @@ 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) {
const tTimerConfig timer = TimerConfig[timer_num];
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
const tTimerConfig timer = timer_config[timer_num];
timer_config_t config;
config.divider = timer.divider;
@@ -115,7 +115,7 @@ void HAL_timer_start(const uint8_t timer_num, uint32_t frequency) {
* @param count threshold at which the interrupt is triggered
*/
void HAL_timer_set_compare(const uint8_t timer_num, hal_timer_t count) {
const tTimerConfig timer = TimerConfig[timer_num];
const tTimerConfig timer = timer_config[timer_num];
timer_set_alarm_value(timer.group, timer.idx, count);
}
@@ -125,7 +125,7 @@ void HAL_timer_set_compare(const uint8_t timer_num, hal_timer_t count) {
* @return the timer current threshold for the alarm to be triggered
*/
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
const tTimerConfig timer = TimerConfig[timer_num];
const tTimerConfig timer = timer_config[timer_num];
uint64_t alarm_value;
timer_get_alarm_value(timer.group, timer.idx, &alarm_value);
@@ -139,7 +139,7 @@ hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
* @return the current counter of the alarm
*/
hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
const tTimerConfig timer = TimerConfig[timer_num];
const tTimerConfig timer = timer_config[timer_num];
uint64_t counter_value;
timer_get_counter_value(timer.group, timer.idx, &counter_value);
return counter_value;
@@ -150,7 +150,7 @@ hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
* @param timer_num timer number to enable interrupts on
*/
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
//const tTimerConfig timer = TimerConfig[timer_num];
//const tTimerConfig timer = timer_config[timer_num];
//timer_enable_intr(timer.group, timer.idx);
}
@@ -159,12 +159,12 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num) {
* @param timer_num timer number to disable interrupts on
*/
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
//const tTimerConfig timer = TimerConfig[timer_num];
//const tTimerConfig timer = timer_config[timer_num];
//timer_disable_intr(timer.group, timer.idx);
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
const tTimerConfig timer = TimerConfig[timer_num];
const tTimerConfig timer = timer_config[timer_num];
return TG[timer.group]->int_ena.val | BIT(timer_num);
}
+19 -19
View File
@@ -32,20 +32,20 @@
typedef uint64_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFFFFFFFFFULL
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 0 // Timer Index for Stepper
#endif
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#endif
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM 1 // Timer Index for Temperature
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP 1 // Timer Index for Temperature
#endif
#ifndef PWM_TIMER_NUM
#define PWM_TIMER_NUM 2 // index of timer to use for PWM outputs
#ifndef MF_TIMER_PWM
#define MF_TIMER_PWM 2 // index of timer to use for PWM outputs
#endif
#ifndef TONE_TIMER_NUM
#define TONE_TIMER_NUM 3 // index of timer for beeper tones
#ifndef MF_TIMER_TONE
#define MF_TIMER_TONE 3 // index of timer for beeper tones
#endif
#define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals
@@ -79,12 +79,12 @@ typedef uint64_t hal_timer_t;
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_TEMP_TIMER_ISR
#define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler()
@@ -121,13 +121,13 @@ typedef struct {
// Public Variables
// ------------------------
extern const tTimerConfig TimerConfig[];
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(TIMER_NUM)
#define HAL_timer_isr_epilogue(TIMER_NUM)
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
+100
View File
@@ -0,0 +1,100 @@
/**
* 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
*
* Copypaste of SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* 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/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(FYSETC_MINI_12864_2_1)
#include <U8glib-HAL.h>
#include "Arduino.h"
#include "../shared/HAL_SPI.h"
#include "HAL.h"
#include "SPI.h"
static SPISettings spiConfig;
#define MDOGLCD_MOSI 23
#define MDOGLCD_SCK 18
#define MLCD_RESET_PIN 0
#define MLCD_PINS_DC 4
#define MDOGLCD_CS 21
#define MDOGLCD_A0 4
#ifndef LCD_SPI_SPEED
#ifdef SD_SPI_SPEED
#define LCD_SPI_SPEED SD_SPI_SPEED // Assume SPI speed shared with SD
#else
#define LCD_SPI_SPEED SPI_FULL_SPEED // Use full speed if SD speed is not supplied
#endif
#endif
uint8_t u8g_eps_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT
if (msgInitCount) {
if (msg == U8G_COM_MSG_INIT) msgInitCount--;
if (msgInitCount) return -1;
}
switch (msg) {
case U8G_COM_MSG_STOP: break;
case U8G_COM_MSG_INIT:
OUT_WRITE(MDOGLCD_CS, HIGH);
OUT_WRITE(MDOGLCD_A0, HIGH);
OUT_WRITE(MLCD_RESET_PIN, HIGH);
u8g_Delay(5);
spiBegin();
spiInit(LCD_SPI_SPEED);
break;
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
WRITE(MDOGLCD_A0, arg_val ? HIGH : LOW);
break;
case U8G_COM_MSG_CHIP_SELECT: /* arg_val == 0 means HIGH level of U8G_PI_CS */
WRITE(MDOGLCD_CS, arg_val ? LOW : HIGH);
break;
case U8G_COM_MSG_RESET:
WRITE(MLCD_RESET_PIN, arg_val);
break;
case U8G_COM_MSG_WRITE_BYTE:
spiSend((uint8_t)arg_val);
break;
case U8G_COM_MSG_WRITE_SEQ:
uint8_t *ptr = (uint8_t*) arg_ptr;
while (arg_val > 0) {
spiSend(*ptr++);
arg_val--;
}
break;
}
return 1;
}
#endif // FYSETC_MINI_12864_2_1
#endif // ARDUINO_ARCH_ESP32
+10 -27
View File
@@ -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__
+98 -52
View File
@@ -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,58 +37,125 @@ 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
// Utility functions
// ------------------------
// Class Utilities
// ------------------------
#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
#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:
// Reset source
inline void HAL_clear_reset_source(void) {}
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
// Earliest possible init, before setup()
MarlinHAL() {}
void HAL_reboot(); // Reset the application state and GPIO
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
/* ---------------- Delay in cycles */
FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {
Clock::delayCycles(x);
}
// 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) {}
// 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) {}
};
+1 -3
View File
@@ -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();
+3 -4
View File
@@ -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();
+13 -14
View File
@@ -37,14 +37,14 @@ typedef uint32_t hal_timer_t;
#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 0 // Timer Index for Stepper
#endif
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#endif
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM 1 // Timer Index for Temperature
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP 1 // Timer Index for Temperature
#endif
#define TEMP_TIMER_RATE 1000000
@@ -58,12 +58,12 @@ typedef uint32_t hal_timer_t;
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() extern "C" void TIMER0_IRQHandler()
@@ -77,7 +77,6 @@ typedef uint32_t hal_timer_t;
#define HAL_PWM_TIMER_ISR() extern "C" void TIMER3_IRQHandler()
#define HAL_PWM_TIMER_IRQn
void HAL_timer_init();
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
@@ -93,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(TIMER_NUM)
#define HAL_timer_isr_epilogue(TIMER_NUM)
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
+22 -24
View File
@@ -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
+99 -62
View File
@@ -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,28 +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
//
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
//
// ADC API
// ADC
//
#define ADC_MEDIAN_FILTER_SIZE (23) // Higher values increase step delay (phase shift),
@@ -154,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) {
@@ -194,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
* 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
*/
void set_pwm_frequency(const pin_t pin, int f_desired);
// Default graphical display delays
#define CPU_ST7920_DELAY_1 600
#define CPU_ST7920_DELAY_2 750
#define CPU_ST7920_DELAY_3 750
/**
* 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);
// ------------------------
// Class Utilities
// ------------------------
// Reset source
void HAL_clear_reset_source(void);
uint8_t HAL_get_reset_source(void);
#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
void HAL_reboot();
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 will run at the same frequency and
* All Software PWM pins will run at the same frequency
*/
static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
};
+2 -1
View File
@@ -65,4 +65,5 @@ class libServo: public Servo {
}
};
#define HAL_SERVO_LIB libServo
class libServo;
typedef libServo hal_servo_t;
+8 -10
View File
@@ -21,19 +21,17 @@
*/
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfigPre.h"
#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
#include "../../inc/MarlinConfig.h"
#include <pwm.h>
void set_pwm_frequency(const pin_t pin, int f_desired) {
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 MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
LPC176x::pwm_set_frequency(pin, f_desired);
}
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);
}
#endif // NEEDS_HARDWARE_PWM
#endif // TARGET_LPC1768
+1 -1
View File
@@ -113,7 +113,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#define _IS_RX1_1 IS_RX1
#if IS_TX1(TMC_SW_SCK)
#error "Serial port pins (1) conflict with other pins!"
#elif HAS_WIRED_LCD
#elif HAS_ROTARY_ENCODER
#if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1)
#error "Serial port pins (1) conflict with Encoder Buttons!"
#elif ANY_TX(1, SD_SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK_PIN) \
+1 -1
View File
@@ -77,7 +77,7 @@ public:
//uint32_t spiRate() const { return spi_speed; }
static inline uint32_t spiRate2Clock(uint32_t spiRate) {
static uint32_t spiRate2Clock(uint32_t spiRate) {
uint32_t Marlin_speed[7]; // CPSR is always 2
Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
+3 -3
View File
@@ -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.
+2 -2
View File
@@ -65,8 +65,8 @@ private:
static uint16_t getRawData(const XPTCoordinate coordinate);
static bool isTouched();
static inline void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); };
static inline void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
static void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); };
static void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
static uint16_t HardwareIO(uint16_t data);
#endif
+2 -2
View File
@@ -40,7 +40,7 @@ void HAL_timer_init() {
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
switch (timer_num) {
case 0:
case MF_TIMER_STEP:
LPC_TIM0->MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them
LPC_TIM0->MR0 = uint32_t(STEPPER_TIMER_RATE) / frequency; // Match value (period) to set frequency
LPC_TIM0->TCR = _BV(SBIT_CNTEN); // Counter Enable
@@ -49,7 +49,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
NVIC_EnableIRQ(TIMER0_IRQn);
break;
case 1:
case MF_TIMER_TEMP:
LPC_TIM1->MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them
LPC_TIM1->MR0 = uint32_t(TEMP_TIMER_RATE) / frequency;
LPC_TIM1->TCR = _BV(SBIT_CNTEN); // Counter Enable
+32 -32
View File
@@ -60,17 +60,17 @@ typedef uint32_t hal_timer_t;
#define HAL_TIMER_RATE ((F_CPU) / 4) // frequency of timers peripherals
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 0 // Timer Index for Stepper
#endif
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#endif
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM 1 // Timer Index for Temperature
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP 1 // Timer Index for Temperature
#endif
#ifndef PWM_TIMER_NUM
#define PWM_TIMER_NUM 3 // Timer Index for PWM
#ifndef MF_TIMER_PWM
#define MF_TIMER_PWM 3 // Timer Index for PWM
#endif
#define TEMP_TIMER_RATE 1000000
@@ -84,23 +84,23 @@ typedef uint32_t hal_timer_t;
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(STEP_TIMER_NUM)
#define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_STEP)
#endif
#ifndef HAL_TEMP_TIMER_ISR
#define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(TEMP_TIMER_NUM)
#define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_TEMP)
#endif
// Timer references by index
#define STEP_TIMER_PTR _HAL_TIMER(STEP_TIMER_NUM)
#define TEMP_TIMER_PTR _HAL_TIMER(TEMP_TIMER_NUM)
#define STEP_TIMER_PTR _HAL_TIMER(MF_TIMER_STEP)
#define TEMP_TIMER_PTR _HAL_TIMER(MF_TIMER_TEMP)
// ------------------------
// Public functions
@@ -110,38 +110,38 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
switch (timer_num) {
case 0: STEP_TIMER_PTR->MR0 = compare; break; // Stepper Timer Match Register 0
case 1: TEMP_TIMER_PTR->MR0 = compare; break; // Temp Timer Match Register 0
case MF_TIMER_STEP: STEP_TIMER_PTR->MR0 = compare; break; // Stepper Timer Match Register 0
case MF_TIMER_TEMP: TEMP_TIMER_PTR->MR0 = compare; break; // Temp Timer Match Register 0
}
}
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
switch (timer_num) {
case 0: return STEP_TIMER_PTR->MR0; // Stepper Timer Match Register 0
case 1: return TEMP_TIMER_PTR->MR0; // Temp Timer Match Register 0
case MF_TIMER_STEP: return STEP_TIMER_PTR->MR0; // Stepper Timer Match Register 0
case MF_TIMER_TEMP: return TEMP_TIMER_PTR->MR0; // Temp Timer Match Register 0
}
return 0;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
switch (timer_num) {
case 0: return STEP_TIMER_PTR->TC; // Stepper Timer Count
case 1: return TEMP_TIMER_PTR->TC; // Temp Timer Count
case MF_TIMER_STEP: return STEP_TIMER_PTR->TC; // Stepper Timer Count
case MF_TIMER_TEMP: return TEMP_TIMER_PTR->TC; // Temp Timer Count
}
return 0;
}
FORCE_INLINE static void HAL_timer_enable_interrupt(const uint8_t timer_num) {
switch (timer_num) {
case 0: NVIC_EnableIRQ(TIMER0_IRQn); break; // Enable interrupt handler
case 1: NVIC_EnableIRQ(TIMER1_IRQn); break; // Enable interrupt handler
case MF_TIMER_STEP: NVIC_EnableIRQ(TIMER0_IRQn); break; // Enable interrupt handler
case MF_TIMER_TEMP: NVIC_EnableIRQ(TIMER1_IRQn); break; // Enable interrupt handler
}
}
FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) {
switch (timer_num) {
case 0: NVIC_DisableIRQ(TIMER0_IRQn); break; // Disable interrupt handler
case 1: NVIC_DisableIRQ(TIMER1_IRQn); break; // Disable interrupt handler
case MF_TIMER_STEP: NVIC_DisableIRQ(TIMER0_IRQn); break; // Disable interrupt handler
case MF_TIMER_TEMP: NVIC_DisableIRQ(TIMER1_IRQn); break; // Disable interrupt handler
}
// We NEED memory barriers to ensure Interrupts are actually disabled!
@@ -157,17 +157,17 @@ FORCE_INLINE static bool NVIC_GetEnableIRQ(IRQn_Type IRQn) {
FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
switch (timer_num) {
case 0: return NVIC_GetEnableIRQ(TIMER0_IRQn); // Check if interrupt is enabled or not
case 1: return NVIC_GetEnableIRQ(TIMER1_IRQn); // Check if interrupt is enabled or not
case MF_TIMER_STEP: return NVIC_GetEnableIRQ(TIMER0_IRQn); // Check if interrupt is enabled or not
case MF_TIMER_TEMP: return NVIC_GetEnableIRQ(TIMER1_IRQn); // Check if interrupt is enabled or not
}
return false;
}
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
switch (timer_num) {
case 0: SBI(STEP_TIMER_PTR->IR, SBIT_CNTEN); break;
case 1: SBI(TEMP_TIMER_PTR->IR, SBIT_CNTEN); break;
case MF_TIMER_STEP: SBI(STEP_TIMER_PTR->IR, SBIT_CNTEN); break;
case MF_TIMER_TEMP: SBI(TEMP_TIMER_PTR->IR, SBIT_CNTEN); break;
}
}
#define HAL_timer_isr_epilogue(TIMER_NUM)
#define HAL_timer_isr_epilogue(T) NOOP
+102 -98
View File
@@ -1,123 +1,127 @@
#
# sets output_port
# upload_extra_script.py
# set the output_port
# if target_filename is found then that drive is used
# else if target_drive is found then that drive is used
#
from __future__ import print_function
target_filename = "FIRMWARE.CUR"
target_drive = "REARM"
import pioutil
if pioutil.is_pio_build():
import os,getpass,platform
target_filename = "FIRMWARE.CUR"
target_drive = "REARM"
current_OS = platform.system()
Import("env")
import os,getpass,platform
def print_error(e):
print('\nUnable to find destination disk (%s)\n' \
'Please select it in platformio.ini using the upload_port keyword ' \
'(https://docs.platformio.org/en/latest/projectconf/section_env_upload.html) ' \
'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \
%(e, env.get('PIOENV')))
current_OS = platform.system()
Import("env")
def before_upload(source, target, env):
try:
#
# Find a disk for upload
#
upload_disk = 'Disk not found'
target_file_found = False
target_drive_found = False
if current_OS == 'Windows':
def print_error(e):
print('\nUnable to find destination disk (%s)\n' \
'Please select it in platformio.ini using the upload_port keyword ' \
'(https://docs.platformio.org/en/latest/projectconf/section_env_upload.html) ' \
'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \
%(e, env.get('PIOENV')))
def before_upload(source, target, env):
try:
#
# platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
# Windows - doesn't care about the disk's name, only cares about the drive letter
import subprocess,string
from ctypes import windll
# Find a disk for upload
#
upload_disk = 'Disk not found'
target_file_found = False
target_drive_found = False
if current_OS == 'Windows':
#
# platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
# Windows - doesn't care about the disk's name, only cares about the drive letter
import subprocess,string
from ctypes import windll
# getting list of drives
# https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
drives = []
bitmask = windll.kernel32.GetLogicalDrives()
for letter in string.ascii_uppercase:
if bitmask & 1:
drives.append(letter)
bitmask >>= 1
# getting list of drives
# https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
drives = []
bitmask = windll.kernel32.GetLogicalDrives()
for letter in string.ascii_uppercase:
if bitmask & 1:
drives.append(letter)
bitmask >>= 1
for drive in drives:
final_drive_name = drive + ':\\'
# print ('disc check: {}'.format(final_drive_name))
try:
volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
except Exception as e:
print ('error:{}'.format(e))
continue
else:
if target_drive in volume_info and not target_file_found: # set upload if not found target file yet
target_drive_found = True
upload_disk = final_drive_name
if target_filename in volume_info:
if not target_file_found:
for drive in drives:
final_drive_name = drive + ':\\'
# print ('disc check: {}'.format(final_drive_name))
try:
volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
except Exception as e:
print ('error:{}'.format(e))
continue
else:
if target_drive in volume_info and not target_file_found: # set upload if not found target file yet
target_drive_found = True
upload_disk = final_drive_name
target_file_found = True
if target_filename in volume_info:
if not target_file_found:
upload_disk = final_drive_name
target_file_found = True
elif current_OS == 'Linux':
#
# platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
#
drives = os.listdir(os.path.join(os.sep, 'media', getpass.getuser()))
if target_drive in drives: # If target drive is found, use it.
target_drive_found = True
upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), target_drive) + os.sep
else:
elif current_OS == 'Linux':
#
# platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
#
drives = os.listdir(os.path.join(os.sep, 'media', getpass.getuser()))
if target_drive in drives: # If target drive is found, use it.
target_drive_found = True
upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), target_drive) + os.sep
else:
for drive in drives:
try:
files = os.listdir(os.path.join(os.sep, 'media', getpass.getuser(), drive))
except:
continue
else:
if target_filename in files:
upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), drive) + os.sep
target_file_found = True
break
#
# set upload_port to drive if found
#
if target_file_found or target_drive_found:
env.Replace(
UPLOAD_FLAGS="-P$UPLOAD_PORT"
)
elif current_OS == 'Darwin': # MAC
#
# platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
#
drives = os.listdir('/Volumes') # human readable names
if target_drive in drives and not target_file_found: # set upload if not found target file yet
target_drive_found = True
upload_disk = '/Volumes/' + target_drive + '/'
for drive in drives:
try:
files = os.listdir(os.path.join(os.sep, 'media', getpass.getuser(), drive))
filenames = os.listdir('/Volumes/' + drive + '/') # will get an error if the drive is protected
except:
continue
else:
if target_filename in files:
upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), drive) + os.sep
if target_filename in filenames:
if not target_file_found:
upload_disk = '/Volumes/' + drive + '/'
target_file_found = True
break
#
# set upload_port to drive if found
#
#
# Set upload_port to drive if found
#
if target_file_found or target_drive_found:
env.Replace(
UPLOAD_FLAGS="-P$UPLOAD_PORT"
)
env.Replace(UPLOAD_PORT=upload_disk)
print('\nUpload disk: ', upload_disk, '\n')
else:
print_error('Autodetect Error')
elif current_OS == 'Darwin': # MAC
#
# platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
#
drives = os.listdir('/Volumes') # human readable names
if target_drive in drives and not target_file_found: # set upload if not found target file yet
target_drive_found = True
upload_disk = '/Volumes/' + target_drive + '/'
for drive in drives:
try:
filenames = os.listdir('/Volumes/' + drive + '/') # will get an error if the drive is protected
except:
continue
else:
if target_filename in filenames:
if not target_file_found:
upload_disk = '/Volumes/' + drive + '/'
target_file_found = True
except Exception as e:
print_error(str(e))
#
# Set upload_port to drive if found
#
if target_file_found or target_drive_found:
env.Replace(UPLOAD_PORT=upload_disk)
print('\nUpload disk: ', upload_disk, '\n')
else:
print_error('Autodetect Error')
except Exception as e:
print_error(str(e))
env.AddPreAction("upload", before_upload)
env.AddPreAction("upload", before_upload)
+107 -61
View File
@@ -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,44 +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();
// Reset source
inline void HAL_clear_reset_source(void) {}
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
/* ---------------- Delay in cycles */
@@ -154,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;
}
@@ -188,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;
}
@@ -206,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);
}
};
+2 -2
View File
@@ -62,8 +62,8 @@ private:
static uint16_t getRawData(const XPTCoordinate coordinate);
static bool isTouched();
static inline void DataTransferBegin();
static inline void DataTransferEnd();
static void DataTransferBegin();
static void DataTransferEnd();
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
static uint16_t HardwareIO(uint16_t data);
#endif
+15 -15
View File
@@ -37,17 +37,17 @@ typedef uint64_t hal_timer_t;
#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 0 // Timer Index for Stepper
#endif
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#endif
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM 1 // Timer Index for Temperature
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP 1 // Timer Index for Temperature
#endif
#ifndef SYSTICK_TIMER_NUM
#define SYSTICK_TIMER_NUM 2 // Timer Index for Systick
#ifndef MF_TIMER_SYSTICK
#define MF_TIMER_SYSTICK 2 // Timer Index for Systick
#endif
#define SYSTICK_TIMER_FREQUENCY 1000
@@ -62,12 +62,12 @@ typedef uint64_t hal_timer_t;
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() extern "C" void TIMER0_IRQHandler()
@@ -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(TIMER_NUM)
#define HAL_timer_isr_epilogue(TIMER_NUM)
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
@@ -208,8 +208,11 @@ uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_pt
}
#endif
#elif !ANY(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI, HAS_MARLINUI_HD44780) && HAS_MARLINUI_U8GLIB
#elif NONE(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI, HAS_MARLINUI_HD44780) && HAS_MARLINUI_U8GLIB
#include <U8glib-HAL.h>
uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {return 0;}
#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#endif // __PLAT_NATIVE_SIM__
+208 -59
View File
@@ -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)
@@ -54,22 +50,28 @@
#define GET_TEMP_5_ADC() TERN(HAS_TEMP_ADC_5, PIN_TO_ADC(TEMP_5_PIN), -1)
#define GET_TEMP_6_ADC() TERN(HAS_TEMP_ADC_6, PIN_TO_ADC(TEMP_6_PIN), -1)
#define GET_TEMP_7_ADC() TERN(HAS_TEMP_ADC_7, PIN_TO_ADC(TEMP_7_PIN), -1)
#define GET_PROBE_ADC() TERN(HAS_TEMP_PROBE, PIN_TO_ADC(TEMP_PROBE_PIN), -1)
#define GET_BED_ADC() TERN(HAS_TEMP_ADC_BED, PIN_TO_ADC(TEMP_BED_PIN), -1)
#define GET_CHAMBER_ADC() TERN(HAS_TEMP_ADC_CHAMBER, PIN_TO_ADC(TEMP_CHAMBER_PIN), -1)
#define GET_PROBE_ADC() TERN(HAS_TEMP_ADC_PROBE, PIN_TO_ADC(TEMP_PROBE_PIN), -1)
#define GET_COOLER_ADC() TERN(HAS_TEMP_ADC_COOLER, PIN_TO_ADC(TEMP_COOLER_PIN), -1)
#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 \
|| GET_TEMP_4_ADC() == n || GET_TEMP_5_ADC() == n || GET_TEMP_6_ADC() == n || GET_TEMP_7_ADC() == n \
|| GET_PROBE_ADC() == n \
|| GET_BED_ADC() == n \
|| GET_CHAMBER_ADC() == n \
|| GET_COOLER_ADC() == n \
|| GET_BED_ADC() == n \
|| GET_CHAMBER_ADC() == n \
|| GET_PROBE_ADC() == n \
|| GET_COOLER_ADC() == n \
|| GET_BOARD_ADC() == n \
|| GET_FILAMENT_WIDTH_ADC() == n \
|| GET_BUTTONS_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)
@@ -89,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
// ------------------------
@@ -106,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,
@@ -137,24 +249,36 @@ uint16_t HAL_adc_result;
#if GET_TEMP_7_ADC() == 0
TEMP_7_PIN,
#endif
#if GET_PROBE_ADC() == 0
TEMP_PROBE_PIN,
#endif
#if GET_BED_ADC() == 0
TEMP_BED_PIN,
#endif
#if GET_CHAMBER_ADC() == 0
TEMP_CHAMBER_PIN,
#endif
#if GET_PROBE_ADC() == 0
TEMP_PROBE_PIN,
#endif
#if GET_COOLER_ADC() == 0
TEMP_COOLER_PIN,
#endif
#if GET_BOARD_ADC() == 0
TEMP_BOARD_PIN,
#endif
#if GET_FILAMENT_WIDTH_ADC() == 0
FILWIDTH_PIN,
#endif
#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,
@@ -180,33 +304,44 @@ uint16_t HAL_adc_result;
#if GET_TEMP_7_ADC() == 1
TEMP_7_PIN,
#endif
#if GET_PROBE_ADC() == 1
TEMP_PROBE_PIN,
#endif
#if GET_BED_ADC() == 1
TEMP_BED_PIN,
#endif
#if GET_CHAMBER_ADC() == 1
TEMP_CHAMBER_PIN,
#endif
#if GET_PROBE_ADC() == 1
TEMP_PROBE_PIN,
#endif
#if GET_COOLER_ADC() == 1
TEMP_COOLER_PIN,
#endif
#if GET_BOARD_ADC() == 1
TEMP_BOARD_PIN,
#endif
#if GET_FILAMENT_WIDTH_ADC() == 1
FILWIDTH_PIN,
#endif
#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
@@ -231,34 +366,45 @@ uint16_t HAL_adc_result;
#if GET_TEMP_7_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_7_PIN) },
#endif
#if GET_PROBE_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) },
#endif
#if GET_BED_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_BED_PIN) },
#endif
#if GET_CHAMBER_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
#endif
#if GET_PROBE_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) },
#endif
#if GET_COOLER_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) },
#endif
#if GET_BOARD_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_BOARD_PIN) },
#endif
#if GET_FILAMENT_WIDTH_ADC() == 0
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
#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
@@ -283,24 +429,36 @@ uint16_t HAL_adc_result;
#if GET_TEMP_7_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_7_PIN) },
#endif
#if GET_PROBE_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) },
#endif
#if GET_BED_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_BED_PIN) },
#endif
#if GET_CHAMBER_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
#endif
#if GET_PROBE_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) },
#endif
#if GET_COOLER_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) },
#endif
#if GET_BOARD_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_BOARD_PIN) },
#endif
#if GET_FILAMENT_WIDTH_ADC() == 1
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
#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)
@@ -312,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
@@ -343,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
@@ -380,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
@@ -393,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)
@@ -412,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;
@@ -436,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);
@@ -454,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);
@@ -491,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__
+84 -44
View File
@@ -89,46 +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();
#define cli() __disable_irq() // Disable interrupts
#define sei() __enable_irq() // Enable interrupts
//
// 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);
//
// Pin Map
// Pin Mapping for M42, M43, M226
//
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
@@ -137,37 +121,93 @@ void HAL_adc_start_conversion(const uint8_t adc_pin);
//
// 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 push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
#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();
};
+4 -4
View File
@@ -53,7 +53,7 @@
static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval)
FORCE_INLINE static uint16_t getTimerCount() {
Tc * const tc = TimerConfig[SERVO_TC].pTc;
Tc * const tc = timer_config[SERVO_TC].pTc;
tc->COUNT16.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC;
SYNC(tc->COUNT16.SYNCBUSY.bit.CTRLB || tc->COUNT16.SYNCBUSY.bit.COUNT);
@@ -65,7 +65,7 @@ FORCE_INLINE static uint16_t getTimerCount() {
// Interrupt handler for the TC
// ----------------------------
HAL_SERVO_TIMER_ISR() {
Tc * const tc = TimerConfig[SERVO_TC].pTc;
Tc * const tc = timer_config[SERVO_TC].pTc;
const timer16_Sequence_t timer =
#ifndef _useTimer1
_timer2
@@ -125,7 +125,7 @@ HAL_SERVO_TIMER_ISR() {
}
void initISR(timer16_Sequence_t timer) {
Tc * const tc = TimerConfig[SERVO_TC].pTc;
Tc * const tc = timer_config[SERVO_TC].pTc;
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
static bool initialized = false; // Servo TC has been initialized
@@ -202,7 +202,7 @@ void initISR(timer16_Sequence_t timer) {
}
void finISR(timer16_Sequence_t timer) {
Tc * const tc = TimerConfig[SERVO_TC].pTc;
Tc * const tc = timer_config[SERVO_TC].pTc;
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
// Disable the match channel interrupt request
+1 -1
View File
@@ -36,7 +36,7 @@
#error "OnBoard SPI BUS can't be shared with other devices."
#endif
#if SERVO_TC == RTC_TIMER_NUM
#if SERVO_TC == MF_TIMER_RTC
#error "Servos can't use RTC timer"
#endif
+11 -11
View File
@@ -31,13 +31,13 @@
// Local defines
// --------------------------------------------------------------------------
#define NUM_HARDWARE_TIMERS 8
#define NUM_HARDWARE_TIMERS 9
// --------------------------------------------------------------------------
// Private Variables
// --------------------------------------------------------------------------
const tTimerConfig TimerConfig[NUM_HARDWARE_TIMERS+1] = {
const tTimerConfig timer_config[NUM_HARDWARE_TIMERS] = {
{ {.pTc=TC0}, TC0_IRQn, TC_PRIORITY(0) }, // 0 - stepper (assigned priority 2)
{ {.pTc=TC1}, TC1_IRQn, TC_PRIORITY(1) }, // 1 - stepper (needed by 32 bit timers)
{ {.pTc=TC2}, TC2_IRQn, 5 }, // 2 - tone (reserved by framework and fixed assigned priority 5)
@@ -67,19 +67,19 @@ FORCE_INLINE void Disable_Irq(IRQn_Type irq) {
// --------------------------------------------------------------------------
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
IRQn_Type irq = timer_config[timer_num].IRQ_Id;
// Disable interrupt, just in case it was already enabled
Disable_Irq(irq);
if (timer_num == RTC_TIMER_NUM) {
Rtc * const rtc = TimerConfig[timer_num].pRtc;
if (timer_num == MF_TIMER_RTC) {
Rtc * const rtc = timer_config[timer_num].pRtc;
// Disable timer interrupt
rtc->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;
// RTC clock setup
OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC32K; // External 32.768KHz oscillator
OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC32K; // External 32.768kHz oscillator
// Stop timer, just in case, to be able to reconfigure it
rtc->MODE0.CTRLA.bit.ENABLE = false;
@@ -101,7 +101,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
SYNC(rtc->MODE0.SYNCBUSY.bit.ENABLE);
}
else {
Tc * const tc = TimerConfig[timer_num].pTc;
Tc * const tc = timer_config[timer_num].pTc;
// Disable timer interrupt
tc->COUNT32.INTENCLR.reg = TC_INTENCLR_OVF; // disable overflow interrupt
@@ -141,17 +141,17 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
}
// Finally, enable IRQ
NVIC_SetPriority(irq, TimerConfig[timer_num].priority);
NVIC_SetPriority(irq, timer_config[timer_num].priority);
NVIC_EnableIRQ(irq);
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
const IRQn_Type irq = timer_config[timer_num].IRQ_Id;
NVIC_EnableIRQ(irq);
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
const IRQn_Type irq = timer_config[timer_num].IRQ_Id;
Disable_Irq(irq);
}
@@ -161,7 +161,7 @@ static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
const IRQn_Type irq = timer_config[timer_num].IRQ_Id;
return NVIC_GetEnabledIRQ(irq);
}
+31 -31
View File
@@ -25,21 +25,22 @@
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
#define RTC_TIMER_NUM 8 // This is not a TC but a RTC
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
#define HAL_TIMER_RATE F_CPU // frequency of timers peripherals
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#define MF_TIMER_RTC 8 // This is not a TC but a RTC
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 0 // Timer Index for Stepper
#endif
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#endif
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM RTC_TIMER_NUM // Timer Index for Temperature
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP MF_TIMER_RTC // Timer Index for Temperature
#endif
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
@@ -52,30 +53,29 @@ typedef uint32_t hal_timer_t;
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#define TC_PRIORITY(t) t == SERVO_TC ? 1 \
: (t == STEP_TIMER_NUM || t == PULSE_TIMER_NUM) ? 2 \
: (t == TEMP_TIMER_NUM) ? 6 \
: 7
#define TC_PRIORITY(t) ( t == SERVO_TC ? 1 \
: (t == MF_TIMER_STEP || t == MF_TIMER_PULSE) ? 2 \
: (t == MF_TIMER_TEMP) ? 6 : 7 )
#define _TC_HANDLER(t) void TC##t##_Handler()
#define TC_HANDLER(t) _TC_HANDLER(t)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() TC_HANDLER(STEP_TIMER_NUM)
#define HAL_STEP_TIMER_ISR() TC_HANDLER(MF_TIMER_STEP)
#endif
#if STEP_TIMER_NUM != PULSE_TIMER_NUM
#define HAL_PULSE_TIMER_ISR() TC_HANDLER(PULSE_TIMER_NUM)
#if MF_TIMER_STEP != MF_TIMER_PULSE
#define HAL_PULSE_TIMER_ISR() TC_HANDLER(MF_TIMER_PULSE)
#endif
#if TEMP_TIMER_NUM == RTC_TIMER_NUM
#if MF_TIMER_TEMP == MF_TIMER_RTC
#define HAL_TEMP_TIMER_ISR() void RTC_Handler()
#else
#define HAL_TEMP_TIMER_ISR() TC_HANDLER(TEMP_TIMER_NUM)
#define HAL_TEMP_TIMER_ISR() TC_HANDLER(MF_TIMER_TEMP)
#endif
// --------------------------------------------------------------------------
@@ -95,7 +95,7 @@ typedef struct {
// Public Variables
// --------------------------------------------------------------------------
extern const tTimerConfig TimerConfig[];
extern const tTimerConfig timer_config[];
// --------------------------------------------------------------------------
// Public functions
@@ -104,20 +104,20 @@ extern const tTimerConfig TimerConfig[];
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
// Should never be called with timer RTC_TIMER_NUM
Tc * const tc = TimerConfig[timer_num].pTc;
// Should never be called with timer MF_TIMER_RTC
Tc * const tc = timer_config[timer_num].pTc;
tc->COUNT32.CC[0].reg = compare;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
// Should never be called with timer RTC_TIMER_NUM
Tc * const tc = TimerConfig[timer_num].pTc;
// Should never be called with timer MF_TIMER_RTC
Tc * const tc = timer_config[timer_num].pTc;
return (hal_timer_t)tc->COUNT32.CC[0].reg;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
// Should never be called with timer RTC_TIMER_NUM
Tc * const tc = TimerConfig[timer_num].pTc;
// Should never be called with timer MF_TIMER_RTC
Tc * const tc = timer_config[timer_num].pTc;
tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC;
SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB || tc->COUNT32.SYNCBUSY.bit.COUNT);
return tc->COUNT32.COUNT.reg;
@@ -128,13 +128,13 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
if (timer_num == RTC_TIMER_NUM) {
Rtc * const rtc = TimerConfig[timer_num].pRtc;
if (timer_num == MF_TIMER_RTC) {
Rtc * const rtc = timer_config[timer_num].pRtc;
// Clear interrupt flag
rtc->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
}
else {
Tc * const tc = TimerConfig[timer_num].pTc;
Tc * const tc = timer_config[timer_num].pTc;
// Clear interrupt flag
tc->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF;
}
+11 -19
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.
@@ -87,7 +89,7 @@ void HAL_init() {
SetTimerInterruptPriorities();
#if ENABLED(EMERGENCY_PARSER) && USBD_USE_CDC
#if ENABLED(EMERGENCY_PARSER) && (USBD_USE_CDC || USBD_USE_CDC_MSC)
USB_Hook_init();
#endif
@@ -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
void flashFirmware(const int16_t) { HAL_reboot(); }
WEAK void flashFirmware(const int16_t) { hal.reboot(); }
// Maple Compatibility
volatile uint32_t systick_uptime_millis = 0;
+107 -79
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,73 +115,32 @@
#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
// ------------------------
typedef int16_t pin_t;
#ifdef STM32G0B1xx
typedef int32_t pin_t;
#else
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
@@ -190,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)
@@ -222,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, int 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);
};
+1 -1
View File
@@ -135,7 +135,7 @@ void install_min_serial() {
HAL_min_serial_out = &TX;
}
#if DISABLED(DYNAMIC_VECTORTABLE) && DISABLED(STM32F0xx) // Cortex M0 can't jump to a symbol that's too far from the current function, so we work around this in exception_arm.cpp
#if NONE(DYNAMIC_VECTORTABLE, STM32F0xx, STM32G0xx) // Cortex M0 can't jump to a symbol that's too far from the current function, so we work around this in exception_arm.cpp
extern "C" {
__attribute__((naked)) void JumpHandler_ASM() {
__asm__ __volatile__ (
+4 -4
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
+7 -4
View File
@@ -114,16 +114,19 @@ byte MarlinSPI::transfer(uint8_t _data) {
return rxData;
}
__STATIC_INLINE void LL_SPI_EnableDMAReq_RX(SPI_TypeDef *SPIx) { SET_BIT(SPIx->CR2, SPI_CR2_RXDMAEN); }
__STATIC_INLINE void LL_SPI_EnableDMAReq_TX(SPI_TypeDef *SPIx) { SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN); }
uint8_t MarlinSPI::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length) {
const uint8_t ff = 0xFF;
//if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) //only enable if disabled
//if (!LL_SPI_IsEnabled(_spi.handle)) // only enable if disabled
__HAL_SPI_ENABLE(&_spi.handle);
if (receiveBuf) {
setupDma(_spi.handle, _dmaRx, DMA_PERIPH_TO_MEMORY, true);
HAL_DMA_Start(&_dmaRx, (uint32_t)&(_spi.handle.Instance->DR), (uint32_t)receiveBuf, length);
SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_RXDMAEN); /* Enable Rx DMA Request */
LL_SPI_EnableDMAReq_RX(_spi.handle.Instance); // Enable Rx DMA Request
}
// check for 2 lines transfer
@@ -136,7 +139,7 @@ uint8_t MarlinSPI::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16
if (transmitBuf) {
setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, mincTransmit);
HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length);
SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
LL_SPI_EnableDMAReq_TX(_spi.handle.Instance); // Enable Tx DMA Request
}
if (transmitBuf) {
@@ -160,7 +163,7 @@ uint8_t MarlinSPI::dmaSend(const void * transmitBuf, uint16_t length, bool minc)
setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, minc);
HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length);
__HAL_SPI_ENABLE(&_spi.handle);
SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
LL_SPI_EnableDMAReq_TX(_spi.handle.Instance); // Enable Tx DMA Request
HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
HAL_DMA_Abort(&_dmaTx);
// DeInit objects
+4 -4
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;
+52 -26
View File
@@ -24,39 +24,65 @@
#ifdef HAL_STM32
#include "../../inc/MarlinConfigPre.h"
#include "../../inc/MarlinConfig.h"
#if NEEDS_HARDWARE_PWM
// Array to support sticky frequency sets per timer
static uint16_t timer_freq[TIMER_NUM];
#include "HAL.h"
#include "timers.h"
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);
TIM_TypeDef * const Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM);
void set_pwm_frequency(const pin_t pin, int f_desired) {
if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer
const timer_index_t index = get_timer_index(Instance);
const bool needs_freq = (HardwareTimer_Handle[index] == nullptr);
if (needs_freq) // A new instance must be set to the default frequency of PWM_FREQUENCY
HardwareTimer_Handle[index]->__this = new HardwareTimer((TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM));
PinName pin_name = digitalPinToPinName(pin);
TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); // Get HAL timer instance
HardwareTimer * const HT = (HardwareTimer *)(HardwareTimer_Handle[index]->__this);
const uint32_t channel = STM_PIN_CHANNEL(pinmap_function(pin_name, PinMap_PWM));
const TimerModes_t previousMode = HT->getMode(channel);
if (previousMode != TIMER_OUTPUT_COMPARE_PWM1)
HT->setMode(channel, TIMER_OUTPUT_COMPARE_PWM1, pin);
LOOP_S_L_N(i, 0, NUM_HARDWARE_TIMERS) // Protect used timers
if (timer_instance[i] && timer_instance[i]->getHandle()->Instance == Instance)
return;
if (needs_freq && timer_freq[index] == 0) // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY
set_pwm_frequency(pin_name, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no.
pwm_start(pin_name, f_desired, 0, RESOLUTION_8B_COMPARE_FORMAT);
}
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
PinName pin_name = digitalPinToPinName(pin);
TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM);
uint16_t adj_val = Instance->ARR * v / v_size;
if (invert) adj_val = Instance->ARR - adj_val;
switch (get_pwm_channel(pin_name)) {
case TIM_CHANNEL_1: LL_TIM_OC_SetCompareCH1(Instance, adj_val); break;
case TIM_CHANNEL_2: LL_TIM_OC_SetCompareCH2(Instance, adj_val); break;
case TIM_CHANNEL_3: LL_TIM_OC_SetCompareCH3(Instance, adj_val); break;
case TIM_CHANNEL_4: LL_TIM_OC_SetCompareCH4(Instance, adj_val); break;
// Note the resolution is sticky here, the input can be upto 16 bits and that would require RESOLUTION_16B_COMPARE_FORMAT (16)
// If such a need were to manifest then we would need to calc the resolution based on the v_size parameter and add code for it.
HT->setCaptureCompare(channel, duty, RESOLUTION_8B_COMPARE_FORMAT); // Set the duty, the calc is done in the library :)
pinmap_pinout(pin_name, PinMap_PWM); // Make sure the pin output state is set.
if (previousMode != TIMER_OUTPUT_COMPARE_PWM1) HT->resume();
}
else {
pinMode(pin, OUTPUT);
digitalWrite(pin, duty < v_size / 2 ? LOW : HIGH);
}
}
#endif // NEEDS_HARDWARE_PWM
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
const timer_index_t index = get_timer_index(Instance);
// Protect used timers.
#ifdef STEP_TIMER
if (index == TIMER_INDEX(STEP_TIMER)) return;
#endif
#ifdef TEMP_TIMER
if (index == TIMER_INDEX(TEMP_TIMER)) return;
#endif
#if defined(PULSE_TIMER) && MF_TIMER_PULSE != MF_TIMER_STEP
if (index == TIMER_INDEX(PULSE_TIMER)) return;
#endif
if (HardwareTimer_Handle[index] == nullptr) // If frequency is set before duty we need to create a handle here.
HardwareTimer_Handle[index]->__this = new HardwareTimer((TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM));
HardwareTimer * const HT = (HardwareTimer *)(HardwareTimer_Handle[index]->__this);
HT->setOverflow(f_desired, HERTZ_FORMAT);
timer_freq[index] = f_desired; // Save the last frequency so duty will not set the default for this timer number.
}
#endif // HAL_STM32
+5 -1
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
@@ -28,6 +28,8 @@
#if ENABLED(SDIO_SUPPORT)
#include "sdio.h"
#include <stdint.h>
#include <stdbool.h>
@@ -49,14 +51,6 @@
#error "SDIO only supported with STM32F103xE, STM32F103xG, STM32F4xx, or STM32F7xx."
#endif
// Fixed
#define SDIO_D0_PIN PC8
#define SDIO_D1_PIN PC9
#define SDIO_D2_PIN PC10
#define SDIO_D3_PIN PC11
#define SDIO_CK_PIN PC12
#define SDIO_CMD_PIN PD2
SD_HandleTypeDef hsd; // create SDIO structure
// F4 supports one DMA for RX and another for TX, but Marlin will never
// do read and write at same time, so we use the same DMA for both.
@@ -65,7 +59,7 @@ DMA_HandleTypeDef hdma_sdio;
/*
SDIO_INIT_CLK_DIV is 118
SDIO clock frequency is 48MHz / (TRANSFER_CLOCK_DIV + 2)
SDIO init clock frequency should not exceed 400KHz = 48MHz / (118 + 2)
SDIO init clock frequency should not exceed 400kHz = 48MHz / (118 + 2)
Default TRANSFER_CLOCK_DIV is 2 (118 / 40)
Default SDIO clock frequency is 48MHz / (2 + 2) = 12 MHz
+29
View File
@@ -0,0 +1,29 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 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/>.
*
*/
#pragma once
#define SDIO_D0_PIN PC8
#define SDIO_D1_PIN PC9
#define SDIO_D2_PIN PC10
#define SDIO_D3_PIN PC11
#define SDIO_CK_PIN PC12
#define SDIO_CMD_PIN PD2
+30 -6
View File
@@ -161,11 +161,11 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
for (i = 0; i < 4; i++) {
#if TFT_MISO_PIN != TFT_MOSI_PIN
//if (hspi->Init.Direction == SPI_DIRECTION_2LINES) {
while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {}
SPIx.Instance->DR = 0;
//}
#endif
while ((SPIx.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {}
while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_RXNE)) {}
Data = (Data << 8) | SPIx.Instance->DR;
}
@@ -195,8 +195,8 @@ bool TFT_SPI::isBusy() {
void TFT_SPI::Abort() {
// Wait for any running spi
while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {}
while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {}
while ( __HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_BSY)) {}
// First, abort any running dma
HAL_DMA_Abort(&DMAtx);
// DeInit objects
@@ -214,8 +214,8 @@ void TFT_SPI::Transmit(uint16_t Data) {
SPIx.Instance->DR = Data;
while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {}
while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {}
while ( __HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_BSY)) {}
if (TFT_MISO_PIN != TFT_MOSI_PIN)
__HAL_SPI_CLEAR_OVRFLAG(&SPIx); // Clear overrun flag in 2 Lines communication mode because received is not read
@@ -242,5 +242,29 @@ void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Coun
Abort();
}
#if ENABLED(USE_SPI_DMA_TC)
void TFT_SPI::TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DMAtx.Init.MemInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx);
if (TFT_MISO_PIN == TFT_MOSI_PIN)
SPI_1LINE_TX(&SPIx);
DataTransferBegin();
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
HAL_DMA_Start_IT(&DMAtx, (uint32_t)Data, (uint32_t)&(SPIx.Instance->DR), Count);
__HAL_SPI_ENABLE(&SPIx);
SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); // Enable Tx DMA Request
}
extern "C" void DMA2_Stream3_IRQHandler(void) { HAL_DMA_IRQHandler(&TFT_SPI::DMAtx); }
#endif
#endif // HAS_SPI_TFT
#endif // HAL_STM32
+14 -4
View File
@@ -36,20 +36,25 @@
#define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
#endif
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO_DRIVER TFT_SPI
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO_DRIVER TFT_SPI
class TFT_SPI {
private:
static SPI_HandleTypeDef SPIx;
static DMA_HandleTypeDef DMAtx;
static uint32_t ReadID(uint16_t Reg);
static void Transmit(uint16_t Data);
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
#if ENABLED(USE_SPI_DMA_TC)
static void TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
#endif
public:
static DMA_HandleTypeDef DMAtx;
static void Init();
static uint32_t GetID();
static bool isBusy();
@@ -63,6 +68,11 @@ public:
static void WriteReg(uint16_t Reg) { WRITE(TFT_A0_PIN, LOW); Transmit(Reg); WRITE(TFT_A0_PIN, HIGH); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); }
#if ENABLED(USE_SPI_DMA_TC)
static void WriteSequenceIT(uint16_t *Data, uint16_t Count) { TransmitDMA_IT(DMA_MINC_ENABLE, Data, Count); }
#endif
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
+2 -2
View File
@@ -69,8 +69,8 @@ private:
static uint16_t getRawData(const XPTCoordinate coordinate);
static bool isTouched();
static inline void DataTransferBegin() { if (SPIx.Instance) { HAL_SPI_Init(&SPIx); } WRITE(TOUCH_CS_PIN, LOW); };
static inline void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
static void DataTransferBegin() { if (SPIx.Instance) { HAL_SPI_Init(&SPIx); } WRITE(TOUCH_CS_PIN, LOW); };
static void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
static uint16_t HardwareIO(uint16_t data);
static uint16_t SoftwareIO(uint16_t data);
static uint16_t IO(uint16_t data = 0) { return SPIx.Instance ? HardwareIO(data) : SoftwareIO(data); }
+18 -12
View File
@@ -67,17 +67,17 @@
#endif
#endif
#ifdef STM32F0xx
#if defined(STM32F0xx) || defined(STM32G0xx)
#define MCU_STEP_TIMER 16
#define MCU_TEMP_TIMER 17
#elif defined(STM32F1xx)
#define MCU_STEP_TIMER 4
#define MCU_TEMP_TIMER 2
#elif defined(STM32F401xC) || defined(STM32F401xE)
#define MCU_STEP_TIMER 9
#define MCU_STEP_TIMER 9 // STM32F401 has no TIM6, TIM7, or TIM8
#define MCU_TEMP_TIMER 10
#elif defined(STM32F4xx) || defined(STM32F7xx) || defined(STM32H7xx)
#define MCU_STEP_TIMER 6 // STM32F401 has no TIM6, TIM7, or TIM8
#define MCU_STEP_TIMER 6
#define MCU_TEMP_TIMER 14 // TIM7 is consumed by Software Serial if used.
#endif
@@ -97,9 +97,15 @@
#define STEP_TIMER_DEV _TIMER_DEV(STEP_TIMER)
#define TEMP_TIMER_DEV _TIMER_DEV(TEMP_TIMER)
// ------------------------
// --------------------------------------------------------------------------
// Local defines
// --------------------------------------------------------------------------
#define NUM_HARDWARE_TIMERS 2
// --------------------------------------------------------------------------
// Private Variables
// ------------------------
// --------------------------------------------------------------------------
HardwareTimer *timer_instance[NUM_HARDWARE_TIMERS] = { nullptr };
@@ -110,7 +116,7 @@ HardwareTimer *timer_instance[NUM_HARDWARE_TIMERS] = { nullptr };
uint32_t GetStepperTimerClkFreq() {
// Timer input clocks vary between devices, and in some cases between timers on the same device.
// Retrieve at runtime to ensure device compatibility. Cache result to avoid repeated overhead.
static uint32_t clkfreq = timer_instance[STEP_TIMER_NUM]->getTimerClkFreq();
static uint32_t clkfreq = timer_instance[MF_TIMER_STEP]->getTimerClkFreq();
return clkfreq;
}
@@ -118,7 +124,7 @@ uint32_t GetStepperTimerClkFreq() {
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
if (!HAL_timer_initialized(timer_num)) {
switch (timer_num) {
case STEP_TIMER_NUM: // STEPPER TIMER - use a 32bit timer if possible
case MF_TIMER_STEP: // STEPPER TIMER - use a 32bit timer if possible
timer_instance[timer_num] = new HardwareTimer(STEP_TIMER_DEV);
/* Set the prescaler to the final desired value.
* This will change the effective ISR callback frequency but when
@@ -137,7 +143,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timer_instance[timer_num]->setPrescaleFactor(STEPPER_TIMER_PRESCALE); //the -1 is done internally
timer_instance[timer_num]->setOverflow(_MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* /frequency */), TICK_FORMAT);
break;
case TEMP_TIMER_NUM: // TEMP TIMER - any available 16bit timer
case MF_TIMER_TEMP: // TEMP TIMER - any available 16bit timer
timer_instance[timer_num] = new HardwareTimer(TEMP_TIMER_DEV);
// The prescale factor is computed automatically for HERTZ_FORMAT
timer_instance[timer_num]->setOverflow(frequency, HERTZ_FORMAT);
@@ -157,10 +163,10 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
// These calls can be removed and replaced with
// timer_instance[timer_num]->setInterruptPriority
switch (timer_num) {
case STEP_TIMER_NUM:
case MF_TIMER_STEP:
timer_instance[timer_num]->setInterruptPriority(STEP_TIMER_IRQ_PRIO, 0);
break;
case TEMP_TIMER_NUM:
case MF_TIMER_TEMP:
timer_instance[timer_num]->setInterruptPriority(TEMP_TIMER_IRQ_PRIO, 0);
break;
}
@@ -170,10 +176,10 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
if (HAL_timer_initialized(timer_num) && !timer_instance[timer_num]->hasInterrupt()) {
switch (timer_num) {
case STEP_TIMER_NUM:
case MF_TIMER_STEP:
timer_instance[timer_num]->attachInterrupt(Step_Handler);
break;
case TEMP_TIMER_NUM:
case MF_TIMER_TEMP:
timer_instance[timer_num]->attachInterrupt(Temp_Handler);
break;
}
+13 -17
View File
@@ -40,17 +40,13 @@
#define hal_timer_t uint32_t
#define HAL_TIMER_TYPE_MAX UINT16_MAX
#define NUM_HARDWARE_TIMERS 2
// Marlin timer_instance[] content (unrelated to timer selection)
#define MF_TIMER_STEP 0 // Timer Index for Stepper
#define MF_TIMER_TEMP 1 // Timer Index for Temperature
#define MF_TIMER_PULSE MF_TIMER_STEP
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#endif
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#endif
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM 1 // Timer Index for Temperature
#endif
#define TIMER_INDEX_(T) TIMER##T##_INDEX // TIMER#_INDEX enums (timer_index_t) depend on TIM#_BASE defines.
#define TIMER_INDEX(T) TIMER_INDEX_(T) // Convert Timer ID to HardwareTimer_Handle index.
#define TEMP_TIMER_FREQUENCY 1000 // Temperature::isr() is expected to be called at around 1kHz
@@ -64,12 +60,12 @@ extern uint32_t GetStepperTimerClkFreq();
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
extern void Step_Handler();
extern void Temp_Handler();
@@ -120,5 +116,5 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const ha
}
}
#define HAL_timer_isr_prologue(TIMER_NUM)
#define HAL_timer_isr_epilogue(TIMER_NUM)
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
+1 -1
View File
@@ -26,7 +26,7 @@
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(EMERGENCY_PARSER) && USBD_USE_CDC
#if ENABLED(EMERGENCY_PARSER) && (USBD_USE_CDC || USBD_USE_CDC_MSC)
#include "usb_serial.h"
#include "../../feature/e_parser.h"
+109 -228
View File
@@ -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,148 +112,37 @@
#endif
#endif
uint16_t HAL_adc_result;
// ------------------------
// Private Variables
// ADC
// ------------------------
STM32ADC adc(ADC1);
const uint8_t adc_pins[] = {
#if HAS_TEMP_ADC_0
TEMP_0_PIN,
#endif
#if HAS_TEMP_ADC_PROBE
TEMP_PROBE_PIN,
#endif
#if HAS_HEATED_BED
TEMP_BED_PIN,
#endif
#if HAS_TEMP_CHAMBER
TEMP_CHAMBER_PIN,
#endif
#if HAS_TEMP_COOLER
TEMP_COOLER_PIN,
#endif
#if HAS_TEMP_ADC_1
TEMP_1_PIN,
#endif
#if HAS_TEMP_ADC_2
TEMP_2_PIN,
#endif
#if HAS_TEMP_ADC_3
TEMP_3_PIN,
#endif
#if HAS_TEMP_ADC_4
TEMP_4_PIN,
#endif
#if HAS_TEMP_ADC_5
TEMP_5_PIN,
#endif
#if HAS_TEMP_ADC_6
TEMP_6_PIN,
#endif
#if HAS_TEMP_ADC_7
TEMP_7_PIN,
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
FILWIDTH_PIN,
#endif
#if HAS_ADC_BUTTONS
ADC_KEYPAD_PIN,
#endif
#if HAS_JOY_ADC_X
JOY_X_PIN,
#endif
#if HAS_JOY_ADC_Y
JOY_Y_PIN,
#endif
#if HAS_JOY_ADC_Z
JOY_Z_PIN,
#endif
#if ENABLED(POWER_MONITOR_CURRENT)
POWER_MONITOR_CURRENT_PIN,
#endif
#if ENABLED(POWER_MONITOR_VOLTAGE)
POWER_MONITOR_VOLTAGE_PIN,
#endif
};
// Watch out for recursion here! Our pin_t is signed, so pass through to Arduino -> analogRead(uint8_t)
enum TempPinIndex : char {
#if HAS_TEMP_ADC_0
TEMP_0,
#endif
#if HAS_TEMP_ADC_PROBE
TEMP_PROBE,
#endif
#if HAS_HEATED_BED
TEMP_BED,
#endif
#if HAS_TEMP_CHAMBER
TEMP_CHAMBER,
#endif
#if HAS_TEMP_COOLER
TEMP_COOLER_PIN,
#endif
#if HAS_TEMP_ADC_1
TEMP_1,
#endif
#if HAS_TEMP_ADC_2
TEMP_2,
#endif
#if HAS_TEMP_ADC_3
TEMP_3,
#endif
#if HAS_TEMP_ADC_4
TEMP_4,
#endif
#if HAS_TEMP_ADC_5
TEMP_5,
#endif
#if HAS_TEMP_ADC_6
TEMP_6,
#endif
#if HAS_TEMP_ADC_7
TEMP_7,
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
FILWIDTH,
#endif
#if HAS_ADC_BUTTONS
ADC_KEY,
#endif
#if HAS_JOY_ADC_X
JOY_X,
#endif
#if HAS_JOY_ADC_Y
JOY_Y,
#endif
#if HAS_JOY_ADC_Z
JOY_Z,
#endif
#if ENABLED(POWER_MONITOR_CURRENT)
POWERMON_CURRENT,
#endif
#if ENABLED(POWER_MONITOR_VOLTAGE)
POWERMON_VOLTS,
#endif
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;
}
@@ -261,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
//
@@ -280,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);
@@ -299,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.
@@ -314,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
@@ -355,106 +243,99 @@ 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) {
//TEMP_PINS pin_index;
TempPinIndex pin_index;
switch (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))
ADCIndex pin_index;
switch (pin) {
default: return;
#if HAS_TEMP_ADC_0
case TEMP_0_PIN: pin_index = TEMP_0; break;
#endif
#if HAS_TEMP_ADC_PROBE
case TEMP_PROBE_PIN: pin_index = TEMP_PROBE; break;
#endif
#if HAS_HEATED_BED
case TEMP_BED_PIN: pin_index = TEMP_BED; break;
#endif
#if HAS_TEMP_CHAMBER
case TEMP_CHAMBER_PIN: pin_index = TEMP_CHAMBER; break;
#endif
#if HAS_TEMP_COOLER
case TEMP_COOLER_PIN: pin_index = TEMP_COOLER; break;
#endif
#if HAS_TEMP_ADC_1
case TEMP_1_PIN: pin_index = TEMP_1; break;
#endif
#if HAS_TEMP_ADC_2
case TEMP_2_PIN: pin_index = TEMP_2; break;
#endif
#if HAS_TEMP_ADC_3
case TEMP_3_PIN: pin_index = TEMP_3; break;
#endif
#if HAS_TEMP_ADC_4
case TEMP_4_PIN: pin_index = TEMP_4; break;
#endif
#if HAS_TEMP_ADC_5
case TEMP_5_PIN: pin_index = TEMP_5; break;
#endif
#if HAS_TEMP_ADC_6
case TEMP_6_PIN: pin_index = TEMP_6; break;
#endif
#if HAS_TEMP_ADC_7
case TEMP_7_PIN: pin_index = TEMP_7; break;
#endif
#if HAS_JOY_ADC_X
case JOY_X_PIN: pin_index = JOY_X; break;
#endif
#if HAS_JOY_ADC_Y
case JOY_Y_PIN: pin_index = JOY_Y; break;
#endif
#if HAS_JOY_ADC_Z
case JOY_Z_PIN: pin_index = JOY_Z; break;
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
case FILWIDTH_PIN: pin_index = FILWIDTH; break;
#endif
#if HAS_ADC_BUTTONS
case ADC_KEYPAD_PIN: pin_index = ADC_KEY; break;
#endif
#if ENABLED(POWER_MONITOR_CURRENT)
case POWER_MONITOR_CURRENT_PIN: pin_index = POWERMON_CURRENT; break;
#endif
#if ENABLED(POWER_MONITOR_VOLTAGE)
case POWER_MONITOR_VOLTAGE_PIN: pin_index = POWERMON_VOLTS; break;
#endif
_TCASE(HAS_TEMP_ADC_0, TEMP_0_PIN, TEMP_0)
_TCASE(HAS_TEMP_ADC_1, TEMP_1_PIN, TEMP_1)
_TCASE(HAS_TEMP_ADC_2, TEMP_2_PIN, TEMP_2)
_TCASE(HAS_TEMP_ADC_3, TEMP_3_PIN, TEMP_3)
_TCASE(HAS_TEMP_ADC_4, TEMP_4_PIN, TEMP_4)
_TCASE(HAS_TEMP_ADC_5, TEMP_5_PIN, TEMP_5)
_TCASE(HAS_TEMP_ADC_6, TEMP_6_PIN, TEMP_6)
_TCASE(HAS_TEMP_ADC_7, TEMP_7_PIN, TEMP_7)
_TCASE(HAS_HEATED_BED, TEMP_BED_PIN, TEMP_BED)
_TCASE(HAS_TEMP_CHAMBER, TEMP_CHAMBER_PIN, TEMP_CHAMBER)
_TCASE(HAS_TEMP_ADC_PROBE, TEMP_PROBE_PIN, TEMP_PROBE)
_TCASE(HAS_TEMP_COOLER, TEMP_COOLER_PIN, TEMP_COOLER)
_TCASE(HAS_TEMP_BOARD, TEMP_BOARD_PIN, TEMP_BOARD)
_TCASE(HAS_JOY_ADC_X, JOY_X_PIN, JOY_X)
_TCASE(HAS_JOY_ADC_Y, JOY_Y_PIN, JOY_Y)
_TCASE(HAS_JOY_ADC_Z, JOY_Z_PIN, JOY_Z)
_TCASE(FILAMENT_WIDTH_SENSOR, FILWIDTH_PIN, FILWIDTH)
_TCASE(HAS_ADC_BUTTONS, ADC_KEYPAD_PIN, ADC_KEY)
_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] >> (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__
+109 -85
View File
@@ -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 (!primask) (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,39 +192,115 @@ 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)
#define JTAG_DISABLE() afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY)
#define JTAG_DISABLE() afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY)
#define JTAGSWD_DISABLE() afio_cfg_debug_ports(AFIO_DEBUG_NONE)
#define PLATFORM_M997_SUPPORT
void flashFirmware(const int16_t);
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
#ifndef PWM_FREQUENCY
#define PWM_FREQUENCY 1000 // Default PWM Frequency
#endif
/**
* 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, int 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__
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.
*/
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);
};
+8
View File
@@ -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
*/
-8
View File
@@ -414,12 +414,4 @@ private:
*/
};
/**
* @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
}
extern SPIClass SPI;
+9 -9
View File
@@ -60,7 +60,7 @@ uint8_t ServoCount = 0;
#define US_TO_ANGLE(us) int16_t(map((us), SERVO_DEFAULT_MIN_PW, SERVO_DEFAULT_MAX_PW, minAngle, maxAngle))
void libServo::servoWrite(uint8_t inPin, uint16_t duty_cycle) {
#ifdef SERVO0_TIMER_NUM
#ifdef MF_TIMER_SERVO0
if (servoIndex == 0) {
pwmSetDuty(duty_cycle);
return;
@@ -74,7 +74,7 @@ void libServo::servoWrite(uint8_t inPin, uint16_t duty_cycle) {
libServo::libServo() {
servoIndex = ServoCount < MAX_SERVOS ? ServoCount++ : INVALID_SERVO;
timer_set_interrupt_priority(SERVO0_TIMER_NUM, SERVO0_TIMER_IRQ_PRIO);
HAL_timer_set_interrupt_priority(MF_TIMER_SERVO0, SERVO0_TIMER_IRQ_PRIO);
}
bool libServo::attach(const int32_t inPin, const int32_t inMinAngle, const int32_t inMaxAngle) {
@@ -85,7 +85,7 @@ bool libServo::attach(const int32_t inPin, const int32_t inMinAngle, const int32
maxAngle = inMaxAngle;
angle = -1;
#ifdef SERVO0_TIMER_NUM
#ifdef MF_TIMER_SERVO0
if (servoIndex == 0 && setupSoftPWM(inPin)) {
pin = inPin; // set attached()
return true;
@@ -119,7 +119,7 @@ bool libServo::detach() {
int32_t libServo::read() const {
if (attached()) {
#ifdef SERVO0_TIMER_NUM
#ifdef MF_TIMER_SERVO0
if (servoIndex == 0) return angle;
#endif
timer_dev *tdev = PIN_MAP[pin].timer_device;
@@ -141,9 +141,9 @@ void libServo::move(const int32_t value) {
}
}
#ifdef SERVO0_TIMER_NUM
#ifdef MF_TIMER_SERVO0
extern "C" void Servo_IRQHandler() {
static timer_dev *tdev = get_timer_dev(SERVO0_TIMER_NUM);
static timer_dev *tdev = HAL_get_timer_dev(MF_TIMER_SERVO0);
uint16_t SR = timer_get_status(tdev);
if (SR & TIMER_SR_CC1IF) { // channel 1 off
#ifdef SERVO0_PWM_OD
@@ -164,7 +164,7 @@ void libServo::move(const int32_t value) {
}
bool libServo::setupSoftPWM(const int32_t inPin) {
timer_dev *tdev = get_timer_dev(SERVO0_TIMER_NUM);
timer_dev *tdev = HAL_get_timer_dev(MF_TIMER_SERVO0);
if (!tdev) return false;
#ifdef SERVO0_PWM_OD
OUT_WRITE_OD(inPin, 1);
@@ -189,7 +189,7 @@ void libServo::move(const int32_t value) {
}
void libServo::pwmSetDuty(const uint16_t duty_cycle) {
timer_dev *tdev = get_timer_dev(SERVO0_TIMER_NUM);
timer_dev *tdev = HAL_get_timer_dev(MF_TIMER_SERVO0);
timer_set_compare(tdev, 1, duty_cycle);
timer_generate_update(tdev);
if (duty_cycle) {
@@ -208,7 +208,7 @@ void libServo::move(const int32_t value) {
}
void libServo::pauseSoftPWM() { // detach
timer_dev *tdev = get_timer_dev(SERVO0_TIMER_NUM);
timer_dev *tdev = HAL_get_timer_dev(MF_TIMER_SERVO0);
timer_pause(tdev);
pwmSetDuty(0);
}
+2 -1
View File
@@ -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:
+16 -14
View File
@@ -30,25 +30,27 @@ if __name__ == "__main__":
# extra script for linker options
else:
from SCons.Script import DefaultEnvironment
env = DefaultEnvironment()
env.Append(
import pioutil
if pioutil.is_pio_build():
from SCons.Script import DefaultEnvironment
env = DefaultEnvironment()
env.Append(
ARFLAGS=["rcs"],
ASFLAGS=["-x", "assembler-with-cpp"],
CXXFLAGS=[
"-fabi-version=0",
"-fno-use-cxa-atexit",
"-fno-threadsafe-statics"
"-fabi-version=0",
"-fno-use-cxa-atexit",
"-fno-threadsafe-statics"
],
LINKFLAGS=[
"-Os",
"-mcpu=cortex-m3",
"-ffreestanding",
"-mthumb",
"--specs=nano.specs",
"--specs=nosys.specs",
"-u_printf_float",
"-Os",
"-mcpu=cortex-m3",
"-ffreestanding",
"-mthumb",
"--specs=nano.specs",
"--specs=nosys.specs",
"-u_printf_float",
],
)
)
+38 -21
View File
@@ -21,32 +21,57 @@
*/
#ifdef __STM32F1__
#include "../../inc/MarlinConfigPre.h"
#if NEEDS_HARDWARE_PWM
#include "../../inc/MarlinConfig.h"
#include <pwm.h>
#include "HAL.h"
#include "timers.h"
void set_pwm_frequency(const pin_t pin, int f_desired) {
#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)
static uint16_t timer_freq[NR_TIMERS];
inline uint8_t timer_and_index_for_pin(const pin_t pin, timer_dev **timer_ptr) {
*timer_ptr = PIN_MAP[pin].timer_device;
for (uint8_t i = 0; i < NR_TIMERS; i++) if (*timer_ptr == HAL_get_timer_dev(i))
return i;
return 0;
}
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);
if (timer_freq[timer_and_index_for_pin(pin, &timer)] == 0)
set_pwm_frequency(pin, PWM_FREQUENCY);
const uint8_t channel = PIN_MAP[pin].timer_channel;
timer_set_compare(timer, channel, duty);
timer_set_mode(timer, channel, TIMER_PWM); // PWM Output Mode
}
else {
pinMode(pin, OUTPUT);
digitalWrite(pin, duty < v_size / 2 ? LOW : HIGH);
}
}
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 = PIN_MAP[pin].timer_device;
uint8_t channel = PIN_MAP[pin].timer_channel;
timer_dev *timer; UNUSED(timer);
timer_freq[timer_and_index_for_pin(pin, &timer)] = f_desired;
// Protect used timers
if (timer == get_timer_dev(TEMP_TIMER_NUM)) return;
if (timer == get_timer_dev(STEP_TIMER_NUM)) return;
#if PULSE_TIMER_NUM != STEP_TIMER_NUM
if (timer == get_timer_dev(PULSE_TIMER_NUM)) return;
if (timer == HAL_get_timer_dev(MF_TIMER_TEMP)) return;
if (timer == HAL_get_timer_dev(MF_TIMER_STEP)) return;
#if MF_TIMER_PULSE != MF_TIMER_STEP
if (timer == HAL_get_timer_dev(MF_TIMER_PULSE)) return;
#endif
if (!(timer->regs.bas->SR & TIMER_CR1_CEN)) // Ensure the timer is enabled
timer_init(timer);
const uint8_t channel = PIN_MAP[pin].timer_channel;
timer_set_mode(timer, channel, TIMER_PWM);
uint16_t preload = 255; // Lock 255 PWM resolution for high frequencies
// Preload (resolution) cannot be equal to duty of 255 otherwise it may not result in digital off or on.
uint16_t preload = 254;
int32_t prescaler = (HAL_TIMER_RATE) / (preload + 1) / f_desired - 1;
if (prescaler > 65535) { // For low frequencies increase prescaler
prescaler = 65535;
@@ -57,12 +82,4 @@ void set_pwm_frequency(const pin_t pin, int f_desired) {
timer_set_prescaler(timer, prescaler);
}
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
timer_dev *timer = PIN_MAP[pin].timer_device;
uint16_t max_val = timer->regs.bas->ARR * v / v_size;
if (invert) max_val = v_size - max_val;
pwmWrite(pin, max_val);
}
#endif // NEEDS_HARDWARE_PWM
#endif // __STM32F1__
+1 -1
View File
@@ -39,7 +39,7 @@
#error "SERIAL_STATS_DROPPED_RX is not supported on the STM32F1 platform."
#endif
#if ENABLED(NEOPIXEL_LED) && DISABLED(MKS_MINI_12864_V3)
#if ENABLED(NEOPIXEL_LED) && DISABLED(FYSETC_MINI_12864_2_1)
#error "NEOPIXEL_LED (Adafruit NeoPixel) is not supported for HAL/STM32F1. Comment out this line to proceed at your own risk!"
#endif
+8 -3
View File
@@ -38,8 +38,13 @@
#define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_2
#endif
#define CS_LOW() WRITE(ONBOARD_SD_CS_PIN, LOW) // Set OnboardSPI cs low
#define CS_HIGH() WRITE(ONBOARD_SD_CS_PIN, HIGH) // Set OnboardSPI cs high
#if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SD_SS_PIN
#define CS_LOW() WRITE(ONBOARD_SD_CS_PIN, LOW) // Set OnboardSPI cs low
#define CS_HIGH() WRITE(ONBOARD_SD_CS_PIN, HIGH) // Set OnboardSPI cs high
#else
#define CS_LOW()
#define CS_HIGH()
#endif
#define FCLK_FAST() ONBOARD_SD_SPI.setClockDivider(SPI_CLOCK_MAX)
#define FCLK_SLOW() ONBOARD_SD_SPI.setClockDivider(SPI_BAUD_PCLK_DIV_256)
@@ -278,7 +283,7 @@ DSTATUS disk_initialize (
if (drv) return STA_NOINIT; // Supports only drive 0
sd_power_on(); // Initialize SPI
if (Stat & STA_NODISK) return Stat; // Is a card existing in the soket?
if (Stat & STA_NODISK) return Stat; // Is a card existing in the socket?
FCLK_SLOW();
for (n = 10; n; n--) xchg_spi(0xFF); // Send 80 dummy clocks
+7 -7
View File
@@ -54,11 +54,11 @@ extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS];
#define M43_NEVER_TOUCH(Q) (Q >= 9 && Q <= 12) // SERIAL/USB pins PA9(TX) PA10(RX)
#endif
static inline int8_t get_pin_mode(pin_t pin) {
static int8_t get_pin_mode(pin_t pin) {
return VALID_PIN(pin) ? _GET_MODE(pin) : -1;
}
static inline pin_t DIGITAL_PIN_TO_ANALOG_PIN(pin_t pin) {
static pin_t DIGITAL_PIN_TO_ANALOG_PIN(pin_t pin) {
if (!VALID_PIN(pin)) return -1;
int8_t adc_channel = int8_t(PIN_MAP[pin].adc_channel);
#ifdef NUM_ANALOG_INPUTS
@@ -67,7 +67,7 @@ static inline pin_t DIGITAL_PIN_TO_ANALOG_PIN(pin_t pin) {
return pin_t(adc_channel);
}
static inline bool IS_ANALOG(pin_t pin) {
static bool IS_ANALOG(pin_t pin) {
if (!VALID_PIN(pin)) return false;
if (PIN_MAP[pin].adc_channel != ADCx) {
#ifdef NUM_ANALOG_INPUTS
@@ -78,11 +78,11 @@ static inline bool IS_ANALOG(pin_t pin) {
return false;
}
static inline bool GET_PINMODE(const pin_t pin) {
static bool GET_PINMODE(const pin_t pin) {
return VALID_PIN(pin) && !IS_INPUT(pin);
}
static inline bool GET_ARRAY_IS_DIGITAL(const int16_t array_pin) {
static bool GET_ARRAY_IS_DIGITAL(const int16_t array_pin) {
const pin_t pin = GET_ARRAY_PIN(array_pin);
return (!IS_ANALOG(pin)
#ifdef NUM_ANALOG_INPUTS
@@ -93,7 +93,7 @@ static inline bool GET_ARRAY_IS_DIGITAL(const int16_t array_pin) {
#include "../../inc/MarlinConfig.h" // Allow pins/pins.h to set density
static inline void pwm_details(const pin_t pin) {
static void pwm_details(const pin_t pin) {
if (PWM_PIN(pin)) {
timer_dev * const tdev = PIN_MAP[pin].timer_device;
const uint8_t channel = PIN_MAP[pin].timer_channel;
@@ -113,7 +113,7 @@ static inline void pwm_details(const pin_t pin) {
}
}
static inline void print_port(pin_t pin) {
static void print_port(pin_t pin) {
const char port = 'A' + char(pin >> 4); // pin div 16
const int16_t gbit = PIN_MAP[pin].gpio_bit;
char buffer[8];
+2 -2
View File
@@ -65,8 +65,8 @@ private:
static uint16_t getRawData(const XPTCoordinate coordinate);
static bool isTouched();
static inline void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); };
static inline void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
static void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); };
static void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
static uint16_t HardwareIO(uint16_t data);
#endif
+13 -17
View File
@@ -47,10 +47,7 @@
* TODO: Calculate Timer prescale value, so we get the 32bit to adjust
*/
void timer_set_interrupt_priority(uint_fast8_t timer_num, uint_fast8_t priority) {
void HAL_timer_set_interrupt_priority(uint_fast8_t timer_num, uint_fast8_t priority) {
nvic_irq_num irq_num;
switch (timer_num) {
case 1: irq_num = NVIC_TIMER1_CC; break;
@@ -73,7 +70,6 @@ void timer_set_interrupt_priority(uint_fast8_t timer_num, uint_fast8_t priority)
nvic_irq_set_priority(irq_num, priority);
}
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
/**
* Give the Stepper ISR a higher priority (lower number)
@@ -81,7 +77,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
*/
switch (timer_num) {
case STEP_TIMER_NUM:
case MF_TIMER_STEP:
timer_pause(STEP_TIMER_DEV);
timer_set_mode(STEP_TIMER_DEV, STEP_TIMER_CHAN, TIMER_OUTPUT_COMPARE); // counter
timer_set_count(STEP_TIMER_DEV, 0);
@@ -91,11 +87,11 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (STEPPER_TIMER_RATE) / frequency));
timer_no_ARR_preload_ARPE(STEP_TIMER_DEV); // Need to be sure no preload on ARR register
timer_attach_interrupt(STEP_TIMER_DEV, STEP_TIMER_CHAN, stepTC_Handler);
timer_set_interrupt_priority(STEP_TIMER_NUM, STEP_TIMER_IRQ_PRIO);
HAL_timer_set_interrupt_priority(MF_TIMER_STEP, STEP_TIMER_IRQ_PRIO);
timer_generate_update(STEP_TIMER_DEV);
timer_resume(STEP_TIMER_DEV);
break;
case TEMP_TIMER_NUM:
case MF_TIMER_TEMP:
timer_pause(TEMP_TIMER_DEV);
timer_set_mode(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, TIMER_OUTPUT_COMPARE);
timer_set_count(TEMP_TIMER_DEV, 0);
@@ -103,7 +99,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timer_set_reload(TEMP_TIMER_DEV, 0xFFFF);
timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (F_CPU) / (TEMP_TIMER_PRESCALE) / frequency));
timer_attach_interrupt(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, tempTC_Handler);
timer_set_interrupt_priority(TEMP_TIMER_NUM, TEMP_TIMER_IRQ_PRIO);
HAL_timer_set_interrupt_priority(MF_TIMER_TEMP, TEMP_TIMER_IRQ_PRIO);
timer_generate_update(TEMP_TIMER_DEV);
timer_resume(TEMP_TIMER_DEV);
break;
@@ -112,31 +108,31 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
switch (timer_num) {
case STEP_TIMER_NUM: ENABLE_STEPPER_DRIVER_INTERRUPT(); break;
case TEMP_TIMER_NUM: ENABLE_TEMPERATURE_INTERRUPT(); break;
case MF_TIMER_STEP: ENABLE_STEPPER_DRIVER_INTERRUPT(); break;
case MF_TIMER_TEMP: ENABLE_TEMPERATURE_INTERRUPT(); break;
}
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
switch (timer_num) {
case STEP_TIMER_NUM: DISABLE_STEPPER_DRIVER_INTERRUPT(); break;
case TEMP_TIMER_NUM: DISABLE_TEMPERATURE_INTERRUPT(); break;
case MF_TIMER_STEP: DISABLE_STEPPER_DRIVER_INTERRUPT(); break;
case MF_TIMER_TEMP: DISABLE_TEMPERATURE_INTERRUPT(); break;
}
}
static inline bool timer_irq_enabled(const timer_dev * const dev, const uint8_t interrupt) {
static inline bool HAL_timer_irq_enabled(const timer_dev * const dev, const uint8_t interrupt) {
return bool(*bb_perip(&(dev->regs).gen->DIER, interrupt));
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
switch (timer_num) {
case STEP_TIMER_NUM: return timer_irq_enabled(STEP_TIMER_DEV, STEP_TIMER_CHAN);
case TEMP_TIMER_NUM: return timer_irq_enabled(TEMP_TIMER_DEV, TEMP_TIMER_CHAN);
case MF_TIMER_STEP: return HAL_timer_irq_enabled(STEP_TIMER_DEV, STEP_TIMER_CHAN);
case MF_TIMER_TEMP: return HAL_timer_irq_enabled(TEMP_TIMER_DEV, TEMP_TIMER_CHAN);
}
return false;
}
timer_dev* get_timer_dev(int number) {
timer_dev* HAL_get_timer_dev(int number) {
switch (number) {
#if STM32_HAVE_TIMER(1)
case 1: return &timer1;
+36 -36
View File
@@ -65,30 +65,30 @@ typedef uint16_t hal_timer_t;
* - Otherwise it uses Timer 8 on boards with STM32_HIGH_DENSITY
* or Timer 4 on other boards.
*/
#ifndef STEP_TIMER_NUM
#ifndef MF_TIMER_STEP
#if defined(MCU_STM32F103CB) || defined(MCU_STM32F103C8)
#define STEP_TIMER_NUM 4 // For C8/CB boards, use timer 4
#define MF_TIMER_STEP 4 // For C8/CB boards, use timer 4
#else
#define STEP_TIMER_NUM 5 // for other boards, five is fine.
#define MF_TIMER_STEP 5 // for other boards, five is fine.
#endif
#endif
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#endif
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM 2 // Timer Index for Temperature
//#define TEMP_TIMER_NUM 4 // 2->4, Timer 2 for Stepper Current PWM
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP 2 // Timer Index for Temperature
//#define MF_TIMER_TEMP 4 // 2->4, Timer 2 for Stepper Current PWM
#endif
#if MB(BTT_SKR_MINI_E3_V1_0, BTT_SKR_E3_DIP, BTT_SKR_MINI_E3_V1_2, MKS_ROBIN_LITE, MKS_ROBIN_E3D, MKS_ROBIN_E3)
// SKR Mini E3 boards use PA8 as FAN_PIN, so TIMER 1 is used for Fan PWM.
#ifdef STM32_HIGH_DENSITY
#define SERVO0_TIMER_NUM 8 // tone.cpp uses Timer 4
#define MF_TIMER_SERVO0 8 // tone.cpp uses Timer 4
#else
#define SERVO0_TIMER_NUM 3 // tone.cpp uses Timer 8
#define MF_TIMER_SERVO0 3 // tone.cpp uses Timer 8
#endif
#else
#define SERVO0_TIMER_NUM 1 // SERVO0 or BLTOUCH
#define MF_TIMER_SERVO0 1 // SERVO0 or BLTOUCH
#endif
#define STEP_TIMER_IRQ_PRIO 2
@@ -98,22 +98,22 @@ typedef uint16_t hal_timer_t;
#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define STEPPER_TIMER_PRESCALE 18 // prescaler for setting stepper timer, 4Mhz
#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define STEPPER_TIMER_PRESCALE 18 // prescaler for setting stepper timer, 4Mhz
#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
timer_dev* get_timer_dev(int number);
#define TIMER_DEV(num) get_timer_dev(num)
#define STEP_TIMER_DEV TIMER_DEV(STEP_TIMER_NUM)
#define TEMP_TIMER_DEV TIMER_DEV(TEMP_TIMER_NUM)
timer_dev* HAL_get_timer_dev(int number);
#define TIMER_DEV(num) HAL_get_timer_dev(num)
#define STEP_TIMER_DEV TIMER_DEV(MF_TIMER_STEP)
#define TEMP_TIMER_DEV TIMER_DEV(MF_TIMER_TEMP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() timer_enable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN)
#define DISABLE_TEMPERATURE_INTERRUPT() timer_disable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN)
@@ -138,8 +138,8 @@ extern "C" {
// Public Variables
// ------------------------
//static HardwareTimer StepperTimer(STEP_TIMER_NUM);
//static HardwareTimer TempTimer(TEMP_TIMER_NUM);
//static HardwareTimer StepperTimer(MF_TIMER_STEP);
//static HardwareTimer TempTimer(MF_TIMER_TEMP);
// ------------------------
// Public functions
@@ -163,13 +163,13 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
switch (timer_num) {
case STEP_TIMER_NUM:
case MF_TIMER_STEP:
// NOTE: WE have set ARPE = 0, which means the Auto reload register is not preloaded
// and there is no need to use any compare, as in the timer mode used, setting ARR to the compare value
// will result in exactly the same effect, ie triggering an interrupt, and on top, set counter to 0
timer_set_reload(STEP_TIMER_DEV, compare); // We reload direct ARR as needed during counting up
break;
case TEMP_TIMER_NUM:
case MF_TIMER_TEMP:
timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, compare);
break;
}
@@ -177,18 +177,18 @@ FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const ha
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
switch (timer_num) {
case STEP_TIMER_NUM:
// No counter to clear
timer_generate_update(STEP_TIMER_DEV);
return;
case TEMP_TIMER_NUM:
timer_set_count(TEMP_TIMER_DEV, 0);
timer_generate_update(TEMP_TIMER_DEV);
return;
case MF_TIMER_STEP:
// No counter to clear
timer_generate_update(STEP_TIMER_DEV);
return;
case MF_TIMER_TEMP:
timer_set_count(TEMP_TIMER_DEV, 0);
timer_generate_update(TEMP_TIMER_DEV);
return;
}
}
#define HAL_timer_isr_epilogue(TIMER_NUM)
#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
@@ -196,6 +196,6 @@ FORCE_INLINE static void timer_no_ARR_preload_ARPE(timer_dev *dev) {
bb_peri_set_bit(&(dev->regs).gen->CR1, TIMER_CR1_ARPE_BIT, 0);
}
void timer_set_interrupt_priority(uint_fast8_t timer_num, uint_fast8_t priority);
void HAL_timer_set_interrupt_priority(uint_fast8_t timer_num, uint_fast8_t priority);
#define TIMER_OC_NO_PRELOAD 0 // Need to disable preload also on compare registers.
+44 -41
View File
@@ -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__
+97 -39
View File
@@ -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,58 +77,111 @@ 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
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
extern "C" int freeMemory();
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
#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(); }
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
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
//
// 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);
}
};
+10 -10
View File
@@ -47,7 +47,7 @@ FORCE_INLINE static void __DSB() {
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
switch (timer_num) {
case 0:
case MF_TIMER_STEP:
FTM0_MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN;
FTM0_SC = 0x00; // Set this to zero before changing the modulus
FTM0_CNT = 0x0000; // Reset the count to zero
@@ -56,7 +56,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
FTM0_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM0_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 8
FTM0_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA;
break;
case 1:
case MF_TIMER_TEMP:
FTM1_MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN; // Disable write protection, Enable FTM1
FTM1_SC = 0x00; // Set this to zero before changing the modulus
FTM1_CNT = 0x0000; // Reset the count to zero
@@ -70,15 +70,15 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
switch (timer_num) {
case 0: NVIC_ENABLE_IRQ(IRQ_FTM0); break;
case 1: NVIC_ENABLE_IRQ(IRQ_FTM1); break;
case MF_TIMER_STEP: NVIC_ENABLE_IRQ(IRQ_FTM0); break;
case MF_TIMER_TEMP: NVIC_ENABLE_IRQ(IRQ_FTM1); break;
}
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
switch (timer_num) {
case 0: NVIC_DISABLE_IRQ(IRQ_FTM0); break;
case 1: NVIC_DISABLE_IRQ(IRQ_FTM1); break;
case MF_TIMER_STEP: NVIC_DISABLE_IRQ(IRQ_FTM0); break;
case MF_TIMER_TEMP: NVIC_DISABLE_IRQ(IRQ_FTM1); break;
}
// We NEED memory barriers to ensure Interrupts are actually disabled!
@@ -89,20 +89,20 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) {
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
switch (timer_num) {
case 0: return NVIC_IS_ENABLED(IRQ_FTM0);
case 1: return NVIC_IS_ENABLED(IRQ_FTM1);
case MF_TIMER_STEP: return NVIC_IS_ENABLED(IRQ_FTM0);
case MF_TIMER_TEMP: return NVIC_IS_ENABLED(IRQ_FTM1);
}
return false;
}
void HAL_timer_isr_prologue(const uint8_t timer_num) {
switch (timer_num) {
case 0:
case MF_TIMER_STEP:
FTM0_CNT = 0x0000;
FTM0_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag
FTM0_C0SC &= ~FTM_CSC_CHF; // Clear FTM Channel Compare flag
break;
case 1:
case MF_TIMER_TEMP:
FTM1_CNT = 0x0000;
FTM1_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag
FTM1_C0SC &= ~FTM_CSC_CHF; // Clear FTM Channel Compare flag
+18 -18
View File
@@ -46,14 +46,14 @@ typedef uint32_t hal_timer_t;
#define HAL_TIMER_RATE (FTM0_TIMER_RATE)
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 0 // Timer Index for Stepper
#endif
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#endif
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM 1 // Timer Index for Temperature
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP 1 // Timer Index for Temperature
#endif
#define TEMP_TIMER_FREQUENCY 1000
@@ -66,12 +66,12 @@ typedef uint32_t hal_timer_t;
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler()
@@ -84,23 +84,23 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
switch (timer_num) {
case 0: FTM0_C0V = compare; break;
case 1: FTM1_C0V = compare; break;
case MF_TIMER_STEP: FTM0_C0V = compare; break;
case MF_TIMER_TEMP: FTM1_C0V = compare; break;
}
}
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
switch (timer_num) {
case 0: return FTM0_C0V;
case 1: return FTM1_C0V;
case MF_TIMER_STEP: return FTM0_C0V;
case MF_TIMER_TEMP: return FTM1_C0V;
}
return 0;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
switch (timer_num) {
case 0: return FTM0_CNT;
case 1: return FTM1_CNT;
case MF_TIMER_STEP: return FTM0_CNT;
case MF_TIMER_TEMP: return FTM1_CNT;
}
return 0;
}
@@ -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(TIMER_NUM)
#define HAL_timer_isr_epilogue(T) NOOP
+59 -55
View File
@@ -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;
}

Some files were not shown because too many files have changed in this diff Show More