Browse Source

Add support for i2c slave address

Scott Lahteine 8 years ago
parent
commit
a99ecf71d8

+ 1
- 0
Marlin/Configuration_adv.h View File

@@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
795 795
 // @section i2cbus
796 796
 
797 797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798 799
 
799 800
 #endif // CONFIGURATION_ADV_H

+ 12
- 0
Marlin/Marlin_main.cpp View File

@@ -835,6 +835,14 @@ void servo_init() {
835 835
   void enableStepperDrivers() { pinMode(STEPPER_RESET_PIN, INPUT); }  // set to input, which allows it to be pulled high by pullups
836 836
 #endif
837 837
 
838
+#if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
839
+
840
+  void i2c_listener(int bytes) {
841
+    i2c.receive(bytes);        // just echo all bytes received to serial
842
+  }
843
+
844
+#endif
845
+
838 846
 /**
839 847
  * Marlin entry-point: Set up before the program loop
840 848
  *  - Set up the kill pin, filament runout, power hold
@@ -981,6 +989,10 @@ void setup() {
981 989
       for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
982 990
         mixing_virtual_tool_mix[t][i] = mixing_factor[i];
983 991
   #endif
992
+
993
+  #if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
994
+    i2c.onReceive(i2c_listener);
995
+  #endif
984 996
 }
985 997
 
986 998
 /**

+ 1
- 0
Marlin/example_configurations/Cartesio/Configuration_adv.h View File

@@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
795 795
 // @section i2cbus
796 796
 
797 797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798 799
 
799 800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/Felix/Configuration_adv.h View File

@@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
795 795
 // @section i2cbus
796 796
 
797 797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798 799
 
799 800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/Hephestos/Configuration_adv.h View File

@@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
795 795
 // @section i2cbus
796 796
 
797 797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798 799
 
799 800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/Hephestos_2/Configuration_adv.h View File

@@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
795 795
 // @section i2cbus
796 796
 
797 797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798 799
 
799 800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/K8200/Configuration_adv.h View File

@@ -801,5 +801,6 @@ const unsigned int dropsegments = 2; //everything with less than this number of
801 801
 // @section i2cbus
802 802
 
803 803
 //#define EXPERIMENTAL_I2CBUS
804
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
804 805
 
805 806
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/K8400/Configuration_adv.h View File

@@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
795 795
 // @section i2cbus
796 796
 
797 797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798 799
 
799 800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/RigidBot/Configuration_adv.h View File

@@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
795 795
 // @section i2cbus
796 796
 
797 797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798 799
 
799 800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/SCARA/Configuration_adv.h View File

@@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
795 795
 // @section i2cbus
796 796
 
797 797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798 799
 
799 800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/TAZ4/Configuration_adv.h View File

@@ -803,5 +803,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
803 803
 // @section i2cbus
804 804
 
805 805
 //#define EXPERIMENTAL_I2CBUS
806
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
806 807
 
807 808
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/WITBOX/Configuration_adv.h View File

@@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
795 795
 // @section i2cbus
796 796
 
797 797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798 799
 
799 800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/delta/biv2.5/Configuration_adv.h View File

@@ -797,5 +797,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
797 797
 // @section i2cbus
798 798
 
799 799
 //#define EXPERIMENTAL_I2CBUS
800
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
800 801
 
801 802
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/delta/generic/Configuration_adv.h View File

@@ -797,5 +797,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
797 797
 // @section i2cbus
798 798
 
799 799
 //#define EXPERIMENTAL_I2CBUS
800
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
800 801
 
801 802
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h View File

@@ -796,5 +796,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
796 796
 // @section i2cbus
797 797
 
798 798
 //#define EXPERIMENTAL_I2CBUS
799
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
799 800
 
800 801
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h View File

@@ -801,5 +801,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
801 801
 // @section i2cbus
802 802
 
803 803
 //#define EXPERIMENTAL_I2CBUS
804
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
804 805
 
805 806
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h View File

@@ -797,5 +797,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
797 797
 // @section i2cbus
798 798
 
799 799
 //#define EXPERIMENTAL_I2CBUS
800
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
800 801
 
801 802
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/makibox/Configuration_adv.h View File

@@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
795 795
 // @section i2cbus
796 796
 
797 797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798 799
 
799 800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h View File

@@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
795 795
 // @section i2cbus
796 796
 
797 797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798 799
 
799 800
 #endif // CONFIGURATION_ADV_H

+ 20
- 21
Marlin/twibus.cpp View File

@@ -29,25 +29,28 @@
29 29
 #include <Wire.h>
30 30
 
31 31
 TWIBus::TWIBus() {
32
-  Wire.begin(); // We use no address so we will join the BUS as the master
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
33 37
   this->reset();
34 38
 }
35 39
 
36 40
 void TWIBus::reset() {
37
-  this->addr = 0;
38 41
   this->buffer_s = 0;
39 42
   this->buffer[0] = 0x00;
40 43
 }
41 44
 
42
-void TWIBus::address(uint8_t addr) {
45
+void TWIBus::address(const uint8_t addr) {
43 46
   this->addr = addr;
44 47
 
45 48
   #if ENABLED(DEBUG_TWIBUS)
46
-    debug(PSTR("sendto"), this->addr);
49
+    debug(PSTR("address"), this->addr);
47 50
   #endif
48 51
 }
49 52
 
50
-void TWIBus::addbyte(char c) {
53
+void TWIBus::addbyte(const char c) {
51 54
   if (buffer_s >= sizeof(this->buffer)) return;
52 55
   this->buffer[this->buffer_s++] = c;
53 56
 
@@ -67,39 +70,35 @@ void TWIBus::send() {
67 70
   Wire.write(this->buffer, this->buffer_s);
68 71
   Wire.endTransmission();
69 72
 
70
-    // Reset the buffer after sending the data
73
+  // Reset the buffer after sending the data
71 74
   this->reset();
72 75
 }
73 76
 
74
-void TWIBus::reqbytes(uint8_t bytes) {
77
+void TWIBus::reqbytes(const uint8_t bytes) {
75 78
   if (!this->addr) return;
76 79
 
77 80
   #if ENABLED(DEBUG_TWIBUS)
78 81
     debug(PSTR("reqbytes"), bytes);
79 82
   #endif
80 83
 
84
+  // requestFrom() is a blocking function
81 85
   millis_t t = millis() + this->timeout;
82 86
   Wire.requestFrom(this->addr, bytes);
87
+  while (Wire.available() < bytes && PENDING(millis(), t)) { /*nada*/ }
83 88
 
