📄 sysmoti2c.c
字号:
/* sysMotI2c.c - I2C Driver Source Module *//* Copyright 1984-2005 Wind River Systems, Inc. *//* Copyright 1996-2000 Motorola, Inc. All Rights Reserved *//*modification history--------------------01e,14jun06,dtr Fix freq check.01d,03aug05,dtr Compiler warnings removed.01c,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.*//* 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.*/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: not printf or logMsg statements here because called during sysHwInit().* If output is desired a pollled or debug dump routine should be used.** RETURNS: OK, or ERROR if not prpmc600 board.*/I2C_DRV_CTRL i2C1DrvCtrl ;I2C_DRV_CTRL i2C2DrvCtrl ;I2C_DRV_CTRL * pI2cDrvCtrl[2] = { NULL, NULL } ;STATUS i2cDrvInit ( int unit, int i2cControllerType /* I2C controller type */ ) { UINT8 divider ; UINT32 temp; /* * 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 ; } /* 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/I2C2 - clock = csb_clk / 3. = 111MHz. -> need to get to 100KHz * div by 1024. gives 100+Khz. * */ temp = sysClkFreqGet(); if(temp == 333000000) { divider = 0x7 ; /* 111000000 / 1024 */ } else if(temp == 266000000) { divider = 0x6 ; /* 889000000 / 832 */ } else { divider = 0x7 ; /* 111000000 / 1024 */ } i2cIoctl(I2C_IOCTL_RMW_AND_OR, (UINT32)(pI2cDrvCtrl[unit]->baseAdrs+MPC834X_I2C_FREQ_DIV_REG), ((UINT8)~MPC834X_I2C_FREQ_DIV_REG_MASK), divider); /* set the slave address */ i2cIoctl(I2C_IOCTL_RMW_AND_OR, (UINT32)(pI2cDrvCtrl[unit]->baseAdrs+MPC834X_I2C_ADR_REG), ((UINT8)~MPC834X_I2C_ADDRESS_REG_MASK), 0x7e); /* 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); 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 ( 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.*/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 + -