JBA
5 years ago
committed by
GitHub
7 changed files with 1753 additions and 4 deletions
@ -0,0 +1,294 @@ |
|||||
|
/*
|
||||
|
anycubic_serial.cpp --- Support for Anycubic i3 Mega TFT serial connection |
||||
|
Created by Christian Hopp on 09.12.17. |
||||
|
|
||||
|
Original file: |
||||
|
HardwareSerial.cpp - Hardware serial library for Wiring |
||||
|
Copyright (c) 2006 Nicholas Zambetti. All right reserved. |
||||
|
|
||||
|
This library is free software; you can redistribute it and/or |
||||
|
modify it under the terms of the GNU Lesser General Public |
||||
|
License as published by the Free Software Foundation; either |
||||
|
version 2.1 of the License, or (at your option) any later version. |
||||
|
|
||||
|
This library is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
Lesser General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU Lesser General Public |
||||
|
License along with this library; if not, write to the Free Software |
||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
|
||||
|
Modified 23 November 2006 by David A. Mellis |
||||
|
Modified 28 September 2010 by Mark Sproul |
||||
|
Modified 14 August 2012 by Alarus |
||||
|
*/ |
||||
|
|
||||
|
#include "../../../../inc/MarlinConfig.h" |
||||
|
|
||||
|
#if ENABLED(ANYCUBIC_TFT_MODEL) |
||||
|
|
||||
|
#include "Arduino.h" |
||||
|
|
||||
|
// this next line disables the entire HardwareSerial.cpp,
|
||||
|
// so I can support AtTiny series and other chips without a UART
|
||||
|
#ifdef UBRR3H |
||||
|
|
||||
|
#include "anycubic_serial.h" |
||||
|
|
||||
|
#include <stdlib.h> |
||||
|
#include <stdio.h> |
||||
|
#include <string.h> |
||||
|
#include <inttypes.h> |
||||
|
#include "wiring_private.h" |
||||
|
|
||||
|
// Define constants and variables for buffering incoming serial data. We're
|
||||
|
// using a ring buffer (I think), in which head is the index of the location
|
||||
|
// to which to write the next incoming character and tail is the index of the
|
||||
|
// location from which to read.
|
||||
|
#if (RAMEND < 1000) |
||||
|
#define SERIAL_BUFFER_SIZE 64 |
||||
|
#else |
||||
|
#define SERIAL_BUFFER_SIZE 128 |
||||
|
#endif |
||||
|
|
||||
|
struct ring_buffer { |
||||
|
unsigned char buffer[SERIAL_BUFFER_SIZE]; |
||||
|
volatile unsigned int head; |
||||
|
volatile unsigned int tail; |
||||
|
}; |
||||
|
|
||||
|
#ifdef UBRR3H |
||||
|
ring_buffer rx_buffer_ajg = { { 0 }, 0, 0 }; |
||||
|
ring_buffer tx_buffer_ajg = { { 0 }, 0, 0 }; |
||||
|
#endif |
||||
|
|
||||
|
inline void store_char(unsigned char c, ring_buffer *buffer) { |
||||
|
int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE; |
||||
|
|
||||
|
// 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 != buffer->tail) { |
||||
|
buffer->buffer[buffer->head] = c; |
||||
|
buffer->head = i; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#if defined(USART3_RX_vect) && defined(UDR3) |
||||
|
void serialEvent3() __attribute__((weak)); |
||||
|
void serialEvent3() {} |
||||
|
#define serialEvent3_implemented |
||||
|
ISR(USART3_RX_vect) { |
||||
|
if (bit_is_clear(UCSR3A, UPE3)) { |
||||
|
unsigned char c = UDR3; |
||||
|
store_char(c, &rx_buffer_ajg); |
||||
|
} |
||||
|
else { |
||||
|
unsigned char c = UDR3; |
||||
|
} |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#ifdef USART3_UDRE_vect |
||||
|
|
||||
|
ISR(USART3_UDRE_vect) { |
||||
|
if (tx_buffer_ajg.head == tx_buffer_ajg.tail) { |
||||
|
// Buffer empty, so disable interrupts
|
||||
|
cbi(UCSR3B, UDRIE3); |
||||
|
} |
||||
|
else { |
||||
|
// There is more data in the output buffer. Send the next byte
|
||||
|
unsigned char c = tx_buffer_ajg.buffer[tx_buffer_ajg.tail]; |
||||
|
tx_buffer_ajg.tail = (tx_buffer_ajg.tail + 1) % SERIAL_BUFFER_SIZE; |
||||
|
|
||||
|
UDR3 = c; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
// Constructors ////////////////////////////////////////////////////////////////
|
||||
|
|
||||
|
AnycubicSerialClass::AnycubicSerialClass(ring_buffer *rx_buffer, ring_buffer *tx_buffer, |
||||
|
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, |
||||
|
volatile uint8_t *ucsra, volatile uint8_t *ucsrb, |
||||
|
volatile uint8_t *ucsrc, volatile uint8_t *udr, |
||||
|
uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x |
||||
|
) { |
||||
|
_rx_buffer = rx_buffer; |
||||
|
_tx_buffer = tx_buffer; |
||||
|
_ubrrh = ubrrh; |
||||
|
_ubrrl = ubrrl; |
||||
|
_ucsra = ucsra; |
||||
|
_ucsrb = ucsrb; |
||||
|
_ucsrc = ucsrc; |
||||
|
_udr = udr; |
||||
|
_rxen = rxen; |
||||
|
_txen = txen; |
||||
|
_rxcie = rxcie; |
||||
|
_udrie = udrie; |
||||
|
_u2x = u2x; |
||||
|
} |
||||
|
|
||||
|
// Public Methods //////////////////////////////////////////////////////////////
|
||||
|
|
||||
|
void AnycubicSerialClass::begin(unsigned long baud) { |
||||
|
uint16_t baud_setting; |
||||
|
bool use_u2x = true; |
||||
|
|
||||
|
#if F_CPU == 16000000UL |
||||
|
// hardcoded 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) use_u2x = false; |
||||
|
#endif |
||||
|
|
||||
|
try_again: |
||||
|
|
||||
|
if (use_u2x) { |
||||
|
*_ucsra = 1 << _u2x; |
||||
|
baud_setting = (F_CPU / 4 / baud - 1) / 2; |
||||
|
} else { |
||||
|
*_ucsra = 0; |
||||
|
baud_setting = (F_CPU / 8 / baud - 1) / 2; |
||||
|
} |
||||
|
|
||||
|
if ((baud_setting > 4095) && use_u2x) { |
||||
|
use_u2x = false; |
||||
|
goto try_again; |
||||
|
} |
||||
|
|
||||
|
// assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
|
||||
|
*_ubrrh = baud_setting >> 8; |
||||
|
*_ubrrl = baud_setting; |
||||
|
|
||||
|
transmitting = false; |
||||
|
|
||||
|
sbi(*_ucsrb, _rxen); |
||||
|
sbi(*_ucsrb, _txen); |
||||
|
sbi(*_ucsrb, _rxcie); |
||||
|
cbi(*_ucsrb, _udrie); |
||||
|
} |
||||
|
|
||||
|
void AnycubicSerialClass::begin(unsigned long baud, byte config) { |
||||
|
uint16_t baud_setting; |
||||
|
uint8_t current_config; |
||||
|
bool use_u2x = true; |
||||
|
|
||||
|
#if F_CPU == 16000000UL |
||||
|
// hardcoded 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) use_u2x = false; |
||||
|
#endif |
||||
|
|
||||
|
try_again: |
||||
|
|
||||
|
if (use_u2x) { |
||||
|
*_ucsra = 1 << _u2x; |
||||
|
baud_setting = (F_CPU / 4 / baud - 1) / 2; |
||||
|
} |
||||
|
else { |
||||
|
*_ucsra = 0; |
||||
|
baud_setting = (F_CPU / 8 / baud - 1) / 2; |
||||
|
} |
||||
|
|
||||
|
if ((baud_setting > 4095) && use_u2x) { |
||||
|
use_u2x = false; |
||||
|
goto try_again; |
||||
|
} |
||||
|
|
||||
|
// assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
|
||||
|
*_ubrrh = baud_setting >> 8; |
||||
|
*_ubrrl = baud_setting; |
||||
|
|
||||
|
//set the data bits, parity, and stop bits
|
||||
|
#ifdef __AVR_ATmega8__ |
||||
|
config |= 0x80; // select UCSRC register (shared with UBRRH)
|
||||
|
#endif |
||||
|
*_ucsrc = config; |
||||
|
|
||||
|
sbi(*_ucsrb, _rxen); |
||||
|
sbi(*_ucsrb, _txen); |
||||
|
sbi(*_ucsrb, _rxcie); |
||||
|
cbi(*_ucsrb, _udrie); |
||||
|
} |
||||
|
|
||||
|
void AnycubicSerialClass::end() { |
||||
|
// wait for transmission of outgoing data
|
||||
|
while (_tx_buffer->head != _tx_buffer->tail) |
||||
|
; |
||||
|
|
||||
|
cbi(*_ucsrb, _rxen); |
||||
|
cbi(*_ucsrb, _txen); |
||||
|
cbi(*_ucsrb, _rxcie); |
||||
|
cbi(*_ucsrb, _udrie); |
||||
|
|
||||
|
// clear any received data
|
||||
|
_rx_buffer->head = _rx_buffer->tail; |
||||
|
} |
||||
|
|
||||
|
int AnycubicSerialClass::available(void) { |
||||
|
return (int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE; |
||||
|
} |
||||
|
|
||||
|
int AnycubicSerialClass::peek(void) { |
||||
|
if (_rx_buffer->head == _rx_buffer->tail) { |
||||
|
return -1; |
||||
|
} else { |
||||
|
return _rx_buffer->buffer[_rx_buffer->tail]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int AnycubicSerialClass::read(void) { |
||||
|
// if the head isn't ahead of the tail, we don't have any characters
|
||||
|
if (_rx_buffer->head == _rx_buffer->tail) { |
||||
|
return -1; |
||||
|
} else { |
||||
|
unsigned char c = _rx_buffer->buffer[_rx_buffer->tail]; |
||||
|
_rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % SERIAL_BUFFER_SIZE; |
||||
|
return c; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void AnycubicSerialClass::flush() { |
||||
|
// UDR is kept full while the buffer is not empty, so TXC triggers when EMPTY && SENT
|
||||
|
while (transmitting && ! (*_ucsra & _BV(TXC0))); |
||||
|
transmitting = false; |
||||
|
} |
||||
|
|
||||
|
size_t AnycubicSerialClass::write(uint8_t c) { |
||||
|
int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE; |
||||
|
|
||||
|
// If the output buffer is full, there's nothing for it other than to
|
||||
|
// wait for the interrupt handler to empty it a bit
|
||||
|
// ???: return 0 here instead?
|
||||
|
while (i == _tx_buffer->tail) |
||||
|
; |
||||
|
|
||||
|
_tx_buffer->buffer[_tx_buffer->head] = c; |
||||
|
_tx_buffer->head = i; |
||||
|
|
||||
|
sbi(*_ucsrb, _udrie); |
||||
|
// clear the TXC bit -- "can be cleared by writing a one to its bit location"
|
||||
|
transmitting = true; |
||||
|
sbi(*_ucsra, TXC0); |
||||
|
|
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
AnycubicSerialClass::operator bool() { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
// Preinstantiate Objects //////////////////////////////////////////////////////
|
||||
|
|
||||
|
#ifdef UBRR3H |
||||
|
AnycubicSerialClass AnycubicSerial(&rx_buffer_ajg, &tx_buffer_ajg, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3); |
||||
|
#endif |
||||
|
|
||||
|
#endif // UBRR3H
|
||||
|
#endif // ANYCUBIC_TFT_MODEL
|
@ -0,0 +1,143 @@ |
|||||
|
/*
|
||||
|
anycubic_serial.h --- Support for Anycubic i3 Mega TFT serial connection |
||||
|
Created by Christian Hopp on 09.12.17. |
||||
|
|
||||
|
Original file: |
||||
|
|
||||
|
HardwareSerial.h - Hardware serial library for Wiring |
||||
|
Copyright (c) 2006 Nicholas Zambetti. All right reserved. |
||||
|
|
||||
|
This library is free software; you can redistribute it and/or |
||||
|
modify it under the terms of the GNU Lesser General Public |
||||
|
License as published by the Free Software Foundation; either |
||||
|
version 2.1 of the License, or (at your option) any later version. |
||||
|
|
||||
|
This library is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
Lesser General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU Lesser General Public |
||||
|
License along with this library; if not, write to the Free Software |
||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
|
||||
|
Modified 28 September 2010 by Mark Sproul |
||||
|
Modified 14 August 2012 by Alarus |
||||
|
*/ |
||||
|
#pragma once |
||||
|
|
||||
|
#include <inttypes.h> |
||||
|
#include <avr/pgmspace.h> |
||||
|
|
||||
|
#include "Stream.h" |
||||
|
|
||||
|
#define FORCE_INLINE __attribute__((always_inline)) inline |
||||
|
|
||||
|
struct ring_buffer; |
||||
|
|
||||
|
class AnycubicSerialClass : public Stream { |
||||
|
private: |
||||
|
ring_buffer *_rx_buffer; |
||||
|
ring_buffer *_tx_buffer; |
||||
|
volatile uint8_t *_ubrrh; |
||||
|
volatile uint8_t *_ubrrl; |
||||
|
volatile uint8_t *_ucsra; |
||||
|
volatile uint8_t *_ucsrb; |
||||
|
volatile uint8_t *_ucsrc; |
||||
|
volatile uint8_t *_udr; |
||||
|
uint8_t _rxen; |
||||
|
uint8_t _txen; |
||||
|
uint8_t _rxcie; |
||||
|
uint8_t _udrie; |
||||
|
uint8_t _u2x; |
||||
|
bool transmitting; |
||||
|
public: |
||||
|
AnycubicSerialClass(ring_buffer *rx_buffer, ring_buffer *tx_buffer, |
||||
|
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, |
||||
|
volatile uint8_t *ucsra, volatile uint8_t *ucsrb, |
||||
|
volatile uint8_t *ucsrc, volatile uint8_t *udr, |
||||
|
uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x |
||||
|
); |
||||
|
void begin(unsigned long); |
||||
|
void begin(unsigned long, uint8_t); |
||||
|
void end(); |
||||
|
virtual int available(void); |
||||
|
virtual int peek(void); |
||||
|
virtual int read(void); |
||||
|
virtual void flush(void); |
||||
|
virtual size_t write(uint8_t); |
||||
|
inline size_t write(unsigned long n) { return write((uint8_t)n); } |
||||
|
inline size_t write(long n) { return write((uint8_t)n); } |
||||
|
inline size_t write(unsigned int n) { return write((uint8_t)n); } |
||||
|
inline size_t write(int n) { return write((uint8_t)n); } |
||||
|
using Print::write; // pull in write(str) and write(buf, size) from Print
|
||||
|
operator bool(); |
||||
|
}; |
||||
|
|
||||
|
// Define config for Serial.begin(baud, config);
|
||||
|
#define SERIAL_5N1 0x00 |
||||
|
#define SERIAL_6N1 0x02 |
||||
|
#define SERIAL_7N1 0x04 |
||||
|
#define SERIAL_8N1 0x06 |
||||
|
#define SERIAL_5N2 0x08 |
||||
|
#define SERIAL_6N2 0x0A |
||||
|
#define SERIAL_7N2 0x0C |
||||
|
#define SERIAL_8N2 0x0E |
||||
|
#define SERIAL_5E1 0x20 |
||||
|
#define SERIAL_6E1 0x22 |
||||
|
#define SERIAL_7E1 0x24 |
||||
|
#define SERIAL_8E1 0x26 |
||||
|
#define SERIAL_5E2 0x28 |
||||
|
#define SERIAL_6E2 0x2A |
||||
|
#define SERIAL_7E2 0x2C |
||||
|
#define SERIAL_8E2 0x2E |
||||
|
#define SERIAL_5O1 0x30 |
||||
|
#define SERIAL_6O1 0x32 |
||||
|
#define SERIAL_7O1 0x34 |
||||
|
#define SERIAL_8O1 0x36 |
||||
|
#define SERIAL_5O2 0x38 |
||||
|
#define SERIAL_6O2 0x3A |
||||
|
#define SERIAL_7O2 0x3C |
||||
|
#define SERIAL_8O2 0x3E |
||||
|
|
||||
|
extern void serialEventRun(void) __attribute__((weak)); |
||||
|
|
||||
|
#define ANYCUBIC_SERIAL_PROTOCOL(x) (AnycubicSerial.print(x)) |
||||
|
#define ANYCUBIC_SERIAL_PROTOCOL_F(x,y) (AnycubicSerial.print(x,y)) |
||||
|
#define ANYCUBIC_SERIAL_PROTOCOLPGM(x) (AnycubicSerialprintPGM(PSTR(x))) |
||||
|
#define ANYCUBIC_SERIAL_(x) (AnycubicSerial.print(x),AnycubicSerial.write('\n')) |
||||
|
#define ANYCUBIC_SERIAL_PROTOCOLLN(x) (AnycubicSerial.print(x),AnycubicSerial.write('\r'),AnycubicSerial.write('\n')) |
||||
|
#define ANYCUBIC_SERIAL_PROTOCOLLNPGM(x) (AnycubicSerialprintPGM(PSTR(x)),AnycubicSerial.write('\r'),AnycubicSerial.write('\n')) |
||||
|
|
||||
|
#define ANYCUBIC_SERIAL_START() (AnycubicSerial.write('\r'),AnycubicSerial.write('\n')) |
||||
|
#define ANYCUBIC_SERIAL_CMD_SEND(x) (AnycubicSerialprintPGM(PSTR(x)),AnycubicSerial.write('\r'),AnycubicSerial.write('\n')) |
||||
|
#define ANYCUBIC_SERIAL_ENTER() (AnycubicSerial.write('\r'),AnycubicSerial.write('\n')) |
||||
|
#define ANYCUBIC_SERIAL_SPACE() (AnycubicSerial.write(' ')) |
||||
|
|
||||
|
const char newErr[] PROGMEM = "ERR "; |
||||
|
const char newSucc[] PROGMEM = "OK"; |
||||
|
|
||||
|
#define ANYCUBIC_SERIAL_ERROR_START (AnycubicSerialprintPGM(newErr)) |
||||
|
#define ANYCUBIC_SERIAL_ERROR(x) ANYCUBIC_SERIAL_PROTOCOL(x) |
||||
|
#define ANYCUBIC_SERIAL_ERRORPGM(x) ANYCUBIC_SERIAL_PROTOCOLPGM(x) |
||||
|
#define ANYCUBIC_SERIAL_ERRORLN(x) ANYCUBIC_SERIAL_PROTOCOLLN(x) |
||||
|
#define ANYCUBIC_SERIAL_ERRORLNPGM(x) ANYCUBIC_SERIAL_PROTOCOLLNPGM(x) |
||||
|
|
||||
|
//##define ANYCUBIC_SERIAL_ECHO_START (AnycubicSerialprintPGM(newSucc))
|
||||
|
#define ANYCUBIC_SERIAL_ECHOLN(x) ANYCUBIC_SERIAL_PROTOCOLLN(x) |
||||
|
#define ANYCUBIC_SERIAL_SUCC_START (AnycubicSerialprintPGM(newSucc)) |
||||
|
#define ANYCUBIC_SERIAL_ECHOPAIR(name,value) (serial_echopair_P(PSTR(name),(value))) |
||||
|
#define ANYCUBIC_SERIAL_ECHOPGM(x) ANYCUBIC_SERIAL_PROTOCOLPGM(x) |
||||
|
#define ANYCUBIC_SERIAL_ECHO(x) ANYCUBIC_SERIAL_PROTOCOL(x) |
||||
|
|
||||
|
FORCE_INLINE void AnycubicSerialprintPGM(const char *str) { |
||||
|
char ch=pgm_read_byte(str); |
||||
|
while (ch) { |
||||
|
AnycubicSerial.write(ch); |
||||
|
ch=pgm_read_byte(++str); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#ifdef UBRR3H |
||||
|
extern AnycubicSerialClass AnycubicSerial; |
||||
|
#endif |
File diff suppressed because it is too large
@ -0,0 +1,114 @@ |
|||||
|
/**
|
||||
|
* anycubic_tft.h --- Support for Anycubic i3 Mega TFT |
||||
|
* Created by Christian Hopp on 09.12.17. |
||||
|
* Improved by David Ramiro |
||||
|
* Converted to ext_iu by John BouAntoun 21 June 2020 |
||||
|
* |
||||
|
* 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 |
||||
|
*/ |
||||
|
#pragma once |
||||
|
|
||||
|
#include "../../../../inc/MarlinConfigPre.h" |
||||
|
#include "../../../../sd/SdFatConfig.h" // for the FILENAME_LENGTH macro |
||||
|
|
||||
|
// command sending macro's with debugging capability
|
||||
|
#define ANYCUBIC_SENDCOMMANDPGM(x) ANYCUBIC_SERIAL_PROTOCOLLNPGM(x) |
||||
|
#define ANYCUBIC_SENDCOMMANDPGM_VAL(x,y) (ANYCUBIC_SERIAL_PROTOCOLPGM(x), ANYCUBIC_SERIAL_PROTOCOLLN(itostr3(y))) |
||||
|
#define ANYCUBIC_SENDCOMMAND(x) ANYCUBIC_SERIAL_PROTOCOLLN(x) |
||||
|
#if ENABLED(ANYCUBIC_TFT_DEBUG) |
||||
|
#define ANYCUBIC_SENDCOMMAND_DBG_PGM(x,y) (ANYCUBIC_SERIAL_PROTOCOLLNPGM(x), SERIAL_ECHOLNPGM(y)) |
||||
|
#define ANYCUBIC_SENDCOMMAND_DBG_PGM_VAL(x,y,z) (ANYCUBIC_SERIAL_PROTOCOLLNPGM(x), SERIAL_ECHOPGM(y), SERIAL_ECHOLN(z)) |
||||
|
#else |
||||
|
#define ANYCUBIC_SENDCOMMAND_DBG_PGM(x,y) (ANYCUBIC_SERIAL_PROTOCOLLNPGM(x)) |
||||
|
#define ANYCUBIC_SENDCOMMAND_DBG_PGM_VAL(x,y,z) (ANYCUBIC_SERIAL_PROTOCOLLNPGM(x)) |
||||
|
#endif |
||||
|
|
||||
|
char *itostr2(const uint8_t &x); |
||||
|
#ifndef ULTRA_LCD |
||||
|
char *itostr3(const int); |
||||
|
char *ftostr32(const float &); |
||||
|
#endif |
||||
|
|
||||
|
#define TFTBUFSIZE 4 |
||||
|
#define TFT_MAX_CMD_SIZE 96 |
||||
|
|
||||
|
enum AnycubicMediaPrintState { |
||||
|
AMPRINTSTATE_NOT_PRINTING, |
||||
|
AMPRINTSTATE_PRINTING, |
||||
|
AMPRINTSTATE_PAUSE_REQUESTED, |
||||
|
AMPRINTSTATE_PAUSED, |
||||
|
AMPRINTSTATE_STOP_REQUESTED |
||||
|
}; |
||||
|
|
||||
|
enum AnycubicMediaPauseState { |
||||
|
AMPAUSESTATE_NOT_PAUSED, |
||||
|
AMPAUSESTATE_PARKING, |
||||
|
AMPAUSESTATE_PARKED, |
||||
|
AMPAUSESTATE_FILAMENT_OUT, |
||||
|
AMPAUSESTATE_FIAMENT_PRUGING, |
||||
|
AMPAUSESTATE_HEATER_TIMEOUT, |
||||
|
AMPAUSESTATE_REHEATING, |
||||
|
AMPAUSESTATE_REHEAT_FINISHED |
||||
|
}; |
||||
|
|
||||
|
class AnycubicTFTClass { |
||||
|
public: |
||||
|
AnycubicTFTClass(); |
||||
|
void OnSetup(); |
||||
|
void OnCommandScan(); |
||||
|
void OnKillTFT(); |
||||
|
void OnSDCardStateChange(bool); |
||||
|
void OnSDCardError(); |
||||
|
void OnFilamentRunout(); |
||||
|
void OnUserConfirmRequired(const char *); |
||||
|
void OnPrintTimerStarted(); |
||||
|
void OnPrintTimerPaused(); |
||||
|
void OnPrintTimerStopped(); |
||||
|
|
||||
|
private: |
||||
|
char TFTcmdbuffer[TFTBUFSIZE][TFT_MAX_CMD_SIZE]; |
||||
|
int TFTbuflen=0; |
||||
|
int TFTbufindr = 0; |
||||
|
int TFTbufindw = 0; |
||||
|
char serial3_char; |
||||
|
int serial3_count = 0; |
||||
|
char *TFTstrchr_pointer; |
||||
|
uint8_t SpecialMenu = false; |
||||
|
AnycubicMediaPrintState mediaPrintingState = AMPRINTSTATE_NOT_PRINTING; |
||||
|
AnycubicMediaPauseState mediaPauseState = AMPAUSESTATE_NOT_PAUSED; |
||||
|
|
||||
|
float CodeValue(); |
||||
|
bool CodeSeen(char); |
||||
|
bool IsNozzleHomed(); |
||||
|
void RenderCurrentFileList(); |
||||
|
void RenderSpecialMenu(uint16_t); |
||||
|
void RenderCurrentFolder(uint16_t); |
||||
|
void GetCommandFromTFT(); |
||||
|
void CheckSDCardChange(); |
||||
|
void CheckPauseState(); |
||||
|
void CheckPrintCompletion(); |
||||
|
void HandleSpecialMenu(); |
||||
|
void DoSDCardStateCheck(); |
||||
|
void DoFilamentRunoutCheck(); |
||||
|
void StartPrint(); |
||||
|
void PausePrint(); |
||||
|
void ResumePrint(); |
||||
|
void StopPrint(); |
||||
|
|
||||
|
char SelectedDirectory[30]; |
||||
|
char SelectedFile[FILENAME_LENGTH]; |
||||
|
}; |
||||
|
|
||||
|
extern AnycubicTFTClass AnycubicTFT; |
@ -0,0 +1,104 @@ |
|||||
|
/**
|
||||
|
* Marlin 3D Printer Firmware |
||||
|
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
|
* |
||||
|
* Based on Sprinter and grbl. |
||||
|
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm |
||||
|
* |
||||
|
* This program is free software: you can redistribute it and/or modify |
||||
|
* it under the terms of the GNU General Public License as published by |
||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||
|
* (at your option) any later version. |
||||
|
* |
||||
|
* This program is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
* GNU General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU General Public License |
||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
/**
|
||||
|
* extui_anycubic_tft.cpp |
||||
|
*/ |
||||
|
|
||||
|
#include "../inc/MarlinConfigPre.h" |
||||
|
|
||||
|
#if BOTH(ANYCUBIC_TFT_MODEL, EXTENSIBLE_UI) |
||||
|
|
||||
|
#include "extui/lib/anycubic/anycubic_tft.h" |
||||
|
#include "extui/ui_api.h" |
||||
|
|
||||
|
#include <Arduino.h> // for the ::tone() call |
||||
|
|
||||
|
namespace ExtUI { |
||||
|
|
||||
|
void onStartup() { AnycubicTFT.OnSetup(); } |
||||
|
void onIdle() { AnycubicTFT.OnCommandScan(); } |
||||
|
void onPrinterKilled(PGM_P const error, PGM_P const component) { AnycubicTFT.OnKillTFT(); } |
||||
|
void onMediaInserted() { AnycubicTFT.OnSDCardStateChange(true); } |
||||
|
void onMediaError() { AnycubicTFT.OnSDCardError(); } |
||||
|
void onMediaRemoved() { AnycubicTFT.OnSDCardStateChange(false); } |
||||
|
void onPlayTone(const uint16_t frequency, const uint16_t duration) { |
||||
|
#if ENABLED(SPEAKER) |
||||
|
::tone(BEEPER_PIN, frequency, duration); |
||||
|
#endif |
||||
|
} |
||||
|
void onPrintTimerStarted() { AnycubicTFT.OnPrintTimerStarted(); } |
||||
|
void onPrintTimerPaused() { AnycubicTFT.OnPrintTimerPaused(); } |
||||
|
void onPrintTimerStopped() { AnycubicTFT.OnPrintTimerStopped(); } |
||||
|
void onFilamentRunout(const extruder_t extruder) { AnycubicTFT.OnFilamentRunout(); } |
||||
|
void onUserConfirmRequired(const char * const msg) { AnycubicTFT.OnUserConfirmRequired(msg); } |
||||
|
void onStatusChanged(const char * const msg) {} |
||||
|
void onFactoryReset() {} |
||||
|
|
||||
|
void onStoreSettings(char *buff) { |
||||
|
// Called when saving to EEPROM (i.e. M500). If the ExtUI needs
|
||||
|
// permanent data to be stored, it can write up to eeprom_data_size bytes
|
||||
|
// into buff.
|
||||
|
|
||||
|
// Example:
|
||||
|
// static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size);
|
||||
|
// memcpy(buff, &myDataStruct, sizeof(myDataStruct));
|
||||
|
} |
||||
|
|
||||
|
void onLoadSettings(const char *buff) { |
||||
|
// Called while loading settings from EEPROM. If the ExtUI
|
||||
|
// needs to retrieve data, it should copy up to eeprom_data_size bytes
|
||||
|
// from buff
|
||||
|
|
||||
|
// Example:
|
||||
|
// static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size);
|
||||
|
// memcpy(&myDataStruct, buff, sizeof(myDataStruct));
|
||||
|
} |
||||
|
|
||||
|
void onConfigurationStoreWritten(bool success) { |
||||
|
// Called after the entire EEPROM has been written,
|
||||
|
// whether successful or not.
|
||||
|
} |
||||
|
|
||||
|
void onConfigurationStoreRead(bool success) { |
||||
|
// Called after the entire EEPROM has been read,
|
||||
|
// whether successful or not.
|
||||
|
} |
||||
|
|
||||
|
void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) { |
||||
|
// Called when any mesh points are updated
|
||||
|
} |
||||
|
|
||||
|
#if ENABLED(POWER_LOSS_RECOVERY) |
||||
|
void onPowerLossResume() { |
||||
|
// Called on resume from power-loss
|
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#if HAS_PID_HEATING |
||||
|
void onPidTuning(const result_t rst) { |
||||
|
// Called for temperature PID tuning result
|
||||
|
} |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
#endif // ANYCUBIC_TFT_MODEL && EXTENSIBLE_UI
|
Loading…
Reference in new issue