📄 ppc860i2c.c
字号:
#include "ppc860I2C.h"
#include "ppc860siu.h"
#include "cachelib.h"
#define PB27 (0x00010)
#define PB26 (0x00020)
_UCHAR8 I2C_printf_switch;
unsigned char pI2CRxBuffer[I2C_MAX_BUF_LEN];
unsigned char pI2CTxBuffer[I2C_MAX_BUF_LEN];
extern _INT32 vxImmrGet (_VOID);
/*****************************************************************************
*初始化I2C:
波特率设为8.9k;主模式;
RAM PARAM的设置;收2400,发2420;
R/T BD的设置,只有一个表;
开工
******************************************************************************/
_VOID ppc860I2C_Init()
{
_INT32 immrVal;
immrVal = vxImmrGet();
I2C_printf_switch = TRUE;
/*PB27 SDA PB26 SCL*/
* PBPAR(immrVal) |= PB27|PB26;
* PBDIR(immrVal) |= PB27|PB26;
* PBODR(immrVal) |= (PB27|PB26);
/*Init Param ram*/
M860_I2C_16_WR( immrVal + I2C_PARAM_OFFSET+ I2C_PARAM_RBASE,M860_I2C_BD_RBASE);
M860_I2C_16_WR( immrVal + I2C_PARAM_OFFSET+ I2C_PARAM_TBASE,M860_I2C_BD_TBASE);
M860_I2C_8_WR ( immrVal + I2C_PARAM_OFFSET + I2C_PARAM_RFCR, 0x10);
M860_I2C_8_WR ( immrVal + I2C_PARAM_OFFSET + I2C_PARAM_TFCR, 0x10);
M860_I2C_16_WR( immrVal + I2C_PARAM_OFFSET + I2C_PARAM_MRBLR,I2C_MAX_BUF_LEN);
/*Init TxBD and RxBD */
M860_I2C_32_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_ADDR_OFF, pI2CRxBuffer); /*data*/
M860_I2C_32_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_ADDR_OFF, pI2CTxBuffer);
/* RESET ALL REGISTERS */
*I2MOD(immrVal) &= 0x00;
*I2ADD(immrVal) &= 0x00;
*I2BRG(immrVal) &= 0x00;
*I2CER(immrVal) |= 0xFF;
*I2CMR(immrVal) &= 0x00;
*CPCR(immrVal) &= 0x0000;
*I2COM(immrVal) &= 0x00;
/*初始化I2C*/
/*初始化I2C*/
*I2MOD(immrVal) |= 0x00; /*Disable I2C before init it*/
*I2MOD(immrVal) |= 0x01; /*enable I2C*/
*I2ADD(immrVal) |= 0x0e; /*slave addr*/
*I2BRG(immrVal) |= 0x4f; /*brg/4/56=223k*/
*I2CER(immrVal) |= 0x17;
*I2CMR(immrVal) |= 0x00;
*CPCR(immrVal) |= 0x0011; /* ISSUE COMMAND */
}
/**********************************************
I2C的发送函数。
参数: _UCHAR8 *buffer:
_USHORT16 length:
***********************************************/
_ULONG32 I2CSend( _UCHAR8 *buffer, _USHORT16 length )
{
_UCHAR8 ucEvent;
_ULONG32 i,j;
_INT32 immrVal;
_USHORT16 uwLen;
immrVal = vxImmrGet();
M860_I2C_16_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_LEN_OFF, length);
if(length > I2C_MAX_BUF_LEN)
{
I2C_PRINTF("I2C 传输最大值为%d",I2C_MAX_BUF_LEN);
return OS_ERROR;
}
else
{
memcpy( (char *)pI2CTxBuffer, buffer, length);
cacheFlush(DATA_CACHE,pI2CTxBuffer,length);
M860_I2C_16_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_STAT_OFF, 0xac00);/*ready wrapand last*/
M860_I2C_16_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_LEN_OFF, 0);
M860_I2C_32_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_ADDR_OFF, pI2CRxBuffer);
M860_I2C_16_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_STAT_OFF, 0xb000);
}
for(i=0;i<length;i++)
{
I2C_PRINTF("\r\nI2C: Send out %x",pI2CTxBuffer[i]);
}
I2C_PRINTF("\r\nI2C:total send out %d bytes.",length);
/* 启动发送机制 */
*I2COM(immrVal) |= 0x81; /*I2COM_STR;*/
taskDelay(10);
for(i = 0; i<0xff; i++)
{
ucEvent = *I2CER(immrVal);
if(ucEvent&0x10)
{
I2C_PRINTF("\r\n I2C Transmision Error!");
*I2CER(immrVal) |= 0xff;
return OS_ERROR;
}
if(ucEvent&0x04)
{
for(j=0;j<0xff;j++)
;
I2C_PRINTF("\r\n I2C Busy !");
*I2CER(immrVal) |= 0xff;
if(i==(0xff-1))
{
I2C_PRINTF("\r\n I2C Busy Error!!!");
*I2CER(immrVal) |= 0xff;
return OS_ERROR;
}
continue;
}
if(ucEvent& 0x02)
{
M860_I2C_16_RD( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_LEN_OFF, uwLen);
if(length != uwLen)
{
continue;
}
return OS_OK;
}
}
return OS_ERROR;
}
/*************************************************
当需要产生两个start的时候,调用此函数
**************************************************/
_ULONG32 I2CSendStartTwice( _UCHAR8 *ucFirstBuf,_UCHAR8 uclength1, _UCHAR8 *ucSecondBuf,_UCHAR8 uclength2)
{
_UCHAR8 ucEvent;
_ULONG32 i,j;
_USHORT16 uwLen;
_INT32 immrVal;
immrVal = vxImmrGet();
if(((uclength1+2) > I2C_MAX_BUF_LEN)||((uclength2+1) > I2C_MAX_BUF_LEN))
{
I2C_PRINTF("I2C 传输最大值为%d",I2C_MAX_BUF_LEN);
return OS_ERROR;
}
else
{
/*第一个bd存放第一个buffer。要求不产生stop,*/
M860_I2C_16_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_LEN_OFF, uclength1);
M860_I2C_32_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_ADDR_OFF, (&ucFirstBuf[0]));
M860_I2C_16_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_STAT_OFF, 0x8400);/*ready not_ wrap and not_ last*/
M860_I2C_16_WR( immrVal + M860_I2C_BD_TBASE + 0x08 + M860_I2C_BD_LEN_OFF, uclength2);
M860_I2C_32_WR( immrVal + M860_I2C_BD_TBASE + 0x08 + M860_I2C_BD_ADDR_OFF, (&ucSecondBuf[0]));
M860_I2C_16_WR( immrVal + M860_I2C_BD_TBASE + 0x08 + M860_I2C_BD_STAT_OFF, 0xac00);/*ready wrap and last*/
M860_I2C_16_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_LEN_OFF, 0);
M860_I2C_32_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_ADDR_OFF, pI2CRxBuffer);
M860_I2C_16_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_STAT_OFF, 0xb000);
}
for(i=0;i<uclength1;i++)
{
I2C_PRINTF("\r\nI2C: Send out %x",ucFirstBuf[i]);
}
I2C_PRINTF("\r\nI2C: Send out %x",ucSecondBuf[0]);
I2C_PRINTF("\r\nI2C:total send out %x bytes.",(uclength1+1));
*I2COM(immrVal) = 0x81;
taskDelay(10);
for(i = 0; i<0xff; i++)
{
ucEvent = *I2CER(immrVal);
if(ucEvent&0x10)
{
I2C_PRINTF("\r\n I2C Transmision Error!");
*I2CER(immrVal) |= 0xff;
return OS_ERROR;
}
if(ucEvent&0x04)
{
for(j=0;j<0xff;j++)
;
I2C_PRINTF("\r\n I2C Busy !");
*I2CER(immrVal) |= 0xff;
if(i==(0xff-1))
{
I2C_PRINTF("\r\n I2C Busy Error!!!");
*I2CER(immrVal) |= 0xff;
return OS_ERROR;
}
continue;
}
if(ucEvent& 0x02)
{
M860_I2C_16_RD( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_LEN_OFF, uwLen);
if(uclength2 != uwLen)
{
continue;
}
return OS_OK;
}
}
return OS_ERROR;
}
_ULONG32 I2CReceive(_UCHAR8 *buffer, _USHORT16 *length)
{
_INT32 immrVal;
_UCHAR8 i;
immrVal = vxImmrGet();
M860_I2C_16_RD( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_LEN_OFF, (*length) );
if((*length) > I2C_MAX_BUF_LEN)
return OS_ERROR;
cacheInvalidate( DATA_CACHE,pI2CRxBuffer,(*length) );
for(i=0;i<(*length);i++)
{
I2C_PRINTF("\r\nI2C:Recv %x",pI2CRxBuffer[i]);
}
I2C_PRINTF("\r\nI2C:Recv Total :%x bytes",(*length));
memcpy((_CHAR8 *)buffer, (_UCHAR8 *)pI2CRxBuffer, (*length));
return OS_OK;
}
#if 1
/*************************
*以下为自环测试函数
**************************/
_VOID I2();
_VOID StartAndRecv();
_VOID TestI2()
{
I2();
StartAndRecv();
return ;
}
_VOID I2()
{
_INT32 immrVal;
_UCHAR8 *TxBuf;
immrVal = vxImmrGet();
/*PB27 SDA PB26 SCL*/
* PBPAR(immrVal) |= PB27|PB26;
* PBDIR(immrVal) |= PB27|PB26;
* PBODR(immrVal) |= (PB27|PB26);
/*Init Param ram*/
M860_I2C_16_WR( immrVal + I2C_PARAM_OFFSET+ I2C_PARAM_RBASE,M860_I2C_BD_RBASE);
M860_I2C_16_WR( immrVal + I2C_PARAM_OFFSET + I2C_PARAM_TBASE,M860_I2C_BD_TBASE);
M860_I2C_8_WR ( immrVal + I2C_PARAM_OFFSET + I2C_PARAM_RFCR, 0x10);
M860_I2C_8_WR ( immrVal + I2C_PARAM_OFFSET + I2C_PARAM_TFCR, 0x10);
M860_I2C_16_WR ( immrVal + I2C_PARAM_OFFSET + I2C_PARAM_MRBLR,I2C_MAX_BUF_LEN);
/*初始化I2C*/
*I2MOD(immrVal) = 0; /*BRG/32 BIT[5:6]=00*/
*I2ADD(immrVal) = 0x0e; /*0000 1110*/
*I2BRG(immrVal) = 0x4f; /*50M/32/164 = 9.5kHz*/
*I2CER(immrVal) = 0x17;
*I2CMR(immrVal) = 0x00;
*I2MOD(immrVal) = 0x01; /*enable i2c mode*/
/*Init TxBD and RxBD */
M860_I2C_16_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_LEN_OFF, 0); /*data length*/
M860_I2C_32_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_ADDR_OFF,pI2CRxBuffer); /*data*/
M860_I2C_16_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_STAT_OFF, 0xb000); /*ready and wrap*/
M860_I2C_16_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_LEN_OFF, 0x003);
M860_I2C_32_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_ADDR_OFF, pI2CTxBuffer);
TxBuf = pI2CTxBuffer;
TxBuf[0] = 0x9a;
TxBuf[1] = 0xac;
TxBuf[2] = 0x0;
M860_I2C_16_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_STAT_OFF, 0xac00);
while( (*CPCR(immrVal))& (0x0001) ); /* SPIN UNTIL READY TO ISSUE COMMAND */
*CPCR(immrVal)= (0x0011); /* ISSUE COMMAND */
while( (*CPCR(immrVal))& (0x0001) ); /* SPIN UNTIL COMMAND PROCESSED */
}
_VOID StartAndRecv()
{
_UCHAR8 ucEvent;
_ULONG32 i,j;
_INT32 immrVal;
_USHORT16 uwLen;
_USHORT16 *wTemp;
_USHORT16 length;
immrVal = vxImmrGet();
*I2COM( immrVal ) = 0x81;
taskDelay(10);
M860_I2C_16_RD( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_LEN_OFF, length );
wTemp=(_USHORT16 *)(immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_STAT_OFF);
I2C_PRINTF("\r\nThe TBASE state is %x ", *wTemp );
wTemp=(_USHORT16 *)(immrVal + 0x0870);
I2C_PRINTF("\r\nI2CER is %x ", *wTemp );
wTemp=(_USHORT16 *)(immrVal + 0x0874 );
I2C_PRINTF("\r\nI2CMR is %x ", *wTemp );
I2C_PRINTF( "\r\nI2C:Recvbuffer get %x %x %x..... total : %x\n",pI2CRxBuffer[0],pI2CRxBuffer[1],pI2CRxBuffer[2],length);
for(i = 0; i<0xff; i++)
{
ucEvent = *I2CER(immrVal);
if(ucEvent&0x10)
{
I2C_PRINTF("\r\n I2C Transmision Error!");
*I2CER(immrVal) = 0xff;
return ;
}
if(ucEvent&0x04)
{
for(j=0;j<0xff;j++)
;
I2C_PRINTF("\r\n I2C Busy !");
*I2CER(immrVal) = 0xff;
if(i==(0xff-1))
{
I2C_PRINTF("\r\n I2C Busy Error!!!");
*I2CER(immrVal) = 0xff;
return ;
}
continue;
}
if(ucEvent& 0x02)
{
M860_I2C_16_RD( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_LEN_OFF, uwLen);
if(2 != uwLen)
{
continue;
}
return ;
}
}
return ;
}
#endif
#if 0/*use microcode*/
_VOID ppc860I2C_Init()
{
_INT32 immrVal;
immrVal = vxImmrGet();
M860_I2C_16_WR( immrVal + I2C_PARAM_OFFSET + 0x2c,I2C_RELOCAT_OFFSET);
/*PB27 SDA PB26 SCL*/
* PBPAR(immrVal) |= PB27|PB26;
* PBDIR(immrVal) |= PB27|PB26;
* PBODR(immrVal) &= ~(PB27|PB26);
/*Init Param ram*/
M860_I2C_16_WR( immrVal + I2C_NEW_BASE_ADRS+ I2C_PARAM_RBASE,M860_I2C_BD_RBASE);
M860_I2C_16_WR( immrVal + I2C_NEW_BASE_ADRS + I2C_PARAM_TBASE,M860_I2C_BD_TBASE);
M860_I2C_8_WR ( immrVal + I2C_NEW_BASE_ADRS + I2C_PARAM_RFCR, 0x10);
M860_I2C_8_WR ( immrVal + I2C_NEW_BASE_ADRS + I2C_PARAM_TFCR, 0x10);
M860_I2C_16_WR( immrVal + I2C_NEW_BASE_ADRS + I2C_PARAM_MRBLR,I2C_MAX_BUF_LEN);
/*for i2c microcode initial*/
M860_I2C_32_WR( immrVal + I2C_NEW_BASE_ADRS + I2C_PARAM_RSTATE, 0);
M860_I2C_16_WR( immrVal + I2C_NEW_BASE_ADRS + I2C_PARAM_RBPTR, M860_I2C_BD_RBASE);
M860_I2C_32_WR( immrVal + I2C_NEW_BASE_ADRS + I2C_PARAM_TSTATE, 0);
M860_I2C_16_WR( immrVal + I2C_NEW_BASE_ADRS + I2C_PARAM_TBPTR, M860_I2C_BD_TBASE);
/*Init TxBD and RxBD */
M860_I2C_16_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_STAT_OFF, 0x2000); /*状态字*/
M860_I2C_16_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_LEN_OFF, 0); /*data length*/
M860_I2C_32_WR( immrVal + M860_I2C_BD_RBASE + M860_I2C_BD_ADDR_OFF, pI2CRxBuffer); /*data*/
M860_I2C_16_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_STAT_OFF, 0x2800);
M860_I2C_16_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_LEN_OFF, 0);
M860_I2C_32_WR( immrVal + M860_I2C_BD_TBASE + M860_I2C_BD_ADDR_OFF, pI2CTxBuffer);
/*初始化I2C*/
/*初始化I2C*/
*I2MOD(immrVal) = 0x0; /*Disable I2C before init it*/
*I2ADD(immrVal) = 0x80;
*I2BRG(immrVal) = 0x20; /*brg/32/70=22k*/
*I2CER(immrVal) = 0x17;
*I2CMR(immrVal) = 0x00;
*I2MOD(immrVal) = 0x01; /*enable I2C*/
*CPCR(immrVal) = 0x0011; /* ISSUE COMMAND */
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -