873 lines
25 KiB
C
873 lines
25 KiB
C
/****************************************************************************
|
|
* arch/arm/src/stm32/stm32_ltdc.c
|
|
*
|
|
* Copyright (C) 2013 Ken Pettit. All rights reserved.
|
|
* Author: Ken Pettit <pettitd@gmail.com>
|
|
*
|
|
* References:
|
|
* STM32F429 Technical Reference Manual and Data Sheet
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
|
* used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <debug.h>
|
|
|
|
#include <nuttx/video/fb.h>
|
|
#include <nuttx/kmalloc.h>
|
|
|
|
#include <arch/board/board.h>
|
|
|
|
#include "up_arch.h"
|
|
#include "up_internal.h"
|
|
#include "stm32.h"
|
|
#include "stm32_ltdc.h"
|
|
|
|
/****************************************************************************
|
|
* Pre-Processor Definitions
|
|
****************************************************************************/
|
|
/* Configuration ************************************************************/
|
|
|
|
#ifndef CONFIG_STM32_LTDC_DEFBACKLIGHT
|
|
# define CONFIG_STM32_LTDC_DEFBACKLIGHT 0xf0
|
|
#endif
|
|
#define STM32_LTDC_BACKLIGHT_OFF 0x00
|
|
|
|
/* Color/video formats */
|
|
|
|
/* Layer 1 format */
|
|
|
|
#if defined(CONFIG_STM32_LTDC_L1_L8)
|
|
# define STM32_LTDC_L1_BPP 8
|
|
# define STM32_LTDC_L1_COLOR_FMT FB_FMT_RGB8
|
|
#elif defined(CONFIG_STM32_LTDC_L1_AL44)
|
|
# define STM32_LTDC_L1_BPP 8
|
|
# define STM32_LTDC_L1_COLOR_FMT ???
|
|
#elif defined(CONFIG_STM32_LTDC_L1_AL88)
|
|
# define STM32_LTDC_L1_BPP 16
|
|
# define STM32_LTDC_L1_COLOR_FMT ???
|
|
#elif defined(CONFIG_STM32_LTDC_L1_ARGB4444)
|
|
# define STM32_LTDC_L1_BPP 16
|
|
# define STM32_LTDC_L1_COLOR_FMT ???
|
|
#elif defined(CONFIG_STM32_LTDC_L1_RGB565)
|
|
# define STM32_LTDC_L1_BPP 16
|
|
# define STM32_LTDC_L1_COLOR_FMT FB_FMT_RGB16_565
|
|
#elif defined(CONFIG_STM32_LTDC_L1_ARGB1555)
|
|
# define STM32_LTDC_L1_BPP 16
|
|
# define STM32_LTDC_L1_COLOR_FMT ???
|
|
#elif defined(CONFIG_STM32_LTDC_L1_RGB888)
|
|
# define STM32_LTDC_L1_BPP 24
|
|
# define STM32_LTDC_L1_COLOR_FMT FB_FMT_RGB24
|
|
#elif defined(CONFIG_STM32_LTDC_L1_ARGB8888)
|
|
# define STM32_LTDC_L1_BPP 32
|
|
# define STM32_LTDC_L1_COLOR_FMT ???
|
|
#endif
|
|
|
|
/* Layer 2 format */
|
|
|
|
#if defined(CONFIG_STM32_LTDC_L2_L8)
|
|
# define STM32_LTDC_L2_BPP 8
|
|
# define STM32_LTDC_L2_COLOR_FMT FB_FMT_RGB8
|
|
#elif defined(CONFIG_STM32_LTDC_L2_AL44)
|
|
# define STM32_LTDC_L2_BPP 8
|
|
# define STM32_LTDC_L2_COLOR_FMT ???
|
|
#elif defined(CONFIG_STM32_LTDC_L2_AL88)
|
|
# define STM32_LTDC_L2_BPP 16
|
|
# define STM32_LTDC_L2_COLOR_FMT ???
|
|
#elif defined(CONFIG_STM32_LTDC_L2_ARGB4444)
|
|
# define STM32_LTDC_L2_BPP 16
|
|
# define STM32_LTDC_L2_COLOR_FMT ???
|
|
#elif defined(CONFIG_STM32_LTDC_L2_RGB565)
|
|
# define STM32_LTDC_L2_BPP 16
|
|
# define STM32_LTDC_L2_COLOR_FMT FB_FMT_RGB16_565
|
|
#elif defined(CONFIG_STM32_LTDC_L2_ARGB1555)
|
|
# define STM32_LTDC_L2_BPP 16
|
|
# define STM32_LTDC_L2_COLOR_FMT ???
|
|
#elif defined(CONFIG_STM32_LTDC_L2_RGB888)
|
|
# define STM32_LTDC_L2_BPP 24
|
|
# define STM32_LTDC_L2_COLOR_FMT FB_FMT_RGB24
|
|
#elif defined(CONFIG_STM32_LTDC_L2_ARGB8888)
|
|
# define STM32_LTDC_L2_BPP 32
|
|
# define STM32_LTDC_L2_COLOR_FMT ???
|
|
#endif
|
|
|
|
/* Framebuffer sizes in bytes */
|
|
|
|
#ifndef BOARD_LTDC_WIDTH
|
|
# error BOARD_LTDC_WIDTH must be defined in the board.h header file
|
|
#endif
|
|
|
|
#ifndef BOARD_LTDC_HEIGHT
|
|
# error BOARD_LTDC_HEIGHT must be defined in the board.h header file
|
|
#endif
|
|
|
|
#if STM32_LTDC_L1_BPP == 8
|
|
# define STM32_L1_STRIDE (BOARD_LTDC_WIDTH)
|
|
#elif STM32_LTDC_L1_BPP == 16
|
|
# define STM32_L1_STRIDE ((BOARD_LTDC_WIDTH * 16 + 7) / 8)
|
|
#elif STM32_LTDC_L1_BPP == 24
|
|
# define STM32_L1_STRIDE ((BOARD_LTDC_WIDTH * 24 + 7) / 8)
|
|
#elif STM32_LTDC_L1_BPP == 32
|
|
# define STM32_L1_STRIDE ((BOARD_LTDC_WIDTH * 32 + 7) / 8)
|
|
#else
|
|
# error Undefined or unrecognized base resolution
|
|
#endif
|
|
|
|
#define STM32_L1_FBSIZE (STM32_L1_STRIDE * BOARD_LTDC_HEIGHT)
|
|
|
|
#ifdef CONFIG_STM32_LTDC_L2
|
|
# ifndef CONFIG_STM32_LTDC_L2_WIDTH
|
|
# define CONFIG_STM32_LTDC_L2_WIDTH BOARD_LTDC_WIDTH
|
|
# endif
|
|
|
|
# if CONFIG_STM32_LTDC_L2_WIDTH > BOARD_LTDC_WIDTH
|
|
# error Width of Layer 2 exceeds the width of the display
|
|
# endif
|
|
|
|
# ifndef CONFIG_STM32_LTDC_L2_HEIGHT
|
|
# define CONFIG_STM32_LTDC_L2_HEIGHT BOARD_LTDC_HEIGHT
|
|
# endif
|
|
|
|
# if CONFIG_STM32_LTDC_L2_HEIGHT > BOARD_LTDC_HEIGHT
|
|
# error Height of Layer 2 exceeds the height of the display
|
|
# endif
|
|
|
|
# if STM32_LTDC_L2_BPP == 8
|
|
# define STM32_L2_STRIDE (CONFIG_STM32_LTDC_L2_WIDTH)
|
|
# elif STM32_LTDC_L2_BPP == 16
|
|
# define STM32_L2_STRIDE ((CONFIG_STM32_LTDC_L2_WIDTH * 16 + 7) / 8)
|
|
# elif STM32_LTDC_L2_BPP == 24
|
|
# define STM32_L2_STRIDE ((CONFIG_STM32_LTDC_L2_WIDTH * 24 + 7) / 8)
|
|
# elif STM32_LTDC_L2_BPP == 32
|
|
# define STM32_L2_STRIDE ((CONFIG_STM32_LTDC_L2_WIDTH * 32 + 7) / 8)
|
|
# else
|
|
# error Undefined or unrecognized base resolution
|
|
# endif
|
|
|
|
# define STM32_L2_FBSIZE (STM32_L2_STRIDE * CONFIG_STM32_LTDC_L2_HEIGHT)
|
|
|
|
#else
|
|
# define STM32_L2_FBSIZE (0)
|
|
#endif
|
|
|
|
/* Total memory used for framebuffers */
|
|
|
|
#define STM32_TOTAL_FBSIZE (STM32_L1_FBSIZE + STM32_L2_FBSIZE)
|
|
|
|
/* Debug */
|
|
|
|
#ifndef CONFIG_DEBUG
|
|
# undef CONFIG_STM32_LTDC_REGDEBUG
|
|
#endif
|
|
|
|
/* Preallocated LTDC framebuffers */
|
|
/* Maybe we need some meta-data for each layer? */
|
|
|
|
#define SIZEOF_STM32_LAYER_META_S 32
|
|
#define STM32_LTDC_LAYER_META_SIZE (2*SIZEOF_STM32_LAYER_META_S)
|
|
#define STM32_LTDC_LAYER_META_END (CONFIG_STM32_LTDC_FB_BASE+STM32_LTDC_LAYER_META_SIZE)
|
|
|
|
/* Position the framebuffer memory in the center of the memory set aside. We
|
|
* will use any skirts before or after the framebuffer memory as a guard against
|
|
* wild framebuffer writes.
|
|
*/
|
|
|
|
#define STM32_LTDC_BUFFER_SIZE (CONFIG_STM32_LTDC_FB_SIZE-STM32_LTDC_LAYER_META_SIZE)
|
|
#define STM32_LTDC_BUFFER_FREE (STM32_LTDC_BUFFER_SIZE-STM32_TOTAL_FBSIZE)
|
|
#define STM32_LTDC_BUFFER_START (STM32_LTDC_LAYER_META_END + STM32_LTDC_BUFFER_FREE/2)
|
|
|
|
#if STM32_LTDC_BUFFER_FREE < 0
|
|
# error "STM32_LTDC_BUFFER_SIZE not large enough for frame buffers"
|
|
#endif
|
|
|
|
/* Layer frame buffer */
|
|
|
|
#define STM32_LTDC_BUFFER_L1 STM32_LTDC_BUFFER_START
|
|
#define STM32_LTDC_ENDBUF_L1 (STM32_LTDC_BUFFER_L1 + STM32_L1_FBSIZE)
|
|
|
|
#ifdef CONFIG_STM32_LTDC_L2
|
|
# define STM32_LTDC_BUFFER_L2 STM32_LTDC_ENDBUF_L1
|
|
# define STM32_LTDC_ENDBUF_L2 (STM32_LTDC_BUFFER_L2 + STM32_L2_FBSIZE)
|
|
#else
|
|
# define STM32_LTDC_ENDBUF_L2 STM32_LTDC_ENDBUF_L1
|
|
#endif
|
|
|
|
/* Layer helpers */
|
|
|
|
#define LTDC_NLAYERS 2
|
|
|
|
#define LAYER(i) g_ltdc.layer[i]
|
|
#define LAYER_L1 g_ltdc.layer[LTDC_LAYER_L1]
|
|
#define LAYER_L2 g_ltdc.layer[LTDC_LAYER_L2]
|
|
|
|
/****************************************************************************
|
|
* Private Types
|
|
****************************************************************************/
|
|
/* This enumeration names each layer supported by the hardware */
|
|
|
|
enum stm32_layer_e
|
|
{
|
|
LTDC_LAYER_L1 = 0, /* LCD Layer 1*/
|
|
LTDC_LAYER_L2, /* LCD Layer 2 */
|
|
};
|
|
|
|
/* LTDC General Layer information */
|
|
|
|
struct stm32_layer_s
|
|
{
|
|
/* Descriptors and buffering */
|
|
|
|
uint8_t *framebuffer; /* DMA framebuffer memory */
|
|
uint8_t lid; /* Layer ID (see enum stm32_layer_e) */
|
|
|
|
/* Window position information */
|
|
|
|
uint16_t xpos; /* Window x position */
|
|
uint16_t width; /* Window width */
|
|
uint16_t ypos; /* Window y position */
|
|
uint16_t height; /* Window width */
|
|
|
|
/* Color information */
|
|
|
|
uint8_t bpp; /* Bits per pixel */
|
|
};
|
|
|
|
/* This structure provides the overall state of the LTDC */
|
|
|
|
struct stm32_ltdc_s
|
|
{
|
|
/* Layer information */
|
|
|
|
struct stm32_layer_s layer[LTDC_NLAYERS];
|
|
|
|
/* Debug stuff */
|
|
|
|
#ifdef CONFIG_STM32_LtDC_REGDEBUG
|
|
bool wrlast; /* True: Last access was a write */
|
|
uintptr_t addrlast; /* Last address accessed */
|
|
uint32_t vallast; /* Last value read or written */
|
|
int ntimes; /* Number of consecutive accesses */
|
|
#endif
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Private Function Prototypes
|
|
****************************************************************************/
|
|
/* Register operations ******************************************************/
|
|
|
|
#if defined(CONFIG_STM32_LTDC_REGDEBUG) && defined(CONFIG_DEBUG)
|
|
static bool stm32_checkreg(bool wr, uint32_t regval, uintptr_t address);
|
|
static uint32_t stm32_getreg(uintptr_t addr);
|
|
static void stm32_putreg(uintptr_t addr, uint32_t val);
|
|
#else
|
|
# define stm32_getreg(addr) getreg32(addr)
|
|
# define stm32_putreg(addr,val) putreg32(val,addr)
|
|
#endif
|
|
static void stm32_wait_lcdstatus(uint32_t mask, uint32_t value);
|
|
|
|
/* Frame buffer interface ***************************************************/
|
|
/* Get information about the video controller configuration and the
|
|
* configuration of each color plane.
|
|
*/
|
|
|
|
static int stm32_getvideoinfo(struct fb_vtable_s *vtable,
|
|
struct fb_videoinfo_s *vinfo);
|
|
static int stm32_getplaneinfo(struct fb_vtable_s *vtable,
|
|
int planeno, struct fb_planeinfo_s *pinfo);
|
|
|
|
/* The following is provided only if the video hardware supports RGB color
|
|
* mapping
|
|
*/
|
|
|
|
#ifdef CONFIG_FB_CMAP
|
|
static int stm32_getcmap(struct fb_vtable_s *vtable,
|
|
struct fb_cmap_s *cmap);
|
|
static int stm32_putcmap(struct fb_vtable_s *vtable,
|
|
const struct fb_cmap_s *cmap);
|
|
#endif
|
|
|
|
/* Initialization ***********************************************************/
|
|
|
|
#ifdef CONFIG_FB_CMAP
|
|
static int stm32_setclut(struct stm32_layer_s *layer,
|
|
const struct fb_cmap_s *cmap);
|
|
static int stm32_getclut(struct stm32_layer_s *layer,
|
|
struct fb_cmap_s *cmap);
|
|
#endif
|
|
|
|
static void stm32_backlight(uint32_t level);
|
|
static void stm32_l1_disable(void);
|
|
static void stm32_l2_disable(void);
|
|
static void stm32_lcd_disable(void);
|
|
static void stm32_layer_color(void);
|
|
static void stm32_lcd_enable(void);
|
|
static void stm32_layer_configure(void);
|
|
static void stm32_show_layer(struct stm32_layer_s *layer,
|
|
uint32_t dispx, uint32_t dispy, uint32_t dispw, uint32_t disph);
|
|
|
|
/****************************************************************************
|
|
* Private Data
|
|
****************************************************************************/
|
|
|
|
/* This structure describes the video controller */
|
|
|
|
static const struct fb_videoinfo_s g_videoinfo =
|
|
{
|
|
.fmt = STM32_LTDC_L1_COLOR_FMT,
|
|
.xres = BOARD_LTDC_WIDTH,
|
|
.yres = BOARD_LTDC_HEIGHT,
|
|
.nplanes = 1,
|
|
};
|
|
|
|
/* This structure provides the overall state of the LTDC */
|
|
|
|
static struct stm32_ltdc_s g_ltdc;
|
|
|
|
/* This structure provides the base layer interface */
|
|
|
|
static const struct fb_vtable_s g_vtable =
|
|
{
|
|
.getvideoinfo = stm32_getvideoinfo,
|
|
.getplaneinfo = stm32_getplaneinfo,
|
|
#ifdef CONFIG_FB_CMAP
|
|
.getcmap = stm32_getcmap,
|
|
.putcmap = stm32_putcmap,
|
|
#endif
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Public Data
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Private Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_checkreg
|
|
*
|
|
* Description:
|
|
* Check if the current register access is a duplicate of the preceding.
|
|
*
|
|
* Input Parameters:
|
|
* regval - The value to be written
|
|
* address - The address of the register to write to
|
|
*
|
|
* Returned Value:
|
|
* true: This is the first register access of this type.
|
|
* flase: This is the same as the preceding register access.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_STM32_LTDC_REGDEBUG
|
|
static bool stm32_checkreg(bool wr, uint32_t regval, uintptr_t address)
|
|
{
|
|
if (wr == g_lcdc.wrlast && /* Same kind of access? */
|
|
regval == g_lcdc.vallast && /* Same value? */
|
|
address == g_lcdc.addrlast) /* Same address? */
|
|
{
|
|
/* Yes, then just keep a count of the number of times we did this. */
|
|
|
|
g_lcdc.ntimes++;
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
/* Did we do the previous operation more than once? */
|
|
|
|
if (g_lcdc.ntimes > 0)
|
|
{
|
|
/* Yes... show how many times we did it */
|
|
|
|
lldbg("...[Repeats %d times]...\n", g_lcdc.ntimes);
|
|
}
|
|
|
|
/* Save information about the new access */
|
|
|
|
g_lcdc.wrlast = wr;
|
|
g_lcdc.vallast = regval;
|
|
g_lcdc.addrlast = address;
|
|
g_lcdc.ntimes = 0;
|
|
}
|
|
|
|
/* Return true if this is the first time that we have done this operation */
|
|
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_getreg
|
|
*
|
|
* Description:
|
|
* Read any 32-bit register using an absolute
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_STM32_LTDC_REGDEBUG
|
|
static uint32_t stm32_getreg(uintptr_t address)
|
|
{
|
|
uint32_t regval = getreg32(address);
|
|
|
|
if (stm_checkreg(false, regval, address))
|
|
{
|
|
lldbg("%08x->%08x\n", address, regval);
|
|
}
|
|
|
|
return regval;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_putreg
|
|
*
|
|
* Description:
|
|
* Write to any 32-bit register using an absolute address
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_STM32_LTDC_REGDEBUG
|
|
static void stm32_putreg(uintptr_t address, uint32_t regval)
|
|
{
|
|
if (stm_checkreg(true, regval, address))
|
|
{
|
|
lldbg("%08x<-%08x\n", address, regval);
|
|
}
|
|
|
|
putreg32(regval, address);
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_wait_lcdstatus
|
|
*
|
|
* Description:
|
|
* Wait for the masked set of bits in the LTDC status register to take a
|
|
* specific value.
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_wait_lcdstatus(uint32_t mask, uint32_t value)
|
|
{
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_getvideoinfo
|
|
****************************************************************************/
|
|
|
|
static int stm32_getvideoinfo(struct fb_vtable_s *vtable,
|
|
struct fb_videoinfo_s *vinfo)
|
|
{
|
|
gvdbg("vtable=%p vinfo=%p\n", vtable, vinfo);
|
|
if (vtable && vinfo)
|
|
{
|
|
memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s));
|
|
return OK;
|
|
}
|
|
|
|
gdbg("ERROR: Returning EINVAL\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_getplaneinfo
|
|
****************************************************************************/
|
|
|
|
static int stm32_getplaneinfo(struct fb_vtable_s *vtable, int planeno,
|
|
struct fb_planeinfo_s *pinfo)
|
|
{
|
|
gvdbg("vtable=%p planeno=%d pinfo=%p\n", vtable, planeno, pinfo);
|
|
if (vtable && planeno == 0 && pinfo)
|
|
{
|
|
pinfo->fbmem = (void *)LAYER_L1.framebuffer;
|
|
pinfo->fblen = STM32_L1_FBSIZE;
|
|
pinfo->stride = STM32_L1_STRIDE,
|
|
pinfo->bpp = LAYER_L1.bpp;
|
|
return OK;
|
|
}
|
|
|
|
gdbg("Returning EINVAL\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_base_getcmap
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_FB_CMAP
|
|
static int stm32_getcmap(struct fb_vtable_s *vtable,
|
|
struct fb_cmap_s *cmap)
|
|
{
|
|
return stm_getclut(&LAYER_L1, cmap);
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: stm_base_putcmap
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_FB_CMAP
|
|
static int stm32_putcmap(struct fb_vtable_s *vtable,
|
|
const struct fb_cmap_s *cmap)
|
|
{
|
|
return stm32_setclut(&LAYER_L1, cmap);
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_setposition
|
|
*
|
|
* Description:
|
|
* Set the new position of a move-able layer (any layer except the base
|
|
* layer).
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_setposition(int lid, uint32_t x, uint32_t y)
|
|
{
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_setclut
|
|
*
|
|
* Description:
|
|
* Set a range of CLUT values for any layer
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_FB_CMAP
|
|
static int stm32_setclut(struct stm32_layer_s *layer,
|
|
const struct fb_cmap_s *cmap)
|
|
{
|
|
|
|
return OK;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_getclut
|
|
*
|
|
* Description:
|
|
* Get a range of CLUT values for any layer
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_FB_CMAP
|
|
static int stm32_getclut(struct stm_layer_s *layer,
|
|
struct fb_cmap_s *cmap)
|
|
{
|
|
|
|
return OK;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_backlight
|
|
*
|
|
* Description:
|
|
* Set the backlight level
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_backlight(uint32_t level)
|
|
{
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_l1_disable
|
|
*
|
|
* Description:
|
|
* Disable Layer 1
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_l1_disable(void)
|
|
{
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_l2_disable
|
|
*
|
|
* Description:
|
|
* Disable Layer 2
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_l2_disable(void)
|
|
{
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_lcd_disable
|
|
*
|
|
* Description:
|
|
* Disable the LCD peripheral
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_lcd_disable(void)
|
|
{
|
|
/* Disable layers */
|
|
|
|
stm32_l1_disable();
|
|
stm32_l2_disable();
|
|
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_layer_position
|
|
*
|
|
* Description:
|
|
* Configure LTDC layer position
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_layer_position(void)
|
|
{
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_layer_color
|
|
*
|
|
* Description:
|
|
* Configure LTDC layer color mode
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_layer_color(void)
|
|
{
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_lcd_enable
|
|
*
|
|
* Description:
|
|
* Enable the LCD for normal use
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_lcd_enable(void)
|
|
{
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_layer_configure
|
|
*
|
|
* Description:
|
|
* Configure layer layer structures and framebuffers
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_layer_configure(void)
|
|
{
|
|
/* Common layer initialization */
|
|
|
|
memset(&LAYER_L1, 0, sizeof(struct stm32_layer_s));
|
|
LAYER_L1.lid = LTDC_LAYER_L1;
|
|
LAYER_L1.framebuffer = (uint8_t *)STM32_LTDC_BUFFER_L1;
|
|
|
|
memset(&LAYER_L2, 0, sizeof(struct stm32_layer_s));
|
|
LAYER_L2.lid = LTDC_LAYER_L2;
|
|
#ifdef CONFIG_STM32_LTDC_L2
|
|
LAYER_L2.framebuffer = (uint8_t *)STM32_LTDC_BUFFER_L2;
|
|
#endif
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_ltdc_periphconfig
|
|
*
|
|
* Description:
|
|
* Configures the LTDC peripheral clock and SAI PLL clocks to drive the
|
|
* LCD.
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_config_lcd_clock(void)
|
|
{
|
|
uint32_t regval;
|
|
|
|
/* Configure the SAI PLL to provide the LCD_CLK */
|
|
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_show_layer
|
|
*
|
|
* Description:
|
|
* Show the given layer with the specified window
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_show_layer(struct stm32_layer_s *layer,
|
|
uint32_t dispx, uint32_t dispy,
|
|
uint32_t dispw, uint32_t disph)
|
|
{
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_show_l1
|
|
*
|
|
* Description:
|
|
* Show Layer 1 (the "base" layer)
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void stm32_show_l1(void)
|
|
{
|
|
stm32_show_layer(&LAYER_L1, 0, 0, BOARD_LTDC_WIDTH, BOARD_LTDC_HEIGHT);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: up_fbinitialize
|
|
*
|
|
* Description:
|
|
* Initialize the framebuffer video hardware
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_fbinitialize(void)
|
|
{
|
|
gvdbg("Entry\n");
|
|
|
|
/* Configure layer layer structures, DMA descriptor memory, and
|
|
* framebuffers
|
|
*/
|
|
|
|
stm32_layer_configure();
|
|
|
|
/* Disable the LCD */
|
|
|
|
stm32_lcd_disable();
|
|
|
|
gvdbg("Configuring the LCD controller\n");
|
|
|
|
/* Configure and Enable the LCD clock */
|
|
|
|
/* Disable LCD interrupts */
|
|
|
|
/* Configure layer positions */
|
|
|
|
stm32_layer_position();
|
|
|
|
/* Configure layer colors */
|
|
|
|
stm32_layer_color();
|
|
|
|
/* Clear the display memory */
|
|
|
|
stm32_lcdclear(CONFIG_STM32_LTDC_BACKCOLOR);
|
|
|
|
/* And turn the LCD on */
|
|
|
|
gvdbg("Enabling the display\n");
|
|
stm32_lcd_enable();
|
|
|
|
/* Display layer 1 */
|
|
|
|
stm32_show_l1();
|
|
|
|
/* Enable the backlight.
|
|
*
|
|
* REVISIT: Backlight level could be dynamically adjustable
|
|
*/
|
|
|
|
stm32_backlight(CONFIG_STM32_LTDC_DEFBACKLIGHT);
|
|
|
|
return OK;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: stm32_fbgetvplane
|
|
*
|
|
* Description:
|
|
* Return a a reference to the framebuffer object for the specified video
|
|
* plane.
|
|
*
|
|
* Input parameters:
|
|
* None
|
|
*
|
|
* Returned value:
|
|
* Reference to the framebuffer object (NULL on failure)
|
|
*
|
|
***************************************************************************/
|
|
|
|
struct fb_vtable_s *up_fbgetvplane(int vplane)
|
|
{
|
|
gvdbg("vplane: %d\n", vplane);
|
|
if (vplane == 0)
|
|
{
|
|
return (struct fb_vtable_s *)&g_vtable;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: fb_uninitialize
|
|
*
|
|
* Description:
|
|
* Uninitialize the framebuffer driver. Bad things will happen if you
|
|
* call this without first calling fb_initialize()!
|
|
*
|
|
****************************************************************************/
|
|
|
|
void fb_uninitialize(void)
|
|
{
|
|
/* Disable the LCD controller */
|
|
|
|
stm32_lcd_disable();
|
|
}
|
|
|
|
/************************************************************************************
|
|
* Name: stm32_lcdclear
|
|
*
|
|
* Description:
|
|
* This is a non-standard LCD interface just for the STM32. Clearing the display
|
|
* in the normal way by writing a sequences of runs that covers the entire display
|
|
* can be slow. Here the display is cleared by simply setting all video memory to
|
|
* the specified color.
|
|
*
|
|
************************************************************************************/
|
|
|
|
void stm32_lcdclear(nxgl_mxpixel_t color)
|
|
{
|
|
}
|