瀏覽代碼

Add support for i2c slave address

Scott Lahteine 8 年之前
父節點
當前提交
a99ecf71d8

+ 1
- 0
Marlin/Configuration_adv.h 查看文件

795
 // @section i2cbus
795
 // @section i2cbus
796
 
796
 
797
 //#define EXPERIMENTAL_I2CBUS
797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798
 
799
 
799
 #endif // CONFIGURATION_ADV_H
800
 #endif // CONFIGURATION_ADV_H

+ 12
- 0
Marlin/Marlin_main.cpp 查看文件

835
   void enableStepperDrivers() { pinMode(STEPPER_RESET_PIN, INPUT); }  // set to input, which allows it to be pulled high by pullups
835
   void enableStepperDrivers() { pinMode(STEPPER_RESET_PIN, INPUT); }  // set to input, which allows it to be pulled high by pullups
836
 #endif
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
  * Marlin entry-point: Set up before the program loop
847
  * Marlin entry-point: Set up before the program loop
840
  *  - Set up the kill pin, filament runout, power hold
848
  *  - Set up the kill pin, filament runout, power hold
981
       for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
989
       for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
982
         mixing_virtual_tool_mix[t][i] = mixing_factor[i];
990
         mixing_virtual_tool_mix[t][i] = mixing_factor[i];
983
   #endif
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 查看文件

795
 // @section i2cbus
795
 // @section i2cbus
796
 
796
 
797
 //#define EXPERIMENTAL_I2CBUS
797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798
 
799
 
799
 #endif // CONFIGURATION_ADV_H
800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/Felix/Configuration_adv.h 查看文件

795
 // @section i2cbus
795
 // @section i2cbus
796
 
796
 
797
 //#define EXPERIMENTAL_I2CBUS
797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798
 
799
 
799
 #endif // CONFIGURATION_ADV_H
800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/Hephestos/Configuration_adv.h 查看文件

795
 // @section i2cbus
795
 // @section i2cbus
796
 
796
 
797
 //#define EXPERIMENTAL_I2CBUS
797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798
 
799
 
799
 #endif // CONFIGURATION_ADV_H
800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/Hephestos_2/Configuration_adv.h 查看文件

795
 // @section i2cbus
795
 // @section i2cbus
796
 
796
 
797
 //#define EXPERIMENTAL_I2CBUS
797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798
 
799
 
799
 #endif // CONFIGURATION_ADV_H
800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/K8200/Configuration_adv.h 查看文件

801
 // @section i2cbus
801
 // @section i2cbus
802
 
802
 
803
 //#define EXPERIMENTAL_I2CBUS
803
 //#define EXPERIMENTAL_I2CBUS
804
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
804
 
805
 
805
 #endif // CONFIGURATION_ADV_H
806
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/K8400/Configuration_adv.h 查看文件

795
 // @section i2cbus
795
 // @section i2cbus
796
 
796
 
797
 //#define EXPERIMENTAL_I2CBUS
797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798
 
799
 
799
 #endif // CONFIGURATION_ADV_H
800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/RigidBot/Configuration_adv.h 查看文件

795
 // @section i2cbus
795
 // @section i2cbus
796
 
796
 
797
 //#define EXPERIMENTAL_I2CBUS
797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798
 
799
 
799
 #endif // CONFIGURATION_ADV_H
800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/SCARA/Configuration_adv.h 查看文件

795
 // @section i2cbus
795
 // @section i2cbus
796
 
796
 
797
 //#define EXPERIMENTAL_I2CBUS
797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798
 
799
 
799
 #endif // CONFIGURATION_ADV_H
800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/TAZ4/Configuration_adv.h 查看文件

803
 // @section i2cbus
803
 // @section i2cbus
804
 
804
 
805
 //#define EXPERIMENTAL_I2CBUS
805
 //#define EXPERIMENTAL_I2CBUS
806
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
806
 
807
 
807
 #endif // CONFIGURATION_ADV_H
808
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/WITBOX/Configuration_adv.h 查看文件

