📄 mpc107i2c.c
字号:
} /* * since this is the first time through, generate a START(MSTA) and * place the I2C interface into a master transmitter mode(MTX). */ mpc107I2cRegRdWrMod(MPC107_I2C_READ_OR_WRITE, MPC107_I2C_I2CCR, (MPC107_I2CCR_MTX | MPC107_I2CCR_MSTA),0); SYNC; mpc107I2cCycleDelay (1); /* * The first time through, set "i2cDoRepeatStart". If this routine * is called again BEFORE a STOP is sent, then we are doing a * "dummy write", which sets the devices internal byte pointer * to the byte we intend to read. */ i2cDoRepeatStart = TRUE; return (OK); }/***************************************************************************** mpc107i2cCycleStop - perform I2C "stop" cycle** This routine is used is to perform an I2C stop cycle.** RETURNS: N/A*/LOCAL void mpc107i2cCycleStop (void) { mpc107I2cCycleDelay (1); /* * turn off MSTA bit(which will generate a STOP bus cycle) * turn off MTX bit(which places the I2C interface into receive mode * turn off TXAK bit(which allows 9th clock cycle acknowledges) */ mpc107I2cRegRdWrMod(MPC107_I2C_READ_AND_WRITE, MPC107_I2C_I2CCR, (~(MPC107_I2CCR_MTX | MPC107_I2CCR_MSTA | MPC107_I2CCR_TXAK)), 0); SYNC; mpc107I2cCycleDelay (1); /* Clear the global I2C "Repeat Start" flag.*/ i2cDoRepeatStart = FALSE; return ; }/***************************************************************************** mpc107i2cRegRdWrMod - i2c Registers In/OutLong and/or-ing wrapper.** The purpose of this routine is to perform AND, OR, and* AND/OR or In/Out operations with syncronization.** RETURNS: The data read for read operations.*/LOCAL UINT32 mpc107I2cRegRdWrMod ( UINT32 ioControlFlag, /* input/ouput control flag */ /* 0, write */ /* 1, read */ /* 2, read/modify/write (ORing) */ /* 3, read/modify/write (ANDing) */ /* 4, read/modify/write (AND/ORing) */ UINT32 address, /* address of device register */ UINT32 wdata1, /* data item 1 for read/write operation */ UINT32 wdata2 /* data item 2 for read/write operation */ ) { UINT32 i2cTempData = 0; if (ioControlFlag == MPC107_I2C_WRITE) /* Write */ { /* * Data <wdata1> is to be written in * the register specified by <address> */ MPC107EUMBBARWRITE(address, wdata1); } else if (ioControlFlag == MPC107_I2C_READ) /* Read */ { /* Data is read from the register specified by <address> */ i2cTempData =MPC107EUMBBARREAD(address); } else if (ioControlFlag == MPC107_I2C_READ_OR_WRITE) /* Read OR Write */ { /* * Data <wdata1> is bitwise ORed with the data read * from the register specified by <address> and the * resultant data is written to the register */ i2cTempData =MPC107EUMBBARREAD(address) | wdata1 ; SYNC; MPC107EUMBBARWRITE(address, i2cTempData); } else if (ioControlFlag == MPC107_I2C_READ_AND_WRITE) /* Read AND Write */ { /* * Data <wdata1> is bitwise ANDed with the data read * from the register specified by address and the * resultant data is written to the register */ i2cTempData =MPC107EUMBBARREAD(address) & wdata1; SYNC; MPC107EUMBBARWRITE(address, i2cTempData); } else if (ioControlFlag == MPC107_I2C_READ_ANDOR_WRITE)/* Read ANDOR write */ { /* * Data <wdata1> is bitwise ANDed with the data read * from the register specified by <address> and data * <wdata2> is bitwise ORed, and the resultant data * is written to the register */ i2cTempData =MPC107EUMBBARREAD(address); SYNC; i2cTempData &= wdata1; i2cTempData |= wdata2; MPC107EUMBBARWRITE(address, i2cTempData); } SYNC; return (i2cTempData); }/***************************************************************************** mpc107I2cDoOperation - i2c do operation** The purpose of this routine is to execute the operation as specified* by the passed command packet.** RETURNS: N/A*/LOCAL VOID mpc107I2cDoOperation ( UINT32 deviceAddress, /* device I2C bus address */ MPC107_I2C_CMD_PCKT * pI2cCmdPacket /* pointer to command packet */ ) { INT32 byteCount; /* byte counter */ INT32 statusVariable; /* local status variable */ UCHAR * pWriteData; /* pointer to write data buffer */ /* Command interface to stop. This is for previous error exits. */ mpc107i2cCycleStop (); if (pI2cCmdPacket->command == MPC107_I2C_READOP) /* read operation */ { statusVariable = 0; for (byteCount = 0; byteCount < pI2cCmdPacket->nBytes; byteCount++) { /* Start cycle */ if ((mpc107i2cCycleStart ()) != 0) { statusVariable = MPC107_I2C_ERR_CYCLE_START; break; } /* Write the device address */ mpc107i2cCycleWrite (deviceAddress); if ((mpc107i2cCycleAckIn ()) != 0) { statusVariable = MPC107_I2C_ERR_CYCLE_ACKIN; break; } /* Write the byte offset */ mpc107i2cCycleWrite (byteCount); if ((mpc107i2cCycleAckIn ()) != 0) { statusVariable = MPC107_I2C_ERR_CYCLE_ACKIN; break; } /* Write the device address */ mpc107i2cCycleWrite (deviceAddress | MPC107_I2C_DEVICE_READ_ENABLE); if ((mpc107i2cCycleAckIn ()) != 0) { statusVariable = MPC107_I2C_ERR_CYCLE_ACKIN; break; } /* Read the data from the IIC interface */ mpc107i2cCycleRead ((UCHAR *) (pI2cCmdPacket->memoryAddress + byteCount)); { statusVariable = MPC107_I2C_ERR_CYCLE_READ; break; } /* Generate the Stop Cycle */ mpc107i2cCycleStop () ; } /* update the caller's command packet with status of the operation */ pI2cCmdPacket->status = statusVariable; } /* * write operation for each byte * perform the byte write operation, a delay must be * exercised following each byte write */ if (pI2cCmdPacket->command == MPC107_I2C_WRITOP) { /* Initialize pointer to caller's write data buffer. */ pWriteData = (UCHAR *)pI2cCmdPacket->memoryAddress; /* Write the specified number of bytes from the EEPROM. */ statusVariable = 0; for (byteCount = 0; byteCount < pI2cCmdPacket->nBytes; byteCount++) { /* Generate the Start Cycle */ if ((mpc107i2cCycleStart ()) != 0) { statusVariable = MPC107_I2C_ERR_CYCLE_START; break; } /* Write the device address */ mpc107i2cCycleWrite (deviceAddress); if ((mpc107i2cCycleAckIn ()) != 0) { statusVariable = MPC107_I2C_ERR_CYCLE_ACKIN; break; } /* Write the byte offset */ mpc107i2cCycleWrite (byteCount); if ((mpc107i2cCycleAckIn()) != 0) { statusVariable = MPC107_I2C_ERR_CYCLE_ACKIN; break; } /* Write the device address */ mpc107i2cCycleWrite (deviceAddress); if ((mpc107i2cCycleAckIn ()) != 0) { statusVariable = MPC107_I2C_ERR_CYCLE_ACKIN; break; } /* Write the data */ mpc107i2cCycleWrite (*(pWriteData + byteCount)); if ((mpc107i2cCycleAckIn ()) != 0) { statusVariable = MPC107_I2C_ERR_CYCLE_ACKIN; break; } /* Generate the Stop Cycle */ mpc107i2cCycleStop (); } /* update the caller's command packet with status of the operation */ pI2cCmdPacket->status = statusVariable; } }/***************************************************************************** mpc107I2cCycleDelay() - delay for the specified amount of time (MS)** This routine will delay for the specified amount of time by counting* decrementer ticks.** This routine is not dependent on a particular rollover value for* the decrementer, it should work no matter what the rollover* value is.** A small amount of count may be lost at the rollover point resulting in* the mpc107I2cCycleDelay() causing a slightly longer delay than requested.** This routine will produce incorrect results if the delay time requested* requires a count larger than 0xffffffff to hold the decrementer* elapsed tick count. For a System Bus Speed of 67 MHZ this amounts to* about 258 seconds.** RETURNS: N/A*/LOCAL void mpc107I2cCycleDelay ( UINT delay /* length of time in MS to delay */ ) { register UINT32 oldval; /* decrementer value */ register UINT32 newval; /* decrementer value */ register UINT32 totalDelta; /* Dec. delta for entire delay period */ register UINT32 decElapsed; /* cumulative decrementer ticks */ /* Calculate delta of decrementer ticks for desired elapsed time. */ totalDelta = ((MPC107_DEFAULT_BUS_CLOCK / 4) / 1000) * delay; /* * Now keep grabbing decrementer value and incrementing "decElapsed" until * we hit the desired delay value. Compensate for the fact that we may * read the decrementer at 0xffffffff before the interrupt service * routine has a chance to set in the rollover value. */ decElapsed = 0; oldval = mpc107GetDec (); while (decElapsed < totalDelta) { newval = mpc107GetDec(); if ( MPC107_DELTA(oldval,newval) < 1000 ) decElapsed += MPC107_DELTA(oldval,newval); /* no rollover */ else if (newval > oldval) decElapsed += abs((INT32)oldval); /* rollover */ oldval = newval; } }/***************************************************************************** mpc107GetDec - read from the Decrementer register SPR22.** This routine will read the contents the decrementer (SPR22)** From a C point of view, the routine is defined as follows:** UINT32 mpc107GetDec()** RETURNS: value of SPR22 (in r3)*/LOCAL UINT32 mpc107GetDec(void) { return vxDecGet (); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -