Implement HAL and apply macros across code-base

Implement AVR Platform
This commit is contained in:
Christopher Pepper
2017-06-18 00:36:10 +01:00
committed by Scott Lahteine
parent fb04dfcda8
commit 4b16fa3272
65 changed files with 2264 additions and 761 deletions

94
Marlin/src/HAL/HAL.h Normal file
View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,595 @@
/**
* 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_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;
#define NAME_FORMAT "%-35s" // one place to specify the format of all the sources of names
// "-" left justify, "28" minimum width of name, pad with blanks
#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && ((P) <= analogInputToDigitalPin(15) || (P) <= analogInputToDigitalPin(7)))
/**
* This routine minimizes RAM usage by creating a FLASH resident array to
* store the pin names, pin numbers and analog/digital flag.
*
* Creating the array in FLASH is a two pass process. The first pass puts the
* name strings into FLASH. The second pass actually creates the array.
*
* Both passes use the same pin list. The list contains two macro names. The
* actual macro definitions are changed depending on which pass is being done.
*
*/
// first pass - put the name strings into FLASH
#define _ADD_PIN_2(PIN_NAME, ENTRY_NAME) static const char ENTRY_NAME[] PROGMEM = { PIN_NAME };
#define _ADD_PIN(PIN_NAME, COUNTER) _ADD_PIN_2(PIN_NAME, entry_NAME_##COUNTER)
#define REPORT_NAME_DIGITAL(NAME, COUNTER) _ADD_PIN(#NAME, COUNTER)
#define REPORT_NAME_ANALOG(NAME, COUNTER) _ADD_PIN(#NAME, COUNTER)
#include "../../../pinsDebug_list.h"
#line 51
// manually add pins that have names that are macros which don't play well with these macros
#if SERIAL_PORT == 0 && (AVR_ATmega2560_FAMILY || AVR_ATmega1284_FAMILY)
static const char RXD_NAME[] PROGMEM = { "RXD" };
static const char TXD_NAME[] PROGMEM = { "TXD" };
#endif
/////////////////////////////////////////////////////////////////////////////
// second pass - create the array
#undef _ADD_PIN_2
#undef _ADD_PIN
#undef REPORT_NAME_DIGITAL
#undef REPORT_NAME_ANALOG
#define _ADD_PIN_2(ENTRY_NAME, NAME, IS_DIGITAL) { ENTRY_NAME, NAME, IS_DIGITAL },
#define _ADD_PIN(NAME, COUNTER, IS_DIGITAL) _ADD_PIN_2(entry_NAME_##COUNTER, NAME, IS_DIGITAL)
#define REPORT_NAME_DIGITAL(NAME, COUNTER) _ADD_PIN(NAME, COUNTER, true)
#define REPORT_NAME_ANALOG(NAME, COUNTER) _ADD_PIN(analogInputToDigitalPin(NAME), COUNTER, false)
typedef struct {
const char * const name;
uint8_t pin;
bool is_digital;
} PinInfo;
const PinInfo pin_array[] PROGMEM = {
/**
* [pin name] [pin number] [is digital or analog] 1 = digital, 0 = analog
* Each entry takes up 6 bytes in FLASH:
* 2 byte pointer to location of the name string
* 2 bytes containing the pin number
* analog pin numbers were convereted to digital when the array was created
* 2 bytes containing the digital/analog bool flag
*/
// manually add pins ...
#if SERIAL_PORT == 0
#if AVR_ATmega2560_FAMILY
{ RXD_NAME, 0, true },
{ TXD_NAME, 1, true },
#elif AVR_ATmega1284_FAMILY
{ RXD_NAME, 8, true },
{ TXD_NAME, 9, true },
#endif
#endif
#include "../../../pinsDebug_list.h"
#line 102
};
#define AVR_ATmega2560_FAMILY_PLUS_70 (MOTHERBOARD == BOARD_BQ_ZUM_MEGA_3D \
|| MOTHERBOARD == BOARD_MIGHTYBOARD_REVE \
|| MOTHERBOARD == BOARD_MINIRAMBO \
|| MOTHERBOARD == BOARD_SCOOVO_X9H)
#if AVR_AT90USB1286_FAMILY
// Working with Teensyduino extension so need to re-define some things
#include "pinsDebug_Teensyduino.h"
// Can't use the "digitalPinToPort" function from the Teensyduino type IDEs
// portModeRegister takes a different argument
#define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p)
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p)
#define digitalPinToPort_DEBUG(p) digitalPinToPort_Teensy(p)
#define get_pinMode(pin) (*portModeRegister(pin) & digitalPinToBitMask_DEBUG(pin))
#elif AVR_ATmega2560_FAMILY_PLUS_70 // So we can access/display all the pins on boards using more than 70
#include "pinsDebug_plus_70.h"
#define digitalPinToTimer_DEBUG(p) digitalPinToTimer_plus_70(p)
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask_plus_70(p)
#define digitalPinToPort_DEBUG(p) digitalPinToPort_plus_70(p)
bool get_pinMode(int8_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); }
#else
#define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p)
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p)
#define digitalPinToPort_DEBUG(p) digitalPinToPort(p)
bool get_pinMode(int8_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); }
#endif
#if defined(__AVR_ATmega1284P__) // 1284 IDE extensions set this to the number of
#undef NUM_DIGITAL_PINS // digital only pins while all other CPUs have it
#define NUM_DIGITAL_PINS 32 // set to digital only + digital/analog
#endif
#define PWM_PRINT(V) do{ sprintf_P(buffer, PSTR("PWM: %4d"), V); SERIAL_ECHO(buffer); }while(0)
#define PWM_CASE(N,Z) \
case TIMER##N##Z: \
if (TCCR##N##A & (_BV(COM##N##Z##1) | _BV(COM##N##Z##0))) { \
PWM_PRINT(OCR##N##Z); \
return true; \
} else return false
/**
* Print a pin's PWM status.
* Return true if it's currently a PWM pin.
*/
static bool HAL_pwm_status(uint8_t pin) {
char buffer[20]; // for the sprintf statements
switch (digitalPinToTimer_DEBUG(pin)) {
#if defined(TCCR0A) && defined(COM0A1)
#ifdef TIMER0A
#if !AVR_AT90USB1286_FAMILY // not available in Teensyduino type IDEs
PWM_CASE(0, A);
#endif
#endif
PWM_CASE(0, B);
#endif
#if defined(TCCR1A) && defined(COM1A1)
PWM_CASE(1, A);
PWM_CASE(1, B);
#if defined(COM1C1) && defined(TIMER1C)
PWM_CASE(1, C);
#endif
#endif
#if defined(TCCR2A) && defined(COM2A1)
PWM_CASE(2, A);
PWM_CASE(2, B);
#endif
#if defined(TCCR3A) && defined(COM3A1)
PWM_CASE(3, A);
PWM_CASE(3, B);
#ifdef COM3C1
PWM_CASE(3, C);
#endif
#endif
#ifdef TCCR4A
PWM_CASE(4, A);
PWM_CASE(4, B);
PWM_CASE(4, C);
#endif
#if defined(TCCR5A) && defined(COM5A1)
PWM_CASE(5, A);
PWM_CASE(5, B);
PWM_CASE(5, C);
#endif
case NOT_ON_TIMER:
default:
return false;
}
SERIAL_PROTOCOL_SP(2);
} // pwm_status
const volatile uint8_t* const PWM_other[][3] PROGMEM = {
{ &TCCR0A, &TCCR0B, &TIMSK0 },
{ &TCCR1A, &TCCR1B, &TIMSK1 },
#if defined(TCCR2A) && defined(COM2A1)
{ &TCCR2A, &TCCR2B, &TIMSK2 },
#endif
#if defined(TCCR3A) && defined(COM3A1)
{ &TCCR3A, &TCCR3B, &TIMSK3 },
#endif
#ifdef TCCR4A
{ &TCCR4A, &TCCR4B, &TIMSK4 },
#endif
#if defined(TCCR5A) && defined(COM5A1)
{ &TCCR5A, &TCCR5B, &TIMSK5 },
#endif
};
const volatile uint8_t* const PWM_OCR[][3] PROGMEM = {
#ifdef TIMER0A
{ &OCR0A, &OCR0B, 0 },
#else
{ 0, &OCR0B, 0 },
#endif
#if defined(COM1C1) && defined(TIMER1C)
{ (const uint8_t*)&OCR1A, (const uint8_t*)&OCR1B, (const uint8_t*)&OCR1C },
#else
{ (const uint8_t*)&OCR1A, (const uint8_t*)&OCR1B, 0 },
#endif
#if defined(TCCR2A) && defined(COM2A1)
{ &OCR2A, &OCR2B, 0 },
#endif
#if defined(TCCR3A) && defined(COM3A1)
#ifdef COM3C1
{ (const uint8_t*)&OCR3A, (const uint8_t*)&OCR3B, (const uint8_t*)&OCR3C },
#else
{ (const uint8_t*)&OCR3A, (const uint8_t*)&OCR3B, 0 },
#endif
#endif
#ifdef TCCR4A
{ (const uint8_t*)&OCR4A, (const uint8_t*)&OCR4B, (const uint8_t*)&OCR4C },
#endif
#if defined(TCCR5A) && defined(COM5A1)
{ (const uint8_t*)&OCR5A, (const uint8_t*)&OCR5B, (const uint8_t*)&OCR5C },
#endif
};
#define TCCR_A(T) pgm_read_word(&PWM_other[T][0])
#define TCCR_B(T) pgm_read_word(&PWM_other[T][1])
#define TIMSK(T) pgm_read_word(&PWM_other[T][2])
#define CS_0 0
#define CS_1 1
#define CS_2 2
#define WGM_0 0
#define WGM_1 1
#define WGM_2 3
#define WGM_3 4
#define TOIE 0
#define OCR_VAL(T, L) pgm_read_word(&PWM_OCR[T][L])
static void err_is_counter() { SERIAL_PROTOCOLPGM(" non-standard PWM mode"); }
static void err_is_interrupt() { SERIAL_PROTOCOLPGM(" compare interrupt enabled"); }
static void err_prob_interrupt() { SERIAL_PROTOCOLPGM(" overflow interrupt enabled"); }
#if AVR_ATmega2560_FAMILY || AVR_AT90USB1286_FAMILY
static void print_is_also_tied() { SERIAL_PROTOCOLPGM(" is also tied to this pin"); SERIAL_PROTOCOL_SP(14); }
#endif
void com_print(uint8_t N, uint8_t Z) {
const uint8_t *TCCRA = (uint8_t*)TCCR_A(N);
SERIAL_PROTOCOLPGM(" COM");
SERIAL_PROTOCOLCHAR(N + '0');
switch (Z) {
case 'A':
SERIAL_PROTOCOLPAIR("A: ", ((*TCCRA & (_BV(7) | _BV(6))) >> 6));
break;
case 'B':
SERIAL_PROTOCOLPAIR("B: ", ((*TCCRA & (_BV(5) | _BV(4))) >> 4));
break;
case 'C':
SERIAL_PROTOCOLPAIR("C: ", ((*TCCRA & (_BV(3) | _BV(2))) >> 2));
break;
}
}
void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N - WGM bit layout
char buffer[20]; // for the sprintf statements
const uint8_t *TCCRB = (uint8_t*)TCCR_B(T),
*TCCRA = (uint8_t*)TCCR_A(T);
uint8_t WGM = (((*TCCRB & _BV(WGM_2)) >> 1) | (*TCCRA & (_BV(WGM_0) | _BV(WGM_1))));
if (N == 4) WGM |= ((*TCCRB & _BV(WGM_3)) >> 1);
SERIAL_PROTOCOLPGM(" TIMER");
SERIAL_PROTOCOLCHAR(T + '0');
SERIAL_PROTOCOLCHAR(L);
SERIAL_PROTOCOL_SP(3);
if (N == 3) {
const uint8_t *OCRVAL8 = (uint8_t*)OCR_VAL(T, L - 'A');
PWM_PRINT(*OCRVAL8);
}
else {
const uint16_t *OCRVAL16 = (uint16_t*)OCR_VAL(T, L - 'A');
PWM_PRINT(*OCRVAL16);
}
SERIAL_PROTOCOLPAIR(" WGM: ", WGM);
com_print(T,L);
SERIAL_PROTOCOLPAIR(" CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) ));
SERIAL_PROTOCOLPGM(" TCCR");
SERIAL_PROTOCOLCHAR(T + '0');
SERIAL_PROTOCOLPAIR("A: ", *TCCRA);
SERIAL_PROTOCOLPGM(" TCCR");
SERIAL_PROTOCOLCHAR(T + '0');
SERIAL_PROTOCOLPAIR("B: ", *TCCRB);
const uint8_t *TMSK = (uint8_t*)TIMSK(T);
SERIAL_PROTOCOLPGM(" TIMSK");
SERIAL_PROTOCOLCHAR(T + '0');
SERIAL_PROTOCOLPAIR(": ", *TMSK);
const uint8_t OCIE = L - 'A' + 1;
if (N == 3) { if (WGM == 0 || WGM == 2 || WGM == 4 || WGM == 6) err_is_counter(); }
else { if (WGM == 0 || WGM == 4 || WGM == 12 || WGM == 13) err_is_counter(); }
if (TEST(*TMSK, OCIE)) err_is_interrupt();
if (TEST(*TMSK, TOIE)) err_prob_interrupt();
}
static void HAL_pwm_details(uint8_t pin) {
switch (digitalPinToTimer_DEBUG(pin)) {
#if defined(TCCR0A) && defined(COM0A1)
#ifdef TIMER0A
#if !AVR_AT90USB1286_FAMILY // not available in Teensyduino type IDEs
case TIMER0A: timer_prefix(0, 'A', 3); break;
#endif
#endif
case TIMER0B: timer_prefix(0, 'B', 3); break;
#endif
#if defined(TCCR1A) && defined(COM1A1)
case TIMER1A: timer_prefix(1, 'A', 4); break;
case TIMER1B: timer_prefix(1, 'B', 4); break;
#if defined(COM1C1) && defined(TIMER1C)
case TIMER1C: timer_prefix(1, 'C', 4); break;
#endif
#endif
#if defined(TCCR2A) && defined(COM2A1)
case TIMER2A: timer_prefix(2, 'A', 3); break;
case TIMER2B: timer_prefix(2, 'B', 3); break;
#endif
#if defined(TCCR3A) && defined(COM3A1)
case TIMER3A: timer_prefix(3, 'A', 4); break;
case TIMER3B: timer_prefix(3, 'B', 4); break;
#ifdef COM3C1
case TIMER3C: timer_prefix(3, 'C', 4); break;
#endif
#endif
#ifdef TCCR4A
case TIMER4A: timer_prefix(4, 'A', 4); break;
case TIMER4B: timer_prefix(4, 'B', 4); break;
case TIMER4C: timer_prefix(4, 'C', 4); break;
#endif
#if defined(TCCR5A) && defined(COM5A1)
case TIMER5A: timer_prefix(5, 'A', 4); break;
case TIMER5B: timer_prefix(5, 'B', 4); break;
case TIMER5C: timer_prefix(5, 'C', 4); break;
#endif
case NOT_ON_TIMER: break;
}
SERIAL_PROTOCOLPGM(" ");
// on pins that have two PWMs, print info on second PWM
#if AVR_ATmega2560_FAMILY || AVR_AT90USB1286_FAMILY
// looking for port B7 - PWMs 0A and 1C
if (digitalPinToPort_DEBUG(pin) == 'B' - 64 && 0x80 == digitalPinToBitMask_DEBUG(pin)) {
#if !AVR_AT90USB1286_FAMILY
SERIAL_PROTOCOLPGM("\n .");
SERIAL_PROTOCOL_SP(18);
SERIAL_PROTOCOLPGM("TIMER1C");
print_is_also_tied();
timer_prefix(1, 'C', 4);
#else
SERIAL_PROTOCOLPGM("\n .");
SERIAL_PROTOCOL_SP(18);
SERIAL_PROTOCOLPGM("TIMER0A");
print_is_also_tied();
timer_prefix(0, 'A', 3);
#endif
}
#endif
} // pwm_details
#ifndef digitalRead_mod // Use Teensyduino's version of digitalRead - it doesn't disable the PWMs
int digitalRead_mod(const int8_t pin) { // same as digitalRead except the PWM stop section has been removed
const uint8_t port = digitalPinToPort_DEBUG(pin);
return (port != NOT_A_PIN) && (*portInputRegister(port) & digitalPinToBitMask_DEBUG(pin)) ? HIGH : LOW;
}
#endif
void print_port(int8_t pin) { // print port number
#ifdef digitalPinToPort_DEBUG
uint8_t x;
SERIAL_PROTOCOLPGM(" Port: ");
#if AVR_AT90USB1286_FAMILY
x = (pin == 46 || pin == 47) ? 'E' : digitalPinToPort_DEBUG(pin) + 64;
#else
x = digitalPinToPort_DEBUG(pin) + 64;
#endif
SERIAL_CHAR(x);
#if AVR_AT90USB1286_FAMILY
if (pin == 46)
x = '2';
else if (pin == 47)
x = '3';
else {
uint8_t temp = digitalPinToBitMask_DEBUG(pin);
for (x = '0'; x < '9' && temp != 1; x++) temp >>= 1;
}
#else
uint8_t temp = digitalPinToBitMask_DEBUG(pin);
for (x = '0'; x < '9' && temp != 1; x++) temp >>= 1;
#endif
SERIAL_CHAR(x);
#else
SERIAL_PROTOCOL_SP(10);
#endif
}
static void print_input_or_output(const bool isout) {
serialprintPGM(isout ? PSTR("Output = ") : PSTR("Input = "));
}
// pretty report with PWM info
inline void report_pin_state_extended(int8_t pin, bool ignore, bool extended = false, const char *start_string = "") {
uint8_t temp_char;
char *name_mem_pointer, buffer[30]; // for the sprintf statements
bool found = false, multi_name_pin = false;
for (uint8_t x = 0; x < COUNT(pin_array); x++) { // scan entire array and report all instances of this pin
if (pgm_read_byte(&pin_array[x].pin) == pin) {
if (found) multi_name_pin = true;
found = true;
if (!multi_name_pin) { // report digitial and analog pin number only on the first time through
sprintf_P(buffer, PSTR("%sPIN: %3d "), start_string, pin); // digital pin number
SERIAL_ECHO(buffer);
print_port(pin);
if (IS_ANALOG(pin)) {
sprintf_P(buffer, PSTR(" (A%2d) "), int(pin - analogInputToDigitalPin(0))); // analog pin number
SERIAL_ECHO(buffer);
}
else SERIAL_ECHO_SP(8); // add padding if not an analog pin
}
else {
SERIAL_CHAR('.');
SERIAL_ECHO_SP(26 + strlen(start_string)); // add padding if not the first instance found
}
name_mem_pointer = (char*)pgm_read_word(&pin_array[x].name);
for (uint8_t y = 0; y < 28; y++) { // always print pin name
temp_char = pgm_read_byte(name_mem_pointer + y);
if (temp_char != 0)
MYSERIAL.write(temp_char);
else {
for (uint8_t i = 0; i < 28 - y; i++) MYSERIAL.write(' ');
break;
}
}
if (extended) {
if (pin_is_protected(pin) && !ignore)
SERIAL_ECHOPGM("protected ");
else {
#if AVR_AT90USB1286_FAMILY //Teensy IDEs don't know about these pins so must use FASTIO
if (pin == 46 || pin == 47) {
if (pin == 46) {
print_input_or_output(GET_OUTPUT(46));
SERIAL_PROTOCOL(READ(46));
}
else if (pin == 47) {
print_input_or_output(GET_OUTPUT(47));
SERIAL_PROTOCOL(READ(47));
}
}
else
#endif
{
if (!(pgm_read_byte(&pin_array[x].is_digital))) {
sprintf_P(buffer, PSTR("Analog in = %5d"), analogRead(pin - analogInputToDigitalPin(0)));
SERIAL_ECHO(buffer);
}
else {
if (!get_pinMode(pin)) {
//pinMode(pin, INPUT_PULLUP); // make sure input isn't floating - stopped doing this
// because this could interfere with inductive/capacitive
// sensors (high impedance voltage divider) and with PT100 amplifier
print_input_or_output(false);
SERIAL_PROTOCOL(digitalRead_mod(pin));
}
else if (HAL_pwm_status(pin)) {
// do nothing
}
else {
print_input_or_output(true);
SERIAL_PROTOCOL(digitalRead_mod(pin));
}
}
if (!multi_name_pin && extended) HAL_pwm_details(pin); // report PWM capabilities only on the first pass & only if doing an extended report
}
}
}
SERIAL_EOL();
} // end of IF
} // end of for loop
if (!found) {
sprintf_P(buffer, PSTR("%sPIN: %3d "), start_string, pin);
SERIAL_ECHO(buffer);
print_port(pin);
if (IS_ANALOG(pin)) {
sprintf_P(buffer, PSTR(" (A%2d) "), int(pin - analogInputToDigitalPin(0))); // analog pin number
SERIAL_ECHO(buffer);
}
else
SERIAL_ECHO_SP(8); // add padding if not an analog pin
SERIAL_ECHOPGM("<unused/unknown>");
if (extended) {
#if AVR_AT90USB1286_FAMILY //Teensy IDEs don't know about these pins so must use FASTIO
if (pin == 46 || pin == 47) {
SERIAL_PROTOCOL_SP(12);
if (pin == 46) {
print_input_or_output(GET_OUTPUT(46));
SERIAL_PROTOCOL(READ(46));
}
else {
print_input_or_output(GET_OUTPUT(47));
SERIAL_PROTOCOL(READ(47));
}
}
else
#endif
{
if (get_pinMode(pin)) {
SERIAL_PROTOCOL_SP(12);
print_input_or_output(true);
SERIAL_PROTOCOL(digitalRead_mod(pin));
}
else {
if (IS_ANALOG(pin)) {
sprintf_P(buffer, PSTR(" Analog in = %5d"), analogRead(pin - analogInputToDigitalPin(0)));
SERIAL_ECHO(buffer);
SERIAL_ECHOPGM(" ");
}
else
SERIAL_ECHO_SP(12); // add padding if not an analog pin
print_input_or_output(false);
SERIAL_PROTOCOL(digitalRead_mod(pin));
}
//if (!pwm_status(pin)) SERIAL_CHAR(' '); // add padding if it's not a PWM pin
if (extended) pwm_details(pin); // report PWM capabilities only if doing an extended report
}
}
SERIAL_EOL();
}
}
#endif //HAL_PINSDEBUG_AVR_H

View File

@ -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

View File

@ -0,0 +1,520 @@
/**
* 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/>.
*
*/
/**
* MarlinSerial.cpp - Hardware serial library for Wiring
* Copyright (c) 2006 Nicholas Zambetti. All right reserved.
*
* Modified 23 November 2006 by David A. Mellis
* Modified 28 September 2010 by Mark Sproul
* Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
*/
#ifdef ARDUINO_ARCH_AVR
#include "MarlinSerial.h"
#include "../../../Marlin.h"
// Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.)
#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
#if UART_PRESENT(SERIAL_PORT)
ring_buffer_r rx_buffer = { { 0 }, 0, 0 };
#if TX_BUFFER_SIZE > 0
ring_buffer_t tx_buffer = { { 0 }, 0, 0 };
static bool _written;
#endif
#endif
#if ENABLED(EMERGENCY_PARSER)
#include "../../../stepper.h"
#include "../../../language.h"
// Currently looking for: M108, M112, M410
// If you alter the parser please don't forget to update the capabilities in Conditionals_post.h
FORCE_INLINE void emergency_parser(const unsigned char c) {
static e_parser_state state = state_RESET;
switch (state) {
case state_RESET:
switch (c) {
case ' ': break;
case 'N': state = state_N; break;
case 'M': state = state_M; break;
default: state = state_IGNORE;
}
break;
case state_N:
switch (c) {
case '0': case '1': case '2':
case '3': case '4': case '5':
case '6': case '7': case '8':
case '9': case '-': case ' ': break;
case 'M': state = state_M; break;
default: state = state_IGNORE;
}
break;
case state_M:
switch (c) {
case ' ': break;
case '1': state = state_M1; break;
case '4': state = state_M4; break;
default: state = state_IGNORE;
}
break;
case state_M1:
switch (c) {
case '0': state = state_M10; break;
case '1': state = state_M11; break;
default: state = state_IGNORE;
}
break;
case state_M10:
state = (c == '8') ? state_M108 : state_IGNORE;
break;
case state_M11:
state = (c == '2') ? state_M112 : state_IGNORE;
break;
case state_M4:
state = (c == '1') ? state_M41 : state_IGNORE;
break;
case state_M41:
state = (c == '0') ? state_M410 : state_IGNORE;
break;
case state_IGNORE:
if (c == '\n') state = state_RESET;
break;
default:
if (c == '\n') {
switch (state) {
case state_M108:
wait_for_user = wait_for_heatup = false;
break;
case state_M112:
kill(PSTR(MSG_KILLED));
break;
case state_M410:
quickstop_stepper();
break;
default:
break;
}
state = state_RESET;
}
}
}
#endif // EMERGENCY_PARSER
FORCE_INLINE void store_char(unsigned char c) {
CRITICAL_SECTION_START;
const uint8_t h = rx_buffer.head,
i = (uint8_t)(h + 1) & (RX_BUFFER_SIZE - 1);
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != rx_buffer.tail) {
rx_buffer.buffer[h] = c;
rx_buffer.head = i;
}
CRITICAL_SECTION_END;
#if ENABLED(EMERGENCY_PARSER)
emergency_parser(c);
#endif
}
#if TX_BUFFER_SIZE > 0
FORCE_INLINE void _tx_udr_empty_irq(void) {
// If interrupts are enabled, there must be more data in the output
// buffer. Send the next byte
const uint8_t t = tx_buffer.tail,
c = tx_buffer.buffer[t];
tx_buffer.tail = (t + 1) & (TX_BUFFER_SIZE - 1);
M_UDRx = c;
// clear the TXC bit -- "can be cleared by writing a one to its bit
// location". This makes sure flush() won't return until the bytes
// actually got written
SBI(M_UCSRxA, M_TXCx);
if (tx_buffer.head == tx_buffer.tail) {
// Buffer empty, so disable interrupts
CBI(M_UCSRxB, M_UDRIEx);
}
}
#ifdef M_USARTx_UDRE_vect
ISR(M_USARTx_UDRE_vect) {
_tx_udr_empty_irq();
}
#endif
#endif // TX_BUFFER_SIZE
#ifdef M_USARTx_RX_vect
ISR(M_USARTx_RX_vect) {
const unsigned char c = M_UDRx;
store_char(c);
}
#endif
// Public Methods
void MarlinSerial::begin(const long baud) {
uint16_t baud_setting;
bool useU2X = true;
#if F_CPU == 16000000UL && SERIAL_PORT == 0
// hard-coded exception for compatibility with the bootloader shipped
// with the Duemilanove and previous boards and the firmware on the 8U2
// on the Uno and Mega 2560.
if (baud == 57600) useU2X = false;
#endif
if (useU2X) {
M_UCSRxA = _BV(M_U2Xx);
baud_setting = (F_CPU / 4 / baud - 1) / 2;
}
else {
M_UCSRxA = 0;
baud_setting = (F_CPU / 8 / baud - 1) / 2;
}
// assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
M_UBRRxH = baud_setting >> 8;
M_UBRRxL = baud_setting;
SBI(M_UCSRxB, M_RXENx);
SBI(M_UCSRxB, M_TXENx);
SBI(M_UCSRxB, M_RXCIEx);
#if TX_BUFFER_SIZE > 0
CBI(M_UCSRxB, M_UDRIEx);
_written = false;
#endif
}
void MarlinSerial::end() {
CBI(M_UCSRxB, M_RXENx);
CBI(M_UCSRxB, M_TXENx);
CBI(M_UCSRxB, M_RXCIEx);
CBI(M_UCSRxB, M_UDRIEx);
}
void MarlinSerial::checkRx(void) {
if (TEST(M_UCSRxA, M_RXCx)) {
const uint8_t c = M_UDRx;
store_char(c);
}
}
int MarlinSerial::peek(void) {
CRITICAL_SECTION_START;
const int v = rx_buffer.head == rx_buffer.tail ? -1 : rx_buffer.buffer[rx_buffer.tail];
CRITICAL_SECTION_END;
return v;
}
int MarlinSerial::read(void) {
int v;
CRITICAL_SECTION_START;
const uint8_t t = rx_buffer.tail;
if (rx_buffer.head == t)
v = -1;
else {
v = rx_buffer.buffer[t];
rx_buffer.tail = (uint8_t)(t + 1) & (RX_BUFFER_SIZE - 1);
}
CRITICAL_SECTION_END;
return v;
}
uint8_t MarlinSerial::available(void) {
CRITICAL_SECTION_START;
const uint8_t h = rx_buffer.head,
t = rx_buffer.tail;
CRITICAL_SECTION_END;
return (uint8_t)(RX_BUFFER_SIZE + h - t) & (RX_BUFFER_SIZE - 1);
}
void MarlinSerial::flush(void) {
// RX
// don't reverse this or there may be problems if the RX interrupt
// occurs after reading the value of rx_buffer_head but before writing
// the value to rx_buffer_tail; the previous value of rx_buffer_head
// may be written to rx_buffer_tail, making it appear as if the buffer
// were full, not empty.
CRITICAL_SECTION_START;
rx_buffer.head = rx_buffer.tail;
CRITICAL_SECTION_END;
}
#if TX_BUFFER_SIZE > 0
uint8_t MarlinSerial::availableForWrite(void) {
CRITICAL_SECTION_START;
const uint8_t h = tx_buffer.head,
t = tx_buffer.tail;
CRITICAL_SECTION_END;
return (uint8_t)(TX_BUFFER_SIZE + h - t) & (TX_BUFFER_SIZE - 1);
}
void MarlinSerial::write(const uint8_t c) {
_written = true;
CRITICAL_SECTION_START;
bool emty = (tx_buffer.head == tx_buffer.tail);
CRITICAL_SECTION_END;
// If the buffer and the data register is empty, just write the byte
// to the data register and be done. This shortcut helps
// significantly improve the effective datarate at high (>
// 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
if (emty && TEST(M_UCSRxA, M_UDREx)) {
CRITICAL_SECTION_START;
M_UDRx = c;
SBI(M_UCSRxA, M_TXCx);
CRITICAL_SECTION_END;
return;
}
const uint8_t i = (tx_buffer.head + 1) & (TX_BUFFER_SIZE - 1);
// If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit
while (i == tx_buffer.tail) {
if (!TEST(SREG, SREG_I)) {
// Interrupts are disabled, so we'll have to poll the data
// register empty flag ourselves. If it is set, pretend an
// interrupt has happened and call the handler to free up
// space for us.
if (TEST(M_UCSRxA, M_UDREx))
_tx_udr_empty_irq();
}
else {
// nop, the interrupt handler will free up space for us
}
}
tx_buffer.buffer[tx_buffer.head] = c;
{ CRITICAL_SECTION_START;
tx_buffer.head = i;
SBI(M_UCSRxB, M_UDRIEx);
CRITICAL_SECTION_END;
}
return;
}
void MarlinSerial::flushTX(void) {
// TX
// If we have never written a byte, no need to flush. This special
// case is needed since there is no way to force the TXC (transmit
// complete) bit to 1 during initialization
if (!_written)
return;
while (TEST(M_UCSRxB, M_UDRIEx) || !TEST(M_UCSRxA, M_TXCx)) {
if (!TEST(SREG, SREG_I) && TEST(M_UCSRxB, M_UDRIEx))
// Interrupts are globally disabled, but the DR empty
// interrupt should be enabled, so poll the DR empty flag to
// prevent deadlock
if (TEST(M_UCSRxA, M_UDREx))
_tx_udr_empty_irq();
}
// If we get here, nothing is queued anymore (DRIE is disabled) and
// the hardware finished tranmission (TXC is set).
}
#else
void MarlinSerial::write(uint8_t c) {
while (!TEST(M_UCSRxA, M_UDREx))
;
M_UDRx = c;
}
#endif
// end NEW
/// imports from print.h
void MarlinSerial::print(char c, int base) {
print((long)c, base);
}
void MarlinSerial::print(unsigned char b, int base) {
print((unsigned long)b, base);
}
void MarlinSerial::print(int n, int base) {
print((long)n, base);
}
void MarlinSerial::print(unsigned int n, int base) {
print((unsigned long)n, base);
}
void MarlinSerial::print(long n, int base) {
if (base == 0)
write(n);
else if (base == 10) {
if (n < 0) {
print('-');
n = -n;
}
printNumber(n, 10);
}
else
printNumber(n, base);
}
void MarlinSerial::print(unsigned long n, int base) {
if (base == 0) write(n);
else printNumber(n, base);
}
void MarlinSerial::print(double n, int digits) {
printFloat(n, digits);
}
void MarlinSerial::println(void) {
print('\r');
print('\n');
}
void MarlinSerial::println(const String& s) {
print(s);
println();
}
void MarlinSerial::println(const char c[]) {
print(c);
println();
}
void MarlinSerial::println(char c, int base) {
print(c, base);
println();
}
void MarlinSerial::println(unsigned char b, int base) {
print(b, base);
println();
}
void MarlinSerial::println(int n, int base) {
print(n, base);
println();
}
void MarlinSerial::println(unsigned int n, int base) {
print(n, base);
println();
}
void MarlinSerial::println(long n, int base) {
print(n, base);
println();
}
void MarlinSerial::println(unsigned long n, int base) {
print(n, base);
println();
}
void MarlinSerial::println(double n, int digits) {
print(n, digits);
println();
}
// Private Methods
void MarlinSerial::printNumber(unsigned long n, uint8_t base) {
if (n) {
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
int8_t i = 0;
while (n) {
buf[i++] = n % base;
n /= base;
}
while (i--)
print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
}
else
print('0');
}
void MarlinSerial::printFloat(double number, uint8_t digits) {
// Handle negative numbers
if (number < 0.0) {
print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i = 0; i < digits; ++i)
rounding *= 0.1;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits) {
print('.');
// Extract digits from the remainder one at a time
while (digits--) {
remainder *= 10.0;
int toPrint = int(remainder);
print(toPrint);
remainder -= toPrint;
}
}
}
// Preinstantiate
MarlinSerial customizedSerial;
#endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
// For AT90USB targets use the UART for BT interfacing
#if defined(USBCON) && ENABLED(BLUETOOTH)
HardwareSerial bluetoothSerial;
#endif
#endif

