📄 mtxi2c.c
字号:
/* mtxI2c.c - Motorola MTX I2C bus driver *//* Copyright 1984-1999 Wind River Systems, Inc. *//* Copyright 1997,1998,1999 Motorola, Inc., All Rights Reserved *//*modification history--------------------01d,05aug99,dmw changed compile-time I2C and BSMR addresses to stack variables to support CHRP mode addressing.01c,17jul99,dmw added hawk I2C declarations for MTXPlus.01b,25feb99,dat merge from motorola drop (SPR 25357)01a,16apr98,srr converted to C from assembly language.*//*DESCRIPTIONThis module implements the I2c bus access functions.*//* includes */#include "vxWorks.h"#include "config.h"#include "mtxI2c.h"#ifdef INCLUDE_I2C/* Macros for all i/o operations to use */#ifndef I2C_READ#define I2C_READ(readAddr, lvalue) \ (lvalue = *(UCHAR *)(readAddr))#endif#ifndef I2C_WRITE#define I2C_WRITE(writeAddr, value) \ (*(UCHAR *)(writeAddr) = value)#endifIMPORT STATUS sysHawkI2cRangeRead (UCHAR devAddr, /* addr of the eeprom */ UCHAR devOffset, /* starting offset */ UINT16 byteCount, /* num bytes to read */ UCHAR * pBfr); /* destination buffer *//* defines */#define DFLT_PCI_ST_ADDR3 (0x8000) /* Deflt PCI start ADDR3 */#define PREP_BSMR_ADDR (UCHAR *)(0x80000803) /* PReP BMSR address */#define PREP_I2C_CMD_STAT (UCHAR *)(0x80000980) /* PReP I2C Status */#define PREP_I2C_CTRL_REG (UCHAR *)(0x80000981) /* PReP I2C Ctrl *//* forward declarations */void mtxI2cInit (void);void mtxI2cIdleWait (void);STATUS mtxI2cStatusRead (UCHAR);/******************************************************************************** mtxI2cDimmGet - read I2C bus** This function's purpose is to read data from the I2C.** RETURNS: N/A*/void mtxI2cDimmGet ( UINT slaveAdr, /* slave I2C device address. */ UCHAR * bufPtr, /* address of buffer to fill. */ UINT count /* number of bytes to read. */ ) { int i; /* index */ char status; /* status from I2C */ UCHAR * dataBufPtr; /* local data buffer ptr */ UCHAR *bmsr = PREP_BSMR_ADDR; /* PReP BMSR address */ UCHAR *I2cCmdStat = PREP_I2C_CMD_STAT; /* PReP I2C Status address */ UCHAR *I2cCtrlReg = PREP_I2C_CTRL_REG; /* PReP I2C Ctrl address */ /* * Check to see if we are using extended PCI. This occurs when control-x * is performed (i.e. address decoders are already programmed with * extended PCI values). By default (power-up), a 64K PReP window is * programmed into the Raven to access ISA I/O by the hardware. */ if ((*(UINT32 *)(RAVEN_BASE_ADRS + RAVEN_MPC_MSADD3) >> 16) != DFLT_PCI_ST_ADDR3) { I2cCmdStat = (UCHAR *)I2C_CMD_STAT; I2cCtrlReg = (UCHAR *)I2C_CTRL_REG; bmsr = SYS_REG_BMSR; } if (*bmsr == SYS_REG_BMSR_MTX_PLUS) { sysHawkI2cRangeRead (slaveAdr, 0, count, bufPtr); return; } mtxI2cInit (); /* Initialize I2C device. */ /* * Done initilizing I2C device, now read from DIMM. * Wait for bus to be idle. */ do { I2C_READ (I2cCtrlReg, status); /* read status */ EIEIO_SYNC; } while (!(status & I2C_BUS_BUSY)); I2C_WRITE (I2cCmdStat, slaveAdr); /* write slave addr to I2C ctrl reg */ EIEIO_SYNC; I2C_WRITE (I2cCtrlReg, I2C_START_CMD); /* generate 'START' command */ EIEIO_SYNC; if (mtxI2cStatusRead (I2C_ERROR_CHECK) == ERROR) return; I2C_WRITE (I2cCmdStat, 0); /* write "0" to I2C control reg */ EIEIO_SYNC; if (mtxI2cStatusRead (I2C_ERROR_CHECK) == ERROR) return; I2C_WRITE (I2cCtrlReg, I2C_START_CMD); /* 'REPEAT START' command */ EIEIO_SYNC; /* write slave address with read bit set to I2C control reg */ I2C_WRITE (I2cCmdStat, (slaveAdr | I2C_READ_BIT)); EIEIO_SYNC; if (mtxI2cStatusRead (I2C_ERROR_CHECK) == ERROR) return; /* * get data byte - this is slave address so throw it away. * actually, this first byte is trashed by transmitter. This * byte is the first byte from the EEPROM (0x80). */ I2C_READ (I2cCmdStat, status); EIEIO_SYNC; for (i=0, dataBufPtr=bufPtr; i < count ;i++) { mtxI2cStatusRead (FALSE); I2C_READ (I2cCmdStat, *dataBufPtr++); /* read byte from S0 register */ EIEIO_SYNC; } I2C_WRITE (I2cCtrlReg, I2C_ACK); /* set ACK bit in S0 for negative ack */ EIEIO_SYNC; I2C_READ (I2cCmdStat, status); /* read second to lastbyte from S0 reg*/ EIEIO_SYNC; mtxI2cStatusRead (FALSE); I2C_WRITE (I2cCtrlReg, I2C_STOP_CMD); /* generate 'STOP' command. */ EIEIO_SYNC; I2C_READ (I2cCmdStat, status); /* read lastbyte from S0 register */ EIEIO_SYNC; }/******************************************************************************** mtxI2cInit - initialize the I2C controller** This function's purpose is to perform the intialization sequence* for the I2C controller.** RETURNS: N/A*/void mtxI2cInit (void) { int i; /* index for delay loop */ UCHAR *I2cCmdStat = PREP_I2C_CMD_STAT; /* default I2C stat reg */ UCHAR *I2cCtrlReg = PREP_I2C_CTRL_REG; /* default I2C ctrl reg */ /* check to see if we are using extended PCI. */ if ((*(UINT32 *)(RAVEN_BASE_ADRS + RAVEN_MPC_MSADD3) >> 16) != DFLT_PCI_ST_ADDR3) { I2cCmdStat = (UCHAR *)I2C_CMD_STAT; I2cCtrlReg = (UCHAR *)I2C_CTRL_REG; } I2C_WRITE (I2cCtrlReg, I2C_SERIAL_OFF); /* I2C serial interface off */ EIEIO_SYNC; I2C_WRITE (I2cCmdStat, I2C_OWN_ADDR); /* set effective I2C own addr */ EIEIO_SYNC; I2C_WRITE (I2cCtrlReg, I2C_NW_SET_CLK); /* next write will set clock */ EIEIO_SYNC; I2C_WRITE (I2cCmdStat, I2C_CLK_RATE); /* set system clock */ EIEIO_SYNC; I2C_WRITE (I2cCtrlReg, I2C_SERIAL_ON); /* I2C serial interface on */ EIEIO_SYNC; for (i=0; i < I2C_DELAY ;i++) /* small delay */ ; }/******************************************************************************** mtxI2cStatusRead - read status from the I2C controller** This function's purpose is to read the status from the command/status* register of the I2C controller until the PIN bit is cleared.* If the errorCheck flag is set then the Last Bit Received bit is tested* and status returned.** RETURNS: ERROR if the Last Bit Received bit is set, OK if clear.*/STATUS mtxI2cStatusRead ( UCHAR errorCheck /* flag to perform error checking */ ) { char status; /* status from I2C */ UCHAR *I2cCmdStat = PREP_I2C_CMD_STAT; /* default I2C stat reg */ UCHAR *I2cCtrlReg = PREP_I2C_CTRL_REG; /* default I2C ctrl reg */ /* check to see if we are using extended PCI addressing. */ if ((*(UINT32 *)(RAVEN_BASE_ADRS + RAVEN_MPC_MSADD3) >> 16) != DFLT_PCI_ST_ADDR3) { I2cCmdStat = (UCHAR *)I2C_CMD_STAT; I2cCtrlReg = (UCHAR *)I2C_CTRL_REG; } /* Wait for PIN bit to be clear */ do { I2C_READ (I2cCtrlReg, status); /* read status */ EIEIO_SYNC; } while (status & I2C_PIN_MASK); /* verify last bit received is set */ if ((errorCheck == TRUE) && (status & I2C_LRB_MASK)) { I2C_WRITE (I2cCtrlReg, I2C_STOP_CMD); /* generate 'STOP' command. */ EIEIO_SYNC; I2C_READ (I2cCmdStat, status); /* read lastbyte from S0 reg */ EIEIO_SYNC; return(ERROR); } return(OK); }#endif /* INCLUDE_I2C */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -