rt-thread-official/bsp/gd32303e-eval/Libraries/GD32F30x_standard_peripheral/Source/gd32f30x_i2c.c

684 lines
21 KiB
C
Raw Normal View History

2018-05-21 11:13:46 +08:00
/*!
\file gd32f30x_i2c.c
\brief I2C driver
*/
/*
Copyright (C) 2017 GigaDevice
2017-02-10, V1.0.1, firmware for GD32F30x
*/
#include "gd32f30x_i2c.h"
#define I2CCLK_MAX 0x7fU /*!< i2cclk max value */
#define I2C_FLAG_MASK 0x0000FFFFU /*!< i2c flag mask */
/*!
\brief reset I2C
\param[in] i2c_periph: I2Cx(x=0,1)
\param[out] none
\retval none
*/
void i2c_deinit(uint32_t i2c_periph)
{
switch(i2c_periph){
case I2C0:
/* reset I2C0 */
rcu_periph_reset_enable(RCU_I2C0RST);
rcu_periph_reset_disable(RCU_I2C0RST);
break;
case I2C1:
/* reset I2C1 */
rcu_periph_reset_enable(RCU_I2C1RST);
rcu_periph_reset_disable(RCU_I2C1RST);
break;
default:
break;
}
}
/*!
\brief configure I2C clock
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz)
and fast mode plus (up to 1MHz)
\param[in] dutycyc: duty cycle in fast mode or fast mode plus
\arg I2C_DTCY_2: T_low/T_high=2
\arg I2C_DTCY_16_9: T_low/T_high=16/9
\param[out] none
\retval none
*/
void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc)
{
uint32_t pclk1,clkc,freq,risetime;
uint32_t temp;
pclk1 = rcu_clock_freq_get(CK_APB1);
/* I2C peripheral clock frequency */
freq = (uint32_t)(pclk1/1000000U);
if(freq >= I2CCLK_MAX){
freq = I2CCLK_MAX;
}
temp = I2C_CTL1(i2c_periph);
temp &= ~I2C_CTL1_I2CCLK;
temp |= freq;
I2C_CTL1(i2c_periph) = temp;
if(100000U >= clkspeed){
/* the maximum SCL rise time is 1000ns in standard mode */
risetime = (uint32_t)((pclk1/1000000U)+1U);
if(risetime >= I2CCLK_MAX){
I2C_RT(i2c_periph) = I2CCLK_MAX;
}else{
I2C_RT(i2c_periph) = risetime;
}
clkc = (uint32_t)(pclk1/(clkspeed*2U));
if(clkc < 0x04U){
/* the CLKC in standard mode minmum value is 4 */
clkc = 0x04U;
}
I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc);
}else if(400000U >= clkspeed){
/* the maximum SCL rise time is 300ns in fast mode */
I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)300U)/(uint32_t)1000U)+(uint32_t)1U);
if(I2C_DTCY_2 == dutycyc){
/* I2C duty cycle is 2 */
clkc = (uint32_t)(pclk1/(clkspeed*3U));
I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY;
}else{
/* I2C duty cycle is 16/9 */
clkc = (uint32_t)(pclk1/(clkspeed*25U));
I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
}
if(0U == (clkc & I2C_CKCFG_CLKC)){
/* the CLKC in fast mode minmum value is 1 */
clkc |= 0x0001U;
}
I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
I2C_CKCFG(i2c_periph) |= clkc;
}else{
/* fast mode plus, the maximum SCL rise time is 120ns */
I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)120U)/(uint32_t)1000U)+(uint32_t)1U);
if(I2C_DTCY_2 == dutycyc){
/* I2C duty cycle is 2 */
clkc = (uint32_t)(pclk1/(clkspeed*3U));
I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY;
}else{
/* I2C duty cycle is 16/9 */
clkc = (uint32_t)(pclk1/(clkspeed*25U));
I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
}
/* enable fast mode */
I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
I2C_CKCFG(i2c_periph) |= clkc;
/* enable I2C fast mode plus */
I2C_FMPCFG(i2c_periph) = I2C_FMPCFG_FMPEN;
}
}
/*!
\brief configure I2C address
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] mode:
\arg I2C_I2CMODE_ENABLE: I2C mode
\arg I2C_SMBUSMODE_ENABLE: SMBus mode
\param[in] addformat: 7bits or 10bits
\arg I2C_ADDFORMAT_7BITS: 7bits
\arg I2C_ADDFORMAT_10BITS: 10bits
\param[in] addr: I2C address
\param[out] none
\retval none
*/
void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr)
{
/* SMBus/I2C mode selected */
uint32_t ctl = 0U;
ctl = I2C_CTL0(i2c_periph);
ctl &= ~(I2C_CTL0_SMBEN);
ctl |= mode;
I2C_CTL0(i2c_periph) = ctl;
/* configure address */
I2C_SADDR0(i2c_periph) = (addformat | addr);
}
/*!
\brief SMBus type selection
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] ack:
\arg I2C_SMBUS_DEVICE: device
\arg I2C_SMBUS_HOST: host
\param[out] none
\retval none
*/
void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type)
{
if(I2C_SMBUS_HOST == type){
I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL;
}else{
I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL);
}
}
/*!
\brief whether or not to send an ACK
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] ack:
\arg I2C_ACK_ENABLE: ACK will be sent
\arg I2C_ACK_DISABLE: ACK will not be sent
\param[out] none
\retval none
*/
void i2c_ack_config(uint32_t i2c_periph, uint32_t ack)
{
if(I2C_ACK_ENABLE == ack){
I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN;
}else{
I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN);
}
}
/*!
\brief I2C POAP position configure
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] pos:
\arg I2C_ACKPOS_CURRENT: whether to send ACK or not for the current
\arg I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte
\param[out] none
\retval none
*/
void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos)
{
/* configure I2C POAP position */
if(I2C_ACKPOS_NEXT == pos){
I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP;
}else{
I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP);
}
}
/*!
\brief master send slave address
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] addr: slave address
\param[in] trandirection: transmitter or receiver
\arg I2C_TRANSMITTER: transmitter
\arg I2C_RECEIVER: receiver
\param[out] none
\retval none
*/
void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection)
{
if(I2C_TRANSMITTER == trandirection){
addr = addr & I2C_TRANSMITTER;
}else{
addr = addr | I2C_RECEIVER;
}
I2C_DATA(i2c_periph) = addr;
}
/*!
\brief dual-address mode switch
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] dualaddr:
\arg I2C_DUADEN_DISABLE: disable dual-address mode
\arg I2C_DUADEN_ENABLE: enable dual-address mode
\param[out] none
\retval none
*/
void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t dualaddr)
{
if(I2C_DUADEN_ENABLE == dualaddr){
I2C_SADDR1(i2c_periph) |= I2C_SADDR1_DUADEN;
}else{
I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN);
}
}
/*!
\brief enable I2C
\param[in] i2c_periph: I2Cx(x=0,1)
\param[out] none
\retval none
*/
void i2c_enable(uint32_t i2c_periph)
{
I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN;
}
/*!
\brief disable I2C
\param[in] i2c_periph: I2Cx(x=0,1)
\param[out] none
\retval none
*/
void i2c_disable(uint32_t i2c_periph)
{
I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_I2CEN);
}
/*!
\brief generate a START condition on I2C bus
\param[in] i2c_periph: I2Cx(x=0,1)
\param[out] none
\retval none
*/
void i2c_start_on_bus(uint32_t i2c_periph)
{
I2C_CTL0(i2c_periph) |= I2C_CTL0_START;
}
/*!
\brief generate a STOP condition on I2C bus
\param[in] i2c_periph: I2Cx(x=0,1)
\param[out] none
\retval none
*/
void i2c_stop_on_bus(uint32_t i2c_periph)
{
I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP;
}
/*!
\brief I2C transmit data function
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] data: data of transmission
\param[out] none
\retval none
*/
void i2c_data_transmit(uint32_t i2c_periph, uint8_t data)
{
I2C_DATA(i2c_periph) = DATA_TRANS(data);
}
/*!
\brief I2C receive data function
\param[in] i2c_periph: I2Cx(x=0,1)
\param[out] none
\retval data of received
*/
uint8_t i2c_data_receive(uint32_t i2c_periph)
{
return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph));
}
/*!
\brief enable I2C DMA mode
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] dmastate:
\arg I2C_DMA_ON: DMA mode enable
\arg I2C_DMA_OFF: DMA mode disable
\param[out] none
\retval none
*/
void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate)
{
/* configure I2C DMA function */
uint32_t ctl = 0U;
ctl = I2C_CTL1(i2c_periph);
ctl &= ~(I2C_CTL1_DMAON);
ctl |= dmastate;
I2C_CTL1(i2c_periph) = ctl;
}
/*!
\brief flag indicating DMA last transfer
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] dmalast:
\arg I2C_DMALST_ON: next DMA EOT is the last transfer
\arg I2C_DMALST_OFF: next DMA EOT is not the last transfer
\param[out] none
\retval none
*/
void i2c_dma_last_transfer_enable(uint32_t i2c_periph, uint32_t dmalast)
{
/* configure DMA last transfer */
uint32_t ctl = 0U;
ctl = I2C_CTL1(i2c_periph);
ctl &= ~(I2C_CTL1_DMALST);
ctl |= dmalast;
I2C_CTL1(i2c_periph) = ctl;
}
/*!
\brief whether to stretch SCL low when data is not ready in slave mode
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] stretchpara:
\arg I2C_SCLSTRETCH_ENABLE: SCL stretching is enabled
\arg I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled
\param[out] none
\retval none
*/
void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara)
{
/* configure I2C SCL strerching enable or disable */
uint32_t ctl = 0U;
ctl = I2C_CTL0(i2c_periph);
ctl &= ~(I2C_CTL0_DISSTRC);
ctl |= stretchpara;
I2C_CTL0(i2c_periph) = ctl;
}
/*!
\brief whether or not to response to a general call
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] gcallpara:
\arg I2C_GCEN_ENABLE: slave will response to a general call
\arg I2C_GCEN_DISABLE: slave will not response to a general call
\param[out] none
\retval none
*/
void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara)
{
/* configure slave response to a general call enable or disable */
uint32_t ctl = 0U;
ctl = I2C_CTL0(i2c_periph);
ctl &= ~(I2C_CTL0_GCEN);
ctl |= gcallpara;
I2C_CTL0(i2c_periph) = ctl;
}
/*!
\brief software reset I2C
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] sreset:
\arg I2C_SRESET_SET: I2C is under reset
\arg I2C_SRESET_RESET: I2C is not under reset
\param[out] none
\retval none
*/
void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset)
{
/* modify CTL0 and configure software reset I2C state */
uint32_t ctl = 0U;
ctl = I2C_CTL0(i2c_periph);
ctl &= ~(I2C_CTL0_SRESET);
ctl |= sreset;
I2C_CTL0(i2c_periph) = ctl;
}
/*!
\brief check I2C flag is set or not
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] flag:
\arg I2C_FLAG_SBSEND: start condition send out
\arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode
\arg I2C_FLAG_BTC: byte transmission finishes
\arg I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode
\arg I2C_FLAG_STPDET: stop condition detected in slave mode
\arg I2C_FLAG_RBNE: I2C_DATA is not Empty during receiving
\arg I2C_FLAG_TBE: I2C_DATA is empty during transmitting
\arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus
\arg I2C_FLAG_LOSTARB: arbitration lost in master mode
\arg I2C_FLAG_AERR: acknowledge error
\arg I2C_FLAG_OUERR: overrun or underrun situation occurs in slave mode
\arg I2C_FLAG_PECERR: PEC error when receiving data
\arg I2C_FLAG_SMBTO: timeout signal in SMBus mode
\arg I2C_FLAG_SMBALT: SMBus alert status
\arg I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode
\arg I2C_FLAG_I2CBSY: busy flag
\arg I2C_FLAG_TRS: whether the I2C is a transmitter or a receiver
\arg I2C_FLAG_RXGC: general call address (00h) received
\arg I2C_FLAG_DEFSMB: default address of SMBus device
\arg I2C_FLAG_HSTSMB: SMBus host header detected in slave mode
\arg I2C_FLAG_DUMOD: dual flag in slave mode indicating which address is matched in dual-address mode
\param[out] none
\retval FlagStatus: SET or RESET
*/
FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag)
{
uint32_t reg = 0U;
FlagStatus reval = RESET;
/* get the flag in which register */
reg = (BIT(31) & flag);
if((BIT(31) == reg)){
if((I2C_STAT1(i2c_periph)&(flag & I2C_FLAG_MASK))){
reval = SET;
}else{
reval = RESET;
}
}else{
if((I2C_STAT0(i2c_periph)&(flag & I2C_FLAG_MASK))){
reval = SET;
}else{
reval = RESET;
}
}
/* return the flag status */
return reval;
}
/*!
\brief clear I2C flag
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] flag: flag type
\arg I2C_FLAG_SMBALT: SMBus Alert status
\arg I2C_FLAG_SMBTO: timeout signal in SMBus mode
\arg I2C_FLAG_PECERR: PEC error when receiving data
\arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode
\arg I2C_FLAG_AERR: acknowledge error
\arg I2C_FLAG_LOSTARB: arbitration lost in master mode
\arg I2C_FLAG_BERR: a bus error
\arg I2C_FLAG_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1
\param[out] none
\retval none
*/
void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag)
{
if(I2C_FLAG_ADDSEND == flag){
/* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
I2C_STAT0(i2c_periph);
I2C_STAT1(i2c_periph);
}else{
I2C_STAT0(i2c_periph) &= ~(flag);
}
}
/*!
\brief enable I2C interrupt
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] inttype: interrupt type
\arg I2C_INT_ERR: error interrupt enable
\arg I2C_INT_EV: event interrupt enable
\arg I2C_INT_BUF: buffer interrupt enable
\param[out] none
\retval none
*/
void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t inttype)
{
I2C_CTL1(i2c_periph) |= (inttype);
}
/*!
\brief disable I2C interrupt
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] inttype: interrupt type
\arg I2C_INT_ERR: error interrupt enable
\arg I2C_INT_EV: event interrupt enable
\arg I2C_INT_BUF: buffer interrupt enable
\param[out] none
\retval none
*/
void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t inttype)
{
I2C_CTL1(i2c_periph) &= ~(inttype);
}
/*!
\brief check I2C interrupt flag
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] int_flag: interrupt flag
\arg I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag
\arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
\arg I2C_INT_FLAG_BTC: byte transmission finishes
\arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag
\arg I2C_INT_FLAG_STPDET: etop condition detected in slave mode interrupt flag
\arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag
\arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag
\arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
\arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
\arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag
\arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
\arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
\arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
\arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag
\param[out] none
\retval none
*/
FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, uint32_t intflag)
{
uint32_t evie, errie, bufie;
evie = I2C_CTL1(i2c_periph)&I2C_CTL1_EVIE;
errie = I2C_CTL1(i2c_periph)&I2C_CTL1_ERRIE;
/* check I2C event interrupt enable bit */
if((intflag&0x00ffU) && evie){
if(intflag&0x001fU){
/* check I2C event flags except TBE and RBNE */
if(intflag & I2C_STAT0(i2c_periph)){
return SET;
}else{
return RESET;
}
}else{
/* check I2C event flags TBE and RBNE */
bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE;
if(bufie){
if(intflag & I2C_STAT0(i2c_periph)){
return SET;
}else{
return RESET;
}
}else{
return RESET;
}
}
/* check I2C error interrupt enable bit */
}else if((intflag&0xff00U) && errie){
/* check I2C error flags */
if(intflag & I2C_STAT0(i2c_periph)){
return SET;
}else{
return RESET;
}
}else{
return RESET;
}
}
/*!
\brief clear I2C interrupt flag
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] intflag: interrupt flag
\arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
\arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
\arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
\arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag
\arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
\arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
\arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
\arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag
\param[out] none
\retval none
*/
void i2c_interrupt_flag_clear(uint32_t i2c_periph, uint32_t intflag)
{
if(I2C_INT_FLAG_ADDSEND == intflag){
/* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
I2C_STAT0(i2c_periph);
I2C_STAT1(i2c_periph);
}else{
I2C_STAT0(i2c_periph) &= ~(intflag);
}
}
/*!
\brief I2C PEC calculation on or off
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] pecpara:
\arg I2C_PEC_ENABLE: PEC calculation on
\arg I2C_PEC_DISABLE: PEC calculation off
\param[out] none
\retval none
*/
void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate)
{
/* on/off PEC calculation */
uint32_t ctl = 0U;
ctl = I2C_CTL0(i2c_periph);
ctl &= ~(I2C_CTL0_PECEN);
ctl |= pecstate;
I2C_CTL0(i2c_periph) = ctl;
}
/*!
\brief I2C whether to transfer PEC value
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] pecpara:
\arg I2C_PECTRANS_ENABLE: transfer PEC
\arg I2C_PECTRANS_DISABLE: not transfer PEC
\param[out] none
\retval none
*/
void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara)
{
/* whether to transfer PEC */
uint32_t ctl = 0U;
ctl = I2C_CTL0(i2c_periph);
ctl &= ~(I2C_CTL0_PECTRANS);
ctl |= pecpara;
I2C_CTL0(i2c_periph) = ctl;
}
/*!
\brief get packet error checking value
\param[in] i2c_periph: I2Cx(x=0,1)
\param[out] none
\retval PEC value
*/
uint8_t i2c_pec_value_get(uint32_t i2c_periph)
{
return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_ECV)>>8);
}
/*!
\brief I2C issue alert through SMBA pin
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] smbuspara:
\arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin
\arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin
\param[out] none
\retval none
*/
void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara)
{
/* issue alert through SMBA pin configure*/
uint32_t ctl = 0U;
ctl = I2C_CTL0(i2c_periph);
ctl &= ~(I2C_CTL0_SALT);
ctl |= smbuspara;
I2C_CTL0(i2c_periph) = ctl;
}
/*!
\brief enable or disable I2C ARP protocol in SMBus switch
\param[in] i2c_periph: I2Cx(x=0,1)
\param[in] smbuspara:
\arg I2C_ARP_ENABLE: enable ARP
\arg I2C_ARP_DISABLE: disable ARP
\param[out] none
\retval none
*/
void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate)
{
/* enable or disable I2C ARP protocol*/
uint32_t ctl = 0U;
ctl = I2C_CTL0(i2c_periph);
ctl &= ~(I2C_CTL0_ARPEN);
ctl |= arpstate;
I2C_CTL0(i2c_periph) = ctl;
}