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 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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. * (http://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 (http://www.pjrc.com)
  12. * -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
  13. * -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
  14. *
  15. * This library is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU Lesser General Public
  17. * License as published by the Free Software Foundation; either
  18. * version 2.1 of the License, or (at your option) any later version.
  19. *
  20. * This library is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  23. * Lesser General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU Lesser General Public
  26. * License along with this library; if not, write to the Free Software
  27. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  28. *
  29. * The latest version of this library can always be found at
  30. * http://arduiniana.org.
  31. */
  32. #ifdef TARGET_LPC1768
  33. //
  34. // Includes
  35. //
  36. //#include <WInterrupts.h>
  37. #include "../../../inc/MarlinConfig.h"
  38. #include "../../shared/Delay.h"
  39. #include <stdint.h>
  40. #include <stdarg.h>
  41. #include <Arduino.h>
  42. #include <pinmapping.h>
  43. #include "../fastio.h"
  44. #include "SoftwareSerial.h"
  45. void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
  46. void GpioDisableInt(uint32_t port, uint32_t pin);
  47. //
  48. // Statics
  49. //
  50. SoftwareSerial *SoftwareSerial::active_object = 0;
  51. unsigned char SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF];
  52. volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
  53. volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
  54. typedef struct _DELAY_TABLE {
  55. long baud;
  56. uint16_t rx_delay_centering;
  57. uint16_t rx_delay_intrabit;
  58. uint16_t rx_delay_stopbit;
  59. uint16_t tx_delay;
  60. } DELAY_TABLE;
  61. // rough delay estimation
  62. static const DELAY_TABLE table[] = {
  63. //baud |rxcenter|rxintra |rxstop |tx { 250000, 2, 4, 4, 4, }, //Done but not good due to instruction cycle error { 115200, 4, 8, 8, 8, }, //Done but not good due to instruction cycle error
  64. //{ 74880, 69, 139, 62, 162, }, // estimation
  65. //{ 57600, 100, 185, 1, 208, }, // Done but not good due to instruction cycle error
  66. //{ 38400, 13, 26, 26, 26, }, // Done
  67. //{ 19200, 26, 52, 52, 52, }, // Done { 9600, 52, 104, 104, 104, }, // Done
  68. //{ 4800, 104, 208, 208, 208, },
  69. //{ 2400, 208, 417, 417, 417, },
  70. //{ 1200, 416, 833, 833, 833,},
  71. };
  72. //
  73. // Private methods
  74. //
  75. inline void SoftwareSerial::tunedDelay(const uint32_t count) {
  76. DELAY_US(count);
  77. }
  78. // This function sets the current object as the "listening"
  79. // one and returns true if it replaces another
  80. bool SoftwareSerial::listen() {
  81. if (!_rx_delay_stopbit)
  82. return false;
  83. if (active_object != this) {
  84. if (active_object)
  85. active_object->stopListening();
  86. _buffer_overflow = false;
  87. _receive_buffer_head = _receive_buffer_tail = 0;
  88. active_object = this;
  89. setRxIntMsk(true);
  90. return true;
  91. }
  92. return false;
  93. }
  94. // Stop listening. Returns true if we were actually listening.
  95. bool SoftwareSerial::stopListening() {
  96. if (active_object == this) {
  97. setRxIntMsk(false);
  98. active_object = NULL;
  99. return true;
  100. }
  101. return false;
  102. }
  103. //
  104. // The receive routine called by the interrupt handler
  105. //
  106. void SoftwareSerial::recv() {
  107. uint8_t d = 0;
  108. // If RX line is high, then we don't see any start bit
  109. // so interrupt is probably not for us
  110. if (_inverse_logic ? rx_pin_read() : !rx_pin_read()) {
  111. // Disable further interrupts during reception, this prevents
  112. // triggering another interrupt directly after we return, which can
  113. // cause problems at higher baudrates.
  114. setRxIntMsk(false);//__disable_irq();//
  115. // Wait approximately 1/2 of a bit width to "center" the sample
  116. tunedDelay(_rx_delay_centering);
  117. // Read each of the 8 bits
  118. for (uint8_t i=8; i > 0; --i) {
  119. tunedDelay(_rx_delay_intrabit);
  120. d >>= 1;
  121. if (rx_pin_read()) d |= 0x80;
  122. }
  123. if (_inverse_logic) d = ~d;
  124. // if buffer full, set the overflow flag and return
  125. uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
  126. if (next != _receive_buffer_head) {
  127. // save new data in buffer: tail points to where byte goes
  128. _receive_buffer[_receive_buffer_tail] = d; // save new byte
  129. _receive_buffer_tail = next;
  130. }
  131. else {
  132. _buffer_overflow = true;
  133. }
  134. tunedDelay(_rx_delay_stopbit);
  135. // Re-enable interrupts when we're sure to be inside the stop bit
  136. setRxIntMsk(true); //__enable_irq();//
  137. }
  138. }
  139. uint32_t SoftwareSerial::rx_pin_read() {
  140. return digitalRead(_receivePin);
  141. }
  142. //
  143. // Interrupt handling
  144. //
  145. /* static */
  146. inline void SoftwareSerial::handle_interrupt() {
  147. if (active_object)
  148. active_object->recv();
  149. }
  150. extern "C" void intWrapper() {
  151. SoftwareSerial::handle_interrupt();
  152. }
  153. //
  154. // Constructor
  155. //
  156. SoftwareSerial::SoftwareSerial(pin_t receivePin, pin_t transmitPin, bool inverse_logic /* = false */) :
  157. _rx_delay_centering(0),
  158. _rx_delay_intrabit(0),
  159. _rx_delay_stopbit(0),
  160. _tx_delay(0),
  161. _buffer_overflow(false),
  162. _inverse_logic(inverse_logic) {
  163. setTX(transmitPin);
  164. setRX(receivePin);
  165. }
  166. //
  167. // Destructor
  168. //
  169. SoftwareSerial::~SoftwareSerial() {
  170. end();
  171. }
  172. void SoftwareSerial::setTX(pin_t tx) {
  173. // First write, then set output. If we do this the other way around,
  174. // the pin would be output low for a short while before switching to
  175. // output hihg. Now, it is input with pullup for a short while, which
  176. // is fine. With inverse logic, either order is fine.
  177. digitalWrite(tx, _inverse_logic ? LOW : HIGH);
  178. pinMode(tx,OUTPUT);
  179. _transmitPin = tx;
  180. }
  181. void SoftwareSerial::setRX(pin_t rx) {
  182. pinMode(rx, INPUT_PULLUP); // pullup for normal logic!
  183. //if (!_inverse_logic)
  184. // digitalWrite(rx, HIGH);
  185. _receivePin = rx;
  186. _receivePort = LPC1768_PIN_PORT(rx);
  187. _receivePortPin = LPC1768_PIN_PIN(rx);
  188. /* GPIO_T * rxPort = digitalPinToPort(rx);
  189. _receivePortRegister = portInputRegister(rxPort);
  190. _receiveBitMask = digitalPinToBitMask(rx);*/
  191. }
  192. //
  193. // Public methods
  194. //
  195. void SoftwareSerial::begin(long speed) {
  196. _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;
  197. for(uint8_t i = 0; i < sizeof(table)/sizeof(table[0]); ++i) {
  198. long baud = table[i].baud;
  199. if (baud == speed) {
  200. _rx_delay_centering = table[i].rx_delay_centering;
  201. _rx_delay_intrabit = table[i].rx_delay_intrabit;
  202. _rx_delay_stopbit = table[i].rx_delay_stopbit;
  203. _tx_delay = table[i].tx_delay;
  204. break;
  205. }
  206. }
  207. attachInterrupt(_receivePin, intWrapper, CHANGE); //this->handle_interrupt, CHANGE);
  208. listen();
  209. tunedDelay(_tx_delay);
  210. }
  211. void SoftwareSerial::setRxIntMsk(bool enable) {
  212. if (enable)
  213. GpioEnableInt(_receivePort,_receivePin,CHANGE);
  214. else
  215. GpioDisableInt(_receivePort,_receivePin);
  216. }
  217. void SoftwareSerial::end() {
  218. stopListening();
  219. }
  220. // Read data from buffer
  221. int16_t SoftwareSerial::read() {
  222. if (!isListening()) return -1;
  223. // Empty buffer?
  224. if (_receive_buffer_head == _receive_buffer_tail) return -1;
  225. // Read from "head"
  226. uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
  227. _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
  228. return d;
  229. }
  230. size_t SoftwareSerial::available() {
  231. if (!isListening()) return 0;
  232. return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
  233. }
  234. size_t SoftwareSerial::write(uint8_t b) {
  235. // By declaring these as local variables, the compiler will put them
  236. // in registers _before_ disabling interrupts and entering the
  237. // critical timing sections below, which makes it a lot easier to
  238. // verify the cycle timings
  239. bool inv = _inverse_logic;
  240. uint16_t delay = _tx_delay;
  241. if (inv) b = ~b;
  242. cli(); // turn off interrupts for a clean txmit
  243. // Write the start bit
  244. digitalWrite(_transmitPin, !!inv);
  245. tunedDelay(delay);
  246. // Write each of the 8 bits
  247. for (uint8_t i = 8; i > 0; --i) {
  248. digitalWrite(_transmitPin, b & 1); // send 1 //(GPIO_Desc[_transmitPin].P)->DOUT |= GPIO_Desc[_transmitPin].bit;
  249. // send 0 //(GPIO_Desc[_transmitPin].P)->DOUT &= ~GPIO_Desc[_transmitPin].bit;
  250. tunedDelay(delay);
  251. b >>= 1;
  252. }
  253. // restore pin to natural state
  254. digitalWrite(_transmitPin, !inv);
  255. sei(); // turn interrupts back on
  256. tunedDelay(delay);
  257. return 1;
  258. }
  259. void SoftwareSerial::flush() {
  260. if (!isListening()) return;
  261. cli();
  262. _receive_buffer_head = _receive_buffer_tail = 0;
  263. sei();
  264. }
  265. int16_t SoftwareSerial::peek() {
  266. if (!isListening())
  267. return -1;
  268. // Empty buffer?
  269. if (_receive_buffer_head == _receive_buffer_tail)
  270. return -1;
  271. // Read from "head"
  272. return _receive_buffer[_receive_buffer_head];
  273. }
  274. #endif // TARGET_LPC1768