Forum: Mikrocontroller und Digitale Elektronik S1D13700 Init Timing Fehler


von Christoph (Gast)


Lesenswert?

Hallo Leute.

Ich versuche schon länger ein 320x240 Display mit einem EPSON 
S1D1370002A1 zum rennen zu bekommen.

Mein Problem ist das irgendwas an der Init faul ist.
Ich habe das Teil bei Ebay gekauft und an einem Festrechner mit LCDInfo 
getestet. Es funktioniert prima.

Dann habe ich mich daran gemacht mit einem ATMEGA32 rumzuspielen.
Alle nötigen Pins habe ich verbunden und auch die Init habe ich mir 
angeschaut und umgesetzt. Die Kommunikation selbst funktioniert 
einwandfrei.

Das Problem ist, das das Teil scheinbar von der Mondphase abhängt.
Manchmal geht es an, manchmal nicht. Ich vermute das hat irgendwas mit 
den Timings zu tun.

Im folgenden meine Funktionen für Init und Kommunikation.
Meine Init:
1
void LcdInit(void)
2
{
3
  unsigned char ucDelay = 0,ucStartTime;
4
  unsigned int uiDelay = 0, uiStartTime;
5
  DATADIR |= 0xFF;
6
  CONTROLDIR |= ((1 << CDPIN) | (1 << CSPIN) |
7
                 (1 << RDPIN) | (1 << WRPIN) | (1 <<RSTPIN));
8
  RSTHIGH;
9
  WRLOW;
10
  RDLOW;
11
  CSLOW;
12
  EPSONDATA;
13
14
  ucDelay = 0;
15
  ucStartTime = TimerGet1SecTick();
16
  while (ucDelay < 3) // wait 3 sec
17
    ucDelay = TimerGet1SecDiff(ucStartTime);
18
19
  EpsonSendCmd(0x40); // SystemSet
20
21
  uiDelay = 0;
22
  uiStartTime = TimerGet1MSecTick();
23
  while (uiDelay < 40) // wait 200 msec
24
    uiDelay = TimerGet1MSecDiff(uiStartTime);
25
26
  EpsonSendData1(0x30);
27
  EpsonSendData1(0x05); // char width in px -1 (here 6)
28
  EpsonSendData1(0x07); // char height -1 (here 8)
29
  EpsonSendData1(0x34); // number of chars per row
30
  EpsonSendData1(0x87); // width
31
  EpsonSendData1(0xEF); // height 240 lines
32
  EpsonSendData1(0x35); // horizontal adress range register
33
  EpsonSendData1(0x00); 
34
35
  ucDelay = 0;
36
  ucStartTime = TimerGet1SecTick();
37
  while (ucDelay < 3) // wait 3 sec
38
    ucDelay = TimerGet1SecDiff(ucStartTime);
39
40
  EpsonSendCmd(0x40); // SystemSet
41
42
  uiDelay = 0;
43
  uiStartTime = TimerGet1MSecTick();
44
  while (uiDelay < 40) // wait 200 msec
45
    uiDelay = TimerGet1MSecDiff(uiStartTime);
46
47
  EpsonSendData1(0x30);
48
  EpsonSendData1(0x05); // char width in px -1 (here 6)
49
  EpsonSendData1(0x07); // char height -1 (here 8)
50
  EpsonSendData1(0x34); // number of chars per row
51
  EpsonSendData1(0x87); // width
52
  EpsonSendData1(0xEF); // height 240 lines
53
  EpsonSendData1(0x35); // horizontal adress range register
54
  EpsonSendData1(0x00); 
55
56
  uiDelay = 0;
57
  uiStartTime = TimerGet1MSecTick();
58
  while (uiDelay < 0xFF) // wait 200 msec
59
    uiDelay = TimerGet1MSecDiff(uiStartTime);
60
61
  EpsonSendCmd(0x44);               // SCROLL
62
  EpsonSendData2((unsigned int)(DISP1HOME));   // layer 1 home adress
63
  EpsonSendData1(0xFE);             // 240 Lines
64
  EpsonSendData2((unsigned int)(DISP2HOME));   // layer 2 home adress
65
  EpsonSendData1(0xFE);             // 240 Lines
66
  EpsonSendData2((unsigned int)(DISP3HOME));   // layer 3 home adress
67
  EpsonSendData2((unsigned int)0x0000);             // Dont care
68
69
  EpsonSendCmd(0x58); // DISPON/OFF
70
  EpsonSendData1(0x14); // no flash no cursor
71
72
  EpsonSendCmd(0x4C);          // Cursor direction right
73
74
  EpsonSendCmd(0x5B); // OVLAY
75
  EpsonSendData1(0x01); // ORMODE
76
77
  EpsonSendCmd(0x5A); // HDOTSCR
78
  EpsonSendData1(0x00);
79
80
  LcdClearLayer(1);
81
82
  uiDelay = 0;
83
  uiStartTime = TimerGet1MSecTick();
84
  while (uiDelay < 200) // wait 20 msec
85
    uiDelay = TimerGet1MSecDiff(uiStartTime);
86
87
  LcdClearLayer(2);
88
89
  uiDelay = 0;
90
  uiStartTime = TimerGet1MSecTick();
91
  while (uiDelay < 200) // wait 20 msec
92
    uiDelay = TimerGet1MSecDiff(uiStartTime);
93
94
  LcdClearLayer(3);
95
96
  uiDelay = 0;
97
  uiStartTime = TimerGet1MSecTick();
98
  while (uiDelay < 200) // wait 20 msec
99
    uiDelay = TimerGet1MSecDiff(uiStartTime);
100
101
  EpsonSendCmd(0x59); // DISPON/OFF
102
  EpsonSendData1(0x14); // no flash no cursor
103
  return;
104
}
105
106
void slope(unsigned char cnt)
107
{
108
  unsigned char i;
109
  for (i=0; i < cnt; i++)
110
    asm volatile("nop");
111
}
112
113
void EpsonSendCmd(unsigned char cmd)
114
{
115
  EPSONCMD;
116
  WRHIGH;
117
  CSHIGH;
118
  RDHIGH;
119
  DATAPORT = cmd;
120
  slope(20);
121
  CSLOW;
122
  slope(20);
123
  WRLOW;
124
  slope(20);
125
  WRHIGH;
126
  slope(20);
127
  CSHIGH;
128
}
129
130
131
void EpsonSendData1(unsigned char cmd)
132
{
133
  EPSONDATA;
134
  WRHIGH;
135
  CSHIGH;
136
  RDHIGH;
137
  DATAPORT = cmd;
138
  slope(20);
139
  CSLOW;
140
  slope(20);
141
  WRLOW;
142
  slope(20);  
143
  WRHIGH;
144
  slope(20);
145
  CSHIGH;
146
  EPSONCMD;
147
}
Data2 macht nichts anderes als zwei mal Data1 mit gesplittetem int 
aufzurufen.

