Hello
For my bachelor thesis I am working on a project based on the LaunchPad EK-TM4C1294XL. I connected an external sdram (IS42S16320D-7TL) to the epi of the microcontroller. I am using tivaWare and the epi example with an adjusted pin configuration. The example, which writes and reads the first and the last two elements of the ram works perfectly.
To be shure that all cells of the memory are working, I wrote a little test script, which writes in all cells the same value and reads it back afterwards. If the written and the read value differ, it prints a message on the uart. After the read, the value is incremented, so that every cell is tested with every possible value.
Unfortunately I get very strange results with specific values and I can’t figure out why.
The first error occurs allways at the value 0x8000. The addresses differ, but are always even.
It is the first time I am working with external sdram and I already spend some nights on that problem, but couldn't find a solution for it. That’s why I would like to ask more experienced users for help.
Thank you
Jochen
I append my test code, parts of a uart log file.
#include <stdint.h> #include <stdbool.h> #include <stdlib.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_uart.h" #include "inc/hw_epi.h" #include "driverlib/gpio.h" #include "driverlib/epi.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "utils/uartstdio.h" #include "utils/ustdlib.h" //***************************************************************************** // // The starting and ending address for the 64MB SDRAM chip (32Meg x 16bits) on // the SDRAM daughter board. // //***************************************************************************** #define SDRAM_START_ADDRESS 0x00000000 #define SDRAM_END_ADDRESS 0x01FFFFFF //= dez33554431 = 33554432 Zellen a 16 Bit = 8192 Zeilen * 1024 Spalten * 4 Banks //***************************************************************************** // // The Mapping address space for the EPI SDRAM. // //***************************************************************************** #define SDRAM_MAPPING_ADDRESS 0x60000000 //***************************************************************************** // //! \addtogroup example_list //! <h1>uDMA (udma_demo)</h1> //! //! //! UART0, connected to the ICDI virtual COM port and running at 115,200, //! 8-N-1, is used to display messages from this application. // //***************************************************************************** //**************************************************************************** // // System clock rate in Hz. // //**************************************************************************** uint32_t g_ui32SysClock; //***************************************************************************** // // pointer to SDRam Beginning // //***************************************************************************** static volatile uint16_t *g_pui16EPISdram; //***************************************************************************** // // The error routine that is called if the driver library encounters an error. // //***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif void ConfigureUART(void) { // // Enable the GPIO Peripheral used by the UART. // MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Enable UART0 // MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); MAP_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0); // // Configure GPIO Pins for UART mode. // MAP_GPIOPinConfigure(GPIO_PA0_U0RX); MAP_GPIOPinConfigure(GPIO_PA1_U0TX); MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Initialize the UART for console I/O. // UARTStdioConfig(0, 115200, g_ui32SysClock); } //***************************************************************************** int main(void) { // // Set the clocking to run directly from the crystal at 120MHz. // g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); ConfigureUART(); SysCtlDelay(30000000); UARTprintf("\033[2J\033[H"); //clear window UARTprintf("EPI Demo\n"); //Enable EPI Module MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_EPI0); //Enable GPIO Ports MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); //Enable GPIO special function MAP_GPIOPinConfigure(GPIO_PK0_EPI0S0); MAP_GPIOPinConfigure(GPIO_PH1_EPI0S1); MAP_GPIOPinConfigure(GPIO_PK2_EPI0S2); MAP_GPIOPinConfigure(GPIO_PK3_EPI0S3); MAP_GPIOPinConfigure(GPIO_PC7_EPI0S4); MAP_GPIOPinConfigure(GPIO_PC6_EPI0S5); MAP_GPIOPinConfigure(GPIO_PC5_EPI0S6); MAP_GPIOPinConfigure(GPIO_PC4_EPI0S7); MAP_GPIOPinConfigure(GPIO_PA6_EPI0S8); MAP_GPIOPinConfigure(GPIO_PA7_EPI0S9); MAP_GPIOPinConfigure(GPIO_PG1_EPI0S10); MAP_GPIOPinConfigure(GPIO_PG0_EPI0S11); MAP_GPIOPinConfigure(GPIO_PM3_EPI0S12); MAP_GPIOPinConfigure(GPIO_PM2_EPI0S13); MAP_GPIOPinConfigure(GPIO_PM1_EPI0S14); MAP_GPIOPinConfigure(GPIO_PM0_EPI0S15); MAP_GPIOPinConfigure(GPIO_PL0_EPI0S16); MAP_GPIOPinConfigure(GPIO_PL1_EPI0S17); MAP_GPIOPinConfigure(GPIO_PL2_EPI0S18); MAP_GPIOPinConfigure(GPIO_PL3_EPI0S19); //EPI020 ... EPI027 not used for SDRAM MAP_GPIOPinConfigure(GPIO_PB3_EPI0S28); MAP_GPIOPinConfigure(GPIO_PN2_EPI0S29); MAP_GPIOPinConfigure(GPIO_PN3_EPI0S30); MAP_GPIOPinConfigure(GPIO_PK5_EPI0S31); GPIOPinTypeEPI(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7); GPIOPinTypeEPI(GPIO_PORTB_BASE, GPIO_PIN_3); GPIOPinTypeEPI(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); GPIOPinTypeEPI(GPIO_PORTG_BASE, GPIO_PIN_0 | GPIO_PIN_1); GPIOPinTypeEPI(GPIO_PORTH_BASE, GPIO_PIN_1); GPIOPinTypeEPI(GPIO_PORTK_BASE, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5); GPIOPinTypeEPI(GPIO_PORTL_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); GPIOPinTypeEPI(GPIO_PORTM_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); GPIOPinTypeEPI(GPIO_PORTN_BASE, GPIO_PIN_2 | GPIO_PIN_3); // // Set the EPI divider. // EPIDividerSet(EPI0_BASE, 1); //1 ==> 1/2 * sysClock = 60MHz // // Select SDRAM mode. // EPIModeSet(EPI0_BASE, EPI_MODE_SDRAM); // // Configure SDRAM mode. // EPIConfigSDRAMSet(EPI0_BASE, (EPI_SDRAM_CORE_FREQ_50_100 | EPI_SDRAM_FULL_POWER | EPI_SDRAM_SIZE_512MBIT), 400); // // Set the address map. // EPIAddressMapSet(EPI0_BASE, EPI_ADDR_RAM_SIZE_256MB | EPI_ADDR_RAM_BASE_6); //Although our SDRAM is only 64MB, there is no 64MB aperture option so we pick the next larger size. // // Wait for the EPI initialization to complete. // while(HWREG(EPI0_BASE + EPI_O_STAT) & EPI_STAT_INITSEQ) { // // Wait for SDRAM initialization to complete. // } // Set Pointer to beginning of SDRam g_pui16EPISdram = (uint16_t *)0x60000000; //other adresses possible to, see errata sheet // // At this point, the SDRAM is accessible and available for use. // // // Read the initial data in SDRAM, and display it on the console. // UARTprintf(" SDRAM Initial Data:\n"); UARTprintf(" Mem[0x6000.0000] = 0x%4x\n", g_pui16EPISdram[SDRAM_START_ADDRESS]); UARTprintf(" Mem[0x6000.0001] = 0x%4x\n", g_pui16EPISdram[SDRAM_START_ADDRESS + 1]); UARTprintf(" Mem[0x603F.FFFE] = 0x%4x\n", g_pui16EPISdram[SDRAM_END_ADDRESS - 1]); UARTprintf(" Mem[0x603F.FFFF] = 0x%4x\n\n", g_pui16EPISdram[SDRAM_END_ADDRESS]); // // Display what writes we are doing on the console. // UARTprintf(" SDRAM Write:\n"); UARTprintf(" Mem[0x6000.0000] <- 0xabcd\n"); UARTprintf(" Mem[0x6000.0001] <- 0x1234\n"); UARTprintf(" Mem[0x603F.FFFE] <- 0xdcba\n"); UARTprintf(" Mem[0x603F.FFFF] <- 0x0000\n\n"); // // Write to the first 2 and last 2 address of the SDRAM . Since the // SDRAM card is word addressable, we will write words. // g_pui16EPISdram[SDRAM_START_ADDRESS] = 0xabcd; g_pui16EPISdram[SDRAM_START_ADDRESS + 1] = 0x1234; g_pui16EPISdram[SDRAM_END_ADDRESS - 1] = 0xdcba; g_pui16EPISdram[SDRAM_END_ADDRESS] = 0x0000; // // Read back the data you wrote, and display it on the console. // UARTprintf(" SDRAM Read:\n"); UARTprintf(" Mem[0x6000.0000] = 0x%4x\n", g_pui16EPISdram[SDRAM_START_ADDRESS]); UARTprintf(" Mem[0x6000.0001] = 0x%4x\n", g_pui16EPISdram[SDRAM_START_ADDRESS + 1]); UARTprintf(" Mem[0x603F.FFFE] = 0x%4x\n", g_pui16EPISdram[SDRAM_END_ADDRESS - 1]); UARTprintf(" Mem[0x603F.FFFF] = 0x%4x\n\n", g_pui16EPISdram[SDRAM_END_ADDRESS]); UARTprintf("full Test\n\n\n"); for(j=0x7fff;j<=0xFFFF;j++) { UARTprintf("\n\nWert 0x%4x\n\n",j); for(i = SDRAM_START_ADDRESS; i<=SDRAM_END_ADDRESS;i++) { g_pui16EPISdram[i] = j; } for(i = SDRAM_START_ADDRESS; i<=SDRAM_END_ADDRESS;i++) { tmp = g_pui16EPISdram[i]; if(tmp != j) UARTprintf("A %10d W:0x%4x\n", i, tmp); //Adresse Istwert } } while(1) {} }