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

📄 iic.c

📁 三星s3c2460开发板完整功能测试代码
💻 C
字号:
//====================================================================
// File Name	: 2460IIC.c
// Function	: S3C2460 IIC-bus Master Tx/Rx mode Test Program
//                (Interrupt / Non Interrupt (Polling))
// Date         : Jun , 2003
//====================================================================

#include <string.h>
#include "2460addr.h"
#include "2460lib.h"
#include "option.h"

#define WRDATA      (1)
#define POLLACK     (2)
#define RDDATA      (3)
#define SETRDADDR   (4)

#define IICBUFSIZE 0x20

void Test_Iic(void);
void Test_Iic2(void);
void Wr24C080(unsigned int slvAddr,unsigned int addr,unsigned char data);
void Rd24C080(unsigned int slvAddr,unsigned int addr,unsigned char *data);
void _Wr24C080(unsigned int slvAddr,unsigned int addr,unsigned char data);
void _Rd24C080(unsigned int slvAddr,unsigned int addr,unsigned char *data);

void __irq IicInt(void);
void IicPoll(void);
void Run_IicPoll(void);

static unsigned char _iicData[IICBUFSIZE];
static volatile int _iicDataCount=0;
static volatile int _iicStatus=0;
static volatile int _iicMode=0;
static int _iicPt=0;



//===================================================================
//  "Interrupt mode" for IIC block
//===================================================================

//******************[ Test_Iic ]**************************************

void * func_iic_test[][2]=
{	
    //        				"123456789012345678"
    //Interrupt test
    (void *)Test_Iic,			"IIC by interrupt  ",
    //polling test
    (void *)Test_Iic2,			"IIC by polling    ",
    0,0
};

void Ch13_Iic_Test(void)
{
    int i;
	    
    printf("\nIIC test.\n");

    while(1)
    {
	i=0;
	printf("\n\n");
	while(1)
	{   //display menu
	    printf("%2d:%s",i,func_iic_test[i][1]);
	    i++;
	    if((int)(func_iic_test[i][0])==0)
	    {
		printf("\n");
		break;
	    }
	    if((i%3)==0)
	    printf("\n");
	}

	printf("\nSelect (\"-1\" to exit) : ");
	i = GetIntNum();
	if(i==-1) 
	    break;		// return.
	if(i>=0 && (i<((sizeof(func_iic_test)-1)/8)) )	// select and execute...
	    ( (void (*)(void)) (func_iic_test[i][0]) )();
    }
    printf("\nIIC test end.\n");
}


void Test_Iic(void)
{
    unsigned int i,j;
    static unsigned char data[256];


    printf("[ IIC Test(Interrupt) using KS24C080 ]\n");

    pISR_IIC_SPI = (unsigned)IicInt;
    rSRCPND=BIT_IIC_SPI;
    rSUBSRCPND=BIT_SUB_IIC;
    rINTMSK &= ~(BIT_IIC_SPI);
    rINTSUBMSK &= ~(BIT_SUB_IIC);

    //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
    // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz
    rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);

    rIICADD  = 0x10;                    //2410 slave address = [7:1]
    rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)	
    rIICLC=(1<<2)|(0<<0);    // filter enable, SDA delay: 0:0clk, 1: 5clk, 2: 10clk, 3: 15clk

    printf("Write test data into KS24C080\n");
   

    for(i=0x0;i<256;i++)
        Wr24C080(0xa0,(unsigned char)i,i);	// 7bit address format : address(device addr)+data(word addr)+data
   
    for(i=0x0;i<256;i++)
        data[i] = 0;
     
    printf("Read test data from KS24C080\n");

    for(i=0x0;i<256;i++)
        Rd24C080(0xa0,(unsigned char)i,&(data[i]));    // 7bit address format : address(device addr)+data(word addr)+data
	
        //Line changed 0 ~ f
    for(i=0;i<16;i++)
    {
        for(j=0;j<16;j++)
            printf("%2x ",data[i*16+j]);
        printf("\n");
    }
    rINTSUBMSK |= (BIT_SUB_IIC);
    rINTMSK |= BIT_IIC_SPI;
}


//*************************[ Wr24C080 ]****************************
void Wr24C080(unsigned int slvAddr,unsigned int addr,unsigned char data)
{
    _iicMode      = WRDATA;
    _iicPt        = 0;
    _iicData[0]   = (unsigned char)addr;
    _iicData[1]   = data;
    _iicDataCount = 2;

    rIICDS   = slvAddr;         //0xa0
    rIICSTAT = 0xf0;            //MasTx,Start
    //Clearing the pending bit isn't needed because the pending bit has been cleared.

    while(_iicDataCount!=-1);	// Tx 'addr+addr+data'


	

//    printf("@%d ",_iicDataCount);
    _iicMode = POLLACK;

    while(1)
    {
        rIICDS     = slvAddr;
        _iicStatus = 0x100;
        rIICSTAT   = 0xf0;              //MasTx,Start, NACK flag clear
        rIICCON    = 0xaf;              //Resumes IIC operation. Int pending clear
	
        while(_iicStatus==0x100);
	
        if(!(_iicStatus&0x1))
            break;                      //When ACK is received
    }					//If there is no ACK, repeat Tx(addr).
//    printf("0x%x \n",data);
    rIICSTAT = 0xd0;                    //Stop MasTx condition
    rIICCON  = 0xaf;                    //Resumes IIC operation.
    Delay(1);                           //Wait until stop condtion is in effect.
    //Write is completed.
}

