Blame | Last modification | View Log | RSS feed
/*** Marlin 3D Printer Firmware* Copyright (C) 2016 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/>.**/#include "MarlinConfig.h"#if ENABLED(EXPERIMENTAL_I2CBUS)#include "twibus.h"#include <Wire.h>#include "Marlin.h"TWIBus::TWIBus() {#if I2C_SLAVE_ADDRESS == 0Wire.begin(); // No address joins the BUS as the master#elseWire.begin(I2C_SLAVE_ADDRESS); // Join the bus as a slave#endifthis->reset();}void TWIBus::reset() {this->buffer_s = 0;this->buffer[0] = 0x00;}void TWIBus::address(const uint8_t adr) {if (!WITHIN(adr, 8, 127)) {SERIAL_ECHO_START();SERIAL_ECHOLNPGM("Bad I2C address (8-127)");}this->addr = adr;#if ENABLED(DEBUG_TWIBUS)debug(PSTR("address"), adr);#endif}void TWIBus::addbyte(const byte c) {if (this->buffer_s >= COUNT(this->buffer)) return;this->buffer[this->buffer_s++] = c;#if ENABLED(DEBUG_TWIBUS)debug(PSTR("addbyte"), c);#endif}void TWIBus::addbytes(byte src[], uint8_t bytes) {#if ENABLED(DEBUG_TWIBUS)debug(PSTR("addbytes"), bytes);#endifwhile (bytes--) this->addbyte(*src++);}void TWIBus::addstring(char str[]) {#if ENABLED(DEBUG_TWIBUS)debug(PSTR("addstring"), str);#endifwhile (char c = *str++) this->addbyte(c);}void TWIBus::send() {#if ENABLED(DEBUG_TWIBUS)debug(PSTR("send"), this->addr);#endifWire.beginTransmission(this->addr);Wire.write(this->buffer, this->buffer_s);Wire.endTransmission();this->reset();}// staticvoid TWIBus::echoprefix(uint8_t bytes, const char prefix[], uint8_t adr) {SERIAL_ECHO_START();serialprintPGM(prefix);SERIAL_ECHOPAIR(": from:", adr);SERIAL_ECHOPAIR(" bytes:", bytes);SERIAL_ECHOPGM (" data:");}// staticvoid TWIBus::echodata(uint8_t bytes, const char prefix[], uint8_t adr) {echoprefix(bytes, prefix, adr);while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read());SERIAL_EOL();}void TWIBus::echobuffer(const char prefix[], uint8_t adr) {echoprefix(this->buffer_s, prefix, adr);for (uint8_t i = 0; i < this->buffer_s; i++) SERIAL_CHAR(this->buffer[i]);SERIAL_EOL();}bool TWIBus::request(const uint8_t bytes) {if (!this->addr) return false;#if ENABLED(DEBUG_TWIBUS)debug(PSTR("request"), bytes);#endif// requestFrom() is a blocking functionif (Wire.requestFrom(this->addr, bytes) == 0) {#if ENABLED(DEBUG_TWIBUS)debug("request fail", this->addr);#endifreturn false;}return true;}void TWIBus::relay(const uint8_t bytes) {#if ENABLED(DEBUG_TWIBUS)debug(PSTR("relay"), bytes);#endifif (this->request(bytes))echodata(bytes, PSTR("i2c-reply"), this->addr);}uint8_t TWIBus::capture(byte *dst, const uint8_t bytes) {this->reset();uint8_t count = 0;while (count < bytes && Wire.available())dst[count++] = Wire.read();#if ENABLED(DEBUG_TWIBUS)debug(PSTR("capture"), count);#endifreturn count;}// staticvoid TWIBus::flush() {while (Wire.available()) Wire.read();}#if I2C_SLAVE_ADDRESS > 0void TWIBus::receive(uint8_t bytes) {#if ENABLED(DEBUG_TWIBUS)debug(PSTR("receive"), bytes);#endifechodata(bytes, PSTR("i2c-receive"), 0);}void TWIBus::reply(char str[]/*=NULL*/) {#if ENABLED(DEBUG_TWIBUS)debug(PSTR("reply"), str);#endifif (str) {this->reset();this->addstring(str);}Wire.write(this->buffer, this->buffer_s);this->reset();}#endif#if ENABLED(DEBUG_TWIBUS)// staticvoid TWIBus::prefix(const char func[]) {SERIAL_ECHOPGM("TWIBus::");serialprintPGM(func);SERIAL_ECHOPGM(": ");}void TWIBus::debug(const char func[], uint32_t adr) {if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(adr); }}void TWIBus::debug(const char func[], char c) {if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(c); }}void TWIBus::debug(const char func[], char str[]) {if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(str); }}#endif#endif // EXPERIMENTAL_I2CBUS