24LC00 an I2C Dongle

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
regenbiegen
Posts: 8
Joined: Thu Jun 19, 2008 4:06 pm

24LC00 an I2C Dongle

Post by regenbiegen »

Hallo,

ich hab ein 24LC00 EEPROM an dem IO-Warrior24 I2C Dongle laufen.
Der 24LC00 wird mit 3,3V vom Dongle versorgt und SDA und SCL hängen über jeweils 10k Ohm an 3,3V.

Simple-I2C erkennt den Dongle, aber er findet den 24LC00 nicht (No I2C devices found).

Per Oszilloskop habe ich mit die Versorgungsspanuung, SDA und SCL angesehen.
Wenn ich "Search I2C" drücke ist der Takt da und es gehen Daten über SDA.

Wo ist hier das Problem ?

Gruss,
Bernd
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: 24LC00 an I2C Dongle

Post by Guido Körber »

Sehen die Signale sauber aus?

Sonst wäre meine erste Idee zu schauen ob SDA/SCL nicht vertauscht sind.
regenbiegen
Posts: 8
Joined: Thu Jun 19, 2008 4:06 pm

Re: 24LC00 an I2C Dongle

Post by regenbiegen »

Hallo,

die Signale sehen gut aus und SCL ist mit CL und SDA mit DA verbunden.

Muss ich evtl. Einstellungen von simple-i2c verändern ?

Gruss,
Bernd
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: 24LC00 an I2C Dongle

Post by Christoph Jung »

Wir haben eine neue Version des Simple-I2C. Vllt. klappt es damit besser.

http://www.codemercs.de/uploads/tx_sbdo ... le-I2C.zip
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
regenbiegen
Posts: 8
Joined: Thu Jun 19, 2008 4:06 pm

Re: 24LC00 an I2C Dongle

Post by regenbiegen »

Mit der neuen Version siehts so aus. (siehe Anhang)
Klappt besser, aber es ist wirklich nur ein 24LC00 und nicht 8 ;-)

Gruss,
Bernd
Attachments
24lc00s.PNG
24lc00s.PNG (35.56 KiB) Viewed 9259 times
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: 24LC00 an I2C Dongle

Post by Christoph Jung »

So wie ich das Datenblatt vom 24LC00 verstehe gibt es die Adresse A0 bis AE, weil drei der unteren Bits "egal" sind. Also einfach mal versuchen auf A0 (bzw. 50) zu schreiben.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
regenbiegen
Posts: 8
Joined: Thu Jun 19, 2008 4:06 pm

Re: 24LC00 an I2C Dongle

Post by regenbiegen »

Hallo,

ich hab angefangen zu versuchen das 24LC00 EEPROM auszulesen. Der Code ist an ein Beispiel hier aus dem Forum angelehnt.
Das Problem ist das er auf das IowKitRead bis in alle Ewigkeit wartet, er kommt also nie bis zu dem nachfolgenden printf.

Woran kann das liegen ?

Gruss,
Bernd

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <iowkit.h>

#define repeat 8

int main(int argc, char** argv) {

IOWKIT_HANDLE ioHandle;
IOWKIT_SPECIAL_REPORT report;

ioHandle = IowKitOpenDevice();

if (ioHandle != NULL)
{
printf("success, access device \n");

// reset address pointer
memset(&report, 0x00, IOWKIT_SPECIAL_REPORT_SIZE);
report.ReportID = 0x03; // I2C-Read-Mode, chapter 5.10.1 in IOWarriorDatasheet.pdf
report.Bytes[0] = 0x80; // Start Bit
report.Bytes[1] = 0xA0 | 0x00; // Adress 0xA0 for the 24xx00 EEPROM, LSB=0 for write operation
report.Bytes[2] = 0x00; // reset the EEPROM internal address pointer to 0

printf("IowKitWrite - reset address pointer\n");
IowKitWrite(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);

// read byte
memset(&report, 0x00, IOWKIT_SPECIAL_REPORT_SIZE);
report.ReportID = 0x03; // I2C-Read-Mode, chapter 5.10.1 in IOWarriorDatasheet.pdf
report.Bytes[0] = 0x80; // Start Bit
report.Bytes[1] = 0xA0 | 0x01; // Adress 0xA0 for the 24xx00 EEPROM, LSB=1 for write operation

printf("IowKitWrite - read byte\n");
IowKitWrite(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);
printf("IowKitRead - read byte\n");
IowKitRead(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);

printf("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", report.Bytes[0], report.Bytes[1], report.Bytes[2], report.Bytes[3],
report.Bytes[4], report.Bytes[5], report.Bytes[6], report.Bytes[7]);

IowKitCloseDevice(ioHandle);
} else {
printf("didn't open IoWarrior, handle error");
}

return (0);
}
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: 24LC00 an I2C Dongle

Post by Christoph Jung »

Es fehlt die Initialisierung, dmit der I2C genutzt werden kann. Zudem ist der erste Schreibbefehl fehlerhaft.


IowKitRead() wartet so lange, bis Daten zurückkommen. Wenn nichts zurück kommt, dann "hängt" das Programm. Einfach nach dem IowKitOpenDevice() ein IowKitSetTimeout(ioHandle, 1000) einbauen, damit der Lesevorgang nacht 1 Sekunde abgebrochen wird.


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <iowkit.h>

#define repeat 8

int main(int argc, char** argv) {

IOWKIT_HANDLE ioHandle;
IOWKIT_SPECIAL_REPORT report;

ioHandle = IowKitOpenDevice();
IowKitSetTimeout(ioHandle, 1000); //Timeout für Lesen mit 1 Sekunde

if (ioHandle != NULL)
{
//Initialisieren des IO-Warriors für I2C
memset(&report, 0x00, IOWKIT_SPECIAL_REPORT_SIZE);
report.ReportID = 0x01; //I2C Special Mode
report.Bytes[0] = 0x01; // Enable
report.Bytes[1] = 0x00; // Keine Flags
report.Bytes[2] = 0x00; // Timeout 0 -> 128ms
IowKitWrite(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);


printf("success, access device \n");

// reset address pointer
memset(&report, 0x00, IOWKIT_SPECIAL_REPORT_SIZE);
report.ReportID = 0x02; // I2C-Write-Mode, chapter 5.10.1 in IOWarriorDatasheet.pdf
report.Bytes[0] = 0xC2; // Start Bit + stop bit + 2 Byte zum senden
report.Bytes[1] = 0xA0 | 0x00; // Adress 0xA0 for the 24xx00 EEPROM, LSB=0 for write operation
report.Bytes[2] = 0x00; // reset the EEPROM internal address pointer to 0

printf("IowKitWrite - reset address pointer\n");
IowKitWrite(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);
IowKitRead(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE); //Lesen des ACK Reports

// read byte
memset(&report, 0x00, IOWKIT_SPECIAL_REPORT_SIZE);
report.ReportID = 0x03; // I2C-Read-Mode, chapter 5.10.1 in IOWarriorDatasheet.pdf
report.Bytes[0] = 0x80 + 6; // Start Bit und wieviele Bytes gelesen werden sollen z.B. 6 Bytes
report.Bytes[1] = 0xA0 | 0x01; // Adress 0xA0 for the 24xx00 EEPROM, LSB=1 for write operation

printf("IowKitWrite - read byte\n");
IowKitWrite(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);
printf("IowKitRead - read byte\n");
IowKitRead(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);

printf("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", report.Bytes[0], report.Bytes[1], report.Bytes[2], report.Bytes[3],
report.Bytes[4], report.Bytes[5], report.Bytes[6]);


IowKitCloseDevice(ioHandle);
} else {
printf("didn't open IoWarrior, handle error");
}

return (0);
}


Hoffe ich hab nichts vergessen.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
regenbiegen
Posts: 8
Joined: Thu Jun 19, 2008 4:06 pm

Re: 24LC00 an I2C Dongle

Post by regenbiegen »

Hallo,

Herr Jung erstmal vielen Dank für Ihre Hilfe.
Ich hab das ganze so verändert das jetzt alle 16Bytes vom 24LC00 gelesen werden, und zwar immer vier Bytes auf einmal.

Das Problem ist das das Ergebnis schwankt.

success, access device
IowKitWrite - reset address pointer
0x06 0xaa 0x22 0xff 0xff
0x06 0x74 0x00 0xff 0xff
0x06 0xff 0xff 0xff 0x00
0x06 0xff 0xff 0x5a 0x2a
IowKitWrite - reset address pointer
0x06 0xff 0xff 0xff 0xff
0x06 0x74 0x00 0xff 0xff
0x06 0xff 0xff 0xff 0xff
0x06 0xff 0xff 0x5a 0x2a

Die ersten beiden Bytes sind entweder "0xaa 0x22" oder eben "0xff 0xff".
Schreiben klappt gar nicht.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <iowkit.h>

#define repeat 8


void write16(IOWKIT_HANDLE ioHandle, IOWKIT_SPECIAL_REPORT report)
{
int i;

// reset address pointer
memset(&report, 0x00, IOWKIT_SPECIAL_REPORT_SIZE);
report.ReportID = 0x02; // I2C-Write-Mode, chapter 5.10.1 in IOWarriorDatasheet.pdf
report.Bytes[0] = 0xC2; // Start Bit + stop bit + 2 Byte zum senden
report.Bytes[1] = 0xA0 | 0x00; // Adress 0xA0 for the 24xx00 EEPROM, LSB=0 for write operation
report.Bytes[2] = 0x00; // reset the EEPROM internal address pointer to 0

printf("IowKitWrite - reset address pointer\n");
IowKitWrite(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);
IowKitRead(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE); //Lesen des ACK Reports

for ( i = 0; i < 4; i++)
{
memset(&report, 0x00, IOWKIT_SPECIAL_REPORT_SIZE);
report.ReportID = 0x02; // I2C-Read-Mode, chapter 5.10.1 in IOWarriorDatasheet.pdf
report.Bytes[0] = 0x80 + 4; // Start Bit und wieviele Bytes gelesen werden sollen z.B. 4 Bytes
report.Bytes[1] = 0xA0 | 0x00; // Adress 0xA0 for the 24xx00 EEPROM, LSB=0 for write operation
report.Bytes[2] = 0x51;
report.Bytes[3] = 0x52;
report.Bytes[4] = 0x53;
report.Bytes[5] = 0x54;

IowKitWrite(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);
IowKitRead(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);

printf("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", report.Bytes[0], report.Bytes[1], report.Bytes[2], report.Bytes[3], report.Bytes[4]);
}

}

