📄 mpc107i2c.c
字号:
/* mpc107I2c.c - MPC107 I2C support *//* Copyright 1996-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01d,15sep01,dat Use of vxDecGet routine01c,11sep00,rcs fix include paths01b,22jun00,bri updated to WindRiver coding standards.01a,18jun00,bri created - based on Kahlua I2C driver.*//*DESCRIPTIONThis module contains routines for the I2C interface of MPC107.The I2C interface is a two-wire, bidirectional serial bus that providesa simple, efficient way to exchange data between integrated circuit(IC) devices.The I2C interface allows the MPC107 to exchange data with other I 2 C devicessuch as microcontrollers, EEPROMs, real-time clock devices, A/D converters,and LCDs.This module provides the routines for writing/reading data to/fromthe I2C interface with MPC107 as a "master" device .The routine mpc107i2cWrite() is used for writing data to an EEPROM typeslave device .The routine mpc107i2cRead() is used for reading data from an EEPROM typeslave device .Support for other I2C slave devices can be added easily by using theroutines provided in this module .Reading/writing data from/to the I2C interface with MPC107 as a "slave" deviceare not supported in this module .However, additional I2C bus controllers can be easily be added as required..SH INITIALIZATIONThe routine mpc107I2cInit() should be called to initialize theIIC interface.The user has to specify the the following parameters forprogramming the I2C Frequency Divider Register (I2CFDR):.IP DFFSRSpecifies the Digital filter frequency sampling rate of the I2C interface.DFFSR can be changed by changing MPC107_DFFSR_DATA in the header file..IP FDRSpecifies the Frequency divider ratio.FDR can be changed by changingMPC107_FDR_DATA in the header file ..LPThe user has to specify the the following parameters forprogramming the I2C Address Register (I2CADR) :.IP ADDRSpecifies the Slave address used by the I2C interface when MPC107 is configuredas a slave.ADDR can be changed by changing MPC107_ADR_DATA in the header file.LPRefer to MPC107 users manual for further details about the valuesto be programmed in the I2C registers .*//* includes */#include "vxWorks.h"#include "sysLib.h"#include "stdlib.h"#include "drv/multi/mpc107.h"#include "drv/multi/mpc107I2c.h"#include "drv/intrCtl/mpc107Epic.h"/* globals *//* static file scope locals */BOOL i2cDoRepeatStart = FALSE; /* Repeat start *//* forward Declarations */LOCAL INT32 mpc107i2cCycleStart (void);LOCAL void mpc107i2cCycleStop (void);LOCAL void mpc107i2cCycleRead (UCHAR* data);LOCAL void mpc107i2cCycleWrite (UCHAR data);LOCAL INT32 mpc107i2cCycleAckIn (void);LOCAL void mpc107I2cCycleDelay (UINT milliSec);LOCAL UINT32 mpc107GetDec (void);LOCAL UINT32 mpc107I2cRegRdWrMod (UINT32 operation , UINT32 address , UINT32 data1, UINT32 data2);LOCAL VOID mpc107I2cDoOperation (UINT32 deviceAddress, MPC107_I2C_CMD_PCKT * pI2cCmdPacket);/***************************************************************************** mpc107I2cInit - initialize the IIC interface** This routine initializes the IIC Interface.** The "Frequency Divider Register" is initialized depending on* the clock frequency.The slave address is also programmed. The IIC* interface is programmed to be in Master/Receive Mode with interrupts disabled.* After all the initialization is done the IIC interface is enabled.* This routine must be called before the user can use the IIC interface to* read /write data.** RETURNS: N/A*/void mpc107I2cInit (void) { /* Update the frequency divider register */ mpc107I2cRegRdWrMod(MPC107_I2C_WRITE, MPC107_I2C_I2CFDR, MPC107_I2CFDR_DEFAULT, 0); SYNC; /* Update the I2CADR to define the slave address for this device */ mpc107I2cRegRdWrMod(MPC107_I2C_WRITE, MPC107_I2C_I2CADR, MPC107_I2CADR_DEFAULT, 0); SYNC; /* * Update control register to select Master * Receive mode and interrupt-disabled */ mpc107I2cRegRdWrMod(MPC107_I2C_WRITE, MPC107_I2C_I2CCR, MPC107_I2CCR_DEFAULT,0); SYNC; /* Enable the I2C interface */ mpc107I2cRegRdWrMod(MPC107_I2C_READ_OR_WRITE, MPC107_I2C_I2CCR, MPC107_I2CCR_MEN,0); SYNC; }/***************************************************************************** mpc107i2cRead - read from the slave device on IIC bus** This routine reads the specified number of bytes from the specified slave* device with MPC107 as the master .** RETURNS: OK, or Error on a bad request*/INT32 mpc107i2cRead ( UINT32 deviceAddress, /* Device I2C bus address */ UINT32 numBytes, /* number of Bytes to read */ char * pBuf /* pointer to buffer to receive data */ ) { MPC107_I2C_CMD_PCKT i2cCmdPacket; /* command packet */ /* Check for a bad request. */ if (numBytes == 0) { return (ERROR); } /* Build command packet. */ i2cCmdPacket.command = MPC107_I2C_READOP; i2cCmdPacket.status = 0; i2cCmdPacket.memoryAddress = (UINT32)pBuf; i2cCmdPacket.nBytes = numBytes; mpc107I2cDoOperation(deviceAddress, (MPC107_I2C_CMD_PCKT *)&i2cCmdPacket); /* Return the appropriate status. */ return (i2cCmdPacket.status); }/***************************************************************************** mpc107i2cWrite - write to the slave device on IIC bus** This routine is used to write the specified number of* bytes to the specified slave device with MPC 107 as a master** RETURNS: OK, or ERROR on a bad request.*/INT32 mpc107i2cWrite ( UINT32 deviceAddress, /* Devices I2C bus address */ UINT32 numBytes, /* number of bytes to write */ char * pBuf /* pointer to buffer of send data */ ) { MPC107_I2C_CMD_PCKT i2cCmdPacket; /* command packet */ /* Check for a NOP request. */ if (numBytes == 0) { return (ERROR); } /* Build command packet. */ i2cCmdPacket.command = MPC107_I2C_WRITOP; i2cCmdPacket.status = 0; i2cCmdPacket.memoryAddress = (UINT32)pBuf; i2cCmdPacket.nBytes = numBytes; /* Take ownership, call driver, release ownership. */ mpc107I2cDoOperation(deviceAddress, (MPC107_I2C_CMD_PCKT *)&i2cCmdPacket); /* Return the appropriate status. */ return (i2cCmdPacket.status); }/***************************************************************************** mpc107i2cCycleRead - perform I2C "read" cycle** This routine is used to perform a read from the I2C bus .** RETURNS: N/A*/LOCAL void mpc107i2cCycleRead ( UCHAR * pReadDataBuf /* pointer to read data buffer */ ) { UINT32 readData = 0; mpc107I2cCycleDelay (1); /* * Configure the I2C interface into receive mode(MTX=0) and set * the interface to NOT acknowledge(TXAK=1) the incoming data on * the 9th clock cycle. * This is required when doing random reads of a I2C device. */ mpc107I2cRegRdWrMod(MPC107_I2C_READ_ANDOR_WRITE, MPC107_I2C_I2CCR,~(MPC107_I2CCR_MTX), MPC107_I2CCR_TXAK); SYNC; mpc107I2cCycleDelay (1); /* Perform a "dummy read". This latches the data off the I2C bus. */ mpc107I2cRegRdWrMod(MPC107_I2C_READ,MPC107_I2C_I2CDR, 0, 0); SYNC; mpc107I2cCycleDelay (1); /* Perform the actual read */ readData = mpc107I2cRegRdWrMod(MPC107_I2C_READ, MPC107_I2C_I2CDR, 0, 0); SYNC; *pReadDataBuf = (UCHAR)readData; /* copy the read data */ return; }/***************************************************************************** mpc107i2cCycleWrite - perform I2C "write" cycle** This routine is used is to perform a write to the I2C bus.* Data is written to the I2C interface .** RETURNS: N/A*/LOCAL void mpc107i2cCycleWrite ( UCHAR writeData /* character to write */ ) { mpc107I2cCycleDelay (1); /* * Write the requested data to the data register, which will cause * it to be transmitted on the I2C bus. */ mpc107I2cRegRdWrMod(MPC107_I2C_WRITE, MPC107_I2C_I2CDR, writeData, 0); SYNC; mpc107I2cCycleDelay (1); return; }/***************************************************************************** mpc107i2cCycleAckIn - perform I2C "acknowledge-in" cycle** This routine is used to perform an I2C acknowledge-in on the bus.** RETURNS: OK, or ERROR if timed out waiting for an ACK .*/LOCAL STATUS mpc107i2cCycleAckIn (void) { UINT32 statusReg = 0; UINT32 timeOutCount; /* * wait until an *internal* device interrupt has been generated, then * clear it. if it is not received, return with an error. * we are polling, so NO processor interrupt is generated. */ for (timeOutCount = 100; timeOutCount; timeOutCount--) { mpc107I2cCycleDelay (1); statusReg = mpc107I2cRegRdWrMod(MPC107_I2C_READ, MPC107_I2C_I2CSR,0,0); SYNC; if ((statusReg & MPC107_I2CSR_MIF) != 0) { mpc107I2cRegRdWrMod(MPC107_I2C_READ_AND_WRITE, MPC107_I2C_I2CSR,~(MPC107_I2CSR_MIF),0); SYNC; break; } } if (timeOutCount == 0) { return (ERROR); } return (OK); }/***************************************************************************** mpc107i2cCycleStart - perform I2C "start" cycle** This routine is used is to perform an I2C start cycle.** RETURNS: OK, or ERROR if timed out waiting for the IIC bus to be free.*/LOCAL STATUS mpc107i2cCycleStart (void) { UINT32 timeOutCount; UINT32 statusReg = 0; /* * if this is a repeat start, then set the required bits and return. * this driver ONLY supports one repeat start between the start cycle and * stop cycles. */ if(i2cDoRepeatStart) /* If a repeat start */ { mpc107I2cCycleDelay (1); mpc107I2cRegRdWrMod(MPC107_I2C_READ_OR_WRITE, MPC107_I2C_I2CCR, (MPC107_I2CCR_RSTA | MPC107_I2CCR_MSTA | MPC107_I2CCR_MTX),0); SYNC; mpc107I2cCycleDelay (1); i2cDoRepeatStart = FALSE; /* one repeat start only, so clear this */ return(OK); } /* * wait until the I2C bus is free. if it doesn't become free * within a *reasonable* amount of time, exit with an error. */ for (timeOutCount = 10; timeOutCount; timeOutCount--) { mpc107I2cCycleDelay (1); statusReg = mpc107I2cRegRdWrMod(MPC107_I2C_READ, MPC107_I2C_I2CSR, 0, 0); SYNC; if ((statusReg & MPC107_I2CSR_MBB) == 0) { break; } } if (timeOutCount == 0) { return (ERROR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -