cancel
Showing results for 
Search instead for 
Did you mean: 

I2C Questions on STM32F427

pohua
Associate II
Posted on November 25, 2016 at 09:35

I have a slave device which is address 0x78 for write and address 0x79 for read.

I want to confirm that why the below I2C transaction is difference?

I want to reset the slave device and the mapping register information as the below shown.

Reset register (R/W)

register address:0x3008

register default value:0x02

1.The return data=0x00 is success when the address doesn't shift left 1bit

#define OV5642_DEVICE_WRITE_ADDRESS 0x78

0690X00000605SxQAI.png

2.The return data=0xFF is failure when the address doesn't shift left 1bit

#define OV5642_DEVICE_WRITE_ADDRESS 0x78<<1

0690X00000605SUQAY.png

Subroutine

void OV5642_Reset(void)

{

  OV5642_WriteReg(SC_SYS_0, 0x80);

}

uint8_t OV5642_WriteReg(uint16_t Addr, uint8_t Data)

{

  uint32_t timeout = DCMI_TIMEOUT_MAX;

  

  /* Generate the Start Condition */

  I2C_GenerateSTART(I2C1, ENABLE);

  /* Test on I2C1 EV5 and clear it */

  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))

  {

    /* If the timeout delay is exceeded, exit with error code */

    if ((timeout--) == 0) return 0xFF;

  }

   

  /* Send DCMI selected device slave Address for write */

  I2C_Send7bitAddress(I2C1, OV5642_DEVICE_WRITE_ADDRESS, I2C_Direction_Transmitter);

 

  /* Test on I2C1 EV6 and clear it */

  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))

  {

    /* If the timeout delay is exceeded, exit with error code */

    if ((timeout--) == 0) return 0xFF;

  }

 

  /* Send I2C1 location address LSB */

  I2C_SendData(I2C1, (uint8_t)(Addr>>8));

I2C_SendData(I2C1, (uint8_t)(Addr));

  /* Test on I2C1 EV8 and clear it */

  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))

  {

    /* If the timeout delay is exceeded, exit with error code */

    if ((timeout--) == 0) return 0xFF;

  }

  

  /* Send Data */

  I2C_SendData(I2C1, Data);

  /* Test on I2C1 EV8 and clear it */

  timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */

  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))

  {

    /* If the timeout delay is exceeded, exit with error code */

    if ((timeout--) == 0) return 0xFF;

  }  

 

  /* Send I2C1 STOP Condition */

  I2C_GenerateSTOP(I2C1, ENABLE);

  

  /* If operation is OK, return 0 */

  return 0;

}
2 REPLIES 2
Posted on November 25, 2016 at 13:43

This is an often recurring confusion resulting from the unfortunate way how the I2C address is defined. Quoting from the specification, UM10204 rev.6, ch.3.1.10 ''The slave address and R/W bit'':

 

 After the START condition (S), a slave address is sent.

 

This address is seven bits long followed by an eighth bit which is a data direction bit (R/W) [...]

 

 

So, the definition of address is 7 bits, in your case 0x3C. From that, you construct the first transmitted byte so that you left-shift it by one and then add the read/write bit.

The problem is, that some people don't read the specification, or don't understand it, or take inappropriate shortcuts. So then you have datasheets incorrectly specifying ''read and write address'' which is the case here; and you have functions which incorrectly expect ''shifted address'', which is again the case here, coincidentally matching in their incorrectness...

JW
pohua
Associate II
Posted on November 28, 2016 at 04:08

Dear JW:

Thanks for your responsed and the I2C can work after I stuied the RM0090 and the F427's spec. for I2C.

Now, the I2C can access our device.