View File

@ -0,0 +1,177 @@
/**
* 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/>.
*
*/
/**
MarlinSerial.h - Hardware serial library for Wiring
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
Modified 28 September 2010 by Mark Sproul
Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
*/
#ifndef MARLINSERIAL_H
#define MARLINSERIAL_H
#include "../../../MarlinConfig.h"
#include <WString.h>
#ifndef SERIAL_PORT
#define SERIAL_PORT 0
#endif
// The presence of the UBRRH register is used to detect a UART.
#define UART_PRESENT(port) ((port == 0 && (defined(UBRRH) || defined(UBRR0H))) || \
(port == 1 && defined(UBRR1H)) || (port == 2 && defined(UBRR2H)) || \
(port == 3 && defined(UBRR3H)))
// These are macros to build serial port register names for the selected SERIAL_PORT (C preprocessor
// requires two levels of indirection to expand macro values properly)
#define SERIAL_REGNAME(registerbase,number,suffix) SERIAL_REGNAME_INTERNAL(registerbase,number,suffix)
#if SERIAL_PORT == 0 && (!defined(UBRR0H) || !defined(UDR0)) // use un-numbered registers if necessary
#define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##suffix
#else
#define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix
#endif
// Registers used by MarlinSerial class (expanded depending on selected serial port)
#define M_UCSRxA SERIAL_REGNAME(UCSR,SERIAL_PORT,A) // defines M_UCSRxA to be UCSRnA where n is the serial port number
#define M_UCSRxB SERIAL_REGNAME(UCSR,SERIAL_PORT,B)
#define M_RXENx SERIAL_REGNAME(RXEN,SERIAL_PORT,)
#define M_TXENx SERIAL_REGNAME(TXEN,SERIAL_PORT,)
#define M_TXCx SERIAL_REGNAME(TXC,SERIAL_PORT,)
#define M_RXCIEx SERIAL_REGNAME(RXCIE,SERIAL_PORT,)
#define M_UDREx SERIAL_REGNAME(UDRE,SERIAL_PORT,)
#define M_UDRIEx SERIAL_REGNAME(UDRIE,SERIAL_PORT,)
#define M_UDRx SERIAL_REGNAME(UDR,SERIAL_PORT,)
#define M_UBRRxH SERIAL_REGNAME(UBRR,SERIAL_PORT,H)
#define M_UBRRxL SERIAL_REGNAME(UBRR,SERIAL_PORT,L)
#define M_RXCx SERIAL_REGNAME(RXC,SERIAL_PORT,)
#define M_USARTx_RX_vect SERIAL_REGNAME(USART,SERIAL_PORT,_RX_vect)
#define M_U2Xx SERIAL_REGNAME(U2X,SERIAL_PORT,)
#define M_USARTx_UDRE_vect SERIAL_REGNAME(USART,SERIAL_PORT,_UDRE_vect)
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
#define BYTE 0
#ifndef USBCON
// Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the
// location to which to write the next incoming character and rx_buffer_tail
// is the index of the location from which to read.
// 256 is the max limit due to uint8_t head and tail. Use only powers of 2. (...,16,32,64,128,256)
#ifndef RX_BUFFER_SIZE
#define RX_BUFFER_SIZE 128
#endif
#ifndef TX_BUFFER_SIZE
#define TX_BUFFER_SIZE 32
#endif
#if !((RX_BUFFER_SIZE == 256) ||(RX_BUFFER_SIZE == 128) ||(RX_BUFFER_SIZE == 64) ||(RX_BUFFER_SIZE == 32) ||(RX_BUFFER_SIZE == 16) ||(RX_BUFFER_SIZE == 8) ||(RX_BUFFER_SIZE == 4) ||(RX_BUFFER_SIZE == 2))
#error "RX_BUFFER_SIZE has to be a power of 2 and >= 2"
#endif
#if !((TX_BUFFER_SIZE == 256) ||(TX_BUFFER_SIZE == 128) ||(TX_BUFFER_SIZE == 64) ||(TX_BUFFER_SIZE == 32) ||(TX_BUFFER_SIZE == 16) ||(TX_BUFFER_SIZE == 8) ||(TX_BUFFER_SIZE == 4) ||(TX_BUFFER_SIZE == 2) ||(TX_BUFFER_SIZE == 0))
#error TX_BUFFER_SIZE has to be a power of 2 or 0
#endif
struct ring_buffer_r {
unsigned char buffer[RX_BUFFER_SIZE];
volatile uint8_t head;
volatile uint8_t tail;
};
#if TX_BUFFER_SIZE > 0
struct ring_buffer_t {
unsigned char buffer[TX_BUFFER_SIZE];
volatile uint8_t head;
volatile uint8_t tail;
};
#endif
#if UART_PRESENT(SERIAL_PORT)
extern ring_buffer_r rx_buffer;
#if TX_BUFFER_SIZE > 0
extern ring_buffer_t tx_buffer;
#endif
#endif
class MarlinSerial { //: public Stream
public:
MarlinSerial() {};
static void begin(const long);
static void end();
static int peek(void);
static int read(void);
static void flush(void);
static uint8_t available(void);
static void checkRx(void);
static void write(const uint8_t c);
#if TX_BUFFER_SIZE > 0
static uint8_t availableForWrite(void);
static void flushTX(void);
#endif
private:
static void printNumber(unsigned long, const uint8_t);
static void printFloat(double, uint8_t);
public:
static FORCE_INLINE void write(const char* str) { while (*str) write(*str++); }
static FORCE_INLINE void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
static FORCE_INLINE void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
static FORCE_INLINE void print(const char* str) { write(str); }
static void print(char, int = BYTE);
static void print(unsigned char, int = BYTE);
static void print(int, int = DEC);
static void print(unsigned int, int = DEC);
static void print(long, int = DEC);
static void print(unsigned long, int = DEC);
static void print(double, int = 2);
static void println(const String& s);
static void println(const char[]);
static void println(char, int = BYTE);
static void println(unsigned char, int = BYTE);
static void println(int, int = DEC);
static void println(unsigned int, int = DEC);
static void println(long, int = DEC);
static void println(unsigned long, int = DEC);
static void println(double, int = 2);
static void println(void);
operator bool() { return true; }
};
extern MarlinSerial customizedSerial;
#endif // !USBCON
// Use the UART for Bluetooth in AT90USB configurations
#if defined(USBCON) && ENABLED(BLUETOOTH)
extern HardwareSerial bluetoothSerial;
#endif
#endif // MARLINSERIAL_H

View File

@ -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;

View File

@ -0,0 +1,196 @@
/**
* 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/>.
*
*/
/**
* Endstop Interrupts
*
* Without endstop interrupts the endstop pins must be polled continually in
* the stepper-ISR via endstops.update(), most of the time finding no change.
* With this feature endstops.update() is called only when we know that at
* least one endstop has changed state, saving valuable CPU cycles.
*
* This feature only works when all used endstop pins can generate either an
* 'external interrupt' or a 'pin change interrupt'.
*
* Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'.
* (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino)
*/
#ifndef _ENDSTOP_INTERRUPTS_H_
#define _ENDSTOP_INTERRUPTS_H_
#include "../../../macros.h"
/**
* Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h)
*
* These macros for the Arduino MEGA do not include the two connected pins on Port J (D13, D14).
* So we extend them here because these are the normal pins for Y_MIN and Y_MAX on RAMPS.
* There are more PCI-enabled processor pins on Port J, but they are not connected to Arduino MEGA.
*/
#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_MEGA)
#undef digitalPinToPCICR
#define digitalPinToPCICR(p) ( WITHIN(p, 10, 15) || \
WITHIN(p, 50, 53) || \
WITHIN(p, 62, 69) ? &PCICR : (uint8_t*)0 )
#undef digitalPinToPCICRbit
#define digitalPinToPCICRbit(p) ( WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? 0 : \
WITHIN(p, 14, 15) ? 1 : \
WITHIN(p, 62, 69) ? 2 : \
0 )
#undef digitalPinToPCMSK
#define digitalPinToPCMSK(p) ( WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? &PCMSK0 : \
WITHIN(p, 14, 15) ? &PCMSK1 : \
WITHIN(p, 62, 69) ? &PCMSK2 : \
(uint8_t *)0 )
#undef digitalPinToPCMSKbit
#define digitalPinToPCMSKbit(p) ( WITHIN(p, 10, 13) ? ((p) - 6) : \
(p) == 14 || (p) == 51 ? 2 : \
(p) == 15 || (p) == 52 ? 1 : \
(p) == 50 ? 3 : \
(p) == 53 ? 0 : \
WITHIN(p, 62, 69) ? ((p) - 62) : \
0 )
#endif
// Install Pin change interrupt for a pin. Can be called multiple times.
void pciSetup(byte pin) {
SBI(*digitalPinToPCMSK(pin), digitalPinToPCMSKbit(pin)); // enable pin
SBI(PCIFR, digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
SBI(PCICR, digitalPinToPCICRbit(pin)); // enable interrupt for the group
}
// Handlers for pin change interrupts
#ifdef PCINT0_vect
ISR(PCINT0_vect) { endstop_ISR_worker(); }
#endif
#ifdef PCINT1_vect
ISR(PCINT1_vect) { endstop_ISR_worker(); }
#endif
#ifdef PCINT2_vect
ISR(PCINT2_vect) { endstop_ISR_worker(); }
#endif
#ifdef PCINT3_vect
ISR(PCINT3_vect) { endstop_ISR_worker(); }
#endif
void setup_endstop_interrupts( void ) {
#if HAS_X_MAX
#if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT) // if pin has an external interrupt
attachInterrupt(digitalPinToInterrupt(X_MAX_PIN), endstop_ISR, CHANGE); // assign it
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(X_MAX_PIN) != NULL, "X_MAX_PIN is not interrupt-capable"); // if pin has no pin change interrupt - error
pciSetup(X_MAX_PIN); // assign it
#endif
#endif
#if HAS_X_MIN
#if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(X_MIN_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(X_MIN_PIN) != NULL, "X_MIN_PIN is not interrupt-capable");
pciSetup(X_MIN_PIN);
#endif
#endif
#if HAS_Y_MAX
#if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(Y_MAX_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Y_MAX_PIN) != NULL, "Y_MAX_PIN is not interrupt-capable");
pciSetup(Y_MAX_PIN);
#endif
#endif
#if HAS_Y_MIN
#if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(Y_MIN_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Y_MIN_PIN) != NULL, "Y_MIN_PIN is not interrupt-capable");
pciSetup(Y_MIN_PIN);
#endif
#endif
#if HAS_Z_MAX
#if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(Z_MAX_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Z_MAX_PIN) != NULL, "Z_MAX_PIN is not interrupt-capable");
pciSetup(Z_MAX_PIN);
#endif
#endif
#if HAS_Z_MIN
#if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(Z_MIN_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Z_MIN_PIN) != NULL, "Z_MIN_PIN is not interrupt-capable");
pciSetup(Z_MIN_PIN);
#endif
#endif
#if HAS_Z2_MAX
#if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(Z2_MAX_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Z2_MAX_PIN) != NULL, "Z2_MAX_PIN is not interrupt-capable");
pciSetup(Z2_MAX_PIN);
#endif
#endif
#if HAS_Z2_MIN
#if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(Z2_MIN_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Z2_MIN_PIN) != NULL, "Z2_MIN_PIN is not interrupt-capable");
pciSetup(Z2_MIN_PIN);
#endif
#endif
#if HAS_Z_MIN_PROBE_PIN
#if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(Z_MIN_PROBE_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Z_MIN_PROBE_PIN) != NULL, "Z_MIN_PROBE_PIN is not interrupt-capable");
pciSetup(Z_MIN_PROBE_PIN);
#endif
#endif
// If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI.
}
#endif // _ENDSTOP_INTERRUPTS_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,720 @@
/**
* 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/>.
*
*/
/**
* Pin mapping for the 1281 and 2561
*
* 1281 38 39 40 41 42 43 44 45 16 10 11 12 06 07 08 09 30 31 32 33 34 35 36 37 17 18 19 20 21 22 23 24 00 01 13 05 02 03 14 15 46 47 48 49 50 51 52 53 25 26 27 28 29 04
* Port A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7 G0 G1 G2 G3 G4 G5
* Marlin 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
*/
#ifndef _FASTIO_1281
#define _FASTIO_1281
#include "fastio_AVR.h"
// change for your board
#define DEBUG_LED DIO46
// UART
#define RXD DIO0
#define TXD DIO1
// SPI
#define SCK DIO10
#define MISO DIO12
#define MOSI DIO11
#define SS DIO16
// TWI (I2C)
#define SCL DIO17
#define SDA DIO18
// Timers and PWM
#define OC0A DIO9
#define OC0B DIO4
#define OC1A DIO7
#define OC1B DIO8
#define OC2A DIO6
#define OC3A DIO5
#define OC3B DIO2
#define OC3C DIO3
// Digital I/O
#define DIO0_PIN PINE0
#define DIO0_RPORT PINE
#define DIO0_WPORT PORTE
#define DIO0_DDR DDRE
#define DIO0_PWM NULL
#define DIO1_PIN PINE1
#define DIO1_RPORT PINE
#define DIO1_WPORT PORTE
#define DIO1_DDR DDRE
#define DIO1_PWM NULL
#define DIO2_PIN PINE4
#define DIO2_RPORT PINE
#define DIO2_WPORT PORTE
#define DIO2_DDR DDRE
#define DIO2_PWM &OCR3BL
#define DIO3_PIN PINE5
#define DIO3_RPORT PINE
#define DIO3_WPORT PORTE
#define DIO3_DDR DDRE
#define DIO3_PWM &OCR3CL
#define DIO4_PIN PING5
#define DIO4_RPORT PING
#define DIO4_WPORT PORTG
#define DIO4_DDR DDRG
#define DIO4_PWM &OCR0B
#define DIO5_PIN PINE3
#define DIO5_RPORT PINE
#define DIO5_WPORT PORTE
#define DIO5_DDR DDRE
#define DIO5_PWM &OCR3AL
#define DIO6_PIN PINB4
#define DIO6_RPORT PINB
#define DIO6_WPORT PORTB
#define DIO6_DDR DDRB
#define DIO6_PWM &OCR2AL
#define DIO7_PIN PINB5
#define DIO7_RPORT PINB
#define DIO7_WPORT PORTB
#define DIO7_DDR DDRB
#define DIO7_PWM &OCR1AL
#define DIO8_PIN PINB6
#define DIO8_RPORT PINB
#define DIO8_WPORT PORTB
#define DIO8_DDR DDRB
#define DIO8_PWM &OCR1BL
#define DIO9_PIN PINB7
#define DIO9_RPORT PINB
#define DIO9_WPORT PORTB
#define DIO9_DDR DDRB
#define DIO9_PWM &OCR0AL
#define DIO10_PIN PINB1
#define DIO10_RPORT PINB
#define DIO10_WPORT PORTB
#define DIO10_DDR DDRB
#define DIO10_PWM NULL
#define DIO11_PIN PINB2
#define DIO11_RPORT PINB
#define DIO11_WPORT PORTB
#define DIO11_DDR DDRB
#define DIO11_PWM NULL
#define DIO12_PIN PINB3
#define DIO12_RPORT PINB
#define DIO12_WPORT PORTB
#define DIO12_DDR DDRB
#define DIO12_PWM NULL
#define DIO13_PIN PINE2
#define DIO13_RPORT PINE
#define DIO13_WPORT PORTE
#define DIO13_DDR DDRE
#define DIO13_PWM NULL
#define DIO14_PIN PINE6
#define DIO14_RPORT PINE
#define DIO14_WPORT PORTE
#define DIO14_DDR DDRE
#define DIO14_PWM NULL
#define DIO15_PIN PINE7
#define DIO15_RPORT PINE
#define DIO15_WPORT PORTE
#define DIO15_DDR DDRE
#define DIO15_PWM NULL
#define DIO16_PIN PINB0
#define DIO16_RPORT PINB
#define DIO16_WPORT PORTB
#define DIO16_DDR DDRB
#define DIO16_PWM NULL
#define DIO17_PIN PIND0
#define DIO17_RPORT PIND
#define DIO17_WPORT PORTD
#define DIO17_DDR DDRD
#define DIO17_PWM NULL
#define DIO18_PIN PIND1
#define DIO18_RPORT PIND
#define DIO18_WPORT PORTD
#define DIO18_DDR DDRD
#define DIO18_PWM NULL
#define DIO19_PIN PIND2
#define DIO19_RPORT PIND
#define DIO19_WPORT PORTD
#define DIO19_DDR DDRD
#define DIO19_PWM NULL
#define DIO20_PIN PIND3
#define DIO20_RPORT PIND
#define DIO20_WPORT PORTD
#define DIO20_DDR DDRD
#define DIO20_PWM NULL
#define DIO21_PIN PIND4
#define DIO21_RPORT PIND
#define DIO21_WPORT PORTD
#define DIO21_DDR DDRD
#define DIO21_PWM NULL
#define DIO22_PIN PIND5
#define DIO22_RPORT PIND
#define DIO22_WPORT PORTD
#define DIO22_DDR DDRD
#define DIO22_PWM NULL
#define DIO23_PIN PIND6
#define DIO23_RPORT PIND
#define DIO23_WPORT PORTD
#define DIO23_DDR DDRD
#define DIO23_PWM NULL
#define DIO24_PIN PIND7
#define DIO24_RPORT PIND
#define DIO24_WPORT PORTD
#define DIO24_DDR DDRD
#define DIO24_PWM NULL
#define DIO25_PIN PING0
#define DIO25_RPORT PING
#define DIO25_WPORT PORTG
#define DIO25_DDR DDRG
#define DIO25_PWM NULL
#define DIO26_PIN PING1
#define DIO26_RPORT PING
#define DIO26_WPORT PORTG
#define DIO26_DDR DDRG
#define DIO26_PWM NULL
#define DIO27_PIN PING2
#define DIO27_RPORT PING
#define DIO27_WPORT PORTG
#define DIO27_DDR DDRG
#define DIO27_PWM NULL
#define DIO28_PIN PING3
#define DIO28_RPORT PING
#define DIO28_WPORT PORTG
#define DIO28_DDR DDRG
#define DIO28_PWM NULL
#define DIO29_PIN PING4
#define DIO29_RPORT PING
#define DIO29_WPORT PORTG
#define DIO29_DDR DDRG
#define DIO29_PWM NULL
#define DIO30_PIN PINC0
#define DIO30_RPORT PINC
#define DIO30_WPORT PORTC
#define DIO30_DDR DDRC
#define DIO30_PWM NULL
#define DIO31_PIN PINC1
#define DIO31_RPORT PINC
#define DIO31_WPORT PORTC
#define DIO31_DDR DDRC
#define DIO31_PWM NULL
#define DIO32_PIN PINC2
#define DIO32_RPORT PINC
#define DIO32_WPORT PORTC
#define DIO32_DDR DDRC
#define DIO32_PWM NULL
#define DIO33_PIN PINC3
#define DIO33_RPORT PINC
#define DIO33_WPORT PORTC
#define DIO33_DDR DDRC
#define DIO33_PWM NULL
#define DIO34_PIN PINC4
#define DIO34_RPORT PINC
#define DIO34_WPORT PORTC
#define DIO34_DDR DDRC
#define DIO34_PWM NULL
#define DIO35_PIN PINC5
#define DIO35_RPORT PINC
#define DIO35_WPORT PORTC
#define DIO35_DDR DDRC
#define DIO35_PWM NULL
#define DIO36_PIN PINC6
#define DIO36_RPORT PINC
#define DIO36_WPORT PORTC
#define DIO36_DDR DDRC
#define DIO36_PWM NULL
#define DIO37_PIN PINC7
#define DIO37_RPORT PINC
#define DIO37_WPORT PORTC
#define DIO37_DDR DDRC
#define DIO37_PWM NULL
#define DIO38_PIN PINA0
#define DIO38_RPORT PINA
#define DIO38_WPORT PORTA
#define DIO38_DDR DDRA
#define DIO38_PWM NULL
#define DIO39_PIN PINA1
#define DIO39_RPORT PINA
#define DIO39_WPORT PORTA
#define DIO39_DDR DDRA
#define DIO39_PWM NULL
#define DIO40_PIN PINA2
#define DIO40_RPORT PINA
#define DIO40_WPORT PORTA
#define DIO40_DDR DDRA
#define DIO40_PWM NULL
#define DIO41_PIN PINA3
#define DIO41_RPORT PINA
#define DIO41_WPORT PORTA
#define DIO41_DDR DDRA
#define DIO41_PWM NULL
#define DIO42_PIN PINA4
#define DIO42_RPORT PINA
#define DIO42_WPORT PORTA
#define DIO42_DDR DDRA
#define DIO42_PWM NULL
#define DIO43_PIN PINA5
#define DIO43_RPORT PINA
#define DIO43_WPORT PORTA
#define DIO43_DDR DDRA
#define DIO43_PWM NULL
#define DIO44_PIN PINA6
#define DIO44_RPORT PINA
#define DIO44_WPORT PORTA
#define DIO44_DDR DDRA
#define DIO44_PWM NULL
#define DIO45_PIN PINA7
#define DIO45_RPORT PINA
#define DIO45_WPORT PORTA
#define DIO45_DDR DDRA
#define DIO45_PWM NULL
#define DIO46_PIN PINF0
#define DIO46_RPORT PINF
#define DIO46_WPORT PORTF
#define DIO46_DDR DDRF
#define DIO46_PWM NULL
#define DIO47_PIN PINF1
#define DIO47_RPORT PINF
#define DIO47_WPORT PORTF
#define DIO47_DDR DDRF
#define DIO47_PWM NULL
#define DIO48_PIN PINF2
#define DIO48_RPORT PINF
#define DIO48_WPORT PORTF
#define DIO48_DDR DDRF
#define DIO48_PWM NULL
#define DIO49_PIN PINF3
#define DIO49_RPORT PINF
#define DIO49_WPORT PORTF
#define DIO49_DDR DDRF
#define DIO49_PWM NULL
#define DIO50_PIN PINF4
#define DIO50_RPORT PINF
#define DIO50_WPORT PORTF
#define DIO50_DDR DDRF
#define DIO50_PWM NULL
#define DIO51_PIN PINF5
#define DIO51_RPORT PINF
#define DIO51_WPORT PORTF
#define DIO51_DDR DDRF
#define DIO51_PWM NULL
#define DIO52_PIN PINF6
#define DIO52_RPORT PINF
#define DIO52_WPORT PORTF
#define DIO52_DDR DDRF
#define DIO52_PWM NULL
#define DIO53_PIN PINF7
#define DIO53_RPORT PINF
#define DIO53_WPORT PORTF
#define DIO53_DDR DDRF
#define DIO53_PWM NULL
#undef PA0
#define PA0_PIN PINA0
#define PA0_RPORT PINA
#define PA0_WPORT PORTA
#define PA0_DDR DDRA
#define PA0_PWM NULL
#undef PA1
#define PA1_PIN PINA1
#define PA1_RPORT PINA
#define PA1_WPORT PORTA
#define PA1_DDR DDRA
#define PA1_PWM NULL
#undef PA2
#define PA2_PIN PINA2
#define PA2_RPORT PINA
#define PA2_WPORT PORTA
#define PA2_DDR DDRA
#define PA2_PWM NULL
#undef PA3
#define PA3_PIN PINA3
#define PA3_RPORT PINA
#define PA3_WPORT PORTA
#define PA3_DDR DDRA
#define PA3_PWM NULL
#undef PA4
#define PA4_PIN PINA4
#define PA4_RPORT PINA
#define PA4_WPORT PORTA
#define PA4_DDR DDRA
#define PA4_PWM NULL
#undef PA5
#define PA5_PIN PINA5
#define PA5_RPORT PINA
#define PA5_WPORT PORTA
#define PA5_DDR DDRA
#define PA5_PWM NULL
#undef PA6
#define PA6_PIN PINA6
#define PA6_RPORT PINA
#define PA6_WPORT PORTA
#define PA6_DDR DDRA
#define PA6_PWM NULL
#undef PA7
#define PA7_PIN PINA7
#define PA7_RPORT PINA
#define PA7_WPORT PORTA
#define PA7_DDR DDRA
#define PA7_PWM NULL
#undef PB0
#define PB0_PIN PINB0
#define PB0_RPORT PINB
#define PB0_WPORT PORTB
#define PB0_DDR DDRB
#define PB0_PWM NULL
#undef PB1
#define PB1_PIN PINB1
#define PB1_RPORT PINB
#define PB1_WPORT PORTB
#define PB1_DDR DDRB
#define PB1_PWM NULL
#undef PB2
#define PB2_PIN PINB2
#define PB2_RPORT PINB
#define PB2_WPORT PORTB
#define PB2_DDR DDRB
#define PB2_PWM NULL
#undef PB3
#define PB3_PIN PINB3
#define PB3_RPORT PINB
#define PB3_WPORT PORTB
#define PB3_DDR DDRB
#define PB3_PWM NULL
#undef PB4
#define PB4_PIN PINB4
#define PB4_RPORT PINB
#define PB4_WPORT PORTB
#define PB4_DDR DDRB
#define PB4_PWM &OCR2A
#undef PB5
#define PB5_PIN PINB5
#define PB5_RPORT PINB
#define PB5_WPORT PORTB
#define PB5_DDR DDRB
#define PB5_PWM NULL
#undef PB6
#define PB6_PIN PINB6
#define PB6_RPORT PINB
#define PB6_WPORT PORTB
#define PB6_DDR DDRB
#define PB6_PWM NULL
#undef PB7
#define PB7_PIN PINB7
#define PB7_RPORT PINB
#define PB7_WPORT PORTB
#define PB7_DDR DDRB
#define PB7_PWM &OCR0A
#undef PC0
#define PC0_PIN PINC0
#define PC0_RPORT PINC
#define PC0_WPORT PORTC
#define PC0_DDR DDRC
#define PC0_PWM NULL
#undef PC1
#define PC1_PIN PINC1
#define PC1_RPORT PINC
#define PC1_WPORT PORTC
#define PC1_DDR DDRC
#define PC1_PWM NULL
#undef PC2
#define PC2_PIN PINC2
#define PC2_RPORT PINC
#define PC2_WPORT PORTC
#define PC2_DDR DDRC
#define PC2_PWM NULL
#undef PC3
#define PC3_PIN PINC3
#define PC3_RPORT PINC
#define PC3_WPORT PORTC
#define PC3_DDR DDRC
#define PC3_PWM NULL
#undef PC4
#define PC4_PIN PINC4
#define PC4_RPORT PINC
#define PC4_WPORT PORTC
#define PC4_DDR DDRC
#define PC4_PWM NULL
#undef PC5
#define PC5_PIN PINC5
#define PC5_RPORT PINC
#define PC5_WPORT PORTC
#define PC5_DDR DDRC
#define PC5_PWM NULL
#undef PC6
#define PC6_PIN PINC6
#define PC6_RPORT PINC
#define PC6_WPORT PORTC
#define PC6_DDR DDRC
#define PC6_PWM NULL
#undef PC7
#define PC7_PIN PINC7
#define PC7_RPORT PINC
#define PC7_WPORT PORTC
#define PC7_DDR DDRC
#define PC7_PWM NULL
#undef PD0
#define PD0_PIN PIND0
#define PD0_RPORT PIND
#define PD0_WPORT PORTD
#define PD0_DDR DDRD
#define PD0_PWM NULL
#undef PD1
#define PD1_PIN PIND1
#define PD1_RPORT PIND
#define PD1_WPORT PORTD
#define PD1_DDR DDRD
#define PD1_PWM NULL
#undef PD2
#define PD2_PIN PIND2
#define PD2_RPORT PIND
#define PD2_WPORT PORTD
#define PD2_DDR DDRD
#define PD2_PWM NULL
#undef PD3
#define PD3_PIN PIND3
#define PD3_RPORT PIND
#define PD3_WPORT PORTD
#define PD3_DDR DDRD
#define PD3_PWM NULL
#undef PD4
#define PD4_PIN PIND4
#define PD4_RPORT PIND
#define PD4_WPORT PORTD
#define PD4_DDR DDRD
#define PD4_PWM NULL
#undef PD5
#define PD5_PIN PIND5
#define PD5_RPORT PIND
#define PD5_WPORT PORTD
#define PD5_DDR DDRD
#define PD5_PWM NULL
#undef PD6
#define PD6_PIN PIND6
#define PD6_RPORT PIND
#define PD6_WPORT PORTD
#define PD6_DDR DDRD
#define PD6_PWM NULL
#undef PD7
#define PD7_PIN PIND7
#define PD7_RPORT PIND
#define PD7_WPORT PORTD
#define PD7_DDR DDRD
#define PD7_PWM NULL
#undef PE0
#define PE0_PIN PINE0
#define PE0_RPORT PINE
#define PE0_WPORT PORTE
#define PE0_DDR DDRE
#define PE0_PWM NULL
#undef PE1
#define PE1_PIN PINE1
#define PE1_RPORT PINE
#define PE1_WPORT PORTE
#define PE1_DDR DDRE
#define PE1_PWM NULL
#undef PE2
#define PE2_PIN PINE2
#define PE2_RPORT PINE
#define PE2_WPORT PORTE
#define PE2_DDR DDRE
#define PE2_PWM NULL
#undef PE3
#define PE3_PIN PINE3
#define PE3_RPORT PINE
#define PE3_WPORT PORTE
#define PE3_DDR DDRE
#define PE3_PWM &OCR3AL
#undef PE4
#define PE4_PIN PINE4
#define PE4_RPORT PINE
#define PE4_WPORT PORTE
#define PE4_DDR DDRE
#define PE4_PWM &OCR3BL
#undef PE5
#define PE5_PIN PINE5
#define PE5_RPORT PINE
#define PE5_WPORT PORTE
#define PE5_DDR DDRE
#define PE5_PWM &OCR3CL
#undef PE6
#define PE6_PIN PINE6
#define PE6_RPORT PINE
#define PE6_WPORT PORTE
#define PE6_DDR DDRE
#define PE6_PWM NULL
#undef PE7
#define PE7_PIN PINE7
#define PE7_RPORT PINE
#define PE7_WPORT PORTE
#define PE7_DDR DDRE
#define PE7_PWM NULL
#undef PF0
#define PF0_PIN PINF0
#define PF0_RPORT PINF
#define PF0_WPORT PORTF
#define PF0_DDR DDRF
#define PF0_PWM NULL
#undef PF1
#define PF1_PIN PINF1
#define PF1_RPORT PINF
#define PF1_WPORT PORTF
#define PF1_DDR DDRF
#define PF1_PWM NULL
#undef PF2
#define PF2_PIN PINF2
#define PF2_RPORT PINF
#define PF2_WPORT PORTF
#define PF2_DDR DDRF
#define PF2_PWM NULL
#undef PF3
#define PF3_PIN PINF3
#define PF3_RPORT PINF
#define PF3_WPORT PORTF
#define PF3_DDR DDRF
#define PF3_PWM NULL
#undef PF4
#define PF4_PIN PINF4
#define PF4_RPORT PINF
#define PF4_WPORT PORTF
#define PF4_DDR DDRF
#define PF4_PWM NULL
#undef PF5
#define PF5_PIN PINF5
#define PF5_RPORT PINF
#define PF5_WPORT PORTF
#define PF5_DDR DDRF
#define PF5_PWM NULL
#undef PF6
#define PF6_PIN PINF6
#define PF6_RPORT PINF
#define PF6_WPORT PORTF
#define PF6_DDR DDRF
#define PF6_PWM NULL
#undef PF7
#define PF7_PIN PINF7
#define PF7_RPORT PINF
#define PF7_WPORT PORTF
#define PF7_DDR DDRF
#define PF7_PWM NULL
#undef PG0
#define PG0_PIN PING0
#define PG0_RPORT PING
#define PG0_WPORT PORTG
#define PG0_DDR DDRG
#define PG0_PWM NULL
#undef PG1
#define PG1_PIN PING1
#define PG1_RPORT PING
#define PG1_WPORT PORTG
#define PG1_DDR DDRG
#define PG1_PWM NULL
#undef PG2
#define PG2_PIN PING2
#define PG2_RPORT PING
#define PG2_WPORT PORTG
#define PG2_DDR DDRG
#define PG2_PWM NULL
#undef PG3
#define PG3_PIN PING3
#define PG3_RPORT PING
#define PG3_WPORT PORTG
#define PG3_DDR DDRG
#define PG3_PWM NULL
#undef PG4
#define PG4_PIN PING4
#define PG4_RPORT PING
#define PG4_WPORT PORTG
#define PG4_DDR DDRG
#define PG4_PWM NULL
#undef PG5
#define PG5_PIN PING5
#define PG5_RPORT PING
#define PG5_WPORT PORTG
#define PG5_DDR DDRG
#define PG5_PWM &OCR0B
#endif // _FASTIO_1281

