Implement HAL and apply macros across code-base

Implement AVR Platform
2.0.x
Christopher Pepper 8 years ago committed by Scott Lahteine
parent fb04dfcda8
commit 4b16fa3272

6
.gitignore vendored

@ -118,7 +118,11 @@ tags
# PlatformIO files/dirs # PlatformIO files/dirs
.pio* .pio*
lib/readme.txt .pioenvs
.piolibdeps
.clang_complete
.gcc-flags.json
lib/
#Visual Studio #Visual Studio
*.sln *.sln

@ -203,6 +203,22 @@
#define DEFAULT_KEEPALIVE_INTERVAL 2 #define DEFAULT_KEEPALIVE_INTERVAL 2
#endif #endif
#ifdef CPU_32_BIT
/**
* Hidden options for developer
*/
// Double stepping start from STEP_DOUBLER_FREQUENCY + 1, quad stepping start from STEP_DOUBLER_FREQUENCY * 2 + 1
#ifndef STEP_DOUBLER_FREQUENCY
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
#define STEP_DOUBLER_FREQUENCY 60000 // Hz
#else
#define STEP_DOUBLER_FREQUENCY 80000 // Hz
#endif
#endif
// Disable double / quad stepping
//#define DISABLE_MULTI_STEPPING
#endif
/** /**
* Provide a MAX_AUTORETRACT for older configs * Provide a MAX_AUTORETRACT for older configs
*/ */
@ -214,17 +230,34 @@
* MAX_STEP_FREQUENCY differs for TOSHIBA * MAX_STEP_FREQUENCY differs for TOSHIBA
*/ */
#if ENABLED(CONFIG_STEPPERS_TOSHIBA) #if ENABLED(CONFIG_STEPPERS_TOSHIBA)
#ifdef CPU_32_BIT
#define MAX_STEP_FREQUENCY STEP_DOUBLER_FREQUENCY // Max step frequency for Toshiba Stepper Controllers, 96kHz is close to maximum for an Arduino Due
#else
#define MAX_STEP_FREQUENCY 10000 // Max step frequency for Toshiba Stepper Controllers #define MAX_STEP_FREQUENCY 10000 // Max step frequency for Toshiba Stepper Controllers
#endif
#else
#ifdef CPU_32_BIT
#define MAX_STEP_FREQUENCY (STEP_DOUBLER_FREQUENCY * 4) // Max step frequency for the Due is approx. 330kHz
#else #else
#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step) #define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step)
#endif #endif
#endif
// MS1 MS2 Stepper Driver Microstepping mode table // MS1 MS2 Stepper Driver Microstepping mode table
#define MICROSTEP1 LOW,LOW #define MICROSTEP1 LOW,LOW
#define MICROSTEP2 HIGH,LOW #define MICROSTEP2 HIGH,LOW
#define MICROSTEP4 LOW,HIGH #define MICROSTEP4 LOW,HIGH
#define MICROSTEP8 HIGH,HIGH #define MICROSTEP8 HIGH,HIGH
#ifdef __SAM3X8E__
#if MB(ALLIGATOR)
#define MICROSTEP16 LOW,LOW
#define MICROSTEP32 HIGH,HIGH
#else
#define MICROSTEP16 HIGH,HIGH
#endif
#else
#define MICROSTEP16 HIGH,HIGH #define MICROSTEP16 HIGH,HIGH
#endif
/** /**
* Advance calculated values * Advance calculated values
@ -350,6 +383,10 @@
#define BED_USES_THERMISTOR #define BED_USES_THERMISTOR
#endif #endif
#ifdef __SAM3X8E__
#define HEATER_USES_AD595 (ENABLED(HEATER_0_USES_AD595) || ENABLED(HEATER_1_USES_AD595) || ENABLED(HEATER_2_USES_AD595) || ENABLED(HEATER_3_USES_AD595))
#endif
/** /**
* Flags for PID handling * Flags for PID handling
*/ */
@ -873,6 +910,18 @@
// Stepper pulse duration, in cycles // Stepper pulse duration, in cycles
#define STEP_PULSE_CYCLES ((MINIMUM_STEPPER_PULSE) * CYCLES_PER_MICROSECOND) #define STEP_PULSE_CYCLES ((MINIMUM_STEPPER_PULSE) * CYCLES_PER_MICROSECOND)
#ifdef CPU_32_BIT
// Add additional delay for between direction signal and pulse signal of stepper
#ifndef STEPPER_DIRECTION_DELAY
#define STEPPER_DIRECTION_DELAY 0 // time in microseconds
#endif
#endif
#ifndef __SAM3X8E__ //todo: hal: broken hal encapsulation
#undef UI_VOLTAGE_LEVEL
#undef RADDS_DISPLAY
#undef MOTOR_CURRENT
#endif
#if ENABLED(SDCARD_SORT_ALPHA) #if ENABLED(SDCARD_SORT_ALPHA)
#define HAS_FOLDER_SORTING (FOLDER_SORTING || ENABLED(SDSORT_GCODE)) #define HAS_FOLDER_SORTING (FOLDER_SORTING || ENABLED(SDSORT_GCODE))
@ -928,4 +977,32 @@
#endif #endif
#endif #endif
// Use float instead of double. Needs profiling.
#if defined(ARDUINO_ARCH_SAM) && ENABLED(DELTA_FAST_SQRT)
#undef ATAN2
#undef FABS
#undef POW
#undef SQRT
#undef CEIL
#undef FLOOR
#undef LROUND
#undef FMOD
#define ATAN2(y, x) atan2f(y, x)
#define FABS(x) fabsf(x)
#define POW(x, y) powf(x, y)
#define SQRT(x) sqrtf(x)
#define CEIL(x) ceilf(x)
#define FLOOR(x) floorf(x)
#define LROUND(x) lroundf(x)
#define FMOD(x, y) fmodf(x, y)
#endif
#ifdef TEENSYDUINO
#undef max
#define max(a,b) ((a)>(b)?(a):(b))
#undef min
#define min(a,b) ((a)<(b)?(a):(b))
#define NOT_A_PIN 0 // For PINS_DEBUGGING
#endif
#endif // CONDITIONALS_POST_H #endif // CONDITIONALS_POST_H

@ -28,20 +28,15 @@
#include <string.h> #include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include "MarlinConfig.h" #include "MarlinConfig.h"
#ifdef DEBUG_GCODE_PARSER #ifdef DEBUG_GCODE_PARSER
#include "gcode.h" #include "gcode.h"
#endif #endif
#include "src/HAL/HAL.h"
#include "enum.h" #include "enum.h"
#include "types.h" #include "types.h"
#include "fastio.h"
#include "utility.h" #include "utility.h"
#include "serial.h" #include "serial.h"

@ -23,18 +23,17 @@
#ifndef MARLIN_CONFIG_H #ifndef MARLIN_CONFIG_H
#define MARLIN_CONFIG_H #define MARLIN_CONFIG_H
#include "fastio.h"
#include "macros.h" #include "macros.h"
#include "src/HAL/HAL.h"
#include "boards.h" #include "boards.h"
#include "Version.h" #include "Version.h"
#include "Configuration.h" #include "Configuration.h"
#include "Conditionals_LCD.h" #include "Conditionals_LCD.h"
#include "Configuration_adv.h" #include "Configuration_adv.h"
#include "pins.h" #include "pins.h"
#ifndef USBCON #if defined(ARDUINO_ARCH_AVR) && !defined(USBCON)
#define HardwareSerial_h // trick to disable the standard HWserial #define HardwareSerial_h // trick to disable the standard HWserial
#endif #endif
#include "Arduino.h"
#include "Conditionals_post.h" #include "Conditionals_post.h"
#include "SanityCheck.h" #include "SanityCheck.h"

@ -251,7 +251,9 @@
#include "cardreader.h" #include "cardreader.h"
#include "configuration_store.h" #include "configuration_store.h"
#include "language.h" #include "language.h"
#include "pins_arduino.h" #ifdef ARDUINO
#include "pins_arduino.h"
#endif
#include "math.h" #include "math.h"
#include "nozzle.h" #include "nozzle.h"
#include "duration_t.h" #include "duration_t.h"
@ -275,10 +277,6 @@
#include "buzzer.h" #include "buzzer.h"
#endif #endif
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
#endif
#if ENABLED(MAX7219_DEBUG) #if ENABLED(MAX7219_DEBUG)
#include "Max7219_Debug_LEDs.h" #include "Max7219_Debug_LEDs.h"
#endif #endif
@ -297,7 +295,7 @@
#endif #endif
#if HAS_SERVOS #if HAS_SERVOS
#include "servo.h" #include "src/HAL/servo.h"
#endif #endif
#if HAS_DIGIPOTSS #if HAS_DIGIPOTSS
@ -317,7 +315,7 @@
#endif #endif
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
#include "endstop_interrupts.h" #include "src/HAL/HAL_endstop_interrupts.h"
#endif #endif
#if ENABLED(M100_FREE_MEMORY_WATCHER) #if ENABLED(M100_FREE_MEMORY_WATCHER)
@ -653,7 +651,7 @@ float cartes[XYZ] = { 0 };
static bool send_ok[BUFSIZE]; static bool send_ok[BUFSIZE];
#if HAS_SERVOS #if HAS_SERVOS
Servo servo[NUM_SERVOS]; HAL_SERVO_LIB servo[NUM_SERVOS];
#define MOVE_SERVO(I, P) servo[I].move(P) #define MOVE_SERVO(I, P) servo[I].move(P)
#if HAS_Z_SERVO_ENDSTOP #if HAS_Z_SERVO_ENDSTOP
#define DEPLOY_Z_SERVO() MOVE_SERVO(Z_ENDSTOP_SERVO_NR, z_servo_angle[0]) #define DEPLOY_Z_SERVO() MOVE_SERVO(Z_ENDSTOP_SERVO_NR, z_servo_angle[0])
@ -789,26 +787,6 @@ inline void sync_plan_position_e() { planner.set_e_position_mm(current_position[
#endif #endif
#if ENABLED(SDSUPPORT)
#include "SdFatUtil.h"
int freeMemory() { return SdFatUtil::FreeRam(); }
#else
extern "C" {
extern char __bss_end;
extern char __heap_start;
extern void* __brkval;
int freeMemory() {
int free_memory;
if ((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
}
}
#endif // !SDSUPPORT
#if ENABLED(DIGIPOT_I2C) #if ENABLED(DIGIPOT_I2C)
extern void digipot_i2c_set_current(uint8_t channel, float current); extern void digipot_i2c_set_current(uint8_t channel, float current);
extern void digipot_i2c_init(); extern void digipot_i2c_init();
@ -11845,7 +11823,7 @@ void ok_to_send() {
delta_diagonal_rod_2_tower[C_AXIS] = sq(diagonal_rod + drt[C_AXIS]); delta_diagonal_rod_2_tower[C_AXIS] = sq(diagonal_rod + drt[C_AXIS]);
} }
#if ENABLED(DELTA_FAST_SQRT) #if ENABLED(DELTA_FAST_SQRT) && defined(ARDUINO_ARCH_AVR)
/** /**
* Fast inverse sqrt from Quake III Arena * Fast inverse sqrt from Quake III Arena
* See: https://en.wikipedia.org/wiki/Fast_inverse_square_root * See: https://en.wikipedia.org/wiki/Fast_inverse_square_root
@ -13357,17 +13335,22 @@ void setup() {
#endif #endif
MYSERIAL.begin(BAUDRATE); MYSERIAL.begin(BAUDRATE);
while(!MYSERIAL);
SERIAL_PROTOCOLLNPGM("start"); SERIAL_PROTOCOLLNPGM("start");
SERIAL_ECHO_START(); SERIAL_ECHO_START();
// Check startup - does nothing if bootloader sets MCUSR to 0 // Check startup - does nothing if bootloader sets MCUSR to 0
byte mcu = MCUSR; byte mcu = HAL_get_reset_source();
if (mcu & 1) SERIAL_ECHOLNPGM(MSG_POWERUP); if (mcu & 1) SERIAL_ECHOLNPGM(MSG_POWERUP);
if (mcu & 2) SERIAL_ECHOLNPGM(MSG_EXTERNAL_RESET); if (mcu & 2) SERIAL_ECHOLNPGM(MSG_EXTERNAL_RESET);
if (mcu & 4) SERIAL_ECHOLNPGM(MSG_BROWNOUT_RESET); if (mcu & 4) SERIAL_ECHOLNPGM(MSG_BROWNOUT_RESET);
if (mcu & 8) SERIAL_ECHOLNPGM(MSG_WATCHDOG_RESET); if (mcu & 8) SERIAL_ECHOLNPGM(MSG_WATCHDOG_RESET);
if (mcu & 32) SERIAL_ECHOLNPGM(MSG_SOFTWARE_RESET); if (mcu & 32) SERIAL_ECHOLNPGM(MSG_SOFTWARE_RESET);
MCUSR = 0; HAL_clear_reset_source();
#if ENABLED(USE_WATCHDOG) //reinit watchdog after HAL_get_reset_source call
watchdog_init();
#endif
SERIAL_ECHOPGM(MSG_MARLIN); SERIAL_ECHOPGM(MSG_MARLIN);
SERIAL_CHAR(' '); SERIAL_CHAR(' ');
@ -13406,10 +13389,6 @@ void setup() {
thermalManager.init(); // Initialize temperature loop thermalManager.init(); // Initialize temperature loop
#if ENABLED(USE_WATCHDOG)
watchdog_init();
#endif
stepper.init(); // Initialize stepper, this enables interrupts! stepper.init(); // Initialize stepper, this enables interrupts!
servo_init(); servo_init();
@ -13619,4 +13598,3 @@ void loop() {
endstops.report_state(); endstops.report_state();
idle(); idle();
} }

@ -31,136 +31,6 @@
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
#include "Sd2Card.h" #include "Sd2Card.h"
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
#endif
//------------------------------------------------------------------------------
#if DISABLED(SOFTWARE_SPI)
// functions for hardware SPI
//------------------------------------------------------------------------------
// make sure SPCR rate is in expected bits
#if (SPR0 != 0 || SPR1 != 1)
#error "unexpected SPCR bits"
#endif
/**
* Initialize hardware SPI
* Set SCK rate to F_CPU/pow(2, 1 + spiRate) for spiRate [0,6]
*/
static void spiInit(uint8_t spiRate) {
// See avr processor documentation
SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
}
//------------------------------------------------------------------------------
/** SPI receive a byte */
static uint8_t spiRec() {
SPDR = 0xFF;
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
return SPDR;
}
//------------------------------------------------------------------------------
/** SPI read data - only one call so force inline */
static inline __attribute__((always_inline))
void spiRead(uint8_t* buf, uint16_t nbyte) {
if (nbyte-- == 0) return;
SPDR = 0xFF;
for (uint16_t i = 0; i < nbyte; i++) {
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
buf[i] = SPDR;
SPDR = 0xFF;
}
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
buf[nbyte] = SPDR;
}
//------------------------------------------------------------------------------
/** SPI send a byte */
static void spiSend(uint8_t b) {
SPDR = b;
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
}
//------------------------------------------------------------------------------
/** SPI send block - only one call so force inline */
static inline __attribute__((always_inline))
void spiSendBlock(uint8_t token, const uint8_t* buf) {
SPDR = token;
for (uint16_t i = 0; i < 512; i += 2) {
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
SPDR = buf[i];
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
SPDR = buf[i + 1];
}
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
}
//------------------------------------------------------------------------------
#else // SOFTWARE_SPI
//------------------------------------------------------------------------------
/** nop to tune soft SPI timing */
#define nop asm volatile ("nop\n\t")
//------------------------------------------------------------------------------
/** Soft SPI receive byte */
static uint8_t spiRec() {
uint8_t data = 0;
// no interrupts during byte receive - about 8 us
cli();
// output pin high - like sending 0xFF
WRITE(SPI_MOSI_PIN, HIGH);
for (uint8_t i = 0; i < 8; i++) {
WRITE(SPI_SCK_PIN, HIGH);
// adjust so SCK is nice
nop;
nop;
data <<= 1;
if (READ(SPI_MISO_PIN)) data |= 1;
WRITE(SPI_SCK_PIN, LOW);
}
// enable interrupts
sei();
return data;
}
//------------------------------------------------------------------------------
/** Soft SPI read data */
static void spiRead(uint8_t* buf, uint16_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++)
buf[i] = spiRec();
}
//------------------------------------------------------------------------------
/** Soft SPI send byte */
static void spiSend(uint8_t data) {
// no interrupts during byte send - about 8 us
cli();
for (uint8_t i = 0; i < 8; i++) {
WRITE(SPI_SCK_PIN, LOW);
WRITE(SPI_MOSI_PIN, data & 0x80);
data <<= 1;
WRITE(SPI_SCK_PIN, HIGH);
}
// hold SCK high for a few ns
nop;
nop;
nop;
nop;
WRITE(SPI_SCK_PIN, LOW);
// enable interrupts
sei();
}
//------------------------------------------------------------------------------
/** Soft SPI send block */
void spiSendBlock(uint8_t token, const uint8_t* buf) {
spiSend(token);
for (uint16_t i = 0; i < 512; i++)
spiSend(buf[i]);
}
#endif // SOFTWARE_SPI
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// send command and return error code. Return zero for OK // send command and return error code. Return zero for OK
uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
@ -310,23 +180,12 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
#endif #endif
// set pin modes // set pin modes
pinMode(chipSelectPin_, OUTPUT); //todo: should use chipSelectPin ?
chipSelectHigh(); spiBegin();
SET_INPUT(SPI_MISO_PIN);
SET_OUTPUT(SPI_MOSI_PIN);
SET_OUTPUT(SPI_SCK_PIN);
#if DISABLED(SOFTWARE_SPI)
// SS must be in output mode even it is not chip select
SET_OUTPUT(SS_PIN);
// set SS high - may be chip select for another SPI device
#if SET_SPI_SS_HIGH
WRITE(SS_PIN, HIGH);
#endif // SET_SPI_SS_HIGH
// set SCK rate for initialization commands // set SCK rate for initialization commands
spiRate_ = SPI_SD_INIT_RATE; spiRate_ = SPI_SD_INIT_RATE;
spiInit(spiRate_); spiInit(spiRate_);
#endif // SOFTWARE_SPI
// must supply min of 74 clock cycles with CS high. // must supply min of 74 clock cycles with CS high.
for (uint8_t i = 0; i < 10; i++) spiSend(0xFF); for (uint8_t i = 0; i < 10; i++) spiSend(0xFF);

@ -39,18 +39,6 @@
#include "SdFatConfig.h" #include "SdFatConfig.h"
#include "SdInfo.h" #include "SdInfo.h"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// SPI speed is F_CPU/2^(1 + index), 0 <= index <= 6
/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */
uint8_t const SPI_FULL_SPEED = 0;
/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */
uint8_t const SPI_HALF_SPEED = 1;
/** Set SCK rate to F_CPU/8. See Sd2Card::setSckRate(). */
uint8_t const SPI_QUARTER_SPEED = 2;
/** Set SCK rate to F_CPU/16. See Sd2Card::setSckRate(). */
uint8_t const SPI_EIGHTH_SPEED = 3;
/** Set SCK rate to F_CPU/32. See Sd2Card::setSckRate(). */
uint8_t const SPI_SIXTEENTH_SPEED = 4;
//------------------------------------------------------------------------------
/** init timeout ms */ /** init timeout ms */
uint16_t const SD_INIT_TIMEOUT = 2000; uint16_t const SD_INIT_TIMEOUT = 2000;
/** erase timeout ms */ /** erase timeout ms */
@ -133,6 +121,9 @@ uint8_t const SD_CARD_TYPE_SDHC = 3;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// SPI pin definitions - do not edit here - change in SdFatConfig.h // SPI pin definitions - do not edit here - change in SdFatConfig.h
// //
#define SD_CHIP_SELECT_PIN SS_PIN
#if 0
#if DISABLED(SOFTWARE_SPI) #if DISABLED(SOFTWARE_SPI)
// hardware pin defs // hardware pin defs
/** The default chip select pin for the SD card is SS. */ /** The default chip select pin for the SD card is SS. */
@ -156,6 +147,9 @@ uint8_t const SD_CARD_TYPE_SDHC = 3;
/** SPI Clock pin */ /** SPI Clock pin */
#define SPI_SCK_PIN SOFT_SPI_SCK_PIN #define SPI_SCK_PIN SOFT_SPI_SCK_PIN
#endif // SOFTWARE_SPI #endif // SOFTWARE_SPI
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
* \class Sd2Card * \class Sd2Card

@ -34,7 +34,8 @@
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
#include "SdBaseFile.h" #include "SdBaseFile.h"
#include <Print.h> //todo: HAL: create wrapper for Print?
//#include <Print.h>
#ifndef SdFile_h #ifndef SdFile_h
#define SdFile_h #define SdFile_h
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -42,7 +43,7 @@
* \class SdFile * \class SdFile
* \brief SdBaseFile with Print. * \brief SdBaseFile with Print.
*/ */
class SdFile : public SdBaseFile, public Print { class SdFile : public SdBaseFile/*, public Print*/ {
public: public:
SdFile() {} SdFile() {}
SdFile(const char* name, uint8_t oflag); SdFile(const char* name, uint8_t oflag);

@ -76,6 +76,7 @@
#define BOARD_BRAINWAVE 82 // Brainwave (AT90USB646) #define BOARD_BRAINWAVE 82 // Brainwave (AT90USB646)
#define BOARD_SAV_MKI 83 // SAV Mk-I (AT90USB1286) #define BOARD_SAV_MKI 83 // SAV Mk-I (AT90USB1286)
#define BOARD_TEENSY2 84 // Teensy++2.0 (AT90USB1286) - CLI compile: HARDWARE_MOTHERBOARD=84 make #define BOARD_TEENSY2 84 // Teensy++2.0 (AT90USB1286) - CLI compile: HARDWARE_MOTHERBOARD=84 make
#define BOARD_TEENSY35_36 841 // Teensy3.5 and Teensy3.6
#define BOARD_BRAINWAVE_PRO 85 // Brainwave Pro (AT90USB1286) #define BOARD_BRAINWAVE_PRO 85 // Brainwave Pro (AT90USB1286)
#define BOARD_GEN3_PLUS 9 // Gen3+ #define BOARD_GEN3_PLUS 9 // Gen3+
#define BOARD_GEN3_MONOLITHIC 22 // Gen3 Monolithic Electronics #define BOARD_GEN3_MONOLITHIC 22 // Gen3 Monolithic Electronics
@ -100,6 +101,28 @@
#define BOARD_BAM_DICE_DUE 402 // 2PrintBeta BAM&DICE Due with STK drivers #define BOARD_BAM_DICE_DUE 402 // 2PrintBeta BAM&DICE Due with STK drivers
#define BOARD_BQ_ZUM_MEGA_3D 503 // bq ZUM Mega 3D #define BOARD_BQ_ZUM_MEGA_3D 503 // bq ZUM Mega 3D
#define BOARD_ZRIB_V20 504 // zrib V2.0 control board (Chinese knock off RAMPS replica) #define BOARD_ZRIB_V20 504 // zrib V2.0 control board (Chinese knock off RAMPS replica)
//ARM 32
#define BOARD_DUE3DOM 1411 // DUE3DOM for Arduino DUE
#define BOARD_DUE3DOM_MINI 1412 // DUE3DOM MINI for Arduino DUE
#define BOARD_RADDS 1502 // RADDS
#define BOARD_RAMPS_FD_V1 1503 // RAMPS-FD v1
#define BOARD_RAMPS_FD_V2 1504 // RAMPS-FD v2
#define BOARD_RAMPS_SMART_EFB 1523 // RAMPS-SMART (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS_SMART_EEB 1524 // RAMPS-SMART (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS_SMART_EFF 1525 // RAMPS-SMART (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_SMART_EEF 1526 // RAMPS-SMART (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_SMART_SF 1528 // RAMPS-SMART (Power outputs: Spindle, Controller Fan)
#define BOARD_RAMPS_DUO_EFB 1533 // RAMPS Duo (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS_DUO_EEB 1534 // RAMPS Duo (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS_DUO_EFF 1535 // RAMPS Duo (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_DUO_EEF 1536 // RAMPS Duo (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_DUO_SF 1538 // RAMPS Duo (Power outputs: Spindle, Controller Fan)
#define BOARD_RAMPS4DUE_EFB 1543 // RAMPS4DUE (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS4DUE_EEB 1544 // RAMPS4DUE (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS4DUE_EFF 1545 // RAMPS4DUE (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS4DUE_EEF 1546 // RAMPS4DUE (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS4DUE_SF 1548 // RAMPS4DUE (Power outputs: Spindle, Controller Fan)
#define BOARD_ALLIGATOR 1602 // Alligator Board R2
#define MB(board) (MOTHERBOARD==BOARD_##board) #define MB(board) (MOTHERBOARD==BOARD_##board)

@ -24,7 +24,6 @@
#define __BUZZER_H__ #define __BUZZER_H__
#include "types.h" #include "types.h"
#include "fastio.h"
#include "circularqueue.h" #include "circularqueue.h"
#include "temperature.h" #include "temperature.h"

@ -23,7 +23,7 @@
#ifndef __CIRCULARQUEUE_H__ #ifndef __CIRCULARQUEUE_H__
#define __CIRCULARQUEUE_H__ #define __CIRCULARQUEUE_H__
#include <Arduino.h> #include <stdint.h>
/** /**
* @brief Circular Queue class * @brief Circular Queue class

@ -252,12 +252,14 @@ void MarlinSettings::postprocess() {
} }
#if ENABLED(EEPROM_SETTINGS) #if ENABLED(EEPROM_SETTINGS)
#include "src/HAL/persistent_store_api.h"
#define DUMMY_PID_VALUE 3000.0f #define DUMMY_PID_VALUE 3000.0f
#define EEPROM_START() int eeprom_index = EEPROM_OFFSET #define EEPROM_START() int eeprom_index = EEPROM_OFFSET; HAL::PersistentStore::access_start()
#define EEPROM_FINISH() HAL::PersistentStore::access_finish()
#define EEPROM_SKIP(VAR) eeprom_index += sizeof(VAR) #define EEPROM_SKIP(VAR) eeprom_index += sizeof(VAR)
#define EEPROM_WRITE(VAR) write_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc) #define EEPROM_WRITE(VAR) HAL::PersistentStore::write_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc)
#define EEPROM_READ(VAR) read_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc) #define EEPROM_READ(VAR) HAL::PersistentStore::read_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc)
#define EEPROM_ASSERT(TST,ERR) if (!(TST)) do{ SERIAL_ERROR_START(); SERIAL_ERRORLNPGM(ERR); eeprom_read_error = true; }while(0) #define EEPROM_ASSERT(TST,ERR) if (!(TST)) do{ SERIAL_ERROR_START(); SERIAL_ERRORLNPGM(ERR); eeprom_read_error = true; }while(0)
const char version[4] = EEPROM_VERSION; const char version[4] = EEPROM_VERSION;
@ -268,39 +270,6 @@ void MarlinSettings::postprocess() {
int MarlinSettings::meshes_begin; int MarlinSettings::meshes_begin;
#endif #endif
void MarlinSettings::write_data(int &pos, const uint8_t *value, uint16_t size, uint16_t *crc) {
if (eeprom_error) return;
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t v = *value;
// EEPROM has only ~100,000 write cycles,
// so only write bytes that have changed!
if (v != eeprom_read_byte(p)) {
eeprom_write_byte(p, v);
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_START();
SERIAL_ECHOLNPGM(MSG_ERR_EEPROM_WRITE);
eeprom_error = true;
return;
}
}
crc16(crc, &v, 1);
pos++;
value++;
};
}
void MarlinSettings::read_data(int &pos, uint8_t* value, uint16_t size, uint16_t *crc) {
if (eeprom_error) return;
do {
uint8_t c = eeprom_read_byte((unsigned char*)pos);
*value = c;
crc16(crc, &c, 1);
pos++;
value++;
} while (--size);
}
/** /**
* M500 - Store Configuration * M500 - Store Configuration
*/ */
@ -668,7 +637,7 @@ void MarlinSettings::postprocess() {
if (ubl.state.storage_slot >= 0) if (ubl.state.storage_slot >= 0)
store_mesh(ubl.state.storage_slot); store_mesh(ubl.state.storage_slot);
#endif #endif
EEPROM_FINISH();
return !eeprom_error; return !eeprom_error;
} }
@ -1067,6 +1036,7 @@ void MarlinSettings::postprocess() {
#if ENABLED(EEPROM_CHITCHAT) && DISABLED(DISABLE_M503) #if ENABLED(EEPROM_CHITCHAT) && DISABLED(DISABLE_M503)
report(); report();
#endif #endif
EEPROM_FINISH();
return !eeprom_error; return !eeprom_error;
} }
@ -1107,7 +1077,7 @@ void MarlinSettings::postprocess() {
uint16_t crc = 0; uint16_t crc = 0;
int pos = meshes_end - (slot + 1) * sizeof(ubl.z_values); int pos = meshes_end - (slot + 1) * sizeof(ubl.z_values);
write_data(pos, (uint8_t *)&ubl.z_values, sizeof(ubl.z_values), &crc); HAL::PersistentStore::write_data(pos, (uint8_t *)&ubl.z_values, sizeof(ubl.z_values), &crc);
// Write crc to MAT along with other data, or just tack on to the beginning or end // Write crc to MAT along with other data, or just tack on to the beginning or end
@ -1138,7 +1108,7 @@ void MarlinSettings::postprocess() {
uint16_t crc = 0; uint16_t crc = 0;
int pos = meshes_end - (slot + 1) * sizeof(ubl.z_values); int pos = meshes_end - (slot + 1) * sizeof(ubl.z_values);
uint8_t * const dest = into ? (uint8_t*)into : (uint8_t*)&ubl.z_values; uint8_t * const dest = into ? (uint8_t*)into : (uint8_t*)&ubl.z_values;
read_data(pos, dest, sizeof(ubl.z_values), &crc); HAL::PersistentStore::read_data(pos, dest, sizeof(ubl.z_values), &crc);
// Compare crc with crc from MAT, or read from end // Compare crc with crc from MAT, or read from end

@ -72,8 +72,6 @@ class MarlinSettings {
#endif #endif
static void write_data(int &pos, const uint8_t *value, uint16_t size, uint16_t *crc);
static void read_data(int &pos, uint8_t *value, uint16_t size, uint16_t *crc);
#endif #endif
}; };

@ -0,0 +1,108 @@
/***************************************************************
*
* External DAC for Alligator Board
*
****************************************************************/
#include "Marlin.h"
#if MB(ALLIGATOR)
#include "stepper.h"
#include "dac_dac084s085.h"
dac084s085::dac084s085() {
return ;
}
void dac084s085::begin() {
uint8_t externalDac_buf[2] = {0x20,0x00};//all off
// All SPI chip-select HIGH
pinMode (DAC0_SYNC, OUTPUT);
digitalWrite( DAC0_SYNC , HIGH );
#if EXTRUDERS > 1
pinMode (DAC1_SYNC, OUTPUT);
digitalWrite( DAC1_SYNC , HIGH );
#endif
digitalWrite( SPI_EEPROM1_CS , HIGH );
digitalWrite( SPI_EEPROM2_CS , HIGH );
digitalWrite( SPI_FLASH_CS , HIGH );
digitalWrite( SS_PIN , HIGH );
spiBegin();
//init onboard DAC
delayMicroseconds(2U);
digitalWrite( DAC0_SYNC , LOW );
delayMicroseconds(2U);
digitalWrite( DAC0_SYNC , HIGH );
delayMicroseconds(2U);
digitalWrite( DAC0_SYNC , LOW );
spiSend(SPI_CHAN_DAC,externalDac_buf , 2);
digitalWrite( DAC0_SYNC , HIGH );
#if EXTRUDERS > 1
//init Piggy DAC
delayMicroseconds(2U);
digitalWrite( DAC1_SYNC , LOW );
delayMicroseconds(2U);
digitalWrite( DAC1_SYNC , HIGH );
delayMicroseconds(2U);
digitalWrite( DAC1_SYNC , LOW );
spiSend(SPI_CHAN_DAC,externalDac_buf , 2);
digitalWrite( DAC1_SYNC , HIGH );
#endif
return;
}
void dac084s085::setValue(uint8_t channel, uint8_t value) {
if(channel >= 7) // max channel (X,Y,Z,E0,E1,E2,E3)
return;
if(value > 255) value = 255;
uint8_t externalDac_buf[2] = {0x10,0x00};
if(channel > 3)
externalDac_buf[0] |= (7 - channel << 6);
else
externalDac_buf[0] |= (3 - channel << 6);
externalDac_buf[0] |= (value>>4);
externalDac_buf[1] |= (value<<4);
// All SPI chip-select HIGH
digitalWrite( DAC0_SYNC , HIGH );
#if EXTRUDERS > 1
digitalWrite( DAC1_SYNC , HIGH );
#endif
digitalWrite( SPI_EEPROM1_CS , HIGH );
digitalWrite( SPI_EEPROM2_CS , HIGH );
digitalWrite( SPI_FLASH_CS , HIGH );
digitalWrite( SS_PIN , HIGH );
if(channel > 3) { // DAC Piggy E1,E2,E3
digitalWrite(DAC1_SYNC , LOW);
delayMicroseconds(2U);
digitalWrite(DAC1_SYNC , HIGH);
delayMicroseconds(2U);
digitalWrite(DAC1_SYNC , LOW);
}
else { // DAC onboard X,Y,Z,E0
digitalWrite(DAC0_SYNC , LOW);
delayMicroseconds(2U);
digitalWrite(DAC0_SYNC , HIGH);
delayMicroseconds(2U);
digitalWrite(DAC0_SYNC , LOW);
}
delayMicroseconds(2U);
spiSend(SPI_CHAN_DAC,externalDac_buf , 2);
return;
}
#endif

@ -0,0 +1,11 @@
#ifndef dac084s085_h
#define dac084s085_h
class dac084s085 {
public:
dac084s085();
static void begin(void);
static void setValue(uint8_t channel, uint8_t value);
};
#endif //dac084s085_h

@ -43,7 +43,7 @@ char* hex_word(const uint16_t w) {
} }
char* hex_address(const void * const w) { char* hex_address(const void * const w) {
(void)hex_word((uint16_t)w); (void)hex_word((int)w);
return _hex; return _hex;
} }

@ -36,11 +36,6 @@
#define _O2 __attribute__((optimize("O2"))) #define _O2 __attribute__((optimize("O2")))
#define _O3 __attribute__((optimize("O3"))) #define _O3 __attribute__((optimize("O3")))
// Bracket code that shouldn't be interrupted
#ifndef CRITICAL_SECTION_START
#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli();
#define CRITICAL_SECTION_END SREG = _sreg;
#endif
// Clock speed factors // Clock speed factors
#define CYCLES_PER_MICROSECOND (F_CPU / 1000000L) // 16 or 20 #define CYCLES_PER_MICROSECOND (F_CPU / 1000000L) // 16 or 20

@ -231,6 +231,72 @@
#elif MB(5DPRINT) #elif MB(5DPRINT)
#include "pins_5DPRINT.h" // AT90USB1286 #include "pins_5DPRINT.h" // AT90USB1286
//
// 32-bit Boards
//
#elif MB(TEENSY35_36)
#include "pins_TEENSY35_36.h"
#elif MB(DUE3DOM)
#include "pins_DUE3DOM.h"
#elif MB(DUE3DOM_MINI)
#include "pins_DUE3DOM_MINI.h"
#elif MB(RADDS)
#include "pins_RADDS.h"
#elif MB(RAMPS_FD_V1)
#include "pins_RAMPS_FD.h"
#elif MB(RAMPS_FD_V2)
#include "pins_RAMPS_FD_V2.h"
#elif MB(RAMPS_SMART_EFB)
#define IS_RAMPS_EFB
#include "pins_RAMPS_SMART.h"
#elif MB(RAMPS_SMART_EEB)
#define IS_RAMPS_EEB
#include "pins_RAMPS_SMART.h"
#elif MB(RAMPS_SMART_EFF)
#define IS_RAMPS_EFF
#include "pins_RAMPS_SMART.h"
#elif MB(RAMPS_SMART_EEF)
#define IS_RAMPS_EEF
#include "pins_RAMPS_SMART.h"
#elif MB(RAMPS_SMART_SF)
#define IS_RAMPS_SF
#include "pins_RAMPS_SMART.h"
#elif MB(RAMPS_DUO_EFB)
#define IS_RAMPS_EFB
#include "pins_RAMPS_DUO.h"
#elif MB(RAMPS_DUO_EEB)
#define IS_RAMPS_EEB
#include "pins_RAMPS_DUO.h"
#elif MB(RAMPS_DUO_EFF)
#define IS_RAMPS_EFF
#include "pins_RAMPS_DUO.h"
#elif MB(RAMPS_DUO_EEF)
#define IS_RAMPS_EEF
#include "pins_RAMPS_DUO.h"
#elif MB(RAMPS_DUO_SF)
#define IS_RAMPS_SF
#include "pins_RAMPS_DUO.h"
#elif MB(RAMPS4DUE_EFB)
#define IS_RAMPS_EFB
#include "pins_RAMPS4DUE.h"
#elif MB(RAMPS4DUE_EEB)
#define IS_RAMPS_EEB
#include "pins_RAMPS4DUE.h"
#elif MB(RAMPS4DUE_EFF)
#define IS_RAMPS_EFF
#include "pins_RAMPS4DUE.h"
#elif MB(RAMPS4DUE_EEF)
#define IS_RAMPS_EEF
#include "pins_RAMPS4DUE.h"
#elif MB(RAMPS4DUE_SF)
#define IS_RAMPS_SF
#include "pins_RAMPS4DUE.h"
#elif MB(ALLIGATOR)
#include "pins_ALLIGATOR_R2.h"
#elif MB(RAMPS_FD_V1) || MB(RAMPS_FD_V2)
#include "pins_RAMPS_FD_v1.h"
#else #else
#error "Unknown MOTHERBOARD value set in Configuration.h" #error "Unknown MOTHERBOARD value set in Configuration.h"
#endif #endif
@ -606,47 +672,9 @@
#define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS)) #define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS))
/** // Note: default SPI pins are defined in the HAL
* Define SPI Pins: SCK, MISO, MOSI, SS
*/ #include "src/HAL/HAL_spi_pins.h"
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
#define AVR_SCK_PIN 13
#define AVR_MISO_PIN 12
#define AVR_MOSI_PIN 11
#define AVR_SS_PIN 10
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
#define AVR_SCK_PIN 7
#define AVR_MISO_PIN 6
#define AVR_MOSI_PIN 5
#define AVR_SS_PIN 4
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define AVR_SCK_PIN 52
#define AVR_MISO_PIN 50
#define AVR_MOSI_PIN 51
#define AVR_SS_PIN 53
#elif defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__)
#define AVR_SCK_PIN 21
#define AVR_MISO_PIN 23
#define AVR_MOSI_PIN 22
#define AVR_SS_PIN 20
#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
#define AVR_SCK_PIN 10
#define AVR_MISO_PIN 12
#define AVR_MOSI_PIN 11
#define AVR_SS_PIN 16
#endif
#ifndef SCK_PIN
#define SCK_PIN AVR_SCK_PIN
#endif
#ifndef MISO_PIN
#define MISO_PIN AVR_MISO_PIN
#endif
#ifndef MOSI_PIN
#define MOSI_PIN AVR_MOSI_PIN
#endif
#ifndef SS_PIN
#define SS_PIN AVR_SS_PIN
#endif
#endif // __PINS_H__ #endif // __PINS_H__

@ -44,8 +44,10 @@
* 7 | 11 * 7 | 11
*/ */
#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__) #if !defined(IS_RAMPS_SMART) && !defined(IS_RAMPS_DUO) && !defined(IS_RAMPS4DUE)
#if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__)
#error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu." #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu."
#endif
#endif #endif
#ifndef BOARD_NAME #ifndef BOARD_NAME

@ -1222,7 +1222,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const
} }
block->acceleration_steps_per_s2 = accel; block->acceleration_steps_per_s2 = accel;
block->acceleration = accel / steps_per_mm; block->acceleration = accel / steps_per_mm;
block->acceleration_rate = (long)(accel * 16777216.0 / ((F_CPU) * 0.125)); // * 8.388608 block->acceleration_rate = (long)(accel * 16777216.0 / (HAL_STEPPER_TIMER_RATE)); // 16777216 = <<24
// Initial limit on the segment entry velocity // Initial limit on the segment entry velocity
float vmax_junction; float vmax_junction;

@ -26,8 +26,6 @@
#include "macros.h" #include "macros.h"
#include "language.h" #include "language.h"
#include "stopwatch.h" #include "stopwatch.h"
#include <avr/eeprom.h>
// Print debug messages with M111 S2 // Print debug messages with M111 S2
//#define DEBUG_PRINTCOUNTER //#define DEBUG_PRINTCOUNTER
@ -51,8 +49,14 @@ class PrintCounter: public Stopwatch {
* @brief EEPROM address * @brief EEPROM address
* @details Defines the start offset address where the data is stored. * @details Defines the start offset address where the data is stored.
*/ */
#if ENABLED(I2C_EEPROM) || ENABLED(SPI_EEPROM)
// round up address to next page boundary (assuming 32 byte pages)
const uint32_t address = 0x40;
#elif defined(CPU_32_BIT)
const uint32_t address = 0x32;
#else
const uint16_t address = 0x32; const uint16_t address = 0x32;
#endif
/** /**
* @brief Interval in seconds between counter updates * @brief Interval in seconds between counter updates
* @details This const value defines what will be the time between each * @details This const value defines what will be the time between each

@ -20,8 +20,8 @@
* *
*/ */
#ifndef __SPI_H__ #ifndef __PRIVATE_SPI_H__
#define __SPI_H__ #define __PRIVATE_SPI_H__
#include <stdint.h> #include <stdint.h>
#include "softspi.h" #include "softspi.h"
@ -54,4 +54,4 @@ class SPI<MISO_PIN, MOSI_PIN, SCK_PIN> {
}; };
#endif // __SPI_H__ #endif // __PRIVATE_SPI_H__

@ -23,20 +23,26 @@
#ifndef __SERIAL_H__ #ifndef __SERIAL_H__
#define __SERIAL_H__ #define __SERIAL_H__
#include "MarlinConfig.h" #include "src/HAL/HAL.h"
#ifdef USBCON //todo: HAL: breaks encapsulation
// For AVR only, define a serial interface based on configuration
#ifdef ARDUINO_ARCH_AVR
#ifdef USBCON
#include "HardwareSerial.h" #include "HardwareSerial.h"
#if ENABLED(BLUETOOTH) #if ENABLED(BLUETOOTH)
#define MYSERIAL bluetoothSerial #define MYSERIAL bluetoothSerial
#else #else
#define MYSERIAL Serial #define MYSERIAL Serial
#endif // BLUETOOTH #endif // BLUETOOTH
#else #else
#include "MarlinSerial.h" #include "src/HAL/HAL_AVR/MarlinSerial.h"
#define MYSERIAL customizedSerial #define MYSERIAL customizedSerial
#endif
#endif #endif
#include "MarlinConfig.h"
extern const char echomagic[] PROGMEM; extern const char echomagic[] PROGMEM;
extern const char errormagic[] PROGMEM; extern const char errormagic[] PROGMEM;

@ -0,0 +1,94 @@
/* **************************************************************************
Marlin 3D Printer Firmware
Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
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 <http://www.gnu.org/licenses/>.
****************************************************************************/
/**
* Description: HAL wrapper
*
* Supports platforms :
* ARDUINO_ARCH_SAM : For Arduino Due and other boards based on Atmel SAM3X8E
* ARDUINO_ARCH_AVR : For all Atmel AVR boards
*/
#ifndef _HAL_H
#define _HAL_H
#include <stdint.h>
/**
* SPI speed where 0 <= index <= 6
*
* Approximate rates :
*
* 0 : 8 - 10 MHz
* 1 : 4 - 5 MHz
* 2 : 2 - 2.5 MHz
* 3 : 1 - 1.25 MHz
* 4 : 500 - 625 kHz
* 5 : 250 - 312 kHz
* 6 : 125 - 156 kHz
*
* On AVR, actual speed is F_CPU/2^(1 + index).
* On other platforms, speed should be in range given above where possible.
*/
/** Set SCK to max rate */
uint8_t const SPI_FULL_SPEED = 0;
/** Set SCK rate to half max rate. */
uint8_t const SPI_HALF_SPEED = 1;
/** Set SCK rate to quarter max rate. */
uint8_t const SPI_QUARTER_SPEED = 2;
/** Set SCK rate to 1/8 max rate. */
uint8_t const SPI_EIGHTH_SPEED = 3;
/** Set SCK rate to 1/16 of max rate. */
uint8_t const SPI_SIXTEENTH_SPEED = 4;
/** Set SCK rate to 1/32 of max rate. */
uint8_t const SPI_SPEED_5 = 5;
/** Set SCK rate to 1/64 of max rate. */
uint8_t const SPI_SPEED_6 = 6;
// Standard SPI functions
/** Initialise SPI bus */
void spiBegin(void);
/** Configure SPI for specified SPI speed */
void spiInit(uint8_t spiRate);
/** Write single byte to SPI */
void spiSend(uint8_t b);
/** Read single byte from SPI */
uint8_t spiRec(void);
/** Read from SPI into buffer */
void spiRead(uint8_t* buf, uint16_t nbyte);
/** Write token and then write from 512 byte buffer to SPI (for SD card) */
void spiSendBlock(uint8_t token, const uint8_t* buf);
#ifdef ARDUINO_ARCH_AVR
#include "HAL_AVR/HAL_AVR.h"
#elif defined(ARDUINO_ARCH_SAM)
#define CPU_32_BIT
#include "HAL_DUE/HAL_Due.h"
#include "math_32bit.h"
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define CPU_32_BIT
#include "HAL_TEENSY35_36/HAL_Teensy.h"
#include "math_32bit.h"
#else
#error Unsupported Platform!
#endif
#endif /* HAL_H_ */

@ -0,0 +1,100 @@
/* **************************************************************************
Marlin 3D Printer Firmware
Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
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 <http://www.gnu.org/licenses/>.
****************************************************************************/
/**
* Description: HAL for AVR
*
* For ARDUINO_ARCH_AVR
*/
#ifdef ARDUINO_ARCH_AVR
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include "../HAL.h"
#include "../../../macros.h"
// --------------------------------------------------------------------------
// Externals
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Local defines
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Types
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Variables
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
//uint8_t MCUSR;
// --------------------------------------------------------------------------
// Private Variables
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Function prototypes
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Private functions
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
#if ENABLED(SDSUPPORT)
#include "../../../SdFatUtil.h"
int freeMemory() { return SdFatUtil::FreeRam(); }
#else
extern "C" {
extern char __bss_end;
extern char __heap_start;
extern void* __brkval;
int freeMemory() {
int free_memory;
if ((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
}
}
#endif //!SDSUPPORT
#endif

@ -0,0 +1,160 @@
/* **************************************************************************
Marlin 3D Printer Firmware
Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
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 <http://www.gnu.org/licenses/>.
****************************************************************************/
/**
* Description: HAL for AVR
*
* For ARDUINO_ARCH_AVR
*/
#ifndef _HAL_AVR_H
#define _HAL_AVR_H
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include <stdint.h>
#include "Arduino.h"
#include <util/delay.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include "fastio_AVR.h"
#include "watchdog_AVR.h"
#include "math_AVR.h"
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
//#define analogInputToDigitalPin(IO) IO
#ifndef CRITICAL_SECTION_START
#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli();
#define CRITICAL_SECTION_END SREG = _sreg;
#endif
// On AVR this is in math.h?
//#define square(x) ((x)*(x))
// --------------------------------------------------------------------------
// Types
// --------------------------------------------------------------------------
#define HAL_TIMER_TYPE uint16_t
#define HAL_TIMER_TYPE_MAX 0xFFFF
#define HAL_SERVO_LIB Servo
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
//extern uint8_t MCUSR;
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
//void cli(void);
//void _delay_ms(int delay);
inline void HAL_clear_reset_source(void) { MCUSR = 0; }
inline uint8_t HAL_get_reset_source(void) { return MCUSR; }
extern "C" {
int freeMemory(void);
}
// eeprom
//void eeprom_write_byte(unsigned char *pos, unsigned char value);
//unsigned char eeprom_read_byte(unsigned char *pos);
// timers
#define STEP_TIMER_NUM OCR1A
#define TEMP_TIMER_NUM 0
#define TEMP_TIMER_FREQUENCY (F_CPU / 64.0 / 256.0)
#define HAL_TIMER_RATE ((F_CPU) / 8.0)
#define HAL_STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_PRESCALE INT0_PRESCALER
#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0B)
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0B)
//void HAL_timer_start (uint8_t timer_num, uint32_t frequency);
#define HAL_timer_start (timer_num,frequency)
//void HAL_timer_set_count (uint8_t timer_num, uint16_t count);
#define HAL_timer_set_count(timer,count) timer = (count)
#define HAL_timer_get_current_count(timer) timer
//void HAL_timer_isr_prologue (uint8_t timer_num);
#define HAL_timer_isr_prologue(timer_num)
#define HAL_STEP_TIMER_ISR ISR(TIMER1_COMPA_vect)
#define HAL_TEMP_TIMER_ISR ISR(TIMER0_COMPB_vect)
#define HAL_ENABLE_ISRs() do { cli(); if (thermalManager.in_temp_isr)DISABLE_TEMPERATURE_INTERRUPT(); else ENABLE_TEMPERATURE_INTERRUPT(); ENABLE_STEPPER_DRIVER_INTERRUPT(); } while(0)
// ADC
#ifdef DIDR2
#define HAL_ANALOG_SELECT(pin) do{ if (pin < 8) SBI(DIDR0, pin); else SBI(DIDR2, pin - 8); }while(0)
#else
#define HAL_ANALOG_SELECT(pin) do{ SBI(DIDR0, pin); }while(0)
#endif
inline void HAL_adc_init(void) {
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
DIDR0 = 0;
#ifdef DIDR2
DIDR2 = 0;
#endif
}
#define SET_ADMUX_ADCSRA(pin) ADMUX = _BV(REFS0) | (pin & 0x07); SBI(ADCSRA, ADSC)
#ifdef MUX5
#define HAL_START_ADC(pin) if (pin > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#else
#define HAL_START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#endif
#define HAL_READ_ADC ADC
// --------------------------------------------------------------------------
//
// --------------------------------------------------------------------------
#endif // _HAL_AVR_H

@ -20,6 +20,16 @@
* *
*/ */
#ifndef HAL_PINSDEBUG_AVR_H
void HAL_print_analog_pin(char buffer[], int8_t pin) {
sprintf(buffer, "(A%2d) ", int(pin - analogInputToDigitalPin(0)));
}
void HAL_analog_pin_state(char buffer[], int8_t pin) {
sprintf(buffer, "Analog in =% 5d", analogRead(pin - analogInputToDigitalPin(0)));
}
bool endstop_monitor_flag = false; bool endstop_monitor_flag = false;
#define NAME_FORMAT "%-35s" // one place to specify the format of all the sources of names #define NAME_FORMAT "%-35s" // one place to specify the format of all the sources of names
@ -46,7 +56,7 @@ bool endstop_monitor_flag = false;
#define REPORT_NAME_DIGITAL(NAME, COUNTER) _ADD_PIN(#NAME, COUNTER) #define REPORT_NAME_DIGITAL(NAME, COUNTER) _ADD_PIN(#NAME, COUNTER)
#define REPORT_NAME_ANALOG(NAME, COUNTER) _ADD_PIN(#NAME, COUNTER) #define REPORT_NAME_ANALOG(NAME, COUNTER) _ADD_PIN(#NAME, COUNTER)
#include "pinsDebug_list.h" #include "../../../pinsDebug_list.h"
#line 51 #line 51
// manually add pins that have names that are macros which don't play well with these macros // manually add pins that have names that are macros which don't play well with these macros
@ -97,7 +107,7 @@ const PinInfo pin_array[] PROGMEM = {
#endif #endif
#endif #endif
#include "pinsDebug_list.h" #include "../../../pinsDebug_list.h"
#line 102 #line 102
}; };
@ -146,7 +156,7 @@ const PinInfo pin_array[] PROGMEM = {
* Print a pin's PWM status. * Print a pin's PWM status.
* Return true if it's currently a PWM pin. * Return true if it's currently a PWM pin.
*/ */
static bool pwm_status(uint8_t pin) { static bool HAL_pwm_status(uint8_t pin) {
char buffer[20]; // for the sprintf statements char buffer[20]; // for the sprintf statements
switch (digitalPinToTimer_DEBUG(pin)) { switch (digitalPinToTimer_DEBUG(pin)) {
@ -338,7 +348,7 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
if (TEST(*TMSK, TOIE)) err_prob_interrupt(); if (TEST(*TMSK, TOIE)) err_prob_interrupt();
} }
static void pwm_details(uint8_t pin) { static void HAL_pwm_details(uint8_t pin) {
switch (digitalPinToTimer_DEBUG(pin)) { switch (digitalPinToTimer_DEBUG(pin)) {
#if defined(TCCR0A) && defined(COM0A1) #if defined(TCCR0A) && defined(COM0A1)
@ -514,7 +524,7 @@ inline void report_pin_state_extended(int8_t pin, bool ignore, bool extended = f
print_input_or_output(false); print_input_or_output(false);
SERIAL_PROTOCOL(digitalRead_mod(pin)); SERIAL_PROTOCOL(digitalRead_mod(pin));
} }
else if (pwm_status(pin)) { else if (HAL_pwm_status(pin)) {
// do nothing // do nothing
} }
else { else {
@ -522,7 +532,7 @@ inline void report_pin_state_extended(int8_t pin, bool ignore, bool extended = f
SERIAL_PROTOCOL(digitalRead_mod(pin)); SERIAL_PROTOCOL(digitalRead_mod(pin));
} }
} }
if (!multi_name_pin && extended) pwm_details(pin); // report PWM capabilities only on the first pass & only if doing an extended report if (!multi_name_pin && extended) HAL_pwm_details(pin); // report PWM capabilities only on the first pass & only if doing an extended report
} }
} }
} }
@ -581,3 +591,5 @@ inline void report_pin_state_extended(int8_t pin, bool ignore, bool extended = f
SERIAL_EOL(); SERIAL_EOL();
} }
} }
#endif //HAL_PINSDEBUG_AVR_H

