2013-09-23 02:19 AM
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;
}
2013-09-23 08:12 AM
It worked!! ^^
I had to add the XCLK signal.2013-09-23 08:13 AM
It worked!! ^^
I had to add the XCLK signal.