View File

@ -0,0 +1,362 @@
/**
* 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/>.
*
*/
/**
* Pin mapping for the 168, 328, and 328P
*
* 168 08 09 10 11 12 13 14 15 16 17 18 19 20 21 00 01 02 03 04 05 06 07
* Port B0 B1 B2 B3 B4 B5 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7
* Marlin 08 09 10 11 12 13 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
*/
#ifndef _FASTIO_168
#define _FASTIO_168
#include "fastio_AVR.h"
#define DEBUG_LED AIO5
// UART
#define RXD DIO0
#define TXD DIO1
// SPI
#define SCK DIO13
#define MISO DIO12
#define MOSI DIO11
#define SS DIO10
// TWI (I2C)
#define SCL AIO5
#define SDA AIO4
// Timers and PWM
#define OC0A DIO6
#define OC0B DIO5
#define OC1A DIO9
#define OC1B DIO10
#define OC2A DIO11
#define OC2B DIO3
// Digital I/O
#define DIO0_PIN PIND0
#define DIO0_RPORT PIND
#define DIO0_WPORT PORTD
#define DIO0_DDR DDRD
#define DIO0_PWM NULL
#define DIO1_PIN PIND1
#define DIO1_RPORT PIND
#define DIO1_WPORT PORTD
#define DIO1_DDR DDRD
#define DIO1_PWM NULL
#define DIO2_PIN PIND2
#define DIO2_RPORT PIND
#define DIO2_WPORT PORTD
#define DIO2_DDR DDRD
#define DIO2_PWM NULL
#define DIO3_PIN PIND3
#define DIO3_RPORT PIND
#define DIO3_WPORT PORTD
#define DIO3_DDR DDRD
#define DIO3_PWM &OCR2B
#define DIO4_PIN PIND4
#define DIO4_RPORT PIND
#define DIO4_WPORT PORTD
#define DIO4_DDR DDRD
#define DIO4_PWM NULL
#define DIO5_PIN PIND5
#define DIO5_RPORT PIND
#define DIO5_WPORT PORTD
#define DIO5_DDR DDRD
#define DIO5_PWM &OCR0B
#define DIO6_PIN PIND6
#define DIO6_RPORT PIND
#define DIO6_WPORT PORTD
#define DIO6_DDR DDRD
#define DIO6_PWM &OCR0A
#define DIO7_PIN PIND7
#define DIO7_RPORT PIND
#define DIO7_WPORT PORTD
#define DIO7_DDR DDRD
#define DIO7_PWM NULL
#define DIO8_PIN PINB0
#define DIO8_RPORT PINB
#define DIO8_WPORT PORTB
#define DIO8_DDR DDRB
#define DIO8_PWM NULL
#define DIO9_PIN PINB1
#define DIO9_RPORT PINB
#define DIO9_WPORT PORTB
#define DIO9_DDR DDRB
#define DIO9_PWM NULL
#define DIO10_PIN PINB2
#define DIO10_RPORT PINB
#define DIO10_WPORT PORTB
#define DIO10_DDR DDRB
#define DIO10_PWM NULL
#define DIO11_PIN PINB3
#define DIO11_RPORT PINB
#define DIO11_WPORT PORTB
#define DIO11_DDR DDRB
#define DIO11_PWM &OCR2A
#define DIO12_PIN PINB4
#define DIO12_RPORT PINB
#define DIO12_WPORT PORTB
#define DIO12_DDR DDRB
#define DIO12_PWM NULL
#define DIO13_PIN PINB5
#define DIO13_RPORT PINB
#define DIO13_WPORT PORTB
#define DIO13_DDR DDRB
#define DIO13_PWM NULL
#define DIO14_PIN PINC0
#define DIO14_RPORT PINC
#define DIO14_WPORT PORTC
#define DIO14_DDR DDRC
#define DIO14_PWM NULL
#define DIO15_PIN PINC1
#define DIO15_RPORT PINC
#define DIO15_WPORT PORTC
#define DIO15_DDR DDRC
#define DIO15_PWM NULL
#define DIO16_PIN PINC2
#define DIO16_RPORT PINC
#define DIO16_WPORT PORTC
#define DIO16_DDR DDRC
#define DIO16_PWM NULL
#define DIO17_PIN PINC3
#define DIO17_RPORT PINC
#define DIO17_WPORT PORTC
#define DIO17_DDR DDRC
#define DIO17_PWM NULL
#define DIO18_PIN PINC4
#define DIO18_RPORT PINC
#define DIO18_WPORT PORTC
#define DIO18_DDR DDRC
#define DIO18_PWM NULL
#define DIO19_PIN PINC5
#define DIO19_RPORT PINC
#define DIO19_WPORT PORTC
#define DIO19_DDR DDRC
#define DIO19_PWM NULL
#define DIO20_PIN PINC6
#define DIO20_RPORT PINC
#define DIO20_WPORT PORTC
#define DIO20_DDR DDRC
#define DIO20_PWM NULL
#define DIO21_PIN PINC7
#define DIO21_RPORT PINC
#define DIO21_WPORT PORTC
#define DIO21_DDR DDRC
#define DIO21_PWM NULL
#undef PB0
#define PB0_PIN PINB0
#define PB0_RPORT PINB
#define PB0_WPORT PORTB
#define PB0_DDR DDRB
#define PB0_PWM NULL
#undef PB1
#define PB1_PIN PINB1
#define PB1_RPORT PINB
#define PB1_WPORT PORTB
#define PB1_DDR DDRB
#define PB1_PWM NULL
#undef PB2
#define PB2_PIN PINB2
#define PB2_RPORT PINB
#define PB2_WPORT PORTB
#define PB2_DDR DDRB
#define PB2_PWM NULL
#undef PB3
#define PB3_PIN PINB3
#define PB3_RPORT PINB
#define PB3_WPORT PORTB
#define PB3_DDR DDRB
#define PB3_PWM &OCR2A
#undef PB4
#define PB4_PIN PINB4
#define PB4_RPORT PINB
#define PB4_WPORT PORTB
#define PB4_DDR DDRB
#define PB4_PWM NULL
#undef PB5
#define PB5_PIN PINB5
#define PB5_RPORT PINB
#define PB5_WPORT PORTB
#define PB5_DDR DDRB
#define PB5_PWM NULL
#undef PB6
#define PB6_PIN PINB6
#define PB6_RPORT PINB
#define PB6_WPORT PORTB
#define PB6_DDR DDRB
#define PB6_PWM NULL
#undef PB7
#define PB7_PIN PINB7
#define PB7_RPORT PINB
#define PB7_WPORT PORTB
#define PB7_DDR DDRB
#define PB7_PWM NULL
#undef PC0
#define PC0_PIN PINC0
#define PC0_RPORT PINC
#define PC0_WPORT PORTC
#define PC0_DDR DDRC
#define PC0_PWM NULL
#undef PC1
#define PC1_PIN PINC1
#define PC1_RPORT PINC
#define PC1_WPORT PORTC
#define PC1_DDR DDRC
#define PC1_PWM NULL
#undef PC2
#define PC2_PIN PINC2
#define PC2_RPORT PINC
#define PC2_WPORT PORTC
#define PC2_DDR DDRC
#define PC2_PWM NULL
#undef PC3
#define PC3_PIN PINC3
#define PC3_RPORT PINC
#define PC3_WPORT PORTC
#define PC3_DDR DDRC
#define PC3_PWM NULL
#undef PC4
#define PC4_PIN PINC4
#define PC4_RPORT PINC
#define PC4_WPORT PORTC
#define PC4_DDR DDRC
#define PC4_PWM NULL
#undef PC5
#define PC5_PIN PINC5
#define PC5_RPORT PINC
#define PC5_WPORT PORTC
#define PC5_DDR DDRC
#define PC5_PWM NULL
#undef PC6
#define PC6_PIN PINC6
#define PC6_RPORT PINC
#define PC6_WPORT PORTC
#define PC6_DDR DDRC
#define PC6_PWM NULL
#undef PC7
#define PC7_PIN PINC7
#define PC7_RPORT PINC
#define PC7_WPORT PORTC
#define PC7_DDR DDRC
#define PC7_PWM NULL
#undef PD0
#define PD0_PIN PIND0
#define PD0_RPORT PIND
#define PD0_WPORT PORTD
#define PD0_DDR DDRD
#define PD0_PWM NULL
#undef PD1
#define PD1_PIN PIND1
#define PD1_RPORT PIND
#define PD1_WPORT PORTD
#define PD1_DDR DDRD
#define PD1_PWM NULL
#undef PD2
#define PD2_PIN PIND2
#define PD2_RPORT PIND
#define PD2_WPORT PORTD
#define PD2_DDR DDRD
#define PD2_PWM NULL
#undef PD3
#define PD3_PIN PIND3
#define PD3_RPORT PIND
#define PD3_WPORT PORTD
#define PD3_DDR DDRD
#define PD3_PWM &OCR2B
#undef PD4
#define PD4_PIN PIND4
#define PD4_RPORT PIND
#define PD4_WPORT PORTD
#define PD4_DDR DDRD
#define PD4_PWM NULL
#undef PD5
#define PD5_PIN PIND5
#define PD5_RPORT PIND
#define PD5_WPORT PORTD
#define PD5_DDR DDRD
#define PD5_PWM &OCR0B
#undef PD6
#define PD6_PIN PIND6
#define PD6_RPORT PIND
#define PD6_WPORT PORTD
#define PD6_DDR DDRD
#define PD6_PWM &OCR0A
#undef PD7
#define PD7_PIN PIND7
#define PD7_RPORT PIND
#define PD7_WPORT PORTD
#define PD7_DDR DDRD
#define PD7_PWM NULL
#endif // _FASTIO_168

View File