@ -0,0 +1,213 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Originally from Arduino Sd2Card Library
* Copyright (C) 2009 by William Greiman
*/
/**
* Description: HAL for AVR - SPI functions
*
* For ARDUINO_ARCH_AVR
*/
#ifdef ARDUINO_ARCH_AVR
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include "../../../MarlinConfig.h"
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
void spiBegin (void) {
SET_OUTPUT(SS_PIN);
WRITE(SS_PIN, HIGH);
SET_OUTPUT(SCK_PIN);
SET_INPUT(MISO_PIN);
SET_OUTPUT(MOSI_PIN);
#if DISABLED(SOFTWARE_SPI)
// SS must be in output mode even it is not chip select
SET_OUTPUT(SS_PIN);
// set SS high - may be chip select for another SPI device
#if SET_SPI_SS_HIGH
WRITE(SS_PIN, HIGH);
#endif // SET_SPI_SS_HIGH
// set a default rate
spiInit(1);
#endif // SOFTWARE_SPI
}
//------------------------------------------------------------------------------
#if DISABLED(SOFTWARE_SPI)
// functions for hardware SPI
//------------------------------------------------------------------------------
// make sure SPCR rate is in expected bits
#if (SPR0 != 0 || SPR1 != 1)
#error "unexpected SPCR bits"
#endif
/**
* Initialize hardware SPI
* Set SCK rate to F_CPU/pow(2, 1 + spiRate) for spiRate [0,6]
*/
void spiInit(uint8_t spiRate) {
// See avr processor documentation
CBI(
#ifdef PRR
PRR
#elif defined(PRR0)
PRR0
#endif
, PRSPI);
SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
}
//------------------------------------------------------------------------------
/** SPI receive a byte */
uint8_t spiRec(void) {
SPDR = 0XFF;
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
return SPDR;
}
//------------------------------------------------------------------------------
/** SPI read data */
void spiRead(uint8_t* buf, uint16_t nbyte) {
if (nbyte-- == 0) return;
SPDR = 0XFF;
for (uint16_t i = 0; i < nbyte; i++) {
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
buf[i] = SPDR;
SPDR = 0XFF;
}
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
buf[nbyte] = SPDR;
}
//------------------------------------------------------------------------------
/** SPI send a byte */
void spiSend(uint8_t b) {
SPDR = b;
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
}
//------------------------------------------------------------------------------
/** SPI send block */
void spiSendBlock(uint8_t token, const uint8_t* buf) {
SPDR = token;
for (uint16_t i = 0; i < 512; i += 2) {
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
SPDR = buf[i];
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
SPDR = buf[i + 1];
}
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
}
//------------------------------------------------------------------------------
#else // SOFTWARE_SPI
//------------------------------------------------------------------------------
/** nop to tune soft SPI timing */
#define nop asm volatile ("\tnop\n")
/** Set SPI rate */
void spiInit(uint8_t spiRate) {
// nothing to do
UNUSED(spiRate);
}
//------------------------------------------------------------------------------
/** Soft SPI receive byte */
uint8_t spiRec() {
uint8_t data = 0;
// no interrupts during byte receive - about 8 us
cli();
// output pin high - like sending 0XFF
WRITE(MOSI_PIN, HIGH);
for (uint8_t i = 0; i < 8; i++) {
WRITE(SCK_PIN, HIGH);
// adjust so SCK is nice
nop;
nop;
data <<= 1;
if (READ(MISO_PIN)) data |= 1;
WRITE(SCK_PIN, LOW);
}
// enable interrupts
sei();
return data;
}
//------------------------------------------------------------------------------
/** Soft SPI read data */
void spiRead(uint8_t* buf, uint16_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++)
buf[i] = spiRec();
}
//------------------------------------------------------------------------------
/** Soft SPI send byte */
void spiSend(uint8_t data) {
// no interrupts during byte send - about 8 us
cli();
for (uint8_t i = 0; i < 8; i++) {
WRITE(SCK_PIN, LOW);
WRITE(MOSI_PIN, data & 0X80);
data <<= 1;
WRITE(SCK_PIN, HIGH);
}
// hold SCK high for a few ns
nop;
nop;
nop;
nop;
WRITE(SCK_PIN, LOW);
// enable interrupts
sei();
}
//------------------------------------------------------------------------------
/** Soft SPI send block */
void spiSendBlock(uint8_t token, const uint8_t* buf) {
spiSend(token);
for (uint16_t i = 0; i < 512; i++)
spiSend(buf[i]);
}
#endif // SOFTWARE_SPI
#endif // ARDUINO_ARCH_AVR

@ -28,9 +28,10 @@
* Modified 28 September 2010 by Mark Sproul * Modified 28 September 2010 by Mark Sproul
* Modified 14 February 2016 by Andreas Hardtung (added tx buffer) * Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
*/ */
#ifdef ARDUINO_ARCH_AVR
#include "MarlinSerial.h" #include "MarlinSerial.h"
#include "Marlin.h" #include "../../../Marlin.h"
// Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.) // Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.)
@ -46,8 +47,8 @@
#if ENABLED(EMERGENCY_PARSER) #if ENABLED(EMERGENCY_PARSER)
#include "stepper.h" #include "../../../stepper.h"
#include "language.h" #include "../../../language.h"
// Currently looking for: M108, M112, M410 // Currently looking for: M108, M112, M410
// If you alter the parser please don't forget to update the capabilities in Conditionals_post.h // If you alter the parser please don't forget to update the capabilities in Conditionals_post.h
@ -515,3 +516,5 @@
#if defined(USBCON) && ENABLED(BLUETOOTH) #if defined(USBCON) && ENABLED(BLUETOOTH)
HardwareSerial bluetoothSerial; HardwareSerial bluetoothSerial;
#endif #endif
#endif

@ -32,7 +32,9 @@
#ifndef MARLINSERIAL_H #ifndef MARLINSERIAL_H
#define MARLINSERIAL_H #define MARLINSERIAL_H
#include "MarlinConfig.h" #include "../../../MarlinConfig.h"
#include <WString.h>
#ifndef SERIAL_PORT #ifndef SERIAL_PORT
#define SERIAL_PORT 0 #define SERIAL_PORT 0
@ -160,6 +162,7 @@
static void println(unsigned long, int = DEC); static void println(unsigned long, int = DEC);
static void println(double, int = 2); static void println(double, int = 2);
static void println(void); static void println(void);
operator bool() { return true; }
}; };
extern MarlinSerial customizedSerial; extern MarlinSerial customizedSerial;

@ -0,0 +1,90 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
/*
Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
Copyright (c) 2009 Michael Margolis. 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
*/
/*
* Defines for 16 bit timers used with Servo library
*
* If _useTimerX is defined then TimerX is a 16 bit timer on the current board
* timer16_Sequence_t enumerates the sequence that the timers should be allocated
* _Nbr_16timers indicates how many 16 bit timers are available.
*/
/**
* AVR Only definitions
* --------------------
*/
#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays
#define PRESCALER 8 // timer prescaler
// Say which 16 bit timers can be used and in what order
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
//#define _useTimer1
#define _useTimer3
#define _useTimer4
#if !HAS_MOTOR_CURRENT_PWM
#define _useTimer5 // Timer 5 is used for motor current PWM and can't be used for servos.
#endif
#elif defined(__AVR_ATmega32U4__)
#define _useTimer3
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define _useTimer3
#elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega2561__)
#define _useTimer3
#else
// everything else
#endif
typedef enum {
#if ENABLED(_useTimer1)
_timer1,
#endif
#if ENABLED(_useTimer3)
_timer3,
#endif
#if ENABLED(_useTimer4)
_timer4,
#endif
#if ENABLED(_useTimer5)
_timer5,
#endif
_Nbr_16timers
} timer16_Sequence_t;

@ -38,7 +38,7 @@
#ifndef _ENDSTOP_INTERRUPTS_H_ #ifndef _ENDSTOP_INTERRUPTS_H_
#define _ENDSTOP_INTERRUPTS_H_ #define _ENDSTOP_INTERRUPTS_H_
#include "macros.h" #include "../../../macros.h"
/** /**
* Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h) * Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h)
@ -72,8 +72,6 @@
0 ) 0 )
#endif #endif
volatile uint8_t e_hit = 0; // Different from 0 when the endstops should be tested in detail.
// Must be reset to 0 by the test function when finished.
// Install Pin change interrupt for a pin. Can be called multiple times. // Install Pin change interrupt for a pin. Can be called multiple times.
void pciSetup(byte pin) { void pciSetup(byte pin) {
@ -82,14 +80,6 @@ void pciSetup(byte pin) {
SBI(PCICR, digitalPinToPCICRbit(pin)); // enable interrupt for the group SBI(PCICR, digitalPinToPCICRbit(pin)); // enable interrupt for the group
} }
// This is what is really done inside the interrupts.
FORCE_INLINE void endstop_ISR_worker( void ) {
e_hit = 2; // Because the detection of a e-stop hit has a 1 step debouncer it has to be called at least twice.
}
// Use one Routine to handle each group
// One ISR for all EXT-Interrupts
void endstop_ISR(void) { endstop_ISR_worker(); }
// Handlers for pin change interrupts // Handlers for pin change interrupts
#ifdef PCINT0_vect #ifdef PCINT0_vect

@ -31,7 +31,7 @@
#ifndef _FASTIO_1280 #ifndef _FASTIO_1280
#define _FASTIO_1280 #define _FASTIO_1280
#include "fastio.h" #include "fastio_AVR.h"
// change for your board // change for your board
#define DEBUG_LED DIO21 #define DEBUG_LED DIO21

@ -31,7 +31,7 @@
#ifndef _FASTIO_1281 #ifndef _FASTIO_1281
#define _FASTIO_1281 #define _FASTIO_1281
#include "fastio.h" #include "fastio_AVR.h"
// change for your board // change for your board
#define DEBUG_LED DIO46 #define DEBUG_LED DIO46

@ -31,7 +31,7 @@
#ifndef _FASTIO_168 #ifndef _FASTIO_168
#define _FASTIO_168 #define _FASTIO_168
#include "fastio.h" #include "fastio_AVR.h"
#define DEBUG_LED AIO5 #define DEBUG_LED AIO5

@ -31,7 +31,7 @@
#ifndef _FASTIO_644 #ifndef _FASTIO_644
#define _FASTIO_644 #define _FASTIO_644
#include "fastio.h" #include "fastio_AVR.h"
#define DEBUG_LED DIO0 #define DEBUG_LED DIO0

@ -32,7 +32,7 @@
#ifndef _FASTIO_AT90USB #ifndef _FASTIO_AT90USB
#define _FASTIO_AT90USB #define _FASTIO_AT90USB
#include "fastio.h" #include "fastio_AVR.h"
// change for your board // change for your board
#define DEBUG_LED DIO31 /* led D5 red */ #define DEBUG_LED DIO31 /* led D5 red */

@ -30,7 +30,7 @@
#define _FASTIO_ARDUINO_H #define _FASTIO_ARDUINO_H
#include <avr/io.h> #include <avr/io.h>
#include "macros.h" #include "../../../macros.h"
#define AVR_AT90USB1286_FAMILY (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__)) #define AVR_AT90USB1286_FAMILY (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__))
#define AVR_ATmega1284_FAMILY (defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)) #define AVR_ATmega1284_FAMILY (defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__))
@ -38,7 +38,6 @@
#define AVR_ATmega2561_FAMILY (defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)) #define AVR_ATmega2561_FAMILY (defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__))
#define AVR_ATmega328_FAMILY (defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328p__)) #define AVR_ATmega328_FAMILY (defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328p__))
/** /**
* Include Ports and Functions * Include Ports and Functions
*/ */
@ -57,7 +56,7 @@
#endif #endif
#ifndef _BV #ifndef _BV
#define _BV(PIN) (1UL << PIN) #define _BV(bit) (1UL << (bit))
#endif #endif
/** /**
@ -269,7 +268,7 @@ typedef enum {
#define PWM_CHK_MOTOR_CURRENT(p) false #define PWM_CHK_MOTOR_CURRENT(p) false
#endif #endif
#if defined(NUM_SERVOS) #ifdef NUM_SERVOS
#if AVR_ATmega2560_FAMILY #if AVR_ATmega2560_FAMILY
#define PWM_CHK_SERVO(p) ( p == 5 || NUM_SERVOS > 12 && p == 6 || NUM_SERVOS > 24 && p == 46) //PWMS 3A, 4A & 5A #define PWM_CHK_SERVO(p) ( p == 5 || NUM_SERVOS > 12 && p == 6 || NUM_SERVOS > 24 && p == 46) //PWMS 3A, 4A & 5A
#elif AVR_ATmega2561_FAMILY #elif AVR_ATmega2561_FAMILY

@ -0,0 +1,112 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef MATH_AVR_H
#define MATH_AVR_H
/**
* Optimized math functions for AVR
*/
// intRes = longIn1 * longIn2 >> 24
// uses:
// r26 to store 0
// r27 to store bits 16-23 of the 48bit result. The top bit is used to round the two byte result.
// note that the lower two bytes and the upper byte of the 48bit result are not calculated.
// this can cause the result to be out by one as the lower bytes may cause carries into the upper ones.
// B0 A0 are bits 24-39 and are the returned value
// C1 B1 A1 is longIn1
// D2 C2 B2 A2 is longIn2
//
#define MultiU24X32toH16(intRes, longIn1, longIn2) \
asm volatile ( \
"clr r26 \n\t" \
"mul %A1, %B2 \n\t" \
"mov r27, r1 \n\t" \
"mul %B1, %C2 \n\t" \
"movw %A0, r0 \n\t" \
"mul %C1, %C2 \n\t" \
"add %B0, r0 \n\t" \
"mul %C1, %B2 \n\t" \
"add %A0, r0 \n\t" \
"adc %B0, r1 \n\t" \
"mul %A1, %C2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %B1, %B2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %C1, %A2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %B1, %A2 \n\t" \
"add r27, r1 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"lsr r27 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"mul %D2, %A1 \n\t" \
"add %A0, r0 \n\t" \
"adc %B0, r1 \n\t" \
"mul %D2, %B1 \n\t" \
"add %B0, r0 \n\t" \
"clr r1 \n\t" \
: \
"=&r" (intRes) \
: \
"d" (longIn1), \
"d" (longIn2) \
: \
"r26" , "r27" \
)
// intRes = intIn1 * intIn2 >> 16
// uses:
// r26 to store 0
// r27 to store the byte 1 of the 24 bit result
#define MultiU16X8toH16(intRes, charIn1, intIn2) \
asm volatile ( \
"clr r26 \n\t" \
"mul %A1, %B2 \n\t" \
"movw %A0, r0 \n\t" \
"mul %A1, %A2 \n\t" \
"add %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"lsr r0 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"clr r1 \n\t" \
: \
"=&r" (intRes) \
: \
"d" (charIn1), \
"d" (intIn2) \
: \
"r26" \
)
#endif

