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

📄 iic.c

📁 一个比较好的三星s3c4510的启动代码
💻 C
字号:
/*************************************************************************/
/*                                                                       */
/* FILE NAME                                      VERSION                */
/*                                                                       */
/*      iic.c                      		 KS32C50100   : version 1.0 */
/*                                                                       */
/* COMPONENT                                                             */
/*                                                                       */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*      I2C control function library for SNDS100 evaluation board.       */
/*                                                                       */
/* AUTHOR                                                                */
/*                                                                       */
/*                                                                       */
/* DATA STRUCTURES                                                       */
/*                                                                       */
/*                                                                       */
/* FUNCTIONS                                                             */
/*                                                                       */
/*                                                                       */
/* DEPENDENCIES                                                          */
/*                                                                       */
/*                                                                       */
/* HISTORY                                                               */
/*                                                                       */
/*************************************************************************/
#include <math.h>
#include "std.h"
#include "apdialog.h"
#include "snds.h"
#include "uart.h"
#include "isr.h"
#include "memory.h"
#include "pollio.h"
#include "iic.h"
#include "sysconf.h"


IIC_DATA_TX_FORMAT  iic_txmit;
IIC_DATA_RX_FORMAT  iic_recv;

/******************************************************************
 *                                                                *
 *                   IIC SETUP ROUTINE                            *
 *                                                                *
 ******************************************************************/
void IicSetup(void)
{
	// Reset IIC Controller
	IICCON = IICRESET;

	// Set Prescale Value: fSCL is IIC serial clock frequency
	// fSCL defined at sysconf.h
	IICPS = SetPreScaler((int)fSCL);  //support upto 100KHz
}

/******************************************************************
 *                                                                *
 *     SETUP IIC PRESCALER VALUE FROM SERIAL CLOCK FREQUENCY      *
 *                                                                *
 ******************************************************************/
int  SetPreScaler(int sclk) 
{  
     return((int)(((fMCLK/sclk)-3.0)/16.0)-0.5);  //add 0.5 for 
}


/******************************************************************
 *                                                                *
 *           IIC INTERRUPT SERVICE ROUTINES                       *
 *                                                                *
 ******************************************************************/
void IICWriteIsr(void)
{
     if(!(iic_txmit.FLAG & (U32)iic_byte_addr_msb)) { 
          /* Send byte address: MSB */
          IICBUF = iic_txmit.BYTE_ADDR_MSB;
          iic_txmit.FLAG |= (U32)iic_byte_addr_msb; 
     }
     else if(!(iic_txmit.FLAG & (U32)iic_byte_addr_lsb)) {
          /* Send byte address: LSB */
          IICBUF = iic_txmit.BYTE_ADDR_LSB;
          iic_txmit.FLAG |= (U32)iic_byte_addr_lsb; 
     }
     else if(iic_txmit.BuffByteCnt < iic_txmit.WriteDataSize) {
          IICBUF = iic_txmit.PAGE_BUFFER[iic_txmit.BuffByteCnt++]; 
     }
     else { 
            /* STOP IIC Controller */
            IICCON = STOP;
            /* byte data or page data transmit done */
            iic_txmit.FLAG |= (U32)iic_page_tx_done;
     }
}

void IICReadIsr(void)
{
     if(!(iic_recv.FLAG & (U32)iic_byte_addr_msb)) { 
     //else if(!(iic_recv.FLAG & (U32)iic_byte_addr_msb)) { 
          /* Send byte address: MSB */
          IICBUF = iic_recv.BYTE_ADDR_MSB;
          iic_recv.FLAG |= (U32)iic_byte_addr_msb; /* send msb byte addr */
     }
     else if(!(iic_recv.FLAG & (U32)iic_byte_addr_lsb)) {
          /* Send byte address: LSB */
          IICBUF = iic_recv.BYTE_ADDR_LSB;
          iic_recv.FLAG |= (U32)iic_byte_addr_lsb; /* send lsb byte addr */
     }
     else if(!(iic_recv.FLAG & (U32)iic_repeat_start)) {
          /* Repeat Start */
          IICCON = RESTART; 
          IICCON = START|ACK|IEN;
          IICBUF = iic_recv.SLAVE_ADDR|S_READ;
          iic_recv.FLAG |= (U32)iic_repeat_start;
     }
     else if(!(iic_recv.FLAG & (U32)iic_multi_recv)) {
          /* Receive multiple data */
          IICCON = ACK|IEN;
          iic_recv.FLAG |= (U32)iic_multi_recv;
     }
     else if(iic_recv.ByteReadCnt < iic_recv.ReadDataSize) {
          *(iic_recv.RCV_BUFFER)++ = IICBUF;
          iic_recv.ByteReadCnt++;
     }
     else if(!(iic_recv.FLAG & (U32)iic_no_more_recv)) { 
            /* Now,no more received data is required from slave */
            IICCON = NOACK|IEN;
            iic_recv.FLAG |= (U32)iic_no_more_recv;
     }
     else { /* Receive last data and STOP */
            *(iic_recv.RCV_BUFFER)++ = IICBUF;

            /* STOP IIC Controller */
            IICCON = STOP;

            /* byte data receive done */
            iic_recv.FLAG |= (U32)iic_byte_rx_done;
     }
}


