📄 sysmoti2c.c
字号:
/* sysMotI2c.c - I2C Driver Source Module *//* Copyright (c) 2000, 2002, 2005 Wind River Systems, Inc. *//* Copyright 1996-2000 Motorola, Inc. All Rights Reserved *//*modification history--------------------01d,15nov05,mdo Documentation fixes for apigen01c,21may02,gtf modified for Raytheon NetFires bsp.01b,10mar00,rhk changed over to use sysCalcBusSpd, removed 100MHz speed.01a,28feb00,rhk created from version 01d, MV2100 BSP.*//*DESCRIPTIONThis file contains generic functions to read/write an I2C device.Currently the file only supports the Mpc834x I2C interface.However, additional I2C bus controllers can be easily be addedas required.INCLUDE FILES: sysMotI2c.h*//* includes */#include "vxWorks.h" /* vxWorks generics */#include "config.h"#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 "semLib.h"#include "config.h" /* BSP specifics */#include "sysMotI2c.h" /* driver specifics */#include "sysMpc834xI2c.h" /* Mpc834x I2C Driver Header Module */#include "stdio.h"#include "logLib.h"#include "stdlib.h"/* defines */#undef I2C_DRIVER_DEBUG/* externals */#ifdef I2C_DRIVER_TESTSIMPORT int printf(); /* formatted print */#endifIMPORT int sysClkRateGet(); /* system clock rate */IMPORT int rawFsDevInit(); /* raw file system device init */IMPORT void sysMpc834xMsDelay (UINT mSeconds);/* locals */LOCAL UINT8 i2cInByte (UINT32);LOCAL void i2cOutByte (UINT32,UINT8);/* Driver/controller routines table for the Mpc834x device. */i2cDrvRoutines_t i2cDrvRoutinesTableMpc834x = { (int(*)())i2cCycleMpc834xStart, (int(*)())i2cCycleMpc834xStop, (int(*)())i2cCycleMpc834xRead, (int(*)())i2cCycleMpc834xWrite, (int(*)())i2cCycleMpc834xAckIn, (int(*)())i2cCycleMpc834xAckOut, (int(*)())i2cCycleMpc834xKnownState, (void(*)())i2cCycleMpc834xDelay};/* driver/controller routines table, indexed by the "I2C_DRV_TYPE". */i2cDrvRoutines_t *i2cDrvRoutinesTables[] = { (i2cDrvRoutines_t *)&i2cDrvRoutinesTableMpc834x /* index 0 */};/******************************************************************************** i2cIoctl - i2cIn/OutByte and/or-ing wrapper.** The purpose of this function is to perform and, or and* and/or i2cIn/OutByte operations with synchronization.** RETURNS: UINT32, for read operations.** ERRNO*/UINT8 i2cIoctl ( 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 */ UINT8 bdata1, /* data item 1 for read/write operation */ UINT8 bdata2 /* data item 2 for read/write operation */ ) { UINT8 u8temp;#ifdef I2C_DRIVER_DEBUG logMsg("i2cIoctl: adrs - 0x%x.\n", address,2,3,4,5,6);#endif i2cCycleMpc834xDelay(1); if ( ioctlflg == I2C_IOCTL_WR ) /* write */ { i2cOutByte(address, bdata1); } else if ( ioctlflg == I2C_IOCTL_RD ) /* read */ { bdata1 = i2cInByte(address); } else if ( ioctlflg == I2C_IOCTL_RMW_OR ) /* ORing */ { u8temp = i2cInByte(address); u8temp |= bdata1; i2cCycleMpc834xDelay(1); i2cOutByte(address, u8temp); } else if ( ioctlflg == I2C_IOCTL_RMW_AND ) /* ANDing */ { u8temp = i2cInByte(address); u8temp &= bdata1; i2cCycleMpc834xDelay(1); i2cOutByte(address, u8temp); } else if ( ioctlflg == I2C_IOCTL_RMW_AND_OR ) /* AND/ORing */ { u8temp = i2cInByte(address); u8temp &= bdata1; u8temp |= bdata2; i2cCycleMpc834xDelay(1); i2cOutByte(address, u8temp); } i2cCycleMpc834xDelay(1); return(bdata1); }/******************************************************************************** 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.** NOTE: Do not call printf or logMsg statements here because it is called * during sysHwInit(). If output is desired a polled or debug dump routine * should be used.** RETURNS: OK, or ERROR if not prpmc600 board.** ERRNO*/#if 0LOCAL I2C_DRV_CTRL *pI2cDrvCtrl[2] = { NULL, NULL } ;#elseI2C_DRV_CTRL i2C1DrvCtrl ;I2C_DRV_CTRL i2C2DrvCtrl ;I2C_DRV_CTRL * pI2cDrvCtrl[2] = { NULL, NULL } ;#endifSTATUS i2cDrvInit ( int unit, int i2cControllerType /* I2C controller type */ ) { /* * Check for unknown controller type, and initialize I2C controller * for operation (if needed). Note: a switch statement will not work here if * executing from ROM due to branch history table creation. */ if (pI2cDrvCtrl[unit] == NULL) { if (unit == 0) { pI2cDrvCtrl[unit] = &i2C1DrvCtrl ; pI2cDrvCtrl[unit]->baseAdrs = M834X_I2C1_BASE ; } else if (unit == 1) { pI2cDrvCtrl[unit] = &i2C2DrvCtrl ; pI2cDrvCtrl[unit]->baseAdrs = M834X_I2C2_BASE ; } pI2cDrvCtrl[unit]->baseAdrs += CCSBAR ; } #if 0 if ( i2cControllerType == 0 ) /* Mpc834x(MPC834X) */ #else if (1) #endif { /* disable the I2C module, set the device to Master Mode */ i2cIoctl(I2C_IOCTL_RMW_AND_OR, (UINT32)(pI2cDrvCtrl[unit]->baseAdrs+MPC834X_I2C_CONTROL_REG), ((UINT8)~MPC834X_I2C_CONTROL_REG_MEN), MPC834X_I2C_CONTROL_REG_MSTA); /* initialize and enable the I2C interface *//*I2C1 - clock = csb_clk / 3. = 111MHz. -> need to get to 100KHz. -> div by 1024. gives 100+Khz.I2C2 - clock = csb_clk. = SYS_CLK_FREQ. -> div by 3072. gives 100+Khz.The freq div register needs to be set such that the I2C bus is 100KHz... */ if ( SYS_CLK_FREQ == FREQ_333_MHZ ) /* 50MHz */ { UINT8 divider ; if (unit == 0) divider = 0x7 ; /* 1024 */ else divider = 0xe ; /* 3072 */ i2cIoctl(I2C_IOCTL_RMW_AND_OR, (UINT32)(pI2cDrvCtrl[unit]->baseAdrs+MPC834X_I2C_FREQ_DIV_REG), ((UINT8)~MPC834X_I2C_FREQ_DIV_REG_MASK), divider); /* 0x20 - div by 160 (~300KHz), 0x24 - div by 320 (~150KHz)*/ } /* set the slave address */ i2cIoctl(I2C_IOCTL_RMW_AND_OR, (UINT32)(pI2cDrvCtrl[unit]->baseAdrs+MPC834X_I2C_ADR_REG), ((UINT8)~MPC834X_I2C_ADDRESS_REG_MASK), 1); /* enable the interface */ i2cIoctl(I2C_IOCTL_RMW_OR, (UINT32)(pI2cDrvCtrl[unit]->baseAdrs+MPC834X_I2C_CONTROL_REG), MPC834X_I2C_CONTROL_REG_MEN, 0); /* * set the device to slave mode. This is required for * clearing a BUS BUSY lockup condition. */ i2cIoctl(I2C_IOCTL_RMW_AND, (UINT32)(pI2cDrvCtrl[unit]->baseAdrs+MPC834X_I2C_CONTROL_REG), ((UINT8)~MPC834X_I2C_CONTROL_REG_MSTA), 0); } 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** ERRNO*/int i2cRead ( int unit, UINT32 deviceAddress, /* Device's I2C bus address */ int deviceType, unsigned int startBlk, /* starting block to read or register to read */ unsigned int numBlks, /* number of blocks to read or single/double byte register */ char * pBuf /* pointer to buffer to receive data */ ) { int localStatus; /* local status variable */ i2cCmdPckt_t i2cCmdPacket; /* command packet */ /* Check to see if the driver's been installed */ if(pI2cDrvCtrl[unit]->baseAdrs == 0) { logMsg("I2C driver for unit %d not initialized.\n", unit,2,3,4,5,6); return ERROR ; } /* 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; i2cCmdPacket.deviceType = deviceType ; localStatus = i2cDoOp(unit, deviceAddress, (i2cCmdPckt_t *)&i2cCmdPacket);#ifdef I2C_DRIVER_DEBUG logMsg("command =%08X\r\n", i2cCmdPacket.command,2,3,4,5,6); logMsg("status =%08X\r\n", i2cCmdPacket.status,2,3,4,5,6); logMsg("memory address =%08X\r\n", i2cCmdPacket.memoryAddress,2,3,4,5,6); logMsg("block number =%08X\r\n", i2cCmdPacket.blockNumber,2,3,4,5,6); logMsg("number of blocks =%08X\r\n", i2cCmdPacket.nBlocks,2,3,4,5,6); logMsg("expected count =%08X\r\n", i2cCmdPacket.eCount,2,3,4,5,6); logMsg("actual count =%08X\r\n", i2cCmdPacket.aCount,2,3,4,5,6);#endif /* Return the appropriate status. */ if ( i2cCmdPacket.status != 0 ) { logMsg("i2cCmdPacket.status - 0x%x\n",i2cCmdPacket.status,2,3,4,5,6); localStatus = ERROR ; } else localStatus = OK ; 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.** ERRNO*/int i2cWrite ( int unit, UINT32 deviceAddress, /* Device's I2C bus address */ int deviceType, 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 to see if the driver's been installed */ if(pI2cDrvCtrl[unit]->baseAdrs == 0) { logMsg("I2C driver for unit %d not initialized.\n", unit,2,3,4,5,6); return ERROR ; } /* 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; i2cCmdPacket.deviceType = deviceType ; /* Take ownership, call driver, release ownership. */ localStatus = i2cDoOp(unit, deviceAddress, (i2cCmdPckt_t *)&i2cCmdPacket);#ifdef I2C_DRIVER_DEBUG logMsg("command =%08X\r\n", i2cCmdPacket.command,2,3,4,5,6); logMsg("status =%08X\r\n", i2cCmdPacket.status,2,3,4,5,6); logMsg("memory address =%08X\r\n", i2cCmdPacket.memoryAddress,2,3,4,5,6); logMsg("block number =%08X\r\n", i2cCmdPacket.blockNumber,2,3,4,5,6); logMsg("number of blocks =%08X\r\n", i2cCmdPacket.nBlocks,2,3,4,5,6); logMsg("expected count =%08X\r\n", i2cCmdPacket.eCount,2,3,4,5,6); logMsg("actual count =%08X\r\n", i2cCmdPacket.aCount,2,3,4,5,6);#endif /* Return the appropriate status. */ if ( i2cCmdPacket.status != 0 ) { logMsg("i2cCmdPacket.status - 0x%x\n",i2cCmdPacket.status,2,3,4,5,6); localStatus = ERROR ; } else localStatus = OK ; return localStatus ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -