Probleme beim IIC Lesen unter Linux mit IOW40 1.0.3.0

Dies ist das deutsche Forum für alle Themen um den IO-Warrior. Beiträge bitte nur in Deutsch.

Moderator: Guido Körber

Post Reply
Hartwig
Posts: 8
Joined: Mon Jun 13, 2005 12:07 pm
Location: München

Probleme beim IIC Lesen unter Linux mit IOW40 1.0.3.0

Post by Hartwig »

Nachfolgende Routinen funktionieren mit IOW40 V1.0.2.1R, jedoch NICHT mit Realease V1.0.3.0R, scheinbar klappt das Lesen von IIC nicht mehr.
(Unter Windows funktioniert die V1.0.3.0R ohne Probleme)

Das Problem zeigt sich u.a. mit folgenden Linuxversionen (auf x86 Hardware):

Kernel 2.6.20.15 mit IOWarrior Modul (Debian)
Kernel 2.6.35 mit IOWarrior Kernel Modul (Ubuntu)

Gelesen wird ein Datenbyte von einem EEPROM (Adresse A0/A1) Datenbyte ist 0xFF

=====================================
Hex-Log mit Chip-Release 1.0.2.1 :

Write: 02 C2 A0 00
Read : 02 02 00 0000000000

Write: 03 01 A1 0000000000
Read : 03 01 FF 0000000000

=====================================
Hex-Log mit Chip-Release 1.0.3.0

Write: 02 C2 A0 00
Read : 02 02 00 0000000000

Write: 03 01 A1 0000000000
Read : 0000000000000000
Read : 0000000000000000
Read : 0000000000000000
Read : 0000000000000000
Read : 0000000000000000
Read : 0000000000000000
...
=====================================




int IOWarrior::IICWrite(unsigned char Address, unsigned char *Command, unsigned char CommandLen)
{
int ReturnCode;
unsigned char BytesToWrite = CommandLen + 1; // Includes Address;
unsigned char DataToWrite[8];
unsigned char Result[8];

int i;
int CommandPointer=0;

DataToWrite[0] = 0x02; // IOWarrior Send IIC command
DataToWrite[1] = 0x80; // Generate Startbit
DataToWrite[2] = Address & 0xFE; // force IIC write bit

while (BytesToWrite > 0)
{
int BytesInThisPacket;
if (BytesToWrite <= 6)
{
BytesInThisPacket = BytesToWrite;
BytesToWrite = 0;
DataToWrite[1] |= 0x40; // Generate Stopbit
}
else
{
BytesInThisPacket = 6;
BytesToWrite -= 6;
}

DataToWrite[1] &= 0xF8; // Reset Counter
DataToWrite[1] += BytesInThisPacket;

for ( i = (DataToWrite[1] & 0x80) ? 1 : 0; i < BytesInThisPacket; i++)
{
DataToWrite[i+2] = Command[CommandPointer++];
}

cout << endl << "Write Command: ";
for (i=0; i < 8; i++)
{
cout << "0x" << hex << cout.width(2) << (int)DataToWrite << " ";
}

ReturnCode = ioctl(m_Handle1, IOW_WRITE, DataToWrite);
DataToWrite[1] &= 0x7F; // Reset Startbit

cout << "ReturnCode: " << ReturnCode << endl;

ReturnCode = ioctl(m_Handle1, IOW_READ, Result);

cout << "Write Answere: ";
for (i=0; i < 8; i++)
{
cout << "0x" << hex << cout.width(2) << (int)Result << " ";
}
cout << "ReturnCode: " << ReturnCode << endl;

}

return ReturnCode;
}

int IOWarrior::IICRead(unsigned char Address, unsigned char *Buffer, unsigned char BufferLen)
{
int ReturnCode;
unsigned char DataToWrite[8] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned char Result[8];
int BufferPointer = 0;
int BytesToRead = BufferLen;
int i;

/*
// Can't send longer than 5 Byte commands.
if (BufferLen > 6) return -1;
*/
DataToWrite[0] = 0x03; // IOWarrior Send IIC command
DataToWrite[1] = BufferLen; // build IOWarrior IIC flags
DataToWrite[2] = Address | 1; // force IIC read bit

cout << endl << "Read Command: ";
for (i=0; i < 8; i++)
{
cout << "0x" << hex << cout.width(2) << (int)DataToWrite << " ";
}

ReturnCode = ioctl(m_Handle1, IOW_WRITE, DataToWrite);

cout << "ReturnCode: " << ReturnCode << endl;


while (BytesToRead)
{
ReturnCode = ioctl(m_Handle1, IOW_READ, Result);

for (i=2; i < 2 + ((Result[1] & 0x07)); i++)
{
Buffer[BufferPointer++] = Result;
}
BytesToRead -= Result[1] & 0x07;

cout << "Read Answere: ";
for (i=0; i < 8; i++)
{
cout << "0x" << hex << cout.width(2) << (int)Result << " ";
}
cout << "ReturnCode: " << ReturnCode << endl;

}

return ReturnCode;
}
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: Probleme beim IIC Lesen unter Linux mit IOW40 1.0.3.0

Post by Guido Körber »

Das Verhalten haben wir bisher nirgendwo gesehen, müssen wir mal versuchen nachzuvollziehen. Regulär arbeiten wir hier unter MacOS und Windows.
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: Probleme beim IIC Lesen unter Linux mit IOW40 1.0.3.0

Post by Christoph Jung »

