Files
2026-01-12 18:46:01 +08:00

359 lines
12 KiB
C

/**
* @file sdrv_i2c.h
* @brief SemiDrive I2C driver header file.
*
* @copyright (c) 2022 Semidrive Semiconductor.
* @All rights reserved.
*
*/
#ifndef SDRV_I2C_DRV_H_
#define SDRV_I2C_DRV_H_
#include <types.h>
#include <sdrv_common.h>
/**
* @brief i2c controller supported errcode
*/
enum {
/* transfer stat group */
SDRV_I2CDRV_TRANS_OK = SDRV_STATUS_OK,
SDRV_I2CDRV_TRANS_GO = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_I2C, 11),
SDRV_I2CDRV_TRANS_NAK = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_I2C, 12),
SDRV_I2CDRV_TRANS_ERR = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_I2C, 13),
SDRV_I2CDRV_TRANS_ABORT = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_I2C, 14),
SDRV_I2CDRV_TRANS_TIMEOUT = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_I2C, 15),
};
/**
* @brief i2c controller supported operation mode
*/
typedef enum {
SDRV_I2CDRV_MASTER = 1, /**< i2c controller master mode */
SDRV_I2CDRV_SLAVE, /**< i2c controller slave mode */
} sdrv_i2cdrv_opmode_t;
/**
* @brief i2c controller supported speed mode
*/
typedef enum {
SDRV_I2CDRV_SSPEED = 1, /**< 100kHz */
SDRV_I2CDRV_FSPEED, /**< 400kHz */
SDRV_I2CDRV_PSPEED, /**< 1MHz */
SDRV_I2CDRV_HSPEED, /**< 3.4MHz */
SDRV_I2CDRV_USPEED, /**< 5MHz */
} sdrv_i2cdrv_speed_t;
/**
* @brief i2c controller supported transfer mode
* (only applicable for master mode)
*/
typedef enum {
SDRV_I2CDRV_POLL = 1, /**<polling mode */
SDRV_I2CDRV_INTP, /**< interrupt mode */
} sdrv_i2cdrv_tsmode_t;
/**
* @brief i2c bus stat(only applicable for master mode)
*/
typedef enum {
SDRV_I2CDRV_BUS_IDLE = 1, /**<i2c bus is idle */
SDRV_I2CDRV_BUS_BUSY, /**<i2c bus is busy */
} sdrv_i2cdrv_bus_stat_t;
typedef enum i2c_slave_event {
I2C_SLV_NONE_EVENT = 0x0U,
I2C_SLV_RECEIVE_EVENT, /**< Callback is requested to provide a buffer in which to place received data (slave-receiver role). */
I2C_SLV_TRANSMIT_EVENT, /**< Callback is requested to provide a buffer in which to to transmit data (slave-transmitter role). */
I2C_SLV_COMPLETION_EVENT, /**< All data in the active transfer have been consumed. */
I2C_SLV_STOP_EVENT, /**< The stop condition may have been detected before all data in the active transfer have been consumed */
}i2c_slave_event_t;
typedef status_t sdrv_i2cdrv_trans_stat_t;
typedef struct sdrv_i2c_cfg sdrv_i2c_cfg_t;
typedef struct sdrv_i2cdrv_mctrl sdrv_i2cdrv_mctrl_t;
typedef struct sdrv_i2c sdrv_i2c_t;
typedef struct sdrv_i2cdrv_sctrl sdrv_i2cdrv_sctrl_t;
typedef struct i2c_slave_transfer i2c_slave_transfer_t;
typedef void (*sdrv_i2c_cb_t)(sdrv_i2c_t *ctrl, void *param,
sdrv_i2cdrv_trans_stat_t stat);
/**
* @brief Slave event callback function pointer type.
* This callback is used only for the slave non-blocking transfer API. To install a callback,
* use the sdrv_i2c_slave_transfer_create() function after you have init i2c slave module.
*
*/
typedef void (*i2c_slave_callback_t)(sdrv_i2c_t *ctrl, i2c_slave_transfer_t *transfer,
void *param);
/**
* @i2c controller config info
*/
struct sdrv_i2c_cfg {
uint32_t clk; /**<sclk allocate from system */
paddr_t base; /**<base address allocate from system */
uint32_t irq; /**<irq allocate from system */
uint32_t id; /**<id allocate from system */
uint32_t inited; /**<ctrl already init or not by customer */
sdrv_i2cdrv_opmode_t opmode; /**<master or slave operation mode set */
sdrv_i2cdrv_tsmode_t tsmode; /**<interrupt or polling transfer mode set */
uint32_t slave_addr; /**<if work in slave mode , config slave device address,
7bit without LSB rw bit. mater mode ignore it */
sdrv_i2cdrv_speed_t speed; /**<speed(100k/400k/1M/3.4M/5M) mode set */
sdrv_i2cdrv_bus_stat_t bus_stat; /**<bus stat change trace */
};
/**
* @i2c controller master mode relative resource
*/
struct sdrv_i2cdrv_mctrl {
uint16_t slave_addr; /**<slave device address,7bit without LSB rw bit */
uint8_t *buf; /**<point to data write or read customer buf */
uint16_t len; /**<buf length from customer */
int read_flag; /**<1:read ; 0:write */
bool need_stop; /**<true: end with stop signal */
uint16_t cur_len; /**<length of data already write or read success */
status_t trans_stat; /**< current transfer stat flag */
uint32_t trans_errcode; /**<error code flag */
sdrv_i2c_cb_t cb; /**<interrupt callback function */
void *cb_param; /**<callback customer parameter */
};
/**
* @brief i2c salve transfer config info.
* Structure with settings to initialize the I2C slave transfer.
*/
typedef struct i2c_slave_transfer_config {
i2c_slave_callback_t callback; /**<interrupt callback function */
void *cb_param; /**<callback customer parameter */
} i2c_slave_transfer_config_t;
/*! @brief I2C slave transfer structure */
struct i2c_slave_transfer
{
sdrv_i2c_t *ctrl; /**< Pointer to handle that contains this transfer. */
i2c_slave_event_t event; /**< Reason the callback is being invoked. */
uint8_t slave_addr; /**< Matching address send by master. 7-bits plus R/nW bit0 */
uint8_t *buffer; /**< Transfer buffer for receive data */
size_t buffer_bytes; /**< Transfer size in bytes */
size_t transferred_bytes; /**< Number of bytes transferred during this transfer. */
status_t status; /**< Success or error code describing how the transfer completed. Only applies for
#I2C_SLV_COMPLETION_EVENT&I2C_SLV_STOP_EVENT */
};
/**
* @i2c controller slave mode relative resource
*/
typedef struct sdrv_i2cdrv_sctrl {
uint32_t slave_addr; /**<work in slave mode , slave device address,*/
i2c_slave_transfer_t transfer; /**< I2C slave transfer. */
i2c_slave_callback_t callback; /**<interrupt callback function */
void *cb_param; /**<callback customer parameter */
};
/**
* @i2c controller object structure
*/
struct sdrv_i2c {
sdrv_i2c_cfg_t *cfg; /**<point to i2c config in i2c_cfg.c */
sdrv_i2cdrv_mctrl_t mctrl; /**<controller as master object structure */
sdrv_i2cdrv_sctrl_t sctrl; /**<controller as slave object structure */
};
/**
* @brief Set i2c controller transfer mode
*
* @note This API is deprecated.
* @param[in] ctrl i2c controller instance pointer
* @param[in] tsmode transmode to be set
*
* @return SDRV_STATUS_OK
*/
static inline status_t sdrv_i2c_set_transmode(sdrv_i2c_t *ctrl,
sdrv_i2cdrv_tsmode_t tsmode)
{
return SDRV_STATUS_OK;
}
/**
* @brief Set i2c controller speed mode
*
* @note This API is deprecated.
* @param[in] ctrl i2c controller instance pointer
* @param[in] speed speed mode to be set
*
* @return SDRV_STATUS_OK
*/
static inline status_t sdrv_i2c_set_speedmode(sdrv_i2c_t *ctrl,
sdrv_i2cdrv_speed_t speed)
{
return SDRV_STATUS_OK;
}
/**
* @brief Init the i2c controller.
*
* @param[in] ctrl i2c controller instance pointer
*
* @return SDRV_STATUS_OK/SDRV_STATUS_FAIL
*/
extern status_t sdrv_i2c_init_ctrl(sdrv_i2c_t *ctrl);
/**
* @brief Write data to slave device use poll blocking format
*
* @param[in] ctrl i2c controller instance pointer
* @param[in] addr slave device 7bit addr not include LSB read/write bit
* @param[in] wbuf point to data buf for send
* @param[in] wlen data buf len
* @param[in] timeout timeout in milliseconds to wait (0 = wait forever)
* @param[in] need_stop whether send stop signal or hold sda after finish write
*
* @return SDRV_STATUS_OK/SDRV_STATUS_FAIL
*/
extern status_t sdrv_i2c_write(sdrv_i2c_t *ctrl, uint16_t addr,
uint8_t *wbuf, uint16_t wlen,
uint32_t timeout, bool need_stop);
/**
* @brief Read data from slave device use poll blocking format
*
* @param[in] ctrl i2c controller instance pointer
* @param[in] addr slave device 7bit addr not include LSB read/write bit
* @param[out] rbuf point to data buf for receive
* @param[in] rlen data buf len
* @param[in] timeout timeout in milliseconds to wait (0 = wait forever)
* @param[in] need_stop whether send stop signal or hold sda after finish read
*
* @return SDRV_STATUS_OK/SDRV_STATUS_FAIL
*/
extern status_t sdrv_i2c_read(sdrv_i2c_t *ctrl, uint16_t addr,
uint8_t *rbuf, uint16_t rlen,
uint32_t timeout, bool need_stop);
/**
* @brief Write data to slave device use interrupt non-blocking format
*
* @param[in] ctrl i2c controller instance pointer
* @param[in] addr slave device 7bit addr not include LSB read/write bit
* @param[in] wbuf point to data buf for send
* @param[in] wlen data buf len
* @param[in] need_stop whether send stop signal or hold sda after finish write
* @param[in] cb callback function pointer
* @param[in] cb_param callback user parameter
*
* @return SDRV_STATUS_OK/SDRV_STATUS_FAIL
*/
extern status_t sdrv_i2c_write_async(sdrv_i2c_t *ctrl,
uint16_t addr, uint8_t *wbuf, uint16_t wlen,
bool need_stop, sdrv_i2c_cb_t cb, void *cb_param);
/**
* @brief Read data from slave device use interrupt non-blocking format
*
* @param[in] ctrl i2c controller instance pointer
* @param[in] addr slave device 7bit addr not include LSB read/write bit
* @param[out] rbuf point to data buf for receive
* @param[in] rlen data buf len
* @param[in] need_stop whether send stop signal or hold sda after complete read
* @param[in] cb callback function pointer
* @param[in] cb_param callback user parameter
*
* @return SDRV_STATUS_OK/SDRV_STATUS_FAIL
*/
extern status_t sdrv_i2c_read_async(sdrv_i2c_t *ctrl,
uint16_t addr, uint8_t *rbuf, uint16_t rlen,
bool need_stop, sdrv_i2c_cb_t cb, void *cb_param);
/**
* @brief Get transfer stat(only applicable for master).
*
* @param[in] ctrl i2c controller instance pointer
*
* @return SDRV_I2CDRV_TRANS_OK
* SDRV_I2CDRV_TRANS_GO
* SDRV_I2CDRV_TRANS_ERR
* SDRV_I2CDRV_TRANS_NAK
* SDRV_I2CDRV_TRANS_ABORT
* SDRV_I2CDRV_TRANS_TIMEOUT
*/
extern status_t sdrv_i2c_get_trans_stat(sdrv_i2c_t *ctrl);
/**
* @brief Get bus stat(only applicable for master).
* @this api will abandon,please use
* sdrv_i2c_lock_bus/sdrv_i2c_unlock_bus instead
*
* @param[in] ctrl i2c controller instance pointer
*
* @return SDRV_I2CDRV_BUS_IDLE/SDRV_I2CDRV_BUS_BUSY
*/
extern sdrv_i2cdrv_bus_stat_t sdrv_i2c_get_bus_stat(sdrv_i2c_t *ctrl);
/**
* @brief Set bus stat(only applicable for master).
* @this api will abandon,please use
* sdrv_i2c_lock_bus/sdrv_i2c_unlock_bus instead
*
* @param[in] ctrl i2c controller instance pointer
* @param[in] bus_stat bus stat to be set
*
* @return SDRV_STATUS_OK
*/
extern status_t sdrv_i2c_set_bus_stat(sdrv_i2c_t *ctrl,
sdrv_i2cdrv_bus_stat_t bus_stat);
/**
* @brief Lock bus stat(only applicable for master).
*
* @param[in] ctrl i2c controller instance pointer
*
* @return SDRV_STATUS_OK/SDRV_STATUS_FAIL
*/
extern status_t sdrv_i2c_lock_bus(sdrv_i2c_t *ctrl);
/**
* @brief Unlock bus stat(only applicable for master).
*
* @param[in] ctrl i2c controller instance pointer
*
* @return SDRV_STATUS_OK
*/
extern status_t sdrv_i2c_unlock_bus(sdrv_i2c_t *ctrl);
/* i2c slave interface */
/**
* @brief Creates a transfer for the I2C slave non-blocking APIs.
*
* The creation of a transfer is for use with the non-blocking APIs. Once a transfer
* is created, there is not a corresponding destroy handle. If the user wants to
* terminate a transfer, the sdrv_i2c_slave_deinit() API shall be called.
*
* @param ctrl Pointer to the I2C controller
* @param config Pointer to the I2C transfer config
* @return status_t
*/
extern status_t sdrv_i2c_slave_transfer_create(sdrv_i2c_t *ctrl, i2c_slave_transfer_config_t *config);
/**
* @brief Initializes the I2C slave module.
* This function enables the peripheral clock and initializes the I2C slave peripheral as described by the user
* provided configuration.
*
* @param ctrl Pointer to the I2C controller
* @return status_t
*/
extern status_t sdrv_i2c_slave_init(sdrv_i2c_t *ctrl);
/**
* @brief Deinitializes the I2C slave controller.
*
* @param ctrl Pointer to the I2C controller
* @return status_t
*/
status_t sdrv_i2c_slave_deinit(sdrv_i2c_t *ctrl);
#endif