This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Advice on implementing CMSIS I2C Driver for stm32

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;