Mega644 --> XMega256-A3U

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

Mega644 --> XMega256-A3U

 · 
Posted: 12.05.2012 - 15:03  ·  #1
Hallo @ all,

ich habe mein funktionierendes rundes Display nochmal neu layoutet und jetzt anstatt eines Mega644 einen XMega256-A3U drin. Das Programm wurde 1:1 übertragen und angepaßt. Control-Pins des Displays liegen auf Port D und F, Daten auf Port E.
Ich bekomm das Display aber nicht zum laufen :'(
Muß ich irgendwas auf den angegebenen Ports beachten, abschalten, .... ? Verhindert evtl. irgend eine Standardeinstellung des µC daß das funktioniert ?

Code

Program I2C_BTR160_2;

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

Device = xmega256A3U, VCC=3.1;
{ $BOOTRST $20000}         {Reset Jump to $20000}

Import SysTick, LCDGraphic, SoftPWM, RTClock;

From System Import CharSet;

Define
  OSCtype        = int32MHz,
                   PLLmul=2,
                   prescB=1,
                   prescC=1;
  SysTick        = 10;             {msec}
  StackSize      = $0200, iData;
  FrameSize      = $0200, iData;

  LCDGraphic     = 160,160, 8;              { Display 160 x 160                }
  LCDgraphMode   = readonly, iData;
  DefCharSet     = 'Graphchars.pchr';
  GViewports     = 1, iData;
  TGraphStr      = 24;

  RTClock        = iData, DateTime;
  RTCSource      = SysTick;

  SoftPWMport    = PortD;                   { use PortA for PWM output         }
  SoftPWMtimer   = Timer_C0, 10;            { use timer2, PWM cycle time msec  }
  SoftPWMres     = 100;                     { PWM resolution is 127 Points     }
  SoftPWMchans   = 1, 4;                    { 1 channel, bit4 is the first bit }
Implementation

{$IDATA}

{--------------------------------------------------------------}
{ Type Declarations }
Type
{------------------------------------------------------------------------------}
{ Const Declarations }
Const
  elabbmp         : Array[1..(32*32 div 8)+2] of Byte = 'e-lab.pbmp';
{------------------------------------------------------------------------------}
{ Var Declarations }
Var
  //   /Reset PortD, 5
  //    A0    PortD, 6
  //   /WR    PortD, 7
  //   /CS    PortF, 1
  //   /RD    PortF, 0

  //LCD_DOut[@PortD]  : Byte;

  LCD_WR[@PortD,7]     : Bit;    //Write Signal
  LCD_RD[@PortF,0]     : Bit;    //Read Signal
  LCD_A0[@PortD,6]     : Bit;    //Select Command , 0  Command send  , 1 Data send
  LCD_CS[@PortF,1]     : Bit;    //Chip Select
  LCD_RST[@PortD,5]    : Bit;    //Reset
  //LCD_PWM[@PortD,4]    : Bit;    // HG-LED on

  Xpd, Ypd             : Integer;           // Rotate-Var Destination
  Xps, Yps             : Integer;           // Rotate-Var Source
{------------------------------------------------------------------------------}
{ Functions }
{$IDATA}
Procedure Init_Port;
  Begin
    PortD:=%11100000;      // /WR A0 /Reset PWM xxxx
    PortE:=%00000000;      // Datenport
    PortF:=%00000001;      // xxxxxx /CS /RD
    DDRD:=%11110000;
    DDRE:=%11111111;
    DDRF:=$00000011;
  End Init_Port;


Procedure Write_C(Daten:Byte);
  Begin
    LCD_A0:=0;                              // 0=Command
    LCD_WR:=0;
    PortE:=Daten;
    LCD_WR:=1;
  End Write_C;


Procedure Write_D(Daten:Byte);
  Begin
    LCD_A0:=1;                              //1=Data
    LCD_WR:=0;
    PortE:=Daten;
    LCD_WR:=1;
  End Write_D;


Procedure Backlight(Bright:Byte);
  Begin
    If Bright in [0..100]
      then
        SoftPWMArr[1]:=Bright;
      EndIf;
  End Backlight;


