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

📄 iic.c

📁 用于开发Linux的Bootloader源代码
💻 C
字号:
/*
//==Program Name:iic.c================================
//--Program Description:iic fuction-------- 
//--Author:Yanyou Song---E-mail:syyo@163.com-----------------
//--Some Program&Fuction May Have BUG------------------------
//--The Code Is Strictly In public,Forbiding Updata On Net---
//--Use This Code Caused All The Problem Is Irrespective The 
Programmer,Aftermath By Yourself!!---------------------------
//--Copyright Yanyou Song,All rights reserved.---------------
//--Design Data:2006-09-11 ----------------------------------
//===========================================================

//===========程序名称:Main_entry.c======================= 
//--程序目的:iic函数-----------------------------
//-----设计&编写者 :宋彦佑--电子邮件:syyo@163.com---------
//------------程序&函数有存在BUG的可能--------------------
//------此原码不公开!!不允许公布在因特网上!!------------
//--使用此代码引起的一切问题与设计&编写者无关,后果自负---
//------------作者保留此代码的所有权力--------------------
//----设计日期:-2006-now---------------------------------
//========================================================

//--------最后更改日期---------
//---the last revision time----
//2006-10-20 

*/

#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
	//syany IICPS = SetPreScaler((int)fSCL);  //support upto 100KHz
	IICPS = 0x02;  
	
}

/******************************************************************
 *                                                                *
 *     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 + -