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