XMega, DOGXL & SD-Karte

Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2133
Registered: 03 / 2003
Subject:

XMega, DOGXL & SD-Karte

 · 
Posted: 11.05.2012 - 17:33  ·  #1
Hallo @ all,

Diesen Thread vom DOGXL-Display mit XMega128-A3 kennt ja vielleicht der eine oder andere und das funktioniert ja auch soweit. Ich habe mich nun getraut den SD-Kartenslot mit einer SD-Karte (1 GByte, FAT) zu bestücken. Auf der SD-Karte ist ein txt-File mit ca. 4000 Zeilen je bis zu 250 Zeichen.
Das Display hat eine Hintergrundbeleuchtung die per SoftPWM mit Transistor an PortA, 0..2 hängt.

Ich greife auf die SD-Karte zu und lese die Zeilen und sobald ich das mache, fängt die Beleuchtung zu flackern an wie bekloppt. Hab auch schon den SoftPWM komplett entfernt und die HG-Beleuchtung komplett abgeschaltet. Wenn ich dann auf die Datei zugreife (man glaubt es kaum) schaltet die HG-Beleuchtung ein und flackert. Ripple während des Zugriffs 10mV also schließe ich das als Fehler mal aus.

Die SD-Karte hängt an PortE mit SPI_E.

Was hat nun das eine mit dem anderen zu tun ? Ich hab wirklich keine Idee mehr was das soll :'(

Code

Program I2C_DOGXL;
{ Display EA DOGXL160, 3-Wire 8-Bit SPI-Mode write-only                        }
{ D6 = PC2         CD = PC3         CS0/A2 = PC4     MOSI = PC5                }
{ Reset = PD0      BM0 = PD1                                                   }
{ SPI 4wire 8Bit SPI: BM0&D6=Lo      SPI 3wire 8Bit SPI: BM0$CS0=Lo, D6=High   }
{                                                                              }
{ Touch an ADCB 4..7; Referenz extern an VDD                                   }
{ Hintergrundbeleuchtung an PA0..2                                             }
{                                                                              }
{ bei der Initialisierung werden alle Pixel für 500ms eingeschaltet            }

{$NOSHADOW}
{ $WG}                     {global Warnings off}

Device = xmega128A3, VCC=3.3;
{ $BOOTRST $10000}         {Reset Jump to $10000}

Import SysTick, LCDGraphic, SPI_C, ADC_B, FAT16;
From System Import CharSet, LongWord;

Define
  OSCtype        = int32MHz,
                   PLLmul=4,
                   prescB=1,
                   prescC=1;
  SysTick        = 5;             {msec}
  StackSize      = $0200, iData;
  FrameSize      = $0200, iData;
  
  LCDGraphic     = 160, 104, 8;     { x-pix, y-pix, accesswidth}
  LCDgraphMode   = column, iData;
  DefCharSet     = 'Graphchars.pchr';
  GViewports     = 1, iData;        { logical ViewPorts, scalings}
  TGraphStr      = 24;

  SPIorderC      = MSB;
  SPImodeC       = 0;
  SPIprescC      = 0;
  SPI_SSC        = none;
  
  ADCrefB        = RefextB;
  ADCprescB      = 256;
  ADCchansB      = [4..7];
  
  FAT16          = SPI_E, PortE, 4, iData;
  F16_MMCspeed   = standard;             // standard, slow, fast
  F16_FileHandles= 1;
  F16_DirLevels  = 1;
  F16_StrLen     = 250;

Uses UFAT16;

Implementation

