- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 1 von 1

Thema: XMEGA/XPLAINED: DMA Zugriff auf SDRAM läuft nicht

  1. #1
    Erfahrener Benutzer Roboter-Spezialist Avatar von erik_wolfram
    Registriert seit
    02.12.2009
    Ort
    Berlin
    Beiträge
    406

    XMEGA/XPLAINED: DMA Zugriff auf SDRAM läuft nicht

    Anzeige

    Praxistest und DIY Projekte
    Hallo,

    leider stehe ich schon wieder vor einem neuen Problem - mir gelingt es nicht per DMA in den SDRAM zu schreiben.
    Hierzu habe ich zunächst das Tutorial "AVR1312: Using the XMEGA External Bus Interface" abgearbeitet welches ohne Probleme lief.

    Beim DMA-Zugriff funktioniert das leider nicht. Nach längerem Suchen ist mir dann aufgefallen, dass die Funktion DMA_SetupBlock() aus dem Tutorial "AVR1514: XMEGA-A1 Xplained Training - Direct Memory Access Controller" nur bis 16 Bit Addressen ausgeführt war. Dementsprechend habe ich die Funktion für 24-Bit Addressen modifiziert. Die erste Addresse wird auch beschrieben, aber alle weiteren Folgeaddressen bleiben per DMA unbeschrieben. Die Inkrementierung der Addressen ist im entsprechenden DMA-Kanal vorgenommen.

    Hier mal ein Auszug meines Codes:
    Code:
    #define SDRAM_SIZE        0x800000UL                        // Größe des benötigten SDRAMs
    #define MEMORY_BLOCK    0                                // MEMORY_BLOCK = (16MB/RAM_SIZE - 1)
    uint32_t SDRAM_ADDR =    (SDRAM_SIZE * MEMORY_BLOCK);        // Addresse des SDRAM-Bereichs
    
    DMA_CH_t * SDRAMChannel = &DMA.CH0;
    
    void initSDRAM()
    {
        // Bus Pins als Ausgang, außer die Datenleitungen (DQ0-DQ3)
        PORTH.DIR = 0xFF;
        PORTK.DIR = 0xFF;
        PORTJ.DIR = 0xF0;
        
        EBI_Enable( EBI_SDDATAW_4BIT_gc,        // Datengröße 4 Bit
        EBI_LPCMODE_ALE1_gc,
        EBI_SRMODE_ALE12_gc,
        EBI_IFMODE_3PORT_gc );
        
        EBI_EnableSDRAM(    EBI_CS_ASPACE_8MB_gc,   /* 8 MB address space. */
                            SDRAM_ADDR,             /* Base address. */
                            false,                  /* 2 cycle CAS Latency. */
                            true,                   /* 12 Row bits. */
                            EBI_SDCOL_10BIT_gc,     /* 10 Column bits. */
                            EBI_MRDLY_2CLK_gc,      /* 2 cycle Mode Register Delay. (min 2CLK) */
                            EBI_ROWCYCDLY_1CLK_gc,  /* 1 cycle Row Cycle Delay. */
                            EBI_RPDLY_1CLK_gc,      /* 1 cycle Row to Pre-charge Delay. (min 37ns) */
                            EBI_WRDLY_2CLK_gc,      /* 2 cycle Write Recovery Delay. (1CLK + 7ns)*/
                            EBI_ESRDLY_1CLK_gc,     /* 1 cycle Exit Self Refresh to Active Delay. (min 67ns) */
                            EBI_ROWCOLDLY_1CLK_gc,  /* 1 cycle Row to Column Delay. (min 15ns) */
                            0x001F,                 /* 31 cycle Refresh Period (max 15.625us). */
                            0x00C8 );               /* 200 cycle Initialization Delay (min 100us). */
        
        delay_us( 100 );
    }
    
    void SetupSDRAMChannel( DMA_CH_t * dmaChannel )
    {
        TCF1.CNT = 0x62;
       
        dmaChannel->SRCADDR0 = (( (uint16_t) (void *) &TCF1.CNT) >> 0*8 ) & 0xFF;
        dmaChannel->SRCADDR1 = (( (uint16_t) (void *) &TCF1.CNT) >> 1*8 ) & 0xFF;
        dmaChannel->SRCADDR2 = 0;
    
        // 24-Bit Addresse muss manuell gesetzt werden
        dmaChannel->DESTADDR0 = (( (uint32_t) SDRAM_ADDR) >> 0*8 ) & 0xFF;
        dmaChannel->DESTADDR1 = (( (uint32_t) SDRAM_ADDR) >> 1*8 ) & 0xFF;
        dmaChannel->DESTADDR2 = (( (uint32_t) SDRAM_ADDR) >> 2*8 ) & 0xFF;
        
        dmaChannel->ADDRCTRL = DMA_CH_SRCRELOAD_NONE_gc | DMA_CH_SRCDIR_FIXED_gc | DMA_CH_DESTRELOAD_NONE_gc | DMA_CH_DESTDIR_INC_gc;
        dmaChannel->TRFCNT = 1;
        dmaChannel->CTRLA |= DMA_CH_BURSTLEN_1BYTE_gc;
        
        DMA_EnableSingleShot( dmaChannel );
        DMA_SetTriggerSource( dmaChannel, DMA_CH_TRIGSRC_TCC0_OVF_gc ); 
    }
    
    ISR( TCC0_OVF_vect ){}
        
    ISR( TCC1_OVF_vect ){}
        
    void SetUpAllTimers( void )
    {    
        TCC1.PER = 1000;                                        // Überlauf bei Grenzwert der zu nehmenden Samples
        TCC1.CNT = 48;            // 0
        EVSYS_SetEventSource( 0, EVSYS_CHMUX_TCC0_OVF_gc );        // Event channel 0 erfasst die Überläufe des Timers TCC1
        TCC1.CTRLA = TC_CLKSEL_EVCH0_gc;                        // Als clock source wird der event channel 0 gesetzt
        
        TCC0.PER = 1000;
        // Timer Iinterupt aktivieren und Priorität setzten
        TCC0.INTCTRLA = TC_OVFINTLVL_MED_gc;    
        // annährend gleichzeitiges Starten der Timer mit Prescaler von 1
        TCC0.CTRLA = (TCC0.CTRLA & ~TC0_CLKSEL_gm) | TC_CLKSEL_DIV1_gc;
    }
    
    int main( void )
    {
        // SDRAM initialisieren
        initSDRAM();
        
        for (uint32_t i = 0; i < 5; i++) {
            __far_mem_write( i + SDRAM_ADDR, 0x65 );
        }    
        
        DMA_Enable();
        
        // DMA-Kanäle initialisieren
        SetupSDRAMChannel( SDRAMChannel );
    
        // DMA-Kanäle starten    
        DMA_EnableChannel( SDRAMChannel );
        
        SetUpAllTimers();
            
        // Warten bis 10 Werte im SDRAM
        while( TCC1.CNT < 10){}
            
        uint8_t result;    
            
        for (uint8_t i = 0; i < 5; i++) 
        {
            result = __far_mem_read( i + SDRAM_ADDR );
            .... // AUsgabe
        }
    ....
    Die SDRAM zugriffe mit den vorgefertigten Funktionen funktionieren - in den Funktionen wird nochmal betont, dass GCC die 24 Bit Addressen nicht unterstützt.

    Ich hoffe es sieht jemand den Fehler. Ich habe hierzu schon die Application Notes durchgearbeitet - bin aber leider nicht fündig geworden.

    Gruß Erik


    [EDIT] Erhöhe ich den Trafficcount TRFCNT im DMA - so werden die folgenden Addressen entsprechend mit dem gleichen Wert beschrieben..

    [EDIT No.2] Es tut mir leid - nach langem Suchen habe ich den Fehler gefunden. Beim Kopieren/Ändern der Funktion DMA_SetupBlock habe ich TRFCNT ausversehen auf 1 gesetzt - da muss natürlich die 0 für unendich hin.
    Meinetwegen kann dieses Thema gerne wieder gelöscht werden - ich sehe hier leider keine Möglichkeit das selbst zu tun.
    Geändert von erik_wolfram (21.07.2014 um 08:37 Uhr)
    Meine Projekte auf Youtube

Ähnliche Themen

  1. [ERLEDIGT] Atmel XMEGA-A1 Xplained
    Von tucow im Forum Kaufen, Verkaufen, Tauschen, Suchen
    Antworten: 1
    Letzter Beitrag: 19.02.2013, 23:38
  2. XMega Event System & DMA -- Taster & Timer
    Von Che Guevara im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 04.03.2012, 23:04
  3. Atmel XMEGA-A3BU: Xplained #3
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 31.01.2012, 21:30
  4. SDRAM/DDR-SDRAM + AVR
    Von Johannes G. im Forum Elektronik
    Antworten: 1
    Letzter Beitrag: 08.12.2006, 20:12
  5. Eagle: Zugriff auf nicht angezeigt Pins eines Bauteils
    Von starkeeper im Forum Konstruktion/CAD/3D-Druck/Sketchup und Platinenlayout Eagle & Fritzing u.a.
    Antworten: 6
    Letzter Beitrag: 07.03.2006, 18:08

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress