From 479ff81bc703d950ae2da1a5e677406e940f3828 Mon Sep 17 00:00:00 2001 From: "Frederic.Pillon" Date: Fri, 14 Jun 2019 10:24:40 +0200 Subject: [PATCH 1/3] [I2C] Reorder i2c_t field to avoid padding Signed-off-by: Frederic.Pillon --- cores/arduino/stm32/twi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/arduino/stm32/twi.h b/cores/arduino/stm32/twi.h index 4646658945..ea7d67b0f1 100644 --- a/cores/arduino/stm32/twi.h +++ b/cores/arduino/stm32/twi.h @@ -100,13 +100,13 @@ struct i2c_s { #if !defined(STM32F0xx) && !defined(STM32L0xx) IRQn_Type irqER; #endif //!defined(STM32F0xx) && !defined(STM32L0xx) - volatile uint8_t slaveMode; - uint8_t isMaster; volatile int slaveRxNbData; // Number of accumulated bytes received in Slave mode void (*i2c_onSlaveReceive)(uint8_t *, int); void (*i2c_onSlaveTransmit)(void); volatile uint8_t i2cTxRxBuffer[I2C_TXRX_BUFFER_SIZE]; volatile uint8_t i2cTxRxBufferSize; + volatile uint8_t slaveMode; + uint8_t isMaster; }; ///@brief I2C state From b5455953a8dd63064613eacd428c8120048ee63e Mon Sep 17 00:00:00 2001 From: "Frederic.Pillon" Date: Fri, 14 Jun 2019 10:26:05 +0200 Subject: [PATCH 2/3] [I2C] Remove redundant boolean master member Available in i2c_t structure field isMaster Signed-off-by: Frederic.Pillon --- cores/arduino/stm32/twi.c | 6 ++---- cores/arduino/stm32/twi.h | 2 +- libraries/Wire/src/Wire.cpp | 14 +++++--------- libraries/Wire/src/Wire.h | 1 - 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/cores/arduino/stm32/twi.c b/cores/arduino/stm32/twi.c index 9df7ebdccb..19cd9d283e 100644 --- a/cores/arduino/stm32/twi.c +++ b/cores/arduino/stm32/twi.c @@ -79,7 +79,7 @@ static I2C_HandleTypeDef *i2c_handles[I2C_NUM]; */ void i2c_init(i2c_t *obj) { - i2c_custom_init(obj, I2C_100KHz, I2C_ADDRESSINGMODE_7BIT, 0x33, 1); + i2c_custom_init(obj, I2C_100KHz, I2C_ADDRESSINGMODE_7BIT, 0x33); } /** @@ -88,10 +88,9 @@ void i2c_init(i2c_t *obj) * @param timing : one of the i2c_timing_e * @param addressingMode : I2C_ADDRESSINGMODE_7BIT or I2C_ADDRESSINGMODE_10BIT * @param ownAddress : device address - * @param master : set to 1 to choose the master mode * @retval none */ -void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, uint32_t ownAddress, uint8_t master) +void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, uint32_t ownAddress) { if (obj == NULL) { return; @@ -211,7 +210,6 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u Error_Handler(); } - obj->isMaster = master; /* Initialize default values */ obj->slaveRxNbData = 0; obj->slaveMode = SLAVE_MODE_LISTEN; diff --git a/cores/arduino/stm32/twi.h b/cores/arduino/stm32/twi.h index ea7d67b0f1..f336eee63e 100644 --- a/cores/arduino/stm32/twi.h +++ b/cores/arduino/stm32/twi.h @@ -153,7 +153,7 @@ typedef enum { /* Exported functions ------------------------------------------------------- */ void i2c_init(i2c_t *obj); void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, - uint32_t ownAddress, uint8_t master); + uint32_t ownAddress); void i2c_deinit(i2c_t *obj); void i2c_setTiming(i2c_t *obj, uint32_t frequency); i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address, uint8_t *data, uint16_t size); diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 7258794d64..781e41484e 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -78,15 +78,11 @@ void TwoWire::begin(uint8_t address) ownAddress = address << 1; - if (address == MASTER_ADDRESS) { - master = true; - } else { - master = false; - } + _i2c.isMaster = (address == MASTER_ADDRESS) ? 1 : 0; - i2c_custom_init(&_i2c, I2C_100KHz, I2C_ADDRESSINGMODE_7BIT, ownAddress, master); + i2c_custom_init(&_i2c, I2C_100KHz, I2C_ADDRESSINGMODE_7BIT, ownAddress); - if (master == false) { + if (_i2c.isMaster == 0) { // i2c_attachSlaveTxEvent(&_i2c, reinterpret_cast(&TwoWire::onRequestService)); // i2c_attachSlaveRxEvent(&_i2c, reinterpret_cast(&TwoWire::onReceiveService)); @@ -119,7 +115,7 @@ void TwoWire::setClock(uint32_t frequency) uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) { UNUSED(sendStop); - if (master == true) { + if (_i2c.isMaster == 1) { allocateRxBuffer(quantity); // error if no memory block available to allocate the buffer if (rxBuffer == nullptr) { @@ -216,7 +212,7 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop) UNUSED(sendStop); int8_t ret = 4; - if (master == true) { + if (_i2c.isMaster == 1) { // transmit buffer (blocking) switch (i2c_master_write(&_i2c, txAddress, txBuffer, txBufferLength)) { case I2C_OK : diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index 00a6ab620c..662a084a76 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -49,7 +49,6 @@ class TwoWire : public Stream { static uint8_t transmitting; uint8_t ownAddress; - bool master; i2c_t _i2c; static void (*user_onRequest)(void); From f7e971625efae6ebb1f0e74521a75f5febc15dcd Mon Sep 17 00:00:00 2001 From: "Frederic.Pillon" Date: Fri, 14 Jun 2019 10:46:46 +0200 Subject: [PATCH 3/3] [I2C] Add general call mode API Adding true to the 3 Wire::begin() method will enable the general call mode else false per default. Signed-off-by: Frederic.Pillon --- cores/arduino/stm32/twi.c | 2 +- cores/arduino/stm32/twi.h | 1 + libraries/Wire/src/Wire.cpp | 12 +++++++----- libraries/Wire/src/Wire.h | 6 +++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/cores/arduino/stm32/twi.c b/cores/arduino/stm32/twi.c index 19cd9d283e..f7a61ed4fe 100644 --- a/cores/arduino/stm32/twi.c +++ b/cores/arduino/stm32/twi.c @@ -192,7 +192,7 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u handle->Init.OwnAddress2 = 0xFF; handle->Init.AddressingMode = addressingMode; handle->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; - handle->Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + handle->Init.GeneralCallMode = (obj->generalCall == 0) ? I2C_GENERALCALL_DISABLE : I2C_GENERALCALL_ENABLE; handle->Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; handle->State = HAL_I2C_STATE_RESET; diff --git a/cores/arduino/stm32/twi.h b/cores/arduino/stm32/twi.h index f336eee63e..e6f4337845 100644 --- a/cores/arduino/stm32/twi.h +++ b/cores/arduino/stm32/twi.h @@ -107,6 +107,7 @@ struct i2c_s { volatile uint8_t i2cTxRxBufferSize; volatile uint8_t slaveMode; uint8_t isMaster; + uint8_t generalCall; }; ///@brief I2C state diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 781e41484e..f3b84022de 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -59,12 +59,12 @@ TwoWire::TwoWire(uint8_t sda, uint8_t scl) // Public Methods ////////////////////////////////////////////////////////////// -void TwoWire::begin(void) +void TwoWire::begin(bool generalCall) { - begin(MASTER_ADDRESS); + begin(MASTER_ADDRESS, generalCall); } -void TwoWire::begin(uint8_t address) +void TwoWire::begin(uint8_t address, bool generalCall) { rxBufferIndex = 0; rxBufferLength = 0; @@ -80,6 +80,8 @@ void TwoWire::begin(uint8_t address) _i2c.isMaster = (address == MASTER_ADDRESS) ? 1 : 0; + _i2c.generalCall = (generalCall == true) ? 1 : 0; + i2c_custom_init(&_i2c, I2C_100KHz, I2C_ADDRESSINGMODE_7BIT, ownAddress); if (_i2c.isMaster == 0) { @@ -91,9 +93,9 @@ void TwoWire::begin(uint8_t address) } } -void TwoWire::begin(int address) +void TwoWire::begin(int address, bool generalCall) { - begin((uint8_t)address); + begin((uint8_t)address, generalCall); } void TwoWire::end(void) diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index 662a084a76..da3bee5da1 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -82,9 +82,9 @@ class TwoWire : public Stream { { _i2c.sda = sda; }; - void begin(); - void begin(uint8_t); - void begin(int); + void begin(bool generalCall = false); + void begin(uint8_t, bool generalCall = false); + void begin(int, bool generalCall = false); void end(); void setClock(uint32_t); void beginTransmission(uint8_t);