Hallo, ich beschäftige mich gerade mit dem EBI des XMEGA128A1. Nach gründlichem Studium des Datenblatts will mir aber leider noch nicht klar werden was es mit der Base Address auf sich hat. Kann mich jemand aufklären?
Unter dieser Adresse wird (als 'hugemem') der angeschlossene RAM Chip in den Adressraum eingeblendet (mit Hilfe der RAS und CAS Leitungen). Auf dem XMega Xplained A1 Board z.B. ist der 8MByte SDRAM als 3-Port eingebunden und EBI CS so programmiert, das der Chip ab Adresse 0x800000 in den Adressraum eingeblendet wird, mit einer Länge von ebenfalls 0x800000:
1 | #define CONFIG_HAVE_HUGEMEM
|
2 | |
3 | //! Base address of SDRAM on board
|
4 | #define BOARD_EBI_SDRAM_BASE 0x800000UL
|
5 | |
6 | //! Size of SDRAM on board, given in bytes.
|
7 | #define BOARD_EBI_SDRAM_SIZE 0x800000UL
|
Als Beispiel mal die EBI Init für das XPlained A1:
1 | static void InitSDRAM(void) { |
2 | /*
|
3 | * Configure the EBI port with 12 address lines, no address latches or
|
4 | * low pin count, and set it in SDRAM mode with 3-port EBI port.
|
5 | */
|
6 | ebi_setup_port(12, 0, 0, EBI_PORT_3PORT | EBI_PORT_SDRAM); |
7 | |
8 | /*
|
9 | * Configure the EBI chip select for an 8 MB SDRAM located at
|
10 | * \ref BOARD_EBI_SDRAM_BASE.
|
11 | */
|
12 | ebi_cs_set_mode(&cs_config, EBI_CS_MODE_SDRAM_gc); |
13 | ebi_cs_set_address_size(&cs_config, EBI_CS_ASIZE_8MB_gc); |
14 | ebi_cs_set_base_address(&cs_config, BOARD_EBI_SDRAM_BASE); |
15 | |
16 | /* Configure the EBI chip select to be in SDRAM mode. */
|
17 | ebi_sdram_set_mode(&cs_config, EBI_CS_SDMODE_NORMAL_gc); |
18 | |
19 | /* Setup the number of SDRAM rows and columns. */
|
20 | ebi_sdram_set_row_bits(&sdram_config, 12); |
21 | ebi_sdram_set_col_bits(&sdram_config, 10); |
22 | |
23 | /* Further, setup the SDRAM timing. */
|
24 | ebi_sdram_set_cas_latency(&sdram_config, 3); |
25 | ebi_sdram_set_mode_delay(&sdram_config, EBI_MRDLY_2CLK_gc); |
26 | ebi_sdram_set_row_cycle_delay(&sdram_config, EBI_ROWCYCDLY_7CLK_gc); |
27 | ebi_sdram_set_row_to_precharge_delay(&sdram_config, EBI_RPDLY_7CLK_gc); |
28 | ebi_sdram_set_write_recovery_delay(&sdram_config, EBI_WRDLY_1CLK_gc); |
29 | ebi_sdram_set_self_refresh_to_active_delay(&sdram_config, |
30 | EBI_ESRDLY_7CLK_gc); |
31 | ebi_sdram_set_row_to_col_delay(&sdram_config, EBI_ROWCOLDLY_7CLK_gc); |
32 | ebi_sdram_set_refresh_period(&sdram_config, BOARD_EBI_SDRAM_REFRESH); |
33 | ebi_sdram_set_initialization_delay(&sdram_config, |
34 | BOARD_EBI_SDRAM_INITDLY); |
35 | |
36 | /* Write SDRAM configuration into the EBI registers. */
|
37 | ebi_sdram_write_config(&sdram_config); |
38 | /* Write the chip select configuration into the EBI registers. */
|
39 | ebi_cs_write_config(EBI_SDRAM_CS, &cs_config); |
40 | |
41 | ebi_enable_cs(EBI_SDRAM_CS, &cs_config); |
42 | do { |
43 | // Wait for SDRAM to initialize.
|
44 | } while (!ebi_sdram_is_ready()); |
45 | |
46 | /* Debug: Enable LED1: SDRAM is ready. */
|
47 | LED_PORT.OUTCLR = OLED1; |
48 | _delay_ms(100); |
49 | LED_PORT.OUTSET = OLED1; |
50 | }
|
:
Bearbeitet durch User
Das mit der Startadresse hab ich mir schon gedacht. Da das Register BASEADDR aber nur 12 Bit groß ist, vermute ich dass es sich hierbei nur um einen Multiplikator handelt. Im Datenblatt steht das die Basisadresse ein Vielfaches von 4096 sein muss und wenn man nun 4096 mit der größten Zahl die in BASEADDR stehen kann (4096) multipliziert, kommt man auf die 16MB die max vom EBI Adressiert werden können. Leider bekomme ich das EBI aber immer noch nicht zum Laufen und hänge deshalb den Code an. Es wird übrigens 512K SRAM verwendet.
1 | #define SRAM_groese 0x80000
|
2 | #define Basisadresse 0x80000 // ACHTUNG MUSS EIN VIELFACHES VON 4096 SEIN
|
3 | #define BASEADDR_ (Basisadresse/4096)
|
4 | |
5 | void EBI_SRAM_init (void) { |
6 | |
7 | PORTH_OUTSET = (1<<RAM_CE)|(1<<RAM_WE)|(1<<RAM_OE); // setze alle low aktiven signale auf 1 (Datenblatt Seite 269) |
8 | |
9 | EBI_CTRL = 0b01001001; // AL1&2 und 3port 8bit datenbus |
10 | EBI_CS0_CTRLA = 0b00101101; // 512Kb CS=Sram |
11 | EBI_CS0_CTRLB = 0b00000111; // /7CLK |
12 | EBI_CS0_BASEADDR = BASEADDR_; |
13 | |
14 | |
15 | __far_mem_write(Basisadresse,1); |
16 | |
17 | if(__far_mem_read(Basisadresse) == 1) FT232_sende_String("\nEBI OK\n");else FT232_sende_String("\nEBI FEHLER\n"); |
18 | |
19 | |
20 | }
|
Hm, ob die Adressen so stimmen? Habe auch einen Xmega128A3U zum Spielen und ausprobieren da und daher unter anderem auf einen alten, interessanten Thread gestoßen: Beitrag "Re: XMEGA/ AVR-EXPLAIN code examples und Diskussion"
Vielen Dank für den Link! Nur leider wird bei den meisten Beispielen SDRAM benutzt. Ich hab jetzt mal versucht ob der RAM Hardwaremäßig funktioniert (Code im Anhang) und das tut er . Außerdem habe ich bemerkt das die Adress Latch´s nicht aktualisiert werden wenn es übers EBI läuft.
1 | void uint8_t EBI_SRAM_Read (uint32_t Adresse) { |
2 | PORTK_OUT = ((uint32_t)Adresse >> 16); |
3 | PORTH_OUTSET = (1<<RAM_REG_1); |
4 | PORTH_OUTCLR = (1<<RAM_REG_1); |
5 | PORTK_OUT = ((uint32_t)Adresse >> 8); |
6 | PORTH_OUTSET = (1<<RAM_REG_0); |
7 | PORTH_OUTCLR = (1<<RAM_REG_0); |
8 | PORTK_OUT = (uint32_t)Adresse; |
9 | |
10 | PORTJ_DIR = 0x00; |
11 | PORTH_OUTCLR = (1<<RAM_OE); |
12 | return (PORTJ_IN); |
13 | };
|
14 | |
15 | void EBI_SRAM_write (uint32_t Adresse,uint8_t byte) { |
16 | PORTK_OUT = ((uint32_t)Adresse >> 16); |
17 | PORTH_OUTSET = (1<<RAM_REG_1); |
18 | PORTH_OUTCLR = (1<<RAM_REG_1); |
19 | PORTK_OUT = ((uint32_t)Adresse >> 8); |
20 | PORTH_OUTSET = (1<<RAM_REG_0); |
21 | PORTH_OUTCLR = (1<<RAM_REG_0); |
22 | PORTK_OUT = (uint32_t)Adresse; |
23 | |
24 | PORTH_OUTSET = (1<<RAM_OE); |
25 | PORTJ_DIR = 0xFF; |
26 | PORTJ_OUT = byte; |
27 | PORTH_OUTCLR = (1<<RAM_WE); |
28 | PORTH_OUTSET = (1<<RAM_WE); |
29 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.