Merge branch 'MK3' into PFW-873

This commit is contained in:
MRprusa3d 2019-07-10 16:50:14 +02:00 committed by GitHub
commit 98bae7af9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 919 additions and 567 deletions

View File

@ -1,6 +1,13 @@
dist: trusty dist: trusty
before_install: before_install:
- sudo apt-get install -y ninja-build - sudo apt-get install -y ninja-build
# Arduino IDE adds a lot of noise caused by network traffic, trying to firewall it off
- sudo iptables -P INPUT DROP
- sudo iptables -P FORWARD DROP
- sudo iptables -P OUTPUT ACCEPT
- sudo iptables -A INPUT -i lo -j ACCEPT
- sudo iptables -A OUTPUT -o lo -j ACCEPT
- sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
script: script:
- bash -x test.sh - bash -x test.sh
- cp Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h Firmware/Configuration_prusa.h - cp Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h Firmware/Configuration_prusa.h

View File

@ -16,8 +16,8 @@ extern uint16_t nPrinterType;
extern PGM_P sPrinterName; extern PGM_P sPrinterName;
// Firmware version // Firmware version
#define FW_VERSION "3.7.1" #define FW_VERSION "3.7.2-RC1"
#define FW_COMMIT_NR 2266 #define FW_COMMIT_NR 2359
// FW_VERSION_UNKNOWN means this is an unofficial build. // FW_VERSION_UNKNOWN means this is an unofficial build.
// The firmware should only be checked into github with this symbol. // The firmware should only be checked into github with this symbol.
#define FW_DEV_VERSION FW_VERSION_UNKNOWN #define FW_DEV_VERSION FW_VERSION_UNKNOWN

3
Firmware/Marlin.h Normal file → Executable file
View File

@ -323,7 +323,6 @@ extern float retract_recover_length_swap;
extern uint8_t host_keepalive_interval; extern uint8_t host_keepalive_interval;
extern unsigned long starttime; extern unsigned long starttime;
extern unsigned long stoptime; extern unsigned long stoptime;
extern int bowden_length[4]; extern int bowden_length[4];
@ -392,7 +391,7 @@ extern bool wizard_active; //autoload temporarily disabled during wizard
extern LongTimer safetyTimer; extern LongTimer safetyTimer;
#define PRINT_PERCENT_DONE_INIT 0xff #define PRINT_PERCENT_DONE_INIT 0xff
#define PRINTER_ACTIVE (IS_SD_PRINTING || is_usb_printing || isPrintPaused || (custom_message_type == CUSTOM_MSG_TYPE_TEMCAL) || saved_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL) || card.paused || mmu_print_saved) #define PRINTER_ACTIVE (IS_SD_PRINTING || is_usb_printing || isPrintPaused || (custom_message_type == CustomMsg::TempCal) || saved_printing || (lcd_commands_type == LcdCommands::Layer1Cal) || card.paused || mmu_print_saved)
//! Beware - mcode_in_progress is set as soon as the command gets really processed, //! Beware - mcode_in_progress is set as soon as the command gets really processed,
//! which is not the same as posting the M600 command into the command queue //! which is not the same as posting the M600 command into the command queue
//! There can be a considerable lag between posting M600 and its real processing which might result //! There can be a considerable lag between posting M600 and its real processing which might result

View File

