ExtUI for Anycubic I3 Mega (#18655)
This commit is contained in:
		| @@ -79,7 +79,7 @@ void GcodeSuite::M125() { | ||||
|  | ||||
|   if (pause_print(retract, park_point, 0, show_lcd)) { | ||||
|     TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true)); | ||||
|     if (!sd_printing || show_lcd) { | ||||
|     if (ENABLED(EXTENSIBLE_UI) || !sd_printing || show_lcd) { | ||||
|       wait_for_confirmation(false, 0); | ||||
|       resume_print(0, 0, -retract, 0); | ||||
|     } | ||||
|   | ||||
							
								
								
									
										294
									
								
								Marlin/src/lcd/extui/lib/anycubic/anycubic_serial.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										294
									
								
								Marlin/src/lcd/extui/lib/anycubic/anycubic_serial.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
							
								
								
									
										143
									
								
								Marlin/src/lcd/extui/lib/anycubic/anycubic_serial.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								Marlin/src/lcd/extui/lib/anycubic/anycubic_serial.h
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
							
								
								
									
										1066
									
								
								Marlin/src/lcd/extui/lib/anycubic/anycubic_tft.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1066
									
								
								Marlin/src/lcd/extui/lib/anycubic/anycubic_tft.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										114
									
								
								Marlin/src/lcd/extui/lib/anycubic/anycubic_tft.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								Marlin/src/lcd/extui/lib/anycubic/anycubic_tft.h
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
							
								
								
									
										104
									
								
								Marlin/src/lcd/extui_anycubic_tft.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								Marlin/src/lcd/extui_anycubic_tft.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
| @@ -38,15 +38,38 @@ | ||||
| #endif | ||||
|  | ||||
| // | ||||
| // Custom Limit Switches | ||||
| // Limit Switches | ||||
| // | ||||
| //#define ANYCUBIC_4_MAX_PRO_ENDSTOPS | ||||
|  | ||||
| #define X_MIN_PIN                              3 | ||||
|  | ||||
| #if ENABLED(ANYCUBIC_4_MAX_PRO_ENDSTOPS) | ||||
|   #define X_MAX_PIN                           43 | ||||
|   #define Y_MIN_PIN                           19 | ||||
| #else | ||||
|   #define X_MAX_PIN                           43 | ||||
| #endif | ||||
|  | ||||
| // Labeled pins | ||||
| #if ENABLED(ANYCUBIC_4_MAX_PRO_ENDSTOPS) | ||||
|   #define Y_STOP_PIN                          19 | ||||
| #else | ||||
|   #define Y_STOP_PIN                          42 | ||||
| #endif | ||||
|  | ||||
| #define Z_STOP_PIN                            18 | ||||
|  | ||||
| // | ||||
| // Z Probe (when not Z_MIN_PIN) | ||||
| // | ||||
| #define Z_MIN_PROBE_PIN                        2 | ||||
|  | ||||
| #ifndef FIL_RUNOUT_PIN | ||||
|   #define FIL_RUNOUT_PIN                      19 | ||||
| #endif | ||||
|  | ||||
| // | ||||
| // Heaters / Fans | ||||
| // | ||||
| #define TG_HEATER_BED_PIN                      8 | ||||
| #define TG_HEATER_0_PIN                       10 | ||||
| #define TG_HEATER_1_PIN                       45  // Anycubic Kossel: Unused | ||||
| @@ -55,6 +78,11 @@ | ||||
| #define TG_FAN1_PIN                            7  // Anycubic Kossel: Unused | ||||
| #define TG_FAN2_PIN                           44  // Anycubic Kossel: Hotend fan | ||||
|  | ||||
| #define CONTROLLER_FAN_PIN           TG_FAN1_PIN | ||||
|  | ||||
| #define BEEPER_PIN                            31 | ||||
| #define SD_DETECT_PIN                         49 | ||||
|  | ||||
| // Remap MOSFET pins to common usages: | ||||
|  | ||||
| #define RAMPS_D10_PIN            TG_HEATER_0_PIN  // HEATER_0_PIN is always RAMPS_D10_PIN in pins_RAMPS.h | ||||
|   | ||||
		Reference in New Issue
	
	Block a user