We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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