Browse Source

Add request, capture, flush to TWIBus

Scott Lahteine 8 years ago
parent
commit
bd928a69ec
3 changed files with 102 additions and 16 deletions
  1. 2
    2
      Marlin/Marlin_main.cpp
  2. 50
    9
      Marlin/twibus.cpp
  3. 50
    5
      Marlin/twibus.h

+ 2
- 2
Marlin/Marlin_main.cpp View File

@@ -5285,8 +5285,8 @@ inline void gcode_M121() { endstops.enable_globally(false); }
5285 5285
 
5286 5286
     uint8_t bytes = code_seen('B') ? code_value_byte() : 1;
5287 5287
 
5288
-    if (i2c.addr > 0 && bytes > 0 && bytes <= 32) {
5289
-      i2c.reqbytes(bytes);
5288
+    if (i2c.addr && bytes && bytes <= TWIBUS_BUFFER_SIZE) {
5289
+      i2c.relay(bytes);
5290 5290
     }
5291 5291
     else {
5292 5292
       SERIAL_ERROR_START;

+ 50
- 9
Marlin/twibus.cpp View File

@@ -86,32 +86,72 @@ void TWIBus::send() {
86 86
   this->reset();
87 87
 }
88 88
 
89
-void TWIBus::echodata(uint8_t bytes, const char prefix[], uint8_t adr) {
89
+// static
90
+void TWIBus::echoprefix(uint8_t bytes, const char prefix[], uint8_t adr) {
90 91
   SERIAL_ECHO_START;
91 92
   serialprintPGM(prefix);
92 93
   SERIAL_ECHOPAIR(": from:", adr);
93 94
   SERIAL_ECHOPAIR(" bytes:", bytes);
94 95
   SERIAL_ECHOPGM (" data:");
96
+}
97
+
98
+// static
99
+void TWIBus::echodata(uint8_t bytes, const char prefix[], uint8_t adr) {
100
+  echoprefix(bytes, prefix, adr);
95 101
   while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read());
96 102
   SERIAL_EOL;
97 103
 }
98 104
 
99
-void TWIBus::reqbytes(const uint8_t bytes) {
100
-  if (!this->addr) return;
105
+void TWIBus::echobuffer(const char prefix[], uint8_t adr) {
106
+  echoprefix(this->buffer_s, prefix, adr);
107
+  for (uint8_t i = 0; i < this->buffer_s; i++) SERIAL_CHAR(this->buffer[i]);
108
+  SERIAL_EOL;
109
+}
110
+
111
+bool TWIBus::request(const uint8_t bytes) {
112
+  if (!this->addr) return false;
101 113
 
102 114
   #if ENABLED(DEBUG_TWIBUS)
103
-    debug(PSTR("reqbytes"), bytes);
115
+    debug(PSTR("request"), bytes);
104 116
   #endif
105 117
 
106 118
   // requestFrom() is a blocking function
107 119
   Wire.requestFrom(this->addr, bytes);
108 120
 
109
-  // Wait until all bytes arrive, or timeout
121
+  // Wait for all bytes to arrive
110 122
   millis_t t = millis() + this->timeout;
111
-  while (Wire.available() < bytes && PENDING(millis(), t)) { /*nada*/ }
123
+  while (Wire.available() < bytes)
124
+    if (ELAPSED(millis(), t)) {
125
+      #if ENABLED(DEBUG_TWIBUS)
126
+        SERIAL_ECHO_START;
127
+        SERIAL_ECHOLNPGM("i2c timeout");
128
+      #endif
129
+      return false;
130
+    }
131
+
132
+  return true;
133
+}
134
+
135
+void TWIBus::relay(const uint8_t bytes) {
136
+  #if ENABLED(DEBUG_TWIBUS)
137
+    debug(PSTR("relay"), bytes);
138
+  #endif
139
+
140
+  if (this->request(bytes))
141
+    echodata(bytes, PSTR("i2c-reply"), this->addr);
142
+}
143
+
144
+uint8_t TWIBus::capture(char *dst, const uint8_t bytes) {
145
+  this->reset();
146
+  uint8_t count = 0;
147
+  while (count < bytes && Wire.available())
148
+    dst[count++] = Wire.read();
149
+  return count;
150
+}
112 151
 
113
-  // Simply echo the data to the bus
114
-  this->echodata(bytes, PSTR("i2c-reply"), this->addr);
152
+// static
153
+void TWIBus::flush() {
154
+  while (Wire.available()) Wire.read();
115 155
 }
116 156
 
117 157
 #if I2C_SLAVE_ADDRESS > 0
@@ -120,7 +160,7 @@ void TWIBus::reqbytes(const uint8_t bytes) {
120 160
     #if ENABLED(DEBUG_TWIBUS)
121 161
       debug(PSTR("receive"), bytes);
122 162
     #endif
123
-    this->echodata(bytes, PSTR("i2c-receive"), 0);
163
+    echodata(bytes, PSTR("i2c-receive"), 0);
124 164
   }
125 165
 
126 166
   void TWIBus::reply(char str[]/*=NULL*/) {
@@ -142,6 +182,7 @@ void TWIBus::reqbytes(const uint8_t bytes) {
142 182
 
143 183
 #if ENABLED(DEBUG_TWIBUS)
144 184
 
185
+  // static
145 186
   void TWIBus::prefix(const char func[]) {
146 187
     SERIAL_ECHOPGM("TWIBus::");
147 188
     serialprintPGM(func);

+ 50
- 5
Marlin/twibus.h View File

@@ -33,6 +33,8 @@
33 33
 typedef void (*twiReceiveFunc_t)(int bytes);
34 34
 typedef void (*twiRequestFunc_t)();
35 35
 
36
+#define TWIBUS_BUFFER_SIZE 32
37
+
36 38
 /**
37 39
  * TWIBUS class
38 40
  *
@@ -70,7 +72,7 @@ class TWIBus {
70 72
      * @brief Internal buffer
71 73
      * @details A fixed buffer. TWI commands can be no longer than this.
72 74
      */
73
-    char buffer[32];
75
+    char buffer[TWIBUS_BUFFER_SIZE];
74 76
 
75 77
 
76 78
   public:
@@ -135,6 +137,14 @@ class TWIBus {
135 137
     void address(const uint8_t adr);
136 138
 
137 139
     /**
140
+     * @brief Prefix for echo to serial
141
+     * @details Echo a label, length, address, and "data:"
142
+     *
143
+     * @param bytes the number of bytes to request
144
+     */
145
+    static void echoprefix(uint8_t bytes, const char prefix[], uint8_t adr);
146
+
147
+    /**
138 148
      * @brief Echo data on the bus to serial
139 149
      * @details Echo some number of bytes from the bus
140 150
      *          to serial in a parser-friendly format.
@@ -144,14 +154,48 @@ class TWIBus {
144 154
     static void echodata(uint8_t bytes, const char prefix[], uint8_t adr);
145 155
 
146 156
     /**
147
-     * @brief Request data from the slave device
157
+     * @brief Echo data in the buffer to serial
158
+     * @details Echo the entire buffer to serial
159
+     *          to serial in a parser-friendly format.
160
+     *
161
+     * @param bytes the number of bytes to request
162
+     */
163
+    void echobuffer(const char prefix[], uint8_t adr);
164
+
165
+    /**
166
+     * @brief Request data from the slave device and wait.
148 167
      * @details Request a number of bytes from a slave device.
149
-     *          This implementation simply sends the data to serial
150
-     *          in a parser-friendly format.
168
+     *          Wait for the data to arrive until the timeout
169
+     *          interval expires. Return true on success.
170
+     *
171
+     * @param bytes the number of bytes to request
172
+     * @return status of the request: true=success, false=timeout
173
+     */
174
+    bool request(const uint8_t bytes);
175
+
176
+    /**
177
+     * @brief Capture data from the bus into the buffer.
178
+     * @details Capture data after a request has succeeded.
179
+     *
180
+     * @param bytes the number of bytes to request
181
+     * @return the number of bytes captured to the buffer
182
+     */
183
+    uint8_t capture(char *dst, const uint8_t bytes);
184
+
185
+    /**
186
+     * @brief Flush the i2c bus.
187
+     * @details Get all bytes on the bus and throw them away.
188
+     */
189
+    static void flush();
190
+
191
+    /**
192
+     * @brief Request data from the slave device, echo to serial.
193
+     * @details Request a number of bytes from a slave device and output
194
+     *          the returned data to serial in a parser-friendly format.
151 195
      *
152 196
      * @param bytes the number of bytes to request
153 197
      */
154
-    void reqbytes(const uint8_t bytes);
198
+    void relay(const uint8_t bytes);
155 199
 
156 200
     #if I2C_SLAVE_ADDRESS > 0
157 201
 
@@ -181,6 +225,7 @@ class TWIBus {
181 225
       /**
182 226
        * @brief Send a reply to the bus
183 227
        * @details Send the buffer and clear it.
228
+       *          If a string is passed, write it into the buffer first.
184 229
        */
185 230
       void reply(char str[]=NULL);
186 231
       inline void reply(const char str[]) { this->reply((char*)str); }

Loading…
Cancel
Save