84
-    // requestFrom() is a blocking function
85
-  while (Wire.available() < bytes) {
86
-    if (ELAPSED(millis(), t)) break;
87
-    else continue;
88
-  }
89
+  this->relaydata(bytes);
89 90
 
91
+  // Reset the buffer after sending the data
92
+  this->reset();
93
+}
94
+
95
+void TWIBus::relaydata(uint8_t bytes) {
90 96
   SERIAL_ECHO_START;
91 97
   SERIAL_ECHOPAIR("i2c-reply: from:", this->addr);
92
-  SERIAL_ECHOPAIR(" bytes:", Wire.available());
98
+  SERIAL_ECHOPAIR(" bytes:", bytes);
93 99
   SERIAL_ECHOPGM (" data:");
94
-
95
-    // Protect against buffer overflows if the number of received bytes
96
-    // is less than the number of requested bytes
97
-  uint8_t wba = Wire.available();
98
-  for (int i = 0; i < wba; i++) SERIAL_CHAR(Wire.read());
100
+  while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read());
99 101
   SERIAL_EOL;
100
-
101
-  // Reset the buffer after sending the data
102
-  this->reset();
103 102
 }
104 103
 
105 104
 #if ENABLED(DEBUG_TWIBUS)

+ 54
- 23
Marlin/twibus.h View File

@@ -25,9 +25,13 @@
25 25
 
26 26
 #include "macros.h"
27 27
 
28
+#include <Wire.h>
29
+
28 30
 // Print debug messages with M111 S2 (Uses 236 bytes of PROGMEM)
29 31
 //#define DEBUG_TWIBUS
30 32
 
33
+typedef void (*twiSlaveFunc_t)(int bytes);
34
+
31 35
 /**
32 36
  * TWIBUS class
33 37
  *
@@ -49,29 +53,28 @@ class TWIBus {
49 53
   private:
50 54
     /**
51 55
      * @brief Timeout value in milliseconds
52
-     * @details For blocking operations this constant value will set the max
53
-     * amount of time Marlin will keep waiting for a reply. Useful is something
54
-     * goes wrong on the bus and the SDA/SCL lines are held up by another device.
56
+     * @details Maximum amount of time (ms) to wait for a reply.
57
+     *          Useful if something goes wrong on the bus and the
58
+     *          SDA/SCL lines are held up by another device.
55 59
      */
56 60
     const int timeout = 5;
57 61
 
58 62
     /**
59 63
      * @brief Target device address
60
-     * @description This stores, until the buffer is flushed, the target device
61
-     * address, take not we do follow Arduino 7bit addressing.
64
+     * @description The target device address. Persists until changed.
65
+     *              
62 66
      */
63 67
     uint8_t addr = 0;
64 68
 
65 69
     /**
66 70
      * @brief Number of bytes on buffer
67
-     * @description This var holds the total number of bytes on our buffer
68
-     * waiting to be flushed to the bus.
71
+     * @description Number of bytes in the buffer waiting to be flushed to the bus.
69 72
      */
70 73
     uint8_t buffer_s = 0;
71 74
 
72 75
     /**
73 76
      * @brief Internal buffer
74
-     * @details This is a fixed buffer, TWI command cannot be longer than this
77
+     * @details A fixed buffer. TWI commands can be no longer than this.
75 78
      */
76 79
     char buffer[30];
77 80
 
@@ -79,49 +82,77 @@ class TWIBus {
79 82
   public:
80 83
     /**
81 84
      * @brief Class constructor
82
-     * @details Initialized the TWI bus and clears the buffer
85
+     * @details Initialize the TWI bus and clear the buffer
83 86
      */
84 87
     TWIBus();
85 88
 
86 89
     /**
87 90
      * @brief Reset the buffer
88
-     * @details Brings the internal buffer to a known-empty state
91
+     * @details Set the buffer to a known-empty state
89 92
      */
90 93
     void reset();
91 94
 
92 95
     /**
93 96
      * @brief Send the buffer data to the bus
94
-     * @details Flushed the buffer into the bus targeting the cached slave device
95
-     * address.
97
+     * @details Flush the buffer to the bus at the target address.
96 98
      */
97 99
     void send();
98 100
 
99 101
     /**
100 102
      * @brief Add one byte to the buffer
101
-     * @details Adds the byte to the buffer in a sequential way, if buffer is full
102
-     * the request is silently ignored.
103
+     * @details Add a byte to the end of the buffer.
104
+     *          Silently fails if the buffer is full.
103 105
      *
104 106
      * @param c a data byte
105 107
      */
106
-    void addbyte(char c);
108
+    void addbyte(const char c);
107 109
 
108 110
     /**
109
-     * @brief Sets the target slave address
110
-     * @details The target slave address is stored so it can be later used when
111
-     * the complete packet needs to be sent over the bus.
111
+     * @brief Set the target slave address
112
+     * @details The target slave address for sending the full packet.
112 113
      *
113 114
      * @param addr 7-bit integer address
114 115
      */
115
-    void address(uint8_t addr);
116
+    void address(const uint8_t addr);
117
+
118
+    /**
119
+     * @brief Request data from the slave device
120
+     * @details Request a number of bytes from a slave device.
121
+     *          This implementation simply sends the data to serial
122
+     *          in a parser-friendly format.
123
+     *
124
+     * @param bytes the number of bytes to request
125
+     */
126
+    void reqbytes(const uint8_t bytes);
116 127
 
117 128
     /**
118
-     * @brief Request data from slave device
119
-     * @details Requests data from a slave device, when the data is received it will
120
-     * be relayed to the serial line using a parser-friendly formatting.
129
+     * @brief Relay data from the slave device to serial
130
+     * @details Relay a number of bytes from the bus to
131
+     *          serial in a parser-friendly format.
121 132
      *
122 133
      * @param bytes the number of bytes to request
123 134
      */
124
-    void reqbytes(uint8_t bytes);
135
+    void relaydata(uint8_t bytes);
136
+
137
+    #if I2C_SLAVE_ADDRESS > 0
138
+
139
+      /**
140
+       * @brief Receive bytes (passively)
141
+       * @details Receive bytes sent to our slave address.
142
+       *          and simply echo them to serial.
143
+       */
144
+      inline void receive(uint8_t bytes) { relaydata(bytes); }
145
+
146
+      /**
147
+       * @brief Register a slave handler
148
+       * @details Set a handler to receive data from the bus,
149
+       *          so we can act as a slave.
150
+       *
151
+       * @param handler A function to handle receiving bytes
152
+       */
153
+      inline void onReceive(const twiSlaveFunc_t handler) { Wire.onReceive(handler); }
154
+
155
+    #endif
125 156
 
126 157
     #if ENABLED(DEBUG_TWIBUS)
127 158
 

Loading…
Cancel
Save