/* io.c contient la procedure pour configurer la camera * (I2C) */ #include "io.h" #include #include #include #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) { }