Forum: Mikrocontroller und Digitale Elektronik EDIPTFT32 gibt falschen ACK zurück.


von Maik G. (maik_l)


Lesenswert?

Moin zusammen.

Ich versuche seit Wochen ein ACK zu erreichen, weiß gerade nur nicht, ob 
ich da einem Denkfehler auf dem leim gegangen bin wie bei der Auswahl 
des Übertragungsmodus...
Dies habe ich nunmehr erfolgreich zum laufen bekommen...
Daten welche auf dem Display erscheinen sollen, werden auch sauber 
dargestellt.

Nur sowie ich einen das ACK haben will, bekomme ich alles nur kein ACK 
bzw NAK.

der Code schaut wie folgt aus...
1
#include <iostream>
2
#include <sstream>
3
#include <string>
4
#include <stdlib.h>
5
#include </home/satan/Programming/APIs/gnublin.h>
6
#include </home/satan/Programming/APIs/TestColor.h>
7
8
9
using namespace std;
10
11
/* const for eDIP-Display ; Kontroll */
12
unsigned int    Read    = 0x6F;
13
unsigned char   bcc     = 0x00;
14
char            DC1     = 0x11;
15
char            DC2     = 0x12;
16
char            _1      = 0x01;
17
char            _2      = 0x02;
18
char            _3      = 0x03;
19
char            D       = 0x44;
20
char            I       = 0x49;
21
char            S       = 0x53;
22
23
/* var for eDIP-Display ; Data */
24
25
unsigned char   sbbr, rbbf;     /* [S]end [B]uffer [B]yte [R]eady
26
                                   [R]eceive [B]uffer [B]yte [F]ree */
27
uint8_t         ACK;            /* Read ACK from eDIP-Display */
28
unsigned char   _DC2, __2;
29
30
31
#define rt_Bar "#fb,3,8,1,"
32
#define gn_Bar "#fb,4,8,1,"
33
#define bl_Bar "#fb,2,8,1,"
34
35
gnublin_i2c I2C;
36
37
void ReadSender(){
38
    bcc = 0;
39
    cout << "Sende " << DC2 << " Status: " << I2C.send(DC2) << "\n";
40
    cout << "Sende " << _1 << " Status: " << I2C.send(_1) << "\n";
41
    cout << "Sende " << S << " Status: " << I2C.send(S) << "\n";
42
    bcc = DC2 + _1 + S;
43
    cout << "Sende " << bcc << " Status: " << I2C.send(bcc) << "\n";
44
    I2C.receive(&ACK, 1);
45
    cout << "Lese " << ACK << "\n";
46
    printf ("Versuche ACK zu lesen: %x\n", ACK);
47
48
}
49
50
void ReadBuffer(){
51
    bcc = 0;
52
    cout << "Sende " << DC2 << " Status: " << I2C.send(DC2) << "\n";
53
    cout << "Sende " << _1 << " Status: " << I2C.send(_1) << "\n";
54
    cout << "Sende " << I << " Status: " << I2C.send(I) << "\n";
55
    bcc = DC2 + _1 + I;
56
    I2C.receive(&ACK, 1);
57
    cout << "Lese " << ACK << "\n";
58
    cout << "\tLese Buffer:";
59
    if (I2C.receive((unsigned char*)_DC2, 1) != 1){
60
        cout << I2C.getErrorMessage() << "\n";
61
    }
62
    if (I2C.receive((unsigned char*)__2, 1) != 1){
63
        cout << I2C.getErrorMessage() << "\n";
64
    }
65
    if (I2C.receive((unsigned char*)sbbr, 1) != 1){
66
        cout << I2C.getErrorMessage() << "\n";
67
    }
68
    if (I2C.receive((unsigned char*)rbbf, 1) != 1){
69
        cout << I2C.getErrorMessage() << "\n";
70
    }
71
    cout << "\tDaten zu 100% geladen...\nDC in: " << _DC2 << "\n2 in: " << __2;
72
    cout << "\nsbbr in: " << sbbr << "\nfbbr in:" << rbbf << "\n";
73
}
74
75
void SendData(string Data){
76
77
    unsigned char lang= Data.length();
78
79
    stringstream sData;
80
    bcc = 0;
81
    sData << Data;
82
83
    cout << "Sende " << DC1 << " Status: " << I2C.send(DC1) << "\n";
84
    cout << "Sende " << lang << " Status: " << I2C.send(lang) << "\n";
85
86
    for (unsigned int a=0; a < lang; a++){
87
        cout << "Sende " << Data[a] << " Status: " << I2C.send(Data[a]) << "\n";
88
    }
89
90
    uint8_t response;
91
    cout << "Versuche ACK zu lesen: " << I2C.receive(&response, 1) << " Rückgabe: " << response ;
92
93
}
94
95
int main()
96
{
97
    cout << "Start I2C-1: " << I2C.setAddress(Read) << "\n";
98
    cout << "Slave found at: " << I2C.getAddress() << "\n";
99
100
    SendData("\x23""H75,");
101
    SendData("\x23""TI,");
102
    SendData("\x23""SV,");
103
    ReadSender();
104
}

