#include #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "i2c.h" #include "debug.h" static void I2C1_InitI2C(void); static void I2C2_InitI2C(void); static int8_t I2C1_Timeout(I2C_TypeDef* I2Cx, int8_t val); //static char IsInitialized = 0; void I2C1_Init(I2C_TypeDef* I2Cx) { GPIO_InitTypeDef GPIO_InitStructure; // initialize only once! /*if(IsInitialized) { return; }*/ if(I2C1 == I2Cx) { // I2C-Clock enable RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // Clock Enable Pins RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); // I2C reset RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // SCL-Pin GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_Init(GPIOB, &GPIO_InitStructure); // I2C init I2C1_InitI2C(); } else if(I2C2 == I2Cx) { // I2C-Clock enable RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); // Clock Enable Pins RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // I2C reset RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // SCL-Pin GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; GPIO_Init(GPIOB, &GPIO_InitStructure); // I2C init I2C2_InitI2C(); } //IsInitialized = 1; } static void I2C1_InitI2C(void) { I2C_InitTypeDef I2C_InitStructure; I2C_DeInit(I2C1); // I2C-Config I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C1_CLOCK_FRQ; // Init Struktur I2C_Init(I2C1, &I2C_InitStructure); // I2C enable I2C_Cmd(I2C1, ENABLE); } static void I2C2_InitI2C(void) { I2C_InitTypeDef I2C_InitStructure; I2C_DeInit(I2C2); // I2C-Config I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C1_CLOCK_FRQ; // Init Struktur I2C_Init(I2C2, &I2C_InitStructure); // I2C enable I2C_Cmd(I2C2, ENABLE); } int16_t I2C1_ReadByte(I2C_TypeDef* I2Cx, uint8_t slave_adr, uint8_t adr) { int16_t ret = 0; uint32_t timeout = I2C1_TIMEOUT; // Start-Sequence I2C_GenerateSTART(I2Cx, ENABLE); timeout = I2C1_TIMEOUT; while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_SB)) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -1)); } // ACK disable I2C_AcknowledgeConfig(I2Cx, DISABLE); // send slave-address (write) I2C_Send7bitAddress(I2Cx, slave_adr, I2C_Direction_Transmitter); timeout = I2C1_TIMEOUT; while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR)) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -2)); } // clear ADDR-Flag I2Cx->SR2; timeout = I2C1_TIMEOUT; while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_TXE)) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -3)); } // send address I2C_SendData(I2Cx, adr); timeout = I2C1_TIMEOUT; while((!I2C_GetFlagStatus(I2Cx, I2C_FLAG_TXE)) || (!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF))) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -4)); } // Start-Sequence I2C_GenerateSTART(I2Cx, ENABLE); timeout = I2C1_TIMEOUT; while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_SB)) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -5)); } // send slave-address(read) I2C_Send7bitAddress(I2Cx, slave_adr, I2C_Direction_Receiver); timeout = I2C1_TIMEOUT; while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR)) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -6)); } // clear ADDR-Flag I2Cx->SR2; timeout = I2C1_TIMEOUT; while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_RXNE)) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -7)); } // Stop-Sequence I2C_GenerateSTOP(I2Cx, ENABLE); // read data ret = (int16_t)(I2C_ReceiveData(I2Cx)); // ACK enable I2C_AcknowledgeConfig(I2Cx, ENABLE); return ret; } int16_t I2C1_ReadByte16(I2C_TypeDef* I2Cx, uint8_t slave_adr, uint8_t adr) { return (I2C1_ReadByte(I2Cx, slave_adr, adr) << 8 | I2C1_ReadByte(I2Cx, slave_adr, adr)); } int16_t I2C1_WriteByte(I2C_TypeDef* I2Cx, uint8_t slave_adr, uint8_t adr, uint8_t wert) { uint32_t timeout = I2C1_TIMEOUT; // Start-Sequence I2C_GenerateSTART(I2Cx, ENABLE); timeout = I2C1_TIMEOUT; while(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_SB)) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -1)); } // send slave-address (write) I2C_Send7bitAddress(I2Cx, slave_adr, I2C_Direction_Transmitter); timeout = I2C1_TIMEOUT; while (!I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR)) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -2)); } // clear ADDR-Flag I2Cx->SR2; timeout = I2C1_TIMEOUT; while (!I2C_GetFlagStatus(I2Cx, I2C_FLAG_TXE)) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -3)); } // send address I2C_SendData(I2Cx, adr); timeout = I2C1_TIMEOUT; while (!I2C_GetFlagStatus(I2Cx, I2C_FLAG_TXE)) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -4)); } // send data I2C_SendData(I2Cx, wert); timeout = I2C1_TIMEOUT; while ((!I2C_GetFlagStatus(I2Cx, I2C_FLAG_TXE)) || (!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BTF))) { if(timeout != 0) timeout--; else return(I2C1_Timeout(I2Cx, -5)); } // Stop-Sequence I2C_GenerateSTOP(I2Cx, ENABLE); return 0; } void I2C_Scan(I2C_TypeDef* I2Cx) { int adr = 1, cnt = 0; d_printf("\fScanning...\r\n"); for(adr = 1; adr < 127; adr++) { int16_t ret = I2C1_ReadByte(I2Cx, adr<<1, 0); if(ret >= 0) { d_printf("Found device at 0x%X\r\n", adr); cnt++; } } d_printf("Found %d devices\r\n", cnt); } static int8_t I2C1_Timeout(I2C_TypeDef* I2Cx, int8_t val) { // Stop / Reset I2C_GenerateSTOP(I2Cx, ENABLE); I2C_SoftwareResetCmd(I2Cx, ENABLE); I2C_SoftwareResetCmd(I2Cx, DISABLE); // I2C deinit I2C_DeInit(I2Cx); if(I2C1 == I2Cx) { // I2C init I2C1_InitI2C(); } else if(I2C2 == I2Cx) { // I2C init I2C2_InitI2C(); } return val; }