AnsweredAssumed Answered

I2C Acknowledge problem

Question asked by hosS on Sep 23, 2013
Latest reply on Sep 23, 2013 by hosS
Hi,
I am trying to establish I2C communication between STM32F4 and OV5642 Camera module (http://www.arducam.com/camera-modules/5mp-ov5642/)  and I want to test it separately. I already worked with I2C and I am sure of the electronic connexions (3.3V, 4.7k pullups). I am only connexting Power, GND, I2C1_SCL and I2C1_SDA.
The communication starts right (SB flag=1), then when the device address is sent (0x78) I get an acknowledge failure. I think that maybe I am missing something, I hope someone can help me out. Here is my code:
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
#include "main.h"
 
/* Private variables ---------------------------------------------------------*/
__IO uint32_t TimingDelay;
 
/* Private function prototypes -----------------------------------------------*/
void I2C1_Config(void);
uint8_t DCMI_SingleRandomWrite1(uint8_t , uint16_t , uint8_t );
 
int main(void)
{
  
  /* SysTick end of count event each 10ms */
  RCC_GetClocksFreq(&RCC_Clocks);
  SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);
 
   I2C1_Config();
//  I2C_GenerateSTOP(I2C2, ENABLE);
     
    DCMI_SingleRandomWrite1(0x78 , 0x3103 , 0x93 );
 
    while (1)
    {
    }
}  
 
 
/**
  * @brief  Configures the I2C2 used for OV9655 camera module configuration.
  * @param  None
  * @retval None
  */
void I2C1_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  I2C_InitTypeDef  I2C_InitStruct;
 
 
  /* GPIOB clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
   
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
   
  /* I2C1 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
 
  /* Connect I2C1 pins to AF4 ************************************************/
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); 
   
  /* Configure I2C1 GPIOs *****************************************************/ 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  
  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
  /* Configure I2C1 ***********************************************************/ 
  /* I2C DeInit */  
  I2C_DeInit(I2C1);
   
  /* Set the I2C structure parameters */
  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_Enable;
  I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStruct.I2C_ClockSpeed = 30000;
   
  /* Initialize the I2C peripheral w/ selected parameters */
  I2C_Init(I2C1, &I2C_InitStruct);
 
  /* Enable the I2C peripheral */
  I2C_Cmd(I2C1, ENABLE);
}
 
/**
  * @brief  Writes a byte at a specific Camera register
  * @param  Device: OV9655 write address.
  * @param  Addr: OV9655 register address.
  * @param  Data: data to be written to the specific register
  * @retval 0x00 if write operation is OK.
  *         0xFF if timeout condition occured (device not connected or bus error).
  */
uint8_t DCMI_SingleRandomWrite1(uint8_t Device, uint16_t Addr, uint8_t Data)
{
  uint8_t LSB_Addr, MSB_Addr;
  uint32_t timeout = DCMI_TIMEOUT_MAX;
 
  LSB_Addr=(uint8_t)(Addr);
  MSB_Addr=(uint8_t)(Addr>>8);
 
   
  /* 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 exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  }
    
  /* Send DCMI selcted device slave Address for write */
  I2C_Send7bitAddress(I2C1, Device, 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 exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  }
  
  /* Send I2C1 location address MSB */
  I2C_SendData(I2C1, (uint8_t)(MSB_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 exeeded, exit with error code */
    if ((timeout--) == 0) return 0xFF;
  }
 
    /* Send I2C1 location address LSB */
  I2C_SendData(I2C1, (uint8_t)(LSB_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 exeeded, 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 exeeded, 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;
}
 

Outcomes