Echt keinen plan, warum ich bei ReadSender kein ACK/NAK bekomme sonder 
irgendwelchen Datenmüll.
Hat jemand von euch eine Idee?

Zusatzinfo: Programme schreibe ich alle mit Code:Blocks und arbeite auf 
den GNUBLIN Systemboards.

von Peter D. (peda)


Lesenswert?

Ich kenn Deine I2C-Lib ja nicht, aber üblicher Weise braucht man auch 
die Funktionen Start, sende Adresse+R/W und Stop.

Versuch doch erstmal, einen standard I2C-Slave im Page-Mode zuzugreifen, 
z.B EEPROM 24C64.

Es sieht auch nicht sonderlich übersichtlich aus, wenn man Funktions- 
und Debug-Code miteinander verwurstet. Ich würde dafür wenigstens 
separate Zeilen nehmen.

Besser wäre natürlich, daß man nur bei falschen Ergebnissen in einen 
Fehlerabbruch geht, der dann den Fehler ausgibt. Es ist ja in der Regel 
sinnlos, bei einem Fehler mit dem nächsten Schritt weiter zu machen.
Und bei einem I2C-Fehler muß man ja wenigstens noch ein Stop senden, um 
den Bus wieder in den Ruhezustand zu bringen.

P.S.:
IMHO muß man auch die Paketlänge und die korrekte CRC senden, sonst 
kommt natürlich kein ACK.

: Bearbeitet durch User
von Maik G. (maik_l)


Lesenswert?

Peter Dannegger schrieb:
> Ich kenn Deine I2C-Lib ja nicht, aber üblicher Weise braucht man auch
> die Funktionen Start, sende Adresse+R/W und Stop.

wird alles durch die API 
http://gnublin.org/gnublin-api/doc/html_de/classgnublin__i2c.html 
gesteuert...

> Versuch doch erstmal, einen standard I2C-Slave im Page-Mode zuzugreifen,
> z.B EEPROM 24C64.

Ähmmm da seh ich aber keine Daten soweit ich das im Filter habe...

> Es sieht auch nicht sonderlich übersichtlich aus, wenn man Funktions-
> und Debug-Code miteinander verwurstet. Ich würde dafür wenigstens
> separate Zeilen nehmen.

Jedesmal rein und raus ebenso bescheiden. die von dir erwähnten 
Debugzeilen fliegen sowieso, wenn ich ein ACK bzw NAK sehe...

> Besser wäre natürlich, daß man nur bei falschen Ergebnissen in einen
> Fehlerabbruch geht, der dann den Fehler ausgibt. Es ist ja in der Regel
> sinnlos, bei einem Fehler mit dem nächsten Schritt weiter zu machen.
> Und bei einem I2C-Fehler muß man ja wenigstens noch ein Stop senden, um
> den Bus wieder in den Ruhezustand zu bringen.

