Add support for i2c slave address
This commit is contained in:
parent
58c8e6cef2
commit
a99ecf71d8
@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -835,6 +835,14 @@ void servo_init() {
|
|||||||
void enableStepperDrivers() { pinMode(STEPPER_RESET_PIN, INPUT); } // set to input, which allows it to be pulled high by pullups
|
void enableStepperDrivers() { pinMode(STEPPER_RESET_PIN, INPUT); } // set to input, which allows it to be pulled high by pullups
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
|
||||||
|
|
||||||
|
void i2c_listener(int bytes) {
|
||||||
|
i2c.receive(bytes); // just echo all bytes received to serial
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marlin entry-point: Set up before the program loop
|
* Marlin entry-point: Set up before the program loop
|
||||||
* - Set up the kill pin, filament runout, power hold
|
* - Set up the kill pin, filament runout, power hold
|
||||||
@ -981,6 +989,10 @@ void setup() {
|
|||||||
for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
|
for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
|
||||||
mixing_virtual_tool_mix[t][i] = mixing_factor[i];
|
mixing_virtual_tool_mix[t][i] = mixing_factor[i];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
|
||||||
|
i2c.onReceive(i2c_listener);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -801,5 +801,6 @@ const unsigned int dropsegments = 2; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -803,5 +803,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -797,5 +797,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -797,5 +797,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -796,5 +796,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -801,5 +801,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -797,5 +797,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -795,5 +795,6 @@ const unsigned int dropsegments = 5; //everything with less than this number of
|
|||||||
// @section i2cbus
|
// @section i2cbus
|
||||||
|
|
||||||
//#define EXPERIMENTAL_I2CBUS
|
//#define EXPERIMENTAL_I2CBUS
|
||||||
|
#define I2C_SLAVE_ADDRESS 0 // Set non-zero to act as a slave
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
@ -29,25 +29,28 @@
|
|||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
|
|
||||||
TWIBus::TWIBus() {
|
TWIBus::TWIBus() {
|
||||||
Wire.begin(); // We use no address so we will join the BUS as the master
|
#if I2C_SLAVE_ADDRESS == 0
|
||||||
|
Wire.begin(); // No address joins the BUS as the master
|
||||||
|
#else
|
||||||
|
Wire.begin(I2C_SLAVE_ADDRESS); // Join the bus as a slave
|
||||||
|
#endif
|
||||||
this->reset();
|
this->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TWIBus::reset() {
|
void TWIBus::reset() {
|
||||||
this->addr = 0;
|
|
||||||
this->buffer_s = 0;
|
this->buffer_s = 0;
|
||||||
this->buffer[0] = 0x00;
|
this->buffer[0] = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TWIBus::address(uint8_t addr) {
|
void TWIBus::address(const uint8_t addr) {
|
||||||
this->addr = addr;
|
this->addr = addr;
|
||||||
|
|
||||||
#if ENABLED(DEBUG_TWIBUS)
|
#if ENABLED(DEBUG_TWIBUS)
|
||||||
debug(PSTR("sendto"), this->addr);
|
debug(PSTR("address"), this->addr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TWIBus::addbyte(char c) {
|
void TWIBus::addbyte(const char c) {
|
||||||
if (buffer_s >= sizeof(this->buffer)) return;
|
if (buffer_s >= sizeof(this->buffer)) return;
|
||||||
this->buffer[this->buffer_s++] = c;
|
this->buffer[this->buffer_s++] = c;
|
||||||
|
|
||||||
@ -67,41 +70,37 @@ void TWIBus::send() {
|
|||||||
Wire.write(this->buffer, this->buffer_s);
|
Wire.write(this->buffer, this->buffer_s);
|
||||||
Wire.endTransmission();
|
Wire.endTransmission();
|
||||||
|
|
||||||
// Reset the buffer after sending the data
|
// Reset the buffer after sending the data
|
||||||
this->reset();
|
this->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TWIBus::reqbytes(uint8_t bytes) {
|
void TWIBus::reqbytes(const uint8_t bytes) {
|
||||||
if (!this->addr) return;
|
if (!this->addr) return;
|
||||||
|
|
||||||
#if ENABLED(DEBUG_TWIBUS)
|
#if ENABLED(DEBUG_TWIBUS)
|
||||||
debug(PSTR("reqbytes"), bytes);
|
debug(PSTR("reqbytes"), bytes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// requestFrom() is a blocking function
|
||||||
millis_t t = millis() + this->timeout;
|
millis_t t = millis() + this->timeout;
|
||||||
Wire.requestFrom(this->addr, bytes);
|
Wire.requestFrom(this->addr, bytes);
|
||||||
|
while (Wire.available() < bytes && PENDING(millis(), t)) { /*nada*/ }
|
||||||
|
|
||||||
// requestFrom() is a blocking function
|
this->relaydata(bytes);
|
||||||
while (Wire.available() < bytes) {
|
|
||||||
if (ELAPSED(millis(), t)) break;
|
|
||||||
else continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SERIAL_ECHO_START;
|
|
||||||
SERIAL_ECHOPAIR("i2c-reply: from:", this->addr);
|
|
||||||
SERIAL_ECHOPAIR(" bytes:", Wire.available());
|
|
||||||
SERIAL_ECHOPGM (" data:");
|
|
||||||
|
|
||||||
// Protect against buffer overflows if the number of received bytes
|
|
||||||
// is less than the number of requested bytes
|
|
||||||
uint8_t wba = Wire.available();
|
|
||||||
for (int i = 0; i < wba; i++) SERIAL_CHAR(Wire.read());
|
|
||||||
SERIAL_EOL;
|
|
||||||
|
|
||||||
// Reset the buffer after sending the data
|
// Reset the buffer after sending the data
|
||||||
this->reset();
|
this->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TWIBus::relaydata(uint8_t bytes) {
|
||||||
|
SERIAL_ECHO_START;
|
||||||
|
SERIAL_ECHOPAIR("i2c-reply: from:", this->addr);
|
||||||
|
SERIAL_ECHOPAIR(" bytes:", bytes);
|
||||||
|
SERIAL_ECHOPGM (" data:");
|
||||||
|
while (bytes-- && Wire.available()) SERIAL_CHAR(Wire.read());
|
||||||
|
SERIAL_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
#if ENABLED(DEBUG_TWIBUS)
|
#if ENABLED(DEBUG_TWIBUS)
|
||||||
|
|
||||||
void TWIBus::debug(const char func[], int32_t val/*=-1*/) {
|
void TWIBus::debug(const char func[], int32_t val/*=-1*/) {
|
||||||
|
@ -25,9 +25,13 @@
|
|||||||
|
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
// Print debug messages with M111 S2 (Uses 236 bytes of PROGMEM)
|
// Print debug messages with M111 S2 (Uses 236 bytes of PROGMEM)
|
||||||
//#define DEBUG_TWIBUS
|
//#define DEBUG_TWIBUS
|
||||||
|
|
||||||
|
typedef void (*twiSlaveFunc_t)(int bytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TWIBUS class
|
* TWIBUS class
|
||||||
*
|
*
|
||||||
@ -49,29 +53,28 @@ class TWIBus {
|
|||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Timeout value in milliseconds
|
* @brief Timeout value in milliseconds
|
||||||
* @details For blocking operations this constant value will set the max
|
* @details Maximum amount of time (ms) to wait for a reply.
|
||||||
* amount of time Marlin will keep waiting for a reply. Useful is something
|
* Useful if something goes wrong on the bus and the
|
||||||
* goes wrong on the bus and the SDA/SCL lines are held up by another device.
|
* SDA/SCL lines are held up by another device.
|
||||||
*/
|
*/
|
||||||
const int timeout = 5;
|
const int timeout = 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Target device address
|
* @brief Target device address
|
||||||
* @description This stores, until the buffer is flushed, the target device
|
* @description The target device address. Persists until changed.
|
||||||
* address, take not we do follow Arduino 7bit addressing.
|
*
|
||||||
*/
|
*/
|
||||||
uint8_t addr = 0;
|
uint8_t addr = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Number of bytes on buffer
|
* @brief Number of bytes on buffer
|
||||||
* @description This var holds the total number of bytes on our buffer
|
* @description Number of bytes in the buffer waiting to be flushed to the bus.
|
||||||
* waiting to be flushed to the bus.
|
|
||||||
*/
|
*/
|
||||||
uint8_t buffer_s = 0;
|
uint8_t buffer_s = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Internal buffer
|
* @brief Internal buffer
|
||||||
* @details This is a fixed buffer, TWI command cannot be longer than this
|
* @details A fixed buffer. TWI commands can be no longer than this.
|
||||||
*/
|
*/
|
||||||
char buffer[30];
|
char buffer[30];
|
||||||
|
|
||||||
@ -79,49 +82,77 @@ class TWIBus {
|
|||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Class constructor
|
* @brief Class constructor
|
||||||
* @details Initialized the TWI bus and clears the buffer
|
* @details Initialize the TWI bus and clear the buffer
|
||||||
*/
|
*/
|
||||||
TWIBus();
|
TWIBus();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reset the buffer
|
* @brief Reset the buffer
|
||||||
* @details Brings the internal buffer to a known-empty state
|
* @details Set the buffer to a known-empty state
|
||||||
*/
|
*/
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send the buffer data to the bus
|
* @brief Send the buffer data to the bus
|
||||||
* @details Flushed the buffer into the bus targeting the cached slave device
|
* @details Flush the buffer to the bus at the target address.
|
||||||
* address.
|
|
||||||
*/
|
*/
|
||||||
void send();
|
void send();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add one byte to the buffer
|
* @brief Add one byte to the buffer
|
||||||
* @details Adds the byte to the buffer in a sequential way, if buffer is full
|
* @details Add a byte to the end of the buffer.
|
||||||
* the request is silently ignored.
|
* Silently fails if the buffer is full.
|
||||||
*
|
*
|
||||||
* @param c a data byte
|
* @param c a data byte
|
||||||
*/
|
*/
|
||||||
void addbyte(char c);
|
void addbyte(const char c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the target slave address
|
* @brief Set the target slave address
|
||||||
* @details The target slave address is stored so it can be later used when
|
* @details The target slave address for sending the full packet.
|
||||||
* the complete packet needs to be sent over the bus.
|
|
||||||
*
|
*
|
||||||
* @param addr 7-bit integer address
|
* @param addr 7-bit integer address
|
||||||
*/
|
*/
|
||||||
void address(uint8_t addr);
|
void address(const uint8_t addr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Request data from slave device
|
* @brief Request data from the slave device
|
||||||
* @details Requests data from a slave device, when the data is received it will
|
* @details Request a number of bytes from a slave device.
|
||||||
* be relayed to the serial line using a parser-friendly formatting.
|
* This implementation simply sends the data to serial
|
||||||
|
* in a parser-friendly format.
|
||||||
*
|
*
|
||||||
* @param bytes the number of bytes to request
|
* @param bytes the number of bytes to request
|
||||||
*/
|
*/
|
||||||
void reqbytes(uint8_t bytes);
|
void reqbytes(const uint8_t bytes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Relay data from the slave device to serial
|
||||||
|
* @details Relay a number of bytes from the bus to
|
||||||
|
* serial in a parser-friendly format.
|
||||||
|
*
|
||||||
|
* @param bytes the number of bytes to request
|
||||||
|
*/
|
||||||
|
void relaydata(uint8_t bytes);
|
||||||
|
|
||||||
|
#if I2C_SLAVE_ADDRESS > 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Receive bytes (passively)
|
||||||
|
* @details Receive bytes sent to our slave address.
|
||||||
|
* and simply echo them to serial.
|
||||||
|
*/
|
||||||
|
inline void receive(uint8_t bytes) { relaydata(bytes); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register a slave handler
|
||||||
|
* @details Set a handler to receive data from the bus,
|
||||||
|
* so we can act as a slave.
|
||||||
|
*
|
||||||
|
* @param handler A function to handle receiving bytes
|
||||||
|
*/
|
||||||
|
inline void onReceive(const twiSlaveFunc_t handler) { Wire.onReceive(handler); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(DEBUG_TWIBUS)
|
#if ENABLED(DEBUG_TWIBUS)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user