@ -0,0 +1,531 @@
/**
* 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/>.
*
*/
/**
* Pin mapping for the 644, 644p, 644pa, and 1284p
*
* 644p 31 30 29 28 27 26 25 24 00 01 02 03 04 05 06 07 16 17 18 19 20 21 22 23 08 09 10 11 12 13 14 15
* Port A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7
* Marlin 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
*/
#ifndef _FASTIO_644
#define _FASTIO_644
#include "fastio_AVR.h"
#define DEBUG_LED DIO0
// UART
#define RXD DIO8
#define TXD DIO9
#define RXD0 DIO8
#define TXD0 DIO9
#define RXD1 DIO10
#define TXD1 DIO11
// SPI
#define SCK DIO7
#define MISO DIO6
#define MOSI DIO5
#define SS DIO4
// TWI (I2C)
#define SCL DIO16
#define SDA DIO17
// Timers and PWM
#define OC0A DIO3
#define OC0B DIO4
#define OC1A DIO13
#define OC1B DIO12
#define OC2A DIO15
#define OC2B DIO14
// Digital I/O
#define DIO0_PIN PINB0
#define DIO0_RPORT PINB
#define DIO0_WPORT PORTB
#define DIO0_DDR DDRB
#define DIO0_PWM NULL
#define DIO1_PIN PINB1
#define DIO1_RPORT PINB
#define DIO1_WPORT PORTB
#define DIO1_DDR DDRB
#define DIO1_PWM NULL
#define DIO2_PIN PINB2
#define DIO2_RPORT PINB
#define DIO2_WPORT PORTB
#define DIO2_DDR DDRB
#define DIO2_PWM NULL
#define DIO3_PIN PINB3
#define DIO3_RPORT PINB
#define DIO3_WPORT PORTB
#define DIO3_DDR DDRB
#define DIO3_PWM OCR0A
#define DIO4_PIN PINB4
#define DIO4_RPORT PINB
#define DIO4_WPORT PORTB
#define DIO4_DDR DDRB
#define DIO4_PWM OCR0B
#define DIO5_PIN PINB5
#define DIO5_RPORT PINB
#define DIO5_WPORT PORTB
#define DIO5_DDR DDRB
#define DIO5_PWM NULL
#define DIO6_PIN PINB6
#define DIO6_RPORT PINB
#define DIO6_WPORT PORTB
#define DIO6_DDR DDRB
#define DIO6_PWM NULL
#define DIO7_PIN PINB7
#define DIO7_RPORT PINB
#define DIO7_WPORT PORTB
#define DIO7_DDR DDRB
#define DIO7_PWM NULL
#define DIO8_PIN PIND0
#define DIO8_RPORT PIND
#define DIO8_WPORT PORTD
#define DIO8_DDR DDRD
#define DIO8_PWM NULL
#define DIO9_PIN PIND1
#define DIO9_RPORT PIND
#define DIO9_WPORT PORTD
#define DIO9_DDR DDRD
#define DIO9_PWM NULL
#define DIO10_PIN PIND2
#define DIO10_RPORT PIND
#define DIO10_WPORT PORTD
#define DIO10_DDR DDRD
#define DIO10_PWM NULL
#define DIO11_PIN PIND3
#define DIO11_RPORT PIND
#define DIO11_WPORT PORTD
#define DIO11_DDR DDRD
#define DIO11_PWM NULL
#define DIO12_PIN PIND4
#define DIO12_RPORT PIND
#define DIO12_WPORT PORTD
#define DIO12_DDR DDRD
#define DIO12_PWM OCR1B
#define DIO13_PIN PIND5
#define DIO13_RPORT PIND
#define DIO13_WPORT PORTD
#define DIO13_DDR DDRD
#define DIO13_PWM OCR1A
#define DIO14_PIN PIND6
#define DIO14_RPORT PIND
#define DIO14_WPORT PORTD
#define DIO14_DDR DDRD
#define DIO14_PWM OCR2B
#define DIO15_PIN PIND7
#define DIO15_RPORT PIND
#define DIO15_WPORT PORTD
#define DIO15_DDR DDRD
#define DIO15_PWM OCR2A
#define DIO16_PIN PINC0
#define DIO16_RPORT PINC
#define DIO16_WPORT PORTC
#define DIO16_DDR DDRC
#define DIO16_PWM NULL
#define DIO17_PIN PINC1
#define DIO17_RPORT PINC
#define DIO17_WPORT PORTC
#define DIO17_DDR DDRC
#define DIO17_PWM NULL
#define DIO18_PIN PINC2
#define DIO18_RPORT PINC
#define DIO18_WPORT PORTC
#define DIO18_DDR DDRC
#define DIO18_PWM NULL
#define DIO19_PIN PINC3
#define DIO19_RPORT PINC
#define DIO19_WPORT PORTC
#define DIO19_DDR DDRC
#define DIO19_PWM NULL
#define DIO20_PIN PINC4
#define DIO20_RPORT PINC
#define DIO20_WPORT PORTC
#define DIO20_DDR DDRC
#define DIO20_PWM NULL
#define DIO21_PIN PINC5
#define DIO21_RPORT PINC
#define DIO21_WPORT PORTC
#define DIO21_DDR DDRC
#define DIO21_PWM NULL
#define DIO22_PIN PINC6
#define DIO22_RPORT PINC
#define DIO22_WPORT PORTC
#define DIO22_DDR DDRC
#define DIO22_PWM NULL
#define DIO23_PIN PINC7
#define DIO23_RPORT PINC
#define DIO23_WPORT PORTC
#define DIO23_DDR DDRC
#define DIO23_PWM NULL
#define DIO24_PIN PINA7
#define DIO24_RPORT PINA
#define DIO24_WPORT PORTA
#define DIO24_DDR DDRA
#define DIO24_PWM NULL
#define DIO25_PIN PINA6
#define DIO25_RPORT PINA
#define DIO25_WPORT PORTA
#define DIO25_DDR DDRA
#define DIO25_PWM NULL
#define DIO26_PIN PINA5
#define DIO26_RPORT PINA
#define DIO26_WPORT PORTA
#define DIO26_DDR DDRA
#define DIO26_PWM NULL
#define DIO27_PIN PINA4
#define DIO27_RPORT PINA
#define DIO27_WPORT PORTA
#define DIO27_DDR DDRA
#define DIO27_PWM NULL
#define DIO28_PIN PINA3
#define DIO28_RPORT PINA
#define DIO28_WPORT PORTA
#define DIO28_DDR DDRA
#define DIO28_PWM NULL
#define DIO29_PIN PINA2
#define DIO29_RPORT PINA
#define DIO29_WPORT PORTA
#define DIO29_DDR DDRA
#define DIO29_PWM NULL
#define DIO30_PIN PINA1
#define DIO30_RPORT PINA
#define DIO30_WPORT PORTA
#define DIO30_DDR DDRA
#define DIO30_PWM NULL
#define DIO31_PIN PINA0
#define DIO31_RPORT PINA
#define DIO31_WPORT PORTA
#define DIO31_DDR DDRA
#define DIO31_PWM NULL
#define AIO0_PIN PINA0
#define AIO0_RPORT PINA
#define AIO0_WPORT PORTA
#define AIO0_DDR DDRA
#define AIO0_PWM NULL
#define AIO1_PIN PINA1
#define AIO1_RPORT PINA
#define AIO1_WPORT PORTA
#define AIO1_DDR DDRA
#define AIO1_PWM NULL
#define AIO2_PIN PINA2
#define AIO2_RPORT PINA
#define AIO2_WPORT PORTA
#define AIO2_DDR DDRA
#define AIO2_PWM NULL
#define AIO3_PIN PINA3
#define AIO3_RPORT PINA
#define AIO3_WPORT PORTA
#define AIO3_DDR DDRA
#define AIO3_PWM NULL
#define AIO4_PIN PINA4
#define AIO4_RPORT PINA
#define AIO4_WPORT PORTA
#define AIO4_DDR DDRA
#define AIO4_PWM NULL
#define AIO5_PIN PINA5
#define AIO5_RPORT PINA
#define AIO5_WPORT PORTA
#define AIO5_DDR DDRA
#define AIO5_PWM NULL
#define AIO6_PIN PINA6
#define AIO6_RPORT PINA
#define AIO6_WPORT PORTA
#define AIO6_DDR DDRA
#define AIO6_PWM NULL
#define AIO7_PIN PINA7
#define AIO7_RPORT PINA
#define AIO7_WPORT PORTA
#define AIO7_DDR DDRA
#define AIO7_PWM NULL
#undef PA0
#define PA0_PIN PINA0
#define PA0_RPORT PINA
#define PA0_WPORT PORTA
#define PA0_DDR DDRA
#define PA0_PWM NULL
#undef PA1
#define PA1_PIN PINA1
#define PA1_RPORT PINA
#define PA1_WPORT PORTA
#define PA1_DDR DDRA
#define PA1_PWM NULL
#undef PA2
#define PA2_PIN PINA2
#define PA2_RPORT PINA
#define PA2_WPORT PORTA
#define PA2_DDR DDRA
#define PA2_PWM NULL
#undef PA3
#define PA3_PIN PINA3
#define PA3_RPORT PINA
#define PA3_WPORT PORTA
#define PA3_DDR DDRA
#define PA3_PWM NULL
#undef PA4
#define PA4_PIN PINA4
#define PA4_RPORT PINA
#define PA4_WPORT PORTA
#define PA4_DDR DDRA
#define PA4_PWM NULL
#undef PA5
#define PA5_PIN PINA5
#define PA5_RPORT PINA
#define PA5_WPORT PORTA
#define PA5_DDR DDRA
#define PA5_PWM NULL
#undef PA6
#define PA6_PIN PINA6
#define PA6_RPORT PINA
#define PA6_WPORT PORTA
#define PA6_DDR DDRA
#define PA6_PWM NULL
#undef PA7
#define PA7_PIN PINA7
#define PA7_RPORT PINA
#define PA7_WPORT PORTA
#define PA7_DDR DDRA
#define PA7_PWM NULL
#undef PB0
#define PB0_PIN PINB0
#define PB0_RPORT PINB
#define PB0_WPORT PORTB
#define PB0_DDR DDRB
#define PB0_PWM NULL
#undef PB1
#define PB1_PIN PINB1
#define PB1_RPORT PINB
#define PB1_WPORT PORTB
#define PB1_DDR DDRB
#define PB1_PWM NULL
#undef PB2
#define PB2_PIN PINB2
#define PB2_RPORT PINB
#define PB2_WPORT PORTB
#define PB2_DDR DDRB
#define PB2_PWM NULL
#undef PB3
#define PB3_PIN PINB3
#define PB3_RPORT PINB
#define PB3_WPORT PORTB
#define PB3_DDR DDRB
#define PB3_PWM OCR0A
#undef PB4
#define PB4_PIN PINB4
#define PB4_RPORT PINB
#define PB4_WPORT PORTB
#define PB4_DDR DDRB
#define PB4_PWM OCR0B
#undef PB5
#define PB5_PIN PINB5
#define PB5_RPORT PINB
#define PB5_WPORT PORTB
#define PB5_DDR DDRB
#define PB5_PWM NULL
#undef PB6
#define PB6_PIN PINB6
#define PB6_RPORT PINB
#define PB6_WPORT PORTB
#define PB6_DDR DDRB
#define PB6_PWM NULL
#undef PB7
#define PB7_PIN PINB7
#define PB7_RPORT PINB
#define PB7_WPORT PORTB
#define PB7_DDR DDRB
#define PB7_PWM NULL
#undef PC0
#define PC0_PIN PINC0
#define PC0_RPORT PINC
#define PC0_WPORT PORTC
#define PC0_DDR DDRC
#define PC0_PWM NULL
#undef PC1
#define PC1_PIN PINC1
#define PC1_RPORT PINC
#define PC1_WPORT PORTC
#define PC1_DDR DDRC
#define PC1_PWM NULL
#undef PC2
#define PC2_PIN PINC2
#define PC2_RPORT PINC
#define PC2_WPORT PORTC
#define PC2_DDR DDRC
#define PC2_PWM NULL
#undef PC3
#define PC3_PIN PINC3
#define PC3_RPORT PINC
#define PC3_WPORT PORTC
#define PC3_DDR DDRC
#define PC3_PWM NULL
#undef PC4
#define PC4_PIN PINC4
#define PC4_RPORT PINC
#define PC4_WPORT PORTC
#define PC4_DDR DDRC
#define PC4_PWM NULL
#undef PC5
#define PC5_PIN PINC5
#define PC5_RPORT PINC
#define PC5_WPORT PORTC
#define PC5_DDR DDRC
#define PC5_PWM NULL
#undef PC6
#define PC6_PIN PINC6
#define PC6_RPORT PINC
#define PC6_WPORT PORTC
#define PC6_DDR DDRC
#define PC6_PWM NULL
#undef PC7
#define PC7_PIN PINC7
#define PC7_RPORT PINC
#define PC7_WPORT PORTC
#define PC7_DDR DDRC
#define PC7_PWM NULL
#undef PD0
#define PD0_PIN PIND0
#define PD0_RPORT PIND
#define PD0_WPORT PORTD
#define PD0_DDR DDRD
#define PD0_PWM NULL
#undef PD1
#define PD1_PIN PIND1
#define PD1_RPORT PIND
#define PD1_WPORT PORTD
#define PD1_DDR DDRD
#define PD1_PWM NULL
#undef PD2
#define PD2_PIN PIND2
#define PD2_RPORT PIND
#define PD2_WPORT PORTD
#define PD2_DDR DDRD
#define PD2_PWM NULL
#undef PD3
#define PD3_PIN PIND3
#define PD3_RPORT PIND
#define PD3_WPORT PORTD
#define PD3_DDR DDRD
#define PD3_PWM NULL
#undef PD4
#define PD4_PIN PIND4
#define PD4_RPORT PIND
#define PD4_WPORT PORTD
#define PD4_DDR DDRD
#define PD4_PWM NULL
#undef PD5
#define PD5_PIN PIND5
#define PD5_RPORT PIND
#define PD5_WPORT PORTD
#define PD5_DDR DDRD
#define PD5_PWM NULL
#undef PD6
#define PD6_PIN PIND6
#define PD6_RPORT PIND
#define PD6_WPORT PORTD
#define PD6_DDR DDRD
#define PD6_PWM OCR2B
#undef PD7
#define PD7_PIN PIND7
#define PD7_RPORT PIND
#define PD7_WPORT PORTD
#define PD7_DDR DDRD
#define PD7_PWM OCR2A
#endif // _FASTIO_644

View File