{$IDATA}
{------------------------------------------------------------------------------}
{ Type Declarations }
Type
{------------------------------------------------------------------------------}
{ Const Declarations }
Const
  KeybText        : Array[0..17] of Char = ('B','D','L','S','W',#25,
                                            '0','1','2','3','4',#25,
                                            '5','6','7','8','9',#29);
  CITypeConst     : Array[0..4] of String[3] = ('B','D','LOC','SM','W');
{------------------------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
Var
  Col          : Word;                      // Columncounter
  Page         : Byte;                      // Pagecounter
  FByte, SByte : Byte;                      // Lo-/Highbyte Display 8-Bit e-lab --> DOGXL
  RAM_Temp     : Array[0..159] of Byte;     // nächste/ungerade Page
  RAM_Count    : Byte;                      // Counter für RAM_Temp
  
  X, Y         : Integer;                   // Touchscreen ADCs
  SX, SY       : Integer;                   // SetPixel-Kooordinaten
  
  TouchValue   : Byte;                      // Feldnummer Touch
  OP1, OP2     : String[10];                // Type & ???
  SString      : String[10];                // Suchstring GIN+LOC+1234
  CITypeSet    : Boolean;                   // LOC, W, SM, ..... gesetzt
  CIType       : String[3];                 // LOC, W, SM, .....
  CINumber     : String[4];                 // CI-Nummer
  
  SDReady      : Boolean;                   // Karte ok ?
  FileReady    : Boolean;                   // CMDB open ?
  CMDB         : File of Text;              // Dateityp
  CMDBLine     : String[250];
  CMDBP        : Array[0..10] of String[24];
  
{------------------------------------------------------------------------------}
{ functions }
Procedure WriteLCD(Arg: Byte; IsData: Boolean);
  Begin
    If IsData=true
      then
        PortC:=PortC or %00001000;          // Daten
      else
        PortC:=PortC and %11110111;         // Befehl
      EndIf;
    SPIOutByteC(Arg);                       // Output arg
  End WriteLCD;
  
  
Procedure GraphInit;
  Var Counter : Byte;
  Begin
    PortC:=%00000100;                       // Set SPI
    PortD:=%00000000;                       // /Reset
    MDelay(10);
    PortD:=%00000001;                       // Reset
    MDelay(10);
    
    WriteLCD($F1,false);                    // Set COM to 103
    WriteLCD($67,false);
    WriteLCD($C0,false);                    // COM and ROW normal
    WriteLCD($40,false);                    // ScrollLine 0
    WriteLCD($50,false);
    WriteLCD($00,false);                    // RAMAddr = 0
    WriteLCD($10,false);
    WriteLCD($60,false);                    // Page Address 0
    WriteLCD($84,false);                    // Partial Display Control off
    WriteLCD($2B,false);                    // Panelloading
    WriteLCD($EB,false);                    // BIAS 1/12
    WriteLCD($81,false);                    // Contrast 0..255
    WriteLCD($65,false);
    WriteLCD($89,false);                    // Auto Increment $89
    WriteLCD($F8,false);                    // Window Function disable
    WriteLCD($AF,false);                    // Display on
    WriteLCD($A5,false);                    // all Pixel on (Test)
    MDelay(500);
    WriteLCD($A4,false);                    // all Pixel off
  End GraphInit;
  
  
{$D-}
UserDevice GraphIOS(Cmd: Byte; Arg: Byte);
  Begin
    If Cmd=0
      then                                        // set page addr
        Page:=$60 or (Arg*2);                     // valid page# 0,2,4,6,.....
        WriteLCD(Page,false);
        WriteLCD($00,false);
        WriteLCD($10,false);
        Col:=0;
        RAM_Count:=0;
      else
        If Col<160
          then
            FByte:=0;
            SByte:=0;
            If Bit(Arg,0) then FByte:=$03; EndIf;
            If Bit(Arg,1) then FByte:=FByte or $0C; EndIf;
            If Bit(Arg,2) then FByte:=FByte or $30; EndIf;
            If Bit(Arg,3) then FByte:=FByte or $C0; EndIf;
            If Bit(Arg,4) then SByte:=$03; EndIf;
            If Bit(Arg,5) then SByte:=SByte or $0C; EndIf;
            If Bit(Arg,6) then SByte:=SByte or $30; EndIf;
            If Bit(Arg,7) then SByte:=SByte or $C0; EndIf;
            WriteLCD(FByte,true);
            RAM_Temp[Col]:=SByte;
            Inc(Col);
            Inc(RAM_Count);
          EndIf;
        If RAM_Count=160
          then
            WriteLCD(Page+1,false);
            WriteLCD($00,false);
            WriteLCD($10,false);
            For RAM_Count:=0 to 159 do
              WriteLCD(RAM_Temp[RAM_Count],true);
              EndFor;
          EndIf;
    EndIf;
  End GraphIOS;
{$D+}


Procedure Start(Bright:Byte);
  Var Test : Byte;
  Begin
    gSetTextJustify(alHorLeft, alVertTop);
    gSetTextMode(wmSetPix);
    gSetTextBkGnd(bkNormal);
    gSetCharSetRam(false);
    gClrScr(0);
    gDispRefresh;
    MDelay(1000);
    
    CITypeSet:=false;
    CIType:='';
    CINumber:='';
    
    SDReady:=false;
    FileReady:=false;
    
    If SDReady=false                        // Speicherkarte initialisieren
      then
        //Repeat
          SDReady:=F16_DiskReset;           // Reset
          //until SDReady=true;
        gDrawString(2,0,1,1,TxtRot0,'SD-Reset ok');
        gDispRefresh;
        MDelay(1000);
        If F16_DiskInit                     // Init
          then
            SDReady:=F16_DiskReset;         // Reset
            If SDReady                      // Speicherkarte ok ?
              then                          // ja
                gDrawString(2,10,1,1,TxtRot0,'SD-Init ok');
                gDispRefresh;
                MDelay(1000);
              EndIf;
          else                              // Speicherkarte nicht ok
          EndIf;
        FileReady:=F16_FileAssign(CMDB,'\','CMDB.txt');
        FileReady:=F16_FileReset(CMDB);
        If FileReady
          then
            gDrawString(2,20,1,1,TxtRot0,'Open CMDB.txt ok');
            gDispRefresh;
            MDelay(1000);
          EndIf;
        gDispRefresh;
        MDelay(3000);
        gClrScr(0);
      EndIf;
  End Start;
  
  
Procedure Init_Ports;
  Begin
    DDRA:=%00000000;                             // PWM PortA 0..2
    DDRB:=%11110000;                             // Touch & Erweiterung
    DDRC:=%10111100;                             // Display SPI/I²C & Steuerung
    DDRD:=%00000011;                             // Display-Steuerung
    PortA:=%00000000;
    PortB:=%00000000;
    PortC:=%00001100;
    PortD:=%00000000;
    MDelay(10);
  End Init_Ports;
  

Procedure ShowTouch(Nr:Byte);
  Var X, Y  : Integer;
  Begin
    Y:=Integer(Nr div 6);
    X:=Integer(Nr-(Lo(Y)*6));
    gSetLineMode(wmXorPix);
    gFillRect((X*23)+1,(Y*24)+32,(X*23)+22,(Y*24)+54,$FF);
    gDispRefresh;
    MDelay(100);
    gFillRect((X*23)+1,(Y*24)+32,(X*23)+22,(Y*24)+54,$FF);
    gDispRefresh;
    gSetLineMode(wmSetPix);
  End ShowTouch;
  
  
Function ReadTouch:Byte;
  Var TC : Byte;
  Begin
    DDRB:=%10100000;
    PortB:=%10000000;                       // Left=0 Right=1
    MDelay(15);
    X:=Integer(GetADCB(0));
    MDelay(15);
    X:=Integer(GetADCB(0));
    If X in [890..3670]
      then
        SX:=(X-890) div 462;                // X-Koordinate Tastatur
      else                                  // div --> (3670-890) / 6 = 463
        SX:=1000;
      EndIf;
    DDRB:=%01010000;
    PortB:=%00010000;                       // Bottom=1 Top=0
    MDelay(15);
    Y:=Integer(GetADCB(1));
    MDelay(15);
    Y:=Integer(GetADCB(1));
    If Y in [1990..3640]
      then
        SY:=(Y-1990) div 552;               // Y-Koordinate Tastatur
      else                                  // div --> (3640-1990) / 3 = 550 (553)
        SY:=1000;
      EndIf;
    If ((SX=1000) or (SY=1000))
      then
        TC:=100;                            // keine Taste
      else
        TC:=Lo((SY*6)+SX);                  // Tastenwert 0-17
      EndIf;
    DDRB:=%00000000;
    PortB:=%00000000;
    Return(TC);
  End ReadTouch;
  
  
Procedure ShowInp;
  Var XD, YD : Integer;
  Begin
    gClrScr(0);
    gDrawRect(0,0,159,28,$FF);
    gDrawLine(50,0,50,28,$FF);
    gDrawLine(99,0,99,28,$FF);
    gDrawRect(141,31,159,103,$FF);
    For XD:=0 to 6 do
      gDrawLine(XD*23,31,XD*23,103,$FF);
      EndFor;
    For YD:=0 to 3 do
      gDrawLine(0,(YD*24)+31,138,(YD*24)+31,$FF);
      EndFor;
    gSetTextJustify(alHorCenter, alVertTop);
    For XD:=0 to 5 do
      gDrawString((XD*23)+10,35,2,2,TxtRot0,KeybText[XD]);
      gDrawString((XD*23)+10,59,2,2,TxtRot0,KeybText[XD+6]);
      gDrawString((XD*23)+10,83,2,2,TxtRot0,KeybText[XD+12]);
      EndFor;
    gSetTextBkGnd(bkTransp);
    gDrawString(146,77,2,2,TxtRot0,'C');
    gDrawString(151,86,2,2,TxtRot0,'H');
    gSetTextBkGnd(bkNormal);
    gDrawString(145,54,1,1,TxtRot90,'(C)2012');
    gSetTextJustify(alHorLeft, alVertTop);
    gDrawString(5,6,2,2,TxtRot0,'GIN');
    //gDrawString(55,6,2,2,TxtRot0,'LOC');
    //gDrawString(103,6,2,2,TxtRot0,'5432');
    gDispRefresh;
  End ShowInp;
  

Function SearchCI(SS:String[10]):Boolean;
  Var SLength : Byte;
      SFind   : Boolean;
      CMDBTS  : String[10];
      Counter : Byte;
      T       : Array[0..10] of Byte;
  Begin
    SLength:=Length(SS);
    SFind:=false;
    T[0]:=1;
    gClrScr(0);
    Repeat
      ReadLn(CMDB,CMDBLine);
      CMDBTS:=Copy(CMDBLine,1,SLength);
      If SS=CMDBTS
        then
          SFind:=true;
          For Counter:=0 to 10 do
            CMDBP[Counter]:='';
            EndFor;
          For Counter:=1 to 10 do
            T[Counter]:=(PosN('*',CMDBLine,T[Counter-1]+1))+1;
            EndFor;
          CMDBP[0]:=Copy(CMDBLine,1,SLength);
          CMDBP[1]:=Copy(CMDBLine,T[1],T[2]-T[1]-1);
          CMDBP[2]:=Copy(CMDBLine,T[2],T[3]-T[2]-1);
          CMDBP[3]:=Copy(CMDBLine,T[3],T[4]-T[3]-1);
          CMDBP[4]:=Copy(CMDBLine,T[4],T[5]-T[4]-1);
          CMDBP[5]:=Copy(CMDBLine,T[5],T[6]-T[5]-1);
          CMDBP[6]:=Copy(CMDBLine,T[6],T[7]-T[6]-1);
          CMDBP[7]:=Copy(CMDBLine,T[7],T[8]-T[7]-1);
          CMDBP[8]:=Copy(CMDBLine,T[8],T[9]-T[8]-1);
          CMDBP[9]:=Copy(CMDBLine,T[9],T[10]-T[9]-1);
          CMDBP[10]:=Copy(CMDBLine,T[10],Length(CMDBLine));
        EndIf;
      Until ((SFind=true) or (CMDBLine=''));
    Return(SFind);
  End SearchCI;
  
  
Procedure ShowResult;
  Begin
  End ShowResult;
{------------------------------------------------------------------------------}
{ Main Program }
{$IDATA}

Begin
  EnableInts($87);
  MDelay(10);
  Init_Ports;
  GraphInit;
  Start(30);
  ShowInp;
  
  Loop
    TouchValue:=ReadTouch;
    If TouchValue in [0..17]
      then
        Case TouchValue of
           0.. 4:If CITypeSet=false
                   then
                     CIType:=CITypeConst[TouchValue];
                     gFillRect(51,1,98,27,$00);
                     gDrawString(55,6,2,2,TxtRot0,CIType);
                     CITypeSet:=true;
                   EndIf;|
               5:If CITypeSet=true
                   then
                     CIType:='';
                     gFillRect(51,1,98,27,$00);
                     CITypeSet:=false;
                   EndIf;|
           6..10:If Length(CINumber)<4
                   then
                     CINumber:=CINumber+KeybText[TouchValue];
                   EndIf;
                 gFillRect(100,1,158,27,$00);
                 gDrawString(103,6,2,2,TxtRot0,CINumber);|
              11:CINumber:='';
                 gFillRect(100,1,158,27,$00);|
          12..16:If Length(CINumber)<4
                   then
                     CINumber:=CINumber+KeybText[TouchValue];
                   EndIf;
                 gFillRect(100,1,158,27,$00);
                 gDrawString(103,6,2,2,TxtRot0,CINumber);|
              17:SString:='GIN'+CIType+CINumber;
                 If SearchCI(SString)=true
                   then
                     gClrScr(0);
                     gDrawString(2, 0,1,1,TxtRot0,CMDBP[0]);
                     gDrawString(2, 8,1,1,TxtRot0,CMDBP[1]);
                     gDrawString(2,16,1,1,TxtRot0,CMDBP[2]);
                     gDrawString(2,24,1,1,TxtRot0,CMDBP[3]);
                     gDrawString(2,32,1,1,TxtRot0,CMDBP[4]);
                     gDrawString(2,40,1,1,TxtRot0,CMDBP[5]);
                     gDrawString(2,48,1,1,TxtRot0,CMDBP[6]);
                     gDrawString(2,56,1,1,TxtRot0,CMDBP[7]);
                     gDrawString(2,64,1,1,TxtRot0,CMDBP[8]);
                     gDrawString(2,72,1,1,TxtRot0,CMDBP[9]);
                     gDrawString(2,80,1,1,TxtRot0,CMDBP[10]);
                     gDispRefresh;
                     Repeat
                       until ReadTouch in [0..17];
                     ShowInp;
                     gDispRefresh;
                     CIType:='';
                     CINumber:='';
                   else
                     gFillRect(51,1,98,27,$00);
                     gFillRect(100,1,158,27,$00);
                     gDispRefresh;
                   EndIf;
                 |
          EndCase;
        ShowTouch(TouchValue);
        gDispRefresh;
      EndIf;
    Endloop;
End I2C_DOGXL.


gruss
Harry

PS: Mehr Fragen später noch :D dann zu Text-Datei-Zugriff
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2133
Registered: 03 / 2003
Subject:

Re: XMega, DOGXL & SD-Karte

 · 
Posted: 11.05.2012 - 17:51  ·  #2
..... und noch gleich die andere(n) Frage(n):

Die Zeilen in obigen erwähnter Text-Datei sind wie folgt aufgebaut:

AAAAAA1234*BBBBB*CCCCC*DDDDD*EEEEE*FFFFF*GGGGG*HHHHH*IIIII*JJJJJ*KKKKK<CR><LF>

Wobei AAAAAA1234 maximal 10 Zeichen hat und BBBBB bis KKKKK zusammen bis zu 240 Zeichen.

Ich möchte nun (um Zeit zu sparen) nur AAAAAA1234 lesen und wenn es das ist was ich suche den Rest der Zeile. Wenn AAAAAA1234 nicht das ist was ich suche zur nächsten Zeile springen. Nur wie mache ich das möglichst schnell ohne den Rest der Zeile lesen zu müssen ? Read liest nur die Anzahl Zeichen die ich will und ReadLn die ganze Zeile. Ich möchte die nächste Zeile/Anfang anspringen - wie ?

Und wie spinge ich zum Anfang der Datei ? Muß ich die Datei schließen und neu öffnen ? Geht das nicht anderst ?

gruss
Harry
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: XMega, DOGXL & SD-Karte

 · 
Posted: 13.05.2012 - 17:16  ·  #3
Hallo Harry,

das mit dem Geflackere kann ich mir auch nicht erklären, da PortA ja ganz weit weg ist von PortE. Das müsste man mal genauer untersuchen.

FileOfText: man weiss niemals wie lang so ein string ist, daher kennt man auch nicht sein Ende bzw. den Anfang des nächsten strings. Das gute daran ist, dass ja immer 512byte Blöcke gelesen werden.
Die Chance dass der nächste string schon im Lesebuffer steht ist damit relativ gross und damit ist
das lesen eines kompletten strings eigentlich kein overhead.

Zum File-Anfang springen: F16_Seek...

rolf
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   64   78 · Page-Gen-Time: 0.031942s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI