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

📄 lib_i2c.c

📁 AT91fr40162的FLASH读写程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	    MY_PIO_SODR = I2C_pt->SCL_line;     //* set SCL line
    	MY_PIO_SODR = I2C_pt->SDA_line;     //* set SDA line
	}
	else {
		SETSDATOOUTPUT
		SETSCL
		SETSDA
		K=(_BYTE)(loadAddress/256);
   		I2C_line.DeviceAddress = AT24C64_I2C_ADDRESS+2*K;
	}	
    //* get byte to transmit
    I2C_pt->I2CByte = I2C_pt->DeviceAddress | WRITE_BIT ;
    I2C_pt->LoadAddress = loadAddress;                  //* get address in Target
    I2C_pt->nbI2CByte = nbByte;                         //* get nb byte to transmit
    I2C_pt->countBit = 8;                               //* initialize countBit
    I2C_pt->nb_ACK = 10;                                 //* initialize nb_ACK

    //* Send Write
    I2C_pt->mode = LOW_ADDRESS_WRITE ;// I2C_pt->mode = HIGH_ADDRESS_WRITE;                  //*

    //* change interrupt handler to AT91_I2CSendStartSDA
    I2C_pt->I2CTCHandler = AT91_I2CSendStartSDA;

     //* Enable RC compare interrupt
    I2C_pt->timerBase->TC_IER = TC_CPCS;
}

//*-----------------------------------------------------------------------------
//* Function Name       : AT91_I2CRead (I2Cdesc *I2C_pt, _WORD loadAddress, _BYTE nbByte)
//* Object              : I2C RANDOM Read & Sequential Read
//*   I2C sequence:
//* start addI2C W ACK loadAddressMSD ACK loadAddressLSB ACK Start addI2C R data NACK stop
//* Input Parameters    : <I2C_pt> = I2C Peripheral Descriptor pointer
//*         : loadAddress address of return buffer
//*         : nbByte
//* Output Parameters   : none
//*-----------------------------------------------------------------------------
void AT91_I2CRead (I2Cdesc *I2C_pt, _WORD loadAddress, _DWORD nbByte )
{
    _DWORD   loop;
    _BYTE K;

    //* clean the rx buff for shifting byte
    for(loop = 0; loop < nbByte ; loop++) {
        I2C_pt->RxPtr[loop]=0;
    }

    //* initialize state
    I2C_pt->state = NOK;
	if (I2C_pt->I2CType==I2CFLASH) {
	    MY_PIO_OER  = I2C_pt->SDA_line;     //* set SDA line as an output
	    MY_PIO_OER  = I2C_pt->SCL_line;     //* set SCL line as an output
	    MY_PIO_SODR = I2C_pt->SCL_line;     //* set SCL line
	    MY_PIO_SODR = I2C_pt->SDA_line;     //* set SDA line
	}
	else {
		SETSDATOOUTPUT
		SETSCL
		SETSDA
		K=(_BYTE)(loadAddress/256);
   		I2C_line.DeviceAddress = AT24C64_I2C_ADDRESS+2*K;
		
	}	
    //* get byte to read
    I2C_pt->I2CByte = I2C_pt->DeviceAddress | WRITE_BIT;
    I2C_pt->LoadAddress = loadAddress;                  //* get address
    I2C_pt->nbI2CByte = nbByte;                         //* get nb byte to transmit
    I2C_pt->countBit = 8;                               //* initialize countBit
    I2C_pt->nb_ACK = 10;                                //* initialize nb_ACK

    //* next mode
   I2C_pt->mode =  LOW_ADDRESS_READ; //I2C_pt->mode = HIGH_ADDRESS_READ; //

    //* change interrupt handler to AT91_I2CSendStartSDA
    I2C_pt->I2CTCHandler = AT91_I2CSendStartSDA;

     //* Enable RC compare interrupt
    I2C_pt->timerBase->TC_IER = TC_CPCS;
}