@ -0,0 +1,702 @@
/**
* 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/>.
*
*/
/**
* Pin mapping (Teensy) for AT90USB646, 647, 1286, and 1287
*
* AT90USB 51 50 49 48 47 46 45 44 10 11 12 13 14 15 16 17 35 36 37 38 39 40 41 42 25 26 27 28 29 30 31 32 33 34 43 09 18 19 01 02 61 60 59 58 57 56 55 54
* > Teensy 28 29 30 31 32 33 34 35 20 21 22 23 24 25 26 27 10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07 08 09(46*47)36 37 18 19 38 39 40 41 42 43 44 45
* Port A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7
* The pins 46 and 47 are not supported by Teensyduino, but are supported below as E2 and E3
*/
#ifndef _FASTIO_AT90USB
#define _FASTIO_AT90USB
#include "fastio_AVR.h"
// change for your board
#define DEBUG_LED DIO31 /* led D5 red */
// SPI
#define SCK DIO21 // 9
#define MISO DIO23 // 11
#define MOSI DIO22 // 10
#define SS DIO20 // 8
// Digital I/O
#define DIO0_PIN PIND0
#define DIO0_RPORT PIND
#define DIO0_WPORT PORTD
#define DIO0_PWM NULL
#define DIO0_DDR DDRD
#define DIO1_PIN PIND1
#define DIO1_RPORT PIND
#define DIO1_WPORT PORTD
#define DIO1_PWM NULL
#define DIO1_DDR DDRD
#define DIO2_PIN PIND2
#define DIO2_RPORT PIND
#define DIO2_WPORT PORTD
#define DIO2_PWM NULL
#define DIO2_DDR DDRD
#define DIO3_PIN PIND3
#define DIO3_RPORT PIND
#define DIO3_WPORT PORTD
#define DIO3_PWM NULL
#define DIO3_DDR DDRD
#define DIO4_PIN PIND4
#define DIO4_RPORT PIND
#define DIO4_WPORT PORTD
#define DIO4_PWM NULL
#define DIO4_DDR DDRD
#define DIO5_PIN PIND5
#define DIO5_RPORT PIND
#define DIO5_WPORT PORTD
#define DIO5_PWM NULL
#define DIO5_DDR DDRD
#define DIO6_PIN PIND6
#define DIO6_RPORT PIND
#define DIO6_WPORT PORTD
#define DIO6_PWM NULL
#define DIO6_DDR DDRD
#define DIO7_PIN PIND7
#define DIO7_RPORT PIND
#define DIO7_WPORT PORTD
#define DIO7_PWM NULL
#define DIO7_DDR DDRD
#define DIO8_PIN PINE0
#define DIO8_RPORT PINE
#define DIO8_WPORT PORTE
#define DIO8_PWM NULL
#define DIO8_DDR DDRE
#define DIO9_PIN PINE1
#define DIO9_RPORT PINE
#define DIO9_WPORT PORTE
#define DIO9_PWM NULL
#define DIO9_DDR DDRE
#define DIO10_PIN PINC0
#define DIO10_RPORT PINC
#define DIO10_WPORT PORTC
#define DIO10_PWM NULL
#define DIO10_DDR DDRC
#define DIO11_PIN PINC1
#define DIO11_RPORT PINC
#define DIO11_WPORT PORTC
#define DIO11_PWM NULL
#define DIO11_DDR DDRC
#define DIO12_PIN PINC2
#define DIO12_RPORT PINC
#define DIO12_WPORT PORTC
#define DIO12_PWM NULL
#define DIO12_DDR DDRC
#define DIO13_PIN PINC3
#define DIO13_RPORT PINC
#define DIO13_WPORT PORTC
#define DIO13_PWM NULL
#define DIO13_DDR DDRC
#define DIO14_PIN PINC4
#define DIO14_RPORT PINC
#define DIO14_WPORT PORTC
#define DIO14_PWM NULL
#define DIO14_DDR DDRC
#define DIO15_PIN PINC5
#define DIO15_RPORT PINC
#define DIO15_WPORT PORTC
#define DIO15_PWM NULL
#define DIO15_DDR DDRC
#define DIO16_PIN PINC6
#define DIO16_RPORT PINC
#define DIO16_WPORT PORTC
#define DIO16_PWM NULL
#define DIO16_DDR DDRC
#define DIO17_PIN PINC7
#define DIO17_RPORT PINC
#define DIO17_WPORT PORTC
#define DIO17_PWM NULL
#define DIO17_DDR DDRC
#define DIO18_PIN PINE6
#define DIO18_RPORT PINE
#define DIO18_WPORT PORTE
#define DIO18_PWM NULL
#define DIO18_DDR DDRE
#define DIO19_PIN PINE7
#define DIO19_RPORT PINE
#define DIO19_WPORT PORTE
#define DIO19_PWM NULL
#define DIO19_DDR DDRE
#define DIO20_PIN PINB0
#define DIO20_RPORT PINB
#define DIO20_WPORT PORTB
#define DIO20_PWM NULL
#define DIO20_DDR DDRB
#define DIO21_PIN PINB1
#define DIO21_RPORT PINB
#define DIO21_WPORT PORTB
#define DIO21_PWM NULL
#define DIO21_DDR DDRB
#define DIO22_PIN PINB2
#define DIO22_RPORT PINB
#define DIO22_WPORT PORTB
#define DIO22_PWM NULL
#define DIO22_DDR DDRB
#define DIO23_PIN PINB3
#define DIO23_RPORT PINB
#define DIO23_WPORT PORTB
#define DIO23_PWM NULL
#define DIO23_DDR DDRB
#define DIO24_PIN PINB4
#define DIO24_RPORT PINB
#define DIO24_WPORT PORTB
#define DIO24_PWM NULL
#define DIO24_DDR DDRB
#define DIO25_PIN PINB5
#define DIO25_RPORT PINB
#define DIO25_WPORT PORTB
#define DIO25_PWM NULL
#define DIO25_DDR DDRB
#define DIO26_PIN PINB6
#define DIO26_RPORT PINB
#define DIO26_WPORT PORTB
#define DIO26_PWM NULL
#define DIO26_DDR DDRB
#define DIO27_PIN PINB7
#define DIO27_RPORT PINB
#define DIO27_WPORT PORTB
#define DIO27_PWM NULL
#define DIO27_DDR DDRB
#define DIO28_PIN PINA0
#define DIO28_RPORT PINA
#define DIO28_WPORT PORTA
#define DIO28_PWM NULL
#define DIO28_DDR DDRA
#define DIO29_PIN PINA1
#define DIO29_RPORT PINA
#define DIO29_WPORT PORTA
#define DIO29_PWM NULL
#define DIO29_DDR DDRA
#define DIO30_PIN PINA2
#define DIO30_RPORT PINA
#define DIO30_WPORT PORTA
#define DIO30_PWM NULL
#define DIO30_DDR DDRA
#define DIO31_PIN PINA3
#define DIO31_RPORT PINA
#define DIO31_WPORT PORTA
#define DIO31_PWM NULL
#define DIO31_DDR DDRA
#define DIO32_PIN PINA4
#define DIO32_RPORT PINA
#define DIO32_WPORT PORTA
#define DIO32_PWM NULL
#define DIO32_DDR DDRA
#define DIO33_PIN PINA5
#define DIO33_RPORT PINA
#define DIO33_WPORT PORTA
#define DIO33_PWM NULL
#define DIO33_DDR DDRA
#define DIO34_PIN PINA6
#define DIO34_RPORT PINA
#define DIO34_WPORT PORTA
#define DIO34_PWM NULL
#define DIO34_DDR DDRA
#define DIO35_PIN PINA7
#define DIO35_RPORT PINA
#define DIO35_WPORT PORTA
#define DIO35_PWM NULL
#define DIO35_DDR DDRA
#define DIO36_PIN PINE4
#define DIO36_RPORT PINE
#define DIO36_WPORT PORTE
#define DIO36_PWM NULL
#define DIO36_DDR DDRE
#define DIO37_PIN PINE5
#define DIO37_RPORT PINE
#define DIO37_WPORT PORTE
#define DIO37_PWM NULL
#define DIO37_DDR DDRE
#define DIO38_PIN PINF0
#define DIO38_RPORT PINF
#define DIO38_WPORT PORTF
#define DIO38_PWM NULL
#define DIO38_DDR DDRF
#define DIO39_PIN PINF1
#define DIO39_RPORT PINF
#define DIO39_WPORT PORTF
#define DIO39_PWM NULL
#define DIO39_DDR DDRF
#define DIO40_PIN PINF2
#define DIO40_RPORT PINF
#define DIO40_WPORT PORTF
#define DIO40_PWM NULL
#define DIO40_DDR DDRF
#define DIO41_PIN PINF3
#define DIO41_RPORT PINF
#define DIO41_WPORT PORTF
#define DIO41_PWM NULL
#define DIO41_DDR DDRF
#define DIO42_PIN PINF4
#define DIO42_RPORT PINF
#define DIO42_WPORT PORTF
#define DIO42_PWM NULL
#define DIO42_DDR DDRF
#define DIO43_PIN PINF5
#define DIO43_RPORT PINF
#define DIO43_WPORT PORTF
#define DIO43_PWM NULL
#define DIO43_DDR DDRF
#define DIO44_PIN PINF6
#define DIO44_RPORT PINF
#define DIO44_WPORT PORTF
#define DIO44_PWM NULL
#define DIO44_DDR DDRF
#define DIO45_PIN PINF7
#define DIO45_RPORT PINF
#define DIO45_WPORT PORTF
#define DIO45_PWM NULL
#define DIO45_DDR DDRF
#define AIO0_PIN PINF0
#define AIO0_RPORT PINF
#define AIO0_WPORT PORTF
#define AIO0_PWM NULL
#define AIO0_DDR DDRF
#define AIO1_PIN PINF1
#define AIO1_RPORT PINF
#define AIO1_WPORT PORTF
#define AIO1_PWM NULL
#define AIO1_DDR DDRF
#define AIO2_PIN PINF2
#define AIO2_RPORT PINF
#define AIO2_WPORT PORTF
#define AIO2_PWM NULL
#define AIO2_DDR DDRF
#define AIO3_PIN PINF3
#define AIO3_RPORT PINF
#define AIO3_WPORT PORTF
#define AIO3_PWM NULL
#define AIO3_DDR DDRF
#define AIO4_PIN PINF4
#define AIO4_RPORT PINF
#define AIO4_WPORT PORTF
#define AIO4_PWM NULL
#define AIO4_DDR DDRF
#define AIO5_PIN PINF5
#define AIO5_RPORT PINF
#define AIO5_WPORT PORTF
#define AIO5_PWM NULL
#define AIO5_DDR DDRF
#define AIO6_PIN PINF6
#define AIO6_RPORT PINF
#define AIO6_WPORT PORTF
#define AIO6_PWM NULL
#define AIO6_DDR DDRF
#define AIO7_PIN PINF7
#define AIO7_RPORT PINF
#define AIO7_WPORT PORTF
#define AIO7_PWM NULL
#define AIO7_DDR DDRF
//-- Begin not supported by Teensyduino
//-- don't use Arduino functions on these pins pinMode/digitalWrite/etc
#define DIO46_PIN PINE2
#define DIO46_RPORT PINE
#define DIO46_WPORT PORTE
#define DIO46_PWM NULL
#define DIO46_DDR DDRE
#define DIO47_PIN PINE3
#define DIO47_RPORT PINE
#define DIO47_WPORT PORTE
#define DIO47_PWM NULL
#define DIO47_DDR DDRE
#define TEENSY_E2 46
#define TEENSY_E3 47
//-- end not supported by Teensyduino
#undef PA0
#define PA0_PIN PINA0
#define PA0_RPORT PINA
#define PA0_WPORT PORTA
#define PA0_PWM NULL
#define PA0_DDR DDRA
#undef PA1
#define PA1_PIN PINA1
#define PA1_RPORT PINA
#define PA1_WPORT PORTA
#define PA1_PWM NULL
#define PA1_DDR DDRA
#undef PA2
#define PA2_PIN PINA2
#define PA2_RPORT PINA
#define PA2_WPORT PORTA
#define PA2_PWM NULL
#define PA2_DDR DDRA
#undef PA3
#define PA3_PIN PINA3
#define PA3_RPORT PINA
#define PA3_WPORT PORTA
#define PA3_PWM NULL
#define PA3_DDR DDRA
#undef PA4
#define PA4_PIN PINA4
#define PA4_RPORT PINA
#define PA4_WPORT PORTA
#define PA4_PWM NULL
#define PA4_DDR DDRA
#undef PA5
#define PA5_PIN PINA5
#define PA5_RPORT PINA
#define PA5_WPORT PORTA
#define PA5_PWM NULL
#define PA5_DDR DDRA
#undef PA6
#define PA6_PIN PINA6
#define PA6_RPORT PINA
#define PA6_WPORT PORTA
#define PA6_PWM NULL
#define PA6_DDR DDRA
#undef PA7
#define PA7_PIN PINA7
#define PA7_RPORT PINA
#define PA7_WPORT PORTA
#define PA7_PWM NULL
#define PA7_DDR DDRA
#undef PB0
#define PB0_PIN PINB0
#define PB0_RPORT PINB
#define PB0_WPORT PORTB
#define PB0_PWM NULL
#define PB0_DDR DDRB
#undef PB1
#define PB1_PIN PINB1
#define PB1_RPORT PINB
#define PB1_WPORT PORTB
#define PB1_PWM NULL
#define PB1_DDR DDRB
#undef PB2
#define PB2_PIN PINB2
#define PB2_RPORT PINB
#define PB2_WPORT PORTB
#define PB2_PWM NULL
#define PB2_DDR DDRB
#undef PB3
#define PB3_PIN PINB3
#define PB3_RPORT PINB
#define PB3_WPORT PORTB
#define PB3_PWM NULL
#define PB3_DDR DDRB
#undef PB4
#define PB4_PIN PINB4
#define PB4_RPORT PINB
#define PB4_WPORT PORTB
#define PB4_PWM NULL
#define PB4_DDR DDRB
#undef PB5
#define PB5_PIN PINB5
#define PB5_RPORT PINB
#define PB5_WPORT PORTB
#define PB5_PWM NULL
#define PB5_DDR DDRB
#undef PB6
#define PB6_PIN PINB6
#define PB6_RPORT PINB
#define PB6_WPORT PORTB
#define PB6_PWM NULL
#define PB6_DDR DDRB
#undef PB7
#define PB7_PIN PINB7
#define PB7_RPORT PINB
#define PB7_WPORT PORTB
#define PB7_PWM NULL
#define PB7_DDR DDRB
#undef PC0
#define PC0_PIN PINC0
#define PC0_RPORT PINC
#define PC0_WPORT PORTC
#define PC0_PWM NULL
#define PC0_DDR DDRC
#undef PC1
#define PC1_PIN PINC1
#define PC1_RPORT PINC
#define PC1_WPORT PORTC
#define PC1_PWM NULL
#define PC1_DDR DDRC
#undef PC2
#define PC2_PIN PINC2
#define PC2_RPORT PINC
#define PC2_WPORT PORTC
#define PC2_PWM NULL
#define PC2_DDR DDRC
#undef PC3
#define PC3_PIN PINC3
#define PC3_RPORT PINC
#define PC3_WPORT PORTC
#define PC3_PWM NULL
#define PC3_DDR DDRC
#undef PC4
#define PC4_PIN PINC4
#define PC4_RPORT PINC
#define PC4_WPORT PORTC
#define PC4_PWM NULL
#define PC4_DDR DDRC
#undef PC5
#define PC5_PIN PINC5
#define PC5_RPORT PINC
#define PC5_WPORT PORTC
#define PC5_PWM NULL
#define PC5_DDR DDRC
#undef PC6
#define PC6_PIN PINC6
#define PC6_RPORT PINC
#define PC6_WPORT PORTC
#define PC6_PWM NULL
#define PC6_DDR DDRC
#undef PC7
#define PC7_PIN PINC7
#define PC7_RPORT PINC
#define PC7_WPORT PORTC
#define PC7_PWM NULL
#define PC7_DDR DDRC
#undef PD0
#define PD0_PIN PIND0
#define PD0_RPORT PIND
#define PD0_WPORT PORTD
#define PD0_PWM NULL
#define PD0_DDR DDRD
#undef PD1
#define PD1_PIN PIND1
#define PD1_RPORT PIND
#define PD1_WPORT PORTD
#define PD1_PWM NULL
#define PD1_DDR DDRD
#undef PD2
#define PD2_PIN PIND2
#define PD2_RPORT PIND
#define PD2_WPORT PORTD
#define PD2_PWM NULL
#define PD2_DDR DDRD
#undef PD3
#define PD3_PIN PIND3
#define PD3_RPORT PIND
#define PD3_WPORT PORTD
#define PD3_PWM NULL
#define PD3_DDR DDRD
#undef PD4
#define PD4_PIN PIND4
#define PD4_RPORT PIND
#define PD4_WPORT PORTD
#define PD4_PWM NULL
#define PD4_DDR DDRD
#undef PD5
#define PD5_PIN PIND5
#define PD5_RPORT PIND
#define PD5_WPORT PORTD
#define PD5_PWM NULL
#define PD5_DDR DDRD
#undef PD6
#define PD6_PIN PIND6
#define PD6_RPORT PIND
#define PD6_WPORT PORTD
#define PD6_PWM NULL
#define PD6_DDR DDRD
#undef PD7
#define PD7_PIN PIND7
#define PD7_RPORT PIND
#define PD7_WPORT PORTD
#define PD7_PWM NULL
#define PD7_DDR DDRD
#undef PE0
#define PE0_PIN PINE0
#define PE0_RPORT PINE
#define PE0_WPORT PORTE
#define PE0_PWM NULL
#define PE0_DDR DDRE
#undef PE1
#define PE1_PIN PINE1
#define PE1_RPORT PINE
#define PE1_WPORT PORTE
#define PE1_PWM NULL
#define PE1_DDR DDRE
#undef PE2
#define PE2_PIN PINE2
#define PE2_RPORT PINE
#define PE2_WPORT PORTE
#define PE2_PWM NULL
#define PE2_DDR DDRE
#undef PE3
#define PE3_PIN PINE3
#define PE3_RPORT PINE
#define PE3_WPORT PORTE
#define PE3_PWM NULL
#define PE3_DDR DDRE
#undef PE4
#define PE4_PIN PINE4
#define PE4_RPORT PINE
#define PE4_WPORT PORTE
#define PE4_PWM NULL
#define PE4_DDR DDRE
#undef PE5
#define PE5_PIN PINE5
#define PE5_RPORT PINE
#define PE5_WPORT PORTE
#define PE5_PWM NULL
#define PE5_DDR DDRE
#undef PE6
#define PE6_PIN PINE6
#define PE6_RPORT PINE
#define PE6_WPORT PORTE
#define PE6_PWM NULL
#define PE6_DDR DDRE
#undef PE7
#define PE7_PIN PINE7
#define PE7_RPORT PINE
#define PE7_WPORT PORTE
#define PE7_PWM NULL
#define PE7_DDR DDRE
#undef PF0
#define PF0_PIN PINF0
#define PF0_RPORT PINF
#define PF0_WPORT PORTF
#define PF0_PWM NULL
#define PF0_DDR DDRF
#undef PF1
#define PF1_PIN PINF1
#define PF1_RPORT PINF
#define PF1_WPORT PORTF
#define PF1_PWM NULL
#define PF1_DDR DDRF
#undef PF2
#define PF2_PIN PINF2
#define PF2_RPORT PINF
#define PF2_WPORT PORTF
#define PF2_PWM NULL
#define PF2_DDR DDRF
#undef PF3
#define PF3_PIN PINF3
#define PF3_RPORT PINF
#define PF3_WPORT PORTF
#define PF3_PWM NULL
#define PF3_DDR DDRF
#undef PF4
#define PF4_PIN PINF4
#define PF4_RPORT PINF
#define PF4_WPORT PORTF
#define PF4_PWM NULL
#define PF4_DDR DDRF
#undef PF5
#define PF5_PIN PINF5
#define PF5_RPORT PINF
#define PF5_WPORT PORTF
#define PF5_PWM NULL
#define PF5_DDR DDRF
#undef PF6
#define PF6_PIN PINF6
#define PF6_RPORT PINF
#define PF6_WPORT PORTF
#define PF6_PWM NULL
#define PF6_DDR DDRF
#undef PF7
#define PF7_PIN PINF7
#define PF7_RPORT PINF
#define PF7_WPORT PORTF
#define PF7_PWM NULL
#define PF7_DDR DDRF
/**
* some of the pin mapping functions of the Teensduino extension to the Arduino IDE
* do not function the same as the other Arduino extensions
*/
//digitalPinToTimer(pin) function works like Arduino but Timers are not defined
#define TIMER0B 1
#define TIMER1A 7
#define TIMER1B 8
#define TIMER1C 9
#define TIMER2A 6
#define TIMER2B 2
#define TIMER3A 5
#define TIMER3B 4
#define TIMER3C 3
#endif // _FASTIO_AT90USB

View File