//**********************[ Rd24C080 ] ***********************************
void Rd24C080(unsigned int slvAddr,unsigned int addr,unsigned char *data)
{
    _iicMode      = SETRDADDR;
    _iicPt        = 0;
    _iicData[0]   = (unsigned char)addr;
    _iicDataCount = 1;

    rIICDS   = slvAddr;
    rIICSTAT = 0xf0;                    //MasTx,Start
      //Clearing the pending bit isn't needed because the pending bit has been cleared.
    while(_iicDataCount!=-1);

    _iicMode      = RDDATA;
    _iicPt        = 0;
    _iicDataCount = 1;

    rIICDS        = slvAddr;
    rIICSTAT      = 0xb0;               //MasRx,Start
    rIICCON       = 0xaf;               //Resumes IIC operation.
    while(_iicDataCount!=-1);

    *data = _iicData[1];
//    printf("0x%x \n",*data);
}


//-------------------------------------------------------------------------
void __irq IicInt(void)
{
    unsigned int iicSt,i;

    rINTSUBMSK |= (BIT_SUB_IIC);
    rINTMSK |= BIT_IIC_SPI;
    ClearPending(BIT_IIC_SPI);
    rSUBSRCPND = BIT_SUB_IIC;
    iicSt   = rIICSTAT;

    if(iicSt & 0x8){};           //When bus arbitration is failed.
    if(iicSt & 0x4){};           //When a slave address is matched with IICADD
    if(iicSt & 0x2){};           //When a slave address is 0000000b
    if(iicSt & 0x1){};           //When ACK isn't received

    switch(_iicMode)
    {
       case POLLACK:
           _iicStatus = iicSt;
           break;

       case RDDATA:
//	     printf("[ S%d ]",_iicDataCount);
           if((_iicDataCount--)==0)
           {
               _iicData[_iicPt++] = rIICDS;
		rIICSTAT = 0x90;                 //Stop MasRx condition
       //        rIICSTAT = 0x0;                 //Stop MasRx condition
               rIICCON  = 0xaf;                 //Resumes IIC operation.
               Delay(1);                        //Wait until stop condtion is in effect.
                                                //Too long time...
                                                //The pending bit will not be set after issuing stop condition.
               break;
           }
           _iicData[_iicPt++] = rIICDS;         //The last data has to be read with no ack.
           if((_iicDataCount)==0)
               rIICCON = 0x2f;                  //Resumes IIC operation with NOACK.
           else
               rIICCON = 0xaf;                  //Resumes IIC operation with ACK
               break;

        case WRDATA:
//	     printf("[ S%d ]",_iicDataCount);
            if((_iicDataCount--)==0)
            {
    
                rIICSTAT = 0xd0;                //Stop MasTx condition, ACK flag clear
      //         rIICSTAT = 0x0;                //Stop MasTx condition, ACK flag clear
                rIICCON  = 0xaf;                //Resumes IIC operation.
                Delay(1);                       //Wait until stop condtion is in effect.
                //The pending bit will not be set after issuing stop condition.
     
		 break;
            }
            rIICDS = _iicData[_iicPt++];        //_iicData[0] has dummy.
            for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL
            rIICCON = 0xaf;                     //resumes IIC operation.
            break;

        case SETRDADDR:
//          printf("[ S%d ]",_iicDataCount);
            if((_iicDataCount--)==0)
                break;                          //IIC operation is stopped because of IICCON[4]
            rIICDS = _iicData[_iicPt++];
            for(i=0;i<10;i++);                  //For setup time until rising edge of IICSCL
            rIICCON = 0xaf;                     //Resumes IIC operation.
            break;

        default:
            break;
    }

   
    rINTSUBMSK &= ~(BIT_SUB_IIC);
     rINTMSK &= ~(BIT_IIC_SPI);
}

//===================================================================
//  "Non-Interrupt mode" for IIC block
//===================================================================

//*********************[ Test_Iic2 ]*********************************
void Test_Iic2(void)
{
    unsigned int i,j;
    static unsigned char data[256];

    printf("[ IIC Test(Polling) using KS24C080 ]\n");

    //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
    rIICCON  = (1<<7) | (0<<6) | (1<<5) | (0xf);

    rIICADD  = 0x10;                    //2410 slave address = [7:1]
    rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)

    rIICLC=(1<<2)|(1<<0);    // filter enable, SDA delay: 0:0clk, 1: 5clk, 2: 10clk, 3: 15clk
    printf("Write test data into KS24C080\n");

    for(i=0;i<256;i++)
        _Wr24C080(0xa0,(unsigned char)i,255-i);
    for(i=0;i<256;i++)
        data[i] = 0;

    printf("Read test data from KS24C080\n");
    for(i=0;i<256;i++)
        _Rd24C080(0xa0,(unsigned char)i,&(data[i]));

    for(i=0;i<16;i++)
    {
        for(j=0;j<16;j++)
            printf("%2x ",data[i*16+j]);
        printf("\n");
    }
}

