Multiple purpose SDRAM use

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Multiple purpose SDRAM use

855 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Mon Feb 10 06:56:42 MST 2014
Hi,

In my project (using the MCB4357 board), I'm using the SDRAM for a lot of things:

- emWin buffering
- calculation buffering
- file system cache (not implemented yet, but will do it)

The code is not running from SDRAM though and I'm not using an OS. So it's a single process. Is there a problem doing this? I'm asking this because I observe the following problems:

- Sometimes, always the same pixels on my display do not behave like they should, but sometimes they are ok.
- When I'm doing calculations, so I'm heavily using the SDRAM for calculation buffering, my display gets corrupted (a lot of small lines of about 5 pixels appear everywhere on the screen

The first thing I checked was my memory allocation for my buffers (different addresses and length should not overlap), but that seems ok. So I'm not sure if using the SDRAM the way I want to use it is ok.

Any tips?

Thanks a lot.
Labels (1)
0 Kudos
7 Replies

720 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by LVL on Mon Feb 24 07:46:06 MST 2014
I could be related to this problem:
http://www.lpcware.com/content/forum/lpcopen-204-problem-sdram-related-boardsetupmuxing
0 Kudos

720 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Tue Feb 11 14:55:48 MST 2014
hum, I found the problem.It was not related to my buffers, but to the SDRAM configuration.

I used a file named SDRAM_Init.c originally taken from an example (can't recall if it was from a Keil example or a LPC one, but it was for the MCB4357 board I'm sure). That configuration was working fine on some MCB4357 boards (that I don't have anymore). After validating that the SDRAM chip had indeed changed between the boards, I used the initialization code made by Keil in the MCB4357 emWin demo and all my problems are gone. No more random pixels, no more weird screen lines when doing my calculations.
0 Kudos

720 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Mon Feb 10 14:38:02 MST 2014
Here is the code. I just reduced my GUI buffer to only 8K and left it in internal RAM. I still have both problems, so it it's not related to this I presume.


LCDConf.c

/*********************************************************************
*
*       Layer configuration
*
**********************************************************************
*/


//
// Physical display size
//
#define XSIZE_PHYS 240
#define YSIZE_PHYS 320

//
// Color conversion
//
//#define COLOR_CONVERSION GUICC_M565
#define COLOR_CONVERSION GUICC_565

//
// Buffers / VScreens
//
#define VRAM_ADDR0x28000000
#define NUM_BUFFERS   1
#define NUM_VSCREENS  1
#define BITSPERPIXEL16

//
// Display orientation
//
#define DISPLAY_ORIENTATION  0
//#define DISPLAY_ORIENTATION               (GUI_MIRROR_X | GUI_MIRROR_Y)
//#define DISPLAY_ORIENTATION (GUI_SWAP_XY | GUI_MIRROR_Y)
//#define DISPLAY_ORIENTATION (GUI_SWAP_XY | GUI_MIRROR_X)

//
// Display driver
//
//#define DISPLAY_DRIVER GUIDRV_LIN_16
#if   (DISPLAY_ORIENTATION == (GUI_MIRROR_X))
  #define DISPLAY_DRIVER GUIDRV_LIN_OX_16
#elif (DISPLAY_ORIENTATION == (GUI_MIRROR_Y))
  #define DISPLAY_DRIVER GUIDRV_LIN_OY_16
#elif (DISPLAY_ORIENTATION == (GUI_MIRROR_X | GUI_MIRROR_Y))
  #define DISPLAY_DRIVER GUIDRV_LIN_OXY_16
#elif (DISPLAY_ORIENTATION == (GUI_SWAP_XY))
  #define DISPLAY_DRIVER GUIDRV_LIN_OS_16
#elif (DISPLAY_ORIENTATION == (GUI_SWAP_XY | GUI_MIRROR_X))
  #define DISPLAY_DRIVER GUIDRV_LIN_OSX_16
#elif (DISPLAY_ORIENTATION == (GUI_SWAP_XY | GUI_MIRROR_Y))
  #define DISPLAY_DRIVER GUIDRV_LIN_OSY_16
#else
  #define DISPLAY_DRIVER GUIDRV_LIN_16
#endif

//
// Touch screen
//
#define USE_TOUCH   0
//
// Touch screen calibration
#define TOUCH_X_MIN 0x00E0
#define TOUCH_X_MAX 0x0F40
#define TOUCH_Y_MIN 0x00C0
#define TOUCH_Y_MAX 0x0F60

/*********************************************************************
*
*       Configuration checking
*
**********************************************************************
*/
#ifndef   XSIZE_PHYS
  #error Physical X size of display is not defined!
#endif
#ifndef   YSIZE_PHYS
  #error Physical Y size of display is not defined!
#endif
#ifndef   COLOR_CONVERSION
  #error Color conversion not defined!
#endif
#ifndef   DISPLAY_DRIVER
  #error No display driver defined!
#endif
#ifndef   NUM_VSCREENS
  #define NUM_VSCREENS 1
#else
  #if (NUM_VSCREENS <= 0)
    #error At least one screeen needs to be defined!
  #endif
#endif
#if (NUM_VSCREENS > 1) && (NUM_BUFFERS > 1)
  #error Virtual screens and multiple buffers are not allowed!
#endif
#ifndef   DISPLAY_ORIENTATION
  #define DISPLAY_ORIENTATION  0
#endif

#if ((DISPLAY_ORIENTATION & GUI_SWAP_XY) != 0)
#define LANDSCAPE   1
#else
#define LANDSCAPE   0
#endif

#if (LANDSCAPE == 1)
#define WIDTH       YSIZE_PHYS  /* Screen Width (in pixels)         */
#define HEIGHT      XSIZE_PHYS  /* Screen Hight (in pixels)         */
#else
#define WIDTH       XSIZE_PHYS  /* Screen Width (in pixels)         */
#define HEIGHT      YSIZE_PHYS  /* Screen Hight (in pixels)         */
#endif

#if ((DISPLAY_ORIENTATION & GUI_SWAP_XY) != 0)
  #if ((DISPLAY_ORIENTATION & GUI_MIRROR_X) != 0)
    #define TOUCH_TOP    TOUCH_X_MAX
    #define TOUCH_BOTTOM TOUCH_X_MIN
  #else
    #define TOUCH_TOP    TOUCH_X_MIN
    #define TOUCH_BOTTOM TOUCH_X_MAX
  #endif
  #if ((DISPLAY_ORIENTATION & GUI_MIRROR_Y) != 0)
    #define TOUCH_LEFT   TOUCH_Y_MAX
    #define TOUCH_RIGHT  TOUCH_Y_MIN
  #else
    #define TOUCH_LEFT   TOUCH_Y_MIN
    #define TOUCH_RIGHT  TOUCH_Y_MAX
  #endif
#else
  #if ((DISPLAY_ORIENTATION & GUI_MIRROR_X) != 0)
    #define TOUCH_LEFT   TOUCH_X_MAX
    #define TOUCH_RIGHT  TOUCH_X_MIN
  #else
    #define TOUCH_LEFT   TOUCH_X_MIN
    #define TOUCH_RIGHT  TOUCH_X_MAX
  #endif
  #if ((DISPLAY_ORIENTATION & GUI_MIRROR_Y) != 0)
    #define TOUCH_TOP    TOUCH_Y_MAX
    #define TOUCH_BOTTOM TOUCH_Y_MIN
  #else
    #define TOUCH_TOP    TOUCH_Y_MIN
    #define TOUCH_BOTTOM TOUCH_Y_MAX
  #endif
#endif

/*
#pragma data_alignment=8 // 8 byte align frame buffer
#pragma location="VRAM"
static __no_init U32 _aVRAM[NUM_BUFFERS * NBSP_LCD_VRAM_BUFFER_SIZE_IN_BYTES / (4)];
#define VRAM_ADDR (U32)&_aVRAM[0]
*/

/*********************************************************************
*
*       Driver Port functions
*
**********************************************************************
*/
extern void LCD_X_Init(void);
#if (GCONFIG_USE_PROTO_LCD == 0)
extern void LCD_X_Write00_16(U16 c);
extern void LCD_X_Write01_16(U16 c);
#endif

/*********************************************************************
*
*       Private code
*
**********************************************************************
*/
static void LCDConf_Delay (int cnt) {
  cnt <<= 15;
  while (cnt--);
}

#if (GCONFIG_USE_PROTO_LCD == 0)
static void wr_reg (U16 reg, U16 dat) {
  LCD_X_Write00_16(reg);
  LCD_X_Write01_16(dat);
}
#endif

/*********************************************************************
*
*       _InitController
*
* Purpose:
*   Initializes the display controller
*/
static void _InitController(void) {
#ifndef WIN32

  LCD_X_Init();

  /* LCD with HX8347-D LCD Controller                                         */

#if (GCONFIG_USE_PROTO_LCD == 0)
  /* Driving ability settings ------------------------------------------------*/
  wr_reg(0xEA, 0x00);                   /* Power control internal used (1)    */
  wr_reg(0xEB, 0x20);                   /* Power control internal used (2)    */
  wr_reg(0xEC, 0x0C);                   /* Source control internal used (1)   */
  wr_reg(0xED, 0xC7);                   /* Source control internal used (2)   */
  wr_reg(0xE8, 0x38);                   /* Source output period Normal mode   */
  wr_reg(0xE9, 0x10);                   /* Source output period Idle mode     */
  wr_reg(0xF1, 0x01);                   /* RGB 18-bit interface ;0x0110       */
  wr_reg(0xF2, 0x10);

  /* Adjust the Gamma Curve --------------------------------------------------*/
  wr_reg(0x40, 0x01);
  wr_reg(0x41, 0x00);
  wr_reg(0x42, 0x00);
  wr_reg(0x43, 0x10);
  wr_reg(0x44, 0x0E);
  wr_reg(0x45, 0x24);
  wr_reg(0x46, 0x04);
  wr_reg(0x47, 0x50);
  wr_reg(0x48, 0x02);
  wr_reg(0x49, 0x13);
  wr_reg(0x4A, 0x19);
  wr_reg(0x4B, 0x19);
  wr_reg(0x4C, 0x16);

  wr_reg(0x50, 0x1B);
  wr_reg(0x51, 0x31);
  wr_reg(0x52, 0x2F);
  wr_reg(0x53, 0x3F);
  wr_reg(0x54, 0x3F);
  wr_reg(0x55, 0x3E);
  wr_reg(0x56, 0x2F);
  wr_reg(0x57, 0x7B);
  wr_reg(0x58, 0x09);
  wr_reg(0x59, 0x06);
  wr_reg(0x5A, 0x06);
  wr_reg(0x5B, 0x0C);
  wr_reg(0x5C, 0x1D);
  wr_reg(0x5D, 0xCC);

  /* Power voltage setting ---------------------------------------------------*/
  wr_reg(0x1B, 0x1B);
  wr_reg(0x1A, 0x01);
  wr_reg(0x24, 0x2F);
  wr_reg(0x25, 0x57);
  wr_reg(0x23, 0x88);

  /* Power on setting --------------------------------------------------------*/
  wr_reg(0x18, 0x36);                   /* Internal oscillator frequency adj  */
  wr_reg(0x19, 0x01);                   /* Enable internal oscillator         */
  wr_reg(0x01, 0x00);                   /* Normal mode, no scrool             */
  wr_reg(0x1F, 0x88);                   /* Power control 6 - DDVDH Off        */
  LCDConf_Delay(200);
  wr_reg(0x1F, 0x82);                   /* Power control 6 - Step-up: 3 x VCI */
  LCDConf_Delay(50);                 
  wr_reg(0x1F, 0x92);                   /* Power control 6 - Step-up: On      */
  LCDConf_Delay(50);
  wr_reg(0x1F, 0xD2);                   /* Power control 6 - VCOML active     */
  LCDConf_Delay(50);

  /* Color selection ---------------------------------------------------------*/
  wr_reg(0x17, 0x55);                   /* RGB, System interface: 16 Bit/Pixel*/
  wr_reg(0x00, 0x00);                   /* Scrolling off, no standby          */

  /* Interface config --------------------------------------------------------*/
  wr_reg(0x2F, 0x11);                   /* LCD Drive: 1-line inversion        */
  wr_reg(0x31, 0x02);                   /* Value for SPI: 0x00, RBG: 0x02     */
  wr_reg(0x32, 0x00);                   /* DPL=0, HSPL=0, VSPL=0, EPL=0       */

  /* Display on setting ------------------------------------------------------*/
  wr_reg(0x28, 0x38);                   /* PT(0,0) active, VGL/VGL            */
  LCDConf_Delay(200);
  wr_reg(0x28, 0x3C);                   /* Display active, VGL/VGL            */

  wr_reg(0x16, 0x00);                   /* Mem Access Control (MX/Y/V/L,BGR)  */

  /* Display scrolling settings ----------------------------------------------*/
  wr_reg(0x0E, 0x00);                   /* TFA MSB                            */
  wr_reg(0x0F, 0x00);                   /* TFA LSB                            */
  wr_reg(0x10, 320 >> 8);               /* VSA MSB                            */
  wr_reg(0x11, 320 &  0xFF);            /* VSA LSB                            */
  wr_reg(0x12, 0x00);                   /* BFA MSB                            */
  wr_reg(0x13, 0x00);                   /* BFA LSB                            */
#endif

#endif  /* WIN32 */
}

/*********************************************************************
*
*       _SetVRAMAddr
*
* Purpose:
*   Should set the frame buffer base address
*/
static void _SetVRAMAddr(void * pVRAM) {
  /* TBD by customer */
}

/*********************************************************************
*
*       _SetOrg
*
* Purpose:
*   Should set the origin of the display typically by modifying the
*   frame buffer base address register
*/
static void _SetOrg(int xPos, int yPos) {
  /* TBD by customer */
//LPC_LCD->UPBASE = NBSP_SDRAM_GUI_VRAM_ADDR + (xPos * YSIZE_PHYS * PIXEL_WIDTH);
}

/*********************************************************************
*
*       _SetLUTEntry
*
* Purpose:
*   Should set the desired LUT entry
*/
static void _SetLUTEntry(LCD_COLOR Color, U8 Pos) {
  /* TBD by customer */
}

/*********************************************************************
*
*       Public code
*
**********************************************************************
*/
/*********************************************************************
*
*       LCD_X_Config
*
* Purpose:
*   Called during the initialization process in order to set up the
*   display driver configuration.
*   
*/
void LCD_X_Config(void) {
  
  #if (NUM_BUFFERS > 1)
    GUI_MULTIBUF_Config(NUM_BUFFERS);
  #endif
  //
  // Set display driver and color conversion for 1st layer
  //
  GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER, COLOR_CONVERSION, 0, 0);
  //
  // Display driver configuration, required for Lin-driver
  //
  if (LCD_GetSwapXY()) {
    LCD_SetSizeEx (0, YSIZE_PHYS, XSIZE_PHYS);
    LCD_SetVSizeEx(0, YSIZE_PHYS * NUM_VSCREENS, XSIZE_PHYS);
  } else {
    LCD_SetSizeEx (0, XSIZE_PHYS, YSIZE_PHYS);
    LCD_SetVSizeEx(0, XSIZE_PHYS, YSIZE_PHYS * NUM_VSCREENS);
  }
  LCD_SetVRAMAddrEx(0, (void *)VRAM_ADDR);

  #if (USE_TOUCH == 1)
    //
    // Set orientation of touch screen
    //
    GUI_TOUCH_SetOrientation(DISPLAY_ORIENTATION);
    //
    // Calibrate touch screen
    //
    GUI_TOUCH_Calibrate(GUI_COORD_X, 0, WIDTH  - 1, TOUCH_LEFT, TOUCH_RIGHT);
    GUI_TOUCH_Calibrate(GUI_COORD_Y, 0, HEIGHT - 1, TOUCH_TOP,  TOUCH_BOTTOM);
  #endif
  //
  // Set user palette data (only required if no fixed palette is used)
  //
  #if defined(PALETTE)
    LCD_SetLUTEx(0, PALETTE);
  #endif
}

/*********************************************************************
*
*       LCD_X_DisplayDriver
*
* Purpose:
*   This function is called by the display driver for several purposes.
*   To support the according task the routine needs to be adapted to
*   the display controller. Please note that the commands marked with
*   'optional' are not cogently required and should only be adapted if 
*   the display controller supports these features.
*
* Parameter:
*   LayerIndex - Index of layer to be configured
*   Cmd        - Please refer to the details in the switch statement below
*   pData      - Pointer to a LCD_X_DATA structure
*
* Return Value:
*   < -1 - Error
*     -1 - Command not handled
*      0 - OK
*/
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
  int r;

  switch (Cmd) {
  //
  // Required
  //
  case LCD_X_INITCONTROLLER: {
    //
    // Called during the initialization process in order to set up the
    // display controller and put it into operation. If the display
    // controller is not initialized by any external routine this needs
    // to be adapted by the customer...
    //
    _InitController();
    return 0;
  }
  case LCD_X_SETVRAMADDR: {
    //
    // Required for setting the address of the video RAM for drivers
    // with memory mapped video RAM which is passed in the 'pVRAM' element of p
    //
    LCD_X_SETVRAMADDR_INFO * p;
    p = (LCD_X_SETVRAMADDR_INFO *)pData;
    _SetVRAMAddr(p->pVRAM);
    return 0;
  }
  case LCD_X_SETORG: {
    //
    // Required for setting the display origin which is passed in the 'xPos' and 'yPos' element of p
    //
    LCD_X_SETORG_INFO * p;
    p = (LCD_X_SETORG_INFO *)pData;
    _SetOrg(p->xPos, p->yPos);
    return 0;
  }
  case LCD_X_SETLUTENTRY: {
    //
    // Required for setting a lookup table entry which is passed in the 'Pos' and 'Color' element of p
    //
    LCD_X_SETLUTENTRY_INFO * p;
    p = (LCD_X_SETLUTENTRY_INFO *)pData;
    _SetLUTEntry(p->Color, p->Pos);
    return 0;
  }
  /*
  case LCD_X_SHOWBUFFER: {
LCD_X_SHOWBUFFER_INFO * p;
p = (LCD_X_SHOWBUFFER_INFO *)pData;
//
// Make the given buffer visible
//
LPC_LCD->UPBASE = NBSP_SDRAM_GUI_VRAM_ADDR + (NBSP_LCD_VRAM_BUFFER_SIZE_IN_BYTES * p->Index);
//
// Send a confirmation that the buffer is visible now
//
GUI_MULTIBUF_Confirm(p->Index);
}
break;
  */
  default:
    r = -1;
  }
  return r;
}

