1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-16 01:53:51 +01:00

cpu/esp8266: periph/i2c fix

This commit is contained in:
Schorcht 2018-09-27 17:48:20 +02:00
parent c4016fcf3b
commit 6307ace126

View File

@ -53,8 +53,8 @@
extern uint8_t system_get_cpu_freq(void);
extern bool system_update_cpu_freq(uint8_t freq);
/* max clock stretching counter */
#define I2C_CLOCK_STRETCH 400
/* max clock stretching counter (ca. 10 ms) */
#define I2C_CLOCK_STRETCH 40000
typedef struct
{
@ -128,9 +128,9 @@ static int _i2c_read_bit (_i2c_bus_t* bus, bool* bit);
static int _i2c_write_byte (_i2c_bus_t* bus, uint8_t byte);
static int _i2c_read_byte (_i2c_bus_t* bus, uint8_t* byte, bool ack);
static int _i2c_arbitration_lost (_i2c_bus_t* bus, const char* func);
static void _i2c_abort (_i2c_bus_t* bus, const char* func);
/* implementation of i2c interface */
void i2c_init(i2c_t dev)
{
if (I2C_NUMOF != sizeof(_i2c_bus)/sizeof(_i2c_bus_t)) {
@ -217,12 +217,16 @@ int /* IRAM */ i2c_read_bytes(i2c_t dev, uint16_t addr, void *data, size_t len,
/* send address bytes wit read flag */
if ((res = _i2c_write_byte (bus, addr1)) != 0 ||
(res = _i2c_write_byte (bus, addr2)) != 0) {
/* abort transfer */
_i2c_abort (bus, __func__);
return res;
}
}
else {
/* send address byte with read flag */
if ((res = _i2c_write_byte (bus, (addr << 1 | I2C_READ))) != 0) {
/* abort transfer */
_i2c_abort (bus, __func__);
return res;
}
}
@ -231,7 +235,9 @@ int /* IRAM */ i2c_read_bytes(i2c_t dev, uint16_t addr, void *data, size_t len,
/* receive bytes if send address was successful */
for (unsigned int i = 0; i < len; i++) {
if ((res = _i2c_read_byte (bus, &(((uint8_t*)data)[i]), i < len-1)) != 0) {
break;
/* abort transfer */
_i2c_abort (bus, __func__);
return res;
}
}
@ -272,12 +278,16 @@ int /* IRAM */ i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data, size_
/* send address bytes without read flag */
if ((res = _i2c_write_byte (bus, addr1)) != 0 ||
(res = _i2c_write_byte (bus, addr2)) != 0) {
/* abort transfer */
_i2c_abort (bus, __func__);
return res;
}
}
else {
/* send address byte without read flag */
if ((res = _i2c_write_byte (bus, addr << 1)) != 0) {
/* abort transfer */
_i2c_abort (bus, __func__);
return res;
}
}
@ -286,7 +296,9 @@ int /* IRAM */ i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data, size_
/* send bytes if send address was successful */
for (unsigned int i = 0; i < len; i++) {
if ((res = _i2c_write_byte (bus, ((uint8_t*)data)[i])) != 0) {
break;
/* abort transfer */
_i2c_abort (bus, __func__);
return res;
}
}
@ -372,6 +384,18 @@ static inline void _i2c_clear_sda(_i2c_bus_t* bus)
GPIO.OUT_CLEAR = bus->sda_bit;
}
static void _i2c_abort(_i2c_bus_t* bus, const char* func)
{
DEBUG("%s: dev=%u\n", func, bus->dev);
/* reset SCL and SDA to passive HIGH (floating and pulled-up) */
_i2c_set_sda (bus);
_i2c_set_scl (bus);
/* reset repeated start indicator */
bus->started = false;
}
static /* IRAM */ int _i2c_arbitration_lost (_i2c_bus_t* bus, const char* func)
{
DEBUG("%s: arbitration lost dev=%u\n", func, bus->dev);
@ -471,7 +495,7 @@ static /* IRAM */ int _i2c_stop_cond(_i2c_bus_t* bus)
res = -ETIMEDOUT;
}
/* wait t_SU;STO - hold time (repeated) START condition, */
/* wait t_SU;STO - hold time STOP condition, */
/* min. in us: 4.0 (SM), 0.6 (FM), 0.26 (FPM), 0.16 (HSM); no max. */
_i2c_delay (bus);
@ -484,6 +508,8 @@ static /* IRAM */ int _i2c_stop_cond(_i2c_bus_t* bus)
/* wait t_BUF - bus free time between a STOP and a START condition */
/* min. in us: 4.7 (SM), 1.3 (FM), 0.5 (FPM), 0.16 (HSM); no max. */
_i2c_delay (bus);
/* one additional delay */
_i2c_delay (bus);
/* if SDA is low, arbitration is lost and someone else is driving the bus */
if (_i2c_read_sda (bus) == 0) {