コード例 #1
0
ファイル: cmem7_i2c.c プロジェクト: 54chenjq/rt-thread
static uint16_t i2c_NormalizeAddr(I2C0_Type* I2Cx, uint16_t addr) {
  assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	
	if (I2Cx->CTRL_b.MODE == I2C_Mode_Master) {
		if (I2Cx->CTRL_b.MASTER_ADDR_WIDTH == I2C_ADDR_WIDTH_7BIT) {
			addr &= 0x007F;
		} else {
			addr &= 0x3FF;
		}
	}
	
	if (I2Cx->CTRL_b.MODE == I2C_Mode_Slave) {
		if (I2Cx->CTRL_b.SLAVE_ADDR_WIDTH == I2C_ADDR_WIDTH_7BIT) {
			addr &= 0x007F;
		} else {
			addr &= 0x3FF;
		}
	}
	
	return addr;
}
コード例 #2
0
ファイル: rtl876x_i2c.c プロジェクト: wanghao-xznu/BumbleBee1
/**
  * @brief  Send data in master mode through the I2Cx peripheral.
  * @param  I2Cx: where x can be 0 or 1 to select the I2C peripheral.
  * @param  Data: Byte to be transmitted..
  * @retval None
  */
void I2C_MasterWrite(I2C_TypeDef* I2Cx, uint8_t* pBuf, uint8_t len)
{
    uint8_t cnt = 0;
    /* Check the parameters */
    assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  
    /* Write in the DR register the data to be sent */
    for(cnt = 0; cnt < len; cnt++)
    {
        if(cnt >= len - 1)
        {
            /*generate stop signal*/
            I2Cx->IC_DATA_CMD = (*pBuf++) | (1 << 9);
        }
        else
        {
            I2Cx->IC_DATA_CMD = *pBuf++;
        }
		/* wait for flag of I2C_FLAG_MST_ACTIVITY */
        while((I2Cx->IC_STATUS & (1 << 5)) == 1);
    }   
}
コード例 #3
0
/**
  * @brief  Checks whether the specified I2C flag is set or not.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  I2C_FLAG: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg I2C_FLAG_DUALF: Dual flag (Slave mode)
  *     @arg I2C_FLAG_SMBHOST: SMBus host header (Slave mode)
  *     @arg I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode)
  *     @arg I2C_FLAG_GENCALL: General call header flag (Slave mode)
  *     @arg I2C_FLAG_TRA: Transmitter/Receiver flag
  *     @arg I2C_FLAG_BUSY: Bus busy flag
  *     @arg I2C_FLAG_MSL: Master/Slave flag
  *     @arg I2C_FLAG_SMBALERT: SMBus Alert flag
  *     @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag
  *     @arg I2C_FLAG_PECERR: PEC error in reception flag
  *     @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)
  *     @arg I2C_FLAG_AF: Acknowledge failure flag
  *     @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)
  *     @arg I2C_FLAG_BERR: Bus error flag
  *     @arg I2C_FLAG_TXE: Data register empty flag (Transmitter)
  *     @arg I2C_FLAG_RXNE: Data register not empty (Receiver) flag
  *     @arg I2C_FLAG_STOPF: Stop detection flag (Slave mode)
  *     @arg I2C_FLAG_ADD10: 10-bit header sent flag (Master mode)
  *     @arg I2C_FLAG_BTF: Byte transfer finished flag
  *     @arg I2C_FLAG_ADDR: Address sent flag (Master mode) "ADSL"
  *   Address matched flag (Slave mode)"ENDA"
  *     @arg I2C_FLAG_SB: Start bit flag (Master mode)
  * @retval The new state of I2C_FLAG (SET or RESET).
  */
FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) {
    FlagStatus bitstatus = RESET;
    __IO uint32_t i2creg = 0, i2cxbase = 0;

    /* Check the parameters */
    assert_param(IS_I2C_ALL_PERIPH(I2Cx));
    assert_param(IS_I2C_GET_FLAG(I2C_FLAG));

    /* Get the I2Cx peripheral base address */
    i2cxbase = (uint32_t)I2Cx;

    /* Read flag register index */
    i2creg = I2C_FLAG >> 28;

    /* Get bit[23:0] of the flag */
    I2C_FLAG &= FLAG_Mask;

    if(i2creg != 0) {
        /* Get the I2Cx SR1 register address */
        i2cxbase += 0x14;
    } else {
        /* Flag in I2Cx SR2 Register */
        I2C_FLAG = (uint32_t)(I2C_FLAG >> 16);
        /* Get the I2Cx SR2 register address */
        i2cxbase += 0x18;
    }

    if(((*(__IO uint32_t*)i2cxbase) & I2C_FLAG) != (uint32_t)RESET) {
        /* I2C_FLAG is set */
        bitstatus = SET;
    } else {
        /* I2C_FLAG is reset */
        bitstatus = RESET;
    }

    /* Return the I2C_FLAG status */
    return bitstatus;
}
コード例 #4
0
ファイル: cmem7_i2c.c プロジェクト: 54chenjq/rt-thread
void I2C_ClearStatus(I2C0_Type* I2Cx, uint32_t Status) {
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	assert_param(IS_I2C_STATUS(Status));
	
	if (Status & I2C_STATUS_RX_FIFO_NOT_EMPTY) {
		// It can't be clear by sw but read
	} 
	
	if (Status & I2C_STATUS_RD_REQUEST) {
		i2c_ReadClear(I2Cx->CLR_RD_REQ_b.CLEAR);
	} 
	
	if (Status & I2C_STATUS_TX_ABORT) {
		i2c_ReadClear(I2Cx->CLR_TX_ABRT_b.CLEAR);
	} 
	
	if (Status & I2C_STATUS_RX_DONE) {
		i2c_ReadClear(I2Cx->CLR_RX_DONE_b.CLEAR);
	} 
	
	if (Status & I2C_STATUS_TX_DONE) {
		i2c_ReadClear(I2Cx->CLR_TX_DONE_b.CLEAR);
	} 
}
コード例 #5
0
ファイル: cmem7_i2c.c プロジェクト: 54chenjq/rt-thread
void I2C_ClearInt(I2C0_Type* I2Cx, uint32_t Int) {
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	assert_param(IS_I2C_INT(Int));
	
	if (Int == I2C_INT_RX_FIFO_NOT_EMPTY) {
		// It can't be clear by sw but read data
	} 
	
	if (Int == I2C_INT_RD_REQUEST) {
		i2c_ReadClear(I2Cx->CLR_RD_REQ_b.CLEAR);
	} 
	
	if (Int == I2C_INT_TX_ABORT) {
		i2c_ReadClear(I2Cx->CLR_TX_ABRT_b.CLEAR);
	} 
	
	if (Int == I2C_INT_RX_DONE) {
		i2c_ReadClear(I2Cx->CLR_RX_DONE_b.CLEAR);
	} 
	
	if (Int == I2C_INT_TX_DONE) {
		i2c_ReadClear(I2Cx->CLR_TX_DONE_b.CLEAR);
	} 
}
コード例 #6
0
/**
  * @brief  Initializes the I2Cx peripheral according to the specified 
  *   parameters in the I2C_InitStruct.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  I2C_InitStruct: pointer to a I2C_InitTypeDef structure that
  *   contains the configuration information for the specified I2C peripheral.
  * @retval None
  */
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)
{
  uint16_t tmpreg = 0, freqrange = 0;
  uint16_t result = 0x04;
  uint32_t pclk1 = 8000000;
  RCC_ClocksTypeDef  rcc_clocks;
  /* Check the parameters */
  assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->I2C_ClockSpeed));
  assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode));
  assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle));
  assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1));
  assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack));
  assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress));

/*---------------------------- I2Cx CR2 Configuration ------------------------*/
  /* Get the I2Cx CR2 value */
  tmpreg = I2Cx->CR2;
  /* Clear frequency FREQ[5:0] bits */
  tmpreg &= CR2_FREQ_Reset;
  /* Get pclk1 frequency value */
  RCC_GetClocksFreq(&rcc_clocks);
  pclk1 = rcc_clocks.PCLK1_Frequency;
  /* Set frequency bits depending on pclk1 value */
  freqrange = (uint16_t)(pclk1 / 1000000);
  tmpreg |= freqrange;
  /* Write to I2Cx CR2 */
  I2Cx->CR2 = tmpreg;