Procedure GraphInit;
  Begin
    // Der ST7529 ist ein LCD-Controller mit 32-Graustufen. Im vorliegenden Programm
    // wird das Display nur schwarz/weiß betrieben. Im Display-RAM und mit den folgenden
    // Einstellungen ist 1 Pixel = 1 Byte wobei $F8=Pixel ein und $00=Pixel aus.
    // %76543xxx Bit 3-7 = Graustufenwert     x=nicht verwendet

    LCD_RST:=0;
    MDelay(10);
    LCD_RST:=1;
    MDelay(10);

    Write_C($30);                    // Ext in
    Write_C($94);                    // Sleep out
    Write_C($D1);                    // Internal Osc on

    Write_C($20);                    // Power Control
    Write_D($08);                    //
    MDelay(10);                      //
    Write_C($20);                    // Power Control
    Write_D($0B);                    //
    MDelay(10);

    Write_C($81);                    // Electronic Volume Control - Contrast
    Write_D($30);                    // $38
    Write_D($04);                    // $04

    Write_C($CA);                    // Display Control
    Write_D($00);                    //
    Write_D($27);                    //
    Write_D($00);                    //

    Write_C($A7);                    // Normal Display

  // Mit den folgenden beiden Parametern $BB und $BC kann man die Scanreihenfolge
  // des Display-RAMs und die Orientierung festlegen.
  // Hierbei lohnt es sich bei fehlerhafter Displayausgabe ein bisschen zu spielen ;o)

    Write_C($BB);                    // COM Scan Direction
    Write_D($01);                    // $01 = Com0...Com79 + Com159...COM80

    Write_C($BC);                    // Data Scan Direction
    Write_D($02);                    // Line normal; Col reverse; $02 = rechts oben --> Pixel 0
    Write_D($01);                    // Segment Arrangement P3 P2 P1
    Write_D($02);                    // 32 Gray Scale, $02 = 3 Byte, 3 Pixel
                                     // ($01 = 2 Byte, 3 Pixel)

    Write_C($31);                    // Ext out

    Write_C($32);                    // Analog Circuit Set
    Write_D($00);                    // OSC frequency Adjustment
    Write_D($03);                    // Booster Efficiency Set
    Write_D($02);                    // Bias Setting

    Write_C($30);                    // Ext in

    Write_C($AF);                    // Display On
  End GraphInit;


{$D-}
UserDevice GraphIOS(cmd:Byte;Arg:Byte);
  Var MD : Byte;
  Begin
    If cmd=0
      then
        Write_C($15);        //Set Column Adress  , sichtbarer Bereich 16 - 72
        Write_D($10);
        Write_D($48);
        Write_C($75);        //Set Row Adress  , sichtbarer Bereich 0-159
        Write_D($00+Arg);
        Write_D($00+Arg);
        Write_C($5C);        //Befehl Write RAM bleibt aktiv bis ein nächstes Kommando kommt

        //Write_D($00);        // hierdurch wird das komplette Bild um 1 Pixel horizontal verschoben
        //Write_D($00);      // d.h. es kann die Ausgabe horizontal getrimmt werden.
      else
        For MD:=7 downto 0 do
          If Bit(Arg,MD)
            then
              Write_D($F8);  // Pixel on
            else
              Write_D($00);  // Pixel off
            EndIf;
          EndFor;
      EndIf;
  End GraphIOS;
{$D+}


Procedure Start;                            { Start des Programmes             }
  Begin
    gSetTextJustify(alHorCenter, alVertCenter);
    gSetTextMode(wmSetPix);
    gSetCharSetRam(false);
    gClrScr($00);
    gDispRefresh;
  End Start;


Procedure nRTCTickSecond;
  Var HMS : Integer;
  Begin
    gClrScr(0);
    HMS:=Integer(RTCgetSecond);
    RotatePnti(HMS*6,0,-69,Xps,Yps);
    gDrawCircle(79+Xps,79+Yps,10,$FF);
    gDrawString(78+Xps,79+Yps,1,1,TxtRot0,IntToStr(HMS));
    HMS:=Integer(RTCgetMinute);
    RotatePnti(HMS*6,0,-47,Xps,Yps);
    gDrawCircle(79+Xps,79+Yps,10,$FF);
    gDrawString(78+Xps,79+Yps,1,1,TxtRot0,IntToStr(HMS));
    HMS:=Integer(RTCgetHour);
    RotatePnti(HMS*30,0,-25,Xps,Yps);
    gDrawCircle(79+Xps,79+Yps,10,$FF);
    gDrawString(78+Xps,79+Yps,1,1,TxtRot0,IntToStr(HMS));
    HMS:=Integer(RTCgetDay);
    gDrawString(79,79,1,1,TxtRot0,IntToStr(HMS));
    gDispRefresh;
  End nRTCTickSecond;


Procedure Main;
  Var Counter : Integer;
  Begin
    For Counter:=1 to 7 do
      gDrawCircle(80,80,Counter*10,$FF);
      EndFor;
    gDrawLine(0,80,159,80,$FF);
    gDrawLine(80,0,80,159,$FF);
    gDrawLine(0,0,160,160,$FF);
    gDrawLine(0,160,160,0,$FF);
    gDrawString(120,66,5,5,TxtRot0,'C');
    gDrawString(130,90,5,5,TxtRot0,'H');

  End Main;
{------------------------------------------------------------------------------}
{ Main Program }
{$IDATA}

Begin
  EnableInts($87);
  Init_Port;
  Backlight(30);
  GraphInit;
  Start;
  Loop
    //gDrawCircle(80,80,81,$FF);
    gDrawCircle(80,80,80,$FF);
    gDrawCircle(80,80,79,$FF);
    Main;
    gDispRefresh;
    Endloop;

End I2C_BTR160_2.


gruss
Harry
golf
Benutzer
Avatar
Gender:
Location: Donauwörth
Age: 71
Posts: 256
Registered: 11 / 2009
Subject:

Re: Mega644 --> XMega256-A3U

 · 