Die Timerfunktionen sollten korrekt arbeiten. Da ich kein Oszi hab konte 
ich das nur über ein sekündliches Blinken in der Mainschleife 
überprüfen.
Im Datenblatt hab ich gelesen das die Karre ein bisschen Zeit braucht 
bis sie bereit für Befehle ist, das hab ich mit einigen Sekunden 
reichlich bemessen.

Wie gesagt, wenn es wirklich angeht, dann funktioniert auch mein 
restlicher Code. Der Knackpunkt ist wahrscheinlich wirklich wie ich 
sicher und reproduzierbar aus dem Sleepmode rauskomme. In den meisten 
Fällen sehe ich nur ein kurzes Leuchten der Hintergrundbeleuchtung 
unmittelbar nach der Init und dann ist Schluss.

Wenn irgendjemand mit dem Teil schon Erfahrungen gemacht hat wär ich 
dankbar für einen Hinweise.

Ach so: Clock sind ext. 16MHz und 24MHz am EPSON.
Mit internem 8MHz Clock hab ich auch schon probiert, geht auch nicht.

mfG
Christoph

von Wolfgang-G (Gast)


Lesenswert?

ich häng mich nur mal an, da ich Probleme mit S1D13305 habe

von Peter B. (atmelfriend)


Lesenswert?

