731 lines
21 KiB
C
731 lines
21 KiB
C
/*!
|
|
\file gd32f4xx_i2c.c
|
|
\brief I2C driver
|
|
|
|
*/
|
|
|
|
/*
|
|
Copyright (C) 2016 GigaDevice
|
|
|
|
2016-08-15, V1.0.0, firmware for GD32F4xx
|
|
*/
|
|
|
|
#include "gd32f4xx_i2c.h"
|
|
|
|
#define I2CCLK_MAX 0x3fU /*!< i2cclk max value */
|
|
#define I2C_STATE_MASK 0x0000FFFFU /*!< i2c state mask */
|
|
|
|
/*!
|
|
\brief reset I2C
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_deinit(uint32_t i2c_periph)
|
|
{
|
|
switch(i2c_periph){
|
|
case I2C0:
|
|
rcu_periph_reset_enable(RCU_I2C0RST);
|
|
rcu_periph_reset_disable(RCU_I2C0RST);
|
|
break;
|
|
case I2C1:
|
|
rcu_periph_reset_enable(RCU_I2C1RST);
|
|
rcu_periph_reset_disable(RCU_I2C1RST);
|
|
break;
|
|
case I2C2:
|
|
rcu_periph_reset_enable(RCU_I2C2RST);
|
|
rcu_periph_reset_disable(RCU_I2C2RST);
|
|
break;
|
|
default:
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief I2C clock configure
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] clkspeed: i2c clock speed
|
|
\param[in] dutycyc: duty cycle in fast mode
|
|
\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,i2cclk,risetime;
|
|
pclk1 = rcu_clock_freq_get(CK_APB1);
|
|
/* I2C Peripheral clock frequency */
|
|
i2cclk=((pclk1)/(uint32_t)(1000000));
|
|
if(i2cclk >= I2CCLK_MAX){
|
|
i2cclk = I2CCLK_MAX;
|
|
}
|
|
|
|
I2C_CTL1(i2c_periph) |= (I2C_CTL1_I2CCLK & i2cclk) ;
|
|
|
|
if(100000U >= clkspeed){
|
|
/* standard mode the maximum SCL rise time in standard mode is 1000ns */
|
|
risetime = (uint32_t)((pclk1/1000000U)+1U);
|
|
if(risetime >= I2CCLK_MAX){
|
|
I2C_RT(i2c_periph) |= I2CCLK_MAX;
|
|
}else{
|
|
I2C_RT(i2c_periph) |= (uint32_t)((pclk1/1000000U)+1U);
|
|
}
|
|
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{
|
|
/* fast mode the maximum SCL rise time in standard mode is 300ns */
|
|
I2C_RT(i2c_periph) |= (uint16_t)(((i2cclk*(uint16_t)300)/(uint16_t)1000)+(uint16_t)1);
|
|
if(I2C_DTCY_2 == dutycyc){
|
|
/* I2C_DutyCycle == 2 */
|
|
clkc = (uint16_t)(pclk1/(clkspeed*3U));
|
|
} else{
|
|
/* I2C_DutyCycle == 16/9 */
|
|
clkc = (uint16_t)(pclk1/(clkspeed*25U));
|
|
I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
|
|
}
|
|
if((clkc & I2C_CKCFG_CLKC) == 0U){
|
|
/* The CLKC in standard mode minmum value is 1*/
|
|
clkc |= (uint16_t)0x0001;
|
|
}
|
|
I2C_CKCFG(i2c_periph) |= clkc;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief I2C address configure
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] i2cmod:
|
|
\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 i2cmod,uint32_t addformat,uint32_t addr)
|
|
{
|
|
/* SMBus/I2C mode selected */
|
|
uint32_t ctl = 0U;
|
|
ctl = I2C_CTL0(i2c_periph);
|
|
ctl &= ~(I2C_CTL0_SMBEN);
|
|
ctl |= i2cmod;
|
|
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,2)
|
|
\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,2)
|
|
\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,uint8_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,2)
|
|
\param[in] pos:
|
|
\arg I2C_ACK_ENABLE: ACK will be sent
|
|
\arg I2C_ACK_DISABLE: ACK will not be sent
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_ackpos_config(uint32_t i2c_periph,uint8_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,2)
|
|
\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,uint8_t addr,uint32_t trandirection)
|
|
{
|
|
if(I2C_TRANSMITTER==trandirection){
|
|
addr = (uint8_t)((uint32_t)addr & I2C_TRANSMITTER);
|
|
}else{
|
|
addr = (uint8_t)((uint32_t)addr|I2C_RECEIVER);
|
|
}
|
|
I2C_DATA(i2c_periph) = addr;
|
|
}
|
|
|
|
/*!
|
|
\brief dual-address mode switch
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] dualaddr:
|
|
\arg I2C_DUADEN_DISABLE: dual-address mode disabled
|
|
\arg I2C_DUADEN_ENABLE: dual-address mode enabled
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_dualaddr_enable(uint32_t i2c_periph,uint8_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,2)
|
|
\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,2)
|
|
\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,2)
|
|
\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,2)
|
|
\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,2)
|
|
\param[in] data: data of transmission
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_transmit_data(uint32_t i2c_periph,uint8_t data)
|
|
{
|
|
I2C_DATA(i2c_periph) = data;
|
|
}
|
|
|
|
/*!
|
|
\brief i2c receive data function
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[out] none
|
|
\retval data of received
|
|
*/
|
|
uint8_t i2c_receive_data(uint32_t i2c_periph)
|
|
{
|
|
return (uint8_t)I2C_DATA(i2c_periph);
|
|
}
|
|
|
|
/*!
|
|
\brief I2C DMA mode enable
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] dmastste:
|
|
\arg I2C_DMA_ON: DMA mode enabled
|
|
\arg I2C_DMA_OFF: DMA mode disabled
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_dma_enable(uint32_t i2c_periph,uint32_t dmastste)
|
|
{
|
|
/* configure i2c DMA function */
|
|
uint32_t ctl = 0U;
|
|
ctl = I2C_CTL1(i2c_periph);
|
|
ctl &= ~(I2C_CTL1_DMAON);
|
|
ctl |= dmastste;
|
|
I2C_CTL1(i2c_periph) = ctl;
|
|
|
|
}
|
|
|
|
/*!
|
|
\brief flag indicating DMA last transfer
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] dmastste:
|
|
\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,2)
|
|
\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 Cal
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\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,2)
|
|
\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 state
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] state:
|
|
\arg I2C_SBSEND: start condition send out
|
|
\arg I2C_ADDSEND: address is sent in master mode or received and matches in slave mode
|
|
\arg I2C_BTC: byte transmission finishes
|
|
\arg I2C_ADD10SEND: header of 10-bit address is sent in master mode
|
|
\arg I2C_STPDET: etop condition detected in slave mode
|
|
\arg I2C_RBNE: I2C_DATA is not Empty during receiving
|
|
\arg I2C_TBE: I2C_DATA is empty during transmitting
|
|
\arg I2C_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus
|
|
\arg I2C_LOSTARB: arbitration lost in master mode
|
|
\arg I2C_AERR: acknowledge error
|
|
\arg I2C_OUERR: over-run or under-run situation occurs in slave mode
|
|
\arg I2C_PECERR: PEC error when receiving data
|
|
\arg I2C_SMBTO: timeout signal in SMBus mode
|
|
\arg I2C_SMBALT: SMBus alert status
|
|
\arg I2C_MASTER: a flag indicating whether I2C block is in master or slave mode
|
|
\arg I2C_I2CBSY: busy flag
|
|
\arg I2C_TRS: whether the I2C is a transmitter or a receiver
|
|
\arg I2C_RXGC: general call address (00h) received
|
|
\arg I2C_DEFSMB: default address of SMBus device
|
|
\arg I2C_HSTSMB: SMBus host header detected in slave mode
|
|
\arg I2C_DUMODF: dual flag in slave mode indicating which address is matched in dual-address mode
|
|
\param[out] none
|
|
\retval state of i2c
|
|
*/
|
|
FlagStatus i2c_flag_get(uint32_t i2c_periph,uint32_t state )
|
|
{
|
|
uint32_t reg = 0U;
|
|
FlagStatus regstate = RESET;
|
|
/* get the state in which register */
|
|
reg = (BIT(31) & state);
|
|
if((BIT(31) == reg)){
|
|
if((I2C_STAT1(i2c_periph)&(state & I2C_STATE_MASK))){
|
|
regstate = SET;
|
|
}else{
|
|
regstate = RESET;
|
|
}
|
|
}else{
|
|
if((I2C_STAT0(i2c_periph)&(state & I2C_STATE_MASK))){
|
|
regstate = SET;
|
|
}else{
|
|
regstate = RESET;
|
|
}
|
|
}
|
|
/* return the state */
|
|
return regstate;
|
|
}
|
|
|
|
/*!
|
|
\brief clear i2c state
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] state: state type
|
|
\@arg I2C_STAT0_SMBALT: SMBus Alert status
|
|
\@arg I2C_STAT0_SMBTO: timeout signal in SMBus mode
|
|
\@arg I2C_STAT0_PECERR: PEC error when receiving data
|
|
\@arg I2C_STAT0_OUERR: over-run or under-run situation occurs in slave mode
|
|
\@arg I2C_STAT0_AERR: acknowledge error
|
|
\@arg I2C_STAT0_LOSTARB: arbitration lost in master mode
|
|
\@arg I2C_STAT0_BERR: a bus error
|
|
\@arg I2C_STAT0_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 state)
|
|
{
|
|
if(I2C_STAT0_ADDSEND == state){
|
|
/* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
|
|
I2C_STAT0(i2c_periph);
|
|
I2C_STAT1(i2c_periph);
|
|
}else{
|
|
I2C_STAT0(i2c_periph) &= ~(state);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief enable i2c interrupt
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] inttype: interrupt type
|
|
\arg I2C_CTL1_ERRIE: error interrupt enable
|
|
\arg I2C_CTL1_EVIE: event interrupt enable
|
|
\arg I2C_CTL1_BUFIE: 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,2)
|
|
\param[in] inttype: interrupt type
|
|
\arg I2C_CTL1_ERRIE: error interrupt enable
|
|
\arg I2C_CTL1_EVIE: event interrupt enable
|
|
\arg I2C_CTL1_BUFIE: 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 I2C PEC calculation on or off
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\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,2)
|
|
\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 packet error checking value
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[out] none
|
|
\retval PEC value
|
|
*/
|
|
uint8_t i2c_pec_value(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,2)
|
|
\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_alert_issue(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 I2C ARP protocol in SMBus switch enable or disable
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] smbuspara:
|
|
\arg I2C_ARP_ENABLE: ARP is enabled
|
|
\arg I2C_ARP_DISABLE: ARP is disabled
|
|
\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;
|
|
}
|
|
|
|
/*!
|
|
\brief analog noise filter disable
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_analog_noise_filter_disable(uint32_t i2c_periph)
|
|
{
|
|
I2C_FCTL(i2c_periph) |= I2C_FCTL_AFD;
|
|
}
|
|
|
|
/*!
|
|
\brief analog noise filter enable
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_analog_noise_filter_enable(uint32_t i2c_periph)
|
|
{
|
|
I2C_FCTL(i2c_periph) &= ~(I2C_FCTL_AFD);
|
|
}
|
|
|
|
/*!
|
|
\brief digital noise filter configuration
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] dfilterpara: refer to enum i2c_gcall_config_enum
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_digital_noise_filter_config(uint32_t i2c_periph,i2c_digital_filter_enum dfilterpara)
|
|
{
|
|
I2C_FCTL(i2c_periph) |= dfilterpara;
|
|
}
|
|
|
|
/*!
|
|
\brief enable SAM_V interface
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_sam_enable(uint32_t i2c_periph)
|
|
{
|
|
I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN;
|
|
}
|
|
|
|
/*!
|
|
\brief disable SAM_V interface
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_sam_disable(uint32_t i2c_periph)
|
|
{
|
|
I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN);
|
|
}
|
|
|
|
/*!
|
|
\brief enable SAM_V interface timeout detect
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_sam_timeout_enable(uint32_t i2c_periph)
|
|
{
|
|
I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN;
|
|
}
|
|
|
|
/*!
|
|
\brief disable SAM_V interface timeout detect
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_sam_timeout_disable(uint32_t i2c_periph)
|
|
{
|
|
I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN);
|
|
}
|
|
|
|
/*!
|
|
\brief enable the specified I2C SAM interrupt
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] inttype: interrupt type
|
|
\@arg I2C_SAMCS_TFFIE: txframe fall interrupt
|
|
\@arg I2C_SAMCS_TFRIE: txframe rise interrupt
|
|
\@arg I2C_SAMCS_RFFIE: rxframe fall interrupt
|
|
\@arg I2C_SAMCS_RFRIE: rxframe rise interrupt
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_sam_interrupt_enable(uint32_t i2c_periph,uint32_t inttype)
|
|
{
|
|
I2C_SAMCS(i2c_periph) |= (inttype);
|
|
}
|
|
|
|
/*!
|
|
\brief disable i2c interrupt
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] inttype: interrupt type
|
|
\@arg I2C_SAMCS_TFFIE: txframe fall interrupt
|
|
\@arg I2C_SAMCS_TFRIE: txframe rise interrupt
|
|
\@arg I2C_SAMCS_RFFIE: rxframe fall interrupt
|
|
\@arg I2C_SAMCS_RFRIE: rxframe rise interrupt
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_sam_interrupt_disable(uint32_t i2c_periph,uint32_t inttype)
|
|
{
|
|
I2C_SAMCS(i2c_periph) &= ~(inttype);
|
|
}
|
|
|
|
/*!
|
|
\brief check i2c SAM state
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] samstate: state type
|
|
\@arg I2C_SAMCS_TXF: level of txframe signal
|
|
\@arg I2C_SAMCS_RXF: level of rxframe signal
|
|
\@arg I2C_SAMCS_TFF: txframe fall flag
|
|
\@arg I2C_SAMCS_TFR: txframe rise flag
|
|
\@arg I2C_SAMCS_RFF: rxframe fall flag
|
|
\@arg I2C_SAMCS_RFR: rxframe rise flag
|
|
\param[out] none
|
|
\retval state of i2c SAM
|
|
*/
|
|
FlagStatus i2c_sam_flag_get(uint32_t i2c_periph,uint32_t samstate)
|
|
{
|
|
FlagStatus reg = RESET;
|
|
if(I2C_SAMCS(i2c_periph)&samstate){
|
|
reg =SET;
|
|
}else{
|
|
reg =RESET;
|
|
}
|
|
return reg;
|
|
}
|
|
|
|
/*!
|
|
\brief clear i2c SAM state
|
|
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
|
\param[in] samstate: state type
|
|
\@arg I2C_SAMCS_TFF: txframe fall flag
|
|
\@arg I2C_SAMCS_TFR: txframe rise flag
|
|
\@arg I2C_SAMCS_RFF: rxframe fall flag
|
|
\@arg I2C_SAMCS_RFR: rxframe rise flag
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void i2c_sam_flag_clear(uint32_t i2c_periph,uint32_t samstate)
|
|
{
|
|
I2C_SAMCS(i2c_periph) &= ~(samstate);
|
|
|
|
}
|
|
|