资源描述
/*File: i2c.hPurpose :*/#ifndef _I2C_H_#define _I2C_H_/* Includes */* Defines */#define SENSORS_I2CI2C2#define I2C_SPEED400000#define I2C_OWN_ADDRESS0x00#define I2C_Config() I2cMaster_Init();/* Prototypes */void I2cMaster_Init(void);unsigned long Sensors_I2C_WriteRegister(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, const unsigned char *RegisterValue);unsigned long Sensors_I2C_ReadRegister(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue);int Sensors_I2C_WriteRegister_swap(unsigned char slave_addr,unsigned char reg_addr,unsigned char len, unsigned char *data_ptr); int Sensors_I2C_ReadRegister_swap(unsigned char slave_addr,unsigned char reg_addr,unsigned char len, unsigned char *data_ptr); int I2C_Reset_User();#endif / _I2C_H_/*File: i2c.cPurpose : I2c 3 to communicate with the sensorsAuthor :* Includes */#include #include stm32l1xx.h#include i2c.h#include gpio.h#include log.h#include discover_board.h#include main.h/* Defines */#define I2Cx_FLAG_TIMEOUT(uint32_t) 900)#define I2Cx_LONG_TIMEOUT(uint32_t)(300 * I2Cx_FLAG_TIMEOUT)#define SENSORS_I2C_SCL_GPIO_PORTGPIOB#define SENSORS_I2C_SCL_GPIO_CLKRCC_AHBPeriph_GPIOB#define SENSORS_I2C_SCL_GPIO_PINGPIO_Pin_10#define SENSORS_I2C_SCL_GPIO_PINSOURCE GPIO_PinSource10#define SENSORS_I2C_SDA_GPIO_PORTGPIOB#define SENSORS_I2C_SDA_GPIO_CLKRCC_AHBPeriph_GPIOB#define SENSORS_I2C_SDA_GPIO_PINGPIO_Pin_11#define SENSORS_I2C_SDA_GPIO_PINSOURCEGPIO_PinSource11#define SENSORS_I2C_RCC_CLK #define SENSORS_I2C_AFRCC_APB1Periph_I2C2GPIO_AF_I2C2#define WAIT_FOR_FLAG(flag, value, timeout, errorcode) I2CTimeout = timeout;while(I2C_GetFlagStatus(SENSORS_I2C, flag) != value) if(I2CTimeout-) = 0) return I2Cx_TIMEOUT_UserCallback(errorcode); #define CLEAR_ADDR_BITI2C_ReadRegister(SENSORS_I2C, I2C_Register_SR1);I2C_ReadRegister(SENSORS_I2C, I2C_Register_SR2);/* Globals */* Prototypes */* Function */static uint32_t I2Cx_TIMEOUT_UserCallback(char value);void I2cMaster_Init(void)GPIO_InitTypeDef GPIO_InitStructure;I2C_InitTypeDef I2C_InitStructure;/* Enable I2Cx clock */RCC_APB1PeriphClockCmd(SENSORS_I2C_RCC_CLK, ENABLE);/* Enable I2C GPIO clock */RCC_AHBPeriphClockCmd(SENSORS_I2C_SCL_GPIO_CLK | SENSORS_I2C_SDA_GPIO_CLK, ENABLE);/* Configure I2Cx pin: SCL -*/GPIO_InitStructure.GPIO_Pin = SENSORS_I2C_SCL_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;/* Connect pins to Periph */GPIO_PinAFConfig(SENSORS_I2C_SCL_GPIO_PORT, SENSORS_I2C_SCL_GPIO_PINSOURCE, SENSORS_I2C_AF); GPIO_Init(SENSORS_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);/* Configure I2Cx pin: SDA -*/GPIO_InitStructure.GPIO_Pin = SENSORS_I2C_SDA_GPIO_PIN;/* Connect pins to Periph */GPIO_PinAFConfig(SENSORS_I2C_SDA_GPIO_PORT, SENSORS_I2C_SDA_GPIO_PINSOURCE, SENSORS_I2C_AF); GPIO_Init(SENSORS_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);I2C_DeInit(SENSORS_I2C);I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = I2C_OWN_ADDRESS;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;/* Enable the I2C peripheral */I2C_Cmd(SENSORS_I2C, ENABLE);/* Initialize the I2C peripheral */I2C_Init(SENSORS_I2C, &I2C_InitStructure);/* brief Basic management of the timeout situation.* param None.* retval None.*/static uint32_t I2Cx_TIMEOUT_UserCallback(char value)/* The following code allows I2C error recovery and return to normal communicationif the error source doesnt still exist (ie. hardware issue.) */I2C_InitTypeDef I2C_InitStructure;I2C_GenerateSTOP(SENSORS_I2C, ENABLE);I2C_SoftwareResetCmd(SENSORS_I2C, ENABLE);I2C_SoftwareResetCmd(SENSORS_I2C, DISABLE);I2C_DeInit(SENSORS_I2C);I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = I2C_OWN_ADDRESS;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;/* Enable the I2C peripheral */I2C_Cmd(SENSORS_I2C, ENABLE);/* Initialize the I2C peripheral */I2C_Init(SENSORS_I2C, &I2C_InitStructure);#ifdef User_debugMPL_LOGI(I2C Restarted.n);#endifreturn 1;int I2C_Reset_User()return I2Cx_TIMEOUT_UserCallback(0);/* brief Writes a Byte to a given register to the sensors through the control interface (I2C)* param RegisterAddr: The address (location) of the register to be written.* param RegisterValue: the Byte value to be written into destination register.* retval 0 if correct communication, else wrong communication*/unsigned long Sensors_I2C_WriteRegister(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, const unsignedchar *RegisterValue)uint32_t result = 0;uint32_t i = RegisterLen;_IO uint32_t I2CTimeout = I2Cx_LONG_TIMEOUT;/RegisterValue = RegisterValue + (RegisterLen - 1);/* Wait for the busy flag to be cleared */WAIT_FOR_FLAG (I2C_FLAG_BUSY, RESET, I2Cx_LONG_TIMEOUT, 1);/* Start the config sequence */I2C_GenerateSTART(SENSORS_I2C, ENABLE);/* Wait for the start bit to be set */WAIT_FOR_FLAG (I2C_FLAG_SB, SET, I2Cx_FLAG_TIMEOUT, 2);/* Transmit the slave address and enable writing operation */I2C_Send7bitAddress(SENSORS_I2C, (Address1), I2C_Direction_Transmitter);/* Wait for address bit to be set */WAIT_FOR_FLAG (I2C_FLAG_ADDR, SET, I2Cx_FLAG_TIMEOUT, 3);/* clear the ADDR interrupt bit - this is done by reading SR1 and SR2*/CLEAR_ADDR_BIT/* Wait for address bit to be set */WAIT_FOR_FLAG (I2C_FLAG_TXE, SET, I2Cx_FLAG_TIMEOUT, 4);/* Transmit the first address for write operation */I2C_SendData(SENSORS_I2C, RegisterAddr);while (i-)/* Wait for address bit to be set */WAIT_FOR_FLAG (I2C_FLAG_TXE, SET, I2Cx_FLAG_TIMEOUT, 5);/* Prepare the register value to be sent */I2C_SendData(SENSORS_I2C, *RegisterValue-);I2C_SendData(SENSORS_I2C, *RegisterValue+);/* Wait for address bit to be set */WAIT_FOR_FLAG (I2C_FLAG_BTF, SET, I2Cx_FLAG_TIMEOUT, 6);/* End the configuration sequence */I2C_GenerateSTOP(SENSORS_I2C, ENABLE);/* Return the verifying value: 0 (Passed) or 1 (Failed) */return result;unsigned long Sensors_I2C_ReadRegister(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char*RegisterValue)uint32_t result = 0;uint8_t bytesRemaining = RegisterLen;_IO uint32_t I2CTimeout = I2Cx_LONG_TIMEOUT;/* Wait for the busy flag to be cleared */WAIT_FOR_FLAG (I2C_FLAG_BUSY, RESET, I2Cx_LONG_TIMEOUT, 7);/* Start the config sequence */I2C_GenerateSTART(SENSORS_I2C, ENABLE);/* Wait for the start bit to be set */WAIT_FOR_FLAG (I2C_FLAG_SB, SET, I2Cx_FLAG_TIMEOUT, 8);/* Transmit the slave address and enable writing operation */I2C_Send7bitAddress(SENSORS_I2C, (Address1), I2C_Direction_Transmitter);/* Wait for the start bit to be set */WAIT_FOR_FLAG (I2C_FLAG_ADDR, SET, I2Cx_FLAG_TIMEOUT, 9);/* clear the ADDR interrupt bit - this is done by reading SR1 and SR2*/CLEAR_ADDR_BIT;/* Wait for address bit to be set */WAIT_FOR_FLAG (I2C_FLAG_TXE, SET, I2Cx_FLAG_TIMEOUT, 10);/* Transmit the register address to be read */I2C_SendData(SENSORS_I2C, RegisterAddr);/* Wait for address bit to be set */WAIT_FOR_FLAG (I2C_FLAG_TXE, SET, I2Cx_FLAG_TIMEOUT, 11);/*! Send START condition a second time */I2C_GenerateSTART(SENSORS_I2C, ENABLE);/* Wait for the start bit to be set */WAIT_FOR_FLAG (I2C_FLAG_SB, SET, I2Cx_FLAG_TIMEOUT, 12);/*! Send address for read */I2C_Send7bitAddress(SENSORS_I2C, (Address1), I2C_Direction_Receiver);/* Wait for the start bit to be set */WAIT_FOR_FLAG (I2C_FLAG_ADDR, SET, I2Cx_FLAG_TIMEOUT, 13);if (RegisterLen = 1) /*! Disable Acknowledgment */I2C_AcknowledgeConfig(SENSORS_I2C, DISABLE);/* clear the ADDR interrupt bit - this is done by reading SR1 and SR2*/CLEAR_ADDR_BIT;/*! Send STOP Condition */I2C_GenerateSTOP(SENSORS_I2C, ENABLE);/* Wait for the RXNE bit to be set */WAIT_FOR_FLAG (I2C_FLAG_RXNE, SET, I2Cx_FLAG_TIMEOUT, 14);/bytesRemaining-;/RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C);RegisterValue0 = I2C_ReceiveData(SENSORS_I2C); else if( RegisterLen = 2) /*!CR1 |= I2C_CR1_POS;/* clear the ADDR interrupt bit - this is done by reading SR1 and SR2*/CLEAR_ADDR_BIT;/* Wait for the buffer full bit to be set */WAIT_FOR_FLAG (I2C_FLAG_BTF, SET, I2Cx_FLAG_TIMEOUT, 15);/*! Send STOP Condition */I2C_GenerateSTOP(SENSORS_I2C, ENABLE);/* Read 2 bytes */bytesRemaining-;/RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C);/RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C);RegisterValue0 = I2C_ReceiveData(SENSORS_I2C);RegisterValue1 = I2C_ReceiveData(SENSORS_I2C); else /* more than 2 bytes */* clear the ADDR interrupt bit - this is done by reading SR1 and SR2*/ CLEAR_ADDR_BIT;while(bytesRemaining)if( bytesRemaining = 3)/* Wait for the buffer full bit to be set */WAIT_FOR_FLAG (I2C_FLAG_BTF, SET, I2Cx_FLAG_TIMEOUT, 16);/*! Disable Acknowledgment */I2C_AcknowledgeConfig(SENSORS_I2C, DISABLE);/* Read 1 bytes */bytesRemaining-;/RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C);*RegisterValue+ = I2C_ReceiveData(SENSORS_I2C);/*! Send STOP Condition */I2C_GenerateSTOP(SENSORS_I2C, ENABLE);/* Read 1 bytes */bytesRemaining-;/RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C);*RegisterValue+ = I2C_ReceiveData(SENSORS_I2C);/* Wait for the buffer full bit to be set */WAIT_FOR_FLAG (I2C_FLAG_RXNE, SET, I2Cx_FLAG_TIMEOUT, 17);/* Read 1 bytes */bytesRemaining-;/RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C);*RegisterValue+ = I2C_ReceiveData(SENSORS_I2C);else/* Wait for the RXNE bit to be set */WAIT_FOR_FLAG (I2C_FLAG_RXNE, SET, I2Cx_FLAG_TIMEOUT, 18);/* Read 2 bytes */bytesRemaining-;/RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C);*RegisterValue+ = I2C_ReceiveData(SENSORS_I2C);/* Clear BTF flag */I2C_ClearFlag(SENSORS_I2C, I2C_FLAG_BTF);/* Wait for the busy flag to be cleared */WAIT_FOR_FLAG (I2C_FLAG_BUSY, RESET, I2Cx_LONG_TIMEOUT, 19);/*!CR1 &= I2C_CR1_POS;/* Return the byte read from sensor */return result;int Sensors_I2C_WriteRegister_swap(unsigned char slave_addr,unsigned char reg_addr,unsigned char len, unsigned char *data_ptr)char retries=0;int ret = 0;unsigned short retry_in_mlsec = 5;tryWriteAgain:ret = 0;ret = Sensors_I2C_WriteRegister( slave_addr, reg_addr, len, data_ptr);if(ret & retry_in_mlsec)if( retries+ 4 )#ifdef User_debugMPL_LOGI(I2C:Failed to Write.n);#endifreturn ret;#ifdef User_debugMPL_LOGI(I2C:Retry to write.n);#endifDelay(retry_in_mlsec);goto tryWriteAgain;Delay(retry_in_mlsec);return ret;int Sensors_I2C_ReadRegister_swap(unsigned char slave_addr,unsigned char reg_addr,unsigned char len, unsigned char *data_ptr)char retries=0;int ret = 0;unsigned short retry_in_mlsec = 5;tryReadAgain:ret = 0;ret = Sensors_I2C_ReadRegister( slave_addr, reg_addr, len, data_ptr);if(ret & retry_in_mlsec)if( retries+ 4 )#ifdef User_debugMPL_LOGI(I2C:Falied to read.n);#endifreturn ret;#ifdef User_debugMPL_LOGI(I2C:Retry to read.n);#endifDelay(retry_in_mlsec);goto tryReadAgain;Delay(retry_in_mlsec);return ret;
展开阅读全文