A Color Vision System for Embedded Robotics Applications

Click here to return to article

'C' Processor side I2C Interface:



// FPGA addresses of use.
#define I2C_PRERlo *(unsigned char volatile *)(FPGA_BASE_ADDR + (0x0 + (channel * 0x10)))
#define I2C_PRERhi *(unsigned char volatile *)(FPGA_BASE_ADDR + (0x1 + (channel * 0x10)))
#define I2C_CONTROL *(unsigned char volatile *)(FPGA_BASE_ADDR + (0x2 + (channel * 0x10)))
#define I2C_TX_REG *(unsigned char volatile *)(FPGA_BASE_ADDR + (0x3 + (channel * 0x10)))
#define I2C_RX_REG *(unsigned char volatile *)(FPGA_BASE_ADDR + (0x3 + (channel * 0x10)))
#define I2C_COMMAND *(unsigned char volatile *)(FPGA_BASE_ADDR + (0x4 + (channel * 0x10)))
#define I2C_STATUS *(unsigned char volatile *)(FPGA_BASE_ADDR + (0x4 + (channel * 0x10)))

#define I2C_ENB 0x80
#define I2C_IRQ_EN 0x40

void init_I2c(unsigned int channel) 
{ 
	system_usec_timer = 0;
	delay_usec(10);
	I2C_PRERlo = 99; // (50mhz/(5*100Khz))-1 
	I2C_PRERhi = 0; 
	I2C_CONTROL = (I2C_ENB | I2C_IRQ_EN); // I2C enable + INTERUPT ENABLE
	dprintf("\n\rI2C init ch:%d,val:%d\n\r",channel,(I2C_ENB | I2C_IRQ_EN));
	return; 
}

// defines for the command register
#define I2C_STA 0X80
#define I2C_STO 0x40
#define I2C_RD 0X20
#define I2C_WR 0X10
#define I2C_ACK 0X08
#define I2C_IACK 0x01

// defines for the status register
#define I2C_RxACK 0x80
#define I2C_BUSY 0x40
#define I2C_AL 0x20
#define I2C_TIP 0x02
#define I2C_IRQ 0x01

void i2c_Write(unsigned int channel, unsigned char AA,unsigned char BB,unsigned char CC) 
{ 
	I2C_TX_REG = (AA << 1);
	I2C_COMMAND = (I2C_WR | I2C_STA);
	while(0 != (I2C_STATUS & I2C_TIP))
	{
		feed_watchdog();
	}
	while(0 == (I2C_STATUS & I2C_IRQ))
	{
		feed_watchdog();
		dprintf("\n\r(ch:%d) for IRQ(%d)...1",channel,I2C_STATUS);
	}
	I2C_COMMAND = I2C_IACK;

	I2C_TX_REG = BB;
	I2C_COMMAND = I2C_WR;
	while(0 != (I2C_STATUS & I2C_TIP))
	{
		feed_watchdog();
	}
	while(0 == (I2C_STATUS & I2C_IRQ))
	{
		feed_watchdog();
		dprintf("\n\rWaiting for IRQ...2");
	}
	I2C_COMMAND = I2C_IACK;

	I2C_TX_REG = CC;
	I2C_COMMAND = (I2C_STO | I2C_WR);
	while(0 != (I2C_STATUS & I2C_TIP))
	{
		feed_watchdog();
	}
	while(0 == (I2C_STATUS & I2C_IRQ))
	{
		feed_watchdog();
		dprintf("\n\rWaiting for IRQ...3");
	}
	I2C_COMMAND = I2C_IACK;
	return;
} 

unsigned char i2c_Read(unsigned int channel,unsigned char AA,unsigned char BB) 
{
	unsigned char CC;
	I2C_TX_REG = (AA << 1);
	I2C_COMMAND = (I2C_STA | I2C_WR);
	while(0 != (I2C_STATUS & I2C_TIP))
	{
		feed_watchdog();
	}
	while(0 == (I2C_STATUS & I2C_IRQ))
	{
		feed_watchdog();
		dprintf("\n\rWaiting for IRQ...4");
	}
	I2C_COMMAND = I2C_IACK;


	I2C_TX_REG = BB;
	I2C_COMMAND = I2C_WR;
	while(0 != (I2C_STATUS & I2C_TIP))
	{
		feed_watchdog();
	}
	while(0 == (I2C_STATUS & I2C_IRQ))
	{
		feed_watchdog();
		dprintf("\n\rWaiting for IRQ...5");
	}
	I2C_COMMAND = I2C_IACK;


	I2C_TX_REG = (AA << 1) + 1;
	I2C_COMMAND = (I2C_STA | I2C_WR);
	while(0 != (I2C_STATUS & I2C_TIP))
	{
		feed_watchdog();
	}
	while(0 == (I2C_STATUS & I2C_IRQ))
	{
		feed_watchdog();
		dprintf("\n\rWaiting for IRQ...6");
	}
	I2C_COMMAND = I2C_IACK;


	I2C_COMMAND = (I2C_RD | I2C_STO | I2C_ACK);
	while(0 != (I2C_STATUS & I2C_TIP))
	{
		feed_watchdog();
	}
	while(0 == (I2C_STATUS & I2C_IRQ))
	{
		feed_watchdog();
		dprintf("\n\rWaiting for IRQ...7");
	}
	I2C_COMMAND = I2C_IACK;
	CC = I2C_RX_REG;
	return(CC);
}

And to call it, it looks like this:

// init
	init_I2c(1);
// sample write
	i2c_Write(1,0x24,0x11,( 0x1c | (test_val << 7))); 
// sample read
	cuck = i2c_Read(1,0x24,0x02); 
	dprintf("\r0x02(0x%x)",cuck);

Click here to return to article