Browse Source

✨ M261 S I2C output format (#22890)

Co-authored-by: Scott Lahteine <github@thinkyhead.com>
Stuart Pittaway 3 years ago
parent
commit
ad14b5052c
No account linked to committer's email address

+ 53
- 8
Marlin/src/feature/twibus.cpp View File

@@ -28,11 +28,17 @@
28 28
 
29 29
 #include <Wire.h>
30 30
 
31
+#include "../libs/hex_print.h"
32
+
31 33
 TWIBus i2c;
32 34
 
33 35
 TWIBus::TWIBus() {
34 36
   #if I2C_SLAVE_ADDRESS == 0
35
-    Wire.begin();                  // No address joins the BUS as the master
37
+    Wire.begin(                    // No address joins the BUS as the master
38
+      #if PINS_EXIST(I2C_SCL, I2C_SDA) && DISABLED(SOFT_I2C_EEPROM)
39
+        pin_t(I2C_SDA_PIN), pin_t(I2C_SCL_PIN)
40
+      #endif
41
+    );
36 42
   #else
37 43
     Wire.begin(I2C_SLAVE_ADDRESS); // Join the bus as a slave
38 44
   #endif
@@ -88,14 +94,53 @@ void TWIBus::echoprefix(uint8_t bytes, FSTR_P const pref, uint8_t adr) {
88 94
 }
89 95
 
90 96
 // static
91
-void TWIBus::echodata(uint8_t bytes, FSTR_P const pref, uint8_t adr) {
92
-  echoprefix(bytes, pref, adr);
93
-  while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read());
97
+void TWIBus::echodata(uint8_t bytes, FSTR_P const pref, uint8_t adr, const uint8_t style/*=0*/) {
98
+  union TwoBytesToInt16 { uint8_t bytes[2]; int16_t integervalue; };
99
+  TwoBytesToInt16 ConversionUnion;
100
+
101
+  echoprefix(bytes, pref, adr);  
102
+
103
+  while (bytes-- && Wire.available()) {
104
+    int value = Wire.read();
105
+    switch (style) {
106
+
107
+      // Style 1, HEX DUMP
108
+      case 1:
109
+        SERIAL_CHAR(hex_nybble((value & 0xF0) >> 4));
110
+        SERIAL_CHAR(hex_nybble(value & 0x0F));
111
+        if (bytes) SERIAL_CHAR(' ');
112
+        break;
113
+
114
+      // Style 2, signed two byte integer (int16)
115
+      case 2:
116
+        if (bytes == 1)
117
+          ConversionUnion.bytes[1] = (uint8_t)value;
118
+        else if (bytes == 0) {
119
+          ConversionUnion.bytes[0] = (uint8_t)value;
120
+          // Output value in base 10 (standard decimal)
121
+          SERIAL_ECHO(ConversionUnion.integervalue);
122
+        }
123
+        break;
124
+
125
+      // Style 3, unsigned byte, base 10 (uint8)
126
+      case 3:
127
+        SERIAL_ECHO(value);
128
+        if (bytes) SERIAL_CHAR(' ');
129
+        break;
130
+
131
+      // Default style (zero), raw serial output
132
+      default:
133
+        // This can cause issues with some serial consoles, Pronterface is an example where things go wrong
134
+        SERIAL_CHAR(value);
135
+        break;
136
+    }
137
+  }
138
+
94 139
   SERIAL_EOL();
95 140
 }
96 141
 
97
-void TWIBus::echobuffer(FSTR_P const pref, uint8_t adr) {
98
-  echoprefix(buffer_s, pref, adr);
142
+void TWIBus::echobuffer(FSTR_P const prefix, uint8_t adr) {
143
+  echoprefix(buffer_s, prefix, adr);
99 144
   LOOP_L_N(i, buffer_s) SERIAL_CHAR(buffer[i]);
100 145
   SERIAL_EOL();
101 146
 }
@@ -114,11 +159,11 @@ bool TWIBus::request(const uint8_t bytes) {
114 159
   return true;
115 160
 }
116 161
 
117
-void TWIBus::relay(const uint8_t bytes) {
162
+void TWIBus::relay(const uint8_t bytes, const uint8_t style/*=0*/) {
118 163
   debug(F("relay"), bytes);
119 164
 
120 165
   if (request(bytes))
121
-    echodata(bytes, F("i2c-reply"), addr);
166
+    echodata(bytes, F("i2c-reply"), addr, style);
122 167
 }
123 168
 
124 169
 uint8_t TWIBus::capture(char *dst, const uint8_t bytes) {

+ 6
- 4
Marlin/src/feature/twibus.h View File

@@ -142,7 +142,7 @@ class TWIBus {
142 142
      *
143 143
      * @param bytes the number of bytes to request
144 144
      */
145
-    static void echoprefix(uint8_t bytes, FSTR_P prefix, uint8_t adr);
145
+    static void echoprefix(uint8_t bytes, FSTR_P const prefix, uint8_t adr);
146 146
 
147 147
     /**
148 148
      * @brief Echo data on the bus to serial
@@ -150,8 +150,9 @@ class TWIBus {
150 150
      *          to serial in a parser-friendly format.
151 151
      *
152 152
      * @param bytes the number of bytes to request
153
+     * @param style Output format for the bytes, 0 = Raw byte [default], 1 = Hex characters, 2 = uint16_t
153 154
      */
154
-    static void echodata(uint8_t bytes, FSTR_P prefix, uint8_t adr);
155
+    static void echodata(uint8_t bytes, FSTR_P const prefix, uint8_t adr, const uint8_t style=0);
155 156
 
156 157
     /**
157 158
      * @brief Echo data in the buffer to serial
@@ -160,7 +161,7 @@ class TWIBus {
160 161
      *
161 162
      * @param bytes the number of bytes to request
162 163
      */
163
-    void echobuffer(FSTR_P prefix, uint8_t adr);
164
+    void echobuffer(FSTR_P const prefix, uint8_t adr);
164 165
 
165 166
     /**
166 167
      * @brief Request data from the slave device and wait.
@@ -192,10 +193,11 @@ class TWIBus {
192 193
      * @brief Request data from the slave device, echo to serial.
193 194
      * @details Request a number of bytes from a slave device and output
194 195
      *          the returned data to serial in a parser-friendly format.
196
+     * @style Output format for the bytes, 0 = raw byte [default], 1 = Hex characters, 2 = uint16_t
195 197
      *
196 198
      * @param bytes the number of bytes to request
197 199
      */
198
-    void relay(const uint8_t bytes);
200
+    void relay(const uint8_t bytes, const uint8_t style=0);
199 201
 
200 202
     #if I2C_SLAVE_ADDRESS > 0
201 203
 

+ 4
- 3
Marlin/src/gcode/feature/i2c/M260_M261.cpp View File

@@ -60,15 +60,16 @@ void GcodeSuite::M260() {
60 60
 /**
61 61
  * M261: Request X bytes from I2C slave device
62 62
  *
63
- * Usage: M261 A<slave device address base 10> B<number of bytes>
63
+ * Usage: M261 A<slave device address base 10> B<number of bytes> S<style>
64 64
  */
65 65
 void GcodeSuite::M261() {
66 66
   if (parser.seen('A')) i2c.address(parser.value_byte());
67 67
 
68
-  uint8_t bytes = parser.byteval('B', 1);
68
+  const uint8_t bytes = parser.byteval('B', 1),   // Bytes to request
69
+                style = parser.byteval('S');      // Serial output style (ASCII, HEX etc)
69 70
 
70 71
   if (i2c.addr && bytes && bytes <= TWIBUS_BUFFER_SIZE)
71
-    i2c.relay(bytes);
72
+    i2c.relay(bytes, style);
72 73
   else
73 74
     SERIAL_ERROR_MSG("Bad i2c request");
74 75
 }

+ 1
- 1
Marlin/src/libs/hex_print.h View File

@@ -27,7 +27,7 @@
27 27
 // Utility functions to create and print hex strings as nybble, byte, and word.
28 28
 //
29 29
 
30
-FORCE_INLINE char hex_nybble(const uint8_t n) {
30
+constexpr char hex_nybble(const uint8_t n) {
31 31
   return (n & 0xF) + ((n & 0xF) < 10 ? '0' : 'A' - 10);
32 32
 }
33 33
 char* hex_byte(const uint8_t b);

Loading…
Cancel
Save