/************************** * Arlotto 23 01 04 * Dialogue i2c avec le SFR08 * Quartz à 4 Mhz * ****************************/ #include #include "biosdem.h" /******************************** * * Notation : * S : start , rS : Repeated Start, St : Stop * AdW : @ i2c en écriture ex : E0 * AdR : @ i2c en lecture ex : E1 * DWx : donnée écrite n° x * DRx : donnée lue n° x ** Principe de l'échange : * Envoi de la demande de ranging : S E0 00 51 St * ^ ^ * positionne le pointeur @module en 0 * (Ecriture @i2c E0 à @module 0 (cmd register) de la valeur 0x51 (cm) * Attente de 70 ms (65mini) * Lecture à partir de l'@module 2 : S E0 02 rS E1 dh dl St * ^ ^ * positionne le pointeur @module en 2 * Conclusion : * Avec avoir positionné le pointeur d'@module en X par une séquence * de la forme S AdW X on peut : * - soit continuer l'écriture qui se fait alors * à partir de l'adresse module X en continuant à envoyer des données et en * terminant par un St : Ex : S AdW X DW0 DW1 DW2 ... St * - soit faire une lecture en inversant le sens de transfert sans libérer * le bus par un rS suivi de AdR et d'autant de lectures que l'on veut suivies d'un St * Ex : S AdW X rS AdR DR0 DR1 DR2 ... St * A priori le pointeur X conserve sa valeur et une séquence de lecture * de la forme S AdR DR0 DR1 ... St devrait démarrer la lecture à partir * de la valeur de X positionner par la lecture/écriture précédente (non vérifié). */ int read_distance(void) { char dh,dl; int d ; SEN = 1; // send start bit while(SEN); // and wait for it to clear ACKDT = 0; // acknowledge bit ACKSTAT=1; SSPIF = 0; SSPBUF = 0xE0; // 11100000 - write command while(!SSPIF); // wait for interrupt SSPIF = 0; #ifdef __DEBUG_SONAR ACKLED=!ACKSTAT; ACKSTAT=1; #endif SSPIF = 0; SSPBUF = 0x00; // adress of cmd register while(!SSPIF); // wait for interrupt SSPIF = 0; #ifdef __DEBUG_SONAR ACKLED=!ACKSTAT; ACKSTAT=1; #endif SSPIF = 0; SSPBUF = 0x51; // start ranging cm result while(!SSPIF); // wait for interrupt SSPIF = 0; // then clear it. #ifdef __DEBUG_SONAR ACKLED=!ACKSTAT; ACKSTAT=1; #endif PEN = 1; // send stop bit while(PEN); // DelayMs(70); // wait 65ms mini SEN = 1; // send start bit while(SEN); // and wait for it to clear ACKDT = 0; // acknowledge bit ACKSTAT=1; SSPIF = 0; SSPBUF = 0xE0; // 11100000 - write command while(!SSPIF); // wait for interrupt SSPIF = 0; #ifdef __DEBUG_SONAR ACKLED=!ACKSTAT; ACKSTAT=1; #endif SSPIF = 0; SSPBUF = 0x02; // adress of 1st Echo register while(!SSPIF); // wait for interrupt SSPIF = 0; #ifdef __DEBUG_SONAR ACKLED=!ACKSTAT; ACKSTAT=1; #endif RSEN = 1; // send start bit while(RSEN); // and wait for it to clear SSPIF = 0; SSPBUF = 0xE1; // 11000001 - read command while(!SSPIF); // wait for interrupt SSPIF = 0; // then clear it. RCEN = 1; // start receiving while(!STAT_BF); // wait for data dh = SSPBUF; // and get it ACKEN = 1; // start acknowledge sequence while(ACKEN); // wait for ack. sequence to end RCEN = 1; // start receiving while(!STAT_BF); // wait for data dl = SSPBUF; // and get it ACKDT=1; // very important ?? ACKEN = 1; // start acknowledge sequence while(ACKEN); // wait for ack. sequence to end PEN = 1; // send stop bit while(PEN); // d = (dh<<8) + dl ; return d ; }