Fehlerabbruche habe ich Bisher keine gehabt. sonst läuft das Programm ja 
wie es soll... erhalte im ACSII-Modus nur kein ACK / NAK. Egal, ob ich 
bcc mit sende oder nicht. Im beschriebenen BINÄR-Modus arbeitet das 
System nicht.

> P.S.:
> IMHO muß man auch die Paketlänge und die korrekte CRC senden, sonst
> kommt natürlich kein ACK.

Soviel zum Thema Paketlänge...
1
    I2C.send(lang);

von Peter D. (peda)


Lesenswert?

Maik LoveNigth schrieb:
> wird alles durch die API
> http://gnublin.org/gnublin-api/doc/html_de/classgnublin__i2c.html
> gesteuert...

Na wenn Du das sagst.
Ich würds trotzdem erstmal mit einem EEPROM testen.

Maik LoveNigth schrieb:
>> Versuch doch erstmal, einen standard I2C-Slave im Page-Mode zuzugreifen,
>> z.B EEPROM 24C64.
>
> Ähmmm da seh ich aber keine Daten soweit ich das im Filter habe...

Du schreibst was rein "Hallo Welt" und dann liest Du es aus.

Maik LoveNigth schrieb:
> Soviel zum Thema Paketlänge...    I2C.send(lang);

Genau das meinte ich mit verwursten. In den riesen Debugausgaben 
übersieht man leicht die Funktion.
Und was machst Du, wenn die Daten 0-Bytes enthalten?
Und wo wird die CRC gesendet?

von Maik G. (maik_l)


Lesenswert?

Peter Dannegger schrieb:
> Maik LoveNigth schrieb:
>> wird alles durch die API
>> http://gnublin.org/gnublin-api/doc/html_de/classgnublin__i2c.html
>> gesteuert...
>
> Na wenn Du das sagst.
> Ich würds trotzdem erstmal mit einem EEPROM testen.
>
> Maik LoveNigth schrieb:
>>> Versuch doch erstmal, einen standard I2C-Slave im Page-Mode zuzugreifen,
>>> z.B EEPROM 24C64.
Schauen, ob ich noch einen alten finde... Mach mir da a keine Hoffnung.
Bestellen??? Hmmm. Mindesbestellwert?!
> Maik LoveNigth schrieb:
>> Soviel zum Thema Paketlänge...    I2C.send(lang);
>
> Genau das meinte ich mit verwursten. In den riesen Debugausgaben
> übersieht man leicht die Funktion.

Da geb ich dir recht... Aber wer schreibt darf sowas nicht übersehen, 
und wenn doch muß er halt Trafic in kauf nehmen.
Bei so kleinen sachen geht das ja noch aber wenn es ü 2K zeilen Code 
sind... Aber wir verstehen uns.
> Und was machst Du, wenn die Daten 0-Bytes enthalten?

[c]if (Data != '')
     {
     Anweisung
     }

Darüber mach ich mir gedanken, wenn es soweit kommen sollte.
> Und wo wird die CRC gesendet?

Wenn du mit CRC das im Datesheet beschriebene bbc meinst...
Spielt keine Rolle, ob ich das im ACSII-Modus mitschicke oder nicht...

ACK Ist und bleibt <> 0x06 und NAK <> 0x15

und das ist das KERNPROBLEM...
Habe hier Sehr viele Themen gefunden, was dieses TFT-Display angeht, NUR 
Nicht die Bohne, wie das mit dem ACK gelöst wurde...

Wie gesagt... Selbst wenn ich es mir eine 24cxx teste wird das ergebnis 
das selbe sein... Das weiß ich jetzt schon...

Edit: Ob ich das nun via RS, I²C oder SPI mache spielt keine Rolle... 
das Problem ist und bleibt das selbe...

: Bearbeitet durch User
von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Ich kann Dir ja mal meinen funktionierenden Code zeigen.
Er läuft auf dem ATmega2560 über die UART3.

Ich hab die UART genommen, weil man da nicht irgendwelche Wartezeiten 
einbauen muß.
Bei I2C oder SPI muß man das nämlich.

von Maik G. (maik_l)


