2016-12-21 07:03 AM
Hi all,
I'm new on ST device, i'm trying to test the I2C bus but I can't understand how it works.. I do not want to use the HAL library but manage directly the register, but the I2C Interface on ST produce the state of transmission (0x08,0x10,0x28...) like other uC? or it manages all the transmission?
Thanks.
Lorenzo.
2016-12-21 08:13 AM
Hi
Meneghello.Lorenzo
,-Nesrine-
Ifmy suggestanswers your question, please mark it as correct.
2016-12-21 08:21 AM
Lorenzo,
no, the I2C interface does not expose discrete states of the internal state machine as is usual in I2C peripherals following the Philips 'standard' implementation. Rather, you have to infer the internal state from various individual status bits. Read thoroughly the I2C chapter in the RM of the STM32 model of your choice. Beware, there are several evolutionary incarnations of that peripheral in various STM32 models, differing in some of the details.
JW
2016-12-22 03:49 AM
Very hard work.. There's nothing online ? example code?
Thanks.
2016-12-22 04:03 AM
Hi
Meneghello.Lorenzo
,If I suppose that you are using STM32F4 product, Irecommend you to start with the examples available at ST website:
firmware package:
STM32Cube_FW_F4_V1.0\Projects\STM32F4-Discovery\Examples\I2C, if you are a Cube userorSTM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Examples\I2Cif you are SPL user
-Nesrine-
2016-12-22 04:45 AM
The I2C itself is really simple. But to get a stable Communication between Slave and Master could take some time. I use the HAL-Driver and for Init the Driver i2c.c/.h generated from Cube. On top I have a Busdriver which is handling the Data and Transmit + Receive. Simplest Solution is to work with a State Machine. For this I have following States:
typedef enum{
eI2C_IsErrorOccured = 0,
eI2C_IsReadyForSend = 1,
eI2C_IsReadyForReceive = 2,
eI2C_IsSending = 3, //!< Status while Sending (only Bonus for Debugging, not really needed)
eI2C_IsReceiving = 4, //!< Status while Receiving (only Bonus for Debugging, not really needed)
eI2C_SendIsDone = 5, //!< after Tx Complete Interrupt
eI2C_ReceiveIsDone = 6, //!< after Rx Complete Interrupt
} TE_I2C_SEND_RECEIVE_STATE;
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
Build your Driver around this. Keep in Mind, that Slave and Master must have a possibility to get synchron after Errors.
Good luck!
2016-12-22 08:18 AM
Thanks all for reply, I'm trying to send a single byte but when I set the START bit on CR2, the STOPF and NACK flag will comes active.. I don't have any device on the bus..
2016-12-22 04:53 PM
Which STM32? How did you initialize the related GPIO pins?
JW
2016-12-23 02:09 AM
I'm using the STM32F042K6 and this is the code:
// I2C Peripheral Disable
I2C1->CR1 &= ~0x01;
//Enable the i2c
RCC->APB1ENR |= (1<<21);
RCC->CFGR3 |= (1<<4); //SYSCLK 48Mhz
//Reset the Peripheral
RCC->APB1RSTR |= (1<<21);
RCC->APB1RSTR &= ~(1<<21);
//Configure and initialize the GPIOs
GPIOA->MODER |= 0x280000;
GPIOA->OSPEEDR |= 0x280000;
GPIOA->PUPDR |= 0x140000;
//Connect GPIO pins to peripheral
GPIOA->AFR[1] |= 0x440;
//Configure and Initialize the I2C
I2C1->TIMINGR = 0xB0420F13;
//100kHz
I2C1->OAR1 = 0;
I2C1->CR2 &= ~0x01;
//Addressing mode 7 bit
I2C1->OAR2 = 0;
I2C1->CR2 |= 0x80000;
I2C1->CR1 &= ~(1<<19);
I2C1->CR1 |= (1<<17);
// I2C Peripheral Enable
I2C1->CR1 |= 0x01;
2016-12-23 07:07 AM
I would expect that. If you don't have any device on the bus you won't get the ACK after the START bit, address and R/W bit. That's why the NACK flag is set. You have to use another device with I2C to debug the communication. Also without a logic analyzer with I2C protocol or at least oscilloscope it may be quite challenging.