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.

twibus.cpp 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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. #include "../inc/MarlinConfig.h"
  23. #if ENABLED(EXPERIMENTAL_I2CBUS)
  24. #include "twibus.h"
  25. #include <Wire.h>
  26. #include "../libs/hex_print.h"
  27. TWIBus i2c;
  28. TWIBus::TWIBus() {
  29. #if I2C_SLAVE_ADDRESS == 0
  30. #if PINS_EXIST(I2C_SCL, I2C_SDA) && DISABLED(SOFT_I2C_EEPROM)
  31. Wire.setSDA(pin_t(I2C_SDA_PIN));
  32. Wire.setSCL(pin_t(I2C_SCL_PIN));
  33. #endif
  34. Wire.begin(); // No address joins the BUS as the master
  35. #else
  36. Wire.begin(I2C_SLAVE_ADDRESS); // Join the bus as a slave
  37. #endif
  38. reset();
  39. }
  40. void TWIBus::reset() {
  41. buffer_s = 0;
  42. buffer[0] = 0x00;
  43. }
  44. void TWIBus::address(const uint8_t adr) {
  45. if (!WITHIN(adr, 8, 127))
  46. SERIAL_ECHO_MSG("Bad I2C address (8-127)");
  47. addr = adr;
  48. debug(F("address"), adr);
  49. }
  50. void TWIBus::addbyte(const char c) {
  51. if (buffer_s >= COUNT(buffer)) return;
  52. buffer[buffer_s++] = c;
  53. debug(F("addbyte"), c);
  54. }
  55. void TWIBus::addbytes(char src[], uint8_t bytes) {
  56. debug(F("addbytes"), bytes);
  57. while (bytes--) addbyte(*src++);
  58. }
  59. void TWIBus::addstring(char str[]) {
  60. debug(F("addstring"), str);
  61. while (char c = *str++) addbyte(c);
  62. }
  63. void TWIBus::send() {
  64. debug(F("send"), addr);
  65. Wire.beginTransmission(I2C_ADDRESS(addr));
  66. Wire.write(buffer, buffer_s);
  67. Wire.endTransmission();
  68. reset();
  69. }
  70. // static
  71. void TWIBus::echoprefix(uint8_t bytes, FSTR_P const pref, uint8_t adr) {
  72. SERIAL_ECHO_START();
  73. SERIAL_ECHOF(pref);
  74. SERIAL_ECHOPGM(": from:", adr, " bytes:", bytes, " data:");
  75. }
  76. // static
  77. void TWIBus::echodata(uint8_t bytes, FSTR_P const pref, uint8_t adr, const uint8_t style/*=0*/) {
  78. union TwoBytesToInt16 { uint8_t bytes[2]; int16_t integervalue; };
  79. TwoBytesToInt16 ConversionUnion;
  80. echoprefix(bytes, pref, adr);
  81. while (bytes-- && Wire.available()) {
  82. int value = Wire.read();
  83. switch (style) {
  84. // Style 1, HEX DUMP
  85. case 1:
  86. SERIAL_CHAR(hex_nybble((value & 0xF0) >> 4));
  87. SERIAL_CHAR(hex_nybble(value & 0x0F));
  88. if (bytes) SERIAL_CHAR(' ');
  89. break;
  90. // Style 2, signed two byte integer (int16)
  91. case 2:
  92. if (bytes == 1)
  93. ConversionUnion.bytes[1] = (uint8_t)value;
  94. else if (bytes == 0) {
  95. ConversionUnion.bytes[0] = (uint8_t)value;
  96. // Output value in base 10 (standard decimal)
  97. SERIAL_ECHO(ConversionUnion.integervalue);
  98. }
  99. break;
  100. // Style 3, unsigned byte, base 10 (uint8)
  101. case 3:
  102. SERIAL_ECHO(value);
  103. if (bytes) SERIAL_CHAR(' ');
  104. break;
  105. // Default style (zero), raw serial output
  106. default:
  107. // This can cause issues with some serial consoles, Pronterface is an example where things go wrong
  108. SERIAL_CHAR(value);
  109. break;
  110. }
  111. }
  112. SERIAL_EOL();
  113. }
  114. void TWIBus::echobuffer(FSTR_P const prefix, uint8_t adr) {
  115. echoprefix(buffer_s, prefix, adr);
  116. LOOP_L_N(i, buffer_s) SERIAL_CHAR(buffer[i]);
  117. SERIAL_EOL();
  118. }
  119. bool TWIBus::request(const uint8_t bytes) {
  120. if (!addr) return false;
  121. debug(F("request"), bytes);
  122. // requestFrom() is a blocking function
  123. if (Wire.requestFrom(I2C_ADDRESS(addr), bytes) == 0) {
  124. debug(F("request fail"), I2C_ADDRESS(addr));
  125. return false;
  126. }
  127. return true;
  128. }
  129. void TWIBus::relay(const uint8_t bytes, const uint8_t style/*=0*/) {
  130. debug(F("relay"), bytes);
  131. if (request(bytes))
  132. echodata(bytes, F("i2c-reply"), addr, style);
  133. }
  134. uint8_t TWIBus::capture(char *dst, const uint8_t bytes) {
  135. reset();
  136. uint8_t count = 0;
  137. while (count < bytes && Wire.available())
  138. dst[count++] = Wire.read();
  139. debug(F("capture"), count);
  140. return count;
  141. }
  142. // static
  143. void TWIBus::flush() {
  144. while (Wire.available()) Wire.read();
  145. }
  146. #if I2C_SLAVE_ADDRESS > 0
  147. void TWIBus::receive(uint8_t bytes) {
  148. debug(F("receive"), bytes);
  149. echodata(bytes, F("i2c-receive"), 0);
  150. }
  151. void TWIBus::reply(char str[]/*=nullptr*/) {
  152. debug(F("reply"), str);
  153. if (str) {
  154. reset();
  155. addstring(str);
  156. }
  157. Wire.write(buffer, buffer_s);
  158. reset();
  159. }
  160. void i2c_on_receive(int bytes) { // just echo all bytes received to serial
  161. i2c.receive(bytes);
  162. }
  163. void i2c_on_request() { // just send dummy data for now
  164. i2c.reply("Hello World!\n");
  165. }
  166. #endif
  167. #if ENABLED(DEBUG_TWIBUS)
  168. // static
  169. void TWIBus::prefix(FSTR_P const func) {
  170. SERIAL_ECHOPGM("TWIBus::", func, ": ");
  171. }
  172. void TWIBus::debug(FSTR_P const func, uint32_t adr) {
  173. if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(adr); }
  174. }
  175. void TWIBus::debug(FSTR_P const func, char c) {
  176. if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(c); }
  177. }
  178. void TWIBus::debug(FSTR_P const func, char str[]) {
  179. if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(str); }
  180. }
  181. #endif
  182. #endif // EXPERIMENTAL_I2CBUS