Posted: 12.05.2012 - 17:13  ·  #2
hallo harry,
falls noch nicht probiert, würde ich auf jeden Fall einmal versuchsweise die Taktrate des ATXmegas heruntersetzen um Timingprobleme auszuschliessen. Der ST7529 hat eine System Cycle Time von min 200nsec.

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

Re: Mega644 --> XMega256-A3U

 · 
Posted: 13.05.2012 - 08:44  ·  #3
Hallo golf,

hab ich schon. Einmal mit diversen NOPs und Pausen und natürlich mit verringertem Takt 2, 8 und 16 MHz.

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

Re: Mega644 --> XMega256-A3U

 · 
Posted: 14.05.2012 - 11:41  ·  #4
Hi @ all,

Nachdem ich das immer noch nicht zum laufen gebracht hab, hab ich folgendes gemacht: auf Port D (belegt Bit 4-7), E (belegt Bit 0-7) und F (belegt Bit 0-1) ein Bitmuster ausgegeben und mit dem Oszi kontrolliert. Und nur versteh ich wieder mal nichts mehr: alles ist ok, bis auf F1. Diesen Pin kann ich nicht ändern. Natürlich alles nochmal auf Kurzschlüsse und Leiterbahnunterbrechungen kontrolliert: nichts zu finden. Kann der tatsächlich defekt sein oder liegt da noch irgendwas drauf, was ich erst deaktivieren muß ? Das Datenblatt hab ich natürlich soweit mir verständlich durchgeschaut.

Code

Procedure TestPorts;
  Begin
    If TD<15
      then
        Inc(TD);
      else
        TD:=0;
      EndIf;
    If TE<255
      then
        Inc(TE);
      else
        TE:=0;
      EndIf;
    If TF<3
      then
        Inc(TF);
      else
        TF:=0;
      EndIf;
    PortD:=TD SHL 4;
    PortE:=TE;
    PortF:=TF;
    MDelay(1);
  End TestPorts;


gruss
Harry

Ich kenne mich ja mit ASM ned aus, hab mir aber trotzdem grad mal das ASM-File angeschaut. Da gibts was, das ich nicht verstehe: im Datenblatt sind die Basisadressen der Ports angegeben "Peripheral Module Address Map" und dort steht:
0x0600 PORTA Port A
0x0620 PORTB Port B
0x0640 PORTC Port C
0x0660 PORTD Port D
0x0680 PORTE Port E
0x06A0 PORTF Port F
0x07E0 PORTR Port R

Im ASM-File steht aber:
PORTA .EQU 604h
PORTB .EQU 624h
PORTC .EQU 644h
PORTD .EQU 664h
PORTE .EQU 684h
PORTF .EQU 6A4h
PORTR .EQU 7E4h

Wieso stimmt das nicht überein ? Hat das evtl. was mit meinem Problem zu tun ?
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2133
Registered: 03 / 2003
Subject:

Re: Mega644 --> XMega256-A3U

 · 
Posted: 14.05.2012 - 12:15  ·  #5
Ich glaubs nicht - ich habs :happy:

Selbstgemachter Fehler der nicht aufgefallen ist. Oben im Quellcode hatte ich folgendes drin:
Code

Procedure Init_Port; 
  Begin 
    PortD:=%11100000;      // /WR A0 /Reset PWM xxxx 
    PortE:=%00000000;      // Datenport 
    PortF:=%00000001;      // xxxxxx /CS /RD 
    DDRD:=%11110000; 
    DDRE:=%11111111; 
    DDRF:=$00000011; 
  End Init_Port;

Na wem fällt es auf ?






.... genau: DDRF:=$00000011;

Aufgefallen ist es mir, als ich versucht hab die Pins 2 und 3 als Ausgang zu aktivieren und der Compiler plötzlich gemeckert hat. Bin ich d..f :'(

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

Re: Mega644 --> XMega256-A3U

 · 
Posted: 14.05.2012 - 12:35  ·  #6
Ich hoffe ich darf nach diesem Desaster noch eine Frage anhängen:

Beim SoftPWM kann ich als verwendeten Timer Timer_C0, C1, D0, D1, E0, E1 und F0 angeben. Woher weiß man, welchen man nehmen sollte ? Kann mir das bitte jemand erklären ? Ich habe einfach mal alle durchprobiert und aus der Procedure nRTCTickSecond wieder RTCTickSecond (also Aufruf jede Sekunde) gemacht. Nun blinkt jede Sekunde meine HG-Beleuchtung. :'( Wie kann das sein ? Was hat das eine mit dem anderen zu tun ?

seufzende Grüsse
Harry

@golf: Ich brauch nach dem Anlegen der Daten an PortE drei NOPs bevor ich WR=1 machen kann. Mit weniger funktioniert es nicht mehr. Wenn ich davon ausgehe, daß ein NOP 31.3ns benötigt (bei 32MHz) sind das in etwa die 100ns die im Datenblatt des ST stehen. Auf jeden Fall ist das deutlich schneller als mit dem Mega644 :happy:
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   106   120 · Page-Gen-Time: 0.067822s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI