summaryrefslogtreecommitdiff
path: root/2004/n/fpga/doc/dcd/ovcam/io.c
blob: 0fd6d2175be3d8f7e72622280494c8a3a55534d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/* io.c contient la procedure pour configurer la camera
 * (I2C)
 */

#include "io.h"
#include <sys/ports.h>

#include <sys/sio.h>
#include <sys/interrupts.h>

#define I2CCLK BITN(3)
#define I2CDATA BITN(4)

void 
i2c_init (void)
{
	// 1 ---> ouput
	// 0 ---> input
	// configuration des lignes en sortie
	_io_ports[M6811_DDRA] = I2CCLK | I2CDATA;
        // mise � 1 des lignes dans (lib�ration du bus
	_io_ports[M6811_PORTA] |= I2CCLK |I2CDATA;	
}

/*
 * Start procedure
 * Data   ---------------\________________
 * Clk    --------------------\___________
 *
 */

void
i2c_start(void)
{
	_io_ports[M6811_PORTA] &= ~I2CDATA;
	wait_2v5us();
	_io_ports[M6811_PORTA] &= ~I2CCLK;
	wait_2v5us();
}
/*
 * End procedure
 * Data   ___________________/-----
 * Clk    _________/---------------
 *
 */

void
i2c_end(void)
{
	_io_ports[M6811_PORTA] |= I2CCLK;
	wait_2v5us();
	_io_ports[M6811_PORTA] |= I2CDATA;
	wait_2v5us();
}

	void
wait_2v5us(void)
{
	unsigned char i;
	for (i=0;i<200;i++)
	{
		__asm__("nop");
	}
}

void
i2c_send_charnl (unsigned char data)
{
	unsigned char cmpt;
	for (cmpt=0;cmpt<8;cmpt++)
	{
		if (data & 0x80)	// si le bit de poids fort est 1, il faut mettre 1 sur la ligne
		{
			_io_ports[M6811_PORTA] |= I2CDATA;
		}
		else
		{
			_io_ports[M6811_PORTA] &= ~I2CDATA;
		}
		wait_2v5us();
		wait_2v5us();
		// on s'occupe de produire un front d'horloge
		_io_ports[M6811_PORTA] |= I2CCLK;
		wait_2v5us();
		_io_ports[M6811_PORTA] &= ~I2CCLK;
		wait_2v5us();
		_io_ports[M6811_PORTA] &= ~I2CDATA;
		/* Nous avons trait� le bit de poid le plus fort
		 * continuons */
		data = data << 1;
	}
	wait_2v5us();
	_io_ports[M6811_PORTA] |= I2CCLK;
	wait_2v5us();
	_io_ports[M6811_PORTA] &= ~I2CCLK;
	wait_2v5us();
}

unsigned char 
i2c_read_char (void)
{
	char cmpt;
	unsigned char data = 0;
	// configuration de la ligne data en entr�
	_io_ports[M6811_DDRA] &= ~I2CDATA;
	for (cmpt=0; cmpt<8;cmpt++)
	{
		_io_ports[M6811_PORTA] |=I2CCLK;
		wait_2v5us();
		_io_ports[M6811_PORTA];
		if (_io_ports[M6811_PORTA] & I2CDATA) //si ligne data est � 1
			data++;
		wait_2v5us();
		_io_ports[M6811_PORTA] &=~I2CCLK;
		wait_2v5us();
		data = data<<1;
	}
	// traitement de l'ack dans le cas d'une derniere lecture
	_io_ports[M6811_DDRA] |= I2CDATA;
	_io_ports[M6811_PORTA] |= I2CDATA;
	wait_2v5us();
	_io_ports[M6811_PORTA] |= I2CCLK;
	wait_2v5us();
	_io_ports[M6811_PORTA] &= ~I2CCLK;
	wait_2v5us();
	_io_ports[M6811_PORTA] &= ~I2CDATA;
	return data;
}

void
i2c_send (unsigned char reg,unsigned char data)
{
	// on d�clanche un procedure de start
	i2c_start();
	// C0 est l'adresse d'ecriture de l'ov6620
	i2c_send_charnl(0xc0);
	// On specifie le registre
	i2c_send_charnl(reg);
	// on donnee la valeur
	i2c_send_charnl(data);
	// procedure de stop
	i2c_end(); 
}

unsigned char
i2c_recv(unsigned char reg)
{
	unsigned char data;
	
	/* pour lire un registre particuli�, il faut commencer par
	 * ecrire le registre que l'on veut lire
	 */
	
	i2c_start();
	i2c_send_charnl(0xc0);
	i2c_send_charnl(reg);
	i2c_end();
	
	
	i2c_start();
	i2c_send_charnl(0xC1);
	data = i2c_read_char();
	i2c_end();
	return data;
	
}

void
i2c_dump(unsigned char * tab)
{
}