Hello, I am considering implementing I2C Driver for an stm32 device using the interface defined by cmsis. One thing that has my attention however, is it seems a little constraining. I have worked with various devices that use I2C in the past and many of them require an I2C transaction in the following form:
START | ADDRESS(W) | REGISTER_ADDRESS | REP_START | ADDRESS(R/W) | DATA | STOP
When I read through some examples on how to use the driver it seems that Transmit and Receive are expected to do the following.
Transmit: START | ADDRESS(W) | DATA | STOP
Receive: START | ADDRESS(R) | DATA | STOP
Is there a standard way to generate I2C transactions that are slightly more complicated than Transmit and Receive?
typedef struct _ARM_DRIVER_I2C { ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_I2C_GetVersion : Get driver version. ARM_I2C_CAPABILITIES (*GetCapabilities)(void); ///< Pointer to \ref ARM_I2C_GetCapabilities : Get driver capabilities. int32_t (*Initialize) (ARM_I2C_SignalEvent_t cb_event); ///< Pointer to \ref ARM_I2C_Initialize : Initialize I2C Interface. int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_I2C_Uninitialize : De-initialize I2C Interface. int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_I2C_PowerControl : Control I2C Interface Power. int32_t (*MasterTransmit) (uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending); ///< Pointer to \ref ARM_I2C_MasterTransmit : Start transmitting data as I2C Master. int32_t (*MasterReceive) (uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending); ///< Pointer to \ref ARM_I2C_MasterReceive : Start receiving data as I2C Master. int32_t (*SlaveTransmit) ( const uint8_t *data, uint32_t num); ///< Pointer to \ref ARM_I2C_SlaveTransmit : Start transmitting data as I2C Slave. int32_t (*SlaveReceive) ( uint8_t *data, uint32_t num); ///< Pointer to \ref ARM_I2C_SlaveReceive : Start receiving data as I2C Slave. int32_t (*GetDataCount) (void); ///< Pointer to \ref ARM_I2C_GetDataCount : Get transferred data count. int32_t (*Control) (uint32_t control, uint32_t arg); ///< Pointer to \ref ARM_I2C_Control : Control I2C Interface. ARM_I2C_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_I2C_GetStatus : Get I2C status. } const ARM_DRIVER_I2C;
It looks to me that the xfer_pending is an indication to your driver implementation to not do a STOP
you should be able to do a Transmit with xfer_pending true followed by a receive with xfer_pending false;
Okay thanks, that makes sense. Not sure how i missed that hah