UAVX Multicopter Flight Controller.

Dependencies:   mbed

Committer:
gke
Date:
Tue Apr 26 12:12:29 2011 +0000
Revision:
2:90292f8bd179
Parent:
1:1e3318a30ddd
Not flightworthy. Posted for others to make use of the I2C SW code.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gke 0:62a1c91a859a 1 // ===============================================================================================
gke 0:62a1c91a859a 2 // = UAVXArm Quadrocopter Controller =
gke 0:62a1c91a859a 3 // = Copyright (c) 2008 by Prof. Greg Egan =
gke 0:62a1c91a859a 4 // = Original V3.15 Copyright (c) 2007 Ing. Wolfgang Mahringer =
gke 2:90292f8bd179 5 // = http://code.google.com/p/uavp-mods/ =
gke 0:62a1c91a859a 6 // ===============================================================================================
gke 0:62a1c91a859a 7
gke 0:62a1c91a859a 8 // This is part of UAVXArm.
gke 0:62a1c91a859a 9
gke 0:62a1c91a859a 10 // UAVXArm is free software: you can redistribute it and/or modify it under the terms of the GNU
gke 0:62a1c91a859a 11 // General Public License as published by the Free Software Foundation, either version 3 of the
gke 0:62a1c91a859a 12 // License, or (at your option) any later version.
gke 0:62a1c91a859a 13
gke 0:62a1c91a859a 14 // UAVXArm is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without
gke 0:62a1c91a859a 15 // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
gke 0:62a1c91a859a 16 // See the GNU General Public License for more details.
gke 0:62a1c91a859a 17
gke 0:62a1c91a859a 18 // You should have received a copy of the GNU General Public License along with this program.
gke 0:62a1c91a859a 19 // If not, see http://www.gnu.org/licenses/
gke 0:62a1c91a859a 20
gke 0:62a1c91a859a 21 #include "UAVXArm.h"
gke 0:62a1c91a859a 22
gke 1:1e3318a30ddd 23 boolean I2C0AddressResponds(uint8);
gke 1:1e3318a30ddd 24 #ifdef HAVE_I2C1
gke 1:1e3318a30ddd 25 boolean I2C1AddressResponds(uint8);
gke 1:1e3318a30ddd 26 #endif // HAVE_I2C1
gke 1:1e3318a30ddd 27 void TrackMinI2CRate(uint32);
gke 1:1e3318a30ddd 28 void ShowI2CDeviceName(uint8);
gke 1:1e3318a30ddd 29 uint8 ScanI2CBus(void);
gke 1:1e3318a30ddd 30 boolean ESCWaitClkHi(void);
gke 1:1e3318a30ddd 31 void ProgramSlaveAddress(uint8);
gke 1:1e3318a30ddd 32 void ConfigureESCs(void);
gke 1:1e3318a30ddd 33
gke 2:90292f8bd179 34 uint16 I2CError[256];
gke 2:90292f8bd179 35 uint8 I2CSpeed = 10; // 100KHz
gke 0:62a1c91a859a 36 uint32 MinI2CRate = I2C_MAX_RATE_HZ;
gke 0:62a1c91a859a 37
gke 1:1e3318a30ddd 38 //______________________________________________________________________________________________
gke 1:1e3318a30ddd 39
gke 1:1e3318a30ddd 40 // Software I2C
gke 1:1e3318a30ddd 41
gke 1:1e3318a30ddd 42 #ifdef SW_I2C
gke 1:1e3318a30ddd 43
gke 2:90292f8bd179 44 void SDelay(uint16 d) { // 1.25 + 0.0475 * n uS ~0.05uS per click
gke 2:90292f8bd179 45
gke 2:90292f8bd179 46 volatile int16 v;
gke 2:90292f8bd179 47
gke 2:90292f8bd179 48 for (v = 0; v < d ; v++ ) {};
gke 2:90292f8bd179 49
gke 2:90292f8bd179 50 } // SDelay
gke 2:90292f8bd179 51
gke 2:90292f8bd179 52 /*
gke 2:90292f8bd179 53 #define SCLLowStartT SDelay(I2CSpeed)
gke 2:90292f8bd179 54 #define DataLowPadT SDelay(I2CSpeed)
gke 2:90292f8bd179 55 #define SCLLowPadT SDelay(I2CSpeed)
gke 2:90292f8bd179 56 #define SCLHighT SDelay(I2CSpeed)
gke 2:90292f8bd179 57 */
gke 2:90292f8bd179 58
gke 2:90292f8bd179 59 #if ( I2C_MAX_RATE_HZ == 400000 )
gke 1:1e3318a30ddd 60
gke 2:90292f8bd179 61 #define SCLLowStartT SDelay(10)
gke 2:90292f8bd179 62 #define DataLowPadT SDelay(16) // 10
gke 2:90292f8bd179 63 #define SCLLowPadT SDelay(6)
gke 2:90292f8bd179 64 #define SCLHighT SDelay(10)
gke 2:90292f8bd179 65
gke 2:90292f8bd179 66 #else
gke 2:90292f8bd179 67
gke 2:90292f8bd179 68 #define SCLLowStartT SDelay(82)
gke 2:90292f8bd179 69 #define DataLowPadT SDelay(82)
gke 2:90292f8bd179 70 #define SCLLowPadT SDelay(82)
gke 2:90292f8bd179 71 #define SCLHighT SDelay(85)
gke 2:90292f8bd179 72
gke 2:90292f8bd179 73 #endif //I2C400KHZ
gke 2:90292f8bd179 74
gke 2:90292f8bd179 75
gke 2:90292f8bd179 76 #define I2CSDALow {I2C0SDA.write(0);I2C0SDA.output();SCLLowPadT;}
gke 2:90292f8bd179 77 #define I2CSDAFloat {I2C0SDA.input();SCLLowPadT;}
gke 2:90292f8bd179 78 #define I2CSCLLow {I2C0SCL.write(0);I2C0SCL.output();}
gke 2:90292f8bd179 79 #define I2CSCLFloat {I2C0SCL.input();SCLHighT;}
gke 1:1e3318a30ddd 80
gke 1:1e3318a30ddd 81 void MyI2C::frequency(uint32 f) {
gke 1:1e3318a30ddd 82 // delay depending on rate
gke 2:90292f8bd179 83
gke 2:90292f8bd179 84 if ( f == 400000 )
gke 2:90292f8bd179 85 I2CSpeed = 10;
gke 2:90292f8bd179 86 else
gke 2:90292f8bd179 87 I2CSpeed = 80;
gke 1:1e3318a30ddd 88 } // frequency
gke 1:1e3318a30ddd 89
gke 2:90292f8bd179 90 void MyI2C::start(void) {
gke 2:90292f8bd179 91
gke 2:90292f8bd179 92 I2CSDAFloat;
gke 2:90292f8bd179 93 r = waitclock();
gke 2:90292f8bd179 94 I2CSDALow;
gke 2:90292f8bd179 95 SCLLowStartT;
gke 2:90292f8bd179 96 I2CSCLLow;
gke 2:90292f8bd179 97 } // start
gke 2:90292f8bd179 98
gke 2:90292f8bd179 99 void MyI2C::stop(void) {
gke 2:90292f8bd179 100
gke 2:90292f8bd179 101 I2CSDALow;
gke 2:90292f8bd179 102 r = waitclock();
gke 2:90292f8bd179 103 I2CSDAFloat;
gke 2:90292f8bd179 104 SCLLowStartT;
gke 2:90292f8bd179 105
gke 2:90292f8bd179 106 } // stop
gke 2:90292f8bd179 107
gke 1:1e3318a30ddd 108 boolean MyI2C::waitclock(void) {
gke 1:1e3318a30ddd 109 static uint32 s;
gke 1:1e3318a30ddd 110
gke 1:1e3318a30ddd 111 I2CSCLFloat; // set SCL to input, output a high
gke 1:1e3318a30ddd 112 s = 0;
gke 2:90292f8bd179 113 while ( I2C0SCL.read() == 0 )
gke 2:90292f8bd179 114 if ( ++s > 16000 ) { // ~1mS
gke 2:90292f8bd179 115 I2CError[0]++;
gke 2:90292f8bd179 116 // possible add SCL cycles here to attempt to force device reset
gke 1:1e3318a30ddd 117 Stats[I2CFailS]++;
gke 1:1e3318a30ddd 118 return (false);
gke 1:1e3318a30ddd 119 }
gke 1:1e3318a30ddd 120 return( true );
gke 1:1e3318a30ddd 121 } // waitclock
gke 1:1e3318a30ddd 122
gke 2:90292f8bd179 123 uint8 MyI2C::read(uint8 ack) {
gke 2:90292f8bd179 124 static uint8 s, d;
gke 1:1e3318a30ddd 125
gke 1:1e3318a30ddd 126 I2CSDAFloat;
gke 2:90292f8bd179 127 d = 0;
gke 2:90292f8bd179 128 s = 8;
gke 2:90292f8bd179 129 do {
gke 2:90292f8bd179 130 if ( waitclock() ) {
gke 2:90292f8bd179 131 d <<= 1;
gke 2:90292f8bd179 132 if ( I2C0SDA.read() ) {
gke 2:90292f8bd179 133 d |= 1;
gke 2:90292f8bd179 134 I2CSCLLow;
gke 2:90292f8bd179 135 DataLowPadT;
gke 2:90292f8bd179 136 } else {
gke 2:90292f8bd179 137 I2CSCLLow;
gke 2:90292f8bd179 138 SDelay(10);//DataLowPadT;
gke 2:90292f8bd179 139 }
gke 2:90292f8bd179 140 } else
gke 2:90292f8bd179 141 return( 0 );
gke 2:90292f8bd179 142 } while ( --s );
gke 2:90292f8bd179 143
gke 2:90292f8bd179 144 if ( ack == I2C_NACK )
gke 2:90292f8bd179 145 I2C0SDA.write(0xffff); // Port write with mask selecting SDA - messy
gke 2:90292f8bd179 146 else
gke 2:90292f8bd179 147 I2C0SDA.write(0);
gke 2:90292f8bd179 148 I2C0SDA.output();
gke 2:90292f8bd179 149
gke 2:90292f8bd179 150 SCLLowPadT;
gke 2:90292f8bd179 151
gke 2:90292f8bd179 152 if ( waitclock() ) {
gke 2:90292f8bd179 153 I2CSCLLow;
gke 2:90292f8bd179 154 return( d );
gke 2:90292f8bd179 155 } else
gke 2:90292f8bd179 156 return( 0 );
gke 2:90292f8bd179 157
gke 2:90292f8bd179 158 } // read
gke 1:1e3318a30ddd 159
gke 2:90292f8bd179 160 uint8 MyI2C::write(uint8 d) {
gke 2:90292f8bd179 161 static uint8 s, r;
gke 2:90292f8bd179 162
gke 2:90292f8bd179 163 for ( s = 0; s < 8; s++) {
gke 2:90292f8bd179 164 if ( d & 0x80 ) {
gke 2:90292f8bd179 165 I2CSDAFloat;
gke 2:90292f8bd179 166 } else {
gke 2:90292f8bd179 167 I2CSDALow;
gke 2:90292f8bd179 168 }
gke 1:1e3318a30ddd 169
gke 2:90292f8bd179 170 if ( waitclock() ) {
gke 2:90292f8bd179 171 I2CSCLLow;
gke 2:90292f8bd179 172 d <<= 1;
gke 2:90292f8bd179 173 } else
gke 2:90292f8bd179 174 return(I2C_NACK);
gke 2:90292f8bd179 175 }
gke 2:90292f8bd179 176
gke 1:1e3318a30ddd 177 I2CSDAFloat;
gke 2:90292f8bd179 178 if ( waitclock() ) {
gke 2:90292f8bd179 179 if ( I2C0SDA.read() )
gke 2:90292f8bd179 180 r = I2C_NACK;
gke 2:90292f8bd179 181 else
gke 2:90292f8bd179 182 r = I2C_ACK;
gke 2:90292f8bd179 183 I2CSDALow;// kill runt pulses
gke 2:90292f8bd179 184 I2CSCLLow;
gke 2:90292f8bd179 185 return ( r );
gke 2:90292f8bd179 186 } else {
gke 2:90292f8bd179 187 // I2CSCLLow;
gke 2:90292f8bd179 188 return(I2C_NACK);
gke 2:90292f8bd179 189 }
gke 2:90292f8bd179 190
gke 2:90292f8bd179 191 } // write
gke 1:1e3318a30ddd 192
gke 1:1e3318a30ddd 193 uint8 MyI2C::blockread(uint8 a, char* S, uint8 l) {
gke 1:1e3318a30ddd 194 static uint8 b;
gke 1:1e3318a30ddd 195 static boolean err;
gke 1:1e3318a30ddd 196
gke 1:1e3318a30ddd 197 I2C0.start();
gke 1:1e3318a30ddd 198 err = I2C0.write(a|1) != I2C_ACK;
gke 1:1e3318a30ddd 199 for (b = 0; b < (l - 1); b++)
gke 1:1e3318a30ddd 200 S[b] = I2C0.read(I2C_ACK);
gke 1:1e3318a30ddd 201 S[l-1] = I2C0.read(I2C_NACK);
gke 1:1e3318a30ddd 202 I2C0.stop();
gke 1:1e3318a30ddd 203
gke 1:1e3318a30ddd 204 return( err );
gke 1:1e3318a30ddd 205 } // blockread
gke 1:1e3318a30ddd 206
gke 2:90292f8bd179 207 boolean MyI2C::blockwrite(uint8 a, const char* S, uint8 l) {
gke 1:1e3318a30ddd 208 static uint8 b;
gke 1:1e3318a30ddd 209
gke 1:1e3318a30ddd 210 I2C0.start();
gke 2:90292f8bd179 211 if ( I2C0.write(a) != I2C_ACK ) goto BlockWriteError; // use this?
gke 1:1e3318a30ddd 212 for ( b = 0; b < l; b++ )
gke 2:90292f8bd179 213 if ( I2C0.write(S[b]) != I2C_ACK ) goto BlockWriteError;
gke 1:1e3318a30ddd 214 I2C0.stop();
gke 1:1e3318a30ddd 215
gke 2:90292f8bd179 216 return(false);
gke 2:90292f8bd179 217
gke 2:90292f8bd179 218 BlockWriteError:
gke 2:90292f8bd179 219 I2C0.stop();
gke 2:90292f8bd179 220
gke 2:90292f8bd179 221 return(true);
gke 2:90292f8bd179 222
gke 1:1e3318a30ddd 223 } // blockwrite
gke 1:1e3318a30ddd 224
gke 1:1e3318a30ddd 225 #endif // SW_I2C
gke 1:1e3318a30ddd 226
gke 1:1e3318a30ddd 227 //______________________________________________________________________________________________
gke 1:1e3318a30ddd 228
gke 0:62a1c91a859a 229 void TrackMinI2CRate(uint32 r) {
gke 2:90292f8bd179 230
gke 2:90292f8bd179 231 // CURRENTLY USING DEFINE TO SPECIFY RATE - UAVXArm.h
gke 1:1e3318a30ddd 232 if ( r < MinI2CRate )
gke 1:1e3318a30ddd 233 MinI2CRate = r;
gke 0:62a1c91a859a 234 } // TrackMinI2CRate
gke 0:62a1c91a859a 235
gke 1:1e3318a30ddd 236 void ShowI2CDeviceName(uint8 d) {
gke 0:62a1c91a859a 237 TxChar(' ');
gke 0:62a1c91a859a 238 switch ( d ) {
gke 1:1e3318a30ddd 239 case ADXL345_ID:
gke 1:1e3318a30ddd 240 TxString("ADXL345 Acc");
gke 1:1e3318a30ddd 241 break;
gke 1:1e3318a30ddd 242 case ITG3200_ID:
gke 1:1e3318a30ddd 243 TxString("ITG3200 Gyro");
gke 1:1e3318a30ddd 244 break;
gke 1:1e3318a30ddd 245 case HMC5843_ID:
gke 1:1e3318a30ddd 246 TxString("HMC5843 Magnetometer");
gke 1:1e3318a30ddd 247 break;
gke 1:1e3318a30ddd 248 case HMC6352_ID:
gke 1:1e3318a30ddd 249 TxString("HMC6352 Compass");
gke 1:1e3318a30ddd 250 break;
gke 1:1e3318a30ddd 251 case ADS7823_ID:
gke 1:1e3318a30ddd 252 TxString("ADS7823 ADC");
gke 1:1e3318a30ddd 253 break;
gke 1:1e3318a30ddd 254 case MCP4725_ID_0xCC:
gke 1:1e3318a30ddd 255 TxString("MCP4725 DAC");
gke 1:1e3318a30ddd 256 break;
gke 1:1e3318a30ddd 257 case MCP4725_ID_0xC8:
gke 1:1e3318a30ddd 258 TxString("MCP4725 DAC");
gke 1:1e3318a30ddd 259 break;
gke 1:1e3318a30ddd 260 case BOSCH_ID:
gke 1:1e3318a30ddd 261 TxString("Bosch Baro");
gke 1:1e3318a30ddd 262 break;
gke 1:1e3318a30ddd 263 case TMP100_ID:
gke 1:1e3318a30ddd 264 TxString("TMP100 Temp");
gke 1:1e3318a30ddd 265 break;
gke 1:1e3318a30ddd 266 case PCA9551_ID:
gke 1:1e3318a30ddd 267 TxString("PCA9551 LED");
gke 1:1e3318a30ddd 268 break;
gke 1:1e3318a30ddd 269 case LISL_ID:
gke 1:1e3318a30ddd 270 TxString("LIS3L Acc");
gke 1:1e3318a30ddd 271 break;
gke 1:1e3318a30ddd 272 default:
gke 1:1e3318a30ddd 273 break;
gke 0:62a1c91a859a 274 } // switch
gke 0:62a1c91a859a 275 TxChar(' ');
gke 0:62a1c91a859a 276
gke 0:62a1c91a859a 277 } // ShowI2CDeviceName
gke 0:62a1c91a859a 278
gke 1:1e3318a30ddd 279 boolean I2C0AddressResponds(uint8 s) {
gke 1:1e3318a30ddd 280 static boolean r;
gke 1:1e3318a30ddd 281 I2C0.start();
gke 1:1e3318a30ddd 282 r = I2C0.write(s) == I2C_ACK;
gke 1:1e3318a30ddd 283 I2C0.stop();
gke 1:1e3318a30ddd 284 return (r);
gke 1:1e3318a30ddd 285 } // I2C0AddressResponds
gke 1:1e3318a30ddd 286
gke 1:1e3318a30ddd 287 #ifdef HAVE_IC1
gke 1:1e3318a30ddd 288 boolean I2C1AddressResponds(uint8 s) {
gke 1:1e3318a30ddd 289 static boolean r;
gke 1:1e3318a30ddd 290 I2C1.start();
gke 1:1e3318a30ddd 291 r = I2C1.write(s) == I2C_ACK;
gke 1:1e3318a30ddd 292 I2C1.stop();
gke 1:1e3318a30ddd 293 return (r);
gke 1:1e3318a30ddd 294 } // I2C1AddressResponds
gke 1:1e3318a30ddd 295 #endif // HAVE_IC1
gke 1:1e3318a30ddd 296
gke 0:62a1c91a859a 297 uint8 ScanI2CBus(void) {
gke 0:62a1c91a859a 298 uint8 s;
gke 0:62a1c91a859a 299 uint8 d;
gke 0:62a1c91a859a 300
gke 0:62a1c91a859a 301 d = 0;
gke 0:62a1c91a859a 302 TxString("Buss 0\r\n");
gke 2:90292f8bd179 303
gke 2:90292f8bd179 304 #ifdef SW_I2C
gke 2:90292f8bd179 305 TxString("I2C Ver.:\tSoftware\r\n");
gke 2:90292f8bd179 306 #else
gke 2:90292f8bd179 307 TxString("I2C Ver.:\tHardware (CAUTION)\r\n");
gke 2:90292f8bd179 308 #endif // SW_I2C
gke 2:90292f8bd179 309
gke 2:90292f8bd179 310 #if ( I2C_MAX_RATE_HZ == 400000 )
gke 2:90292f8bd179 311 TxString("Rate:\t400KHz\r\n");
gke 2:90292f8bd179 312 #else
gke 2:90292f8bd179 313 TxString("Rate:\t100KHz\r\n");
gke 2:90292f8bd179 314 #endif
gke 2:90292f8bd179 315 TxString("SCL Hangs:\t");
gke 2:90292f8bd179 316 TxVal32(I2CError[0], 0, 0);
gke 2:90292f8bd179 317 TxNextLine();
gke 0:62a1c91a859a 318 for ( s = 0x10 ; s <= 0xf6 ; s += 2 ) {
gke 1:1e3318a30ddd 319 if ( I2C0AddressResponds(s) ) {
gke 1:1e3318a30ddd 320 d++;
gke 1:1e3318a30ddd 321 TxString("\t0x");
gke 1:1e3318a30ddd 322 TxValH(s);
gke 2:90292f8bd179 323 TxChar(HT);
gke 2:90292f8bd179 324 TxVal32(I2CError[s], 0, HT);
gke 1:1e3318a30ddd 325 ShowI2CDeviceName( s );
gke 1:1e3318a30ddd 326 TxNextLine();
gke 1:1e3318a30ddd 327 }
gke 1:1e3318a30ddd 328 Delay1mS(2);
gke 1:1e3318a30ddd 329 }
gke 1:1e3318a30ddd 330
gke 1:1e3318a30ddd 331 #ifdef HAVE_I2C1
gke 1:1e3318a30ddd 332 TxString("Buss 1\r\n");
gke 2:90292f8bd179 333
gke 2:90292f8bd179 334 #ifdef SW_I2C
gke 2:90292f8bd179 335 TxString("I2C Ver.:\tSoftware\r\n");
gke 2:90292f8bd179 336 #else
gke 2:90292f8bd179 337 TxString("I2C Ver.:\tHardware (CAUTION)\r\n");
gke 2:90292f8bd179 338 #endif // SW_I2C
gke 2:90292f8bd179 339
gke 2:90292f8bd179 340 #if ( I2C_MAX_RATE_HZ == 400000 )
gke 2:90292f8bd179 341 TxString("Rate:\t400KHz\r\n");
gke 2:90292f8bd179 342 #else
gke 2:90292f8bd179 343 TxString("Rate:\t100KHz\r\n");
gke 2:90292f8bd179 344 #endif
gke 2:90292f8bd179 345 TxString("SCL Hangs:\t");
gke 2:90292f8bd179 346 TxNextLine();
gke 1:1e3318a30ddd 347 for ( s = 0x10 ; s <= 0xf6 ; s += 2 ) {
gke 2:90292f8bd179 348 if ( I2C0AddressResponds(s) ) {
gke 0:62a1c91a859a 349 d++;
gke 0:62a1c91a859a 350 TxString("\t0x");
gke 0:62a1c91a859a 351 TxValH(s);
gke 2:90292f8bd179 352 TxChar(HT);
gke 2:90292f8bd179 353 TxVal32(I2CError[s], 0, HT);
gke 0:62a1c91a859a 354 ShowI2CDeviceName( s );
gke 0:62a1c91a859a 355 TxNextLine();
gke 0:62a1c91a859a 356 }
gke 0:62a1c91a859a 357 Delay1mS(2);
gke 0:62a1c91a859a 358 }
gke 1:1e3318a30ddd 359 #endif // HAVE_I2C1
gke 0:62a1c91a859a 360
gke 0:62a1c91a859a 361 PCA9551Test();
gke 0:62a1c91a859a 362
gke 0:62a1c91a859a 363 return(d);
gke 0:62a1c91a859a 364 } // ScanI2CBus
gke 0:62a1c91a859a 365
gke 1:1e3318a30ddd 366 void ProgramSlaveAddress(uint8 a) {
gke 0:62a1c91a859a 367 static uint8 s;
gke 0:62a1c91a859a 368
gke 0:62a1c91a859a 369 for (s = 0x10 ; s < 0xf0 ; s += 2 ) {
gke 0:62a1c91a859a 370 I2CESC.start();
gke 0:62a1c91a859a 371 if ( I2CESC.read(s) == I2C_ACK )
gke 1:1e3318a30ddd 372 if ( s == a ) { // ESC is already programmed OK
gke 0:62a1c91a859a 373 I2CESC.stop();
gke 0:62a1c91a859a 374 TxString("\tESC at SLA 0x");
gke 1:1e3318a30ddd 375 TxValH(a);
gke 0:62a1c91a859a 376 TxString(" is already programmed OK\r\n");
gke 0:62a1c91a859a 377 return;
gke 0:62a1c91a859a 378 } else {
gke 0:62a1c91a859a 379 if ( I2CESC.read(0x87) == I2C_ACK ) // select register 0x07
gke 1:1e3318a30ddd 380 if ( I2CESC.write( a ) == I2C_ACK ) { // new slave address
gke 0:62a1c91a859a 381 I2CESC.stop();
gke 0:62a1c91a859a 382 TxString("\tESC at SLA 0x");
gke 0:62a1c91a859a 383 TxValH(s);
gke 0:62a1c91a859a 384 TxString(" reprogrammed to SLA 0x");
gke 1:1e3318a30ddd 385 TxValH(a);
gke 0:62a1c91a859a 386 TxNextLine();
gke 0:62a1c91a859a 387 return;
gke 0:62a1c91a859a 388 }
gke 0:62a1c91a859a 389 }
gke 0:62a1c91a859a 390 I2CESC.stop();
gke 0:62a1c91a859a 391 }
gke 0:62a1c91a859a 392 TxString("\tESC at SLA 0x");
gke 1:1e3318a30ddd 393 TxValH(a);
gke 0:62a1c91a859a 394 TxString(" no response - check cabling and pullup resistors!\r\n");
gke 0:62a1c91a859a 395 } // ProgramSlaveAddress
gke 0:62a1c91a859a 396
gke 0:62a1c91a859a 397 boolean CheckESCBus(void) {
gke 0:62a1c91a859a 398 return ( true );
gke 0:62a1c91a859a 399 } // CheckESCBus
gke 0:62a1c91a859a 400
gke 0:62a1c91a859a 401 void ConfigureESCs(void) {
gke 0:62a1c91a859a 402 int8 m;
gke 0:62a1c91a859a 403
gke 0:62a1c91a859a 404 if ( (int8)P[ESCType] == ESCYGEI2C ) {
gke 0:62a1c91a859a 405 TxString("\r\nProgram YGE ESCs\r\n");
gke 0:62a1c91a859a 406 for ( m = 0 ; m < NoOfI2CESCOutputs ; m++ ) {
gke 1:1e3318a30ddd 407 TxString("Connect ONLY M");
gke 1:1e3318a30ddd 408 TxChar('1' + m);
gke 0:62a1c91a859a 409 TxString(" ESC, then press any key \r\n");
gke 0:62a1c91a859a 410 while ( PollRxChar() != 'x' ); // UAVPSet uses 'x' for any key button
gke 0:62a1c91a859a 411 // TxString("\r\n");
gke 0:62a1c91a859a 412 ProgramSlaveAddress( 0x62 + ( m*2 ));
gke 0:62a1c91a859a 413 }
gke 0:62a1c91a859a 414 TxString("\r\nConnect ALL ESCs and power-cycle the Quadrocopter\r\n");
gke 0:62a1c91a859a 415 } else
gke 0:62a1c91a859a 416 TxString("\r\nYGEI2C not selected as ESC?\r\n");
gke 0:62a1c91a859a 417 } // ConfigureESCs
gke 0:62a1c91a859a 418
gke 2:90292f8bd179 419 void InitI2C(void) {
gke 2:90292f8bd179 420
gke 2:90292f8bd179 421 uint8 i;
gke 2:90292f8bd179 422
gke 2:90292f8bd179 423 for ( i = 0; i < 255; i++ )
gke 2:90292f8bd179 424 I2CError[i] = 0;
gke 2:90292f8bd179 425
gke 2:90292f8bd179 426 } // InitI2C
gke 0:62a1c91a859a 427
gke 0:62a1c91a859a 428
gke 2:90292f8bd179 429