Subversion Repositories Tronxy-X3A-Marlin

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ron 1
/**
2
 * Marlin 3D Printer Firmware
3
 * Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
 
23
#include "MarlinConfig.h"
24
 
25
#if ENABLED(EXPERIMENTAL_I2CBUS)
26
 
27
#include "twibus.h"
28
#include <Wire.h>
29
#include "Marlin.h"
30
 
31
TWIBus::TWIBus() {
32
  #if I2C_SLAVE_ADDRESS == 0
33
    Wire.begin();                  // No address joins the BUS as the master
34
  #else
35
    Wire.begin(I2C_SLAVE_ADDRESS); // Join the bus as a slave
36
  #endif
37
  this->reset();
38
}
39
 
40
void TWIBus::reset() {
41
  this->buffer_s = 0;
42
  this->buffer[0] = 0x00;
43
}
44
 
45
void TWIBus::address(const uint8_t adr) {
46
  if (!WITHIN(adr, 8, 127)) {
47
    SERIAL_ECHO_START();
48
    SERIAL_ECHOLNPGM("Bad I2C address (8-127)");
49
  }
50
 
51
  this->addr = adr;
52
 
53
  #if ENABLED(DEBUG_TWIBUS)
54
    debug(PSTR("address"), adr);
55
  #endif
56
}
57
 
58
void TWIBus::addbyte(const byte c) {
59
  if (this->buffer_s >= COUNT(this->buffer)) return;
60
  this->buffer[this->buffer_s++] = c;
61
  #if ENABLED(DEBUG_TWIBUS)
62
    debug(PSTR("addbyte"), c);
63
  #endif
64
}
65
 
66
void TWIBus::addbytes(byte src[], uint8_t bytes) {
67
  #if ENABLED(DEBUG_TWIBUS)
68
    debug(PSTR("addbytes"), bytes);
69
  #endif
70
  while (bytes--) this->addbyte(*src++);
71
}
72
 
73
void TWIBus::addstring(char str[]) {
74
  #if ENABLED(DEBUG_TWIBUS)
75
    debug(PSTR("addstring"), str);
76
  #endif
77
  while (char c = *str++) this->addbyte(c);
78
}
79
 
80
void TWIBus::send() {
81
  #if ENABLED(DEBUG_TWIBUS)
82
    debug(PSTR("send"), this->addr);
83
  #endif
84
 
85
  Wire.beginTransmission(this->addr);
86
  Wire.write(this->buffer, this->buffer_s);
87
  Wire.endTransmission();
88
 
89
  this->reset();
90
}
91
 
92
// static
93
void TWIBus::echoprefix(uint8_t bytes, const char prefix[], uint8_t adr) {
94
  SERIAL_ECHO_START();
95
  serialprintPGM(prefix);
96
  SERIAL_ECHOPAIR(": from:", adr);
97
  SERIAL_ECHOPAIR(" bytes:", bytes);
98
  SERIAL_ECHOPGM (" data:");
99
}
100
 
101
// static
102
void TWIBus::echodata(uint8_t bytes, const char prefix[], uint8_t adr) {
103
  echoprefix(bytes, prefix, adr);
104
  while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read());
105
  SERIAL_EOL();
106
}
107
 
108
void TWIBus::echobuffer(const char prefix[], uint8_t adr) {
109
  echoprefix(this->buffer_s, prefix, adr);
110
  for (uint8_t i = 0; i < this->buffer_s; i++) SERIAL_CHAR(this->buffer[i]);
111
  SERIAL_EOL();
112
}
113
 
114
bool TWIBus::request(const uint8_t bytes) {
115
  if (!this->addr) return false;
116
 
117
  #if ENABLED(DEBUG_TWIBUS)
118
    debug(PSTR("request"), bytes);
119
  #endif
120
 
121
  // requestFrom() is a blocking function
122
  if (Wire.requestFrom(this->addr, bytes) == 0) {
123
    #if ENABLED(DEBUG_TWIBUS)
124
      debug("request fail", this->addr);
125
    #endif
126
    return false;
127
  }
128
 
129
  return true;
130
}
131
 
132
void TWIBus::relay(const uint8_t bytes) {
133
  #if ENABLED(DEBUG_TWIBUS)
134
    debug(PSTR("relay"), bytes);
135
  #endif
136
 
137
  if (this->request(bytes))
138
    echodata(bytes, PSTR("i2c-reply"), this->addr);
139
}
140
 
141
uint8_t TWIBus::capture(byte *dst, const uint8_t bytes) {
142
  this->reset();
143
  uint8_t count = 0;
144
  while (count < bytes && Wire.available())
145
    dst[count++] = Wire.read();
146
 
147
  #if ENABLED(DEBUG_TWIBUS)
148
    debug(PSTR("capture"), count);
149
  #endif
150
 
151
  return count;
152
}
153
 
154
// static
155
void TWIBus::flush() {
156
  while (Wire.available()) Wire.read();
157
}
158
 
159
#if I2C_SLAVE_ADDRESS > 0
160
 
161
  void TWIBus::receive(uint8_t bytes) {
162
    #if ENABLED(DEBUG_TWIBUS)
163
      debug(PSTR("receive"), bytes);
164
    #endif
165
    echodata(bytes, PSTR("i2c-receive"), 0);
166
  }
167
 
168
  void TWIBus::reply(char str[]/*=NULL*/) {
169
    #if ENABLED(DEBUG_TWIBUS)
170
      debug(PSTR("reply"), str);
171
    #endif
172
 
173
    if (str) {
174
      this->reset();
175
      this->addstring(str);
176
    }
177
 
178
    Wire.write(this->buffer, this->buffer_s);
179
 
180
    this->reset();
181
  }
182
 
183
#endif
184
 
185
#if ENABLED(DEBUG_TWIBUS)
186
 
187
  // static
188
  void TWIBus::prefix(const char func[]) {
189
    SERIAL_ECHOPGM("TWIBus::");
190
    serialprintPGM(func);
191
    SERIAL_ECHOPGM(": ");
192
  }
193
  void TWIBus::debug(const char func[], uint32_t adr) {
194
    if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(adr); }
195
  }
196
  void TWIBus::debug(const char func[], char c) {
197
    if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(c); }
198
  }
199
  void TWIBus::debug(const char func[], char str[]) {
200
    if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(str); }
201
  }
202
 
203
#endif
204
 
205
#endif // EXPERIMENTAL_I2CBUS