/*---------------------------- I2Cx CCR Configuration ------------------------*/
  /* Disable the selected I2C peripheral to configure TRISE */
  I2Cx->CR1 &= CR1_PE_Reset;
  /* Reset tmpreg value */
  /* Clear F/S, DUTY and CCR[11:0] bits */
  tmpreg = 0;

  /* Configure speed in standard mode */
  if (I2C_InitStruct->I2C_ClockSpeed <= 100000)
  {
    /* Standard mode speed calculate */
    result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1));
    /* Test if CCR value is under 0x4*/
    if (result < 0x04)
    {
      /* Set minimum allowed value */
      result = 0x04;  
    }
    /* Set speed value for standard mode */
    tmpreg |= result;	  

    // [ILG]
    #if defined ( __GNUC__ )
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wconversion"
    #endif

    /* Set Maximum Rise Time for standard mode */
    I2Cx->TRISE = freqrange + 1;
    
    // [ILG]
    #if defined ( __GNUC__ )
    #pragma GCC diagnostic pop
    #endif
    
  }
  /* Configure speed in fast mode */
  else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/
  {
    if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2)
    {
      /* Fast mode speed calculate: Tlow/Thigh = 2 */
      result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3));
    }
    else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/
    {
      /* Fast mode speed calculate: Tlow/Thigh = 16/9 */
      result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25));
      /* Set DUTY bit */
      result |= I2C_DutyCycle_16_9;
    }

    /* Test if CCR value is under 0x1*/
    if ((result & CCR_CCR_Set) == 0)
    {
      /* Set minimum allowed value */
      result |= (uint16_t)0x0001;  
    }
    /* Set speed value and set F/S bit for fast mode */
    tmpreg |= (uint16_t)(result | CCR_FS_Set);
    /* Set Maximum Rise Time for fast mode */
    I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1);  
  }

  /* Write to I2Cx CCR */
  I2Cx->CCR = tmpreg;
  /* Enable the selected I2C peripheral */
  I2Cx->CR1 |= CR1_PE_Set;

/*---------------------------- I2Cx CR1 Configuration ------------------------*/
  /* Get the I2Cx CR1 value */
  tmpreg = I2Cx->CR1;
  /* Clear ACK, SMBTYPE and  SMBUS bits */
  tmpreg &= CR1_CLEAR_Mask;
  /* Configure I2Cx: mode and acknowledgement */
  /* Set SMBTYPE and SMBUS bits according to I2C_Mode value */
  /* Set ACK bit according to I2C_Ack value */
  tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack);
  /* Write to I2Cx CR1 */
  I2Cx->CR1 = tmpreg;

/*---------------------------- I2Cx OAR1 Configuration -----------------------*/
  /* Set I2Cx Own Address1 and acknowledged address */
  I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1);
}
コード例 #7
0
ファイル: rtl876x_i2c.c プロジェクト: wanghao-xznu/BumbleBee1
/**
  * @brief  Initializes the I2Cx peripheral according to the specified 
  *   parameters in the I2C_InitStruct.
  * @param  I2Cx: where x can be 0 or 1 to select the I2C peripheral.
  * @param  I2C_InitStruct: pointer to a I2C_InitTypeDef structure that
  *   contains the configuration information for the specified I2C peripheral.
  * @retval None
  */
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)
{
    /* Check the parameters */
    assert_param(IS_I2C_ALL_PERIPH(I2Cx));
    assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->I2C_ClockSpeed));

    /* Disable I2C device before change configuration */
    I2Cx->IC_ENABLE &= ~0x0001; 

    /* ------------------------------ Initialize I2C device ------------------------------*/
    if(I2C_DeviveMode_Master == I2C_InitStruct->I2C_DeviveMode)
    {
        /*configure I2C device mode which can be selected for master or slave*/
        I2Cx->IC_CON = I2C_InitStruct->I2C_DeviveMode |(I2C_InitStruct->I2C_AddressMode << 4)| BIT(5);
        
        /*set target address*/
        I2Cx->IC_TAR = (I2C_InitStruct->I2C_SlaveAddress & 0x3ff)
                        |(I2C_InitStruct->I2C_AddressMode << 12);
        /*set SDA hold time in master mode*/
        I2Cx->IC_SDA_HOLD = 0x01;
        
        #if 1
        /*set Tx empty level*/
        I2Cx->IC_TX_TL = 0;
        /*set Rx full level*/
        I2Cx->IC_RX_TL = 0;
        #endif
    }
    else
    {
		/* set to slave mode */
		I2Cx->IC_CON = (I2C_InitStruct->I2C_DeviveMode) | (I2C_InitStruct->I2C_AddressMode << 3);
        /* set Ack in slave mode */
        I2Cx->IC_ACK_GENERAL_CALL &= I2C_InitStruct->I2C_Ack;
        /* set slave address */
        I2Cx->IC_SAR = I2C_InitStruct->I2C_SlaveAddress;      
        /* set SDA hold time in slave mode */
        I2Cx->IC_SDA_HOLD = 0x07;
        /* set SDA setup time delay only in slave mode(master greater than 2) ,delay time:[(IC_SDA_SETUP - 1) * (ic_clk_period)]*/
        I2Cx->IC_SDA_SETUP = 0x02;
    }    

    /*------------------------------ configure I2C speed ------------------------------*/
    /*Configure I2C speed in standard mode*/
    if (I2C_InitStruct->I2C_ClockSpeed < 100000)
    {
        I2Cx->IC_CON &= 0xfffb;
        /*configure I2C speed*/
        I2Cx->IC_SS_SCL_HCNT = 20 + (4000*(PLATFORM_CLOCK/10000)) / (I2C_InitStruct->I2C_ClockSpeed);
        I2Cx->IC_SS_SCL_LCNT = 20 + (4700*(PLATFORM_CLOCK/10000)) / (I2C_InitStruct->I2C_ClockSpeed);
    }
    /*Configure I2C speed in fast mode*/
    else if(I2C_InitStruct->I2C_ClockSpeed <= 400000)
    {
        
        I2Cx->IC_CON &= 0xfffd;
        if(I2C_InitStruct->I2C_ClockSpeed == 100000)
        {
            /*configure I2C speed*/
            I2Cx->IC_FS_SCL_HCNT = 66 + (600*(PLATFORM_CLOCK/10000)*4) / (I2C_InitStruct->I2C_ClockSpeed);
            I2Cx->IC_FS_SCL_LCNT = 10 + (1300*(PLATFORM_CLOCK/10000)) / (I2C_InitStruct->I2C_ClockSpeed);
        }
        else if(I2C_InitStruct->I2C_ClockSpeed == 200000)
        {
            /*configure I2C speed*/
            I2Cx->IC_FS_SCL_HCNT = 32 + (600*(PLATFORM_CLOCK/10000)*4) / (I2C_InitStruct->I2C_ClockSpeed);
            I2Cx->IC_FS_SCL_LCNT = (1300*(PLATFORM_CLOCK/10000)*4) / (I2C_InitStruct->I2C_ClockSpeed);
        }
        else
        {
            if(I2C_InitStruct->I2C_ClockSpeed == 400000)
            {
                /*configure I2C speed*/
                I2Cx->IC_FS_SCL_HCNT = 8 + (600*(PLATFORM_CLOCK/10000)*4) / (I2C_InitStruct->I2C_ClockSpeed);
                I2Cx->IC_FS_SCL_LCNT = 1 + (1300*(PLATFORM_CLOCK/10000)*4) / (I2C_InitStruct->I2C_ClockSpeed);
            }
        }
    }
    /*Configure I2C speed in high mode*/
    else
    {
        if(I2C_InitStruct->I2C_ClockSpeed <= 3400000)
        {
            /*configure I2C speed*/
            I2Cx->IC_HS_SCL_HCNT = 8 + (60*(PLATFORM_CLOCK/10000)*30) / (I2C_InitStruct->I2C_ClockSpeed);
            I2Cx->IC_HS_SCL_LCNT = 1 + (120*(PLATFORM_CLOCK/10000)*30) / (I2C_InitStruct->I2C_ClockSpeed);
        }
    }   
}
コード例 #8
0
ファイル: rtl876x_i2c.c プロジェクト: wanghao-xznu/BumbleBee1
/**
  * @brief  Sends data and read data in master mode through the I2Cx peripheral.Attention:Read data with time out mechanism.
  * @param  I2Cx: where x can be 0 or 1 to select the I2C peripheral.
  * @param  Data: Byte to be transmitted..
  * @retval Actual length of read data 
  */
uint8_t I2C_RepeatRead(I2C_TypeDef* I2Cx, uint8_t* pWriteBuf, uint8_t Writelen, uint8_t* pReadBuf, uint8_t Readlen)
{
    uint8_t cnt = 0;
    uint32_t reg_value = 0;
    uint8_t rev_len = 0;
    uint32_t time_out = 0xfffff;
    
    /* Check the parameters */
    assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  
    /*------------------------------ write data section ------------------------------*/
    /* write data in the IC_DATA_CMD register */
    for(cnt = 0; cnt < Writelen; cnt++)
    {
    
        #if 0
        /*wait for I2C_FLAG_TFNF flag that Tx FIFO is not full*/
        while((I2Cx->IC_STATUS & BIT(1)) == 0);
        #endif
        
        I2Cx->IC_DATA_CMD = *pWriteBuf++;
    }
    
    /*------------------------------ read data section ------------------------------*/
    for(cnt = 0; cnt < Readlen; cnt++)
    {
        if(cnt >= Readlen - 1)
        {
            /*generate stop singal in last byte which to be sent*/
            I2Cx->IC_DATA_CMD = reg_value | BIT(8) |BIT(9);
        }
        else
        {
            I2Cx->IC_DATA_CMD = reg_value | BIT(8);      
        }
        
        /*read data */
        if(cnt > 0)
        {
            /*wait for I2C_FLAG_RFNE flag*/
			time_out = 0xfffff;
            while(((I2Cx->IC_STATUS & BIT(3))==0) && (time_out!=0))
            {
                time_out--;
            }
            if(time_out > 0)
            {
                *pReadBuf++ = (uint8_t)I2Cx->IC_DATA_CMD;
                rev_len++;
            }
        }
    }

    /*read data*/
    time_out = 0xfffff;
    while(((I2Cx->IC_STATUS & BIT(3))==0) && (time_out!=0))
    {
        time_out--;
    }
    if(time_out > 0)
    {
        *pReadBuf = (uint8_t)I2Cx->IC_DATA_CMD;
        rev_len++;
    }
    
    return rev_len;
}
コード例 #9
0
ファイル: cmem7_i2c.c プロジェクト: 54chenjq/rt-thread
void I2C_Enable(I2C0_Type* I2Cx, BOOL enable) {
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	
  I2Cx->ENABLE_b.EN = enable;
}
コード例 #10
0
/**
  * @brief  Returns the PEC value for the specified I2C.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @retval The PEC value.
  */
uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx) {
    /* Check the parameters */
    assert_param(IS_I2C_ALL_PERIPH(I2Cx));
    /* Return the selected I2C PEC value */
    return ((I2Cx->SR2) >> 8);
}
コード例 #11
0
/**
  * @brief  Returns the most recent received data by the I2Cx peripheral.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @retval The value of the received data.
  */
uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx) {
    /* Check the parameters */
    assert_param(IS_I2C_ALL_PERIPH(I2Cx));
    /* Return the data in the DR register */
    return (uint8_t)I2Cx->DR;
}
コード例 #12
0
/**
  * @brief  Sends a data byte through the I2Cx peripheral.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  Data: Byte to be transmitted..
  * @retval None
  */
void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data) {
    /* Check the parameters */
    assert_param(IS_I2C_ALL_PERIPH(I2Cx));
    /* Write in the DR register the data to be sent */
    I2Cx->DR = Data;
}