i2c.c 2.07 KB
Newer Older
1 2
#include "types.h"
#include "board.h"
3
#include "syscon.h"
4

5
#define I2C_DELAY 300
6

7
void mi2c_delay()
8
{
9 10 11
	int i;
	for (i = 0; i < I2C_DELAY; i++)
		asm volatile ("nop");
12 13
}

14 15 16
#define M_SDA_OUT(i, x) { gpio_out(i2c_if[i].sda, x); mi2c_delay(); }
#define M_SCL_OUT(i, x) { gpio_out(i2c_if[i].scl, x); mi2c_delay(); }
#define M_SDA_IN(i) gpio_in(i2c_if[i].sda)
17

18
void mi2c_start(uint8_t i2cif)
19
{
20 21
	M_SDA_OUT(i2cif, 0);
	M_SCL_OUT(i2cif, 0);
22 23
}

24
void mi2c_repeat_start(uint8_t i2cif)
25
{
26 27 28 29
	M_SDA_OUT(i2cif, 1);
	M_SCL_OUT(i2cif, 1);
	M_SDA_OUT(i2cif, 0);
	M_SCL_OUT(i2cif, 0);
30 31
}

32
void mi2c_stop(uint8_t i2cif)
33
{
34 35 36
	M_SDA_OUT(i2cif, 0);
	M_SCL_OUT(i2cif, 1);
	M_SDA_OUT(i2cif, 1);
37 38
}

39
unsigned char mi2c_put_byte(uint8_t i2cif, unsigned char data)
40
{
41 42
	char i;
	unsigned char ack;
43

44 45 46 47 48
	for (i = 0; i < 8; i++, data <<= 1) {
		M_SDA_OUT(i2cif, data & 0x80);
		M_SCL_OUT(i2cif, 1);
		M_SCL_OUT(i2cif, 0);
	}
49

50 51
	M_SDA_OUT(i2cif, 1);
	M_SCL_OUT(i2cif, 1);
52

53
	ack = M_SDA_IN(i2cif);	/* ack: sda is pulled low ->success.     */
54

55 56
	M_SCL_OUT(i2cif, 0);
	M_SDA_OUT(i2cif, 0);
57

58
	return ack != 0;
59 60
}

61
void mi2c_get_byte(uint8_t i2cif, unsigned char *data, uint8_t last)
62 63
{

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
	int i;
	unsigned char indata = 0;

	M_SDA_OUT(i2cif, 1);
	/* assert: scl is low */
	M_SCL_OUT(i2cif, 0);

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

	if (last) {
		M_SDA_OUT(i2cif, 1);	//noack
		M_SCL_OUT(i2cif, 1);
		M_SCL_OUT(i2cif, 0);
	} else {
		M_SDA_OUT(i2cif, 0);	//ack
		M_SCL_OUT(i2cif, 1);
		M_SCL_OUT(i2cif, 0);
	}

	*data = indata;
90 91
}

92
void mi2c_init(uint8_t i2cif)
93
{
94 95
	M_SCL_OUT(i2cif, 1);
	M_SDA_OUT(i2cif, 1);
96
}
97

98 99
uint8_t mi2c_devprobe(uint8_t i2cif, uint8_t i2c_addr)
{
100 101 102 103
	uint8_t ret;
	mi2c_start(i2cif);
	ret = !mi2c_put_byte(i2cif, i2c_addr << 1);
	mi2c_stop(i2cif);
104

105
	return ret;
106 107
}

108 109 110
//void mi2c_scan(uint8_t i2cif)
//{
//    int i;
111
//
112 113 114 115 116 117
//    //for(i=0;i<0x80;i++)
//    for(i=0x50;i<0x51;i++)
//    {
//     mi2c_start(i2cif);
//     if(!mi2c_put_byte(i2cif, i<<1)) mprintf("found : %x\n", i);
//     mi2c_stop(i2cif);
118 119
//
//    }
120 121
//    mprintf("Nothing more found...\n");
//}