📄 i2c8260.c
字号:
/* i2c8260.c - I2C bus interface for PPC 8260 */
/*
modification history
--------------------
01a,05dec01,gev written
*/
/*
DESCRIPTION
This module implements the I2c bus access functions for PPC 8260.
*/
/* includes */
#include "vxWorks.h" /* types */
#include "intLib.h"
#include "config.h" /* mbx860 BSP definitions */
#include "vxLib.h"
#include "m8260cp.h"
#include "i2c8260.h" /* I2C I/O definitions */
#define PPC8260_DPR_I2C(dprbase) ((VINT16 *) ((dprbase) + 0x8AFC))
#define IO_SYNC __asm__(" sync") /* Macro for I/O operations to use */
LOCAL I2C_PARAM *pI2C;
LOCAL UCHAR *txbuf1,*txbuf2;;
LOCAL UCHAR *rxbuf;
LOCAL I2C_DESC *rxbd; /* Pointer to BD area of DPRAM */
LOCAL I2C_DESC *txbd1; /* Pointer to BD area of DPRAM */
LOCAL I2C_DESC *txbd2; /* Pointer to BD area of DPRAM */
/******************************************************************************
* I2CrCmd - execute an I2C related CP command
*
* This component's purpose is to execute the command
* passed. The channel command register is read prior
* to execution to verify that there are no outstanding
* commands, this is done by waiting for a zero status.
* The channel command register is also read after the command
* execution to insure command completion prior to returning.
*
* RETURNS: N/A
*/
LOCAL void I2CrCmd(UINT32 immrVal,UINT32 cmd)
{
volatile UINT32 cpcrVal;
int intLevel;
intLevel = intLock(); /* we cannot be interrupted during this */
/* we wouldn't need to do this first wait if we knew
that all other code that issues CP commands waited
for CP commands to complete *after* issuance.
Since we don't know that, we must wait.
*/
/* wait for any pending CP commands to complete */
while(*M8260_CPCR(immrVal) & M8260_CPCR_FLG)
;
/* issue the command to the CP */
cpcrVal = (M8260_CPCR_OP((UINT8)cmd)
| M8260_CPCR_SBC(M8260_CPCR_SBC_I2C)
| M8260_CPCR_PAGE(M8260_CPCR_PAGE_I2C)
| M8260_CPCR_MCN(0)
| M8260_CPCR_FLG);
/* issue command */
*M8260_CPCR(immrVal) = cpcrVal;
IO_SYNC;
/* wait for issued command to complete */
while(*M8260_CPCR(immrVal) & M8260_CPCR_FLG)
;
intUnlock(intLevel);
}
LOCAL STATUS sysI2CInit(void)
{
UINT32 immrVal;
immrVal = vxImmrGet();
pI2C = (I2C_PARAM*)sys82xxDpramAlignedMalloc(sizeof(I2C_PARAM),64);
*PPC8260_DPR_I2C(immrVal) = (UINT16)((UINT32)pI2C);
*I2MOD(immrVal) = DISABLE_I2C; /* Disable I2C before initializing it */
*M8260_IOP_PDPAR(immrVal) |= (PD14 | PD15);
*M8260_IOP_PDDIR(immrVal) &= ~(PD14 | PD15);
*M8260_IOP_PDSO(immrVal) |= (PD14 | PD15);
*M8260_IOP_PDODR(immrVal) |= (PD14 | PD15);
/* I2C Parameter RAM */
pI2C->rfcr = 0x10;
pI2C->tfcr = 0x10;
pI2C->mrblr = I2C_BUFF_MAX_LEN;
#if 1
txbuf1 = sys82xxDpramAlignedMalloc(8 * I2C_BUFF_MAX_LEN,16);
#else
txbuf1 = cacheDmaMalloc(8 * I2C_BUFF_MAX_LEN);
#endif
txbuf2 = txbuf1 + I2C_BUFF_MAX_LEN;
rxbuf = txbuf2 + I2C_BUFF_MAX_LEN;
rxbd = (I2C_DESC*)sys82xxDpramAlignedMalloc(2 * sizeof(I2C_DESC),8);
txbd1 = (I2C_DESC*)sys82xxDpramAlignedMalloc(2 * sizeof(I2C_DESC),8);
txbd2 = txbd1 + 1;
pI2C->rbase = (UINT16)((UINT32)rxbd);
pI2C->tbase = (UINT16)((UINT32)txbd1);
I2CrCmd(immrVal,M8260_CPCR_RT_INIT); /* Init rx and tx */
/* I2C Registers */
*I2ADD(immrVal) = 0x00; /* Slave address */
*I2BRG(immrVal) = 0xff /* BRGCLK */; /* Arbitrary choice of baud rate: BRGCLK/32 */
*I2CER(immrVal) = CLEAR_I2C_EVENTS; /* Clear out I2C events */
*I2CMR(immrVal) = DISABLE_INTERRUPT_I2C; /* Disable interrupts from I2C */
*I2MOD(immrVal) = ENABLE_I2C;
return OK;
}
LOCAL BOOL i2cPollReadDone(UINT32 immrVal)
{
UCHAR event,evdone;
int timeleft;
timeleft = 120;
evdone = (I2C_EV_TXB|I2C_EV_RXB);
do{
event = *I2CER(immrVal);
if(event & (I2C_EV_TXE /* |I2C_EV_BUSY */ )){
taskDelay(2);
break;
}
if((event & evdone) == evdone){
break;
}
taskDelay(1);
}while(--timeleft > 0);
*I2CER(immrVal) = event;
return (event & evdone) == evdone;
}
LOCAL BOOL i2cPollWriteDone(UINT32 immrVal)
{
UCHAR event,evdone;
int timeleft;
timeleft = 120;
evdone = (I2C_EV_TXB);
do{
event = *I2CER(immrVal);
if(event & (I2C_EV_TXE /* |I2C_EV_BUSY */ )){
taskDelay(2);
break;
}
if((event & evdone) == evdone){
break;
}
taskDelay(1);
}while(--timeleft > 0);
taskDelay(1);
*I2CER(immrVal) = event;
return (event & evdone) == evdone;
}
int i2cReadEEprom(UCHAR devI2CAdr, UCHAR Address, int len, UCHAR *pdata)
{
UINT32 immrVal = vxImmrGet();
int thisLen,totaLen = 0;
if(!len) return len;
do{
thisLen = (len > I2C_BUFF_MAX_LEN) ? I2C_BUFF_MAX_LEN /* -1 */ : len /* -1 */;
txbuf1[0] = (char)devI2CAdr; /* Slave address w/o read bit */
txbuf1[1] = (char)Address;
txbuf2[0] = (char)(devI2CAdr|R_BIT); /* Slave address with read bit */
txbd1->length = 2; /* 1 byte slave addr + addr */
txbd1->data = (char*)txbuf1;
txbd1->status = (READY_BIT | TRANSMIT_START_BIT);
txbd2->length = thisLen+1; /* 1 byte slave addr + len bytes data */
txbd2->data = (char*)txbuf2;
txbd2->status = (READY_BIT | LAST_BIT | WRAP_BIT | TRANSMIT_START_BIT | INT_BIT);
rxbd->length = 0; /* reset */
rxbd->data = (char*)rxbuf; /* point RX BD to first RX buffer address */
rxbd->status = (READY_BIT | WRAP_BIT | INT_BIT);
/* Set master mode and issue start */
IO_SYNC;
*I2COM(immrVal) = (MASTER_MODE | START_BIT);
IO_SYNC;
if(i2cPollReadDone(immrVal)){
thisLen = rxbd->length;
memcpy(pdata,rxbd->data,thisLen);
len -= thisLen;
pdata += thisLen;
totaLen += thisLen;
Address += thisLen;
}else{
len = -1;
}
}while(len > 0);
return totaLen;
}
int i2cReadAT24C02(UCHAR devI2CAdr, UCHAR Address, int len, UCHAR *pdata)
{
return i2cReadEEprom(devI2CAdr, Address, len, pdata);
}
int i2cWriteAT24C02(UCHAR devI2CAdr, UCHAR Address, int len, UCHAR *pdata)
{
UINT32 immrVal = vxImmrGet();
int x;
if (!len) return 0;
for (x=0; x<len; x++)
{
txbuf1[0] = (char)devI2CAdr; /* Slave address w/o read bit */
txbuf1[1] = (char)Address+x;
txbuf1[2] = (char)pdata[x];
txbd1->length = 3; /* 1 byte slave addr + addr + data */
txbd1->data = (char*)(&txbuf1[0]);
txbd1->status = (READY_BIT | LAST_BIT | WRAP_BIT |
TRANSMIT_START_BIT | INT_BIT);
/* Set master mode and issue start */
IO_SYNC;
*I2COM(immrVal) = (MASTER_MODE | START_BIT);
IO_SYNC;
if( ! i2cPollWriteDone(immrVal))
{
return -1 * x;
}
}
return x;
}
int i2cReadTemp(UCHAR devI2CAdr,UCHAR Address,UCHAR *pdata)
{
UINT32 immrVal = vxImmrGet();
txbuf1[0] = (char)devI2CAdr; /* Slave address w/o read bit */
txbuf1[1] = (char)Address; /* only 2 bits have meaning */
txbuf2[0] = (char)(devI2CAdr|R_BIT); /* Slave address with read bit */
txbd1->length = 2; /* 1 byte slave addr + addr */
txbd1->data = (char*)txbuf1;
txbd1->status = (READY_BIT | TRANSMIT_START_BIT);
txbd2->length = 3; /* 1 byte slave addr + 2 bytes data */
txbd2->data = (char*)txbuf2;
txbd2->status = (READY_BIT | LAST_BIT | WRAP_BIT | TRANSMIT_START_BIT | INT_BIT);
rxbd->length = 0; /* reset */
rxbd->data = (char*)rxbuf; /* point RX BD to first RX buffer address */
rxbd->status = (READY_BIT | WRAP_BIT | INT_BIT);
/* Set master mode and issue start */
*I2COM(immrVal) = (MASTER_MODE | START_BIT);
if(i2cPollReadDone(immrVal)){
memcpy(pdata,rxbd->data,2);
return 2;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -