ARM as Master: Problems with I2C Bus and atmega32 as slave

Ritchie rotarn at gmx.de
Mon Jul 16 15:59:18 EDT 2012


Hello,

after upgrading my board with the new kernel 2.26.22, which is using a
new kernel driver for i2c I run into problems with a atmega32 (20Mhz)
controller.

The communication does not work with a data request longer then 2 bytes.

How can I figure out, which speed of the I2C Bus from the linux board is
using. Hardware I2C Clients are working well, but size of data is always
shorter then 3 bytes. Own PIC Controller also working well.

Does this code still working with the changed driver or do I have to
improve the code for the new kernel driver.

Reading Code

int	RobyVariable::read_i2c(int Kommando, unsigned char *buffer, int laenge)
{
int								result;																	// Return value of the function
short	int		i;																							// Loop counter
unsigned char 		address[2];														// I2C Adresse + commando Byte
unsigned char		swapbufferL;														// Swapbuffer for Low/High
Buffer (16Bit)
int								iTries=3;																// Number of tries, if a error occurs
int								iError =true;															// iError Flag


	m_FirstRead=true;																		// Read Flag for the first read is set
	while ( iTries > 0 && iError == true)									// As long the counter
greater than zero
		{
		iError =false;																				// We do not have a error
		address[0]=(unsigned char) Kommando;						// Internal command for the
I2C slave
		address[1]=0;																					// Terminate string with 0
		
		m_messageBuffer[0].addr =(__u16) m_I2CAdresse;		// Destination adress
		m_messageBuffer[0].flags=0;													// Access with 7Bit Adr.
		m_messageBuffer[0].len= 1;														// Only one byte (the command )
		m_messageBuffer[0].buf=address;										// Assign the buffer of the
data to send
		m_msgset.msgs = m_messageBuffer;									// Assign the message Buffer
		m_msgset.nmsgs = 1;
		result=ioctl(m_DeviceHandle, I2C_RDWR, &m_msgset);		// Write down the
command to the Slave
		if (result < 0 )																					// Do we have any error
				{
				iError =true;																				// We have a error
				cout	<< "Error read_i2c 1(" << result << "/" << iTries << ")  " ;	//
make note of it, but continue
				}

		memset(buffer,0,laenge);																// Clear the request buffer
		m_messageBuffer[0].addr =(__u16) m_I2CAdresse;			// Assign destination
adress
		m_messageBuffer[0].flags=I2C_M_SEVENBIT + I2C_M_RD;	// Access with
7Bit Adr.  and read mode
		m_messageBuffer[0].len=laenge;												// Buffer Size of the
reading data from client
		m_messageBuffer[0].buf=buffer;												// Assign the Buffer of reading
		m_msgset.msgs = m_messageBuffer;									// Assign Message Buffer
		m_msgset.nmsgs = 1;

		result=ioctl(m_DeviceHandle, I2C_RDWR, &m_msgset);	// reading data
from slave
		if (result >= 0 )																					// reading ok.
			{
			if(  m_Endians == BIG_ENDIAN_DATATYPE )
				{
				for(i=0;i<m_NumberOfElements * m_ElementSize; i += m_ElementSize)
					{
					swapbufferL =  buffer[i+1];
					buffer[i+1]=buffer[i];
					buffer[i]=swapbufferL;
					}
				}
			}
		else
			{
			iError =true;
			cout	<< "Error in read_i2c 2(" << result << "/" << iTries << ")  " ;
			}

		if( iError == true )
			usleep(100000);									// wait, if error happen. Slave should get
time to reset

		iTries--;															// decrease trying counter
	}

	return	result;
}


Thanks in advance for any help in this matter.


R.



More information about the linux-arm mailing list