//*-----------------------------------------------------------------------------
//* Function Name       : AT91_I2CWaitTime
//* Object              : I2C
//* Input Parameters    : <I2C_pt> = I2C Peripheral Descriptor pointer
//*         loadAddress - Address on slave
//*         nbByte      - Read to bytes
//*         I2C_address -  I2C address Divice
//*         mcki        - MCKI freq in KHz
//* Output Parameters   : FALSE if input parameter are out of range
//*-----------------------------------------------------------------------------
_DWORD AT91_I2CWaitTime (I2Cdesc *I2C_pt,_DWORD time,_DWORD mcki)
{
    while(I2C_pt->state != OK);
    mcki = mcki/2;											//* load timer value for 0,2 ms
    if ((mcki <= 0x0FFFF ) & ((time ) < 128)) {				//* check input value
        I2C_pt->timerBase->TC_RC = mcki;    				//* work in step of 1 ms 
        I2C_pt->state = NOK;								//* initialize state
        I2C_pt->countBit = time ;							//* initialize countBit time
        I2C_pt->I2CTCHandler = AT91_I2CWait;				//* change interrupt handler to AT91_I2CWait
        I2C_pt->timerBase->TC_RC = mcki;					//* load timer value for 1 ms
        I2C_pt->timerBase->TC_IER = TC_CPCS;				//* Enable RC compare interrupt
        I2C_pt->timerBase->TC_CCR = TC_SWTRG;				//* Trig the timer
    }
    else {
        return (FALSE);
    }
    return (TRUE);
}

//*---------------------------------------------------------------------------------------
//* Function Name       : AT91_I2CTransfertEnd(I2Cdesc *I2C_pt)
//* Object              : Wait the end I2C transfert when I2C_line.state != OK
//* Input Parameters    : None
//* Output Parameters   : none
//*---------------------------------------------------------------------------------------
void  AT91_I2CTransfertEnd(I2Cdesc *I2C_pt)
{
	_DWORD i,j;
    for(i=0; i<3; i++)  
    	for (j=0;j<MCK/5;j++) 
    		if (I2C_pt->state == OK) break;
    if (I2C_pt->state != OK) {
    	I2C_pt->cRetCode = C_ICTIMEOUT;
    	I2C_pt->state = OK;
    }	
    		
}


//*---------------------------------------------------------------------------------------
//* Function Name       : AT91_irq_open
//* Object              : 开中断
//* Input Parameters    : None
//* Output Parameters   : none
//*---------------------------------------------------------------------------------------
void AT91_irq_open(_DWORD irq_id,_DWORD priority,_DWORD src_type,TypeAICHandler handler_pt )
{
    _DWORD       mask ;
    mask = 0x1 << irq_id ;
    //* Disable the interrupt on the interrupt controller
    AIC_BASE->AIC_IDCR = mask ;
    //* Save the interrupt handler routine pointer and the interrupt priority
    AIC_BASE->AIC_SVR[irq_id] = (_DWORD) handler_pt ;
    //* Store the Source Mode Register
    AIC_BASE->AIC_SMR[irq_id] = src_type | priority  ;
    //* Clear the interrupt on the interrupt controller
    AIC_BASE->AIC_ICCR = mask ;
    //* Enable the interrupt on the interrupt controller
    AIC_BASE->AIC_IECR = mask ;
}

//*-----------------------------------------------------------------------------
//* Function Name       :  no_handler_tc (I2Cdesc *I2C_pt)
//* Object              : I2C Error
//* Input Parameters    : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters   : none
//*-----------------------------------------------------------------------------
void no_handler_tc (I2Cdesc *I2C_pt)
{
   	AT91_I2C_LineClose(&I2C_line);
}

//*-----------------------------------------------------------------------------
//* Function Name       :  AT91_I2CError(I2Cdesc *I2C_pt)
//* Object              : I2C Error
//* Input Parameters    : <I2C_pt> = I2C Peripheral Descriptor pointer
//*         : loadAddress  Address on slave
//*         : nbByte       Read to bytes
//*         : I2C_address  I2C address Divice
//* Output Parameters   : none
//*-----------------------------------------------------------------------------
void AT91_I2CError(I2Cdesc *I2C_pt)
{
    //* change interrupt handler to at91_I2CTxSendStopSDA
    I2C_pt->I2CTCHandler = AT91_I2CSendStopSDA;
    I2C_line.cRetCode  = C_NOTOK;

}

