Skip to content
Snippets Groups Projects
i2c.c 1.53 KiB
Newer Older
#include "types.h"
#include "board.h"
#include "gpio.h"

#define I2C_DELAY 100

static void mi2c_delay()
{
    int i;
    for(i=0;i<I2C_DELAY;i++) asm volatile ("nop");
}

#define M_SDA_OUT(x) { gpio_out(GPIO_PIN_SDA_OUT, x); mi2c_delay(); }
#define M_SCL_OUT(x) { gpio_out(GPIO_PIN_SCL_OUT, x); mi2c_delay(); }
#define M_SDA_IN gpio_in(GPIO_PIN_SDA_IN)

void mi2c_start()
{
  M_SDA_OUT(0);
  M_SCL_OUT(0);
}

void mi2c_repeat_start()
{
  M_SDA_OUT(1);
  M_SCL_OUT(1);
  M_SDA_OUT(0);
  M_SCL_OUT(0);
}

void mi2c_stop()
{
  M_SDA_OUT(0);
  M_SCL_OUT(1);
  M_SDA_OUT(1);
}

unsigned char mi2c_put_byte(unsigned char data)
{
  char i;
  unsigned char ack;

  for (i=0;i<8;i++, data<<=1)
    {
      M_SDA_OUT(data&0x80);
      M_SCL_OUT(1);
      M_SCL_OUT(0);
    }

  M_SDA_OUT(1);
  M_SCL_OUT(1);

  ack = M_SDA_IN;	/* ack: sda is pulled low ->success.	 */

  M_SCL_OUT(0);
  M_SDA_OUT(0);

  return ack!=0;
}

void mi2c_get_byte(unsigned char *data)
{

  int i;
  unsigned char indata = 0;

  /* assert: scl is low */
  M_SCL_OUT(0);

  for (i=0;i<8;i++)
    {
      M_SCL_OUT(1);
      indata <<= 1;
      if ( M_SDA_IN ) indata |= 0x01;
      M_SCL_OUT(0);
    }

  M_SDA_OUT(1);
  *data= indata;
}

void mi2c_init()
{
    gpio_dir(GPIO_PIN_SDA_OUT, 1);
    gpio_dir(GPIO_PIN_SCL_OUT, 1);
    gpio_dir(GPIO_PIN_SDA_IN, 0);
        
		
  M_SCL_OUT(1);
  M_SDA_OUT(1);
}

void mi2c_scan()
{
    int i;
    
    for(i=0;i<0x80;i++)
    {
	mi2c_start();
	mprintf("scan %d\n",i);
	if(!mi2c_put_byte(i<<1)) mprintf("found : %x\n", i);
	mi2c_stop();
	
    }    
}