Merge remote-tracking branch 'upstream/MK3_3.10.0' into PFW-1189
This commit is contained in:
commit
681bc560c9
@ -16,8 +16,8 @@ extern uint16_t nPrinterType;
|
||||
extern PGM_P sPrinterName;
|
||||
|
||||
// Firmware version
|
||||
#define FW_VERSION "3.10.0-RC1"
|
||||
#define FW_COMMIT_NR 4078
|
||||
#define FW_VERSION "3.10.0-RC2"
|
||||
#define FW_COMMIT_NR 4104
|
||||
// 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
|
||||
@ -551,9 +551,10 @@ enum CalibrationStatus
|
||||
|
||||
// Try to maintain a minimum distance from the bed even when Z is
|
||||
// unknown when doing the following operations
|
||||
#define MIN_Z_FOR_LOAD 50
|
||||
#define MIN_Z_FOR_UNLOAD 50
|
||||
#define MIN_Z_FOR_PREHEAT 10
|
||||
#define MIN_Z_FOR_LOAD 50 // lcd filament loading or autoload
|
||||
#define MIN_Z_FOR_UNLOAD 50 // lcd filament unloading
|
||||
#define MIN_Z_FOR_SWAP 27 // filament change (including M600)
|
||||
#define MIN_Z_FOR_PREHEAT 10 // lcd preheat
|
||||
|
||||
#include "Configuration_adv.h"
|
||||
#include "thermistortables.h"
|
||||
|
@ -387,6 +387,12 @@ const unsigned int dropsegments=5; //everything with less than this number of st
|
||||
*/
|
||||
#define EXTENDED_CAPABILITIES_REPORT
|
||||
|
||||
/**
|
||||
* Enable M120/M121 G-code commands
|
||||
*
|
||||
*/
|
||||
//#define M120_M121_ENABLED //Be careful enabling and using these G-code commands.
|
||||
|
||||
//===========================================================================
|
||||
//============================= Define Defines ============================
|
||||
//===========================================================================
|
||||
|
@ -103,10 +103,10 @@
|
||||
#include "tmc2130.h"
|
||||
#endif //TMC2130
|
||||
|
||||
#ifdef W25X20CL
|
||||
#include "w25x20cl.h"
|
||||
#include "optiboot_w25x20cl.h"
|
||||
#endif //W25X20CL
|
||||
#ifdef XFLASH
|
||||
#include "xflash.h"
|
||||
#include "optiboot_xflash.h"
|
||||
#endif //XFLASH
|
||||
|
||||
#ifdef BLINKM
|
||||
#include "BlinkM.h"
|
||||
@ -219,7 +219,7 @@ unsigned int heating_status;
|
||||
unsigned int heating_status_counter;
|
||||
bool loading_flag = false;
|
||||
|
||||
|
||||
#define XY_NO_RESTORE_FLAG (mesh_bed_leveling_flag || homing_flag)
|
||||
|
||||
char snmm_filaments_used = 0;
|
||||
|
||||
@ -305,7 +305,12 @@ bool no_response = false;
|
||||
uint8_t important_status;
|
||||
uint8_t saved_filament_type;
|
||||
|
||||
#define SAVED_TARGET_UNSET (X_MIN_POS-1)
|
||||
// Define some coordinates outside the clamp limits (making them invalid past the parsing stage) so
|
||||
// that they can be used later for various logical checks
|
||||
#define X_COORD_INVALID (X_MIN_POS-1)
|
||||
#define Y_COORD_INVALID (Y_MIN_POS-1)
|
||||
|
||||
#define SAVED_TARGET_UNSET X_COORD_INVALID
|
||||
float saved_target[NUM_AXIS] = {SAVED_TARGET_UNSET, 0, 0, 0};
|
||||
|
||||
// save/restore printing in case that mmu was not responding
|
||||
@ -375,7 +380,7 @@ boolean chdkActive = false;
|
||||
bool saved_printing = false; //!< Print is paused and saved in RAM
|
||||
static uint32_t saved_sdpos = 0; //!< SD card position, or line number in case of USB printing
|
||||
uint8_t saved_printing_type = PRINTING_TYPE_SD;
|
||||
static float saved_pos[4] = { 0, 0, 0, 0 };
|
||||
static float saved_pos[4] = { X_COORD_INVALID, 0, 0, 0 };
|
||||
static uint16_t saved_feedrate2 = 0; //!< Default feedrate (truncated from float)
|
||||
static int saved_feedmultiply2 = 0;
|
||||
static uint8_t saved_active_extruder = 0;
|
||||
@ -588,19 +593,6 @@ void crashdet_restore_print_and_continue()
|
||||
// babystep_apply();
|
||||
}
|
||||
|
||||
|
||||
void crashdet_stop_and_save_print2()
|
||||
{
|
||||
cli();
|
||||
planner_abort_hard(); //abort printing
|
||||
cmdqueue_reset(); //empty cmdqueue
|
||||
card.sdprinting = false;
|
||||
card.closefile();
|
||||
// Reset and re-enable the stepper timer just before the global interrupts are enabled.
|
||||
st_reset_timer();
|
||||
sei();
|
||||
}
|
||||
|
||||
void crashdet_detected(uint8_t mask)
|
||||
{
|
||||
st_synchronize();
|
||||
@ -910,7 +902,7 @@ uint8_t check_printer_version()
|
||||
|
||||
#if (LANG_MODE != 0) //secondary language support
|
||||
|
||||
#ifdef W25X20CL
|
||||
#ifdef XFLASH
|
||||
|
||||
|
||||
// language update from external flash
|
||||
@ -936,7 +928,7 @@ void update_sec_lang_from_external_flash()
|
||||
cli();
|
||||
uint16_t size = header.size - state * LANGBOOT_BLOCKSIZE;
|
||||
if (size > LANGBOOT_BLOCKSIZE) size = LANGBOOT_BLOCKSIZE;
|
||||
w25x20cl_rd_data(src_addr + state * LANGBOOT_BLOCKSIZE, (uint8_t*)LANGBOOT_RAMBUFFER, size);
|
||||
xflash_rd_data(src_addr + state * LANGBOOT_BLOCKSIZE, (uint8_t*)LANGBOOT_RAMBUFFER, size);
|
||||
if (state == 0)
|
||||
{
|
||||
//TODO - check header integrity
|
||||
@ -954,7 +946,7 @@ void update_sec_lang_from_external_flash()
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_W25X20CL
|
||||
#ifdef DEBUG_XFLASH
|
||||
|
||||
uint8_t lang_xflash_enum_codes(uint16_t* codes)
|
||||
{
|
||||
@ -964,7 +956,7 @@ uint8_t lang_xflash_enum_codes(uint16_t* codes)
|
||||
while (1)
|
||||
{
|
||||
printf_P(_n("LANGTABLE%d:"), count);
|
||||
w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t));
|
||||
xflash_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t));
|
||||
if (header.magic != LANG_MAGIC)
|
||||
{
|
||||
puts_P(_n("NG!"));
|
||||
@ -992,17 +984,17 @@ void list_sec_lang_from_external_flash()
|
||||
printf_P(_n("XFlash lang count = %hhd\n"), count);
|
||||
}
|
||||
|
||||
#endif //DEBUG_W25X20CL
|
||||
#endif //DEBUG_XFLASH
|
||||
|
||||
#endif //W25X20CL
|
||||
#endif //XFLASH
|
||||
|
||||
#endif //(LANG_MODE != 0)
|
||||
|
||||
|
||||
static void w25x20cl_err_msg()
|
||||
static void xflash_err_msg()
|
||||
{
|
||||
lcd_clear();
|
||||
lcd_puts_P(_n("External SPI flash\nW25X20CL is not res-\nponding. Language\nswitch unavailable."));
|
||||
lcd_puts_P(_n("External SPI flash\nXFLASH is not res-\nponding. Language\nswitch unavailable."));
|
||||
}
|
||||
|
||||
// "Setup" function is called by the Arduino framework on startup.
|
||||
@ -1028,23 +1020,23 @@ void setup()
|
||||
fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream
|
||||
stdout = uartout;
|
||||
|
||||
#ifdef W25X20CL
|
||||
bool w25x20cl_success = w25x20cl_init();
|
||||
#ifdef XFLASH
|
||||
bool xflash_success = xflash_init();
|
||||
uint8_t optiboot_status = 1;
|
||||
if (w25x20cl_success)
|
||||
if (xflash_success)
|
||||
{
|
||||
optiboot_status = optiboot_w25x20cl_enter();
|
||||
optiboot_status = optiboot_xflash_enter();
|
||||
#if (LANG_MODE != 0) //secondary language support
|
||||
update_sec_lang_from_external_flash();
|
||||
#endif //(LANG_MODE != 0)
|
||||
}
|
||||
else
|
||||
{
|
||||
w25x20cl_err_msg();
|
||||
xflash_err_msg();
|
||||
}
|
||||
#else
|
||||
const bool w25x20cl_success = true;
|
||||
#endif //W25X20CL
|
||||
const bool xflash_success = true;
|
||||
#endif //XFLASH
|
||||
|
||||
|
||||
setup_killpin();
|
||||
@ -1091,7 +1083,7 @@ void setup()
|
||||
}
|
||||
|
||||
|
||||
#ifndef W25X20CL
|
||||
#ifndef XFLASH
|
||||
SERIAL_PROTOCOLLNPGM("start");
|
||||
#else
|
||||
if ((optiboot_status != 0) || (selectedSerialPort != 0))
|
||||
@ -1172,7 +1164,7 @@ void setup()
|
||||
#undef LT_PRINT_TEST
|
||||
|
||||
#if 0
|
||||
w25x20cl_rd_data(0x25ba, (uint8_t*)&block_buffer, 1024);
|
||||
xflash_rd_data(0x25ba, (uint8_t*)&block_buffer, 1024);
|
||||
for (uint16_t i = 0; i < 1024; i++)
|
||||
{
|
||||
if ((i % 16) == 0) printf_P(_n("%04x:"), 0x25ba+i);
|
||||
@ -1269,11 +1261,11 @@ void setup()
|
||||
|
||||
tp_init(); // Initialize temperature loop
|
||||
|
||||
if (w25x20cl_success) lcd_splash(); // we need to do this again, because tp_init() kills lcd
|
||||
if (xflash_success) lcd_splash(); // we need to do this again, because tp_init() kills lcd
|
||||
else
|
||||
{
|
||||
w25x20cl_err_msg();
|
||||
puts_P(_n("W25X20CL not responding."));
|
||||
xflash_err_msg();
|
||||
puts_P(_n("XFLASH not responding."));
|
||||
}
|
||||
#ifdef EXTRUDER_ALTFAN_DETECT
|
||||
SERIAL_ECHORPGM(_n("Extruder fan type: "));
|
||||
@ -1458,16 +1450,16 @@ void setup()
|
||||
|
||||
#if (LANG_MODE != 0) //secondary language support
|
||||
|
||||
#ifdef DEBUG_W25X20CL
|
||||
W25X20CL_SPI_ENTER();
|
||||
#ifdef DEBUG_XFLASH
|
||||
XFLASH_SPI_ENTER();
|
||||
uint8_t uid[8]; // 64bit unique id
|
||||
w25x20cl_rd_uid(uid);
|
||||
puts_P(_n("W25X20CL UID="));
|
||||
xflash_rd_uid(uid);
|
||||
puts_P(_n("XFLASH UID="));
|
||||
for (uint8_t i = 0; i < 8; i ++)
|
||||
printf_P(PSTR("%02hhx"), uid[i]);
|
||||
putchar('\n');
|
||||
list_sec_lang_from_external_flash();
|
||||
#endif //DEBUG_W25X20CL
|
||||
#endif //DEBUG_XFLASH
|
||||
|
||||
// lang_reset();
|
||||
if (!lang_select(eeprom_read_byte((uint8_t*)EEPROM_LANG)))
|
||||
@ -2668,16 +2660,15 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
|
||||
static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, long home_y_value, bool home_z_axis, long home_z_value, bool without_mbl)
|
||||
#endif //TMC2130
|
||||
{
|
||||
// Flag for the display update routine and to disable the print cancelation during homing.
|
||||
st_synchronize();
|
||||
homing_flag = true;
|
||||
|
||||
#if 0
|
||||
SERIAL_ECHOPGM("G28, initial "); print_world_coordinates();
|
||||
SERIAL_ECHOPGM("G28, initial "); print_physical_coordinates();
|
||||
#endif
|
||||
|
||||
// Flag for the display update routine and to disable the print cancelation during homing.
|
||||
homing_flag = true;
|
||||
|
||||
// Which axes should be homed?
|
||||
bool home_x = home_x_axis;
|
||||
bool home_y = home_y_axis;
|
||||
@ -2920,24 +2911,21 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
|
||||
|
||||
#if (defined(MESH_BED_LEVELING) && !defined(MK1BP))
|
||||
if (home_x_axis || home_y_axis || without_mbl || home_z_axis)
|
||||
{
|
||||
{
|
||||
if (! home_z && mbl_was_active) {
|
||||
// Re-enable the mesh bed leveling if only the X and Y axes were re-homed.
|
||||
mbl.active = true;
|
||||
// and re-adjust the current logical Z axis with the bed leveling offset applicable at the current XY position.
|
||||
current_position[Z_AXIS] -= mbl.get_z(st_get_position_mm(X_AXIS), st_get_position_mm(Y_AXIS));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
st_synchronize();
|
||||
homing_flag = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (farm_mode) { prusa_statistics(20); };
|
||||
|
||||
st_synchronize();
|
||||
homing_flag = false;
|
||||
|
||||
#if 0
|
||||
SERIAL_ECHOPGM("G28, final "); print_world_coordinates();
|
||||
SERIAL_ECHOPGM("G28, final "); print_physical_coordinates();
|
||||
@ -2954,6 +2942,422 @@ static void gcode_G28(bool home_x_axis, bool home_y_axis, bool home_z_axis)
|
||||
#endif //TMC2130
|
||||
}
|
||||
|
||||
|
||||
// G80 - Automatic mesh bed leveling
|
||||
static void gcode_G80()
|
||||
{
|
||||
st_synchronize();
|
||||
if (waiting_inside_plan_buffer_line_print_aborted)
|
||||
return;
|
||||
|
||||
mesh_bed_leveling_flag = true;
|
||||
#ifndef PINDA_THERMISTOR
|
||||
static bool run = false; // thermistor-less PINDA temperature compensation is running
|
||||
#endif // ndef PINDA_THERMISTOR
|
||||
|
||||
#ifdef SUPPORT_VERBOSITY
|
||||
int8_t verbosity_level = 0;
|
||||
if (code_seen('V')) {
|
||||
// Just 'V' without a number counts as V1.
|
||||
char c = strchr_pointer[1];
|
||||
verbosity_level = (c == ' ' || c == '\t' || c == 0) ? 1 : code_value_short();
|
||||
}
|
||||
#endif //SUPPORT_VERBOSITY
|
||||
// Firstly check if we know where we are
|
||||
if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) {
|
||||
// We don't know where we are! HOME!
|
||||
// Push the commands to the front of the message queue in the reverse order!
|
||||
// There shall be always enough space reserved for these commands.
|
||||
repeatcommand_front(); // repeat G80 with all its parameters
|
||||
enquecommand_front_P(G28W0);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t nMeasPoints = MESH_MEAS_NUM_X_POINTS;
|
||||
if (code_seen('N')) {
|
||||
nMeasPoints = code_value_uint8();
|
||||
if (nMeasPoints != 7) {
|
||||
nMeasPoints = 3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nMeasPoints = eeprom_read_byte((uint8_t*)EEPROM_MBL_POINTS_NR);
|
||||
}
|
||||
|
||||
uint8_t nProbeRetry = 3;
|
||||
if (code_seen('R')) {
|
||||
nProbeRetry = code_value_uint8();
|
||||
if (nProbeRetry > 10) {
|
||||
nProbeRetry = 10;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nProbeRetry = eeprom_read_byte((uint8_t*)EEPROM_MBL_PROBE_NR);
|
||||
}
|
||||
bool magnet_elimination = (eeprom_read_byte((uint8_t*)EEPROM_MBL_MAGNET_ELIMINATION) > 0);
|
||||
|
||||
#ifndef PINDA_THERMISTOR
|
||||
if (run == false && temp_cal_active == true && calibration_status_pinda() == true && target_temperature_bed >= 50)
|
||||
{
|
||||
temp_compensation_start();
|
||||
run = true;
|
||||
repeatcommand_front(); // repeat G80 with all its parameters
|
||||
enquecommand_front_P(G28W0);
|
||||
break;
|
||||
}
|
||||
run = false;
|
||||
#endif //PINDA_THERMISTOR
|
||||
// Save custom message state, set a new custom message state to display: Calibrating point 9.
|
||||
CustomMsg custom_message_type_old = custom_message_type;
|
||||
unsigned int custom_message_state_old = custom_message_state;
|
||||
custom_message_type = CustomMsg::MeshBedLeveling;
|
||||
custom_message_state = (nMeasPoints * nMeasPoints) + 10;
|
||||
lcd_update(1);
|
||||
|
||||
mbl.reset(); //reset mesh bed leveling
|
||||
|
||||
// Reset baby stepping to zero, if the babystepping has already been loaded before.
|
||||
babystep_undo();
|
||||
|
||||
// Cycle through all points and probe them
|
||||
// First move up. During this first movement, the babystepping will be reverted.
|
||||
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
||||
plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60);
|
||||
// The move to the first calibration point.
|
||||
current_position[X_AXIS] = BED_X0;
|
||||
current_position[Y_AXIS] = BED_Y0;
|
||||
|
||||
#ifdef SUPPORT_VERBOSITY
|
||||
if (verbosity_level >= 1)
|
||||
{
|
||||
bool clamped = world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]);
|
||||
clamped ? SERIAL_PROTOCOLPGM("First calibration point clamped.\n") : SERIAL_PROTOCOLPGM("No clamping for first calibration point.\n");
|
||||
}
|
||||
#else //SUPPORT_VERBOSITY
|
||||
world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]);
|
||||
#endif //SUPPORT_VERBOSITY
|
||||
|
||||
int XY_AXIS_FEEDRATE = homing_feedrate[X_AXIS] / 20;
|
||||
plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE);
|
||||
// Wait until the move is finished.
|
||||
st_synchronize();
|
||||
if (waiting_inside_plan_buffer_line_print_aborted)
|
||||
{
|
||||
custom_message_type = custom_message_type_old;
|
||||
custom_message_state = custom_message_state_old;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t mesh_point = 0; //index number of calibration point
|
||||
int Z_LIFT_FEEDRATE = homing_feedrate[Z_AXIS] / 40;
|
||||
bool has_z = is_bed_z_jitter_data_valid(); //checks if we have data from Z calibration (offsets of the Z heiths of the 8 calibration points from the first point)
|
||||
#ifdef SUPPORT_VERBOSITY
|
||||
if (verbosity_level >= 1) {
|
||||
has_z ? SERIAL_PROTOCOLPGM("Z jitter data from Z cal. valid.\n") : SERIAL_PROTOCOLPGM("Z jitter data from Z cal. not valid.\n");
|
||||
}
|
||||
#endif // SUPPORT_VERBOSITY
|
||||
int l_feedmultiply = setup_for_endstop_move(false); //save feedrate and feedmultiply, sets feedmultiply to 100
|
||||
while (mesh_point != nMeasPoints * nMeasPoints) {
|
||||
// Get coords of a measuring point.
|
||||
uint8_t ix = mesh_point % nMeasPoints; // from 0 to MESH_NUM_X_POINTS - 1
|
||||
uint8_t iy = mesh_point / nMeasPoints;
|
||||
/*if (!mbl_point_measurement_valid(ix, iy, nMeasPoints, true)) {
|
||||
printf_P(PSTR("Skipping point [%d;%d] \n"), ix, iy);
|
||||
custom_message_state--;
|
||||
mesh_point++;
|
||||
continue; //skip
|
||||
}*/
|
||||
if (iy & 1) ix = (nMeasPoints - 1) - ix; // Zig zag
|
||||
if (nMeasPoints == 7) //if we have 7x7 mesh, compare with Z-calibration for points which are in 3x3 mesh
|
||||
{
|
||||
has_z = ((ix % 3 == 0) && (iy % 3 == 0)) && is_bed_z_jitter_data_valid();
|
||||
}
|
||||
float z0 = 0.f;
|
||||
if (has_z && (mesh_point > 0)) {
|
||||
uint16_t z_offset_u = 0;
|
||||
if (nMeasPoints == 7) {
|
||||
z_offset_u = eeprom_read_word((uint16_t*)(EEPROM_BED_CALIBRATION_Z_JITTER + 2 * ((ix/3) + iy - 1)));
|
||||
}
|
||||
else {
|
||||
z_offset_u = eeprom_read_word((uint16_t*)(EEPROM_BED_CALIBRATION_Z_JITTER + 2 * (ix + iy * 3 - 1)));
|
||||
}
|
||||
z0 = mbl.z_values[0][0] + *reinterpret_cast<int16_t*>(&z_offset_u) * 0.01;
|
||||
#ifdef SUPPORT_VERBOSITY
|
||||
if (verbosity_level >= 1) {
|
||||
printf_P(PSTR("Bed leveling, point: %d, calibration Z stored in eeprom: %d, calibration z: %f \n"), mesh_point, z_offset_u, z0);
|
||||
}
|
||||
#endif // SUPPORT_VERBOSITY
|
||||
}
|
||||
|
||||
// Move Z up to MESH_HOME_Z_SEARCH.
|
||||
if((ix == 0) && (iy == 0)) current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
||||
else current_position[Z_AXIS] += 2.f / nMeasPoints; //use relative movement from Z coordinate where PINDa triggered on previous point. This makes calibration faster.
|
||||
float init_z_bckp = current_position[Z_AXIS];
|
||||
plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE);
|
||||
st_synchronize();
|
||||
|
||||
// Move to XY position of the sensor point.
|
||||
current_position[X_AXIS] = BED_X(ix, nMeasPoints);
|
||||
current_position[Y_AXIS] = BED_Y(iy, nMeasPoints);
|
||||
|
||||
//printf_P(PSTR("[%f;%f]\n"), current_position[X_AXIS], current_position[Y_AXIS]);
|
||||
|
||||
|
||||
#ifdef SUPPORT_VERBOSITY
|
||||
if (verbosity_level >= 1) {
|
||||
bool clamped = world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]);
|
||||
SERIAL_PROTOCOL(mesh_point);
|
||||
clamped ? SERIAL_PROTOCOLPGM(": xy clamped.\n") : SERIAL_PROTOCOLPGM(": no xy clamping\n");
|
||||
}
|
||||
#else //SUPPORT_VERBOSITY
|
||||
world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]);
|
||||
#endif // SUPPORT_VERBOSITY
|
||||
|
||||
//printf_P(PSTR("after clamping: [%f;%f]\n"), current_position[X_AXIS], current_position[Y_AXIS]);
|
||||
plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE);
|
||||
st_synchronize();
|
||||
if (waiting_inside_plan_buffer_line_print_aborted)
|
||||
{
|
||||
custom_message_type = custom_message_type_old;
|
||||
custom_message_state = custom_message_state_old;
|
||||
return;
|
||||
}
|
||||
|
||||
// Go down until endstop is hit
|
||||
const float Z_CALIBRATION_THRESHOLD = 1.f;
|
||||
if (!find_bed_induction_sensor_point_z((has_z && mesh_point > 0) ? z0 - Z_CALIBRATION_THRESHOLD : -10.f, nProbeRetry)) { //if we have data from z calibration max allowed difference is 1mm for each point, if we dont have data max difference is 10mm from initial point
|
||||
printf_P(_T(MSG_BED_LEVELING_FAILED_POINT_LOW));
|
||||
break;
|
||||
}
|
||||
if (init_z_bckp - current_position[Z_AXIS] < 0.1f) { //broken cable or initial Z coordinate too low. Go to MESH_HOME_Z_SEARCH and repeat last step (z-probe) again to distinguish between these two cases.
|
||||
//printf_P(PSTR("Another attempt! Current Z position: %f\n"), current_position[Z_AXIS]);
|
||||
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
||||
plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE);
|
||||
st_synchronize();
|
||||
|
||||
if (!find_bed_induction_sensor_point_z((has_z && mesh_point > 0) ? z0 - Z_CALIBRATION_THRESHOLD : -10.f, nProbeRetry)) { //if we have data from z calibration max allowed difference is 1mm for each point, if we dont have data max difference is 10mm from initial point
|
||||
printf_P(_T(MSG_BED_LEVELING_FAILED_POINT_LOW));
|
||||
break;
|
||||
}
|
||||
if (MESH_HOME_Z_SEARCH - current_position[Z_AXIS] < 0.1f) {
|
||||
puts_P(PSTR("Bed leveling failed. Sensor disconnected or cable broken."));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_z && fabs(z0 - current_position[Z_AXIS]) > Z_CALIBRATION_THRESHOLD) { //if we have data from z calibration, max. allowed difference is 1mm for each point
|
||||
puts_P(PSTR("Bed leveling failed. Sensor triggered too high."));
|
||||
break;
|
||||
}
|
||||
#ifdef SUPPORT_VERBOSITY
|
||||
if (verbosity_level >= 10) {
|
||||
SERIAL_ECHOPGM("X: ");
|
||||
MYSERIAL.print(current_position[X_AXIS], 5);
|
||||
SERIAL_ECHOLNPGM("");
|
||||
SERIAL_ECHOPGM("Y: ");
|
||||
MYSERIAL.print(current_position[Y_AXIS], 5);
|
||||
SERIAL_PROTOCOLPGM("\n");
|
||||
}
|
||||
#endif // SUPPORT_VERBOSITY
|
||||
float offset_z = 0;
|
||||
|
||||
#ifdef PINDA_THERMISTOR
|
||||
offset_z = temp_compensation_pinda_thermistor_offset(current_temperature_pinda);
|
||||
#endif //PINDA_THERMISTOR
|
||||
// #ifdef SUPPORT_VERBOSITY
|
||||
/* if (verbosity_level >= 1)
|
||||
{
|
||||
SERIAL_ECHOPGM("mesh bed leveling: ");
|
||||
MYSERIAL.print(current_position[Z_AXIS], 5);
|
||||
SERIAL_ECHOPGM(" offset: ");
|
||||
MYSERIAL.print(offset_z, 5);
|
||||
SERIAL_ECHOLNPGM("");
|
||||
}*/
|
||||
// #endif // SUPPORT_VERBOSITY
|
||||
mbl.set_z(ix, iy, current_position[Z_AXIS] - offset_z); //store measured z values z_values[iy][ix] = z - offset_z;
|
||||
|
||||
custom_message_state--;
|
||||
mesh_point++;
|
||||
lcd_update(1);
|
||||
}
|
||||
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
||||
#ifdef SUPPORT_VERBOSITY
|
||||
if (verbosity_level >= 20) {
|
||||
SERIAL_ECHOLNPGM("Mesh bed leveling while loop finished.");
|
||||
SERIAL_ECHOLNPGM("MESH_HOME_Z_SEARCH: ");
|
||||
MYSERIAL.print(current_position[Z_AXIS], 5);
|
||||
}
|
||||
#endif // SUPPORT_VERBOSITY
|
||||
plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE);
|
||||
st_synchronize();
|
||||
if (mesh_point != nMeasPoints * nMeasPoints) {
|
||||
Sound_MakeSound(e_SOUND_TYPE_StandardAlert);
|
||||
bool bState;
|
||||
do { // repeat until Z-leveling o.k.
|
||||
lcd_display_message_fullscreen_P(_i("Some problem encountered, Z-leveling enforced ..."));
|
||||
#ifdef TMC2130
|
||||
lcd_wait_for_click_delay(MSG_BED_LEVELING_FAILED_TIMEOUT);
|
||||
calibrate_z_auto(); // Z-leveling (X-assembly stay up!!!)
|
||||
#else // TMC2130
|
||||
lcd_wait_for_click_delay(0); // ~ no timeout
|
||||
lcd_calibrate_z_end_stop_manual(true); // Z-leveling (X-assembly stay up!!!)
|
||||
#endif // TMC2130
|
||||
// ~ Z-homing (can not be used "G28", because X & Y-homing would have been done before (Z-homing))
|
||||
bState=enable_z_endstop(false);
|
||||
current_position[Z_AXIS] -= 1;
|
||||
plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40);
|
||||
st_synchronize();
|
||||
enable_z_endstop(true);
|
||||
#ifdef TMC2130
|
||||
tmc2130_home_enter(Z_AXIS_MASK);
|
||||
#endif // TMC2130
|
||||
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
||||
plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40);
|
||||
st_synchronize();
|
||||
#ifdef TMC2130
|
||||
tmc2130_home_exit();
|
||||
#endif // TMC2130
|
||||
enable_z_endstop(bState);
|
||||
} 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)
|
||||
|
||||
custom_message_type = custom_message_type_old;
|
||||
custom_message_state = custom_message_state_old;
|
||||
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)!)
|
||||
repeatcommand_front(); // re-run (i.e. of "G80")
|
||||
return;
|
||||
}
|
||||
clean_up_after_endstop_move(l_feedmultiply);
|
||||
// SERIAL_ECHOLNPGM("clean up finished ");
|
||||
|
||||
#ifndef PINDA_THERMISTOR
|
||||
if(temp_cal_active == true && calibration_status_pinda() == true) temp_compensation_apply(); //apply PINDA temperature compensation
|
||||
#endif
|
||||
babystep_apply(); // Apply Z height correction aka baby stepping before mesh bed leveing gets activated.
|
||||
// SERIAL_ECHOLNPGM("babystep applied");
|
||||
bool eeprom_bed_correction_valid = eeprom_read_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID) == 1;
|
||||
#ifdef SUPPORT_VERBOSITY
|
||||
if (verbosity_level >= 1) {
|
||||
eeprom_bed_correction_valid ? SERIAL_PROTOCOLPGM("Bed correction data valid\n") : SERIAL_PROTOCOLPGM("Bed correction data not valid\n");
|
||||
}
|
||||
#endif // SUPPORT_VERBOSITY
|
||||
|
||||
for (uint8_t i = 0; i < 4; ++i) {
|
||||
unsigned char codes[4] = { 'L', 'R', 'F', 'B' };
|
||||
long correction = 0;
|
||||
if (code_seen(codes[i]))
|
||||
correction = code_value_long();
|
||||
else if (eeprom_bed_correction_valid) {
|
||||
unsigned char *addr = (i < 2) ?
|
||||
((i == 0) ? (unsigned char*)EEPROM_BED_CORRECTION_LEFT : (unsigned char*)EEPROM_BED_CORRECTION_RIGHT) :
|
||||
((i == 2) ? (unsigned char*)EEPROM_BED_CORRECTION_FRONT : (unsigned char*)EEPROM_BED_CORRECTION_REAR);
|
||||
correction = eeprom_read_int8(addr);
|
||||
}
|
||||
if (correction == 0)
|
||||
continue;
|
||||
|
||||
if (labs(correction) > BED_ADJUSTMENT_UM_MAX) {
|
||||
SERIAL_ERROR_START;
|
||||
SERIAL_ECHOPGM("Excessive bed leveling correction: ");
|
||||
SERIAL_ECHO(correction);
|
||||
SERIAL_ECHOLNPGM(" microns");
|
||||
}
|
||||
else {
|
||||
float offset = float(correction) * 0.001f;
|
||||
switch (i) {
|
||||
case 0:
|
||||
for (uint8_t row = 0; row < nMeasPoints; ++row) {
|
||||
for (uint8_t col = 0; col < nMeasPoints - 1; ++col) {
|
||||
mbl.z_values[row][col] += offset * (nMeasPoints - 1 - col) / (nMeasPoints - 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (uint8_t row = 0; row < nMeasPoints; ++row) {
|
||||
for (uint8_t col = 1; col < nMeasPoints; ++col) {
|
||||
mbl.z_values[row][col] += offset * col / (nMeasPoints - 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (uint8_t col = 0; col < nMeasPoints; ++col) {
|
||||
for (uint8_t row = 0; row < nMeasPoints; ++row) {
|
||||
mbl.z_values[row][col] += offset * (nMeasPoints - 1 - row) / (nMeasPoints - 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (uint8_t col = 0; col < nMeasPoints; ++col) {
|
||||
for (uint8_t row = 1; row < nMeasPoints; ++row) {
|
||||
mbl.z_values[row][col] += offset * row / (nMeasPoints - 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// SERIAL_ECHOLNPGM("Bed leveling correction finished");
|
||||
if (nMeasPoints == 3) {
|
||||
mbl.upsample_3x3(); //interpolation from 3x3 to 7x7 points using largrangian polynomials while using the same array z_values[iy][ix] for storing (just coppying measured data to new destination and interpolating between them)
|
||||
}
|
||||
/*
|
||||
SERIAL_PROTOCOLPGM("Num X,Y: ");
|
||||
SERIAL_PROTOCOL(MESH_NUM_X_POINTS);
|
||||
SERIAL_PROTOCOLPGM(",");
|
||||
SERIAL_PROTOCOL(MESH_NUM_Y_POINTS);
|
||||
SERIAL_PROTOCOLPGM("\nZ search height: ");
|
||||
SERIAL_PROTOCOL(MESH_HOME_Z_SEARCH);
|
||||
SERIAL_PROTOCOLLNPGM("\nMeasured points:");
|
||||
for (int y = MESH_NUM_Y_POINTS-1; y >= 0; y--) {
|
||||
for (int x = 0; x < MESH_NUM_X_POINTS; x++) {
|
||||
SERIAL_PROTOCOLPGM(" ");
|
||||
SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5);
|
||||
}
|
||||
SERIAL_PROTOCOLPGM("\n");
|
||||
}
|
||||
*/
|
||||
if (nMeasPoints == 7 && magnet_elimination) {
|
||||
mbl_interpolation(nMeasPoints);
|
||||
}
|
||||
/*
|
||||
SERIAL_PROTOCOLPGM("Num X,Y: ");
|
||||
SERIAL_PROTOCOL(MESH_NUM_X_POINTS);
|
||||
SERIAL_PROTOCOLPGM(",");
|
||||
SERIAL_PROTOCOL(MESH_NUM_Y_POINTS);
|
||||
SERIAL_PROTOCOLPGM("\nZ search height: ");
|
||||
SERIAL_PROTOCOL(MESH_HOME_Z_SEARCH);
|
||||
SERIAL_PROTOCOLLNPGM("\nMeasured points:");
|
||||
for (int y = MESH_NUM_Y_POINTS-1; y >= 0; y--) {
|
||||
for (int x = 0; x < MESH_NUM_X_POINTS; x++) {
|
||||
SERIAL_PROTOCOLPGM(" ");
|
||||
SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5);
|
||||
}
|
||||
SERIAL_PROTOCOLPGM("\n");
|
||||
}
|
||||
*/
|
||||
// SERIAL_ECHOLNPGM("Upsample finished");
|
||||
mbl.active = 1; //activate mesh bed leveling
|
||||
// SERIAL_ECHOLNPGM("Mesh bed leveling activated");
|
||||
go_home_with_z_lift();
|
||||
// SERIAL_ECHOLNPGM("Go home finished");
|
||||
//unretract (after PINDA preheat retraction)
|
||||
if ((degHotend(active_extruder) > EXTRUDE_MINTEMP) && eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE) && calibration_status_pinda() && (target_temperature_bed >= 50)) {
|
||||
current_position[E_AXIS] += default_retraction;
|
||||
plan_buffer_line_curposXYZE(400);
|
||||
}
|
||||
KEEPALIVE_STATE(NOT_BUSY);
|
||||
// Restore custom message state
|
||||
lcd_setstatuspgm(_T(WELCOME_MSG));
|
||||
custom_message_type = custom_message_type_old;
|
||||
custom_message_state = custom_message_state_old;
|
||||
mesh_bed_run_from_menu = false;
|
||||
lcd_update(2);
|
||||
|
||||
st_synchronize();
|
||||
mesh_bed_leveling_flag = false;
|
||||
}
|
||||
|
||||
|
||||
void adjust_bed_reset()
|
||||
{
|
||||
eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID, 1);
|
||||
@ -3218,12 +3622,12 @@ static T gcode_M600_filament_change_z_shift()
|
||||
#ifdef FILAMENTCHANGE_ZADD
|
||||
static_assert(Z_MAX_POS < (255 - FILAMENTCHANGE_ZADD), "Z-range too high, change the T type from uint8_t to uint16_t");
|
||||
// avoid floating point arithmetics when not necessary - results in shorter code
|
||||
T z_shift = T(FILAMENTCHANGE_ZADD); // always move above printout
|
||||
T ztmp = T( current_position[Z_AXIS] );
|
||||
T z_shift = 0;
|
||||
if(ztmp < T(25)){
|
||||
z_shift = T(25) - ztmp; // make sure to be at least 25mm above the heat bed
|
||||
}
|
||||
return z_shift + T(FILAMENTCHANGE_ZADD); // always move above printout
|
||||
if((ztmp + z_shift) < T(MIN_Z_FOR_SWAP)){
|
||||
z_shift = T(MIN_Z_FOR_SWAP) - ztmp; // make sure to be at least 25mm above the heat bed
|
||||
}
|
||||
return z_shift;
|
||||
#else
|
||||
return T(0);
|
||||
#endif
|
||||
@ -3272,7 +3676,7 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
|
||||
|
||||
// Unload filament
|
||||
if (mmu_enabled) extr_unload(); //unload just current filament for multimaterial printers (used also in M702)
|
||||
else unload_filament(); //unload filament for single material (used also in M702)
|
||||
else unload_filament(true); //unload filament for single material (used also in M702)
|
||||
//finish moves
|
||||
st_synchronize();
|
||||
|
||||
@ -3559,6 +3963,8 @@ static void extended_capabilities_report()
|
||||
#endif //FANCHECK and TACH_0 or TACH_1
|
||||
// AUTOREPORT_POSITION (M114)
|
||||
cap_line(PSTR("AUTOREPORT_POSITION"), ENABLED(AUTO_REPORT));
|
||||
// EXTENDED_M20 (support for L and T parameters)
|
||||
cap_line(PSTR("EXTENDED_M20"), 1);
|
||||
//@todo Update RepRap cap
|
||||
}
|
||||
#endif //EXTENDED_CAPABILITIES_REPORT
|
||||
@ -4013,10 +4419,10 @@ void process_commands()
|
||||
}
|
||||
else if (code_seen_P(PSTR("RESET"))) { // PRUSA RESET
|
||||
#ifdef WATCHDOG
|
||||
#if defined(W25X20CL) && defined(BOOTAPP)
|
||||
#if defined(XFLASH) && defined(BOOTAPP)
|
||||
boot_app_magic = BOOT_APP_MAGIC;
|
||||
boot_app_flags = BOOT_APP_FLG_RUN;
|
||||
#endif //defined(W25X20CL) && defined(BOOTAPP)
|
||||
#endif //defined(XFLASH) && defined(BOOTAPP)
|
||||
softReset();
|
||||
#elif defined(BOOTAPP) //this is a safety precaution. This is because the new bootloader turns off the heaters, but the old one doesn't. The watchdog should be used most of the time.
|
||||
asm volatile("jmp 0x3E000");
|
||||
@ -4530,9 +4936,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
|
||||
gcode_G28(home_x, home_x_value, home_y, home_y_value, home_z, home_z_value, without_mbl);
|
||||
#endif //TMC2130
|
||||
if ((home_x || home_y || without_mbl || home_z) == false) {
|
||||
// Push the commands to the front of the message queue in the reverse order!
|
||||
// There shall be always enough space reserved for these commands.
|
||||
goto case_G80;
|
||||
gcode_G80();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -4745,8 +5149,9 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
|
||||
*/
|
||||
case 30:
|
||||
{
|
||||
homing_flag = true;
|
||||
st_synchronize();
|
||||
homing_flag = true;
|
||||
|
||||
// TODO: make sure the bed_level_rotation_matrix is identity or the planner will get set incorectly
|
||||
int l_feedmultiply = setup_for_endstop_move();
|
||||
|
||||
@ -4849,7 +5254,9 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
|
||||
}
|
||||
}
|
||||
|
||||
st_synchronize();
|
||||
homing_flag = true; // keep homing on to avoid babystepping while the LCD is enabled
|
||||
|
||||
lcd_update_enable(true);
|
||||
KEEPALIVE_STATE(NOT_BUSY); //no need to print busy messages as we print current temperatures periodicaly
|
||||
SERIAL_ECHOLNPGM("PINDA probe calibration start");
|
||||
@ -5084,11 +5491,11 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
|
||||
* v Y-axis
|
||||
*/
|
||||
|
||||
case 80:
|
||||
|
||||
case 80: {
|
||||
#ifdef MK1BP
|
||||
break;
|
||||
#endif //MK1BP
|
||||
<<<<<<< HEAD
|
||||
case_G80:
|
||||
{
|
||||
mesh_bed_leveling_flag = true;
|
||||
@ -5482,6 +5889,9 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
|
||||
mesh_bed_run_from_menu = false;
|
||||
lcd_update(2);
|
||||
|
||||
=======
|
||||
gcode_G80();
|
||||
>>>>>>> upstream/MK3_3.10.0
|
||||
}
|
||||
break;
|
||||
|
||||
@ -5727,16 +6137,17 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
|
||||
### M20 - SD Card file list <a href="https://reprap.org/wiki/G-code#M20:_List_SD_card">M20: List SD card</a>
|
||||
#### Usage
|
||||
|
||||
M20 [ L ]
|
||||
M20 [ L | T ]
|
||||
#### Parameters
|
||||
- `L` - Reports ling filenames instead of just short filenames. Requires host software parsing.
|
||||
- `T` - Report timestamps as well. The value is one uint32_t encoded as hex. Requires host software parsing (Cap:EXTENDED_M20).
|
||||
- `L` - Reports long filenames instead of just short filenames. Requires host software parsing (Cap:EXTENDED_M20).
|
||||
*/
|
||||
case 20:
|
||||
KEEPALIVE_STATE(NOT_BUSY); // do not send busy messages during listing. Inhibits the output of manage_heater()
|
||||
SERIAL_PROTOCOLLNRPGM(_N("Begin file list"));////MSG_BEGIN_FILE_LIST
|
||||
card.ls(code_seen('L'));
|
||||
card.ls(CardReader::ls_param(code_seen('L'), code_seen('T')));
|
||||
SERIAL_PROTOCOLLNRPGM(_N("End file list"));////MSG_END_FILE_LIST
|
||||
break;
|
||||
break;
|
||||
|
||||
/*!
|
||||
### M21 - Init SD card <a href="https://reprap.org/wiki/G-code#M21:_Initialize_SD_card">M21: Initialize SD card</a>
|
||||
@ -6969,19 +7380,21 @@ Sigma_Exit:
|
||||
lcd_setstatus(strchr_pointer + 5);
|
||||
break;*/
|
||||
|
||||
#ifdef M120_M121_ENABLED
|
||||
/*!
|
||||
### M120 - Enable endstops <a href="https://reprap.org/wiki/G-code#M120:_Enable_endstop_detection">M120: Enable endstop detection</a>
|
||||
### M120 - Enable endstops <a href="https://reprap.org/wiki/G-code#M120:_Enable_endstop_detection">M120: Enable endstop detection</a>
|
||||
*/
|
||||
case 120:
|
||||
enable_endstops(true) ;
|
||||
break;
|
||||
|
||||
/*!
|
||||
### M121 - Disable endstops <a href="https://reprap.org/wiki/G-code#M121:_Disable_endstop_detection">M121: Disable endstop detection</a>
|
||||
### M121 - Disable endstops <a href="https://reprap.org/wiki/G-code#M121:_Disable_endstop_detection">M121: Disable endstop detection</a>
|
||||
*/
|
||||
case 121:
|
||||
enable_endstops(false) ;
|
||||
break;
|
||||
#endif //M120_M121_ENABLED
|
||||
|
||||
/*!
|
||||
### M119 - Get endstop states <a href="https://reprap.org/wiki/G-code#M119:_Get_Endstop_Status">M119: Get Endstop Status</a>
|
||||
@ -10845,8 +11258,9 @@ void uvlo_()
|
||||
}
|
||||
|
||||
// save the global state at planning time
|
||||
bool pos_invalid = XY_NO_RESTORE_FLAG;
|
||||
uint16_t feedrate_bckp;
|
||||
if (current_block)
|
||||
if (current_block && !pos_invalid)
|
||||
{
|
||||
memcpy(saved_target, current_block->gcode_target, sizeof(saved_target));
|
||||
feedrate_bckp = current_block->gcode_feedrate;
|
||||
@ -10924,8 +11338,13 @@ void uvlo_()
|
||||
eeprom_update_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS), z_microsteps);
|
||||
|
||||
// Store the current position.
|
||||
eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0), current_position[X_AXIS]);
|
||||
eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4), current_position[Y_AXIS]);
|
||||
if (pos_invalid)
|
||||
eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0), X_COORD_INVALID);
|
||||
else
|
||||
{
|
||||
eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0), current_position[X_AXIS]);
|
||||
eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4), current_position[Y_AXIS]);
|
||||
}
|
||||
|
||||
// Store the current feed rate, temperatures, fan speed and extruder multipliers (flow rates)
|
||||
eeprom_update_word((uint16_t*)EEPROM_UVLO_FEEDRATE, feedrate_bckp);
|
||||
@ -11183,11 +11602,6 @@ bool recover_machine_state_after_power_panic()
|
||||
// Recover last E axis position
|
||||
current_position[E_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E));
|
||||
|
||||
memcpy(destination, current_position, sizeof(destination));
|
||||
|
||||
SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial ");
|
||||
print_world_coordinates();
|
||||
|
||||
// 3) Initialize the logical to physical coordinate system transformation.
|
||||
world2machine_initialize();
|
||||
// SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial ");
|
||||
@ -11199,7 +11613,11 @@ bool recover_machine_state_after_power_panic()
|
||||
|
||||
// 5) Set the physical positions from the logical positions using the world2machine transformation
|
||||
// This is only done to inizialize Z/E axes with physical locations, since X/Y are unknown.
|
||||
clamp_to_software_endstops(current_position);
|
||||
memcpy(destination, current_position, sizeof(destination));
|
||||
plan_set_position_curposXYZE();
|
||||
SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial ");
|
||||
print_world_coordinates();
|
||||
|
||||
// 6) Power up the Z motors, mark their positions as known.
|
||||
axis_known_position[Z_AXIS] = true;
|
||||
@ -11236,7 +11654,7 @@ void restore_print_from_eeprom(bool mbl_was_active) {
|
||||
int feedrate_rec;
|
||||
int feedmultiply_rec;
|
||||
uint8_t fan_speed_rec;
|
||||
char cmd[30];
|
||||
char cmd[48];
|
||||
char filename[13];
|
||||
uint8_t depth = 0;
|
||||
char dir_name[9];
|
||||
@ -11277,10 +11695,13 @@ void restore_print_from_eeprom(bool mbl_was_active) {
|
||||
|
||||
// Move to the XY print position in logical coordinates, where the print has been killed, but
|
||||
// without shifting Z along the way. This requires performing the move without mbl.
|
||||
sprintf_P(cmd, PSTR("G1 X%f Y%f F3000"),
|
||||
eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0)),
|
||||
eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4)));
|
||||
enquecommand(cmd);
|
||||
float pos_x = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0));
|
||||
float pos_y = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4));
|
||||
if (pos_x != X_COORD_INVALID)
|
||||
{
|
||||
sprintf_P(cmd, PSTR("G1 X%f Y%f F3000"), pos_x, pos_y);
|
||||
enquecommand(cmd);
|
||||
}
|
||||
|
||||
// Enable MBL and switch to logical positioning
|
||||
if (mbl_was_active)
|
||||
@ -11460,7 +11881,8 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
|
||||
#endif
|
||||
|
||||
// save the global state at planning time
|
||||
if (current_block)
|
||||
bool pos_invalid = XY_NO_RESTORE_FLAG;
|
||||
if (current_block && !pos_invalid)
|
||||
{
|
||||
memcpy(saved_target, current_block->gcode_target, sizeof(saved_target));
|
||||
saved_feedrate2 = current_block->gcode_feedrate;
|
||||
@ -11472,7 +11894,10 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
|
||||
}
|
||||
|
||||
planner_abort_hard(); //abort printing
|
||||
|
||||
memcpy(saved_pos, current_position, sizeof(saved_pos));
|
||||
if (pos_invalid) saved_pos[X_AXIS] = X_COORD_INVALID;
|
||||
|
||||
saved_feedmultiply2 = feedmultiply; //save feedmultiply
|
||||
saved_active_extruder = active_extruder; //save active_extruder
|
||||
saved_extruder_temperature = degTargetHotend(active_extruder);
|
||||
@ -11566,6 +11991,13 @@ void restore_print_from_ram_and_continue(float e_move)
|
||||
fans_check_enabled = false;
|
||||
#endif
|
||||
|
||||
// do not restore XY for commands that do not require that
|
||||
if (saved_pos[X_AXIS] == X_COORD_INVALID)
|
||||
{
|
||||
saved_pos[X_AXIS] = current_position[X_AXIS];
|
||||
saved_pos[Y_AXIS] = current_position[Y_AXIS];
|
||||
}
|
||||
|
||||
//first move print head in XY to the saved position:
|
||||
plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], current_position[Z_AXIS], saved_pos[E_AXIS] - e_move, homing_feedrate[Z_AXIS]/13, active_extruder);
|
||||
//then move Z
|
||||
|
@ -178,14 +178,17 @@ eof_or_fail:
|
||||
}
|
||||
|
||||
bool SdFile::gfEnsureBlock(){
|
||||
if ( vol_->cacheRawBlock(gfBlock, SdVolume::CACHE_FOR_READ)){
|
||||
// this comparison is heavy-weight, especially when there is another one inside cacheRawBlock
|
||||
// but it is necessary to avoid computing of terminateOfs if not needed
|
||||
if( gfBlock != vol_->cacheBlockNumber_ ){
|
||||
if ( ! vol_->cacheRawBlock(gfBlock, SdVolume::CACHE_FOR_READ)){
|
||||
return false;
|
||||
}
|
||||
// terminate with a '\n'
|
||||
const uint16_t terminateOfs = fileSize_ - gfOffset;
|
||||
const uint32_t terminateOfs = fileSize_ - gfOffset;
|
||||
vol_->cache()->data[ terminateOfs < 512 ? terminateOfs : 512 ] = '\n';
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SdFile::gfComputeNextFileBlock() {
|
||||
|
@ -61,10 +61,9 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters
|
||||
+* LS_Count - Add +1 to nrFiles for every file within the parent
|
||||
+* LS_GetFilename - Get the filename of the file indexed by nrFiles
|
||||
+* LS_SerialPrint - Print the full path and size of each file to serial output
|
||||
+* LS_SerialPrint_LFN - Print the full path, long filename and size of each file to serial output
|
||||
+*/
|
||||
|
||||
void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) {
|
||||
void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/, LsAction lsAction, ls_param lsParams) {
|
||||
static uint8_t recursionCnt = 0;
|
||||
// RAII incrementer for the recursionCnt
|
||||
class _incrementer
|
||||
@ -80,8 +79,12 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
|
||||
for (position = parent.curPosition(); parent.readDir(p, longFilename) > 0; position = parent.curPosition()) {
|
||||
if (recursionCnt > MAX_DIR_DEPTH)
|
||||
return;
|
||||
else if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // If the entry is a directory and the action is LS_SerialPrint
|
||||
|
||||
uint8_t pn0 = p.name[0];
|
||||
if (pn0 == DIR_NAME_FREE) break;
|
||||
if (pn0 == DIR_NAME_DELETED || pn0 == '.') continue;
|
||||
if (longFilename[0] == '.') continue;
|
||||
if (!DIR_IS_FILE_OR_SUBDIR(&p) || (p.attributes & DIR_ATT_HIDDEN)) continue;
|
||||
if (DIR_IS_SUBDIR(&p) && lsAction == LS_SerialPrint) { // If the entry is a directory and the action is LS_SerialPrint
|
||||
// Get the short name for the item, which we know is a folder
|
||||
char lfilename[FILENAME_LENGTH];
|
||||
createFilename(lfilename, p);
|
||||
@ -99,29 +102,22 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
|
||||
// Get a new directory object using the full path
|
||||
// and dive recursively into it.
|
||||
|
||||
if (lsAction == LS_SerialPrint_LFN)
|
||||
if (lsParams.LFN)
|
||||
printf_P(PSTR("DIR_ENTER: %s \"%s\"\n"), path, longFilename[0] ? longFilename : lfilename);
|
||||
|
||||
SdFile dir;
|
||||
if (!dir.open(parent, lfilename, O_READ)) {
|
||||
if (lsAction == LS_SerialPrint || lsAction == LS_SerialPrint_LFN) {
|
||||
//SERIAL_ECHO_START();
|
||||
//SERIAL_ECHOPGM(_i("Cannot open subdir"));////MSG_SD_CANT_OPEN_SUBDIR
|
||||
//SERIAL_ECHOLN(lfilename);
|
||||
}
|
||||
//SERIAL_ECHO_START();
|
||||
//SERIAL_ECHOPGM(_i("Cannot open subdir"));////MSG_SD_CANT_OPEN_SUBDIR
|
||||
//SERIAL_ECHOLN(lfilename);
|
||||
}
|
||||
lsDive(path, dir);
|
||||
lsDive(path, dir, NULL, lsAction, lsParams);
|
||||
// close() is done automatically by destructor of SdFile
|
||||
|
||||
if (lsAction == LS_SerialPrint_LFN)
|
||||
if (lsParams.LFN)
|
||||
puts_P(PSTR("DIR_EXIT"));
|
||||
}
|
||||
else {
|
||||
uint8_t pn0 = p.name[0];
|
||||
if (pn0 == DIR_NAME_FREE) break;
|
||||
if (pn0 == DIR_NAME_DELETED || pn0 == '.') continue;
|
||||
if (longFilename[0] == '.') continue;
|
||||
if (!DIR_IS_FILE_OR_SUBDIR(&p) || (p.attributes & DIR_ATT_HIDDEN)) continue;
|
||||
filenameIsDir = DIR_IS_SUBDIR(&p);
|
||||
if (!filenameIsDir && (p.name[8] != 'G' || p.name[9] == '~')) continue;
|
||||
switch (lsAction) {
|
||||
@ -129,17 +125,29 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
|
||||
nrFiles++;
|
||||
break;
|
||||
|
||||
case LS_SerialPrint_LFN:
|
||||
case LS_SerialPrint:
|
||||
createFilename(filename, p);
|
||||
SERIAL_PROTOCOL(prepend);
|
||||
SERIAL_PROTOCOL(filename);
|
||||
|
||||
MYSERIAL.write(' ');
|
||||
SERIAL_PROTOCOL(p.fileSize);
|
||||
|
||||
if (lsAction == LS_SerialPrint_LFN)
|
||||
printf_P(PSTR("\"%s\" "), LONGEST_FILENAME);
|
||||
if (lsParams.timestamp)
|
||||
{
|
||||
crmodDate = p.lastWriteDate;
|
||||
crmodTime = p.lastWriteTime;
|
||||
if( crmodDate < p.creationDate || ( crmodDate == p.creationDate && crmodTime < p.creationTime ) ){
|
||||
crmodDate = p.creationDate;
|
||||
crmodTime = p.creationTime;
|
||||
}
|
||||
printf_P(PSTR(" %#lx"), ((uint32_t)crmodDate << 16) | crmodTime);
|
||||
}
|
||||
|
||||
SERIAL_PROTOCOLLN(p.fileSize);
|
||||
if (lsParams.LFN)
|
||||
printf_P(PSTR(" \"%s\""), LONGEST_FILENAME);
|
||||
|
||||
SERIAL_PROTOCOLLN();
|
||||
manage_heater();
|
||||
break;
|
||||
|
||||
@ -181,14 +189,10 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
|
||||
} // while readDir
|
||||
}
|
||||
|
||||
void CardReader::ls(bool printLFN)
|
||||
void CardReader::ls(ls_param params)
|
||||
{
|
||||
lsAction = printLFN ? LS_SerialPrint_LFN : LS_SerialPrint;
|
||||
//if(lsAction==LS_Count)
|
||||
//nrFiles=0;
|
||||
|
||||
root.rewind();
|
||||
lsDive("",root);
|
||||
lsDive("",root, NULL, LS_SerialPrint, params);
|
||||
}
|
||||
|
||||
|
||||
@ -695,38 +699,34 @@ void CardReader::closefile(bool store_location)
|
||||
void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/)
|
||||
{
|
||||
curDir=&workDir;
|
||||
lsAction=LS_GetFilename;
|
||||
nrFiles=nr;
|
||||
curDir->rewind();
|
||||
lsDive("",*curDir,match);
|
||||
lsDive("",*curDir,match, LS_GetFilename);
|
||||
|
||||
}
|
||||
|
||||
void CardReader::getfilename_simple(uint32_t position, const char * const match/*=NULL*/)
|
||||
{
|
||||
curDir = &workDir;
|
||||
lsAction = LS_GetFilename;
|
||||
nrFiles = 0;
|
||||
curDir->seekSet(position);
|
||||
lsDive("", *curDir, match);
|
||||
lsDive("", *curDir, match, LS_GetFilename);
|
||||
}
|
||||
|
||||
void CardReader::getfilename_next(uint32_t position, const char * const match/*=NULL*/)
|
||||
{
|
||||
curDir = &workDir;
|
||||
lsAction = LS_GetFilename;
|
||||
nrFiles = 1;
|
||||
curDir->seekSet(position);
|
||||
lsDive("", *curDir, match);
|
||||
lsDive("", *curDir, match, LS_GetFilename);
|
||||
}
|
||||
|
||||
uint16_t CardReader::getnrfilenames()
|
||||
{
|
||||
curDir=&workDir;
|
||||
lsAction=LS_Count;
|
||||
nrFiles=0;
|
||||
curDir->rewind();
|
||||
lsDive("",*curDir);
|
||||
lsDive("",*curDir, NULL, LS_Count);
|
||||
//SERIAL_ECHOLN(nrFiles);
|
||||
return nrFiles;
|
||||
}
|
||||
|
@ -8,12 +8,25 @@
|
||||
#define MAX_DIR_DEPTH 6
|
||||
|
||||
#include "SdFile.h"
|
||||
enum LsAction {LS_SerialPrint,LS_SerialPrint_LFN,LS_Count,LS_GetFilename};
|
||||
class CardReader
|
||||
{
|
||||
public:
|
||||
CardReader();
|
||||
|
||||
enum LsAction : uint8_t
|
||||
{
|
||||
LS_SerialPrint,
|
||||
LS_Count,
|
||||
LS_GetFilename,
|
||||
};
|
||||
struct ls_param
|
||||
{
|
||||
bool LFN : 1;
|
||||
bool timestamp : 1;
|
||||
inline ls_param():LFN(0), timestamp(0) { }
|
||||
inline ls_param(bool LFN, bool timestamp):LFN(LFN), timestamp(timestamp) { }
|
||||
} __attribute__((packed));
|
||||
|
||||
void initsd();
|
||||
void write_command(char *buf);
|
||||
void write_command_no_newline(char *buf);
|
||||
@ -43,7 +56,7 @@ public:
|
||||
uint16_t getWorkDirDepth();
|
||||
|
||||
|
||||
void ls(bool printLFN);
|
||||
void ls(ls_param params);
|
||||
bool chdir(const char * relpath, bool doPresort);
|
||||
void updir();
|
||||
void setroot(bool doPresort);
|
||||
@ -59,9 +72,12 @@ public:
|
||||
|
||||
FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
|
||||
bool eof() { return sdpos>=filesize; }
|
||||
// There may be a potential performance problem - when the comment reading fails, sdpos points to the last correctly read character.
|
||||
// However, repeated reading (e.g. after power panic) the comment will be read again - it should survive correctly, it will just take a few moments to skip
|
||||
FORCE_INLINE int16_t getFilteredGcodeChar() { sdpos = file.curPosition();return (int16_t)file.readFilteredGcode();};
|
||||
FORCE_INLINE int16_t getFilteredGcodeChar()
|
||||
{
|
||||
int16_t c = (int16_t)file.readFilteredGcode();
|
||||
sdpos = file.curPosition();
|
||||
return c;
|
||||
};
|
||||
void setIndex(long index) {sdpos = index;file.seekSetFilteredGcode(index);};
|
||||
FORCE_INLINE uint8_t percentDone(){if(!isFileOpen()) return 0; if(filesize) return sdpos/((filesize+99)/100); else return 0;};
|
||||
FORCE_INLINE char* getWorkDirName(){workDir.getFilename(filename);return filename;};
|
||||
@ -119,12 +135,11 @@ private:
|
||||
|
||||
bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware.
|
||||
|
||||
LsAction lsAction; //stored for recursion.
|
||||
int16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory.
|
||||
char* diveDirName;
|
||||
|
||||
bool diveSubfolder (const char *&fileName);
|
||||
void lsDive(const char *prepend, SdFile parent, const char * const match=NULL);
|
||||
void lsDive(const char *prepend, SdFile parent, const char * const match=NULL, LsAction lsAction = LS_GetFilename, ls_param lsParams = ls_param());
|
||||
#ifdef SDCARD_SORT_ALPHA
|
||||
void flush_presort();
|
||||
#endif
|
||||
|
@ -600,7 +600,7 @@ void get_command()
|
||||
}
|
||||
// The new command buffer could be updated non-atomically, because it is not yet considered
|
||||
// to be inside the active queue.
|
||||
sd_count.value = (card.get_sdpos()+1) - sdpos_atomic;
|
||||
sd_count.value = card.get_sdpos() - sdpos_atomic;
|
||||
cmdbuffer[bufindw] = CMDBUFFER_CURRENT_TYPE_SDCARD;
|
||||
cmdbuffer[bufindw+1] = sd_count.lohi.lo;
|
||||
cmdbuffer[bufindw+2] = sd_count.lohi.hi;
|
||||
@ -625,7 +625,7 @@ void get_command()
|
||||
// or a 115200 Bd serial line receive interrupt, which will not trigger faster than 12kHz.
|
||||
++ buflen;
|
||||
bufindw += len;
|
||||
sdpos_atomic = card.get_sdpos()+1;
|
||||
sdpos_atomic = card.get_sdpos();
|
||||
if (bufindw == sizeof(cmdbuffer))
|
||||
bufindw = 0;
|
||||
sei();
|
||||
|
@ -54,14 +54,6 @@
|
||||
#define TMC2130_SPCR SPI_SPCR(TMC2130_SPI_RATE, 1, 1, 1, 0)
|
||||
#define TMC2130_SPSR SPI_SPSR(TMC2130_SPI_RATE)
|
||||
|
||||
//W25X20CL configuration
|
||||
//pinout:
|
||||
#define W25X20CL_PIN_CS 32
|
||||
//spi:
|
||||
#define W25X20CL_SPI_RATE 0 // fosc/4 = 4MHz
|
||||
#define W25X20CL_SPCR SPI_SPCR(W25X20CL_SPI_RATE, 1, 1, 1, 0)
|
||||
#define W25X20CL_SPSR SPI_SPSR(W25X20CL_SPI_RATE)
|
||||
|
||||
//LANG - Multi-language support
|
||||
//#define LANG_MODE 0 // primary language only
|
||||
#define LANG_MODE 1 // sec. language support
|
||||
|
@ -97,6 +97,9 @@ void eeprom_init()
|
||||
#ifdef PINDA_TEMP_COMP
|
||||
if (eeprom_read_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_PINDA_TEMP_COMPENSATION, 0);
|
||||
#endif //PINDA_TEMP_COMP
|
||||
|
||||
if (eeprom_read_dword((uint32_t*)EEPROM_JOB_ID) == EEPROM_EMPTY_VALUE32)
|
||||
eeprom_update_dword((uint32_t*)EEPROM_JOB_ID, 0);
|
||||
}
|
||||
|
||||
//! @brief Get default sheet name for index
|
||||
@ -107,10 +110,10 @@ if (eeprom_read_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION) == 0xff) eeprom_u
|
||||
//! | 1 | Smooth2 |
|
||||
//! | 2 | Textur1 |
|
||||
//! | 3 | Textur2 |
|
||||
//! | 4 | Custom1 |
|
||||
//! | 5 | Custom2 |
|
||||
//! | 6 | Custom3 |
|
||||
//! | 7 | Custom4 |
|
||||
//! | 4 | Satin 1 |
|
||||
//! | 5 | Satin 2 |
|
||||
//! | 6 | Custom1 |
|
||||
//! | 7 | Custom2 |
|
||||
//!
|
||||
//! @param[in] index
|
||||
//! @param[out] sheetName
|
||||
@ -126,41 +129,16 @@ void eeprom_default_sheet_name(uint8_t index, SheetName &sheetName)
|
||||
{
|
||||
strcpy_P(sheetName.c, PSTR("Textur"));
|
||||
}
|
||||
else if (index < 6)
|
||||
{
|
||||
strcpy_P(sheetName.c, PSTR("Satin "));
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy_P(sheetName.c, PSTR("Custom"));
|
||||
}
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
sheetName.c[6] = '1';
|
||||
break;
|
||||
case 1:
|
||||
sheetName.c[6] = '2';
|
||||
break;
|
||||
case 2:
|
||||
sheetName.c[6] = '1';
|
||||
break;
|
||||
case 3:
|
||||
sheetName.c[6] = '2';
|
||||
break;
|
||||
case 4:
|
||||
sheetName.c[6] = '1';
|
||||
break;
|
||||
case 5:
|
||||
sheetName.c[6] = '2';
|
||||
break;
|
||||
case 6:
|
||||
sheetName.c[6] = '3';
|
||||
break;
|
||||
case 7:
|
||||
sheetName.c[6] = '4';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
sheetName.c[6] = '0' + ((index % 2)+1);
|
||||
sheetName.c[7] = '\0';
|
||||
}
|
||||
|
||||
|
@ -276,19 +276,19 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
|
||||
| 0x0D71 3441 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 4th sheet - Z offset | ^ | D3 Ax0d71 C2
|
||||
| 0x0D73 3443 | uint8 | ^ | 00h 0 | ffh 255 | 4th sheet - bed temp | ^ | D3 Ax0d73 C1
|
||||
| 0x0D74 3444 | uint8 | ^ | 00h 0 | ffh 255 | 4th sheet - PINDA temp | ^ | D3 Ax0d74 C1
|
||||
| 0x0D75 3445 | char | _5th Sheet block_ | 437573746f6d31| ffffffffffffff | 5th sheet - Name: _Custom1_ | ^ | D3 Ax0d75 C7
|
||||
| 0x0D75 3445 | char | _5th Sheet block_ | 536174696e2031| ffffffffffffff | 5th sheet - Name: _Satin 1_ | ^ | D3 Ax0d75 C7
|
||||
| 0x0D7C 3452 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 5th sheet - Z offset | ^ | D3 Ax0d7c C2
|
||||
| 0x0D7E 3454 | uint8 | ^ | 00h 0 | ffh 255 | 5th sheet - bed temp | ^ | D3 Ax0d7e C1
|
||||
| 0x0D7F 3455 | uint8 | ^ | 00h 0 | ffh 255 | 5th sheet - PINDA temp | ^ | D3 Ax0d7f C1
|
||||
| 0x0D80 3456 | char | _6th Sheet block_ | 437573746f6d32| ffffffffffffff | 6th sheet - Name: _Custom2_ | ^ | D3 Ax0d80 C7
|
||||
| 0x0D80 3456 | char | _6th Sheet block_ | 536174696e2032| ffffffffffffff | 6th sheet - Name: _Satin 2_ | ^ | D3 Ax0d80 C7
|
||||
| 0x0D87 3463 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 6th sheet - Z offset | ^ | D3 Ax0d87 C2
|
||||
| 0x0D89 3465 | uint8 | ^ | 00h 0 | ffh 255 | 6th sheet - bed temp | ^ | D3 Ax0d89 C1
|
||||
| 0x0D8A 3466 | uint8 | ^ | 00h 0 | ffh 255 | 6th sheet - PINDA temp | ^ | D3 Ax0d8a C1
|
||||
| 0x0D8B 3467 | char | _7th Sheet block_ | 437573746f6d33| ffffffffffffff | 7th sheet - Name: _Custom3_ | ^ | D3 Ax0d8b C7
|
||||
| 0x0D8B 3467 | char | _7th Sheet block_ | 437573746f6d31| ffffffffffffff | 7th sheet - Name: _Custom1_ | ^ | D3 Ax0d8b C7
|
||||
| 0x0D92 3474 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 7th sheet - Z offset | ^ | D3 Ax0d92 C2
|
||||
| 0x0D94 3476 | uint8 | ^ | 00h 0 | ffh 255 | 7th sheet - bed temp | ^ | D3 Ax0d94 C1
|
||||
| 0x0D95 3477 | uint8 | ^ | 00h 0 | ffh 255 | 7th sheet - PINDA temp | ^ | D3 Ax0d95 C1
|
||||
| 0x0D96 3478 | char | _8th Sheet block_ | 437573746f6d34| ffffffffffffff | 8th sheet - Name: _Custom4_ | ^ | D3 Ax0d96 C7
|
||||
| 0x0D96 3478 | char | _8th Sheet block_ | 437573746f6d32| ffffffffffffff | 8th sheet - Name: _Custom2_ | ^ | D3 Ax0d96 C7
|
||||
| 0x0D9D 3485 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 8th sheet - Z offset | ^ | D3 Ax0d9d C2
|
||||
| 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
|
||||
@ -324,6 +324,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
|
||||
| 0x0D11 3345 | float | EEPROM_UVLO_ACCELL | ??? | ff ff ff ffh | Power panic saved normal acceleration | ??? | D3 Ax0d11 C4
|
||||
| 0x0D0D 3341 | float | EEPROM_UVLO_RETRACT_ACCELL | ??? | ff ff ff ffh | Power panic saved retract acceleration | ??? | D3 Ax0d0d C4
|
||||
| 0x0D09 3337 | float | EEPROM_UVLO_TRAVEL_ACCELL | ??? | ff ff ff ffh | Power panic saved travel acceleration | ??? | D3 Ax0d09 C4
|
||||
| 0x0D05 3333 | uint32_t | EEPROM_JOB_ID | ??? | 00 00 00 00h | Job ID used by host software | D3 only | D3 Ax0d05 C4
|
||||
|
||||
| Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code
|
||||
| :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--:
|
||||
@ -337,6 +338,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
|
||||
|
||||
#define EEPROM_EMPTY_VALUE 0xFF
|
||||
#define EEPROM_EMPTY_VALUE16 0xFFFF
|
||||
#define EEPROM_EMPTY_VALUE32 0xFFFFFFFFl
|
||||
// The total size of the EEPROM is
|
||||
// 4096 for the Atmega2560
|
||||
#define EEPROM_TOP 4096
|
||||
@ -534,8 +536,10 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
|
||||
#define EEPROM_UVLO_RETRACT_ACCELL (EEPROM_UVLO_ACCELL-4) // float
|
||||
#define EEPROM_UVLO_TRAVEL_ACCELL (EEPROM_UVLO_RETRACT_ACCELL-4) // float
|
||||
|
||||
#define EEPROM_JOB_ID (EEPROM_UVLO_TRAVEL_ACCELL-4) //uint32_t
|
||||
|
||||
//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_TRAVEL_ACCELL
|
||||
#define EEPROM_LAST_ITEM EEPROM_JOB_ID
|
||||
// !!!!!
|
||||
// !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
|
||||
// !!!!!
|
||||
|
@ -7,9 +7,9 @@
|
||||
#include "Configuration.h"
|
||||
#include "pins.h"
|
||||
|
||||
#ifdef W25X20CL
|
||||
#include "w25x20cl.h"
|
||||
#endif //W25X20CL
|
||||
#ifdef XFLASH
|
||||
#include "xflash.h"
|
||||
#endif //XFLASH
|
||||
|
||||
// Currently active language selection.
|
||||
uint8_t lang_selected = 0;
|
||||
@ -54,7 +54,7 @@ uint8_t lang_select(uint8_t lang)
|
||||
lang_table = 0;
|
||||
lang_selected = lang;
|
||||
}
|
||||
#ifdef W25X20CL
|
||||
#ifdef XFLASH
|
||||
if (lang_get_code(lang) == lang_get_code(LANG_ID_SEC)) lang = LANG_ID_SEC;
|
||||
if (lang == LANG_ID_SEC) //current secondary language
|
||||
{
|
||||
@ -68,7 +68,7 @@ uint8_t lang_select(uint8_t lang)
|
||||
}
|
||||
}
|
||||
}
|
||||
#else //W25X20CL
|
||||
#else //XFLASH
|
||||
if (lang == LANG_ID_SEC)
|
||||
{
|
||||
uint16_t table = _SEC_LANG_TABLE;
|
||||
@ -82,7 +82,7 @@ uint8_t lang_select(uint8_t lang)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //W25X20CL
|
||||
#endif //XFLASH
|
||||
if (lang_selected == lang)
|
||||
{
|
||||
eeprom_update_byte((unsigned char*)EEPROM_LANG, lang_selected);
|
||||
@ -107,19 +107,19 @@ uint8_t lang_get_count()
|
||||
{
|
||||
if (pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE))) == 0xffffffff)
|
||||
return 1; //signature not set - only primary language will be available
|
||||
#ifdef W25X20CL
|
||||
W25X20CL_SPI_ENTER();
|
||||
#ifdef XFLASH
|
||||
XFLASH_SPI_ENTER();
|
||||
uint8_t count = 2; //count = 1+n (primary + secondary + all in xflash)
|
||||
uint32_t addr = 0x00000; //start of xflash
|
||||
lang_table_header_t header; //table header structure
|
||||
while (1)
|
||||
{
|
||||
w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash
|
||||
xflash_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash
|
||||
if (header.magic != LANG_MAGIC) break; //break if magic not valid
|
||||
addr += header.size; //calc address of next table
|
||||
count++; //inc counter
|
||||
}
|
||||
#else //W25X20CL
|
||||
#else //XFLASH
|
||||
uint16_t table = _SEC_LANG_TABLE;
|
||||
uint8_t count = 1; //count = 1 (primary)
|
||||
while (pgm_read_dword(((uint32_t*)table)) == LANG_MAGIC) //magic valid
|
||||
@ -127,14 +127,14 @@ uint8_t lang_get_count()
|
||||
table += pgm_read_word((uint16_t*)(table + 4));
|
||||
count++;
|
||||
}
|
||||
#endif //W25X20CL
|
||||
#endif //XFLASH
|
||||
return count;
|
||||
}
|
||||
|
||||
uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* offset)
|
||||
{
|
||||
if (lang == LANG_ID_PRI) return 0; //primary lang not supported for this function
|
||||
#ifdef W25X20CL
|
||||
#ifdef XFLASH
|
||||
if (lang == LANG_ID_SEC)
|
||||
{
|
||||
uint16_t ui = _SEC_LANG_TABLE; //table pointer
|
||||
@ -142,18 +142,18 @@ uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* off
|
||||
if (offset) *offset = ui;
|
||||
return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid
|
||||
}
|
||||
W25X20CL_SPI_ENTER();
|
||||
XFLASH_SPI_ENTER();
|
||||
uint32_t addr = 0x00000; //start of xflash
|
||||
lang--;
|
||||
while (1)
|
||||
{
|
||||
w25x20cl_rd_data(addr, (uint8_t*)(header), sizeof(lang_table_header_t)); //read table header from xflash
|
||||
xflash_rd_data(addr, (uint8_t*)(header), sizeof(lang_table_header_t)); //read table header from xflash
|
||||
if (header->magic != LANG_MAGIC) break; //break if not valid
|
||||
if (offset) *offset = addr;
|
||||
if (--lang == 0) return 1;
|
||||
addr += header->size; //calc address of next table
|
||||
}
|
||||
#else //W25X20CL
|
||||
#else //XFLASH
|
||||
if (lang == LANG_ID_SEC)
|
||||
{
|
||||
uint16_t ui = _SEC_LANG_TABLE; //table pointer
|
||||
@ -161,32 +161,32 @@ uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* off
|
||||
if (offset) *offset = ui;
|
||||
return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid
|
||||
}
|
||||
#endif //W25X20CL
|
||||
#endif //XFLASH
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t lang_get_code(uint8_t lang)
|
||||
{
|
||||
if (lang == LANG_ID_PRI) return LANG_CODE_EN; //primary lang = EN
|
||||
#ifdef W25X20CL
|
||||
#ifdef XFLASH
|
||||
if (lang == LANG_ID_SEC)
|
||||
{
|
||||
uint16_t ui = _SEC_LANG_TABLE; //table pointer
|
||||
if (pgm_read_dword(((uint32_t*)(ui + 0))) != LANG_MAGIC) return LANG_CODE_XX; //magic not valid
|
||||
return pgm_read_word(((uint32_t*)(ui + 10))); //return lang code from progmem
|
||||
}
|
||||
W25X20CL_SPI_ENTER();
|
||||
XFLASH_SPI_ENTER();
|
||||
uint32_t addr = 0x00000; //start of xflash
|
||||
lang_table_header_t header; //table header structure
|
||||
lang--;
|
||||
while (1)
|
||||
{
|
||||
w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash
|
||||
xflash_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash
|
||||
if (header.magic != LANG_MAGIC) break; //break if not valid
|
||||
if (--lang == 0) return header.code;
|
||||
addr += header.size; //calc address of next table
|
||||
}
|
||||
#else //W25X20CL
|
||||
#else //XFLASH
|
||||
uint16_t table = _SEC_LANG_TABLE;
|
||||
uint8_t count = 1; //count = 1 (primary)
|
||||
while (pgm_read_dword((uint32_t*)table) == LANG_MAGIC) //magic valid
|
||||
@ -195,7 +195,7 @@ uint16_t lang_get_code(uint8_t lang)
|
||||
table += pgm_read_word((uint16_t*)(table + 4));
|
||||
count++;
|
||||
}
|
||||
#endif //W25X20CL
|
||||
#endif //XFLASH
|
||||
return LANG_CODE_XX;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include "Marlin.h"
|
||||
#include "Configuration.h"
|
||||
#include "ConfigurationStore.h"
|
||||
#include "language.h"
|
||||
@ -1065,7 +1064,7 @@ error:
|
||||
}
|
||||
|
||||
#ifdef NEW_XYZCAL
|
||||
bool xyzcal_find_bed_induction_sensor_point_xy();
|
||||
BedSkewOffsetDetectionResultType xyzcal_find_bed_induction_sensor_point_xy();
|
||||
#endif //NEW_XYZCAL
|
||||
// Search around the current_position[X,Y],
|
||||
// look for the induction sensor response.
|
||||
@ -1081,7 +1080,7 @@ bool xyzcal_find_bed_induction_sensor_point_xy();
|
||||
#endif //HEATBED_V2
|
||||
|
||||
#ifdef HEATBED_V2
|
||||
bool find_bed_induction_sensor_point_xy(int
|
||||
BedSkewOffsetDetectionResultType find_bed_induction_sensor_point_xy(int
|
||||
#if !defined (NEW_XYZCAL) && defined (SUPPORT_VERBOSITY)
|
||||
verbosity_level
|
||||
#endif
|
||||
@ -1137,7 +1136,7 @@ bool find_bed_induction_sensor_point_xy(int
|
||||
|
||||
// go_xyz(current_position[X_AXIS], current_position[Y_AXIS], MESH_HOME_Z_SEARCH, homing_feedrate[Z_AXIS]/60);
|
||||
go_xyz(x0, y0, current_position[Z_AXIS], feedrate);
|
||||
// Continously lower the Z axis.
|
||||
// Continuously lower the Z axis.
|
||||
endstops_hit_on_purpose();
|
||||
enable_z_endstop(true);
|
||||
bool direction = false;
|
||||
@ -1335,7 +1334,7 @@ bool find_bed_induction_sensor_point_xy(int
|
||||
#endif //NEW_XYZCAL
|
||||
}
|
||||
#else //HEATBED_V2
|
||||
bool find_bed_induction_sensor_point_xy(int verbosity_level)
|
||||
BedSkewOffsetDetectionResultType find_bed_induction_sensor_point_xy(int verbosity_level)
|
||||
{
|
||||
#ifdef NEW_XYZCAL
|
||||
return xyzcal_find_bed_induction_sensor_point_xy();
|
||||
@ -1531,7 +1530,9 @@ bool find_bed_induction_sensor_point_xy(int verbosity_level)
|
||||
}
|
||||
|
||||
enable_z_endstop(false);
|
||||
return found;
|
||||
if (found)
|
||||
return BED_SKEW_OFFSET_DETECTION_POINT_FOUND;
|
||||
return BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND;
|
||||
#endif //NEW_XYZCAL
|
||||
}
|
||||
|
||||
@ -2238,9 +2239,15 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level
|
||||
|
||||
// Collect the rear 2x3 points.
|
||||
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH + FIND_BED_INDUCTION_SENSOR_POINT_Z_STEP * iteration * 0.3;
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
// Don't let the manage_inactivity() function remove power from the motors.
|
||||
refresh_cmd_timeout();
|
||||
|
||||
/// Retry point scanning if a point with bad data appears.
|
||||
/// Bad data could be cause by "cold" sensor.
|
||||
/// This behavior vanishes after few point scans so retry will help.
|
||||
for (int retries = 0; retries <= 1; ++retries) {
|
||||
bool retry = false;
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
// Don't let the manage_inactivity() function remove power from the motors.
|
||||
refresh_cmd_timeout();
|
||||
#ifdef MESH_BED_CALIBRATION_SHOW_LCD
|
||||
lcd_set_cursor(0, next_line);
|
||||
lcd_print(k + 1);
|
||||
@ -2304,8 +2311,19 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level
|
||||
if (verbosity_level >= 10)
|
||||
delay_keep_alive(3000);
|
||||
#endif // SUPPORT_VERBOSITY
|
||||
if (!find_bed_induction_sensor_point_xy(verbosity_level))
|
||||
return BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND;
|
||||
|
||||
BedSkewOffsetDetectionResultType result;
|
||||
result = find_bed_induction_sensor_point_xy(verbosity_level);
|
||||
switch(result){
|
||||
case BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND:
|
||||
return BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND;
|
||||
case BED_SKEW_OFFSET_DETECTION_POINT_SCAN_FAILED:
|
||||
retry = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef NEW_XYZCAL
|
||||
#ifndef HEATBED_V2
|
||||
|
||||
@ -2380,6 +2398,9 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level
|
||||
}
|
||||
#endif // SUPPORT_VERBOSITY
|
||||
}
|
||||
if (!retry)
|
||||
break;
|
||||
}
|
||||
DBG(_n("All 4 calibration points found.\n"));
|
||||
delay_keep_alive(0); //manage_heater, reset watchdog, manage inactivity
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#ifndef MESH_BED_CALIBRATION_H
|
||||
#define MESH_BED_CALIBRATION_H
|
||||
#pragma once
|
||||
|
||||
#include "Marlin.h"
|
||||
|
||||
#define BED_ZERO_REF_X (- 22.f + X_PROBE_OFFSET_FROM_EXTRUDER) // -22 + 23 = 1
|
||||
#define BED_ZERO_REF_Y (- 0.6f + Y_PROBE_OFFSET_FROM_EXTRUDER + 4.f) // -0.6 + 5 + 4 = 8.4
|
||||
@ -145,11 +146,6 @@ inline bool world2machine_clamp(float &x, float &y)
|
||||
machine2world(tmpx, tmpy, x, y);
|
||||
return clamped;
|
||||
}
|
||||
|
||||
bool find_bed_induction_sensor_point_z(float minimum_z = -10.f, uint8_t n_iter = 3, int verbosity_level = 0);
|
||||
bool find_bed_induction_sensor_point_xy(int verbosity_level = 0);
|
||||
void go_home_with_z_lift();
|
||||
|
||||
/**
|
||||
* @brief Bed skew and offest detection result
|
||||
*
|
||||
@ -159,8 +155,10 @@ void go_home_with_z_lift();
|
||||
|
||||
enum BedSkewOffsetDetectionResultType {
|
||||
// Detection failed, some point was not found.
|
||||
BED_SKEW_OFFSET_DETECTION_POINT_FOUND = 0, //!< Point found
|
||||
BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND = -1, //!< Point not found.
|
||||
BED_SKEW_OFFSET_DETECTION_FITTING_FAILED = -2, //!< Fitting failed
|
||||
BED_SKEW_OFFSET_DETECTION_POINT_SCAN_FAILED = -3, //!< Point scan failed, try again
|
||||
|
||||
// Detection finished with success.
|
||||
BED_SKEW_OFFSET_DETECTION_PERFECT = 0, //!< Perfect.
|
||||
@ -168,6 +166,10 @@ enum BedSkewOffsetDetectionResultType {
|
||||
BED_SKEW_OFFSET_DETECTION_SKEW_EXTREME = 2 //!< Extremely skewed.
|
||||
};
|
||||
|
||||
bool find_bed_induction_sensor_point_z(float minimum_z = -10.f, uint8_t n_iter = 3, int verbosity_level = 0);
|
||||
BedSkewOffsetDetectionResultType find_bed_induction_sensor_point_xy(int verbosity_level = 0);
|
||||
void go_home_with_z_lift();
|
||||
|
||||
extern BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level, uint8_t &too_far_mask);
|
||||
#ifndef NEW_XYZCAL
|
||||
extern BedSkewOffsetDetectionResultType improve_bed_offset_and_skew(int8_t method, int8_t verbosity_level, uint8_t &too_far_mask);
|
||||
@ -213,4 +215,3 @@ extern void mbl_settings_init();
|
||||
|
||||
extern bool mbl_point_measurement_valid(uint8_t ix, uint8_t iy, uint8_t meas_points, bool zigzag);
|
||||
extern void mbl_interpolation(uint8_t meas_points);
|
||||
#endif /* MESH_BED_CALIBRATION_H */
|
||||
|
@ -1,6 +0,0 @@
|
||||
#ifndef OPTIBOOT_W25X20CL_H
|
||||
#define OPTIBOOT_W25X20CL_H
|
||||
|
||||
extern uint8_t optiboot_w25x20cl_enter();
|
||||
|
||||
#endif /* OPTIBOOT_W25X20CL_H */
|
@ -4,7 +4,7 @@
|
||||
// Licence GLP 2 or later.
|
||||
|
||||
#include "Marlin.h"
|
||||
#include "w25x20cl.h"
|
||||
#include "xflash.h"
|
||||
#include "stk500.h"
|
||||
#include "bootapp.h"
|
||||
#include <avr/wdt.h>
|
||||
@ -16,14 +16,14 @@ static unsigned const int __attribute__((section(".version")))
|
||||
optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER;
|
||||
|
||||
#if 0
|
||||
#define W25X20CL_SIGNATURE_0 9
|
||||
#define W25X20CL_SIGNATURE_1 8
|
||||
#define W25X20CL_SIGNATURE_2 7
|
||||
#define XFLASH_SIGNATURE_0 9
|
||||
#define XFLASH_SIGNATURE_1 8
|
||||
#define XFLASH_SIGNATURE_2 7
|
||||
#else
|
||||
//FIXME this is a signature of ATmega2560!
|
||||
#define W25X20CL_SIGNATURE_0 0x1E
|
||||
#define W25X20CL_SIGNATURE_1 0x98
|
||||
#define W25X20CL_SIGNATURE_2 0x01
|
||||
#define XFLASH_SIGNATURE_0 0x1E
|
||||
#define XFLASH_SIGNATURE_1 0x98
|
||||
#define XFLASH_SIGNATURE_2 0x01
|
||||
#endif
|
||||
|
||||
#define RECV_READY ((UCSR0A & _BV(RXC0)) != 0)
|
||||
@ -78,7 +78,7 @@ extern struct block_t *block_buffer;
|
||||
//! @brief Enter an STK500 compatible Optiboot boot loader waiting for flashing the languages to an external flash memory.
|
||||
//! @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()
|
||||
uint8_t optiboot_xflash_enter()
|
||||
{
|
||||
// Make sure to check boot_app_magic as well. Since these bootapp flags are located right in the middle of the stack,
|
||||
// they can be unintentionally changed. As a workaround to the language upload problem, do not only check for one bit if it's set,
|
||||
@ -154,7 +154,7 @@ uint8_t optiboot_w25x20cl_enter()
|
||||
}
|
||||
|
||||
spi_init();
|
||||
w25x20cl_init();
|
||||
xflash_init();
|
||||
wdt_disable();
|
||||
|
||||
/* Forever loop: exits by causing WDT reset */
|
||||
@ -254,16 +254,16 @@ uint8_t optiboot_w25x20cl_enter()
|
||||
// During a single bootloader run, only erase a 64kB block once.
|
||||
// An 8bit bitmask 'pages_erased' covers 512kB of FLASH memory.
|
||||
if ((address == 0) && (pages_erased & (1 << (addr >> 16))) == 0) {
|
||||
w25x20cl_wait_busy();
|
||||
w25x20cl_enable_wr();
|
||||
w25x20cl_block64_erase(addr);
|
||||
xflash_wait_busy();
|
||||
xflash_enable_wr();
|
||||
xflash_block64_erase(addr);
|
||||
pages_erased |= (1 << (addr >> 16));
|
||||
}
|
||||
w25x20cl_wait_busy();
|
||||
w25x20cl_enable_wr();
|
||||
w25x20cl_page_program(addr, buff, savelength);
|
||||
w25x20cl_wait_busy();
|
||||
w25x20cl_disable_wr();
|
||||
xflash_wait_busy();
|
||||
xflash_enable_wr();
|
||||
xflash_page_program(addr, buff, savelength);
|
||||
xflash_wait_busy();
|
||||
xflash_disable_wr();
|
||||
}
|
||||
}
|
||||
/* Read memory block mode, length is big endian. */
|
||||
@ -279,8 +279,8 @@ uint8_t optiboot_w25x20cl_enter()
|
||||
// Read the destination type. It should always be 'F' as flash. It is not checked.
|
||||
(void)getch();
|
||||
verifySpace();
|
||||
w25x20cl_wait_busy();
|
||||
w25x20cl_rd_data(addr, buff, length);
|
||||
xflash_wait_busy();
|
||||
xflash_rd_data(addr, buff, length);
|
||||
for (i = 0; i < length; ++ i)
|
||||
putch(buff[i]);
|
||||
}
|
||||
@ -288,9 +288,9 @@ uint8_t optiboot_w25x20cl_enter()
|
||||
else if(ch == STK_READ_SIGN) {
|
||||
// READ SIGN - return what Avrdude wants to hear
|
||||
verifySpace();
|
||||
putch(W25X20CL_SIGNATURE_0);
|
||||
putch(W25X20CL_SIGNATURE_1);
|
||||
putch(W25X20CL_SIGNATURE_2);
|
||||
putch(XFLASH_SIGNATURE_0);
|
||||
putch(XFLASH_SIGNATURE_1);
|
||||
putch(XFLASH_SIGNATURE_2);
|
||||
}
|
||||
else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
|
||||
// Adaboot no-wait mod
|
6
Firmware/optiboot_xflash.h
Normal file
6
Firmware/optiboot_xflash.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef OPTIBOOT_XFLASH_H
|
||||
#define OPTIBOOT_XFLASH_H
|
||||
|
||||
extern uint8_t optiboot_xflash_enter();
|
||||
|
||||
#endif /* OPTIBOOT_XFLASH_H */
|
@ -15,9 +15,11 @@
|
||||
#define AMBIENT_THERMISTOR
|
||||
#define PINDA_THERMISTOR
|
||||
|
||||
#define W25X20CL // external 256kB flash
|
||||
#define XFLASH // external 256kB flash
|
||||
#define BOOTAPP // bootloader support
|
||||
|
||||
#define XFLASH_PIN_CS 32
|
||||
|
||||
#define X_TMC2130_CS 41
|
||||
#define X_TMC2130_DIAG 64 // !!! changed from 40 (EINY03)
|
||||
#define X_STEP_PIN 37
|
||||
|
@ -68,8 +68,9 @@ uint8_t tmc2130_sg_diag_mask = 0x00;
|
||||
uint8_t tmc2130_sg_crash = 0;
|
||||
uint16_t tmc2130_sg_err[4] = {0, 0, 0, 0};
|
||||
uint16_t tmc2130_sg_cnt[4] = {0, 0, 0, 0};
|
||||
#ifdef DEBUG_CRASHDET_COUNTERS
|
||||
bool tmc2130_sg_change = false;
|
||||
|
||||
#endif
|
||||
|
||||
bool skip_debug_msg = false;
|
||||
|
||||
@ -255,7 +256,9 @@ void tmc2130_st_isr()
|
||||
if (tmc2130_sg_cnt[axis] < tmc2130_sg_err[axis])
|
||||
{
|
||||
tmc2130_sg_cnt[axis] = tmc2130_sg_err[axis];
|
||||
#ifdef DEBUG_CRASHDET_COUNTERS
|
||||
tmc2130_sg_change = true;
|
||||
#endif
|
||||
uint8_t sg_thr = 64;
|
||||
// if (axis == Y_AXIS) sg_thr = 64;
|
||||
if (tmc2130_sg_err[axis] >= sg_thr)
|
||||
@ -409,7 +412,9 @@ void tmc2130_check_overtemp()
|
||||
|
||||
}
|
||||
checktime = _millis();
|
||||
#ifdef DEBUG_CRASHDET_COUNTERS
|
||||
tmc2130_sg_change = true;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG_CRASHDET_COUNTERS
|
||||
if (tmc2130_sg_change)
|
||||
|
@ -2201,15 +2201,16 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed)
|
||||
}
|
||||
else
|
||||
{
|
||||
lcd_set_cursor(0, 0);
|
||||
lcdui_print_temp(LCD_STR_THERMOMETER[0], (int) degHotend(0), (int) degTargetHotend(0));
|
||||
|
||||
if (!bFilamentWaitingFlag)
|
||||
{
|
||||
// First run after the filament preheat selection:
|
||||
// setup the fixed LCD parts and raise Z as we wait
|
||||
bFilamentWaitingFlag = true;
|
||||
|
||||
lcd_clear();
|
||||
lcd_draw_update = 1;
|
||||
lcd_puts_at_P(0, 3, _i(">Cancel")); ////MSG_ c=20 r=1
|
||||
|
||||
lcd_set_cursor(0, 1);
|
||||
switch (eFilamentAction)
|
||||
{
|
||||
@ -2236,9 +2237,15 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed)
|
||||
// handled earlier
|
||||
break;
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
lcd_puts_at_P(0, 3, _T(MSG_CANCEL));
|
||||
=======
|
||||
>>>>>>> upstream/MK3_3.10.0
|
||||
}
|
||||
|
||||
lcd_set_cursor(0, 0);
|
||||
lcdui_print_temp(LCD_STR_THERMOMETER[0], (int) degHotend(0), (int) degTargetHotend(0));
|
||||
|
||||
if (lcd_clicked())
|
||||
{
|
||||
bFilamentWaitingFlag = false;
|
||||
@ -4361,7 +4368,7 @@ void menu_setlang(unsigned char lang)
|
||||
}
|
||||
|
||||
#ifdef COMMUNITY_LANG_SUPPORT
|
||||
#ifdef W25X20CL
|
||||
#ifdef XFLASH
|
||||
static void lcd_community_language_menu()
|
||||
{
|
||||
MENU_BEGIN();
|
||||
@ -4375,7 +4382,7 @@ static void lcd_community_language_menu()
|
||||
}
|
||||
MENU_END();
|
||||
}
|
||||
#endif //W25X20CL
|
||||
#endif //XFLASH
|
||||
#endif //COMMUNITY_LANG_SUPPORT && W52X20CL
|
||||
|
||||
|
||||
@ -4390,7 +4397,7 @@ static void lcd_language_menu()
|
||||
return;
|
||||
}
|
||||
uint8_t cnt = lang_get_count();
|
||||
#ifdef W25X20CL
|
||||
#ifdef XFLASH
|
||||
if (cnt == 2) //display secondary language in case of clear xflash
|
||||
{
|
||||
if (menu_item_text_P(lang_get_name_by_code(lang_get_code(1))))
|
||||
@ -4401,9 +4408,9 @@ static void lcd_language_menu()
|
||||
}
|
||||
else
|
||||
for (int i = 2; i < 8; i++) //skip seconday language - solved in lang_select (MK3) 'i < 8' for 7 official languages
|
||||
#else //W25X20CL
|
||||
#else //XFLASH
|
||||
for (int i = 1; i < cnt; i++) //all seconday languages (MK2/25)
|
||||
#endif //W25X20CL
|
||||
#endif //XFLASH
|
||||
if (menu_item_text_P(lang_get_name_by_code(lang_get_code(i))))
|
||||
{
|
||||
menu_setlang(i);
|
||||
@ -4411,9 +4418,9 @@ static void lcd_language_menu()
|
||||
}
|
||||
|
||||
#ifdef COMMUNITY_LANG_SUPPORT
|
||||
#ifdef W25X20CL
|
||||
#ifdef XFLASH
|
||||
MENU_ITEM_SUBMENU_P(_T(MSG_COMMUNITY_MADE), lcd_community_language_menu); ////MSG_COMMUNITY_MADE c=18
|
||||
#endif //W25X20CL
|
||||
#endif //XFLASH
|
||||
#endif //COMMUNITY_LANG_SUPPORT && W52X20CL
|
||||
|
||||
MENU_END();
|
||||
@ -4885,7 +4892,7 @@ void lcd_wizard(WizState state)
|
||||
lcd_display_message_fullscreen_P(_i("Now I will preheat nozzle for PLA."));
|
||||
wait_preheat();
|
||||
//unload current filament
|
||||
unload_filament();
|
||||
unload_filament(true);
|
||||
//load filament
|
||||
lcd_wizard_load();
|
||||
setTargetHotend(0, 0); //we are finished, cooldown nozzle
|
||||
@ -6200,13 +6207,14 @@ static void change_extr_menu(){
|
||||
}
|
||||
#endif //SNMM
|
||||
|
||||
//unload filament for single material printer (used in M702 gcode)
|
||||
void unload_filament()
|
||||
// unload filament for single material printer (used in M702 gcode)
|
||||
// @param automatic: If true, unload_filament is part of a unload+load sequence (M600)
|
||||
void unload_filament(bool automatic)
|
||||
{
|
||||
custom_message_type = CustomMsg::FilamentLoading;
|
||||
lcd_setstatuspgm(_T(MSG_UNLOADING_FILAMENT));
|
||||
|
||||
raise_z_above(MIN_Z_FOR_UNLOAD);
|
||||
raise_z_above(automatic? MIN_Z_FOR_SWAP: MIN_Z_FOR_UNLOAD);
|
||||
|
||||
// extr_unload2();
|
||||
|
||||
@ -6323,15 +6331,15 @@ unsigned char lcd_choose_color() {
|
||||
|
||||
}
|
||||
|
||||
#include "w25x20cl.h"
|
||||
#include "xflash.h"
|
||||
|
||||
#ifdef LCD_TEST
|
||||
static void lcd_test_menu()
|
||||
{
|
||||
W25X20CL_SPI_ENTER();
|
||||
w25x20cl_enable_wr();
|
||||
w25x20cl_chip_erase();
|
||||
w25x20cl_disable_wr();
|
||||
XFLASH_SPI_ENTER();
|
||||
xflash_enable_wr();
|
||||
xflash_chip_erase();
|
||||
xflash_disable_wr();
|
||||
}
|
||||
#endif //LCD_TEST
|
||||
|
||||
@ -6672,7 +6680,11 @@ static void lcd_main_menu()
|
||||
}
|
||||
MENU_ITEM_SUBMENU_P(_i("Support"), lcd_support_menu);////MSG_SUPPORT c=18
|
||||
#ifdef LCD_TEST
|
||||
<<<<<<< HEAD
|
||||
MENU_ITEM_SUBMENU_P(_i("W25x20CL init"), lcd_test_menu);
|
||||
=======
|
||||
MENU_ITEM_SUBMENU_P(_i("XFLASH init"), lcd_test_menu);////MSG_SUPPORT
|
||||
>>>>>>> upstream/MK3_3.10.0
|
||||
#endif //LCD_TEST
|
||||
|
||||
MENU_END();
|
||||
|
@ -195,7 +195,7 @@ extern bool bFilamentAction;
|
||||
void mFilamentItem(uint16_t nTemp,uint16_t nTempBed);
|
||||
void mFilamentItemForce();
|
||||
void lcd_generic_preheat_menu();
|
||||
void unload_filament();
|
||||
void unload_filament(bool automatic = false);
|
||||
|
||||
void stack_error();
|
||||
void lcd_printer_connected();
|
||||
|
@ -159,7 +159,7 @@
|
||||
|
||||
//#define DEBUG_BUILD
|
||||
//#define DEBUG_SEC_LANG //secondary language debug output at startup
|
||||
//#define DEBUG_W25X20CL //debug external spi flash
|
||||
//#define DEBUG_XFLASH //debug external spi flash
|
||||
#ifdef DEBUG_BUILD
|
||||
//#define _NO_ASM
|
||||
#define DEBUG_DCODES //D codes
|
||||
|
@ -161,7 +161,7 @@
|
||||
|
||||
//#define DEBUG_BUILD
|
||||
//#define DEBUG_SEC_LANG //secondary language debug output at startup
|
||||
//#define DEBUG_W25X20CL //debug external spi flash
|
||||
//#define DEBUG_XFLASH //debug external spi flash
|
||||
#ifdef DEBUG_BUILD
|
||||
//#define _NO_ASM
|
||||
#define DEBUG_DCODES //D codes
|
||||
|
@ -1,44 +0,0 @@
|
||||
//w25x20cl.h
|
||||
#ifndef _W25X20CL_H
|
||||
#define _W25X20CL_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "config.h"
|
||||
#include "spi.h"
|
||||
|
||||
|
||||
|
||||
#define W25X20CL_STATUS_BUSY 0x01
|
||||
#define W25X20CL_STATUS_WEL 0x02
|
||||
#define W25X20CL_STATUS_BP0 0x04
|
||||
#define W25X20CL_STATUS_BP1 0x08
|
||||
#define W25X20CL_STATUS_TB 0x20
|
||||
#define W25X20CL_STATUS_SRP 0x80
|
||||
|
||||
#define W25X20CL_SPI_ENTER() spi_setup(W25X20CL_SPCR, W25X20CL_SPSR)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif //defined(__cplusplus)
|
||||
|
||||
|
||||
extern int8_t w25x20cl_init(void);
|
||||
extern void w25x20cl_enable_wr(void);
|
||||
extern void w25x20cl_disable_wr(void);
|
||||
extern uint8_t w25x20cl_rd_status_reg(void);
|
||||
extern void w25x20cl_wr_status_reg(uint8_t val);
|
||||
extern void w25x20cl_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt);
|
||||
extern void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt);
|
||||
extern void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt);
|
||||
extern void w25x20cl_sector_erase(uint32_t addr);
|
||||
extern void w25x20cl_block32_erase(uint32_t addr);
|
||||
extern void w25x20cl_block64_erase(uint32_t addr);
|
||||
extern void w25x20cl_chip_erase(void);
|
||||
extern void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt);
|
||||
extern void w25x20cl_rd_uid(uint8_t* uid);
|
||||
extern void w25x20cl_wait_busy(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif //defined(__cplusplus)
|
||||
#endif //_W25X20CL_H
|
@ -1,13 +1,18 @@
|
||||
//w25x20cl.c
|
||||
//xflash.c
|
||||
|
||||
#include "w25x20cl.h"
|
||||
#include "xflash.h"
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "spi.h"
|
||||
#include "fastio.h"
|
||||
|
||||
#define _MFRID 0xEF
|
||||
#define _DEVID 0x11
|
||||
#ifdef XFLASH
|
||||
|
||||
#define _MFRID_W25X20CL 0xEF
|
||||
#define _DEVID_W25X20CL 0x11
|
||||
|
||||
#define _MFRID_GD25Q20C 0xC8
|
||||
#define _DEVID_GD25Q20C 0x11
|
||||
|
||||
#define _CMD_ENABLE_WR 0x06
|
||||
#define _CMD_ENABLE_WR_VSR 0x50
|
||||
@ -31,8 +36,8 @@
|
||||
#define _CMD_JEDEC_ID 0x9f
|
||||
#define _CMD_RD_UID 0x4b
|
||||
|
||||
#define _CS_LOW() WRITE(W25X20CL_PIN_CS, 0)
|
||||
#define _CS_HIGH() WRITE(W25X20CL_PIN_CS, 1)
|
||||
#define _CS_LOW() WRITE(XFLASH_PIN_CS, 0)
|
||||
#define _CS_HIGH() WRITE(XFLASH_PIN_CS, 1)
|
||||
|
||||
//#define _SPI_TX swspi_tx
|
||||
//#define _SPI_RX swspi_rx
|
||||
@ -40,33 +45,33 @@
|
||||
#define _SPI_RX() spi_txrx(0xff)
|
||||
|
||||
|
||||
int w25x20cl_mfrid_devid(void);
|
||||
int xflash_mfrid_devid(void);
|
||||
|
||||
|
||||
int8_t w25x20cl_init(void)
|
||||
int8_t xflash_init(void)
|
||||
{
|
||||
_CS_HIGH();
|
||||
SET_OUTPUT(W25X20CL_PIN_CS);
|
||||
W25X20CL_SPI_ENTER();
|
||||
if (!w25x20cl_mfrid_devid()) return 0;
|
||||
SET_OUTPUT(XFLASH_PIN_CS);
|
||||
XFLASH_SPI_ENTER();
|
||||
if (!xflash_mfrid_devid()) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void w25x20cl_enable_wr(void)
|
||||
void xflash_enable_wr(void)
|
||||
{
|
||||
_CS_LOW();
|
||||
_SPI_TX(_CMD_ENABLE_WR); // send command 0x06
|
||||
_CS_HIGH();
|
||||
}
|
||||
|
||||
void w25x20cl_disable_wr(void)
|
||||
void xflash_disable_wr(void)
|
||||
{
|
||||
_CS_LOW();
|
||||
_SPI_TX(_CMD_DISABLE_WR); // send command 0x04
|
||||
_CS_HIGH();
|
||||
}
|
||||
|
||||
uint8_t w25x20cl_rd_status_reg(void)
|
||||
uint8_t xflash_rd_status_reg(void)
|
||||
{
|
||||
_CS_LOW();
|
||||
_SPI_TX(_CMD_RD_STATUS_REG); // send command 0x90
|
||||
@ -75,6 +80,7 @@ uint8_t w25x20cl_rd_status_reg(void)
|
||||
return val;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void w25x20cl_wr_status_reg(uint8_t val)
|
||||
{
|
||||
_CS_LOW();
|
||||
@ -82,8 +88,9 @@ void w25x20cl_wr_status_reg(uint8_t val)
|
||||
_SPI_TX(val); // send value
|
||||
_CS_HIGH();
|
||||
}
|
||||
#endif
|
||||
|
||||
void w25x20cl_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt)
|
||||
void xflash_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt)
|
||||
{
|
||||
_CS_LOW();
|
||||
_SPI_TX(_CMD_RD_DATA); // send command 0x03
|
||||
@ -95,7 +102,7 @@ void w25x20cl_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt)
|
||||
_CS_HIGH();
|
||||
}
|
||||
|
||||
void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt)
|
||||
void xflash_page_program(uint32_t addr, uint8_t* data, uint16_t cnt)
|
||||
{
|
||||
_CS_LOW();
|
||||
_SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02
|
||||
@ -107,7 +114,7 @@ void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt)
|
||||
_CS_HIGH();
|
||||
}
|
||||
|
||||
void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt)
|
||||
void xflash_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt)
|
||||
{
|
||||
_CS_LOW();
|
||||
_SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02
|
||||
@ -119,7 +126,7 @@ void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt)
|
||||
_CS_HIGH();
|
||||
}
|
||||
|
||||
void w25x20cl_erase(uint8_t cmd, uint32_t addr)
|
||||
void xflash_erase(uint8_t cmd, uint32_t addr)
|
||||
{
|
||||
_CS_LOW();
|
||||
_SPI_TX(cmd); // send command 0x20
|
||||
@ -129,22 +136,22 @@ void w25x20cl_erase(uint8_t cmd, uint32_t addr)
|
||||
_CS_HIGH();
|
||||
}
|
||||
|
||||
void w25x20cl_sector_erase(uint32_t addr)
|
||||
void xflash_sector_erase(uint32_t addr)
|
||||
{
|
||||
return w25x20cl_erase(_CMD_SECTOR_ERASE, addr);
|
||||
return xflash_erase(_CMD_SECTOR_ERASE, addr);
|
||||
}
|
||||
|
||||
void w25x20cl_block32_erase(uint32_t addr)
|
||||
void xflash_block32_erase(uint32_t addr)
|
||||
{
|
||||
return w25x20cl_erase(_CMD_BLOCK32_ERASE, addr);
|
||||
return xflash_erase(_CMD_BLOCK32_ERASE, addr);
|
||||
}
|
||||
|
||||
void w25x20cl_block64_erase(uint32_t addr)
|
||||
void xflash_block64_erase(uint32_t addr)
|
||||
{
|
||||
return w25x20cl_erase(_CMD_BLOCK64_ERASE, addr);
|
||||
return xflash_erase(_CMD_BLOCK64_ERASE, addr);
|
||||
}
|
||||
|
||||
void w25x20cl_chip_erase(void)
|
||||
void xflash_chip_erase(void)
|
||||
{
|
||||
_CS_LOW();
|
||||
_SPI_TX(_CMD_CHIP_ERASE); // send command 0xc7
|
||||
@ -152,33 +159,37 @@ void w25x20cl_chip_erase(void)
|
||||
}
|
||||
|
||||
|
||||
void w25x20cl_rd_uid(uint8_t* uid)
|
||||
void xflash_rd_uid(uint8_t* uid)
|
||||
{
|
||||
_CS_LOW();
|
||||
_SPI_TX(_CMD_RD_UID); // send command 0x4b
|
||||
uint8_t cnt = 4; // 4 dummy bytes
|
||||
while (cnt--) // receive dummy bytes
|
||||
_SPI_RX();
|
||||
while (cnt--) // transmit dummy bytes
|
||||
_SPI_TX(0x00);
|
||||
cnt = 8; // 8 bytes UID
|
||||
while (cnt--) // receive UID
|
||||
uid[7 - cnt] = _SPI_RX();
|
||||
_CS_HIGH();
|
||||
}
|
||||
|
||||
int w25x20cl_mfrid_devid(void)
|
||||
int xflash_mfrid_devid(void)
|
||||
{
|
||||
_CS_LOW();
|
||||
_SPI_TX(_CMD_MFRID_DEVID); // send command 0x90
|
||||
uint8_t cnt = 3; // 3 address bytes
|
||||
while (cnt--) // send address bytes
|
||||
_SPI_TX(0x00);
|
||||
uint8_t w25x20cl_mfrid = _SPI_RX(); // receive mfrid
|
||||
uint8_t w25x20cl_devid = _SPI_RX(); // receive devid
|
||||
uint8_t xflash_mfrid = _SPI_RX(); // receive mfrid
|
||||
uint8_t xflash_devid = _SPI_RX(); // receive devid
|
||||
_CS_HIGH();
|
||||
return ((w25x20cl_mfrid == _MFRID) && (w25x20cl_devid == _DEVID));
|
||||
return
|
||||
((xflash_mfrid == _MFRID_W25X20CL) && (xflash_devid == _DEVID_W25X20CL)) ||
|
||||
((xflash_mfrid == _MFRID_GD25Q20C) && (xflash_devid == _DEVID_GD25Q20C));
|
||||
}
|
||||
|
||||
void w25x20cl_wait_busy(void)
|
||||
void xflash_wait_busy(void)
|
||||
{
|
||||
while (w25x20cl_rd_status_reg() & W25X20CL_STATUS_BUSY) ;
|
||||
while (xflash_rd_status_reg() & XFLASH_STATUS_BUSY) ;
|
||||
}
|
||||
|
||||
#endif //XFLASH
|
50
Firmware/xflash.h
Normal file
50
Firmware/xflash.h
Normal file
@ -0,0 +1,50 @@
|
||||
//xflash.h
|
||||
#ifndef _XFLASH_H
|
||||
#define _XFLASH_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "config.h"
|
||||
#include "spi.h"
|
||||
|
||||
|
||||
|
||||
#define XFLASH_STATUS_BUSY 0x01
|
||||
#define XFLASH_STATUS_WEL 0x02
|
||||
#define XFLASH_STATUS_BP0 0x04
|
||||
#define XFLASH_STATUS_BP1 0x08
|
||||
#define XFLASH_STATUS_TB 0x20
|
||||
#define XFLASH_STATUS_SRP 0x80
|
||||
|
||||
#define XFLASH_SPI_RATE 0 // fosc/4 = 4MHz
|
||||
#define XFLASH_SPCR SPI_SPCR(XFLASH_SPI_RATE, 1, 1, 1, 0)
|
||||
#define XFLASH_SPSR SPI_SPSR(XFLASH_SPI_RATE)
|
||||
|
||||
#define XFLASH_SPI_ENTER() spi_setup(XFLASH_SPCR, XFLASH_SPSR)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif //defined(__cplusplus)
|
||||
|
||||
|
||||
extern int8_t xflash_init(void);
|
||||
extern void xflash_enable_wr(void);
|
||||
extern void xflash_disable_wr(void);
|
||||
extern uint8_t xflash_rd_status_reg(void);
|
||||
#if 0
|
||||
extern void w25x20cl_wr_status_reg(uint8_t val);
|
||||
#endif
|
||||
extern void xflash_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt);
|
||||
extern void xflash_page_program(uint32_t addr, uint8_t* data, uint16_t cnt);
|
||||
extern void xflash_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt);
|
||||
extern void xflash_sector_erase(uint32_t addr);
|
||||
extern void xflash_block32_erase(uint32_t addr);
|
||||
extern void xflash_block64_erase(uint32_t addr);
|
||||
extern void xflash_chip_erase(void);
|
||||
extern void xflash_page_program(uint32_t addr, uint8_t* data, uint16_t cnt);
|
||||
extern void xflash_rd_uid(uint8_t* uid);
|
||||
extern void xflash_wait_busy(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif //defined(__cplusplus)
|
||||
#endif //_XFLASH_H
|
@ -837,7 +837,7 @@ void dynamic_circle(uint8_t *matrix_32x32, float &x, float &y, float &r, uint8_t
|
||||
for (int8_t i = iterations; i > 0; --i){
|
||||
|
||||
//@size=128B
|
||||
DBG(_n(" [%f, %f][%f] circle\n"), x, y, r);
|
||||
// DBG(_n(" [%f, %f][%f] circle\n"), x, y, r);
|
||||
|
||||
/// read points on the circle
|
||||
for (uint8_t p = 0; p < num_points; ++p){
|
||||
@ -904,12 +904,42 @@ uint8_t find_patterns(uint8_t *matrix32, uint16_t *pattern08, uint16_t *pattern1
|
||||
return match10;
|
||||
}
|
||||
|
||||
/// Scan should include normal data.
|
||||
/// If it's too extreme (00, FF) it could be caused by biased sensor.
|
||||
/// \return true if data looks normal
|
||||
bool check_scan(uint8_t *matrix32){
|
||||
/// magic constants that define normality
|
||||
const int16_t threshold_total = 900;
|
||||
const int threshold_extreme = 50;
|
||||
|
||||
int16_t mins = 0;
|
||||
int16_t maxs = 0;
|
||||
|
||||
for (int16_t i = 0; i < 32*32;++i){
|
||||
if (matrix32[i] == 0) {
|
||||
++mins;
|
||||
} else if (matrix32[i] == 0xFF){
|
||||
++maxs;
|
||||
}
|
||||
}
|
||||
const int16_t rest = 1024 - mins - maxs;
|
||||
|
||||
if (mins + maxs > threshold_total
|
||||
&& mins > threshold_extreme
|
||||
&& maxs > threshold_extreme
|
||||
&& mins > rest
|
||||
&& maxs > rest)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// scans area around the current head location and
|
||||
/// searches for the center of the calibration pin
|
||||
bool xyzcal_scan_and_process(void){
|
||||
BedSkewOffsetDetectionResultType xyzcal_scan_and_process(){
|
||||
//@size=44
|
||||
DBG(_n("sizeof(block_buffer)=%d\n"), sizeof(block_t)*BLOCK_BUFFER_SIZE);
|
||||
bool ret = false;
|
||||
// DBG(_n("sizeof(block_buffer)=%d\n"), sizeof(block_t)*BLOCK_BUFFER_SIZE);
|
||||
BedSkewOffsetDetectionResultType ret = BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND;
|
||||
int16_t x = _X;
|
||||
int16_t y = _Y;
|
||||
const int16_t z = _Z;
|
||||
@ -925,6 +955,8 @@ bool xyzcal_scan_and_process(void){
|
||||
|
||||
xyzcal_scan_pixels_32x32_Zhop(x, y, z, 2400, 200, matrix32);
|
||||
print_image(matrix32);
|
||||
if (!check_scan(matrix32))
|
||||
return BED_SKEW_OFFSET_DETECTION_POINT_SCAN_FAILED;
|
||||
|
||||
/// SEARCH FOR BINARY CIRCLE
|
||||
uint8_t uc = 0;
|
||||
@ -955,7 +987,7 @@ bool xyzcal_scan_and_process(void){
|
||||
x = round_to_i16(xf);
|
||||
y = round_to_i16(yf);
|
||||
xyzcal_lineXYZ_to(x, y, z, 200, 0);
|
||||
ret = true;
|
||||
ret = BED_SKEW_OFFSET_DETECTION_POINT_FOUND;
|
||||
}
|
||||
|
||||
/// wipe buffer
|
||||
@ -964,11 +996,11 @@ bool xyzcal_scan_and_process(void){
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool xyzcal_find_bed_induction_sensor_point_xy(void){
|
||||
bool ret = false;
|
||||
BedSkewOffsetDetectionResultType xyzcal_find_bed_induction_sensor_point_xy(void){
|
||||
BedSkewOffsetDetectionResultType ret = BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND;
|
||||
|
||||
//@size=258
|
||||
DBG(_n("xyzcal_find_bed_induction_sensor_point_xy x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]);
|
||||
// DBG(_n("xyzcal_find_bed_induction_sensor_point_xy x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]);
|
||||
st_synchronize();
|
||||
|
||||
xyzcal_meassure_enter();
|
||||
|
@ -1,9 +1,9 @@
|
||||
//xyzcal.h - xyz calibration with image processing
|
||||
#ifndef _XYZCAL_H
|
||||
#define _XYZCAL_H
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "mesh_bed_calibration.h"
|
||||
|
||||
extern void xyzcal_meassure_enter(void);
|
||||
|
||||
@ -17,11 +17,4 @@ extern bool xyzcal_spiral8(int16_t cx, int16_t cy, int16_t z0, int16_t dz, int16
|
||||
|
||||
//extern int8_t xyzcal_meassure_pinda_hysterezis(int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t samples);
|
||||
|
||||
extern bool xyzcal_searchZ(void);
|
||||
|
||||
extern bool xyzcal_scan_and_process(void);
|
||||
|
||||
extern bool xyzcal_find_bed_induction_sensor_point_xy(void);
|
||||
|
||||
|
||||
#endif //_XYZCAL_H
|
||||
extern BedSkewOffsetDetectionResultType xyzcal_find_bed_induction_sensor_point_xy();
|
||||
|
@ -88,7 +88,7 @@ generate_binary()
|
||||
rm -f lang_$1.dat
|
||||
LNG=$1
|
||||
#check lang dictionary
|
||||
./lang-check.py $1 --no-warning
|
||||
./lang-check.py $1 #--no-warning
|
||||
#create lang_xx.tmp - different processing for 'en' language
|
||||
if [ "$1" = "en" ]; then
|
||||
#remove comments and empty lines
|
||||
|
@ -1,9 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Version 1.0.1
|
||||
#
|
||||
#############################################################################
|
||||
# Change log:
|
||||
# 7 May 2019, Ondrej Tuma, Initial
|
||||
# 9 June 2020, 3d-gussner, Added version and Change log
|
||||
# 9 June 2020, 3d-gussner, Wrap text to 20 char and rows
|
||||
# 9 June 2020, 3d-gussner, colored output
|
||||
# 2 Apr. 2021, 3d-gussner, Fix and improve text warp
|
||||
#############################################################################
|
||||
#
|
||||
"""Check lang files."""
|
||||
from argparse import ArgumentParser
|
||||
from traceback import print_exc
|
||||
from sys import stderr
|
||||
import textwrap
|
||||
|
||||
red = lambda text: '\033[0;31m' + text + '\033[0m'
|
||||
green = lambda text: '\033[0;32m' + text + '\033[0m'
|
||||
yellow = lambda text: '\033[0;33m' + text + '\033[0m'
|
||||
|
||||
def parse_txt(lang, no_warning):
|
||||
"""Parse txt file and check strings to display definition."""
|
||||
@ -12,48 +28,67 @@ def parse_txt(lang, no_warning):
|
||||
else:
|
||||
file_path = "lang_en_%s.txt" % lang
|
||||
|
||||
print(green("Start %s lang-check" % lang))
|
||||
|
||||
lines = 1
|
||||
with open(file_path) as src:
|
||||
while True:
|
||||
comment = src.readline().split(' ')
|
||||
src.readline() # source
|
||||
#print (comment) #Debug
|
||||
source = src.readline()[:-1]
|
||||
#print (source) #Debug
|
||||
translation = src.readline()[:-1]
|
||||
#print (translation) #Debug
|
||||
#Wrap text to 20 chars and rows
|
||||
wrapper = textwrap.TextWrapper(width=20)
|
||||
#wrap original/source
|
||||
rows_count_source = 0
|
||||
for line in wrapper.wrap(source.strip('"')):
|
||||
rows_count_source += 1
|
||||
#print (line) #Debug
|
||||
#wrap translation
|
||||
rows_count_translation = 0
|
||||
for line in wrapper.wrap(translation.strip('"')):
|
||||
rows_count_translation += 1
|
||||
#print (line) #Debug
|
||||
#End wrap text
|
||||
|
||||
#Check if columns and rows are defined
|
||||
cols = None
|
||||
rows = None
|
||||
for item in comment[1:]:
|
||||
key, val = item.split('=')
|
||||
if key == 'c':
|
||||
cols = int(val)
|
||||
#print ("c=",cols) #Debug
|
||||
elif key == 'r':
|
||||
rows = int(val)
|
||||
#print ("r=",rows) #Debug
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"Unknown display definition %s on line %d" %
|
||||
(' '.join(comment), lines))
|
||||
if cols is None and rows is None:
|
||||
if not no_warning:
|
||||
print("[W]: No display definition on line %d" % lines)
|
||||
print(yellow("[W]: No display definition on line %d" % lines))
|
||||
cols = len(translation) # propably fullscreen
|
||||
if rows is None:
|
||||
rows = 1
|
||||
|
||||
if len(translation)-2 > cols*rows:
|
||||
stderr.write(
|
||||
"[E]: Text %s is longer then definiton on line %d\n" %
|
||||
(translation, lines))
|
||||
stderr.flush()
|
||||
if rows_count_translation > rows_count_source and rows_count_translation > rows:
|
||||
print(red("[E]: Text %s is longer then definiton on line %d rows diff=%d, EN=%s\n" % (translation, lines, rows_count_translation-rows, source)))
|
||||
|
||||
if len(src.readline()) != 1: # empty line
|
||||
break
|
||||
lines += 4
|
||||
print(green("End %s lang-check" % lang))
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function."""
|
||||
parser = ArgumentParser(
|
||||
description=__doc__,
|
||||
usage="$(prog)s lang")
|
||||
usage="%(prog)s lang")
|
||||
parser.add_argument(
|
||||
"lang", nargs='?', default="en", type=str,
|
||||
help="Check lang file (en|cs|de|es|fr|nl|it|pl)")
|
||||
|
Loading…
Reference in New Issue
Block a user