My Marlin configs for Fabrikator Mini and CTC i3 Pro B
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.

MarlinSerial.h 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #pragma once
  23. /**
  24. * MarlinSerial.h - Hardware serial library for Wiring
  25. * Copyright (c) 2006 Nicholas Zambetti. All right reserved.
  26. *
  27. * Modified 28 September 2010 by Mark Sproul
  28. * Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
  29. * Modified 01 October 2017 by Eduardo José Tagle (added XON/XOFF)
  30. * Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances
  31. */
  32. #include <WString.h>
  33. #include "../../inc/MarlinConfigPre.h"
  34. #ifndef SERIAL_PORT
  35. #define SERIAL_PORT 0
  36. #endif
  37. #ifndef USBCON
  38. // The presence of the UBRRH register is used to detect a UART.
  39. #define UART_PRESENT(port) ((port == 0 && (defined(UBRRH) || defined(UBRR0H))) || \
  40. (port == 1 && defined(UBRR1H)) || (port == 2 && defined(UBRR2H)) || \
  41. (port == 3 && defined(UBRR3H)))
  42. // These are macros to build serial port register names for the selected SERIAL_PORT (C preprocessor
  43. // requires two levels of indirection to expand macro values properly)
  44. #define SERIAL_REGNAME(registerbase,number,suffix) SERIAL_REGNAME_INTERNAL(registerbase,number,suffix)
  45. #if SERIAL_PORT == 0 && (!defined(UBRR0H) || !defined(UDR0)) // use un-numbered registers if necessary
  46. #define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##suffix
  47. #else
  48. #define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix
  49. #endif
  50. // Registers used by MarlinSerial class (expanded depending on selected serial port)
  51. // Templated 8bit register (generic)
  52. #define UART_REGISTER_DECL_BASE(registerbase, suffix) \
  53. template<int portNr> struct R_##registerbase##x##suffix {}
  54. // Templated 8bit register (specialization for each port)
  55. #define UART_REGISTER_DECL(port, registerbase, suffix) \
  56. template<> struct R_##registerbase##x##suffix<port> { \
  57. constexpr R_##registerbase##x##suffix(int) {} \
  58. FORCE_INLINE void operator=(uint8_t newVal) const { SERIAL_REGNAME(registerbase,port,suffix) = newVal; } \
  59. FORCE_INLINE operator uint8_t() const { return SERIAL_REGNAME(registerbase,port,suffix); } \
  60. }
  61. // Templated 1bit register (generic)
  62. #define UART_BIT_DECL_BASE(registerbase, suffix, bit) \
  63. template<int portNr>struct B_##bit##x {}
  64. // Templated 1bit register (specialization for each port)
  65. #define UART_BIT_DECL(port, registerbase, suffix, bit) \
  66. template<> struct B_##bit##x<port> { \
  67. constexpr B_##bit##x(int) {} \
  68. FORCE_INLINE void operator=(int newVal) const { \
  69. if (newVal) \
  70. SBI(SERIAL_REGNAME(registerbase,port,suffix),SERIAL_REGNAME(bit,port,)); \
  71. else \
  72. CBI(SERIAL_REGNAME(registerbase,port,suffix),SERIAL_REGNAME(bit,port,)); \
  73. } \
  74. FORCE_INLINE operator bool() const { return TEST(SERIAL_REGNAME(registerbase,port,suffix),SERIAL_REGNAME(bit,port,)); } \
  75. }
  76. #define UART_DECL_BASE() \
  77. UART_REGISTER_DECL_BASE(UCSR,A);\
  78. UART_REGISTER_DECL_BASE(UDR,);\
  79. UART_REGISTER_DECL_BASE(UBRR,H);\
  80. UART_REGISTER_DECL_BASE(UBRR,L);\
  81. UART_BIT_DECL_BASE(UCSR,B,RXEN);\
  82. UART_BIT_DECL_BASE(UCSR,B,TXEN);\
  83. UART_BIT_DECL_BASE(UCSR,A,TXC);\
  84. UART_BIT_DECL_BASE(UCSR,B,RXCIE);\
  85. UART_BIT_DECL_BASE(UCSR,A,UDRE);\
  86. UART_BIT_DECL_BASE(UCSR,A,FE);\
  87. UART_BIT_DECL_BASE(UCSR,A,DOR);\
  88. UART_BIT_DECL_BASE(UCSR,B,UDRIE);\
  89. UART_BIT_DECL_BASE(UCSR,A,RXC);\
  90. UART_BIT_DECL_BASE(UCSR,A,U2X)
  91. #define UART_DECL(port) \
  92. UART_REGISTER_DECL(port,UCSR,A);\
  93. UART_REGISTER_DECL(port,UDR,);\
  94. UART_REGISTER_DECL(port,UBRR,H);\
  95. UART_REGISTER_DECL(port,UBRR,L);\
  96. UART_BIT_DECL(port,UCSR,B,RXEN);\
  97. UART_BIT_DECL(port,UCSR,B,TXEN);\
  98. UART_BIT_DECL(port,UCSR,A,TXC);\
  99. UART_BIT_DECL(port,UCSR,B,RXCIE);\
  100. UART_BIT_DECL(port,UCSR,A,UDRE);\
  101. UART_BIT_DECL(port,UCSR,A,FE);\
  102. UART_BIT_DECL(port,UCSR,A,DOR);\
  103. UART_BIT_DECL(port,UCSR,B,UDRIE);\
  104. UART_BIT_DECL(port,UCSR,A,RXC);\
  105. UART_BIT_DECL(port,UCSR,A,U2X)
  106. // Declare empty templates
  107. UART_DECL_BASE();
  108. // And all the specializations for each possible serial port
  109. #if UART_PRESENT(0)
  110. UART_DECL(0);
  111. #endif
  112. #if UART_PRESENT(1)
  113. UART_DECL(1);
  114. #endif
  115. #if UART_PRESENT(2)
  116. UART_DECL(2);
  117. #endif
  118. #if UART_PRESENT(3)
  119. UART_DECL(3);
  120. #endif
  121. #define DEC 10
  122. #define HEX 16
  123. #define OCT 8
  124. #define BIN 2
  125. #define BYTE 0
  126. // Templated type selector
  127. template<bool b, typename T, typename F> struct TypeSelector { typedef T type;} ;
  128. template<typename T, typename F> struct TypeSelector<false, T, F> { typedef F type; };
  129. template<typename Cfg>
  130. class MarlinSerial {
  131. protected:
  132. // Registers
  133. static constexpr R_UCSRxA<Cfg::PORT> R_UCSRA = 0;
  134. static constexpr R_UDRx<Cfg::PORT> R_UDR = 0;
  135. static constexpr R_UBRRxH<Cfg::PORT> R_UBRRH = 0;
  136. static constexpr R_UBRRxL<Cfg::PORT> R_UBRRL = 0;
  137. // Bits
  138. static constexpr B_RXENx<Cfg::PORT> B_RXEN = 0;
  139. static constexpr B_TXENx<Cfg::PORT> B_TXEN = 0;
  140. static constexpr B_TXCx<Cfg::PORT> B_TXC = 0;
  141. static constexpr B_RXCIEx<Cfg::PORT> B_RXCIE = 0;
  142. static constexpr B_UDREx<Cfg::PORT> B_UDRE = 0;
  143. static constexpr B_FEx<Cfg::PORT> B_FE = 0;
  144. static constexpr B_DORx<Cfg::PORT> B_DOR = 0;
  145. static constexpr B_UDRIEx<Cfg::PORT> B_UDRIE = 0;
  146. static constexpr B_RXCx<Cfg::PORT> B_RXC = 0;
  147. static constexpr B_U2Xx<Cfg::PORT> B_U2X = 0;
  148. // Base size of type on buffer size
  149. typedef typename TypeSelector<(Cfg::RX_SIZE>256), uint16_t, uint8_t>::type ring_buffer_pos_t;
  150. struct ring_buffer_r {
  151. volatile ring_buffer_pos_t head, tail;
  152. unsigned char buffer[Cfg::RX_SIZE];
  153. };
  154. struct ring_buffer_t {
  155. volatile uint8_t head, tail;
  156. unsigned char buffer[Cfg::TX_SIZE];
  157. };
  158. static ring_buffer_r rx_buffer;
  159. static ring_buffer_t tx_buffer;
  160. static bool _written;
  161. static constexpr uint8_t XON_XOFF_CHAR_SENT = 0x80, // XON / XOFF Character was sent
  162. XON_XOFF_CHAR_MASK = 0x1F; // XON / XOFF character to send
  163. // XON / XOFF character definitions
  164. static constexpr uint8_t XON_CHAR = 17, XOFF_CHAR = 19;
  165. static uint8_t xon_xoff_state,
  166. rx_dropped_bytes,
  167. rx_buffer_overruns,
  168. rx_framing_errors;
  169. static ring_buffer_pos_t rx_max_enqueued;
  170. static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_head();
  171. static volatile bool rx_tail_value_not_stable;
  172. static volatile uint16_t rx_tail_value_backup;
  173. static FORCE_INLINE void atomic_set_rx_tail(ring_buffer_pos_t value);
  174. static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_tail();
  175. public:
  176. FORCE_INLINE static void store_rxd_char();
  177. FORCE_INLINE static void _tx_udr_empty_irq();
  178. public:
  179. MarlinSerial() {};
  180. static void begin(const long);
  181. static void end();
  182. static int peek();
  183. static int read();
  184. static void flush();
  185. static ring_buffer_pos_t available();
  186. static void write(const uint8_t c);
  187. static void flushTX();
  188. #ifdef DGUS_SERIAL_PORT
  189. static ring_buffer_pos_t get_tx_buffer_free();
  190. #endif
  191. FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
  192. FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
  193. FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
  194. FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
  195. FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
  196. FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
  197. FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
  198. FORCE_INLINE static void print(const char* str) { write(str); }
  199. static void print(char, int = BYTE);
  200. static void print(unsigned char, int = BYTE);
  201. static void print(int, int = DEC);
  202. static void print(unsigned int, int = DEC);
  203. static void print(long, int = DEC);
  204. static void print(unsigned long, int = DEC);
  205. static void print(double, int = 2);
  206. static void println(const String& s);
  207. static void println(const char[]);
  208. static void println(char, int = BYTE);
  209. static void println(unsigned char, int = BYTE);
  210. static void println(int, int = DEC);
  211. static void println(unsigned int, int = DEC);
  212. static void println(long, int = DEC);
  213. static void println(unsigned long, int = DEC);
  214. static void println(double, int = 2);
  215. static void println();
  216. operator bool() { return true; }
  217. private:
  218. static void printNumber(unsigned long, const uint8_t);
  219. static void printFloat(double, uint8_t);
  220. };
  221. template <uint8_t serial>
  222. struct MarlinSerialCfg {
  223. static constexpr int PORT = serial;
  224. static constexpr unsigned int RX_SIZE = RX_BUFFER_SIZE;
  225. static constexpr unsigned int TX_SIZE = TX_BUFFER_SIZE;
  226. static constexpr bool XONOFF = ENABLED(SERIAL_XON_XOFF);
  227. static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
  228. static constexpr bool DROPPED_RX = ENABLED(SERIAL_STATS_DROPPED_RX);
  229. static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS);
  230. static constexpr bool RX_FRAMING_ERRORS = ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS);
  231. static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED);
  232. };
  233. extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
  234. #ifdef SERIAL_PORT_2
  235. extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
  236. #endif
  237. #endif // !USBCON
  238. #ifdef INTERNAL_SERIAL_PORT
  239. template <uint8_t serial>
  240. struct MarlinInternalSerialCfg {
  241. static constexpr int PORT = serial;
  242. static constexpr unsigned int RX_SIZE = 32;
  243. static constexpr unsigned int TX_SIZE = 32;
  244. static constexpr bool XONOFF = false;
  245. static constexpr bool EMERGENCYPARSER = false;
  246. static constexpr bool DROPPED_RX = false;
  247. static constexpr bool RX_OVERRUNS = false;
  248. static constexpr bool RX_FRAMING_ERRORS = false;
  249. static constexpr bool MAX_RX_QUEUED = false;
  250. };
  251. extern MarlinSerial<MarlinInternalSerialCfg<INTERNAL_SERIAL_PORT>> internalSerial;
  252. #endif
  253. #ifdef DGUS_SERIAL_PORT
  254. template <uint8_t serial>
  255. struct MarlinInternalSerialCfg {
  256. static constexpr int PORT = serial;
  257. static constexpr unsigned int RX_SIZE = DGUS_RX_BUFFER_SIZE;
  258. static constexpr unsigned int TX_SIZE = DGUS_TX_BUFFER_SIZE;
  259. static constexpr bool XONOFF = false;
  260. static constexpr bool EMERGENCYPARSER = false;
  261. static constexpr bool DROPPED_RX = false;
  262. static constexpr bool RX_OVERRUNS = BOTH(HAS_DGUS_LCD, DGUS_SERIAL_STATS_RX_BUFFER_OVERRUNS);
  263. static constexpr bool RX_FRAMING_ERRORS = false;
  264. static constexpr bool MAX_RX_QUEUED = false;
  265. };
  266. extern MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>> internalDgusSerial;
  267. #endif
  268. // Use the UART for Bluetooth in AT90USB configurations
  269. #if defined(USBCON) && ENABLED(BLUETOOTH)
  270. extern HardwareSerial bluetoothSerial;
  271. #endif