Merge branch 'bugfix-2.0.x' into Trex_2.0.x_Devel
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
Vendored
+11
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -486,7 +486,7 @@ void MarlinSerial<Cfg>::write(const uint8_t c) {
|
||||
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
|
||||
|
||||
// If global interrupts are disabled (as the result of being called from an ISR)...
|
||||
if (!ISRS_ENABLED()) {
|
||||
if (!hal.isr_state()) {
|
||||
|
||||
// Make room by polling if it is possible to transmit, and do so!
|
||||
while (i == tx_buffer.tail) {
|
||||
@@ -534,7 +534,7 @@ void MarlinSerial<Cfg>::flushTX() {
|
||||
if (!_written) return;
|
||||
|
||||
// If global interrupts are disabled (as the result of being called from an ISR)...
|
||||
if (!ISRS_ENABLED()) {
|
||||
if (!hal.isr_state()) {
|
||||
|
||||
// Wait until everything was transmitted - We must do polling, as interrupts are disabled
|
||||
while (tx_buffer.head != tx_buffer.tail || !B_TXC) {
|
||||
|
||||
@@ -191,13 +191,13 @@
|
||||
rx_framing_errors;
|
||||
static ring_buffer_pos_t rx_max_enqueued;
|
||||
|
||||
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_head();
|
||||
FORCE_INLINE static ring_buffer_pos_t atomic_read_rx_head();
|
||||
|
||||
static volatile bool rx_tail_value_not_stable;
|
||||
static volatile uint16_t rx_tail_value_backup;
|
||||
|
||||
static FORCE_INLINE void atomic_set_rx_tail(ring_buffer_pos_t value);
|
||||
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_tail();
|
||||
FORCE_INLINE static void atomic_set_rx_tail(ring_buffer_pos_t value);
|
||||
FORCE_INLINE static ring_buffer_pos_t atomic_read_rx_tail();
|
||||
|
||||
public:
|
||||
FORCE_INLINE static void store_rxd_char();
|
||||
@@ -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; }
|
||||
|
||||
@@ -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
@@ -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__
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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__ (
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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--;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -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--;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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) {}
|
||||
};
|
||||
|
||||
@@ -31,9 +31,7 @@ void cli() { } // Disable
|
||||
void sei() { } // Enable
|
||||
|
||||
// Time functions
|
||||
void _delay_ms(const int delay_ms) {
|
||||
delay(delay_ms);
|
||||
}
|
||||
void _delay_ms(const int ms) { delay(ms); }
|
||||
|
||||
uint32_t millis() {
|
||||
return (uint32_t)Clock::millis();
|
||||
|
||||
@@ -59,10 +59,9 @@ typedef uint8_t byte;
|
||||
#endif
|
||||
|
||||
#define sq(v) ((v) * (v))
|
||||
#define square(v) sq(v)
|
||||
#define constrain(value, arg_min, arg_max) ((value) < (arg_min) ? (arg_min) :((value) > (arg_max) ? (arg_max) : (value)))
|
||||
|
||||
//Interrupts
|
||||
// Interrupts
|
||||
void cli(); // Disable
|
||||
void sei(); // Enable
|
||||
void attachInterrupt(uint32_t pin, void (*callback)(), uint32_t mode);
|
||||
@@ -74,8 +73,8 @@ extern "C" {
|
||||
}
|
||||
|
||||
// Time functions
|
||||
extern "C" void delay(const int milis);
|
||||
void _delay_ms(const int delay);
|
||||
extern "C" void delay(const int ms);
|
||||
void _delay_ms(const int ms);
|
||||
void delayMicroseconds(unsigned long);
|
||||
uint32_t millis();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
DefaultSerial1 USBSerial(false, UsbSerial);
|
||||
|
||||
uint32_t HAL_adc_reading = 0;
|
||||
uint32_t MarlinHAL::adc_result = 0;
|
||||
|
||||
// U8glib required functions
|
||||
extern "C" {
|
||||
@@ -41,8 +41,6 @@ extern "C" {
|
||||
void u8g_Delay(uint16_t val) { delay(val); }
|
||||
}
|
||||
|
||||
//************************//
|
||||
|
||||
// return free heap space
|
||||
int freeMemory() {
|
||||
char stack_end;
|
||||
@@ -54,7 +52,27 @@ int freeMemory() {
|
||||
return result;
|
||||
}
|
||||
|
||||
// scan command line for code
|
||||
void MarlinHAL::reboot() { NVIC_SystemReset(); }
|
||||
|
||||
uint8_t MarlinHAL::get_reset_source() {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
if (watchdog_timed_out()) return RST_WATCHDOG;
|
||||
#endif
|
||||
return RST_POWER_ON;
|
||||
}
|
||||
|
||||
void MarlinHAL::clear_reset_source() {
|
||||
TERN_(USE_WATCHDOG, watchdog_clear_timeout_flag());
|
||||
}
|
||||
|
||||
void flashFirmware(const int16_t) {
|
||||
delay(500); // Give OS time to disconnect
|
||||
USB_Connect(false); // USB clear connection
|
||||
delay(1000); // Give OS time to notice
|
||||
hal.reboot();
|
||||
}
|
||||
|
||||
// For M42/M43, scan command line for pin code
|
||||
// return index into pin map array if found and the pin is valid.
|
||||
// return dval if not found or not a valid pin.
|
||||
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
|
||||
@@ -63,24 +81,4 @@ int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
|
||||
return ind > -1 ? ind : dval;
|
||||
}
|
||||
|
||||
void flashFirmware(const int16_t) {
|
||||
delay(500); // Give OS time to disconnect
|
||||
USB_Connect(false); // USB clear connection
|
||||
delay(1000); // Give OS time to notice
|
||||
HAL_reboot();
|
||||
}
|
||||
|
||||
void HAL_clear_reset_source(void) {
|
||||
TERN_(USE_WATCHDOG, watchdog_clear_timeout_flag());
|
||||
}
|
||||
|
||||
uint8_t HAL_get_reset_source(void) {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
if (watchdog_timed_out()) return RST_WATCHDOG;
|
||||
#endif
|
||||
return RST_POWER_ON;
|
||||
}
|
||||
|
||||
void HAL_reboot() { NVIC_SystemReset(); }
|
||||
|
||||
#endif // TARGET_LPC1768
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
|
||||
#define CPU_32_BIT
|
||||
|
||||
void HAL_init();
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <algorithm>
|
||||
@@ -47,12 +45,9 @@ extern "C" volatile uint32_t _millis;
|
||||
#include <pinmapping.h>
|
||||
#include <CDCSerial.h>
|
||||
|
||||
//
|
||||
// Default graphical display delays
|
||||
//
|
||||
#define CPU_ST7920_DELAY_1 600
|
||||
#define CPU_ST7920_DELAY_2 750
|
||||
#define CPU_ST7920_DELAY_3 750
|
||||
// ------------------------
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
|
||||
typedef ForwardSerial1Class< decltype(UsbSerial) > DefaultSerial1;
|
||||
extern DefaultSerial1 USBSerial;
|
||||
@@ -114,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);
|
||||
};
|
||||
|
||||
@@ -65,4 +65,5 @@ class libServo: public Servo {
|
||||
}
|
||||
};
|
||||
|
||||
#define HAL_SERVO_LIB libServo
|
||||
class libServo;
|
||||
typedef libServo hal_servo_t;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
@@ -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__ (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
@@ -91,6 +91,14 @@ static const spi_pins board_spi_pins[] __FLASH__ = {
|
||||
static void *_spi3_this;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset.
|
||||
*/
|
||||
static inline void waitSpiTxEnd(spi_dev *spi_d) {
|
||||
while (spi_is_tx_empty(spi_d) == 0) { /* nada */ } // wait until TXE=1
|
||||
while (spi_is_busy(spi_d) != 0) { /* nada */ } // wait until BSY=0
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
||||
@@ -414,12 +414,4 @@ private:
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset.
|
||||
*/
|
||||
static 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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
|
||||
#include <Wire.h>
|
||||
|
||||
// ------------------------
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
|
||||
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
|
||||
#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X)
|
||||
#if WITHIN(SERIAL_PORT, 0, 3)
|
||||
@@ -40,45 +44,9 @@
|
||||
#endif
|
||||
USBSerialType USBSerial(false, SerialUSB);
|
||||
|
||||
uint16_t HAL_adc_result;
|
||||
|
||||
static const uint8_t pin2sc1a[] = {
|
||||
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 0, 19, 3, 31, // 0-13, we treat them as A0-A13
|
||||
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 (A0-A9)
|
||||
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, // 24-33
|
||||
0+64, 19+64, 3+64, 31+64, // 34-37 (A10-A13)
|
||||
26, 22, 23, 27, 29, 30 // 38-43: temp. sensor, VREF_OUT, A14, bandgap, VREFH, VREFL. A14 isn't connected to anything in Teensy 3.0.
|
||||
};
|
||||
|
||||
/*
|
||||
// disable interrupts
|
||||
void cli() { noInterrupts(); }
|
||||
|
||||
// enable interrupts
|
||||
void sei() { interrupts(); }
|
||||
*/
|
||||
|
||||
void HAL_adc_init() {
|
||||
analog_init();
|
||||
while (ADC0_SC3 & ADC_SC3_CAL) {}; // Wait for calibration to finish
|
||||
NVIC_ENABLE_IRQ(IRQ_FTM1);
|
||||
}
|
||||
|
||||
void HAL_clear_reset_source() { }
|
||||
|
||||
uint8_t HAL_get_reset_source() {
|
||||
switch (RCM_SRS0) {
|
||||
case 128: return RST_POWER_ON; break;
|
||||
case 64: return RST_EXTERNAL; break;
|
||||
case 32: return RST_WATCHDOG; break;
|
||||
// case 8: return RST_LOSS_OF_LOCK; break;
|
||||
// case 4: return RST_LOSS_OF_CLOCK; break;
|
||||
// case 2: return RST_LOW_VOLTAGE; break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HAL_reboot() { _reboot_Teensyduino_(); }
|
||||
// ------------------------
|
||||
// Class Utilities
|
||||
// ------------------------
|
||||
|
||||
extern "C" {
|
||||
extern char __bss_end;
|
||||
@@ -95,8 +63,43 @@ extern "C" {
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_adc_start_conversion(const uint8_t adc_pin) { ADC0_SC1A = pin2sc1a[adc_pin]; }
|
||||
// ------------------------
|
||||
// MarlinHAL Class
|
||||
// ------------------------
|
||||
|
||||
uint16_t HAL_adc_get_result() { return ADC0_RA; }
|
||||
void MarlinHAL::reboot() { _reboot_Teensyduino_(); }
|
||||
|
||||
uint8_t MarlinHAL::get_reset_source() {
|
||||
switch (RCM_SRS0) {
|
||||
case 128: return RST_POWER_ON; break;
|
||||
case 64: return RST_EXTERNAL; break;
|
||||
case 32: return RST_WATCHDOG; break;
|
||||
// case 8: return RST_LOSS_OF_LOCK; break;
|
||||
// case 4: return RST_LOSS_OF_CLOCK; break;
|
||||
// case 2: return RST_LOW_VOLTAGE; break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ADC
|
||||
|
||||
void MarlinHAL::adc_init() {
|
||||
analog_init();
|
||||
while (ADC0_SC3 & ADC_SC3_CAL) {}; // Wait for calibration to finish
|
||||
NVIC_ENABLE_IRQ(IRQ_FTM1);
|
||||
}
|
||||
|
||||
void MarlinHAL::adc_start(const pin_t pin) {
|
||||
static const uint8_t pin2sc1a[] = {
|
||||
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 0, 19, 3, 31, // 0-13, we treat them as A0-A13
|
||||
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 (A0-A9)
|
||||
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, // 24-33
|
||||
0+64, 19+64, 3+64, 31+64, // 34-37 (A10-A13)
|
||||
26, 22, 23, 27, 29, 30 // 38-43: temp. sensor, VREF_OUT, A14, bandgap, VREFH, VREFL. A14 isn't connected to anything in Teensy 3.0.
|
||||
};
|
||||
ADC0_SC1A = pin2sc1a[pin];
|
||||
}
|
||||
|
||||
uint16_t MarlinHAL::adc_value() { return ADC0_RA; }
|
||||
|
||||
#endif // __MK20DX256__
|
||||
|
||||
@@ -36,12 +36,9 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define CPU_ST7920_DELAY_1 600
|
||||
#define CPU_ST7920_DELAY_2 750
|
||||
#define CPU_ST7920_DELAY_3 750
|
||||
|
||||
//#undef MOTHERBOARD
|
||||
//#define MOTHERBOARD BOARD_TEENSY31_32
|
||||
// ------------------------
|
||||
// Defines
|
||||
// ------------------------
|
||||
|
||||
#define IS_32BIT_TEENSY 1
|
||||
#define IS_TEENSY_31_32 1
|
||||
@@ -49,6 +46,14 @@
|
||||
#define IS_TEENSY32 1
|
||||
#endif
|
||||
|
||||
#define CPU_ST7920_DELAY_1 600
|
||||
#define CPU_ST7920_DELAY_2 750
|
||||
#define CPU_ST7920_DELAY_3 750
|
||||
|
||||
// ------------------------
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
|
||||
#include "../../core/serial_hook.h"
|
||||
|
||||
#define Serial0 Serial
|
||||
@@ -72,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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user