Prof Greg Egan
/
UAVXArm-GKE
UAVX Multicopter Flight Controller.
Diff: i2c.c
- 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");