Ich habe hier ein Hitachi Display 320x240. Als Controller wird ein 
S1D13700 benutzt. Der haengt direkt am Adress/Datenbus von einem ATMega 
1281, Modus also Generic Direct.
Da ich dummerweise einen 40 MHz Oberton Quartz gekauft habe, laeuft der 
SID13700 bis ich den richtigen Quartz habe mit einem 25MHz Quartz. Hat 
den Nachteil, der zum Testen nicht so wild ist, das ich die 16 MHz Clock 
vom ATMega durch 2 teilen muss, sonst ist er zu schnell.
Es werden 3 Grafik Layers benutzt, kein Text Layer.
Anbei die Initialisierung:

    //Reset the chip
    S1d13700_Res_act;
    delay_ms(2);
    S1d13700_Res_inact
    delay_ms(5);

    //Exit sleep mode after reset
    S1d13700_Command;       //Set virtual a15 to 1
    S1_PSMR = 0x00;         //8008
    delay_us(100);
    S1_MCR = 0x30;          //Dummy write, see manual 8000
    delay_us(100);

    S1_MCR = 0x30;          //Single panel 8000
    S1_HCSR = 87;           //FX 8001
    S1_VCSR = 00;           //FY 8002

    S1_CBPRR = 39;          //Bytes per line (320 / 8) - 1 8003
//    S1_TCBPRR = 0xa9;         //Calculatory 40 MHz 8004
    S1_TCBPRR = 100;        //25 MHz
    S1_FHR = 239;           //240 lines 8005

    S1_HARR0 = 40;         //8006
    S1_HARR1 = 0;           //8007

    //First screen block starts at 0
    S1_SB1AR0 = 0x00;       //800b
    S1_SB1AR1 = 0x00;       //800c
    S1_SB1SR = 239;         //800d
    //Second screen block starts at 2580h = 320/8 * 240
    S1_SB2AR0 = 0x80;
    S1_SB2AR1 = 0x25;
    S1_SB2SR = 239;
    //Third screen block
    S1_SB3AR0 = 0x00;       //8011
    S1_SB3AR1 = 0x4b;       //8012
    //Forth screen block
    S1_SB4AR0 = 0x00;       //8013
    S1_SB4AR1 = 0x00;       //8014

    //Cursor, anyway not needed
    S1_CWR = 0x07;          //8015
    S1_CHR = 0x87;          //8016
    S1_DAR = 0x54;          //Display screen block 1..3 800a
    S1_CSDR = 0x00;         //Cursor shift direction 8017

    //Horizontal pixel scroll
    S1_HPSR =0x00;         //801b
    //Overlay control
    S1_OR = 0x1c;           //3 grafic layers, OR mode 8018


    #ifdef DEBUG_GEN
      printf("S1D13700: ");
    #endif
    if(S1_MCR != 0x30)
    {
        S1_DER = 0x00;          //Display off to avoid demages
        global_err = GLB_ERR_S1;
        #ifdef DEBUG_GEN
          printf("FAILURE!\r\n");
        #endif
    }
    else
    {
        S1_DER = 0x01;          //Display enable 8009
        #ifdef DEBUG_GEN
          printf("OK\r\n");
        #endif
    }

    //Erase the chip memory
    S1d13700_Data;                                      //Set the 
virtual A15 to Low
    memset((unsigned char*)S1d13700_MEMSTART, 0x00, S1d13700_MEMSIZE);

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.