Skip to content

I2c reset functionality #678

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions cores/esp32/esp32-hal-i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "rom/ets_sys.h"
#include "driver/periph_ctrl.h"
#include "soc/i2c_reg.h"
#include "soc/i2c_struct.h"
#include "soc/dport_reg.h"
Expand Down Expand Up @@ -154,6 +155,13 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat

I2C_MUTEX_LOCK();

if (i2c->dev->status_reg.bus_busy == 1)
{
//log_w( "Busy Timeout! Addr: %x", address >> 1 );
I2C_MUTEX_UNLOCK();
return I2C_ERROR_BUSY;
}

while(dataLen) {
uint8_t willSend = (dataLen > 32)?32:dataLen;
uint8_t dataSend = willSend;
Expand Down Expand Up @@ -221,7 +229,7 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat
//Transmission did not finish and ACK_ERR is set
if(i2c->dev->int_raw.ack_err) {
//log_w("Ack Error! Addr: %x", address >> 1);
while(i2c->dev->status_reg.bus_busy);
while((i2c->dev->status_reg.bus_busy) && ((millis() - startAt)>50));
I2C_MUTEX_UNLOCK();
return I2C_ERROR_ACK;
}
Expand Down Expand Up @@ -250,6 +258,13 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data

I2C_MUTEX_LOCK();

if (i2c->dev->status_reg.bus_busy == 1)
{
//log_w( "Busy Timeout! Addr: %x", address >> 1 );
I2C_MUTEX_UNLOCK();
return I2C_ERROR_BUSY;
}

i2cResetFiFo(i2c);
i2cResetCmd(i2c);

Expand Down Expand Up @@ -445,7 +460,25 @@ void i2cInitFix(i2c_t * i2c){
i2c->dev->fifo_data.data = 0;
i2cSetCmd(i2c, 1, I2C_CMD_WRITE, 1, false, false, false);
i2cSetCmd(i2c, 2, I2C_CMD_STOP, 0, false, false, false);
if (i2c->dev->status_reg.bus_busy) // If this condition is true, the while loop will timeout as done will not be set
{
//log_e("Busy at initialization!");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe leave the error uncommented? otherwise what is the point of the check? :P

Copy link
Contributor Author

@lonerzzz lonerzzz Sep 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that you commented means it served its point. :) I left it commented out since I wanted to highlight where the error comes into play and because of the fact most errors don't have error logging enabled in the read and write methods so was unsure when we want to show and not show.

I can certainly add it with any others we think should be there.

Any other concerns?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can uncomment the logs, since when I wrote it there was no way to control the log level :P now there is :)

i2c->dev->ctr.trans_start = 1;
while(!i2c->dev->command[2].done);
uint16_t count = 50000;
while ((!i2c->dev->command[2].done) && (--count > 0));
I2C_MUTEX_UNLOCK();
}

void i2cReset(i2c_t* i2c){
if(i2c == NULL){
return;
}
I2C_MUTEX_LOCK();
periph_module_t moduleId = (i2c == &_i2c_bus_array[0])?PERIPH_I2C0_MODULE:PERIPH_I2C1_MODULE;
periph_module_disable( moduleId );
delay( 20 ); // Seems long but delay was chosen to ensure system teardown and setup without core generation
periph_module_enable( moduleId );
I2C_MUTEX_UNLOCK();
}

4 changes: 3 additions & 1 deletion cores/esp32/esp32-hal-i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ typedef enum {
I2C_ERROR_DEV,
I2C_ERROR_ACK,
I2C_ERROR_TIMEOUT,
I2C_ERROR_BUS
I2C_ERROR_BUS,
I2C_ERROR_BUSY
} i2c_err_t;

struct i2c_struct_t;
Expand All @@ -50,6 +51,7 @@ i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda);
i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop);
i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop);

void i2cReset(i2c_t* i2c);

#ifdef __cplusplus
}
Expand Down
7 changes: 7 additions & 0 deletions libraries/Wire/src/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,4 +211,11 @@ void TwoWire::flush(void)
txLength = 0;
}

void TwoWire::reset(void)
{
i2cReset( i2c );
i2c = NULL;
begin( sda, scl );
}

TwoWire Wire = TwoWire(0);
2 changes: 2 additions & 0 deletions libraries/Wire/src/Wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ class TwoWire: public Stream
int peek(void);
void flush(void);

void reset(void);

inline size_t write(const char * s)
{
return write((uint8_t*) s, strlen(s));
Expand Down