2013-03-05 03:16 AM
Hi,
I am programming the STM3241G-EVAL to work as a i2c slave to comunicate with a mother board running Linux. In the tests I am using the linux i2c-tools.When I try to send a byte (0x35) to the device address (0x0A), it does not get it right. I have checked the signal with an osciloscope and there is a byte of zeros between the address byte and the data (see the image).Does anyone know what that byte is and why it is there? the documentation says that after the address byte (the device is configured to have 7-bit address) and the ACK, it is sent the data. #i2c-signal2013-03-05 03:45 AM
What is sending this data, presumably the PC if the STM32 is a SLAVE?
What is the command line for the tool generating the transaction? What part is the SLAVE device emulating?2013-03-05 04:49 AM
Yes, the PC sends the data as Master and the STM32 is the Slave.
I already figured out what is that zero byte, it is the data address (that I don't really need, but that seems to be necesary for the command). But I still don't know why the device doesn't understand the transaction. The command line I am using is: i2cset -y 0 5 0 0x35 where i2cset is one of the linux i2c-tools -y is to skip confirmation 0 is the i2c bus 5 is the address of the STM32 (it shifts the 0x0A to 0x05, I think it is because it doesn't count the read/write bit of the address) 0 is the data address -> that is the zero byte I didn't understand 0x35 is the data to write After launching the command both lines SCL and SDA go down. And thelastevent = I2C_GetLastEvent(I2C1); in the interrupt routine gets continiusly the value0x20044 (RxNE and STOPF bits set in SR1) When I pause the execution SCL and SDA go high again. Could it be a timing problem? maybe the STM32 is too fast? The device I am using is the stm32f417void I2C1_EV_IRQHandler(){
uint32_t lastevent;
lastevent = I2C_GetLastEvent(I2C1);
switch(lastevent){
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
STM_EVAL_LEDToggle(LED1);
I2C_CleanADDR();
break;
case I2C_EVENT_SLAVE_BYTE_RECEIVED:
(void) I2C1->SR1;
received_data = I2C_ReceiveData(I2C1);
WRITE_flag = 1;
STM_EVAL_LEDToggle(LED2);
break;
case I2C_EVENT_SLAVE_STOP_DETECTED:
STM_EVAL_LEDToggle(LED3);
I2C_CleanSTOPF();
break;
default:
STM_EVAL_LEDToggle(LED4); // it gets here continiusly with lastevent = 0x20044
}
}
inline void I2C_CleanADDR(void)
{
while ((I2C1->SR1 & I2C_SR1_ADDR) == I2C_SR1_ADDR)
{
(void)I2C1->SR1;
(void)I2C1->SR2;
}
}
inline void I2C_CleanSTOPF(void)
{
while ((I2C1->SR1&I2C_SR1_STOPF) == I2C_SR1_STOPF)
{
(void)I2C1->SR1;
I2C1->CR1 |= 0x1;
}
}
2013-03-05 09:40 AM
It gets there continuously because you don't service the state.
/*** @brief Communication events
*
* Wait on one of these events when EV1 has already been checked and:
*
* - Slave RECEIVER mode:
* - EV2: When the application is expecting a data byte to be received.
* - EV4: When the application is expecting the end of the communication: master
* sends a stop condition and data transmission is stopped.
*
* - Slave Transmitter mode:
* - EV3: When a byte has been transmitted by the slave and the application is expecting
* the end of the byte transmission. The two events I2C_EVENT_SLAVE_BYTE_TRANSMITTED and
* I2C_EVENT_SLAVE_BYTE_TRANSMITTING are similar. The second one can optionally be
* used when the user software doesn't guarantee the EV3 is managed before the
* current byte end of transfer.
* - EV3_2: When the master sends a NACK in order to tell slave that data transmission
* shall end (before sending the STOP condition). In this case slave has to stop sending
* data bytes and expect a Stop condition on the bus.
*
* @note In case the user software does not guarantee that the event EV2 is
* managed before the current byte end of transfer, then user may check on EV2
* and BTF flag at the same time (ie. (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_BTF)).
* In this case the communication may be slower.
*
*/