@ -92,7 +92,7 @@ Before creating a suggestion, please check [this list](#before-submitting-a-sugg
#### Before Submitting a Feature Request
#### Before Submitting a Feature Request
* **Check the [Marlin website](http://marlinfw.org/)** for tips — you might discover that the feature is already included. Most importantly, check if you're using [the latest version of Marlin](https://github.com/MarlinFirmware/Marlin/releases) and if you can get the desired behavior by changing [Marlin's config settings](http://marlinfw.org/docs/configuration/configuration.html).
* **Check the [Marlin website](https://marlinfw.org/)** for tips — you might discover that the feature is already included. Most importantly, check if you're using [the latest version of Marlin](https://github.com/MarlinFirmware/Marlin/releases) and if you can get the desired behavior by changing [Marlin's config settings](https://marlinfw.org/docs/configuration/configuration.html).
* **Perform a [cursory search](https://github.com/MarlinFirmware/Marlin/issues?q=is%3Aissue)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
* **Perform a [cursory search](https://github.com/MarlinFirmware/Marlin/issues?q=is%3Aissue)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
#### How Do I Submit A (Good) Feature Request?
#### How Do I Submit A (Good) Feature Request?
@ -116,12 +116,12 @@ Unsure where to begin contributing to Marlin? You can start by looking through t
### Pull Requests
### Pull Requests
Pull Requests should always be targeted to working branches (e.g., `bugfix-1.1.x` and/or `bugfix-2.0.x`) and never to release branches (e.g., `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](http://marlinfw.org/docs/development/getting_started_pull_requests.html) and Github's [Pull Request](https://help.github.com/articles/creating-a-pull-request/) documentation.
Pull Requests should always be targeted to working branches (e.g., `bugfix-1.1.x` and/or `bugfix-2.0.x`) and never to release branches (e.g., `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](https://marlinfw.org/docs/development/getting_started_pull_requests.html) and Github's [Pull Request](https://help.github.com/articles/creating-a-pull-request/) documentation.
* Fill in [the required template](pull_request_template.md).
* Fill in [the required template](pull_request_template.md).
* Don't include issue numbers in the PR title.
* Don't include issue numbers in the PR title.
* Include pictures, diagrams, and links to videos in your Pull Request to demonstrate your changes, if needed.
* Include pictures, diagrams, and links to videos in your Pull Request to demonstrate your changes, if needed.
* Follow the [Coding Standards](http://marlinfw.org/docs/development/coding_standards.html) posted on our website.
* Follow the [Coding Standards](https://marlinfw.org/docs/development/coding_standards.html) posted on our website.
* Document new code with clear and concise comments.
* Document new code with clear and concise comments.
* End all files with a newline.
* End all files with a newline.
@ -136,7 +136,7 @@ Pull Requests should always be targeted to working branches (e.g., `bugfix-1.1.x
### C++ Coding Standards
### C++ Coding Standards
* Please read and follow the [Coding Standards](http://marlinfw.org/docs/development/coding_standards.html) posted on our website. Failure to follow these guidelines will delay evaluation and acceptance of Pull Requests.
* Please read and follow the [Coding Standards](https://marlinfw.org/docs/development/coding_standards.html) posted on our website. Failure to follow these guidelines will delay evaluation and acceptance of Pull Requests.
Support Requests posted here will be automatically closed!
Do you want to ask a question? Are you looking for support? Please don't post here. Support Requests posted here will be automatically closed!
This Issue Queue is for Marlin bug reports and development-related issues, and we prefer not to handle user-support questions here. See https://github.com/MarlinFirmware/Marlin/blob/1.1.x/.github/contributing.md#i-dont-want-to-read-this-whole-thing-i-just-have-a-question.
Instead use one of the following options:
For best results getting help with configuration and troubleshooting, please use the following resources:
- The Marlin Firmware forum at https://reprap.org/forum/list.php?415
- The MarlinFirmware Facebook Group at https://www.facebook.com/groups/1049718498464482/
- The MarlinFirmware Discord Server at https://discord.gg/n5NJ59y.
- RepRap.org Marlin Forum http://forums.reprap.org/list.php?415
Before filing an issue be sure to test the latest "bugfix" branch to see whether the issue is already addressed.
- Tom's 3D Forums https://discuss.toms3d.org/
- Facebook Group "Marlin Firmware" https://www.facebook.com/groups/1049718498464482/
- Facebook Group "Marlin Firmware for 3D Printers" https://www.facebook.com/groups/3Dtechtalk/
- Marlin Configuration https://www.youtube.com/results?search_query=marlin+configuration on YouTube
After seeking help from the community, if the consensus points to to a bug in Marlin, then you should post a Bug Report at https://github.com/MarlinFirmware/Marlin/issues/new/choose).
#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current
#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current
#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
#define PID_K1 0.95 // Smoothing factor within any PID loop
#define PID_K1 0.95 // Smoothing factor within any PID loop
#if ENABLED(PIDTEMP)
#if ENABLED(PIDTEMP)
//#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of PROGMEM)
//#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of PROGMEM)
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of PROGMEM)
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of PROGMEM)
//#define PID_DEBUG // Sends debug data to the serial port. Use 'M303 D' to toggle activation.
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
//#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders)
//#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders)
// Set/get with gcode: M301 E[extruder number, 0-2]
// Set/get with gcode: M301 E[extruder number, 0-2]
#define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
// is more than PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
// If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
// If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
@ -548,6 +554,14 @@
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
#endif // PIDTEMPBED
#endif // PIDTEMPBED
#if EITHER(PIDTEMP, PIDTEMPBED)
//#define PID_DEBUG // Sends debug data to the serial port. Use 'M303 D' to toggle activation.
//#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
#define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
// is more than PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
A("lds r16, %[timsk0]")/* 2 Load into R0 the Temperature timer Interrupt mask register */ \
A("push r16")/* 2 Save TIMSK0 into the stack */ \
A("andi r16,~%[msk0]")/* 1 Disable the temperature ISR */ \
A("sts %[timsk0], r16")/* 2 And set the new value */ \
A("lds r16, %[timsk1]")/* 2 Load into R0 the stepper timer Interrupt mask register [TIMSK1] */ \
A("andi r16,~%[msk1]")/* 1 Disable the stepper ISR */ \
A("sts %[timsk1], r16")/* 2 And set the new value */ \
A("push r16")/* 2 Save TIMSK1 into stack */ \
A("in r16, 0x3B")/* 1 Get RAMPZ register */ \
A("push r16")/* 2 Save RAMPZ into stack */ \
A("in r16, 0x3C")/* 1 Get EIND register */ \
A("push r0")/* C runtime can modify all the following registers without restoring them */ \
A("push r1") \
A("push r18") \
A("push r19") \
A("push r20") \
A("push r21") \
A("push r22") \
A("push r23") \
A("push r24") \
A("push r25") \
A("push r26") \
A("push r27") \
A("push r30") \
A("push r31") \
A("clr r1")/* C runtime expects this register to be 0 */ \
A("call TIMER1_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") \
A("pop r26") \
A("pop r25") \
A("pop r24") \
A("pop r23") \
A("pop r22") \
A("pop r21") \
A("pop r20") \
A("pop r19") \
A("pop r18") \
A("pop r1") \
A("pop r0") \
A("out 0x3C, r16")/* 1 Restore EIND register */ \
A("pop r16")/* 2 Get the original RAMPZ register value */ \
A("out 0x3B, r16")/* 1 Restore RAMPZ register to its original value */ \
A("pop r16")/* 2 Get the original TIMSK1 value but with stepper ISR disabled */ \
A("ori r16,%[msk1]")/* 1 Reenable the stepper ISR */ \
A("cli")/* 1 Disable global interrupts - Reenabling Stepper ISR can reenter amd temperature can reenter, and we want that, if it happens, after this ISR has ended */ \
A("sts %[timsk1], r16")/* 2 And restore the old value - This reenables the stepper ISR */ \
A("pop r16")/* 2 Get the temperature timer Interrupt mask register [TIMSK0] */ \
A("sts %[timsk0], r16")/* 2 And restore the old value - This reenables the temperature ISR */ \
A("pop r16")/* 2 Get the old SREG value */ \
A("out __SREG__, r16")/* 1 And restore the SREG value */ \
A("lds r16, %[timsk0]")/* 2 Load into R0 the Temperature timer Interrupt mask register */ \
A("andi r16,~%[msk0]")/* 1 Disable the temperature ISR */ \
A("sts %[timsk0], r16")/* 2 And set the new value */ \
A("sei")/* 1 Enable global interrupts - It is safe, as the temperature ISR is disabled, so we cannot reenter it */ \
A("push r16")/* 2 Save TIMSK0 into stack */ \
A("in r16, 0x3B")/* 1 Get RAMPZ register */ \
A("push r16")/* 2 Save RAMPZ into stack */ \
A("in r16, 0x3C")/* 1 Get EIND register */ \
A("push r0")/* C runtime can modify all the following registers without restoring them */ \
A("push r1") \
A("push r18") \
A("push r19") \
A("push r20") \
A("push r21") \
A("push r22") \
A("push r23") \
A("push r24") \
A("push r25") \
A("push r26") \
A("push r27") \
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("pop r31") \
A("pop r30") \
A("pop r27") \
A("pop r26") \
A("pop r25") \
A("pop r24") \
A("pop r23") \
A("pop r22") \
A("pop r21") \
A("pop r20") \
A("pop r19") \
A("pop r18") \
A("pop r1") \
A("pop r0") \
A("out 0x3C, r16")/* 1 Restore EIND register */ \
A("pop r16")/* 2 Get the original RAMPZ register value */ \
A("out 0x3B, r16")/* 1 Restore RAMPZ register to its original value */ \
A("pop r16")/* 2 Get the original TIMSK0 value but with temperature ISR disabled */ \
A("ori r16,%[msk0]")/* 1 Enable temperature ISR */ \
A("cli")/* 1 Disable global interrupts - We must do this, as we will reenable the temperature ISR, and we don't want to reenter this handler until the current one is done */ \
A("sts %[timsk0], r16")/* 2 And restore the old value */ \
A("pop r16")/* 2 Get the old SREG */ \
A("out __SREG__, r16")/* 1 And restore the SREG value */ \
A("pop r16")/* 2 Restore R16 */ \
A("reti")/* 4 Return from interrupt */ \
: \
:[timsk0]"i"((uint16_t)&TIMSK0), \
[msk0]"M"((uint8_t)(1<<OCIE0B)) \
: \
); \
} \
voidTIMER0_COMPB_vect_bottom()
// ADC
// ADC
#ifdef DIDR2
#ifdef DIDR2
#define HAL_ANALOG_SELECT(ind) do{ if (ind < 8) SBI(DIDR0, ind); else SBI(DIDR2, ind & 0x07); }while(0)
#define HAL_ANALOG_SELECT(ind) do{ if (ind < 8) SBI(DIDR0, ind); else SBI(DIDR2, ind & 0x07); }while(0)
#error "MONITOR_DRIVER_STATUS causes performance issues when used with SoftwareSerial-connected drivers. Disable MONITOR_DRIVER_STATUS or use hardware serial to continue."
#error "MONITOR_DRIVER_STATUS causes performance issues when used with SoftwareSerial-connected drivers. Disable MONITOR_DRIVER_STATUS or use hardware serial to continue."
A("lds r16, %[timsk0]")/* 2 Load into R0 the Temperature timer Interrupt mask register */ \
A("push r16")/* 2 Save TIMSK0 into the stack */ \
A("andi r16,~%[msk0]")/* 1 Disable the temperature ISR */ \
A("sts %[timsk0], r16")/* 2 And set the new value */ \
A("lds r16, %[timsk1]")/* 2 Load into R0 the stepper timer Interrupt mask register [TIMSK1] */ \
A("andi r16,~%[msk1]")/* 1 Disable the stepper ISR */ \
A("sts %[timsk1], r16")/* 2 And set the new value */ \
A("push r16")/* 2 Save TIMSK1 into stack */ \
A("in r16, 0x3B")/* 1 Get RAMPZ register */ \
A("push r16")/* 2 Save RAMPZ into stack */ \
A("in r16, 0x3C")/* 1 Get EIND register */ \
A("push r0")/* C runtime can modify all the following registers without restoring them */ \
A("push r1") \
A("push r18") \
A("push r19") \
A("push r20") \
A("push r21") \
A("push r22") \
A("push r23") \
A("push r24") \
A("push r25") \
A("push r26") \
A("push r27") \
A("push r30") \
A("push r31") \
A("clr r1")/* C runtime expects this register to be 0 */ \
A("call TIMER1_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") \
A("pop r26") \
A("pop r25") \
A("pop r24") \
A("pop r23") \
A("pop r22") \
A("pop r21") \
A("pop r20") \
A("pop r19") \
A("pop r18") \
A("pop r1") \
A("pop r0") \
A("out 0x3C, r16")/* 1 Restore EIND register */ \
A("pop r16")/* 2 Get the original RAMPZ register value */ \
A("out 0x3B, r16")/* 1 Restore RAMPZ register to its original value */ \
A("pop r16")/* 2 Get the original TIMSK1 value but with stepper ISR disabled */ \
A("ori r16,%[msk1]")/* 1 Reenable the stepper ISR */ \
A("cli")/* 1 Disable global interrupts - Reenabling Stepper ISR can reenter amd temperature can reenter, and we want that, if it happens, after this ISR has ended */ \
A("sts %[timsk1], r16")/* 2 And restore the old value - This reenables the stepper ISR */ \
A("pop r16")/* 2 Get the temperature timer Interrupt mask register [TIMSK0] */ \
A("sts %[timsk0], r16")/* 2 And restore the old value - This reenables the temperature ISR */ \
A("pop r16")/* 2 Get the old SREG value */ \
A("out __SREG__, r16")/* 1 And restore the SREG value */ \
A("lds r16, %[timsk0]")/* 2 Load into R0 the Temperature timer Interrupt mask register */ \
A("andi r16,~%[msk0]")/* 1 Disable the temperature ISR */ \
A("sts %[timsk0], r16")/* 2 And set the new value */ \
A("sei")/* 1 Enable global interrupts - It is safe, as the temperature ISR is disabled, so we cannot reenter it */ \
A("push r16")/* 2 Save TIMSK0 into stack */ \
A("in r16, 0x3B")/* 1 Get RAMPZ register */ \
A("push r16")/* 2 Save RAMPZ into stack */ \
A("in r16, 0x3C")/* 1 Get EIND register */ \
A("push r0")/* C runtime can modify all the following registers without restoring them */ \
A("push r1") \
A("push r18") \
A("push r19") \
A("push r20") \
A("push r21") \
A("push r22") \
A("push r23") \
A("push r24") \
A("push r25") \
A("push r26") \
A("push r27") \
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("pop r31") \
A("pop r30") \
A("pop r27") \
A("pop r26") \
A("pop r25") \
A("pop r24") \
A("pop r23") \
A("pop r22") \
A("pop r21") \
A("pop r20") \
A("pop r19") \
A("pop r18") \
A("pop r1") \
A("pop r0") \
A("out 0x3C, r16")/* 1 Restore EIND register */ \
A("pop r16")/* 2 Get the original RAMPZ register value */ \
A("out 0x3B, r16")/* 1 Restore RAMPZ register to its original value */ \
A("pop r16")/* 2 Get the original TIMSK0 value but with temperature ISR disabled */ \
A("ori r16,%[msk0]")/* 1 Enable temperature ISR */ \
A("cli")/* 1 Disable global interrupts - We must do this, as we will reenable the temperature ISR, and we don't want to reenter this handler until the current one is done */ \
A("sts %[timsk0], r16")/* 2 And restore the old value */ \
A("pop r16")/* 2 Get the old SREG */ \
A("out __SREG__, r16")/* 1 And restore the SREG value */ \