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
 
5285
 
5286
     uint8_t bytes = code_seen('B') ? code_value_byte() : 1;
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
     else {
5291
     else {
5292
       SERIAL_ERROR_START;
5292
       SERIAL_ERROR_START;

+ 50
- 9
Marlin/twibus.cpp View File

86
   this->reset();
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
   SERIAL_ECHO_START;
91
   SERIAL_ECHO_START;
91
   serialprintPGM(prefix);
92
   serialprintPGM(prefix);
92
   SERIAL_ECHOPAIR(": from:", adr);
93
   SERIAL_ECHOPAIR(": from:", adr);
93
   SERIAL_ECHOPAIR(" bytes:", bytes);
94
   SERIAL_ECHOPAIR(" bytes:", bytes);
94
   SERIAL_ECHOPGM (" data:");
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
   while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read());
101
   while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read());
96
   SERIAL_EOL;
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
   #if ENABLED(DEBUG_TWIBUS)
114
   #if ENABLED(DEBUG_TWIBUS)
103
-    debug(PSTR("reqbytes"), bytes);
115
+    debug(PSTR("request"), bytes);
104
   #endif
116
   #endif
105
 
117
 
106
   // requestFrom() is a blocking function
118
   // requestFrom() is a blocking function
107
   Wire.requestFrom(this->addr, bytes);
119
   Wire.requestFrom(this->addr, bytes);
108
 
120
 
109
-  // Wait until all bytes arrive, or timeout
121
+  // Wait for all bytes to arrive
110
   millis_t t = millis() + this->timeout;
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
 #if I2C_SLAVE_ADDRESS > 0
157
 #if I2C_SLAVE_ADDRESS > 0
120
     #if ENABLED(DEBUG_TWIBUS)
160
     #if ENABLED(DEBUG_TWIBUS)
121
       debug(PSTR("receive"), bytes);
161
       debug(PSTR("receive"), bytes);
122
     #endif
162
     #endif
123
-    this->echodata(bytes, PSTR("i2c-receive"), 0);
163
+    echodata(bytes, PSTR("i2c-receive"), 0);
124
   }
164
   }
125
 
165
 
126
   void TWIBus::reply(char str[]/*=NULL*/) {
166
   void TWIBus::reply(char str[]/*=NULL*/) {
142
 
182
 
143
 #if ENABLED(DEBUG_TWIBUS)
183
 #if ENABLED(DEBUG_TWIBUS)
144
 
184
 
185
+  // static
145
   void TWIBus::prefix(const char func[]) {
186
   void TWIBus::prefix(const char func[]) {
146
     SERIAL_ECHOPGM("TWIBus::");
187
     SERIAL_ECHOPGM("TWIBus::");
147
     serialprintPGM(func);
188
     serialprintPGM(func);

+ 50
- 5
Marlin/twibus.h View File

33
 typedef void (*twiReceiveFunc_t)(int bytes);
33
 typedef void (*twiReceiveFunc_t)(int bytes);
34
 typedef void (*twiRequestFunc_t)();
34
 typedef void (*twiRequestFunc_t)();
35
 
35
 
36
+#define TWIBUS_BUFFER_SIZE 32
37
+
36
 /**
38
 /**
37
  * TWIBUS class
39
  * TWIBUS class
38
  *
40
  *
70
      * @brief Internal buffer
72
      * @brief Internal buffer
71
      * @details A fixed buffer. TWI commands can be no longer than this.
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
   public:
78
   public:
135
     void address(const uint8_t adr);
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
      * @brief Echo data on the bus to serial
148
      * @brief Echo data on the bus to serial
139
      * @details Echo some number of bytes from the bus
149
      * @details Echo some number of bytes from the bus
140
      *          to serial in a parser-friendly format.
150
      *          to serial in a parser-friendly format.
144
     static void echodata(uint8_t bytes, const char prefix[], uint8_t adr);
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
      * @details Request a number of bytes from a slave device.
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
      * @param bytes the number of bytes to request
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
     #if I2C_SLAVE_ADDRESS > 0
200
     #if I2C_SLAVE_ADDRESS > 0
157
 
201
 
181
       /**
225
       /**
182
        * @brief Send a reply to the bus
226
        * @brief Send a reply to the bus
183
        * @details Send the buffer and clear it.
227
        * @details Send the buffer and clear it.
228
+       *          If a string is passed, write it into the buffer first.
184
        */
229
        */
185
       void reply(char str[]=NULL);
230
       void reply(char str[]=NULL);
186
       inline void reply(const char str[]) { this->reply((char*)str); }
231
       inline void reply(const char str[]) { this->reply((char*)str); }

Loading…
Cancel
Save