From 21dcfb23f45b11bdb41c316d75d9bed1fd406cfa Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Thu, 31 Oct 2019 15:31:08 +0100 Subject: [PATCH 01/58] Follow RepRap Wiki G-codes documentation M120 is Enable endstops M121 is disable endstops I guess this was just a typo issue. --- Firmware/Marlin_main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a2cbece5..593194c6 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -6366,16 +6366,16 @@ Sigma_Exit: lcd_setstatus(strchr_pointer + 5); break;*/ - //! ### M120 - Disable endstops + //! ### M120 - Ensable endstops // ---------------------------------------- case 120: - enable_endstops(false) ; + enable_endstops(true) ; break; - //! ### M121 - Enable endstops + //! ### M121 - Disable endstops // ---------------------------------------- case 121: - enable_endstops(true) ; + enable_endstops(false) ; break; //! ### M119 - Get endstop states From 6017600714a751a46b879964d186ea97115c5277 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Sun, 16 Jun 2019 21:05:13 +0200 Subject: [PATCH 02/58] Reintroduce the ability to disable TMC interpolation per-axis --- Firmware/tmc2130.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Firmware/tmc2130.cpp b/Firmware/tmc2130.cpp index 108d00b1..b87272e2 100755 --- a/Firmware/tmc2130.cpp +++ b/Firmware/tmc2130.cpp @@ -437,6 +437,9 @@ void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_ uint8_t tbl = tmc2130_chopper_config[axis].tbl; //blanking time, original value = 2 if (axis == E_AXIS) { +#if defined(TMC2130_INTPOL_E) && (TMC2130_INTPOL_E == 0) + intpol = 0; +#endif #ifdef TMC2130_CNSTOFF_E // fd = 0 (slow decay only) hstrt = 0; //fd0..2 @@ -447,6 +450,16 @@ void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_ // toff = TMC2130_TOFF_E; // toff = 3-5 // rndtf = 1; } +#if defined(TMC2130_INTPOL_XY) && (TMC2130_INTPOL_XY == 0) + else if (axis == X_AXIS || axis == Y_AXIS) { + intpol = 0; + } +#endif +#if defined(TMC2130_INTPOL_Z) && (TMC2130_INTPOL_Z == 0) + else if (axis == Z_AXIS) { + intpol = 0; + } +#endif // DBG(_n("tmc2130_setup_chopper(axis=%hhd, mres=%hhd, curh=%hhd, curr=%hhd\n"), axis, mres, current_h, current_r); // DBG(_n(" toff=%hhd, hstr=%hhd, hend=%hhd, tbl=%hhd\n"), toff, hstrt, hend, tbl); if (current_r <= 31) From 6ceca9bf85f93479e677194635e873bbfa831bbb Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Tue, 18 Feb 2020 11:52:36 +0100 Subject: [PATCH 03/58] Implement double-edge stepping Introduce new wrapper macros to tick the stepper pins. Default to the original raising-edge stepping mode. When using the TMC double-edge stepping mode (aka half-wave or square-wave mode) the _LO macros become no-ops. --- Firmware/stepper.cpp | 128 +++++++++++++++++++++++++++++-------------- Firmware/tmc2130.cpp | 16 +++++- 2 files changed, 100 insertions(+), 44 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index de250ec9..8f2a4f12 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -48,6 +48,50 @@ int fsensor_counter; //counter for e-steps uint16_t SP_min = 0x21FF; #endif //DEBUG_STACK_MONITOR + +/* + * Stepping macros + */ +#define _STEP_PIN_X_AXIS X_STEP_PIN +#define _STEP_PIN_Y_AXIS Y_STEP_PIN +#define _STEP_PIN_Z_AXIS Z_STEP_PIN +#define _STEP_PIN_E_AXIS E0_STEP_PIN + +#ifdef DEBUG_XSTEP_DUP_PIN +#define _STEP_PIN_X_DUP_AXIS DEBUG_XSTEP_DUP_PIN +#endif +#ifdef DEBUG_YSTEP_DUP_PIN +#define _STEP_PIN_Y_DUP_AXIS DEBUG_YSTEP_DUP_PIN +#endif +#ifdef Y_DUAL_STEPPER_DRIVERS +#error Y_DUAL_STEPPER_DRIVERS not fully implemented +#define _STEP_PIN_Y2_AXIS Y2_STEP_PIN +#endif +#ifdef Z_DUAL_STEPPER_DRIVERS +#error Z_DUAL_STEPPER_DRIVERS not fully implemented +#define _STEP_PIN_Z2_AXIS Z2_STEP_PIN +#endif + +#ifdef TMC2130_DEDGE_STEPPING +#define STEP_NC_HI(axis) TOGGLE(_STEP_PIN_##axis) +#define STEP_NC_LO(axis) //NOP +#else + +#define _STEP_HI_X_AXIS !INVERT_X_STEP_PIN +#define _STEP_LO_X_AXIS INVERT_X_STEP_PIN +#define _STEP_HI_Y_AXIS !INVERT_Y_STEP_PIN +#define _STEP_LO_Y_AXIS INVERT_Y_STEP_PIN +#define _STEP_HI_Z_AXIS !INVERT_Z_STEP_PIN +#define _STEP_LO_Z_AXIS INVERT_Z_STEP_PIN +#define _STEP_HI_E_AXIS !INVERT_E_STEP_PIN +#define _STEP_LO_E_AXIS INVERT_E_STEP_PIN + +#define STEP_NC_HI(axis) WRITE_NC(_STEP_PIN_##axis, _STEP_HI_##axis) +#define STEP_NC_LO(axis) WRITE_NC(_STEP_PIN_##axis, _STEP_LO_##axis) + +#endif //TMC2130_DEDGE_STEPPING + + //=========================================================================== //=============================public variables ============================ //=========================================================================== @@ -300,9 +344,9 @@ FORCE_INLINE void stepper_next_block() _delay_us(100); for (uint8_t i = 0; i < st_backlash_x; i++) { - WRITE_NC(X_STEP_PIN, !INVERT_X_STEP_PIN); + STEP_NC_HI(X_AXIS); _delay_us(100); - WRITE_NC(X_STEP_PIN, INVERT_X_STEP_PIN); + STEP_NC_LO(X_AXIS); _delay_us(900); } } @@ -323,9 +367,9 @@ FORCE_INLINE void stepper_next_block() _delay_us(100); for (uint8_t i = 0; i < st_backlash_y; i++) { - WRITE_NC(Y_STEP_PIN, !INVERT_Y_STEP_PIN); + STEP_NC_HI(Y_AXIS); _delay_us(100); - WRITE_NC(Y_STEP_PIN, INVERT_Y_STEP_PIN); + STEP_NC_LO(Y_AXIS); _delay_us(900); } } @@ -607,44 +651,44 @@ FORCE_INLINE void stepper_tick_lowres() // Step in X axis counter_x.lo += current_block->steps_x.lo; if (counter_x.lo > 0) { - WRITE_NC(X_STEP_PIN, !INVERT_X_STEP_PIN); + STEP_NC_HI(X_AXIS); #ifdef DEBUG_XSTEP_DUP_PIN - WRITE_NC(DEBUG_XSTEP_DUP_PIN,!INVERT_X_STEP_PIN); + STEP_NC_HI(X_DUP_AXIS); #endif //DEBUG_XSTEP_DUP_PIN counter_x.lo -= current_block->step_event_count.lo; count_position[X_AXIS]+=count_direction[X_AXIS]; - WRITE_NC(X_STEP_PIN, INVERT_X_STEP_PIN); + STEP_NC_LO(X_AXIS); #ifdef DEBUG_XSTEP_DUP_PIN - WRITE_NC(DEBUG_XSTEP_DUP_PIN,INVERT_X_STEP_PIN); + STEP_NC_LO(X_DUP_AXIS); #endif //DEBUG_XSTEP_DUP_PIN } // Step in Y axis counter_y.lo += current_block->steps_y.lo; if (counter_y.lo > 0) { - WRITE_NC(Y_STEP_PIN, !INVERT_Y_STEP_PIN); + STEP_NC_HI(Y_AXIS); #ifdef DEBUG_YSTEP_DUP_PIN - WRITE_NC(DEBUG_YSTEP_DUP_PIN,!INVERT_Y_STEP_PIN); + STEP_NC_HI(Y_DUP_AXIS); #endif //DEBUG_YSTEP_DUP_PIN counter_y.lo -= current_block->step_event_count.lo; count_position[Y_AXIS]+=count_direction[Y_AXIS]; - WRITE_NC(Y_STEP_PIN, INVERT_Y_STEP_PIN); + STEP_NC_LO(Y_AXIS); #ifdef DEBUG_YSTEP_DUP_PIN - WRITE_NC(DEBUG_YSTEP_DUP_PIN,INVERT_Y_STEP_PIN); + STEP_NC_LO(Y_DUP_AXIS); #endif //DEBUG_YSTEP_DUP_PIN } // Step in Z axis counter_z.lo += current_block->steps_z.lo; if (counter_z.lo > 0) { - WRITE_NC(Z_STEP_PIN, !INVERT_Z_STEP_PIN); + STEP_NC_HI(Z_AXIS); counter_z.lo -= current_block->step_event_count.lo; count_position[Z_AXIS]+=count_direction[Z_AXIS]; - WRITE_NC(Z_STEP_PIN, INVERT_Z_STEP_PIN); + STEP_NC_LO(Z_AXIS); } // Step in E axis counter_e.lo += current_block->steps_e.lo; if (counter_e.lo > 0) { #ifndef LIN_ADVANCE - WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); + STEP_NC_HI(E_AXIS); #endif /* LIN_ADVANCE */ counter_e.lo -= current_block->step_event_count.lo; count_position[E_AXIS] += count_direction[E_AXIS]; @@ -654,7 +698,7 @@ FORCE_INLINE void stepper_tick_lowres() #ifdef FILAMENT_SENSOR fsensor_counter += count_direction[E_AXIS]; #endif //FILAMENT_SENSOR - WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN); + STEP_NC_LO(E_AXIS); #endif } if(++ step_events_completed.lo >= current_block->step_event_count.lo) @@ -669,44 +713,44 @@ FORCE_INLINE void stepper_tick_highres() // Step in X axis counter_x.wide += current_block->steps_x.wide; if (counter_x.wide > 0) { - WRITE_NC(X_STEP_PIN, !INVERT_X_STEP_PIN); + STEP_NC_HI(X_AXIS); #ifdef DEBUG_XSTEP_DUP_PIN - WRITE_NC(DEBUG_XSTEP_DUP_PIN,!INVERT_X_STEP_PIN); + STEP_NC_HI(X_DUP_AXIS); #endif //DEBUG_XSTEP_DUP_PIN counter_x.wide -= current_block->step_event_count.wide; count_position[X_AXIS]+=count_direction[X_AXIS]; - WRITE_NC(X_STEP_PIN, INVERT_X_STEP_PIN); + STEP_NC_LO(X_AXIS); #ifdef DEBUG_XSTEP_DUP_PIN - WRITE_NC(DEBUG_XSTEP_DUP_PIN,INVERT_X_STEP_PIN); + STEP_NC_LO(X_DUP_AXIS); #endif //DEBUG_XSTEP_DUP_PIN } // Step in Y axis counter_y.wide += current_block->steps_y.wide; if (counter_y.wide > 0) { - WRITE_NC(Y_STEP_PIN, !INVERT_Y_STEP_PIN); + STEP_NC_HI(Y_AXIS); #ifdef DEBUG_YSTEP_DUP_PIN - WRITE_NC(DEBUG_YSTEP_DUP_PIN,!INVERT_Y_STEP_PIN); + STEP_NC_HI(Y_DUP_AXIS); #endif //DEBUG_YSTEP_DUP_PIN counter_y.wide -= current_block->step_event_count.wide; count_position[Y_AXIS]+=count_direction[Y_AXIS]; - WRITE_NC(Y_STEP_PIN, INVERT_Y_STEP_PIN); + STEP_NC_LO(Y_AXIS); #ifdef DEBUG_YSTEP_DUP_PIN - WRITE_NC(DEBUG_YSTEP_DUP_PIN,INVERT_Y_STEP_PIN); + STEP_NC_LO(Y_DUP_AXIS); #endif //DEBUG_YSTEP_DUP_PIN } // Step in Z axis counter_z.wide += current_block->steps_z.wide; if (counter_z.wide > 0) { - WRITE_NC(Z_STEP_PIN, !INVERT_Z_STEP_PIN); + STEP_NC_HI(Z_AXIS); counter_z.wide -= current_block->step_event_count.wide; count_position[Z_AXIS]+=count_direction[Z_AXIS]; - WRITE_NC(Z_STEP_PIN, INVERT_Z_STEP_PIN); + STEP_NC_LO(Z_AXIS); } // Step in E axis counter_e.wide += current_block->steps_e.wide; if (counter_e.wide > 0) { #ifndef LIN_ADVANCE - WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); + STEP_NC_HI(E_AXIS); #endif /* LIN_ADVANCE */ counter_e.wide -= current_block->step_event_count.wide; count_position[E_AXIS]+=count_direction[E_AXIS]; @@ -716,7 +760,7 @@ FORCE_INLINE void stepper_tick_highres() #ifdef FILAMENT_SENSOR fsensor_counter += count_direction[E_AXIS]; #endif //FILAMENT_SENSOR - WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN); + STEP_NC_LO(E_AXIS); #endif } if(++ step_events_completed.wide >= current_block->step_event_count.wide) @@ -997,9 +1041,9 @@ FORCE_INLINE void advance_isr_scheduler() { bool rev = (e_steps < 0); do { - WRITE_NC(E0_STEP_PIN, !INVERT_E_STEP_PIN); + STEP_NC_HI(E_AXIS); e_steps += (rev? 1: -1); - WRITE_NC(E0_STEP_PIN, INVERT_E_STEP_PIN); + STEP_NC_LO(E_AXIS); #if defined(FILAMENT_SENSOR) && defined(PAT9125) fsensor_counter += (rev? -1: 1); #endif @@ -1385,14 +1429,14 @@ void babystep(const uint8_t axis,const bool direction) WRITE(X_DIR_PIN,(INVERT_X_DIR)^direction); //perform step - WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); + STEP_NC_HI(X_AXIS); #ifdef DEBUG_XSTEP_DUP_PIN - WRITE(DEBUG_XSTEP_DUP_PIN,!INVERT_X_STEP_PIN); + STEP_NC_HI(X_DUP_AXIS); #endif //DEBUG_XSTEP_DUP_PIN delayMicroseconds(1); - WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); + STEP_NC_LO(X_AXIS); #ifdef DEBUG_XSTEP_DUP_PIN - WRITE(DEBUG_XSTEP_DUP_PIN,INVERT_X_STEP_PIN); + STEP_NC_LO(X_DUP_AXIS); #endif //DEBUG_XSTEP_DUP_PIN //get old pin state back. @@ -1408,14 +1452,14 @@ void babystep(const uint8_t axis,const bool direction) WRITE(Y_DIR_PIN,(INVERT_Y_DIR)^direction); //perform step - WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN); + STEP_NC_HI(Y_AXIS); #ifdef DEBUG_YSTEP_DUP_PIN - WRITE(DEBUG_YSTEP_DUP_PIN,!INVERT_Y_STEP_PIN); + STEP_NC_HI(Y_DUP_AXIS); #endif //DEBUG_YSTEP_DUP_PIN delayMicroseconds(1); - WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN); + STEP_NC_LO(Y_AXIS); #ifdef DEBUG_YSTEP_DUP_PIN - WRITE(DEBUG_YSTEP_DUP_PIN,INVERT_Y_STEP_PIN); + STEP_NC_LO(Y_DUP_AXIS); #endif //DEBUG_YSTEP_DUP_PIN //get old pin state back. @@ -1434,14 +1478,14 @@ void babystep(const uint8_t axis,const bool direction) WRITE(Z2_DIR_PIN,(INVERT_Z_DIR)^direction^BABYSTEP_INVERT_Z); #endif //perform step - WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN); + STEP_NC_HI(Z_AXIS); #ifdef Z_DUAL_STEPPER_DRIVERS - WRITE(Z2_STEP_PIN, !INVERT_Z_STEP_PIN); + STEP_NC_HI(Z2_AXIS); #endif delayMicroseconds(1); - WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN); + STEP_NC_LO(Z_AXIS); #ifdef Z_DUAL_STEPPER_DRIVERS - WRITE(Z2_STEP_PIN, INVERT_Z_STEP_PIN); + STEP_NC_LO(Z2_AXIS); #endif //get old pin state back. diff --git a/Firmware/tmc2130.cpp b/Firmware/tmc2130.cpp index b87272e2..20c23704 100755 --- a/Firmware/tmc2130.cpp +++ b/Firmware/tmc2130.cpp @@ -428,6 +428,11 @@ void tmc2130_check_overtemp() void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r) { uint8_t intpol = (mres != 0); // intpol to 256 only if microsteps aren't 256 +#ifdef TMC2130_DEDGE_STEPPING + uint8_t dedge = 1; +#else + uint8_t dedge = 0; +#endif uint8_t toff = tmc2130_chopper_config[axis].toff; // toff = 3 (fchop = 27.778kHz) uint8_t hstrt = tmc2130_chopper_config[axis].hstr; //initial 4, modified to 5 uint8_t hend = tmc2130_chopper_config[axis].hend; //original value = 1 @@ -464,12 +469,12 @@ void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_ // DBG(_n(" toff=%hhd, hstr=%hhd, hend=%hhd, tbl=%hhd\n"), toff, hstrt, hend, tbl); if (current_r <= 31) { - tmc2130_wr_CHOPCONF(axis, toff, hstrt, hend, fd3, 0, rndtf, chm, tbl, 1, 0, 0, 0, mres, intpol, 0, 0); + tmc2130_wr_CHOPCONF(axis, toff, hstrt, hend, fd3, 0, rndtf, chm, tbl, 1, 0, 0, 0, mres, intpol, dedge, 0); tmc2130_wr(axis, TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((current_r & 0x1f) << 8) | (current_h & 0x1f)); } else { - tmc2130_wr_CHOPCONF(axis, toff, hstrt, hend, fd3, 0, rndtf, chm, tbl, 0, 0, 0, 0, mres, intpol, 0, 0); + tmc2130_wr_CHOPCONF(axis, toff, hstrt, hend, fd3, 0, rndtf, chm, tbl, 0, 0, 0, 0, mres, intpol, dedge, 0); tmc2130_wr(axis, TMC2130_REG_IHOLD_IRUN, 0x000f0000 | (((current_r >> 1) & 0x1f) << 8) | ((current_h >> 1) & 0x1f)); } } @@ -706,10 +711,17 @@ static uint8_t tmc2130_rx(uint8_t axis, uint8_t addr, uint32_t* rval) #define _SET_DIR_Z(dir) { WRITE(Z_DIR_PIN, dir?INVERT_Z_DIR:!INVERT_Z_DIR); asm("nop"); } #define _SET_DIR_E(dir) { WRITE(E0_DIR_PIN, dir?INVERT_E0_DIR:!INVERT_E0_DIR); asm("nop"); } +#ifdef TMC2130_DEDGE_STEPPING +#define _DO_STEP_X { TOGGLE(X_STEP_PIN); asm("nop"); } +#define _DO_STEP_Y { TOGGLE(Y_STEP_PIN); asm("nop"); } +#define _DO_STEP_Z { TOGGLE(Z_STEP_PIN); asm("nop"); } +#define _DO_STEP_E { TOGGLE(E0_STEP_PIN); asm("nop"); } +#else #define _DO_STEP_X { WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); asm("nop"); WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); asm("nop"); } #define _DO_STEP_Y { WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN); asm("nop"); WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN); asm("nop"); } #define _DO_STEP_Z { WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN); asm("nop"); WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN); asm("nop"); } #define _DO_STEP_E { WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); asm("nop"); WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN); asm("nop"); } +#endif uint16_t tmc2130_get_res(uint8_t axis) From 1181beffb1c47828a1d40303348b53f2c06345e7 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Mon, 17 Jun 2019 21:10:18 +0200 Subject: [PATCH 04/58] Enable DEDGE stepping on supported variants --- Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 1 + Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 1 + 2 files changed, 2 insertions(+) diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index b135d8d1..e1eb2ef1 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -269,6 +269,7 @@ // #define TMC2130_UNLOAD_CURRENT_R 12 // lower current for M600 to protect filament sensor - Unused #define TMC2130_STEALTH_Z +#define TMC2130_DEDGE_STEPPING //#define TMC2130_SERVICE_CODES_M910_M918 diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index e618c54e..d4c52281 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -271,6 +271,7 @@ // #define TMC2130_UNLOAD_CURRENT_R 12 // lower current for M600 to protect filament sensor - Unused #define TMC2130_STEALTH_Z +#define TMC2130_DEDGE_STEPPING //#define TMC2130_SERVICE_CODES_M910_M918 From e6b182aa9fc3a8f812a8580a0c25152418f3c2bc Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Tue, 18 Jun 2019 17:11:01 +0200 Subject: [PATCH 05/58] Implement proper step/delay pauses in tmc2130 functions Add constants for the various required delays in tmc2130.h, which will come in handy for stepper.cpp as well. Move the delays in the _set functions and remove the pauses from the various calling points and macros. Note that the hard-coded pause wouldn't cut it for the stepper ISR, but it's fine for other use cases. --- Firmware/tmc2130.cpp | 39 ++++++++++++++++++++------------------- Firmware/tmc2130.h | 4 ++++ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/Firmware/tmc2130.cpp b/Firmware/tmc2130.cpp index 20c23704..15646b92 100755 --- a/Firmware/tmc2130.cpp +++ b/Firmware/tmc2130.cpp @@ -696,31 +696,31 @@ static uint8_t tmc2130_rx(uint8_t axis, uint8_t addr, uint32_t* rval) #define _GET_PWR_Z (READ(Z_ENABLE_PIN) == Z_ENABLE_ON) #define _GET_PWR_E (READ(E0_ENABLE_PIN) == E_ENABLE_ON) -#define _SET_PWR_X(ena) { WRITE(X_ENABLE_PIN, ena?X_ENABLE_ON:!X_ENABLE_ON); asm("nop"); } -#define _SET_PWR_Y(ena) { WRITE(Y_ENABLE_PIN, ena?Y_ENABLE_ON:!Y_ENABLE_ON); asm("nop"); } -#define _SET_PWR_Z(ena) { WRITE(Z_ENABLE_PIN, ena?Z_ENABLE_ON:!Z_ENABLE_ON); asm("nop"); } -#define _SET_PWR_E(ena) { WRITE(E0_ENABLE_PIN, ena?E_ENABLE_ON:!E_ENABLE_ON); asm("nop"); } +#define _SET_PWR_X(ena) WRITE(X_ENABLE_PIN, ena?X_ENABLE_ON:!X_ENABLE_ON) +#define _SET_PWR_Y(ena) WRITE(Y_ENABLE_PIN, ena?Y_ENABLE_ON:!Y_ENABLE_ON) +#define _SET_PWR_Z(ena) WRITE(Z_ENABLE_PIN, ena?Z_ENABLE_ON:!Z_ENABLE_ON) +#define _SET_PWR_E(ena) WRITE(E0_ENABLE_PIN, ena?E_ENABLE_ON:!E_ENABLE_ON) #define _GET_DIR_X (READ(X_DIR_PIN) == INVERT_X_DIR) #define _GET_DIR_Y (READ(Y_DIR_PIN) == INVERT_Y_DIR) #define _GET_DIR_Z (READ(Z_DIR_PIN) == INVERT_Z_DIR) #define _GET_DIR_E (READ(E0_DIR_PIN) == INVERT_E0_DIR) -#define _SET_DIR_X(dir) { WRITE(X_DIR_PIN, dir?INVERT_X_DIR:!INVERT_X_DIR); asm("nop"); } -#define _SET_DIR_Y(dir) { WRITE(Y_DIR_PIN, dir?INVERT_Y_DIR:!INVERT_Y_DIR); asm("nop"); } -#define _SET_DIR_Z(dir) { WRITE(Z_DIR_PIN, dir?INVERT_Z_DIR:!INVERT_Z_DIR); asm("nop"); } -#define _SET_DIR_E(dir) { WRITE(E0_DIR_PIN, dir?INVERT_E0_DIR:!INVERT_E0_DIR); asm("nop"); } +#define _SET_DIR_X(dir) WRITE(X_DIR_PIN, dir?INVERT_X_DIR:!INVERT_X_DIR) +#define _SET_DIR_Y(dir) WRITE(Y_DIR_PIN, dir?INVERT_Y_DIR:!INVERT_Y_DIR) +#define _SET_DIR_Z(dir) WRITE(Z_DIR_PIN, dir?INVERT_Z_DIR:!INVERT_Z_DIR) +#define _SET_DIR_E(dir) WRITE(E0_DIR_PIN, dir?INVERT_E0_DIR:!INVERT_E0_DIR) #ifdef TMC2130_DEDGE_STEPPING -#define _DO_STEP_X { TOGGLE(X_STEP_PIN); asm("nop"); } -#define _DO_STEP_Y { TOGGLE(Y_STEP_PIN); asm("nop"); } -#define _DO_STEP_Z { TOGGLE(Z_STEP_PIN); asm("nop"); } -#define _DO_STEP_E { TOGGLE(E0_STEP_PIN); asm("nop"); } +#define _DO_STEP_X TOGGLE(X_STEP_PIN) +#define _DO_STEP_Y TOGGLE(Y_STEP_PIN) +#define _DO_STEP_Z TOGGLE(Z_STEP_PIN) +#define _DO_STEP_E TOGGLE(E0_STEP_PIN) #else -#define _DO_STEP_X { WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); asm("nop"); WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); asm("nop"); } -#define _DO_STEP_Y { WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN); asm("nop"); WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN); asm("nop"); } -#define _DO_STEP_Z { WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN); asm("nop"); WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN); asm("nop"); } -#define _DO_STEP_E { WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); asm("nop"); WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN); asm("nop"); } +#define _DO_STEP_X { WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); delayMicroseconds(TMC2130_MINIMUM_PULSE); WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); } +#define _DO_STEP_Y { WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN); delayMicroseconds(TMC2130_MINIMUM_PULSE); WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN); } +#define _DO_STEP_Z { WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN); delayMicroseconds(TMC2130_MINIMUM_PULSE); WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN); } +#define _DO_STEP_E { WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); delayMicroseconds(TMC2130_MINIMUM_PULSE); WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN); } #endif @@ -762,6 +762,7 @@ void tmc2130_set_pwr(uint8_t axis, uint8_t pwr) case Z_AXIS: _SET_PWR_Z(pwr); break; case E_AXIS: _SET_PWR_E(pwr); break; } + delayMicroseconds(TMC2130_SET_PWR_DELAY); } uint8_t tmc2130_get_inv(uint8_t axis) @@ -798,6 +799,7 @@ void tmc2130_set_dir(uint8_t axis, uint8_t dir) case Z_AXIS: _SET_DIR_Z(dir); break; case E_AXIS: _SET_DIR_E(dir); break; } + delayMicroseconds(TMC2130_SET_DIR_DELAY); } void tmc2130_do_step(uint8_t axis) @@ -813,8 +815,8 @@ void tmc2130_do_step(uint8_t axis) void tmc2130_do_steps(uint8_t axis, uint16_t steps, uint8_t dir, uint16_t delay_us) { - tmc2130_set_dir(axis, dir); - delayMicroseconds(100); + if (tmc2130_get_dir(axis) != dir) + tmc2130_set_dir(axis, dir); while (steps--) { tmc2130_do_step(axis); @@ -845,7 +847,6 @@ void tmc2130_goto_step(uint8_t axis, uint8_t step, uint8_t dir, uint16_t delay_u cnt = steps; } tmc2130_set_dir(axis, dir); - delayMicroseconds(100); mscnt = tmc2130_rd_MSCNT(axis); while ((cnt--) && ((mscnt >> shift) != step)) { diff --git a/Firmware/tmc2130.h b/Firmware/tmc2130.h index ed4c0d7c..4b5b764c 100644 --- a/Firmware/tmc2130.h +++ b/Firmware/tmc2130.h @@ -29,6 +29,10 @@ extern uint8_t tmc2130_sg_homing_axes_mask; #define TMC2130_WAVE_FAC1000_MAX 200 #define TMC2130_WAVE_FAC1000_STP 1 +#define TMC2130_MINIMUM_PULSE 0 // minimum pulse width in uS +#define TMC2130_SET_DIR_DELAY 20 // minimum delay after setting direction in uS +#define TMC2130_SET_PWR_DELAY 0 // minimum delay after changing pwr mode in uS + extern uint8_t tmc2130_home_enabled; extern uint8_t tmc2130_home_origin[2]; extern uint8_t tmc2130_home_bsteps[2]; From 6ea198a866efcc6ecc55d2c7c29a4535ee9bee14 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Sun, 14 Jul 2019 17:39:06 +0200 Subject: [PATCH 06/58] Fix DEDGE in sm4.c (fixes xyz calibration) --- Firmware/sm4.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Firmware/sm4.c b/Firmware/sm4.c index 34cf8a3c..b68e0276 100644 --- a/Firmware/sm4.c +++ b/Firmware/sm4.c @@ -129,11 +129,15 @@ void sm4_set_dir_bits(uint8_t dir_bits) void sm4_do_step(uint8_t axes_mask) { #if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3) || (MOTHERBOARD == BOARD_EINSY_1_0a)) +#ifdef TMC2130_DEDGE_STEPPING + PORTC ^= (axes_mask & 0x0f); //set step signals by mask +#else register uint8_t portC = PORTC & 0xf0; PORTC = portC | (axes_mask & 0x0f); //set step signals by mask asm("nop"); PORTC = portC; //set step signals to zero asm("nop"); +#endif #endif //((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3) || (MOTHERBOARD == BOARD_EINSY_1_0a)) } From 78bbfc62379719a127cd5edcc48b3eb21aa2594f Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Sun, 14 Jul 2019 18:53:37 +0200 Subject: [PATCH 07/58] Fix delay calculations inside babystep() - Avoid all delays when using DEDGE stepping - Correctly account for direction change delays --- Firmware/stepper.cpp | 179 +++++++++++++++++++++++++------------------ 1 file changed, 105 insertions(+), 74 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index 8f2a4f12..b3cc5a57 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -72,6 +72,14 @@ uint16_t SP_min = 0x21FF; #define _STEP_PIN_Z2_AXIS Z2_STEP_PIN #endif +#ifdef TMC2130 +#define STEPPER_MINIMUM_PULSE TMC2130_MINIMUM_PULSE +#define STEPPER_SET_DIR_DELAY TMC2130_SET_DIR_DELAY +#else +#define STEPPER_MINIMUM_PULSE 2 +#define STEPPER_SET_DIR_DELAY 100 +#endif + #ifdef TMC2130_DEDGE_STEPPING #define STEP_NC_HI(axis) TOGGLE(_STEP_PIN_##axis) #define STEP_NC_LO(axis) //NOP @@ -1416,89 +1424,112 @@ void quickStop() #ifdef BABYSTEPPING void babystep(const uint8_t axis,const bool direction) { - //MUST ONLY BE CALLED BY A ISR, it depends on that no other ISR interrupts this - //store initial pin states - switch(axis) - { - case X_AXIS: - { - enable_x(); - uint8_t old_x_dir_pin= READ(X_DIR_PIN); //if dualzstepper, both point to same direction. - - //setup new step - WRITE(X_DIR_PIN,(INVERT_X_DIR)^direction); - - //perform step - STEP_NC_HI(X_AXIS); + // MUST ONLY BE CALLED BY A ISR as stepper pins are manipulated directly. + // note: when switching direction no delay is inserted at the end when the + // original is restored. We assume enough time passes as the function + // returns and the stepper is manipulated again (to avoid dead times) + switch(axis) + { + case X_AXIS: + { + enable_x(); + uint8_t old_x_dir_pin = READ(X_DIR_PIN); //if dualzstepper, both point to same direction. + uint8_t new_x_dir_pin = (INVERT_X_DIR)^direction; + + //setup new step + if (new_x_dir_pin != old_x_dir_pin) { + WRITE_NC(X_DIR_PIN, new_x_dir_pin); + delayMicroseconds(STEPPER_SET_DIR_DELAY); + } + + //perform step + STEP_NC_HI(X_AXIS); #ifdef DEBUG_XSTEP_DUP_PIN - STEP_NC_HI(X_DUP_AXIS); -#endif //DEBUG_XSTEP_DUP_PIN - delayMicroseconds(1); - STEP_NC_LO(X_AXIS); + STEP_NC_HI(X_DUP_AXIS); +#endif +#ifndef TMC2130_DEDGE_STEPPING + delayMicroseconds(STEPPER_MINIMUM_PULSE); + STEP_NC_LO(X_AXIS); #ifdef DEBUG_XSTEP_DUP_PIN - STEP_NC_LO(X_DUP_AXIS); -#endif //DEBUG_XSTEP_DUP_PIN + STEP_NC_LO(X_DUP_AXIS); +#endif +#endif - //get old pin state back. - WRITE(X_DIR_PIN,old_x_dir_pin); - } - break; - case Y_AXIS: - { - enable_y(); - uint8_t old_y_dir_pin= READ(Y_DIR_PIN); //if dualzstepper, both point to same direction. - - //setup new step - WRITE(Y_DIR_PIN,(INVERT_Y_DIR)^direction); - - //perform step - STEP_NC_HI(Y_AXIS); + //get old pin state back. + WRITE_NC(X_DIR_PIN, old_x_dir_pin); + } + break; + + case Y_AXIS: + { + enable_y(); + uint8_t old_y_dir_pin = READ(Y_DIR_PIN); //if dualzstepper, both point to same direction. + uint8_t new_y_dir_pin = (INVERT_Y_DIR)^direction; + + //setup new step + if (new_y_dir_pin != old_y_dir_pin) { + WRITE_NC(Y_DIR_PIN, new_y_dir_pin); + delayMicroseconds(STEPPER_SET_DIR_DELAY); + } + + //perform step + STEP_NC_HI(Y_AXIS); #ifdef DEBUG_YSTEP_DUP_PIN - STEP_NC_HI(Y_DUP_AXIS); -#endif //DEBUG_YSTEP_DUP_PIN - delayMicroseconds(1); - STEP_NC_LO(Y_AXIS); + STEP_NC_HI(Y_DUP_AXIS); +#endif +#ifndef TMC2130_DEDGE_STEPPING + delayMicroseconds(STEPPER_MINIMUM_PULSE); + STEP_NC_LO(Y_AXIS); #ifdef DEBUG_YSTEP_DUP_PIN - STEP_NC_LO(Y_DUP_AXIS); -#endif //DEBUG_YSTEP_DUP_PIN + STEP_NC_LO(Y_DUP_AXIS); +#endif +#endif - //get old pin state back. - WRITE(Y_DIR_PIN,old_y_dir_pin); + //get old pin state back. + WRITE_NC(Y_DIR_PIN, old_y_dir_pin); + } + break; - } - break; - - case Z_AXIS: - { - enable_z(); - uint8_t old_z_dir_pin= READ(Z_DIR_PIN); //if dualzstepper, both point to same direction. - //setup new step - WRITE(Z_DIR_PIN,(INVERT_Z_DIR)^direction^BABYSTEP_INVERT_Z); - #ifdef Z_DUAL_STEPPER_DRIVERS - WRITE(Z2_DIR_PIN,(INVERT_Z_DIR)^direction^BABYSTEP_INVERT_Z); - #endif - //perform step - STEP_NC_HI(Z_AXIS); - #ifdef Z_DUAL_STEPPER_DRIVERS - STEP_NC_HI(Z2_AXIS); - #endif - delayMicroseconds(1); - STEP_NC_LO(Z_AXIS); - #ifdef Z_DUAL_STEPPER_DRIVERS - STEP_NC_LO(Z2_AXIS); - #endif + case Z_AXIS: + { + enable_z(); + uint8_t old_z_dir_pin = READ(Z_DIR_PIN); //if dualzstepper, both point to same direction. + uint8_t new_z_dir_pin = (INVERT_Z_DIR)^direction^BABYSTEP_INVERT_Z; - //get old pin state back. - WRITE(Z_DIR_PIN,old_z_dir_pin); - #ifdef Z_DUAL_STEPPER_DRIVERS - WRITE(Z2_DIR_PIN,old_z_dir_pin); - #endif + //setup new step + if (new_z_dir_pin != old_z_dir_pin) { + WRITE_NC(Z_DIR_PIN, new_z_dir_pin); +#ifdef Z_DUAL_STEPPER_DRIVERS + WRITE_NC(Z2_DIR_PIN, new_z_dir_pin); +#endif + delayMicroseconds(STEPPER_SET_DIR_DELAY); + } - } - break; - - default: break; - } + //perform step + STEP_NC_HI(Z_AXIS); +#ifdef Z_DUAL_STEPPER_DRIVERS + STEP_NC_HI(Z2_AXIS); +#endif +#ifndef TMC2130_DEDGE_STEPPING + delayMicroseconds(STEPPER_MINIMUM_PULSE); + STEP_NC_LO(Z_AXIS); +#ifdef Z_DUAL_STEPPER_DRIVERS + STEP_NC_LO(Z2_AXIS); +#endif +#endif + + //get old pin state back. + if (new_z_dir_pin != old_z_dir_pin) { + WRITE_NC(Z_DIR_PIN, old_z_dir_pin); +#ifdef Z_DUAL_STEPPER_DRIVERS + WRITE_NC(Z2_DIR_PIN, old_z_dir_pin); +#endif + } + } + break; + + default: break; + } } #endif //BABYSTEPPING From 502bc8c72ddcb92828a4016546439674b2a74d5d Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Thu, 20 Aug 2020 12:33:52 +0200 Subject: [PATCH 08/58] Isolate more pat9125 code Remove probing from Marlin_main and move it into pat9125_probe so that it can support the various variants. --- Firmware/Marlin_main.cpp | 15 ++++----------- Firmware/config.h | 4 +++- Firmware/pat9125.c | 39 +++++++++++++++++++++++++++++---------- Firmware/pat9125.h | 1 + 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 2a261db2..e3be3dfb 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -88,18 +88,13 @@ #include "la10compat.h" #endif -#ifdef SWSPI -#include "swspi.h" -#endif //SWSPI - #include "spi.h" -#ifdef SWI2C -#include "swi2c.h" -#endif //SWI2C - #ifdef FILAMENT_SENSOR #include "fsensor.h" +#ifdef IR_SENSOR +#include "pat9125.h" // for pat9125_probe +#endif #endif //FILAMENT_SENSOR #ifdef TMC2130 @@ -864,9 +859,7 @@ static void check_if_fw_is_on_right_printer(){ #ifdef FILAMENT_SENSOR if((PRINTER_TYPE == PRINTER_MK3) || (PRINTER_TYPE == PRINTER_MK3S)){ #ifdef IR_SENSOR - swi2c_init(); - const uint8_t pat9125_detected = swi2c_readByte_A8(PAT9125_I2C_ADDR,0x00,NULL); - if (pat9125_detected){ + if (pat9125_probe()){ lcd_show_fullscreen_message_and_wait_P(_i("MK3S firmware detected on MK3 printer"));}////c=20 r=3 #endif //IR_SENSOR diff --git a/Firmware/config.h b/Firmware/config.h index 1a0a9700..b7705584 100644 --- a/Firmware/config.h +++ b/Firmware/config.h @@ -23,7 +23,6 @@ #define ADC_CALLBACK adc_ready //callback function () //SWI2C configuration -#define SWI2C //#define SWI2C_SDA 20 //SDA on P3 //#define SWI2C_SCL 21 //SCL on P3 #define SWI2C_A8 @@ -31,7 +30,10 @@ #define SWI2C_TMO 2048 //2048 cycles timeout //PAT9125 configuration +//#define PAT9125_SWSPI #define PAT9125_SWI2C +//#define PAT9125_I2C + #define PAT9125_I2C_ADDR 0x75 //ID=LO //#define PAT9125_I2C_ADDR 0x79 //ID=HI //#define PAT9125_I2C_ADDR 0x73 //ID=NC diff --git a/Firmware/pat9125.c b/Firmware/pat9125.c index de4693d2..10b06b3e 100644 --- a/Firmware/pat9125.c +++ b/Firmware/pat9125.c @@ -26,12 +26,15 @@ #define PAT9125_BANK_SELECTION 0x7f -#ifdef PAT9125_SWSPI +#if defined(PAT9125_SWSPI) #include "swspi.h" -#endif //PAT9125_SWSPI -#ifdef PAT9125_SWI2C +#elif defined(PAT9125_SWI2C) #include "swi2c.h" -#endif //PAT9125_SWI2C +#elif defined(PAT9125_I2C) +#error not implemented +#else +#error unknown PAT9125 communication method +#endif uint8_t pat9125_PID1 = 0; @@ -103,14 +106,30 @@ extern FILE _uartout; #define uartout (&_uartout) +uint8_t pat9125_probe() +{ +#if defined(PAT9125_SWSPI) + swspi_init(); + //#error not implemented +#elif defined(PAT9125_SWI2C) + swi2c_init(); + return swi2c_readByte_A8(PAT9125_I2C_ADDR,0x00,NULL); +#elif defined(PAT9125_I2C) + twi_init(); + #ifdef IR_SENSOR + // NOTE: this is called from the MK3S variant, so it should be kept minimal + #error not implemented + #else + return pat9125_rd_reg(PAT9125_PID1) != 0; + #endif +#endif +} + uint8_t pat9125_init(void) { -#ifdef PAT9125_SWSPI - swspi_init(); -#endif //PAT9125_SWSPI -#ifdef PAT9125_SWI2C - swi2c_init(); -#endif //PAT9125_SWI2C + if (!pat9125_probe()) + return 0; + // Verify that the sensor responds with its correct product ID. pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1); pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2); diff --git a/Firmware/pat9125.h b/Firmware/pat9125.h index 12f7fe94..1fb2539f 100755 --- a/Firmware/pat9125.h +++ b/Firmware/pat9125.h @@ -18,6 +18,7 @@ extern int16_t pat9125_y; extern uint8_t pat9125_b; extern uint8_t pat9125_s; +extern uint8_t pat9125_probe(void); // Return non-zero if PAT9125 can be trivially detected extern uint8_t pat9125_init(void); extern uint8_t pat9125_update(void); // update all sensor data extern uint8_t pat9125_update_y(void); // update _y only From 240dc1132ee90fe3680e787dcde665306cc3bcf2 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Thu, 20 Aug 2020 12:36:01 +0200 Subject: [PATCH 09/58] Include initial implementation based on Arduino's twi --- Firmware/config.h | 4 +- Firmware/pat9125.c | 47 ++-- Firmware/twi.c | 561 +++++++++++++++++++++++++++++++++++++++++++++ Firmware/twi.h | 55 +++++ 4 files changed, 646 insertions(+), 21 deletions(-) create mode 100644 Firmware/twi.c create mode 100644 Firmware/twi.h diff --git a/Firmware/config.h b/Firmware/config.h index b7705584..b107d0ec 100644 --- a/Firmware/config.h +++ b/Firmware/config.h @@ -31,8 +31,8 @@ //PAT9125 configuration //#define PAT9125_SWSPI -#define PAT9125_SWI2C -//#define PAT9125_I2C +//#define PAT9125_SWI2C +#define PAT9125_I2C #define PAT9125_I2C_ADDR 0x75 //ID=LO //#define PAT9125_I2C_ADDR 0x79 //ID=HI diff --git a/Firmware/pat9125.c b/Firmware/pat9125.c index 10b06b3e..bf2c0d95 100644 --- a/Firmware/pat9125.c +++ b/Firmware/pat9125.c @@ -31,7 +31,7 @@ #elif defined(PAT9125_SWI2C) #include "swi2c.h" #elif defined(PAT9125_I2C) -#error not implemented +#include "twi.h" #else #error unknown PAT9125 communication method #endif @@ -253,39 +253,48 @@ uint8_t pat9125_update_bs(void) uint8_t pat9125_rd_reg(uint8_t addr) { uint8_t data = 0; -#ifdef PAT9125_SWSPI +#if defined(PAT9125_SWSPI) swspi_start(); swspi_tx(addr & 0x7f); data = swspi_rx(); swspi_stop(); -#endif //PAT9125_SWSPI -#ifdef PAT9125_SWI2C +#elif defined(PAT9125_SWI2C) if (!swi2c_readByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error - { - pat9125_PID1 = 0xff; - pat9125_PID2 = 0xff; - return 0; - } -#endif //PAT9125_SWI2C + goto error; +#elif defined(PAT9125_I2C) + if (twi_writeTo(PAT9125_I2C_ADDR,&addr,1,1,0) != 0 || + twi_readFrom(PAT9125_I2C_ADDR,&data,1,1) != 1) + goto error; +#endif return data; + + error: + pat9125_PID1 = 0xff; + pat9125_PID2 = 0xff; + return 0; } void pat9125_wr_reg(uint8_t addr, uint8_t data) { -#ifdef PAT9125_SWSPI +#if defined(PAT9125_SWSPI) swspi_start(); swspi_tx(addr | 0x80); swspi_tx(data); swspi_stop(); -#endif //PAT9125_SWSPI -#ifdef PAT9125_SWI2C +#elif defined(PAT9125_SWI2C) if (!swi2c_writeByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error - { - pat9125_PID1 = 0xff; - pat9125_PID2 = 0xff; - return; - } -#endif //PAT9125_SWI2C + goto error; +#elif defined(PAT9125_I2C) + if (twi_writeTo(PAT9125_I2C_ADDR,&addr,1,1,0) != 0 || + twi_writeTo(PAT9125_I2C_ADDR,&data,1,1,1) != 0) + goto error; +#endif + return; + + error: + pat9125_PID1 = 0xff; + pat9125_PID2 = 0xff; + return; } uint8_t pat9125_wr_reg_verify(uint8_t addr, uint8_t data) diff --git a/Firmware/twi.c b/Firmware/twi.c new file mode 100644 index 00000000..171af730 --- /dev/null +++ b/Firmware/twi.c @@ -0,0 +1,561 @@ +/* + twi.c - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts +*/ + +#include <math.h> +#include <stdlib.h> +#include <inttypes.h> +#include <avr/io.h> +#include <avr/interrupt.h> +#include <compat/twi.h> +#include "Arduino.h" // for digitalWrite + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif + +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +#include "pins_arduino.h" +#include "twi.h" + +static volatile uint8_t twi_state; +static volatile uint8_t twi_slarw; +static volatile uint8_t twi_sendStop; // should the transaction end with a stop +static volatile uint8_t twi_inRepStart; // in the middle of a repeated start + +static void (*twi_onSlaveTransmit)(void); +static void (*twi_onSlaveReceive)(uint8_t*, int); + +static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_masterBufferIndex; +static volatile uint8_t twi_masterBufferLength; + +static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_txBufferIndex; +static volatile uint8_t twi_txBufferLength; + +static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_rxBufferIndex; + +static volatile uint8_t twi_error; + +/* + * Function twi_init + * Desc readys twi pins and sets twi bitrate + * Input none + * Output none + */ +void twi_init(void) +{ + // initialize state + twi_state = TWI_READY; + twi_sendStop = true; // default value + twi_inRepStart = false; + + // activate internal pullups for twi. + digitalWrite(SDA, 1); + digitalWrite(SCL, 1); + + // initialize twi prescaler and bit rate + cbi(TWSR, TWPS0); + cbi(TWSR, TWPS1); + TWBR = ((F_CPU / TWI_FREQ) - 16) / 2; + + /* twi bit rate formula from atmega128 manual pg 204 + SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) + note: TWBR should be 10 or higher for master mode + It is 72 for a 16mhz Wiring board with 100kHz TWI */ + + // enable twi module, acks, and twi interrupt + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); +} + +/* + * Function twi_disable + * Desc disables twi pins + * Input none + * Output none + */ +void twi_disable(void) +{ + // disable twi module, acks, and twi interrupt + TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA)); + + // deactivate internal pullups for twi. + digitalWrite(SDA, 0); + digitalWrite(SCL, 0); +} + +/* + * Function twi_slaveInit + * Desc sets slave address and enables interrupt + * Input none + * Output none + */ +void twi_setAddress(uint8_t address) +{ + // set twi slave address (skip over TWGCE bit) + TWAR = address << 1; +} + +/* + * Function twi_setClock + * Desc sets twi bit rate + * Input Clock Frequency + * Output none + */ +void twi_setFrequency(uint32_t frequency) +{ + TWBR = ((F_CPU / frequency) - 16) / 2; + + /* twi bit rate formula from atmega128 manual pg 204 + SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) + note: TWBR should be 10 or higher for master mode + It is 72 for a 16mhz Wiring board with 100kHz TWI */ +} + +/* + * Function twi_readFrom + * Desc attempts to become twi bus master and read a + * series of bytes from a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes to read into array + * sendStop: Boolean indicating whether to send a stop at the end + * Output number of bytes read + */ +uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 0; + } + + // wait until twi is ready, become master receiver + while(TWI_READY != twi_state){ + continue; + } + twi_state = TWI_MRX; + twi_sendStop = sendStop; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; + + // initialize buffer iteration vars + twi_masterBufferIndex = 0; + twi_masterBufferLength = length-1; // This is not intuitive, read on... + // On receive, the previously configured ACK/NACK setting is transmitted in + // response to the received byte before the interrupt is signalled. + // Therefor we must actually set NACK when the _next_ to last byte is + // received, causing that NACK to be sent in response to receiving the last + // expected byte of data. + + // build sla+w, slave device address + w bit + twi_slarw = TW_READ; + twi_slarw |= address << 1; + + if (true == twi_inRepStart) { + // if we're in the repeated start state, then we've already sent the start, + // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. + // We need to remove ourselves from the repeated start state before we enable interrupts, + // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning + // up. Also, don't enable the START interrupt. There may be one pending from the + // repeated start that we sent ourselves, and that would really confuse things. + twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR + do { + TWDR = twi_slarw; + } while(TWCR & _BV(TWWC)); + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START + } + else + // send start condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); + + // wait for read operation to complete + while(TWI_MRX == twi_state){ + continue; + } + + if (twi_masterBufferIndex < length) + length = twi_masterBufferIndex; + + // copy twi buffer to data + for(i = 0; i < length; ++i){ + data[i] = twi_masterBuffer[i]; + } + + return length; +} + +/* + * Function twi_writeTo + * Desc attempts to become twi bus master and write a + * series of bytes to a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes in array + * wait: boolean indicating to wait for write or not + * sendStop: boolean indicating whether or not to send a stop at the end + * Output 0 .. success + * 1 .. length to long for buffer + * 2 .. address send, NACK received + * 3 .. data send, NACK received + * 4 .. other twi error (lost bus arbitration, bus error, ..) + */ +uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 1; + } + + // wait until twi is ready, become master transmitter + while(TWI_READY != twi_state){ + continue; + } + twi_state = TWI_MTX; + twi_sendStop = sendStop; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; + + // initialize buffer iteration vars + twi_masterBufferIndex = 0; + twi_masterBufferLength = length; + + // copy data to twi buffer + for(i = 0; i < length; ++i){ + twi_masterBuffer[i] = data[i]; + } + + // build sla+w, slave device address + w bit + twi_slarw = TW_WRITE; + twi_slarw |= address << 1; + + // if we're in a repeated start, then we've already sent the START + // in the ISR. Don't do it again. + // + if (true == twi_inRepStart) { + // if we're in the repeated start state, then we've already sent the start, + // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. + // We need to remove ourselves from the repeated start state before we enable interrupts, + // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning + // up. Also, don't enable the START interrupt. There may be one pending from the + // repeated start that we sent outselves, and that would really confuse things. + twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR + do { + TWDR = twi_slarw; + } while(TWCR & _BV(TWWC)); + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START + } + else + // send start condition + TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs + + // wait for write operation to complete + while(wait && (TWI_MTX == twi_state)){ + continue; + } + + if (twi_error == 0xFF) + return 0; // success + else if (twi_error == TW_MT_SLA_NACK) + return 2; // error: address send, nack received + else if (twi_error == TW_MT_DATA_NACK) + return 3; // error: data send, nack received + else + return 4; // other twi error +} + +/* + * Function twi_transmit + * Desc fills slave tx buffer with data + * must be called in slave tx event callback + * Input data: pointer to byte array + * length: number of bytes in array + * Output 1 length too long for buffer + * 2 not slave transmitter + * 0 ok + */ +uint8_t twi_transmit(const uint8_t* data, uint8_t length) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < (twi_txBufferLength+length)){ + return 1; + } + + // ensure we are currently a slave transmitter + if(TWI_STX != twi_state){ + return 2; + } + + // set length and copy data into tx buffer + for(i = 0; i < length; ++i){ + twi_txBuffer[twi_txBufferLength+i] = data[i]; + } + twi_txBufferLength += length; + + return 0; +} + +/* + * Function twi_attachSlaveRxEvent + * Desc sets function called before a slave read operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) +{ + twi_onSlaveReceive = function; +} + +/* + * Function twi_attachSlaveTxEvent + * Desc sets function called before a slave write operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveTxEvent( void (*function)(void) ) +{ + twi_onSlaveTransmit = function; +} + +/* + * Function twi_reply + * Desc sends byte or readys receive line + * Input ack: byte indicating to ack or to nack + * Output none + */ +void twi_reply(uint8_t ack) +{ + // transmit master read ready signal, with or without ack + if(ack){ + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); + }else{ + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); + } +} + +/* + * Function twi_stop + * Desc relinquishes bus master status + * Input none + * Output none + */ +void twi_stop(void) +{ + // send stop condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); + + // wait for stop condition to be exectued on bus + // TWINT is not set after a stop condition! + while(TWCR & _BV(TWSTO)){ + continue; + } + + // update twi state + twi_state = TWI_READY; +} + +/* + * Function twi_releaseBus + * Desc releases bus control + * Input none + * Output none + */ +void twi_releaseBus(void) +{ + // release bus + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); + + // update twi state + twi_state = TWI_READY; +} + +ISR(TWI_vect) +{ + switch(TW_STATUS){ + // All Master + case TW_START: // sent start condition + case TW_REP_START: // sent repeated start condition + // copy device address and r/w bit to output register and ack + TWDR = twi_slarw; + twi_reply(1); + break; + + // Master Transmitter + case TW_MT_SLA_ACK: // slave receiver acked address + case TW_MT_DATA_ACK: // slave receiver acked data + // if there is data to send, send it, otherwise stop + if(twi_masterBufferIndex < twi_masterBufferLength){ + // copy data to output register and ack + TWDR = twi_masterBuffer[twi_masterBufferIndex++]; + twi_reply(1); + }else{ + if (twi_sendStop) + twi_stop(); + else { + twi_inRepStart = true; // we're gonna send the START + // don't enable the interrupt. We'll generate the start, but we + // avoid handling the interrupt until we're in the next transaction, + // at the point where we would normally issue the start. + TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; + twi_state = TWI_READY; + } + } + break; + case TW_MT_SLA_NACK: // address sent, nack received + twi_error = TW_MT_SLA_NACK; + twi_stop(); + break; + case TW_MT_DATA_NACK: // data sent, nack received + twi_error = TW_MT_DATA_NACK; + twi_stop(); + break; + case TW_MT_ARB_LOST: // lost bus arbitration + twi_error = TW_MT_ARB_LOST; + twi_releaseBus(); + break; + + // Master Receiver + case TW_MR_DATA_ACK: // data received, ack sent + // put byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + case TW_MR_SLA_ACK: // address sent, ack received + // ack if more bytes are expected, otherwise nack + if(twi_masterBufferIndex < twi_masterBufferLength){ + twi_reply(1); + }else{ + twi_reply(0); + } + break; + case TW_MR_DATA_NACK: // data received, nack sent + // put final byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + if (twi_sendStop) + twi_stop(); + else { + twi_inRepStart = true; // we're gonna send the START + // don't enable the interrupt. We'll generate the start, but we + // avoid handling the interrupt until we're in the next transaction, + // at the point where we would normally issue the start. + TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; + twi_state = TWI_READY; + } + break; + case TW_MR_SLA_NACK: // address sent, nack received + twi_stop(); + break; + // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case + + // Slave Receiver + case TW_SR_SLA_ACK: // addressed, returned ack + case TW_SR_GCALL_ACK: // addressed generally, returned ack + case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack + case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack + // enter slave receiver mode + twi_state = TWI_SRX; + // indicate that rx buffer can be overwritten and ack + twi_rxBufferIndex = 0; + twi_reply(1); + break; + case TW_SR_DATA_ACK: // data received, returned ack + case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack + // if there is still room in the rx buffer + if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ + // put byte in buffer and ack + twi_rxBuffer[twi_rxBufferIndex++] = TWDR; + twi_reply(1); + }else{ + // otherwise nack + twi_reply(0); + } + break; + case TW_SR_STOP: // stop or repeated start condition received + // ack future responses and leave slave receiver state + twi_releaseBus(); + // put a null char after data if there's room + if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ + twi_rxBuffer[twi_rxBufferIndex] = '\0'; + } + // callback to user defined callback + twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); + // since we submit rx buffer to "wire" library, we can reset it + twi_rxBufferIndex = 0; + break; + case TW_SR_DATA_NACK: // data received, returned nack + case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack + // nack back at master + twi_reply(0); + break; + + // Slave Transmitter + case TW_ST_SLA_ACK: // addressed, returned ack + case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack + // enter slave transmitter mode + twi_state = TWI_STX; + // ready the tx buffer index for iteration + twi_txBufferIndex = 0; + // set tx buffer length to be zero, to verify if user changes it + twi_txBufferLength = 0; + // request for txBuffer to be filled and length to be set + // note: user must call twi_transmit(bytes, length) to do this + twi_onSlaveTransmit(); + // if they didn't change buffer & length, initialize it + if(0 == twi_txBufferLength){ + twi_txBufferLength = 1; + twi_txBuffer[0] = 0x00; + } + // transmit first byte from buffer, fall + case TW_ST_DATA_ACK: // byte sent, ack returned + // copy data to output register + TWDR = twi_txBuffer[twi_txBufferIndex++]; + // if there is more to send, ack, otherwise nack + if(twi_txBufferIndex < twi_txBufferLength){ + twi_reply(1); + }else{ + twi_reply(0); + } + break; + case TW_ST_DATA_NACK: // received nack, we are done + case TW_ST_LAST_DATA: // received ack, but we are done already! + // ack future responses + twi_reply(1); + // leave slave receiver state + twi_state = TWI_READY; + break; + + // All + case TW_NO_INFO: // no state information + break; + case TW_BUS_ERROR: // bus error, illegal stop/start + twi_error = TW_BUS_ERROR; + twi_stop(); + break; + } +} + diff --git a/Firmware/twi.h b/Firmware/twi.h new file mode 100644 index 00000000..cb48708c --- /dev/null +++ b/Firmware/twi.h @@ -0,0 +1,55 @@ +/* + twi.h - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef twi_h +#define twi_h + + #include <inttypes.h> + + //#define ATMEGA8 + + #ifndef TWI_FREQ + #define TWI_FREQ 400000L + #endif + + #ifndef TWI_BUFFER_LENGTH + #define TWI_BUFFER_LENGTH 32 + #endif + + #define TWI_READY 0 + #define TWI_MRX 1 + #define TWI_MTX 2 + #define TWI_SRX 3 + #define TWI_STX 4 + + void twi_init(void); + void twi_disable(void); + void twi_setAddress(uint8_t); + void twi_setFrequency(uint32_t); + uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t); + uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); + uint8_t twi_transmit(const uint8_t*, uint8_t); + void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); + void twi_attachSlaveTxEvent( void (*)(void) ); + void twi_reply(uint8_t); + void twi_stop(void); + void twi_releaseBus(void); + +#endif + From 7f425120f09dc33b7bd1b75af4d42cdad5ad1441 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Thu, 20 Aug 2020 15:29:57 +0200 Subject: [PATCH 10/58] Strip down the TWI code - Only implement a single syncronous read/write function to read a byte, since that's all we need currently - Implement a compact IR_SENSOR probe for PAT9125 - Saves 242 bytes compared to PAT9125_SWI2C --- Firmware/pat9125.c | 13 +- Firmware/twi.c | 518 +++------------------------------------------ Firmware/twi.h | 64 +++--- 3 files changed, 63 insertions(+), 532 deletions(-) diff --git a/Firmware/pat9125.c b/Firmware/pat9125.c index bf2c0d95..ab6342aa 100644 --- a/Firmware/pat9125.c +++ b/Firmware/pat9125.c @@ -118,9 +118,10 @@ uint8_t pat9125_probe() twi_init(); #ifdef IR_SENSOR // NOTE: this is called from the MK3S variant, so it should be kept minimal - #error not implemented + uint8_t addr = PAT9125_PID1; + return (twi_rw8(PAT9125_I2C_ADDR,TW_READ,&addr) == 0); #else - return pat9125_rd_reg(PAT9125_PID1) != 0; + return (pat9125_rd_reg(PAT9125_PID1) != 0); #endif #endif } @@ -262,8 +263,8 @@ uint8_t pat9125_rd_reg(uint8_t addr) if (!swi2c_readByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error goto error; #elif defined(PAT9125_I2C) - if (twi_writeTo(PAT9125_I2C_ADDR,&addr,1,1,0) != 0 || - twi_readFrom(PAT9125_I2C_ADDR,&data,1,1) != 1) + if (twi_rw8(PAT9125_I2C_ADDR,TW_WRITE,&addr) || + twi_rw8(PAT9125_I2C_ADDR,TW_READ,&data)) goto error; #endif return data; @@ -285,8 +286,8 @@ void pat9125_wr_reg(uint8_t addr, uint8_t data) if (!swi2c_writeByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error goto error; #elif defined(PAT9125_I2C) - if (twi_writeTo(PAT9125_I2C_ADDR,&addr,1,1,0) != 0 || - twi_writeTo(PAT9125_I2C_ADDR,&data,1,1,1) != 0) + if (twi_rw8(PAT9125_I2C_ADDR,TW_WRITE,&addr) || + twi_rw8(PAT9125_I2C_ADDR,TW_READ,&data)) goto error; #endif return; diff --git a/Firmware/twi.c b/Firmware/twi.c index 171af730..161db52a 100644 --- a/Firmware/twi.c +++ b/Firmware/twi.c @@ -1,5 +1,5 @@ /* - twi.c - TWI/I2C library for Wiring & Arduino + twi.c - Stripped-down TWI/I2C library Copyright (c) 2006 Nicholas Zambetti. All right reserved. This library is free software; you can redistribute it and/or @@ -20,11 +20,6 @@ */ #include <math.h> -#include <stdlib.h> -#include <inttypes.h> -#include <avr/io.h> -#include <avr/interrupt.h> -#include <compat/twi.h> #include "Arduino.h" // for digitalWrite #ifndef cbi @@ -35,43 +30,11 @@ #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif -#include "pins_arduino.h" #include "twi.h" -static volatile uint8_t twi_state; -static volatile uint8_t twi_slarw; -static volatile uint8_t twi_sendStop; // should the transaction end with a stop -static volatile uint8_t twi_inRepStart; // in the middle of a repeated start -static void (*twi_onSlaveTransmit)(void); -static void (*twi_onSlaveReceive)(uint8_t*, int); - -static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_masterBufferIndex; -static volatile uint8_t twi_masterBufferLength; - -static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_txBufferIndex; -static volatile uint8_t twi_txBufferLength; - -static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_rxBufferIndex; - -static volatile uint8_t twi_error; - -/* - * Function twi_init - * Desc readys twi pins and sets twi bitrate - * Input none - * Output none - */ void twi_init(void) { - // initialize state - twi_state = TWI_READY; - twi_sendStop = true; // default value - twi_inRepStart = false; - // activate internal pullups for twi. digitalWrite(SDA, 1); digitalWrite(SCL, 1); @@ -85,477 +48,46 @@ void twi_init(void) SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) note: TWBR should be 10 or higher for master mode It is 72 for a 16mhz Wiring board with 100kHz TWI */ - - // enable twi module, acks, and twi interrupt - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); } -/* - * Function twi_disable - * Desc disables twi pins - * Input none - * Output none - */ void twi_disable(void) { - // disable twi module, acks, and twi interrupt - TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA)); - // deactivate internal pullups for twi. digitalWrite(SDA, 0); digitalWrite(SCL, 0); } -/* - * Function twi_slaveInit - * Desc sets slave address and enables interrupt - * Input none - * Output none - */ -void twi_setAddress(uint8_t address) +uint8_t twi_waitfor(uint8_t status) { - // set twi slave address (skip over TWGCE bit) - TWAR = address << 1; + while(!(TWCR & _BV(TWINT))); + return (TW_STATUS != status); } -/* - * Function twi_setClock - * Desc sets twi bit rate - * Input Clock Frequency - * Output none - */ -void twi_setFrequency(uint32_t frequency) +uint8_t twi_rw8(uint8_t address, uint8_t mode, uint8_t* data) { - TWBR = ((F_CPU / frequency) - 16) / 2; - - /* twi bit rate formula from atmega128 manual pg 204 - SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) - note: TWBR should be 10 or higher for master mode - It is 72 for a 16mhz Wiring board with 100kHz TWI */ -} + // send start condition + TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA); + if(twi_waitfor(TW_START)) + return 1; -/* - * Function twi_readFrom - * Desc attempts to become twi bus master and read a - * series of bytes from a device on the bus - * Input address: 7bit i2c device address - * data: pointer to byte array - * length: number of bytes to read into array - * sendStop: Boolean indicating whether to send a stop at the end - * Output number of bytes read - */ -uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) -{ - uint8_t i; + // send address + TWDR = mode; + TWDR |= (address << 1); + TWCR = _BV(TWEN) | _BV(TWINT); + if(twi_waitfor(mode == TW_READ? TW_MR_SLA_ACK: TW_MT_SLA_ACK)) + return 2; - // ensure data will fit into buffer - if(TWI_BUFFER_LENGTH < length){ - return 0; - } + // send or receive data + if(mode == TW_WRITE) + TWDR = *data; + TWCR = _BV(TWEN) | _BV(TWINT); + if(twi_waitfor(mode == TW_READ? TW_MR_DATA_NACK: TW_MT_DATA_ACK)) + return 3; + if(mode == TW_READ) + *data = TWDR; - // wait until twi is ready, become master receiver - while(TWI_READY != twi_state){ - continue; - } - twi_state = TWI_MRX; - twi_sendStop = sendStop; - // reset error state (0xFF.. no error occured) - twi_error = 0xFF; + // send stop + TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTO); - // initialize buffer iteration vars - twi_masterBufferIndex = 0; - twi_masterBufferLength = length-1; // This is not intuitive, read on... - // On receive, the previously configured ACK/NACK setting is transmitted in - // response to the received byte before the interrupt is signalled. - // Therefor we must actually set NACK when the _next_ to last byte is - // received, causing that NACK to be sent in response to receiving the last - // expected byte of data. - - // build sla+w, slave device address + w bit - twi_slarw = TW_READ; - twi_slarw |= address << 1; - - if (true == twi_inRepStart) { - // if we're in the repeated start state, then we've already sent the start, - // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. - // We need to remove ourselves from the repeated start state before we enable interrupts, - // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning - // up. Also, don't enable the START interrupt. There may be one pending from the - // repeated start that we sent ourselves, and that would really confuse things. - twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR - do { - TWDR = twi_slarw; - } while(TWCR & _BV(TWWC)); - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START - } - else - // send start condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); - - // wait for read operation to complete - while(TWI_MRX == twi_state){ - continue; - } - - if (twi_masterBufferIndex < length) - length = twi_masterBufferIndex; - - // copy twi buffer to data - for(i = 0; i < length; ++i){ - data[i] = twi_masterBuffer[i]; - } - - return length; -} - -/* - * Function twi_writeTo - * Desc attempts to become twi bus master and write a - * series of bytes to a device on the bus - * Input address: 7bit i2c device address - * data: pointer to byte array - * length: number of bytes in array - * wait: boolean indicating to wait for write or not - * sendStop: boolean indicating whether or not to send a stop at the end - * Output 0 .. success - * 1 .. length to long for buffer - * 2 .. address send, NACK received - * 3 .. data send, NACK received - * 4 .. other twi error (lost bus arbitration, bus error, ..) - */ -uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) -{ - uint8_t i; - - // ensure data will fit into buffer - if(TWI_BUFFER_LENGTH < length){ - return 1; - } - - // wait until twi is ready, become master transmitter - while(TWI_READY != twi_state){ - continue; - } - twi_state = TWI_MTX; - twi_sendStop = sendStop; - // reset error state (0xFF.. no error occured) - twi_error = 0xFF; - - // initialize buffer iteration vars - twi_masterBufferIndex = 0; - twi_masterBufferLength = length; - - // copy data to twi buffer - for(i = 0; i < length; ++i){ - twi_masterBuffer[i] = data[i]; - } - - // build sla+w, slave device address + w bit - twi_slarw = TW_WRITE; - twi_slarw |= address << 1; - - // if we're in a repeated start, then we've already sent the START - // in the ISR. Don't do it again. - // - if (true == twi_inRepStart) { - // if we're in the repeated start state, then we've already sent the start, - // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. - // We need to remove ourselves from the repeated start state before we enable interrupts, - // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning - // up. Also, don't enable the START interrupt. There may be one pending from the - // repeated start that we sent outselves, and that would really confuse things. - twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR - do { - TWDR = twi_slarw; - } while(TWCR & _BV(TWWC)); - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START - } - else - // send start condition - TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs - - // wait for write operation to complete - while(wait && (TWI_MTX == twi_state)){ - continue; - } - - if (twi_error == 0xFF) - return 0; // success - else if (twi_error == TW_MT_SLA_NACK) - return 2; // error: address send, nack received - else if (twi_error == TW_MT_DATA_NACK) - return 3; // error: data send, nack received - else - return 4; // other twi error -} - -/* - * Function twi_transmit - * Desc fills slave tx buffer with data - * must be called in slave tx event callback - * Input data: pointer to byte array - * length: number of bytes in array - * Output 1 length too long for buffer - * 2 not slave transmitter - * 0 ok - */ -uint8_t twi_transmit(const uint8_t* data, uint8_t length) -{ - uint8_t i; - - // ensure data will fit into buffer - if(TWI_BUFFER_LENGTH < (twi_txBufferLength+length)){ - return 1; - } - - // ensure we are currently a slave transmitter - if(TWI_STX != twi_state){ - return 2; - } - - // set length and copy data into tx buffer - for(i = 0; i < length; ++i){ - twi_txBuffer[twi_txBufferLength+i] = data[i]; - } - twi_txBufferLength += length; - return 0; } - -/* - * Function twi_attachSlaveRxEvent - * Desc sets function called before a slave read operation - * Input function: callback function to use - * Output none - */ -void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) -{ - twi_onSlaveReceive = function; -} - -/* - * Function twi_attachSlaveTxEvent - * Desc sets function called before a slave write operation - * Input function: callback function to use - * Output none - */ -void twi_attachSlaveTxEvent( void (*function)(void) ) -{ - twi_onSlaveTransmit = function; -} - -/* - * Function twi_reply - * Desc sends byte or readys receive line - * Input ack: byte indicating to ack or to nack - * Output none - */ -void twi_reply(uint8_t ack) -{ - // transmit master read ready signal, with or without ack - if(ack){ - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); - }else{ - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); - } -} - -/* - * Function twi_stop - * Desc relinquishes bus master status - * Input none - * Output none - */ -void twi_stop(void) -{ - // send stop condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); - - // wait for stop condition to be exectued on bus - // TWINT is not set after a stop condition! - while(TWCR & _BV(TWSTO)){ - continue; - } - - // update twi state - twi_state = TWI_READY; -} - -/* - * Function twi_releaseBus - * Desc releases bus control - * Input none - * Output none - */ -void twi_releaseBus(void) -{ - // release bus - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); - - // update twi state - twi_state = TWI_READY; -} - -ISR(TWI_vect) -{ - switch(TW_STATUS){ - // All Master - case TW_START: // sent start condition - case TW_REP_START: // sent repeated start condition - // copy device address and r/w bit to output register and ack - TWDR = twi_slarw; - twi_reply(1); - break; - - // Master Transmitter - case TW_MT_SLA_ACK: // slave receiver acked address - case TW_MT_DATA_ACK: // slave receiver acked data - // if there is data to send, send it, otherwise stop - if(twi_masterBufferIndex < twi_masterBufferLength){ - // copy data to output register and ack - TWDR = twi_masterBuffer[twi_masterBufferIndex++]; - twi_reply(1); - }else{ - if (twi_sendStop) - twi_stop(); - else { - twi_inRepStart = true; // we're gonna send the START - // don't enable the interrupt. We'll generate the start, but we - // avoid handling the interrupt until we're in the next transaction, - // at the point where we would normally issue the start. - TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; - twi_state = TWI_READY; - } - } - break; - case TW_MT_SLA_NACK: // address sent, nack received - twi_error = TW_MT_SLA_NACK; - twi_stop(); - break; - case TW_MT_DATA_NACK: // data sent, nack received - twi_error = TW_MT_DATA_NACK; - twi_stop(); - break; - case TW_MT_ARB_LOST: // lost bus arbitration - twi_error = TW_MT_ARB_LOST; - twi_releaseBus(); - break; - - // Master Receiver - case TW_MR_DATA_ACK: // data received, ack sent - // put byte into buffer - twi_masterBuffer[twi_masterBufferIndex++] = TWDR; - case TW_MR_SLA_ACK: // address sent, ack received - // ack if more bytes are expected, otherwise nack - if(twi_masterBufferIndex < twi_masterBufferLength){ - twi_reply(1); - }else{ - twi_reply(0); - } - break; - case TW_MR_DATA_NACK: // data received, nack sent - // put final byte into buffer - twi_masterBuffer[twi_masterBufferIndex++] = TWDR; - if (twi_sendStop) - twi_stop(); - else { - twi_inRepStart = true; // we're gonna send the START - // don't enable the interrupt. We'll generate the start, but we - // avoid handling the interrupt until we're in the next transaction, - // at the point where we would normally issue the start. - TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; - twi_state = TWI_READY; - } - break; - case TW_MR_SLA_NACK: // address sent, nack received - twi_stop(); - break; - // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case - - // Slave Receiver - case TW_SR_SLA_ACK: // addressed, returned ack - case TW_SR_GCALL_ACK: // addressed generally, returned ack - case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack - case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack - // enter slave receiver mode - twi_state = TWI_SRX; - // indicate that rx buffer can be overwritten and ack - twi_rxBufferIndex = 0; - twi_reply(1); - break; - case TW_SR_DATA_ACK: // data received, returned ack - case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack - // if there is still room in the rx buffer - if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ - // put byte in buffer and ack - twi_rxBuffer[twi_rxBufferIndex++] = TWDR; - twi_reply(1); - }else{ - // otherwise nack - twi_reply(0); - } - break; - case TW_SR_STOP: // stop or repeated start condition received - // ack future responses and leave slave receiver state - twi_releaseBus(); - // put a null char after data if there's room - if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ - twi_rxBuffer[twi_rxBufferIndex] = '\0'; - } - // callback to user defined callback - twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); - // since we submit rx buffer to "wire" library, we can reset it - twi_rxBufferIndex = 0; - break; - case TW_SR_DATA_NACK: // data received, returned nack - case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack - // nack back at master - twi_reply(0); - break; - - // Slave Transmitter - case TW_ST_SLA_ACK: // addressed, returned ack - case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack - // enter slave transmitter mode - twi_state = TWI_STX; - // ready the tx buffer index for iteration - twi_txBufferIndex = 0; - // set tx buffer length to be zero, to verify if user changes it - twi_txBufferLength = 0; - // request for txBuffer to be filled and length to be set - // note: user must call twi_transmit(bytes, length) to do this - twi_onSlaveTransmit(); - // if they didn't change buffer & length, initialize it - if(0 == twi_txBufferLength){ - twi_txBufferLength = 1; - twi_txBuffer[0] = 0x00; - } - // transmit first byte from buffer, fall - case TW_ST_DATA_ACK: // byte sent, ack returned - // copy data to output register - TWDR = twi_txBuffer[twi_txBufferIndex++]; - // if there is more to send, ack, otherwise nack - if(twi_txBufferIndex < twi_txBufferLength){ - twi_reply(1); - }else{ - twi_reply(0); - } - break; - case TW_ST_DATA_NACK: // received nack, we are done - case TW_ST_LAST_DATA: // received ack, but we are done already! - // ack future responses - twi_reply(1); - // leave slave receiver state - twi_state = TWI_READY; - break; - - // All - case TW_NO_INFO: // no state information - break; - case TW_BUS_ERROR: // bus error, illegal stop/start - twi_error = TW_BUS_ERROR; - twi_stop(); - break; - } -} - diff --git a/Firmware/twi.h b/Firmware/twi.h index cb48708c..abcb8e97 100644 --- a/Firmware/twi.h +++ b/Firmware/twi.h @@ -1,5 +1,5 @@ /* - twi.h - TWI/I2C library for Wiring & Arduino + twi.h - Stripped-down TWI/I2C library Copyright (c) 2006 Nicholas Zambetti. All right reserved. This library is free software; you can redistribute it and/or @@ -17,39 +17,37 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef twi_h -#define twi_h +#pragma once - #include <inttypes.h> - - //#define ATMEGA8 - - #ifndef TWI_FREQ - #define TWI_FREQ 400000L - #endif - - #ifndef TWI_BUFFER_LENGTH - #define TWI_BUFFER_LENGTH 32 - #endif - - #define TWI_READY 0 - #define TWI_MRX 1 - #define TWI_MTX 2 - #define TWI_SRX 3 - #define TWI_STX 4 - - void twi_init(void); - void twi_disable(void); - void twi_setAddress(uint8_t); - void twi_setFrequency(uint32_t); - uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t); - uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); - uint8_t twi_transmit(const uint8_t*, uint8_t); - void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); - void twi_attachSlaveTxEvent( void (*)(void) ); - void twi_reply(uint8_t); - void twi_stop(void); - void twi_releaseBus(void); +#include <inttypes.h> +#include <compat/twi.h> +#ifndef TWI_FREQ +#define TWI_FREQ 400000L #endif +/* + * Function twi_init + * Desc readys twi pins and sets twi bitrate + * Input none + * Output none + */ +void twi_init(void); + +/* + * Function twi_disable + * Desc disables twi pins + * Input none + * Output none + */ +void twi_disable(void); + +/* + * Function twi_rw8 + * Desc read/write a single byte from a device + * Input address: 7bit i2c device address + * mode: TW_READ or TW_WRITE + * data: pointer to byte + * Output 0 on success + */ +uint8_t twi_rw8(uint8_t address, uint8_t mode, uint8_t* data); From 30e7b777e03054417f23d161b9a30df3b96e89ee Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Thu, 20 Aug 2020 22:13:13 +0200 Subject: [PATCH 11/58] Error-out with PAT9125_SWSPI (not fully implemented) .. and likely will never was/be. --- Firmware/pat9125.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/pat9125.c b/Firmware/pat9125.c index ab6342aa..f47d676b 100644 --- a/Firmware/pat9125.c +++ b/Firmware/pat9125.c @@ -110,7 +110,7 @@ uint8_t pat9125_probe() { #if defined(PAT9125_SWSPI) swspi_init(); - //#error not implemented + #error not implemented #elif defined(PAT9125_SWI2C) swi2c_init(); return swi2c_readByte_A8(PAT9125_I2C_ADDR,0x00,NULL); From d8a88379385504241747aca0877076049992e3dc Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Tue, 25 Aug 2020 11:31:35 +0200 Subject: [PATCH 12/58] Document the 3 possible modes --- Firmware/config.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Firmware/config.h b/Firmware/config.h index b107d0ec..c64bd441 100644 --- a/Firmware/config.h +++ b/Firmware/config.h @@ -30,9 +30,9 @@ #define SWI2C_TMO 2048 //2048 cycles timeout //PAT9125 configuration -//#define PAT9125_SWSPI -//#define PAT9125_SWI2C -#define PAT9125_I2C +//#define PAT9125_SWSPI // software SPI mode (incomplete) +//#define PAT9125_SWI2C // software I2C mode +#define PAT9125_I2C // hardware I2C mode #define PAT9125_I2C_ADDR 0x75 //ID=LO //#define PAT9125_I2C_ADDR 0x79 //ID=HI From e37cdab38fd0a8df2bcad4eca3e410e7b9de148f Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Tue, 25 Aug 2020 11:58:48 +0200 Subject: [PATCH 13/58] PAT9125_I2C: accept either NACK or ACK in receive Both would be technically correct. --- Firmware/twi.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/Firmware/twi.c b/Firmware/twi.c index 161db52a..11c708aa 100644 --- a/Firmware/twi.c +++ b/Firmware/twi.c @@ -57,34 +57,52 @@ void twi_disable(void) digitalWrite(SCL, 0); } -uint8_t twi_waitfor(uint8_t status) +static void twi_wait() { while(!(TWCR & _BV(TWINT))); - return (TW_STATUS != status); } uint8_t twi_rw8(uint8_t address, uint8_t mode, uint8_t* data) { // send start condition TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA); - if(twi_waitfor(TW_START)) + twi_wait(); + if(TW_STATUS != TW_START) return 1; // send address TWDR = mode; TWDR |= (address << 1); TWCR = _BV(TWEN) | _BV(TWINT); - if(twi_waitfor(mode == TW_READ? TW_MR_SLA_ACK: TW_MT_SLA_ACK)) - return 2; + twi_wait(); - // send or receive data if(mode == TW_WRITE) + { + if(TW_STATUS != TW_MT_SLA_ACK) + return 2; + + // send data TWDR = *data; - TWCR = _BV(TWEN) | _BV(TWINT); - if(twi_waitfor(mode == TW_READ? TW_MR_DATA_NACK: TW_MT_DATA_ACK)) - return 3; - if(mode == TW_READ) + TWCR = _BV(TWEN) | _BV(TWINT); + twi_wait(); + if(TW_STATUS != TW_MT_DATA_ACK) + return 3; + } + else + { + if(TW_STATUS != TW_MR_SLA_ACK) + return 2; + + // receive data + TWCR = _BV(TWEN) | _BV(TWINT); + twi_wait(); + + // accept ACK or NACK (since only 1 byte is read) + if(!(TW_STATUS & TW_MR_DATA_ACK)) + return 3; + *data = TWDR; + } // send stop TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTO); From 6d476d71447e707df2ee5b3c367a650235357f9b Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Sun, 27 Sep 2020 14:29:07 +0200 Subject: [PATCH 14/58] Still use SWI2C on RAMBo10a boards The wiring for the PAT9125 on RAMBo10a boards is not directly connected to the SCL pin and requires the sw mode. Detect this requirement by checking the definition for the SWI2C_SCL pin in the board definition. Remove SWI2C_SCL/SDA from the other boards to use the HW mode. --- Firmware/config.h | 5 ++++- Firmware/pins_Einsy_1_0.h | 6 ------ Firmware/pins_Rambo_1_3.h | 3 --- Firmware/swi2c.c | 3 +++ 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/Firmware/config.h b/Firmware/config.h index c64bd441..922a5398 100644 --- a/Firmware/config.h +++ b/Firmware/config.h @@ -31,8 +31,11 @@ //PAT9125 configuration //#define PAT9125_SWSPI // software SPI mode (incomplete) -//#define PAT9125_SWI2C // software I2C mode +#ifdef SWI2C_SCL +#define PAT9125_SWI2C // software I2C mode +#else #define PAT9125_I2C // hardware I2C mode +#endif #define PAT9125_I2C_ADDR 0x75 //ID=LO //#define PAT9125_I2C_ADDR 0x79 //ID=HI diff --git a/Firmware/pins_Einsy_1_0.h b/Firmware/pins_Einsy_1_0.h index 14b56233..21578ebd 100755 --- a/Firmware/pins_Einsy_1_0.h +++ b/Firmware/pins_Einsy_1_0.h @@ -18,12 +18,6 @@ #define W25X20CL // external 256kB flash #define BOOTAPP // bootloader support - -#define SWI2C_SDA 20 //SDA on P3 -#define SWI2C_SCL 21 //SCL on P3 - - - #define X_TMC2130_CS 41 #define X_TMC2130_DIAG 64 // !!! changed from 40 (EINY03) #define X_STEP_PIN 37 diff --git a/Firmware/pins_Rambo_1_3.h b/Firmware/pins_Rambo_1_3.h index 538fb4f3..522ad28f 100644 --- a/Firmware/pins_Rambo_1_3.h +++ b/Firmware/pins_Rambo_1_3.h @@ -11,9 +11,6 @@ #define PINDA_THERMISTOR -#define SWI2C_SDA 20 //SDA on P3 -#define SWI2C_SCL 21 //SCL on P3 - #ifdef MICROMETER_LOGGING #define D_DATACLOCK 24 //Y_MAX (green) #define D_DATA 30 //X_MAX (blue) diff --git a/Firmware/swi2c.c b/Firmware/swi2c.c index 49fbc5ef..62a28e1a 100644 --- a/Firmware/swi2c.c +++ b/Firmware/swi2c.c @@ -7,6 +7,7 @@ #include "pins.h" #include "io_atmega2560.h" +#ifdef SWI2C_SCL #define SWI2C_RMSK 0x01 //read mask (bit0 = 1) #define SWI2C_WMSK 0x00 //write mask (bit0 = 0) @@ -187,3 +188,5 @@ uint8_t swi2c_writeByte_A16(uint8_t dev_addr, unsigned short addr, uint8_t* pbyt } #endif //SWI2C_A16 + +#endif //SWI2C_SCL From 384f40956c4292c33ec087e90f9dfa6da5383800 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Sun, 27 Sep 2020 16:42:20 +0200 Subject: [PATCH 15/58] Remove obsolete cbi/sbi --- Firmware/twi.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/Firmware/twi.c b/Firmware/twi.c index 11c708aa..f8c077ab 100644 --- a/Firmware/twi.c +++ b/Firmware/twi.c @@ -22,14 +22,6 @@ #include <math.h> #include "Arduino.h" // for digitalWrite -#ifndef cbi -#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) -#endif - -#ifndef sbi -#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) -#endif - #include "twi.h" @@ -40,8 +32,7 @@ void twi_init(void) digitalWrite(SCL, 1); // initialize twi prescaler and bit rate - cbi(TWSR, TWPS0); - cbi(TWSR, TWPS1); + TWSR &= ~(_BV(TWPS0) | _BV(TWPS1)); TWBR = ((F_CPU / TWI_FREQ) - 16) / 2; /* twi bit rate formula from atmega128 manual pg 204 From c2e8d229a751df2451fd49915c55b4d3ba3f52c7 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Mon, 28 Sep 2020 20:21:07 +0200 Subject: [PATCH 16/58] Be more compliant in the I2C protocol - Enter a repeated-start for reading data - Write in the same session --- Firmware/pat9125.c | 6 +-- Firmware/twi.c | 110 +++++++++++++++++++++++++++++---------------- Firmware/twi.h | 20 ++++++--- 3 files changed, 89 insertions(+), 47 deletions(-) diff --git a/Firmware/pat9125.c b/Firmware/pat9125.c index f47d676b..c6ffecf3 100644 --- a/Firmware/pat9125.c +++ b/Firmware/pat9125.c @@ -263,8 +263,7 @@ uint8_t pat9125_rd_reg(uint8_t addr) if (!swi2c_readByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error goto error; #elif defined(PAT9125_I2C) - if (twi_rw8(PAT9125_I2C_ADDR,TW_WRITE,&addr) || - twi_rw8(PAT9125_I2C_ADDR,TW_READ,&data)) + if (twi_r8(PAT9125_I2C_ADDR,addr,&data)) goto error; #endif return data; @@ -286,8 +285,7 @@ void pat9125_wr_reg(uint8_t addr, uint8_t data) if (!swi2c_writeByte_A8(PAT9125_I2C_ADDR, addr, &data)) //NO ACK error goto error; #elif defined(PAT9125_I2C) - if (twi_rw8(PAT9125_I2C_ADDR,TW_WRITE,&addr) || - twi_rw8(PAT9125_I2C_ADDR,TW_READ,&data)) + if (twi_w8(PAT9125_I2C_ADDR,addr,data)) goto error; #endif return; diff --git a/Firmware/twi.c b/Firmware/twi.c index f8c077ab..6dd1645c 100644 --- a/Firmware/twi.c +++ b/Firmware/twi.c @@ -48,55 +48,89 @@ void twi_disable(void) digitalWrite(SCL, 0); } -static void twi_wait() + +static void twi_stop() { - while(!(TWCR & _BV(TWINT))); + TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTO); } -uint8_t twi_rw8(uint8_t address, uint8_t mode, uint8_t* data) + +static uint8_t twi_wait(uint8_t status) +{ + while(!(TWCR & _BV(TWINT))); + if(TW_STATUS != status) + { + twi_stop(); + return 1; + } + return 0; +} + + +static uint8_t twi_start(uint8_t address, uint8_t reg) { // send start condition TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA); - twi_wait(); - if(TW_STATUS != TW_START) + if(twi_wait(TW_START)) return 1; // send address - TWDR = mode; - TWDR |= (address << 1); + TWDR = TW_WRITE | (address << 1); TWCR = _BV(TWEN) | _BV(TWINT); - twi_wait(); + if(twi_wait(TW_MT_SLA_ACK)) + return 2; - if(mode == TW_WRITE) - { - if(TW_STATUS != TW_MT_SLA_ACK) - return 2; - - // send data - TWDR = *data; - TWCR = _BV(TWEN) | _BV(TWINT); - twi_wait(); - if(TW_STATUS != TW_MT_DATA_ACK) - return 3; - } - else - { - if(TW_STATUS != TW_MR_SLA_ACK) - return 2; - - // receive data - TWCR = _BV(TWEN) | _BV(TWINT); - twi_wait(); - - // accept ACK or NACK (since only 1 byte is read) - if(!(TW_STATUS & TW_MR_DATA_ACK)) - return 3; - - *data = TWDR; - } - - // send stop - TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTO); + // send register + TWDR = reg; + TWCR = _BV(TWEN) | _BV(TWINT); + if(twi_wait(TW_MT_DATA_ACK)) + return 3; return 0; } + + +uint8_t twi_r8(uint8_t address, uint8_t reg, uint8_t* data) +{ + if(twi_start(address, reg)) + return 1; + + // repeat start + TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA); + if(twi_wait(TW_REP_START)) + return 2; + + // start receiving + TWDR = TW_READ | (address << 1); + TWCR = _BV(TWEN) | _BV(TWINT); + if(twi_wait(TW_MR_SLA_ACK)) + return 3; + + // receive data + TWCR = _BV(TWEN) | _BV(TWINT); + if(twi_wait(TW_MR_DATA_NACK)) + return 4; + + *data = TWDR; + + // send stop + twi_stop(); + return 0; +} + + +uint8_t twi_w8(uint8_t address, uint8_t reg, uint8_t data) +{ + if(twi_start(address, reg)) + return 1; + + // send data + TWDR = data; + TWCR = _BV(TWEN) | _BV(TWINT); + if(twi_wait(TW_MT_DATA_ACK)) + return 2; + + // send stop + twi_stop(); + return 0; +} diff --git a/Firmware/twi.h b/Firmware/twi.h index abcb8e97..bdb617fc 100644 --- a/Firmware/twi.h +++ b/Firmware/twi.h @@ -43,11 +43,21 @@ void twi_init(void); void twi_disable(void); /* - * Function twi_rw8 - * Desc read/write a single byte from a device + * Function twi_r8 + * Desc read a single byte from a device * Input address: 7bit i2c device address - * mode: TW_READ or TW_WRITE - * data: pointer to byte + * reg: register address + * data: pointer to byte for result * Output 0 on success */ -uint8_t twi_rw8(uint8_t address, uint8_t mode, uint8_t* data); +uint8_t twi_r8(uint8_t address, uint8_t reg, uint8_t* data); + +/* + * Function twi_w8 + * Desc write a single byte from a device + * Input address: 7bit i2c device address + * reg: register address + * data: byte to write + * Output 0 on success + */ +uint8_t twi_w8(uint8_t address, uint8_t reg, uint8_t data); From df824414eface1c89175eb23e41ca06210bda334 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Mon, 28 Sep 2020 21:02:06 +0200 Subject: [PATCH 17/58] Fix probing in IR_SENSOR --- Firmware/pat9125.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/pat9125.c b/Firmware/pat9125.c index c6ffecf3..58308a9a 100644 --- a/Firmware/pat9125.c +++ b/Firmware/pat9125.c @@ -118,8 +118,8 @@ uint8_t pat9125_probe() twi_init(); #ifdef IR_SENSOR // NOTE: this is called from the MK3S variant, so it should be kept minimal - uint8_t addr = PAT9125_PID1; - return (twi_rw8(PAT9125_I2C_ADDR,TW_READ,&addr) == 0); + uint8_t data; + return (twi_r8(PAT9125_I2C_ADDR,PAT9125_PID1,&data) == 0); #else return (pat9125_rd_reg(PAT9125_PID1) != 0); #endif From 8a27b6abdb556307070c6f5bf2f76711d0436286 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Thu, 7 Jan 2021 11:45:40 +0100 Subject: [PATCH 18/58] Move Z up before xy home running xyz calibration to prevent scratches on bed and sheet --- Firmware/Marlin_main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index c6f9e4b7..a4123ded 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -2974,6 +2974,8 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level) //set_destination_to_current(); int l_feedmultiply = setup_for_endstop_move(); lcd_display_message_fullscreen_P(_T(MSG_AUTO_HOME)); + raise_z_above(MESH_HOME_Z_SEARCH); + st_synchronize(); home_xy(); enable_endstops(false); From dea3f23a69f700032b97f765a77d03b71a2d1e27 Mon Sep 17 00:00:00 2001 From: Voinea Dragos <voinea.dragos.alexandru@gmail.com> Date: Thu, 14 Jan 2021 11:52:22 +0200 Subject: [PATCH 19/58] PRUSA SN in eeprom --- Firmware/Marlin_main.cpp | 38 ++++++++++++++++++++++++++++++-------- Firmware/eeprom.h | 4 +++- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 3be46591..86b14402 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -407,6 +407,7 @@ static void gcode_M105(uint8_t extruder); static void temp_compensation_start(); static void temp_compensation_apply(); +static bool get_PRUSA_SN(char* SN); uint16_t gcode_in_progress = 0; uint16_t mcode_in_progress = 0; @@ -1075,6 +1076,21 @@ void setup() if(!(eeprom_read_byte((uint8_t*)EEPROM_FAN_CHECK_ENABLED))) eeprom_update_byte((unsigned char *)EEPROM_FAN_CHECK_ENABLED,true); } + + + if (eeprom_read_byte((uint8_t*)EEPROM_PRUSA_SN + 19)) //saved EEPROM SN is not valid. Try to retrieve it. + { + char SN[20]; + if (get_PRUSA_SN(SN)) + { + eeprom_update_block(SN, (uint8_t*)EEPROM_PRUSA_SN, 20); + puts_P(PSTR("SN updated")); + } + else + puts_P(PSTR("SN update failed")); + } + + #ifndef W25X20CL SERIAL_PROTOCOLLNPGM("start"); #else @@ -3386,25 +3402,26 @@ void gcode_M701() * * Typical format of S/N is:CZPX0917X003XC13518 * - * Command operates only in farm mode, if not in farm mode, "Not in farm mode." is written to MYSERIAL. - * * Send command ;S to serial port 0 to retrieve serial number stored in 32U2 processor, - * reply is transmitted to serial port 1 character by character. + * reply is transmitted to the selected serial port. * Operation takes typically 23 ms. If the retransmit is not finished until 100 ms, * it is interrupted, so less, or no characters are retransmitted, only newline character is send * in any case. + * The command will fail if the 32U2 processor is unpowered via USB since it is isolated from the rest of the electronics. + * In that case the value that is stored in the EEPROM should be used instead. + * + * @return 1 on success */ -static void gcode_PRUSA_SN() +static bool get_PRUSA_SN(char* SN) { uint8_t selectedSerialPort_bak = selectedSerialPort; - char SN[20]; selectedSerialPort = 0; SERIAL_ECHOLNRPGM(PSTR(";S")); uint8_t numbersRead = 0; ShortTimer timeout; timeout.start(); - while (numbersRead < (sizeof(SN) - 1)) { + while (numbersRead < 19) { if (MSerial.available() > 0) { SN[numbersRead] = MSerial.read(); numbersRead++; @@ -3413,7 +3430,7 @@ static void gcode_PRUSA_SN() } SN[numbersRead] = 0; selectedSerialPort = selectedSerialPort_bak; - SERIAL_ECHOLN(SN); + return (numbersRead == 19); } //! Detection of faulty RAMBo 1.1b boards equipped with bigger capacitors //! at the TACH_1 pin, which causes bad detection of print fan speed. @@ -3950,7 +3967,12 @@ void process_commands() card.openFile(strchr_pointer+4,false); } else if (code_seen("SN")) { // PRUSA SN - gcode_PRUSA_SN(); + char SN[20]; + eeprom_read_block(SN, (uint8_t*)EEPROM_PRUSA_SN, 20); + if (SN[19]) + puts_P(PSTR("SN invalid")); + else + puts(SN); } else if(code_seen("Fir")){ // PRUSA Fir diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index 731db1da..f54bb8ed 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -316,6 +316,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP | 0x0D29 3369 | uint8 | EEPROM_PINDA_TEMP_COMPENSATION | ffh 255 | ffh 255 | PINDA temp compensation unknown state | LCD menu | D3 Ax0d29 C1 | ^ | ^ | ^ | 00h 0 | ^ | PINDA has no temp compensation PINDA v1/2 | ^ | ^ | ^ | ^ | ^ | 01h 1 | ^ | PINDA has temp compensation aka SuperPINDA | ^ | ^ +| 0x0D15 3349 | char[20] | EEPROM_PRUSA_SN | SN[19] == 0 | ffffffffffffffff... | PRUSA Serial number string | PRUSA SN | D3 Ax0d15 C20 | Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code @@ -521,8 +522,9 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE); #define EEPROM_ALTFAN_OVERRIDE (EEPROM_UVLO_LA_K-1) //uint8 #define EEPROM_EXPERIMENTAL_VISIBILITY (EEPROM_ALTFAN_OVERRIDE-1) //uint8 #define EEPROM_PINDA_TEMP_COMPENSATION (EEPROM_EXPERIMENTAL_VISIBILITY-1) //uint8 +#define EEPROM_PRUSA_SN (EEPROM_PINDA_TEMP_COMPENSATION-20) //char[20] //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items. -#define EEPROM_LAST_ITEM EEPROM_PINDA_TEMP_COMPENSATION +#define EEPROM_LAST_ITEM EEPROM_PRUSA_SN // !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! // !!!!! From 20c3f4cb7709692824d7751e150d9df0606b75b3 Mon Sep 17 00:00:00 2001 From: Alex Voinea <voinea.dragos.alexandru@gmail.com> Date: Thu, 14 Jan 2021 12:53:12 +0200 Subject: [PATCH 20/58] Update comments --- Firmware/Marlin_main.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 86b14402..d43e05e5 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1077,8 +1077,9 @@ void setup() eeprom_update_byte((unsigned char *)EEPROM_FAN_CHECK_ENABLED,true); } - - if (eeprom_read_byte((uint8_t*)EEPROM_PRUSA_SN + 19)) //saved EEPROM SN is not valid. Try to retrieve it. + //saved EEPROM SN is not valid. Try to retrieve it. + //SN is valid only if it is NULL terminated. Any other character means either uninitialized or corrupted + if (eeprom_read_byte((uint8_t*)EEPROM_PRUSA_SN + 19)) { char SN[20]; if (get_PRUSA_SN(SN)) @@ -3403,14 +3404,14 @@ void gcode_M701() * Typical format of S/N is:CZPX0917X003XC13518 * * Send command ;S to serial port 0 to retrieve serial number stored in 32U2 processor, - * reply is transmitted to the selected serial port. + * reply is stored in *SN. * Operation takes typically 23 ms. If the retransmit is not finished until 100 ms, - * it is interrupted, so less, or no characters are retransmitted, only newline character is send - * in any case. + * it is interrupted, so less, or no characters are retransmitted, the function returns false * The command will fail if the 32U2 processor is unpowered via USB since it is isolated from the rest of the electronics. * In that case the value that is stored in the EEPROM should be used instead. * * @return 1 on success + * @return 0 on general failure */ static bool get_PRUSA_SN(char* SN) { From 4fed728e083306aa4cddc950a9a1624bf7c61faf Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Tue, 26 Jan 2021 15:59:21 +0100 Subject: [PATCH 21/58] Elide delayMicroseconds for TMC2130 in non-DEDGE mode Introduce new macros TMC2130_MINIMUM_DELAY/STEPPER_MINIMUM_DELAY for blocking pauses. If MINIMUM_PULSE has defined to be zero, avoid the delay call entirely. --- Firmware/stepper.cpp | 8 +++++--- Firmware/tmc2130.cpp | 8 ++++---- Firmware/tmc2130.h | 6 ++++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index b3cc5a57..e06e0602 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -75,9 +75,11 @@ uint16_t SP_min = 0x21FF; #ifdef TMC2130 #define STEPPER_MINIMUM_PULSE TMC2130_MINIMUM_PULSE #define STEPPER_SET_DIR_DELAY TMC2130_SET_DIR_DELAY +#define STEPPER_MINIMUM_DELAY TMC2130_MINIMUM_DELAY #else #define STEPPER_MINIMUM_PULSE 2 #define STEPPER_SET_DIR_DELAY 100 +#define STEPPER_MINIMUM_DELAY delayMicroseconds(STEPPER_MINIMUM_PULSE) #endif #ifdef TMC2130_DEDGE_STEPPING @@ -1448,7 +1450,7 @@ void babystep(const uint8_t axis,const bool direction) STEP_NC_HI(X_DUP_AXIS); #endif #ifndef TMC2130_DEDGE_STEPPING - delayMicroseconds(STEPPER_MINIMUM_PULSE); + STEPPER_MINIMUM_DELAY; STEP_NC_LO(X_AXIS); #ifdef DEBUG_XSTEP_DUP_PIN STEP_NC_LO(X_DUP_AXIS); @@ -1478,7 +1480,7 @@ void babystep(const uint8_t axis,const bool direction) STEP_NC_HI(Y_DUP_AXIS); #endif #ifndef TMC2130_DEDGE_STEPPING - delayMicroseconds(STEPPER_MINIMUM_PULSE); + STEPPER_MINIMUM_DELAY; STEP_NC_LO(Y_AXIS); #ifdef DEBUG_YSTEP_DUP_PIN STEP_NC_LO(Y_DUP_AXIS); @@ -1511,7 +1513,7 @@ void babystep(const uint8_t axis,const bool direction) STEP_NC_HI(Z2_AXIS); #endif #ifndef TMC2130_DEDGE_STEPPING - delayMicroseconds(STEPPER_MINIMUM_PULSE); + STEPPER_MINIMUM_DELAY; STEP_NC_LO(Z_AXIS); #ifdef Z_DUAL_STEPPER_DRIVERS STEP_NC_LO(Z2_AXIS); diff --git a/Firmware/tmc2130.cpp b/Firmware/tmc2130.cpp index 15646b92..41f7b7c1 100755 --- a/Firmware/tmc2130.cpp +++ b/Firmware/tmc2130.cpp @@ -717,10 +717,10 @@ static uint8_t tmc2130_rx(uint8_t axis, uint8_t addr, uint32_t* rval) #define _DO_STEP_Z TOGGLE(Z_STEP_PIN) #define _DO_STEP_E TOGGLE(E0_STEP_PIN) #else -#define _DO_STEP_X { WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); delayMicroseconds(TMC2130_MINIMUM_PULSE); WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); } -#define _DO_STEP_Y { WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN); delayMicroseconds(TMC2130_MINIMUM_PULSE); WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN); } -#define _DO_STEP_Z { WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN); delayMicroseconds(TMC2130_MINIMUM_PULSE); WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN); } -#define _DO_STEP_E { WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); delayMicroseconds(TMC2130_MINIMUM_PULSE); WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN); } +#define _DO_STEP_X { WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); } +#define _DO_STEP_Y { WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN); } +#define _DO_STEP_Z { WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN); } +#define _DO_STEP_E { WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); TMC2130_MINIMUM_DELAY; WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN); } #endif diff --git a/Firmware/tmc2130.h b/Firmware/tmc2130.h index 4b5b764c..36ba5552 100644 --- a/Firmware/tmc2130.h +++ b/Firmware/tmc2130.h @@ -33,6 +33,12 @@ extern uint8_t tmc2130_sg_homing_axes_mask; #define TMC2130_SET_DIR_DELAY 20 // minimum delay after setting direction in uS #define TMC2130_SET_PWR_DELAY 0 // minimum delay after changing pwr mode in uS +#if TMC2130_MINIMUM_PULSE == 0 +#define TMC2130_MINIMUM_DELAY //NOP +#else +#define TMC2130_MINIMUM_DELAY delayMicroseconds(TMC2130_MINIMUM_PULSE) +#endif + extern uint8_t tmc2130_home_enabled; extern uint8_t tmc2130_home_origin[2]; extern uint8_t tmc2130_home_bsteps[2]; From 2a6989ecd559f70ceb08aa471e0399c52747ddc8 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Tue, 26 Jan 2021 16:09:23 +0100 Subject: [PATCH 22/58] Remove TMC2130 special-cases With the new STEPPER_MINIMUM_DELAY being automatically removed for TMC2130 we no longer need to add specialized #ifdefs for DEDGE in babystep. --- Firmware/stepper.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index e06e0602..e74d7154 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -1449,12 +1449,10 @@ void babystep(const uint8_t axis,const bool direction) #ifdef DEBUG_XSTEP_DUP_PIN STEP_NC_HI(X_DUP_AXIS); #endif -#ifndef TMC2130_DEDGE_STEPPING STEPPER_MINIMUM_DELAY; STEP_NC_LO(X_AXIS); #ifdef DEBUG_XSTEP_DUP_PIN STEP_NC_LO(X_DUP_AXIS); -#endif #endif //get old pin state back. @@ -1479,12 +1477,10 @@ void babystep(const uint8_t axis,const bool direction) #ifdef DEBUG_YSTEP_DUP_PIN STEP_NC_HI(Y_DUP_AXIS); #endif -#ifndef TMC2130_DEDGE_STEPPING STEPPER_MINIMUM_DELAY; STEP_NC_LO(Y_AXIS); #ifdef DEBUG_YSTEP_DUP_PIN STEP_NC_LO(Y_DUP_AXIS); -#endif #endif //get old pin state back. @@ -1512,12 +1508,10 @@ void babystep(const uint8_t axis,const bool direction) #ifdef Z_DUAL_STEPPER_DRIVERS STEP_NC_HI(Z2_AXIS); #endif -#ifndef TMC2130_DEDGE_STEPPING STEPPER_MINIMUM_DELAY; STEP_NC_LO(Z_AXIS); #ifdef Z_DUAL_STEPPER_DRIVERS STEP_NC_LO(Z2_AXIS); -#endif #endif //get old pin state back. From b17cdcd4d7ebd9e53a4180cf9e6768845d1b1eef Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Tue, 26 Jan 2021 16:12:59 +0100 Subject: [PATCH 23/58] Ensure MINIMUM_PULSE is always 0 in DEDGE mode This ensures delays are always properly elided without having to check for DEDGE all over the place. --- Firmware/stepper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index e74d7154..8684713b 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -83,6 +83,7 @@ uint16_t SP_min = 0x21FF; #endif #ifdef TMC2130_DEDGE_STEPPING +static_assert(TMC2130_MINIMUM_PULSE == 0, "DEDGE requires/implies TMC2130_MINIMUM_PULSE == 0"); #define STEP_NC_HI(axis) TOGGLE(_STEP_PIN_##axis) #define STEP_NC_LO(axis) //NOP #else From d3734b02cc1fbb8ba9a446d9ac5ef83b91756178 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Tue, 26 Jan 2021 16:18:23 +0100 Subject: [PATCH 24/58] Also fix delay instances inside unused BACKLASH_[XY] --- Firmware/stepper.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index 8684713b..d47dd2dc 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -352,13 +352,13 @@ FORCE_INLINE void stepper_next_block() WRITE_NC(X_DIR_PIN, INVERT_X_DIR); else WRITE_NC(X_DIR_PIN, !INVERT_X_DIR); - _delay_us(100); + delayMicroseconds(STEPPER_SET_DIR_DELAY); for (uint8_t i = 0; i < st_backlash_x; i++) { STEP_NC_HI(X_AXIS); - _delay_us(100); + STEPPER_MINIMUM_DELAY; STEP_NC_LO(X_AXIS); - _delay_us(900); + _delay_us(900); // hard-coded jerk! *bad* } } last_dir_bits &= ~1; @@ -375,13 +375,13 @@ FORCE_INLINE void stepper_next_block() WRITE_NC(Y_DIR_PIN, INVERT_Y_DIR); else WRITE_NC(Y_DIR_PIN, !INVERT_Y_DIR); - _delay_us(100); + delayMicroseconds(STEPPER_SET_DIR_DELAY); for (uint8_t i = 0; i < st_backlash_y; i++) { STEP_NC_HI(Y_AXIS); - _delay_us(100); + STEPPER_MINIMUM_DELAY; STEP_NC_LO(Y_AXIS); - _delay_us(900); + _delay_us(900); // hard-coded jerk! *bad* } } last_dir_bits &= ~2; From a9625747db85f22cb583d4fdc4c4f0dc2706e687 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Tue, 26 Jan 2021 19:37:14 +0100 Subject: [PATCH 25/58] Reinstate the nop instruction as delay in non-DEDGE When TMC2130_MINIMUM_PULSE is 0 a minimum delay is implied. In this case, use a single "nop" instruction. --- Firmware/stepper.cpp | 3 ++- Firmware/tmc2130.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index d47dd2dc..fc8d9f44 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -83,7 +83,8 @@ uint16_t SP_min = 0x21FF; #endif #ifdef TMC2130_DEDGE_STEPPING -static_assert(TMC2130_MINIMUM_PULSE == 0, "DEDGE requires/implies TMC2130_MINIMUM_PULSE == 0"); +static_assert(TMC2130_MINIMUM_DELAY 1, // this will fail to compile when non-empty + "DEDGE implies/requires an empty TMC2130_MINIMUM_DELAY"); #define STEP_NC_HI(axis) TOGGLE(_STEP_PIN_##axis) #define STEP_NC_LO(axis) //NOP #else diff --git a/Firmware/tmc2130.h b/Firmware/tmc2130.h index 36ba5552..485bf41c 100644 --- a/Firmware/tmc2130.h +++ b/Firmware/tmc2130.h @@ -33,8 +33,10 @@ extern uint8_t tmc2130_sg_homing_axes_mask; #define TMC2130_SET_DIR_DELAY 20 // minimum delay after setting direction in uS #define TMC2130_SET_PWR_DELAY 0 // minimum delay after changing pwr mode in uS -#if TMC2130_MINIMUM_PULSE == 0 +#ifdef TMC2130_DEDGE_STEPPING #define TMC2130_MINIMUM_DELAY //NOP +#elif TMC2130_MINIMUM_PULSE == 0 +#define TMC2130_MINIMUM_DELAY asm("nop") #else #define TMC2130_MINIMUM_DELAY delayMicroseconds(TMC2130_MINIMUM_PULSE) #endif From fba83bd3091414bda8d0e1b220ab4f229610e436 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Wed, 27 Jan 2021 12:43:41 +0100 Subject: [PATCH 26/58] Add new flags -c -p -n --- PF-build.sh | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/PF-build.sh b/PF-build.sh index b7539578..5b0979e2 100755 --- a/PF-build.sh +++ b/PF-build.sh @@ -56,7 +56,7 @@ # Some may argue that this is only used by a script, BUT as soon someone accidentally or on purpose starts Arduino IDE # it will use the default Arduino IDE folders and so can corrupt the build environment. # -# Version: 1.0.6-Build_33 +# Version: 1.0.6-Build_36 # Change log: # 12 Jan 2019, 3d-gussner, Fixed "compiler.c.elf.flags=-w -Os -Wl,-u,vfprintf -lprintf_flt -lm -Wl,--gc-sections" in 'platform.txt' # 16 Jan 2019, 3d-gussner, Build_2, Added development check to modify 'Configuration.h' to prevent unwanted LCD messages that Firmware is unknown @@ -135,6 +135,7 @@ # Update exit numbers 1-13 for prepare build env 21-29 for prepare compiling 30-36 compiling # 08 Jan 2021, 3d-gussner, Comment out 'sudo' auto installation # Add '-?' '-h' help option +# 27 Jan 2021, 3d-gussner, Add `-c`, `-p` and `-n` options #### Start check if OSTYPE is supported OS_FOUND=$( command -v uname) @@ -451,7 +452,7 @@ if type git > /dev/null; then git_available="1" fi -while getopts v:l:d:b:o:?h flag +while getopts v:l:d:b:o:c:p:n:?h flag do case "${flag}" in v) variant_flag=${OPTARG};; @@ -459,6 +460,9 @@ while getopts v:l:d:b:o:?h flag d) devel_flag=${OPTARG};; b) build_flag=${OPTARG};; o) output_flag=${OPTARG};; + c) clean_flag=${OPTARG};; + p) prusa_flag=${OPTARG};; + n) new_build_flag=${OPTARG};; ?) help_flag=1;; h) help_flag=1;; esac @@ -469,6 +473,9 @@ while getopts v:l:d:b:o:?h flag #echo "build_flag: $build_flag"; #echo "output_flag: $output_flag"; #echo "help_flag: $help_flag" +#echo "clean_flag: $clean_flag" +#echo "prusa_flag: $prusa_flag" +#echo "new_build_flag: $new_build_flag" # # '?' 'h' argument usage and help @@ -482,19 +489,23 @@ echo "$(tput setaf 2)-l$(tput sgr0) Languages '$(tput setaf 2)ALL$(tput sgr0)' f echo "$(tput setaf 2)-d$(tput sgr0) Devel build '$(tput setaf 2)GOLD$(tput sgr0)', '$(tput setaf 2)RC$(tput sgr0)', '$(tput setaf 2)BETA$(tput sgr0)', '$(tput setaf 2)ALPHA$(tput sgr0)', '$(tput setaf 2)DEBUG$(tput sgr0)', '$(tput setaf 2)DEVEL$(tput sgr0)' and '$(tput setaf 2)UNKNOWN$(tput sgr0)'" echo "$(tput setaf 2)-b$(tput sgr0) Build/commit number '$(tput setaf 2)Auto$(tput sgr0)' needs git or a number" echo "$(tput setaf 2)-o$(tput sgr0) Output '$(tput setaf 2)1$(tput sgr0)' force or '$(tput setaf 2)0$(tput sgr0)' block output and delays" +echo "$(tput setaf 2)-c$(tput sgr0) Do not clean up lang build'$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' yes" +echo "$(tput setaf 2)-p$(tput sgr0) Keep Configuration_prusa.h '$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' yes" +echo "$(tput setaf 2)-n$(tput sgr0) New fresh build '$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' yes" echo "$(tput setaf 2)-?$(tput sgr0) Help" echo "$(tput setaf 2)-h$(tput sgr0) Help" echo echo "Brief USAGE:" -echo " $(tput setaf 2)./PF-build.sh$(tput sgr0) [-v] [-l] [-d] [-b] [-o]" +echo " $(tput setaf 2)./PF-build.sh$(tput sgr0) [-v] [-l] [-d] [-b] [-o] [-c] [-p] [-n]" echo echo "Example:" echo " $(tput setaf 2)./PF-build.sh -v All -l ALL -d GOLD$(tput sgr0)" echo " Will build all variants as multi language and final GOLD version" echo -echo " $(tput setaf 2) ./PF-build.sh -v 1_75mm_MK3S-EINSy10a-E3Dv6full.h -b Auto -l ALL -d GOLD -o 1$(tput sgr0)" +echo " $(tput setaf 2) ./PF-build.sh -v 1_75mm_MK3S-EINSy10a-E3Dv6full.h -b Auto -l ALL -d GOLD -o 1 -c 1 -p 1 -n 1$(tput sgr0)" echo " Will build MK3S multi language final GOLD firmware " -echo " with current commit count number and output extra information" +echo " with current commit count number and output extra information," +echo " not delete lang build temporary files, keep Configuration_prusa.h and build with new fresh build folder." echo exit @@ -807,6 +818,12 @@ do if [ $OUTPUT == "1" ] ; then sleep 2 fi + + #New fresh PF-Firmware-build + if [ "$new_build_flag" == "1" ]; then + rm -r -f $BUILD_PATH/* || exit 36 + fi + #$BUILD_ENV_PATH/arduino-builder -dump-prefs -debug-level 10 -compile -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=$BOARD_PACKAGE_NAME:avr:$BOARD -build-path=$BUILD_PATH -warnings=all $SCRIPT_PATH/Firmware/Firmware.ino || exit 14 $BUILD_ENV_PATH/arduino-builder -compile -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=$BOARD_PACKAGE_NAME:avr:$BOARD -build-path=$BUILD_PATH -warnings=all $SCRIPT_PATH/Firmware/Firmware.ino || exit 30 echo "$(tput sgr 0)" @@ -874,17 +891,21 @@ do fi fi # Cleanup after build - echo "$(tput setaf 3)" - ./fw-clean.sh || exit 34 - ./lang-clean.sh || exit 35 - echo "$(tput sgr 0)" + if [[ -z "$clean_flag" || "$clean_flag" == "0" ]]; then + echo "$(tput setaf 3)" + ./fw-clean.sh || exit 34 + ./lang-clean.sh || exit 35 + echo "$(tput sgr 0)" + fi else echo "$(tput setaf 2)Copying English only firmware to PF-build-hex folder$(tput sgr 0)" cp -f $BUILD_PATH/Firmware.ino.hex $SCRIPT_PATH/../$OUTPUT_FOLDER/FW$FW-Build$BUILD-$VARIANT-EN_ONLY.hex || exit 34 fi # Cleanup Firmware - rm $SCRIPT_PATH/Firmware/Configuration_prusa.h || exit 36 + if [[ -z "$prusa_flag" || "$prusa_flag" == "0" ]]; then + rm $SCRIPT_PATH/Firmware/Configuration_prusa.h || exit 36 + fi if find $SCRIPT_PATH/lang/ -name '*RAMBo10a*.txt' -printf 1 -quit | grep -q 1 then rm $SCRIPT_PATH/lang/*RAMBo10a*.txt @@ -901,6 +922,12 @@ do then rm $SCRIPT_PATH/lang/not_used.txt fi + + #New fresh PF-Firmware-build + if [ "$new_build_flag" == "1" ]; then + rm -r -f $BUILD_PATH/* || exit 36 + fi + # Restore files to previous state sed -i -- "s/^#define FW_DEV_VERSION FW_VERSION_$DEV_STATUS/#define FW_DEV_VERSION FW_VERSION_UNKNOWN/g" $SCRIPT_PATH/Firmware/Configuration.h sed -i -- 's/^#define FW_REPOSITORY "Prusa3d"/#define FW_REPOSITORY "Unknown"/g' $SCRIPT_PATH/Firmware/Configuration.h From e9d5c447322e899b0e7cfdc71146e4911e7a0b5a Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Fri, 29 Jan 2021 00:13:49 +0100 Subject: [PATCH 27/58] Also toggle pins efficiently in sm4.c Use the same technique used in fastio to toggle pins efficiently in sm4 when DEDGE is used. --- Firmware/sm4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/sm4.c b/Firmware/sm4.c index b68e0276..c2f12824 100644 --- a/Firmware/sm4.c +++ b/Firmware/sm4.c @@ -130,7 +130,7 @@ void sm4_do_step(uint8_t axes_mask) { #if ((MOTHERBOARD == BOARD_RAMBO_MINI_1_0) || (MOTHERBOARD == BOARD_RAMBO_MINI_1_3) || (MOTHERBOARD == BOARD_EINSY_1_0a)) #ifdef TMC2130_DEDGE_STEPPING - PORTC ^= (axes_mask & 0x0f); //set step signals by mask + PINC = (axes_mask & 0x0f); // toggle step signals by mask #else register uint8_t portC = PORTC & 0xf0; PORTC = portC | (axes_mask & 0x0f); //set step signals by mask From 30262b0a6eeecade45186a5d708f0c94d4cff20f Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Fri, 29 Jan 2021 17:30:04 +0100 Subject: [PATCH 28/58] Remove redundant definitions of CRITICAL_SECTION_* Move CRITICAL_SECTION_START/END into fastio.h, where it's needed. --- Firmware/Marlin.h | 5 ----- Firmware/fastio.h | 7 +++++++ Firmware/tone04.c | 9 --------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 697f2f72..f81abd8f 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -287,11 +287,6 @@ FORCE_INLINE unsigned long millis_nc() { void setPwmFrequency(uint8_t pin, int val); #endif -#ifndef CRITICAL_SECTION_START - #define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli(); - #define CRITICAL_SECTION_END SREG = _sreg; -#endif //CRITICAL_SECTION_START - extern bool fans_check_enabled; extern float homing_feedrate[]; extern uint8_t axis_relative_modes; diff --git a/Firmware/fastio.h b/Firmware/fastio.h index e4f25ed8..c4fee101 100644 --- a/Firmware/fastio.h +++ b/Firmware/fastio.h @@ -17,6 +17,13 @@ #define MASK(PIN) (1 << PIN) #endif +#ifndef CRITICAL_SECTION_START + #define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli(); + #define CRITICAL_SECTION_END SREG = _sreg; + #include <avr/interrupt.h> +#endif //CRITICAL_SECTION_START + + /* magic I/O routines now you can simply SET_OUTPUT(STEP); WRITE(STEP, 1); WRITE(STEP, 0); diff --git a/Firmware/tone04.c b/Firmware/tone04.c index 41f904a9..5c36a537 100644 --- a/Firmware/tone04.c +++ b/Firmware/tone04.c @@ -7,16 +7,7 @@ #ifdef SYSTEM_TIMER_2 -#include <avr/io.h> -#include <avr/interrupt.h> #include "pins.h" - -#ifndef CRITICAL_SECTION_START - #define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli(); - #define CRITICAL_SECTION_END SREG = _sreg; -#endif //CRITICAL_SECTION_START - - #include "fastio.h" void timer4_init(void) From 1fa7b8cd8d0f04b0332dd242283c57caf600d103 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Fri, 29 Jan 2021 17:48:59 +0100 Subject: [PATCH 29/58] Move SDA/SCL pins into pins.h for fastio compatibility fastio relies on macros for pin definitions, so we cannot use the const declaration in Sd2PinMap or the arduino's definition. Declare SDA/SCL_PIN into pins.h based on the current MCU, which is identical in all our variants. Remove the conflicting/unused declaration in Sd2PinMap. --- Firmware/Sd2PinMap.h | 6 +----- Firmware/pins.h | 5 +++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Firmware/Sd2PinMap.h b/Firmware/Sd2PinMap.h index 8a608731..da50958f 100644 --- a/Firmware/Sd2PinMap.h +++ b/Firmware/Sd2PinMap.h @@ -37,10 +37,6 @@ struct pin_map_t { || defined(__AVR_ATmega2560__) // Mega -// Two Wire (aka I2C) ports -uint8_t const SDA_PIN = 20; // D1 -uint8_t const SCL_PIN = 21; // D0 - #undef MOSI_PIN #undef MISO_PIN // SPI port @@ -365,4 +361,4 @@ static inline __attribute__((always_inline)) #endif // Sd2PinMap_h -#endif \ No newline at end of file +#endif diff --git a/Firmware/pins.h b/Firmware/pins.h index 5d3b4f83..1c20a001 100644 --- a/Firmware/pins.h +++ b/Firmware/pins.h @@ -25,6 +25,11 @@ #error Unknown MOTHERBOARD value in configuration.h #endif +#if !defined(SDA_PIN) && (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)) +#define SDA_PIN 20 +#define SCL_PIN 21 +#endif + //List of pins which to ignore when asked to change by gcode, 0 and 1 are RX and TX, do not mess with those! #define _E0_PINS E0_STEP_PIN, E0_DIR_PIN, E0_ENABLE_PIN, HEATER_0_PIN, #if EXTRUDERS > 1 From 2d71a071f0d4f63c4dbc2bfa56294c497c5988da Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Fri, 29 Jan 2021 17:51:38 +0100 Subject: [PATCH 30/58] Switch twi.c to fastio --- Firmware/twi.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Firmware/twi.c b/Firmware/twi.c index 6dd1645c..e8c9a378 100644 --- a/Firmware/twi.c +++ b/Firmware/twi.c @@ -19,17 +19,18 @@ Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts */ -#include <math.h> -#include "Arduino.h" // for digitalWrite +#include <math.h> +#include "config.h" +#include "fastio.h" #include "twi.h" void twi_init(void) { // activate internal pullups for twi. - digitalWrite(SDA, 1); - digitalWrite(SCL, 1); + WRITE(SDA_PIN, 1); + WRITE(SCL_PIN, 1); // initialize twi prescaler and bit rate TWSR &= ~(_BV(TWPS0) | _BV(TWPS1)); @@ -44,8 +45,8 @@ void twi_init(void) void twi_disable(void) { // deactivate internal pullups for twi. - digitalWrite(SDA, 0); - digitalWrite(SCL, 0); + WRITE(SDA_PIN, 0); + WRITE(SCL_PIN, 0); } From b8b75186fe96a695521402edc1dd015dfc684ffa Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Fri, 29 Jan 2021 18:30:16 +0100 Subject: [PATCH 31/58] Remove the extra copy of CRITICAL_SECTION from fastio --- Firmware/fastio.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Firmware/fastio.h b/Firmware/fastio.h index 94a029a6..855c000e 100644 --- a/Firmware/fastio.h +++ b/Firmware/fastio.h @@ -9,12 +9,6 @@ #include <avr/io.h> #include "macros.h" -#ifndef CRITICAL_SECTION_START - #define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli(); - #define CRITICAL_SECTION_END SREG = _sreg; - #include <avr/interrupt.h> -#endif //CRITICAL_SECTION_START - /* magic I/O routines From 6b6205d2f6a0ddf5045886ba89aa53ce55ab635f Mon Sep 17 00:00:00 2001 From: Voinea Dragos <voinea.dragos.alexandru@gmail.com> Date: Sun, 31 Jan 2021 15:06:20 +0200 Subject: [PATCH 32/58] M27 refactoring and M27 L initial implementation --- Firmware/Marlin_main.cpp | 2 +- Firmware/cardreader.cpp | 55 ++++++++++++++++++++++------------------ Firmware/cardreader.h | 2 +- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 4739dc4a..a1671848 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -5818,7 +5818,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) ### M27 - Get SD status <a href="https://reprap.org/wiki/G-code#M27:_Report_SD_print_status">M27: Report SD print status</a> */ case 27: - card.getStatus(); + card.getStatus(code_seen('L')); break; /*! diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index e228c523..2140a09a 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -502,31 +502,38 @@ uint32_t CardReader::getFileSize() return filesize; } -void CardReader::getStatus() +void CardReader::getStatus(bool arg_L) { - if(sdprinting) - { - if (isPrintPaused) { - SERIAL_PROTOCOLLNPGM("SD print paused"); - } - else if (saved_printing) { - SERIAL_PROTOCOLLNPGM("Print saved"); - } - else { - SERIAL_PROTOCOLLN(LONGEST_FILENAME); - SERIAL_PROTOCOLRPGM(_N("SD printing byte "));////MSG_SD_PRINTING_BYTE - SERIAL_PROTOCOL(sdpos); - SERIAL_PROTOCOL('/'); - SERIAL_PROTOCOLLN(filesize); - uint16_t time = ( _millis() - starttime ) / 60000U; - SERIAL_PROTOCOL(itostr2(time/60)); - SERIAL_PROTOCOL(':'); - SERIAL_PROTOCOLLN(itostr2(time%60)); - } - } - else { - SERIAL_PROTOCOLLNPGM("Not SD printing"); - } + if (isPrintPaused) + { + if (saved_printing && (saved_printing_type == PRINTING_TYPE_SD)) + SERIAL_PROTOCOLLNPGM("SD print paused"); + else + SERIAL_PROTOCOLLNPGM("Print saved"); + } + else if (sdprinting) + { + if (arg_L) + { + SERIAL_PROTOCOL('/'); + for (uint8_t i = 0; i < getWorkDirDepth(); i++) + printf_P(PSTR("%s/"), dir_names[i]); + puts(filename); + } + else + SERIAL_PROTOCOLLN(LONGEST_FILENAME); + + SERIAL_PROTOCOLRPGM(_N("SD printing byte "));////MSG_SD_PRINTING_BYTE + SERIAL_PROTOCOL(sdpos); + SERIAL_PROTOCOL('/'); + SERIAL_PROTOCOLLN(filesize); + uint16_t time = ( _millis() - starttime ) / 60000U; + SERIAL_PROTOCOL(itostr2(time/60)); + SERIAL_PROTOCOL(':'); + SERIAL_PROTOCOLLN(itostr2(time%60)); + } + else + SERIAL_PROTOCOLLNPGM("Not SD printing"); } void CardReader::write_command(char *buf) { diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 25e97882..40098d3c 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -26,7 +26,7 @@ public: void release(); void startFileprint(); uint32_t getFileSize(); - void getStatus(); + void getStatus(bool arg_L); void printingHasFinished(); void getfilename(uint16_t nr, const char* const match=NULL); From 698499f00df6bc7797cdf8bca212661cfd79f8da Mon Sep 17 00:00:00 2001 From: Voinea Dragos <voinea.dragos.alexandru@gmail.com> Date: Sun, 31 Jan 2021 17:18:32 +0200 Subject: [PATCH 33/58] split timer0 and timer2 initialization. Move timer2 init early --- Firmware/Marlin_main.cpp | 2 ++ Firmware/temperature.cpp | 5 ++++- Firmware/timer02.c | 20 ++++++++++++-------- Firmware/timer02.h | 3 +++ 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index d43e05e5..68ecb1c1 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1013,6 +1013,8 @@ static void w25x20cl_err_msg() // are initialized by the main() routine provided by the Arduino framework. void setup() { + timer2_init(); // enables functional millis + mmu_init(); ultralcd_init(); diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 3b38c25c..a1281b64 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -1124,7 +1124,10 @@ void tp_init() adc_init(); - timer0_init(); + timer0_init(); //enables the heatbed timer. + + // timer2 already enabled earlier in the code + // now enable the COMPB temperature interrupt OCR2B = 128; TIMSK2 |= (1<<OCIE2B); diff --git a/Firmware/timer02.c b/Firmware/timer02.c index a866fa25..47f7d2a2 100644 --- a/Firmware/timer02.c +++ b/Firmware/timer02.c @@ -9,13 +9,11 @@ #include <avr/io.h> #include <avr/interrupt.h> +#include "macros.h" void timer0_init(void) { - //save sreg - uint8_t _sreg = SREG; - //disable interrupts for sure - cli(); + CRITICAL_SECTION_START; TCNT0 = 0; // Fast PWM duty (0-255). @@ -25,7 +23,14 @@ void timer0_init(void) TCCR0A = (1 << WGM01) | (1 << WGM00) | (1 << COM0B1) | (1 << COM0B0); TCCR0B = (1 << CS01); // CLK/8 prescaling TIMSK0 |= (1 << TOIE0); // enable timer overflow interrupt - + + CRITICAL_SECTION_END; +} + +void timer2_init(void) +{ + CRITICAL_SECTION_START; + // Everything, that used to be on timer0 was moved to timer2 (delay, beeping, millis etc.) //setup timer2 TCCR2A = 0x00; //COM_A-B=00, WGM_0-1=00 @@ -36,9 +41,8 @@ void timer0_init(void) TIMSK2 &= ~(1<<OCIE2B); //set timer2 OCR registers (OCRB interrupt generated 0.5ms after OVF interrupt) OCR2A = 0; - OCR2B = 128; - //restore sreg (enable interrupts) - SREG = _sreg; + + CRITICAL_SECTION_END; } diff --git a/Firmware/timer02.h b/Firmware/timer02.h index 2eef98f6..3aaa5236 100644 --- a/Firmware/timer02.h +++ b/Firmware/timer02.h @@ -14,6 +14,9 @@ extern "C" { ///! Initializes TIMER0 for fast PWM mode-driven bed heating extern void timer0_init(void); +///! Initializes TIMER2 for time keeping and temperature interrupt +extern void timer2_init(void); + ///! Reimplemented original millis() using timer2 extern unsigned long millis2(void); From 30131c9ab5b8594219f665470664c1fdc42d8bad Mon Sep 17 00:00:00 2001 From: Voinea Dragos <voinea.dragos.alexandru@gmail.com> Date: Sun, 31 Jan 2021 16:56:58 +0200 Subject: [PATCH 34/58] Patch broken string PROGMEM transition with setTargetedHotend() error --- Firmware/Marlin_main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 4739dc4a..1feb6944 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -10026,16 +10026,16 @@ bool setTargetedHotend(int code, uint8_t &extruder) SERIAL_ECHORPGM(_n("M104 Invalid extruder "));////MSG_M104_INVALID_EXTRUDER break; case 105: - SERIAL_ECHO(_n("M105 Invalid extruder "));////MSG_M105_INVALID_EXTRUDER + SERIAL_ECHORPGM(_n("M105 Invalid extruder "));////MSG_M105_INVALID_EXTRUDER break; case 109: - SERIAL_ECHO(_n("M109 Invalid extruder "));////MSG_M109_INVALID_EXTRUDER + SERIAL_ECHORPGM(_n("M109 Invalid extruder "));////MSG_M109_INVALID_EXTRUDER break; case 218: - SERIAL_ECHO(_n("M218 Invalid extruder "));////MSG_M218_INVALID_EXTRUDER + SERIAL_ECHORPGM(_n("M218 Invalid extruder "));////MSG_M218_INVALID_EXTRUDER break; case 221: - SERIAL_ECHO(_n("M221 Invalid extruder "));////MSG_M221_INVALID_EXTRUDER + SERIAL_ECHORPGM(_n("M221 Invalid extruder "));////MSG_M221_INVALID_EXTRUDER break; } SERIAL_PROTOCOLLN((int)extruder); From ec4c1be0582a3ba3a5109a3328c953d8a1847d67 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Fri, 29 Jan 2021 16:34:09 +0100 Subject: [PATCH 35/58] Silence bUpdateEEPROM unused warning in MK3 variant --- Firmware/fsensor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/fsensor.cpp b/Firmware/fsensor.cpp index 7c225bf2..4eac7bd0 100755 --- a/Firmware/fsensor.cpp +++ b/Firmware/fsensor.cpp @@ -233,6 +233,8 @@ void fsensor_init(void) bool fsensor_enable(bool bUpdateEEPROM) { #ifdef PAT9125 + (void)bUpdateEEPROM; // silence unused warning in this variant + if (mmu_enabled == false) { //filament sensor is pat9125, enable only if it is working uint8_t pat9125 = pat9125_init(); printf_P(PSTR("PAT9125_init:%hhu\n"), pat9125); From b6d56bc0f401928e80811c866ec303e198d7eb65 Mon Sep 17 00:00:00 2001 From: Alex Voinea <voinea.dragos.alexandru@gmail.com> Date: Mon, 1 Feb 2021 14:54:37 +0200 Subject: [PATCH 36/58] Change M27 argument from L to P as that makes more sense (path vs LFN)) --- Firmware/Marlin_main.cpp | 2 +- Firmware/cardreader.cpp | 4 ++-- Firmware/cardreader.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a1671848..62ec6f67 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -5818,7 +5818,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) ### M27 - Get SD status <a href="https://reprap.org/wiki/G-code#M27:_Report_SD_print_status">M27: Report SD print status</a> */ case 27: - card.getStatus(code_seen('L')); + card.getStatus(code_seen('P')); break; /*! diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 2140a09a..a9626897 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -502,7 +502,7 @@ uint32_t CardReader::getFileSize() return filesize; } -void CardReader::getStatus(bool arg_L) +void CardReader::getStatus(bool arg_P) { if (isPrintPaused) { @@ -513,7 +513,7 @@ void CardReader::getStatus(bool arg_L) } else if (sdprinting) { - if (arg_L) + if (arg_P) { SERIAL_PROTOCOL('/'); for (uint8_t i = 0; i < getWorkDirDepth(); i++) diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 40098d3c..52445400 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -26,7 +26,7 @@ public: void release(); void startFileprint(); uint32_t getFileSize(); - void getStatus(bool arg_L); + void getStatus(bool arg_P); void printingHasFinished(); void getfilename(uint16_t nr, const char* const match=NULL); From 7e09df6a340972cc9738699ee2a88977d3439534 Mon Sep 17 00:00:00 2001 From: Alex Voinea <voinea.dragos.alexandru@gmail.com> Date: Mon, 1 Feb 2021 14:54:44 +0200 Subject: [PATCH 37/58] Add documentation --- Firmware/Marlin_main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 62ec6f67..652466d7 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -5816,6 +5816,12 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) /*! ### M27 - Get SD status <a href="https://reprap.org/wiki/G-code#M27:_Report_SD_print_status">M27: Report SD print status</a> + #### Usage + + M27 [ P ] + + #### Parameters + - `P` - Show full SFN path instead of LFN only. */ case 27: card.getStatus(code_seen('P')); From 2f4119a6d723fc1e0e7b148aed73101cb89c5369 Mon Sep 17 00:00:00 2001 From: Alex Voinea <voinea.dragos.alexandru@gmail.com> Date: Tue, 2 Feb 2021 13:21:16 +0200 Subject: [PATCH 38/58] M552 - Printer IP address --- Firmware/Marlin.h | 2 ++ Firmware/Marlin_main.cpp | 19 +++++++++++++++++++ Firmware/ultralcd.cpp | 31 +++++++++++++++++++------------ Firmware/util.cpp | 7 +++++++ Firmware/util.h | 3 +++ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 307b8c91..17fce271 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -501,4 +501,6 @@ void raise_z_above(float target, bool plan=true); extern "C" void softReset(); +extern uint32_t IP_address; + #endif diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 9deb5105..61e5a33c 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -321,6 +321,8 @@ uint16_t print_time_remaining_normal = PRINT_TIME_REMAINING_INIT; //estimated re uint8_t print_percent_done_silent = PRINT_PERCENT_DONE_INIT; uint16_t print_time_remaining_silent = PRINT_TIME_REMAINING_INIT; //estimated remaining print time in minutes +uint32_t IP_address = 0; + //=========================================================================== //=============================Private Variables============================= //=========================================================================== @@ -8003,6 +8005,23 @@ Sigma_Exit: break; } #endif // CUSTOM_M_CODE_SET_Z_PROBE_OFFSET + case 552: + { + if (code_seen('P')) + { + uint8_t valCnt = 0; + IP_address = 0; + do + { + *strchr_pointer = '*'; + ((uint8_t*)&IP_address)[valCnt] = code_value_short(); + valCnt++; + } while ((valCnt < 4) && code_seen('.')); + + if (valCnt != 4) + IP_address = 0; + } + } break; #ifdef FILAMENTCHANGEENABLE diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index d7976d27..0f6bc1fa 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2057,8 +2057,8 @@ static void lcd_support_menu() { // 22bytes total int8_t status; // 1byte bool is_flash_air; // 1byte - uint8_t ip[4]; // 4bytes - char ip_str[3*4+3+1]; // 16bytes + uint32_t ip; // 4bytes + char ip_str[IP4_STR_SIZE]; // 16bytes } _menu_data_t; static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); @@ -2069,17 +2069,10 @@ static void lcd_support_menu() _md->status = 1; _md->is_flash_air = card.ToshibaFlashAir_isEnabled(); if (_md->is_flash_air) { - card.ToshibaFlashAir_GetIP(_md->ip); // ip[4] filled with 0 if it failed - // Prepare IP string from ip[4] - sprintf_P(_md->ip_str, PSTR("%d.%d.%d.%d"), - _md->ip[0], _md->ip[1], - _md->ip[2], _md->ip[3]); + card.ToshibaFlashAir_GetIP((uint8_t*)(&_md->ip)); // ip == 0 if it failed } - } else if (_md->is_flash_air && - _md->ip[0] == 0 && _md->ip[1] == 0 && - _md->ip[2] == 0 && _md->ip[3] == 0 && - ++ _md->status == 16) - { + } else if (_md->is_flash_air && _md->ip == 0 && ++ _md->status == 16) + { // Waiting for the FlashAir card to get an IP address from a router. Force an update. _md->status = 0; } @@ -2143,6 +2136,20 @@ static void lcd_support_menu() MENU_ITEM_BACK_P(PSTR(" ")); if (((menu_item - 1) == menu_line) && lcd_draw_update) { lcd_set_cursor(2, menu_row); + ip4_to_str(_md->ip_str, (uint8_t*)(&_md->ip)); + lcd_printf_P(PSTR("%s"), _md->ip_str); + } + } + + // Show the printer IP address, if it is available. + if (IP_address) { + + MENU_ITEM_BACK_P(STR_SEPARATOR); + MENU_ITEM_BACK_P(PSTR("Printer IP Addr:")); //c=18 r=1 + MENU_ITEM_BACK_P(PSTR(" ")); + if (((menu_item - 1) == menu_line) && lcd_draw_update) { + lcd_set_cursor(2, menu_row); + ip4_to_str(_md->ip_str, (uint8_t*)(&IP_address)); lcd_printf_P(PSTR("%s"), _md->ip_str); } } diff --git a/Firmware/util.cpp b/Firmware/util.cpp index e335793a..a25efd35 100644 --- a/Firmware/util.cpp +++ b/Firmware/util.cpp @@ -4,6 +4,7 @@ #include "sound.h" #include "language.h" #include "util.h" +#include <avr/pgmspace.h> // Allocate the version string in the program memory. Otherwise the string lands either on the stack or in the global RAM. const char FW_VERSION_STR[] PROGMEM = FW_VERSION; @@ -604,3 +605,9 @@ else { sPrinterName=_sPrinterName; } } + + +void ip4_to_str(char* dest, uint8_t* IP) +{ + sprintf_P(dest, PSTR("%u.%u.%u.%u"), IP[0], IP[1], IP[2], IP[3]); +} diff --git a/Firmware/util.h b/Firmware/util.h index f25749de..6d34aa08 100644 --- a/Firmware/util.h +++ b/Firmware/util.h @@ -110,4 +110,7 @@ void gcode_level_check(uint16_t nGcodeLevel); void fSetMmuMode(bool bMMu); +#define IP4_STR_SIZE 16 +extern void ip4_to_str(char* dest, uint8_t* IP); + #endif /* UTIL_H */ From 647cde0caeb3365e66d65cf1d558168c2ae2dc29 Mon Sep 17 00:00:00 2001 From: Alex Voinea <voinea.dragos.alexandru@gmail.com> Date: Tue, 2 Feb 2021 13:38:20 +0200 Subject: [PATCH 39/58] Add documentation --- Firmware/Marlin_main.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 61e5a33c..777a05ff 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3734,6 +3734,7 @@ extern uint8_t st_backlash_y; //!@n M503 - print the current settings (from memory not from EEPROM) //!@n M509 - force language selection on next restart //!@n M540 - Use S[0|1] to enable or disable the stop SD card print on endstop hit (requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) +//!@n M552 - Set IP address //!@n M600 - Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal] //!@n M605 - Set dual x-carriage movement mode: S<mode> [ X<duplication x-offset> R<duplication temp offset> ] //!@n M860 - Wait for PINDA thermistor to reach target temperature. @@ -8005,6 +8006,19 @@ Sigma_Exit: break; } #endif // CUSTOM_M_CODE_SET_Z_PROBE_OFFSET + + /*! + ### M552 - Set IP address <a href="https://reprap.org/wiki/G-code#M552:_Set_IP_address.2C_enable.2Fdisable_network_interface">M552: Set IP address, enable/disable network interface"</a> + Sets the printer IP address that is shown in the support menu. Designed to be used with the help of host software. + If P is not specified nothing happens. + If the structure of the IP address is invalid, 0.0.0.0 is assumed and nothing is shown on the screen in the Support menu. + #### Usage + + M552 [ P<IP_address> ] + + #### Parameters + - `P` - The IP address in xxx.xxx.xxx.xxx format. Eg: P192.168.1.14 + */ case 552: { if (code_seen('P')) From 5c9d202871c0bdb63323b77d5ed88827588d9533 Mon Sep 17 00:00:00 2001 From: Alex Voinea <voinea.dragos.alexandru@gmail.com> Date: Tue, 2 Feb 2021 19:08:19 +0200 Subject: [PATCH 40/58] Change MAX_DIR_DEPTH from 10 to 6 You can't run M23 with so many directories as the length of the command will exceed the maximum allowed by cmdqueue --- Firmware/cardreader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 52445400..9bf9bd0a 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -3,7 +3,7 @@ #ifdef SDSUPPORT -#define MAX_DIR_DEPTH 10 +#define MAX_DIR_DEPTH 6 #include "SdFile.h" enum LsAction {LS_SerialPrint,LS_SerialPrint_LFN,LS_Count,LS_GetFilename}; From f6ae3790770d39d3df71911c5112485edc04582b Mon Sep 17 00:00:00 2001 From: Alex Voinea <voinea.dragos.alexandru@gmail.com> Date: Tue, 2 Feb 2021 19:08:44 +0200 Subject: [PATCH 41/58] Fix dir_names array definition. Prevents overrun --- Firmware/Marlin.h | 2 +- Firmware/Marlin_main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 17fce271..aa057bc5 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -352,7 +352,7 @@ extern bool mesh_bed_run_from_menu; extern bool sortAlpha; -extern char dir_names[3][9]; +extern char dir_names[MAX_DIR_DEPTH][9]; extern int8_t lcd_change_fil_state; // save/restore printing diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 777a05ff..4e0511c1 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -228,7 +228,7 @@ bool fan_state[2]; int fan_edge_counter[2]; int fan_speed[2]; -char dir_names[3][9]; +char dir_names[MAX_DIR_DEPTH][9]; bool sortAlpha = false; From 896f4e1dd1b55bc14e77cd63996aab87267a4464 Mon Sep 17 00:00:00 2001 From: Alex Voinea <voinea.dragos.alexandru@gmail.com> Date: Tue, 2 Feb 2021 19:14:05 +0200 Subject: [PATCH 42/58] Fix compile error --- Firmware/Marlin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index aa057bc5..1ed5e0bd 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -352,7 +352,7 @@ extern bool mesh_bed_run_from_menu; extern bool sortAlpha; -extern char dir_names[MAX_DIR_DEPTH][9]; +extern char dir_names[][9]; extern int8_t lcd_change_fil_state; // save/restore printing From 1c76152e62e9aa6fd3dafbc8eecb800cab6003f6 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Sun, 20 Sep 2020 18:15:27 +0200 Subject: [PATCH 43/58] Implement separate travel acceleration (M204 T) Allow to separate extrusion and travel acceleration settings using M204, as Marlin 1.1.x and 2.x does using M204 T. This allows to reduce the number of instructions required during printing, since resetting the acceleration for travel moves is no longer required and can be done a single time during the print. Provision for this parameter was pre-existing, but not implemented. M204 has two forms: the lagacy format (Marlin <1.1): M204 S[print-acc] T[retract-acc] and the newer format: M204 P[print-acc] R[retract-acc] T[travel-acc] The distinction in the MK3 FW is done based on the presence of the P parameter. If P is seen, the new format is adoped. In the new format however, M204 T was ignored until this change. To keep backward compatibility, M204 S[acc] will set both print and travel acceleration, which is identical in behavior to recent versions of Marlin. --- Firmware/ConfigurationStore.cpp | 3 ++- Firmware/ConfigurationStore.h | 1 + Firmware/Marlin_main.cpp | 11 +++-------- Firmware/planner.cpp | 3 ++- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Firmware/ConfigurationStore.cpp b/Firmware/ConfigurationStore.cpp index 0bd13a3a..009a9024 100644 --- a/Firmware/ConfigurationStore.cpp +++ b/Firmware/ConfigurationStore.cpp @@ -184,7 +184,7 @@ static_assert (false, "zprobe_zoffset was not initialized in printers in field t "0.0, if this is not acceptable, increment EEPROM_VERSION to force use default_conf"); #endif -static_assert (sizeof(M500_conf) == 192, "sizeof(M500_conf) has changed, ensure that EEPROM_VERSION has been incremented, " +static_assert (sizeof(M500_conf) == 196, "sizeof(M500_conf) has changed, ensure that EEPROM_VERSION has been incremented, " "or if you added members in the end of struct, ensure that historically uninitialized values will be initialized." "If this is caused by change to more then 8bit processor, decide whether make this struct packed to save EEPROM," "leave as it is to keep fast code, or reorder struct members to pack more tightly."); @@ -232,6 +232,7 @@ static const M500_conf default_conf PROGMEM = #else // TMC2130 {16,16,16,16}, #endif + DEFAULT_TRAVEL_ACCELERATION, }; //! @brief Read M500 configuration diff --git a/Firmware/ConfigurationStore.h b/Firmware/ConfigurationStore.h index b9dca368..3e3caf72 100644 --- a/Firmware/ConfigurationStore.h +++ b/Firmware/ConfigurationStore.h @@ -38,6 +38,7 @@ typedef struct float max_feedrate_silent[4]; //!< max speeds for silent mode unsigned long max_acceleration_units_per_sq_second_silent[4]; unsigned char axis_ustep_resolution[4]; + float travel_acceleration; //!< travel acceleration mm/s^2 } M500_conf; extern M500_conf cs; diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 4e0511c1..f25b5aeb 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -7258,7 +7258,7 @@ Sigma_Exit: // Legacy acceleration format. This format is used by the legacy Marlin, MK2 or MK3 firmware, // and it is also generated by Slic3r to control acceleration per extrusion type // (there is a separate acceleration settings in Slicer for perimeter, first layer etc). - cs.acceleration = code_value(); + cs.acceleration = cs.travel_acceleration = code_value(); // Interpret the T value as retract acceleration in the old Marlin format. if(code_seen('T')) cs.retract_acceleration = code_value(); @@ -7268,13 +7268,8 @@ Sigma_Exit: cs.acceleration = code_value(); if(code_seen('R')) cs.retract_acceleration = code_value(); - if(code_seen('T')) { - // Interpret the T value as the travel acceleration in the new Marlin format. - /*! - @todo Prusa3D firmware currently does not support travel acceleration value independent from the extruding acceleration value. - */ - // travel_acceleration = code_value(); - } + if(code_seen('T')) + cs.travel_acceleration = code_value(); } } break; diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index 2615ef66..ba3791ae 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -1082,7 +1082,8 @@ Having the real displacement of the head, we can calculate the total movement le } else { - block->acceleration_st = ceil(cs.acceleration * steps_per_mm); // convert to: acceleration steps/sec^2 + float acceleration = (block->steps_e.wide == 0? cs.travel_acceleration: cs.acceleration); + block->acceleration_st = ceil(acceleration * steps_per_mm); // convert to: acceleration steps/sec^2 #ifdef LIN_ADVANCE /** From 5589954b77dd35042ed743f8aa8d94c2d717d44f Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Sun, 20 Sep 2020 19:03:05 +0200 Subject: [PATCH 44/58] Add DEFAULT_TRAVEL_ACCELERATION in all variants Use the same value as DEFAULT_ACCELERATION for compatibility. --- Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h | 3 ++- Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h | 3 ++- Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h | 5 +++-- Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h | 5 +++-- Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h | 5 +++-- Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h | 5 +++-- Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 5 +++-- Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 5 +++-- 8 files changed, 22 insertions(+), 14 deletions(-) diff --git a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h index a74b6948..4c20082e 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h @@ -90,8 +90,9 @@ AXIS SETTINGS #define DEFAULT_MAX_ACCELERATION {9000,9000,500,10000} // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for Skeinforge 40+, for older versions raise them a lot. #define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode -#define DEFAULT_ACCELERATION 1500 // X, Y, Z and E max acceleration in mm/s^2 for printing moves +#define DEFAULT_ACCELERATION 1500 // X, Y, Z and E max acceleration in mm/s^2 for printing moves #define DEFAULT_RETRACT_ACCELERATION 1500 // X, Y, Z and E max acceleration in mm/s^2 for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1500 // X, Y, Z and E max acceleration in mm/s^2 for travels #define MANUAL_FEEDRATE {3000, 3000, 1000, 100} // set the speeds for manual moves (mm/min) diff --git a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h index 72ac605f..35313a41 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h @@ -90,8 +90,9 @@ AXIS SETTINGS #define DEFAULT_MAX_ACCELERATION {9000,9000,500,10000} // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for Skeinforge 40+, for older versions raise them a lot. #define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode -#define DEFAULT_ACCELERATION 1500 // X, Y, Z and E max acceleration in mm/s^2 for printing moves +#define DEFAULT_ACCELERATION 1500 // X, Y, Z and E max acceleration in mm/s^2 for printing moves #define DEFAULT_RETRACT_ACCELERATION 1500 // X, Y, Z and E max acceleration in mm/s^2 for retracts +#define DEFAULT_TRAVEL_ACCELERATION 1500 // X, Y, Z and E max acceleration in mm/s^2 for travels #define MANUAL_FEEDRATE {3000, 3000, 1000, 100} // set the speeds for manual moves (mm/min) diff --git a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h index ba40e046..acd7883d 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h @@ -94,8 +94,9 @@ #define DEFAULT_MAX_ACCELERATION {1000, 1000, 200, 5000} // (mm/sec^2) max acceleration (M201) #define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode -#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204S) -#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204T) +#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204P) +#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204R) +#define DEFAULT_TRAVEL_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for travels (M204T) #define MANUAL_FEEDRATE {2700, 2700, 1000, 100} // set the speeds for manual moves (mm/min) diff --git a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h index 33bb4717..ddf7e77a 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h @@ -95,8 +95,9 @@ #define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode -#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204S) -#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204T) +#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204P) +#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204R) +#define DEFAULT_TRAVEL_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for travels (M204T) #define MANUAL_FEEDRATE {2700, 2700, 1000, 100} // set the speeds for manual moves (mm/min) diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h index 19b2c76f..e7b114d9 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h @@ -94,8 +94,9 @@ #define DEFAULT_MAX_ACCELERATION {1000, 1000, 200, 5000} // (mm/sec^2) max acceleration (M201) #define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode -#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204S) -#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204T) +#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204P) +#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204R) +#define DEFAULT_TRAVEL_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for travels (M204T) #define MANUAL_FEEDRATE {2700, 2700, 1000, 100} // set the speeds for manual moves (mm/min) diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h index cc02867d..cde81249 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h @@ -95,8 +95,9 @@ #define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode -#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204S) -#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204T) +#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204P) +#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204R) +#define DEFAULT_TRAVEL_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for travels (M204T) #define MANUAL_FEEDRATE {2700, 2700, 1000, 100} // set the speeds for manual moves (mm/min) diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index 65f7ae99..2c62f2fd 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -99,8 +99,9 @@ #define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode -#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204S) -#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204T) +#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204P) +#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204R) +#define DEFAULT_TRAVEL_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for travels (M204T) #define MANUAL_FEEDRATE {2700, 2700, 1000, 100} // set the speeds for manual moves (mm/min) diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index c7ab7508..d74d75d5 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -101,8 +101,9 @@ #define DEFAULT_MAX_ACCELERATION_SILENT {960, 960, 200, 5000} // (mm/sec^2) max acceleration (M201), silent mode -#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204S) -#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204T) +#define DEFAULT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204P) +#define DEFAULT_RETRACT_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204R) +#define DEFAULT_TRAVEL_ACCELERATION 1250 // X, Y, Z and E max acceleration in mm/s^2 for travels (M204T) #define MANUAL_FEEDRATE {2700, 2700, 1000, 100} // set the speeds for manual moves (mm/min) From 45811f82aa04b58dadd93990298fef36747ea82d Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Sun, 20 Sep 2020 19:04:08 +0200 Subject: [PATCH 45/58] Initialize default travel_acceleration from EEPROM When reading uninitialized memory, preset the travel acceleration to be the same as the default acceleration. --- Firmware/ConfigurationStore.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Firmware/ConfigurationStore.cpp b/Firmware/ConfigurationStore.cpp index 009a9024..c8548564 100644 --- a/Firmware/ConfigurationStore.cpp +++ b/Firmware/ConfigurationStore.cpp @@ -235,6 +235,18 @@ static const M500_conf default_conf PROGMEM = DEFAULT_TRAVEL_ACCELERATION, }; + +static bool is_uninitialized(void* addr, uint8_t len) +{ + while(len--) + { + if(reinterpret_cast<uint8_t*>(addr)[len] != 0xff) + return false; + } + return true; +} + + //! @brief Read M500 configuration //! @retval true Succeeded. Stored settings retrieved or default settings retrieved in case EEPROM has been erased. //! @retval false Failed. Default settings has been retrieved, because of older version or corrupted data. @@ -294,6 +306,9 @@ bool Config_RetrieveSettings() tmc2130_set_res(E_AXIS, cs.axis_ustep_resolution[E_AXIS]); #endif //TMC2130 + if(is_uninitialized(&cs.travel_acceleration, sizeof(cs.travel_acceleration))) + cs.travel_acceleration = cs.acceleration; + reset_acceleration_rates(); // Call updatePID (similar to when we have processed M301) From 76911f67dbd69c22558beb84f45b85f643515372 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Sun, 20 Sep 2020 19:05:19 +0200 Subject: [PATCH 46/58] Take advantage of the new is_uninitialized function Save some space and perform some cleanup --- Firmware/ConfigurationStore.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Firmware/ConfigurationStore.cpp b/Firmware/ConfigurationStore.cpp index c8548564..dc8126ac 100644 --- a/Firmware/ConfigurationStore.cpp +++ b/Firmware/ConfigurationStore.cpp @@ -270,13 +270,9 @@ bool Config_RetrieveSettings() for (uint8_t i = 0; i < (sizeof(cs.max_feedrate_silent)/sizeof(cs.max_feedrate_silent[0])); ++i) { const uint32_t erased = 0xffffffff; - bool initialized = false; - - for(uint8_t j = 0; j < sizeof(float); ++j) - { - if(0xff != reinterpret_cast<uint8_t*>(&(cs.max_feedrate_silent[i]))[j]) initialized = true; + if (is_uninitialized(&(cs.max_feedrate_silent[i]), sizeof(float))) { + memcpy_P(&cs.max_feedrate_silent[i],&default_conf.max_feedrate_silent[i], sizeof(cs.max_feedrate_silent[i])); } - if (!initialized) memcpy_P(&cs.max_feedrate_silent[i],&default_conf.max_feedrate_silent[i], sizeof(cs.max_feedrate_silent[i])); if (erased == cs.max_acceleration_units_per_sq_second_silent[i]) { memcpy_P(&cs.max_acceleration_units_per_sq_second_silent[i],&default_conf.max_acceleration_units_per_sq_second_silent[i],sizeof(cs.max_acceleration_units_per_sq_second_silent[i])); } From f7542aa0644b8ea6d9928e8dbe64e527e686599f Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Sun, 20 Sep 2020 19:06:15 +0200 Subject: [PATCH 47/58] Report travel acceleration in M503 Use the new M204 format consistently also in M503's output --- Firmware/ConfigurationStore.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Firmware/ConfigurationStore.cpp b/Firmware/ConfigurationStore.cpp index dc8126ac..adccb399 100644 --- a/Firmware/ConfigurationStore.cpp +++ b/Firmware/ConfigurationStore.cpp @@ -96,7 +96,7 @@ void Config_PrintSettings(uint8_t level) "%SMaximum feedrates - stealth (mm/s):\n%S M203 X%.2f Y%.2f Z%.2f E%.2f\n" "%SMaximum acceleration - normal (mm/s2):\n%S M201 X%lu Y%lu Z%lu E%lu\n" "%SMaximum acceleration - stealth (mm/s2):\n%S M201 X%lu Y%lu Z%lu E%lu\n" - "%SAcceleration: S=acceleration, T=retract acceleration\n%S M204 S%.2f T%.2f\n" + "%SAcceleration: P=print, R=retract, T=travel\n%S M204 P%.2f R%.2f T%.2f\n" "%SAdvanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)\n%S M205 S%.2f T%.2f B%.2f X%.2f Y%.2f Z%.2f E%.2f\n" "%SHome offset (mm):\n%S M206 X%.2f Y%.2f Z%.2f\n" ), @@ -106,7 +106,7 @@ void Config_PrintSettings(uint8_t level) echomagic, echomagic, cs.max_feedrate_silent[X_AXIS], cs.max_feedrate_silent[Y_AXIS], cs.max_feedrate_silent[Z_AXIS], cs.max_feedrate_silent[E_AXIS], echomagic, echomagic, cs.max_acceleration_units_per_sq_second_normal[X_AXIS], cs.max_acceleration_units_per_sq_second_normal[Y_AXIS], cs.max_acceleration_units_per_sq_second_normal[Z_AXIS], cs.max_acceleration_units_per_sq_second_normal[E_AXIS], echomagic, echomagic, cs.max_acceleration_units_per_sq_second_silent[X_AXIS], cs.max_acceleration_units_per_sq_second_silent[Y_AXIS], cs.max_acceleration_units_per_sq_second_silent[Z_AXIS], cs.max_acceleration_units_per_sq_second_silent[E_AXIS], - echomagic, echomagic, cs.acceleration, cs.retract_acceleration, + echomagic, echomagic, cs.acceleration, cs.retract_acceleration, cs.travel_acceleration, echomagic, echomagic, cs.minimumfeedrate, cs.mintravelfeedrate, cs.minsegmenttime, cs.max_jerk[X_AXIS], cs.max_jerk[Y_AXIS], cs.max_jerk[Z_AXIS], cs.max_jerk[E_AXIS], echomagic, echomagic, cs.add_homing[X_AXIS], cs.add_homing[Y_AXIS], cs.add_homing[Z_AXIS] #else //TMC2130 @@ -114,14 +114,14 @@ void Config_PrintSettings(uint8_t level) "%SSteps per unit:\n%S M92 X%.2f Y%.2f Z%.2f E%.2f\n" "%SMaximum feedrates (mm/s):\n%S M203 X%.2f Y%.2f Z%.2f E%.2f\n" "%SMaximum acceleration (mm/s2):\n%S M201 X%lu Y%lu Z%lu E%lu\n" - "%SAcceleration: S=acceleration, T=retract acceleration\n%S M204 S%.2f T%.2f\n" + "%SAcceleration: P=print, R=retract, T=travel\n%S M204 P%.2f R%.2f T%.2f\n" "%SAdvanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)\n%S M205 S%.2f T%.2f B%.2f X%.2f Y%.2f Z%.2f E%.2f\n" "%SHome offset (mm):\n%S M206 X%.2f Y%.2f Z%.2f\n" ), echomagic, echomagic, cs.axis_steps_per_unit[X_AXIS], cs.axis_steps_per_unit[Y_AXIS], cs.axis_steps_per_unit[Z_AXIS], cs.axis_steps_per_unit[E_AXIS], echomagic, echomagic, max_feedrate[X_AXIS], max_feedrate[Y_AXIS], max_feedrate[Z_AXIS], max_feedrate[E_AXIS], echomagic, echomagic, max_acceleration_units_per_sq_second[X_AXIS], max_acceleration_units_per_sq_second[Y_AXIS], max_acceleration_units_per_sq_second[Z_AXIS], max_acceleration_units_per_sq_second[E_AXIS], - echomagic, echomagic, cs.acceleration, cs.retract_acceleration, + echomagic, echomagic, cs.acceleration, cs.retract_acceleration, cs.travel_acceleration, echomagic, echomagic, cs.minimumfeedrate, cs.mintravelfeedrate, cs.minsegmenttime, cs.max_jerk[X_AXIS], cs.max_jerk[Y_AXIS], cs.max_jerk[Z_AXIS], cs.max_jerk[E_AXIS], echomagic, echomagic, cs.add_homing[X_AXIS], cs.add_homing[Y_AXIS], cs.add_homing[Z_AXIS] #endif //TMC2130 From 186ce0f4b32dda9d5a2fa8e0e2649cc130d2cfca Mon Sep 17 00:00:00 2001 From: Yuri D'Elia <wavexx@thregr.org> Date: Mon, 1 Feb 2021 00:02:49 +0100 Subject: [PATCH 48/58] Handle acceleration settings in UVLO/power panic Acceleration settings need to be saved in UVLO, since these are often changed/set during a print. This is especially important for travel and retract acceleration, which is usually set once per-print. Saving and restoring is not 100% correct. We save the current front-end value, which might ahead of the backend when UVLO is triggered. Print acceleration, likely the most significant, should be saved in the block buffer to be accurate. Acceleration needs to be restored after the UVLO Z repositioning is performed, using an M204 command. This is correct, however we don't save the _temporary_ max acceleration limits set via M201, which could be higher than the saved limits (via M500). This could result in lower clamped values compared to the original print. Maximum acceleration/jerk/feedrate limits should _all_ be saved in UVLO in the future. --- Firmware/Marlin_main.cpp | 11 +++++++++++ Firmware/eeprom.h | 11 +++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index f25b5aeb..780a0bca 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -10963,6 +10963,10 @@ void uvlo_() #endif eeprom_update_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY), (uint16_t)extrudemultiply); + eeprom_update_float((float*)(EEPROM_UVLO_ACCELL), cs.acceleration); + eeprom_update_float((float*)(EEPROM_UVLO_RETRACT_ACCELL), cs.retract_acceleration); + eeprom_update_float((float*)(EEPROM_UVLO_TRAVEL_ACCELL), cs.travel_acceleration); + // Store the saved target eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+0*4), saved_target[X_AXIS]); eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+1*4), saved_target[Y_AXIS]); @@ -11307,6 +11311,13 @@ void restore_print_from_eeprom(bool mbl_was_active) { sprintf_P(cmd, PSTR("G1 Z%f"), eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z))); enquecommand(cmd); + // Restore acceleration settings + float acceleration = eeprom_read_float((float*)(EEPROM_UVLO_ACCELL)); + float retract_acceleration = eeprom_read_float((float*)(EEPROM_UVLO_RETRACT_ACCELL)); + float travel_acceleration = eeprom_read_float((float*)(EEPROM_UVLO_TRAVEL_ACCELL)); + sprintf_P(cmd, PSTR("M204 P%f R%f T%f"), acceleration, retract_acceleration, travel_acceleration); + enquecommand(cmd); + // Unretract. sprintf_P(cmd, PSTR("G1 E%0.3f F2700"), default_retraction); enquecommand(cmd); diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index 03af214f..f9f93b7d 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -319,8 +319,10 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP | ^ | ^ | ^ | 00h 0 | ^ | PINDA has no temp compensation PINDA v1/2 | ^ | ^ | ^ | ^ | ^ | 01h 1 | ^ | PINDA has temp compensation aka SuperPINDA | ^ | ^ | 0x0D15 3349 | char[20] | EEPROM_PRUSA_SN | SN[19] == 0 | ffffffffffffffff... | PRUSA Serial number string | PRUSA SN | D3 Ax0d15 C20 +| 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 - | Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | 0x0012 18 | uint16 | EEPROM_FIRMWARE_VERSION_END | ??? | ff ffh 65535 | ??? | ??? | D3 Ax0012 C2 @@ -525,8 +527,13 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE); #define EEPROM_EXPERIMENTAL_VISIBILITY (EEPROM_ALTFAN_OVERRIDE-1) //uint8 #define EEPROM_PINDA_TEMP_COMPENSATION (EEPROM_EXPERIMENTAL_VISIBILITY-1) //uint8 #define EEPROM_PRUSA_SN (EEPROM_PINDA_TEMP_COMPENSATION-20) //char[20] + +#define EEPROM_UVLO_ACCELL (EEPROM_PRUSA_SN-4) // float +#define EEPROM_UVLO_RETRACT_ACCELL (EEPROM_UVLO_ACCELL-4) // float +#define EEPROM_UVLO_TRAVEL_ACCELL (EEPROM_UVLO_RETRACT_ACCELL-4) // float + //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items. -#define EEPROM_LAST_ITEM EEPROM_PRUSA_SN +#define EEPROM_LAST_ITEM EEPROM_UVLO_TRAVEL_ACCELL // !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! // !!!!! From f343e6432ac33c7417d35d3f2faadcb9f94ae515 Mon Sep 17 00:00:00 2001 From: Voinea Dragos <voinea.dragos.alexandru@gmail.com> Date: Sun, 31 Jan 2021 16:42:01 +0200 Subject: [PATCH 49/58] Fix diveSubfolder string termination --- Firmware/cardreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index a9626897..4b55e816 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -340,9 +340,9 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) { const size_t maxLen = 12; char subdirname[maxLen+1]; - subdirname[maxLen] = 0; const size_t len = ((static_cast<size_t>(dirname_end-dirname_start))>maxLen) ? maxLen : (dirname_end-dirname_start); strncpy(subdirname, dirname_start, len); + subdirname[len] = 0; SERIAL_ECHOLN(subdirname); if (!dir.open(curDir, subdirname, O_READ)) { From 52f7a71dce177cf7dc484988a6701f08e689d9e2 Mon Sep 17 00:00:00 2001 From: Voinea Dragos <voinea.dragos.alexandru@gmail.com> Date: Sat, 6 Feb 2021 14:59:11 +0200 Subject: [PATCH 50/58] More fixes that were extracted from #2405 --- Firmware/Marlin.h | 4 -- Firmware/Marlin_main.cpp | 8 +--- Firmware/cardreader.cpp | 81 +++++++++++++++++++++------------------- Firmware/cardreader.h | 10 +++-- Firmware/messages.c | 1 + Firmware/messages.h | 1 + Firmware/ultralcd.cpp | 12 ++---- 7 files changed, 57 insertions(+), 60 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 1ed5e0bd..cbe03c0f 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -350,10 +350,6 @@ extern unsigned long t_fan_rising_edge; extern bool mesh_bed_leveling_flag; extern bool mesh_bed_run_from_menu; -extern bool sortAlpha; - -extern char dir_names[][9]; - extern int8_t lcd_change_fil_state; // save/restore printing extern bool saved_printing; diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 6db1d277..e5daeee0 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -228,10 +228,6 @@ bool fan_state[2]; int fan_edge_counter[2]; int fan_speed[2]; -char dir_names[MAX_DIR_DEPTH][9]; - -bool sortAlpha = false; - float extruder_multiplier[EXTRUDERS] = {1.0 #if EXTRUDERS > 1 @@ -11281,8 +11277,8 @@ void restore_print_from_eeprom(bool mbl_was_active) { } dir_name[8] = '\0'; MYSERIAL.println(dir_name); - strcpy(dir_names[i], dir_name); - card.chdir(dir_name); + // strcpy(dir_names[i], dir_name); + card.chdir(dir_name, false); } for (int i = 0; i < 8; i++) { diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 4b55e816..418dbb94 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -32,6 +32,7 @@ CardReader::CardReader() workDirDepth = 0; file_subcall_ctr=0; memset(workDirParents, 0, sizeof(workDirParents)); + presort_flag = false; autostart_stilltocheck=true; //the SD start is delayed, because otherwise the serial cannot answer fast enough to make contact with the host software. lastnr=0; @@ -69,12 +70,15 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters +*/ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { + static uint8_t recursionCnt = 0; dir_t p; uint8_t cnt = 0; // Read the next entry from a directory while (parent.readDir(p, longFilename) > 0) { - // If the entry is a directory and the action is LS_SerialPrint - if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { + 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 + recursionCnt++; // Get the short name for the item, which we know is a folder char lfilename[FILENAME_LENGTH]; createFilename(lfilename, p); @@ -108,6 +112,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m if (lsAction == LS_SerialPrint_LFN) puts_P(PSTR("DIR_EXIT")); + recursionCnt--; } else { uint8_t pn0 = p.name[0]; @@ -241,18 +246,18 @@ void CardReader::initsd() } -void CardReader::setroot() +void CardReader::setroot(bool doPresort) { - /*if(!workDir.openRoot(&volume)) - { - SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL); - }*/ workDir=root; + workDirDepth = 0; curDir=&workDir; - #ifdef SDCARD_SORT_ALPHA - presort(); - #endif +#ifdef SDCARD_SORT_ALPHA + if (doPresort) + presort(); + else + presort_flag = true; +#endif } void CardReader::release() { @@ -317,19 +322,17 @@ void CardReader::getAbsFilename(char *t) * @param[in,out] fileName * expects file name including path * in case of absolute path, file name without path is returned - * @param[in,out] dir SdFile object to operate with, - * in case of absolute path, curDir is modified to point to dir, - * so it is not possible to create on stack inside this function, - * as curDir would point to destroyed object. */ -void CardReader::diveSubfolder (const char *fileName, SdFile& dir) +bool CardReader::diveSubfolder (const char *&fileName) { curDir=&root; - if (!fileName) return; + if (!fileName) + return 1; const char *dirname_start, *dirname_end; if (fileName[0] == '/') // absolute path { + setroot(false); dirname_start = fileName + 1; while (*dirname_start) { @@ -344,19 +347,10 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) strncpy(subdirname, dirname_start, len); subdirname[len] = 0; SERIAL_ECHOLN(subdirname); - if (!dir.open(curDir, subdirname, O_READ)) - { - SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); - SERIAL_PROTOCOL(subdirname); - SERIAL_PROTOCOLLN('.'); - return; - } - else - { - //SERIAL_ECHOLN("dive ok"); - } + if (!chdir(subdirname, false)) + return 0; - curDir = &dir; + curDir = &workDir; dirname_start = dirname_end + 1; } else // the reminder after all /fsa/fdsa/ is the filename @@ -373,6 +367,7 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) { curDir = &workDir; } + return 1; } void CardReader::openFile(const char* name,bool read, bool replace_current/*=true*/) @@ -423,9 +418,9 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru } sdprinting = false; - SdFile myDir; const char *fname=name; - diveSubfolder(fname,myDir); + if (!diveSubfolder(fname)) + return; if(read) { @@ -438,10 +433,9 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru SERIAL_PROTOCOLLN(filesize); sdpos = 0; - SERIAL_PROTOCOLLNRPGM(_N("File selected"));////MSG_SD_FILE_SELECTED + SERIAL_PROTOCOLLNRPGM(MSG_FILE_SELECTED); + lcd_setstatuspgm(MSG_FILE_SELECTED); getfilename(0, fname); - lcd_setstatus(longFilename[0] ? longFilename : fname); - lcd_setstatuspgm(PSTR("SD-PRINTING")); } else { @@ -475,9 +469,9 @@ void CardReader::removeFile(const char* name) file.close(); sdprinting = false; - SdFile myDir; const char *fname=name; - diveSubfolder(fname,myDir); + if (!diveSubfolder(fname)) + return; if (file.remove(curDir, fname)) { @@ -670,7 +664,7 @@ uint16_t CardReader::getnrfilenames() return nrFiles; } -void CardReader::chdir(const char * relpath) +bool CardReader::chdir(const char * relpath, bool doPresort) { SdFile newfile; SdFile *parent=&root; @@ -678,23 +672,32 @@ void CardReader::chdir(const char * relpath) if(workDir.isOpen()) parent=&workDir; - if(!newfile.open(*parent,relpath, O_READ)) + if(!newfile.open(*parent,relpath, O_READ) || ((workDirDepth + 1) >= MAX_DIR_DEPTH)) { SERIAL_ECHO_START; SERIAL_ECHORPGM(_n("Cannot enter subdir: "));////MSG_SD_CANT_ENTER_SUBDIR SERIAL_ECHOLN(relpath); + return 0; } else { + strcpy(dir_names[workDirDepth], relpath); + puts(relpath); + if (workDirDepth < MAX_DIR_DEPTH) { for (int d = ++workDirDepth; d--;) workDirParents[d+1] = workDirParents[d]; workDirParents[0]=*parent; } workDir=newfile; - #ifdef SDCARD_SORT_ALPHA + +#ifdef SDCARD_SORT_ALPHA + if (doPresort) presort(); - #endif + else + presort_flag = true; +#endif + return 1; } } diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 9bf9bd0a..819e8bf2 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -39,9 +39,9 @@ public: void ls(bool printLFN); - void chdir(const char * relpath); + bool chdir(const char * relpath, bool doPresort); void updir(); - void setroot(); + void setroot(bool doPresort); #ifdef SDCARD_SORT_ALPHA void presort(); @@ -82,6 +82,10 @@ public: char longFilename[LONG_FILENAME_LENGTH]; bool filenameIsDir; int lastnr; //last number of the autostart; +#ifdef SDCARD_SORT_ALPHA + bool presort_flag; + char dir_names[MAX_DIR_DEPTH][9]; +#endif // SDCARD_SORT_ALPHA private: SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH]; uint16_t workDirDepth; @@ -155,7 +159,7 @@ private: 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; - void diveSubfolder (const char *fileName, SdFile& dir); + bool diveSubfolder (const char *&fileName); void lsDive(const char *prepend, SdFile parent, const char * const match=NULL); #ifdef SDCARD_SORT_ALPHA void flush_presort(); diff --git a/Firmware/messages.c b/Firmware/messages.c index 0b1d58e0..39f0cf33 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -197,3 +197,4 @@ const char MSG_M112_KILL[] PROGMEM_N1 = "M112 called. Emergency Stop."; ////c=20 const char MSG_ADVANCE_K[] PROGMEM_N1 = "Advance K:"; ////c=13 const char MSG_POWERPANIC_DETECTED[] PROGMEM_N1 = "POWER PANIC DETECTED"; ////c=20 const char MSG_LCD_STATUS_CHANGED[] PROGMEM_N1 = "LCD status changed"; +const char MSG_FILE_SELECTED[] PROGMEM_N1 = "File selected"; ////c=20 diff --git a/Firmware/messages.h b/Firmware/messages.h index 0a05c58f..a5b672fa 100644 --- a/Firmware/messages.h +++ b/Firmware/messages.h @@ -197,6 +197,7 @@ extern const char MSG_M112_KILL[]; extern const char MSG_ADVANCE_K[]; extern const char MSG_POWERPANIC_DETECTED[]; extern const char MSG_LCD_STATUS_CHANGED[]; +extern const char MSG_FILE_SELECTED[]; #if defined(__cplusplus) } diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0f6bc1fa..2d92596f 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -4317,7 +4317,7 @@ static void lcd_sort_type_set() { default: sdSort = SD_SORT_TIME; } eeprom_update_byte((unsigned char *)EEPROM_SD_SORT, sdSort); - presort_flag = true; + card.presort_flag = true; } #endif //SDCARD_SORT_ALPHA @@ -8548,7 +8548,7 @@ static void menu_action_sdfile(const char* filename) for (uint_least8_t i = 0; i < depth; i++) { for (uint_least8_t j = 0; j < 8; j++) { - eeprom_write_byte((uint8_t*)EEPROM_DIRS + j + 8 * i, dir_names[i][j]); + eeprom_write_byte((uint8_t*)EEPROM_DIRS + j + 8 * i, card.dir_names[i][j]); } } @@ -8566,12 +8566,8 @@ static void menu_action_sdfile(const char* filename) void menu_action_sddirectory(const char* filename) { - uint8_t depth = (uint8_t)card.getWorkDirDepth(); - - strcpy(dir_names[depth], filename); - MYSERIAL.println(dir_names[depth]); - card.chdir(filename); - lcd_encoder = 0; + card.chdir(filename, true); + lcd_encoder = 0; } /** LCD API **/ From 77a5082b5664c7ccfe05ed08af16c89ad7c7b448 Mon Sep 17 00:00:00 2001 From: Voinea Dragos <voinea.dragos.alexandru@gmail.com> Date: Sat, 6 Feb 2021 17:25:17 +0200 Subject: [PATCH 51/58] Fix presort_flag duplicate declaration --- Firmware/ultralcd.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 2d92596f..a736f8c2 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -75,11 +75,6 @@ int8_t FSensorStateMenu = 1; bool bMenuFSDetect=false; #endif //IR_SENSOR_ANALOG - -#ifdef SDCARD_SORT_ALPHA -bool presort_flag = false; -#endif - LcdCommands lcd_commands_type = LcdCommands::Idle; static uint8_t lcd_commands_step = 0; @@ -7183,8 +7178,8 @@ void lcd_sdcard_menu() { uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); - if (presort_flag == true) { - presort_flag = false; + if (card.presort_flag == true) { + card.presort_flag = false; card.presort(); } if (lcd_draw_update == 0 && LCD_CLICKED == 0) From f5cde38a7c000eeacfc7dc08f46e820359ee8777 Mon Sep 17 00:00:00 2001 From: Alex Voinea <voinea.dragos.alexandru@gmail.com> Date: Sat, 6 Feb 2021 21:06:37 +0200 Subject: [PATCH 52/58] Remove duplicit debug line --- Firmware/cardreader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 418dbb94..8273e3d0 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -346,7 +346,6 @@ bool CardReader::diveSubfolder (const char *&fileName) const size_t len = ((static_cast<size_t>(dirname_end-dirname_start))>maxLen) ? maxLen : (dirname_end-dirname_start); strncpy(subdirname, dirname_start, len); subdirname[len] = 0; - SERIAL_ECHOLN(subdirname); if (!chdir(subdirname, false)) return 0; From c739aa900303fddd86c62bc951f26ef18178a0a8 Mon Sep 17 00:00:00 2001 From: Alex Voinea <voinea.dragos.alexandru@gmail.com> Date: Sun, 7 Feb 2021 21:51:44 +0200 Subject: [PATCH 53/58] M23 full path support. --- Firmware/cardreader.cpp | 22 ++++++++++++++++------ Firmware/cardreader.h | 1 + 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 8273e3d0..c414e282 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -309,6 +309,18 @@ void CardReader::getAbsFilename(char *t) else t[0]=0; } + +void CardReader::printAbsFilenameFast() +{ + SERIAL_PROTOCOL('/'); + for (uint8_t i = 0; i < getWorkDirDepth(); i++) + { + SERIAL_PROTOCOL(dir_names[i]); + SERIAL_PROTOCOL('/'); + } + SERIAL_PROTOCOL(LONGEST_FILENAME); +} + /** * @brief Dive into subfolder * @@ -425,16 +437,16 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru { if (file.open(curDir, fname, O_READ)) { + getfilename(0, fname); filesize = file.fileSize(); SERIAL_PROTOCOLRPGM(_N("File opened: "));////MSG_SD_FILE_OPENED - SERIAL_PROTOCOL(fname); + printAbsFilenameFast(); SERIAL_PROTOCOLRPGM(_n(" Size: "));////MSG_SD_SIZE SERIAL_PROTOCOLLN(filesize); sdpos = 0; SERIAL_PROTOCOLLNRPGM(MSG_FILE_SELECTED); lcd_setstatuspgm(MSG_FILE_SELECTED); - getfilename(0, fname); } else { @@ -508,10 +520,8 @@ void CardReader::getStatus(bool arg_P) { if (arg_P) { - SERIAL_PROTOCOL('/'); - for (uint8_t i = 0; i < getWorkDirDepth(); i++) - printf_P(PSTR("%s/"), dir_names[i]); - puts(filename); + printAbsFilenameFast(); + SERIAL_PROTOCOLLN(); } else SERIAL_PROTOCOLLN(LONGEST_FILENAME); diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 819e8bf2..0e94bd3c 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -34,6 +34,7 @@ public: uint16_t getnrfilenames(); void getAbsFilename(char *t); + void printAbsFilenameFast(); void getDirName(char* name, uint8_t level); uint16_t getWorkDirDepth(); From fb39e7296b126c67a34937576389429d0ffc9de2 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Mon, 8 Feb 2021 10:58:41 +0100 Subject: [PATCH 54/58] Uniform message `Press the knob` --- Firmware/Marlin_main.cpp | 2 +- lang/lang_en.txt | 2 +- lang/lang_en_cz.txt | 2 +- lang/lang_en_de.txt | 2 +- lang/lang_en_es.txt | 2 +- lang/lang_en_fr.txt | 2 +- lang/lang_en_it.txt | 2 +- lang/lang_en_pl.txt | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 6db1d277..bc90849e 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -11786,7 +11786,7 @@ void M600_wait_for_user(float HotendTempBckp) { delay_keep_alive(4); if (_millis() > waiting_start_time + (unsigned long)M600_TIMEOUT * 1000) { - lcd_display_message_fullscreen_P(_i("Press knob to preheat nozzle and continue."));////MSG_PRESS_TO_PREHEAT c=20 r=4 + lcd_display_message_fullscreen_P(_i("Press the knob to preheat nozzle and continue."));////MSG_PRESS_TO_PREHEAT c=20 r=4 wait_for_user_state = 1; setAllTargetHotends(0); st_synchronize(); diff --git a/lang/lang_en.txt b/lang/lang_en.txt index bcb0a444..41879c5a 100644 --- a/lang/lang_en.txt +++ b/lang/lang_en.txt @@ -620,7 +620,7 @@ "Please upgrade." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." #MSG_FS_PAUSE c=5 "Pause" diff --git a/lang/lang_en_cz.txt b/lang/lang_en_cz.txt index 0b3d7b14..4c7efc5e 100644 --- a/lang/lang_en_cz.txt +++ b/lang/lang_en_cz.txt @@ -827,7 +827,7 @@ "Prosim aktualizujte." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Pro nahrati trysky a pokracovani stisknete tlacitko." #MSG_FS_PAUSE c=5 diff --git a/lang/lang_en_de.txt b/lang/lang_en_de.txt index 0a436a9e..f3869931 100644 --- a/lang/lang_en_de.txt +++ b/lang/lang_en_de.txt @@ -827,7 +827,7 @@ "Bitte aktualisieren." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Bitte druecken Sie den Knopf um die Duese vorzuheizen und fortzufahren." #MSG_FS_PAUSE c=5 diff --git a/lang/lang_en_es.txt b/lang/lang_en_es.txt index 2e29fa20..f8b39e17 100644 --- a/lang/lang_en_es.txt +++ b/lang/lang_en_es.txt @@ -827,7 +827,7 @@ "Actualize por favor" #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Pulsa el dial para precalentar la boquilla y continue." #MSG_FS_PAUSE c=5 diff --git a/lang/lang_en_fr.txt b/lang/lang_en_fr.txt index cc0cbb95..f64f800d 100644 --- a/lang/lang_en_fr.txt +++ b/lang/lang_en_fr.txt @@ -827,7 +827,7 @@ "Mettez a jour le FW." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Appuyez sur le bouton pour prechauffer la buse et continuer." #MSG_FS_PAUSE c=5 diff --git a/lang/lang_en_it.txt b/lang/lang_en_it.txt index 8cd93908..e3383336 100644 --- a/lang/lang_en_it.txt +++ b/lang/lang_en_it.txt @@ -827,7 +827,7 @@ "Prego aggiornare." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Premete la manopola per preriscaldare l'ugello e continuare." #MSG_FS_PAUSE c=5 diff --git a/lang/lang_en_pl.txt b/lang/lang_en_pl.txt index 38d1421f..b796c11a 100644 --- a/lang/lang_en_pl.txt +++ b/lang/lang_en_pl.txt @@ -827,7 +827,7 @@ "Prosze zaktualizowac." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Wcisnij pokretlo aby rozgrzac dysze i kontynuowac." #MSG_FS_PAUSE c=5 From 214695105c181796bc5c958aee9fafb65c53ff3f Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Mon, 8 Feb 2021 11:33:46 +0100 Subject: [PATCH 55/58] Fix issue #2958 --- Firmware/ultralcd.cpp | 8 ++++---- lang/lang_en.txt | 6 +++--- lang/lang_en_cz.txt | 6 +++--- lang/lang_en_de.txt | 6 +++--- lang/lang_en_es.txt | 6 +++--- lang/lang_en_fr.txt | 6 +++--- lang/lang_en_it.txt | 6 +++--- lang/lang_en_pl.txt | 6 +++--- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0f6bc1fa..0e654384 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2235,18 +2235,18 @@ uint8_t nLevel; lcd_set_cursor(0,0); lcdui_print_temp(LCD_STR_THERMOMETER[0],(int)degHotend(0),(int)degTargetHotend(0)); -lcd_puts_at_P(0,2, _i("Press the knob")); ////MSG_ c=20 r=1 -lcd_set_cursor(0,3); +lcd_puts_at_P(0,1, _i("Press the knob")); ////MSG_ c=20 +lcd_set_cursor(0,2); switch(eFilamentAction) { case FilamentAction::Load: case FilamentAction::AutoLoad: case FilamentAction::MmuLoad: - lcd_puts_P(_i("to load filament")); ////MSG_ c=20 r=1 + lcd_puts_P(_i("to load filament")); ////MSG_ c=20 r=2 break; case FilamentAction::UnLoad: case FilamentAction::MmuUnLoad: - lcd_puts_P(_i("to unload filament")); ////MSG_ c=20 r=1 + lcd_puts_P(_i("to unload filament")); ////MSG_ c=20 r=2 break; case FilamentAction::MmuEject: case FilamentAction::MmuCut: diff --git a/lang/lang_en.txt b/lang/lang_en.txt index 41879c5a..875aa370 100644 --- a/lang/lang_en.txt +++ b/lang/lang_en.txt @@ -644,7 +644,7 @@ "Print from SD" # -"Press the knob" +"Press the knob" c=20 r=2 #MSG_PRINT_PAUSED c=20 r=1 "Print paused" @@ -875,10 +875,10 @@ "Total failures" # -"to load filament" +"to load filament" c=20 r=2 # -"to unload filament" +"to unload filament" c=20 r=2 #MSG_UNLOAD_FILAMENT c=17 "Unload filament" diff --git a/lang/lang_en_cz.txt b/lang/lang_en_cz.txt index 4c7efc5e..3c8f0f06 100644 --- a/lang/lang_en_cz.txt +++ b/lang/lang_en_cz.txt @@ -859,7 +859,7 @@ "Tisk z SD" # -"Press the knob" +"Press the knob" c=20 r=2 "Stisknete hl. tlacitko" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Celkem selhani" # -"to load filament" +"to load filament" c=20 r=2 "k zavedeni filamentu" # -"to unload filament" +"to unload filament" c=20 r=2 "k vyjmuti filamentu" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_de.txt b/lang/lang_en_de.txt index f3869931..649994d9 100644 --- a/lang/lang_en_de.txt +++ b/lang/lang_en_de.txt @@ -859,7 +859,7 @@ "Drucken von SD" # -"Press the knob" +"Press the knob" c=20 r=2 "Knopf druecken zum" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Gesamte Fehler" # -"to load filament" +"to load filament" c=20 r=2 "Filament laden" # -"to unload filament" +"to unload filament" c=20 r=2 "Filament entladen" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_es.txt b/lang/lang_en_es.txt index f8b39e17..35913020 100644 --- a/lang/lang_en_es.txt +++ b/lang/lang_en_es.txt @@ -859,7 +859,7 @@ "Menu tarjeta SD" # -"Press the knob" +"Press the knob" c=20 r=2 "Pulsa el dial" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Fallos totales" # -"to load filament" +"to load filament" c=20 r=2 "para cargar el filamento" # -"to unload filament" +"to unload filament" c=20 r=2 "para descargar el filamento" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_fr.txt b/lang/lang_en_fr.txt index f64f800d..54dc7a7c 100644 --- a/lang/lang_en_fr.txt +++ b/lang/lang_en_fr.txt @@ -859,7 +859,7 @@ "Impr. depuis la SD" # -"Press the knob" +"Press the knob" c=20 r=2 "App. sur sur bouton" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Total des echecs" # -"to load filament" +"to load filament" c=20 r=2 "pour charger le fil." # -"to unload filament" +"to unload filament" c=20 r=2 "pour decharger fil." #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_it.txt b/lang/lang_en_it.txt index e3383336..d5846cba 100644 --- a/lang/lang_en_it.txt +++ b/lang/lang_en_it.txt @@ -859,7 +859,7 @@ "Stampa da SD" # -"Press the knob" +"Press the knob" c=20 r=2 "Premere la manopola" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Totale fallimenti" # -"to load filament" +"to load filament" c=20 r=2 "per caricare il filamento" # -"to unload filament" +"to unload filament" c=20 r=2 "per scaricare il filamento" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_pl.txt b/lang/lang_en_pl.txt index b796c11a..eb4103ee 100644 --- a/lang/lang_en_pl.txt +++ b/lang/lang_en_pl.txt @@ -859,7 +859,7 @@ "Druk z karty SD" # -"Press the knob" +"Press the knob" c=20 r=2 "Wcisnij pokretlo" #MSG_PRINT_PAUSED c=20 r=1 @@ -1167,11 +1167,11 @@ "Suma bledow" # -"to load filament" +"to load filament" c=20 r=2 "aby zaladow. fil." # -"to unload filament" +"to unload filament" c=20 r=2 "aby rozlad. filament" #MSG_UNLOAD_FILAMENT c=17 From aecbd7ab49ec5fb0f7ca84b6bd40fd3f6823145f Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Mon, 8 Feb 2021 12:17:41 +0100 Subject: [PATCH 56/58] Fix `c=aa` location in lang files Fix too long translations in Spanish and Italian --- Firmware/ultralcd.cpp | 4 ++-- lang/lang_en.txt | 12 ++++++------ lang/lang_en_cz.txt | 12 ++++++------ lang/lang_en_de.txt | 12 ++++++------ lang/lang_en_es.txt | 16 ++++++++-------- lang/lang_en_fr.txt | 12 ++++++------ lang/lang_en_it.txt | 16 ++++++++-------- lang/lang_en_pl.txt | 12 ++++++------ 8 files changed, 48 insertions(+), 48 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0e654384..10fa2da3 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2242,11 +2242,11 @@ switch(eFilamentAction) case FilamentAction::Load: case FilamentAction::AutoLoad: case FilamentAction::MmuLoad: - lcd_puts_P(_i("to load filament")); ////MSG_ c=20 r=2 + lcd_puts_P(_i("to load filament")); ////MSG_ c=20 break; case FilamentAction::UnLoad: case FilamentAction::MmuUnLoad: - lcd_puts_P(_i("to unload filament")); ////MSG_ c=20 r=2 + lcd_puts_P(_i("to unload filament")); ////MSG_ c=20 break; case FilamentAction::MmuEject: case FilamentAction::MmuCut: diff --git a/lang/lang_en.txt b/lang/lang_en.txt index 875aa370..8c0e6eb9 100644 --- a/lang/lang_en.txt +++ b/lang/lang_en.txt @@ -643,8 +643,8 @@ #MSG_CARD_MENU "Print from SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" #MSG_PRINT_PAUSED c=20 r=1 "Print paused" @@ -874,11 +874,11 @@ #MSG_TOTAL_FAILURES c=20 "Total failures" -# -"to load filament" c=20 r=2 +# c=20 +"to load filament" -# -"to unload filament" c=20 r=2 +# c=20 +"to unload filament" #MSG_UNLOAD_FILAMENT c=17 "Unload filament" diff --git a/lang/lang_en_cz.txt b/lang/lang_en_cz.txt index 3c8f0f06..2c0bc664 100644 --- a/lang/lang_en_cz.txt +++ b/lang/lang_en_cz.txt @@ -858,8 +858,8 @@ "Print from SD" "Tisk z SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "Stisknete hl. tlacitko" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,12 +1166,12 @@ "Total failures" "Celkem selhani" -# -"to load filament" c=20 r=2 +# c=20 +"to load filament" "k zavedeni filamentu" -# -"to unload filament" c=20 r=2 +# c=20 +"to unload filament" "k vyjmuti filamentu" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_de.txt b/lang/lang_en_de.txt index 649994d9..e6fd5bcc 100644 --- a/lang/lang_en_de.txt +++ b/lang/lang_en_de.txt @@ -858,8 +858,8 @@ "Print from SD" "Drucken von SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "Knopf druecken zum" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,12 +1166,12 @@ "Total failures" "Gesamte Fehler" -# -"to load filament" c=20 r=2 +# c=20 +"to load filament" "Filament laden" -# -"to unload filament" c=20 r=2 +# c=20 +"to unload filament" "Filament entladen" #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_es.txt b/lang/lang_en_es.txt index 35913020..4e622ebb 100644 --- a/lang/lang_en_es.txt +++ b/lang/lang_en_es.txt @@ -858,8 +858,8 @@ "Print from SD" "Menu tarjeta SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "Pulsa el dial" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,13 +1166,13 @@ "Total failures" "Fallos totales" -# -"to load filament" c=20 r=2 -"para cargar el filamento" +# c=20 +"to load filament" +"para cargar el fil." -# -"to unload filament" c=20 r=2 -"para descargar el filamento" +# c=20 +"to unload filament" +"para descargar fil." #MSG_UNLOAD_FILAMENT c=17 "Unload filament" diff --git a/lang/lang_en_fr.txt b/lang/lang_en_fr.txt index 54dc7a7c..edf2bb8b 100644 --- a/lang/lang_en_fr.txt +++ b/lang/lang_en_fr.txt @@ -858,8 +858,8 @@ "Print from SD" "Impr. depuis la SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "App. sur sur bouton" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,12 +1166,12 @@ "Total failures" "Total des echecs" -# -"to load filament" c=20 r=2 +# c=20 +"to load filament" "pour charger le fil." -# -"to unload filament" c=20 r=2 +# c=20 +"to unload filament" "pour decharger fil." #MSG_UNLOAD_FILAMENT c=17 diff --git a/lang/lang_en_it.txt b/lang/lang_en_it.txt index d5846cba..043d1141 100644 --- a/lang/lang_en_it.txt +++ b/lang/lang_en_it.txt @@ -858,8 +858,8 @@ "Print from SD" "Stampa da SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "Premere la manopola" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,13 +1166,13 @@ "Total failures" "Totale fallimenti" -# -"to load filament" c=20 r=2 -"per caricare il filamento" +# c=20 +"to load filament" +"per caricare il fil." -# -"to unload filament" c=20 r=2 -"per scaricare il filamento" +# c=20 +"to unload filament" +"per scaricare fil." #MSG_UNLOAD_FILAMENT c=17 "Unload filament" diff --git a/lang/lang_en_pl.txt b/lang/lang_en_pl.txt index eb4103ee..4e6be18e 100644 --- a/lang/lang_en_pl.txt +++ b/lang/lang_en_pl.txt @@ -858,8 +858,8 @@ "Print from SD" "Druk z karty SD" -# -"Press the knob" c=20 r=2 +# c=20 +"Press the knob" "Wcisnij pokretlo" #MSG_PRINT_PAUSED c=20 r=1 @@ -1166,12 +1166,12 @@ "Total failures" "Suma bledow" -# -"to load filament" c=20 r=2 +# c=20 +"to load filament" "aby zaladow. fil." -# -"to unload filament" c=20 r=2 +# c=20 +"to unload filament" "aby rozlad. filament" #MSG_UNLOAD_FILAMENT c=17 From 5f49d65546a08d633ea452816718983f0a5a6acc Mon Sep 17 00:00:00 2001 From: "D.R.racer" <drracer@drracer.eu> Date: Mon, 8 Feb 2021 09:49:11 +0100 Subject: [PATCH 57/58] Farmers' request - allow file sorting menu item --- Firmware/ultralcd.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0f6bc1fa..d3686509 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -5291,16 +5291,13 @@ do\ else\ MENU_ITEM_TOGGLE_P(_T(MSG_SD_CARD), _T(MSG_NORMAL), lcd_toshiba_flash_air_compatibility_toggle);\ \ - if (!farm_mode)\ + uint8_t sdSort;\ + EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));\ + switch (sdSort)\ {\ - uint8_t sdSort;\ - EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));\ - switch (sdSort)\ - {\ - case SD_SORT_TIME: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_TIME), lcd_sort_type_set); break;\ - case SD_SORT_ALPHA: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_ALPHA), lcd_sort_type_set); break;\ - default: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_NONE), lcd_sort_type_set);\ - }\ + case SD_SORT_TIME: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_TIME), lcd_sort_type_set); break;\ + case SD_SORT_ALPHA: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_ALPHA), lcd_sort_type_set); break;\ + default: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_NONE), lcd_sort_type_set);\ }\ }\ while (0) From 4fcbf95db65e33d4fa7ee561a510c8f79f2bdfd1 Mon Sep 17 00:00:00 2001 From: Alex Voinea <voinea.dragos.alexandru@gmail.com> Date: Tue, 9 Feb 2021 15:00:46 +0200 Subject: [PATCH 58/58] apply RAII principle on the lsDive recursion limiter --- Firmware/cardreader.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index c414e282..3ca88f63 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -71,14 +71,22 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { static uint8_t recursionCnt = 0; + // RAII incrementer for the recursionCnt + class _incrementer + { + public: + _incrementer() {recursionCnt++;} + ~_incrementer() {recursionCnt--;} + } recursionCntIncrementer; + dir_t p; uint8_t cnt = 0; // Read the next entry from a directory while (parent.readDir(p, longFilename) > 0) { - if (recursionCnt >= MAX_DIR_DEPTH) + 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 - recursionCnt++; + // Get the short name for the item, which we know is a folder char lfilename[FILENAME_LENGTH]; createFilename(lfilename, p); @@ -112,7 +120,6 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m if (lsAction == LS_SerialPrint_LFN) puts_P(PSTR("DIR_EXIT")); - recursionCnt--; } else { uint8_t pn0 = p.name[0];