@ -0,0 +1,57 @@
#include "../persistent_store_api.h"
#include "../../../types.h"
#include "../../../language.h"
#include "../../../serial.h"
#include "../../../utility.h"
#ifdef ARDUINO_ARCH_AVR
#if ENABLED(EEPROM_SETTINGS)
namespace HAL {
namespace PersistentStore {
bool access_start() {
return true;
}
bool access_finish(){
return true;
}
bool write_data(int &pos, const uint8_t *value, uint16_t size, uint16_t *crc) {
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t v = *value;
// EEPROM has only ~100,000 write cycles,
// so only write bytes that have changed!
if (v != eeprom_read_byte(p)) {
eeprom_write_byte(p, v);
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_START();
SERIAL_ECHOLNPGM(MSG_ERR_EEPROM_WRITE);
return false;
}
}
crc16(crc, &v, 1);
pos++;
value++;
};
return true;
}
void read_data(int &pos, uint8_t* value, uint16_t size, uint16_t *crc) {
do {
uint8_t c = eeprom_read_byte((unsigned char*)pos);
*value = c;
crc16(crc, &c, 1);
pos++;
value++;
} while (--size);
}
}
}
#endif // EEPROM_SETTINGS
#endif // ARDUINO_ARCH_AVR

@ -20,6 +20,7 @@
* *
*/ */
/** /**
* servo.cpp - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 * servo.cpp - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
* Copyright (c) 2009 Michael Margolis. All right reserved. * Copyright (c) 2009 Michael Margolis. All right reserved.
@ -50,36 +51,21 @@
* detach() - Stop an attached servo from pulsing its i/o pin. * detach() - Stop an attached servo from pulsing its i/o pin.
* *
*/ */
#include "MarlinConfig.h"
#ifdef ARDUINO_ARCH_AVR
#include "../../../MarlinConfig.h"
#if HAS_SERVOS #if HAS_SERVOS
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <Arduino.h> #include <Arduino.h>
#include "servo.h" #include "../servo.h"
#include "../servo_private.h"
#define usToTicks(_us) (( clockCyclesPerMicrosecond()* _us) / 8) // converts microseconds to tick (assumes prescale of 8) // 12 Aug 2009
#define ticksToUs(_ticks) (( (unsigned)_ticks * 8)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds
#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays // 12 August 2009
//#define NBR_TIMERS ((MAX_SERVOS) / (SERVOS_PER_TIMER))
static ServoInfo_t servo_info[MAX_SERVOS]; // static array of servo info structures
static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval) static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
uint8_t ServoCount = 0; // the total number of attached servos
// convenience macros
#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / (SERVOS_PER_TIMER))) // returns the timer controlling this servo
#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % (SERVOS_PER_TIMER)) // returns the index of the servo on this timer
#define SERVO_INDEX(_timer,_channel) ((_timer*(SERVOS_PER_TIMER)) + _channel) // macro to access servo index by timer and channel
#define SERVO(_timer,_channel) (servo_info[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel
#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo
#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo
/************ static functions common to all instances ***********************/ /************ static functions common to all instances ***********************/
@ -138,8 +124,9 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t
#endif // WIRING #endif // WIRING
/****************** end of static functions ******************************/
static void initISR(timer16_Sequence_t timer) { void initISR(timer16_Sequence_t timer) {
#if ENABLED(_useTimer1) #if ENABLED(_useTimer1)
if (timer == _timer1) { if (timer == _timer1) {
TCCR1A = 0; // normal counting mode TCCR1A = 0; // normal counting mode
@ -198,7 +185,7 @@ static void initISR(timer16_Sequence_t timer) {
#endif #endif
} }
static void finISR(timer16_Sequence_t timer) { void finISR(timer16_Sequence_t timer) {
// Disable use of the given timer // Disable use of the given timer
#ifdef WIRING #ifdef WIRING
if (timer == _timer1) { if (timer == _timer1) {
@ -227,96 +214,6 @@ static void finISR(timer16_Sequence_t timer) {
#endif #endif
} }
static bool isTimerActive(timer16_Sequence_t timer) { #endif // HAS_SERVOS
// returns true if any servo is active on this timer
for (uint8_t channel = 0; channel < SERVOS_PER_TIMER; channel++) {
if (SERVO(timer, channel).Pin.isActive)
return true;
}
return false;
}
/****************** end of static functions ******************************/
Servo::Servo() {
if (ServoCount < MAX_SERVOS) {
this->servoIndex = ServoCount++; // assign a servo index to this instance
servo_info[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009
}
else
this->servoIndex = INVALID_SERVO; // too many servos
}
int8_t Servo::attach(int pin) {
return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
}
int8_t Servo::attach(int pin, int min, int max) {
if (this->servoIndex >= MAX_SERVOS) return -1;
if (pin > 0) servo_info[this->servoIndex].Pin.nbr = pin;
pinMode(servo_info[this->servoIndex].Pin.nbr, OUTPUT); // set servo pin to output
// todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128
this->min = (MIN_PULSE_WIDTH - min) / 4; //resolution of min/max is 4 uS
this->max = (MAX_PULSE_WIDTH - max) / 4;
// initialize the timer if it has not already been initialized
timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
if (!isTimerActive(timer)) initISR(timer);
servo_info[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive
return this->servoIndex;
}
void Servo::detach() {
servo_info[this->servoIndex].Pin.isActive = false;
timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
if (!isTimerActive(timer)) finISR(timer);
}
void Servo::write(int value) {
if (value < MIN_PULSE_WIDTH) { // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
value = map(constrain(value, 0, 180), 0, 180, SERVO_MIN(), SERVO_MAX());
}
this->writeMicroseconds(value);
}
void Servo::writeMicroseconds(int value) {
// calculate and store the values for the given channel
byte channel = this->servoIndex;
if (channel < MAX_SERVOS) { // ensure channel is valid
// ensure pulse width is valid
value = constrain(value, SERVO_MIN(), SERVO_MAX()) - (TRIM_DURATION);
value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - 12 Aug 2009
CRITICAL_SECTION_START;
servo_info[channel].ticks = value;
CRITICAL_SECTION_END;
}
}
// return the value as degrees
int Servo::read() { return map(this->readMicroseconds() + 1, SERVO_MIN(), SERVO_MAX(), 0, 180); }
int Servo::readMicroseconds() {
return (this->servoIndex == INVALID_SERVO) ? 0 : ticksToUs(servo_info[this->servoIndex].ticks) + TRIM_DURATION;
}
bool Servo::attached() { return servo_info[this->servoIndex].Pin.isActive; }
void Servo::move(int value) {
constexpr uint16_t servo_delay[] = SERVO_DELAY;
static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long.");
if (this->attach(0) >= 0) {
this->write(value);
delay(servo_delay[this->servoIndex]);
#if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE)
this->detach();
#endif
}
}
#endif #endif // ARDUINO_ARCH_AVR

@ -0,0 +1,67 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef SPI_PINS_H_
#define SPI_PINS_H_
/**
* Define SPI Pins: SCK, MISO, MOSI, SS
*/
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
#define AVR_SCK_PIN 13
#define AVR_MISO_PIN 12
#define AVR_MOSI_PIN 11
#define AVR_SS_PIN 10
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
#define AVR_SCK_PIN 7
#define AVR_MISO_PIN 6
#define AVR_MOSI_PIN 5
#define AVR_SS_PIN 4
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define AVR_SCK_PIN 52
#define AVR_MISO_PIN 50
#define AVR_MOSI_PIN 51
#define AVR_SS_PIN 53
#elif defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__)
#define AVR_SCK_PIN 21
#define AVR_MISO_PIN 23
#define AVR_MOSI_PIN 22
#define AVR_SS_PIN 20
#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
#define AVR_SCK_PIN 10
#define AVR_MISO_PIN 12
#define AVR_MOSI_PIN 11
#define AVR_SS_PIN 16
#endif
#ifndef SCK_PIN
#define SCK_PIN AVR_SCK_PIN
#endif
#ifndef MISO_PIN
#define MISO_PIN AVR_MISO_PIN
#endif
#ifndef MOSI_PIN
#define MOSI_PIN AVR_MOSI_PIN
#endif
#ifndef SS_PIN
#define SS_PIN AVR_SS_PIN
#endif
#endif /* SPI_PINS_H_ */

@ -20,11 +20,13 @@
* *
*/ */
#include "Marlin.h" #ifdef ARDUINO_ARCH_AVR
#include "../../../Marlin.h"
#if ENABLED(USE_WATCHDOG) #if ENABLED(USE_WATCHDOG)
#include "watchdog.h" #include "watchdog_AVR.h"
// Initialize watchdog with a 4 sec interrupt time // Initialize watchdog with a 4 sec interrupt time
void watchdog_init() { void watchdog_init() {
@ -54,3 +56,4 @@ void watchdog_init() {
#endif // WATCHDOG_RESET_MANUAL #endif // WATCHDOG_RESET_MANUAL
#endif // USE_WATCHDOG #endif // USE_WATCHDOG
#endif // ARDUINO_ARCH_AVR

@ -20,10 +20,11 @@
* *
*/ */
#ifndef WATCHDOG_H #ifndef WATCHDOG_AVR_H
#define WATCHDOG_H #define WATCHDOG_AVR_H
//#include "../../../Marlin.h"
#include "Marlin.h"
#include <avr/wdt.h> #include <avr/wdt.h>
// Initialize watchdog with a 4 second interrupt time // Initialize watchdog with a 4 second interrupt time

@ -0,0 +1,53 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAL_ENDSTOP_INTERRUPTS_H_
#define HAL_ENDSTOP_INTERRUPTS_H_
volatile uint8_t e_hit = 0; // Different from 0 when the endstops should be tested in detail.
// Must be reset to 0 by the test function when finished.
// This is what is really done inside the interrupts.
FORCE_INLINE void endstop_ISR_worker( void ) {
e_hit = 2; // Because the detection of a e-stop hit has a 1 step debouncer it has to be called at least twice.
}
// One ISR for all EXT-Interrupts
void endstop_ISR(void) { endstop_ISR_worker(); }
#ifdef ARDUINO_ARCH_AVR
#include "HAL_AVR/endstop_interrupts.h"
#elif defined(ARDUINO_ARCH_SAM)
#include "HAL_DUE/endstop_interrupts.h"
#elif IS_32BIT_TEENSY
#include "HAL_TEENSY35_36/endstop_interrupts.h"
#else
#error Unsupported Platform!
#endif
#endif /* HAL_ENDSTOP_INTERRUPTS_H_ */

@ -0,0 +1,35 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAL_PINSDEBUG_H
#ifdef ARDUINO_ARCH_AVR
#include "HAL_AVR/HAL_pinsDebug_AVR.h"
#elif defined(ARDUINO_ARCH_SAM)
#include "HAL_DUE/HAL_pinsDebug_Due.h"
#elif IS_32BIT_TEENSY
#include "HAL_TEENSY35_36/HAL_pinsDebug_Teensy.h"
#else
#error Unsupported Platform!
#endif
#endif

@ -0,0 +1,39 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAL_SPI_PINS_H_
#define HAL_SPI_PINS_H_
#include "MarlinConfig.h"
#ifdef ARDUINO_ARCH_SAM
#include "HAL_DUE/spi_pins.h"
#elif defined(IS_32BIT_TEENSY)
#include "HAL_TEENSY35_36/spi_pins.h"
#elif defined(ARDUINO_ARCH_AVR)
#include "HAL_AVR/spi_pins.h"
#else
#error "Unsupported Platform!"
#endif
#endif /* HAL_SPI_PINS_H_ */

@ -0,0 +1,162 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Description: functions for I2C connected external EEPROM.
* Not platform dependent.
*/
#include "../../MarlinConfig.h"
#if ENABLED(I2C_EEPROM)
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include "HAL.h"
#include <Wire.h>
// --------------------------------------------------------------------------
// Externals
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Local defines
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Types
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Variables
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Private Variables
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Function prototypes
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Private functions
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
static bool eeprom_initialised = false;
static uint8_t eeprom_device_address = 0x50;
static void eeprom_init(void) {
if (!eeprom_initialised) {
Wire.begin();
eeprom_initialised = true;
}
}
void eeprom_write_byte(unsigned char *pos, unsigned char value) {
unsigned eeprom_address = (unsigned) pos;
eeprom_init();
Wire.beginTransmission(eeprom_device_address);
Wire.write((int)(eeprom_address >> 8)); // MSB
Wire.write((int)(eeprom_address & 0xFF)); // LSB
Wire.write(value);
Wire.endTransmission();
// wait for write cycle to complete
// this could be done more efficiently with "acknowledge polling"
delay(5);
}
// WARNING: address is a page address, 6-bit end will wrap around
// also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
void eeprom_update_block(const void* pos, void* eeprom_address, size_t n) {
uint8_t eeprom_temp[32] = {0};
uint8_t flag = 0;
eeprom_init();
Wire.beginTransmission(eeprom_device_address);
Wire.write((int)((unsigned)eeprom_address >> 8)); // MSB
Wire.write((int)((unsigned)eeprom_address & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(eeprom_device_address, (byte)n);
for (byte c = 0; c < n; c++) {
if (Wire.available()) eeprom_temp[c] = Wire.read();
flag |= (eeprom_temp[c] ^ *((uint8_t*)pos + c));
}
if (flag) {
Wire.beginTransmission(eeprom_device_address);
Wire.write((int)((unsigned)eeprom_address >> 8)); // MSB
Wire.write((int)((unsigned)eeprom_address & 0xFF)); // LSB
Wire.write((uint8_t*)(pos), n);
Wire.endTransmission();
// wait for write cycle to complete
// this could be done more efficiently with "acknowledge polling"
delay(5);
}
}
unsigned char eeprom_read_byte(unsigned char *pos) {
byte data = 0xFF;
unsigned eeprom_address = (unsigned) pos;
eeprom_init ();
Wire.beginTransmission(eeprom_device_address);
Wire.write((int)(eeprom_address >> 8)); // MSB
Wire.write((int)(eeprom_address & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(eeprom_device_address, (byte)1);
if (Wire.available())
data = Wire.read();
return data;
}
// maybe let's not read more than 30 or 32 bytes at a time!
void eeprom_read_block(void* pos, const void* eeprom_address, size_t n) {
eeprom_init();
Wire.beginTransmission(eeprom_device_address);
Wire.write((int)((unsigned)eeprom_address >> 8)); // MSB
Wire.write((int)((unsigned)eeprom_address & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(eeprom_device_address, (byte)n);
for (byte c = 0; c < n; c++ )
if (Wire.available()) *((uint8_t*)pos + c) = Wire.read();
}
#endif // ENABLED(I2C_EEPROM)

@ -0,0 +1,117 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Description: functions for SPI connected external EEPROM.
* Not platform dependent.
*/
#include "../../MarlinConfig.h"
#if ENABLED(SPI_EEPROM)
#include "HAL.h"
#define CMD_WREN 6 // WREN
#define CMD_READ 2 // WRITE
#define CMD_WRITE 2 // WRITE
uint8_t eeprom_read_byte(uint8_t* pos) {
uint8_t v;
uint8_t eeprom_temp[3];
// set read location
// begin transmission from device
eeprom_temp[0] = CMD_READ;
eeprom_temp[1] = ((unsigned)pos>>8) & 0xFF; // addr High
eeprom_temp[2] = (unsigned)pos& 0xFF; // addr Low
digitalWrite(SPI_EEPROM1_CS, HIGH);
digitalWrite(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3);
v = spiRec(SPI_CHAN_EEPROM1);
digitalWrite(SPI_EEPROM1_CS, HIGH);
return v;
}
void eeprom_read_block(void* dest, const void* eeprom_address, size_t n) {
uint8_t eeprom_temp[3];
// set read location
// begin transmission from device
eeprom_temp[0] = CMD_READ;
eeprom_temp[1] = ((unsigned)eeprom_address>>8) & 0xFF; // addr High
eeprom_temp[2] = (unsigned)eeprom_address& 0xFF; // addr Low
digitalWrite(SPI_EEPROM1_CS, HIGH);
digitalWrite(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3);
uint8_t *p_dest = (uint8_t *)dest;
while (n--)
*p_dest++ = spiRec(SPI_CHAN_EEPROM1);
digitalWrite(SPI_EEPROM1_CS, HIGH);
}
void eeprom_write_byte(uint8_t* pos, uint8_t value) {
uint8_t eeprom_temp[3];
/*write enable*/
eeprom_temp[0] = CMD_WREN;
digitalWrite(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 1);
digitalWrite(SPI_EEPROM1_CS, HIGH);
delay(1);
/*write addr*/
eeprom_temp[0] = CMD_WRITE;
eeprom_temp[1] = ((unsigned)pos>>8) & 0xFF; //addr High
eeprom_temp[2] = (unsigned)pos & 0xFF; //addr Low
digitalWrite(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3);
spiSend(SPI_CHAN_EEPROM1, value);
digitalWrite(SPI_EEPROM1_CS, HIGH);
delay(7); // wait for page write to complete
}
void eeprom_update_block(const void* src, void* eeprom_address, size_t n) {
uint8_t eeprom_temp[3];
/*write enable*/
eeprom_temp[0] = CMD_WREN;
digitalWrite(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 1);
digitalWrite(SPI_EEPROM1_CS, HIGH);
delay(1);
/*write addr*/
eeprom_temp[0] = CMD_WRITE;
eeprom_temp[1] = ((unsigned)eeprom_address>>8) & 0xFF; //addr High
eeprom_temp[2] = (unsigned)eeprom_address & 0xFF; //addr Low
digitalWrite(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3);
spiSend(SPI_CHAN_EEPROM1, (const uint8_t*)src, n);
digitalWrite(SPI_EEPROM1_CS, HIGH);
delay(7); // wait for page write to complete
}
#endif // ENABLED(SPI_EEPROM)

@ -0,0 +1,33 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef MATH_32BIT_H
#define MATH_32BIT_H
/**
* Math helper functions for 32 bit CPUs
*/
#define MultiU32X32toH32(intRes, longIn1, longIn2) intRes = ((uint64_t)longIn1 * longIn2 + 0x80000000) >> 32
#define MultiU32X24toH32(intRes, longIn1, longIn2) intRes = ((uint64_t)longIn1 * longIn2 + 0x00800000) >> 24
#endif

@ -0,0 +1,19 @@
#ifndef _PERSISTENT_STORE_H_
#define _PERSISTENT_STORE_H_
#include <stddef.h>
#include <stdint.h>
namespace HAL {
namespace PersistentStore {
bool access_start();
bool access_finish();
bool write_data(int &pos, const uint8_t *value, uint16_t size, uint16_t *crc);
void read_data(int &pos, uint8_t* value, uint16_t size, uint16_t *crc) ;
}
}
#endif /* _PERSISTANT_STORE_H_ */

@ -0,0 +1,168 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* servo.cpp - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
* Copyright (c) 2009 Michael Margolis. All right reserved.
*/
/**
* A servo is activated by creating an instance of the Servo class passing the desired pin to the attach() method.
* The servos are pulsed in the background using the value most recently written using the write() method
*
* Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached.
* Timers are seized as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four.
*
* The methods are:
*
* Servo - Class for manipulating servo motors connected to Arduino pins.
*
* attach(pin) - Attach a servo motor to an i/o pin.
* attach(pin, min, max) - Attach to a pin, setting min and max values in microseconds
* Default min is 544, max is 2400
*
* write() - Set the servo angle in degrees. (Invalid angles over MIN_PULSE_WIDTH are treated as µs.)
* writeMicroseconds() - Set the servo pulse width in microseconds.
* move(pin, angle) - Sequence of attach(pin), write(angle), delay(SERVO_DELAY).
* With DEACTIVATE_SERVOS_AFTER_MOVE it detaches after SERVO_DELAY.
* read() - Get the last-written servo pulse width as an angle between 0 and 180.
* readMicroseconds() - Get the last-written servo pulse width in microseconds.
* attached() - Return true if a servo is attached.
* detach() - Stop an attached servo from pulsing its i/o pin.
*
*/
#include "../../MarlinConfig.h"
#include "HAL.h"
#if HAS_SERVOS && !IS_32BIT_TEENSY
//#include <Arduino.h>
#include "servo.h"
#include "servo_private.h"
ServoInfo_t servo_info[MAX_SERVOS]; // static array of servo info structures
uint8_t ServoCount = 0; // the total number of attached servos
#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo
#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo
/************ static functions common to all instances ***********************/
static boolean isTimerActive(timer16_Sequence_t timer) {
// returns true if any servo is active on this timer
for (uint8_t channel = 0; channel < SERVOS_PER_TIMER; channel++) {
if (SERVO(timer, channel).Pin.isActive)
return true;
}
return false;
}
/****************** end of static functions ******************************/
Servo::Servo() {
if (ServoCount < MAX_SERVOS) {
this->servoIndex = ServoCount++; // assign a servo index to this instance
servo_info[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009
}
else
this->servoIndex = INVALID_SERVO; // too many servos
}
int8_t Servo::attach(int pin) {
return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
}
int8_t Servo::attach(int pin, int min, int max) {
if (this->servoIndex >= MAX_SERVOS) return -1;
if (pin > 0) servo_info[this->servoIndex].Pin.nbr = pin;
pinMode(servo_info[this->servoIndex].Pin.nbr, OUTPUT); // set servo pin to output
// todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128
this->min = (MIN_PULSE_WIDTH - min) / 4; //resolution of min/max is 4 uS
this->max = (MAX_PULSE_WIDTH - max) / 4;
// initialize the timer if it has not already been initialized
timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
if (!isTimerActive(timer)) initISR(timer);
servo_info[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive
return this->servoIndex;
}
void Servo::detach() {
servo_info[this->servoIndex].Pin.isActive = false;
timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
if (!isTimerActive(timer)) finISR(timer);
}
void Servo::write(int value) {
if (value < MIN_PULSE_WIDTH) { // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds)
value = map(constrain(value, 0, 180), 0, 180, SERVO_MIN(), SERVO_MAX());
}
this->writeMicroseconds(value);
}
void Servo::writeMicroseconds(int value) {
// calculate and store the values for the given channel
byte channel = this->servoIndex;
if (channel < MAX_SERVOS) { // ensure channel is valid
// ensure pulse width is valid
value = constrain(value, SERVO_MIN(), SERVO_MAX()) - (TRIM_DURATION);
value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - 12 Aug 2009
CRITICAL_SECTION_START;
servo_info[channel].ticks = value;
CRITICAL_SECTION_END;
}
}
// return the value as degrees
int Servo::read() { return map(this->readMicroseconds() + 1, SERVO_MIN(), SERVO_MAX(), 0, 180); }
int Servo::readMicroseconds() {
return (this->servoIndex == INVALID_SERVO) ? 0 : ticksToUs(servo_info[this->servoIndex].ticks) + TRIM_DURATION;
}
bool Servo::attached() { return servo_info[this->servoIndex].Pin.isActive; }
void Servo::move(int value) {
constexpr uint16_t servo_delay[] = SERVO_DELAY;
static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long.");
if (this->attach(0) >= 0) {
this->write(value);
delay(servo_delay[this->servoIndex]);
#if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE)
this->detach();
#endif
}
}
#endif // HAS_SERVOS

@ -69,74 +69,20 @@
#ifndef servo_h #ifndef servo_h
#define servo_h #define servo_h
#include <inttypes.h> #if IS_32BIT_TEENSY
#include "HAL_TEENSY35_36/HAL_Servo_Teensy.h" // Teensy HAL uses an inherited library
#else
/** #include <inttypes.h>
* Defines for 16 bit timers used with Servo library
*
* If _useTimerX is defined then TimerX is a 16 bit timer on the current board
* timer16_Sequence_t enumerates the sequence that the timers should be allocated
* _Nbr_16timers indicates how many 16 bit timers are available.
*
*/
// Say which 16 bit timers can be used and in what order #if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAM)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) // we're good to go
//#define _useTimer1 // Timer 1 is used by the stepper ISR
#define _useTimer3
#define _useTimer4
#if !HAS_MOTOR_CURRENT_PWM
#define _useTimer5 // Timer 5 is used for motor current PWM and can't be used for servos.
#endif
#elif defined(__AVR_ATmega32U4__)
#define _useTimer3
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define _useTimer3
#elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega2561__)
#define _useTimer3
#else #else
// everything else #error "This library only supports boards with an AVR or SAM3X processor."
#endif #endif
typedef enum {
#if ENABLED(_useTimer1)
_timer1,
#endif
#if ENABLED(_useTimer3)
_timer3,
#endif
#if ENABLED(_useTimer4)
_timer4,
#endif
#if ENABLED(_useTimer5)
_timer5,
#endif
_Nbr_16timers
} timer16_Sequence_t;
#define Servo_VERSION 2 // software version of this library #define Servo_VERSION 2 // software version of this library
#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
#define REFRESH_INTERVAL 20000 // minimum time to refresh servos in microseconds
#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer
#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER)
#define INVALID_SERVO 255 // flag indicating an invalid servo index
typedef struct {
uint8_t nbr : 6 ; // a pin number from 0 to 63
uint8_t isActive : 1 ; // true if this channel is enabled, pin not pulsed if false
} ServoPin_t;
typedef struct {
ServoPin_t Pin;
unsigned int ticks;
} ServoInfo_t;
class Servo { class Servo {
public: public:
Servo(); Servo();
@ -158,4 +104,6 @@ class Servo {
int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH
}; };
#endif // !TEENSY
#endif #endif

@ -0,0 +1,103 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
/**
servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
Copyright (c) 2009 Michael Margolis. 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 servo_private_h
#define servo_private_h
#include <inttypes.h>
// Architecture specific include
#ifdef ARDUINO_ARCH_AVR
#include "HAL_AVR/ServoTimers.h"
#elif defined(ARDUINO_ARCH_SAM)
#include "HAL_DUE/ServoTimers.h"
#else
#error "This library only supports boards with an AVR or SAM3X processor."
#endif
// Macros
#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
#define REFRESH_INTERVAL 20000 // minimum time to refresh servos in microseconds
#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer
#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER)
#define INVALID_SERVO 255 // flag indicating an invalid servo index
//
#define usToTicks(_us) (( clockCyclesPerMicrosecond()* _us) / PRESCALER) // converts microseconds to tick (PRESCALER depends on architecture)
#define ticksToUs(_ticks) (( (unsigned)_ticks * PRESCALER)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds
//#define NBR_TIMERS ((MAX_SERVOS) / (SERVOS_PER_TIMER))
// convenience macros
#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / (SERVOS_PER_TIMER))) // returns the timer controlling this servo
#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % (SERVOS_PER_TIMER)) // returns the index of the servo on this timer
#define SERVO_INDEX(_timer,_channel) ((_timer*(SERVOS_PER_TIMER)) + _channel) // macro to access servo index by timer and channel
#define SERVO(_timer,_channel) (servo_info[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel
// Types
typedef struct {
uint8_t nbr : 6 ; // a pin number from 0 to 63
uint8_t isActive : 1 ; // true if this channel is enabled, pin not pulsed if false
} ServoPin_t;
typedef struct {
ServoPin_t Pin;
unsigned int ticks;
} ServoInfo_t;
// Global variables
extern uint8_t ServoCount;
extern ServoInfo_t servo_info[MAX_SERVOS];
// Public functions
extern void initISR(timer16_Sequence_t timer);
extern void finISR(timer16_Sequence_t timer);
#endif

@ -48,11 +48,16 @@
#include "stepper.h" #include "stepper.h"
#include "endstops.h" #include "endstops.h"
#include "planner.h" #include "planner.h"
#if MB(ALLIGATOR)
#include "dac_dac084s085.h"
#endif
#include "temperature.h" #include "temperature.h"
#include "ultralcd.h" #include "ultralcd.h"
#include "language.h" #include "language.h"
#include "cardreader.h" #include "cardreader.h"
#include "speed_lookuptable.h" #ifdef ARDUINO_ARCH_AVR
#include "speed_lookuptable.h"
#endif
#if HAS_DIGIPOTSS #if HAS_DIGIPOTSS
#include <SPI.h> #include <SPI.h>
@ -99,9 +104,9 @@ volatile uint32_t Stepper::step_events_completed = 0; // The number of step even
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
constexpr uint16_t ADV_NEVER = 65535; constexpr HAL_TIMER_TYPE ADV_NEVER = HAL_TIMER_TYPE_MAX;
uint16_t Stepper::nextMainISR = 0, HAL_TIMER_TYPE Stepper::nextMainISR = 0,
Stepper::nextAdvanceISR = ADV_NEVER, Stepper::nextAdvanceISR = ADV_NEVER,
Stepper::eISR_Rate = ADV_NEVER; Stepper::eISR_Rate = ADV_NEVER;
@ -144,9 +149,9 @@ volatile signed char Stepper::count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
long Stepper::counter_m[MIXING_STEPPERS]; long Stepper::counter_m[MIXING_STEPPERS];
#endif #endif
unsigned short Stepper::acc_step_rate; // needed for deceleration start point HAL_TIMER_TYPE Stepper::acc_step_rate; // needed for deceleration start point
uint8_t Stepper::step_loops, Stepper::step_loops_nominal; uint8_t Stepper::step_loops, Stepper::step_loops_nominal;
unsigned short Stepper::OCR1A_nominal; HAL_TIMER_TYPE Stepper::OCR1A_nominal;
volatile long Stepper::endstops_trigsteps[XYZ]; volatile long Stepper::endstops_trigsteps[XYZ];
@ -213,66 +218,7 @@ volatile long Stepper::endstops_trigsteps[XYZ];
#define E_APPLY_STEP(v,Q) E_STEP_WRITE(v) #define E_APPLY_STEP(v,Q) E_STEP_WRITE(v)
#endif #endif
// intRes = longIn1 * longIn2 >> 24
// uses:
// r26 to store 0
// r27 to store bits 16-23 of the 48bit result. The top bit is used to round the two byte result.
// note that the lower two bytes and the upper byte of the 48bit result are not calculated.
// this can cause the result to be out by one as the lower bytes may cause carries into the upper ones.
// B0 A0 are bits 24-39 and are the returned value
// C1 B1 A1 is longIn1
// D2 C2 B2 A2 is longIn2
//
#define MultiU24X32toH16(intRes, longIn1, longIn2) \
asm volatile ( \
"clr r26 \n\t" \
"mul %A1, %B2 \n\t" \
"mov r27, r1 \n\t" \
"mul %B1, %C2 \n\t" \
"movw %A0, r0 \n\t" \
"mul %C1, %C2 \n\t" \
"add %B0, r0 \n\t" \
"mul %C1, %B2 \n\t" \
"add %A0, r0 \n\t" \
"adc %B0, r1 \n\t" \
"mul %A1, %C2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %B1, %B2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %C1, %A2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %B1, %A2 \n\t" \
"add r27, r1 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"lsr r27 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"mul %D2, %A1 \n\t" \
"add %A0, r0 \n\t" \
"adc %B0, r1 \n\t" \
"mul %D2, %B1 \n\t" \
"add %B0, r0 \n\t" \
"clr r1 \n\t" \
: \
"=&r" (intRes) \
: \
"d" (longIn1), \
"d" (longIn2) \
: \
"r26" , "r27" \
)
// Some useful constants
#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
/** /**
* __________________________ * __________________________
@ -345,6 +291,8 @@ void Stepper::set_directions() {
* Stepper Driver Interrupt * Stepper Driver Interrupt
* *
* Directly pulses the stepper motors at high frequency. * Directly pulses the stepper motors at high frequency.
*
* AVR :
* Timer 1 runs at a base frequency of 2MHz, with this ISR using OCR1A compare mode. * Timer 1 runs at a base frequency of 2MHz, with this ISR using OCR1A compare mode.
* *
* OCR1A Frequency * OCR1A Frequency
@ -355,7 +303,9 @@ void Stepper::set_directions() {
* 2000 1 KHz - sleep rate * 2000 1 KHz - sleep rate
* 4000 500 Hz - init rate * 4000 500 Hz - init rate
*/ */
ISR(TIMER1_COMPA_vect) {
HAL_STEP_TIMER_ISR {
HAL_timer_isr_prologue(STEP_TIMER_NUM);
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
Stepper::advance_isr_scheduler(); Stepper::advance_isr_scheduler();
#else #else
@ -363,23 +313,23 @@ ISR(TIMER1_COMPA_vect) {
#endif #endif
} }
#define _ENABLE_ISRs() do { cli(); if (thermalManager.in_temp_isr) CBI(TIMSK0, OCIE0B); else SBI(TIMSK0, OCIE0B); ENABLE_STEPPER_DRIVER_INTERRUPT(); } while(0)
void Stepper::isr() { void Stepper::isr() {
uint16_t ocr_val; HAL_TIMER_TYPE ocr_val;
#define ENDSTOP_NOMINAL_OCR_VAL 3000 // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch #define ENDSTOP_NOMINAL_OCR_VAL 3000 // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
#define OCR_VAL_TOLERANCE 1000 // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms #define OCR_VAL_TOLERANCE 1000 // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
#if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE) #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
// Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars) // Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)
CBI(TIMSK0, OCIE0B); // Temperature ISR DISABLE_TEMPERATURE_INTERRUPT(); // Temperature ISR
DISABLE_STEPPER_DRIVER_INTERRUPT(); DISABLE_STEPPER_DRIVER_INTERRUPT();
#if !defined(CPU_32_BIT)
sei(); sei();
#endif #endif
#endif
#define _SPLIT(L) (ocr_val = (uint16_t)L) #define _SPLIT(L) (ocr_val = (HAL_TIMER_TYPE)L)
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
#define SPLIT(L) _SPLIT(L) #define SPLIT(L) _SPLIT(L)
#else // sample endstops in between step pulses #else // sample endstops in between step pulses
@ -405,10 +355,13 @@ void Stepper::isr() {
} }
_NEXT_ISR(ocr_val); _NEXT_ISR(ocr_val);
#ifdef CPU_32_BIT
//todo: HAL?
#else
NOLESS(OCR1A, TCNT1 + 16); NOLESS(OCR1A, TCNT1 + 16);
#endif
_ENABLE_ISRs(); // re-enable ISRs HAL_ENABLE_ISRs(); // re-enable ISRs
return; return;
} }
#endif #endif
@ -420,8 +373,8 @@ void Stepper::isr() {
#ifdef SD_FINISHED_RELEASECOMMAND #ifdef SD_FINISHED_RELEASECOMMAND
if (!cleaning_buffer_counter && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); if (!cleaning_buffer_counter && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
#endif #endif
_NEXT_ISR(200); // Run at max speed - 10 KHz _NEXT_ISR(HAL_STEPPER_TIMER_RATE / 10000); // Run at max speed - 10 KHz
_ENABLE_ISRs(); // re-enable ISRs HAL_ENABLE_ISRs(); // re-enable ISRs
return; return;
} }
@ -450,8 +403,8 @@ void Stepper::isr() {
#if ENABLED(Z_LATE_ENABLE) #if ENABLED(Z_LATE_ENABLE)
if (current_block->steps[Z_AXIS] > 0) { if (current_block->steps[Z_AXIS] > 0) {
enable_Z(); enable_Z();
_NEXT_ISR(2000); // Run at slow speed - 1 KHz _NEXT_ISR(HAL_STEPPER_TIMER_RATE / 1000); // Run at slow speed - 1 KHz
_ENABLE_ISRs(); // re-enable ISRs HAL_ENABLE_ISRs(); // re-enable ISRs
return; return;
} }
#endif #endif
@ -461,8 +414,8 @@ void Stepper::isr() {
// #endif // #endif
} }
else { else {
_NEXT_ISR(2000); // Run at slow speed - 1 KHz _NEXT_ISR(HAL_STEPPER_TIMER_RATE / 1000); // Run at slow speed - 1 KHz
_ENABLE_ISRs(); // re-enable ISRs HAL_ENABLE_ISRs(); // re-enable ISRs
return; return;
} }
} }
@ -613,7 +566,7 @@ void Stepper::isr() {
* 10µs = 160 or 200 cycles. * 10µs = 160 or 200 cycles.
*/ */
#if EXTRA_CYCLES_XYZE > 20 #if EXTRA_CYCLES_XYZE > 20
uint32_t pulse_start = TCNT0; uint32_t pulse_start = HAL_timer_get_current_count(STEP_TIMER_NUM);
#endif #endif
#if HAS_X_STEP #if HAS_X_STEP
@ -645,8 +598,8 @@ void Stepper::isr() {
// For minimum pulse time wait before stopping pulses // For minimum pulse time wait before stopping pulses
#if EXTRA_CYCLES_XYZE > 20 #if EXTRA_CYCLES_XYZE > 20
while (EXTRA_CYCLES_XYZE > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } while (EXTRA_CYCLES_XYZE > (uint32_t)(HAL_timer_get_current_count(STEP_TIMER_NUM) - pulse_start) * (STEPPER_TIMER_PRESCALE)) { /* nada */ }
pulse_start = TCNT0; pulse_start = HAL_timer_get_current_count(STEP_TIMER_NUM);
#elif EXTRA_CYCLES_XYZE > 0 #elif EXTRA_CYCLES_XYZE > 0
DELAY_NOPS(EXTRA_CYCLES_XYZE); DELAY_NOPS(EXTRA_CYCLES_XYZE);
#endif #endif
@ -686,7 +639,7 @@ void Stepper::isr() {
// For minimum pulse time wait after stopping pulses also // For minimum pulse time wait after stopping pulses also
#if EXTRA_CYCLES_XYZE > 20 #if EXTRA_CYCLES_XYZE > 20
if (i) while (EXTRA_CYCLES_XYZE > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } if (i) while (EXTRA_CYCLES_XYZE > (uint32_t)(HAL_timer_get_current_count(STEP_TIMER_NUM) - pulse_start) * (STEPPER_TIMER_PRESCALE)) { /* nada */ }
#elif EXTRA_CYCLES_XYZE > 0 #elif EXTRA_CYCLES_XYZE > 0
if (i) DELAY_NOPS(EXTRA_CYCLES_XYZE); if (i) DELAY_NOPS(EXTRA_CYCLES_XYZE);
#endif #endif
@ -716,14 +669,18 @@ void Stepper::isr() {
// Calculate new timer value // Calculate new timer value
if (step_events_completed <= (uint32_t)current_block->accelerate_until) { if (step_events_completed <= (uint32_t)current_block->accelerate_until) {
#ifdef CPU_32_BIT
MultiU32X24toH32(acc_step_rate, acceleration_time, current_block->acceleration_rate);
#else
MultiU24X32toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate); MultiU24X32toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate);
#endif
acc_step_rate += current_block->initial_rate; acc_step_rate += current_block->initial_rate;
// upper limit // upper limit
NOMORE(acc_step_rate, current_block->nominal_rate); NOMORE(acc_step_rate, current_block->nominal_rate);
// step_rate to timer interval // step_rate to timer interval
const uint16_t timer = calc_timer(acc_step_rate); const HAL_TIMER_TYPE timer = calc_timer(acc_step_rate);
SPLIT(timer); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL SPLIT(timer); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
_NEXT_ISR(ocr_val); _NEXT_ISR(ocr_val);
@ -764,12 +721,17 @@ void Stepper::isr() {
#endif // ADVANCE or LIN_ADVANCE #endif // ADVANCE or LIN_ADVANCE
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
// TODO: HAL
eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], timer, step_loops); eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], timer, step_loops);
#endif #endif
} }
else if (step_events_completed > (uint32_t)current_block->decelerate_after) { else if (step_events_completed > (uint32_t)current_block->decelerate_after) {
uint16_t step_rate; HAL_TIMER_TYPE step_rate;
#ifdef CPU_32_BIT
MultiU32X24toH32(step_rate, deceleration_time, current_block->acceleration_rate);
#else
MultiU24X32toH16(step_rate, deceleration_time, current_block->acceleration_rate); MultiU24X32toH16(step_rate, deceleration_time, current_block->acceleration_rate);
#endif
if (step_rate < acc_step_rate) { // Still decelerating? if (step_rate < acc_step_rate) { // Still decelerating?
step_rate = acc_step_rate - step_rate; step_rate = acc_step_rate - step_rate;
@ -779,7 +741,7 @@ void Stepper::isr() {
step_rate = current_block->final_rate; step_rate = current_block->final_rate;
// step_rate to timer interval // step_rate to timer interval
const uint16_t timer = calc_timer(step_rate); const HAL_TIMER_TYPE timer = calc_timer(step_rate);
SPLIT(timer); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL SPLIT(timer); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
_NEXT_ISR(ocr_val); _NEXT_ISR(ocr_val);
@ -834,14 +796,20 @@ void Stepper::isr() {
SPLIT(OCR1A_nominal); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL SPLIT(OCR1A_nominal); // split step into multiple ISRs if larger than ENDSTOP_NOMINAL_OCR_VAL
_NEXT_ISR(ocr_val); _NEXT_ISR(ocr_val);
// ensure we're running at the correct step rate, even if we just came off an acceleration // ensure we're running at the correct step rate, even if we just came off an acceleration
step_loops = step_loops_nominal; step_loops = step_loops_nominal;
} }
#if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE) #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
#ifdef CPU_32_BIT
// Make sure stepper interrupt does not monopolise CPU by adjusting count to give about 8 us room
uint32_t stepper_timer_count = HAL_timer_get_count(STEP_TIMER_NUM);
uint32_t stepper_timer_current_count = HAL_timer_get_current_count(STEP_TIMER_NUM) + 8 * HAL_TICKS_PER_US;
HAL_timer_set_count(STEP_TIMER_NUM, stepper_timer_count < stepper_timer_current_count ? stepper_timer_current_count : stepper_timer_count);
#else
NOLESS(OCR1A, TCNT1 + 16); NOLESS(OCR1A, TCNT1 + 16);
#endif #endif
#endif
// If current block is finished, reset pointer // If current block is finished, reset pointer
if (all_steps_done) { if (all_steps_done) {
@ -849,7 +817,7 @@ void Stepper::isr() {
planner.discard_current_block(); planner.discard_current_block();
} }
#if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE) #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
_ENABLE_ISRs(); // re-enable ISRs HAL_ENABLE_ISRs(); // re-enable ISRs
#endif #endif
} }
@ -951,7 +919,7 @@ void Stepper::isr() {
void Stepper::advance_isr_scheduler() { void Stepper::advance_isr_scheduler() {
// Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars) // Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)
CBI(TIMSK0, OCIE0B); // Temperature ISR DISABLE_TEMPERATURE_INTERRUPT(); // Temperature ISR
DISABLE_STEPPER_DRIVER_INTERRUPT(); DISABLE_STEPPER_DRIVER_INTERRUPT();
sei(); sei();
@ -984,7 +952,7 @@ void Stepper::isr() {
NOLESS(OCR1A, TCNT1 + 16); NOLESS(OCR1A, TCNT1 + 16);
// Restore original ISR settings // Restore original ISR settings
_ENABLE_ISRs(); HAL_ENABLE_ISRs();
} }
#endif // ADVANCE or LIN_ADVANCE #endif // ADVANCE or LIN_ADVANCE
@ -996,6 +964,15 @@ void Stepper::init() {
digipot_init(); digipot_init();
#endif #endif
#if MB(ALLIGATOR)
const float motor_current[] = MOTOR_CURRENT;
unsigned int digipot_motor = 0;
for (uint8_t i = 0; i < 3 + EXTRUDERS; i++) {
digipot_motor = 255 * (motor_current[i] / 2.5);
dac084s085::setValue(i, digipot_motor);
}
#endif//MB(ALLIGATOR)
// Init Microstepping Pins // Init Microstepping Pins
#if HAS_MICROSTEPS #if HAS_MICROSTEPS
microstep_init(); microstep_init();
@ -1152,6 +1129,7 @@ void Stepper::init() {
E_AXIS_INIT(4); E_AXIS_INIT(4);
#endif #endif
#ifdef ARDUINO_ARCH_AVR
// waveform generation = 0100 = CTC // waveform generation = 0100 = CTC
SET_WGM(1, CTC_OCRnA); SET_WGM(1, CTC_OCRnA);
@ -1168,6 +1146,11 @@ void Stepper::init() {
// Init Stepper ISR to 122 Hz for quick starting // Init Stepper ISR to 122 Hz for quick starting
OCR1A = 0x4000; OCR1A = 0x4000;
TCNT1 = 0; TCNT1 = 0;
#else
// Init Stepper ISR to 122 Hz for quick starting
HAL_timer_start (STEP_TIMER_NUM, 122);
#endif
ENABLE_STEPPER_DRIVER_INTERRUPT(); ENABLE_STEPPER_DRIVER_INTERRUPT();
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
@ -1663,6 +1646,9 @@ void Stepper::report_positions() {
case 4: microstep_ms(driver, MICROSTEP4); break; case 4: microstep_ms(driver, MICROSTEP4); break;
case 8: microstep_ms(driver, MICROSTEP8); break; case 8: microstep_ms(driver, MICROSTEP8); break;
case 16: microstep_ms(driver, MICROSTEP16); break; case 16: microstep_ms(driver, MICROSTEP16); break;
#if MB(ALLIGATOR)
case 32: microstep_ms(driver, MICROSTEP32); break;
#endif
} }
} }

@ -52,31 +52,6 @@
class Stepper; class Stepper;
extern Stepper stepper; extern Stepper stepper;
// intRes = intIn1 * intIn2 >> 16
// uses:
// r26 to store 0
// r27 to store the byte 1 of the 24 bit result
#define MultiU16X8toH16(intRes, charIn1, intIn2) \
asm volatile ( \
"clr r26 \n\t" \
"mul %A1, %B2 \n\t" \
"movw %A0, r0 \n\t" \
"mul %A1, %A2 \n\t" \
"add %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"lsr r0 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"clr r1 \n\t" \
: \
"=&r" (intRes) \
: \
"d" (charIn1), \
"d" (intIn2) \
: \
"r26" \
)
class Stepper { class Stepper {
public: public:
@ -112,8 +87,9 @@ class Stepper {
static volatile uint32_t step_events_completed; // The number of step events executed in the current block static volatile uint32_t step_events_completed; // The number of step events executed in the current block
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE)
static uint16_t nextMainISR, nextAdvanceISR, eISR_Rate; static HAL_TIMER_TYPE nextMainISR, nextAdvanceISR, eISR_Rate;
#define _NEXT_ISR(T) nextMainISR = T #define _NEXT_ISR(T) nextMainISR = T
#if ENABLED(LIN_ADVANCE) #if ENABLED(LIN_ADVANCE)
static volatile int e_steps[E_STEPPERS]; static volatile int e_steps[E_STEPPERS];
static int final_estep_rate; static int final_estep_rate;
@ -127,14 +103,14 @@ class Stepper {
static long old_advance; static long old_advance;
#endif #endif
#else #else
#define _NEXT_ISR(T) OCR1A = T #define _NEXT_ISR(T) HAL_timer_set_count(STEP_TIMER_NUM, T);
#endif // ADVANCE or LIN_ADVANCE #endif // ADVANCE or LIN_ADVANCE
static long acceleration_time, deceleration_time; static long acceleration_time, deceleration_time;
//unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate; //unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
static unsigned short acc_step_rate; // needed for deceleration start point static HAL_TIMER_TYPE acc_step_rate; // needed for deceleration start point
static uint8_t step_loops, step_loops_nominal; static uint8_t step_loops, step_loops_nominal;
static unsigned short OCR1A_nominal; static HAL_TIMER_TYPE OCR1A_nominal;
static volatile long endstops_trigsteps[XYZ]; static volatile long endstops_trigsteps[XYZ];
static volatile long endstops_stepsTotal, endstops_stepsDone; static volatile long endstops_stepsTotal, endstops_stepsDone;
@ -285,11 +261,29 @@ class Stepper {
private: private:
static FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) { static FORCE_INLINE HAL_TIMER_TYPE calc_timer(HAL_TIMER_TYPE step_rate) {
unsigned short timer; HAL_TIMER_TYPE timer;
NOMORE(step_rate, MAX_STEP_FREQUENCY); NOMORE(step_rate, MAX_STEP_FREQUENCY);
// TODO: HAL: tidy this up, use condtionals_post.h
#ifdef CPU_32_BIT
#if ENABLED(DISABLE_MULTI_STEPPING)
step_loops = 1;
#else
if (step_rate > STEP_DOUBLER_FREQUENCY * 2) { // If steprate > (STEP_DOUBLER_FREQUENCY * 2) kHz >> step 4 times
step_rate >>= 2;
step_loops = 4;
}
else if (step_rate > STEP_DOUBLER_FREQUENCY) { // If steprate > STEP_DOUBLER_FREQUENCY kHz >> step 2 times
step_rate >>= 1;
step_loops = 2;
}
else {
step_loops = 1;
}
#endif
#else
if (step_rate > 20000) { // If steprate > 20kHz >> step 4 times if (step_rate > 20000) { // If steprate > 20kHz >> step 4 times
step_rate >>= 2; step_rate >>= 2;
step_loops = 4; step_loops = 4;
@ -301,19 +295,27 @@ class Stepper {
else { else {
step_loops = 1; step_loops = 1;
} }
#endif
#ifdef CPU_32_BIT
// In case of high-performance processor, it is able to calculate in real-time
timer = (uint32_t)(HAL_STEPPER_TIMER_RATE) / step_rate;
if (timer < (HAL_STEPPER_TIMER_RATE / (STEP_DOUBLER_FREQUENCY * 2))) { // (STEP_DOUBLER_FREQUENCY * 2 kHz - this should never happen)
timer = (HAL_STEPPER_TIMER_RATE / (STEP_DOUBLER_FREQUENCY * 2));
}
#else
NOLESS(step_rate, F_CPU / 500000); NOLESS(step_rate, F_CPU / 500000);
step_rate -= F_CPU / 500000; // Correct for minimal speed step_rate -= F_CPU / 500000; // Correct for minimal speed
if (step_rate >= (8 * 256)) { // higher step rate if (step_rate >= (8 * 256)) { // higher step rate
unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate >> 8)][0]; unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate >> 8)][0];
unsigned char tmp_step_rate = (step_rate & 0x00FF); unsigned char tmp_step_rate = (step_rate & 0x00ff);
unsigned short gain = (unsigned short)pgm_read_word_near(table_address + 2); unsigned short gain = (unsigned short)pgm_read_word_near(table_address + 2);
MultiU16X8toH16(timer, tmp_step_rate, gain); MultiU16X8toH16(timer, tmp_step_rate, gain);
timer = (unsigned short)pgm_read_word_near(table_address) - timer; timer = (unsigned short)pgm_read_word_near(table_address) - timer;
} }
else { // lower step rates else { // lower step rates
unsigned short table_address = (unsigned short)&speed_lookuptable_slow[0][0]; unsigned short table_address = (unsigned short)&speed_lookuptable_slow[0][0];
table_address += ((step_rate) >> 1) & 0xFFFC; table_address += ((step_rate) >> 1) & 0xfffc;
timer = (unsigned short)pgm_read_word_near(table_address); timer = (unsigned short)pgm_read_word_near(table_address);
timer -= (((unsigned short)pgm_read_word_near(table_address + 2) * (unsigned char)(step_rate & 0x0007)) >> 3); timer -= (((unsigned short)pgm_read_word_near(table_address + 2) * (unsigned char)(step_rate & 0x0007)) >> 3);
} }
@ -322,6 +324,8 @@ class Stepper {
MYSERIAL.print(MSG_STEPPER_TOO_HIGH); MYSERIAL.print(MSG_STEPPER_TOO_HIGH);
MYSERIAL.println(step_rate); MYSERIAL.println(step_rate);
} }
#endif
return timer; return timer;
} }

@ -32,7 +32,7 @@
#include "language.h" #include "language.h"
#if ENABLED(HEATER_0_USES_MAX6675) #if ENABLED(HEATER_0_USES_MAX6675)
#include "spi.h" #include "private_spi.h"
#endif #endif
#if ENABLED(BABYSTEPPING) #if ENABLED(BABYSTEPPING)
@ -43,10 +43,6 @@
#include "endstops.h" #include "endstops.h"
#endif #endif
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
#endif
#ifdef K1 // Defined in Configuration.h in the PID settings #ifdef K1 // Defined in Configuration.h in the PID settings
#define K2 (1.0-K1) #define K2 (1.0-K1)
#endif #endif
@ -1054,38 +1050,39 @@ void Temperature::init() {
#endif // HEATER_0_USES_MAX6675 #endif // HEATER_0_USES_MAX6675
#ifdef DIDR2 HAL_adc_init();
#define ANALOG_SELECT(pin) do{ if (pin < 8) SBI(DIDR0, pin); else SBI(DIDR2, pin - 8); }while(0)
#else
#define ANALOG_SELECT(pin) do{ SBI(DIDR0, pin); }while(0)
#endif
// Set analog inputs
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
DIDR0 = 0;
#ifdef DIDR2
DIDR2 = 0;
#endif
#if HAS_TEMP_0 #if HAS_TEMP_0
ANALOG_SELECT(TEMP_0_PIN); HAL_ANALOG_SELECT(TEMP_0_PIN);
#endif #endif
#if HAS_TEMP_1 #if HAS_TEMP_1
ANALOG_SELECT(TEMP_1_PIN); HAL_ANALOG_SELECT(TEMP_1_PIN);
#endif #endif
#if HAS_TEMP_2 #if HAS_TEMP_2
ANALOG_SELECT(TEMP_2_PIN); HAL_ANALOG_SELECT(TEMP_2_PIN);
#endif #endif
#if HAS_TEMP_3 #if HAS_TEMP_3
ANALOG_SELECT(TEMP_3_PIN); HAL_ANALOG_SELECT(TEMP_3_PIN);
#endif #endif
#if HAS_TEMP_4 #if HAS_TEMP_4
ANALOG_SELECT(TEMP_4_PIN); HAL_ANALOG_SELECT(TEMP_4_PIN);
#endif #endif
#if HAS_TEMP_BED #if HAS_TEMP_BED
ANALOG_SELECT(TEMP_BED_PIN); HAL_ANALOG_SELECT(TEMP_BED_PIN);
#endif #endif
#if ENABLED(FILAMENT_WIDTH_SENSOR) #if ENABLED(FILAMENT_WIDTH_SENSOR)
ANALOG_SELECT(FILWIDTH_PIN); HAL_ANALOG_SELECT(FILWIDTH_PIN);
#endif
// todo: HAL: fix abstraction
#ifdef ARDUINO_ARCH_AVR
// Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt
OCR0B = 128;
SBI(TIMSK0, OCIE0B);
#else
HAL_timer_start (TEMP_TIMER_NUM, TEMP_TIMER_FREQUENCY);
HAL_timer_enable_interrupt (TEMP_TIMER_NUM);
#endif #endif
#if HAS_AUTO_FAN_0 #if HAS_AUTO_FAN_0
@ -1139,11 +1136,6 @@ void Temperature::init() {
#endif #endif
#endif #endif
// Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt
OCR0B = 128;
SBI(TIMSK0, OCIE0B);
// Wait for temperature measurement to settle // Wait for temperature measurement to settle
delay(250); delay(250);
@ -1415,12 +1407,12 @@ void Temperature::disable_all_heaters() {
uint32_t max6675_temp = 2000; uint32_t max6675_temp = 2000;
#define MAX6675_ERROR_MASK 7 #define MAX6675_ERROR_MASK 7
#define MAX6675_DISCARD_BITS 18 #define MAX6675_DISCARD_BITS 18
#define MAX6675_SPEED_BITS (_BV(SPR1)) // clock ÷ 64 #define MAX6675_SPEED_BITS 3 // (_BV(SPR1)) // clock ÷ 64
#else #else
uint16_t max6675_temp = 2000; uint16_t max6675_temp = 2000;
#define MAX6675_ERROR_MASK 4 #define MAX6675_ERROR_MASK 4
#define MAX6675_DISCARD_BITS 3 #define MAX6675_DISCARD_BITS 3
#define MAX6675_SPEED_BITS (_BV(SPR0)) // clock ÷ 16 #define MAX6675_SPEED_BITS 2 // (_BV(SPR0)) // clock ÷ 16
#endif #endif
int Temperature::read_max6675() { int Temperature::read_max6675() {
@ -1433,14 +1425,8 @@ void Temperature::disable_all_heaters() {
next_max6675_ms = ms + MAX6675_HEAT_INTERVAL; next_max6675_ms = ms + MAX6675_HEAT_INTERVAL;
CBI( spiBegin();
#ifdef PRR spiInit(MAX6675_SPEED_BITS);
PRR
#elif defined(PRR0)
PRR0
#endif
, PRSPI);
SPCR = _BV(MSTR) | _BV(SPE) | MAX6675_SPEED_BITS;
WRITE(MAX6675_SS, 0); // enable TT_MAX6675 WRITE(MAX6675_SS, 0); // enable TT_MAX6675
@ -1451,7 +1437,7 @@ void Temperature::disable_all_heaters() {
// Read a big-endian temperature value // Read a big-endian temperature value
max6675_temp = 0; max6675_temp = 0;
for (uint8_t i = sizeof(max6675_temp); i--;) { for (uint8_t i = sizeof(max6675_temp); i--;) {
max6675_temp |= max6675_spi.receive(); max6675_temp |= spiRec();
if (i > 0) max6675_temp <<= 8; // shift left if not the last byte if (i > 0) max6675_temp <<= 8; // shift left if not the last byte
} }
@ -1607,7 +1593,10 @@ void Temperature::set_current_temp_raw() {
* - For PINS_DEBUGGING, monitor and report endstop pins * - For PINS_DEBUGGING, monitor and report endstop pins
* - For ENDSTOP_INTERRUPTS_FEATURE check endstops if flagged * - For ENDSTOP_INTERRUPTS_FEATURE check endstops if flagged
*/ */
ISR(TIMER0_COMPB_vect) { Temperature::isr(); } HAL_TEMP_TIMER_ISR {
HAL_timer_isr_prologue (TEMP_TIMER_NUM);
Temperature::isr();
}
volatile bool Temperature::in_temp_isr = false; volatile bool Temperature::in_temp_isr = false;
@ -1618,8 +1607,10 @@ void Temperature::isr() {
in_temp_isr = true; in_temp_isr = true;
// Allow UART and stepper ISRs // Allow UART and stepper ISRs
CBI(TIMSK0, OCIE0B); //Disable Temperature ISR DISABLE_TEMPERATURE_INTERRUPT(); //Disable Temperature ISR
#if !defined(CPU_32_BIT)
sei(); sei();
#endif
static int8_t temp_count = -1; static int8_t temp_count = -1;
static ADCSensorState adc_sensor_state = StartupDelay; static ADCSensorState adc_sensor_state = StartupDelay;
@ -1914,13 +1905,6 @@ void Temperature::isr() {
* This gives each ADC 0.9765ms to charge up. * This gives each ADC 0.9765ms to charge up.
*/ */
#define SET_ADMUX_ADCSRA(pin) ADMUX = _BV(REFS0) | (pin & 0x07); SBI(ADCSRA, ADSC)
#ifdef MUX5
#define START_ADC(pin) if (pin > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#else
#define START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#endif
switch (adc_sensor_state) { switch (adc_sensor_state) {
case SensorsReady: { case SensorsReady: {
@ -1940,66 +1924,66 @@ void Temperature::isr() {
#if HAS_TEMP_0 #if HAS_TEMP_0
case PrepareTemp_0: case PrepareTemp_0:
START_ADC(TEMP_0_PIN); HAL_START_ADC(TEMP_0_PIN);
break; break;
case MeasureTemp_0: case MeasureTemp_0:
raw_temp_value[0] += ADC; raw_temp_value[0] += HAL_READ_ADC;
break; break;
#endif #endif
#if HAS_TEMP_BED #if HAS_TEMP_BED
case PrepareTemp_BED: case PrepareTemp_BED:
START_ADC(TEMP_BED_PIN); HAL_START_ADC(TEMP_BED_PIN);
break; break;
case MeasureTemp_BED: case MeasureTemp_BED:
raw_temp_bed_value += ADC; raw_temp_bed_value += HAL_READ_ADC;
break; break;
#endif #endif
#if HAS_TEMP_1 #if HAS_TEMP_1
case PrepareTemp_1: case PrepareTemp_1:
START_ADC(TEMP_1_PIN); HAL_START_ADC(TEMP_1_PIN);
break; break;
case MeasureTemp_1: case MeasureTemp_1:
raw_temp_value[1] += ADC; raw_temp_value[1] += HAL_READ_ADC;
break; break;
#endif #endif
#if HAS_TEMP_2 #if HAS_TEMP_2
case PrepareTemp_2: case PrepareTemp_2:
START_ADC(TEMP_2_PIN); HAL_START_ADC(TEMP_2_PIN);
break; break;
case MeasureTemp_2: case MeasureTemp_2:
raw_temp_value[2] += ADC; raw_temp_value[2] += HAL_READ_ADC;
break; break;
#endif #endif
#if HAS_TEMP_3 #if HAS_TEMP_3
case PrepareTemp_3: case PrepareTemp_3:
START_ADC(TEMP_3_PIN); HAL_START_ADC(TEMP_3_PIN);
break; break;
case MeasureTemp_3: case MeasureTemp_3:
raw_temp_value[3] += ADC; raw_temp_value[3] += HAL_READ_ADC;
break; break;
#endif #endif
#if HAS_TEMP_4 #if HAS_TEMP_4
case PrepareTemp_4: case PrepareTemp_4:
START_ADC(TEMP_4_PIN); HAL_START_ADC(TEMP_4_PIN);
break; break;
case MeasureTemp_4: case MeasureTemp_4:
raw_temp_value[4] += ADC; raw_temp_value[4] += HAL_READ_ADC;
break; break;
#endif #endif
#if ENABLED(FILAMENT_WIDTH_SENSOR) #if ENABLED(FILAMENT_WIDTH_SENSOR)
case Prepare_FILWIDTH: case Prepare_FILWIDTH:
START_ADC(FILWIDTH_PIN); HAL_START_ADC(FILWIDTH_PIN);
break; break;
case Measure_FILWIDTH: case Measure_FILWIDTH:
if (ADC > 102) { // Make sure ADC is reading > 0.5 volts, otherwise don't read. if (HAL_READ_ADC > 102) { // Make sure ADC is reading > 0.5 volts, otherwise don't read.
raw_filwidth_value -= (raw_filwidth_value >> 7); // Subtract 1/128th of the raw_filwidth_value raw_filwidth_value -= (raw_filwidth_value >> 7); // Subtract 1/128th of the raw_filwidth_value
raw_filwidth_value += ((unsigned long)ADC << 7); // Add new ADC reading, scaled by 128 raw_filwidth_value += ((unsigned long)HAL_READ_ADC << 7); // Add new ADC reading, scaled by 128
} }
break; break;
#endif #endif
@ -2130,7 +2114,9 @@ void Temperature::isr() {
} }
#endif #endif
#if !defined(CPU_32_BIT)
cli(); cli();
#endif
in_temp_isr = false; in_temp_isr = false;
SBI(TIMSK0, OCIE0B); //re-enable Temperature ISR ENABLE_TEMPERATURE_INTERRUPT(); //re-enable Temperature ISR
} }

@ -125,7 +125,7 @@ class Temperature {
#endif #endif
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) #if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)
#define PID_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / (F_CPU / 64.0 / 256.0)) #define PID_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / TEMP_TIMER_FREQUENCY)
#endif #endif
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)

@ -1371,7 +1371,7 @@
z_values[x][y] -= tmp_z_values[x][y]; z_values[x][y] -= tmp_z_values[x][y];
} }
mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const MeshPointType type, const float &lx, const float &ly, const bool probe_as_reference, unsigned int bits[16], const bool far_flag) { mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const MeshPointType type, const float &lx, const float &ly, const bool probe_as_reference, uint16_t bits[16], const bool far_flag) {
mesh_index_pair out_mesh; mesh_index_pair out_mesh;
out_mesh.x_index = out_mesh.y_index = -1; out_mesh.x_index = out_mesh.y_index = -1;

@ -27,7 +27,6 @@
#include "ubl.h" #include "ubl.h"
#include "planner.h" #include "planner.h"
#include "stepper.h" #include "stepper.h"
#include <avr/io.h>
#include <math.h> #include <math.h>
extern float destination[XYZE]; extern float destination[XYZE];
@ -737,4 +736,3 @@
#endif // UBL_DELTA #endif // UBL_DELTA
#endif // AUTO_BED_LEVELING_UBL #endif // AUTO_BED_LEVELING_UBL

@ -184,6 +184,7 @@ uint16_t max_display_update_time = 0;
void menu_action_setting_edit_callback_ ## _name(const char * const pstr, _type * const ptr, const _type minValue, const _type maxValue, const screenFunc_t callback, const bool live=false); \ void menu_action_setting_edit_callback_ ## _name(const char * const pstr, _type * const ptr, const _type minValue, const _type maxValue, const screenFunc_t callback, const bool live=false); \
typedef void _name##_void typedef void _name##_void
DECLARE_MENU_EDIT_TYPE(uint32_t, long5);
DECLARE_MENU_EDIT_TYPE(int16_t, int3); DECLARE_MENU_EDIT_TYPE(int16_t, int3);
DECLARE_MENU_EDIT_TYPE(uint8_t, int8); DECLARE_MENU_EDIT_TYPE(uint8_t, int8);
DECLARE_MENU_EDIT_TYPE(float, float3); DECLARE_MENU_EDIT_TYPE(float, float3);
@ -193,7 +194,6 @@ uint16_t max_display_update_time = 0;
DECLARE_MENU_EDIT_TYPE(float, float51); DECLARE_MENU_EDIT_TYPE(float, float51);
DECLARE_MENU_EDIT_TYPE(float, float52); DECLARE_MENU_EDIT_TYPE(float, float52);
DECLARE_MENU_EDIT_TYPE(float, float62); DECLARE_MENU_EDIT_TYPE(float, float62);
DECLARE_MENU_EDIT_TYPE(uint32_t, long5);
void menu_action_setting_edit_bool(const char* pstr, bool* ptr); void menu_action_setting_edit_bool(const char* pstr, bool* ptr);
void menu_action_setting_edit_callback_bool(const char* pstr, bool* ptr, screenFunc_t callbackFunc); void menu_action_setting_edit_callback_bool(const char* pstr, bool* ptr, screenFunc_t callbackFunc);
@ -4039,6 +4039,7 @@ void kill_screen(const char* lcd_msg) {
} \ } \
typedef void _name typedef void _name
DEFINE_MENU_EDIT_TYPE(uint32_t, long5, ftostr5rj, 0.01);
DEFINE_MENU_EDIT_TYPE(int16_t, int3, itostr3, 1); DEFINE_MENU_EDIT_TYPE(int16_t, int3, itostr3, 1);
DEFINE_MENU_EDIT_TYPE(uint8_t, int8, i8tostr3, 1); DEFINE_MENU_EDIT_TYPE(uint8_t, int8, i8tostr3, 1);
DEFINE_MENU_EDIT_TYPE(float, float3, ftostr3, 1.0); DEFINE_MENU_EDIT_TYPE(float, float3, ftostr3, 1.0);
@ -4048,7 +4049,6 @@ void kill_screen(const char* lcd_msg) {
DEFINE_MENU_EDIT_TYPE(float, float51, ftostr51sign, 10.0); DEFINE_MENU_EDIT_TYPE(float, float51, ftostr51sign, 10.0);
DEFINE_MENU_EDIT_TYPE(float, float52, ftostr52sign, 100.0); DEFINE_MENU_EDIT_TYPE(float, float52, ftostr52sign, 100.0);
DEFINE_MENU_EDIT_TYPE(float, float62, ftostr62rj, 100.0); DEFINE_MENU_EDIT_TYPE(float, float62, ftostr62rj, 100.0);
DEFINE_MENU_EDIT_TYPE(uint32_t, long5, ftostr5rj, 0.01);
/** /**
* *

@ -869,6 +869,7 @@ static void lcd_implementation_status_screen() {
} \ } \
typedef void _name##_void typedef void _name##_void
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(uint32_t, long5, ftostr5rj);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(int16_t, int3, itostr3); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(int16_t, int3, itostr3);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(uint8_t, int8, i8tostr3); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(uint8_t, int8, i8tostr3);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float3, ftostr3); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float3, ftostr3);
@ -878,7 +879,6 @@ static void lcd_implementation_status_screen() {
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float51, ftostr51sign); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float51, ftostr51sign);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float52, ftostr52sign); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float52, ftostr52sign);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float62, ftostr62rj); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float62, ftostr62rj);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(uint32_t, long5, ftostr5rj);
#define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) #define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) #define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))

@ -976,6 +976,7 @@ static void lcd_implementation_status_screen() {
} \ } \
typedef void _name##_void typedef void _name##_void
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(uint32_t, long5, ftostr5rj);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(int16_t, int3, itostr3); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(int16_t, int3, itostr3);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(uint8_t, int8, i8tostr3); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(uint8_t, int8, i8tostr3);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float3, ftostr3); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float3, ftostr3);
@ -985,7 +986,6 @@ static void lcd_implementation_status_screen() {
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float51, ftostr51sign); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float51, ftostr51sign);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float52, ftostr52sign); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float52, ftostr52sign);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float62, ftostr62rj); DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(float, float62, ftostr62rj);
DEFINE_LCD_IMPLEMENTATION_DRAWMENU_SETTING_EDIT_TYPE(uint32_t, long5, ftostr5rj);
#define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) #define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) #define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))

Loading…
Cancel
Save