void read16(IOWKIT_HANDLE ioHandle, IOWKIT_SPECIAL_REPORT report)
{
int i;

// reset address pointer
memset(&report, 0x00, IOWKIT_SPECIAL_REPORT_SIZE);
report.ReportID = 0x02; // I2C-Write-Mode, chapter 5.10.1 in IOWarriorDatasheet.pdf
report.Bytes[0] = 0xC2; // Start Bit + stop bit + 2 Byte zum senden
report.Bytes[1] = 0xA0 | 0x00; // Adress 0xA0 for the 24xx00 EEPROM, LSB=0 for write operation
report.Bytes[2] = 0x00; // reset the EEPROM internal address pointer to 0

printf("IowKitWrite - reset address pointer\n");
IowKitWrite(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);
IowKitRead(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE); //Lesen des ACK Reports

for ( i = 0; i < 4; i++)
{
memset(&report, 0x00, IOWKIT_SPECIAL_REPORT_SIZE);
report.ReportID = 0x03; // I2C-Read-Mode, chapter 5.10.1 in IOWarriorDatasheet.pdf
report.Bytes[0] = 0x80 + 4; // Start Bit und wieviele Bytes gelesen werden sollen z.B. 4 Bytes
report.Bytes[1] = 0xA0 | 0x01; // Adress 0xA0 for the 24xx00 EEPROM, LSB=1 for read operation

IowKitWrite(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);
IowKitRead(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);

printf("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", report.Bytes[0], report.Bytes[1], report.Bytes[2], report.Bytes[3], report.Bytes[4]);
}

}

int main(int argc, char** argv)
{
IOWKIT_HANDLE ioHandle;
IOWKIT_SPECIAL_REPORT report;

ioHandle = IowKitOpenDevice();
IowKitSetTimeout(ioHandle, 1000); //Timeout für Lesen mit 1 Sekunde

if (ioHandle != NULL)
{
//Initialisieren des IO-Warriors für I2C
memset(&report, 0x00, IOWKIT_SPECIAL_REPORT_SIZE);
report.ReportID = 0x01; //I2C Special Mode
report.Bytes[0] = 0x01; // Enable
report.Bytes[1] = 0x00; // Keine Flags
report.Bytes[2] = 0x00; // Timeout 0 -> 128ms
IowKitWrite(ioHandle, IOW_PIPE_SPECIAL_MODE, (char*) &report, IOWKIT_SPECIAL_REPORT_SIZE);

printf("success, access device \n");

read16(ioHandle, report);
sleep(1);
// write16(ioHandle, report);
sleep(1);
read16(ioHandle, report);

IowKitCloseDevice(ioHandle);
} else {
printf("didn't open IoWarrior, handle error");
}

return (0);
}
User avatar
Christoph Jung
Posts: 670
Joined: Sun Oct 08, 2006 3:43 pm
Location: Germany / Berlin
Contact:

Re: 24LC00 an I2C Dongle

Post by Christoph Jung »

....
for ( i = 0; i < 4; i++)
{
memset(&report, 0x00, IOWKIT_SPECIAL_REPORT_SIZE);
report.ReportID = 0x02; // I2C-Read-Mode, chapter 5.10.1 in IOWarriorDatasheet.pdf
report.Bytes[0] = 0xC0 + 1 + 4; // Start Bit und wieviele Bytes gelesen werden sollen z.B. 4 Bytes
report.Bytes[1] = 0xA0 | 0x00; // Adress 0xA0 for the 24xx00 EEPROM, LSB=0 for write operation
report.Bytes[2] = 0x51;
report.Bytes[3] = 0x52;
report.Bytes[4] = 0x53;
report.Bytes[5] = 0x54;
....


Das Addressbyte zählt auch zu den zu sendenden Bytes. Also muss das mit in die Anzahl einfließen.
Dann sollte man auch ein Stop-Bit setzten, damit der Report beendet wird. Ansonsten weiß der Chip ja nicht was er nun machen soll und verwirft evtl. die geschriebenen Daten. Das sollte im Datenblatt zum 24LC00 stehen, wie man was schreiben muss.

Ansonsten einfach mit dem Simple-I2C oder den All-In-One tool lesen und schauen was das dazu sagt.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
Post Reply