Ich hatte irgendwo gelesen, dass bei einem Update des Kernels die USB-Module geändert wurden.
Leider bin ich im moment gesundheitlich verhindert um dem Nachzugehen.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
Hartwig
Posts: 8
Joined: Mon Jun 13, 2005 12:07 pm
Location: München

Re: Probleme beim IIC Lesen unter Linux mit IOW40 1.0.3.0

Post by Hartwig »

Wir haben jetzt eine Lösung.
Und zwar haben wir die "ioctl"-Aufrufe gegen "read"/"write"-Aufrufe getauscht.
Anregung hat dazu das "IOWarriorHowTo.pdf"-Dokument gegeben.
Zu finden auf der Codemercs-Website unter: "Downloads/Software/IO-Warrior SDK Linux"
im Verzeichnes des Archivs: "LinuxSDK_01.zip\LinuxSDK\Kernel_2.6\iowkit 1.5\iowarrior-module-2.6.20.tar.gz\iowarrior-module-2.6.20.tar\iowarrior-module-2.6.20\iowarrior-2.6.20\
IOWarriorHowTo.pdf"

Am Ende des Dokument steht nämlich :

> 03/27/2007 Version 0.1.1.0
> Updates reflecting changes to the header,
> removed sections on read/write-ioctl() calls

Die Routinen haben wir wie folgt geändert, und so funktioniert es. Anscheinend ist die "ioctl"-Funktion nicht mehr (ohne weiteres) dazu geeignet mehrere Chipversionen gleichartig zu betreiben. Wer die IOWarriorfunktionen mit einem aktuellen IOWkit kapselt hat vermutlich keine Probleme.

================================================================================================

int IOWarrior::IICWrite(unsigned char Address, unsigned char *Command, unsigned char CommandLen)
{
//int ReturnCode;
unsigned char BytesToWrite = CommandLen + 1; // Includes Address;
unsigned char DataToWrite[8] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned char Result[8] = {0, 0, 0, 0, 0, 0, 0, 0};

int i;
int CommandPointer=0;

DataToWrite[0] = 0x02; // IOWarrior Send IIC command
DataToWrite[1] = 0x80; // Generate Startbit
DataToWrite[2] = Address & 0xFE; // force IIC write bit

while (BytesToWrite > 0)
{
int BytesInThisPacket;
if (BytesToWrite <= 6)
{
BytesInThisPacket = BytesToWrite;
BytesToWrite = 0;
DataToWrite[1] |= 0x40; // Generate Stopbit
}
else
{
BytesInThisPacket = 6;
BytesToWrite -= 6;
}

DataToWrite[1] &= 0xF8; // Reset Counter
DataToWrite[1] += BytesInThisPacket;

for ( i = (DataToWrite[1] & 0x80) ? 1 : 0; i < BytesInThisPacket; i++)
{
DataToWrite[i+2] = Command[CommandPointer++];
}

cout << endl << "Write Command: ";
for (i=0; i < 8; i++)
{
cout << "0x" << hex << cout.width(2) << (int)DataToWrite << " ";
}
cout << endl;

if (write(m_Handle1, DataToWrite, m_IOWReportSizeSpecialMode) != m_IOWReportSizeSpecialMode)
{
cout << "IICWrite()/write() failed!" << endl;
return -1;
}

DataToWrite[1] &= 0x7F; // Reset Startbit

if (read(m_Handle1, Result, m_IOWReportSizeSpecialMode) != m_IOWReportSizeSpecialMode)
{
cout << "IICWrite()/read() failed!" << endl;
return -2;
}
else
{
cout << "Write Answer: ";
for (i=0; i < 8; i++)
{
cout << "0x" << hex << cout.width(2) << (int)Result << " ";
}
cout << endl;
if(Result[1] >> 7)
{
cout << "IICWrite()/Errorbit set!" << endl;
return -3;
}
}
}

return 0;
}

int IOWarrior::IICRead(unsigned char Address, unsigned char *Buffer, unsigned char BufferLen)
{
//int ReturnCode;
unsigned char DataToWrite[8] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned char Result[8] = {0, 0, 0, 0, 0, 0, 0, 0};
int BufferPointer = 0;
int BytesToRead = BufferLen;
int i;

/*
// Can't send longer than 5 Byte commands.
if (BufferLen > 6) return -1;
*/
DataToWrite[0] = 0x03; // IOWarrior Send IIC command
DataToWrite[1] = BufferLen; // build IOWarrior IIC flags
DataToWrite[2] = Address | 1; // force IIC read bit

cout << endl << "Read Command: ";
for (i=0; i < 8; i++)
{
cout << "0x" << hex << cout.width(2) << (int)DataToWrite << " ";
}
cout << endl;

if (write(m_Handle1, DataToWrite, m_IOWReportSizeSpecialMode) != m_IOWReportSizeSpecialMode)
{
cout << "IICRead()/write() failed!" << endl;
return -1;
}

while (BytesToRead)
{
if (read(m_Handle1, Result, m_IOWReportSizeSpecialMode) != m_IOWReportSizeSpecialMode)
{
cout << "IICRead()/read() failed!" << endl;
return -2;
}
else
{
for (i=2; i < 2 + ((Result[1] & 0x07)); i++)
{
Buffer[BufferPointer++] = Result;
}
BytesToRead -= Result[1] & 0x07;

cout << "Read Answer: ";
for (i=0; i < 8; i++)
{
cout << "0x" << hex << cout.width(2) << (int)Result << " ";
}
cout << endl;

if(Result[1] >> 7)
{
cout << "IICRead()/Errorbit set!" << endl;
return -3;
}
}
}

return 0;
}
Post Reply