mirror of
https://github.com/0xFEEDC0DE64/arduino-esp32.git
synced 2025-07-02 21:41:01 +02:00
I2C Slave Implementation
This commit is contained in:
30
libraries/Wire/examples/WireMaster/WireMaster.ino
Normal file
30
libraries/Wire/examples/WireMaster/WireMaster.ino
Normal file
@ -0,0 +1,30 @@
|
||||
#include "Wire.h"
|
||||
|
||||
#define I2C_DEV_ADDR 0x55
|
||||
|
||||
uint32_t i = 0;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
Wire.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(5000);
|
||||
|
||||
//Write message to the slave
|
||||
Wire.beginTransmission(I2C_DEV_ADDR);
|
||||
Wire.printf("Hello World! %u", i++);
|
||||
uint8_t error = Wire.endTransmission(true);
|
||||
Serial.printf("endTransmission: %u\n", error);
|
||||
|
||||
//Read 16 bytes from the slave
|
||||
error = Wire.requestFrom(I2C_DEV_ADDR, 16);
|
||||
Serial.printf("requestFrom: %u\n", error);
|
||||
if(error){
|
||||
uint8_t temp[error];
|
||||
Wire.readBytes(temp, error);
|
||||
log_print_buf(temp, error);
|
||||
}
|
||||
}
|
28
libraries/Wire/examples/WireScan/WireScan.ino
Normal file
28
libraries/Wire/examples/WireScan/WireScan.ino
Normal file
@ -0,0 +1,28 @@
|
||||
#include "Wire.h"
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Wire.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
byte error, address;
|
||||
int nDevices = 0;
|
||||
|
||||
delay(5000);
|
||||
|
||||
Serial.println("Scanning for I2C devices ...");
|
||||
for(address = 0x01; address < 0x7f; address++){
|
||||
Wire.beginTransmission(address);
|
||||
error = Wire.endTransmission();
|
||||
if (error == 0){
|
||||
Serial.printf("I2C device found at address 0x%02X\n", address);
|
||||
nDevices++;
|
||||
} else if(error != 2){
|
||||
Serial.printf("Error %d at address 0x%02X\n", error, address);
|
||||
}
|
||||
}
|
||||
if (nDevices == 0){
|
||||
Serial.println("No I2C devices found");
|
||||
}
|
||||
}
|
37
libraries/Wire/examples/WireSlave/WireSlave.ino
Normal file
37
libraries/Wire/examples/WireSlave/WireSlave.ino
Normal file
@ -0,0 +1,37 @@
|
||||
#include "Wire.h"
|
||||
|
||||
#define I2C_DEV_ADDR 0x55
|
||||
|
||||
uint32_t i = 0;
|
||||
|
||||
void onRequest(){
|
||||
Wire.print(i++);
|
||||
Wire.print(" Packets.");
|
||||
Serial.println("onRequest");
|
||||
}
|
||||
|
||||
void onReceive(int len){
|
||||
Serial.printf("onReceive[%d]: ", len);
|
||||
while(Wire.available()){
|
||||
Serial.write(Wire.read());
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
Wire.onReceive(onReceive);
|
||||
Wire.onRequest(onRequest);
|
||||
Wire.begin((uint8_t)I2C_DEV_ADDR);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
char message[64];
|
||||
snprintf(message, 64, "%u Packets.", i++);
|
||||
Wire.slaveWrite((uint8_t *)message, strlen(message));
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
@ -30,6 +30,7 @@ extern "C" {
|
||||
}
|
||||
|
||||
#include "esp32-hal-i2c.h"
|
||||
#include "esp32-hal-i2c-slave.h"
|
||||
#include "Wire.h"
|
||||
#include "Arduino.h"
|
||||
|
||||
@ -47,6 +48,9 @@ TwoWire::TwoWire(uint8_t bus_num)
|
||||
,nonStopTask(NULL)
|
||||
,lock(NULL)
|
||||
#endif
|
||||
,is_slave(false)
|
||||
,user_onRequest(NULL)
|
||||
,user_onReceive(NULL)
|
||||
{}
|
||||
|
||||
TwoWire::~TwoWire()
|
||||
@ -402,5 +406,102 @@ uint8_t TwoWire::endTransmission(void)
|
||||
return endTransmission(true);
|
||||
}
|
||||
|
||||
bool TwoWire::begin(uint8_t addr, int sdaPin, int sclPin, uint32_t frequency)
|
||||
{
|
||||
if(!frequency){
|
||||
frequency = 100000;
|
||||
} else if(frequency > 1000000){
|
||||
frequency = 1000000;
|
||||
}
|
||||
|
||||
if(sdaPin < 0) { // default param passed
|
||||
if(num == 0) {
|
||||
if(sda==-1) {
|
||||
sdaPin = SDA; //use Default Pin
|
||||
} else {
|
||||
sdaPin = sda; // reuse prior pin
|
||||
}
|
||||
} else {
|
||||
if(sda==-1) {
|
||||
log_e("no Default SDA Pin for Second Peripheral");
|
||||
return false; //no Default pin for Second Peripheral
|
||||
} else {
|
||||
sdaPin = sda; // reuse prior pin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(sclPin < 0) { // default param passed
|
||||
if(num == 0) {
|
||||
if(scl == -1) {
|
||||
sclPin = SCL; // use Default pin
|
||||
} else {
|
||||
sclPin = scl; // reuse prior pin
|
||||
}
|
||||
} else {
|
||||
if(scl == -1) {
|
||||
log_e("no Default SCL Pin for Second Peripheral");
|
||||
return false; //no Default pin for Second Peripheral
|
||||
} else {
|
||||
sclPin = scl; // reuse prior pin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sda = sdaPin;
|
||||
scl = sclPin;
|
||||
i2c_slave_attach_callbacks(num, onRequestService, onReceiveService, this);
|
||||
if(i2c_slave_init(num, sda, scl, addr, frequency, I2C_BUFFER_LENGTH, I2C_BUFFER_LENGTH) != ESP_OK){
|
||||
Serial.println("INIT ERROR");
|
||||
return false;
|
||||
}
|
||||
is_slave = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t TwoWire::slaveWrite(const uint8_t * buffer, size_t len)
|
||||
{
|
||||
return i2c_slave_write(num, buffer, len, _timeOutMillis);
|
||||
}
|
||||
|
||||
void TwoWire::onReceiveService(uint8_t num, uint8_t* inBytes, size_t numBytes, bool stop, void * arg)
|
||||
{
|
||||
TwoWire * wire = (TwoWire*)arg;
|
||||
if(!wire->user_onReceive){
|
||||
return;
|
||||
}
|
||||
for(uint8_t i = 0; i < numBytes; ++i){
|
||||
wire->rxBuffer[i] = inBytes[i];
|
||||
}
|
||||
wire->rxIndex = 0;
|
||||
wire->rxLength = numBytes;
|
||||
wire->user_onReceive(numBytes);
|
||||
}
|
||||
|
||||
void TwoWire::onRequestService(uint8_t num, void * arg)
|
||||
{
|
||||
TwoWire * wire = (TwoWire*)arg;
|
||||
if(!wire->user_onRequest){
|
||||
return;
|
||||
}
|
||||
wire->txLength = 0;
|
||||
wire->user_onRequest();
|
||||
if(wire->txLength){
|
||||
wire->slaveWrite((uint8_t*)wire->txBuffer, wire->txLength);
|
||||
}
|
||||
}
|
||||
|
||||
void TwoWire::onReceive( void (*function)(int) )
|
||||
{
|
||||
user_onReceive = function;
|
||||
}
|
||||
|
||||
// sets function called on slave read
|
||||
void TwoWire::onRequest( void (*function)(void) )
|
||||
{
|
||||
user_onRequest = function;
|
||||
}
|
||||
|
||||
|
||||
TwoWire Wire = TwoWire(0);
|
||||
TwoWire Wire1 = TwoWire(1);
|
||||
|
@ -61,6 +61,12 @@ protected:
|
||||
TaskHandle_t nonStopTask;
|
||||
SemaphoreHandle_t lock;
|
||||
#endif
|
||||
private:
|
||||
bool is_slave;
|
||||
void (*user_onRequest)(void);
|
||||
void (*user_onReceive)(int);
|
||||
static void onRequestService(uint8_t, void *);
|
||||
static void onReceiveService(uint8_t, uint8_t*, size_t, bool, void *);
|
||||
|
||||
public:
|
||||
TwoWire(uint8_t bus_num);
|
||||
@ -70,6 +76,7 @@ public:
|
||||
bool setPins(int sda, int scl);
|
||||
|
||||
bool begin(int sda=-1, int scl=-1, uint32_t frequency=0); // returns true, if successful init of i2c bus
|
||||
bool begin(uint8_t slaveAddr, int sda=-1, int scl=-1, uint32_t frequency=0);
|
||||
bool end();
|
||||
|
||||
void setTimeOut(uint16_t timeOutMillis); // default timeout of i2c transactions is 50ms
|
||||
@ -123,6 +130,7 @@ public:
|
||||
|
||||
void onReceive( void (*)(int) );
|
||||
void onRequest( void (*)(void) );
|
||||
size_t slaveWrite(const uint8_t *, size_t);
|
||||
};
|
||||
|
||||
extern TwoWire Wire;
|
||||
|
Reference in New Issue
Block a user