@ -0,0 +1,319 @@
/**
* 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/>.
*
*/
/**
* Fast I/O Routines
* Use direct port manipulation to save scads of processor time.
* Contributed by Triffid_Hunter. Modified by Kliment and the Marlin team.
*/
#ifndef _FASTIO_ARDUINO_H
#define _FASTIO_ARDUINO_H
#include <avr/io.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_ATmega1284_FAMILY (defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__))
#define AVR_ATmega2560_FAMILY (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__))
#define AVR_ATmega2561_FAMILY (defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__))
#define AVR_ATmega328_FAMILY (defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328p__))
/**
* Include Ports and Functions
*/
#if AVR_ATmega328_FAMILY
#include "fastio_168.h"
#elif AVR_ATmega1284_FAMILY
#include "fastio_644.h"
#elif AVR_ATmega2560_FAMILY
#include "fastio_1280.h"
#elif AVR_AT90USB1286_FAMILY
#include "fastio_AT90USB.h"
#elif AVR_ATmega2561_FAMILY
#include "fastio_1281.h"
#else
#error "Pins for this chip not defined in Arduino.h! If you have a working pins definition, please contribute!"
#endif
#ifndef _BV
#define _BV(bit) (1UL << (bit))
#endif
/**
* Magic I/O routines
*
* Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW);
*
* Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
*/
#define _READ(IO) ((bool)(DIO ## IO ## _RPORT & _BV(DIO ## IO ## _PIN)))
// On some boards pins > 0x100 are used. These are not converted to atomic actions. A critical section is needed.
#define _WRITE_NC(IO, v) do { if (v) {DIO ## IO ## _WPORT |= _BV(DIO ## IO ## _PIN); } else {DIO ## IO ## _WPORT &= ~_BV(DIO ## IO ## _PIN); }; } while (0)
#define _WRITE_C(IO, v) do { if (v) { \
CRITICAL_SECTION_START; \
{DIO ## IO ## _WPORT |= _BV(DIO ## IO ## _PIN); } \
CRITICAL_SECTION_END; \
} \
else { \
CRITICAL_SECTION_START; \
{DIO ## IO ## _WPORT &= ~_BV(DIO ## IO ## _PIN); } \
CRITICAL_SECTION_END; \
} \
} \
while (0)
#define _WRITE(IO, v) do { if (&(DIO ## IO ## _RPORT) >= (uint8_t *)0x100) {_WRITE_C(IO, v); } else {_WRITE_NC(IO, v); }; } while (0)
#define _TOGGLE(IO) do {DIO ## IO ## _RPORT ^= _BV(DIO ## IO ## _PIN); } while (0)
#define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~_BV(DIO ## IO ## _PIN); } while (0)
#define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= _BV(DIO ## IO ## _PIN); } while (0)
#define _GET_INPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) == 0)
#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) != 0)
#define _GET_TIMER(IO) (DIO ## IO ## _PWM)
#define READ(IO) _READ(IO)
#define WRITE(IO,V) _WRITE(IO,V)
#define TOGGLE(IO) _TOGGLE(IO)
#define SET_INPUT(IO) _SET_INPUT(IO)
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0)
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
#define GET_INPUT(IO) _GET_INPUT(IO)
#define GET_OUTPUT(IO) _GET_OUTPUT(IO)
#define GET_TIMER(IO) _GET_TIMER(IO)
#define OUT_WRITE(IO, v) do{ SET_OUTPUT(IO); WRITE(IO, v); }while(0)
/**
* Timer and Interrupt Control
*/
// Waveform Generation Modes
typedef enum {
WGM_NORMAL, // 0
WGM_PWM_PC_8, // 1
WGM_PWM_PC_9, // 2
WGM_PWM_PC_10, // 3
WGM_CTC_OCRnA, // 4 COM OCnx
WGM_FAST_PWM_8, // 5
WGM_FAST_PWM_9, // 6
WGM_FAST_PWM_10, // 7
WGM_PWM_PC_FC_ICRn, // 8
WGM_PWM_PC_FC_OCRnA, // 9 COM OCnA
WGM_PWM_PC_ICRn, // 10
WGM_PWM_PC_OCRnA, // 11 COM OCnA
WGM_CTC_ICRn, // 12 COM OCnx
WGM_reserved, // 13
WGM_FAST_PWM_ICRn, // 14 COM OCnA
WGM_FAST_PWM_OCRnA // 15 COM OCnA
} WaveGenMode;
// Compare Modes
typedef enum {
COM_NORMAL, // 0
COM_TOGGLE, // 1 Non-PWM: OCnx ... Both PWM (WGM 9,11,14,15): OCnA only ... else NORMAL
COM_CLEAR_SET, // 2 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down
COM_SET_CLEAR // 3 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down
} CompareMode;
// Clock Sources
typedef enum {
CS_NONE, // 0
CS_PRESCALER_1, // 1
CS_PRESCALER_8, // 2
CS_PRESCALER_64, // 3
CS_PRESCALER_256, // 4
CS_PRESCALER_1024, // 5
CS_EXT_FALLING, // 6
CS_EXT_RISING // 7
} ClockSource;
// Clock Sources (Timer 2 only)
typedef enum {
CS2_NONE, // 0
CS2_PRESCALER_1, // 1
CS2_PRESCALER_8, // 2
CS2_PRESCALER_32, // 3
CS2_PRESCALER_64, // 4
CS2_PRESCALER_128, // 5
CS2_PRESCALER_256, // 6
CS2_PRESCALER_1024 // 7
} ClockSource2;
// Get interrupt bits in an orderly way
#define GET_WGM(T) (((TCCR##T##A >> WGM##T##0) & 0x3) | ((TCCR##T##B >> WGM##T##2 << 2) & 0xC))
#define GET_CS(T) ((TCCR##T##B >> CS##T##0) & 0x7)
#define GET_COM(T,Q) ((TCCR##T##Q >> COM##T##Q##0) & 0x3)
#define GET_COMA(T) GET_COM(T,A)
#define GET_COMB(T) GET_COM(T,B)
#define GET_COMC(T) GET_COM(T,C)
#define GET_ICNC(T) (!!(TCCR##T##B & _BV(ICNC##T)))
#define GET_ICES(T) (!!(TCCR##T##B & _BV(ICES##T)))
#define GET_FOC(T,Q) (!!(TCCR##T##C & _BV(FOC##T##Q)))
#define GET_FOCA(T) GET_FOC(T,A)
#define GET_FOCB(T) GET_FOC(T,B)
#define GET_FOCC(T) GET_FOC(T,C)
// Set Wave Generation Mode bits
#define _SET_WGM(T,V) do{ \
TCCR##T##A = (TCCR##T##A & ~(0x3 << WGM##T##0)) | (( int(V) & 0x3) << WGM##T##0); \
TCCR##T##B = (TCCR##T##B & ~(0x3 << WGM##T##2)) | (((int(V) >> 2) & 0x3) << WGM##T##2); \
}while(0)
#define SET_WGM(T,V) _SET_WGM(T,WGM_##V)
// Set Clock Select bits
#define _SET_CS(T,V) (TCCR##T##B = (TCCR##T##B & ~(0x7 << CS##T##0)) | ((int(V) & 0x7) << CS##T##0))
#define _SET_CS0(V) _SET_CS(0,V)
#define _SET_CS1(V) _SET_CS(1,V)
#ifdef TCCR2
#define _SET_CS2(V) (TCCR2 = (TCCR2 & ~(0x7 << CS20)) | (int(V) << CS20))
#else
#define _SET_CS2(V) _SET_CS(2,V)
#endif
#define _SET_CS3(V) _SET_CS(3,V)
#define _SET_CS4(V) _SET_CS(4,V)
#define _SET_CS5(V) _SET_CS(5,V)
#define SET_CS0(V) _SET_CS0(CS_##V)
#define SET_CS1(V) _SET_CS1(CS_##V)
#ifdef TCCR2
#define SET_CS2(V) _SET_CS2(CS2_##V)
#else
#define SET_CS2(V) _SET_CS2(CS_##V)
#endif
#define SET_CS3(V) _SET_CS3(CS_##V)
#define SET_CS4(V) _SET_CS4(CS_##V)
#define SET_CS5(V) _SET_CS5(CS_##V)
#define SET_CS(T,V) SET_CS##T(V)
// Set Compare Mode bits
#define _SET_COM(T,Q,V) (TCCR##T##Q = (TCCR##T##Q & ~(0x3 << COM##T##Q##0)) | (int(V) << COM##T##Q##0))
#define SET_COM(T,Q,V) _SET_COM(T,Q,COM_##V)
#define SET_COMA(T,V) SET_COM(T,A,V)
#define SET_COMB(T,V) SET_COM(T,B,V)
#define SET_COMC(T,V) SET_COM(T,C,V)
#define SET_COMS(T,V1,V2,V3) do{ SET_COMA(T,V1); SET_COMB(T,V2); SET_COMC(T,V3); }while(0)
// Set Noise Canceler bit
#define SET_ICNC(T,V) (TCCR##T##B = (V) ? TCCR##T##B | _BV(ICNC##T) : TCCR##T##B & ~_BV(ICNC##T))
// Set Input Capture Edge Select bit
#define SET_ICES(T,V) (TCCR##T##B = (V) ? TCCR##T##B | _BV(ICES##T) : TCCR##T##B & ~_BV(ICES##T))
// Set Force Output Compare bit
#define SET_FOC(T,Q,V) (TCCR##T##C = (V) ? TCCR##T##C | _BV(FOC##T##Q) : TCCR##T##C & ~_BV(FOC##T##Q))
#define SET_FOCA(T,V) SET_FOC(T,A,V)
#define SET_FOCB(T,V) SET_FOC(T,B,V)
#define SET_FOCC(T,V) SET_FOC(T,C,V)
/**
* PWM availability macros
*/
//find out which harware PWMs are already in use
#if PIN_EXISTS(CONTROLLER_FAN)
#define PWM_CHK_FAN_B(p) (p == CONTROLLER_FAN_PIN || p == E0_AUTO_FAN_PIN || p == E1_AUTO_FAN_PIN || p == E2_AUTO_FAN_PIN || p == E3_AUTO_FAN_PIN || p == E4_AUTO_FAN_PIN)
#else
#define PWM_CHK_FAN_B(p) (p == E0_AUTO_FAN_PIN || p == E1_AUTO_FAN_PIN || p == E2_AUTO_FAN_PIN || p == E3_AUTO_FAN_PIN || p == E4_AUTO_FAN_PIN)
#endif
#if PIN_EXISTS(FAN) || PIN_EXISTS(FAN1) || PIN_EXISTS(FAN2)
#if PIN_EXISTS(FAN2)
#define PWM_CHK_FAN_A(p) (p == FAN_PIN || p == FAN1_PIN || p == FAN2_PIN)
#elif PIN_EXISTS(FAN1)
#define PWM_CHK_FAN_A(p) (p == FAN_PIN || p == FAN1_PIN)
#else
#define PWM_CHK_FAN_A(p) p == FAN_PIN
#endif
#else
#define PWM_CHK_FAN_A(p) false
#endif
#if HAS_MOTOR_CURRENT_PWM
#if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
#define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E || p == MOTOR_CURRENT_PWM_Z || p == MOTOR_CURRENT_PWM_XY)
#elif PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
#define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E || p == MOTOR_CURRENT_PWM_Z)
#else
#define PWM_CHK_MOTOR_CURRENT(p) (p == MOTOR_CURRENT_PWM_E)
#endif
#else
#define PWM_CHK_MOTOR_CURRENT(p) false
#endif
#ifdef NUM_SERVOS
#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
#elif AVR_ATmega2561_FAMILY
#define PWM_CHK_SERVO(p) p == 5 //PWM3A
#elif AVR_ATmega1284_FAMILY
#define PWM_CHK_SERVO(p) false
#elif AVR_AT90USB1286_FAMILY
#define PWM_CHK_SERVO(p) p == 16 //PWM3A
#elif AVR_ATmega328_FAMILY
#define PWM_CHK_SERVO(p) false
#endif
#else
#define PWM_CHK_SERVO(p) false
#endif
#if ENABLED(BARICUDA)
#if HAS_HEATER_1 && HAS_HEATER_2
#define PWM_CHK_HEATER(p) (p == HEATER_1_PIN || p == HEATER_2_PIN)
#elif HAS_HEATER_1
#define PWM_CHK_HEATER(p) (p == HEATER_1_PIN)
#endif
#else
#define PWM_CHK_HEATER(p) false
#endif
#define PWM_CHK(p) (PWM_CHK_HEATER(p) || PWM_CHK_SERVO(p) || PWM_CHK_MOTOR_CURRENT(p)\
|| PWM_CHK_FAN_A(p) || PWM_CHK_FAN_B(p))
// define which hardware PWMs are available for the current CPU
// all timer 1 PWMS deleted from this list because they are never available
#if AVR_ATmega2560_FAMILY
#define PWM_PINS(p) ((p >= 2 && p <= 10 ) || p == 13 || p == 44 || p == 45 || p == 46 )
#elif AVR_ATmega2561_FAMILY
#define PWM_PINS(p) ((p >= 2 && p <= 6 ) || p == 9)
#elif AVR_ATmega1284_FAMILY
#define PWM_PINS(p) (p == 3 || p == 4 || p == 14 || p == 15)
#elif AVR_AT90USB1286_FAMILY
#define PWM_PINS(p) (p == 0 || p == 1 || p == 14 || p == 15 || p == 16 || p == 24)
#elif AVR_ATmega328_FAMILY
#define PWM_PINS(p) (p == 3 || p == 5 || p == 6 || p == 11)
#else
#error "unknown CPU"
#endif
// finally - the macro that tells us if a pin is an available hardware PWM
#define USEABLE_HARDWARE_PWM(p) (PWM_PINS(p) && !PWM_CHK(p))
#endif // _FASTIO_ARDUINO_H

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,106 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2017 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/>.
*
*/
//
// some of the pin mapping functions of the Teensduino extension to the Arduino IDE
// do not function the same as the other Arduino extensions
//
#ifndef __PINSDEBUG_TEENSYDUINO_H__
#define __PINSDEBUG_TEENSYDUINO_H__
#undef NUM_DIGITAL_PINS
#define NUM_DIGITAL_PINS 48 // Teensy says 46 but FASTIO is 48
// "digitalPinToPort" function just returns the pin number so need to create our own.
// Can't use the name "digitalPinToPort" for our own because it interferes with the
// FAST_PWM_FAN function if we do
#define PA 1
#define PB 2
#define PC 3
#define PD 4
#define PE 5
#define PF 6
const uint8_t PROGMEM digital_pin_to_port_PGM_Teensy[] = {
PD, // 0 - PD0 - INT0 - PWM
PD, // 1 - PD1 - INT1 - PWM
PD, // 2 - PD2 - INT2 - RX
PD, // 3 - PD3 - INT3 - TX
PD, // 4 - PD4
PD, // 5 - PD5
PD, // 6 - PD6
PD, // 7 - PD7
PE, // 8 - PE0
PE, // 9 - PE1
PC, // 10 - PC0
PC, // 11 - PC1
PC, // 12 - PC2
PC, // 13 - PC3
PC, // 14 - PC4 - PWM
PC, // 15 - PC5 - PWM
PC, // 16 - PC6 - PWM
PC, // 17 - PC7
PE, // 18 - PE6 - INT6
PE, // 19 - PE7 - INT7
PB, // 20 - PB0
PB, // 21 - PB1
PB, // 22 - PB2
PB, // 23 - PB3
PB, // 24 - PB4 - PWM
PB, // 25 - PB5 - PWM
PB, // 26 - PB6 - PWM
PB, // 27 - PB7 - PWM
PA, // 28 - PA0
PA, // 29 - PA1
PA, // 30 - PA2
PA, // 31 - PA3
PA, // 32 - PA4
PA, // 33 - PA5
PA, // 34 - PA6
PA, // 35 - PA7
PE, // 36 - PE4 - INT4
PE, // 37 - PE5 - INT5
PF, // 38 - PF0 - A0
PF, // 39 - PF1 - A1
PF, // 40 - PF2 - A2
PF, // 41 - PF3 - A3
PF, // 42 - PF4 - A4
PF, // 43 - PF5 - A5
PF, // 44 - PF6 - A6
PF, // 45 - PF7 - A7
PE, // 46 - PE2 (not defined in teensyduino)
PE, // 47 - PE3 (not defined in teensyduino)
};
#define digitalPinToPort_Teensy(P) ( pgm_read_byte( digital_pin_to_port_PGM_Teensy + (P) ) )
// digitalPinToBitMask(pin) is OK
#define digitalRead_mod(p) digitalRead(p) // Teensyduino's version of digitalRead doesn't
// disable the PWMs so we can use it as is
// portModeRegister(pin) is OK
#endif // __PINSDEBUG_TEENSYDUINO_H__

View File