//*--------------------------------------------------------------------------------
//* 函数: I2CInitVariable
//* 功能: 初始化I2C读写使用的全局变量
//* 输入:  
//*       dwSDA : FLASH读写的SDA引脚的PIO地址 
//*       dwSCL : FLASH读写的SCL引脚的PIO地址 
//* 返回: 无
//*---------------------------------------------------------------------------------
void I2CInitVariable(_DWORD dwSDA, _DWORD dwSCL )
{
    /*I2C init */
    I2C_line.SDA_line       = dwSDA ;
    I2C_line.SCL_line       = dwSCL ;

    // EPROM AT24C512 address
    I2C_line.DeviceAddress = AT24C256_CHIP1_ADDRESS;
	I2C_line.dwI2CSpeed = I2CICCARDSPEED;
    //* Timer 0 Counter field
    I2C_line.TCBase     = TCB0_BASE;
    I2C_line.timerBase  = (StructTC *) TCB0_BASE;
    I2C_line.channelId  = TC0_ID;

    //* IRQ field
    I2C_line.timerBase->TC_IDR = 0x1FF;             //* disable interrupt
    I2C_line.AICHandler = tc0_asm_interrupt_handler;
    I2C_line.I2CTCHandler = no_handler_tc;
} 

//*--------------------------------------------------------------------------------
//* 函数: I2CTransfertEnd
//* 功能: 等待I2C处理结束
//* 输入: 无 
//* 返回: 无
//*---------------------------------------------------------------------------------
void  I2CTransfertEnd(void)
{
    AT91_I2CTransfertEnd(&I2C_line);
}

//*--------------------------------------------------------------------------------
//* 函数: I2CWritePage
//* 功能: 将BUF中的数据写入I2C中
//* 参数: wAddress: 拟写数据在Flash或IC卡中的起始地址
//*       cLength:  拟写数据的长度
//*       cpBuf:    存放拟写入数据的缓冲区,不超过64个字节
//*	      cChip:    选择0片还是1片FLASH,只对FLASH有效,对I2C无效
//*--------------------------------------------------------------------------------
_BYTE I2CWritePage(_WORD wAddress,_DWORD wLength,_BYTE cChip,_BYTE *cpBuf,_BYTE cI2CType)
{
    //AT91_I2C_LineOpen(&I2C_line,I2C_line.dwI2CSpeed,cChip,cI2CType);
    I2C_line.TxEnd  = I2C_line.TxPtr  = cpBuf;					//* set global buffer aadres
    I2C_line.cRetCode  = C_OK;
    I2C_line.state = OK;
    I2C_line.timerBase->TC_CCR = TC_SWTRG;						//* Trig the timer
    AT91_I2CTransfertEnd(&I2C_line);							//* write modulo page block
    AT91_I2CWrite(&I2C_line,wAddress,wLength);
    AT91_I2CTransfertEnd(&I2C_line);
    //AT91_I2C_LineClose(&I2C_line);
    Delayms(5);
    if (I2C_line.cRetCode!=C_OK) return(I2C_line.cRetCode);
    return(C_OK);
}

//*--------------------------------------------------------------------------------
//* 函数: I2CReadPage
//* 功能: 从I2C中读取数据到BUF中
//* 参数: wAddress: 拟读取数据在Flash或IC卡中的起始地址
//*       cLength:  拟读取数据的长度
//*       cpBuf:    存放读取数据的缓冲区,不超过64个字节
//*	      cChip:    选择0片还是1片FLASH,只对FLASH有效,对I2C无效
//*--------------------------------------------------------------------------------
_BYTE  I2CReadPage(_WORD wAddress,_DWORD wLength,_BYTE cChip,_BYTE *cpBuf,_BYTE cI2CType)
{
    //AT91_I2C_LineOpen(&I2C_line, I2C_line.dwI2CSpeed,cChip,cI2CType);
    I2C_line.RxEnd = I2C_line.RxPtr  = cpBuf;					//* Set the recivied buffer
    I2C_line.cRetCode  = C_OK;
    I2C_line.timerBase->TC_CCR = TC_SWTRG;						//* Trig the timer
    AT91_I2CTransfertEnd(&I2C_line);
    AT91_I2CRead(&I2C_line,wAddress,wLength);
    AT91_I2CTransfertEnd(&I2C_line);
    Delayms(5);
    //AT91_I2C_LineClose(&I2C_line);
    if (I2C_line.cRetCode!=C_OK) return(I2C_line.cRetCode);
    return(C_OK);
}