/*************************** End of file ****************************/



GUIConf.c

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
//
// Define the available number of bytes available for the GUI
//
#define GUI_NUMBYTES  0x2000
//
// Define the average block size
//
#define GUI_BLOCKSIZE 0x80

/*********************************************************************
*
*       Public code
*
**********************************************************************
*/
/*********************************************************************
*
*       GUI_X_Config
*
* Purpose:
*   Called during the initialization process in order to set up the
*   available memory for the GUI.
*/
void GUI_X_Config(void) {
//
// 32 bit aligned memory area
//
static U32 aMemory[GUI_NUMBYTES / 4];

//
// Assign memory to emWin
//
GUI_ALLOC_AssignMemory((U32*)aMemory, GUI_NUMBYTES);
GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE);
}

/*************************** End of file ****************************/



Also, in my LCD_X_Init() function, this is called:
LPC_LCD->UPBASE = 0x28000000;


I can't post the calculations though. But I'll try to replace those calculations with specific SDRAM Read/Write cycles at the same addresses.
0 Kudos

720 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by schisanoa on Mon Feb 10 14:02:24 MST 2014
Without code is not simple help you. If you try with a little small calculation the problem remain the same or the display work better?
0 Kudos

720 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Mon Feb 10 13:49:41 MST 2014
Here are the lines that appears when I do calculations (in attachment). They appear progressively. Before calculations, in this example, the screen was all black.

By the way, apart from the 2 problems mentioned in my original post, my application displays correctly (logo bmp, text, etc.)
0 Kudos

720 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Mon Feb 10 08:59:49 MST 2014
I'm working on the MCB4357 and my final custom board will probably be connected like it. So I'm using the LCD controller in 5:6:5 RGB mode.

- SDRAM is connected to the EMC (dynamic CS, 0x28000000)
- LCD is connected to the LCD controller pins.

SDRAM is used by emWin with the linear driver.

0 Kudos

720 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by schisanoa on Mon Feb 10 08:53:24 MST 2014
Where is connected the display? Are you working with the display controller? What kind of display?
0 Kudos