Lesenswert?

Hmmm...

Ich hab so einen Leisen verdacht, als ob ich das Problem erahne...
Da ich ja mit "enDebian" also Systemboard arbeite werd ich wohl ein 
Problem mit dem Timings bekommen...

setzt mich heut Abend nochmal ran...

von Maik G. (maik_l)


Lesenswert?

Moin peda.

Hab hier nochmal das Programm ohne Debug.
1
#include <cstdio>
2
#include <iostream>
3
#include <sstream>
4
#include <string>
5
#include <stdlib.h>
6
7
//#include with phad
8
#include </home/satan/Programming/APIs/gnublin.h>
9
10
using namespace std;
11
12
/* const for eDIP-Display ; Kontroll */
13
unsigned int    Read    = 0x6F;
14
unsigned char   bcc     = 0x00;
15
char            DC1     = 0x11;
16
char            DC2     = 0x12;
17
char            _1      = 0x01;
18
char            _2      = 0x02;
19
char            _3      = 0x03;
20
char            D       = 0x44;
21
char            I       = 0x49;
22
char            S       = 0x53;
23
24
/* var for eDIP-Display ; Data */
25
26
unsigned char   sbbr, rbbf;     /* [S]end [B]uffer [B]yte [R]eady
27
                                   [R]eceive [B]uffer [B]yte [F]ree */
28
uint8_t         ACK;            /* Read ACK from eDIP-Display */
29
unsigned char   _DC2, __2;
30
31
32
#define rt_Bar "#fb,3,8,1,"
33
#define gn_Bar "#fb,4,8,1,"
34
#define bl_Bar "#fb,2,8,1,"
35
36
gnublin_i2c I2C;
37
38
void ReadSender(){
39
    bcc = 0;
40
    I2C.send(DC2);
41
    I2C.send(_1);
42
    I2C.send(S);
43
    bcc = DC2 + _1 + S;
44
    I2C.send(bcc);
45
    I2C.receive(&ACK, 1);
46
    cout << "Lese " << ACK << "\n";
47
48
}
49
50
void ReadBuffer(){
51
    bcc = 0;
52
    I2C.send(DC2);
53
    I2C.send(_1);
54
    I2C.send(I);
55
    bcc = DC2 + _1 + I;
56
//    cout << "Sende " << bcc << " Status: " << I2C.send(bcc) << "\n";
57
    I2C.receive(&ACK, 1);
58
    cout << "Lese " << ACK << "\n";
59
    cout << "\tLese Buffer:";
60
    I2C.receive((unsigned char*)_DC2, 1);
61
    I2C.receive((unsigned char*)__2, 1);
62
    I2C.receive((unsigned char*)sbbr, 1);
63
    I2C.receive((unsigned char*)rbbf, 1);
64
    cout << "\tDC in: " << _DC2 << "\n2 in: " << __2;
65
    cout << "\nsbbr in: " << sbbr << "\nfbbr in:" << rbbf << "\n";
66
}
67
68
void SendData(string Data){
69
70
    unsigned char lang= Data.length();
71
72
    stringstream sData;
73
    bcc = 0;
74
    sData << Data;
75
76
    I2C.send(DC1);
77
    I2C.send(lang);
78
79
    for (unsigned int a=0; a < lang; a++){
80
        I2C.send(Data[a]);
81
    }
82
83
    uint8_t response;
84
85
    cout << "Versuche ACK zu lesen: " << I2C.receive(&response, 1) << " Rückgabe: " << response ;
86
}
87
88
int main()
89
{
90
    
91
    I2C.setAddress(Read);
92
    cout << "Slave found at: " << I2C.getAddress() << "\n";
93
94
    SendData("\x23""H75,");
95
    SendData("\x23""TI,");
96
    SendData("\x23""SV,");
97
    ReadBuffer();
98
    ReadSender();
99
}

Bin nur noch am überlegen, wie ich das mit dem udelay hinwerfe. Habe 
keine bescheide .h auf dem System liegen und codeblocks liefert wohl 
keine.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.