www.pudn.com > IIC.zip > IIC.c


//*-------------------------------------------------------------------------------------- 
//*      ATMEL Microcontroller Software Support  -  ROUSSET  - 
//*-------------------------------------------------------------------------------------- 
//* The software is delivered "AS IS" without warranty or condition of any 
//* kind, either express, implied or statutory. This includes without 
//* limitation any warranty or condition with respect to merchantability or 
//* fitness for any particular purpose, or against the infringements of 
//* intellectual property rights of others. 
//*-------------------------------------------------------------------------------------- 
//* File Name           : twi.c 
//* Object              : Basic TWI EEPROM driver 
//* Translator          : 
//* 1.0 25/11/02 NL		: Creation 
//*-------------------------------------------------------------------------------------- 
#include "AT91RM9200.H" 
#include "IIC.h" 
 
 
//*========================================================= 
//*		WRITE 
//*========================================================= 
//*---------------------------------------------------------------------------- 
//* \fn    AT91F_TWI_Write 
//* \brief Send n bytes to a slave device 
//*---------------------------------------------------------------------------- 
int AT91F_TWI_Write(const AT91PS_TWI pTwi ,int address, char *data2send, int size) 
{ 
	unsigned int status; 
 
	// Set the TWI Master Mode Register 
	pTwi->TWI_MMR = ( AT91C_EEPROM_I2C_ADDRESS | AT91C_TWI_IADRSZ_2_BYTE ) & ~AT91C_TWI_MREAD;	 
	 
	// Set TWI Internal Address Register 
	pTwi->TWI_IADR = address; 
 
	status = pTwi->TWI_SR; 
		 
	pTwi->TWI_THR = *(data2send++); 
	 
	pTwi->TWI_CR = AT91C_TWI_START; 
		 
	while (size-- >1){ 
 
		// Wait THR Holding register to be empty 
		while (!(pTwi->TWI_SR & AT91C_TWI_TXRDY)); 
	 
		// Send first byte 
		pTwi->TWI_THR = *(data2send++); 
		 
	} 
 
	pTwi->TWI_CR = AT91C_TWI_STOP;		 
 
	status = pTwi->TWI_SR; 
 
	// Wait transfer is finished 
    while (!(pTwi->TWI_SR & AT91C_TWI_TXCOMP)); 
		 
	return AT91C_EEPROM_WRITE_OK; 
} 
 
//*========================================================= 
//*		READ 
//*========================================================= 
//*---------------------------------------------------------------------------- 
//* \fn    AT91F_TWI_Read 
//* \brief Read n bytes from a slave device 
//*---------------------------------------------------------------------------- 
int AT91F_TWI_Read(const AT91PS_TWI pTwi , int address, char *data, int size) 
{ 
	unsigned int status; 
	 
	// Set the TWI Master Mode Register 
	pTwi->TWI_MMR = AT91C_EEPROM_I2C_ADDRESS | AT91C_TWI_IADRSZ_2_BYTE | AT91C_TWI_MREAD;	 
	 
	// Set TWI Internal Address Register 
	pTwi->TWI_IADR = address; 
	 
	// Start transfer 
	pTwi->TWI_CR = AT91C_TWI_START; 
	 
	status = pTwi->TWI_SR; 
		 
	while (size-- >1){ 
		 
		// Wait RHR Holding register is full 
		while (!(pTwi->TWI_SR & AT91C_TWI_RXRDY)); 
 
		// Read byte 
		*(data++) = pTwi->TWI_RHR; 
	 
	} 
	 
	pTwi->TWI_CR = AT91C_TWI_STOP; 
 
	status = pTwi->TWI_SR; 
 
	// Wait transfer is finished 
    while (!(pTwi->TWI_SR & AT91C_TWI_TXCOMP)); 
 
	// Read last byte 
	*data = pTwi->TWI_RHR; 
		 
	return AT91C_EEPROM_READ_OK; 
} 
 
/*void TWI_Write(int address, char *data2send, int size) 
{ 
	unsigned int status; 
 
	// Set the TWI Master Mode Register 
	*AT91C_TWI_MMR = ( 0x00500000 | AT91C_TWI_IADRSZ_2_BYTE ) & ~AT91C_TWI_MREAD;//dadr=0, 
	 
	// Set TWI Internal Address Register 
	*AT91C_TWI_IADR = address; 
 
	status = *AT91C_TWI_SR; 
		 
	*AT91C_TWI_THR = *(data2send++); 
	 
	*AT91C_TWI_CR = AT91C_TWI_START; 
		 
	while (size-- >1){ 
 
		// Wait THR Holding register to be empty 
		while (!(*AT91C_TWI_SR & AT91C_TWI_TXRDY)); 
		 
		// Send first byte 
		*AT91C_TWI_THR = *(data2send++); 
		 
	} 
 
	*AT91C_TWI_CR = AT91C_TWI_STOP;		 
 
	status = *AT91C_TWI_SR; 
 
	// Wait transfer is finished 
    while (!(*AT91C_TWI_SR & AT91C_TWI_TXCOMP)); 
		 
	//return AT91C_EEPROM_WRITE_OK; 
}*/ 
void AT91F_SetTwiClock(const AT91PS_TWI pTwi) 
{ 
	int sclock; 
 
	/* Here, CKDIV = 1 and CHDIV=CLDIV  ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6)*/ 
 
	sclock = (10*AT91C_MASTER_CLOCK /AT91C_TWI_CLOCK); 
	if (sclock % 10 >= 5) 
		sclock = (sclock /10) - 5; 
	else 
		sclock = (sclock /10)- 6; 
	sclock = (sclock + (4 - sclock %4)) >> 2;	// div 4 
 
    pTwi->TWI_CWGR	= 0x00010000 | sclock | (sclock << 8); 
}