795
 // @section i2cbus
795
 // @section i2cbus
796
 
796
 
797
 //#define EXPERIMENTAL_I2CBUS
797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798
 
799
 
799
 #endif // CONFIGURATION_ADV_H
800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/delta/biv2.5/Configuration_adv.h 查看文件

797
 // @section i2cbus
797
 // @section i2cbus
798
 
798
 
799
 //#define EXPERIMENTAL_I2CBUS
799
 //#define EXPERIMENTAL_I2CBUS
800
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
800
 
801
 
801
 #endif // CONFIGURATION_ADV_H
802
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/delta/generic/Configuration_adv.h 查看文件

797
 // @section i2cbus
797
 // @section i2cbus
798
 
798
 
799
 //#define EXPERIMENTAL_I2CBUS
799
 //#define EXPERIMENTAL_I2CBUS
800
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
800
 
801
 
801
 #endif // CONFIGURATION_ADV_H
802
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h 查看文件

796
 // @section i2cbus
796
 // @section i2cbus
797
 
797
 
798
 //#define EXPERIMENTAL_I2CBUS
798
 //#define EXPERIMENTAL_I2CBUS
799
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
799
 
800
 
800
 #endif // CONFIGURATION_ADV_H
801
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h 查看文件

801
 // @section i2cbus
801
 // @section i2cbus
802
 
802
 
803
 //#define EXPERIMENTAL_I2CBUS
803
 //#define EXPERIMENTAL_I2CBUS
804
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
804
 
805
 
805
 #endif // CONFIGURATION_ADV_H
806
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h 查看文件

797
 // @section i2cbus
797
 // @section i2cbus
798
 
798
 
799
 //#define EXPERIMENTAL_I2CBUS
799
 //#define EXPERIMENTAL_I2CBUS
800
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
800
 
801
 
801
 #endif // CONFIGURATION_ADV_H
802
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/makibox/Configuration_adv.h 查看文件

795
 // @section i2cbus
795
 // @section i2cbus
796
 
796
 
797
 //#define EXPERIMENTAL_I2CBUS
797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798
 
799
 
799
 #endif // CONFIGURATION_ADV_H
800
 #endif // CONFIGURATION_ADV_H

+ 1
- 0
Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h 查看文件

795
 // @section i2cbus
795
 // @section i2cbus
796
 
796
 
797
 //#define EXPERIMENTAL_I2CBUS
797
 //#define EXPERIMENTAL_I2CBUS
798
+#define I2C_SLAVE_ADDRESS  0 // Set non-zero to act as a slave
798
 
799
 
799
 #endif // CONFIGURATION_ADV_H
800
 #endif // CONFIGURATION_ADV_H

+ 20
- 21
Marlin/twibus.cpp 查看文件

29
 #include <Wire.h>
29
 #include <Wire.h>
30
 
30
 
31
 TWIBus::TWIBus() {
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
   this->reset();
37
   this->reset();
34
 }
38
 }
35
 
39
 
36
 void TWIBus::reset() {
40
 void TWIBus::reset() {
37
-  this->addr = 0;
38
   this->buffer_s = 0;
41
   this->buffer_s = 0;
39
   this->buffer[0] = 0x00;
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
   this->addr = addr;
46
   this->addr = addr;
44
 
47
 
45
   #if ENABLED(DEBUG_TWIBUS)
48
   #if ENABLED(DEBUG_TWIBUS)
46
-    debug(PSTR("sendto"), this->addr);
49
+    debug(PSTR("address"), this->addr);
47
   #endif
50
   #endif
48
 }
51
 }
49
 
52
 
50
-void TWIBus::addbyte(char c) {
53
+void TWIBus::addbyte(const char c) {
51
   if (buffer_s >= sizeof(this->buffer)) return;
54
   if (buffer_s >= sizeof(this->buffer)) return;
52
   this->buffer[this->buffer_s++] = c;
55
   this->buffer[this->buffer_s++] = c;
53
 
56
 
67
   Wire.write(this->buffer, this->buffer_s);
70
   Wire.write(this->buffer, this->buffer_s);
68
   Wire.endTransmission();
71
   Wire.endTransmission();
69
 
72
 
70
-    // Reset the buffer after sending the data
73
+  // Reset the buffer after sending the data
71
   this->reset();
74
   this->reset();
72
 }
75
 }
