Hi, ich hab da mal ein kleines Problem bei der I2C und dem PIC18F4455
oder auch 18F4550.
Nur vorweg, der I2C Bus geht von der Hardware her zu 100%.
Ich habe angefangen mit USB rumzuspielen, als erstes mit dem Treiber von
Microchip nun will ich das ganze als HID laufen lassen. Die USB Seite
klappt soweit auch gut. Nur gibt es seit dem ich auf den HID Stack
umgestiegen bin, Probleme bei der I2C Schnittstelle.
Ich versuche momentan, einfach nur ein Paar Zeichen über die I2C zu
senden, als Beispiel an ein EEPROM. Dazu nehme ich die von Microchip in
der C Libare vorhandene EEPageWrite funktion. Dies klappt dan auch
Problemlos. Sobald ich aber, die Funktion aus der Quelldatei in meinen
Quellcode Kopiere und in EEPageWrite2 umbenenne, funktioniert diese
nicht mehr.
Geht
while(SSPCON2bits.SEN);// wait until start condition is over
6
if(PIR2bits.BCLIF)// test for bus collision
7
{
8
return(-1);// return with Bus Collision error
9
}
10
else
11
{
12
if(WriteI2C(control))// write 1 byte - R/W bit should be 0
13
{
14
StopI2C();
15
return(-3);// return with write collision error
16
}
17
18
//IdleI2C(); // ensure module is idle
19
if(!SSPCON2bits.ACKSTAT)// test for ACK condition, if received
20
{
21
if(WriteI2C(address))// write address byte to EEPROM
22
{
23
StopI2C();
24
return(-3);// return with write collision error
25
}
26
27
//IdleI2C(); // ensure module is idle
28
if(!SSPCON2bits.ACKSTAT)// test for ACK condition, if received
29
{
30
if(putsI2C(wrptr))
31
{
32
StopI2C();
33
return(-4);// bus device responded possible error
34
}
35
}
36
else
37
{
38
StopI2C();
39
return(-2);// return with Not Ack error
40
}
41
}
42
else
43
{
44
StopI2C();
45
return(-2);// return with Not Ack error
46
}
47
}
48
49
//IdleI2C(); // ensure module is idle
50
StopI2C();// send STOP condition
51
while(SSPCON2bits.PEN);// wait until stop condition is over
52
if(PIR2bits.BCLIF)// test for Bus collision
53
{
54
return(-1);// return with Bus Collision error
55
}
56
return(0);// return with no error
57
}
58
59
unsignedcharsend_x(void)
60
{
61
ReceivedDataBuffer[0]=2;
62
ReceivedDataBuffer[1]=3;
63
ReceivedDataBuffer[2]=4;
64
ReceivedDataBuffer[3]=5;
65
ReceivedDataBuffer[4]=0x00;
66
67
EEPageWrite2(0x42,0x01,ReceivedDataBuffer);
68
return0;
69
}
Er steigt mir jedesmal bei „if ( WriteI2C( control ) ) // write 1
byte - R/W bit should be 0“ aus.
Nun hab ich mir mal Disassemblerlisting angesehn. Da die Funktion ja 1
zu 1 Kopiert wurde, sollte der Compiler in beiden Fällen einen
identischen code erstellen. Leider sind im Code, erhebliche
Abweichungen.
Geht
1484: if ( !SSPCON2bits.ACKSTAT ) // test for ACK condition, if received
Hat vielleicht jemand von euch eine Erklärung. Zum einen Woran es liegen
könnte und zum anderen, warum bei einem copy und past sich der
assemblercode so verkürtzt.
Moin,
wenn es eine selbstgebaute Hardware ist und nicht top secret könnteste
das doch auch mal posten.
Wenn du allerdings vollkommen sicher bist das es 100% von der
Softwareseite kommt...
Gruß
Andi
Bin mir zu 200% sicher das es nicht von der Hardware kommt.
Habe 3 Aufbauten, prototy, PICDEM Boardund nun eine LP von nem LP
HErsteller.
Alle 3 mit verschiedenen PIC's.
Wie schon erwähnt,existieren ja 2 Versionen von der Software, 1x mit
Microchip DLL und 1x mit HID Treiber.
Wenn ich die Firmware, von der Microchip DLL verwende, geht die I2C auf
allen 3 Boards zu 100%.
Wenn ichnun die andere HID Version aufspiele, gehen nur noch die
Original I2C Routinen von Microchip, selbst ein Copy und Past vom
Original und umbenennen des Funktionsaufrufes geht nicht mehr.
Wenn ich mir dann noch das Disassemblerlisting ansehe, finde ich den
unterschied schon erheblich.
Also es muss irgendwo in der Firmware liegen. Ich tippe eher auf
irgendeine Compileranweisung, wodurch der unterschied zustrande kommt.
Achso. Ein angeschlossener PICit Serial analyser, kann auch ohne
Probleme alles ansprechen.
Wennihr wollt, kannich den Quellcodegerne gerne hochladen.
Sobald oben bugy definiert wird, Fängt der Compiler an, seine „feature“
zu zeigen.
Im ersten Durchlauf, die Zeile kommentiert lassen.
Im Disassembly Listing nach „The next line is translated“ suchen.
Es sollte hier das dabei Herauskommen:
1334: // The next line is translated properly.
1335: if ( WriteI2C( control ) ) // write 1 byte -
R/W bit should be 0
25BE 0EFE MOVLW 0xfe
25C0 D88F RCALL 0x26e0
25C2 E105 BNZ 0x25ce
26E0 CFDB MOVFF 0xfdb, 0xfe6
26E2 FFE6 NOP
26E4 EC57 CALL 0x2cae, 0
26E6 F016 NOP
26E8 52E5 MOVF 0xfe5, F, ACCESS
26EA 0900 IORLW 0
26EC 0012 RETURN 0
1336: {
1337: StopI2C();
Im zweiten Durchlauf, den Kommentar '//' vor bugy entfernen.
Im Disassembly Listing nach „The next line is translated“ suchen.
Es sollte hier das dabei Herauskommen:
1334: // The next line is translated properly.
1335: if ( WriteI2C( control ) ) // write 1 byte -
R/W bit should be 0
25BE 0EFE MOVLW 0xfe
25C0 D8AC RCALL 0x271a
25C2 0900 IORLW 0
25C4 E106 BNZ 0x25d2
1336: {
1337: StopI2C();
Durch das definieren von Bugy wird am ende, der Inhalt der Funktion
write_ext_eeprom eingefügt.
Dies sollte aber bei der oben gelisteten Funktion keinen unterschied
ausmachen. Er dürfte höchstens, den Code an eine andere stelle packen,
was er aber selbst in dem Fall nicht macht. Der Compiler baut aus meiner
Sicht einfach nen riesen Mist.
Wieso bewirkt das simple hinzufügen von ein paar I2C Routinen, so einem
fatalen Fehler an einer anderen stelle.
„It's not a bug, it's a feature „