/******************************************************************
 *                                                                *
 *          LIBRARY FUNCTIONS FOR IIC READ & WRITE                *
 *            KS24C32/64   : IIC Serial EEPROM                    *
 *                                                                *
 ******************************************************************/
void IICWriteInt(U8 SlaveAddr,U32 WriteAddr,U8 *data,U32 SizeOfData)
{
    int page,j;
    int no_of_page;      /* Number of page */
    int remain_byte;      
    U32 PageAccessAddr; 


    //SysSetInterrupt(nIIC_INT,IICWriteIsr) ; /*Setup IIC Tx interrupt */
    //Enable_Int(nIIC_INT) ;			

    PageAccessAddr = WriteAddr;
    iic_txmit.SLAVE_ADDR = SlaveAddr;

    no_of_page = (int)(ceil(SizeOfData/(U32)SizeOfPage));
    remain_byte = (int)(SizeOfData%(U32)SizeOfPage);

    for(page=0; page <= no_of_page;page++)
    {
        if(SizeOfData < SizeOfPage) { 
           for(j=0; j < SizeOfData; j++)
               iic_txmit.PAGE_BUFFER[j] = *data++;
           iic_txmit.WriteDataSize = SizeOfData;
        }
        else {
               if(page == no_of_page) {
                   for(j=0; j < remain_byte; j++)
                       iic_txmit.PAGE_BUFFER[j] = *data++;
                   iic_txmit.WriteDataSize = remain_byte;
               }
               else {
                    for(j=0; j < SizeOfPage; j++)
                        iic_txmit.PAGE_BUFFER[j] = *data++;
                    iic_txmit.WriteDataSize = SizeOfPage;
               }
        }

        IicSetup();                 
        iic_txmit.FLAG = 0x0;
        iic_txmit.BuffByteCnt = 0x0;
        iic_txmit.BYTE_ADDR_MSB = (U8)((PageAccessAddr>>8) & 0xff);
        iic_txmit.BYTE_ADDR_LSB = (U8)(PageAccessAddr & 0xff);

        /* Step 1: Setup IICON register for transmit start */
        while(IICCON & BUSY);   /* Wait! the iic bus is busy */
        IICCON = START|ACK|IEN; /* Now, Start to transmit */

        /* Send Slave Address and Write command */
        IICBUF = iic_txmit.SLAVE_ADDR|S_WRITE;

        while(!(iic_txmit.FLAG & iic_page_tx_done));
        PageAccessAddr += SizeOfPage;
        for(j=0; j< (int)Write_Cycle_ms(5); j++);  /* for 5ms write cycle */
    }
}



void *IICReadInt(U8 SlaveAddr,U32 ReadAddr,U32 SizeOfData)
{
    U8 *ReadPtr;  /* data read pointer */

    IicSetup();     
    SysSetInterrupt(nIIC_INT,IICReadIsr) ; /*Setup IIC Tx interrupt */
    Enable_Int(nIIC_INT) ;			

    /*Memory alloc for receive data */
    if((ReadPtr = (U8 *)malloc((unsigned)SizeOfData)) == (U8 *)(NULL))
         Print("\rMemory allocation error occurred!!!\r");
    iic_recv.RCV_BUFFER = ReadPtr;

    iic_recv.FLAG = 0x0;
    iic_recv.ByteReadCnt = 0x0;
    iic_recv.ReadDataSize = SizeOfData;
    iic_recv.SLAVE_ADDR = SlaveAddr;
    iic_recv.BYTE_ADDR_MSB = (U8)((ReadAddr>>8) & 0xff);
    iic_recv.BYTE_ADDR_LSB = (U8)(ReadAddr & 0xff);

    /* Step 1: Setup IICON register for receive start */
    while(IICCON & BUSY);   /* Wait! the iic bus is busy */
    IICCON = START|ACK|IEN;

    /* Send Slave Address and Write command */
    IICBUF = iic_recv.SLAVE_ADDR|S_WRITE;

    while(!(iic_recv.FLAG & iic_byte_rx_done));
    return(ReadPtr);         /* return receive data pointer */
}

void IICWrite(U32 WriteAddr,U8 data,U32 SizeOfData)
{
//while(IICCON & BUSY);   /* Wait! the iic bus is busy */
IICCON = START&ACK;
IICBUF = WriteAddr|S_WRITE;
while(!(IICCON &01));
IICBUF=data;
while(!(IICCON &01));
IICCON = STOP;
}

char IICRead(U32 ReadAddr,U32 SizeOfData)
{
char i;
while(IICCON & BUSY);   /* Wait! the iic bus is busy */
IICCON = START|ACK; /* Now, Start to transmit */
IICBUF=0x0|S_WRITE;
while(!(IICCON &01));
IICCON = RESTART; 
IICCON = START|ACK;
IICBUF = S_READ;
while(!(IICCON &01));   /* Wait! the iic bus is busy */
i=IICBUF;
IICCON = STOP;
return i;
}

⌨️ 快捷键说明

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