73
 
76
 
74
-void TWIBus::reqbytes(uint8_t bytes) {
77
+void TWIBus::reqbytes(const uint8_t bytes) {
75
   if (!this->addr) return;
78
   if (!this->addr) return;
76
 
79
 
77
   #if ENABLED(DEBUG_TWIBUS)
80
   #if ENABLED(DEBUG_TWIBUS)
78
     debug(PSTR("reqbytes"), bytes);
81
     debug(PSTR("reqbytes"), bytes);
79
   #endif
82
   #endif
80
 
83
 
84
+  // requestFrom() is a blocking function
81
   millis_t t = millis() + this->timeout;
85
   millis_t t = millis() + this->timeout;
82
   Wire.requestFrom(this->addr, bytes);
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
   SERIAL_ECHO_START;
96
   SERIAL_ECHO_START;
91
   SERIAL_ECHOPAIR("i2c-reply: from:", this->addr);
97
   SERIAL_ECHOPAIR("i2c-reply: from:", this->addr);
92
-  SERIAL_ECHOPAIR(" bytes:", Wire.available());
98
+  SERIAL_ECHOPAIR(" bytes:", bytes);
93
   SERIAL_ECHOPGM (" data:");
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
   SERIAL_EOL;
101
   SERIAL_EOL;
100
-
101
-  // Reset the buffer after sending the data
102
-  this->reset();
103
 }
102
 }
104
 
103
 
105
 #if ENABLED(DEBUG_TWIBUS)
104
 #if ENABLED(DEBUG_TWIBUS)

+ 54
- 23
Marlin/twibus.h 查看文件

25
 
25
 
26
 #include "macros.h"
26
 #include "macros.h"
27
 
27
 
28
+#include <Wire.h>
29
+
28
 // Print debug messages with M111 S2 (Uses 236 bytes of PROGMEM)
30
 // Print debug messages with M111 S2 (Uses 236 bytes of PROGMEM)
29
 //#define DEBUG_TWIBUS
31
 //#define DEBUG_TWIBUS
30
 
32
 
33
+typedef void (*twiSlaveFunc_t)(int bytes);
34
+
31
 /**
35
 /**
32
  * TWIBUS class
36
  * TWIBUS class
33
  *
37
  *
49
   private:
53
   private:
50
     /**
54
     /**
51
      * @brief Timeout value in milliseconds
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
     const int timeout = 5;
60
     const int timeout = 5;
57
 
61
 
58
     /**
62
     /**
59
      * @brief Target device address
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
     uint8_t addr = 0;
67
     uint8_t addr = 0;
64
 
68
 
65
     /**
69
     /**
66
      * @brief Number of bytes on buffer
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
     uint8_t buffer_s = 0;
73
     uint8_t buffer_s = 0;
71
 
74
 
72
     /**
75
     /**
73
      * @brief Internal buffer
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
     char buffer[30];
79
     char buffer[30];
77
 
80
 
79
   public:
82
   public:
80
     /**
83
     /**
81
      * @brief Class constructor
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
     TWIBus();
87
     TWIBus();
85
 
88
 
86
     /**
89
     /**
87
      * @brief Reset the buffer
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
     void reset();
93
     void reset();
91
 
94
 
92
     /**
95
     /**
93
      * @brief Send the buffer data to the bus
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
     void send();
99
     void send();
98
 
100
 
99
     /**
101
     /**
100
      * @brief Add one byte to the buffer
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
      * @param c a data byte
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
      * @param addr 7-bit integer address
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
      * @param bytes the number of bytes to request
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
     #if ENABLED(DEBUG_TWIBUS)
157
     #if ENABLED(DEBUG_TWIBUS)
127
 
158
 

Loading…
取消
儲存