//***********************************************************************************
//读取信息到IC卡中
//其中:
//函数的返回值为C_OK或C_NOTOK
//wAddress:读写或写入信息在IC卡中的起始地址
//wLength:读取或写入信息的长度
//cpBlockBuf:读取或待写入的信息
//***********************************************************************************
_BYTE I2CReadBlock(_WORD wAddress,_DWORD dwLength,_BYTE cChip,_BYTE *cpBlockBuf,_BYTE cI2CType)
{
   	_BYTE cRetCode;
   	_WORD wAdd;
   	_DWORD dwPageLength,dwCurLen;
   	_WORD wPageSize;
   	wPageSize = I2C_line.wPageSize;
   	wAdd=wAddress;
   	dwCurLen = 0;
   	while (dwCurLen<dwLength) {
   	   		
   		if ((wAdd%wPageSize)==0) {										// 一页的起始
   			dwPageLength = ((dwCurLen+wPageSize>=dwLength)?dwLength-dwCurLen:wPageSize);
   		}
   		else {															// 一页的中间
   			dwPageLength = wPageSize - (wAdd%wPageSize);				// 本页剩余字节的长度
   		    if (dwCurLen + dwPageLength >dwLength) {					// 剩余字节长度不够
   		    	dwPageLength = (dwLength - dwCurLen);
   		    }
   		}
     	cRetCode = I2CReadPage(wAdd,dwPageLength,cChip,cpBlockBuf,cI2CType);
     	if (cRetCode!=C_OK) return(cRetCode);
      	wAdd += (_WORD)dwPageLength;
 		dwCurLen += dwPageLength;     	
      	cpBlockBuf += dwPageLength;
		   		
   	}
   	return(C_OK);
}


//***********************************************************************************
//写入信息到IC卡中
//其中:
//函数的返回值为C_OK或C_NOTOK
//wAddress:读写或写入信息在IC卡中的起始地址
//wLength:读取或写入信息的长度
//cpBlockBuf:读取或待写入的信息
//***********************************************************************************
_BYTE I2CWriteBlock(_WORD wAddress,_DWORD dwLength,_BYTE cChip,_BYTE *cpBlockBuf,_BYTE cI2CType)
{
   	_BYTE cRetCode;
   	_WORD wAdd;
   	_DWORD dwCurLen,dwPageLength;
   	_WORD wPageSize;
   	wPageSize = I2C_line.wPageSize;
   	wAdd=wAddress;
   	dwCurLen = 0;
   	while (dwCurLen<dwLength) {
   	   		
   		if ((wAdd%wPageSize)==0) {											// 一页的起始
   			dwPageLength = ((dwCurLen+wPageSize>=dwLength)?dwLength-dwCurLen:wPageSize);
   		}
   		else {															// 一页的中间
   			dwPageLength = wPageSize - (wAdd%wPageSize);				// 本页剩余字节的长度
   		    if (dwCurLen + dwPageLength >dwLength) {					// 剩余字节长度不够
   		    	dwPageLength = dwLength - dwCurLen;
   		    }
   		}
       	cRetCode = I2CWritePage(wAdd,dwPageLength,cChip,cpBlockBuf,cI2CType);
        if (cRetCode!=C_OK) return(cRetCode);
      	wAdd += dwPageLength;
 		dwCurLen += dwPageLength;     	
      	cpBlockBuf += dwPageLength;
		   		
   	}
   	return(C_OK);
}   	

⌨️ 快捷键说明

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