2020-10-09 06:25:23 -05:00
|
|
|
/**
|
|
|
|
* Marlin 3D Printer Firmware
|
|
|
|
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
|
|
*
|
|
|
|
* Based on Sprinter and grbl.
|
|
|
|
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include "../inc/MarlinConfigPre.h"
|
|
|
|
|
|
|
|
#if ENABLED(MARLIN_DEV_MODE)
|
|
|
|
|
|
|
|
#include "gcode.h"
|
|
|
|
#include "../module/settings.h"
|
2020-10-12 16:39:31 -05:00
|
|
|
#include "../module/temperature.h"
|
2020-10-09 06:25:23 -05:00
|
|
|
#include "../libs/hex_print.h"
|
|
|
|
#include "../HAL/shared/eeprom_if.h"
|
2020-10-12 16:39:31 -05:00
|
|
|
#include "../HAL/shared/Delay.h"
|
2020-10-09 06:25:23 -05:00
|
|
|
|
2021-02-05 22:43:51 -06:00
|
|
|
extern void dump_delay_accuracy_check();
|
|
|
|
|
2020-10-09 06:25:23 -05:00
|
|
|
/**
|
|
|
|
* Dn: G-code for development and testing
|
|
|
|
*
|
|
|
|
* See https://reprap.org/wiki/G-code#D:_Debug_codes
|
|
|
|
*
|
|
|
|
* Put whatever else you need here to test ongoing development.
|
|
|
|
*/
|
|
|
|
void GcodeSuite::D(const int16_t dcode) {
|
|
|
|
switch (dcode) {
|
|
|
|
|
|
|
|
case -1:
|
|
|
|
for (;;); // forever
|
|
|
|
|
|
|
|
case 0:
|
|
|
|
HAL_reboot();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: {
|
|
|
|
// Zero or pattern-fill the EEPROM data
|
|
|
|
#if ENABLED(EEPROM_SETTINGS)
|
|
|
|
persistentStore.access_start();
|
|
|
|
size_t total = persistentStore.capacity();
|
|
|
|
int pos = 0;
|
|
|
|
const uint8_t value = 0x0;
|
2020-10-29 17:33:59 -05:00
|
|
|
while (total--) persistentStore.write_data(pos, &value, 1);
|
2020-10-09 06:25:23 -05:00
|
|
|
persistentStore.access_finish();
|
|
|
|
#else
|
|
|
|
settings.reset();
|
|
|
|
settings.save();
|
|
|
|
#endif
|
|
|
|
HAL_reboot();
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 2: { // D2 Read / Write SRAM
|
|
|
|
#define SRAM_SIZE 8192
|
|
|
|
uint8_t *pointer = parser.hex_adr_val('A');
|
|
|
|
uint16_t len = parser.ushortval('C', 1);
|
|
|
|
uintptr_t addr = (uintptr_t)pointer;
|
2020-10-29 17:33:59 -05:00
|
|
|
NOMORE(addr, size_t(SRAM_SIZE - 1));
|
2020-10-09 06:25:23 -05:00
|
|
|
NOMORE(len, SRAM_SIZE - addr);
|
|
|
|
if (parser.seenval('X')) {
|
|
|
|
// Write the hex bytes after the X
|
|
|
|
uint16_t val = parser.hex_val('X');
|
|
|
|
while (len--) {
|
|
|
|
*pointer = val;
|
|
|
|
pointer++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
while (len--) print_hex_byte(*(pointer++));
|
|
|
|
SERIAL_EOL();
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
2020-10-12 16:39:31 -05:00
|
|
|
#if ENABLED(EEPROM_SETTINGS)
|
|
|
|
case 3: { // D3 Read / Write EEPROM
|
|
|
|
uint8_t *pointer = parser.hex_adr_val('A');
|
|
|
|
uint16_t len = parser.ushortval('C', 1);
|
|
|
|
uintptr_t addr = (uintptr_t)pointer;
|
2020-10-29 17:33:59 -05:00
|
|
|
NOMORE(addr, size_t(persistentStore.capacity() - 1));
|
|
|
|
NOMORE(len, persistentStore.capacity() - addr);
|
2020-10-12 16:39:31 -05:00
|
|
|
if (parser.seenval('X')) {
|
|
|
|
uint16_t val = parser.hex_val('X');
|
2020-10-09 06:25:23 -05:00
|
|
|
#if ENABLED(EEPROM_SETTINGS)
|
|
|
|
persistentStore.access_start();
|
2020-10-29 17:33:59 -05:00
|
|
|
while (len--) {
|
2020-10-09 06:25:23 -05:00
|
|
|
int pos = 0;
|
2020-10-12 16:39:31 -05:00
|
|
|
persistentStore.write_data(pos, (uint8_t *)&val, sizeof(val));
|
2020-10-09 06:25:23 -05:00
|
|
|
}
|
|
|
|
SERIAL_EOL();
|
|
|
|
persistentStore.access_finish();
|
|
|
|
#else
|
2020-10-19 20:38:24 -05:00
|
|
|
SERIAL_ECHOLNPGM("NO EEPROM");
|
2020-10-09 06:25:23 -05:00
|
|
|
#endif
|
|
|
|
}
|
2020-10-12 16:39:31 -05:00
|
|
|
else {
|
2020-10-29 17:33:59 -05:00
|
|
|
// Read bytes from EEPROM
|
|
|
|
#if ENABLED(EEPROM_SETTINGS)
|
|
|
|
persistentStore.access_start();
|
|
|
|
int pos = 0;
|
|
|
|
uint8_t val;
|
|
|
|
while (len--) if (!persistentStore.read_data(pos, &val, 1)) print_hex_byte(val);
|
|
|
|
SERIAL_EOL();
|
|
|
|
persistentStore.access_finish();
|
|
|
|
#else
|
|
|
|
SERIAL_ECHOLNPGM("NO EEPROM");
|
|
|
|
len = 0;
|
|
|
|
#endif
|
2020-10-12 16:39:31 -05:00
|
|
|
SERIAL_EOL();
|
|
|
|
}
|
|
|
|
} break;
|
2020-10-19 20:38:24 -05:00
|
|
|
#endif
|
2020-10-09 06:25:23 -05:00
|
|
|
|
|
|
|
case 4: { // D4 Read / Write PIN
|
|
|
|
// const uint8_t pin = parser.byteval('P');
|
|
|
|
// const bool is_out = parser.boolval('F'),
|
|
|
|
// val = parser.byteval('V', LOW);
|
|
|
|
if (parser.seenval('X')) {
|
|
|
|
// TODO: Write the hex bytes after the X
|
|
|
|
//while (len--) {
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// while (len--) {
|
|
|
|
// TODO: Read bytes from EEPROM
|
|
|
|
// print_hex_byte(eeprom_read_byte(*(adr++));
|
|
|
|
// }
|
|
|
|
SERIAL_EOL();
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
2021-02-05 22:43:51 -06:00
|
|
|
case 5: { // D5 Read / Write onboard Flash
|
2020-10-09 06:25:23 -05:00
|
|
|
#define FLASH_SIZE 1024
|
|
|
|
uint8_t *pointer = parser.hex_adr_val('A');
|
|
|
|
uint16_t len = parser.ushortval('C', 1);
|
|
|
|
uintptr_t addr = (uintptr_t)pointer;
|
2020-10-29 17:33:59 -05:00
|
|
|
NOMORE(addr, size_t(FLASH_SIZE - 1));
|
2020-10-09 06:25:23 -05:00
|
|
|
NOMORE(len, FLASH_SIZE - addr);
|
|
|
|
if (parser.seenval('X')) {
|
|
|
|
// TODO: Write the hex bytes after the X
|
|
|
|
//while (len--) {
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// while (len--) {
|
|
|
|
// TODO: Read bytes from EEPROM
|
|
|
|
// print_hex_byte(eeprom_read_byte(adr++));
|
|
|
|
// }
|
|
|
|
SERIAL_EOL();
|
|
|
|
}
|
|
|
|
} break;
|
2020-10-12 16:39:31 -05:00
|
|
|
|
2021-02-05 22:43:51 -06:00
|
|
|
case 6: // D6 Check delay loop accuracy
|
|
|
|
dump_delay_accuracy_check();
|
|
|
|
break;
|
|
|
|
|
2020-10-12 16:39:31 -05:00
|
|
|
case 100: { // D100 Disable heaters and attempt a hard hang (Watchdog Test)
|
2020-10-19 20:38:24 -05:00
|
|
|
SERIAL_ECHOLNPGM("Disabling heaters and attempting to trigger Watchdog");
|
|
|
|
SERIAL_ECHOLNPGM("(USE_WATCHDOG " TERN(USE_WATCHDOG, "ENABLED", "DISABLED") ")");
|
2020-10-12 16:39:31 -05:00
|
|
|
thermalManager.disable_all_heaters();
|
|
|
|
delay(1000); // Allow time to print
|
|
|
|
DISABLE_ISRS();
|
|
|
|
// Use a low-level delay that does not rely on interrupts to function
|
|
|
|
// Do not spin forever, to avoid thermal risks if heaters are enabled and
|
|
|
|
// watchdog does not work.
|
2020-10-23 19:25:22 -05:00
|
|
|
for (int i = 10000; i--;) DELAY_US(1000UL);
|
2020-10-12 16:39:31 -05:00
|
|
|
ENABLE_ISRS();
|
2020-10-19 20:38:24 -05:00
|
|
|
SERIAL_ECHOLNPGM("FAILURE: Watchdog did not trigger board reset.");
|
2020-10-12 16:39:31 -05:00
|
|
|
}
|
2020-10-09 06:25:23 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|