From 1d3861ef93f8423176c6010ab606abdab00a7cbd Mon Sep 17 00:00:00 2001 From: bnewbold Date: Wed, 31 Mar 2010 08:52:45 +0800 Subject: Major hierarchy reorganization; see README. copy-to-ide and Makefile updated to conform; .gitignore added; LICENSE added --- stm32lib/src/stm32f10x_i2c.c | 1216 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1216 insertions(+) create mode 100644 stm32lib/src/stm32f10x_i2c.c (limited to 'stm32lib/src/stm32f10x_i2c.c') diff --git a/stm32lib/src/stm32f10x_i2c.c b/stm32lib/src/stm32f10x_i2c.c new file mode 100644 index 0000000..360f71d --- /dev/null +++ b/stm32lib/src/stm32f10x_i2c.c @@ -0,0 +1,1216 @@ +/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +* File Name : stm32f10x_i2c.c +* Author : MCD Application Team +* Version : V2.0.2 +* Date : 07/11/2008 +* Description : This file provides all the I2C firmware functions. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_i2c.h" +#include "stm32f10x_rcc.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* I2C SPE mask */ +#define CR1_PE_Set ((u16)0x0001) +#define CR1_PE_Reset ((u16)0xFFFE) + +/* I2C START mask */ +#define CR1_START_Set ((u16)0x0100) +#define CR1_START_Reset ((u16)0xFEFF) + +/* I2C STOP mask */ +#define CR1_STOP_Set ((u16)0x0200) +#define CR1_STOP_Reset ((u16)0xFDFF) + +/* I2C ACK mask */ +#define CR1_ACK_Set ((u16)0x0400) +#define CR1_ACK_Reset ((u16)0xFBFF) + +/* I2C ENGC mask */ +#define CR1_ENGC_Set ((u16)0x0040) +#define CR1_ENGC_Reset ((u16)0xFFBF) + +/* I2C SWRST mask */ +#define CR1_SWRST_Set ((u16)0x8000) +#define CR1_SWRST_Reset ((u16)0x7FFF) + +/* I2C PEC mask */ +#define CR1_PEC_Set ((u16)0x1000) +#define CR1_PEC_Reset ((u16)0xEFFF) + +/* I2C ENPEC mask */ +#define CR1_ENPEC_Set ((u16)0x0020) +#define CR1_ENPEC_Reset ((u16)0xFFDF) + +/* I2C ENARP mask */ +#define CR1_ENARP_Set ((u16)0x0010) +#define CR1_ENARP_Reset ((u16)0xFFEF) + +/* I2C NOSTRETCH mask */ +#define CR1_NOSTRETCH_Set ((u16)0x0080) +#define CR1_NOSTRETCH_Reset ((u16)0xFF7F) + +/* I2C registers Masks */ +#define CR1_CLEAR_Mask ((u16)0xFBF5) + +/* I2C DMAEN mask */ +#define CR2_DMAEN_Set ((u16)0x0800) +#define CR2_DMAEN_Reset ((u16)0xF7FF) + +/* I2C LAST mask */ +#define CR2_LAST_Set ((u16)0x1000) +#define CR2_LAST_Reset ((u16)0xEFFF) + +/* I2C FREQ mask */ +#define CR2_FREQ_Reset ((u16)0xFFC0) + +/* I2C ADD0 mask */ +#define OAR1_ADD0_Set ((u16)0x0001) +#define OAR1_ADD0_Reset ((u16)0xFFFE) + +/* I2C ENDUAL mask */ +#define OAR2_ENDUAL_Set ((u16)0x0001) +#define OAR2_ENDUAL_Reset ((u16)0xFFFE) + +/* I2C ADD2 mask */ +#define OAR2_ADD2_Reset ((u16)0xFF01) + +/* I2C F/S mask */ +#define CCR_FS_Set ((u16)0x8000) + +/* I2C CCR mask */ +#define CCR_CCR_Set ((u16)0x0FFF) + +/* I2C FLAG mask */ +#define FLAG_Mask ((u32)0x00FFFFFF) + +/* I2C Interrupt Enable mask */ +#define ITEN_Mask ((u32)0x07000000) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : I2C_DeInit +* Description : Deinitializes the I2Cx peripheral registers to their default +* reset values. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_DeInit(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + switch (*(u32*)&I2Cx) + { + case I2C1_BASE: + /* Enable I2C1 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); + /* Release I2C1 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); + break; + + case I2C2_BASE: + /* Enable I2C2 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); + /* Release I2C2 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE); + break; + + default: + break; + } +} + +/******************************************************************************* +* Function Name : I2C_Init +* Description : Initializes the I2Cx peripheral according to the specified +* parameters in the I2C_InitStruct. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - I2C_InitStruct: pointer to a I2C_InitTypeDef structure that +* contains the configuration information for the specified +* I2C peripheral. +* Output : None +* Return : None +******************************************************************************/ +void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct) +{ + u16 tmpreg = 0, freqrange = 0; + u16 result = 0x04; + u32 pclk1 = 8000000; + RCC_ClocksTypeDef rcc_clocks; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + 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)); + assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->I2C_ClockSpeed)); + +/*---------------------------- 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 = (u16)(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 = (u16)(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; + /* Set Maximum Rise Time for standard mode */ + I2Cx->TRISE = freqrange + 1; + } + /* 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 = (u16)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3)); + } + else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/ + { + /* Fast mode speed calculate: Tlow/Thigh = 16/9 */ + result = (u16)(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 |= (u16)0x0001; + } + /* Set speed value and set F/S bit for fast mode */ + tmpreg |= result | CCR_FS_Set; + /* Set Maximum Rise Time for fast mode */ + I2Cx->TRISE = (u16)(((freqrange * 300) / 1000) + 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 |= (u16)((u32)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); +} + +/******************************************************************************* +* Function Name : I2C_StructInit +* Description : Fills each I2C_InitStruct member with its default value. +* Input : - I2C_InitStruct: pointer to an I2C_InitTypeDef structure +* which will be initialized. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct) +{ +/*---------------- Reset I2C init structure parameters values ----------------*/ + /* Initialize the I2C_Mode member */ + I2C_InitStruct->I2C_Mode = I2C_Mode_I2C; + + /* Initialize the I2C_DutyCycle member */ + I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2; + + /* Initialize the I2C_OwnAddress1 member */ + I2C_InitStruct->I2C_OwnAddress1 = 0; + + /* Initialize the I2C_Ack member */ + I2C_InitStruct->I2C_Ack = I2C_Ack_Disable; + + /* Initialize the I2C_AcknowledgedAddress member */ + I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; + + /* initialize the I2C_ClockSpeed member */ + I2C_InitStruct->I2C_ClockSpeed = 5000; +} + +/******************************************************************************* +* Function Name : I2C_Cmd +* Description : Enables or disables the specified I2C peripheral. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2Cx peripheral. This parameter +* can be: ENABLE or DISABLE. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C peripheral */ + I2Cx->CR1 |= CR1_PE_Set; + } + else + { + /* Disable the selected I2C peripheral */ + I2Cx->CR1 &= CR1_PE_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_DMACmd +* Description : Enables or disables the specified I2C DMA requests. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2C DMA transfer. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C DMA requests */ + I2Cx->CR2 |= CR2_DMAEN_Set; + } + else + { + /* Disable the selected I2C DMA requests */ + I2Cx->CR2 &= CR2_DMAEN_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_DMALastTransferCmd +* Description : Specifies that the next DMA transfer is the last one. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2C DMA last transfer. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Next DMA transfer is the last transfer */ + I2Cx->CR2 |= CR2_LAST_Set; + } + else + { + /* Next DMA transfer is not the last transfer */ + I2Cx->CR2 &= CR2_LAST_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_GenerateSTART +* Description : Generates I2Cx communication START condition. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2C START condition generation. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None. +*******************************************************************************/ +void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Generate a START condition */ + I2Cx->CR1 |= CR1_START_Set; + } + else + { + /* Disable the START condition generation */ + I2Cx->CR1 &= CR1_START_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_GenerateSTOP +* Description : Generates I2Cx communication STOP condition. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2C STOP condition generation. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None. +*******************************************************************************/ +void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Generate a STOP condition */ + I2Cx->CR1 |= CR1_STOP_Set; + } + else + { + /* Disable the STOP condition generation */ + I2Cx->CR1 &= CR1_STOP_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_AcknowledgeConfig +* Description : Enables or disables the specified I2C acknowledge feature. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2C Acknowledgement. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None. +*******************************************************************************/ +void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the acknowledgement */ + I2Cx->CR1 |= CR1_ACK_Set; + } + else + { + /* Disable the acknowledgement */ + I2Cx->CR1 &= CR1_ACK_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_OwnAddress2Config +* Description : Configures the specified I2C own address2. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - Address: specifies the 7bit I2C own address2. +* Output : None +* Return : None. +*******************************************************************************/ +void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, u8 Address) +{ + u16 tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Get the old register value */ + tmpreg = I2Cx->OAR2; + /* Reset I2Cx Own address2 bit [7:1] */ + tmpreg &= OAR2_ADD2_Reset; + /* Set I2Cx Own address2 */ + tmpreg |= (u16)(Address & (u16)0x00FE); + /* Store the new register value */ + I2Cx->OAR2 = tmpreg; +} + +/******************************************************************************* +* Function Name : I2C_DualAddressCmd +* Description : Enables or disables the specified I2C dual addressing mode. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2C dual addressing mode. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable dual addressing mode */ + I2Cx->OAR2 |= OAR2_ENDUAL_Set; + } + else + { + /* Disable dual addressing mode */ + I2Cx->OAR2 &= OAR2_ENDUAL_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_GeneralCallCmd +* Description : Enables or disables the specified I2C general call feature. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2C General call. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable generall call */ + I2Cx->CR1 |= CR1_ENGC_Set; + } + else + { + /* Disable generall call */ + I2Cx->CR1 &= CR1_ENGC_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_ITConfig +* Description : Enables or disables the specified I2C interrupts. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - I2C_IT: specifies the I2C interrupts sources to be enabled +* or disabled. +* This parameter can be any combination of the following values: +* - I2C_IT_BUF: Buffer interrupt mask +* - I2C_IT_EVT: Event interrupt mask +* - I2C_IT_ERR: Error interrupt mask +* - NewState: new state of the specified I2C interrupts. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_ITConfig(I2C_TypeDef* I2Cx, u16 I2C_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_I2C_CONFIG_IT(I2C_IT)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C interrupts */ + I2Cx->CR2 |= I2C_IT; + } + else + { + /* Disable the selected I2C interrupts */ + I2Cx->CR2 &= (u16)~I2C_IT; + } +} + +/******************************************************************************* +* Function Name : I2C_SendData +* Description : Sends a data byte through the I2Cx peripheral. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - Data: Byte to be transmitted.. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_SendData(I2C_TypeDef* I2Cx, u8 Data) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Write in the DR register the data to be sent */ + I2Cx->DR = Data; +} + +/******************************************************************************* +* Function Name : I2C_ReceiveData +* Description : Returns the most recent received data by the I2Cx peripheral. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* Output : None +* Return : The value of the received data. +*******************************************************************************/ +u8 I2C_ReceiveData(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Return the data in the DR register */ + return (u8)I2Cx->DR; +} + +/******************************************************************************* +* Function Name : I2C_Send7bitAddress +* Description : Transmits the address byte to select the slave device. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - Address: specifies the slave address which will be transmitted +* - I2C_Direction: specifies whether the I2C device will be a +* Transmitter or a Receiver. +* This parameter can be one of the following values +* - I2C_Direction_Transmitter: Transmitter mode +* - I2C_Direction_Receiver: Receiver mode +* Output : None +* Return : None. +*******************************************************************************/ +void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, u8 Address, u8 I2C_Direction) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_DIRECTION(I2C_Direction)); + + /* Test on the direction to set/reset the read/write bit */ + if (I2C_Direction != I2C_Direction_Transmitter) + { + /* Set the address bit0 for read */ + Address |= OAR1_ADD0_Set; + } + else + { + /* Reset the address bit0 for write */ + Address &= OAR1_ADD0_Reset; + } + /* Send the address */ + I2Cx->DR = Address; +} + +/******************************************************************************* +* Function Name : I2C_ReadRegister +* Description : Reads the specified I2C register and returns its value. +* Input1 : - I2C_Register: specifies the register to read. +* This parameter can be one of the following values: +* - I2C_Register_CR1: CR1 register. +* - I2C_Register_CR2: CR2 register. +* - I2C_Register_OAR1: OAR1 register. +* - I2C_Register_OAR2: OAR2 register. +* - I2C_Register_DR: DR register. +* - I2C_Register_SR1: SR1 register. +* - I2C_Register_SR2: SR2 register. +* - I2C_Register_CCR: CCR register. +* - I2C_Register_TRISE: TRISE register. +* Output : None +* Return : The value of the read register. +*******************************************************************************/ +u16 I2C_ReadRegister(I2C_TypeDef* I2Cx, u8 I2C_Register) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_REGISTER(I2C_Register)); + + /* Return the selected register value */ + return (*(vu16 *)(*((vu32 *)&I2Cx) + I2C_Register)); +} + +/******************************************************************************* +* Function Name : I2C_SoftwareResetCmd +* Description : Enables or disables the specified I2C software reset. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2C software reset. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Peripheral under reset */ + I2Cx->CR1 |= CR1_SWRST_Set; + } + else + { + /* Peripheral not under reset */ + I2Cx->CR1 &= CR1_SWRST_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_SMBusAlertConfig +* Description : Drives the SMBusAlert pin high or low for the specified I2C. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - I2C_SMBusAlert: specifies SMBAlert pin level. +* This parameter can be one of the following values: +* - I2C_SMBusAlert_Low: SMBAlert pin driven low +* - I2C_SMBusAlert_High: SMBAlert pin driven high +* Output : None +* Return : None +*******************************************************************************/ +void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, u16 I2C_SMBusAlert) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_SMBUS_ALERT(I2C_SMBusAlert)); + + if (I2C_SMBusAlert == I2C_SMBusAlert_Low) + { + /* Drive the SMBusAlert pin Low */ + I2Cx->CR1 |= I2C_SMBusAlert_Low; + } + else + { + /* Drive the SMBusAlert pin High */ + I2Cx->CR1 &= I2C_SMBusAlert_High; + } +} + +/******************************************************************************* +* Function Name : I2C_TransmitPEC +* Description : Enables or disables the specified I2C PEC transfer. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2C PEC transmission. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C PEC transmission */ + I2Cx->CR1 |= CR1_PEC_Set; + } + else + { + /* Disable the selected I2C PEC transmission */ + I2Cx->CR1 &= CR1_PEC_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_PECPositionConfig +* Description : Selects the specified I2C PEC position. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - I2C_PECPosition: specifies the PEC position. +* This parameter can be one of the following values: +* - I2C_PECPosition_Next: indicates that the next +* byte is PEC +* - I2C_PECPosition_Current: indicates that current +* byte is PEC +* Output : None +* Return : None +*******************************************************************************/ +void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, u16 I2C_PECPosition) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_PEC_POSITION(I2C_PECPosition)); + + if (I2C_PECPosition == I2C_PECPosition_Next) + { + /* Next byte in shift register is PEC */ + I2Cx->CR1 |= I2C_PECPosition_Next; + } + else + { + /* Current byte in shift register is PEC */ + I2Cx->CR1 &= I2C_PECPosition_Current; + } +} + +/******************************************************************************* +* Function Name : I2C_CalculatePEC +* Description : Enables or disables the PEC value calculation of the +* transfered bytes. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2Cx PEC value calculation. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C PEC calculation */ + I2Cx->CR1 |= CR1_ENPEC_Set; + } + else + { + /* Disable the selected I2C PEC calculation */ + I2Cx->CR1 &= CR1_ENPEC_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_GetPEC +* Description : Returns the PEC value for the specified I2C. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* Output : None +* Return : The PEC value. +*******************************************************************************/ +u8 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); +} + +/******************************************************************************* +* Function Name : I2C_ARPCmd +* Description : Enables or disables the specified I2C ARP. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2Cx ARP. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C ARP */ + I2Cx->CR1 |= CR1_ENARP_Set; + } + else + { + /* Disable the selected I2C ARP */ + I2Cx->CR1 &= CR1_ENARP_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_StretchClockCmd +* Description : Enables or disables the specified I2C Clock stretching. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - NewState: new state of the I2Cx Clock stretching. +* This parameter can be: ENABLE or DISABLE. +* Output : None +* Return : None +*******************************************************************************/ +void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == DISABLE) + { + /* Enable the selected I2C Clock stretching */ + I2Cx->CR1 |= CR1_NOSTRETCH_Set; + } + else + { + /* Disable the selected I2C Clock stretching */ + I2Cx->CR1 &= CR1_NOSTRETCH_Reset; + } +} + +/******************************************************************************* +* Function Name : I2C_FastModeDutyCycleConfig +* Description : Selects the specified I2C fast mode duty cycle. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - I2C_DutyCycle: specifies the fast mode duty cycle. +* This parameter can be one of the following values: +* - I2C_DutyCycle_2: I2C fast mode Tlow/Thigh = 2 +* - I2C_DutyCycle_16_9: I2C fast mode Tlow/Thigh = 16/9 +* Output : None +* Return : None +*******************************************************************************/ +void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, u16 I2C_DutyCycle) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_DUTY_CYCLE(I2C_DutyCycle)); + + if (I2C_DutyCycle != I2C_DutyCycle_16_9) + { + /* I2C fast mode Tlow/Thigh=2 */ + I2Cx->CCR &= I2C_DutyCycle_2; + } + else + { + /* I2C fast mode Tlow/Thigh=16/9 */ + I2Cx->CCR |= I2C_DutyCycle_16_9; + } +} + +/******************************************************************************* +* Function Name : I2C_GetLastEvent +* Description : Returns the last I2Cx Event. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* Output : None +* Return : The last event +*******************************************************************************/ +u32 I2C_GetLastEvent(I2C_TypeDef* I2Cx) +{ + u32 lastevent = 0; + u32 flag1 = 0, flag2 = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Read the I2Cx status register */ + flag1 = I2Cx->SR1; + flag2 = I2Cx->SR2; + flag2 = flag2 << 16; + + /* Get the last event value from I2C status register */ + lastevent = (flag1 | flag2) & FLAG_Mask; + + /* Return status */ + return lastevent; +} + +/******************************************************************************* +* Function Name : I2C_CheckEvent +* Description : Checks whether the last I2Cx Event is equal to the one passed +* as parameter. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - I2C_EVENT: specifies the event to be checked. +* This parameter can be one of the following values: +* - I2C_EVENT_SLAVE_ADDRESS_MATCHED : EV1 +* - I2C_EVENT_SLAVE_BYTE_RECEIVED : EV2 +* - I2C_EVENT_SLAVE_BYTE_TRANSMITTED : EV3 +* - I2C_EVENT_SLAVE_ACK_FAILURE : EV3-2 +* - I2C_EVENT_MASTER_MODE_SELECT : EV5 +* - I2C_EVENT_MASTER_MODE_SELECTED : EV6 +* - I2C_EVENT_MASTER_BYTE_RECEIVED : EV7 +* - I2C_EVENT_MASTER_BYTE_TRANSMITTED : EV8 +* - I2C_EVENT_MASTER_MODE_ADDRESS10 : EV9 +* - I2C_EVENT_SLAVE_STOP_DETECTED : EV4 +* Output : None +* Return : An ErrorStatus enumuration value: +* - SUCCESS: Last event is equal to the I2C_EVENT +* - ERROR: Last event is different from the I2C_EVENT +*******************************************************************************/ +ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, u32 I2C_EVENT) +{ + u32 lastevent = 0; + u32 flag1 = 0, flag2 = 0; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_EVENT(I2C_EVENT)); + + /* Read the I2Cx status register */ + flag1 = I2Cx->SR1; + flag2 = I2Cx->SR2; + flag2 = flag2 << 16; + + /* Get the last event value from I2C status register */ + lastevent = (flag1 | flag2) & FLAG_Mask; + + /* Check whether the last event is equal to I2C_EVENT */ + if (lastevent == I2C_EVENT ) + { + /* SUCCESS: last event is equal to I2C_EVENT */ + status = SUCCESS; + } + else + { + /* ERROR: last event is different from I2C_EVENT */ + status = ERROR; + } + + /* Return status */ + return status; +} + +/******************************************************************************* +* Function Name : I2C_GetFlagStatus +* Description : Checks whether the specified I2C flag is set or not. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - I2C_FLAG: specifies the flag to check. +* This parameter can be one of the following values: +* - I2C_FLAG_DUALF: Dual flag (Slave mode) +* - I2C_FLAG_SMBHOST: SMBus host header (Slave mode) +* - I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode) +* - I2C_FLAG_GENCALL: General call header flag (Slave mode) +* - I2C_FLAG_TRA: Transmitter/Receiver flag +* - I2C_FLAG_BUSY: Bus busy flag +* - I2C_FLAG_MSL: Master/Slave flag +* - I2C_FLAG_SMBALERT: SMBus Alert flag +* - I2C_FLAG_TIMEOUT: Timeout or Tlow error flag +* - I2C_FLAG_PECERR: PEC error in reception flag +* - I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) +* - I2C_FLAG_AF: Acknowledge failure flag +* - I2C_FLAG_ARLO: Arbitration lost flag (Master mode) +* - I2C_FLAG_BERR: Bus error flag +* - I2C_FLAG_TXE: Data register empty flag (Transmitter) +* - I2C_FLAG_RXNE: Data register not empty (Receiver) flag +* - I2C_FLAG_STOPF: Stop detection flag (Slave mode) +* - I2C_FLAG_ADD10: 10-bit header sent flag (Master mode) +* - I2C_FLAG_BTF: Byte transfer finished flag +* - I2C_FLAG_ADDR: Address sent flag (Master mode) “ADSL” +* Address matched flag (Slave mode)”ENDAD” +* - I2C_FLAG_SB: Start bit flag (Master mode) +* Output : None +* Return : The new state of I2C_FLAG (SET or RESET). +*******************************************************************************/ +FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, u32 I2C_FLAG) +{ + FlagStatus bitstatus = RESET; + u32 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 = (*(u32*)&(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 = (u32)(I2C_FLAG >> 16); + /* Get the I2Cx SR2 register address */ + i2cxbase += 0x18; + } + + if(((*(vu32 *)i2cxbase) & I2C_FLAG) != (u32)RESET) + { + /* I2C_FLAG is set */ + bitstatus = SET; + } + else + { + /* I2C_FLAG is reset */ + bitstatus = RESET; + } + + /* Return the I2C_FLAG status */ + return bitstatus; +} + +/******************************************************************************* +* Function Name : I2C_ClearFlag +* Description : Clears the I2Cx's pending flags. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - I2C_FLAG: specifies the flag to clear. +* This parameter can be any combination of the following +* values: +* - I2C_FLAG_SMBALERT: SMBus Alert flag +* - I2C_FLAG_TIMEOUT: Timeout or Tlow error flag +* - I2C_FLAG_PECERR: PEC error in reception flag +* - I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) +* - I2C_FLAG_AF: Acknowledge failure flag +* - I2C_FLAG_ARLO: Arbitration lost flag (Master mode) +* - I2C_FLAG_BERR: Bus error flag +* +* Notes: +* - STOPF (STOP detection) is cleared by software +* sequence: a read operation to I2C_SR1 register +* (I2C_GetFlagStatus()) followed by a write operation +* to I2C_CR1 register (I2C_Cmd() to re-enable the +* I2C peripheral). +* - ADD10 (10-bit header sent) is cleared by software +* sequence: a read operation to I2C_SR1 +* (I2C_GetFlagStatus()) followed by writing the +* second byte of the address in DR register. +* - BTF (Byte Transfer Finished) is cleared by software +* sequence: a read operation to I2C_SR1 register +* (I2C_GetFlagStatus()) followed by a read/write to +* I2C_DR register (I2C_SendData()). +* - ADDR (Address sent) is cleared by software sequence: +* a read operation to I2C_SR1 register +* (I2C_GetFlagStatus()) followed by a read operation to +* I2C_SR2 register ((void)(I2Cx->SR2)). +* - SB (Start Bit) is cleared software sequence: a read +* operation to I2C_SR1 register (I2C_GetFlagStatus()) +* followed by a write operation to I2C_DR reigister +* (I2C_SendData()). +* Output : None +* Return : None +*******************************************************************************/ +void I2C_ClearFlag(I2C_TypeDef* I2Cx, u32 I2C_FLAG) +{ + u32 flagpos = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG)); + + /* Get the I2C flag position */ + flagpos = I2C_FLAG & FLAG_Mask; + + /* Clear the selected I2C flag */ + I2Cx->SR1 = (u16)~flagpos; +} + +/******************************************************************************* +* Function Name : I2C_GetITStatus +* Description : Checks whether the specified I2C interrupt has occurred or not. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - I2C_IT: specifies the interrupt source to check. +* This parameter can be one of the following values: +* - I2C_IT_SMBALERT: SMBus Alert flag +* - I2C_IT_TIMEOUT: Timeout or Tlow error flag +* - I2C_IT_PECERR: PEC error in reception flag +* - I2C_IT_OVR: Overrun/Underrun flag (Slave mode) +* - I2C_IT_AF: Acknowledge failure flag +* - I2C_IT_ARLO: Arbitration lost flag (Master mode) +* - I2C_IT_BERR: Bus error flag +* - I2C_IT_TXE: Data register empty flag (Transmitter) +* - I2C_IT_RXNE: Data register not empty (Receiver) flag +* - I2C_IT_STOPF: Stop detection flag (Slave mode) +* - I2C_IT_ADD10: 10-bit header sent flag (Master mode) +* - I2C_IT_BTF: Byte transfer finished flag +* - I2C_IT_ADDR: Address sent flag (Master mode) “ADSL” +* Address matched flag (Slave mode)”ENDAD” +* - I2C_IT_SB: Start bit flag (Master mode) +* Output : None +* Return : The new state of I2C_IT (SET or RESET). +*******************************************************************************/ +ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, u32 I2C_IT) +{ + ITStatus bitstatus = RESET; + u32 enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_GET_IT(I2C_IT)); + + /* Check if the interrupt source is enabled or not */ + enablestatus = (u32)(((I2C_IT & ITEN_Mask) >> 16) & (I2Cx->CR2)) ; + + /* Get bit[23:0] of the flag */ + I2C_IT &= FLAG_Mask; + + /* Check the status of the specified I2C flag */ + if (((I2Cx->SR1 & I2C_IT) != (u32)RESET) && enablestatus) + { + /* I2C_IT is set */ + bitstatus = SET; + } + else + { + /* I2C_IT is reset */ + bitstatus = RESET; + } + /* Return the I2C_IT status */ + return bitstatus; +} + +/******************************************************************************* +* Function Name : I2C_ClearITPendingBit +* Description : Clears the I2Cx’s interrupt pending bits. +* Input : - I2Cx: where x can be 1 or 2 to select the I2C peripheral. +* - I2C_IT: specifies the interrupt pending bit to clear. +* This parameter can be any combination of the following +* values: +* - I2C_IT_SMBALERT: SMBus Alert interrupt +* - I2C_IT_TIMEOUT: Timeout or Tlow error interrupt +* - I2C_IT_PECERR: PEC error in reception interrupt +* - I2C_IT_OVR: Overrun/Underrun interrupt (Slave mode) +* - I2C_IT_AF: Acknowledge failure interrupt +* - I2C_IT_ARLO: Arbitration lost interrupt (Master mode) +* - I2C_IT_BERR: Bus error interrupt +* +* Notes: +* - STOPF (STOP detection) is cleared by software +* sequence: a read operation to I2C_SR1 register +* (I2C_GetITStatus()) followed by a write operation to +* I2C_CR1 register (I2C_Cmd() to re-enable the I2C +* peripheral). +* - ADD10 (10-bit header sent) is cleared by software +* sequence: a read operation to I2C_SR1 +* (I2C_GetITStatus()) followed by writing the second +* byte of the address in I2C_DR register. +* - BTF (Byte Transfer Finished) is cleared by software +* sequence: a read operation to I2C_SR1 register +* (I2C_GetITStatus()) followed by a read/write to +* I2C_DR register (I2C_SendData()). +* - ADDR (Address sent) is cleared by software sequence: +* a read operation to I2C_SR1 register (I2C_GetITStatus()) +* followed by a read operation to I2C_SR2 register +* ((void)(I2Cx->SR2)). +* - SB (Start Bit) is cleared by software sequence: a +* read operation to I2C_SR1 register (I2C_GetITStatus()) +* followed by a write operation to I2C_DR reigister +* (I2C_SendData()). +* Output : None +* Return : None +*******************************************************************************/ +void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, u32 I2C_IT) +{ + u32 flagpos = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLEAR_IT(I2C_IT)); + + /* Get the I2C flag position */ + flagpos = I2C_IT & FLAG_Mask; + + /* Clear the selected I2C flag */ + I2Cx->SR1 = (u16)~flagpos; +} + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ -- cgit v1.2.3