Merge branch 'MK3' into MK3_NEW_SD_COMPILATION
This commit is contained in:
commit
6bc59197ad
42 changed files with 1533 additions and 959 deletions
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -15,6 +15,9 @@ Please, before you create a new bug report, please make sure you searched in ope
|
|||
**MMU Upgrade** - [e.g. MMU2S, MMU2, MMU1]
|
||||
**MMU upgrade firmware version [e.g. 1.0.6, 1.0.6-RC2, ...]
|
||||
|
||||
**SD card or USB/Octoprint**
|
||||
Please let us know if you print via SD card or USB/Octoprint
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@ extern uint16_t nPrinterType;
|
|||
extern PGM_P sPrinterName;
|
||||
|
||||
// Firmware version
|
||||
#define FW_VERSION "3.9.0-RC3"
|
||||
#define FW_COMMIT_NR 3401
|
||||
#define FW_VERSION "3.9.0"
|
||||
#define FW_COMMIT_NR 3421
|
||||
// FW_VERSION_UNKNOWN means this is an unofficial build.
|
||||
// The firmware should only be checked into github with this symbol.
|
||||
#define FW_DEV_VERSION FW_VERSION_UNKNOWN
|
||||
|
|
|
@ -290,6 +290,7 @@
|
|||
#define LA_K_DEF 0 // Default K factor (Unit: mm compression per 1mm/s extruder speed)
|
||||
#define LA_K_MAX 10 // Maximum acceptable K factor (exclusive, see notes in planner.cpp:plan_buffer_line)
|
||||
#define LA_LA10_MIN LA_K_MAX // Lin. Advance 1.0 threshold value (inclusive)
|
||||
//#define LA_FLOWADJ // Adjust LA along with flow/M221 for uniform width
|
||||
//#define LA_NOCOMPAT // Disable Linear Advance 1.0 compatibility
|
||||
//#define LA_LIVE_K // Allow adjusting K in the Tune menu
|
||||
//#define LA_DEBUG // If enabled, this will generate debug information output over USB.
|
||||
|
@ -438,6 +439,10 @@ const unsigned int dropsegments=5; //everything with less than this number of st
|
|||
#undef BED_MINTEMP
|
||||
#undef BED_MAXTEMP
|
||||
#endif
|
||||
#if TEMP_SENSOR_AMBIENT == 0
|
||||
#undef AMBIENT_MINTEMP
|
||||
#undef AMBIENT_MAXTEMP
|
||||
#endif
|
||||
|
||||
|
||||
#endif //__CONFIGURATION_ADV_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "Dcodes.h"
|
||||
//#include "Marlin.h"
|
||||
#include "Marlin.h"
|
||||
#include "Configuration.h"
|
||||
#include "language.h"
|
||||
#include "cmdqueue.h"
|
||||
|
@ -226,9 +226,7 @@ void dcode_0()
|
|||
LOG("D0 - Reset\n");
|
||||
if (code_seen('B')) //bootloader
|
||||
{
|
||||
cli();
|
||||
wdt_enable(WDTO_15MS);
|
||||
while(1);
|
||||
softReset();
|
||||
}
|
||||
else //reset
|
||||
{
|
||||
|
@ -252,8 +250,7 @@ void dcode_1()
|
|||
cli();
|
||||
for (int i = 0; i < 8192; i++)
|
||||
eeprom_write_byte((unsigned char*)i, (unsigned char)0xff);
|
||||
wdt_enable(WDTO_15MS);
|
||||
while(1);
|
||||
softReset();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -420,8 +417,7 @@ void dcode_5()
|
|||
boot_dst_addr = (uint32_t)address;
|
||||
boot_src_addr = (uint32_t)(&data);
|
||||
bootapp_print_vars();
|
||||
wdt_enable(WDTO_15MS);
|
||||
while(1);
|
||||
softReset();
|
||||
}
|
||||
while (count)
|
||||
{
|
||||
|
@ -467,8 +463,7 @@ void dcode_7()
|
|||
boot_copy_size = (uint16_t)0xc00;
|
||||
boot_src_addr = (uint32_t)0x0003e400;
|
||||
boot_dst_addr = (uint32_t)0x0003f400;
|
||||
wdt_enable(WDTO_15MS);
|
||||
while(1);
|
||||
softReset();
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
|
@ -299,7 +299,7 @@ extern float feedrate;
|
|||
extern int feedmultiply;
|
||||
extern int extrudemultiply; // Sets extrude multiply factor (in percent) for all extruders
|
||||
extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
|
||||
extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner
|
||||
extern float extruder_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner
|
||||
extern float current_position[NUM_AXIS] ;
|
||||
extern float destination[NUM_AXIS] ;
|
||||
extern float min_pos[3];
|
||||
|
@ -334,7 +334,6 @@ extern unsigned long stoptime;
|
|||
extern int bowden_length[4];
|
||||
extern bool is_usb_printing;
|
||||
extern bool homing_flag;
|
||||
extern bool temp_cal_active;
|
||||
extern bool loading_flag;
|
||||
extern unsigned int usb_printing_counter;
|
||||
|
||||
|
@ -513,4 +512,6 @@ void load_filament_final_feed();
|
|||
void marlin_wait_for_click();
|
||||
void raise_z_above(float target, bool plan=true);
|
||||
|
||||
extern "C" void softReset();
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -9,6 +9,8 @@
|
|||
extern FILE _uartout;
|
||||
#define uartout (&_uartout)
|
||||
|
||||
extern void softReset();
|
||||
|
||||
void bootapp_print_vars(void)
|
||||
{
|
||||
fprintf_P(uartout, PSTR("boot_src_addr =0x%08lx\n"), boot_src_addr);
|
||||
|
@ -39,8 +41,7 @@ void bootapp_ram2flash(uint16_t rptr, uint16_t fptr, uint16_t size)
|
|||
boot_src_addr = (uint32_t)rptr;
|
||||
boot_dst_addr = (uint32_t)fptr;
|
||||
bootapp_print_vars();
|
||||
wdt_enable(WDTO_15MS);
|
||||
while(1);
|
||||
softReset();
|
||||
}
|
||||
|
||||
void bootapp_reboot_user0(uint8_t reserved)
|
||||
|
@ -50,6 +51,5 @@ void bootapp_reboot_user0(uint8_t reserved)
|
|||
boot_app_flags = BOOT_APP_FLG_USER0;
|
||||
boot_reserved = reserved;
|
||||
bootapp_print_vars();
|
||||
wdt_enable(WDTO_15MS);
|
||||
while(1);
|
||||
softReset();
|
||||
}
|
||||
|
|
|
@ -331,7 +331,7 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir)
|
|||
{
|
||||
SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL);
|
||||
SERIAL_PROTOCOL(subdirname);
|
||||
SERIAL_PROTOCOLLNPGM(".");
|
||||
SERIAL_PROTOCOLLN('.');
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -431,7 +431,7 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru
|
|||
{
|
||||
SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL);
|
||||
SERIAL_PROTOCOL(fname);
|
||||
SERIAL_PROTOCOLLNPGM(".");
|
||||
SERIAL_PROTOCOLLN('.');
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -440,7 +440,7 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru
|
|||
{
|
||||
SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL);
|
||||
SERIAL_PROTOCOL(fname);
|
||||
SERIAL_PROTOCOLLNPGM(".");
|
||||
SERIAL_PROTOCOLLN('.');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -497,17 +497,15 @@ void CardReader::getStatus()
|
|||
SERIAL_PROTOCOLLNPGM("Print saved");
|
||||
}
|
||||
else {
|
||||
SERIAL_PROTOCOL(longFilename);
|
||||
SERIAL_PROTOCOLPGM("\n");
|
||||
SERIAL_PROTOCOLLN(longFilename);
|
||||
SERIAL_PROTOCOLRPGM(_N("SD printing byte "));////MSG_SD_PRINTING_BYTE
|
||||
SERIAL_PROTOCOL(sdpos);
|
||||
SERIAL_PROTOCOLPGM("/");
|
||||
SERIAL_PROTOCOL('/');
|
||||
SERIAL_PROTOCOLLN(filesize);
|
||||
uint16_t time = _millis()/60000 - starttime/60000;
|
||||
uint16_t time = ( _millis() - starttime ) / 60000U;
|
||||
SERIAL_PROTOCOL(itostr2(time/60));
|
||||
SERIAL_PROTOCOL(':');
|
||||
SERIAL_PROTOCOL(itostr2(time%60));
|
||||
SERIAL_PROTOCOLPGM("\n");
|
||||
SERIAL_PROTOCOLLN(itostr2(time%60));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -341,8 +341,9 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
|
|||
| 0x0D9F 3487 | uint8 | ^ | 00h 0 | ffh 255 | 8th sheet - bed temp | ^ | D3 Ax0d9f C1
|
||||
| 0x0DA0 3488 | uint8 | ^ | 00h 0 | ffh 255 | 8th sheet - PINDA temp | ^ | D3 Ax0da0 C1
|
||||
| 0x0DA1 3489 | uint8 | ??? | 00h 0 | ffh 255 | ??? | ??? | D3 Ax0da1 C1
|
||||
| 0x0D48 3400 | uint8 | EEPROM_FSENSOR_PCB | ??? | ffh 255 | Filament Sensor type old vs new | ??? | D3 Ax0d48 C1
|
||||
| ^ | ^ | ^ | ??? | ^ | Filament Sensor type ??? | ^ | ^
|
||||
| 0x0D48 3400 | uint8 | EEPROM_FSENSOR_PCB | ffh 255 | ffh 255 | Filament Sensor type IR unknown | LCD Support | D3 Ax0d48 C1
|
||||
| ^ | ^ | ^ | 00h 0 | ^ | Filament Sensor type IR 0.3 or older | ^ | ^
|
||||
| ^ | ^ | ^ | 01h 1 | ^ | Filament Sensor type IR 0.4 or newer | ^ | ^
|
||||
| 0x0D47 3399 | uint8 | EEPROM_FSENSOR_ACTION_NA | 00h 0 | ffh 255 | Filament Sensor action: __Continue__ | LCD menu | D3 Ax0d47 C1
|
||||
| ^ | ^ | ^ | 01h 1 | ^ | Filament Sensor action: __Pause__ | ^ | ^
|
||||
| 0x0D37 3383 | float | EEPROM_UVLO_SAVED_TARGET | ??? | ff ff ff ffh | Power panic saved target all-axis | ??? | D3 Ax0d37 C16
|
||||
|
@ -358,6 +359,12 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
|
|||
| ^ | ^ | ^ | 00h 0 | ^ | LCD backlight mode: __Dim__ | ^ | ^
|
||||
| 0x0D30 3376 | uint16 | EEPROM_BACKLIGHT_TIMEOUT | 01 00 - ff ff | 0a 00h 65535 | LCD backlight timeout: __10__ seconds | LCD menu | D3 Ax0d30 C2
|
||||
| 0x0D2C 3372 | float | EEPROM_UVLO_LA_K | ??? | ff ff ff ffh | Power panic saved Linear Advanced K value | ??? | D3 Ax0d2c C4
|
||||
| 0x0D2B 3371 | uint8 | EEPROM_ALTFAN_OVERRIDE | ffh 255 | ffh 255 | ALTFAN override unknown state | LCD menu | D3 Ax0d2b C1
|
||||
| ^ | ^ | ^ | 00h 0 | ^ | ALTFAN override deactivated | ^ | ^
|
||||
| ^ | ^ | ^ | 01h 1 | ^ | ALTFAN override activated | ^ | ^
|
||||
| 0x0D2A 3370 | uint8 | EEPROM_EXPERIMENTAL_VISIBILITY | ffh 255 | ffh 255 | Experimental menu visibility unknown state | LCD menu | D3 Ax0d2a C1
|
||||
| ^ | ^ | ^ | 00h 0 | ^ | Experimental menu visibility hidden | ^ | ^
|
||||
| ^ | ^ | ^ | 01h 1 | ^ | Experimental menu visibility visible | ^ | ^
|
||||
|
||||
|
||||
| Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code
|
||||
|
@ -560,8 +567,11 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
|
|||
|
||||
#define EEPROM_UVLO_LA_K (EEPROM_BACKLIGHT_TIMEOUT-4) // float
|
||||
|
||||
#define EEPROM_ALTFAN_OVERRIDE (EEPROM_UVLO_LA_K-1) //uint8
|
||||
#define EEPROM_EXPERIMENTAL_VISIBILITY (EEPROM_ALTFAN_OVERRIDE-1) //uint8
|
||||
|
||||
//This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items.
|
||||
#define EEPROM_LAST_ITEM EEPROM_UVLO_LA_K
|
||||
#define EEPROM_LAST_ITEM EEPROM_EXPERIMENTAL_VISIBILITY
|
||||
// !!!!!
|
||||
// !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
|
||||
// !!!!!
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) != 0)
|
||||
|
||||
/// check if pin is an timer
|
||||
#define _GET_TIMER(IO) ((DIO ## IO ## _PWM)
|
||||
#define _GET_TIMER(IO) (DIO ## IO ## _PWM)
|
||||
|
||||
// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
||||
|
||||
|
|
|
@ -170,6 +170,21 @@ void fsensor_checkpoint_print(void)
|
|||
restore_print_from_ram_and_continue(0);
|
||||
}
|
||||
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
const char* FsensorIRVersionText()
|
||||
{
|
||||
switch(oFsensorPCB)
|
||||
{
|
||||
case ClFsensorPCB::_Old:
|
||||
return _T(MSG_IR_03_OR_OLDER);
|
||||
case ClFsensorPCB::_Rev04:
|
||||
return _T(MSG_IR_04_OR_NEWER);
|
||||
default:
|
||||
return _T(MSG_IR_UNKNOWN);
|
||||
}
|
||||
}
|
||||
#endif //IR_SENSOR_ANALOG
|
||||
|
||||
void fsensor_init(void)
|
||||
{
|
||||
#ifdef PAT9125
|
||||
|
@ -207,9 +222,9 @@ void fsensor_init(void)
|
|||
}
|
||||
printf_P(PSTR("FSensor %S"), (fsensor_enabled?PSTR("ENABLED"):PSTR("DISABLED")));
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
printf_P(PSTR(" (sensor board revision:%S)\n"), (oFsensorPCB==ClFsensorPCB::_Rev04) ? _T(MSG_04_OR_NEWER) : _T(MSG_03_OR_OLDER));
|
||||
printf_P(PSTR(" (sensor board revision:%S)\n"), FsensorIRVersionText());
|
||||
#else //IR_SENSOR_ANALOG
|
||||
printf_P(PSTR("\n"));
|
||||
MYSERIAL.println();
|
||||
#endif //IR_SENSOR_ANALOG
|
||||
if (check_for_ir_sensor()){
|
||||
ir_sensor_detected = true;
|
||||
|
@ -463,22 +478,8 @@ bool fsensor_oq_result(void)
|
|||
}
|
||||
#endif //FSENSOR_QUALITY
|
||||
|
||||
ISR(FSENSOR_INT_PIN_VECT)
|
||||
FORCE_INLINE static void fsensor_isr(int st_cnt)
|
||||
{
|
||||
if (mmu_enabled || ir_sensor_detected) return;
|
||||
if (!((fsensor_int_pin_old ^ FSENSOR_INT_PIN_PIN_REG) & FSENSOR_INT_PIN_MASK)) return;
|
||||
fsensor_int_pin_old = FSENSOR_INT_PIN_PIN_REG;
|
||||
|
||||
// prevent isr re-entry
|
||||
static bool _lock = false;
|
||||
if (_lock) return;
|
||||
_lock = true;
|
||||
|
||||
// fetch fsensor_st_cnt atomically
|
||||
int st_cnt = fsensor_st_cnt;
|
||||
fsensor_st_cnt = 0;
|
||||
sei();
|
||||
|
||||
uint8_t old_err_cnt = fsensor_err_cnt;
|
||||
uint8_t pat9125_res = fsensor_oq_meassure?pat9125_update():pat9125_update_y();
|
||||
if (!pat9125_res)
|
||||
|
@ -563,8 +564,28 @@ ISR(FSENSOR_INT_PIN_VECT)
|
|||
#endif //DEBUG_FSENSOR_LOG
|
||||
|
||||
pat9125_y = 0;
|
||||
_lock = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ISR(FSENSOR_INT_PIN_VECT)
|
||||
{
|
||||
if (mmu_enabled || ir_sensor_detected) return;
|
||||
if (!((fsensor_int_pin_old ^ FSENSOR_INT_PIN_PIN_REG) & FSENSOR_INT_PIN_MASK)) return;
|
||||
fsensor_int_pin_old = FSENSOR_INT_PIN_PIN_REG;
|
||||
|
||||
// prevent isr re-entry
|
||||
static bool _lock = false;
|
||||
if (!_lock)
|
||||
{
|
||||
// fetch fsensor_st_cnt atomically
|
||||
int st_cnt = fsensor_st_cnt;
|
||||
fsensor_st_cnt = 0;
|
||||
|
||||
_lock = true;
|
||||
sei();
|
||||
fsensor_isr(st_cnt);
|
||||
cli();
|
||||
_lock = false;
|
||||
}
|
||||
}
|
||||
|
||||
void fsensor_setup_interrupt(void)
|
||||
|
@ -611,42 +632,41 @@ void fsensor_enque_M600(){
|
|||
void fsensor_update(void)
|
||||
{
|
||||
#ifdef PAT9125
|
||||
if (fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
|
||||
{
|
||||
fsensor_stop_and_save_print();
|
||||
if (fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
|
||||
{
|
||||
fsensor_stop_and_save_print();
|
||||
KEEPALIVE_STATE(IN_HANDLER);
|
||||
|
||||
bool autoload_enabled_tmp = fsensor_autoload_enabled;
|
||||
fsensor_autoload_enabled = false;
|
||||
bool oq_meassure_enabled_tmp = fsensor_oq_meassure_enabled;
|
||||
fsensor_oq_meassure_enabled = true;
|
||||
bool autoload_enabled_tmp = fsensor_autoload_enabled;
|
||||
fsensor_autoload_enabled = false;
|
||||
bool oq_meassure_enabled_tmp = fsensor_oq_meassure_enabled;
|
||||
fsensor_oq_meassure_enabled = true;
|
||||
|
||||
// move the nozzle away while checking the filament
|
||||
current_position[Z_AXIS] += 0.8;
|
||||
if(current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
|
||||
plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder);
|
||||
plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS]);
|
||||
st_synchronize();
|
||||
|
||||
// check the filament in isolation
|
||||
fsensor_reset_err_cnt();
|
||||
fsensor_oq_meassure_start(0);
|
||||
fsensor_oq_meassure_start(0);
|
||||
float e_tmp = current_position[E_AXIS];
|
||||
current_position[E_AXIS] -= 3;
|
||||
plan_buffer_line_curposXYZE(250/60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(250/60);
|
||||
current_position[E_AXIS] = e_tmp;
|
||||
plan_buffer_line_curposXYZE(200/60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(200/60);
|
||||
st_synchronize();
|
||||
fsensor_oq_meassure_stop();
|
||||
fsensor_oq_meassure_stop();
|
||||
|
||||
bool err = false;
|
||||
err |= (fsensor_err_cnt > 0); // final error count is non-zero
|
||||
err |= (fsensor_oq_er_sum > FSENSOR_OQ_MAX_ES); // total error count is above limit
|
||||
err |= (fsensor_oq_yd_sum < FSENSOR_OQ_MIN_YD); // total measured distance is below limit
|
||||
bool err = false;
|
||||
err |= (fsensor_err_cnt > 0); // final error count is non-zero
|
||||
err |= (fsensor_oq_er_sum > FSENSOR_OQ_MAX_ES); // total error count is above limit
|
||||
err |= (fsensor_oq_yd_sum < FSENSOR_OQ_MIN_YD); // total measured distance is below limit
|
||||
|
||||
fsensor_restore_print_and_continue();
|
||||
fsensor_autoload_enabled = autoload_enabled_tmp;
|
||||
fsensor_oq_meassure_enabled = oq_meassure_enabled_tmp;
|
||||
|
||||
unsigned long now = _millis();
|
||||
if (!err && (now - fsensor_softfail_last) > FSENSOR_SOFTERR_DELTA)
|
||||
fsensor_softfail_ccnt = 0;
|
||||
|
@ -663,70 +683,70 @@ void fsensor_update(void)
|
|||
fsensor_softfail_last = 0;
|
||||
fsensor_enque_M600();
|
||||
}
|
||||
}
|
||||
}
|
||||
#else //PAT9125
|
||||
if (CHECK_FSENSOR && ir_sensor_detected)
|
||||
if (CHECK_FSENSOR && ir_sensor_detected)
|
||||
{
|
||||
if(digitalRead(IR_SENSOR_PIN))
|
||||
{ // IR_SENSOR_PIN ~ H
|
||||
if(digitalRead(IR_SENSOR_PIN))
|
||||
{ // IR_SENSOR_PIN ~ H
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
if(!bIRsensorStateFlag)
|
||||
if(!bIRsensorStateFlag)
|
||||
{
|
||||
bIRsensorStateFlag=true;
|
||||
nIRsensorLastTime=_millis();
|
||||
}
|
||||
else
|
||||
{
|
||||
if((_millis()-nIRsensorLastTime)>IR_SENSOR_STEADY)
|
||||
{
|
||||
bIRsensorStateFlag=true;
|
||||
nIRsensorLastTime=_millis();
|
||||
}
|
||||
else
|
||||
{
|
||||
if((_millis()-nIRsensorLastTime)>IR_SENSOR_STEADY)
|
||||
{
|
||||
uint8_t nMUX1,nMUX2;
|
||||
uint16_t nADC;
|
||||
bIRsensorStateFlag=false;
|
||||
// sequence for direct data reading from AD converter
|
||||
DISABLE_TEMPERATURE_INTERRUPT();
|
||||
nMUX1=ADMUX; // ADMUX saving
|
||||
nMUX2=ADCSRB;
|
||||
adc_setmux(VOLT_IR_PIN);
|
||||
ADCSRA|=(1<<ADSC); // first conversion after ADMUX change discarded (preventively)
|
||||
while(ADCSRA&(1<<ADSC))
|
||||
;
|
||||
ADCSRA|=(1<<ADSC); // second conversion used
|
||||
while(ADCSRA&(1<<ADSC))
|
||||
;
|
||||
nADC=ADC;
|
||||
ADMUX=nMUX1; // ADMUX restoring
|
||||
ADCSRB=nMUX2;
|
||||
ENABLE_TEMPERATURE_INTERRUPT();
|
||||
// end of sequence for ...
|
||||
// Detection of correct function of fsensor v04 - it must NOT read >4.6V
|
||||
// If it does, it means a disconnected cables or faulty board
|
||||
if( (oFsensorPCB == ClFsensorPCB::_Rev04) && ( (nADC*OVERSAMPLENR) > IRsensor_Hopen_TRESHOLD ) )
|
||||
{
|
||||
fsensor_disable();
|
||||
fsensor_not_responding = true;
|
||||
printf_P(PSTR("IR sensor not responding (%d)!\n"),1);
|
||||
if((ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA)==ClFsensorActionNA::_Pause)
|
||||
uint8_t nMUX1,nMUX2;
|
||||
uint16_t nADC;
|
||||
bIRsensorStateFlag=false;
|
||||
// sequence for direct data reading from AD converter
|
||||
DISABLE_TEMPERATURE_INTERRUPT();
|
||||
nMUX1=ADMUX; // ADMUX saving
|
||||
nMUX2=ADCSRB;
|
||||
adc_setmux(VOLT_IR_PIN);
|
||||
ADCSRA|=(1<<ADSC); // first conversion after ADMUX change discarded (preventively)
|
||||
while(ADCSRA&(1<<ADSC))
|
||||
;
|
||||
ADCSRA|=(1<<ADSC); // second conversion used
|
||||
while(ADCSRA&(1<<ADSC))
|
||||
;
|
||||
nADC=ADC;
|
||||
ADMUX=nMUX1; // ADMUX restoring
|
||||
ADCSRB=nMUX2;
|
||||
ENABLE_TEMPERATURE_INTERRUPT();
|
||||
// end of sequence for ...
|
||||
// Detection of correct function of fsensor v04 - it must NOT read >4.6V
|
||||
// If it does, it means a disconnected cables or faulty board
|
||||
if( (oFsensorPCB == ClFsensorPCB::_Rev04) && ( (nADC*OVERSAMPLENR) > IRsensor_Hopen_TRESHOLD ) )
|
||||
{
|
||||
fsensor_disable();
|
||||
fsensor_not_responding = true;
|
||||
printf_P(PSTR("IR sensor not responding (%d)!\n"),1);
|
||||
if((ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA)==ClFsensorActionNA::_Pause)
|
||||
|
||||
// if we are printing and FS action is set to "Pause", force pause the print
|
||||
if(oFsensorActionNA==ClFsensorActionNA::_Pause)
|
||||
lcd_pause_print();
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we are printing and FS action is set to "Pause", force pause the print
|
||||
if(oFsensorActionNA==ClFsensorActionNA::_Pause)
|
||||
lcd_pause_print();
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif //IR_SENSOR_ANALOG
|
||||
fsensor_checkpoint_print();
|
||||
fsensor_enque_M600();
|
||||
fsensor_checkpoint_print();
|
||||
fsensor_enque_M600();
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // IR_SENSOR_PIN ~ L
|
||||
bIRsensorStateFlag=false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // IR_SENSOR_PIN ~ L
|
||||
bIRsensorStateFlag=false;
|
||||
#endif //IR_SENSOR_ANALOG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //PAT9125
|
||||
}
|
||||
|
||||
|
@ -734,24 +754,36 @@ void fsensor_update(void)
|
|||
/// This is called only upon start of the printer or when switching the fsensor ON in the menu
|
||||
/// We cannot do temporal window checks here (aka the voltage has been in some range for a period of time)
|
||||
bool fsensor_IR_check(){
|
||||
if( IRsensor_Lmax_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_Hmin_TRESHOLD ){
|
||||
// If the voltage is in forbidden range, the fsensor is ok, but the lever is mounted improperly.
|
||||
// Or the user is so creative so that he can hold a piece of fillament in the hole in such a genius way,
|
||||
// that the IR fsensor reading is within 1.5 and 3V ... this would have been highly unusual
|
||||
// and would have been considered more like a sabotage than normal printer operation
|
||||
printf_P(PSTR("fsensor in forbidden range 1.5-3V - bad lever\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if( oFsensorPCB == ClFsensorPCB::_Rev04 ){
|
||||
// newer IR sensor cannot normally produce 4.6-5V, this is considered a failure/bad mount
|
||||
if( IRsensor_Hopen_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_VMax_TRESHOLD ){
|
||||
printf_P(PSTR("fsensor v0.4 in fault range 4.6-5V - unconnected\n"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise the IR fsensor is considered working correctly
|
||||
return true;
|
||||
if( IRsensor_Lmax_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_Hmin_TRESHOLD ){
|
||||
/// If the voltage is in forbidden range, the fsensor is ok, but the lever is mounted improperly.
|
||||
/// Or the user is so creative so that he can hold a piece of fillament in the hole in such a genius way,
|
||||
/// that the IR fsensor reading is within 1.5 and 3V ... this would have been highly unusual
|
||||
/// and would have been considered more like a sabotage than normal printer operation
|
||||
printf_P(PSTR("fsensor in forbidden range 1.5-3V - check sensor\n"));
|
||||
return false;
|
||||
}
|
||||
if( oFsensorPCB == ClFsensorPCB::_Rev04 ){
|
||||
/// newer IR sensor cannot normally produce 4.6-5V, this is considered a failure/bad mount
|
||||
if( IRsensor_Hopen_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_VMax_TRESHOLD ){
|
||||
printf_P(PSTR("fsensor v0.4 in fault range 4.6-5V - unconnected\n"));
|
||||
return false;
|
||||
}
|
||||
/// newer IR sensor cannot normally produce 0-0.3V, this is considered a failure
|
||||
#if 0 //Disabled as it has to be decided if we gonna use this or not.
|
||||
if( IRsensor_Hopen_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_VMax_TRESHOLD ){
|
||||
printf_P(PSTR("fsensor v0.4 in fault range 0.0-0.3V - wrong IR sensor\n"));
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/// If IR sensor is "uknown state" and filament is not loaded > 1.5V return false
|
||||
#if 0
|
||||
if( (oFsensorPCB == ClFsensorPCB::_Undef) && ( current_voltage_raw_IR > IRsensor_Lmax_TRESHOLD ) ){
|
||||
printf_P(PSTR("Unknown IR sensor version and no filament loaded detected.\n"));
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
// otherwise the IR fsensor is considered working correctly
|
||||
return true;
|
||||
}
|
||||
#endif //IR_SENSOR_ANALOG
|
||||
|
|
|
@ -83,6 +83,7 @@ extern uint8_t fsensor_log;
|
|||
//! @}
|
||||
#endif //PAT9125
|
||||
|
||||
#define VOLT_DIV_REF 5
|
||||
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
#define IR_SENSOR_STEADY 10 // [ms]
|
||||
|
@ -103,8 +104,21 @@ enum class ClFsensorActionNA:uint_least8_t
|
|||
|
||||
extern ClFsensorPCB oFsensorPCB;
|
||||
extern ClFsensorActionNA oFsensorActionNA;
|
||||
extern const char* FsensorIRVersionText();
|
||||
|
||||
extern bool fsensor_IR_check();
|
||||
constexpr uint16_t Voltage2Raw(float V){
|
||||
return ( V * 1023 * OVERSAMPLENR / VOLT_DIV_REF ) + 0.5F;
|
||||
}
|
||||
constexpr float Raw2Voltage(uint16_t raw){
|
||||
return VOLT_DIV_REF*(raw / (1023.F * OVERSAMPLENR) );
|
||||
}
|
||||
constexpr uint16_t IRsensor_Ldiode_TRESHOLD = Voltage2Raw(0.3F); // ~0.3V, raw value=982
|
||||
constexpr uint16_t IRsensor_Lmax_TRESHOLD = Voltage2Raw(1.5F); // ~1.5V (0.3*Vcc), raw value=4910
|
||||
constexpr uint16_t IRsensor_Hmin_TRESHOLD = Voltage2Raw(3.0F); // ~3.0V (0.6*Vcc), raw value=9821
|
||||
constexpr uint16_t IRsensor_Hopen_TRESHOLD = Voltage2Raw(4.6F); // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k), raw value=15059
|
||||
constexpr uint16_t IRsensor_VMax_TRESHOLD = Voltage2Raw(5.F); // ~5V, raw value=16368
|
||||
|
||||
#endif //IR_SENSOR_ANALOG
|
||||
|
||||
#endif //FSENSOR_H
|
||||
|
|
|
@ -59,7 +59,6 @@ enum class States : uint8_t {
|
|||
RISE, ///< 16 fast PWM cycles with increasing duty up to steady ON
|
||||
RISE_TO_ONE, ///< metastate allowing the timer change its state atomically without artefacts on the output pin
|
||||
ONE, ///< steady 1 (ON), no change for the whole period
|
||||
ONE_TO_FALL, ///< metastate allowing the timer change its state atomically without artefacts on the output pin
|
||||
FALL, ///< 16 fast PWM cycles with decreasing duty down to steady OFF
|
||||
FALL_TO_ZERO ///< metastate allowing the timer change its state atomically without artefacts on the output pin
|
||||
};
|
||||
|
@ -155,12 +154,7 @@ ISR(TIMER0_OVF_vect) // timer compare interrupt service routine
|
|||
return; // want full duty for the next ONE cycle again - so keep on heating and just wait for the next timer ovf
|
||||
}
|
||||
// otherwise moving towards FALL
|
||||
// @@TODO it looks like ONE_TO_FALL isn't necessary, there are no artefacts at all
|
||||
state = States::ONE;//_TO_FALL;
|
||||
// TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz
|
||||
// break;
|
||||
// case States::ONE_TO_FALL:
|
||||
// OCR0B = 255; // zero duty
|
||||
state=States::FALL;
|
||||
fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE
|
||||
TCNT0 = 255; // force overflow on the next clock cycle
|
||||
|
|
|
@ -78,10 +78,10 @@ float la10c_jerk(float j)
|
|||
return j;
|
||||
|
||||
// bring low E-jerk values into equivalent LA 1.5 values by
|
||||
// flattening the response in the (1-4.5) range using a piecewise
|
||||
// flattening the response in the (0.3-4.5) range using a piecewise
|
||||
// function. Is it truly worth to preserve the difference between
|
||||
// 1.5/2.5 E-jerk for LA1.0? Probably not, but we try nonetheless.
|
||||
j = j < 1.0? j * 3.625:
|
||||
j = j < 0.3? j * 11.5:
|
||||
j < 4.5? j * 0.25 + 3.375:
|
||||
j;
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bo
|
|||
{
|
||||
menu_menu = menu;
|
||||
lcd_encoder = encoder;
|
||||
menu_top = 0; //reset menu view. Needed if menu_back() is called from deep inside a menu, such as Support
|
||||
CRITICAL_SECTION_END;
|
||||
if (reset_menu_state)
|
||||
menu_data_reset();
|
||||
|
|
|
@ -920,7 +920,7 @@ static inline void go_xy(float x, float y, float fr)
|
|||
|
||||
static inline void go_to_current(float fr)
|
||||
{
|
||||
plan_buffer_line_curposXYZE(fr, active_extruder);
|
||||
plan_buffer_line_curposXYZE(fr);
|
||||
st_synchronize();
|
||||
}
|
||||
|
||||
|
@ -929,7 +929,7 @@ static inline void update_current_position_xyz()
|
|||
current_position[X_AXIS] = st_get_position_mm(X_AXIS);
|
||||
current_position[Y_AXIS] = st_get_position_mm(Y_AXIS);
|
||||
current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
|
||||
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
||||
plan_set_position_curposXYZE();
|
||||
}
|
||||
|
||||
static inline void update_current_position_z()
|
||||
|
|
|
@ -140,8 +140,9 @@ const char MSG_DIM[] PROGMEM_I1 = ISTR("Dim"); ////c=6
|
|||
const char MSG_AUTO[] PROGMEM_I1 = ISTR("Auto"); ////c=6
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
// Beware - the space at the beginning is necessary since it is reused in LCD menu items which are to be with a space
|
||||
const char MSG_04_OR_NEWER[] PROGMEM_I1 = ISTR(" 0.4 or newer");////c=18
|
||||
const char MSG_03_OR_OLDER[] PROGMEM_I1 = ISTR(" 0.3 or older");////c=18
|
||||
const char MSG_IR_04_OR_NEWER[] PROGMEM_I1 = ISTR(" 0.4 or newer");////c=18
|
||||
const char MSG_IR_03_OR_OLDER[] PROGMEM_I1 = ISTR(" 0.3 or older");////c=18
|
||||
const char MSG_IR_UNKNOWN[] PROGMEM_I1 = ISTR("unknown state");////c=18
|
||||
#endif
|
||||
|
||||
//not internationalized messages
|
||||
|
|
|
@ -139,8 +139,9 @@ extern const char MSG_BRIGHT[];
|
|||
extern const char MSG_DIM[];
|
||||
extern const char MSG_AUTO[];
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
extern const char MSG_04_OR_NEWER[];
|
||||
extern const char MSG_03_OR_OLDER[];
|
||||
extern const char MSG_IR_04_OR_NEWER[];
|
||||
extern const char MSG_IR_03_OR_OLDER[];
|
||||
extern const char MSG_IR_UNKNOWN[];
|
||||
#endif
|
||||
|
||||
//not internationalized messages
|
||||
|
|
|
@ -540,7 +540,7 @@ void mmu_command(MmuCmd cmd)
|
|||
void mmu_load_step(bool synchronize)
|
||||
{
|
||||
current_position[E_AXIS] = current_position[E_AXIS] + MMU_LOAD_FEEDRATE * 0.1;
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder);
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE);
|
||||
if (synchronize) st_synchronize();
|
||||
}
|
||||
|
||||
|
@ -605,7 +605,7 @@ bool mmu_get_response(uint8_t move)
|
|||
{
|
||||
printf_P(PSTR("Unload 1\n"));
|
||||
current_position[E_AXIS] = current_position[E_AXIS] - MMU_LOAD_FEEDRATE * MMU_LOAD_TIME_MS*0.001;
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder);
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE);
|
||||
st_synchronize();
|
||||
}
|
||||
}
|
||||
|
@ -623,7 +623,7 @@ bool mmu_get_response(uint8_t move)
|
|||
{
|
||||
printf_P(PSTR("Unload 2\n"));
|
||||
current_position[E_AXIS] = current_position[E_AXIS] - MMU_LOAD_FEEDRATE * MMU_LOAD_TIME_MS*0.001;
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder);
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE);
|
||||
st_synchronize();
|
||||
}
|
||||
}
|
||||
|
@ -701,13 +701,13 @@ void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move)
|
|||
//lift z
|
||||
current_position[Z_AXIS] += Z_PAUSE_LIFT;
|
||||
if (current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
|
||||
plan_buffer_line_curposXYZE(15, active_extruder);
|
||||
plan_buffer_line_curposXYZE(15);
|
||||
st_synchronize();
|
||||
|
||||
//Move XY to side
|
||||
current_position[X_AXIS] = X_PAUSE_POS;
|
||||
current_position[Y_AXIS] = Y_PAUSE_POS;
|
||||
plan_buffer_line_curposXYZE(50, active_extruder);
|
||||
plan_buffer_line_curposXYZE(50);
|
||||
st_synchronize();
|
||||
}
|
||||
if (turn_off_nozzle) {
|
||||
|
@ -758,17 +758,17 @@ void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move)
|
|||
lcd_display_message_fullscreen_P(_i("MMU OK. Resuming temperature..."));
|
||||
delay_keep_alive(3000);
|
||||
}
|
||||
mmu_wait_for_heater_blocking();
|
||||
mmu_wait_for_heater_blocking();
|
||||
}
|
||||
if (move_axes) {
|
||||
lcd_clear();
|
||||
lcd_display_message_fullscreen_P(_i("MMU OK. Resuming position..."));
|
||||
current_position[X_AXIS] = x_position_bckp;
|
||||
current_position[Y_AXIS] = y_position_bckp;
|
||||
plan_buffer_line_curposXYZE(50, active_extruder);
|
||||
plan_buffer_line_curposXYZE(50);
|
||||
st_synchronize();
|
||||
current_position[Z_AXIS] = z_position_bckp;
|
||||
plan_buffer_line_curposXYZE(15, active_extruder);
|
||||
plan_buffer_line_curposXYZE(15);
|
||||
st_synchronize();
|
||||
}
|
||||
else {
|
||||
|
@ -807,19 +807,19 @@ void mmu_load_to_nozzle()
|
|||
current_position[E_AXIS] += 7.2f;
|
||||
}
|
||||
float feedrate = 562;
|
||||
plan_buffer_line_curposXYZE(feedrate / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(feedrate / 60);
|
||||
st_synchronize();
|
||||
current_position[E_AXIS] += 14.4f;
|
||||
feedrate = 871;
|
||||
plan_buffer_line_curposXYZE(feedrate / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(feedrate / 60);
|
||||
st_synchronize();
|
||||
current_position[E_AXIS] += 36.0f;
|
||||
feedrate = 1393;
|
||||
plan_buffer_line_curposXYZE(feedrate / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(feedrate / 60);
|
||||
st_synchronize();
|
||||
current_position[E_AXIS] += 14.4f;
|
||||
feedrate = 871;
|
||||
plan_buffer_line_curposXYZE(feedrate / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(feedrate / 60);
|
||||
st_synchronize();
|
||||
if (!saved_e_relative_mode) axis_relative_modes &= ~E_AXIS_MASK;
|
||||
}
|
||||
|
@ -1072,7 +1072,7 @@ void mmu_filament_ramming()
|
|||
for(uint8_t i = 0; i < (sizeof(ramming_sequence)/sizeof(E_step));++i)
|
||||
{
|
||||
current_position[E_AXIS] += pgm_read_float(&(ramming_sequence[i].extrude));
|
||||
plan_buffer_line_curposXYZE(pgm_read_float(&(ramming_sequence[i].feed_rate)), active_extruder);
|
||||
plan_buffer_line_curposXYZE(pgm_read_float(&(ramming_sequence[i].feed_rate)));
|
||||
st_synchronize();
|
||||
}
|
||||
}
|
||||
|
@ -1446,9 +1446,9 @@ bFilamentAction=false; // NOT in "mmu_fil_eject_menu(
|
|||
static bool can_load()
|
||||
{
|
||||
current_position[E_AXIS] += 60;
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder);
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE);
|
||||
current_position[E_AXIS] -= 52;
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder);
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE);
|
||||
st_synchronize();
|
||||
|
||||
uint_least8_t filament_detected_count = 0;
|
||||
|
@ -1458,7 +1458,7 @@ static bool can_load()
|
|||
for(uint_least8_t i = 0; i < steps; ++i)
|
||||
{
|
||||
current_position[E_AXIS] -= e_increment;
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder);
|
||||
plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE);
|
||||
st_synchronize();
|
||||
if(0 == PIN_GET(IR_SENSOR_PIN))
|
||||
{
|
||||
|
|
|
@ -99,9 +99,11 @@ struct block_t;
|
|||
extern struct block_t *block_buffer;
|
||||
|
||||
//! @brief Enter an STK500 compatible Optiboot boot loader waiting for flashing the languages to an external flash memory.
|
||||
void optiboot_w25x20cl_enter()
|
||||
//! @return 1 if "start\n" was not sent. Optiboot was skipped
|
||||
//! @return 0 if "start\n" was sent. Optiboot ran normally. No need to send "start\n" in setup()
|
||||
uint8_t optiboot_w25x20cl_enter()
|
||||
{
|
||||
if (boot_app_flags & BOOT_APP_FLG_USER0) return;
|
||||
if (boot_app_flags & BOOT_APP_FLG_USER0) return 1;
|
||||
uint8_t ch;
|
||||
uint8_t rampz = 0;
|
||||
register uint16_t address = 0;
|
||||
|
@ -120,38 +122,46 @@ void optiboot_w25x20cl_enter()
|
|||
unsigned long boot_timer = 0;
|
||||
const char *ptr = entry_magic_send;
|
||||
const char *end = strlen_P(entry_magic_send) + ptr;
|
||||
// Initialize the serial line.
|
||||
UCSR0A |= (1 << U2X0);
|
||||
UBRR0L = (((float)(F_CPU))/(((float)(115200))*8.0)-1.0+0.5);
|
||||
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
|
||||
const uint8_t selectedSerialPort_bak = selectedSerialPort;
|
||||
// Flush the serial line.
|
||||
while (RECV_READY) {
|
||||
watchdogReset();
|
||||
// Dummy register read (discard)
|
||||
(void)(*(char *)UDR0);
|
||||
}
|
||||
selectedSerialPort = 0; //switch to Serial0
|
||||
MYSERIAL.flush(); //clear RX buffer
|
||||
int SerialHead = rx_buffer.head;
|
||||
// Send the initial magic string.
|
||||
while (ptr != end)
|
||||
putch(pgm_read_byte(ptr ++));
|
||||
watchdogReset();
|
||||
// Wait for one second until a magic string (constant entry_magic) is received
|
||||
// Wait for two seconds until a magic string (constant entry_magic) is received
|
||||
// from the serial line.
|
||||
ptr = entry_magic_receive;
|
||||
end = strlen_P(entry_magic_receive) + ptr;
|
||||
while (ptr != end) {
|
||||
while (! RECV_READY) {
|
||||
while (rx_buffer.head == SerialHead) {
|
||||
watchdogReset();
|
||||
delayMicroseconds(1);
|
||||
if (++ boot_timer > boot_timeout)
|
||||
{
|
||||
// Timeout expired, continue with the application.
|
||||
return;
|
||||
selectedSerialPort = selectedSerialPort_bak; //revert Serial setting
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ch = UDR0;
|
||||
ch = rx_buffer.buffer[SerialHead];
|
||||
SerialHead = (unsigned int)(SerialHead + 1) % RX_BUFFER_SIZE;
|
||||
if (pgm_read_byte(ptr ++) != ch)
|
||||
{
|
||||
// Magic was not received correctly, continue with the application
|
||||
return;
|
||||
selectedSerialPort = selectedSerialPort_bak; //revert Serial setting
|
||||
return 0;
|
||||
}
|
||||
watchdogReset();
|
||||
}
|
||||
cbi(UCSR0B, RXCIE0); //disable the MarlinSerial0 interrupt
|
||||
// Send the cfm magic string.
|
||||
ptr = entry_magic_cfm;
|
||||
while (ptr != end)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef OPTIBOOT_W25X20CL_H
|
||||
#define OPTIBOOT_W25X20CL_H
|
||||
|
||||
extern void optiboot_w25x20cl_enter();
|
||||
extern uint8_t optiboot_w25x20cl_enter();
|
||||
|
||||
#endif /* OPTIBOOT_W25X20CL_H */
|
||||
|
|
|
@ -226,11 +226,23 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit
|
|||
// Size of Plateau of Nominal Rate.
|
||||
uint32_t plateau_steps = 0;
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
uint16_t final_adv_steps = 0;
|
||||
uint16_t max_adv_steps = 0;
|
||||
if (block->use_advance_lead) {
|
||||
final_adv_steps = final_rate * block->adv_comp;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will
|
||||
// have to use intersection_distance() to calculate when to abort acceleration and start braking
|
||||
// in order to reach the final_rate exactly at the end of this block.
|
||||
if (accel_decel_steps < block->step_event_count.wide) {
|
||||
plateau_steps = block->step_event_count.wide - accel_decel_steps;
|
||||
#ifdef LIN_ADVANCE
|
||||
if (block->use_advance_lead)
|
||||
max_adv_steps = block->nominal_rate * block->adv_comp;
|
||||
#endif
|
||||
} else {
|
||||
uint32_t acceleration_x4 = acceleration << 2;
|
||||
// Avoid negative numbers
|
||||
|
@ -263,14 +275,20 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit
|
|||
decelerate_steps = block->step_event_count.wide;
|
||||
accelerate_steps = block->step_event_count.wide - decelerate_steps;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
uint16_t final_adv_steps = 0;
|
||||
if (block->use_advance_lead) {
|
||||
final_adv_steps = exit_speed * block->adv_comp;
|
||||
}
|
||||
if (block->use_advance_lead) {
|
||||
if(!accelerate_steps || !decelerate_steps) {
|
||||
// accelerate_steps=0: deceleration-only ramp, max_rate is effectively unused
|
||||
// decelerate_steps=0: acceleration-only ramp, max_rate _is_ final_rate
|
||||
max_adv_steps = final_adv_steps;
|
||||
} else {
|
||||
float max_rate = sqrt(acceleration_x2 * accelerate_steps + initial_rate_sqr);
|
||||
max_adv_steps = max_rate * block->adv_comp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section
|
||||
// This block locks the interrupts globally for 4.38 us,
|
||||
|
@ -284,6 +302,7 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit
|
|||
block->final_rate = final_rate;
|
||||
#ifdef LIN_ADVANCE
|
||||
block->final_adv_steps = final_adv_steps;
|
||||
block->max_adv_steps = max_adv_steps;
|
||||
#endif
|
||||
}
|
||||
CRITICAL_SECTION_END;
|
||||
|
@ -671,8 +690,16 @@ void planner_abort_hard()
|
|||
waiting_inside_plan_buffer_line_print_aborted = true;
|
||||
}
|
||||
|
||||
void plan_buffer_line_curposXYZE(float feed_rate, uint8_t extruder) {
|
||||
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feed_rate, extruder );
|
||||
void plan_buffer_line_curposXYZE(float feed_rate) {
|
||||
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feed_rate, active_extruder );
|
||||
}
|
||||
|
||||
void plan_buffer_line_destinationXYZE(float feed_rate) {
|
||||
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feed_rate, active_extruder);
|
||||
}
|
||||
|
||||
void plan_set_position_curposXYZE(){
|
||||
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
||||
}
|
||||
|
||||
float junction_deviation = 0.1;
|
||||
|
@ -1069,12 +1096,20 @@ Having the real displacement of the head, we can calculate the total movement le
|
|||
&& delta_mm[E_AXIS] >= 0
|
||||
&& abs(delta_mm[Z_AXIS]) < 0.5;
|
||||
if (block->use_advance_lead) {
|
||||
#ifdef LA_FLOWADJ
|
||||
// M221/FLOW should change uniformly the extrusion thickness
|
||||
float delta_e = (e - position_float[E_AXIS]) / extruder_multiplier[extruder];
|
||||
#else
|
||||
// M221/FLOW only adjusts for an incorrect source diameter
|
||||
float delta_e = (e - position_float[E_AXIS]);
|
||||
#endif
|
||||
float delta_D = sqrt(sq(x - position_float[X_AXIS])
|
||||
+ sq(y - position_float[Y_AXIS])
|
||||
+ sq(z - position_float[Z_AXIS]));
|
||||
|
||||
// all extrusion moves with LA require a compression which is proportional to the
|
||||
// extrusion_length to distance ratio (e/D)
|
||||
e_D_ratio = (e - position_float[E_AXIS]) /
|
||||
sqrt(sq(x - position_float[X_AXIS])
|
||||
+ sq(y - position_float[Y_AXIS])
|
||||
+ sq(z - position_float[Z_AXIS]));
|
||||
e_D_ratio = delta_e / delta_D;
|
||||
|
||||
// Check for unusual high e_D ratio to detect if a retract move was combined with the last
|
||||
// print move due to min. steps per segment. Never execute this with advance! This assumes
|
||||
|
@ -1124,53 +1159,7 @@ Having the real displacement of the head, we can calculate the total movement le
|
|||
block->acceleration_st = (block->acceleration_st + (bresenham_oversample >> 1)) / bresenham_oversample;
|
||||
#endif
|
||||
|
||||
block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0)));
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
if (block->use_advance_lead) {
|
||||
// the nominal speed doesn't change past this point: calculate the compression ratio for the
|
||||
// segment and the required advance steps
|
||||
block->adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_unit[E_AXIS];
|
||||
block->max_adv_steps = block->nominal_speed * block->adv_comp;
|
||||
|
||||
float advance_speed;
|
||||
if (e_D_ratio > 0)
|
||||
advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]);
|
||||
else
|
||||
advance_speed = cs.max_jerk[E_AXIS] * cs.axis_steps_per_unit[E_AXIS];
|
||||
|
||||
// to save more space we avoid another copy of calc_timer and go through slow division, but we
|
||||
// still need to replicate the *exact* same step grouping policy (see below)
|
||||
if (advance_speed > MAX_STEP_FREQUENCY) advance_speed = MAX_STEP_FREQUENCY;
|
||||
float advance_rate = (F_CPU / 8.0) / advance_speed;
|
||||
if (advance_speed > 20000) {
|
||||
block->advance_rate = advance_rate * 4;
|
||||
block->advance_step_loops = 4;
|
||||
}
|
||||
else if (advance_speed > 10000) {
|
||||
block->advance_rate = advance_rate * 2;
|
||||
block->advance_step_loops = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// never overflow the internal accumulator with very low rates
|
||||
if (advance_rate < UINT16_MAX)
|
||||
block->advance_rate = advance_rate;
|
||||
else
|
||||
block->advance_rate = UINT16_MAX;
|
||||
block->advance_step_loops = 1;
|
||||
}
|
||||
|
||||
#ifdef LA_DEBUG
|
||||
if (block->advance_step_loops > 2)
|
||||
// @wavexx: we should really check for the difference between step_loops and
|
||||
// advance_step_loops instead. A difference of more than 1 will lead
|
||||
// to uneven speed and *should* be adjusted here by furthermore
|
||||
// reducing the speed.
|
||||
SERIAL_ECHOLNPGM("LA: More than 2 steps per eISR loop executed.");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
block->acceleration_rate = ((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0)));
|
||||
|
||||
// Start with a safe speed.
|
||||
// Safe speed is the speed, from which the machine may halt to stop immediately.
|
||||
|
@ -1297,6 +1286,53 @@ Having the real displacement of the head, we can calculate the total movement le
|
|||
|
||||
// Precalculate the division, so when all the trapezoids in the planner queue get recalculated, the division is not repeated.
|
||||
block->speed_factor = block->nominal_rate / block->nominal_speed;
|
||||
|
||||
#ifdef LIN_ADVANCE
|
||||
if (block->use_advance_lead) {
|
||||
// calculate the compression ratio for the segment (the required advance steps are computed
|
||||
// during trapezoid planning)
|
||||
float adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_unit[E_AXIS]; // (step/(mm/s))
|
||||
block->adv_comp = adv_comp / block->speed_factor; // step/(step/min)
|
||||
|
||||
float advance_speed;
|
||||
if (e_D_ratio > 0)
|
||||
advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]);
|
||||
else
|
||||
advance_speed = cs.max_jerk[E_AXIS] * cs.axis_steps_per_unit[E_AXIS];
|
||||
|
||||
// to save more space we avoid another copy of calc_timer and go through slow division, but we
|
||||
// still need to replicate the *exact* same step grouping policy (see below)
|
||||
if (advance_speed > MAX_STEP_FREQUENCY) advance_speed = MAX_STEP_FREQUENCY;
|
||||
float advance_rate = (F_CPU / 8.0) / advance_speed;
|
||||
if (advance_speed > 20000) {
|
||||
block->advance_rate = advance_rate * 4;
|
||||
block->advance_step_loops = 4;
|
||||
}
|
||||
else if (advance_speed > 10000) {
|
||||
block->advance_rate = advance_rate * 2;
|
||||
block->advance_step_loops = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// never overflow the internal accumulator with very low rates
|
||||
if (advance_rate < UINT16_MAX)
|
||||
block->advance_rate = advance_rate;
|
||||
else
|
||||
block->advance_rate = UINT16_MAX;
|
||||
block->advance_step_loops = 1;
|
||||
}
|
||||
|
||||
#ifdef LA_DEBUG
|
||||
if (block->advance_step_loops > 2)
|
||||
// @wavexx: we should really check for the difference between step_loops and
|
||||
// advance_step_loops instead. A difference of more than 1 will lead
|
||||
// to uneven speed and *should* be adjusted here by furthermore
|
||||
// reducing the speed.
|
||||
SERIAL_ECHOLNPGM("LA: More than 2 steps per eISR loop executed.");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
calculate_trapezoid_for_block(block, block->entry_speed, safe_speed);
|
||||
|
||||
if (block->step_event_count.wide <= 32767)
|
||||
|
|
|
@ -73,12 +73,12 @@ typedef struct {
|
|||
// steps_x.y,z, step_event_count, acceleration_rate, direction_bits and active_extruder are set by plan_buffer_line().
|
||||
dda_isteps_t steps_x, steps_y, steps_z, steps_e; // Step count along each axis
|
||||
dda_usteps_t step_event_count; // The number of step events required to complete this block
|
||||
long acceleration_rate; // The acceleration rate used for acceleration calculation
|
||||
uint32_t acceleration_rate; // The acceleration rate used for acceleration calculation
|
||||
unsigned char direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h)
|
||||
unsigned char active_extruder; // Selects the active extruder
|
||||
// accelerate_until and decelerate_after are set by calculate_trapezoid_for_block() and they need to be synchronized with the stepper interrupt controller.
|
||||
long accelerate_until; // The index of the step event on which to stop acceleration
|
||||
long decelerate_after; // The index of the step event on which to start decelerating
|
||||
uint32_t accelerate_until; // The index of the step event on which to stop acceleration
|
||||
uint32_t decelerate_after; // The index of the step event on which to start decelerating
|
||||
|
||||
// Fields used by the motion planner to manage acceleration
|
||||
// float speed_x, speed_y, speed_z, speed_e; // Nominal mm/sec for each axis
|
||||
|
@ -100,13 +100,12 @@ typedef struct {
|
|||
|
||||
// Settings for the trapezoid generator (runs inside an interrupt handler).
|
||||
// Changing the following values in the planner needs to be synchronized with the interrupt handler by disabling the interrupts.
|
||||
//FIXME nominal_rate, initial_rate and final_rate are limited to uint16_t by MultiU24X24toH16 in the stepper interrupt anyway!
|
||||
unsigned long nominal_rate; // The nominal step rate for this block in step_events/sec
|
||||
unsigned long initial_rate; // The jerk-adjusted step rate at start of block
|
||||
unsigned long final_rate; // The minimal rate at exit
|
||||
unsigned long acceleration_st; // acceleration steps/sec^2
|
||||
//FIXME does it have to be unsigned long? Probably uint8_t would be just fine.
|
||||
unsigned long fan_speed;
|
||||
//FIXME does it have to be int? Probably uint8_t would be just fine. Need to change in other places as well
|
||||
int fan_speed;
|
||||
volatile char busy;
|
||||
|
||||
|
||||
|
@ -154,7 +153,11 @@ vector_3 plan_get_position();
|
|||
/// plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[3], ...
|
||||
/// saves almost 5KB.
|
||||
/// The performance penalty is negligible, since these planned lines are usually maintenance moves with the extruder.
|
||||
void plan_buffer_line_curposXYZE(float feed_rate, uint8_t extruder);
|
||||
void plan_buffer_line_curposXYZE(float feed_rate);
|
||||
|
||||
void plan_buffer_line_destinationXYZE(float feed_rate);
|
||||
|
||||
void plan_set_position_curposXYZE();
|
||||
|
||||
void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, uint8_t extruder, const float* gcode_target = NULL);
|
||||
//void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder);
|
||||
|
|
|
@ -80,15 +80,21 @@ asm volatile ( \
|
|||
|
||||
#else //_NO_ASM
|
||||
|
||||
// NOTE: currently not implemented
|
||||
void MultiU16X8toH16(unsigned short& intRes, unsigned char& charIn1, unsigned short& intIn2);
|
||||
void MultiU24X24toH16(uint16_t& intRes, int32_t& longIn1, long& longIn2);
|
||||
static inline void MultiU16X8toH16(uint16_t& intRes, uint8_t& charIn1, uint16_t& intIn2)
|
||||
{
|
||||
intRes = ((uint32_t)charIn1 * (uint32_t)intIn2) >> 16;
|
||||
}
|
||||
|
||||
static inline void MultiU24X24toH16(uint16_t& intRes, uint32_t& longIn1, uint32_t& longIn2)
|
||||
{
|
||||
intRes = ((uint64_t)longIn1 * (uint64_t)longIn2) >> 24;
|
||||
}
|
||||
|
||||
#endif //_NO_ASM
|
||||
|
||||
|
||||
FORCE_INLINE unsigned short calc_timer(uint16_t step_rate, uint8_t& step_loops) {
|
||||
unsigned short timer;
|
||||
uint16_t timer;
|
||||
if(step_rate > MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY;
|
||||
|
||||
if(step_rate > 20000) { // If steprate > 20kHz >> step 4 times
|
||||
|
@ -108,7 +114,7 @@ FORCE_INLINE unsigned short calc_timer(uint16_t step_rate, uint8_t& step_loops)
|
|||
if(step_rate >= (8*256)){ // higher step rate
|
||||
unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate>>8)][0];
|
||||
unsigned char tmp_step_rate = (step_rate & 0x00ff);
|
||||
unsigned short gain = (unsigned short)pgm_read_word_near(table_address+2);
|
||||
uint16_t gain = (uint16_t)pgm_read_word_near(table_address+2);
|
||||
MultiU16X8toH16(timer, tmp_step_rate, gain);
|
||||
timer = (unsigned short)pgm_read_word_near(table_address) - timer;
|
||||
}
|
||||
|
|
|
@ -71,8 +71,7 @@ static dda_isteps_t
|
|||
counter_z,
|
||||
counter_e;
|
||||
volatile dda_usteps_t step_events_completed; // The number of step events executed in the current block
|
||||
static int32_t acceleration_time, deceleration_time;
|
||||
//static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
|
||||
static uint32_t acceleration_time, deceleration_time;
|
||||
static uint16_t acc_step_rate; // needed for deccelaration start point
|
||||
static uint8_t step_loops;
|
||||
static uint16_t OCR1A_nominal;
|
||||
|
@ -125,7 +124,7 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1};
|
|||
|
||||
static uint16_t main_Rate;
|
||||
static uint16_t eISR_Rate;
|
||||
static uint16_t eISR_Err;
|
||||
static uint32_t eISR_Err;
|
||||
|
||||
static uint16_t current_adv_steps;
|
||||
static uint16_t target_adv_steps;
|
||||
|
@ -234,7 +233,7 @@ void invert_z_endstop(bool endstop_invert)
|
|||
// The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
|
||||
// first block->accelerate_until step_events_completed, then keeps going at constant speed until
|
||||
// step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
|
||||
// The slope of acceleration is calculated with the leib ramp alghorithm.
|
||||
// The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far.
|
||||
|
||||
// "The Stepper Driver Interrupt" - This timer interrupt is the workhorse.
|
||||
// It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately.
|
||||
|
@ -348,10 +347,7 @@ FORCE_INLINE void stepper_next_block()
|
|||
|
||||
#ifdef LIN_ADVANCE
|
||||
if (current_block->use_advance_lead) {
|
||||
e_step_loops = current_block->advance_step_loops;
|
||||
target_adv_steps = current_block->max_adv_steps;
|
||||
} else {
|
||||
e_step_loops = 1;
|
||||
}
|
||||
e_steps = 0;
|
||||
nextAdvanceISR = ADV_NEVER;
|
||||
|
@ -736,38 +732,30 @@ FORCE_INLINE uint16_t fastdiv(uint16_t q, uint8_t d)
|
|||
|
||||
FORCE_INLINE void advance_spread(uint16_t timer)
|
||||
{
|
||||
if(eISR_Err > timer)
|
||||
eISR_Err += timer;
|
||||
|
||||
uint8_t ticks = 0;
|
||||
while(eISR_Err >= current_block->advance_rate)
|
||||
{
|
||||
++ticks;
|
||||
eISR_Err -= current_block->advance_rate;
|
||||
}
|
||||
if(!ticks)
|
||||
{
|
||||
// advance-step skipped
|
||||
eISR_Err -= timer;
|
||||
eISR_Rate = timer;
|
||||
nextAdvanceISR = timer;
|
||||
return;
|
||||
}
|
||||
|
||||
// at least one step
|
||||
uint8_t ticks = 1;
|
||||
uint32_t block = current_block->advance_rate;
|
||||
uint16_t max_t = timer - eISR_Err;
|
||||
while (block < max_t)
|
||||
{
|
||||
++ticks;
|
||||
block += current_block->advance_rate;
|
||||
}
|
||||
if (block > timer)
|
||||
eISR_Err += block - timer;
|
||||
else
|
||||
eISR_Err -= timer - block;
|
||||
|
||||
if (ticks <= 4)
|
||||
eISR_Rate = fastdiv(timer, ticks);
|
||||
if (ticks <= 3)
|
||||
eISR_Rate = fastdiv(timer, ticks + 1);
|
||||
else
|
||||
{
|
||||
// >4 ticks are still possible on slow moves
|
||||
eISR_Rate = timer / ticks;
|
||||
eISR_Rate = timer / (ticks + 1);
|
||||
}
|
||||
|
||||
nextAdvanceISR = eISR_Rate / 2;
|
||||
nextAdvanceISR = eISR_Rate;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -799,7 +787,7 @@ FORCE_INLINE void isr() {
|
|||
// 25.12us for acceleration / deceleration.
|
||||
{
|
||||
//WRITE_NC(LOGIC_ANALYZER_CH1, true);
|
||||
if (step_events_completed.wide <= (unsigned long int)current_block->accelerate_until) {
|
||||
if (step_events_completed.wide <= current_block->accelerate_until) {
|
||||
// v = t * a -> acc_step_rate = acceleration_time * current_block->acceleration_rate
|
||||
MultiU24X24toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate);
|
||||
acc_step_rate += uint16_t(current_block->initial_rate);
|
||||
|
@ -812,19 +800,29 @@ FORCE_INLINE void isr() {
|
|||
acceleration_time += timer;
|
||||
#ifdef LIN_ADVANCE
|
||||
if (current_block->use_advance_lead) {
|
||||
if (step_events_completed.wide <= (unsigned long int)step_loops)
|
||||
if (step_events_completed.wide <= (unsigned long int)step_loops) {
|
||||
la_state = ADV_INIT | ADV_ACC_VARY;
|
||||
if (e_extruding && current_adv_steps > target_adv_steps)
|
||||
target_adv_steps = current_adv_steps;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (step_events_completed.wide > (unsigned long int)current_block->decelerate_after) {
|
||||
else if (step_events_completed.wide > current_block->decelerate_after) {
|
||||
uint16_t step_rate;
|
||||
MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate);
|
||||
step_rate = acc_step_rate - step_rate; // Decelerate from aceleration end point.
|
||||
if ((step_rate & 0x8000) || step_rate < uint16_t(current_block->final_rate)) {
|
||||
// Result is negative or too small.
|
||||
step_rate = uint16_t(current_block->final_rate);
|
||||
|
||||
if (step_rate > acc_step_rate) { // Check step_rate stays positive
|
||||
step_rate = uint16_t(current_block->final_rate);
|
||||
}
|
||||
else {
|
||||
step_rate = acc_step_rate - step_rate; // Decelerate from acceleration end point.
|
||||
|
||||
// lower limit
|
||||
if (step_rate < current_block->final_rate)
|
||||
step_rate = uint16_t(current_block->final_rate);
|
||||
}
|
||||
|
||||
// Step_rate to timer interval.
|
||||
uint16_t timer = calc_timer(step_rate, step_loops);
|
||||
_NEXT_ISR(timer);
|
||||
|
@ -832,9 +830,11 @@ FORCE_INLINE void isr() {
|
|||
|
||||
#ifdef LIN_ADVANCE
|
||||
if (current_block->use_advance_lead) {
|
||||
if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops) {
|
||||
if (step_events_completed.wide <= current_block->decelerate_after + step_loops) {
|
||||
target_adv_steps = current_block->final_adv_steps;
|
||||
la_state = ADV_INIT | ADV_ACC_VARY;
|
||||
if (e_extruding && current_adv_steps < target_adv_steps)
|
||||
target_adv_steps = current_adv_steps;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -848,12 +848,12 @@ FORCE_INLINE void isr() {
|
|||
|
||||
#ifdef LIN_ADVANCE
|
||||
if(current_block->use_advance_lead) {
|
||||
if (!nextAdvanceISR) {
|
||||
// Due to E-jerk, there can be discontinuities in pressure state where an
|
||||
// acceleration or deceleration can be skipped or joined with the previous block.
|
||||
// If LA was not previously active, re-check the pressure level
|
||||
la_state = ADV_INIT;
|
||||
}
|
||||
// Due to E-jerk, there can be discontinuities in pressure state where an
|
||||
// acceleration or deceleration can be skipped or joined with the previous block.
|
||||
// If LA was not previously active, re-check the pressure level
|
||||
la_state = ADV_INIT;
|
||||
if (e_extruding)
|
||||
target_adv_steps = current_adv_steps;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -865,14 +865,21 @@ FORCE_INLINE void isr() {
|
|||
#ifdef LIN_ADVANCE
|
||||
// avoid multiple instances or function calls to advance_spread
|
||||
if (la_state & ADV_INIT) {
|
||||
LA_phase = -1;
|
||||
|
||||
if (current_adv_steps == target_adv_steps) {
|
||||
// nothing to be done in this phase
|
||||
// nothing to be done in this phase, cancel any pending eisr
|
||||
la_state = 0;
|
||||
nextAdvanceISR = ADV_NEVER;
|
||||
}
|
||||
else {
|
||||
eISR_Err = current_block->advance_rate / 4;
|
||||
// reset error and iterations per loop for this phase
|
||||
eISR_Err = current_block->advance_rate;
|
||||
e_step_loops = current_block->advance_step_loops;
|
||||
|
||||
if ((la_state & ADV_ACC_VARY) && e_extruding && (current_adv_steps > target_adv_steps)) {
|
||||
// LA could reverse the direction of extrusion in this phase
|
||||
eISR_Err += current_block->advance_rate;
|
||||
LA_phase = 0;
|
||||
}
|
||||
}
|
||||
|
@ -882,11 +889,13 @@ FORCE_INLINE void isr() {
|
|||
advance_spread(main_Rate);
|
||||
if (LA_phase >= 0) {
|
||||
if (step_loops == e_step_loops)
|
||||
LA_phase = (eISR_Rate > main_Rate);
|
||||
LA_phase = (current_block->advance_rate < main_Rate);
|
||||
else {
|
||||
// avoid overflow through division. warning: we need to _guarantee_ step_loops
|
||||
// and e_step_loops are <= 4 due to fastdiv's limit
|
||||
LA_phase = (fastdiv(eISR_Rate, step_loops) > fastdiv(main_Rate, e_step_loops));
|
||||
auto adv_rate_n = fastdiv(current_block->advance_rate, step_loops);
|
||||
auto main_rate_n = fastdiv(main_Rate, e_step_loops);
|
||||
LA_phase = (adv_rate_n < main_rate_n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -928,26 +937,34 @@ FORCE_INLINE void isr() {
|
|||
FORCE_INLINE void advance_isr() {
|
||||
if (current_adv_steps > target_adv_steps) {
|
||||
// decompression
|
||||
if (e_step_loops != 1) {
|
||||
uint16_t d_steps = current_adv_steps - target_adv_steps;
|
||||
if (d_steps < e_step_loops)
|
||||
e_step_loops = d_steps;
|
||||
}
|
||||
e_steps -= e_step_loops;
|
||||
if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
|
||||
if(current_adv_steps > e_step_loops)
|
||||
current_adv_steps -= e_step_loops;
|
||||
else
|
||||
current_adv_steps = 0;
|
||||
nextAdvanceISR = eISR_Rate;
|
||||
current_adv_steps -= e_step_loops;
|
||||
}
|
||||
else if (current_adv_steps < target_adv_steps) {
|
||||
// compression
|
||||
if (e_step_loops != 1) {
|
||||
uint16_t d_steps = target_adv_steps - current_adv_steps;
|
||||
if (d_steps < e_step_loops)
|
||||
e_step_loops = d_steps;
|
||||
}
|
||||
e_steps += e_step_loops;
|
||||
if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
|
||||
current_adv_steps += e_step_loops;
|
||||
nextAdvanceISR = eISR_Rate;
|
||||
}
|
||||
else {
|
||||
|
||||
if (current_adv_steps == target_adv_steps) {
|
||||
// advance steps completed
|
||||
nextAdvanceISR = ADV_NEVER;
|
||||
LA_phase = -1;
|
||||
e_step_loops = 1;
|
||||
}
|
||||
else {
|
||||
// schedule another tick
|
||||
nextAdvanceISR = eISR_Rate;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1017,7 +1034,7 @@ FORCE_INLINE void advance_isr_scheduler() {
|
|||
|
||||
// Schedule the next closest tick, ignoring advance if scheduled too
|
||||
// soon in order to avoid skewing the regular stepper acceleration
|
||||
if (nextAdvanceISR != ADV_NEVER && (nextAdvanceISR + TCNT1 + 40) < nextMainISR)
|
||||
if (nextAdvanceISR != ADV_NEVER && (nextAdvanceISR + 40) < nextMainISR)
|
||||
OCR1A = nextAdvanceISR;
|
||||
else
|
||||
OCR1A = nextMainISR;
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
|
||||
#ifdef SYSTEM_TIMER_2
|
||||
#include "timer02.h"
|
||||
#include "tone04.h"
|
||||
#define _millis millis2
|
||||
#define _micros micros2
|
||||
#define _delay delay2
|
||||
#define _tone tone
|
||||
#define _noTone noTone
|
||||
#define _tone tone4
|
||||
#define _noTone noTone4
|
||||
|
||||
#define timer02_set_pwm0(pwm0)
|
||||
|
||||
|
|
|
@ -143,14 +143,22 @@ static volatile bool temp_meas_ready = false;
|
|||
#ifdef FAN_SOFT_PWM
|
||||
static unsigned char soft_pwm_fan;
|
||||
#endif
|
||||
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
|
||||
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
|
||||
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
|
||||
unsigned long extruder_autofan_last_check = _millis();
|
||||
uint8_t fanSpeedBckp = 255;
|
||||
bool fan_measuring = false;
|
||||
|
||||
#endif
|
||||
uint8_t fanSpeedBckp = 255;
|
||||
|
||||
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1)
|
||||
unsigned long extruder_autofan_last_check = _millis();
|
||||
|
||||
bool fan_measuring = false;
|
||||
uint8_t fanState = 0;
|
||||
#ifdef EXTRUDER_ALTFAN_DETECT
|
||||
struct
|
||||
{
|
||||
uint8_t isAltfan : 1;
|
||||
uint8_t altfanOverride : 1;
|
||||
} altfanStatus;
|
||||
#endif //EXTRUDER_ALTFAN_DETECT
|
||||
#endif
|
||||
|
||||
|
||||
#if EXTRUDERS > 3
|
||||
|
@ -176,6 +184,12 @@ static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP;
|
|||
#ifdef BED_MAXTEMP
|
||||
static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
|
||||
#endif
|
||||
#ifdef AMBIENT_MINTEMP
|
||||
static int ambient_minttemp_raw = AMBIENT_RAW_LO_TEMP;
|
||||
#endif
|
||||
#ifdef AMBIENT_MAXTEMP
|
||||
static int ambient_maxttemp_raw = AMBIENT_RAW_HI_TEMP;
|
||||
#endif
|
||||
|
||||
static void *heater_ttbl_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( (void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE, (void *)HEATER_2_TEMPTABLE );
|
||||
static uint8_t heater_ttbllen_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN );
|
||||
|
@ -210,6 +224,56 @@ static void temp_runaway_check(int _heater_id, float _target_temperature, float
|
|||
static void temp_runaway_stop(bool isPreheat, bool isBed);
|
||||
#endif
|
||||
|
||||
#ifdef EXTRUDER_ALTFAN_DETECT
|
||||
ISR(INT6_vect) {
|
||||
fan_edge_counter[0]++;
|
||||
}
|
||||
|
||||
bool extruder_altfan_detect()
|
||||
{
|
||||
setExtruderAutoFanState(3);
|
||||
|
||||
SET_INPUT(TACH_0);
|
||||
|
||||
uint8_t overrideVal = eeprom_read_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE);
|
||||
if (overrideVal == EEPROM_EMPTY_VALUE)
|
||||
{
|
||||
overrideVal = (calibration_status() == CALIBRATION_STATUS_CALIBRATED) ? 1 : 0;
|
||||
eeprom_update_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE, overrideVal);
|
||||
}
|
||||
altfanStatus.altfanOverride = overrideVal;
|
||||
|
||||
CRITICAL_SECTION_START;
|
||||
EICRB &= ~(1 << ISC61);
|
||||
EICRB |= (1 << ISC60);
|
||||
EIMSK |= (1 << INT6);
|
||||
fan_edge_counter[0] = 0;
|
||||
CRITICAL_SECTION_END;
|
||||
extruder_autofan_last_check = _millis();
|
||||
|
||||
_delay(1000);
|
||||
|
||||
EIMSK &= ~(1 << INT6);
|
||||
|
||||
countFanSpeed();
|
||||
altfanStatus.isAltfan = fan_speed[0] > 100;
|
||||
setExtruderAutoFanState(1);
|
||||
return altfanStatus.isAltfan;
|
||||
}
|
||||
|
||||
void altfanOverride_toggle()
|
||||
{
|
||||
altfanStatus.altfanOverride = !altfanStatus.altfanOverride;
|
||||
eeprom_update_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE, altfanStatus.altfanOverride);
|
||||
}
|
||||
|
||||
bool altfanOverride_get()
|
||||
{
|
||||
return altfanStatus.altfanOverride;
|
||||
}
|
||||
|
||||
#endif //EXTRUDER_ALTFAN_DETECT
|
||||
|
||||
// return "false", if all extruder-heaters are 'off' (ie. "true", if any heater is 'on')
|
||||
bool checkAllHotends(void)
|
||||
{
|
||||
|
@ -239,9 +303,7 @@ bool checkAllHotends(void)
|
|||
const uint8_t safety_check_cycles_count = (extruder < 0) ? 45 : 10; //10 cycles / 20s delay for extruder and 45 cycles / 90s for heatbed
|
||||
float temp_ambient;
|
||||
|
||||
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
|
||||
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
|
||||
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
|
||||
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1)
|
||||
unsigned long extruder_autofan_last_check = _millis();
|
||||
#endif
|
||||
|
||||
|
@ -289,9 +351,7 @@ bool checkAllHotends(void)
|
|||
max=max(max,input);
|
||||
min=min(min,input);
|
||||
|
||||
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
|
||||
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
|
||||
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
|
||||
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1)
|
||||
if(_millis() - extruder_autofan_last_check > 2500) {
|
||||
checkExtruderAutoFans();
|
||||
extruder_autofan_last_check = _millis();
|
||||
|
@ -447,29 +507,31 @@ int getHeaterPower(int heater) {
|
|||
return soft_pwm[heater];
|
||||
}
|
||||
|
||||
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
|
||||
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
|
||||
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
|
||||
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1)
|
||||
|
||||
#if defined(FAN_PIN) && FAN_PIN > -1
|
||||
#if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN
|
||||
#error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN"
|
||||
#endif
|
||||
#if EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN
|
||||
#error "You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to FAN_PIN"
|
||||
#endif
|
||||
#if EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN
|
||||
#error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void setExtruderAutoFanState(int pin, bool state)
|
||||
void setExtruderAutoFanState(uint8_t state)
|
||||
{
|
||||
unsigned char newFanSpeed = (state != 0) ? EXTRUDER_AUTO_FAN_SPEED : 0;
|
||||
// this idiom allows both digital and PWM fan outputs (see M42 handling).
|
||||
pinMode(pin, OUTPUT);
|
||||
digitalWrite(pin, newFanSpeed);
|
||||
//analogWrite(pin, newFanSpeed);
|
||||
//If bit 1 is set (0x02), then the extruder fan speed won't be adjusted according to temperature. Useful for forcing
|
||||
//the fan to either On or Off during certain tests/errors.
|
||||
|
||||
fanState = state;
|
||||
uint8_t newFanSpeed = 0;
|
||||
if (fanState & 0x01)
|
||||
{
|
||||
#ifdef EXTRUDER_ALTFAN_DETECT
|
||||
if (altfanStatus.isAltfan && !altfanStatus.altfanOverride) newFanSpeed = EXTRUDER_ALTFAN_SPEED_SILENT;
|
||||
else newFanSpeed = EXTRUDER_AUTO_FAN_SPEED;
|
||||
#else //EXTRUDER_ALTFAN_DETECT
|
||||
newFanSpeed = EXTRUDER_AUTO_FAN_SPEED;
|
||||
#endif //EXTRUDER_ALTFAN_DETECT
|
||||
}
|
||||
timer4_set_fan0(newFanSpeed);
|
||||
}
|
||||
|
||||
#if (defined(FANCHECK) && (((defined(TACH_0) && (TACH_0 >-1)) || (defined(TACH_1) && (TACH_1 > -1)))))
|
||||
|
@ -503,7 +565,7 @@ void checkFanSpeed()
|
|||
fans_check_enabled = (eeprom_read_byte((uint8_t*)EEPROM_FAN_CHECK_ENABLED) > 0);
|
||||
static unsigned char fan_speed_errors[2] = { 0,0 };
|
||||
#if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 >-1))
|
||||
if ((fan_speed[0] == 0) && (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)){ fan_speed_errors[0]++;}
|
||||
if ((fan_speed[0] < 20) && (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)){ fan_speed_errors[0]++;}
|
||||
else{
|
||||
fan_speed_errors[0] = 0;
|
||||
host_keepalive();
|
||||
|
@ -577,47 +639,14 @@ void fanSpeedError(unsigned char _fan) {
|
|||
|
||||
void checkExtruderAutoFans()
|
||||
{
|
||||
uint8_t fanState = 0;
|
||||
|
||||
// which fan pins need to be turned on?
|
||||
#if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1
|
||||
if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
|
||||
fanState |= 1;
|
||||
#endif
|
||||
#if defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1
|
||||
if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE)
|
||||
{
|
||||
if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
|
||||
fanState |= 1;
|
||||
else
|
||||
fanState |= 2;
|
||||
}
|
||||
#endif
|
||||
#if defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1
|
||||
if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE)
|
||||
{
|
||||
if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
|
||||
fanState |= 1;
|
||||
else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
|
||||
fanState |= 2;
|
||||
else
|
||||
fanState |= 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
// update extruder auto fan states
|
||||
#if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1
|
||||
setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0);
|
||||
#endif
|
||||
#if defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1
|
||||
if (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN)
|
||||
setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0);
|
||||
#endif
|
||||
#if defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1
|
||||
if (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN
|
||||
&& EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
|
||||
setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0);
|
||||
#endif
|
||||
#if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1
|
||||
if (!(fanState & 0x02))
|
||||
{
|
||||
fanState &= ~1;
|
||||
fanState |= current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE;
|
||||
}
|
||||
setExtruderAutoFanState(fanState);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // any extruder auto fan pins set
|
||||
|
@ -641,6 +670,7 @@ void manage_heater()
|
|||
return;
|
||||
// more precisely - this condition partially stabilizes time interval for regulation values evaluation (@ ~ 230ms)
|
||||
|
||||
// ADC values need to be converted before checking: converted values are later used in MINTEMP
|
||||
updateTemperaturesFromRawValues();
|
||||
|
||||
check_max_temp();
|
||||
|
@ -737,9 +767,7 @@ void manage_heater()
|
|||
#define FAN_CHECK_DURATION 100 //100ms
|
||||
|
||||
#ifndef DEBUG_DISABLE_FANCHECK
|
||||
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
|
||||
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
|
||||
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
|
||||
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1)
|
||||
|
||||
#ifdef FAN_SOFT_PWM
|
||||
#ifdef FANCHECK
|
||||
|
@ -1098,7 +1126,9 @@ void tp_init()
|
|||
|
||||
timer0_init();
|
||||
OCR2B = 128;
|
||||
TIMSK2 |= (1<<OCIE2B);
|
||||
TIMSK2 |= (1<<OCIE2B);
|
||||
|
||||
timer4_init(); //for tone and Extruder fan PWM
|
||||
|
||||
// Wait for temperature measurement to settle
|
||||
_delay(250);
|
||||
|
@ -1167,7 +1197,6 @@ void tp_init()
|
|||
#endif //MAXTEMP 2
|
||||
|
||||
#ifdef BED_MINTEMP
|
||||
/* No bed MINTEMP error implemented?!? */
|
||||
while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) {
|
||||
#if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
|
||||
bed_minttemp_raw += OVERSAMPLENR;
|
||||
|
@ -1175,7 +1204,6 @@ void tp_init()
|
|||
bed_minttemp_raw -= OVERSAMPLENR;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif //BED_MINTEMP
|
||||
#ifdef BED_MAXTEMP
|
||||
while(analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) {
|
||||
|
@ -1186,6 +1214,25 @@ void tp_init()
|
|||
#endif
|
||||
}
|
||||
#endif //BED_MAXTEMP
|
||||
|
||||
#ifdef AMBIENT_MINTEMP
|
||||
while(analog2tempAmbient(ambient_minttemp_raw) < AMBIENT_MINTEMP) {
|
||||
#if HEATER_AMBIENT_RAW_LO_TEMP < HEATER_AMBIENT_RAW_HI_TEMP
|
||||
ambient_minttemp_raw += OVERSAMPLENR;
|
||||
#else
|
||||
ambient_minttemp_raw -= OVERSAMPLENR;
|
||||
#endif
|
||||
}
|
||||
#endif //AMBIENT_MINTEMP
|
||||
#ifdef AMBIENT_MAXTEMP
|
||||
while(analog2tempAmbient(ambient_maxttemp_raw) > AMBIENT_MAXTEMP) {
|
||||
#if HEATER_AMBIENT_RAW_LO_TEMP < HEATER_AMBIENT_RAW_HI_TEMP
|
||||
ambient_maxttemp_raw -= OVERSAMPLENR;
|
||||
#else
|
||||
ambient_maxttemp_raw += OVERSAMPLENR;
|
||||
#endif
|
||||
}
|
||||
#endif //AMBIENT_MAXTEMP
|
||||
}
|
||||
|
||||
#if (defined (TEMP_RUNAWAY_BED_HYSTERESIS) && TEMP_RUNAWAY_BED_TIMEOUT > 0) || (defined (TEMP_RUNAWAY_EXTRUDER_HYSTERESIS) && TEMP_RUNAWAY_EXTRUDER_TIMEOUT > 0)
|
||||
|
@ -1357,9 +1404,11 @@ void temp_runaway_stop(bool isPreheat, bool isBed)
|
|||
isBed ? LCD_ALERTMESSAGEPGM("BED PREHEAT ERROR") : LCD_ALERTMESSAGEPGM("PREHEAT ERROR");
|
||||
SERIAL_ERROR_START;
|
||||
isBed ? SERIAL_ERRORLNPGM(" THERMAL RUNAWAY ( PREHEAT HEATBED)") : SERIAL_ERRORLNPGM(" THERMAL RUNAWAY ( PREHEAT HOTEND)");
|
||||
SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN);
|
||||
#ifdef EXTRUDER_ALTFAN_DETECT
|
||||
altfanStatus.altfanOverride = 1; //full speed
|
||||
#endif //EXTRUDER_ALTFAN_DETECT
|
||||
setExtruderAutoFanState(3);
|
||||
SET_OUTPUT(FAN_PIN);
|
||||
WRITE(EXTRUDER_0_AUTO_FAN_PIN, 1);
|
||||
#ifdef FAN_SOFT_PWM
|
||||
fanSpeedSoftPwm = 255;
|
||||
#else //FAN_SOFT_PWM
|
||||
|
@ -1427,26 +1476,55 @@ enum { LCDALERT_NONE = 0, LCDALERT_HEATERMINTEMP, LCDALERT_BEDMINTEMP, LCDALERT_
|
|||
//! to prevent flicker and improve speed
|
||||
uint8_t last_alert_sent_to_lcd = LCDALERT_NONE;
|
||||
|
||||
|
||||
//! update the current temperature error message
|
||||
//! @param type short error abbreviation (PROGMEM)
|
||||
//! @param func optional lcd update function (lcd_setalertstatus when first setting the error)
|
||||
void temp_update_messagepgm(const char* PROGMEM type, void (*func)(const char*) = lcd_updatestatus)
|
||||
{
|
||||
char msg[LCD_WIDTH];
|
||||
strcpy_P(msg, PSTR("Err: "));
|
||||
strcat_P(msg, type);
|
||||
(*func)(msg);
|
||||
}
|
||||
|
||||
//! signal a temperature error on both the lcd and serial
|
||||
//! @param type short error abbreviation (PROGMEM)
|
||||
//! @param e optional extruder index for hotend errors
|
||||
void temp_error_messagepgm(const char* PROGMEM type, uint8_t e = EXTRUDERS)
|
||||
{
|
||||
temp_update_messagepgm(type, lcd_setalertstatus);
|
||||
|
||||
SERIAL_ERROR_START;
|
||||
|
||||
if(e != EXTRUDERS) {
|
||||
SERIAL_ERROR((int)e);
|
||||
SERIAL_ERRORPGM(": ");
|
||||
}
|
||||
|
||||
SERIAL_ERRORPGM("Heaters switched off. ");
|
||||
SERIAL_ERRORRPGM(type);
|
||||
SERIAL_ERRORLNPGM(" triggered!");
|
||||
}
|
||||
|
||||
|
||||
void max_temp_error(uint8_t e) {
|
||||
disable_heater();
|
||||
if(IsStopped() == false) {
|
||||
SERIAL_ERROR_START;
|
||||
SERIAL_ERRORLN((int)e);
|
||||
SERIAL_ERRORLNPGM(": Extruder switched off. MAXTEMP triggered !");
|
||||
LCD_ALERTMESSAGEPGM("Err: MAXTEMP");
|
||||
temp_error_messagepgm(PSTR("MAXTEMP"), e);
|
||||
}
|
||||
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
|
||||
Stop();
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN);
|
||||
|
||||
SET_OUTPUT(FAN_PIN);
|
||||
SET_OUTPUT(BEEPER);
|
||||
WRITE(FAN_PIN, 1);
|
||||
WRITE(EXTRUDER_0_AUTO_FAN_PIN, 1);
|
||||
WRITE(BEEPER, 1);
|
||||
#ifdef EXTRUDER_ALTFAN_DETECT
|
||||
altfanStatus.altfanOverride = 1; //full speed
|
||||
#endif //EXTRUDER_ALTFAN_DETECT
|
||||
setExtruderAutoFanState(3);
|
||||
// fanSpeed will consumed by the check_axes_activity() routine.
|
||||
fanSpeed=255;
|
||||
if (farm_mode) { prusa_statistics(93); }
|
||||
|
@ -1456,18 +1534,15 @@ void min_temp_error(uint8_t e) {
|
|||
#ifdef DEBUG_DISABLE_MINTEMP
|
||||
return;
|
||||
#endif
|
||||
//if (current_temperature_ambient < MINTEMP_MINAMBIENT) return;
|
||||
disable_heater();
|
||||
static const char err[] PROGMEM = "Err: MINTEMP";
|
||||
//if (current_temperature_ambient < MINTEMP_MINAMBIENT) return;
|
||||
static const char err[] PROGMEM = "MINTEMP";
|
||||
if(IsStopped() == false) {
|
||||
SERIAL_ERROR_START;
|
||||
SERIAL_ERRORLN((int)e);
|
||||
SERIAL_ERRORLNPGM(": Extruder switched off. MINTEMP triggered !");
|
||||
lcd_setalertstatuspgm(err);
|
||||
temp_error_messagepgm(err, e);
|
||||
last_alert_sent_to_lcd = LCDALERT_HEATERMINTEMP;
|
||||
} else if( last_alert_sent_to_lcd != LCDALERT_HEATERMINTEMP ){ // only update, if the lcd message is to be changed (i.e. not the same as last time)
|
||||
// we are already stopped due to some error, only update the status message without flickering
|
||||
lcd_updatestatuspgm(err);
|
||||
temp_update_messagepgm(err);
|
||||
last_alert_sent_to_lcd = LCDALERT_HEATERMINTEMP;
|
||||
}
|
||||
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
|
||||
|
@ -1482,37 +1557,27 @@ void min_temp_error(uint8_t e) {
|
|||
}
|
||||
|
||||
void bed_max_temp_error(void) {
|
||||
#if HEATER_BED_PIN > -1
|
||||
//WRITE(HEATER_BED_PIN, 0);
|
||||
#endif
|
||||
disable_heater();
|
||||
if(IsStopped() == false) {
|
||||
SERIAL_ERROR_START;
|
||||
SERIAL_ERRORLNPGM("Temperature heated bed switched off. MAXTEMP triggered !");
|
||||
LCD_ALERTMESSAGEPGM("Err: MAXTEMP BED");
|
||||
temp_error_messagepgm(PSTR("MAXTEMP BED"));
|
||||
}
|
||||
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
|
||||
Stop();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void bed_min_temp_error(void) {
|
||||
#ifdef DEBUG_DISABLE_MINTEMP
|
||||
return;
|
||||
#endif
|
||||
//if (current_temperature_ambient < MINTEMP_MINAMBIENT) return;
|
||||
#if HEATER_BED_PIN > -1
|
||||
//WRITE(HEATER_BED_PIN, 0);
|
||||
#endif
|
||||
static const char err[] PROGMEM = "Err: MINTEMP BED";
|
||||
disable_heater();
|
||||
static const char err[] PROGMEM = "MINTEMP BED";
|
||||
if(IsStopped() == false) {
|
||||
SERIAL_ERROR_START;
|
||||
SERIAL_ERRORLNPGM("Temperature heated bed switched off. MINTEMP triggered !");
|
||||
lcd_setalertstatuspgm(err);
|
||||
temp_error_messagepgm(err);
|
||||
last_alert_sent_to_lcd = LCDALERT_BEDMINTEMP;
|
||||
} else if( last_alert_sent_to_lcd != LCDALERT_BEDMINTEMP ){ // only update, if the lcd message is to be changed (i.e. not the same as last time)
|
||||
// we are already stopped due to some error, only update the status message without flickering
|
||||
lcd_updatestatuspgm(err);
|
||||
temp_update_messagepgm(err);
|
||||
last_alert_sent_to_lcd = LCDALERT_BEDMINTEMP;
|
||||
}
|
||||
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
|
||||
|
@ -1520,6 +1585,33 @@ void bed_min_temp_error(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef AMBIENT_THERMISTOR
|
||||
void ambient_max_temp_error(void) {
|
||||
disable_heater();
|
||||
if(IsStopped() == false) {
|
||||
temp_error_messagepgm(PSTR("MAXTEMP AMB"));
|
||||
}
|
||||
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
|
||||
Stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ambient_min_temp_error(void) {
|
||||
#ifdef DEBUG_DISABLE_MINTEMP
|
||||
return;
|
||||
#endif
|
||||
disable_heater();
|
||||
if(IsStopped() == false) {
|
||||
temp_error_messagepgm(PSTR("MINTEMP AMB"));
|
||||
}
|
||||
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
|
||||
Stop();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HEATER_0_USES_MAX6675
|
||||
#define MAX6675_HEAT_INTERVAL 250
|
||||
long max6675_previous_millis = MAX6675_HEAT_INTERVAL;
|
||||
|
@ -1604,18 +1696,8 @@ void adc_ready(void) //callback from adc when sampling finished
|
|||
|
||||
} // extern "C"
|
||||
|
||||
// Timer2 (originaly timer0) is shared with millies
|
||||
#ifdef SYSTEM_TIMER_2
|
||||
ISR(TIMER2_COMPB_vect)
|
||||
#else //SYSTEM_TIMER_2
|
||||
ISR(TIMER0_COMPB_vect)
|
||||
#endif //SYSTEM_TIMER_2
|
||||
FORCE_INLINE static void temperature_isr()
|
||||
{
|
||||
static bool _lock = false;
|
||||
if (_lock) return;
|
||||
_lock = true;
|
||||
asm("sei");
|
||||
|
||||
if (!temp_meas_ready) adc_cycle();
|
||||
lcd_buttons_update();
|
||||
|
||||
|
@ -1981,8 +2063,24 @@ ISR(TIMER0_COMPB_vect)
|
|||
#if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 > -1))
|
||||
check_fans();
|
||||
#endif //(defined(TACH_0))
|
||||
}
|
||||
|
||||
_lock = false;
|
||||
// Timer2 (originaly timer0) is shared with millies
|
||||
#ifdef SYSTEM_TIMER_2
|
||||
ISR(TIMER2_COMPB_vect)
|
||||
#else //SYSTEM_TIMER_2
|
||||
ISR(TIMER0_COMPB_vect)
|
||||
#endif //SYSTEM_TIMER_2
|
||||
{
|
||||
static bool _lock = false;
|
||||
if (!_lock)
|
||||
{
|
||||
_lock = true;
|
||||
sei();
|
||||
temperature_isr();
|
||||
cli();
|
||||
_lock = false;
|
||||
}
|
||||
}
|
||||
|
||||
void check_max_temp()
|
||||
|
@ -2002,11 +2100,19 @@ void check_max_temp()
|
|||
#else
|
||||
if (current_temperature_bed_raw >= bed_maxttemp_raw) {
|
||||
#endif
|
||||
target_temperature_bed = 0;
|
||||
bed_max_temp_error();
|
||||
}
|
||||
#endif
|
||||
|
||||
//ambient
|
||||
#if defined(AMBIENT_MAXTEMP) && (TEMP_SENSOR_AMBIENT != 0)
|
||||
#if AMBIENT_RAW_LO_TEMP > AMBIENT_RAW_HI_TEMP
|
||||
if (current_temperature_raw_ambient <= ambient_maxttemp_raw) {
|
||||
#else
|
||||
if (current_temperature_raw_ambient >= ambient_maxttemp_raw) {
|
||||
#endif
|
||||
ambient_max_temp_error();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
//! number of repeating the same state with consecutive step() calls
|
||||
//! used to slow down text switching
|
||||
|
@ -2101,12 +2207,32 @@ void check_min_temp_bed()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef AMBIENT_MINTEMP
|
||||
void check_min_temp_ambient()
|
||||
{
|
||||
#if AMBIENT_RAW_LO_TEMP > AMBIENT_RAW_HI_TEMP
|
||||
if (current_temperature_raw_ambient >= ambient_minttemp_raw) {
|
||||
#else
|
||||
if (current_temperature_raw_ambient <= ambient_minttemp_raw) {
|
||||
#endif
|
||||
ambient_min_temp_error();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void check_min_temp()
|
||||
{
|
||||
static bool bCheckingOnHeater=false; // state variable, which allows to short no-checking delay (is set, when temperature is (first time) over heaterMintemp)
|
||||
static bool bCheckingOnBed=false; // state variable, which allows to short no-checking delay (is set, when temperature is (first time) over bedMintemp)
|
||||
#ifdef AMBIENT_THERMISTOR
|
||||
if(current_temperature_raw_ambient>(OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)) // thermistor is NTC type, so operator is ">" ;-)
|
||||
#ifdef AMBIENT_MINTEMP
|
||||
check_min_temp_ambient();
|
||||
#endif
|
||||
#if AMBIENT_RAW_LO_TEMP > AMBIENT_RAW_HI_TEMP
|
||||
if(current_temperature_raw_ambient>(OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)) // thermistor is NTC type
|
||||
#else
|
||||
if(current_temperature_raw_ambient=<(OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW))
|
||||
#endif
|
||||
{ // ambient temperature is low
|
||||
#endif //AMBIENT_THERMISTOR
|
||||
// *** 'common' part of code for MK2.5 & MK3
|
||||
|
@ -2194,4 +2320,20 @@ float unscalePID_d(float d)
|
|||
|
||||
#endif //PIDTEMP
|
||||
|
||||
#ifdef PINDA_THERMISTOR
|
||||
//! @brief PINDA thermistor detected
|
||||
//!
|
||||
//! @retval true firmware should do temperature compensation and allow calibration
|
||||
//! @retval false PINDA thermistor is not detected, disable temperature compensation and calibration
|
||||
//!
|
||||
bool has_temperature_compensation()
|
||||
{
|
||||
#ifdef DETECT_SUPERPINDA
|
||||
return (current_temperature_pinda >= PINDA_MINTEMP) ? true : false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif //PINDA_THERMISTOR
|
||||
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ extern float current_temperature_bed;
|
|||
#ifdef PINDA_THERMISTOR
|
||||
extern uint16_t current_temperature_raw_pinda;
|
||||
extern float current_temperature_pinda;
|
||||
bool has_temperature_compensation();
|
||||
#endif
|
||||
|
||||
#ifdef AMBIENT_THERMISTOR
|
||||
|
@ -245,7 +246,7 @@ FORCE_INLINE void autotempShutdown(){
|
|||
|
||||
void PID_autotune(float temp, int extruder, int ncycles);
|
||||
|
||||
void setExtruderAutoFanState(int pin, bool state);
|
||||
void setExtruderAutoFanState(uint8_t state);
|
||||
void checkExtruderAutoFans();
|
||||
|
||||
|
||||
|
@ -270,10 +271,14 @@ void check_fans();
|
|||
void check_min_temp();
|
||||
void check_max_temp();
|
||||
|
||||
|
||||
#endif
|
||||
#ifdef EXTRUDER_ALTFAN_DETECT
|
||||
extern bool extruder_altfan_detect();
|
||||
extern void altfanOverride_toggle();
|
||||
extern bool altfanOverride_get();
|
||||
#endif //EXTRUDER_ALTFAN_DETECT
|
||||
|
||||
extern unsigned long extruder_autofan_last_check;
|
||||
extern uint8_t fanSpeedBckp;
|
||||
extern bool fan_measuring;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1213,6 +1213,8 @@ const short temptable_1047[][2] PROGMEM = {
|
|||
#endif
|
||||
|
||||
#if (THERMISTORAMBIENT == 2000) //100k thermistor NTCG104LH104JT1
|
||||
# define AMBIENT_RAW_HI_TEMP 0
|
||||
# define AMBIENT_RAW_LO_TEMP 16383
|
||||
const short temptable_2000[][2] PROGMEM = {
|
||||
// Source: https://product.tdk.com/info/en/catalog/datasheets/503021/tpd_ntc-thermistor_ntcg_en.pdf
|
||||
// Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance
|
||||
|
|
126
Firmware/tone04.c
Normal file
126
Firmware/tone04.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
//tone04.c
|
||||
// use atmega timer4 as main tone timer instead of timer2
|
||||
// timer2 is used for System timer.
|
||||
|
||||
#include "system_timer.h"
|
||||
#include "Configuration_prusa.h"
|
||||
|
||||
#ifdef SYSTEM_TIMER_2
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "pins.h"
|
||||
|
||||
#ifndef CRITICAL_SECTION_START
|
||||
#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli();
|
||||
#define CRITICAL_SECTION_END SREG = _sreg;
|
||||
#endif //CRITICAL_SECTION_START
|
||||
|
||||
|
||||
#include "fastio.h"
|
||||
|
||||
void timer4_init(void)
|
||||
{
|
||||
CRITICAL_SECTION_START;
|
||||
|
||||
SET_OUTPUT(BEEPER);
|
||||
WRITE(BEEPER, LOW);
|
||||
|
||||
SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN);
|
||||
|
||||
// Set timer mode 9 (PWM,Phase and Frequency Correct)
|
||||
// Prescaler is CLK/1024
|
||||
// Output compare is disabled on all timer pins
|
||||
// Input capture is disabled
|
||||
// All interrupts are disabled
|
||||
TCCR4A = (1 << WGM40);
|
||||
TCCR4B = (1 << WGM43) | (1 << CS42) | (1 << CS40);
|
||||
OCR4A = 255;
|
||||
OCR4B = 255;
|
||||
OCR4C = 255;
|
||||
TIMSK4 = 0;
|
||||
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
|
||||
#ifdef EXTRUDER_0_AUTO_FAN_PIN
|
||||
void timer4_set_fan0(uint8_t duty)
|
||||
{
|
||||
if (duty == 0 || duty == 255)
|
||||
{
|
||||
// We use digital logic if the duty cycle is 0% or 100%
|
||||
TCCR4A &= ~(1 << COM4C1);
|
||||
OCR4C = 0;
|
||||
WRITE(EXTRUDER_0_AUTO_FAN_PIN, duty);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the timer for fan speed. Enable the timer compare output and set the duty cycle.
|
||||
// This function also handles the impossible scenario of a fan speed change during a Tone.
|
||||
// Better be safe than sorry.
|
||||
CRITICAL_SECTION_START;
|
||||
// Enable the PWM output on the fan pin.
|
||||
TCCR4A |= (1 << COM4C1);
|
||||
OCR4C = (((uint32_t)duty) * ((uint32_t)((TIMSK4 & (1 << OCIE4A))?OCR4A:255))) / ((uint32_t)255);
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
}
|
||||
#endif //EXTRUDER_0_AUTO_FAN_PIN
|
||||
|
||||
// Because of the timer mode change, we need two interrupts. We could also try to assume that the frequency is x2
|
||||
// and use a TOGGLE(), but this seems to work well enough so I left it as it is now.
|
||||
ISR(TIMER4_COMPA_vect)
|
||||
{
|
||||
WRITE(BEEPER, 1);
|
||||
}
|
||||
|
||||
ISR(TIMER4_OVF_vect)
|
||||
{
|
||||
WRITE(BEEPER, 0);
|
||||
}
|
||||
|
||||
void tone4(__attribute__((unused)) uint8_t _pin, uint16_t frequency)
|
||||
{
|
||||
//this ocr and prescalarbits calculation is taken from the Arduino core and simplified for one type of timer only
|
||||
uint8_t prescalarbits = 0b001;
|
||||
uint32_t ocr = F_CPU / frequency / 2 - 1;
|
||||
|
||||
if (ocr > 0xffff)
|
||||
{
|
||||
ocr = F_CPU / frequency / 2 / 64 - 1;
|
||||
prescalarbits = 0b011;
|
||||
}
|
||||
|
||||
CRITICAL_SECTION_START;
|
||||
// Set calcualted prescaler
|
||||
TCCR4B = (TCCR4B & 0b11111000) | prescalarbits;
|
||||
#ifdef EXTRUDER_0_AUTO_FAN_PIN
|
||||
// Scale the fan PWM duty cycle so that it remains constant, but at the tone frequency
|
||||
OCR4C = (((uint32_t)OCR4C) * ocr) / (uint32_t)((TIMSK4 & (1 << OCIE4A))?OCR4A:255);
|
||||
#endif //EXTRUDER_0_AUTO_FAN_PIN
|
||||
// Set calcualted ocr
|
||||
OCR4A = ocr;
|
||||
// Enable Output compare A interrupt and timer overflow interrupt
|
||||
TIMSK4 |= (1 << OCIE4A) | (1 << TOIE4);
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
|
||||
void noTone4(__attribute__((unused)) uint8_t _pin)
|
||||
{
|
||||
CRITICAL_SECTION_START;
|
||||
// Revert prescaler to CLK/1024
|
||||
TCCR4B = (TCCR4B & 0b11111000) | (1 << CS42) | (1 << CS40);
|
||||
#ifdef EXTRUDER_0_AUTO_FAN_PIN
|
||||
// Scale the fan OCR back to the original value.
|
||||
OCR4C = (((uint32_t)OCR4C) * (uint32_t)255) / (uint32_t)((TIMSK4 & (1 << OCIE4A))?OCR4A:255);
|
||||
#endif //EXTRUDER_0_AUTO_FAN_PIN
|
||||
OCR4A = 255;
|
||||
// Disable Output compare A interrupt and timer overflow interrupt
|
||||
TIMSK4 &= ~((1 << OCIE4A) | (1 << TOIE4));
|
||||
CRITICAL_SECTION_END;
|
||||
// Turn beeper off if it was on when noTone was called
|
||||
WRITE(BEEPER, 0);
|
||||
}
|
||||
|
||||
|
||||
#endif //SYSTEM_TIMER_2
|
25
Firmware/tone04.h
Normal file
25
Firmware/tone04.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
//tone04.h
|
||||
// use atmega timer4 as main tone timer instead of timer2
|
||||
// timer2 is used for System timer.
|
||||
#ifndef TIMER04_H
|
||||
#define TIMER04_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif //defined(__cplusplus)
|
||||
|
||||
extern void timer4_init(void);
|
||||
|
||||
extern void timer4_set_fan0(uint8_t duty);
|
||||
|
||||
extern void tone4(uint8_t _pin, uint16_t frequency);
|
||||
|
||||
extern void noTone4(uint8_t _pin);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif //defined(__cplusplus)
|
||||
|
||||
#endif //TIMER02_H
|
|
@ -818,6 +818,36 @@ void lcd_status_screen() // NOT static due to using ins
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ULTIPANEL_FEEDMULTIPLY
|
||||
// Dead zone at 100% feedrate
|
||||
if ((feedmultiply < 100 && (feedmultiply + int(lcd_encoder)) > 100) ||
|
||||
(feedmultiply > 100 && (feedmultiply + int(lcd_encoder)) < 100))
|
||||
{
|
||||
lcd_encoder = 0;
|
||||
feedmultiply = 100;
|
||||
}
|
||||
if (feedmultiply == 100 && int(lcd_encoder) > ENCODER_FEEDRATE_DEADZONE)
|
||||
{
|
||||
feedmultiply += int(lcd_encoder) - ENCODER_FEEDRATE_DEADZONE;
|
||||
lcd_encoder = 0;
|
||||
}
|
||||
else if (feedmultiply == 100 && int(lcd_encoder) < -ENCODER_FEEDRATE_DEADZONE)
|
||||
{
|
||||
feedmultiply += int(lcd_encoder) + ENCODER_FEEDRATE_DEADZONE;
|
||||
lcd_encoder = 0;
|
||||
}
|
||||
else if (feedmultiply != 100)
|
||||
{
|
||||
feedmultiply += int(lcd_encoder);
|
||||
lcd_encoder = 0;
|
||||
}
|
||||
#endif //ULTIPANEL_FEEDMULTIPLY
|
||||
|
||||
if (feedmultiply < 10)
|
||||
feedmultiply = 10;
|
||||
else if (feedmultiply > 999)
|
||||
feedmultiply = 999;
|
||||
|
||||
if (lcd_status_update_delay)
|
||||
lcd_status_update_delay--;
|
||||
else
|
||||
|
@ -894,36 +924,6 @@ void lcd_status_screen() // NOT static due to using ins
|
|||
menu_submenu(lcd_main_menu);
|
||||
lcd_refresh(); // to maybe revive the LCD if static electricity killed it.
|
||||
}
|
||||
|
||||
#ifdef ULTIPANEL_FEEDMULTIPLY
|
||||
// Dead zone at 100% feedrate
|
||||
if ((feedmultiply < 100 && (feedmultiply + int(lcd_encoder)) > 100) ||
|
||||
(feedmultiply > 100 && (feedmultiply + int(lcd_encoder)) < 100))
|
||||
{
|
||||
lcd_encoder = 0;
|
||||
feedmultiply = 100;
|
||||
}
|
||||
if (feedmultiply == 100 && int(lcd_encoder) > ENCODER_FEEDRATE_DEADZONE)
|
||||
{
|
||||
feedmultiply += int(lcd_encoder) - ENCODER_FEEDRATE_DEADZONE;
|
||||
lcd_encoder = 0;
|
||||
}
|
||||
else if (feedmultiply == 100 && int(lcd_encoder) < -ENCODER_FEEDRATE_DEADZONE)
|
||||
{
|
||||
feedmultiply += int(lcd_encoder) + ENCODER_FEEDRATE_DEADZONE;
|
||||
lcd_encoder = 0;
|
||||
}
|
||||
else if (feedmultiply != 100)
|
||||
{
|
||||
feedmultiply += int(lcd_encoder);
|
||||
lcd_encoder = 0;
|
||||
}
|
||||
#endif //ULTIPANEL_FEEDMULTIPLY
|
||||
|
||||
if (feedmultiply < 10)
|
||||
feedmultiply = 10;
|
||||
else if (feedmultiply > 999)
|
||||
feedmultiply = 999;
|
||||
}
|
||||
|
||||
void lcd_commands()
|
||||
|
@ -1943,6 +1943,7 @@ static void lcd_support_menu()
|
|||
sprintf_P(_md->ip_str, PSTR("%d.%d.%d.%d"),
|
||||
_md->ip[0], _md->ip[1],
|
||||
_md->ip[2], _md->ip[3]);
|
||||
|
||||
} else if (_md->is_flash_air &&
|
||||
_md->ip[0] == 0 && _md->ip[1] == 0 &&
|
||||
_md->ip[2] == 0 && _md->ip[3] == 0 &&
|
||||
|
@ -1983,18 +1984,7 @@ static void lcd_support_menu()
|
|||
#ifdef IR_SENSOR_ANALOG
|
||||
MENU_ITEM_BACK_P(STR_SEPARATOR);
|
||||
MENU_ITEM_BACK_P(PSTR("Fil. sensor v.:"));
|
||||
switch(oFsensorPCB)
|
||||
{
|
||||
case ClFsensorPCB::_Old:
|
||||
MENU_ITEM_BACK_P(_T(MSG_03_OR_OLDER));
|
||||
break;
|
||||
case ClFsensorPCB::_Rev04:
|
||||
MENU_ITEM_BACK_P(_T(MSG_04_OR_NEWER));
|
||||
break;
|
||||
case ClFsensorPCB::_Undef:
|
||||
default:
|
||||
MENU_ITEM_BACK_P(PSTR(" unknown state"));
|
||||
}
|
||||
MENU_ITEM_BACK_P(FsensorIRVersionText());
|
||||
#endif // IR_SENSOR_ANALOG
|
||||
|
||||
MENU_ITEM_BACK_P(STR_SEPARATOR);
|
||||
|
@ -2038,6 +2028,7 @@ static void lcd_support_menu()
|
|||
MENU_ITEM_SUBMENU_P(_i("Voltages"), lcd_menu_voltages);////MSG_MENU_VOLTAGES c=18 r=1
|
||||
#endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN
|
||||
|
||||
|
||||
#ifdef DEBUG_BUILD
|
||||
MENU_ITEM_SUBMENU_P(PSTR("Debug"), lcd_menu_debug);////c=18 r=1
|
||||
#endif /* DEBUG_BUILD */
|
||||
|
@ -2324,6 +2315,12 @@ static void mFilamentItem_ASA()
|
|||
mFilamentItem(ASA_PREHEAT_HOTEND_TEMP, ASA_PREHEAT_HPB_TEMP);
|
||||
}
|
||||
|
||||
static void mFilamentItem_PC()
|
||||
{
|
||||
bFilamentPreheatState = false;
|
||||
mFilamentItem(PC_PREHEAT_HOTEND_TEMP, PC_PREHEAT_HPB_TEMP);
|
||||
}
|
||||
|
||||
static void mFilamentItem_ABS()
|
||||
{
|
||||
bFilamentPreheatState = false;
|
||||
|
@ -2383,6 +2380,7 @@ void lcd_generic_preheat_menu()
|
|||
MENU_ITEM_SUBMENU_P(PSTR("PLA - " STRINGIFY(PLA_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PLA_PREHEAT_HPB_TEMP)),mFilamentItem_PLA);
|
||||
MENU_ITEM_SUBMENU_P(PSTR("PET - " STRINGIFY(PET_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PET_PREHEAT_HPB_TEMP)),mFilamentItem_PET);
|
||||
MENU_ITEM_SUBMENU_P(PSTR("ASA - " STRINGIFY(ASA_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(ASA_PREHEAT_HPB_TEMP)),mFilamentItem_ASA);
|
||||
MENU_ITEM_SUBMENU_P(PSTR("PC - " STRINGIFY(PC_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PC_PREHEAT_HPB_TEMP)),mFilamentItem_PC);
|
||||
MENU_ITEM_SUBMENU_P(PSTR("ABS - " STRINGIFY(ABS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(ABS_PREHEAT_HPB_TEMP)),mFilamentItem_ABS);
|
||||
MENU_ITEM_SUBMENU_P(PSTR("HIPS - " STRINGIFY(HIPS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(HIPS_PREHEAT_HPB_TEMP)),mFilamentItem_HIPS);
|
||||
MENU_ITEM_SUBMENU_P(PSTR("PP - " STRINGIFY(PP_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PP_PREHEAT_HPB_TEMP)),mFilamentItem_PP);
|
||||
|
@ -2736,7 +2734,7 @@ static void _lcd_move(const char *name, int axis, int min, int max)
|
|||
if (max_software_endstops && current_position[axis] > max) current_position[axis] = max;
|
||||
lcd_encoder = 0;
|
||||
world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[axis] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[axis] / 60);
|
||||
lcd_draw_update = 1;
|
||||
}
|
||||
}
|
||||
|
@ -2761,7 +2759,7 @@ static void lcd_move_e()
|
|||
{
|
||||
current_position[E_AXIS] += float((int)lcd_encoder) * move_menu_scale;
|
||||
lcd_encoder = 0;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[E_AXIS] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[E_AXIS] / 60);
|
||||
lcd_draw_update = 1;
|
||||
}
|
||||
}
|
||||
|
@ -3279,7 +3277,7 @@ bool lcd_calibrate_z_end_stop_manual(bool only_z)
|
|||
{
|
||||
// Don't know where we are. Let's claim we are Z=0, so the soft end stops will not be triggered when moving up.
|
||||
current_position[Z_AXIS] = 0;
|
||||
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
||||
plan_set_position_curposXYZE();
|
||||
|
||||
// Until confirmed by the confirmation dialog.
|
||||
for (;;) {
|
||||
|
@ -3301,7 +3299,7 @@ bool lcd_calibrate_z_end_stop_manual(bool only_z)
|
|||
// Only move up, whatever direction the user rotates the encoder.
|
||||
current_position[Z_AXIS] += fabs(lcd_encoder);
|
||||
lcd_encoder = 0;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[Z_AXIS] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[Z_AXIS] / 60);
|
||||
}
|
||||
}
|
||||
if (lcd_clicked()) {
|
||||
|
@ -3337,7 +3335,7 @@ calibrated:
|
|||
else {
|
||||
current_position[Z_AXIS] = Z_MAX_POS+4.f;
|
||||
}
|
||||
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
||||
plan_set_position_curposXYZE();
|
||||
return true;
|
||||
|
||||
canceled:
|
||||
|
@ -3741,14 +3739,12 @@ void lcd_temp_cal_show_result(bool result) {
|
|||
eeprom_update_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 1);
|
||||
SERIAL_ECHOLNPGM("Temperature calibration done. Continue with pressing the knob.");
|
||||
lcd_show_fullscreen_message_and_wait_P(_T(MSG_TEMP_CALIBRATION_DONE));
|
||||
temp_cal_active = true;
|
||||
eeprom_update_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE, 1);
|
||||
}
|
||||
else {
|
||||
eeprom_update_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 0);
|
||||
SERIAL_ECHOLNPGM("Temperature calibration failed. Continue with pressing the knob.");
|
||||
lcd_show_fullscreen_message_and_wait_P(_i("Temperature calibration failed"));////MSG_TEMP_CAL_FAILED c=20 r=8
|
||||
temp_cal_active = false;
|
||||
eeprom_update_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE, 0);
|
||||
}
|
||||
lcd_update_enable(true);
|
||||
|
@ -3855,7 +3851,7 @@ void prusa_statistics_err(char c){
|
|||
}
|
||||
|
||||
static void prusa_statistics_case0(uint8_t statnr){
|
||||
SERIAL_ECHO("{");
|
||||
SERIAL_ECHO('{');
|
||||
prusa_stat_printerstatus(statnr);
|
||||
prusa_stat_farm_number();
|
||||
prusa_stat_printinfo();
|
||||
|
@ -3883,7 +3879,7 @@ void prusa_statistics(int _message, uint8_t _fil_nr) {
|
|||
}
|
||||
else
|
||||
{
|
||||
SERIAL_ECHO("{");
|
||||
SERIAL_ECHO('{');
|
||||
prusa_stat_printerstatus(1);
|
||||
prusa_stat_farm_number();
|
||||
prusa_stat_diameter();
|
||||
|
@ -4449,9 +4445,9 @@ void lcd_pinda_calibration_menu()
|
|||
}
|
||||
|
||||
void lcd_temp_calibration_set() {
|
||||
bool temp_cal_active = eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE);
|
||||
temp_cal_active = !temp_cal_active;
|
||||
eeprom_update_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE, temp_cal_active);
|
||||
st_current_init();
|
||||
}
|
||||
|
||||
#ifdef HAS_SECOND_SERIAL_PORT
|
||||
|
@ -4709,7 +4705,7 @@ void lcd_language()
|
|||
static void wait_preheat()
|
||||
{
|
||||
current_position[Z_AXIS] = 100; //move in z axis to make space for loading filament
|
||||
plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60);
|
||||
delay_keep_alive(2000);
|
||||
lcd_display_message_fullscreen_P(_T(MSG_WIZARD_HEATING));
|
||||
lcd_set_custom_characters();
|
||||
|
@ -5416,6 +5412,7 @@ do\
|
|||
}\
|
||||
while (0)
|
||||
|
||||
#if 0 // temporarily unused
|
||||
static void lcd_check_gcode_set(void)
|
||||
{
|
||||
switch(oCheckGcode)
|
||||
|
@ -5434,6 +5431,7 @@ switch(oCheckGcode)
|
|||
}
|
||||
eeprom_update_byte((uint8_t*)EEPROM_CHECK_GCODE,(uint8_t)oCheckGcode);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SETTINGS_GCODE \
|
||||
do\
|
||||
|
@ -5526,6 +5524,25 @@ static void sheets_menu()
|
|||
|
||||
void lcd_hw_setup_menu(void) // can not be "static"
|
||||
{
|
||||
typedef struct
|
||||
{// 2bytes total
|
||||
int8_t status;
|
||||
uint8_t experimental_menu_visibility;
|
||||
} _menu_data_t;
|
||||
static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data");
|
||||
_menu_data_t* _md = (_menu_data_t*)&(menu_data[0]);
|
||||
|
||||
if (_md->status == 0 || lcd_draw_update)
|
||||
{
|
||||
_md->experimental_menu_visibility = eeprom_read_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY);
|
||||
if (_md->experimental_menu_visibility == EEPROM_EMPTY_VALUE)
|
||||
{
|
||||
_md->experimental_menu_visibility = 0;
|
||||
eeprom_update_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY, _md->experimental_menu_visibility);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MENU_BEGIN();
|
||||
MENU_ITEM_BACK_P(_T(bSettings?MSG_SETTINGS:MSG_BACK)); // i.e. default menu-item / menu-item after checking mismatch
|
||||
|
||||
|
@ -5535,8 +5552,16 @@ void lcd_hw_setup_menu(void) // can not be "static"
|
|||
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
FSENSOR_ACTION_NA;
|
||||
MENU_ITEM_FUNCTION_P(PSTR("Fsensor Detection"), lcd_detect_IRsensor);
|
||||
//! Fsensor Detection isn't ready for mmu yet it is temporarily disabled.
|
||||
//! @todo Don't forget to remove this as soon Fsensor Detection works with mmu
|
||||
if(!mmu_enabled) MENU_ITEM_FUNCTION_P(PSTR("Fsensor Detection"), lcd_detect_IRsensor);
|
||||
#endif //IR_SENSOR_ANALOG
|
||||
|
||||
if (_md->experimental_menu_visibility)
|
||||
{
|
||||
MENU_ITEM_SUBMENU_P(PSTR("Experimental"), lcd_experimental_menu);////MSG_MENU_EXPERIMENTAL c=18
|
||||
}
|
||||
|
||||
MENU_END();
|
||||
}
|
||||
|
||||
|
@ -5575,8 +5600,10 @@ static void lcd_settings_menu()
|
|||
#if defined (TMC2130) && defined (LINEARITY_CORRECTION)
|
||||
MENU_ITEM_SUBMENU_P(_i("Lin. correction"), lcd_settings_linearity_correction_menu);
|
||||
#endif //LINEARITY_CORRECTION && TMC2130
|
||||
|
||||
MENU_ITEM_TOGGLE_P(_T(MSG_TEMP_CALIBRATION), temp_cal_active ? _T(MSG_ON) : _T(MSG_OFF), lcd_temp_calibration_set);
|
||||
if(has_temperature_compensation())
|
||||
{
|
||||
MENU_ITEM_TOGGLE_P(_T(MSG_TEMP_CALIBRATION), eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE) ? _T(MSG_ON) : _T(MSG_OFF), lcd_temp_calibration_set);
|
||||
}
|
||||
|
||||
#ifdef HAS_SECOND_SERIAL_PORT
|
||||
MENU_ITEM_TOGGLE_P(_T(MSG_RPI_PORT), (selectedSerialPort == 0) ? _T(MSG_OFF) : _T(MSG_ON), lcd_second_serial_set);
|
||||
|
@ -5680,7 +5707,10 @@ static void lcd_calibration_menu()
|
|||
//MENU_ITEM_FUNCTION_P(MSG_RESET_CALIBRATE_E, lcd_extr_cal_reset);
|
||||
#endif
|
||||
#ifndef MK1BP
|
||||
MENU_ITEM_SUBMENU_P(_i("Temp. calibration"), lcd_pinda_calibration_menu);////MSG_CALIBRATION_PINDA_MENU c=17 r=1
|
||||
if(has_temperature_compensation())
|
||||
{
|
||||
MENU_ITEM_SUBMENU_P(_i("Temp. calibration"), lcd_pinda_calibration_menu);////MSG_CALIBRATION_PINDA_MENU c=17 r=1
|
||||
}
|
||||
#endif //MK1BP
|
||||
}
|
||||
|
||||
|
@ -6197,13 +6227,13 @@ void unload_filament()
|
|||
// extr_unload2();
|
||||
|
||||
current_position[E_AXIS] -= 45;
|
||||
plan_buffer_line_curposXYZE(5200 / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(5200 / 60);
|
||||
st_synchronize();
|
||||
current_position[E_AXIS] -= 15;
|
||||
plan_buffer_line_curposXYZE(1000 / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(1000 / 60);
|
||||
st_synchronize();
|
||||
current_position[E_AXIS] -= 20;
|
||||
plan_buffer_line_curposXYZE(1000 / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(1000 / 60);
|
||||
st_synchronize();
|
||||
|
||||
lcd_display_message_fullscreen_P(_T(MSG_PULL_OUT_FILAMENT));
|
||||
|
@ -6483,7 +6513,7 @@ static bool fan_error_selftest()
|
|||
fanSpeedSoftPwm = 255;
|
||||
#endif //FAN_SOFT_PWM
|
||||
manage_heater(); //enables print fan
|
||||
setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, 1); //force enables the extruder fan untill the first manage_heater() call.
|
||||
setExtruderAutoFanState(3); //force enables the extruder fan
|
||||
#ifdef FAN_SOFT_PWM
|
||||
extruder_autofan_last_check = _millis();
|
||||
fan_measuring = true;
|
||||
|
@ -6491,6 +6521,7 @@ static bool fan_error_selftest()
|
|||
_delay(1000); //delay_keep_alive would turn off extruder fan, because temerature is too low (maybe)
|
||||
manage_heater();
|
||||
fanSpeed = 0;
|
||||
setExtruderAutoFanState(1); //releases lock on the extruder fan
|
||||
#ifdef FAN_SOFT_PWM
|
||||
fanSpeedSoftPwm = 0;
|
||||
#endif //FAN_SOFT_PWM
|
||||
|
@ -7171,13 +7202,13 @@ void lcd_print_stop()
|
|||
cancel_heatup = true; //unroll temperature wait loop stack.
|
||||
|
||||
current_position[Z_AXIS] += 10; //lift Z.
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[Z_AXIS] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[Z_AXIS] / 60);
|
||||
|
||||
if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS]) //if axis are homed, move to parked position.
|
||||
{
|
||||
current_position[X_AXIS] = X_CANCEL_POS;
|
||||
current_position[Y_AXIS] = Y_CANCEL_POS;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
}
|
||||
st_synchronize();
|
||||
|
||||
|
@ -7399,8 +7430,8 @@ void lcd_belttest()
|
|||
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
// called also from marlin_main.cpp
|
||||
void printf_IRSensorAnalogBoardChange(bool bPCBrev04){
|
||||
printf_P(PSTR("Filament sensor board change detected: revision%S\n"), bPCBrev04 ? _T(MSG_04_OR_NEWER) : _T(MSG_03_OR_OLDER));
|
||||
void printf_IRSensorAnalogBoardChange(){
|
||||
printf_P(PSTR("Filament sensor board change detected: revision%S\n"), FsensorIRVersionText());
|
||||
}
|
||||
|
||||
static bool lcd_selftest_IRsensor(bool bStandalone)
|
||||
|
@ -7425,8 +7456,8 @@ static bool lcd_selftest_IRsensor(bool bStandalone)
|
|||
return(false);
|
||||
}
|
||||
if((bPCBrev04 ? 1 : 0) != (uint8_t)oFsensorPCB){ // safer then "(uint8_t)bPCBrev04"
|
||||
printf_IRSensorAnalogBoardChange(bPCBrev04);
|
||||
oFsensorPCB=bPCBrev04 ? ClFsensorPCB::_Rev04 : ClFsensorPCB::_Old;
|
||||
printf_IRSensorAnalogBoardChange();
|
||||
eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB);
|
||||
}
|
||||
return(true);
|
||||
|
@ -7434,22 +7465,26 @@ static bool lcd_selftest_IRsensor(bool bStandalone)
|
|||
|
||||
static void lcd_detect_IRsensor(){
|
||||
bool bAction;
|
||||
|
||||
bool loaded;
|
||||
bMenuFSDetect = true; // inhibits some code inside "manage_inactivity()"
|
||||
bAction = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Is filament loaded?"), false, false);
|
||||
if(bAction){
|
||||
lcd_show_fullscreen_message_and_wait_P(_i("Please unload the filament first, then repeat this action."));////c=20 r=4
|
||||
/// Check if filament is loaded. If it is loaded stop detection.
|
||||
/// @todo Add autodetection with MMU2s
|
||||
loaded = ! READ(IR_SENSOR_PIN);
|
||||
if(loaded ){
|
||||
lcd_show_fullscreen_message_and_wait_P(_i("Please unload the filament first, then repeat this action."));
|
||||
return;
|
||||
} else {
|
||||
lcd_show_fullscreen_message_and_wait_P(_i("Please check the IR sensor connections and filament is unloaded."));
|
||||
bAction = lcd_selftest_IRsensor(true);
|
||||
}
|
||||
bAction = lcd_selftest_IRsensor(true);
|
||||
if(bAction){
|
||||
if(bAction){
|
||||
lcd_show_fullscreen_message_and_wait_P(_i("Sensor verified, remove the filament now."));////c=20 r=3
|
||||
// the fsensor board has been successfully identified, any previous "not responding" may be cleared now
|
||||
fsensor_not_responding = false;
|
||||
// the fsensor board has been successfully identified, any previous "not responding" may be cleared now
|
||||
fsensor_not_responding = false;
|
||||
} else {
|
||||
lcd_show_fullscreen_message_and_wait_P(_i("Verification failed, remove the filament and try again."));////c=20 r=5
|
||||
// here it is unclear what to to with the fsensor_not_responding flag
|
||||
}
|
||||
// here it is unclear what to to with the fsensor_not_responding flag
|
||||
}
|
||||
bMenuFSDetect=false; // de-inhibits some code inside "manage_inactivity()"
|
||||
}
|
||||
#endif //IR_SENSOR_ANALOG
|
||||
|
@ -7465,9 +7500,17 @@ bool lcd_selftest()
|
|||
bool _result = true;
|
||||
bool _swapped_fan = false;
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
//! Check if IR sensor is in unknown state, set it temporarily to 0.3 or older
|
||||
//! @todo This has to be improved
|
||||
if( oFsensorPCB == ClFsensorPCB::_Undef) eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,0);
|
||||
//! Check if IR sensor is in unknown state, if so run Fsensor Detection
|
||||
//! As the Fsensor Detection isn't yet ready for the mmu2s we set temporarily the IR sensor 0.3 or older for mmu2s
|
||||
//! @todo Don't forget to remove this as soon Fsensor Detection works with mmu
|
||||
if( oFsensorPCB == ClFsensorPCB::_Undef) {
|
||||
if (!mmu_enabled) {
|
||||
lcd_detect_IRsensor();
|
||||
}
|
||||
else {
|
||||
eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,0);
|
||||
}
|
||||
}
|
||||
#endif //IR_SENSOR_ANALOG
|
||||
lcd_wait_for_cool_down();
|
||||
lcd_clear();
|
||||
|
@ -7605,7 +7648,7 @@ bool lcd_selftest()
|
|||
current_position[Y_AXIS] += 4;
|
||||
#endif //TMC2130
|
||||
current_position[Z_AXIS] = current_position[Z_AXIS] + 10;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
st_synchronize();
|
||||
set_destination_to_current();
|
||||
_progress = lcd_selftest_screen(TestScreen::AxisZ, _progress, 3, true, 1500);
|
||||
|
@ -7617,7 +7660,7 @@ bool lcd_selftest()
|
|||
|
||||
//raise Z to not damage the bed during and hotend testing
|
||||
current_position[Z_AXIS] += 20;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
st_synchronize();
|
||||
}
|
||||
|
||||
|
@ -7625,7 +7668,7 @@ bool lcd_selftest()
|
|||
if (_result)
|
||||
{
|
||||
current_position[Z_AXIS] = current_position[Z_AXIS] + 10;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
st_synchronize();
|
||||
_progress = lcd_selftest_screen(TestScreen::Home, 0, 2, true, 0);
|
||||
bool bres = tmc2130_home_calibrate(X_AXIS);
|
||||
|
@ -7675,10 +7718,12 @@ bool lcd_selftest()
|
|||
_progress = lcd_selftest_screen(TestScreen::FsensorOk, _progress, 3, true, 2000); //fil sensor OK
|
||||
}
|
||||
#endif //PAT9125
|
||||
//#ifdef IR_SENSOR_ANALOG
|
||||
#if (0)
|
||||
#if 0
|
||||
// Intentionally disabled - that's why we moved the detection to runtime by just checking the two voltages.
|
||||
// The idea is not to force the user to remove and insert the filament on an assembled printer.
|
||||
//def IR_SENSOR_ANALOG
|
||||
_progress = lcd_selftest_screen(TestScreen::Fsensor, _progress, 3, true, 2000); //check filament sensor
|
||||
_result = lcd_selftest_IRsensor();
|
||||
_result = lcd_selftest_IRsensor();
|
||||
if (_result)
|
||||
{
|
||||
_progress = lcd_selftest_screen(TestScreen::FsensorOk, _progress, 3, true, 2000); //filament sensor OK
|
||||
|
@ -7721,7 +7766,7 @@ bool lcd_selftest()
|
|||
|
||||
static void reset_crash_det(unsigned char axis) {
|
||||
current_position[axis] += 10;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
st_synchronize();
|
||||
if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_DET)) tmc2130_sg_stop_on_crash = true;
|
||||
}
|
||||
|
@ -7750,7 +7795,7 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) {
|
|||
// first axis length measurement begin
|
||||
|
||||
current_position[axis] -= (axis_length + margin);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
|
||||
|
||||
st_synchronize();
|
||||
|
@ -7760,11 +7805,11 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) {
|
|||
current_position_init = st_get_position_mm(axis);
|
||||
|
||||
current_position[axis] += 2 * margin;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
st_synchronize();
|
||||
|
||||
current_position[axis] += axis_length;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
|
||||
st_synchronize();
|
||||
|
||||
|
@ -7780,11 +7825,11 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) {
|
|||
|
||||
|
||||
current_position[axis] -= margin;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
st_synchronize();
|
||||
|
||||
current_position[axis] -= (axis_length + margin);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
|
||||
st_synchronize();
|
||||
|
||||
|
@ -7809,7 +7854,7 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) {
|
|||
|
||||
lcd_selftest_error(TestError::Axis, _error_1, "");
|
||||
current_position[axis] = 0;
|
||||
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
||||
plan_set_position_curposXYZE();
|
||||
reset_crash_det(axis);
|
||||
enable_endstops(true);
|
||||
endstops_hit_on_purpose();
|
||||
|
@ -7829,13 +7874,13 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) {
|
|||
|
||||
lcd_selftest_error(TestError::Pulley, _error_1, "");
|
||||
current_position[axis] = 0;
|
||||
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
||||
plan_set_position_curposXYZE();
|
||||
reset_crash_det(axis);
|
||||
endstops_hit_on_purpose();
|
||||
return false;
|
||||
}
|
||||
current_position[axis] = 0;
|
||||
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
||||
plan_set_position_curposXYZE();
|
||||
reset_crash_det(axis);
|
||||
endstops_hit_on_purpose();
|
||||
return true;
|
||||
|
@ -7857,13 +7902,13 @@ static bool lcd_selfcheck_axis(int _axis, int _travel)
|
|||
|
||||
if (_axis == X_AXIS) {
|
||||
current_position[Z_AXIS] += 17;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
}
|
||||
|
||||
do {
|
||||
current_position[_axis] = current_position[_axis] - 1;
|
||||
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
st_synchronize();
|
||||
#ifdef TMC2130
|
||||
if ((READ(Z_MIN_PIN) ^ (bool)Z_MIN_ENDSTOP_INVERTING))
|
||||
|
@ -7943,7 +7988,7 @@ static bool lcd_selfcheck_axis(int _axis, int _travel)
|
|||
}
|
||||
}
|
||||
current_position[_axis] = 0; //simulate axis home to avoid negative numbers for axis position, especially Z.
|
||||
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
||||
plan_set_position_curposXYZE();
|
||||
|
||||
return _stepresult;
|
||||
}
|
||||
|
@ -7966,17 +8011,17 @@ static bool lcd_selfcheck_pulleys(int axis)
|
|||
current_position_init = current_position[axis];
|
||||
|
||||
current_position[axis] += 2;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
for (i = 0; i < 5; i++) {
|
||||
refresh_cmd_timeout();
|
||||
current_position[axis] = current_position[axis] + move;
|
||||
st_current_set(0, 850); //set motor current higher
|
||||
plan_buffer_line_curposXYZE(200, active_extruder);
|
||||
plan_buffer_line_curposXYZE(200);
|
||||
st_synchronize();
|
||||
if (SilentModeMenu != SILENT_MODE_OFF) st_current_set(0, tmp_motor[0]); //set back to normal operation currents
|
||||
else st_current_set(0, tmp_motor_loud[0]); //set motor current back
|
||||
current_position[axis] = current_position[axis] - move;
|
||||
plan_buffer_line_curposXYZE(50, active_extruder);
|
||||
plan_buffer_line_curposXYZE(50);
|
||||
st_synchronize();
|
||||
if (((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) ||
|
||||
((READ(Y_MIN_PIN) ^ Y_MIN_ENDSTOP_INVERTING) == 1)) {
|
||||
|
@ -7993,7 +8038,7 @@ static bool lcd_selfcheck_pulleys(int axis)
|
|||
endstop_triggered = true;
|
||||
if (current_position_init - 1 <= current_position[axis] && current_position_init + 1 >= current_position[axis]) {
|
||||
current_position[axis] += 10;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
st_synchronize();
|
||||
return(true);
|
||||
}
|
||||
|
@ -8004,7 +8049,7 @@ static bool lcd_selfcheck_pulleys(int axis)
|
|||
}
|
||||
else {
|
||||
current_position[axis] -= 1;
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
st_synchronize();
|
||||
if (_millis() > timeout_counter) {
|
||||
lcd_selftest_error(TestError::Pulley, (axis == 0) ? "X" : "Y", "");
|
||||
|
@ -8034,7 +8079,7 @@ static bool lcd_selfcheck_endstops()
|
|||
#endif //!TMC2130
|
||||
if ((READ(Z_MIN_PIN) ^ Z_MIN_ENDSTOP_INVERTING) == 1) current_position[2] += 10;
|
||||
}
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
|
||||
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60);
|
||||
st_synchronize();
|
||||
|
||||
if (
|
||||
|
@ -8360,8 +8405,7 @@ static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite,
|
|||
lcd_set_cursor(0, 1);
|
||||
if(check_opposite == true) lcd_puts_P(_T(MSG_SELFTEST_COOLING_FAN));
|
||||
else lcd_puts_P(_T(MSG_SELFTEST_EXTRUDER_FAN));
|
||||
SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN);
|
||||
WRITE(EXTRUDER_0_AUTO_FAN_PIN, 1);
|
||||
setExtruderAutoFanState(3);
|
||||
break;
|
||||
case 1:
|
||||
// object cooling fan
|
||||
|
@ -8390,23 +8434,6 @@ static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite,
|
|||
lcd_button_pressed = false;
|
||||
do
|
||||
{
|
||||
switch (_fan)
|
||||
{
|
||||
case 0:
|
||||
// extruder cooling fan
|
||||
SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN);
|
||||
WRITE(EXTRUDER_0_AUTO_FAN_PIN, 1);
|
||||
break;
|
||||
case 1:
|
||||
// object cooling fan
|
||||
SET_OUTPUT(FAN_PIN);
|
||||
#ifdef FAN_SOFT_PWM
|
||||
fanSpeedSoftPwm = 255;
|
||||
#else //FAN_SOFT_PWM
|
||||
analogWrite(FAN_PIN, 255);
|
||||
#endif //FAN_SOFT_PWM
|
||||
break;
|
||||
}
|
||||
if (abs((enc_dif - lcd_encoder_diff)) > 2) {
|
||||
if (enc_dif > lcd_encoder_diff) {
|
||||
_result = !check_opposite;
|
||||
|
@ -8433,8 +8460,7 @@ static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite,
|
|||
|
||||
} while (!lcd_clicked());
|
||||
KEEPALIVE_STATE(IN_HANDLER);
|
||||
SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN);
|
||||
WRITE(EXTRUDER_0_AUTO_FAN_PIN, 0);
|
||||
setExtruderAutoFanState(0);
|
||||
SET_OUTPUT(FAN_PIN);
|
||||
#ifdef FAN_SOFT_PWM
|
||||
fanSpeedSoftPwm = 0;
|
||||
|
@ -8454,20 +8480,20 @@ static FanCheck lcd_selftest_fan_auto(int _fan)
|
|||
case 0:
|
||||
fanSpeed = 0;
|
||||
manage_heater(); //turn off fan
|
||||
setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, 1); //extruder fan
|
||||
setExtruderAutoFanState(3); //extruder fan
|
||||
#ifdef FAN_SOFT_PWM
|
||||
extruder_autofan_last_check = _millis();
|
||||
fan_measuring = true;
|
||||
#endif //FAN_SOFT_PWM
|
||||
_delay(2000); //delay_keep_alive would turn off extruder fan, because temerature is too low
|
||||
|
||||
_delay(2000);
|
||||
setExtruderAutoFanState(0); //extruder fan
|
||||
manage_heater(); //count average fan speed from 2s delay and turn off fans
|
||||
|
||||
printf_P(PSTR("Test 1:\n"));
|
||||
printf_P(PSTR("Print fan speed: %d \n"), fan_speed[1]);
|
||||
printf_P(PSTR("Extr fan speed: %d \n"), fan_speed[0]);
|
||||
|
||||
if (!fan_speed[0]) {
|
||||
if (fan_speed[0] < 20) { // < 1200 RPM would mean either a faulty Noctua or Altfan
|
||||
return FanCheck::ExtruderFan;
|
||||
}
|
||||
#ifdef FAN_SOFT_PWM
|
||||
|
@ -8545,7 +8571,7 @@ static FanCheck lcd_selftest_fan_auto(int _fan)
|
|||
static int lcd_selftest_screen(TestScreen screen, int _progress, int _progress_scale, bool _clear, int _delay)
|
||||
{
|
||||
|
||||
lcd_update_enable(false);
|
||||
lcd_update_enable(false);
|
||||
|
||||
const char *_indicator = (_progress >= _progress_scale) ? "-" : "|";
|
||||
|
||||
|
@ -8593,7 +8619,7 @@ static int lcd_selftest_screen(TestScreen screen, int _progress, int _progress_s
|
|||
{
|
||||
//SERIAL_ECHOLNPGM("Other tests");
|
||||
|
||||
TestScreen _step_block = TestScreen::AxisX;
|
||||
TestScreen _step_block = TestScreen::AxisX;
|
||||
lcd_selftest_screen_step(2, 2, ((screen == _step_block) ? 1 : (screen < _step_block) ? 0 : 2), "X", _indicator);
|
||||
|
||||
_step_block = TestScreen::AxisY;
|
||||
|
@ -8605,8 +8631,8 @@ static int lcd_selftest_screen(TestScreen screen, int _progress, int _progress_s
|
|||
_step_block = TestScreen::Bed;
|
||||
lcd_selftest_screen_step(3, 0, ((screen == _step_block) ? 1 : (screen < _step_block) ? 0 : 2), "Bed", _indicator);
|
||||
|
||||
_step_block = TestScreen::Hotend;
|
||||
lcd_selftest_screen_step(3, 9, ((screen == _step_block) ? 1 : (screen < _step_block) ? 0 : 2), "Hotend", _indicator);
|
||||
_step_block = TestScreen::Hotend;
|
||||
lcd_selftest_screen_step(3, 9, ((screen == _step_block) ? 1 : (screen < _step_block) ? 0 : 2), "Hotend", _indicator);
|
||||
}
|
||||
|
||||
if (_delay > 0) delay_keep_alive(_delay);
|
||||
|
@ -8843,13 +8869,14 @@ void lcd_finishstatus() {
|
|||
lcd_draw_update = 2;
|
||||
|
||||
}
|
||||
|
||||
void lcd_setstatus(const char* message)
|
||||
{
|
||||
if (lcd_status_message_level > 0)
|
||||
return;
|
||||
strncpy(lcd_status_message, message, LCD_WIDTH);
|
||||
lcd_finishstatus();
|
||||
lcd_updatestatus(message);
|
||||
}
|
||||
|
||||
void lcd_updatestatuspgm(const char *message){
|
||||
strncpy_P(lcd_status_message, message, LCD_WIDTH);
|
||||
lcd_status_message[LCD_WIDTH] = 0;
|
||||
|
@ -8864,12 +8891,29 @@ void lcd_setstatuspgm(const char* message)
|
|||
return;
|
||||
lcd_updatestatuspgm(message);
|
||||
}
|
||||
|
||||
void lcd_updatestatus(const char *message){
|
||||
strncpy(lcd_status_message, message, LCD_WIDTH);
|
||||
lcd_status_message[LCD_WIDTH] = 0;
|
||||
lcd_finishstatus();
|
||||
// hack lcd_draw_update to 1, i.e. without clear
|
||||
lcd_draw_update = 1;
|
||||
}
|
||||
|
||||
void lcd_setalertstatuspgm(const char* message)
|
||||
{
|
||||
lcd_setstatuspgm(message);
|
||||
lcd_status_message_level = 1;
|
||||
lcd_return_to_status();
|
||||
}
|
||||
|
||||
void lcd_setalertstatus(const char* message)
|
||||
{
|
||||
lcd_setstatus(message);
|
||||
lcd_status_message_level = 1;
|
||||
lcd_return_to_status();
|
||||
}
|
||||
|
||||
void lcd_reset_alert_level()
|
||||
{
|
||||
lcd_status_message_level = 0;
|
||||
|
@ -8889,6 +8933,13 @@ void menu_lcd_longpress_func(void)
|
|||
lcd_quick_feedback();
|
||||
return;
|
||||
}
|
||||
if (menu_menu == lcd_hw_setup_menu)
|
||||
{
|
||||
// only toggle the experimental menu visibility flag
|
||||
lcd_quick_feedback();
|
||||
lcd_experimental_toggle();
|
||||
return;
|
||||
}
|
||||
|
||||
// explicitely listed menus which are allowed to rise the move-z or live-adj-z functions
|
||||
// The lists are not the same for both functions, so first decide which function is to be performed
|
||||
|
@ -9052,3 +9103,25 @@ void lcd_crash_detect_disable()
|
|||
eeprom_update_byte((uint8_t*)EEPROM_CRASH_DET, 0x00);
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcd_experimental_toggle()
|
||||
{
|
||||
uint8_t oldVal = eeprom_read_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY);
|
||||
if (oldVal == EEPROM_EMPTY_VALUE)
|
||||
oldVal = 0;
|
||||
else
|
||||
oldVal = !oldVal;
|
||||
eeprom_update_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY, oldVal);
|
||||
}
|
||||
|
||||
void lcd_experimental_menu()
|
||||
{
|
||||
MENU_BEGIN();
|
||||
MENU_ITEM_BACK_P(_T(MSG_BACK));
|
||||
|
||||
#ifdef EXTRUDER_ALTFAN_DETECT
|
||||
MENU_ITEM_TOGGLE_P(_N("ALTFAN det."), altfanOverride_get()?_T(MSG_OFF):_T(MSG_ON), altfanOverride_toggle);////MSG_MENU_ALTFAN c=18
|
||||
#endif //EXTRUDER_ALTFAN_DETECT
|
||||
|
||||
MENU_END();
|
||||
}
|
||||
|
|
|
@ -23,9 +23,11 @@ void lcd_setstatuspgm(const char* message);
|
|||
//! - always returns the display to the main status screen
|
||||
//! - always makes lcd_reset (which is slow and causes flicker)
|
||||
//! - does not update the message if there is already one (i.e. lcd_status_message_level > 0)
|
||||
void lcd_setalertstatus(const char* message);
|
||||
void lcd_setalertstatuspgm(const char* message);
|
||||
//! only update the alert message on the main status screen
|
||||
//! has no sideeffects, may be called multiple times
|
||||
void lcd_updatestatus(const char *message);
|
||||
void lcd_updatestatuspgm(const char *message);
|
||||
|
||||
void lcd_reset_alert_level();
|
||||
|
@ -142,7 +144,7 @@ extern uint8_t farm_status;
|
|||
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
extern bool bMenuFSDetect;
|
||||
void printf_IRSensorAnalogBoardChange(bool bPCBrev04);
|
||||
void printf_IRSensorAnalogBoardChange();
|
||||
#endif //IR_SENSOR_ANALOG
|
||||
|
||||
extern int8_t SilentModeMenu;
|
||||
|
@ -256,21 +258,7 @@ enum class WizState : uint8_t
|
|||
|
||||
void lcd_wizard(WizState state);
|
||||
|
||||
#define VOLT_DIV_REF 5
|
||||
#ifdef IR_SENSOR_ANALOG
|
||||
constexpr uint16_t Voltage2Raw(float V){
|
||||
return ( V * 1023 * OVERSAMPLENR / VOLT_DIV_REF ) + 0.5F;
|
||||
}
|
||||
constexpr float Raw2Voltage(uint16_t raw){
|
||||
return VOLT_DIV_REF*(raw / (1023.F * OVERSAMPLENR) );
|
||||
}
|
||||
constexpr uint16_t IRsensor_Hmin_TRESHOLD = Voltage2Raw(3.0F); // ~3.0V (0.6*Vcc), raw value=9821
|
||||
constexpr uint16_t IRsensor_Lmax_TRESHOLD = Voltage2Raw(1.5F); // ~1.5V (0.3*Vcc), raw value=4910
|
||||
constexpr uint16_t IRsensor_Hopen_TRESHOLD = Voltage2Raw(4.6F); // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k), raw value=15059
|
||||
constexpr uint16_t IRsensor_Ldiode_TRESHOLD = Voltage2Raw(0.3F); // ~0.3V, raw value=982
|
||||
constexpr uint16_t IRsensor_VMax_TRESHOLD = Voltage2Raw(5.F); // ~5V, raw value=16368
|
||||
|
||||
|
||||
#endif //IR_SENSOR_ANALOG
|
||||
extern void lcd_experimental_toggle();
|
||||
extern void lcd_experimental_menu();
|
||||
|
||||
#endif //ULTRALCD_H
|
||||
|
|
|
@ -330,6 +330,10 @@ PREHEAT SETTINGS
|
|||
#define ASA_PREHEAT_HPB_TEMP 105
|
||||
#define ASA_PREHEAT_FAN_SPEED 0
|
||||
|
||||
#define PC_PREHEAT_HOTEND_TEMP 275
|
||||
#define PC_PREHEAT_HPB_TEMP 105
|
||||
#define PC_PREHEAT_FAN_SPEED 0
|
||||
|
||||
#define ABS_PREHEAT_HOTEND_TEMP 255
|
||||
#define ABS_PREHEAT_HPB_TEMP 100
|
||||
#define ABS_PREHEAT_FAN_SPEED 0
|
||||
|
|
|
@ -326,6 +326,9 @@ PREHEAT SETTINGS
|
|||
#define ASA_PREHEAT_HOTEND_TEMP 260
|
||||
#define ASA_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define PC_PREHEAT_HOTEND_TEMP 275
|
||||
#define PC_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define ABS_PREHEAT_HOTEND_TEMP 255
|
||||
#define ABS_PREHEAT_HPB_TEMP 100
|
||||
|
||||
|
|
|
@ -384,6 +384,9 @@
|
|||
#define ASA_PREHEAT_HOTEND_TEMP 260
|
||||
#define ASA_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define PC_PREHEAT_HOTEND_TEMP 275
|
||||
#define PC_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define ABS_PREHEAT_HOTEND_TEMP 255
|
||||
#define ABS_PREHEAT_HPB_TEMP 100
|
||||
|
||||
|
|
|
@ -385,6 +385,9 @@
|
|||
#define ASA_PREHEAT_HOTEND_TEMP 260
|
||||
#define ASA_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define PC_PREHEAT_HOTEND_TEMP 275
|
||||
#define PC_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define ABS_PREHEAT_HOTEND_TEMP 255
|
||||
#define ABS_PREHEAT_HPB_TEMP 100
|
||||
|
||||
|
|
|
@ -384,6 +384,9 @@
|
|||
#define ASA_PREHEAT_HOTEND_TEMP 260
|
||||
#define ASA_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define PC_PREHEAT_HOTEND_TEMP 275
|
||||
#define PC_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define ABS_PREHEAT_HOTEND_TEMP 255
|
||||
#define ABS_PREHEAT_HPB_TEMP 100
|
||||
|
||||
|
|
|
@ -385,6 +385,9 @@
|
|||
#define ASA_PREHEAT_HOTEND_TEMP 260
|
||||
#define ASA_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define PC_PREHEAT_HOTEND_TEMP 275
|
||||
#define PC_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define ABS_PREHEAT_HOTEND_TEMP 255
|
||||
#define ABS_PREHEAT_HPB_TEMP 100
|
||||
|
||||
|
|
|
@ -294,6 +294,9 @@
|
|||
#if BED_MINTEMP_DELAY>USHRT_MAX
|
||||
#error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)"
|
||||
#endif
|
||||
#define DETECT_SUPERPINDA
|
||||
#define PINDA_MINTEMP BED_MINTEMP
|
||||
#define AMBIENT_MINTEMP -30
|
||||
|
||||
// Maxtemps
|
||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||
|
@ -304,6 +307,7 @@
|
|||
#define HEATER_1_MAXTEMP 305
|
||||
#define HEATER_2_MAXTEMP 305
|
||||
#define BED_MAXTEMP 125
|
||||
#define AMBIENT_MAXTEMP 100
|
||||
|
||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||
// Define PID constants for extruder with PT100
|
||||
|
@ -496,6 +500,9 @@
|
|||
#define ASA_PREHEAT_HOTEND_TEMP 260
|
||||
#define ASA_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define PC_PREHEAT_HOTEND_TEMP 275
|
||||
#define PC_PREHEAT_HPB_TEMP 110
|
||||
|
||||
#define ABS_PREHEAT_HOTEND_TEMP 255
|
||||
#define ABS_PREHEAT_HPB_TEMP 100
|
||||
|
||||
|
|
|
@ -296,6 +296,9 @@
|
|||
#if BED_MINTEMP_DELAY>USHRT_MAX
|
||||
#error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)"
|
||||
#endif
|
||||
#define DETECT_SUPERPINDA
|
||||
#define PINDA_MINTEMP BED_MINTEMP
|
||||
#define AMBIENT_MINTEMP -30
|
||||
|
||||
// Maxtemps
|
||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||
|
@ -306,6 +309,7 @@
|
|||
#define HEATER_1_MAXTEMP 305
|
||||
#define HEATER_2_MAXTEMP 305
|
||||
#define BED_MAXTEMP 125
|
||||
#define AMBIENT_MAXTEMP 100
|
||||
|
||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||
// Define PID constants for extruder with PT100
|
||||
|
@ -331,6 +335,8 @@
|
|||
#define EXTRUDER_2_AUTO_FAN_PIN -1
|
||||
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
|
||||
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
|
||||
#define EXTRUDER_ALTFAN_DETECT
|
||||
#define EXTRUDER_ALTFAN_SPEED_SILENT 128
|
||||
|
||||
|
||||
|
||||
|
@ -498,6 +504,9 @@
|
|||
#define ASA_PREHEAT_HOTEND_TEMP 260
|
||||
#define ASA_PREHEAT_HPB_TEMP 105
|
||||
|
||||
#define PC_PREHEAT_HOTEND_TEMP 275
|
||||
#define PC_PREHEAT_HPB_TEMP 110
|
||||
|
||||
#define ABS_PREHEAT_HOTEND_TEMP 255
|
||||
#define ABS_PREHEAT_HPB_TEMP 100
|
||||
|
||||
|
|
22
README.md
22
README.md
|
@ -26,14 +26,28 @@ The firmware for the Original Prusa i3 printers is proudly based on [Marlin 1.0.
|
|||
|
||||
1. Clone this repository and checkout the correct branch for your desired release version.
|
||||
|
||||
2. Set your printer model.
|
||||
1. Set your printer model.
|
||||
- For MK3 --> skip to step 3.
|
||||
- If you have a different printer model, follow step [2.b](#2b) from Windows build
|
||||
1. Install GNU AWK `sudo apt-get install gawk`
|
||||
If you use mawk instead of gawk you get strange errors when multi language support is generated like:
|
||||
`awk: line 2: function strtonum never defined
|
||||
sed: couldn't write 4 items to stdout: Broken pipe
|
||||
./lang-build.sh: 121: ./lang-build.sh: arithmetic expression: expecting EOF: "0x"awk: line 2: function strtonum never defined
|
||||
sed: couldn't write 4 items to stdout: Broken pipe
|
||||
tr: write error: Broken pipe
|
||||
./lang-build.sh: 121: ./lang-build.sh: arithmetic expression: expecting EOF: "0x"awk: line 2: function strtonum never defined
|
||||
sed: couldn't write 4 items to stdout: Broken pipe
|
||||
tr: write error: Broken pipe
|
||||
tr: write error
|
||||
cut: write error: Broken pipeNG! - some texts not found in lang_en.txt! updating binary:
|
||||
primary language ids...awk: line 2: function strtonum never defined
|
||||
sed: couldn't flush stdout: Broken pipe`
|
||||
|
||||
3. Run `./build.sh`
|
||||
1. Run `./build.sh`
|
||||
- Output hex file is at `"PrusaFirmware/lang/firmware.hex"` . In the same folder you can hex files for other languages as well.
|
||||
|
||||
4. Connect your printer and flash with PrusaSlicer ( Configuration --> Flash printer firmware ) or Slic3r PE.
|
||||
1. Connect your printer and flash with PrusaSlicer ( Configuration --> Flash printer firmware ) or Slic3r PE.
|
||||
- If you wish to flash from Arduino, follow step [2.c](#2c) from Windows build first.
|
||||
|
||||
|
||||
|
@ -182,7 +196,7 @@ Example:
|
|||
|
||||
`ninja`
|
||||
|
||||
## Runing
|
||||
## Running
|
||||
`./tests`
|
||||
|
||||
# 4. Documentation
|
||||
|
|
Loading…
Add table
Reference in a new issue