@ -356,7 +356,6 @@ unsigned long starttime=0;
unsigned long stoptime=0; unsigned long stoptime=0;
unsigned long _usb_timer = 0; unsigned long _usb_timer = 0;
bool extruder_under_pressure = true; bool extruder_under_pressure = true;
@ -1078,6 +1077,7 @@ void setup()
SERIAL_ECHO_START; SERIAL_ECHO_START;
printf_P(PSTR(" " FW_VERSION_FULL "\n")); printf_P(PSTR(" " FW_VERSION_FULL "\n"));
//SERIAL_ECHOPAIR("Active sheet before:", static_cast<unsigned long int>(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet))));
#ifdef DEBUG_SEC_LANG #ifdef DEBUG_SEC_LANG
lang_table_header_t header; lang_table_header_t header;
@ -1426,20 +1426,7 @@ void setup()
printf_P(PSTR("Card NG!\n")); printf_P(PSTR("Card NG!\n"));
#endif //DEBUG_SD_SPEED_TEST #endif //DEBUG_SD_SPEED_TEST
if (eeprom_read_byte((uint8_t*)EEPROM_POWER_COUNT) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_POWER_COUNT, 0); eeprom_init();
if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_X) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_CRASH_COUNT_X, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_Y) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_CRASH_COUNT_Y, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_FERROR_COUNT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_POWER_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_POWER_COUNT_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_MMU_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_FAIL_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
#ifdef SNMM #ifdef SNMM
if (eeprom_read_dword((uint32_t*)EEPROM_BOWDEN_LENGTH) == 0x0ffffffff) { //bowden length used for SNMM if (eeprom_read_dword((uint32_t*)EEPROM_BOWDEN_LENGTH) == 0x0ffffffff) { //bowden length used for SNMM
int _z = BOWDEN_LENGTH; int _z = BOWDEN_LENGTH;
@ -1506,7 +1493,6 @@ void setup()
SilentModeMenu_MMU = 1; SilentModeMenu_MMU = 1;
eeprom_write_byte((uint8_t*)EEPROM_MMU_STEALTH, SilentModeMenu_MMU); eeprom_write_byte((uint8_t*)EEPROM_MMU_STEALTH, SilentModeMenu_MMU);
} }
check_babystep(); //checking if Z babystep is in allowed range
#if !defined(DEBUG_DISABLE_FANCHECK) && defined(FANCHECK) && defined(TACH_1) && TACH_1 >-1 #if !defined(DEBUG_DISABLE_FANCHECK) && defined(FANCHECK) && defined(TACH_1) && TACH_1 >-1
setup_fan_interrupt(); setup_fan_interrupt();
@ -3161,7 +3147,7 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
#endif //IR_SENSOR #endif //IR_SENSOR
lcd_setstatuspgm(_T(WELCOME_MSG)); lcd_setstatuspgm(_T(WELCOME_MSG));
custom_message_type = CUSTOM_MSG_TYPE_STATUS; custom_message_type = CustomMsg::Status;
} }
//! @brief Rise Z if too low to avoid blob/jam before filament loading //! @brief Rise Z if too low to avoid blob/jam before filament loading
@ -3177,6 +3163,11 @@ void gcode_M701()
{ {
printf_P(PSTR("gcode_M701 begin\n")); printf_P(PSTR("gcode_M701 begin\n"));
if (farm_mode)
{
prusa_statistics(22);
}
if (mmu_enabled) if (mmu_enabled)
{ {
extr_adj(tmp_extruder);//loads current extruder extr_adj(tmp_extruder);//loads current extruder
@ -3185,7 +3176,7 @@ void gcode_M701()
else else
{ {
enable_z(); enable_z();
custom_message_type = CUSTOM_MSG_TYPE_F_LOAD; custom_message_type = CustomMsg::FilamentLoading;
#ifdef FSENSOR_QUALITY #ifdef FSENSOR_QUALITY
fsensor_oq_meassure_start(40); fsensor_oq_meassure_start(40);
@ -3215,7 +3206,7 @@ void gcode_M701()
lcd_setstatuspgm(_T(WELCOME_MSG)); lcd_setstatuspgm(_T(WELCOME_MSG));
disable_z(); disable_z();
loading_flag = false; loading_flag = false;
custom_message_type = CUSTOM_MSG_TYPE_STATUS; custom_message_type = CustomMsg::Status;
#ifdef FSENSOR_QUALITY #ifdef FSENSOR_QUALITY
fsensor_oq_meassure_stop(); fsensor_oq_meassure_stop();
@ -4264,7 +4255,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
// setTargetHotend(200, 0); // setTargetHotend(200, 0);
setTargetBed(70 + (start_temp - 30)); setTargetBed(70 + (start_temp - 30));
custom_message_type = CUSTOM_MSG_TYPE_TEMCAL; custom_message_type = CustomMsg::TempCal;
custom_message_state = 1; custom_message_state = 1;
lcd_setstatuspgm(_T(MSG_TEMP_CALIBRATION)); lcd_setstatuspgm(_T(MSG_TEMP_CALIBRATION));
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
@ -4366,7 +4357,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
break; break;
} }
puts_P(_N("PINDA probe calibration start")); puts_P(_N("PINDA probe calibration start"));
custom_message_type = CUSTOM_MSG_TYPE_TEMCAL; custom_message_type = CustomMsg::TempCal;
custom_message_state = 1; custom_message_state = 1;
lcd_setstatuspgm(_T(MSG_TEMP_CALIBRATION)); lcd_setstatuspgm(_T(MSG_TEMP_CALIBRATION));
current_position[X_AXIS] = PINDA_PREHEAT_X; current_position[X_AXIS] = PINDA_PREHEAT_X;
@ -4434,7 +4425,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
} }
custom_message_type = CUSTOM_MSG_TYPE_STATUS; custom_message_type = CustomMsg::Status;
eeprom_update_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 1); eeprom_update_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 1);
puts_P(_N("Temperature calibration done.")); puts_P(_N("Temperature calibration done."));
@ -4494,7 +4485,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
// We don't know where we are! HOME! // We don't know where we are! HOME!
// Push the commands to the front of the message queue in the reverse order! // Push the commands to the front of the message queue in the reverse order!
// There shall be always enough space reserved for these commands. // There shall be always enough space reserved for these commands.
if (lcd_commands_type != LCD_COMMAND_STOP_PRINT) { if (lcd_commands_type != LcdCommands::StopPrint) {
repeatcommand_front(); // repeat G80 with all its parameters repeatcommand_front(); // repeat G80 with all its parameters
enquecommand_front_P((PSTR("G28 W0"))); enquecommand_front_P((PSTR("G28 W0")));
} }
@ -4534,7 +4525,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
if (temp_comp_start) if (temp_comp_start)
if (run == false && temp_cal_active == true && calibration_status_pinda() == true && target_temperature_bed >= 50) { if (run == false && temp_cal_active == true && calibration_status_pinda() == true && target_temperature_bed >= 50) {
if (lcd_commands_type != LCD_COMMAND_STOP_PRINT) { if (lcd_commands_type != LcdCommands::StopPrint) {
temp_compensation_start(); temp_compensation_start();
run = true; run = true;
repeatcommand_front(); // repeat G80 with all its parameters repeatcommand_front(); // repeat G80 with all its parameters
@ -4546,14 +4537,14 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
break; break;
} }
run = false; run = false;
if (lcd_commands_type == LCD_COMMAND_STOP_PRINT) { if (lcd_commands_type == LcdCommands::StopPrint) {
mesh_bed_leveling_flag = false; mesh_bed_leveling_flag = false;
break; break;
} }
// Save custom message state, set a new custom message state to display: Calibrating point 9. // Save custom message state, set a new custom message state to display: Calibrating point 9.
unsigned int custom_message_type_old = custom_message_type; CustomMsg custom_message_type_old = custom_message_type;
unsigned int custom_message_state_old = custom_message_state; unsigned int custom_message_state_old = custom_message_state;
custom_message_type = CUSTOM_MSG_TYPE_MESHBL; custom_message_type = CustomMsg::MeshBedLeveling;
custom_message_state = (nMeasPoints * nMeasPoints) + 10; custom_message_state = (nMeasPoints * nMeasPoints) + 10;
lcd_update(1); lcd_update(1);
@ -4753,7 +4744,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
enable_z_endstop(bState); enable_z_endstop(bState);
} while (st_get_position_mm(Z_AXIS) > MESH_HOME_Z_SEARCH); // i.e. Z-leveling not o.k. } while (st_get_position_mm(Z_AXIS) > MESH_HOME_Z_SEARCH); // i.e. Z-leveling not o.k.
// plan_set_z_position(MESH_HOME_Z_SEARCH); // is not necessary ('do-while' loop always ends at the expected Z-position) // plan_set_z_position(MESH_HOME_Z_SEARCH); // is not necessary ('do-while' loop always ends at the expected Z-position)
custom_message_type=CUSTOM_MSG_TYPE_STATUS; // display / status-line recovery custom_message_type=CustomMsg::Status; // display / status-line recovery
lcd_update_enable(true); // display / status-line recovery lcd_update_enable(true); // display / status-line recovery
gcode_G28(true, true, true); // X & Y & Z-homing (must be after individual Z-homing (problem with spool-holder)!) gcode_G28(true, true, true); // X & Y & Z-homing (must be after individual Z-homing (problem with spool-holder)!)
repeatcommand_front(); // re-run (i.e. of "G80") repeatcommand_front(); // re-run (i.e. of "G80")
@ -6000,7 +5991,7 @@ Sigma_Exit:
SERIAL_PROTOCOLLNRPGM(FW_VERSION_STR_P()); SERIAL_PROTOCOLLNRPGM(FW_VERSION_STR_P());
} else if (code_seen('U')) { } else if (code_seen('U')) {
// Check the firmware version provided. If the firmware version provided by the U code is higher than the currently running firmware, // Check the firmware version provided. If the firmware version provided by the U code is higher than the currently running firmware,
// pause the print and ask the user to upgrade the firmware. // pause the print for 30s and ask the user to upgrade the firmware.
show_upgrade_dialog_if_version_newer(++ strchr_pointer); show_upgrade_dialog_if_version_newer(++ strchr_pointer);
} else { } else {
SERIAL_ECHOPGM("FIRMWARE_NAME:Prusa-Firmware "); SERIAL_ECHOPGM("FIRMWARE_NAME:Prusa-Firmware ");
@ -7824,9 +7815,9 @@ bool bInhibitFlag;
#ifdef IR_SENSOR #ifdef IR_SENSOR
bInhibitFlag=(menu_menu==lcd_menu_show_sensors_state); // Support::SensorInfo menu active bInhibitFlag=(menu_menu==lcd_menu_show_sensors_state); // Support::SensorInfo menu active
#endif // IR_SENSOR #endif // IR_SENSOR
if ((mcode_in_progress != 600) && (eFilamentAction != e_FILAMENT_ACTION_autoLoad) && (!bInhibitFlag)) //M600 not in progress, preHeat @ autoLoad menu not active, Support::ExtruderInfo/SensorInfo menu not active if ((mcode_in_progress != 600) && (eFilamentAction != FilamentAction::AutoLoad) && (!bInhibitFlag)) //M600 not in progress, preHeat @ autoLoad menu not active, Support::ExtruderInfo/SensorInfo menu not active
{ {
if (!moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL) && !wizard_active) if (!moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LcdCommands::Layer1Cal) && !wizard_active)
{ {
if (fsensor_check_autoload()) if (fsensor_check_autoload())
{ {
@ -7850,7 +7841,7 @@ if(0)
show_preheat_nozzle_warning(); show_preheat_nozzle_warning();
lcd_update_enable(true); lcd_update_enable(true);
*/ */
eFilamentAction=e_FILAMENT_ACTION_autoLoad; eFilamentAction=FilamentAction::AutoLoad;
bFilamentFirstRun=false; bFilamentFirstRun=false;
if(target_temperature[0]>=EXTRUDE_MINTEMP) if(target_temperature[0]>=EXTRUDE_MINTEMP)
{ {
@ -8249,12 +8240,15 @@ static void wait_for_heater(long codenum, uint8_t extruder) {
void check_babystep() void check_babystep()
{ {
int babystep_z; int babystep_z = eeprom_read_word(reinterpret_cast<uint16_t *>(&(EEPROM_Sheets_base->
EEPROM_read_B(EEPROM_BABYSTEP_Z, &babystep_z); s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset)));
if ((babystep_z < Z_BABYSTEP_MIN) || (babystep_z > Z_BABYSTEP_MAX)) { if ((babystep_z < Z_BABYSTEP_MIN) || (babystep_z > Z_BABYSTEP_MAX)) {
babystep_z = 0; //if babystep value is out of min max range, set it to 0 babystep_z = 0; //if babystep value is out of min max range, set it to 0
SERIAL_ECHOLNPGM("Z live adjust out of range. Setting to 0"); SERIAL_ECHOLNPGM("Z live adjust out of range. Setting to 0");
EEPROM_save_B(EEPROM_BABYSTEP_Z, &babystep_z); eeprom_write_word(reinterpret_cast<uint16_t *>(&(EEPROM_Sheets_base->
s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset)),
babystep_z);
lcd_show_fullscreen_message_and_wait_P(PSTR("Z live adjust out of range. Setting to 0. Click to continue.")); lcd_show_fullscreen_message_and_wait_P(PSTR("Z live adjust out of range. Setting to 0. Click to continue."));
lcd_update_enable(true); lcd_update_enable(true);
} }
@ -8324,7 +8318,7 @@ void bed_check(float x_dimension, float y_dimension, int x_points_num, int y_poi
float bed_zero_ref_y = (-0.6f + Y_PROBE_OFFSET_FROM_EXTRUDER); float bed_zero_ref_y = (-0.6f + Y_PROBE_OFFSET_FROM_EXTRUDER);
float mesh_home_z_search = 4; float mesh_home_z_search = 4;
float measure_z_heigth = 0.2f; float measure_z_height = 0.2f;
float row[x_points_num]; float row[x_points_num];
int ix = 0; int ix = 0;
int iy = 0; int iy = 0;
@ -8341,7 +8335,7 @@ void bed_check(float x_dimension, float y_dimension, int x_points_num, int y_poi
unsigned int custom_message_type_old = custom_message_type; unsigned int custom_message_type_old = custom_message_type;
unsigned int custom_message_state_old = custom_message_state; unsigned int custom_message_state_old = custom_message_state;
custom_message_type = CUSTOM_MSG_TYPE_MESHBL; custom_message_type = CustomMsg::MeshBedLeveling;
custom_message_state = (x_points_num * y_points_num) + 10; custom_message_state = (x_points_num * y_points_num) + 10;
lcd_update(1); lcd_update(1);
@ -8359,7 +8353,7 @@ void bed_check(float x_dimension, float y_dimension, int x_points_num, int y_poi
} }
st_synchronize(); st_synchronize();
*/ */
destination[Z_AXIS] = measure_z_heigth; destination[Z_AXIS] = measure_z_height;
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], Z_LIFT_FEEDRATE, active_extruder); plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], Z_LIFT_FEEDRATE, active_extruder);
for(int8_t i=0; i < NUM_AXIS; i++) { for(int8_t i=0; i < NUM_AXIS; i++) {
current_position[i] = destination[i]; current_position[i] = destination[i];
@ -8539,7 +8533,7 @@ void bed_analysis(float x_dimension, float y_dimension, int x_points_num, int y_
} }
unsigned int custom_message_type_old = custom_message_type; unsigned int custom_message_type_old = custom_message_type;
unsigned int custom_message_state_old = custom_message_state; unsigned int custom_message_state_old = custom_message_state;
custom_message_type = CUSTOM_MSG_TYPE_MESHBL; custom_message_type = CustomMsg::MeshBedLeveling;
custom_message_state = (x_points_num * y_points_num) + 10; custom_message_state = (x_points_num * y_points_num) + 10;
lcd_update(1); lcd_update(1);
@ -8689,7 +8683,7 @@ void bed_analysis(float x_dimension, float y_dimension, int x_points_num, int y_
void temp_compensation_start() { void temp_compensation_start() {
custom_message_type = CUSTOM_MSG_TYPE_TEMPRE; custom_message_type = CustomMsg::TempCompPreheat;
custom_message_state = PINDA_HEAT_T + 1; custom_message_state = PINDA_HEAT_T + 1;
lcd_update(2); lcd_update(2);
if (degHotend(active_extruder) > EXTRUDE_MINTEMP) { if (degHotend(active_extruder) > EXTRUDE_MINTEMP) {
@ -8710,7 +8704,7 @@ void temp_compensation_start() {
if (custom_message_state == 99 || custom_message_state == 9) lcd_update(2); //force whole display redraw if number of digits changed if (custom_message_state == 99 || custom_message_state == 9) lcd_update(2); //force whole display redraw if number of digits changed
else lcd_update(1); else lcd_update(1);
} }
custom_message_type = CUSTOM_MSG_TYPE_STATUS; custom_message_type = CustomMsg::Status;
custom_message_state = 0; custom_message_state = 0;
} }
@ -9099,8 +9093,7 @@ ISR(INT4_vect) {
EIMSK &= ~(1 << 4); //disable INT4 interrupt to make sure that this code will be executed just once EIMSK &= ~(1 << 4); //disable INT4 interrupt to make sure that this code will be executed just once
SERIAL_ECHOLNPGM("INT4"); SERIAL_ECHOLNPGM("INT4");
//fire normal uvlo only in case where EEPROM_UVLO is 0 or if IS_SD_PRINTING is 1. //fire normal uvlo only in case where EEPROM_UVLO is 0 or if IS_SD_PRINTING is 1.
//Don't change || to && because in some case the printer can be moving although IS_SD_PRINTING is zero if(PRINTER_ACTIVE && (!(eeprom_read_byte((uint8_t*)EEPROM_UVLO)))) uvlo_();
if((IS_SD_PRINTING ) || (!(eeprom_read_byte((uint8_t*)EEPROM_UVLO)))) uvlo_();
if(eeprom_read_byte((uint8_t*)EEPROM_UVLO)) uvlo_tiny(); if(eeprom_read_byte((uint8_t*)EEPROM_UVLO)) uvlo_tiny();
} }

2
Firmware/cmdqueue.cpp Normal file → Executable file
View File

@ -598,7 +598,7 @@ void get_command()
if (farm_mode) if (farm_mode)
{ {
prusa_statistics(6); prusa_statistics(6);
lcd_commands_type = LCD_COMMAND_FARM_MODE_CONFIRM; lcd_commands_type = LcdCommands::FarmModeConfirm;
} }
} }

83
Firmware/eeprom.cpp Normal file
View File

@ -0,0 +1,83 @@
//! @file
//! @date Jun 20, 2019
//! @author Marek Běl
#include "eeprom.h"
#include "Marlin.h"
#include <avr/eeprom.h>
#include <stdint.h>
#include "language.h"
#if 0
template <typename T>
static T eeprom_read(T *address);
template<>
char eeprom_read<char>(char *address)
{
return eeprom_read_byte(reinterpret_cast<uint8_t*>(address));
}
#endif
template <typename T>
static void eeprom_write(T *address, T value);
template<>
void eeprom_write<char>(char *addres, char value)
{
eeprom_write_byte(reinterpret_cast<uint8_t*>(addres), static_cast<uint8_t>(value));
}
template <typename T>
static bool eeprom_is_uninitialized(T *address);
template <>
bool eeprom_is_uninitialized<char>(char *address)
{
return (0xff == eeprom_read_byte(reinterpret_cast<uint8_t*>(address)));
}
bool is_sheet_initialized(){
return (0xffff != eeprom_read_word(reinterpret_cast<uint16_t*>(&(EEPROM_Sheets_base->
s[eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet))].z_offset))));
}
void eeprom_init()
{
if (eeprom_read_byte((uint8_t*)EEPROM_POWER_COUNT) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_POWER_COUNT, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_X) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_CRASH_COUNT_X, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_Y) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_CRASH_COUNT_Y, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_FERROR_COUNT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_POWER_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_POWER_COUNT_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_MMU_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_FAIL_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
if (eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)) == 0xff) eeprom_update_byte(&(EEPROM_Sheets_base->active_sheet), 0);
for (uint_least8_t i = 0; i < (sizeof(Sheets::s)/sizeof(Sheets::s[0])); ++i)
{
bool is_uninitialized = true;
for (uint_least8_t j = 0; j < (sizeof(Sheet::name)/sizeof(Sheet::name[0])); ++j)
{
if (!eeprom_is_uninitialized(&(EEPROM_Sheets_base->s[i].name[j]))) is_uninitialized = false;
}
if(is_uninitialized)
{
eeprom_write(&(EEPROM_Sheets_base->s[i].name[0]), static_cast<char>(i + '1'));
eeprom_write(&(EEPROM_Sheets_base->s[i].name[1]), '\0');
}
}
check_babystep();
}

View File

@ -1,6 +1,35 @@
#ifndef EEPROM_H #ifndef EEPROM_H
#define EEPROM_H #define EEPROM_H
#include <stdint.h>
#ifdef __cplusplus
void eeprom_init();
extern bool is_sheet_initialized();
#endif
typedef struct
{
char name[7]; //!< Can be null terminated, doesn't need to be null terminated
int16_t z_offset; //!< Z_BABYSTEP_MIN .. Z_BABYSTEP_MAX = Z_BABYSTEP_MIN*2/1000 [mm] .. Z_BABYSTEP_MAX*2/1000 [mm]
uint8_t bed_temp; //!< 0 .. 254 [°C]
uint8_t pinda_temp; //!< 0 .. 254 [°C]
} Sheet;
typedef struct
{
Sheet s[3];
uint8_t active_sheet;
} Sheets;
// sizeof(Sheets). Do not change it unless EEPROM_Sheets_base is last item in EEPROM.
// Otherwise it would move following items.
#define EEPROM_SHEETS_SIZEOF 34
#ifdef __cplusplus
static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEPROM_SHEETS_SIZEOF.");
#endif
#define EEPROM_EMPTY_VALUE 0xFF #define EEPROM_EMPTY_VALUE 0xFF
// The total size of the EEPROM is // The total size of the EEPROM is
// 4096 for the Atmega2560 // 4096 for the Atmega2560
@ -171,31 +200,16 @@
#define EEPROM_CHECK_VERSION (EEPROM_CHECK_MODEL-1) // uint8 #define EEPROM_CHECK_VERSION (EEPROM_CHECK_MODEL-1) // uint8
#define EEPROM_CHECK_GCODE (EEPROM_CHECK_VERSION-1) // uint8 #define EEPROM_CHECK_GCODE (EEPROM_CHECK_VERSION-1) // uint8
#define EEPROM_SHEETS_BASE (EEPROM_NOZZLE_DIAMETER_uM - EEPROM_SHEETS_SIZEOF) // Sheets
static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
//This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items.
#define EEPROM_LAST_ITEM EEPROM_SHEETS_BASE
// !!!!! // !!!!!
// !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
// !!!!! // !!!!!
//TMC2130 configuration
#define EEPROM_TMC_AXIS_SIZE //axis configuration block size
#define EEPROM_TMC_X (EEPROM_TMC + 0 * EEPROM_TMC_AXIS_SIZE) //X axis configuration blok
#define EEPROM_TMC_Y (EEPROM_TMC + 1 * EEPROM_TMC_AXIS_SIZE) //Y axis
#define EEPROM_TMC_Z (EEPROM_TMC + 2 * EEPROM_TMC_AXIS_SIZE) //Z axis
#define EEPROM_TMC_E (EEPROM_TMC + 3 * EEPROM_TMC_AXIS_SIZE) //E axis
//TMC2130 - X axis
#define EEPROM_TMC_X_USTEPS_INTPOL (EEPROM_TMC_X + 0) // 1byte, bit 0..4 USTEPS, bit 7 INTPOL
#define EEPROM_TMC_X_PWM_AMPL (EEPROM_TMC_X + 1) // 1byte (0..255)
#define EEPROM_TMC_X_PWM_GRAD_FREQ (EEPROM_TMC_X + 2) // 1byte, bit 0..3 GRAD, bit 4..5 FREQ
#define EEPROM_TMC_X_TCOOLTHRS (EEPROM_TMC_X + 3) // 2bytes (0..)
#define EEPROM_TMC_X_SG_THRS (EEPROM_TMC_X + 5) // 1byte, (-64..+63)
#define EEPROM_TMC_X_CURRENT_H (EEPROM_TMC_X + 6) // 1byte, (0..63)
#define EEPROM_TMC_X_CURRENT_R (EEPROM_TMC_X + 7) // 1byte, (0..63)
#define EEPROM_TMC_X_HOME_SG_THRS (EEPROM_TMC_X + 8) // 1byte, (-64..+63)
#define EEPROM_TMC_X_HOME_CURRENT_R (EEPROM_TMC_X + 9) // 1byte, (-64..+63)
#define EEPROM_TMC_X_HOME_DTCOOLTHRS (EEPROM_TMC_X + 10) // 1byte (-128..+127)
#define EEPROM_TMC_X_DTCOOLTHRS_LOW (EEPROM_TMC_X + 11) // 1byte (-128..+127)
#define EEPROM_TMC_X_DTCOOLTHRS_HIGH (EEPROM_TMC_X + 12) // 1byte (-128..+127)
#define EEPROM_TMC_X_SG_THRS_LOW (EEPROM_TMC_X + 13) // 1byte, (-64..+63)
#define EEPROM_TMC_X_SG_THRS_HIGH (EEPROM_TMC_X + 14) // 1byte, (-64..+63)
// Currently running firmware, each digit stored as uint16_t. // Currently running firmware, each digit stored as uint16_t.
// The flavor differentiates a dev, alpha, beta, release candidate or a release version. // The flavor differentiates a dev, alpha, beta, release candidate or a release version.
@ -209,9 +223,13 @@
#ifdef __cplusplus #ifdef __cplusplus
#include "ConfigurationStore.h" #include "ConfigurationStore.h"
static M500_conf * const EEPROM_M500_base = reinterpret_cast<M500_conf*>(20); //offset for storing settings using M500 static_assert(EEPROM_FIRMWARE_VERSION_END < 20, "Firmware version EEPROM address conflicts with EEPROM_M500_base");
static constexpr M500_conf * const EEPROM_M500_base = reinterpret_cast<M500_conf*>(20); //offset for storing settings using M500
static_assert(((sizeof(M500_conf) + 20) < EEPROM_LAST_ITEM), "M500_conf address space conflicts with previous items.");
#endif #endif
#undef EEPROM_SHEETS_BASE
enum enum
{ {
EEPROM_MMU_CUTTER_ENABLED_enabled = 1, EEPROM_MMU_CUTTER_ENABLED_enabled = 1,

View File

@ -128,19 +128,19 @@ void lay1cal_before_meander()
//! @brief Count extrude length //! @brief Count extrude length
//! //!
//! @param layer_heigth layer heigth in mm //! @param layer_height layer height in mm
//! @param extrusion_width extrusion width in mm //! @param extrusion_width extrusion width in mm
//! @param extrusion_length extrusion length in mm //! @param extrusion_length extrusion length in mm
//! @return filament length in mm which needs to be extruded to form line //! @return filament length in mm which needs to be extruded to form line
static constexpr float count_e(float layer_heigth, float extrusion_width, float extrusion_length) static constexpr float count_e(float layer_height, float extrusion_width, float extrusion_length)
{ {
return (extrusion_length * layer_heigth * extrusion_width / (M_PI * pow(1.75, 2) / 4)); return (extrusion_length * layer_height * extrusion_width / (M_PI * pow(1.75, 2) / 4));
} }
static const float width = 0.4; //!< line width static const float width = 0.4; //!< line width
static const float length = 20 - width; //!< line length static const float length = 20 - width; //!< line length
static const float heigth = 0.2; //!< layer height TODO This is wrong, as current Z height is 0.15 mm static const float height = 0.2; //!< layer height TODO This is wrong, as current Z height is 0.15 mm
static const float extr = count_e(heigth, width, length); //!< E axis movement needed to print line static const float extr = count_e(height, width, length); //!< E axis movement needed to print line
//! @brief Print meander //! @brief Print meander
//! @param cmd_buffer character buffer needed to format gcodes //! @param cmd_buffer character buffer needed to format gcodes
@ -199,7 +199,7 @@ void lay1cal_meander(char *cmd_buffer)
//! @param i iteration //! @param i iteration
void lay1cal_square(char *cmd_buffer, uint8_t i) void lay1cal_square(char *cmd_buffer, uint8_t i)
{ {
const float extr_short_segment = count_e(heigth, width, width); const float extr_short_segment = count_e(height, width, width);
static const char fmt1[] PROGMEM = "G1 X%d Y%-.2f E%-.3f"; static const char fmt1[] PROGMEM = "G1 X%d Y%-.2f E%-.3f";
static const char fmt2[] PROGMEM = "G1 Y%-.2f E%-.3f"; static const char fmt2[] PROGMEM = "G1 Y%-.2f E%-.3f";

109
Firmware/heatbed_pwm.cpp Executable file
View File

@ -0,0 +1,109 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include "io_atmega2560.h"
// All this is about silencing the heat bed, as it behaves like a loudspeaker.
// Basically, we want the PWM heating switched at 30Hz (or so) which is a well ballanced
// frequency for both power supply units (i.e. both PSUs are reasonably silent).
// The only trouble is the rising or falling edge of bed heating - that creates an audible click.
// This audible click may be suppressed by making the rising or falling edge NOT sharp.
// Of course, making non-sharp edges in digital technology is not easy, but there is a solution.
// It is possible to do a fast PWM sequence with duty starting from 0 to 255.
// Doing this at higher frequency than the bed "loudspeaker" can handle makes the click barely audible.
// Technically:
// timer0 is set to fast PWM mode at 62.5kHz (timer0 is linked to the bed heating pin) (zero prescaler)
// To keep the bed switching at 30Hz - we don't want the PWM running at 62kHz all the time
// since it would burn the heatbed's MOSFET:
// 16MHz/256 levels of PWM duty gives us 62.5kHz
// 62.5kHz/256 gives ~244Hz, that is still too fast - 244/8 gives ~30Hz, that's what we need
// So the automaton runs atop of inner 8 (or 16) cycles.
// The finite automaton is running in the ISR(TIMER0_OVF_vect)
///! Definition off finite automaton states
enum class States : uint8_t {
ZERO = 0,
RISE = 1,
ONE = 2,
FALL = 3
};
///! State table for the inner part of the finite automaton
///! Basically it specifies what shall happen if the outer automaton is requesting setting the heat pin to 0 (OFF) or 1 (ON)
///! ZERO: steady 0 (OFF), no change for the whole period
///! RISE: 8 (16) fast PWM cycles with increasing duty up to steady ON
///! ONE: steady 1 (ON), no change for the whole period
///! FALL: 8 (16) fast PWM cycles with decreasing duty down to steady OFF
///! @@TODO move it into progmem
static States stateTable[4*2] = {
// off on
States::ZERO, States::RISE, // ZERO
States::FALL, States::ONE, // RISE
States::FALL, States::ONE, // ONE
States::ZERO, States::RISE // FALL
};
///! Inner states of the finite automaton
static States state = States::ZERO;
///! Inner and outer PWM counters
static uint8_t outer = 0;
static uint8_t inner = 0;
static uint8_t pwm = 0;
///! the slow PWM duty for the next 30Hz cycle
///! Set in the whole firmware at various places
extern unsigned char soft_pwm_bed;
/// Fine tuning of automaton cycles
#if 1
static const uint8_t innerMax = 16;
static const uint8_t innerShift = 4;
#else
static const uint8_t innerMax = 8;
static const uint8_t innerShift = 5;
#endif
ISR(TIMER0_OVF_vect) // timer compare interrupt service routine
{
if( inner ){
switch(state){
case States::ZERO:
OCR0B = 255;
// Commenting the following code saves 6B, but it is left here for reference
// It is not necessary to set it all over again, because we can only get into the ZERO state from the FALL state (which sets this register)
// TCCR0A |= (1 << COM0B1) | (1 << COM0B0);
break;
case States::RISE:
OCR0B = (innerMax - inner) << innerShift;
// TCCR0A |= (1 << COM0B1); // this bit is always 1
TCCR0A &= ~(1 << COM0B0);
break;
case States::ONE:
OCR0B = 255;
// again - may be skipped, because we get into the ONE state only from RISE (which sets this register)
// TCCR0A |= (1 << COM0B1);
TCCR0A &= ~(1 << COM0B0);
break;
case States::FALL:
OCR0B = (innerMax - inner) << innerShift; // this is the same as in RISE, because now we are setting the zero part of duty due to inverting mode
// must switch to inverting mode already here, because it takes a whole PWM cycle and it would make a "1" at the end of this pwm cycle
TCCR0A |= /*(1 << COM0B1) |*/ (1 << COM0B0);
break;
}
--inner;
} else {
if( ! outer ){ // at the end of 30Hz PWM period
// synchro is not needed (almost), soft_pwm_bed is just 1 byte, 1-byte write instruction is atomic
pwm = soft_pwm_bed << 1;
}
if( pwm > outer || pwm >= 254 ){
// soft_pwm_bed has a range of 0-127, that why a <<1 is done here. That also means that we may get only up to 254 which we want to be full-time 1 (ON)
state = stateTable[ uint8_t(state) * 2 + 1 ];
} else {
// switch OFF
state = stateTable[ uint8_t(state) * 2 + 0 ];
}
++outer;
inner = innerMax;
}
}

View File

@ -168,16 +168,40 @@ int menu_draw_item_printf_P(char type_char, const char* format, ...)
} }
*/ */
static char menu_selection_mark(){
return (lcd_encoder == menu_item)?'>':' ';
}
static void menu_draw_item_puts_P(char type_char, const char* str) static void menu_draw_item_puts_P(char type_char, const char* str)
{ {
lcd_set_cursor(0, menu_row); lcd_set_cursor(0, menu_row);
lcd_printf_P(PSTR("%c%-18.18S%c"), (lcd_encoder == menu_item)?'>':' ', str, type_char); lcd_printf_P(PSTR("%c%-18.18S%c"), menu_selection_mark(), str, type_char);
}
//! @brief Format sheet name
//!
//! @param[in] sheet_E Sheet in EEPROM
//! @param[out] buffer for formatted output
void menu_format_sheet_E(const Sheet &sheet_E, SheetFormatBuffer &buffer)
{
uint_least8_t index = sprintf_P(buffer.c, PSTR("%.10S "), _T(MSG_SHEET));
eeprom_read_block(&(buffer.c[index]), sheet_E.name, 7);
//index += 7;
buffer.c[index + 7] = '\0';
}
static void menu_draw_item_puts_E(char type_char, const Sheet &sheet)
{
lcd_set_cursor(0, menu_row);
SheetFormatBuffer buffer;
menu_format_sheet_E(sheet, buffer);
lcd_printf_P(PSTR("%c%-18.18s%c"), menu_selection_mark(), buffer.c, type_char);
} }
static void menu_draw_item_puts_P(char type_char, const char* str, char num) static void menu_draw_item_puts_P(char type_char, const char* str, char num)
{ {
lcd_set_cursor(0, menu_row); lcd_set_cursor(0, menu_row);
lcd_printf_P(PSTR("%c%-.16S "), (lcd_encoder == menu_item)?'>':' ', str); lcd_printf_P(PSTR("%c%-.16S "), menu_selection_mark(), str);
lcd_putc(num); lcd_putc(num);
lcd_set_cursor(19, menu_row); lcd_set_cursor(19, menu_row);
lcd_putc(type_char); lcd_putc(type_char);
@ -224,6 +248,21 @@ uint8_t menu_item_submenu_P(const char* str, menu_func_t submenu)
return 0; return 0;
} }
uint8_t menu_item_submenu_E(const Sheet &sheet, menu_func_t submenu)
{
if (menu_item == menu_line)
{
if (lcd_draw_update) menu_draw_item_puts_E(LCD_STR_ARROW_RIGHT[0], sheet);
if (menu_clicked && (lcd_encoder == menu_item))
{
menu_submenu(submenu);
return menu_item_ret();
}
}
menu_item++;
return 0;
}
uint8_t menu_item_back_P(const char* str) uint8_t menu_item_back_P(const char* str)
{ {
if (menu_item == menu_line) if (menu_item == menu_line)
@ -399,7 +438,7 @@ uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_v
if (lcd_draw_update) if (lcd_draw_update)
{ {
lcd_set_cursor(0, menu_row); lcd_set_cursor(0, menu_row);
menu_draw_P<T>((lcd_encoder == menu_item)?'>':' ', str, *pval); menu_draw_P<T>(menu_selection_mark(), str, *pval);
} }
if (menu_clicked && (lcd_encoder == menu_item)) if (menu_clicked && (lcd_encoder == menu_item))
{ {

View File

@ -3,6 +3,7 @@
#define _MENU_H #define _MENU_H
#include <inttypes.h> #include <inttypes.h>
#include "eeprom.h"
#define MENU_DATA_SIZE 32 #define MENU_DATA_SIZE 32
@ -99,6 +100,10 @@ extern uint8_t menu_item_text_P(const char* str);
#define MENU_ITEM_SUBMENU_P(str, submenu) do { if (menu_item_submenu_P(str, submenu)) return; } while (0) #define MENU_ITEM_SUBMENU_P(str, submenu) do { if (menu_item_submenu_P(str, submenu)) return; } while (0)
extern uint8_t menu_item_submenu_P(const char* str, menu_func_t submenu); extern uint8_t menu_item_submenu_P(const char* str, menu_func_t submenu);
#define MENU_ITEM_SUBMENU_E(sheet, submenu) do { if (menu_item_submenu_E(sheet, submenu)) return; } while (0)
extern uint8_t menu_item_submenu_E(const Sheet &sheet, menu_func_t submenu);
#define MENU_ITEM_BACK_P(str) do { if (menu_item_back_P(str)) return; } while (0) #define MENU_ITEM_BACK_P(str) do { if (menu_item_back_P(str)) return; } while (0)
extern uint8_t menu_item_back_P(const char* str); extern uint8_t menu_item_back_P(const char* str);
@ -125,6 +130,13 @@ extern void menu_draw_float31(const char* str, float val);
extern void menu_draw_float13(const char* str, float val); extern void menu_draw_float13(const char* str, float val);
struct SheetFormatBuffer
{
char c[19];
};
extern void menu_format_sheet_E(const Sheet &sheet_E, SheetFormatBuffer &buffer);
#define MENU_ITEM_EDIT_int3_P(str, pval, minval, maxval) do { if (menu_item_edit_P(str, pval, minval, maxval)) return; } while (0) #define MENU_ITEM_EDIT_int3_P(str, pval, minval, maxval) do { if (menu_item_edit_P(str, pval, minval, maxval)) return; } while (0)
//#define MENU_ITEM_EDIT_int3_P(str, pval, minval, maxval) MENU_ITEM_EDIT(int3, str, pval, minval, maxval) //#define MENU_ITEM_EDIT_int3_P(str, pval, minval, maxval) MENU_ITEM_EDIT(int3, str, pval, minval, maxval)

View File

@ -3031,7 +3031,8 @@ void babystep_load()
check_babystep(); //checking if babystep is in allowed range, otherwise setting babystep to 0 check_babystep(); //checking if babystep is in allowed range, otherwise setting babystep to 0
// End of G80: Apply the baby stepping value. // End of G80: Apply the baby stepping value.
EEPROM_read_B(EEPROM_BABYSTEP_Z, &babystepLoadZ); babystepLoadZ = eeprom_read_word(reinterpret_cast<uint16_t *>(&(EEPROM_Sheets_base->
s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset)));
#if 0 #if 0
SERIAL_ECHO("Z baby step: "); SERIAL_ECHO("Z baby step: ");
@ -3186,4 +3187,4 @@ void mbl_interpolation(uint8_t meas_points) {
} }
} }
} }
} }

View File

@ -10,7 +10,7 @@
//internationalized messages //internationalized messages
const char MSG_AUTO_HOME[] PROGMEM_I1 = ISTR("Auto home"); //// const char MSG_AUTO_HOME[] PROGMEM_I1 = ISTR("Auto home"); ////
const char MSG_AUTO_MODE_ON[] PROGMEM_I1 = ISTR("Mode [auto power]"); //// const char MSG_AUTO_MODE_ON[] PROGMEM_I1 = ISTR("Mode [auto power]"); ////
const char MSG_BABYSTEP_Z[] PROGMEM_I1 = ISTR("Live adjust Z"); //// const char MSG_BABYSTEP_Z[] PROGMEM_I1 = ISTR("Live adjust Z"); //// c=18
const char MSG_BABYSTEP_Z_NOT_SET[] PROGMEM_I1 = ISTR("Distance between tip of the nozzle and the bed surface has not been set yet. Please follow the manual, chapter First steps, section First layer calibration."); ////c=20 r=12 const char MSG_BABYSTEP_Z_NOT_SET[] PROGMEM_I1 = ISTR("Distance between tip of the nozzle and the bed surface has not been set yet. Please follow the manual, chapter First steps, section First layer calibration."); ////c=20 r=12
const char MSG_BED[] PROGMEM_I1 = ISTR("Bed"); //// const char MSG_BED[] PROGMEM_I1 = ISTR("Bed"); ////
const char MSG_BED_DONE[] PROGMEM_I1 = ISTR("Bed done"); //// const char MSG_BED_DONE[] PROGMEM_I1 = ISTR("Bed done"); ////
@ -55,6 +55,7 @@ const char MSG_CUT_FILAMENT[] PROGMEM_I1 = ISTR("Cut filament"); //// Number 1 t
const char MSG_M117_V2_CALIBRATION[] PROGMEM_I1 = ISTR("M117 First layer cal."); ////c=25 r=1 const char MSG_M117_V2_CALIBRATION[] PROGMEM_I1 = ISTR("M117 First layer cal."); ////c=25 r=1
const char MSG_MAIN[] PROGMEM_I1 = ISTR("Main"); //// const char MSG_MAIN[] PROGMEM_I1 = ISTR("Main"); ////
const char MSG_BACK[] PROGMEM_I1 = ISTR("Back"); //// const char MSG_BACK[] PROGMEM_I1 = ISTR("Back"); ////
const char MSG_SHEET[] PROGMEM_I1 = ISTR("Sheet"); ////c=10
const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1[] PROGMEM_I1 = ISTR("Measuring reference height of calibration point"); ////c=60 const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1[] PROGMEM_I1 = ISTR("Measuring reference height of calibration point"); ////c=60
const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2[] PROGMEM_I1 = ISTR(" of 9"); ////c=14 const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2[] PROGMEM_I1 = ISTR(" of 9"); ////c=14
const char MSG_MENU_CALIBRATION[] PROGMEM_I1 = ISTR("Calibration"); //// const char MSG_MENU_CALIBRATION[] PROGMEM_I1 = ISTR("Calibration"); ////
@ -100,6 +101,7 @@ const char MSG_WIZARD_DONE[] PROGMEM_I1 = ISTR("All is done. Happy printing!");
const char MSG_WIZARD_HEATING[] PROGMEM_I1 = ISTR("Preheating nozzle. Please wait."); ////c=20 r=3 const char MSG_WIZARD_HEATING[] PROGMEM_I1 = ISTR("Preheating nozzle. Please wait."); ////c=20 r=3
const char MSG_WIZARD_QUIT[] PROGMEM_I1 = ISTR("You can always resume the Wizard from Calibration -> Wizard."); ////c=20 r=8 const char MSG_WIZARD_QUIT[] PROGMEM_I1 = ISTR("You can always resume the Wizard from Calibration -> Wizard."); ////c=20 r=8
const char MSG_YES[] PROGMEM_I1 = ISTR("Yes"); //// const char MSG_YES[] PROGMEM_I1 = ISTR("Yes"); ////
const char MSG_V2_CALIBRATION[] PROGMEM_I1 = ISTR("First layer cal."); ////c=17 r=1
const char WELCOME_MSG[] PROGMEM_I1 = ISTR(CUSTOM_MENDEL_NAME " OK."); ////c=20 const char WELCOME_MSG[] PROGMEM_I1 = ISTR(CUSTOM_MENDEL_NAME " OK."); ////c=20
//not internationalized messages //not internationalized messages
const char MSG_SD_WORKDIR_FAIL[] PROGMEM_N1 = "workDir open failed"; //// const char MSG_SD_WORKDIR_FAIL[] PROGMEM_N1 = "workDir open failed"; ////

View File

@ -54,6 +54,7 @@ extern const char MSG_LOADING_FILAMENT[];
extern const char MSG_M117_V2_CALIBRATION[]; extern const char MSG_M117_V2_CALIBRATION[];
extern const char MSG_MAIN[]; extern const char MSG_MAIN[];
extern const char MSG_BACK[]; extern const char MSG_BACK[];
extern const char MSG_SHEET[];
extern const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1[]; extern const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1[];
extern const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2[]; extern const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2[];
extern const char MSG_MENU_CALIBRATION[]; extern const char MSG_MENU_CALIBRATION[];
@ -100,6 +101,7 @@ extern const char MSG_WIZARD_DONE[];
extern const char MSG_WIZARD_HEATING[]; extern const char MSG_WIZARD_HEATING[];
extern const char MSG_WIZARD_QUIT[]; extern const char MSG_WIZARD_QUIT[];
extern const char MSG_YES[]; extern const char MSG_YES[];
extern const char MSG_V2_CALIBRATION[];
extern const char WELCOME_MSG[]; extern const char WELCOME_MSG[];
//not internationalized messages //not internationalized messages
extern const char MSG_BROWNOUT_RESET[]; extern const char MSG_BROWNOUT_RESET[];

101
Firmware/mmu.cpp Normal file → Executable file
View File

@ -83,9 +83,11 @@ uint16_t mmu_power_failures = 0;
#ifdef MMU_DEBUG #ifdef MMU_DEBUG
static const auto DEBUG_PUTCHAR = putchar;
static const auto DEBUG_PUTS_P = puts_P; static const auto DEBUG_PUTS_P = puts_P;
static const auto DEBUG_PRINTF_P = printf_P; static const auto DEBUG_PRINTF_P = printf_P;
#else //MMU_DEBUG #else //MMU_DEBUG
#define DEBUG_PUTCHAR(c)
#define DEBUG_PUTS_P(str) #define DEBUG_PUTS_P(str)
#define DEBUG_PRINTF_P( __fmt, ... ) #define DEBUG_PRINTF_P( __fmt, ... )
#endif //MMU_DEBUG #endif //MMU_DEBUG
@ -1081,7 +1083,7 @@ if(0)
extr_unload(); extr_unload();
} }
else { else {
eFilamentAction=e_FILAMENT_ACTION_mmuUnLoad; eFilamentAction=FilamentAction::MmuUnLoad;
bFilamentFirstRun=false; bFilamentFirstRun=false;
if(target_temperature[0]>=EXTRUDE_MINTEMP) if(target_temperature[0]>=EXTRUDE_MINTEMP)
{ {
@ -1377,13 +1379,13 @@ void lcd_mmu_load_to_nozzle(uint8_t filament_nr)
mmu_load_to_nozzle(); mmu_load_to_nozzle();
load_filament_final_feed(); load_filament_final_feed();
st_synchronize(); st_synchronize();
custom_message_type = CUSTOM_MSG_TYPE_F_LOAD; custom_message_type = CustomMsg::FilamentLoading;
lcd_setstatuspgm(_T(MSG_LOADING_FILAMENT)); lcd_setstatuspgm(_T(MSG_LOADING_FILAMENT));
lcd_return_to_status(); lcd_return_to_status();
lcd_update_enable(true); lcd_update_enable(true);
lcd_load_filament_color_check(); lcd_load_filament_color_check();
lcd_setstatuspgm(_T(WELCOME_MSG)); lcd_setstatuspgm(_T(WELCOME_MSG));
custom_message_type = CUSTOM_MSG_TYPE_STATUS; custom_message_type = CustomMsg::Status;
} }
else else
{ {
@ -1452,26 +1454,69 @@ bFilamentAction=false; // NOT in "mmu_fil_eject_menu(
} }
} }
//! @brief Fits filament tip into heatbreak?
//!
//! If PTFE tube is jammed, this causes filament to be unloaded and no longer
//! being detected by the pulley IR sensor.
//! @retval true Fits
//! @retval false Doesn't fit
static bool can_load()
{
current_position[E_AXIS] += 60;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS],
current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
current_position[E_AXIS] -= 52;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS],
current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
st_synchronize();
uint_least8_t filament_detected_count = 0;
const float e_increment = 0.2;
const uint_least8_t steps = 6.0 / e_increment;
DEBUG_PUTS_P(PSTR("MMU can_load:"));
for(uint_least8_t i = 0; i < steps; ++i)
{
current_position[E_AXIS] -= e_increment;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS],
current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
st_synchronize();
if(0 == PIN_GET(IR_SENSOR_PIN))
{
++filament_detected_count;
DEBUG_PUTCHAR('O');
}
else
{
DEBUG_PUTCHAR('o');
}
}
if (filament_detected_count > steps - 4)
{
DEBUG_PUTS_P(PSTR(" succeeded."));
return true;
}
else
{
DEBUG_PUTS_P(PSTR(" failed."));
return false;
}
}
//! @brief load more //! @brief load more
//! //!
//! Try to feed more filament from MMU if it is not detected by filament sensor. //! Try to feed more filament from MMU if it is not detected by filament sensor.
//! Move filament back and forth to nozzle in order to detect jam. //! @retval true Success, filament detected by IR sensor
//! If PTFE tube is jammed, this cause filament to be unloaded and no longer //! @retval false Failed, filament not detected by IR sensor after maximum number of attempts
//! detected by pulley IR sensor in next step. static bool load_more()
static void load_more()
{ {
for (uint8_t i = 0; i < MMU_IDLER_SENSOR_ATTEMPTS_NR; i++) for (uint8_t i = 0; i < MMU_IDLER_SENSOR_ATTEMPTS_NR; i++)
{ {
if (PIN_GET(IR_SENSOR_PIN) == 0) break; if (PIN_GET(IR_SENSOR_PIN) == 0) return true;
DEBUG_PRINTF_P(PSTR("Additional load attempt nr. %d\n"), i); DEBUG_PRINTF_P(PSTR("Additional load attempt nr. %d\n"), i);
mmu_command(MmuCmd::C0); mmu_command(MmuCmd::C0);
manage_response(true, true, MMU_LOAD_MOVE); manage_response(true, true, MMU_LOAD_MOVE);
} }
current_position[E_AXIS] += 60; return false;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
current_position[E_AXIS] -= 58;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
st_synchronize();
} }
static void increment_load_fail() static void increment_load_fail()
@ -1512,24 +1557,28 @@ void mmu_continue_loading(bool blocking)
return; return;
} }
load_more(); bool success = load_more();
if (success) success = can_load();
enum class Ls : uint_least8_t enum class Ls : uint_least8_t
{ {
enter, Enter,
retry, Retry,
unload, Unload,
}; };
Ls state = Ls::enter; Ls state = Ls::Enter;
while (PIN_GET(IR_SENSOR_PIN) != 0) const uint_least8_t max_retry = 2;
uint_least8_t retry = 0;
while (!success)
{ {
switch (state) switch (state)
{ {
case Ls::enter: case Ls::Enter:
increment_load_fail(); increment_load_fail();
// no break // no break
case Ls::retry: case Ls::Retry:
#ifdef MMU_HAS_CUTTER #ifdef MMU_HAS_CUTTER
if (1 == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED)) if (1 == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED))
{ {
@ -1539,10 +1588,12 @@ void mmu_continue_loading(bool blocking)
#endif //MMU_HAS_CUTTER #endif //MMU_HAS_CUTTER
mmu_command(MmuCmd::T0 + tmp_extruder); mmu_command(MmuCmd::T0 + tmp_extruder);
manage_response(true, true, MMU_TCODE_MOVE); manage_response(true, true, MMU_TCODE_MOVE);
load_more(); success = load_more();
state = Ls::unload; if (success) success = can_load();
++retry; // overflow not handled, as it is not dangerous.
if (retry >= max_retry) state = Ls::Unload;
break; break;
case Ls::unload: case Ls::Unload:
stop_and_save_print_to_ram(0, 0); stop_and_save_print_to_ram(0, 0);
//lift z //lift z
@ -1567,7 +1618,7 @@ void mmu_continue_loading(bool blocking)
{ {
marlin_wait_for_click(); marlin_wait_for_click();
restore_print_from_ram_and_continue(0); restore_print_from_ram_and_continue(0);
state = Ls::retry; state = Ls::Retry;
} }
else else
{ {

View File

@ -4,7 +4,7 @@
#define FIRMWARE_SYSTEM_TIMER_H_ #define FIRMWARE_SYSTEM_TIMER_H_
#include "Arduino.h" #include "Arduino.h"
//#define SYSTEM_TIMER_2 #define SYSTEM_TIMER_2
#ifdef SYSTEM_TIMER_2 #ifdef SYSTEM_TIMER_2
#include "timer02.h" #include "timer02.h"
@ -13,12 +13,15 @@
#define _delay delay2 #define _delay delay2
#define _tone tone2 #define _tone tone2
#define _noTone noTone2 #define _noTone noTone2
#define timer02_set_pwm0(pwm0)
#else //SYSTEM_TIMER_2 #else //SYSTEM_TIMER_2
#define _millis millis #define _millis millis
#define _micros micros #define _micros micros
#define _delay delay #define _delay delay
#define _tone tone #define _tone(x, y) /*tone*/
#define _noTone noTone #define _noTone(x) /*noTone*/
#define timer02_set_pwm0(pwm0) #define timer02_set_pwm0(pwm0)
#endif //SYSTEM_TIMER_2 #endif //SYSTEM_TIMER_2

View File

@ -44,8 +44,6 @@
#include "Timer.h" #include "Timer.h"
#include "Configuration_prusa.h" #include "Configuration_prusa.h"
//=========================================================================== //===========================================================================
//=============================public variables============================ //=============================public variables============================
//=========================================================================== //===========================================================================
@ -1130,18 +1128,9 @@ void tp_init()
adc_init(); adc_init();
#ifdef SYSTEM_TIMER_2 timer0_init();
timer02_init();
OCR2B = 128; OCR2B = 128;
TIMSK2 |= (1<<OCIE2B); TIMSK2 |= (1<<OCIE2B);
#else //SYSTEM_TIMER_2
// Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt
OCR0B = 128;
TIMSK0 |= (1<<OCIE0B);
#endif //SYSTEM_TIMER_2
// Wait for temperature measurement to settle // Wait for temperature measurement to settle
_delay(250); _delay(250);
@ -1472,8 +1461,8 @@ void disable_heater()
target_temperature_bed=0; target_temperature_bed=0;
soft_pwm_bed=0; soft_pwm_bed=0;
timer02_set_pwm0(soft_pwm_bed << 1); timer02_set_pwm0(soft_pwm_bed << 1);
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
WRITE(HEATER_BED_PIN,LOW); //WRITE(HEATER_BED_PIN,LOW);
#endif #endif
#endif #endif
} }
@ -1544,7 +1533,7 @@ void min_temp_error(uint8_t e) {
void bed_max_temp_error(void) { void bed_max_temp_error(void) {
#if HEATER_BED_PIN > -1 #if HEATER_BED_PIN > -1
WRITE(HEATER_BED_PIN, 0); //WRITE(HEATER_BED_PIN, 0);
#endif #endif
if(IsStopped() == false) { if(IsStopped() == false) {
SERIAL_ERROR_START; SERIAL_ERROR_START;
@ -1563,7 +1552,7 @@ void bed_min_temp_error(void) {
#endif #endif
//if (current_temperature_ambient < MINTEMP_MINAMBIENT) return; //if (current_temperature_ambient < MINTEMP_MINAMBIENT) return;
#if HEATER_BED_PIN > -1 #if HEATER_BED_PIN > -1
WRITE(HEATER_BED_PIN, 0); //WRITE(HEATER_BED_PIN, 0);
#endif #endif
static const char err[] PROGMEM = "Err: MINTEMP BED"; static const char err[] PROGMEM = "Err: MINTEMP BED";
if(IsStopped() == false) { if(IsStopped() == false) {
@ -1660,7 +1649,6 @@ void adc_ready(void) //callback from adc when sampling finished
} // extern "C" } // extern "C"
// Timer2 (originaly timer0) is shared with millies // Timer2 (originaly timer0) is shared with millies
#ifdef SYSTEM_TIMER_2 #ifdef SYSTEM_TIMER_2
ISR(TIMER2_COMPB_vect) ISR(TIMER2_COMPB_vect)
@ -1676,8 +1664,8 @@ ISR(TIMER0_COMPB_vect)
if (!temp_meas_ready) adc_cycle(); if (!temp_meas_ready) adc_cycle();
lcd_buttons_update(); lcd_buttons_update();
static unsigned char pwm_count = (1 << SOFT_PWM_SCALE); static uint8_t pwm_count = (1 << SOFT_PWM_SCALE);
static unsigned char soft_pwm_0; static uint8_t soft_pwm_0;
#ifdef SLOW_PWM_HEATERS #ifdef SLOW_PWM_HEATERS
static unsigned char slow_pwm_count = 0; static unsigned char slow_pwm_count = 0;
static unsigned char state_heater_0 = 0; static unsigned char state_heater_0 = 0;
@ -1698,7 +1686,7 @@ ISR(TIMER0_COMPB_vect)
#endif #endif
#endif #endif
#if HEATER_BED_PIN > -1 #if HEATER_BED_PIN > -1
static unsigned char soft_pwm_b; // @@DR static unsigned char soft_pwm_b;
#ifdef SLOW_PWM_HEATERS #ifdef SLOW_PWM_HEATERS
static unsigned char state_heater_b = 0; static unsigned char state_heater_b = 0;
static unsigned char state_timer_heater_b = 0; static unsigned char state_timer_heater_b = 0;
@ -1733,14 +1721,25 @@ ISR(TIMER0_COMPB_vect)
#endif #endif
} }
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
#if 0 // @@DR vypnuto pro hw pwm bedu
// tuhle prasarnu bude potreba poustet ve stanovenych intervalech, jinak nemam moc sanci zareagovat
// teoreticky by se tato cast uz vubec nemusela poustet
if ((pwm_count & ((1 << HEATER_BED_SOFT_PWM_BITS) - 1)) == 0) if ((pwm_count & ((1 << HEATER_BED_SOFT_PWM_BITS) - 1)) == 0)
{ {
soft_pwm_b = soft_pwm_bed >> (7 - HEATER_BED_SOFT_PWM_BITS); soft_pwm_b = soft_pwm_bed >> (7 - HEATER_BED_SOFT_PWM_BITS);
#ifndef SYSTEM_TIMER_2 # ifndef SYSTEM_TIMER_2
if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0); // tady budu krokovat pomalou frekvenci na automatu - tohle je rizeni spinani a rozepinani
#endif //SYSTEM_TIMER_2 // jako ridici frekvenci mam 2khz, jako vystupni frekvenci mam 30hz
// 2kHz jsou ovsem ve slysitelnem pasmu, mozna bude potreba jit s frekvenci nahoru (a tomu taky prizpusobit ostatni veci)
// Teoreticky bych mohl stahnout OCR0B citac na 6, cimz bych se dostal nekam ke 40khz a tady potom honit PWM rychleji nebo i pomaleji
// to nicemu nevadi. Soft PWM scale by se 20x zvetsilo (no dobre, 16x), cimz by se to posunulo k puvodnimu 30Hz PWM
//if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0);
# endif //SYSTEM_TIMER_2
} }
#endif #endif
#endif
#ifdef FAN_SOFT_PWM #ifdef FAN_SOFT_PWM
if ((pwm_count & ((1 << FAN_SOFT_PWM_BITS) - 1)) == 0) if ((pwm_count & ((1 << FAN_SOFT_PWM_BITS) - 1)) == 0)
{ {
@ -1762,8 +1761,14 @@ ISR(TIMER0_COMPB_vect)
#if EXTRUDERS > 2 #if EXTRUDERS > 2
if(soft_pwm_2 < pwm_count) WRITE(HEATER_2_PIN,0); if(soft_pwm_2 < pwm_count) WRITE(HEATER_2_PIN,0);
#endif #endif
#if 0 // @@DR
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1 #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
if (soft_pwm_b < (pwm_count & ((1 << HEATER_BED_SOFT_PWM_BITS) - 1))) WRITE(HEATER_BED_PIN,0); if (soft_pwm_b < (pwm_count & ((1 << HEATER_BED_SOFT_PWM_BITS) - 1))){
//WRITE(HEATER_BED_PIN,0);
}
//WRITE(HEATER_BED_PIN, pwm_count & 1 );
#endif
#endif #endif
#ifdef FAN_SOFT_PWM #ifdef FAN_SOFT_PWM
if (soft_pwm_fan < (pwm_count & ((1 << FAN_SOFT_PWM_BITS) - 1))) WRITE(FAN_PIN,0); if (soft_pwm_fan < (pwm_count & ((1 << FAN_SOFT_PWM_BITS) - 1))) WRITE(FAN_PIN,0);
@ -2053,8 +2058,8 @@ void check_max_temp()
struct alert_automaton_mintemp { struct alert_automaton_mintemp {
private: private:
enum { ALERT_AUTOMATON_SPEED_DIV = 5 }; enum { ALERT_AUTOMATON_SPEED_DIV = 5 };
enum class States : uint8_t { INIT = 0, TEMP_ABOVE_MINTEMP, SHOW_PLEASE_RESTART, SHOW_MINTEMP }; enum class States : uint8_t { Init = 0, TempAboveMintemp, ShowPleaseRestart, ShowMintemp };
States state = States::INIT; States state = States::Init;
uint8_t repeat = ALERT_AUTOMATON_SPEED_DIV; uint8_t repeat = ALERT_AUTOMATON_SPEED_DIV;
void substep(States next_state){ void substep(States next_state){
@ -2073,26 +2078,26 @@ public:
static const char m2[] PROGMEM = "MINTEMP fixed"; static const char m2[] PROGMEM = "MINTEMP fixed";
static const char m1[] PROGMEM = "Please restart"; static const char m1[] PROGMEM = "Please restart";
switch(state){ switch(state){
case States::INIT: // initial state - check hysteresis case States::Init: // initial state - check hysteresis
if( current_temp > mintemp ){ if( current_temp > mintemp ){
state = States::TEMP_ABOVE_MINTEMP; state = States::TempAboveMintemp;
} }
// otherwise keep the Err MINTEMP alert message on the display, // otherwise keep the Err MINTEMP alert message on the display,
// i.e. do not transfer to state 1 // i.e. do not transfer to state 1
break; break;
case States::TEMP_ABOVE_MINTEMP: // the temperature has risen above the hysteresis check case States::TempAboveMintemp: // the temperature has risen above the hysteresis check
lcd_setalertstatuspgm(m2); lcd_setalertstatuspgm(m2);
substep(States::SHOW_MINTEMP); substep(States::ShowMintemp);
last_alert_sent_to_lcd = LCDALERT_MINTEMPFIXED; last_alert_sent_to_lcd = LCDALERT_MINTEMPFIXED;
break; break;
case States::SHOW_PLEASE_RESTART: // displaying "Please restart" case States::ShowPleaseRestart: // displaying "Please restart"
lcd_updatestatuspgm(m1); lcd_updatestatuspgm(m1);
substep(States::SHOW_MINTEMP); substep(States::ShowMintemp);
last_alert_sent_to_lcd = LCDALERT_PLEASERESTART; last_alert_sent_to_lcd = LCDALERT_PLEASERESTART;
break; break;
case States::SHOW_MINTEMP: // displaying "MINTEMP fixed" case States::ShowMintemp: // displaying "MINTEMP fixed"
lcd_updatestatuspgm(m2); lcd_updatestatuspgm(m2);
substep(States::SHOW_PLEASE_RESTART); substep(States::ShowPleaseRestart);
last_alert_sent_to_lcd = LCDALERT_MINTEMPFIXED; last_alert_sent_to_lcd = LCDALERT_MINTEMPFIXED;
break; break;
} }

View File

@ -9,48 +9,27 @@
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include "Arduino.h"
#include "io_atmega2560.h" #include "io_atmega2560.h"
#define BEEPER 84 #define BEEPER 84
uint8_t timer02_pwm0 = 0; void timer0_init(void)
void timer02_set_pwm0(uint8_t pwm0)
{
if (timer02_pwm0 == pwm0) return;
if (pwm0)
{
TCCR0A |= (2 << COM0B0);
OCR0B = pwm0 - 1;
}
else
{
TCCR0A &= ~(2 << COM0B0);
OCR0B = 0;
}
timer02_pwm0 = pwm0;
}
void timer02_init(void)
{ {
//save sreg //save sreg
uint8_t _sreg = SREG; uint8_t _sreg = SREG;
//disable interrupts for sure //disable interrupts for sure
cli(); cli();
//mask timer0 interrupts - disable all
TIMSK0 &= ~(1<<TOIE0); TCNT0 = 0;
TIMSK0 &= ~(1<<OCIE0A); // Fast PWM duty (0-255).
TIMSK0 &= ~(1<<OCIE0B); // Due to invert mode (following rows) the duty is set to 255, which means zero all the time (bed not heating)
//setup timer0 OCR0B = 255;
TCCR0A = 0x00; //COM_A-B=00, WGM_0-1=00 // Set fast PWM mode and inverting mode.
TCCR0B = (1 << CS00); //WGM_2=0, CS_0-2=011 TCCR0A = (1 << WGM01) | (1 << WGM00) | (1 << COM0B1) | (1 << COM0B0);
//switch timer0 to fast pwm mode TCCR0B = (1 << CS00); // no clock prescaling
TCCR0A |= (3 << WGM00); //WGM_0-1=11 TIMSK0 |= (1 << TOIE0); // enable timer overflow interrupt
//set OCR0B register to zero
OCR0B = 0; // Everything, that used to be on timer0 was moved to timer2 (delay, beeping, millis etc.)
//disable OCR0B output (will be enabled in timer02_set_pwm0)
TCCR0A &= ~(2 << COM0B0);
//setup timer2 //setup timer2
TCCR2A = 0x00; //COM_A-B=00, WGM_0-1=00 TCCR2A = 0x00; //COM_A-B=00, WGM_0-1=00
TCCR2B = (4 << CS20); //WGM_2=0, CS_0-2=011 TCCR2B = (4 << CS20); //WGM_2=0, CS_0-2=011
@ -66,11 +45,9 @@ void timer02_init(void)
} }
//following code is OVF handler for timer 2 // The following code is OVF handler for timer 2
//it is copy-paste from wiring.c and modified for timer2 // it was copy-pasted from wiring.c and modified for timer2
//variables timer0_overflow_count and timer0_millis are declared in wiring.c // variables timer0_overflow_count and timer0_millis are declared in wiring.c
// the prescaler is set so that timer0 ticks every 64 clock cycles, and the // the prescaler is set so that timer0 ticks every 64 clock cycles, and the
// the overflow handler is called every 256 ticks. // the overflow handler is called every 256 ticks.
@ -85,9 +62,6 @@ void timer02_init(void)
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3) #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
#define FRACT_MAX (1000 >> 3) #define FRACT_MAX (1000 >> 3)
//extern volatile unsigned long timer0_overflow_count;
//extern volatile unsigned long timer0_millis;
//unsigned char timer0_fract = 0;
volatile unsigned long timer2_overflow_count; volatile unsigned long timer2_overflow_count;
volatile unsigned long timer2_millis; volatile unsigned long timer2_millis;
unsigned char timer2_fract = 0; unsigned char timer2_fract = 0;

View File

@ -11,24 +11,25 @@
extern "C" { extern "C" {
#endif //defined(__cplusplus) #endif //defined(__cplusplus)
///! Initializes TIMER0 for fast PWM mode-driven bed heating
extern void timer0_init(void);
extern uint8_t timer02_pwm0; ///! Reimplemented original millis() using timer2
extern void timer02_set_pwm0(uint8_t pwm0);
extern void timer02_init(void);
extern unsigned long millis2(void); extern unsigned long millis2(void);
///! Reimplemented original micros() using timer2
extern unsigned long micros2(void); extern unsigned long micros2(void);
///! Reimplemented original delay() using timer2
extern void delay2(unsigned long ms); extern void delay2(unsigned long ms);
///! Reimplemented original tone() using timer2
///! Does not perform any PWM tone generation, it just sets the beeper pin to 1
extern void tone2(uint8_t _pin, unsigned int frequency/*, unsigned long duration*/); extern void tone2(uint8_t _pin, unsigned int frequency/*, unsigned long duration*/);
///! Turn off beeping - set beeper pin to 0
extern void noTone2(uint8_t _pin); extern void noTone2(uint8_t _pin);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif //defined(__cplusplus) #endif //defined(__cplusplus)

File diff suppressed because it is too large Load Diff

View File

@ -89,31 +89,37 @@ extern void lcd_diag_show_end_stops();
// To be used in lcd_commands_type. // To be used in lcd_commands_type.
#define LCD_COMMAND_IDLE 0 enum class LcdCommands : uint_least8_t
#define LCD_COMMAND_LOAD_FILAMENT 1 {
#define LCD_COMMAND_STOP_PRINT 2 Idle,
#define LCD_COMMAND_FARM_MODE_CONFIRM 4 LoadFilament,
#define LCD_COMMAND_LONG_PAUSE 5 StopPrint,
#define LCD_COMMAND_PID_EXTRUDER 7 FarmModeConfirm,
#define LCD_COMMAND_V2_CAL 8 LongPause,
PidExtruder,
Layer1Cal,
};
extern uint8_t lcd_commands_type; extern LcdCommands lcd_commands_type;
extern int8_t FSensorStateMenu; extern int8_t FSensorStateMenu;
#define CUSTOM_MSG_TYPE_STATUS 0 // status message from lcd_status_message variable enum class CustomMsg : uint_least8_t
#define CUSTOM_MSG_TYPE_MESHBL 1 // Mesh bed leveling in progress {
#define CUSTOM_MSG_TYPE_F_LOAD 2 // Loading filament in progress Status, //!< status message from lcd_status_message variable
#define CUSTOM_MSG_TYPE_PIDCAL 3 // PID tuning in progress MeshBedLeveling, //!< Mesh bed leveling in progress
#define CUSTOM_MSG_TYPE_TEMCAL 4 // PINDA temp calibration FilamentLoading, //!< Loading filament in progress
#define CUSTOM_MSG_TYPE_TEMPRE 5 // Temp compensation preheat PidCal, //!< PID tuning in progress
TempCal, //!< PINDA temperature calibration
TempCompPreheat, //!< Temperature compensation preheat
};
extern unsigned int custom_message_type; extern CustomMsg custom_message_type;
extern unsigned int custom_message_state; extern unsigned int custom_message_state;
extern uint8_t farm_mode; extern uint8_t farm_mode;
extern int farm_no; extern int farm_no;
extern int farm_timer; extern int farm_timer;
extern int farm_status; extern uint8_t farm_status;
#ifdef TMC2130 #ifdef TMC2130
#define SILENT_MODE_NORMAL 0 #define SILENT_MODE_NORMAL 0
@ -148,18 +154,19 @@ void extr_unload_used();
#endif //SNMM #endif //SNMM
void extr_unload(); void extr_unload();
typedef enum enum class FilamentAction : uint_least8_t
{ {
e_FILAMENT_ACTION_none, //!< 'none' state is used as flag for (filament) autoLoad (i.e. opposite for 'autoLoad' state) None, //!< 'none' state is used as flag for (filament) autoLoad (i.e. opposite for 'autoLoad' state)
e_FILAMENT_ACTION_Load, Load,
e_FILAMENT_ACTION_autoLoad, AutoLoad,
e_FILAMENT_ACTION_unLoad, UnLoad,
e_FILAMENT_ACTION_mmuLoad, MmuLoad,
e_FILAMENT_ACTION_mmuUnLoad, MmuUnLoad,
e_FILAMENT_ACTION_mmuEject, MmuEject,
e_FILAMENT_ACTION_mmuCut MmuCut,
} eFILAMENT_ACTION; };
extern eFILAMENT_ACTION eFilamentAction;
extern FilamentAction eFilamentAction;
extern bool bFilamentFirstRun; extern bool bFilamentFirstRun;
extern bool bFilamentPreheatState; extern bool bFilamentPreheatState;
extern bool bFilamentAction; extern bool bFilamentAction;

View File

@ -304,7 +304,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
_tone(BEEPER, 1000); _tone(BEEPER, 1000);
delay_keep_alive(50); delay_keep_alive(50);
_noTone(BEEPER); _noTone(BEEPER);
lcd_wait_for_click(); lcd_wait_for_click_delay(30);
lcd_update_enable(true); lcd_update_enable(true);
lcd_clear(); lcd_clear();
lcd_update(0); lcd_update(0);

View File

@ -426,14 +426,14 @@ do
sleep 2 sleep 2
#$BUILDER -dump-prefs -logger=machine -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=rambo:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=none -quiet $SCRIPT_PATH/Firmware/Firmware.ino || exit 12 #$BUILDER -dump-prefs -logger=machine -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=rambo:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=none -quiet $SCRIPT_PATH/Firmware/Firmware.ino || exit 12
#$BUILDER -compile -logger=machine -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=rambo:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=none -quiet $SCRIPT_PATH/Firmware/Firmware.ino || exit 13 #$BUILDER -compile -logger=machine -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=rambo:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=none -quiet $SCRIPT_PATH/Firmware/Firmware.ino || exit 13
$BUILDER -compile -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=rambo:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=default $SCRIPT_PATH/Firmware/Firmware.ino || exit 14 $BUILDER -compile -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=rambo:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=all $SCRIPT_PATH/Firmware/Firmware.ino || exit 14
echo "$(tput sgr 0)" echo "$(tput sgr 0)"
fi fi
if [ $OSTYPE == "linux-gnu" ] ; then if [ $OSTYPE == "linux-gnu" ] ; then
echo "Start to build Prusa Firmware under Linux 64..." echo "Start to build Prusa Firmware under Linux 64..."
echo "Using variant $VARIANT$(tput setaf 3)" echo "Using variant $VARIANT$(tput setaf 3)"
sleep 2 sleep 2
$BUILD_ENV_PATH/arduino $SCRIPT_PATH/Firmware/Firmware.ino --verify --board rambo:avr:rambo --pref build.path=$BUILD_PATH || exit 14 $BUILD_ENV_PATH/arduino $SCRIPT_PATH/Firmware/Firmware.ino --verify --board rambo:avr:rambo --pref build.path=$BUILD_PATH --pref compiler.warning_level=all || exit 14
echo "$(tput sgr 0)" echo "$(tput sgr 0)"
fi fi

View File

@ -14,8 +14,8 @@
# Build # Build
## Linux ## Linux
Run shell script build.sh to build for MK3 and flash with Sli3er. Run shell script build.sh to build for MK3 and flash with Slic3er.
If you have different printel model, follow step [2.b](#2b) from Windows build first. If you have a different printer model, follow step [2.b](#2b) from Windows build first.
If you wish to flash from Arduino, follow step [2.c](#2c) from Windows build first. If you wish to flash from Arduino, follow step [2.c](#2c) from Windows build first.
The script downloads Arduino with our modifications and Rambo board support installed, unpacks it into folder PF-build-env-\<version\> on the same level, as your Prusa-Firmware folder is located, builds firmware for MK3 using that Arduino in Prusa-Firmware-build folder on the same level as Prusa-Firmware, runs secondary language support scripts. Firmware with secondary language support is generated in lang subfolder. Use firmware.hex for MK3 variant. Use firmware_\<lang\>.hex for other printers. Don't forget to follow step [2.b](#2b) first for non-MK3 printers. The script downloads Arduino with our modifications and Rambo board support installed, unpacks it into folder PF-build-env-\<version\> on the same level, as your Prusa-Firmware folder is located, builds firmware for MK3 using that Arduino in Prusa-Firmware-build folder on the same level as Prusa-Firmware, runs secondary language support scripts. Firmware with secondary language support is generated in lang subfolder. Use firmware.hex for MK3 variant. Use firmware_\<lang\>.hex for other printers. Don't forget to follow step [2.b](#2b) first for non-MK3 printers.
@ -40,11 +40,11 @@ type location
or you can 'manually' modify the item or you can 'manually' modify the item
`"boardsmanager.additional.urls=....."` `"boardsmanager.additional.urls=....."`
at the file `"preferences.txt"` (this parameter allows you to write a comma-separated list of addresses) at the file `"preferences.txt"` (this parameter allows you to write a comma-separated list of addresses)
_note: you can find location of this file on your disk by following way: _note: you can find location of this file on your disk by doing the following:
`File->Preferences->Settings` (`"More preferences can be edited in file ..."`)_ `File->Preferences->Settings` (`"More preferences can be edited in file ..."`)_
than do it then choose
`Tools->Board->BoardsManager` `Tools->Board->BoardsManager`
from viewed list select an item `"RAMBo"` (will probably be labeled as `"RepRap Arduino-compatible Mother Board (RAMBo) by UltiMachine"` from viewed list and select the item labeled `"RAMBo"` (will probably be labeled as `"RepRap Arduino-compatible Mother Board (RAMBo) by UltiMachine"`
_note: select this item for any variant of board used in printers `'Prusa i3 MKx'`, that is for `RAMBo-mini x.y` and `EINSy x.y` to_ _note: select this item for any variant of board used in printers `'Prusa i3 MKx'`, that is for `RAMBo-mini x.y` and `EINSy x.y` to_
'clicking' the item will display the installation button; select choice `"1.0.1"` from the list(last known version as of the date of issue of this document) 'clicking' the item will display the installation button; select choice `"1.0.1"` from the list(last known version as of the date of issue of this document)
_(after installation, the item is labeled as `"INSTALLED"` and can then be used for target board selection)_ _(after installation, the item is labeled as `"INSTALLED"` and can then be used for target board selection)_
@ -66,7 +66,7 @@ b.<a name="2b"></a> In the subdirectory `"Firmware/variants/"` select the config
c.<a name="2c"></a> In file `"Firmware/config.h"` set LANG_MODE to 0. c.<a name="2c"></a> In file `"Firmware/config.h"` set LANG_MODE to 0.
run `"Arduino IDE"`; select the file `"Firmware.ino"` from the subdirectory `"Firmware/"` at the location, where you placed the source codes run `"Arduino IDE"`; select the file `"Firmware.ino"` from the subdirectory `"Firmware/"` at the location, where you placed the source code
`File->Open` `File->Open`
make the desired code customizations; **all changes are on your own risk!** make the desired code customizations; **all changes are on your own risk!**
@ -146,7 +146,7 @@ cmake
build system - ninja or gnu make build system - ninja or gnu make
## Building ## Building
Create folder where you want to build tests. Create a folder where you want to build tests.
Example: Example:

View File

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
BUILD_ENV="1.0.2" BUILD_ENV="1.0.6"
SCRIPT_PATH="$( cd "$(dirname "$0")" ; pwd -P )" SCRIPT_PATH="$( cd "$(dirname "$0")" ; pwd -P )"
if [ ! -d "build-env" ]; then if [ ! -d "build-env" ]; then
@ -31,7 +31,7 @@ if [ ! -f "$SCRIPT_PATH/Firmware/Configuration_prusa.h" ]; then
cp $SCRIPT_PATH/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h $SCRIPT_PATH/Firmware/Configuration_prusa.h || exit 8 cp $SCRIPT_PATH/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h $SCRIPT_PATH/Firmware/Configuration_prusa.h || exit 8
fi fi
$BUILD_ENV_PATH/arduino $SCRIPT_PATH/Firmware/Firmware.ino --verify --board rambo:avr:rambo --pref build.path=$BUILD_PATH --pref compiler.warning_level=all || exit 9 $BUILD_ENV_PATH/arduino $SCRIPT_PATH/Firmware/Firmware.ino --verify --board PrusaResearchRambo:avr:rambo --pref build.path=$BUILD_PATH --pref compiler.warning_level=all || exit 9
export ARDUINO=$BUILD_ENV_PATH export ARDUINO=$BUILD_ENV_PATH

View File

@ -82,7 +82,7 @@ generate_binary()
rm -f lang_$1.dat rm -f lang_$1.dat
LNG=$1 LNG=$1
#check lang dictionary #check lang dictionary
/usr/bin/env python lang-check.py $1 /usr/bin/env python lang-check.py $1 --no-warning
#create lang_xx.tmp - different processing for 'en' language #create lang_xx.tmp - different processing for 'en' language
if [ "$1" = "en" ]; then if [ "$1" = "en" ]; then
#remove comments and empty lines #remove comments and empty lines

View File

@ -38,7 +38,7 @@ def parse_txt(lang, no_warning):
if rows is None: if rows is None:
rows = 1 rows = 1
if len(translation) > cols*rows: if len(translation)-2 > cols*rows:
stderr.write( stderr.write(
"[E]: Text %s is longer then definiton on line %d\n" % "[E]: Text %s is longer then definiton on line %d\n" %
(translation, lines)) (translation, lines))
@ -56,7 +56,7 @@ def main():
usage="$(prog)s lang") usage="$(prog)s lang")
parser.add_argument( parser.add_argument(
"lang", nargs='?', default="en", type=str, "lang", nargs='?', default="en", type=str,
help="Check lang file (en|cs|de|es|fr|it)") help="Check lang file (en|cs|de|es|fr|it|pl)")
parser.add_argument( parser.add_argument(
"--no-warning", action="store_true", "--no-warning", action="store_true",
help="Disable warnings") help="Disable warnings")