|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Copyright (c) 1998 Apple Computer, Inc. All rights reserved. ! 24: * ! 25: * Implementation of the interface for the keylargo I2C interface ! 26: * ! 27: * HISTORY ! 28: * ! 29: */ ! 30: ! 31: #include "PPCI2CInterface.h" ! 32: ! 33: // Uncomment the following define if you wish ro see more logging ! 34: // on the i2c interface: ! 35: // #define DEBUGMODE ! 36: ! 37: // Private Methods: ! 38: // =============== ! 39: ! 40: // FIXME: change the if 0 into if 1 in the following line for final ! 41: // builds so all the simple private functions can be inlined. ! 42: #if 1 ! 43: #define INLINE inline ! 44: #else ! 45: #define INLINE ! 46: #endif ! 47: ! 48: // -------------------------------------------------------------------------- ! 49: // Method: dumpI2CRegisters ! 50: // ! 51: // Purpose: ! 52: // Given the base of the i2c registers inits all the registers ! 53: INLINE void ! 54: PPCI2CInterface::dumpI2CRegisters() ! 55: { ! 56: #ifdef DEBUGMODE ! 57: IOLog("mode 0x%08lx -> 0x%02x\n", (UInt32)mode,*mode); ! 58: IOLog("control 0x%08lx -> 0x%02x\n", (UInt32)control,*control); ! 59: IOLog("status 0x%08lx -> 0x%02x\n", (UInt32)status,*status); ! 60: IOLog("ISR 0x%08lx -> 0x%02x\n", (UInt32)ISR,*ISR); ! 61: IOLog("IER 0x%08lx -> 0x%02x\n", (UInt32)IER,*IER); ! 62: IOLog("address 0x%08lx -> 0x%02x\n", (UInt32)address,*address); ! 63: IOLog("subAddr 0x%08lx -> 0x%02x\n", (UInt32)subAddr,*subAddr); ! 64: //IOLog("data 0x%08lx -> 0x%02x\n", (UInt32)data,*data); ! 65: #endif //DEBUGMODE ! 66: } ! 67: ! 68: // -------------------------------------------------------------------------- ! 69: // Method: SetI2CBase ! 70: // ! 71: // Purpose: ! 72: // Given the base of the i2c registers inits all the registers ! 73: INLINE void ! 74: PPCI2CInterface::SetI2CBase(UInt8 *baseAddress, UInt8 steps) ! 75: { ! 76: I2CRegister base = (I2CRegister)baseAddress; ! 77: ! 78: if (base != NULL) { ! 79: mode = base; // Configure the transmission mode of the i2c cell and the databit rate. ! 80: control = mode + steps; // Holds the 4 bits used to start the operations on the i2c interface. ! 81: status = control + steps; // Status bits for the i2 cell and the i2c interface. ! 82: ISR = status + steps; // Holds the status bits for the interrupt conditions. ! 83: IER = ISR + steps; // Eneables the bits that allow the four interrupt status conditions. ! 84: address = IER + steps; // Holds the 7 bits address and the R/W bit. ! 85: subAddr = address + steps; // the 8bit subaddress.. ! 86: data = subAddr + steps; // from where we read and write data ! 87: ! 88: // Clears interrupt and status register: ! 89: *status = 0x00; ! 90: *ISR = 0x00; ! 91: ! 92: // And remembers the current mode: ! 93: getMode(); ! 94: ! 95: #ifdef DEBUGMODE ! 96: IOLog("PPCI2CInterface::SetI2CBase(0x%08lx,0x%02x)\n",(UInt32)baseAddress, steps); ! 97: dumpI2CRegisters(); ! 98: #endif // DEBUGMODE ! 99: } ! 100: } ! 101: ! 102: // -------------------------------------------------------------------------- ! 103: // Method: shiftedMask ! 104: // ! 105: // Purpose: ! 106: // Returns the mask to use with the register: ! 107: INLINE UInt8 ! 108: PPCI2CInterface::shiftedMask(UInt8 mask, UInt8 shift) ! 109: { ! 110: return (mask << shift); ! 111: } ! 112: ! 113: // -------------------------------------------------------------------------- ! 114: // Method: shiftedCompMask ! 115: // ! 116: // Purpose: ! 117: // Returns the complement of the mask ! 118: INLINE UInt8 ! 119: PPCI2CInterface::shiftedCompMask(UInt8 mask, UInt8 shift) ! 120: { ! 121: return ~shiftedMask(mask, shift); ! 122: } ! 123: ! 124: // -------------------------------------------------------------------------- ! 125: // Method: writeRegisterField ! 126: // ! 127: // Purpose: ! 128: // writes a field of a regiter with the given data. The arguments are ! 129: // the register, the mask for the field, shift to get to the right bits ! 130: // and the new data. ! 131: INLINE void ! 132: PPCI2CInterface::writeRegisterField(I2CRegister reg, UInt8 mask, UInt8 shift, UInt8 newData) ! 133: { ! 134: UInt8 registerValue = *reg; ! 135: UInt8 data = (newData & mask); ! 136: UInt8 nMask = shiftedCompMask(mask, shift); ! 137: ! 138: *reg = (registerValue & nMask) | (data << shift); ! 139: eieio(); ! 140: ! 141: #ifdef DEBUGMODE ! 142: /* IOLog("PPCI2CInterface::writeRegisterField(0x%08lx, 0x%02x, 0x%02x, 0x%02x)\n",(UInt32)reg, mask, shift, newData); ! 143: IOLog("PPCI2CInterface::writeRegisterField() registerValue=0x%02x\n", registerValue); ! 144: IOLog("PPCI2CInterface::writeRegisterField() data=0x%02x\n", data); ! 145: IOLog("PPCI2CInterface::writeRegisterField() nMask=0x%02x\n", nMask); ! 146: IOLog("PPCI2CInterface::writeRegisterField() *reg=0x%02x\n", *reg);*/ ! 147: #endif // DEBUGMODE ! 148: } ! 149: ! 150: // -------------------------------------------------------------------------- ! 151: // Method: readRegisterField ! 152: // ! 153: // Purpose: ! 154: // writes a field of a regiter with the given data. The arguments are ! 155: // the register, the mask for the field and shift to get to the right ! 156: // bits. ! 157: INLINE UInt8 ! 158: PPCI2CInterface::readRegisterField(I2CRegister reg, UInt8 mask, UInt8 shift) ! 159: { ! 160: UInt8 registerValue = *reg; ! 161: UInt8 returnValue = ((registerValue) >> shift) & mask; ! 162: ! 163: #ifdef DEBUGMODE ! 164: /* IOLog("PPCI2CInterface::readRegisterField(0x%08lx, 0x%02x, 0x%02x)\n",(UInt32)reg, mask, shift); ! 165: IOLog("PPCI2CInterface::readRegisterField() *reg=0x%02x\n", *reg); ! 166: IOLog("PPCI2CInterface::readRegisterField() returnValue=0x%02x\n", returnValue);*/ ! 167: #endif // DEBUGMODE ! 168: ! 169: return returnValue; ! 170: } ! 171: ! 172: // Intermediate methods to access to each field of all the registers: ! 173: // ------------------------------------------------------------------ ! 174: ! 175: // Mode register ! 176: INLINE void ! 177: PPCI2CInterface::setMode(I2CMode newMode) ! 178: { ! 179: // remoeber the last mode: ! 180: lastMode = newMode; ! 181: writeRegisterField(mode, (UInt8)kModeMask, (UInt8)I2CModeShift, (UInt8)newMode); ! 182: } ! 183: ! 184: INLINE PPCI2CInterface::I2CMode ! 185: PPCI2CInterface::getMode() ! 186: { ! 187: lastMode = (I2CMode)readRegisterField(mode, (UInt8)kModeMask, (UInt8)I2CModeShift); ! 188: return lastMode; ! 189: } ! 190: ! 191: INLINE void ! 192: PPCI2CInterface::setSpeed(I2CSpeed newSpeed) ! 193: { ! 194: writeRegisterField(mode, (UInt8)kSpeedMask, (UInt8)I2CSpeedShift, (UInt8)newSpeed); ! 195: } ! 196: ! 197: INLINE PPCI2CInterface::I2CSpeed ! 198: PPCI2CInterface::getSpeed() ! 199: { ! 200: return (I2CSpeed)readRegisterField(mode, (UInt8)kSpeedMask, (UInt8)I2CSpeedShift); ! 201: } ! 202: ! 203: // Control register ! 204: INLINE void ! 205: PPCI2CInterface::setControl(I2CControl newControlValue) ! 206: { ! 207: *control = (UInt8)newControlValue; ! 208: eieio(); ! 209: } ! 210: ! 211: INLINE PPCI2CInterface::I2CControl ! 212: PPCI2CInterface::getControl() ! 213: { ! 214: return (I2CControl)(*control); ! 215: } ! 216: ! 217: // Status register ! 218: INLINE void ! 219: PPCI2CInterface::setStatus(I2CStatus newStatusValue) ! 220: { ! 221: *status = (UInt8)newStatusValue; ! 222: eieio(); ! 223: } ! 224: ! 225: INLINE PPCI2CInterface::I2CStatus ! 226: PPCI2CInterface::getStatus() ! 227: { ! 228: return (I2CStatus)(*status); ! 229: } ! 230: ! 231: // Interrupt status ! 232: INLINE void ! 233: PPCI2CInterface::setInterruptStatus(I2CInterruptStatus newStatusValue) ! 234: { ! 235: *ISR = (UInt8)newStatusValue; ! 236: eieio(); ! 237: } ! 238: ! 239: INLINE PPCI2CInterface::I2CInterruptStatus ! 240: PPCI2CInterface::getInterruptStatus() ! 241: { ! 242: return (I2CInterruptStatus)(*ISR); ! 243: } ! 244: ! 245: // Interrupt enable ! 246: INLINE void ! 247: PPCI2CInterface::setInterruptEnable(I2CInterruptEnable newInterruptEnable) ! 248: { ! 249: *IER = (UInt8)newInterruptEnable; ! 250: eieio(); ! 251: } ! 252: ! 253: INLINE PPCI2CInterface::I2CInterruptEnable ! 254: PPCI2CInterface::setInterruptEnable() ! 255: { ! 256: return (I2CInterruptEnable)(*IER); ! 257: } ! 258: ! 259: // Address Register: ! 260: INLINE void ! 261: PPCI2CInterface::setAddress(UInt8 newAddress) ! 262: { ! 263: writeRegisterField(address, (UInt8)kADDRMask, (UInt8)I2CAddressShift, (UInt8)newAddress); ! 264: eieio(); ! 265: } ! 266: ! 267: INLINE void ! 268: PPCI2CInterface::setAddressRegister(UInt8 newAddress, I2CRWMode readMode) ! 269: { ! 270: newAddress &= kADDRMask; ! 271: *address = (newAddress << I2CAddressShift) | readMode; ! 272: eieio(); ! 273: } ! 274: ! 275: INLINE UInt8 ! 276: PPCI2CInterface::getAddress() ! 277: { ! 278: return readRegisterField(address, (UInt8)kADDRMask, (UInt8)I2CAddressShift); ! 279: } ! 280: ! 281: INLINE void ! 282: PPCI2CInterface::setReadWrite(I2CRWMode readMode) ! 283: { ! 284: writeRegisterField(address, (UInt8)kRWMask, (UInt8)I2CRWShift, (UInt8)readMode); ! 285: eieio(); ! 286: } ! 287: ! 288: INLINE PPCI2CInterface::I2CRWMode ! 289: PPCI2CInterface::getReadWrite() ! 290: { ! 291: return (I2CRWMode)readRegisterField(address, (UInt8)kRWMask, (UInt8)I2CRWShift); ! 292: } ! 293: ! 294: // SubAddress register ! 295: INLINE void ! 296: PPCI2CInterface::setSubAddress(UInt8 newSubAddress) ! 297: { ! 298: *subAddr = newSubAddress; ! 299: eieio(); ! 300: } ! 301: ! 302: INLINE UInt8 ! 303: PPCI2CInterface::getSubAddress() ! 304: { ! 305: return (*subAddr); ! 306: } ! 307: ! 308: // Data register ! 309: INLINE void ! 310: PPCI2CInterface::setData(UInt8 newByte) ! 311: { ! 312: *data = newByte; ! 313: eieio(); ! 314: } ! 315: ! 316: INLINE UInt8 ! 317: PPCI2CInterface::getData() ! 318: { ! 319: return (*data); ! 320: } ! 321: ! 322: // -------------------------------------------------------------------------- ! 323: // Method: setAddressAndDirection ! 324: // ! 325: // Purpose: ! 326: // sets the control register with the correct address and data direction. ! 327: INLINE bool ! 328: PPCI2CInterface::setAddressAndDirection() ! 329: { ! 330: // sets the address register: ! 331: if (isReading) { ! 332: setAddressRegister(currentAddress, kReadADDR); ! 333: } ! 334: else { ! 335: setAddressRegister(currentAddress, kWriteADDR); ! 336: } ! 337: ! 338: // sets the subAddress: ! 339: setSubAddress(currentSubaddress); ! 340: ! 341: currentState = ki2cStateWaitingForIADDR; ! 342: setControl((I2CControl)(getControl() | kXAddrCNTRL)); ! 343: ! 344: #ifdef DEBUGMODE ! 345: IOLog("PPCI2CInterface::setAddressAndDirection()\n"); ! 346: #endif // DEBUGMODE ! 347: ! 348: return(true); ! 349: } ! 350: ! 351: // -------------------------------------------------------------------------- ! 352: // Method: i2cStandardSubModeInterrupts ! 353: // ! 354: // Purpose: ! 355: // handles the interrupts and the state machine for the Standard + SubAddress mode: ! 356: bool ! 357: PPCI2CInterface::i2cStandardSubModeInterrupts(UInt8 interruptStatus) ! 358: { ! 359: bool success = true; ! 360: ! 361: switch (currentState) { ! 362: case ki2cStateWaitingForIADDR: ! 363: #ifdef DEBUGMODE ! 364: IOLog("ki2cStateWaitingForIADDR: "); ! 365: #endif // DEBUGMODE ! 366: ! 367: // verify that correct interrupt bit set ! 368: if ((interruptStatus & kIAddrISR) == 0) { ! 369: #ifdef DEBUGMODE ! 370: IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts (ki2cStateWaitingForIADDR): bad state "); ! 371: #endif ! 372: success = false; ! 373: } ! 374: ! 375: if (success) { ! 376: if (getStatus() & kLastAakSTATUS) { ! 377: if (isReading) { ! 378: // if multiple bytes are to be read, set AAK bit ! 379: if (nBytes > 1) ! 380: setControl((I2CControl)(getControl() | kAakCNTRL)); ! 381: } ! 382: else { ! 383: // write operation ! 384: setData(*dataBuffer++); ! 385: nBytes--; ! 386: } ! 387: ! 388: currentState = ki2cStateWaitingForIDATA; ! 389: } ! 390: else { ! 391: // no slave responded, so wait for STOP (control bit does not need to be set, ! 392: // since NAAK sets the control bit automatically) ! 393: #ifdef DEBUGMODE ! 394: IOLog("...no slave..."); ! 395: #endif ! 396: currentState = ki2cStateWaitingForISTOP; ! 397: success = false; ! 398: } ! 399: } ! 400: else { ! 401: // bad state, so abort command ! 402: abortTransfer(); ! 403: } ! 404: ! 405: // clear IADDR bit and go ! 406: setInterruptStatus(kIAddrISR); ! 407: break; ! 408: ! 409: case ki2cStateWaitingForIDATA: ! 410: #ifdef DEBUGMODE ! 411: IOLog("ki2cStateWaitingForIDATA: "); ! 412: #endif ! 413: // verify that correct interrupt bit set ! 414: if ((interruptStatus & kIDataISR) == 0) { ! 415: #ifdef DEBUGMODE ! 416: IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts (ki2cStateWaitingForIDATA): bad state "); ! 417: #endif ! 418: success = false; ! 419: } ! 420: ! 421: if (success) { ! 422: if (isReading) { ! 423: *dataBuffer++ = getData(); ! 424: nBytes--; ! 425: ! 426: if (nBytes == 0) // read operation completed ! 427: currentState = ki2cStateWaitingForISTOP; ! 428: else // if next byte is last byte, clear AAK bit, and state remains unchanged ! 429: setControl(kClrCNTRL); ! 430: } ! 431: else { ! 432: // write operation ! 433: if (getStatus() & kLastAakSTATUS) { ! 434: if (nBytes == 0) { ! 435: // write operation completed ! 436: currentState = ki2cStateWaitingForISTOP; ! 437: setControl((I2CControl)(getControl() | kStopCNTRL)); ! 438: } ! 439: else { ! 440: // send an other byte ! 441: setData(*dataBuffer++); ! 442: nBytes--; ! 443: } ! 444: } ! 445: else { ! 446: // no slave responded, so wait for STOP (control bit does not need to be set, ! 447: // since NAAK sets the control bit automatically) ! 448: #ifdef DEBUGMODE ! 449: IOLog("...no slave..."); ! 450: #endif ! 451: currentState = ki2cStateWaitingForISTOP; ! 452: success = false; ! 453: } ! 454: } ! 455: } ! 456: else { ! 457: // bad state, so abort command ! 458: abortTransfer(); ! 459: } ! 460: ! 461: // clear IDATA bit and go ! 462: setInterruptStatus(kIDataISR); ! 463: break; ! 464: ! 465: case ki2cStateWaitingForISTOP: ! 466: #ifdef DEBUGMODE ! 467: IOLog("ki2cStateWaitingForISTOP: "); ! 468: #endif ! 469: // verify that correct interrupt bit set ! 470: if ((interruptStatus & kIStopISR) == 0) { ! 471: #ifdef DEBUGMODE ! 472: IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts (ki2cStateWaitingForISTOP): bad state "); ! 473: #endif ! 474: success = false; ! 475: } ! 476: ! 477: currentState = ki2cStateIdle; ! 478: setInterruptStatus(kIStopISR); ! 479: break; ! 480: ! 481: case ki2cStateWaitingForISTART: ! 482: #ifdef DEBUGMODE ! 483: IOLog("ki2cStateWaitingForISTART: is not supposed to happen in this state machine "); ! 484: #endif ! 485: break; ! 486: ! 487: case ki2cStateIdle: ! 488: #ifdef DEBUGMODE ! 489: IOLog("ki2cStateIdle: "); ! 490: #endif ! 491: break; ! 492: ! 493: default: ! 494: break; ! 495: } ! 496: #ifdef DEBUGMODE ! 497: IOLog("\n"); ! 498: #endif ! 499: ! 500: // tell the system that this interrupt has been serviced ! 501: return success; ! 502: } ! 503: ! 504: // -------------------------------------------------------------------------- ! 505: // Method: abortTransfer ! 506: // ! 507: // Purpose: ! 508: // ends the data transfer. ! 509: INLINE bool ! 510: PPCI2CInterface::abortTransfer() ! 511: { ! 512: currentState = ki2cStateWaitingForISTOP; ! 513: setControl((I2CControl)(getControl() | kStopCNTRL)); ! 514: return false; ! 515: } ! 516: ! 517: // -------------------------------------------------------------------------- ! 518: // Method: waitForCompletion ! 519: // ! 520: // Purpose: ! 521: // waits until the last command was executed correctly and when it ! 522: // happens it calls the interrupt handler. This is useful for when ! 523: // we use this object without an interrupt handler. ! 524: bool ! 525: PPCI2CInterface::waitForCompletion() ! 526: { ! 527: UInt16 loop = 50 + nBytes * 10; ! 528: UInt8 intStat = getInterruptStatus(); ! 529: ! 530: // First call to the interrupt handler in case the last command ! 531: // is already completed ! 532: ! 533: //IOLog("1] Interrupt Status = 0x%02x\n", intStat); ! 534: if (intStat & kISRMask) ! 535: handleI2CInterrupt(); ! 536: ! 537: // makes 10 loops for each expected interrupt with 1 millisecond delay for each loop: ! 538: while((loop--) && (currentState != ki2cStateIdle)) { ! 539: IOSleep(1); ! 540: ! 541: // If an interrupt occured handle it: ! 542: intStat = getInterruptStatus(); ! 543: ! 544: //IOLog("%d] Interrupt Status = 0x%02x\n", intStat); ! 545: if (intStat & kISRMask) ! 546: handleI2CInterrupt(); ! 547: } ! 548: ! 549: if (currentState != ki2cStateIdle) { ! 550: #ifdef DEBUGMODE ! 551: IOLog("PPCI2CInterface::waitForCompletion error loop is incomplete\n"); ! 552: #endif ! 553: return false; ! 554: } ! 555: else { ! 556: #ifdef DEBUGMODE ! 557: IOLog("PPCI2CInterface::waitForCompletion loop is complete\n"); ! 558: #endif ! 559: return true; ! 560: } ! 561: } ! 562: ! 563: // Public Methods: ! 564: // =============== ! 565: ! 566: // Initialize the address of the registers and the registers themselfs: ! 567: bool ! 568: PPCI2CInterface::initI2CBus(UInt8 *baseAddress, UInt8 steps) ! 569: { ! 570: pollingMode = true; ! 571: currentState = ki2cStateIdle; ! 572: SetI2CBase(baseAddress, steps); ! 573: ! 574: return true; ! 575: } ! 576: ! 577: // The default behavior of this class is to work in "polling mode" ! 578: // where the interrupt handler is called by a polling routine. ! 579: // However it is always possible to attahc the interrupt handler ! 580: // to an hardware interrupt and handle the transfer in the proper ! 581: // way. (the polling mode was created for the sole pourpose to ! 582: // debug the state machine). ! 583: void ! 584: PPCI2CInterface::setPollingMode(bool mode) ! 585: { ! 586: pollingMode = mode; ! 587: } ! 588: ! 589: // These are to setup the mode for the I2C bus: ! 590: void ! 591: PPCI2CInterface::setDumbMode() ! 592: { ! 593: setMode(kDumbMode); ! 594: } ! 595: ! 596: void ! 597: PPCI2CInterface::setStandardMode() ! 598: { ! 599: setMode(kStandardMode); ! 600: } ! 601: ! 602: void ! 603: PPCI2CInterface::setStandardSubMode() ! 604: { ! 605: setMode(kStandardSubMode); ! 606: } ! 607: ! 608: void ! 609: PPCI2CInterface::setCombinedMode() ! 610: { ! 611: setMode(kCombinedMode); ! 612: } ! 613: ! 614: // These instead set the speed: ! 615: bool ! 616: PPCI2CInterface::setKhzSpeed(UInt speed) ! 617: { ! 618: switch (speed) ! 619: { ! 620: case 100: ! 621: setSpeed(k100KhzMode); ! 622: break; ! 623: ! 624: case 50: ! 625: setSpeed(k50KhzMode); ! 626: break; ! 627: ! 628: case 25: ! 629: setSpeed(k25KhzMode); ! 630: break; ! 631: ! 632: default: ! 633: #ifdef DEBUGMODE ! 634: IOLog("PPCI2CInterface::setKhzSpeed Can not set bus speed %d is not allowed\n", speed); ! 635: #endif ! 636: return false; ! 637: break; ! 638: } ! 639: ! 640: return true; ! 641: } ! 642: ! 643: // Test to read the values set by the funtions above: ! 644: bool ! 645: PPCI2CInterface::isInDumbMode() ! 646: { ! 647: return (getMode() == kDumbMode); ! 648: } ! 649: ! 650: bool ! 651: PPCI2CInterface::isInStandardMode() ! 652: { ! 653: return (getMode() == kStandardMode); ! 654: } ! 655: ! 656: bool ! 657: PPCI2CInterface::isInStandardSubMode() ! 658: { ! 659: return (getMode() == kStandardSubMode); ! 660: } ! 661: ! 662: bool ! 663: PPCI2CInterface::isInCombinedMode() ! 664: { ! 665: return (getMode() == kCombinedMode); ! 666: } ! 667: ! 668: // These instead returns the speed: ! 669: UInt ! 670: PPCI2CInterface::getKhzSpeed() ! 671: { ! 672: switch((int)getSpeed()) ! 673: { ! 674: case k100KhzMode: ! 675: return (100); ! 676: break; ! 677: ! 678: case k50KhzMode: ! 679: return (50); ! 680: break; ! 681: ! 682: case k25KhzMode: ! 683: return (25); ! 684: break; ! 685: } ! 686: ! 687: // Returns 0 since the speed was not set to a real value ! 688: return (0); ! 689: } ! 690: ! 691: // Starts the use of the interface: ! 692: bool ! 693: PPCI2CInterface::openI2CBus(UInt8 port) ! 694: { ! 695: portSelect = port; ! 696: ! 697: // Enable all the interrupts: ! 698: setInterruptEnable((I2CInterruptEnable)(kEDataIER | kEAddrIER | kEStopIER | kEStartIER)); ! 699: ! 700: return true; ! 701: } ! 702: ! 703: // Writes a block of data at a given address: ! 704: bool ! 705: PPCI2CInterface::writeI2CBus(UInt8 address, UInt8 subAddress, UInt8 *newData, UInt16 len) ! 706: { ! 707: bool success = true; ! 708: ! 709: // waits for the completion of the previous command ! 710: waitForCompletion(); ! 711: ! 712: // pointer to the data to be transfered ! 713: dataBuffer = newData; ! 714: ! 715: // and the number of bytes still to transfer ! 716: nBytes = len; ! 717: ! 718: // the current transfer address: ! 719: currentAddress = address; ! 720: ! 721: // the current transfer subAddress: ! 722: currentSubaddress = subAddress; ! 723: ! 724: // the data direction: ! 725: isReading = false; ! 726: ! 727: if ((success = setAddressAndDirection()) == true ) { ! 728: if (pollingMode) ! 729: success = waitForCompletion(); ! 730: } ! 731: ! 732: return success; ! 733: } ! 734: ! 735: // Reads a block of data at a given address: ! 736: bool ! 737: PPCI2CInterface::readI2CBus(UInt8 address, UInt8 subAddress, UInt8 *newData, UInt16 len) ! 738: { ! 739: bool success = false; ! 740: ! 741: // waits for the completion of the previous command ! 742: waitForCompletion(); ! 743: ! 744: // pointer to the data to be received ! 745: dataBuffer = data; ! 746: ! 747: // and the number of bytes still to receive ! 748: nBytes = len; ! 749: ! 750: // the current transfer address: ! 751: currentAddress = address; ! 752: ! 753: // the current transfer subAddress: ! 754: currentSubaddress = subAddress; ! 755: ! 756: // the data direction: ! 757: isReading = true; ! 758: ! 759: if ((success = setAddressAndDirection()) == true ) { ! 760: if (pollingMode) ! 761: success = waitForCompletion(); ! 762: } ! 763: ! 764: return success; ! 765: } ! 766: ! 767: // End using the interface: ! 768: bool ! 769: PPCI2CInterface::closei2CBus() ! 770: { ! 771: // For now empty, we may add here some deinitialization parameters. ! 772: return true; ! 773: } ! 774: ! 775: // The interrupt handler: ! 776: // dispatches to the correct interrupt handler according to the current mode set: ! 777: bool ! 778: PPCI2CInterface::handleI2CInterrupt() ! 779: { ! 780: switch(lastMode) ! 781: { ! 782: case kDumbMode: ! 783: #ifdef DEBUGMODE ! 784: IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts kDumbMode is an unsupported mode (for now)\n"); ! 785: #endif ! 786: break; ! 787: ! 788: case kStandardMode: ! 789: #ifdef DEBUGMODE ! 790: IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts kStandardMode is an unsupported mode (for now)\n"); ! 791: #endif ! 792: break; ! 793: ! 794: case kStandardSubMode: ! 795: return (i2cStandardSubModeInterrupts(getInterruptStatus())); ! 796: break; ! 797: ! 798: case kCombinedMode: ! 799: #ifdef DEBUGMODE ! 800: IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts kCombinedMode is an unsupported mode (for now)\n"); ! 801: #endif ! 802: break; ! 803: } ! 804: ! 805: // By default we fail ... ! 806: return false; ! 807: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.