Marlin 2.0 for Flying Bear 4S/5
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

330 lines
13 KiB

/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* 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. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <https://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#include "../config.h"
#ifdef __MARLIN_FIRMWARE__
// Marlin will define the I/O functions for us
#if ENABLED(TOUCH_UI_FTDI_EVE)
#define FTDI_BASIC
#define FTDI_EXTENDED
#endif
#else // !__MARLIN_FIRMWARE__
#include <Arduino.h>
#ifndef CLCD_USE_SOFT_SPI
#include <SPI.h>
#endif
namespace fast_io {
template<typename port_t,uint8_t bits>
struct port_pin {
typedef port_t port;
static inline void set_high() {port::port() = (port::port() | bits);}
static inline void set_low() {port::port() = (port::port() & (~bits));}
static inline void set_input() {port::ddr() = (port::ddr() & (~bits));}
static inline void set_input_pullup() {set_input(); set_high();}
static inline void set_output() {port::ddr() = (port::ddr() | bits);}
static inline uint8_t read() {return port::pin() & bits;}
static inline void write(bool v) {if (v) set_high(); else set_low();}
};
#define MAKE_AVR_PORT_PINS(ID) \
struct port_##ID { \
static volatile uint8_t &pin() {return PIN##ID;}; \
static volatile uint8_t &port() {return PORT##ID;}; \
static volatile uint8_t &ddr() {return DDR##ID;}; \
}; \
typedef port_pin<port_##ID, 0b00000001> AVR_##ID##0; \
typedef port_pin<port_##ID, 0b00000010> AVR_##ID##1; \
typedef port_pin<port_##ID, 0b00000100> AVR_##ID##2; \
typedef port_pin<port_##ID, 0b00001000> AVR_##ID##3; \
typedef port_pin<port_##ID, 0b00010000> AVR_##ID##4; \
typedef port_pin<port_##ID, 0b00100000> AVR_##ID##5; \
typedef port_pin<port_##ID, 0b01000000> AVR_##ID##6; \
typedef port_pin<port_##ID, 0b10000000> AVR_##ID##7;
#ifdef PORTA
MAKE_AVR_PORT_PINS(A);
#endif
#ifdef PORTB
MAKE_AVR_PORT_PINS(B);
#endif
#ifdef PORTC
MAKE_AVR_PORT_PINS(C);
#endif
#ifdef PORTD
MAKE_AVR_PORT_PINS(D);
#endif
#ifdef PORTE
MAKE_AVR_PORT_PINS(E);
#endif
#ifdef PORTF
MAKE_AVR_PORT_PINS(F);
#endif
#ifdef PORTG
MAKE_AVR_PORT_PINS(G);
#endif
#ifdef PORTH
MAKE_AVR_PORT_PINS(H);
#endif
#ifdef PORTJ
MAKE_AVR_PORT_PINS(J);
#endif
#ifdef PORTK
MAKE_AVR_PORT_PINS(K);
#endif
#ifdef PORTL
MAKE_AVR_PORT_PINS(L);
#endif
#ifdef PORTQ
MAKE_AVR_PORT_PINS(Q);
#endif
#ifdef PORTR
MAKE_AVR_PORT_PINS(R);
#endif
#undef MAKE_AVR_PORT_PINS
template<uint8_t p>
struct arduino_digital_pin {
static constexpr uint8_t pin = p;
static inline void set_high() {digitalWrite(p, HIGH);}
static inline void set_low() {digitalWrite(p, LOW);}
static inline void set_input() {pinMode(p, INPUT);}
static inline void set_input_pullup() {pinMode(p, INPUT_PULLUP);}
static inline void set_output() {pinMode(p, OUTPUT);}
static inline uint8_t read() {return digitalRead(p);}
static inline void write(bool v) {digitalWrite(p, v ? HIGH : LOW);}
};
#define MAKE_ARDUINO_PINS(ID) typedef arduino_digital_pin<ID> ARDUINO_DIGITAL_##ID;
MAKE_ARDUINO_PINS( 0);
MAKE_ARDUINO_PINS( 1);
MAKE_ARDUINO_PINS( 2);
MAKE_ARDUINO_PINS( 3);
MAKE_ARDUINO_PINS( 4);
MAKE_ARDUINO_PINS( 5);
MAKE_ARDUINO_PINS( 6);
MAKE_ARDUINO_PINS( 7);
MAKE_ARDUINO_PINS( 8);
MAKE_ARDUINO_PINS( 9);
MAKE_ARDUINO_PINS(10);
MAKE_ARDUINO_PINS(11);
MAKE_ARDUINO_PINS(12);
MAKE_ARDUINO_PINS(13);
MAKE_ARDUINO_PINS(14);
MAKE_ARDUINO_PINS(15);
MAKE_ARDUINO_PINS(16);
MAKE_ARDUINO_PINS(17);
MAKE_ARDUINO_PINS(18);
MAKE_ARDUINO_PINS(19);
MAKE_ARDUINO_PINS(10);
MAKE_ARDUINO_PINS(21);
MAKE_ARDUINO_PINS(22);
MAKE_ARDUINO_PINS(23);
MAKE_ARDUINO_PINS(24);
MAKE_ARDUINO_PINS(25);
MAKE_ARDUINO_PINS(26);
MAKE_ARDUINO_PINS(27);
MAKE_ARDUINO_PINS(28);
MAKE_ARDUINO_PINS(29);
MAKE_ARDUINO_PINS(30);
MAKE_ARDUINO_PINS(31);
MAKE_ARDUINO_PINS(32);
MAKE_ARDUINO_PINS(33);
MAKE_ARDUINO_PINS(34);
MAKE_ARDUINO_PINS(35);
MAKE_ARDUINO_PINS(36);
MAKE_ARDUINO_PINS(37);
MAKE_ARDUINO_PINS(38);
MAKE_ARDUINO_PINS(39);
MAKE_ARDUINO_PINS(40);
MAKE_ARDUINO_PINS(41);
MAKE_ARDUINO_PINS(42);
MAKE_ARDUINO_PINS(43);
MAKE_ARDUINO_PINS(44);
MAKE_ARDUINO_PINS(45);
MAKE_ARDUINO_PINS(46);
MAKE_ARDUINO_PINS(47);
MAKE_ARDUINO_PINS(48);
MAKE_ARDUINO_PINS(49);
MAKE_ARDUINO_PINS(50);
MAKE_ARDUINO_PINS(51);
MAKE_ARDUINO_PINS(52);
MAKE_ARDUINO_PINS(53);
#undef MAKE_ARDUINO_PINS
} // namespace fast_io
#define SET_INPUT(pin) fast_io::pin::set_input()
#define SET_INPUT_PULLUP(pin) do{ fast_io::pin::set_input(); fast_io::pin::set_high(); }while(0)
#define SET_INPUT_PULLDOWN SET_INPUT
#define SET_OUTPUT(pin) fast_io::pin::set_output()
#define READ(pin) fast_io::pin::read()
#define WRITE(pin, value) fast_io::pin::write(value)
#ifndef pgm_read_word_far
#define pgm_read_word_far pgm_read_word
#endif
#ifndef pgm_read_dword_far
#define pgm_read_dword_far pgm_read_dword
#endif
#ifndef pgm_read_ptr_far
#define pgm_read_ptr_far pgm_read_ptr
#endif
// Use NUM_ARGS(__VA_ARGS__) to get the number of variadic arguments
#define _NUM_ARGS(_,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A,OUT,...) OUT
#define NUM_ARGS(V...) _NUM_ARGS(0,V,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
// SERIAL_ECHOPGM / SERIAL_ECHOPGM_P is used to output a key value pair. The key must be a string and the value can be anything
// Print up to 12 pairs of values. Odd elements auto-wrapped in PSTR().
#define __SEP_N(N,V...) _SEP_##N(V)
#define _SEP_N(N,V...) __SEP_N(N,V)
#define _SEP_1(PRE) SERIAL_ECHOPGM(PRE)
#define _SEP_2(PRE,V) do{ Serial.print(F(PRE)); Serial.print(V); }while(0)
#define _SEP_3(a,b,c) do{ _SEP_2(a,b); SERIAL_ECHOPGM(c); }while(0)
#define _SEP_4(a,b,V...) do{ _SEP_2(a,b); _SEP_2(V); }while(0)
// Print up to 1 pairs of values followed by newline
#define __SELP_N(N,V...) _SELP_##N(V)
#define _SELP_N(N,V...) __SELP_N(N,V)
#define _SELP_1(PRE) SERIAL_ECHOLNPGM(PRE)
#define _SELP_2(PRE,V) do{ Serial.print(F(PRE)); Serial.println(V); }while(0)
#define _SELP_3(a,b,c) do{ _SEP_2(a,b); SERIAL_ECHOLNPGM(c); }while(0)
#define _SELP_4(a,b,V...) do{ _SEP_2(a,b); _SELP_2(V); }while(0)
#define SERIAL_ECHO_START()
#define SERIAL_ECHOLNPGM(str) Serial.println(F(str))
#define SERIAL_ECHOPGM(str) Serial.print(F(str))
#define SERIAL_ECHO_MSG(V...) SERIAL_ECHOLNPGM(V)
#define SERIAL_ECHOLNPGM(V...) _SELP_N(NUM_ARGS(V),V)
#define SERIAL_ECHOPGM(str, val) do{ Serial.print(F(str)); Serial.print(val); }while(0)
#define safe_delay delay
// Define macros for compatibility
// Use NUM_ARGS(__VA_ARGS__) to get the number of variadic arguments
#define _NUM_ARGS(_,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A,OUT,...) OUT
#define NUM_ARGS(V...) _NUM_ARGS(0,V,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define _CAT(a,V...) a##V
#define CAT(a,V...) _CAT(a,V)
#define FIRST(a,...) a
#define SECOND(a,b,...) b
#define THIRD(a,b,c,...) c
#define IS_PROBE(V...) SECOND(V, 0) // Get the second item passed, or 0
#define PROBE() ~, 1 // Second item will be 1 if this is passed
#define _NOT_0 PROBE()
#define NOT(x) IS_PROBE(_CAT(_NOT_, x)) // NOT('0') gets '1'. Anything else gets '0'.
#define _BOOL(x) NOT(NOT(x)) // NOT('0') gets '0'. Anything else gets '1'.
#define _DO_1(W,C,A) (_##W##_1(A))
#define _DO_2(W,C,A,B) (_##W##_1(A) C _##W##_1(B))
#define _DO_3(W,C,A,V...) (_##W##_1(A) C _DO_2(W,C,V))
#define _DO_4(W,C,A,V...) (_##W##_1(A) C _DO_3(W,C,V))
#define _DO_5(W,C,A,V...) (_##W##_1(A) C _DO_4(W,C,V))
#define _DO_6(W,C,A,V...) (_##W##_1(A) C _DO_5(W,C,V))
#define _DO_7(W,C,A,V...) (_##W##_1(A) C _DO_6(W,C,V))
#define _DO_8(W,C,A,V...) (_##W##_1(A) C _DO_7(W,C,V))
#define _DO_9(W,C,A,V...) (_##W##_1(A) C _DO_8(W,C,V))
#define _DO_10(W,C,A,V...) (_##W##_1(A) C _DO_9(W,C,V))
#define _DO_11(W,C,A,V...) (_##W##_1(A) C _DO_10(W,C,V))
#define _DO_12(W,C,A,V...) (_##W##_1(A) C _DO_11(W,C,V))
#define _DO_13(W,C,A,V...) (_##W##_1(A) C _DO_12(W,C,V))
#define _DO_14(W,C,A,V...) (_##W##_1(A) C _DO_13(W,C,V))
#define _DO_15(W,C,A,V...) (_##W##_1(A) C _DO_14(W,C,V))
#define _DO_16(W,C,A,V...) (_##W##_1(A) C _DO_15(W,C,V))
#define _DO_17(W,C,A,V...) (_##W##_1(A) C _DO_16(W,C,V))
#define _DO_18(W,C,A,V...) (_##W##_1(A) C _DO_17(W,C,V))
#define _DO_19(W,C,A,V...) (_##W##_1(A) C _DO_18(W,C,V))
#define _DO_20(W,C,A,V...) (_##W##_1(A) C _DO_19(W,C,V))
#define _DO_21(W,C,A,V...) (_##W##_1(A) C _DO_20(W,C,V))
#define _DO_22(W,C,A,V...) (_##W##_1(A) C _DO_21(W,C,V))
#define _DO_23(W,C,A,V...) (_##W##_1(A) C _DO_22(W,C,V))
#define _DO_24(W,C,A,V...) (_##W##_1(A) C _DO_23(W,C,V))
#define _DO_25(W,C,A,V...) (_##W##_1(A) C _DO_24(W,C,V))
#define _DO_26(W,C,A,V...) (_##W##_1(A) C _DO_25(W,C,V))
#define _DO_27(W,C,A,V...) (_##W##_1(A) C _DO_26(W,C,V))
#define _DO_28(W,C,A,V...) (_##W##_1(A) C _DO_27(W,C,V))
#define _DO_29(W,C,A,V...) (_##W##_1(A) C _DO_28(W,C,V))
#define _DO_30(W,C,A,V...) (_##W##_1(A) C _DO_29(W,C,V))
#define _DO_31(W,C,A,V...) (_##W##_1(A) C _DO_30(W,C,V))
#define _DO_32(W,C,A,V...) (_##W##_1(A) C _DO_31(W,C,V))
#define _DO_33(W,C,A,V...) (_##W##_1(A) C _DO_32(W,C,V))
#define _DO_34(W,C,A,V...) (_##W##_1(A) C _DO_33(W,C,V))
#define _DO_35(W,C,A,V...) (_##W##_1(A) C _DO_34(W,C,V))
#define _DO_36(W,C,A,V...) (_##W##_1(A) C _DO_35(W,C,V))
#define _DO_37(W,C,A,V...) (_##W##_1(A) C _DO_36(W,C,V))
#define _DO_38(W,C,A,V...) (_##W##_1(A) C _DO_37(W,C,V))
#define _DO_39(W,C,A,V...) (_##W##_1(A) C _DO_38(W,C,V))
#define _DO_40(W,C,A,V...) (_##W##_1(A) C _DO_39(W,C,V))
#define __DO_N(W,C,N,V...) _DO_##N(W,C,V)
#define _DO_N(W,C,N,V...) __DO_N(W,C,N,V)
#define DO(W,C,V...) _DO_N(W,C,NUM_ARGS(V),V)
#define _ISENA_ ~,1
#define _ISENA_1 ~,1
#define _ISENA_0x1 ~,1
#define _ISENA_true ~,1
#define _ISENA(V...) IS_PROBE(V)
#define _ENA_1(O) _ISENA(CAT(_IS,CAT(ENA_, O)))
#define _DIS_1(O) NOT(_ENA_1(O))
#define ENABLED(V...) DO(ENA,&&,V)
#define DISABLED(V...) DO(DIS,&&,V)
#define TERN(O,A,B) _TERN(_ENA_1(O),B,A) // OPTION converted to '0' or '1'
#define TERN0(O,A) _TERN(_ENA_1(O),0,A) // OPTION converted to A or '0'
#define TERN1(O,A) _TERN(_ENA_1(O),1,A) // OPTION converted to A or '1'
#define TERN_(O,A) _TERN(_ENA_1(O),,A) // OPTION converted to A or '<nul>'
#define _TERN(E,V...) __TERN(_CAT(T_,E),V) // Prepend 'T_' to get 'T_0' or 'T_1'
#define __TERN(T,V...) ___TERN(_CAT(_NO,T),V) // Prepend '_NO' to get '_NOT_0' or '_NOT_1'
#define ___TERN(P,V...) THIRD(P,V) // If first argument has a comma, A. Else B.
#define IF_ENABLED TERN_
#define IF_DISABLED(O,A) _TERN(_ENA_1(O),,A)
#define ANY(V...) !DISABLED(V)
#define NONE(V...) DISABLED(V)
#define ALL(V...) ENABLED(V)
#define BOTH(V1,V2) ALL(V1,V2)
#define EITHER(V1,V2) ANY(V1,V2)
// Remove compiler warning on an unused variable
#ifndef UNUSED
#ifdef HAL_STM32
#define UNUSED(X) (void)X
#else
#define UNUSED(x) ((void)(x))
#endif
#endif
#endif // !__MARLIN_FIRMWARE__
#ifndef SD_SPI_SPEED
#define SD_SPI_SPEED SPI_FULL_SPEED
#endif