bradaas

I2C fail to write to OV7670

Discussion created by bradaas on May 16, 2018

Hi all,

 

I've been attempting to get the i2c working properly on the STM32F051R8, but cannot get write to work. My reads appear to work. The issue is i can get the start condition going then the second byte (register we want to write to), but the 3rd byte (data we are writing) never goes. After the code goes through the first time, it starts to ping pong sending the register address and data from last attempt, aka  sends 0x08, then 0x12, then 0x08...

Im attempting to read and write with a OV7670 camera, and i get ACKs when addressing it properly.

 

I have 4.75k pullups on the lines and using 100 KHz normal mode. Clock timing is from the excel tool, which could be a problem too.

 

*Some debugging code is left in for reading the ISR register as it seems to a value of 32833 the first time through (right after the software delay)

 

#include "OV7670_control.h"
#include "stm32f0xx.h"
#include "stm32f0xx_rcc.h"
#include "stm32f0xx_gpio.h"
#include "stm32f0xx_i2c.h"
#include "stdint.h"
#include "systick_rtc.h"

 

void I2C_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;

//RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); // Enable GPIO port B
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE); // Enable GPIO port F
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);

//GPIO_PinAFConfig (GPIOB, GPIO_PinSource10, GPIO_AF_1); //SCL
//GPIO_PinAFConfig (GPIOB , GPIO_PinSource11, GPIO_AF_1);//SDA
GPIO_PinAFConfig (GPIOF, GPIO_PinSource6, GPIO_AF_1); //SCL
GPIO_PinAFConfig (GPIOF, GPIO_PinSource7, GPIO_AF_1);//SDA

// GPIO config
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
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);
GPIO_Init(GPIOF, &GPIO_InitStructure);

//Configure I2C2, master,fast mode */
/* (1) Timing register value is computed with the
xls file*/

// I2C config
I2C_DeInit(I2C2);
I2C_Cmd(I2C2,DISABLE);

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_AnalogFilter=I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter=0x00;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_Timing=0x10805D88; //0x10805D89; 100khz //0x00801850 400khz

I2C_Init(I2C2, &I2C_InitStructure);
I2C_Cmd(I2C2, ENABLE);

//I2C_NumberOfBytesConfig(I2C2,1);
//I2C_ITConfig(I2C2, I2C_IT_RXI, ENABLE);
//NVIC_SetPriority(I2C2_IRQn,1);
//NVIC_EnableIRQ(I2C2_IRQn);
}

uint8_t I2C2_IRQHandler(void)
{
return I2C_ReceiveData(I2C2);
}

void I2C_Write(uint8_t address, uint8_t registerAddress, uint8_t data)
{
//Check to see if the bus is busy
while(I2C_GetFlagStatus(I2C2, I2C_ISR_BUSY) != RESET); // check no transmission in progress

//I2C_MasterRequestConfig(I2C2,I2C_Direction_Transmitter);
//I2C_NumberOfBytesConfig(I2C2,3);
//I2C_SlaveAddressConfig(I2C2,address);
//I2C_GenerateSTART(I2C2, ENABLE);
I2C_TransferHandling(I2C2, address, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
uint32_t _isrReg0=I2C2->ISR;
//while((I2C2->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS)
while((I2C2->ISR & I2C_ISR_TXE) != I2C_ISR_TXE)
{

if((I2C2->ISR & I2C_ISR_NACKF) == I2C_ISR_NACKF)
{
//I2C_GenerateSTART(I2C2, ENABLE); //retry
I2C_TransferHandling(I2C2, address, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
}
};
uint32_t _isrReg1=I2C2->ISR;
I2C_SendData(I2C2, registerAddress);

//while(((I2C2->ISR & I2C_ISR_TXE) != I2C_ISR_TXE) && ((I2C2->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS) );
Delay_us(100);
uint32_t _isrReg=I2C2->ISR;
I2C_SendData(I2C2, data); // sending data
I2C_GenerateSTOP(I2C2, ENABLE); // set stop bit

}

//I2C all read addresses are odd
uint8_t I2C_Read(uint8_t address, uint8_t registerAddress)
{
uint8_t data=0;

while(I2C_GetFlagStatus(I2C2, I2C_ISR_BUSY) != RESET); // check no transmission in progress
I2C_TransferHandling(I2C2, address, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
while(I2C_GetFlagStatus(I2C2, I2C_ISR_TXE) == RESET); // wait for TX flag set

I2C_SendData(I2C2, (uint8_t)registerAddress); // send data
I2C_GenerateSTOP(I2C2, ENABLE); // set stop bit
while(I2C_GetFlagStatus(I2C2, I2C_ISR_BUSY) != RESET); // check no transmission in progress

I2C_TransferHandling(I2C2, address, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); // configure to receive

data= I2C_ReceiveData(I2C2);

I2C_ClearFlag(I2C2, I2C_ICR_STOPCF); // clear stop bit

return data;
}

Outcomes