summaryrefslogtreecommitdiff
path: root/2004/n/fpga/doc/dcd/ovcam/io.c
diff options
context:
space:
mode:
Diffstat (limited to '2004/n/fpga/doc/dcd/ovcam/io.c')
-rw-r--r--2004/n/fpga/doc/dcd/ovcam/io.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/2004/n/fpga/doc/dcd/ovcam/io.c b/2004/n/fpga/doc/dcd/ovcam/io.c
new file mode 100644
index 0000000..0fd6d21
--- /dev/null
+++ b/2004/n/fpga/doc/dcd/ovcam/io.c
@@ -0,0 +1,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)
+{
+}