2015-05-02 03:30 PM
Hi,
I have been looking at this for hours, but cannot determine why I cannot get the I2C3 operating, even getting a pulse from the SCK line. I am using an STM32F4 device, with an ST LIS3DML sensor. Both SCK and SDA are physically pulled to Vdd with a 10K resistor. GPIO and call to I2C init is below: void init_I2C3(void) { GPIO_InitTypeDef GPIO_InitStruct; I2C_InitTypeDef I2C_InitStruct; // enable APB1 peripheral clock for I2C3 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE); // enable clock for SCL pin RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // enable clock for SDA pin RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStruct); // Connect I2C3 pins to AF GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_I2C3); // SCL GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_I2C3); // SDA // configure I2C3 I2C_InitStruct.I2C_ClockSpeed = 100000; // 100kHz I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStruct.I2C_OwnAddress1 = 0x00; I2C_InitStruct.I2C_Ack = I2C_Ack_Disable; I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_Init(I2C3, &I2C_InitStruct); // enable I2C3 I2C_Cmd(I2C3, ENABLE); }Below is the I2C start, and the I2C send: void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction) { // wait until I2C1 is not busy anymore while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); // Send I2C1 START condition I2C_GenerateSTART(I2Cx, ENABLE); // wait for I2C1 EV5 --> Slave has acknowledged start condition while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); // Send slave Address for write I2C_Send7bitAddress(I2Cx, address, direction); /* wait for I2C1 EV6, check if * either Slave has acknowledged Master transmitter or * Master receiver mode, depending on the transmission * direction */ if(direction == I2C_Direction_Transmitter){ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); } else if(direction == I2C_Direction_Receiver){ while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); } } void I2C_write(I2C_TypeDef* I2Cx, uint8_t data) { I2C_SendData(I2Cx, data); // wait for I2C1 EV8_2 --> byte has been transmitted while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); } uint8_t I2C_read_ack(I2C_TypeDef* I2Cx){ // enable acknowledge of recieved data I2C_AcknowledgeConfig(I2Cx, ENABLE); // wait until one byte has been received while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) ); // read data from I2C data register and return data byte uint8_t data = I2C_ReceiveData(I2Cx); return data; } uint8_t I2C_read_nack(I2C_TypeDef* I2Cx){ // disabe acknowledge of received data // nack also generates stop condition after last byte received // see reference manual for more info I2C_AcknowledgeConfig(I2Cx, DISABLE); I2C_GenerateSTOP(I2Cx, ENABLE); // wait until one byte has been received while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) ); // read data from I2C data register and return data byte uint8_t data = I2C_ReceiveData(I2Cx); return data; }From main, I call: &sharpdefine LIS3MDL_ADDRESS 0x1C &sharpdefine LIS3MDL_WHO_AM_I 0x0F // should return 0x3D init_I2C3(); I2C_start(I2C3, LIS3MDL_ADDRESS<<1, I2C_Direction_Transmitter); I2C_write(I2C3, LIS3MDL_WHO_AM_I); //I2C_read_nack(I2C3); I2C_read_ack(I2C3); However, when scoping the SCK line, there is never a clock burst from the STM32F4. In fact, it hangs the processor if I try to use either read call above. Any idea of what the problem might be? Thank you for any help... #stm32f4 #i2c3