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.

SoftwareSerial.cpp 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /*
  2. * SoftwareSerial.cpp (formerly NewSoftSerial.cpp)
  3. *
  4. * Multi-instance software serial library for Arduino/Wiring
  5. * -- Interrupt-driven receive and other improvements by ladyada
  6. * <https://ladyada.net>
  7. * -- Tuning, circular buffer, derivation from class Print/Stream,
  8. * multi-instance support, porting to 8MHz processors,
  9. * various optimizations, PROGMEM delay tables, inverse logic and
  10. * direct port writing by Mikal Hart <http://www.arduiniana.org>
  11. * -- Pin change interrupt macros by Paul Stoffregen <https://www.pjrc.com>
  12. * -- 20MHz processor support by Garrett Mace <http://www.macetech.com>
  13. * -- ATmega1280/2560 support by Brett Hagman <https://www.roguerobotics.com>
  14. * -- STM32 support by Armin van der Togt
  15. *
  16. * This library is free software; you can redistribute it and/or
  17. * modify it under the terms of the GNU Lesser General Public
  18. * License as published by the Free Software Foundation; either
  19. * version 2.1 of the License, or (at your option) any later version.
  20. *
  21. * This library is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  24. * Lesser General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU Lesser General Public
  27. * License along with this library; if not, write to the Free Software
  28. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  29. *
  30. * The latest version of this library can always be found at
  31. * http://arduiniana.org.
  32. */
  33. //
  34. // Includes
  35. //
  36. #if defined(PLATFORMIO) && defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
  37. #include "../../inc/MarlinConfig.h"
  38. #include "SoftwareSerial.h"
  39. #define OVERSAMPLE 3 // in RX, Timer will generate interruption OVERSAMPLE time during a bit. Thus OVERSAMPLE ticks in a bit. (interrupt not synchonized with edge).
  40. // defined in bit-periods
  41. #define HALFDUPLEX_SWITCH_DELAY 5
  42. // It's best to define TIMER_SERIAL in variant.h. If not defined, we choose one here
  43. // The order is based on (lack of) features and compare channels, we choose the simplest available
  44. // because we only need an update interrupt
  45. #if !defined(TIMER_SERIAL)
  46. #if defined(TIM18_BASE)
  47. #define TIMER_SERIAL TIM18
  48. #elif defined(TIM7_BASE)
  49. #define TIMER_SERIAL TIM7
  50. #elif defined(TIM6_BASE)
  51. #define TIMER_SERIAL TIM6
  52. #elif defined(TIM22_BASE)
  53. #define TIMER_SERIAL TIM22
  54. #elif defined(TIM21_BASE)
  55. #define TIMER_SERIAL TIM21
  56. #elif defined(TIM17_BASE)
  57. #define TIMER_SERIAL TIM17
  58. #elif defined(TIM16_BASE)
  59. #define TIMER_SERIAL TIM16
  60. #elif defined(TIM15_BASE)
  61. #define TIMER_SERIAL TIM15
  62. #elif defined(TIM14_BASE)
  63. #define TIMER_SERIAL TIM14
  64. #elif defined(TIM13_BASE)
  65. #define TIMER_SERIAL TIM13
  66. #elif defined(TIM11_BASE)
  67. #define TIMER_SERIAL TIM11
  68. #elif defined(TIM10_BASE)
  69. #define TIMER_SERIAL TIM10
  70. #elif defined(TIM12_BASE)
  71. #define TIMER_SERIAL TIM12
  72. #elif defined(TIM19_BASE)
  73. #define TIMER_SERIAL TIM19
  74. #elif defined(TIM9_BASE)
  75. #define TIMER_SERIAL TIM9
  76. #elif defined(TIM5_BASE)
  77. #define TIMER_SERIAL TIM5
  78. #elif defined(TIM4_BASE)
  79. #define TIMER_SERIAL TIM4
  80. #elif defined(TIM3_BASE)
  81. #define TIMER_SERIAL TIM3
  82. #elif defined(TIM2_BASE)
  83. #define TIMER_SERIAL TIM2
  84. #elif defined(TIM20_BASE)
  85. #define TIMER_SERIAL TIM20
  86. #elif defined(TIM8_BASE)
  87. #define TIMER_SERIAL TIM8
  88. #elif defined(TIM1_BASE)
  89. #define TIMER_SERIAL TIM1
  90. #else
  91. #error No suitable timer found for SoftwareSerial, define TIMER_SERIAL in variant.h
  92. #endif
  93. #endif
  94. //
  95. // Statics
  96. //
  97. HardwareTimer SoftwareSerial::timer(TIMER_SERIAL);
  98. const IRQn_Type SoftwareSerial::timer_interrupt_number = static_cast<IRQn_Type>(getTimerUpIrq(TIMER_SERIAL));
  99. uint32_t SoftwareSerial::timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TIM_IRQ_PRIO, TIM_IRQ_SUBPRIO);
  100. SoftwareSerial *SoftwareSerial::active_listener = nullptr;
  101. SoftwareSerial *volatile SoftwareSerial::active_out = nullptr;
  102. SoftwareSerial *volatile SoftwareSerial::active_in = nullptr;
  103. int32_t SoftwareSerial::tx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
  104. int32_t volatile SoftwareSerial::rx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
  105. uint32_t SoftwareSerial::tx_buffer = 0;
  106. int32_t SoftwareSerial::tx_bit_cnt = 0;
  107. uint32_t SoftwareSerial::rx_buffer = 0;
  108. int32_t SoftwareSerial::rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
  109. uint32_t SoftwareSerial::cur_speed = 0;
  110. void SoftwareSerial::setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority) {
  111. timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority);
  112. }
  113. //
  114. // Private methods
  115. //
  116. void SoftwareSerial::setSpeed(uint32_t speed) {
  117. if (speed != cur_speed) {
  118. timer.pause();
  119. if (speed != 0) {
  120. // Disable the timer
  121. uint32_t clock_rate, cmp_value;
  122. // Get timer clock
  123. clock_rate = timer.getTimerClkFreq();
  124. int pre = 1;
  125. // Calculate prescale an compare value
  126. do {
  127. cmp_value = clock_rate / (speed * OVERSAMPLE);
  128. if (cmp_value >= UINT16_MAX) {
  129. clock_rate /= 2;
  130. pre *= 2;
  131. }
  132. } while (cmp_value >= UINT16_MAX);
  133. timer.setPrescaleFactor(pre);
  134. timer.setOverflow(cmp_value);
  135. timer.setCount(0);
  136. timer.attachInterrupt(&handleInterrupt);
  137. timer.resume();
  138. NVIC_SetPriority(timer_interrupt_number, timer_interrupt_priority);
  139. }
  140. else
  141. timer.detachInterrupt();
  142. cur_speed = speed;
  143. }
  144. }
  145. // This function sets the current object as the "listening"
  146. // one and returns true if it replaces another
  147. bool SoftwareSerial::listen() {
  148. if (active_listener != this) {
  149. // wait for any transmit to complete as we may change speed
  150. while (active_out);
  151. active_listener->stopListening();
  152. rx_tick_cnt = 1; // 1 : next interrupt will decrease rx_tick_cnt to 0 which means RX pin level will be considered.
  153. rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
  154. setSpeed(_speed);
  155. active_listener = this;
  156. if (!_half_duplex) active_in = this;
  157. return true;
  158. }
  159. return false;
  160. }
  161. // Stop listening. Returns true if we were actually listening.
  162. bool SoftwareSerial::stopListening() {
  163. if (active_listener == this) {
  164. // wait for any output to complete
  165. while (active_out);
  166. if (_half_duplex) setRXTX(false);
  167. active_listener = nullptr;
  168. active_in = nullptr;
  169. // turn off ints
  170. setSpeed(0);
  171. return true;
  172. }
  173. return false;
  174. }
  175. inline void SoftwareSerial::setTX() {
  176. if (_inverse_logic)
  177. LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber);
  178. else
  179. LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber);
  180. pinMode(_transmitPin, OUTPUT);
  181. }
  182. inline void SoftwareSerial::setRX() {
  183. pinMode(_receivePin, _inverse_logic ? INPUT_PULLDOWN : INPUT_PULLUP); // pullup for normal logic!
  184. }
  185. inline void SoftwareSerial::setRXTX(bool input) {
  186. if (_half_duplex) {
  187. if (input) {
  188. if (active_in != this) {
  189. setRX();
  190. rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
  191. rx_tick_cnt = 2; // 2 : next interrupt will be discarded. 2 interrupts required to consider RX pin level
  192. active_in = this;
  193. }
  194. }
  195. else {
  196. if (active_in == this) {
  197. setTX();
  198. active_in = nullptr;
  199. }
  200. }
  201. }
  202. }
  203. inline void SoftwareSerial::send() {
  204. if (--tx_tick_cnt <= 0) { // if tx_tick_cnt > 0 interrupt is discarded. Only when tx_tick_cnt reaches 0 is TX pin set.
  205. if (tx_bit_cnt++ < 10) { // tx_bit_cnt < 10 transmission is not finished (10 = 1 start +8 bits + 1 stop)
  206. // Send data (including start and stop bits)
  207. if (tx_buffer & 1)
  208. LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber);
  209. else
  210. LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber);
  211. tx_buffer >>= 1;
  212. tx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks to send next bit
  213. }
  214. else { // Transmission finished
  215. tx_tick_cnt = 1;
  216. if (_output_pending) {
  217. active_out = nullptr;
  218. // In half-duplex mode wait HALFDUPLEX_SWITCH_DELAY bit-periods after the byte has
  219. // been transmitted before allowing the switch to RX mode
  220. }
  221. else if (tx_bit_cnt > 10 + OVERSAMPLE * HALFDUPLEX_SWITCH_DELAY) {
  222. if (_half_duplex && active_listener == this) setRXTX(true);
  223. active_out = nullptr;
  224. }
  225. }
  226. }
  227. }
  228. //
  229. // The receive routine called by the interrupt handler
  230. //
  231. inline void SoftwareSerial::recv() {
  232. if (--rx_tick_cnt <= 0) { // if rx_tick_cnt > 0 interrupt is discarded. Only when rx_tick_cnt reaches 0 is RX pin considered
  233. bool inbit = LL_GPIO_IsInputPinSet(_receivePinPort, _receivePinNumber) ^ _inverse_logic;
  234. if (rx_bit_cnt == -1) { // rx_bit_cnt = -1 : waiting for start bit
  235. if (!inbit) {
  236. // got start bit
  237. rx_bit_cnt = 0; // rx_bit_cnt == 0 : start bit received
  238. rx_tick_cnt = OVERSAMPLE + 1; // Wait 1 bit (OVERSAMPLE ticks) + 1 tick in order to sample RX pin in the middle of the edge (and not too close to the edge)
  239. rx_buffer = 0;
  240. }
  241. else
  242. rx_tick_cnt = 1; // Waiting for start bit, but wrong level. Wait for next Interrupt to check RX pin level
  243. }
  244. else if (rx_bit_cnt >= 8) { // rx_bit_cnt >= 8 : waiting for stop bit
  245. if (inbit) {
  246. // Stop-bit read complete. Add to buffer.
  247. uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
  248. if (next != _receive_buffer_head) {
  249. // save new data in buffer: tail points to byte destination
  250. _receive_buffer[_receive_buffer_tail] = rx_buffer; // save new byte
  251. _receive_buffer_tail = next;
  252. }
  253. else // rx_bit_cnt = x with x = [0..7] correspond to new bit x received
  254. _buffer_overflow = true;
  255. }
  256. // Full trame received. Restart waiting for start bit at next interrupt
  257. rx_tick_cnt = 1;
  258. rx_bit_cnt = -1;
  259. }
  260. else {
  261. // data bits
  262. rx_buffer >>= 1;
  263. if (inbit) rx_buffer |= 0x80;
  264. rx_bit_cnt++; // Prepare for next bit
  265. rx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks before sampling next bit
  266. }
  267. }
  268. }
  269. //
  270. // Interrupt handling
  271. //
  272. /* static */
  273. inline void SoftwareSerial::handleInterrupt(HardwareTimer*) {
  274. if (active_in) active_in->recv();
  275. if (active_out) active_out->send();
  276. }
  277. //
  278. // Constructor
  279. //
  280. SoftwareSerial::SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic /* = false */) :
  281. _receivePin(receivePin),
  282. _transmitPin(transmitPin),
  283. _receivePinPort(digitalPinToPort(receivePin)),
  284. _receivePinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(receivePin))),
  285. _transmitPinPort(digitalPinToPort(transmitPin)),
  286. _transmitPinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(transmitPin))),
  287. _speed(0),
  288. _buffer_overflow(false),
  289. _inverse_logic(inverse_logic),
  290. _half_duplex(receivePin == transmitPin),
  291. _output_pending(0),
  292. _receive_buffer_tail(0),
  293. _receive_buffer_head(0)
  294. {
  295. if ((receivePin < NUM_DIGITAL_PINS) || (transmitPin < NUM_DIGITAL_PINS)) {
  296. /* Enable GPIO clock for tx and rx pin*/
  297. set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(transmitPin)));
  298. set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(receivePin)));
  299. }
  300. else
  301. _Error_Handler("ERROR: invalid pin number\n", -1);
  302. }
  303. //
  304. // Destructor
  305. //
  306. SoftwareSerial::~SoftwareSerial() { end(); }
  307. //
  308. // Public methods
  309. //
  310. void SoftwareSerial::begin(long speed) {
  311. #ifdef FORCE_BAUD_RATE
  312. speed = FORCE_BAUD_RATE;
  313. #endif
  314. _speed = speed;
  315. if (!_half_duplex) {
  316. setTX();
  317. setRX();
  318. listen();
  319. }
  320. else
  321. setTX();
  322. }
  323. void SoftwareSerial::end() {
  324. stopListening();
  325. }
  326. // Read data from buffer
  327. int SoftwareSerial::read() {
  328. // Empty buffer?
  329. if (_receive_buffer_head == _receive_buffer_tail) return -1;
  330. // Read from "head"
  331. uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
  332. _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
  333. return d;
  334. }
  335. int SoftwareSerial::available() {
  336. return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
  337. }
  338. size_t SoftwareSerial::write(uint8_t b) {
  339. // wait for previous transmit to complete
  340. _output_pending = 1;
  341. while (active_out) { /* nada */ }
  342. // add start and stop bits.
  343. tx_buffer = b << 1 | 0x200;
  344. if (_inverse_logic) tx_buffer = ~tx_buffer;
  345. tx_bit_cnt = 0;
  346. tx_tick_cnt = OVERSAMPLE;
  347. setSpeed(_speed);
  348. if (_half_duplex) setRXTX(false);
  349. _output_pending = 0;
  350. // make us active
  351. active_out = this;
  352. return 1;
  353. }
  354. void SoftwareSerial::flush() {
  355. noInterrupts();
  356. _receive_buffer_head = _receive_buffer_tail = 0;
  357. interrupts();
  358. }
  359. int SoftwareSerial::peek() {
  360. // Empty buffer?
  361. if (_receive_buffer_head == _receive_buffer_tail) return -1;
  362. // Read from "head"
  363. return _receive_buffer[_receive_buffer_head];
  364. }
  365. #endif // ARDUINO_ARCH_STM32 && !STM32GENERIC