⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppc860i2c.c

📁 该程序包括 1)mpc860的IIC总线驱动源代码; 2)mpc860 IIC总线下温度芯片DS1624的驱动源代码 3)mpc860 IIC总线下EEPROM芯片AT24C64的驱动源代码
💻 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 + -