Logo Search packages:      
Sourcecode: xbox-cromwell version File versions  Download package

2bPicResponseAction.c

/*
 * I2C-related code
 * AG 2002-07-27
 */

 /***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "2bload.h"


// ----------------------------  I2C -----------------------------------------------------------
//
// get a value from a given device address
// errors will have b31 set, ie, will be negative, otherwise fetched byte in LSB of return

int I2CTransmitByteGetReturn(u8 bPicAddressI2cFormat, u8 bDataToWrite)
{
      int nRetriesToLive=400;

      //if(IoInputWord(I2C_IO_BASE+0)&0x8000) {  }
      while(IoInputWord(I2C_IO_BASE+0)&0x0800) ;  // Franz's spin while bus busy with any master traffic

      while(nRetriesToLive--) {

            IoOutputByte(I2C_IO_BASE+4, (bPicAddressI2cFormat<<1)|1);
            IoOutputByte(I2C_IO_BASE+8, bDataToWrite);
            IoOutputWord(I2C_IO_BASE+0, 0xffff); // clear down all preexisting errors
            IoOutputByte(I2C_IO_BASE+2, 0x0a);

            {
                  u8 b=0x0;
                  while( (b&0x36)==0 ) { b=IoInputByte(I2C_IO_BASE+0); }

                  if(b&0x24) {
                        //bprintf("I2CTransmitByteGetReturn error %x\n", b);
                  }
                  if(!(b&0x10)) {
                        //bprintf("I2CTransmitByteGetReturn no complete, retry\n");
                  } else {
                        return (int)IoInputByte(I2C_IO_BASE+6);
                  }
            }
      }

      return ERR_I2C_ERROR_BUS;
}

// transmit a word, no returned data from I2C device

int I2CTransmitWord(u8 bPicAddressI2cFormat, u16 wDataToWrite)
{
      int nRetriesToLive=400;

      while(IoInputWord(I2C_IO_BASE+0)&0x0800) ;  // Franz's spin while bus busy with any master traffic

      while(nRetriesToLive--) {
            IoOutputByte(I2C_IO_BASE+4, (bPicAddressI2cFormat<<1)|0);

            IoOutputByte(I2C_IO_BASE+8, (u8)(wDataToWrite>>8));
            IoOutputByte(I2C_IO_BASE+6, (u8)wDataToWrite);
            IoOutputWord(I2C_IO_BASE+0, 0xffff);  // clear down all preexisting errors
            IoOutputByte(I2C_IO_BASE+2, 0x1a);

            {
                  u8 b=0x0;
                  while( (b&0x36)==0 ) { b=IoInputByte(I2C_IO_BASE+0); }

                  if(b&0x24) {
                        //bprintf("I2CTransmitWord error %x\n", b);
                  }
                  if(!(b&0x10)) {
                        //bprintf("I2CTransmitWord no complete, retry\n");
                  } else {
                        return ERR_SUCCESS;
                  }
            }
      }
      return ERR_I2C_ERROR_BUS;
}

// ----------------------------  PIC challenge/response -----------------------------------------------------------
//
// given four bytes, returns a u16
// LSB of return is the 'first' byte, MSB is the 'second' response byte

u16 BootPicManipulation(
      u8 bC,
      u8  bD,
      u8  bE,
      u8  bF
) {
      int n=4;
      u8
            b1 = 0x33,
            b2 = 0xed,
            b3 = ((bC<<2) ^ (bD +0x39) ^ (bE >>2) ^ (bF +0x63)),
            b4 = ((bC+0x0b) ^ (bD>>2) ^ (bE +0x1b))
      ;

      while(n--) {
            b1 += b2 ^ b3;
            b2 += b1 ^ b4;
      }

      return (u16) ((((u16)b2)<<8) | b1);
}

// actual business of getting I2C data from PIC and reissuing munged version
// returns zero if all okay, else error code

int BootPerformPicChallengeResponseAction()
{
      u8 bC, bD, bE, bF;
      int n;

      n=I2CTransmitByteGetReturn( 0x10, 0x1c );
      if(n<0) return n;
      bC=n;
      n=I2CTransmitByteGetReturn( 0x10, 0x1d );
      if(n<0) return n;
      bD=n;
      n=I2CTransmitByteGetReturn( 0x10, 0x1e );
      if(n<0) return n;
      bE=n;
      n=I2CTransmitByteGetReturn( 0x10, 0x1f );
      if(n<0) return n;
      bF=n;

      {
            u16 w=BootPicManipulation(bC, bD, bE, bF);

            I2CTransmitWord( 0x10, 0x2000 | (w&0xff));
            I2CTransmitWord( 0x10, 0x2100 | (w>>8) );
      }

      // continues as part of video setup....
      return ERR_SUCCESS;
}

extern int I2cSetFrontpanelLed(u8 b)
{
      I2CTransmitWord( 0x10, 0x800 | b);  // sequencing thanks to Jarin the Penguin!
      I2CTransmitWord( 0x10, 0x701);
      return ERR_SUCCESS;
}


Generated by  Doxygen 1.6.0   Back to index