UAVX Multicopter Flight Controller.

Dependencies:   mbed

Revision:
1:1e3318a30ddd
Parent:
0:62a1c91a859a
Child:
2:90292f8bd179
--- a/i2c.c	Fri Feb 18 22:28:05 2011 +0000
+++ b/i2c.c	Fri Feb 25 01:35:24 2011 +0000
@@ -20,95 +20,281 @@
 
 #include "UAVXArm.h"
 
+boolean I2C0AddressResponds(uint8);
+#ifdef HAVE_I2C1
+boolean I2C1AddressResponds(uint8);
+#endif // HAVE_I2C1
+void TrackMinI2CRate(uint32);
+void ShowI2CDeviceName(uint8);
+uint8 ScanI2CBus(void);
+boolean ESCWaitClkHi(void);
+void ProgramSlaveAddress(uint8);
+void ConfigureESCs(void);
+
 uint32 MinI2CRate = I2C_MAX_RATE_HZ;
 
+//______________________________________________________________________________________________
+
+// Software I2C
+
+#ifdef SW_I2C
+
+#define I2CDelay5uS wait_us(5)
+#define I2CDelay2uS // wait_us(2)
+#define HighLowDelay // wait_us(1)
+#define FloatDelay // ???
+
+#define I2CSDALow {I2C0SDA.write(0);HighLowDelay;I2C0SDA.output();}
+#define I2CSDAFloat {I2C0SDA.input();}
+#define I2CSCLLow {I2C0SCL.write(0);HighLowDelay;I2C0SCL.output();}
+#define I2CSCLFloat {I2C0SCL.input();FloatDelay;}
+
+void MyI2C::frequency(uint32 f) {
+// delay depending on rate
+} // frequency
+
+boolean MyI2C::waitclock(void) {
+    static uint32 s;
+
+    I2CSCLFloat;        // set SCL to input, output a high
+    s = 0;
+    while ( !I2C0SCL.read() )
+        if ( ++s > 60000 ) {
+            Stats[I2CFailS]++;
+            return (false);
+        }
+    return( true );
+} // waitclock
+
+void MyI2C::start(void) {
+    static boolean r;
+
+    I2CSDAFloat;
+    r = waitclock();
+    I2CSDALow;
+    I2CDelay5uS;
+    I2CSCLLow;
+} // start
+
+void MyI2C::stop(void) {
+    static boolean r;
+
+    I2CSDALow;
+    r = waitclock();
+    I2CSDAFloat;
+    I2CDelay5uS;
+} // stop
+
+uint8 MyI2C::blockread(uint8 a, char* S, uint8 l) {
+    static uint8 b;
+    static boolean err;
+
+    I2C0.start();
+    err = I2C0.write(a|1) != I2C_ACK;
+    for (b = 0; b < (l - 1); b++)
+        S[b] = I2C0.read(I2C_ACK);
+    S[l-1] = I2C0.read(I2C_NACK);
+    I2C0.stop();
+
+    return( err );
+} // blockread
+
+uint8 MyI2C::read(uint8 ack) {
+    static uint8 s, d;
+
+    I2CSDAFloat;
+    d = 0;
+    s = 8;
+    do {
+        if ( waitclock() ) {
+            d <<= 1;
+            if ( I2C0SDA.read() ) d |= 1;
+            I2CSCLLow;
+            I2CDelay2uS;
+        } else
+            return( 0 );
+    } while ( --s );
+
+    I2C0SDA.write(ack);
+    HighLowDelay;
+    I2C0SDA.output();
+    HighLowDelay;
+
+    if ( waitclock() ) {
+        I2CSCLLow;
+        return( d );
+    } else
+        return( 0 );
+} // read
+
+void MyI2C::blockwrite(uint8 a, const char* S, uint8 l) {
+    static uint8 b;
+    static boolean r;
+
+    I2C0.start();
+    r = I2C0.write(a) == I2C_ACK;  // use this?
+    for ( b = 0; b < l; b++ )
+        r |= I2C0.write(S[b]);
+    I2C0.stop();
+
+} // blockwrite
+
+uint8 MyI2C::write(uint8 d) {
+    static uint8 s, r;
+
+    for ( s = 0; s < 8; s++)
+    {
+        if ( d & 0x80 ) {
+            I2CSDAFloat;
+        } else {
+            I2CSDALow;
+        }
+
+        if ( waitclock() ) {
+            I2CSCLLow;
+            d <<= 1;
+        } else
+            return(I2C_NACK);
+    }
+
+    I2CSDAFloat;
+    if ( waitclock() ) {
+        r = I2C0SDA.read();
+        I2CSCLLow;
+        return( r );
+    } else
+        return(I2C_NACK);
+
+} // write
+
+#endif // SW_I2C
+
+//______________________________________________________________________________________________
+
 void TrackMinI2CRate(uint32 r) {
- if ( r < MinI2CRate )
-    MinI2CRate = r;
+    if ( r < MinI2CRate )
+        MinI2CRate = r;
 } // TrackMinI2CRate
 
-void ShowI2CDeviceName(uint8 d)
-{
+void ShowI2CDeviceName(uint8 d) {
     TxChar(' ');
     switch ( d  ) {
-    case ADXL345_ID: TxString("ADXL345 Acc"); break;
-    case ITG3200_ID: TxString("ITG3200 Gyro"); break;
-    case HMC5843_ID: TxString("HMC5843 Magnetometer"); break;
-    case HMC6352_ID: TxString("HMC6352 Compass"); break;
-    case ADS7823_ID: TxString("ADS7823 ADC"); break;
-    case MCP4725_ID: TxString("MCP4725 DAC"); break;
-    case BOSCH_ID: TxString("Bosch Baro"); break;
-    case TMP100_ID: TxString("TMP100 Temp"); break;
-    case PCA9551_ID: TxString("PCA9551 LED");break;
-    case LISL_ID: TxString("LIS3L Acc"); break;
-    default: break;
+        case ADXL345_ID:
+            TxString("ADXL345 Acc");
+            break;
+        case ITG3200_ID:
+            TxString("ITG3200 Gyro");
+            break;
+        case HMC5843_ID:
+            TxString("HMC5843 Magnetometer");
+            break;
+        case HMC6352_ID:
+            TxString("HMC6352 Compass");
+            break;
+        case ADS7823_ID:
+            TxString("ADS7823 ADC");
+            break;
+        case MCP4725_ID_0xCC:
+            TxString("MCP4725 DAC");
+            break;
+        case MCP4725_ID_0xC8:
+            TxString("MCP4725 DAC");
+            break;
+        case BOSCH_ID:
+            TxString("Bosch Baro");
+            break;
+        case TMP100_ID:
+            TxString("TMP100 Temp");
+            break;
+        case PCA9551_ID:
+            TxString("PCA9551 LED");
+            break;
+        case LISL_ID:
+            TxString("LIS3L Acc");
+            break;
+        default:
+            break;
     } // switch
     TxChar(' ');
 
 } // ShowI2CDeviceName
 
+boolean I2C0AddressResponds(uint8 s) {
+    static boolean r;
+    I2C0.start();
+    r = I2C0.write(s) == I2C_ACK;
+    I2C0.stop();
+    return (r);
+} // I2C0AddressResponds
+
+#ifdef HAVE_IC1
+boolean I2C1AddressResponds(uint8 s) {
+    static boolean r;
+    I2C1.start();
+    r = I2C1.write(s) == I2C_ACK;
+    I2C1.stop();
+    return (r);
+} // I2C1AddressResponds
+#endif // HAVE_IC1
+
 uint8 ScanI2CBus(void) {
     uint8 s;
     uint8 d;
 
     d = 0;
-
     TxString("Buss 0\r\n");
     for ( s = 0x10 ; s <= 0xf6 ; s += 2 ) {
-        I2C0.start();
-        if ( I2C0.write(s) == I2C_ACK ) {
+        if (  I2C0AddressResponds(s) ) {
+            d++;
+            DebugPin = 1;
+            TxString("\t0x");
+            TxValH(s);
+            ShowI2CDeviceName( s );
+            TxNextLine();
+            DebugPin = 0;
+        }
+        Delay1mS(2);
+    }
+
+#ifdef HAVE_I2C1
+    TxString("Buss 1\r\n");
+    for ( s = 0x10 ; s <= 0xf6 ; s += 2 ) {
+        if (  I2C0AddressResponds(s) ) {
             d++;
             TxString("\t0x");
             TxValH(s);
             ShowI2CDeviceName( s );
             TxNextLine();
         }
-        I2C0.stop();
-
         Delay1mS(2);
     }
-    
-    /* 
-    TxString("Buss 1\r\n");
-    for ( s = 0x10 ; s <= 0xf6 ; s += 2 ) {
-        I2C1.start();
-        if ( I2C1.write(s) == I2C_ACK ) {
-            d++;
-            TxString("\t0x");
-            TxValH(s);
-            TxNextLine();
-        }
-        I2C1.stop();
-
-        Delay1mS(2);
-    }
-    */
+#endif // HAVE_I2C1
 
     PCA9551Test();
 
     return(d);
 } // ScanI2CBus
 
-void ProgramSlaveAddress(uint8 addr) {
+void ProgramSlaveAddress(uint8 a) {
     static uint8 s;
 
     for (s = 0x10 ; s < 0xf0 ; s += 2 ) {
         I2CESC.start();
         if ( I2CESC.read(s) == I2C_ACK )
-            if ( s == addr ) {   // ESC is already programmed OK
+            if ( s == a ) {   // ESC is already programmed OK
                 I2CESC.stop();
                 TxString("\tESC at SLA 0x");
-                TxValH(addr);
+                TxValH(a);
                 TxString(" is already programmed OK\r\n");
                 return;
             } else {
                 if ( I2CESC.read(0x87) == I2C_ACK ) // select register 0x07
-                    if ( I2CESC.write( addr ) == I2C_ACK ) { // new slave address
+                    if ( I2CESC.write( a ) == I2C_ACK ) { // new slave address
                         I2CESC.stop();
                         TxString("\tESC at SLA 0x");
                         TxValH(s);
                         TxString(" reprogrammed to SLA 0x");
-                        TxValH(addr);
+                        TxValH(a);
                         TxNextLine();
                         return;
                     }
@@ -116,7 +302,7 @@
         I2CESC.stop();
     }
     TxString("\tESC at SLA 0x");
-    TxValH(addr);
+    TxValH(a);
     TxString(" no response - check cabling and pullup resistors!\r\n");
 } // ProgramSlaveAddress
 
@@ -130,25 +316,8 @@
     if ( (int8)P[ESCType] == ESCYGEI2C ) {
         TxString("\r\nProgram YGE ESCs\r\n");
         for ( m = 0 ; m < NoOfI2CESCOutputs ; m++ ) {
-            TxString("Connect ONLY ");
-            switch ( m ) {
-#ifdef HEXACOPTER
-                    not yet!
-#else
-                case 0 :
-                    TxString("Front");
-                    break;
-                case 1 :
-                    TxString("Back");
-                    break;
-                case 2 :
-                    TxString("Right");
-                    break;
-                case 3 :
-                    TxString("Left");
-                    break;
-#endif // HEXACOPTER
-            }
+            TxString("Connect ONLY M");
+            TxChar('1' + m);
             TxString(" ESC, then press any key \r\n");
             while ( PollRxChar() != 'x' ); // UAVPSet uses 'x' for any key button
             //    TxString("\r\n");