@ -0,0 +1,341 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* 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/>.
*
*/
/**
* structurs for 2560 family boards that use morre than 70 pins
*/
#ifndef __PINSDEBUG_PLUS_70_H__
#define __PINSDEBUG_PLUS_70_H__
#undef NUM_DIGITAL_PINS
#if MOTHERBOARD == BOARD_BQ_ZUM_MEGA_3D
#define NUM_DIGITAL_PINS 85
#elif MOTHERBOARD == BOARD_MIGHTYBOARD_REVE
#define NUM_DIGITAL_PINS 80
#elif MOTHERBOARD == BOARD_MINIRAMBO
#define NUM_DIGITAL_PINS 85
#elif MOTHERBOARD == BOARD_SCOOVO_X9H
#define NUM_DIGITAL_PINS 85
#endif
#define PA 1
#define PB 2
#define PC 3
#define PD 4
#define PE 5
#define PF 6
#define PG 7
#define PH 8
#define PJ 10
#define PK 11
#define PL 12
const uint8_t PROGMEM digital_pin_to_port_PGM_plus_70[] = {
// PORTLIST
// -------------------------------------------
PE , // PE 0 ** 0 ** USART0_RX
PE , // PE 1 ** 1 ** USART0_TX
PE , // PE 4 ** 2 ** PWM2
PE , // PE 5 ** 3 ** PWM3
PG , // PG 5 ** 4 ** PWM4
PE , // PE 3 ** 5 ** PWM5
PH , // PH 3 ** 6 ** PWM6
PH , // PH 4 ** 7 ** PWM7
PH , // PH 5 ** 8 ** PWM8
PH , // PH 6 ** 9 ** PWM9
PB , // PB 4 ** 10 ** PWM10
PB , // PB 5 ** 11 ** PWM11
PB , // PB 6 ** 12 ** PWM12
PB , // PB 7 ** 13 ** PWM13
PJ , // PJ 1 ** 14 ** USART3_TX
PJ , // PJ 0 ** 15 ** USART3_RX
PH , // PH 1 ** 16 ** USART2_TX
PH , // PH 0 ** 17 ** USART2_RX
PD , // PD 3 ** 18 ** USART1_TX
PD , // PD 2 ** 19 ** USART1_RX
PD , // PD 1 ** 20 ** I2C_SDA
PD , // PD 0 ** 21 ** I2C_SCL
PA , // PA 0 ** 22 ** D22
PA , // PA 1 ** 23 ** D23
PA , // PA 2 ** 24 ** D24
PA , // PA 3 ** 25 ** D25
PA , // PA 4 ** 26 ** D26
PA , // PA 5 ** 27 ** D27
PA , // PA 6 ** 28 ** D28
PA , // PA 7 ** 29 ** D29
PC , // PC 7 ** 30 ** D30
PC , // PC 6 ** 31 ** D31
PC , // PC 5 ** 32 ** D32
PC , // PC 4 ** 33 ** D33
PC , // PC 3 ** 34 ** D34
PC , // PC 2 ** 35 ** D35
PC , // PC 1 ** 36 ** D36
PC , // PC 0 ** 37 ** D37
PD , // PD 7 ** 38 ** D38
PG , // PG 2 ** 39 ** D39
PG , // PG 1 ** 40 ** D40
PG , // PG 0 ** 41 ** D41
PL , // PL 7 ** 42 ** D42
PL , // PL 6 ** 43 ** D43
PL , // PL 5 ** 44 ** D44
PL , // PL 4 ** 45 ** D45
PL , // PL 3 ** 46 ** D46
PL , // PL 2 ** 47 ** D47
PL , // PL 1 ** 48 ** D48
PL , // PL 0 ** 49 ** D49
PB , // PB 3 ** 50 ** SPI_MISO
PB , // PB 2 ** 51 ** SPI_MOSI
PB , // PB 1 ** 52 ** SPI_SCK
PB , // PB 0 ** 53 ** SPI_SS
PF , // PF 0 ** 54 ** A0
PF , // PF 1 ** 55 ** A1
PF , // PF 2 ** 56 ** A2
PF , // PF 3 ** 57 ** A3
PF , // PF 4 ** 58 ** A4
PF , // PF 5 ** 59 ** A5
PF , // PF 6 ** 60 ** A6
PF , // PF 7 ** 61 ** A7
PK , // PK 0 ** 62 ** A8
PK , // PK 1 ** 63 ** A9
PK , // PK 2 ** 64 ** A10
PK , // PK 3 ** 65 ** A11
PK , // PK 4 ** 66 ** A12
PK , // PK 5 ** 67 ** A13
PK , // PK 6 ** 68 ** A14
PK , // PK 7 ** 69 ** A15
PG , // PG 4 ** 70 **
PG , // PG 3 ** 71 **
PJ , // PJ 2 ** 72 **
PJ , // PJ 3 ** 73 **
PJ , // PJ 7 ** 74 **
PJ , // PJ 4 ** 75 **
PJ , // PJ 5 ** 76 **
PJ , // PJ 6 ** 77 **
PE , // PE 2 ** 78 **
PE , // PE 6 ** 79 **
PE , // PE 7 ** 80 **
PD , // PD 4 ** 81 **
PD , // PD 5 ** 82 **
PD , // PD 6 ** 83 **
PH , // PH 2 ** 84 **
PH , // PH 7 ** 85 **
};
#define digitalPinToPort_plus_70(P) ( pgm_read_byte( digital_pin_to_port_PGM_plus_70 + (P) ) )
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM_plus_70[] = {
// PIN IN PORT
// -------------------------------------------
_BV( 0 ) , // PE 0 ** 0 ** USART0_RX
_BV( 1 ) , // PE 1 ** 1 ** USART0_TX
_BV( 4 ) , // PE 4 ** 2 ** PWM2
_BV( 5 ) , // PE 5 ** 3 ** PWM3
_BV( 5 ) , // PG 5 ** 4 ** PWM4
_BV( 3 ) , // PE 3 ** 5 ** PWM5
_BV( 3 ) , // PH 3 ** 6 ** PWM6
_BV( 4 ) , // PH 4 ** 7 ** PWM7
_BV( 5 ) , // PH 5 ** 8 ** PWM8
_BV( 6 ) , // PH 6 ** 9 ** PWM9
_BV( 4 ) , // PB 4 ** 10 ** PWM10
_BV( 5 ) , // PB 5 ** 11 ** PWM11
_BV( 6 ) , // PB 6 ** 12 ** PWM12
_BV( 7 ) , // PB 7 ** 13 ** PWM13
_BV( 1 ) , // PJ 1 ** 14 ** USART3_TX
_BV( 0 ) , // PJ 0 ** 15 ** USART3_RX
_BV( 1 ) , // PH 1 ** 16 ** USART2_TX
_BV( 0 ) , // PH 0 ** 17 ** USART2_RX
_BV( 3 ) , // PD 3 ** 18 ** USART1_TX
_BV( 2 ) , // PD 2 ** 19 ** USART1_RX
_BV( 1 ) , // PD 1 ** 20 ** I2C_SDA
_BV( 0 ) , // PD 0 ** 21 ** I2C_SCL
_BV( 0 ) , // PA 0 ** 22 ** D22
_BV( 1 ) , // PA 1 ** 23 ** D23
_BV( 2 ) , // PA 2 ** 24 ** D24
_BV( 3 ) , // PA 3 ** 25 ** D25
_BV( 4 ) , // PA 4 ** 26 ** D26
_BV( 5 ) , // PA 5 ** 27 ** D27
_BV( 6 ) , // PA 6 ** 28 ** D28
_BV( 7 ) , // PA 7 ** 29 ** D29
_BV( 7 ) , // PC 7 ** 30 ** D30
_BV( 6 ) , // PC 6 ** 31 ** D31
_BV( 5 ) , // PC 5 ** 32 ** D32
_BV( 4 ) , // PC 4 ** 33 ** D33
_BV( 3 ) , // PC 3 ** 34 ** D34
_BV( 2 ) , // PC 2 ** 35 ** D35
_BV( 1 ) , // PC 1 ** 36 ** D36
_BV( 0 ) , // PC 0 ** 37 ** D37
_BV( 7 ) , // PD 7 ** 38 ** D38
_BV( 2 ) , // PG 2 ** 39 ** D39
_BV( 1 ) , // PG 1 ** 40 ** D40
_BV( 0 ) , // PG 0 ** 41 ** D41
_BV( 7 ) , // PL 7 ** 42 ** D42
_BV( 6 ) , // PL 6 ** 43 ** D43
_BV( 5 ) , // PL 5 ** 44 ** D44
_BV( 4 ) , // PL 4 ** 45 ** D45
_BV( 3 ) , // PL 3 ** 46 ** D46
_BV( 2 ) , // PL 2 ** 47 ** D47
_BV( 1 ) , // PL 1 ** 48 ** D48
_BV( 0 ) , // PL 0 ** 49 ** D49
_BV( 3 ) , // PB 3 ** 50 ** SPI_MISO
_BV( 2 ) , // PB 2 ** 51 ** SPI_MOSI
_BV( 1 ) , // PB 1 ** 52 ** SPI_SCK
_BV( 0 ) , // PB 0 ** 53 ** SPI_SS
_BV( 0 ) , // PF 0 ** 54 ** A0
_BV( 1 ) , // PF 1 ** 55 ** A1
_BV( 2 ) , // PF 2 ** 56 ** A2
_BV( 3 ) , // PF 3 ** 57 ** A3
_BV( 4 ) , // PF 4 ** 58 ** A4
_BV( 5 ) , // PF 5 ** 59 ** A5
_BV( 6 ) , // PF 6 ** 60 ** A6
_BV( 7 ) , // PF 7 ** 61 ** A7
_BV( 0 ) , // PK 0 ** 62 ** A8
_BV( 1 ) , // PK 1 ** 63 ** A9
_BV( 2 ) , // PK 2 ** 64 ** A10
_BV( 3 ) , // PK 3 ** 65 ** A11
_BV( 4 ) , // PK 4 ** 66 ** A12
_BV( 5 ) , // PK 5 ** 67 ** A13
_BV( 6 ) , // PK 6 ** 68 ** A14
_BV( 7 ) , // PK 7 ** 69 ** A15
_BV( 4 ) , // PG 4 ** 70 **
_BV( 3 ) , // PG 3 ** 71 **
_BV( 2 ) , // PJ 2 ** 72 **
_BV( 3 ) , // PJ 3 ** 73 **
_BV( 7 ) , // PJ 7 ** 74 **
_BV( 4 ) , // PJ 4 ** 75 **
_BV( 5 ) , // PJ 5 ** 76 **
_BV( 6 ) , // PJ 6 ** 77 **
_BV( 2 ) , // PE 2 ** 78 **
_BV( 6 ) , // PE 6 ** 79 **
_BV( 7 ) , // PE 7 ** 80 **
_BV( 4 ) , // PD 4 ** 81 **
_BV( 5 ) , // PD 5 ** 82 **
_BV( 6 ) , // PD 6 ** 83 **
_BV( 2 ) , // PH 2 ** 84 **
_BV( 7 ) , // PH 7 ** 85 **
};
#define digitalPinToBitMask_plus_70(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM_plus_70 + (P) ) )
const uint8_t PROGMEM digital_pin_to_timer_PGM_plus_70[] = {
// TIMERS
// -------------------------------------------
NOT_ON_TIMER , // PE 0 ** 0 ** USART0_RX
NOT_ON_TIMER , // PE 1 ** 1 ** USART0_TX
TIMER3B , // PE 4 ** 2 ** PWM2
TIMER3C , // PE 5 ** 3 ** PWM3
TIMER0B , // PG 5 ** 4 ** PWM4
TIMER3A , // PE 3 ** 5 ** PWM5
TIMER4A , // PH 3 ** 6 ** PWM6
TIMER4B , // PH 4 ** 7 ** PWM7
TIMER4C , // PH 5 ** 8 ** PWM8
TIMER2B , // PH 6 ** 9 ** PWM9
TIMER2A , // PB 4 ** 10 ** PWM10
TIMER1A , // PB 5 ** 11 ** PWM11
TIMER1B , // PB 6 ** 12 ** PWM12
TIMER0A , // PB 7 ** 13 ** PWM13
NOT_ON_TIMER , // PJ 1 ** 14 ** USART3_TX
NOT_ON_TIMER , // PJ 0 ** 15 ** USART3_RX
NOT_ON_TIMER , // PH 1 ** 16 ** USART2_TX
NOT_ON_TIMER , // PH 0 ** 17 ** USART2_RX
NOT_ON_TIMER , // PD 3 ** 18 ** USART1_TX
NOT_ON_TIMER , // PD 2 ** 19 ** USART1_RX
NOT_ON_TIMER , // PD 1 ** 20 ** I2C_SDA
NOT_ON_TIMER , // PD 0 ** 21 ** I2C_SCL
NOT_ON_TIMER , // PA 0 ** 22 ** D22
NOT_ON_TIMER , // PA 1 ** 23 ** D23
NOT_ON_TIMER , // PA 2 ** 24 ** D24
NOT_ON_TIMER , // PA 3 ** 25 ** D25
NOT_ON_TIMER , // PA 4 ** 26 ** D26
NOT_ON_TIMER , // PA 5 ** 27 ** D27
NOT_ON_TIMER , // PA 6 ** 28 ** D28
NOT_ON_TIMER , // PA 7 ** 29 ** D29
NOT_ON_TIMER , // PC 7 ** 30 ** D30
NOT_ON_TIMER , // PC 6 ** 31 ** D31
NOT_ON_TIMER , // PC 5 ** 32 ** D32
NOT_ON_TIMER , // PC 4 ** 33 ** D33
NOT_ON_TIMER , // PC 3 ** 34 ** D34
NOT_ON_TIMER , // PC 2 ** 35 ** D35
NOT_ON_TIMER , // PC 1 ** 36 ** D36
NOT_ON_TIMER , // PC 0 ** 37 ** D37
NOT_ON_TIMER , // PD 7 ** 38 ** D38
NOT_ON_TIMER , // PG 2 ** 39 ** D39
NOT_ON_TIMER , // PG 1 ** 40 ** D40
NOT_ON_TIMER , // PG 0 ** 41 ** D41
NOT_ON_TIMER , // PL 7 ** 42 ** D42
NOT_ON_TIMER , // PL 6 ** 43 ** D43
TIMER5C , // PL 5 ** 44 ** D44
TIMER5B , // PL 4 ** 45 ** D45
TIMER5A , // PL 3 ** 46 ** D46
NOT_ON_TIMER , // PL 2 ** 47 ** D47
NOT_ON_TIMER , // PL 1 ** 48 ** D48
NOT_ON_TIMER , // PL 0 ** 49 ** D49
NOT_ON_TIMER , // PB 3 ** 50 ** SPI_MISO
NOT_ON_TIMER , // PB 2 ** 51 ** SPI_MOSI
NOT_ON_TIMER , // PB 1 ** 52 ** SPI_SCK
NOT_ON_TIMER , // PB 0 ** 53 ** SPI_SS
NOT_ON_TIMER , // PF 0 ** 54 ** A0
NOT_ON_TIMER , // PF 1 ** 55 ** A1
NOT_ON_TIMER , // PF 2 ** 56 ** A2
NOT_ON_TIMER , // PF 3 ** 57 ** A3
NOT_ON_TIMER , // PF 4 ** 58 ** A4
NOT_ON_TIMER , // PF 5 ** 59 ** A5
NOT_ON_TIMER , // PF 6 ** 60 ** A6
NOT_ON_TIMER , // PF 7 ** 61 ** A7
NOT_ON_TIMER , // PK 0 ** 62 ** A8
NOT_ON_TIMER , // PK 1 ** 63 ** A9
NOT_ON_TIMER , // PK 2 ** 64 ** A10
NOT_ON_TIMER , // PK 3 ** 65 ** A11
NOT_ON_TIMER , // PK 4 ** 66 ** A12
NOT_ON_TIMER , // PK 5 ** 67 ** A13
NOT_ON_TIMER , // PK 6 ** 68 ** A14
NOT_ON_TIMER , // PK 7 ** 69 ** A15
NOT_ON_TIMER , // PG 4 ** 70 **
NOT_ON_TIMER , // PG 3 ** 71 **
NOT_ON_TIMER , // PJ 2 ** 72 **
NOT_ON_TIMER , // PJ 3 ** 73 **
NOT_ON_TIMER , // PJ 7 ** 74 **
NOT_ON_TIMER , // PJ 4 ** 75 **
NOT_ON_TIMER , // PJ 5 ** 76 **
NOT_ON_TIMER , // PJ 6 ** 77 **
NOT_ON_TIMER , // PE 2 ** 78 **
NOT_ON_TIMER , // PE 6 ** 79 **
};
#define digitalPinToTimer_plus_70(P) ( pgm_read_byte( digital_pin_to_timer_PGM_plus_70 + (P) ) )
/**
* Interrupts that are not implemented
*
* INT6 E6 79
* INT7 E7 80
* PCINT11 J2 72
* PCINT12 J3 73
* PCINT13 J4 75
* PCINT14 J5 76
* PCINT15 J6 77
*/
#endif // __PINSDEBUG_PLUS_70_H__

View File

@ -0,0 +1,219 @@
/**
* 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.
*
*/
#ifdef ARDUINO_ARCH_AVR
#include "../../../MarlinConfig.h"
#if HAS_SERVOS
#include <avr/interrupt.h>
#include <Arduino.h>
#include "../servo.h"
#include "../servo_private.h"
static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
/************ static functions common to all instances ***********************/
static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t* TCNTn, volatile uint16_t* OCRnA) {
if (Channel[timer] < 0)
*TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer
else {
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive)
digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
}
Channel[timer]++; // increment to the next channel
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
*OCRnA = *TCNTn + SERVO(timer, Channel[timer]).ticks;
if (SERVO(timer, Channel[timer]).Pin.isActive) // check if activated
digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
}
else {
// finished all channels so wait for the refresh period to expire before starting over
if (((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL)) // allow a few ticks to ensure the next OCR1A not missed
*OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL);
else
*OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed
Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
}
}
#ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform
// Interrupt handlers for Arduino
#if ENABLED(_useTimer1)
SIGNAL (TIMER1_COMPA_vect) { handle_interrupts(_timer1, &TCNT1, &OCR1A); }
#endif
#if ENABLED(_useTimer3)
SIGNAL (TIMER3_COMPA_vect) { handle_interrupts(_timer3, &TCNT3, &OCR3A); }
#endif
#if ENABLED(_useTimer4)
SIGNAL (TIMER4_COMPA_vect) { handle_interrupts(_timer4, &TCNT4, &OCR4A); }
#endif
#if ENABLED(_useTimer5)
SIGNAL (TIMER5_COMPA_vect) { handle_interrupts(_timer5, &TCNT5, &OCR5A); }
#endif
#else // WIRING
// Interrupt handlers for Wiring
#if ENABLED(_useTimer1)
void Timer1Service() { handle_interrupts(_timer1, &TCNT1, &OCR1A); }
#endif
#if ENABLED(_useTimer3)
void Timer3Service() { handle_interrupts(_timer3, &TCNT3, &OCR3A); }
#endif
#endif // WIRING
/****************** end of static functions ******************************/
void initISR(timer16_Sequence_t timer) {
#if ENABLED(_useTimer1)
if (timer == _timer1) {
TCCR1A = 0; // normal counting mode
TCCR1B = _BV(CS11); // set prescaler of 8
TCNT1 = 0; // clear the timer count
#if defined(__AVR_ATmega8__)|| defined(__AVR_ATmega128__)
SBI(TIFR, OCF1A); // clear any pending interrupts;
SBI(TIMSK, OCIE1A); // enable the output compare interrupt
#else
// here if not ATmega8 or ATmega128
SBI(TIFR1, OCF1A); // clear any pending interrupts;
SBI(TIMSK1, OCIE1A); // enable the output compare interrupt
#endif
#ifdef WIRING
timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service);
#endif
}
#endif
#if ENABLED(_useTimer3)
if (timer == _timer3) {
TCCR3A = 0; // normal counting mode
TCCR3B = _BV(CS31); // set prescaler of 8
TCNT3 = 0; // clear the timer count
#ifdef __AVR_ATmega128__
SBI(TIFR, OCF3A); // clear any pending interrupts;
SBI(ETIMSK, OCIE3A); // enable the output compare interrupt
#else
SBI(TIFR3, OCF3A); // clear any pending interrupts;
SBI(TIMSK3, OCIE3A); // enable the output compare interrupt
#endif
#ifdef WIRING
timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only
#endif
}
#endif
#if ENABLED(_useTimer4)
if (timer == _timer4) {
TCCR4A = 0; // normal counting mode
TCCR4B = _BV(CS41); // set prescaler of 8
TCNT4 = 0; // clear the timer count
TIFR4 = _BV(OCF4A); // clear any pending interrupts;
TIMSK4 = _BV(OCIE4A); // enable the output compare interrupt
}
#endif
#if ENABLED(_useTimer5)
if (timer == _timer5) {
TCCR5A = 0; // normal counting mode
TCCR5B = _BV(CS51); // set prescaler of 8
TCNT5 = 0; // clear the timer count
TIFR5 = _BV(OCF5A); // clear any pending interrupts;
TIMSK5 = _BV(OCIE5A); // enable the output compare interrupt
}
#endif
}
void finISR(timer16_Sequence_t timer) {
// Disable use of the given timer
#ifdef WIRING
if (timer == _timer1) {
CBI(
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
TIMSK1
#else
TIMSK
#endif
, OCIE1A); // disable timer 1 output compare interrupt
timerDetach(TIMER1OUTCOMPAREA_INT);
}
else if (timer == _timer3) {
CBI(
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
TIMSK3
#else
ETIMSK
#endif
, OCIE3A); // disable the timer3 output compare A interrupt
timerDetach(TIMER3OUTCOMPAREA_INT);
}
#else // !WIRING
// For arduino - in future: call here to a currently undefined function to reset the timer
UNUSED(timer);
#endif
}
#endif // HAS_SERVOS
#endif // ARDUINO_ARCH_AVR

View File

@ -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_ */

View File

@ -0,0 +1,59 @@
/**
* 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/>.
*
*/
#ifdef ARDUINO_ARCH_AVR
#include "../../../Marlin.h"
#if ENABLED(USE_WATCHDOG)
#include "watchdog_AVR.h"
// Initialize watchdog with a 4 sec interrupt time
void watchdog_init() {
#if ENABLED(WATCHDOG_RESET_MANUAL)
// We enable the watchdog timer, but only for the interrupt.
// Take care, as this requires the correct order of operation, with interrupts disabled. See the datasheet of any AVR chip for details.
wdt_reset();
_WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE);
_WD_CONTROL_REG = _BV(WDIE) | WDTO_4S;
#else
wdt_enable(WDTO_4S);
#endif
}
//===========================================================================
//=================================== ISR ===================================
//===========================================================================
// Watchdog timer interrupt, called if main program blocks >4sec and manual reset is enabled.
#if ENABLED(WATCHDOG_RESET_MANUAL)
ISR(WDT_vect) {
SERIAL_ERROR_START();
SERIAL_ERRORLNPGM("Something is wrong, please turn off the printer.");
kill(PSTR("ERR:Please Reset")); //kill blocks //16 characters so it fits on a 16x2 display
while (1); //wait for user or serial reset
}
#endif // WATCHDOG_RESET_MANUAL
#endif // USE_WATCHDOG
#endif // ARDUINO_ARCH_AVR

View File

@ -0,0 +1,37 @@
/**
* 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 WATCHDOG_AVR_H
#define WATCHDOG_AVR_H
//#include "../../../Marlin.h"
#include <avr/wdt.h>
// Initialize watchdog with a 4 second interrupt time
void watchdog_init();
// Reset watchdog. MUST be called at least every 4 seconds after the
// first watchdog_init or AVR will go into emergency procedures.
inline void watchdog_reset() { wdt_reset(); }
#endif

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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_ */

168
Marlin/src/HAL/servo.cpp Normal file
View File

@ -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

109
Marlin/src/HAL/servo.h Normal file
View File

@ -0,0 +1,109 @@
/**
* 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
*/
/**
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 sequence used to seize timers is defined in timers.h
The methods are:
Servo - Class for manipulating servo motors connected to Arduino pins.
attach(pin ) - Attaches a servo motor to an i/o pin.
attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds
default min is 544, max is 2400
write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds)
writeMicroseconds() - Sets the servo pulse width in microseconds
read() - Gets the last written servo pulse width as an angle between 0 and 180.
readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release)
attached() - Returns true if there is a servo attached.
detach() - Stops an attached servos from pulsing its i/o pin.
move(angle) - Sequence of attach(0), write(angle),
With DEACTIVATE_SERVOS_AFTER_MOVE wait SERVO_DELAY and detach.
*/
#ifndef servo_h
#define servo_h
#if IS_32BIT_TEENSY
#include "HAL_TEENSY35_36/HAL_Servo_Teensy.h" // Teensy HAL uses an inherited library
#else
#include <inttypes.h>
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_SAM)
// we're good to go
#else
#error "This library only supports boards with an AVR or SAM3X processor."
#endif
#define Servo_VERSION 2 // software version of this library
class Servo {
public:
Servo();
int8_t attach(int pin); // attach the given pin to the next free channel, set pinMode, return channel number (-1 on fail)
int8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes.
void detach();
void write(int value); // if value is < 200 it is treated as an angle, otherwise as pulse width in microseconds
void writeMicroseconds(int value); // write pulse width in microseconds
void move(int value); // attach the servo, then move to value
// if value is < 200 it is treated as an angle, otherwise as pulse width in microseconds
// if DEACTIVATE_SERVOS_AFTER_MOVE wait SERVO_DELAY, then detach
int read(); // returns current pulse width as an angle between 0 and 180 degrees
int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release)
bool attached(); // return true if this servo is attached, otherwise false
private:
uint8_t servoIndex; // index into the channel data for this servo
int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH
int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH
};
#endif // !TEENSY
#endif

View File

@ -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