diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 500a348d81..a93367aa61 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -27,22 +27,6 @@ extern "C" { #include "Wire.h" -// Initialize Class Variables ////////////////////////////////////////////////// -uint8_t *TwoWire::rxBuffer = nullptr; -uint8_t TwoWire::rxBufferAllocated = 0; -uint8_t TwoWire::rxBufferIndex = 0; -uint8_t TwoWire::rxBufferLength = 0; - -uint8_t TwoWire::txAddress = 0; -uint8_t *TwoWire::txBuffer = nullptr; -uint8_t TwoWire::txBufferAllocated = 0; -uint8_t TwoWire::txBufferIndex = 0; -uint8_t TwoWire::txBufferLength = 0; - -uint8_t TwoWire::transmitting = 0; -void (*TwoWire::user_onRequest)(void); -void (*TwoWire::user_onReceive)(int); - // Constructors //////////////////////////////////////////////////////////////// TwoWire::TwoWire() @@ -81,6 +65,13 @@ void TwoWire::begin(uint8_t address, bool generalCall) txBufferLength = 0; resetTxBuffer(); + rxBuffer = nullptr; + rxBufferAllocated = 0; + txAddress = 0; + txBuffer = nullptr; + txBufferAllocated = 0; + _i2c.__this = (void *)this; + user_onRequest = NULL; transmitting = 0; ownAddress = address << 1; @@ -403,44 +394,51 @@ void TwoWire::flush(void) } // behind the scenes function that is called when data is received -void TwoWire::onReceiveService(uint8_t *inBytes, int numBytes) +void TwoWire::onReceiveService(i2c_t *obj) { + uint8_t *inBytes = (uint8_t *) obj->i2cTxRxBuffer; + int numBytes = obj->slaveRxNbData; + + TwoWire *TW = (TwoWire *)(obj->__this); + // don't bother if user hasn't registered a callback - if (user_onReceive) { + if (TW->user_onReceive) { // don't bother if rx buffer is in use by a master requestFrom() op // i know this drops data, but it allows for slight stupidity // meaning, they may not have read all the master requestFrom() data yet - if (rxBufferIndex >= rxBufferLength) { + if (TW->rxBufferIndex >= TW->rxBufferLength) { - allocateRxBuffer(numBytes); + TW->allocateRxBuffer(numBytes); // error if no memory block available to allocate the buffer - if (rxBuffer == nullptr) { + if (TW->rxBuffer == nullptr) { Error_Handler(); } // copy twi rx buffer into local read buffer // this enables new reads to happen in parallel - memcpy(rxBuffer, inBytes, numBytes); + memcpy(TW->rxBuffer, inBytes, numBytes); // set rx iterator vars - rxBufferIndex = 0; - rxBufferLength = numBytes; + TW->rxBufferIndex = 0; + TW->rxBufferLength = numBytes; // alert user program - user_onReceive(numBytes); + TW->user_onReceive(numBytes); } } } // behind the scenes function that is called when data is requested -void TwoWire::onRequestService(void) +void TwoWire::onRequestService(i2c_t *obj) { + TwoWire *TW = (TwoWire *)(obj->__this); + // don't bother if user hasn't registered a callback - if (user_onRequest) { + if (TW->user_onRequest) { // reset tx buffer iterator vars // !!! this will kill any pending pre-master sendTo() activity - txBufferIndex = 0; - txBufferLength = 0; + TW->txBufferIndex = 0; + TW->txBufferLength = 0; // alert user program - user_onRequest(); + TW->user_onRequest(); } } diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index b393ea5954..6a94b36a0e 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -37,28 +37,28 @@ extern "C" { class TwoWire : public Stream { private: - static uint8_t *rxBuffer; - static uint8_t rxBufferAllocated; - static uint8_t rxBufferIndex; - static uint8_t rxBufferLength; + uint8_t *rxBuffer; + uint8_t rxBufferAllocated; + uint8_t rxBufferIndex; + uint8_t rxBufferLength; - static uint8_t txAddress; - static uint8_t *txBuffer; - static uint8_t txBufferAllocated; - static uint8_t txBufferIndex; - static uint8_t txBufferLength; + uint8_t txAddress; + uint8_t *txBuffer; + uint8_t txBufferAllocated; + uint8_t txBufferIndex; + uint8_t txBufferLength; - static uint8_t transmitting; + uint8_t transmitting; uint8_t ownAddress; i2c_t _i2c; - static void (*user_onRequest)(void); - static void (*user_onReceive)(int); - static void onRequestService(void); - static void onReceiveService(uint8_t *, int); + void (*user_onRequest)(void); + void (*user_onReceive)(int); + static void onRequestService(i2c_t *); + static void onReceiveService(i2c_t *); - static void allocateRxBuffer(size_t length); + void allocateRxBuffer(size_t length); void allocateTxBuffer(size_t length); void resetRxBuffer(void); diff --git a/libraries/Wire/src/utility/twi.c b/libraries/Wire/src/utility/twi.c index 7e2420962d..69a5d17fc4 100644 --- a/libraries/Wire/src/utility/twi.c +++ b/libraries/Wire/src/utility/twi.c @@ -948,7 +948,7 @@ i2c_t *get_i2c_obj(I2C_HandleTypeDef *hi2c) * @param function: callback function to use * @retval None */ -void i2c_attachSlaveRxEvent(i2c_t *obj, void (*function)(uint8_t *, int)) +void i2c_attachSlaveRxEvent(i2c_t *obj, void (*function)(i2c_t *)) { if ((obj != NULL) && (function != NULL)) { obj->i2c_onSlaveReceive = function; @@ -961,7 +961,7 @@ void i2c_attachSlaveRxEvent(i2c_t *obj, void (*function)(uint8_t *, int)) * @param function: callback function to use * @retval None */ -void i2c_attachSlaveTxEvent(i2c_t *obj, void (*function)(void)) +void i2c_attachSlaveTxEvent(i2c_t *obj, void (*function)(i2c_t *)) { if ((obj != NULL) && (function != NULL)) { obj->i2c_onSlaveTransmit = function; @@ -986,7 +986,7 @@ void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, ui obj->slaveMode = SLAVE_MODE_TRANSMIT; if (obj->i2c_onSlaveTransmit != NULL) { - obj->i2c_onSlaveTransmit(); + obj->i2c_onSlaveTransmit(obj); } #if defined(STM32F0xx) || defined(STM32F1xx) || defined(STM32F2xx) || defined(STM32F3xx) ||\ defined(STM32F4xx) || defined(STM32L0xx) || defined(STM32L1xx) || defined(STM32MP1xx) @@ -1026,7 +1026,7 @@ void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) /* Previous master transaction now ended, so inform upper layer if needed * then prepare for listening to next request */ if ((obj->slaveMode == SLAVE_MODE_RECEIVE) && (obj->slaveRxNbData != 0)) { - obj->i2c_onSlaveReceive((uint8_t *) obj->i2cTxRxBuffer, obj->slaveRxNbData); + obj->i2c_onSlaveReceive(obj); } obj->slaveMode = SLAVE_MODE_LISTEN; obj->slaveRxNbData = 0; diff --git a/libraries/Wire/src/utility/twi.h b/libraries/Wire/src/utility/twi.h index 07d22a0949..0d12e296b9 100644 --- a/libraries/Wire/src/utility/twi.h +++ b/libraries/Wire/src/utility/twi.h @@ -99,6 +99,7 @@ struct i2c_s { */ I2C_TypeDef *i2c; I2C_HandleTypeDef handle; + void *__this; PinName sda; PinName scl; IRQn_Type irq; @@ -106,8 +107,8 @@ struct i2c_s { IRQn_Type irqER; #endif /* !STM32F0xx && !STM32G0xx && !STM32L0xx */ volatile int slaveRxNbData; // Number of accumulated bytes received in Slave mode - void (*i2c_onSlaveReceive)(uint8_t *, int); - void (*i2c_onSlaveTransmit)(void); + void (*i2c_onSlaveReceive)(i2c_t *); + void (*i2c_onSlaveTransmit)(i2c_t *); volatile uint8_t i2cTxRxBuffer[I2C_TXRX_BUFFER_SIZE]; volatile uint8_t i2cTxRxBufferSize; volatile uint8_t slaveMode; @@ -138,8 +139,8 @@ i2c_status_e i2c_master_read(i2c_t *obj, uint8_t dev_address, uint8_t *data, uin i2c_status_e i2c_IsDeviceReady(i2c_t *obj, uint8_t devAddr, uint32_t trials); -void i2c_attachSlaveRxEvent(i2c_t *obj, void (*function)(uint8_t *, int)); -void i2c_attachSlaveTxEvent(i2c_t *obj, void (*function)(void)); +void i2c_attachSlaveRxEvent(i2c_t *obj, void (*function)(i2c_t *)); +void i2c_attachSlaveTxEvent(i2c_t *obj, void (*function)(i2c_t *)); #ifdef __cplusplus }