📄 sysi2cmpc107.c
字号:
/* sysI2cMpc107.c - I2C Driver Source Module *//* Copyright 1998-2001 Motorola, Inc. All Rights Reserved *//*modification history--------------------01c,12jan01,djs make the variable I2CDoRepeatStart not a global01b,08dec00,djs changed kahlua names to MPC10701a,02nov00,djs created from 01e,14apr00,krp*//*DESCRIPTIONI2C Driver Source (Low Level Routines) ModuleMpc107 Memory Controller (PowerChap Architecture)Notes: 1. GREAT care must be made when sending commands to the Mpc107. Several "i2cCycleMpc107Delay" calls are made in order to not overwhelm the I2C interface. If commands are sent too fast, the I2C interface will lockup and the I2C bus may become unusable without a powercycle. Generally, if if you cause a I2C bus cycle, you should wait for "a while". A possible cause is that the caches were turned on when this driver was written.*//* includes */#include "vxWorks.h" /* vxWorks generics */#include "sysI2cMpc107.h" /* low level definitions, specific */#include "config.h" /* BSP specifics */#include "mpc107.h"#ifdef DEBUG_I2C# include "sdramSpd.h"# include "stdio.h"#endif/* globals *//* If the BSP is using the cache as its initial stack during startup DONOT use global variables. The memory controller may be turned off and the only memory available is the stack.*//* externals */IMPORT int i2cRead(); /* device read operation */IMPORT int i2cWrite(); /* device write operation */#ifdef DEBUG_I2CIMPORT logMsg ();#endifIMPORT UINT32 i2cPciIoctl (UINT32 ioctlflg, UINT32 address, UINT32, UINT32);IMPORT UINT32 abs(UINT32 old);IMPORT STATUS i2cDrvInit (int i2cControllerType);/* forward declarations */void sysMpc107MsDelay (UINT mSeconds);LOCAL UINT32 sysMpc107GetDec(void);void i2cCycleMpc107Delay (int mSeconds);/* debug declarations */#ifdef DEBUG_I2C#define REAL_SPD_SIZE 256char defaultSPD[SPD_SIZE];#endif /* DEBUG_I2C *//******************************************************************************* * i2cCycleMpc107Start - perform I2C "start" cycle* * This function's purpose is to perform an I2C start cycle.* * RETURNS:* zero = operation successful* non-zero = operation failed*/int i2cCycleMpc107Start ( unsigned char * I2CDoRepeatStart ) { unsigned int timeOutCount; unsigned int statusReg = 0; /* * if this is a repeat start, then set the required bits and return. * * NOTE: * this driver ONLY supports one repeat start between the start * stop and cycles. */ if(*I2CDoRepeatStart == TRUE) { i2cCycleMpc107Delay(1); i2cPciIoctl(2, (UINT32)MPC107_I2C_CONTROL_REG, (MPC107_I2C_CONTROL_REG_RSTA | MPC107_I2C_CONTROL_REG_MSTA | MPC107_I2C_CONTROL_REG_MTX),0); SYNC; i2cCycleMpc107Delay(1); *I2CDoRepeatStart = FALSE; return(0); } /* * 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--) { i2cCycleMpc107Delay(1); statusReg = i2cPciIoctl(1, (UINT32)MPC107_I2C_STATUS_REG, 0, 0); SYNC; if (!(statusReg & MPC107_I2C_STATUS_REG_MBB)) { break; } } if (!timeOutCount) { return (-1); } /* * since this is the first time through, generate a START(MSTA) and * place the I2C interface into a master transmitter mode(MTX). */ i2cPciIoctl(2, (UINT32)MPC107_I2C_CONTROL_REG, (MPC107_I2C_CONTROL_REG_MTX | MPC107_I2C_CONTROL_REG_MSTA),0); SYNC; i2cCycleMpc107Delay(1); /* * The first time through, set "I2CDoRepeatStart". If this function * is called again BEFORE a STOP is sent, then we are doing a * "dummy write", which sets the devices internal byte pointer * to the byte we intend to read. */ *I2CDoRepeatStart = TRUE; return (0); }/******************************************************************************* * i2cCycleMpc107Stop - perform I2C "stop" cycle* * This function's purpose is to perform an I2C stop cycle.* * RETURNS:* zero = operation successful* non-zero = operation failed*/int i2cCycleMpc107Stop ( unsigned char * I2CDoRepeatStart ) { i2cCycleMpc107Delay(1); /* * turn off MSTA bit(which will generate a STOP bus cycle) * turn off MTX bit(which places the MPC8240 interface into receive mode * turn off TXAK bit(which allows 9th clock cycle acknowledges) */ i2cPciIoctl(3, (UINT32)MPC107_I2C_CONTROL_REG, (~(MPC107_I2C_CONTROL_REG_MTX | MPC107_I2C_CONTROL_REG_MSTA | MPC107_I2C_CONTROL_REG_TXAK)),0); SYNC; i2cCycleMpc107Delay(1); /* * Clear the global I2C "Repeat Start" flag. */ *I2CDoRepeatStart = FALSE; return (0); }/******************************************************************************* * i2cCycleMpc107Read - perform I2C "read" cycle* * This function's purpose is to perform an I2C read cycle.* * RETURNS:* zero = operation successful* non-zero = operation failed*/int i2cCycleMpc107Read ( unsigned char *pReadDataBuf /* pointer to read data buffer */ ) { unsigned int readData = 0; i2cCycleMpc107Delay(1); /* * place 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. */ i2cPciIoctl(4, (UINT32)MPC107_I2C_CONTROL_REG, (~MPC107_I2C_CONTROL_REG_MTX), MPC107_I2C_CONTROL_REG_TXAK); SYNC; i2cCycleMpc107Delay(1); /* do a "dummy read". this latches the data off the bus. */ i2cPciIoctl(1, (UINT32)MPC107_I2C_DATA_REG, 0, 0); SYNC; i2cCycleMpc107Delay(1); /* now do the actual read, make this one count */ readData = i2cPciIoctl(1, (UINT32)MPC107_I2C_DATA_REG, 0, 0); SYNC; *pReadDataBuf = (unsigned char)readData; return (0); }/******************************************************************************* * i2cCycleMpc107Write - perform I2C "write" cycle* * This function's purpose is to perform an I2C write cycle.* * RETURNS:* zero = operation successful* non-zero = operation failed*/int i2cCycleMpc107Write ( unsigned char writeData /* character to write */ ) { i2cCycleMpc107Delay(1); /* * write the requested data to the data register, which will cause * it to be transmitted on the I2C bus. */ i2cPciIoctl(0, (UINT32)MPC107_I2C_DATA_REG, writeData, 0); SYNC; i2cCycleMpc107Delay(1); return (0); }/******************************************************************************* * i2cCycleMpc107AckIn - perform I2C "acknowledge-in" cycle* * This function's purpose is to perform an I2C acknowledge-in* cycle.* * RETURNS:* zero = operation successful* non-zero = operation failed*/int i2cCycleMpc107AckIn (void) { unsigned int statusReg = 0; unsigned int 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--) { i2cCycleMpc107Delay(1); statusReg = i2cPciIoctl(1, (UINT32)MPC107_I2C_STATUS_REG, 0, 0); SYNC; if (statusReg & MPC107_I2C_STATUS_REG_MIF) { i2cPciIoctl(3, (UINT32)MPC107_I2C_STATUS_REG, (~MPC107_I2C_STATUS_REG_MIF), 0); SYNC; break; } } if (!timeOutCount) { return (-1); } return (0); }/******************************************************************************* * i2cCycleMpc107AckOut - perform I2C "acknowledge-out" cycle* * This function's purpose is to perform an I2C acknowledge-out* cycle.* * RETURN:* zero = operation successful* non-zero = operation failed*/int i2cCycleMpc107AckOut (void) { return (0); }/******************************************************************************* * i2cCycleMpc107KnownState - initialize the I2C bus to a known state* * This function's purpose is to initialize the I2C bus to a* known state.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -