| /******************** (C) COPYRIGHT 2006 STMicroelectronics ******************** | |
| * File Name : 75x_i2c.c | |
| * Author : MCD Application Team | |
| * Date First Issued : 03/10/2006 | |
| * Description : This file provides all the I2C software functions. | |
| ******************************************************************************** | |
| * History: | |
| * 07/17/2006 : V1.0 | |
| * 03/10/2006 : V0.1 | |
| ******************************************************************************** | |
| * THE PRESENT SOFTWARE 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 SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING | |
| * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. | |
| *******************************************************************************/ | |
| /* Includes ------------------------------------------------------------------*/ | |
| #include "75x_i2c.h" | |
| #include "75x_mrcc.h" | |
| /* Private typedef -----------------------------------------------------------*/ | |
| /* Private define ------------------------------------------------------------*/ | |
| /* I2C IT enable */ | |
| #define I2C_IT_Enable 0x01 | |
| #define I2C_IT_Disable 0xFE | |
| /* I2C Peripheral Enable/Disable */ | |
| #define I2C_PE_Set 0x20 | |
| #define I2C_PE_Reset 0xDF | |
| /* I2C START Enable/Disable */ | |
| #define I2C_Start_Enable 0x08 | |
| #define I2C_Start_Disable 0xF7 | |
| /* I2C STOP Enable/Disable */ | |
| #define I2C_Stop_Enable 0x02 | |
| #define I2C_Stop_Disable 0xFD | |
| /* Address direction bit */ | |
| #define I2C_ADD0_Set 0x01 | |
| #define I2C_ADD0_Reset 0xFE | |
| /* I2C Masks */ | |
| #define I2C_Frequency_Mask 0x1F | |
| #define I2C_AddressHigh_Mask 0xF9 | |
| #define I2C_OwnAddress_Mask 0x0300 | |
| #define I2C_StandardMode_Mask 0x7f | |
| #define I2C_FastMode_Mask 0x80 | |
| #define I2C_Event_Mask 0x3FFF | |
| /* Private macro -------------------------------------------------------------*/ | |
| /* Private variables ---------------------------------------------------------*/ | |
| /* Private function prototypes -----------------------------------------------*/ | |
| /* Private functions ---------------------------------------------------------*/ | |
| /******************************************************************************* | |
| * Function Name : I2C_DeInit | |
| * Description : Deinitializes the I2C peripheral registers to their default | |
| * reset values. | |
| * Input : None | |
| * Output : None | |
| * Return : None | |
| *******************************************************************************/ | |
| void I2C_DeInit(void) | |
| { | |
| /* Reset the I2C registers values*/ | |
| MRCC_PeripheralSWResetConfig(MRCC_Peripheral_I2C,ENABLE); | |
| MRCC_PeripheralSWResetConfig(MRCC_Peripheral_I2C,DISABLE); | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_Init | |
| * Description : Initializes the I2C peripheral according to the specified | |
| * parameters in the I2C_Initstruct. | |
| * Input : - 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_InitTypeDef* I2C_InitStruct) | |
| { | |
| u8 ITEState = 0; | |
| u16 Result = 0x0F; | |
| u32 APBClock = 8000000; | |
| MRCC_ClocksTypeDef MRCC_ClocksStatus; | |
| /* Get APBClock frequency value */ | |
| MRCC_GetClocksStatus(&MRCC_ClocksStatus); | |
| APBClock = MRCC_ClocksStatus.PCLK_Frequency; | |
| /* Save ITE bit state */ | |
| ITEState = I2C->CR & 0xFE; | |
| /* Disable I2C peripheral to set FR[2:0] bits */ | |
| I2C_Cmd(DISABLE); | |
| /* Clear frequency FR[2:0] bits */ | |
| I2C->OAR2 &= I2C_Frequency_Mask; | |
| /* Set frequency bits depending on APBClock value */ | |
| if (APBClock < 10000000) | |
| I2C->OAR2 &= 0x1F; | |
| else if (APBClock < 16670000) | |
| I2C->OAR2 |= 0x20; | |
| else if (APBClock < 26670000) | |
| I2C->OAR2 |= 0x40; | |
| else if (APBClock < 40000000) | |
| I2C->OAR2 |= 0x60; | |
| else if (APBClock < 53330000) | |
| I2C->OAR2 |= 0x80; | |
| else if (APBClock < 66000000) | |
| I2C->OAR2 |= 0xA0; | |
| else if (APBClock < 80000000) | |
| I2C->OAR2 |= 0xC0; | |
| else if (APBClock < 100000000) | |
| I2C->OAR2 |= 0xE0; | |
| I2C_Cmd(ENABLE); | |
| /* Restore the ITE bit state */ | |
| I2C->CR |= ITEState; | |
| /* Configure general call */ | |
| if (I2C_InitStruct->I2C_GeneralCall == I2C_GeneralCall_Enable) | |
| { | |
| /* Enable general call */ | |
| I2C->CR |= I2C_GeneralCall_Enable; | |
| } | |
| else | |
| { | |
| /* Disable general call */ | |
| I2C->CR &= I2C_GeneralCall_Disable; | |
| } | |
| /* Configure acknowledgement */ | |
| if (I2C_InitStruct->I2C_Ack == I2C_Ack_Enable) | |
| { | |
| /* Enable acknowledgement */ | |
| I2C->CR |= I2C_Ack_Enable; | |
| } | |
| else | |
| { | |
| /* Disable acknowledgement */ | |
| I2C->CR &= I2C_Ack_Disable; | |
| } | |
| /* Configure LSB own address */ | |
| I2C->OAR1 = I2C_InitStruct->I2C_OwnAddress; | |
| /* Clear MSB own address ADD[9:8] bits */ | |
| I2C->OAR2 &= I2C_AddressHigh_Mask; | |
| /* Set MSB own address value */ | |
| I2C->OAR2 |= (I2C_InitStruct->I2C_OwnAddress & I2C_OwnAddress_Mask)>>7; | |
| /* Configure speed in standard mode */ | |
| if (I2C_InitStruct->I2C_CLKSpeed <= 100000) | |
| { | |
| /* Standard mode speed calculate */ | |
| Result = ((APBClock/I2C_InitStruct->I2C_CLKSpeed)-7)/2; | |
| /* Set speed value and clear FM/SM bit for standard mode in LSB clock divider */ | |
| I2C->CCR = Result & I2C_StandardMode_Mask; | |
| } | |
| /* Configure speed in fast mode */ | |
| else if (I2C_InitStruct->I2C_CLKSpeed <= 400000) | |
| { | |
| /* Fast mode speed calculate */ | |
| Result = ((APBClock/I2C_InitStruct->I2C_CLKSpeed)-9)/3; | |
| /* Set speed value and set FM/SM bit for fast mode in LSB clock divider */ | |
| I2C->CCR = Result | I2C_FastMode_Mask; | |
| } | |
| /* Set speed in MSB clock divider */ | |
| I2C->ECCR = Result >>7; | |
| } | |
| /******************************************************************************* | |
| * 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) | |
| { | |
| /* Initialize the I2C_CLKSpeed member */ | |
| I2C_InitStruct->I2C_CLKSpeed = 5000; | |
| /* Initialize the I2C_OwnAddress member */ | |
| I2C_InitStruct->I2C_OwnAddress = 0x0; | |
| /* Initialize the I2C_GeneralCall member */ | |
| I2C_InitStruct->I2C_GeneralCall = I2C_GeneralCall_Disable; | |
| /* Initialize the I2C_Ack member */ | |
| I2C_InitStruct->I2C_Ack = I2C_Ack_Disable; | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_Cmd | |
| * Description : Enables or disables the I2C peripheral. | |
| * Input : - NewState: new state of the I2C peripheral. This parameter | |
| * can be: ENABLE or DISABLE. | |
| * Output : None | |
| * Return : None. | |
| *******************************************************************************/ | |
| void I2C_Cmd(FunctionalState NewState) | |
| { | |
| if (NewState == ENABLE) | |
| { | |
| /* Enable the I2C peripheral by setting twice the PE bit on the CR register */ | |
| I2C->CR |= I2C_PE_Set; | |
| I2C->CR |= I2C_PE_Set; | |
| } | |
| else | |
| { | |
| /* Disable the I2C peripheral */ | |
| I2C->CR &= I2C_PE_Reset; | |
| } | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_GenerateSTART | |
| * Description : Generates I2C communication START condition. | |
| * Input : - NewState: new state of the I2C START condition generation. | |
| * This parameter can be: ENABLE or DISABLE. | |
| * Output : None | |
| * Return : None. | |
| *******************************************************************************/ | |
| void I2C_GenerateSTART(FunctionalState NewState) | |
| { | |
| if (NewState == ENABLE) | |
| { | |
| /* Generate a START condition */ | |
| I2C->CR |= I2C_Start_Enable; | |
| } | |
| else | |
| { | |
| /* Disable the START condition generation */ | |
| I2C->CR &= I2C_Start_Disable; | |
| } | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_GenerateSTOP | |
| * Description : Generates I2C communication STOP condition. | |
| * Input : - NewState: new state of the I2C STOP condition generation. | |
| * This parameter can be: ENABLE or DISABLE. | |
| * Output : None | |
| * Return : None. | |
| *******************************************************************************/ | |
| void I2C_GenerateSTOP(FunctionalState NewState) | |
| { | |
| if (NewState == ENABLE) | |
| { | |
| /* Generate a SIOP condition */ | |
| I2C->CR |= I2C_Stop_Enable; | |
| } | |
| else | |
| { | |
| /* Disable the STOP condition generation */ | |
| I2C->CR &= I2C_Stop_Disable; | |
| } | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_AcknowledgeConfig | |
| * Description : Enables or disables I2C acknowledge feature. | |
| * Input : - NewState: new state of the I2C Acknowledgement. | |
| * This parameter can be: ENABLE or DISABLE. | |
| * Output : None | |
| * Return : None. | |
| *******************************************************************************/ | |
| void I2C_AcknowledgeConfig(FunctionalState NewState) | |
| { | |
| if (NewState == ENABLE) | |
| { | |
| /* Enable the acknowledgement */ | |
| I2C->CR |= I2C_Ack_Enable; | |
| } | |
| else | |
| { | |
| /* Disable the acknowledgement */ | |
| I2C->CR &= I2C_Ack_Disable; | |
| } | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_ITConfig | |
| * Description : Enables or disables the I2C interrupt. | |
| * Input : - NewState: new state of the I2C interrupt. | |
| * This parameter can be: ENABLE or DISABLE. | |
| * Output : None | |
| * Return : None. | |
| *******************************************************************************/ | |
| void I2C_ITConfig(FunctionalState NewState) | |
| { | |
| if (NewState == ENABLE) | |
| { | |
| /* Enable the I2C interrupt */ | |
| I2C->CR |= I2C_IT_Enable; | |
| } | |
| else | |
| { | |
| /* Disable the I2C interrupt */ | |
| I2C->CR &= I2C_IT_Disable; | |
| } | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_GetLastEvent | |
| * Description : Gets the last I2C event that has occurred. | |
| * Input : None | |
| * Output : None | |
| * Return : The Last happened Event. | |
| *******************************************************************************/ | |
| u16 I2C_GetLastEvent(void) | |
| { | |
| u16 Flag1 = 0, Flag2 = 0, LastEvent = 0; | |
| Flag1 = I2C->SR1; | |
| Flag2 = I2C->SR2; | |
| Flag2 = Flag2<<8; | |
| /* Get the last event value from I2C status register */ | |
| LastEvent = (((Flag1 | (Flag2)) & I2C_Event_Mask)); | |
| /* Return the last event */ | |
| return LastEvent; | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_CheckEvent | |
| * Description : Checks whether the Last I2C Event is equal to the one passed | |
| * as parameter. | |
| * Input : - I2C_EVENT: specifies the event to be checked. This parameter | |
| * can be one of the following values: | |
| * - I2C_EVENT_SLAVE_ADDRESS_MATCHED | |
| * - I2C_EVENT_SLAVE_BYTE_RECEIVED | |
| * - I2C_EVENT_SLAVE_BYTE_TRANSMITTED | |
| * - I2C_EVENT_SLAVE_ACK_FAILURE | |
| * - I2C_EVENT_MASTER_MODE_SELECT | |
| * - I2C_EVENT_MASTER_MODE_SELECTED | |
| * - I2C_EVENT_MASTER_BYTE_RECEIVED | |
| * - I2C_EVENT_MASTER_BYTE_TRANSMITTED | |
| * - I2C_EVENT_MASTER_MODE_ADDRESS10 | |
| * - I2C_EVENT_SLAVE_STOP_DETECTED | |
| * 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(u16 I2C_EVENT) | |
| { | |
| u16 LastEvent = I2C_GetLastEvent(); | |
| /* Check whether the last event is equal to I2C_EVENT */ | |
| if (LastEvent == I2C_EVENT) | |
| { | |
| /* Return SUCCESS when last event is equal to I2C_EVENT */ | |
| return SUCCESS; | |
| } | |
| else | |
| { | |
| /* Return ERROR when last event is different from I2C_EVENT */ | |
| return ERROR; | |
| } | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_SendData | |
| * Description : Sends a data byte. | |
| * Input : - Data: indicates the byte to be transmitted. | |
| * Output : None | |
| * Return : None. | |
| *******************************************************************************/ | |
| void I2C_SendData(u8 Data) | |
| { | |
| /* Write in the DR register the byte to be sent */ | |
| I2C->DR = Data; | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_ReceiveData | |
| * Description : Reads the received byte. | |
| * Input : None | |
| * Output : None | |
| * Return : The received byte | |
| *******************************************************************************/ | |
| u8 I2C_ReceiveData(void) | |
| { | |
| /* Return from the DR register the received byte */ | |
| return I2C->DR; | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_Send7bitAddress | |
| * Description : Transmits the address byte to select the slave device. | |
| * Input : - Address: specifies the slave address which will be transmitted | |
| * - Direction: specifies whether the I2C device will be a | |
| * Transmitter or a Receiver. This parameter can be one of the | |
| * following values | |
| * - I2C_MODE_TRANSMITTER: Transmitter mode | |
| * - I2C_MODE_RECEIVER: Receiver mode | |
| * Output : None | |
| * Return : None. | |
| *******************************************************************************/ | |
| void I2C_Send7bitAddress(u8 Address, u8 Direction) | |
| { | |
| /* Test on the direction to define the read/write bit */ | |
| if (Direction == I2C_MODE_RECEIVER) | |
| { | |
| /* Set the address bit0 for read */ | |
| Address |= I2C_ADD0_Set; | |
| } | |
| else | |
| { | |
| /* Reset the address bit0 for write */ | |
| Address &= I2C_ADD0_Reset; | |
| } | |
| /* Send the address */ | |
| I2C->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_CR: CR register. | |
| * - I2C_SR1: SR1 register. | |
| * - I2C_SR2: SR2 register. | |
| * - I2C_CCR: CCR register. | |
| * - I2C_OAR1: OAR1 register. | |
| * - I2C_OAR2: OAR2 register. | |
| * - I2C_DR: DR register. | |
| * - I2C_ECCR: ECCR register. | |
| * Output : None | |
| * Return : The value of the read register. | |
| *******************************************************************************/ | |
| u8 I2C_ReadRegister(u8 I2C_Register) | |
| { | |
| /* Return the selected register value */ | |
| return (*(u8 *)(I2C_BASE + I2C_Register)); | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_GetFlagStatus | |
| * Description : Checks whether the specified I2C flag is set or not. | |
| * Input : - I2C_FLAG: specifies the flag to check. | |
| * This parameter can be one of the following values: | |
| * - I2C_FLAG_SB: Start bit flag (Master mode) | |
| * - I2C_FLAG_M_SL: Master/Slave flag | |
| * - I2C_FLAG_ADSL: Address matched flag (Slave mode) | |
| * - I2C_FLAG_BTF: Byte transfer finished flag | |
| * - I2C_FLAG_BUSY: Bus busy flag | |
| * - I2C_FLAG_TRA: Transmitter/Receiver flag | |
| * - I2C_FLAG_ADD10: 10-bit addressing in Master mode flag | |
| * - I2C_FLAG_EVF: Event flag | |
| * - I2C_FLAG_GCAL: General call flag (slave mode) | |
| * - I2C_FLAG_BERR: Bus error flag | |
| * - I2C_FLAG_ARLO: Arbitration lost flag | |
| * - I2C_FLAG_STOPF: Stop detection flag (slave mode) | |
| * - I2C_FLAG_AF: Acknowledge failure flag | |
| * - I2C_FLAG_ENDAD: End of address transmission flag | |
| * - I2C_FLAG_ACK: Acknowledge enable flag | |
| * Output : None | |
| * Return : The NewState of the I2C_FLAG (SET or RESET). | |
| *******************************************************************************/ | |
| FlagStatus I2C_GetFlagStatus(u16 I2C_FLAG) | |
| { | |
| u16 Flag1 = 0, Flag2 = 0, Flag3 = 0, Tmp = 0; | |
| Flag1 = I2C->SR1; | |
| Flag2 = I2C->SR2; | |
| Flag2 = Flag2<<8; | |
| Flag3 = I2C->CR & 0x04; | |
| /* Get all the I2C flags in a unique register*/ | |
| Tmp = (((Flag1 | (Flag2)) & I2C_Event_Mask) | (Flag3<<12)); | |
| /* Check the status of the specified I2C flag */ | |
| if((Tmp & I2C_FLAG) != RESET) | |
| { | |
| /* Return SET if I2C_FLAG is set */ | |
| return SET; | |
| } | |
| else | |
| { | |
| /* Return RESET if I2C_FLAG is reset */ | |
| return RESET; | |
| } | |
| } | |
| /******************************************************************************* | |
| * Function Name : I2C_ClearFlag | |
| * Description : Clears the I2Cs pending flags | |
| * Input : - I2C_FLAG: specifies the flag to clear. | |
| * This parameter can be one of the following values: | |
| * - I2C_FLAG_SB: Start bit flag | |
| * - I2C_FLAG_M_SL: Master/Slave flag | |
| * - I2C_FLAG_ADSL: Adress matched flag | |
| * - I2C_FLAG_BTF: Byte transfer finished flag | |
| * - I2C_FLAG_BUSY: Bus busy flag | |
| * - I2C_FLAG_TRA: Transmitter/Receiver flag | |
| * - I2C_FLAG_ADD10: 10-bit addressing in Master mode flag | |
| * - I2C_FLAG_EVF: Event flag | |
| * - I2C_FLAG_GCAL: General call flag | |
| * - I2C_FLAG_BERR: Bus error flag | |
| * - I2C_FLAG_ARLO: Arbitration lost flag | |
| * - I2C_FLAG_STOPF: Stop detection flag | |
| * - I2C_FLAG_AF: Acknowledge failure flag | |
| * - I2C_FLAG_ENDAD: End of address transmission flag | |
| * - I2C_FLAG_ACK: Acknowledge enable flag | |
| * - parameter needed in the case that the flag to be cleared | |
| * need a write in one register | |
| * Output : None | |
| * Return : None | |
| *******************************************************************************/ | |
| void I2C_ClearFlag(u16 I2C_FLAG, ...) | |
| { | |
| u8 Tmp = (u8)*((u32 *) & I2C_FLAG + sizeof(I2C_FLAG)); | |
| /* flags that need a read of the SR2 register to be cleared */ | |
| if ((I2C_FLAG == I2C_FLAG_ADD10) || (I2C_FLAG == I2C_FLAG_EVF) || | |
| (I2C_FLAG == I2C_FLAG_STOPF) || (I2C_FLAG == I2C_FLAG_AF) || | |
| (I2C_FLAG == I2C_FLAG_BERR) || (I2C_FLAG == I2C_FLAG_ARLO) || | |
| (I2C_FLAG == I2C_FLAG_ENDAD)) | |
| { | |
| /* Read the SR2 register */ | |
| (void)I2C->SR2; | |
| /* Two flags need a second step to be cleared */ | |
| switch (I2C_FLAG) | |
| { | |
| case I2C_FLAG_ADD10: | |
| /* Send the MSB 10bit address passed as second parameter */ | |
| I2C->DR = Tmp; | |
| break; | |
| case I2C_FLAG_ENDAD: | |
| /* Write to the I2C_CR register by setting PE bit */ | |
| I2C->CR |= I2C_PE_Set; | |
| break; | |
| } | |
| } | |
| /* flags that need a read of the SR1 register to be cleared */ | |
| else if (I2C_FLAG==I2C_FLAG_SB || I2C_FLAG==I2C_FLAG_ADSL || I2C_FLAG==I2C_FLAG_BTF || I2C_FLAG==I2C_FLAG_TRA) | |
| { | |
| /* Read the SR1 register */ | |
| (void)I2C->SR1; | |
| /* three flags need a second step to be cleared */ | |
| if (I2C_FLAG == I2C_FLAG_SB) | |
| { | |
| /* Send the address byte passed as second parameter */ | |
| I2C->DR=Tmp; | |
| } | |
| else if (I2C_FLAG==I2C_FLAG_BTF || I2C_FLAG==I2C_FLAG_TRA) | |
| { | |
| /* return the received byte in the variable passed as second parameter */ | |
| Tmp=I2C->DR; | |
| } | |
| } | |
| /* flags that need to disable the I2C interface */ | |
| else if ( I2C_FLAG==I2C_FLAG_M_SL || I2C_FLAG==I2C_FLAG_GCAL) | |
| { | |
| I2C_Cmd(DISABLE); | |
| I2C_Cmd(ENABLE); | |
| } | |
| } | |
| /******************* (C) COPYRIGHT 2006 STMicroelectronics *****END OF FILE****/ |