//**************[ _Wr24C080 ]*****************************************
void _Wr24C080(unsigned int slvAddr,unsigned int addr,unsigned char data)
{
    _iicMode      = WRDATA;
    _iicPt        = 0;
    _iicData[0]   = (unsigned char)addr;
    _iicData[1]   = data;
    _iicDataCount = 2;

    rIICDS        = slvAddr;            //0xa0
      //Master Tx mode, Start(Write), IIC-bus data output enable
      //Bus arbitration sucessful, Address as slave status flag Cleared,
      //Address zero status flag cleared, Last received bit is 0
    rIICSTAT      = 0xf0;
      //Clearing the pending bit isn't needed because the pending bit has been cleared.
    while(_iicDataCount!=-1)
       Run_IicPoll();

    _iicMode = POLLACK;

    while(1)
    {
        rIICDS     = slvAddr;
        _iicStatus = 0x100;             //To check if _iicStatus is changed
        rIICSTAT   = 0xf0;              //Master Tx, Start, Output Enable, Sucessful, Cleared, Cleared, 0
        rIICCON    = 0xaf;              //Resumes IIC operation.
        while(_iicStatus==0x100)
            Run_IicPoll();

        if(!(_iicStatus & 0x1))
            break;                      //When ACK is received
    }
    rIICSTAT = 0xd0;                    //Master Tx condition, Stop(Write), Output Enable
    rIICCON  = 0xaf;                    //Resumes IIC operation.
    Delay(1);                           //Wait until stop condtion is in effect.
      //Write is completed.
}

//************************[ _Rd24C080 ]********************************
void _Rd24C080(unsigned int slvAddr,unsigned int addr,unsigned char *data)
{
    _iicMode      = SETRDADDR;
    _iicPt        = 0;
    _iicData[0]   = (unsigned char)addr;
    _iicDataCount = 1;

    rIICDS   = slvAddr;
    rIICSTAT = 0xf0;                    //MasTx,Start
      //Clearing the pending bit isn't needed because the pending bit has been cleared.
    while(_iicDataCount!=-1)
        Run_IicPoll();

    _iicMode      = RDDATA;
    _iicPt        = 0;
    _iicDataCount = 1;

    rIICDS   = slvAddr;
    rIICSTAT = 0xb0;                    //Master Rx,Start
    rIICCON  = 0xaf;                    //Resumes IIC operation.
    while(_iicDataCount!=-1)
        Run_IicPoll();

    *data = _iicData[1];
}

//**********************[ Run_IicPoll ]*********************************
void Run_IicPoll(void)
{
    if(rIICCON & 0x10)                  //Tx/Rx Interrupt Enable
       IicPoll();
}

//**********************[IicPoll ]**************************************
void IicPoll(void)
{
    unsigned int iicSt,i;

    iicSt = rIICSTAT;
    if(iicSt & 0x8){}                   //When bus arbitration is failed.
    if(iicSt & 0x4){}                   //When a slave address is matched with IICADD
    if(iicSt & 0x2){}                   //When a slave address is 0000000b
    if(iicSt & 0x1){}                   //When ACK isn't received

    switch(_iicMode)
    {
        case POLLACK:
            _iicStatus = iicSt;
            break;

        case RDDATA:
            if((_iicDataCount--)==0)
            {
                _iicData[_iicPt++] = rIICDS;

                rIICSTAT = 0x90;                //Stop MasRx condition
                rIICCON  = 0xaf;                //Resumes IIC operation.
                Delay(1);                       //Wait until stop condtion is in effect.
                                                //Too long time...
                                                //The pending bit will not be set after issuing stop condition.
                break;
            }
            _iicData[_iicPt++] = rIICDS;
                        //The last data has to be read with no ack.
            if((_iicDataCount)==0)
                rIICCON = 0x2f;                 //Resumes IIC operation with NOACK.
            else
                rIICCON = 0xaf;                 //Resumes IIC operation with ACK
            break;

        case WRDATA:
            if((_iicDataCount--)==0)
            {
                rIICSTAT = 0xd0;                //stop MasTx condition
                rIICCON  = 0xaf;                //resumes IIC operation.
                Delay(1);                       //wait until stop condtion is in effect.
                       //The pending bit will not be set after issuing stop condition.
                break;
            }
            rIICDS = _iicData[_iicPt++];        //_iicData[0] has dummy.
            for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL
            rIICCON = 0xaf;                     //resumes IIC operation.
            break;

        case SETRDADDR:
//          printf("[S%d]",_iicDataCount);
            if((_iicDataCount--)==0)
            {
                break;                  //IIC operation is stopped because of IICCON[4]
            }
            rIICDS = _iicData[_iicPt++];
            for(i=0;i<10;i++);          //for setup time until rising edge of IICSCL
            rIICCON = 0xaf;             //resumes IIC operation.
            break;

        default:
            break;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -