📄 sysi2cdrv.c
字号:
/* sysI2cDrv.c - I2C Driver Source Module *//* Copyright 1984-2001 Wind River Systems, Inc. *//* Copyright 1996-2001 Motorola, Inc. All Rights Reserved *//*modification history--------------------01c,05jan01,djs removed table of function pointers used by SPD routines01b,08dec00,djs fixed problem initializing I2C interface.01a,02nov00,djs created from 01e,14apr00,krp*//*DESCRIPTIONThis file contains generic functions to read/write an I2C device.Currently the file only supports the MPC107 I2C interface.However, additional I2C bus "controllers can be easily be addedas required.*//* includes */#include "vxWorks.h" /* vxWorks generics */#include "ioLib.h" /* input/output generics */#include "blkIo.h" /* block input/output specifics */#include "semLib.h" /* semaphore operations */#include "cacheLib.h" /* cache control */#include "intLib.h" /* interrupt control */#include "config.h" /* BSP specifics */#include "sysI2cDrv.h" /* driver specifics */#include "mpc107.h" /* processor specifics */#include "sysMotVpd.h"#include "sysI2cMpc107.h" /* I2C Driver Header Module *//* defines */#undef I2C_DRIVER_DEBUG/* externals */#ifdef I2C_DRIVER_TESTSIMPORT int printf(); /* formatted print */#endifIMPORT int i2cCycleMpc107Write ();IMPORT void i2cCycleMpc107Delay ();IMPORT UINT32 sysCalcBusSpd ();IMPORT int i2cCycleMpc107Start (unsigned char *);IMPORT int i2cCycleMpc107Stop (unsigned char *);IMPORT int i2cCycleMpc107Read (unsigned char *);IMPORT int i2cCycleMpc107AckIn (void);IMPORT int i2cCycleMpc107AckOut (void);IMPORT int i2cCycleMpc107KnownState (void);/* locals */extern int i2cDoOp(); /* i2c do operation */extern BLK_DEV *i2cDevCreate(); /* create logical device */extern int i2cRead(); /* device read operation */extern int i2cWrite(); /* device write operation */extern unsigned int i2cAddressMunge(); /* munge device address (EEPROM) */LOCAL UINT32 i2cPciInLong ();LOCAL void i2cPciOutLong ();LOCAL UINT8 i2cPciInByte ();LOCAL void i2cPciOutByte (UINT8 *, UINT8);#ifdef I2C_DRIVER_TESTSunsigned char i2cBufferRead[1024];#endif/******************************************************************************** i2cPciIoctl - i2cPciIn/OutLong and/or-ing wrapper.** The purpose of this function is to perform and, or and* and/or i2cPciIn/OutLong operations with syncronization.** RETURNS: UINT32, for read operations.*/UINT32 i2cPciIoctl ( UINT32 ioctlflg, /* 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 to be operated upon */ UINT32 wdata1, /* data item 1 for read/write operation */ UINT32 wdata2 /* data item 2 for read/write operation */ ) { UINT32 u32temp; if (ioctlflg == 0) /* write */ i2cPciOutLong(address, wdata1); if (ioctlflg == 1) /* read */ { wdata1 = i2cPciInLong(address); } if (ioctlflg == 2) /* ORing */ { u32temp = i2cPciInLong(address); SYNC; u32temp |= wdata1; i2cPciOutLong(address, u32temp); } if (ioctlflg == 3) /* ANDing */ { u32temp = i2cPciInLong(address); SYNC; u32temp &= wdata1; i2cPciOutLong(address, u32temp); } if (ioctlflg == 4) /* AND/ORing */ { u32temp = i2cPciInLong(address); SYNC; u32temp &= wdata1; u32temp |= wdata2; i2cPciOutLong(address, u32temp); } SYNC; return (wdata1); }/******************************************************************************** i2cDrvInit - initialize the i2c device** This function's purpose is to the initialize the I2C device* controller device for operation. This function should only* be executed once during system initialization time.** RETURNS: OK, or ERROR */STATUS i2cDrvInit ( int i2cControllerType /* I2C controller type */ ) { UINT32 busSpeed = 0; UCHAR temp; /* * Check for unknown controller type, and initialize I2C controller * for operation (if needed). Note: a switch will not work here if * executing from ROM due to branch history table creation. */ if (i2cControllerType == 0) { /* disable the I2C module, set the device to Master Mode */ i2cPciIoctl(3, (UINT32)MPC107_I2C_CONTROL_REG, ~((MPC107_I2C_CONTROL_REG_MEN | MPC107_I2C_CONTROL_REG_MSTA)), 0); SYNC; /* Calculate the 60x bus frequency */ busSpeed = sysCalcBusSpd (); /* * If busSpeed is 0, set the bus speed to a default value * and try to come up. */ if (busSpeed <= 0) busSpeed = DEFAULT_BUS_CLOCK; busSpeed = (busSpeed + (MHZ/2)) / MHZ; /* initialize and enable the I2C interface */ if (busSpeed == SPEED83MHZ) /* 83.333 MHz system bus */ { i2cPciIoctl(4, (UINT32)MPC107_I2C_FREQ_DIV_REG, (~MPC107_I2C_FREQ_DIV_REG_MASK), 0x2A); } else if (busSpeed == SPEED100MHZ) /* 100 MHz system bus */ { i2cPciIoctl(4, (UINT32)MPC107_I2C_FREQ_DIV_REG, (~MPC107_I2C_FREQ_DIV_REG_MASK), 0x2B); } else /* default to 66.667 MHz system bus */ { i2cPciIoctl(4, (UINT32)MPC107_I2C_FREQ_DIV_REG, (~MPC107_I2C_FREQ_DIV_REG_MASK), 0x29); } SYNC; /* set the slave address */ i2cPciIoctl(4, (UINT32)MPC107_I2C_ADR_REG, (~MPC107_I2C_ADDRESS_REG_MASK), 0x02); SYNC; /* enable the interface */ i2cPciIoctl(2, (UINT32)MPC107_I2C_CONTROL_REG, MPC107_I2C_CONTROL_REG_MEN, 0); SYNC; /* * set the device to slave mode. This is required for * clearing a BUS BUSY lockup condition. */ /* * Clear the eeprom write-protection bit so we can make * modifications. */ temp = i2cPciInByte( (UINT32)LOPEC_SYS_STAT_REG1 ); i2cPciOutByte( (UINT8 *)LOPEC_SYS_STAT_REG1, (temp & (~LOPEC_EEPROM_WP)) ); } else { return (ERROR); } return (OK); }/******************************************************************************** i2cRead - i2c read blocks** This function's purpose is to read the specified number of* blocks from the specified device.** RETURNS: OK, or Error on a bad request*/int i2cRead ( UINT32 deviceAddress, /* Device's I2C bus address */ unsigned int startBlk, /* starting block to read */ unsigned int numBlks, /* number of blocks to read */ char *pBuf /* pointer to buffer to receive data */ ) { int localStatus; /* local status variable */ i2cCmdPckt_t i2cCmdPacket; /* command packet */ /* Check for a bad request. */ if (!numBlks) { return (ERROR); } /* Build command packet. */ i2cCmdPacket.command = I2C_READOP; i2cCmdPacket.status = 0; i2cCmdPacket.memoryAddress = (unsigned int)pBuf; i2cCmdPacket.blockNumber = startBlk; i2cCmdPacket.nBlocks = numBlks; i2cCmdPacket.eCount = numBlks; i2cCmdPacket.aCount = 0; localStatus = i2cDoOp(deviceAddress, (i2cCmdPckt_t *)&i2cCmdPacket);#ifdef I2C_DRIVER_DEBUG printf("command =%08X\r\n", i2cCmdPacket.command); printf("status =%08X\r\n", i2cCmdPacket.status); printf("memory address =%08X\r\n", i2cCmdPacket.memoryAddress); printf("block number =%08X\r\n", i2cCmdPacket.blockNumber); printf("number of blocks =%08X\r\n", i2cCmdPacket.nBlocks); printf("expected count =%08X\r\n", i2cCmdPacket.eCount); printf("actual count =%08X\r\n", i2cCmdPacket.aCount);#endif /* Return the appropriate status. */ return (localStatus); }/******************************************************************************** i2cWrite - i2c write blocks** This function's purpose is to write the specified number of* blocks to the specified device.** RETURNS: Number of bytes written, or ERROR if bad request.*/int i2cWrite ( UINT32 deviceAddress, /* Device's I2C bus address */ unsigned int startBlk, /* starting block to write */ unsigned int numBlks, /* number of blocks to write */ char *pBuf /* pointer to buffer of send data */ ) { int localStatus; /* local status variable */ i2cCmdPckt_t i2cCmdPacket; /* command packet */ /* Check for a NOP request. */ if (!numBlks) { return (ERROR); } /* Build command packet. */ i2cCmdPacket.command = I2C_WRITOP; i2cCmdPacket.status = 0; i2cCmdPacket.memoryAddress = (unsigned int)pBuf; i2cCmdPacket.blockNumber = startBlk; i2cCmdPacket.nBlocks = numBlks; i2cCmdPacket.eCount = numBlks; i2cCmdPacket.aCount = 0; /* Take ownership, call driver, release ownership. */ localStatus = i2cDoOp(deviceAddress, (i2cCmdPckt_t *)&i2cCmdPacket);#ifdef I2C_DRIVER_DEBUG printf("command =%08X\r\n", i2cCmdPacket.command); printf("status =%08X\r\n", i2cCmdPacket.status); printf("memory address =%08X\r\n", i2cCmdPacket.memoryAddress); printf("block number =%08X\r\n", i2cCmdPacket.blockNumber); printf("number of blocks =%08X\r\n", i2cCmdPacket.nBlocks); printf("expected count =%08X\r\n", i2cCmdPacket.eCount); printf("actual count =%08X\r\n", i2cCmdPacket.aCount);#endif /* Return the appropriate status. */ return (localStatus); }/*******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -