123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959 |
- /**************************************************************************//**
- * @file lcd.c
- * @brief N9H30 LCD driver source file
- *
- * @note
- * SPDX-License-Identifier: Apache-2.0
- * Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
- *****************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include "N9H30.h"
- #include "nu_sys.h"
- #include "nu_lcd.h"
- /** @addtogroup N9H30_Device_Driver N9H30 Device Driver
- @{
- */
- /** @addtogroup N9H30_LCD_Driver LCD Driver
- @{
- */
- /** @addtogroup N9H30_LCD_EXPORTED_CONSTANTS LCD Exported Constants
- @{
- */
- /// @cond HIDDEN_SYMBOLS
- /* LCD attributes */
- static VPOST_T DEF_E50A2V1 =
- {
- 800, /*!< Panel width */
- 480, /*!< Panel height */
- 0, /*!< MPU command line low indicator */
- 0, /*!< MPU command width */
- 0, /*!< MPU bus width */
- VPOSTB_DATA16or18, /*!< Display bus width */
- 0, /*!< MPU mode */
- VPOSTB_COLORTYPE_64K, /*!< Display colors */
- VPOSTB_DEVICE_SYNC_HIGHCOLOR, /*!< Type of display panel */
- 0x020d03a0, /*!< CRTCSIZE register value */
- 0x01e00320, /*!< CRTCDEND register value */
- 0x03250321, /*!< CRTCHR register value */
- 0x03780348, /*!< CRTCHSYNC register value */
- 0x01f001ed /*!< CRTCVR register value */
- };
- static VPOST_T DEF_ILI9341_MPU80 =
- {
- 240, /*!< Panel width */
- 320, /*!< Panel height */
- VPOSTB_CMDLOW, /*!< MPU command line low indicator */
- VPOSTB_CM16t18HIGH, /*!< MPU command width */
- VPOSTB_CMD8, /*!< MPU bus width */
- VPOSTB_DATA16or18, /*!< Display bus width */
- VPOSTB_MPU80, /*!< MPU mode */
- VPOSTB_COLORTYPE_64K, /*!< Display colors */
- VPOSTB_DEVICE_MPU, /*!< Type of display panel */
- 0x01600100, /*!< CRTCSIZE register value */
- 0x014000F0, /*!< CRTCDEND register value */
- 0x00FA00F5, /*!< CRTCHR register value */
- 0x00FC00FA, /*!< CRTCHSYNC register value */
- 0x01500145 /*!< CRTCVR register value */
- };
- static VPOST_T DEF_LSA40AT9001 =
- {
- 800, /*!< Panel width */
- 600, /*!< Panel height */
- 0, /*!< MPU command line low indicator */
- 0, /*!< MPU command width */
- 0, /*!< MPU bus width */
- VPOSTB_DATA16or18, /*!< Display bus width */
- 0, /*!< MPU mode */
- VPOSTB_COLORTYPE_64K, /*!< Display colors */
- VPOSTB_DEVICE_SYNC_HIGHCOLOR, /*!< Type of display panel */
- 0x02800425, /*!< CRTCSIZE register value */
- 0x02580320, /*!< CRTCDEND register value */
- 0x032F032A, /*!< CRTCHR register value */
- 0x0334032A, /*!< CRTCHSYNC register value */
- 0x026C0262 /*!< CRTCVR register value */
- };
- static VPOST_T DEF_FW070TFT =
- {
- 800, /*!< Panel width */
- 480, /*!< Panel height */
- 0, /*!< MPU command line low indicator */
- 0, /*!< MPU command width */
- 0, /*!< MPU bus width */
- VPOSTB_DATA16or18, /*!< Display bus width */
- 0, /*!< MPU mode */
- VPOSTB_COLORTYPE_16M, /*!< Display colors */
- VPOSTB_DEVICE_SYNC_HIGHCOLOR, /*!< Type of display panel */
- 0x020d0420, /*!< CRTCSIZE register value */
- 0x01e00320, /*!< CRTCDEND register value */
- 0x033e0339, /*!< CRTCHR register value */
- 0x040c03f8, /*!< CRTCHSYNC register value */
- 0x020001f6 /*!< CRTCVR register value */
- };
- #define FW043TFT_WIDTH 480 /*!< XRES */
- #define FW043TFT_HEIGHT 272 /*!< YRES */
- #define FW043TFT_MARGIN_LEFT 30 /*!< HBP (Horizontal Back Porch) */
- #define FW043TFT_MARGIN_RIGHT 5 /*!< HFP (Horizontal Front Porch) */
- #define FW043TFT_MARGIN_UPPER 2 /*!< VBP (Vertical Back Porch) */
- #define FW043TFT_MARGIN_LOWER 27 /*!< VFP (Vertical Front Porch) */
- #define FW043TFT_HSYNC_LEN 41 /*!< HPW (HSYNC plus width) */
- #define FW043TFT_VSYNC_LEN 10 /*!< VPW (VSYNC width) */
- static VPOST_T DEF_FW043TFT =
- {
- FW043TFT_WIDTH, /*!< Panel width */
- FW043TFT_HEIGHT, /*!< Panel height */
- 0, /*!< MPU command line low indicator */
- 0, /*!< MPU command width */
- 0, /*!< MPU bus width */
- VPOSTB_DATA16or18, /*!< Display bus width */
- 0, /*!< MPU mode */
- VPOSTB_COLORTYPE_16M, /*!< Display colors */
- VPOSTB_DEVICE_SYNC_HIGHCOLOR, /*!< Type of display panel */
- .sCRTCSIZE =
- {
- /*!< Horizontal Total */
- .HTT = FW043TFT_MARGIN_LEFT + FW043TFT_WIDTH + FW043TFT_MARGIN_RIGHT,
- /*!< Vertical Total */
- .VTT = FW043TFT_MARGIN_UPPER + FW043TFT_HEIGHT + FW043TFT_MARGIN_LOWER,
- },
- .sCRTCDEND =
- {
- /*!< Horizontal Display Enable End */
- .HDEND = FW043TFT_WIDTH,
- /*!< Vertical Display Enable End */
- .VDEND = FW043TFT_HEIGHT,
- },
- .sCRTCHR =
- {
- /*!< Internal Horizontal Retrace Start Timing */
- .HRS = FW043TFT_WIDTH + 1,
- /*!< Internal Horizontal Retrace End Low */
- .HRE = FW043TFT_WIDTH + 5,
- },
- .sCRTCHSYNC =
- {
- /*!< Horizontal Sync Start Timing */
- .HSYNC_S = FW043TFT_WIDTH + FW043TFT_MARGIN_LEFT,
- /*!< Horizontal Sync End Timing */
- .HSYNC_E = FW043TFT_WIDTH + FW043TFT_MARGIN_LEFT + FW043TFT_HSYNC_LEN,
- /*!< Hsync Signal Adjustment For Multi-Cycles Per Pixel Mode Of Sync-Based Unipac-LCD */
- .HSYNC_SHIFT = 0,
- },
- .sCRTCVR =
- {
- /*!< Vertical Internal Retrace Start Timing */
- .VRS = FW043TFT_HEIGHT + FW043TFT_MARGIN_UPPER,
- /*!< Vertical Internal Retrace End Low */
- .VRE = FW043TFT_HEIGHT + FW043TFT_MARGIN_UPPER + FW043TFT_VSYNC_LEN,
- }
- };
- #define FW070TFT_WSVGA_WIDTH 1024 /*!< XRES */
- #define FW070TFT_WSVGA_HEIGHT 600 /*!< YRES */
- #define FW070TFT_WSVGA_MARGIN_LEFT 160 /*!< HBP (Horizontal Back Porch) */
- #define FW070TFT_WSVGA_MARGIN_RIGHT 160 /*!< HFP (Horizontal Front Porch) */
- #define FW070TFT_WSVGA_MARGIN_UPPER 12 /*!< VBP (Vertical Back Porch) */
- #define FW070TFT_WSVGA_MARGIN_LOWER 23 /*!< VFP (Vertical Front Porch) */
- #define FW070TFT_WSVGA_HSYNC_LEN 1 /*!< HPW (HSYNC plus width) */
- #define FW070TFT_WSVGA_VSYNC_LEN 1 /*!< VPW (VSYNC width) */
- static VPOST_T DEF_FW070TFT_WSVGA =
- {
- FW070TFT_WSVGA_WIDTH, /*!< Panel width */
- FW070TFT_WSVGA_HEIGHT, /*!< Panel height */
- 0, /*!< MPU command line low indicator */
- 0, /*!< MPU command width */
- 0, /*!< MPU bus width */
- VPOSTB_DATA16or18, /*!< Display bus width */
- 0, /*!< MPU mode */
- VPOSTB_COLORTYPE_16M, /*!< Display colors */
- VPOSTB_DEVICE_SYNC_HIGHCOLOR, /*!< Type of display panel */
- .sCRTCSIZE =
- {
- /*!< Horizontal Total */
- .HTT = FW070TFT_WSVGA_MARGIN_LEFT + FW070TFT_WSVGA_WIDTH + FW070TFT_WSVGA_MARGIN_RIGHT,
- /*!< Vertical Total */
- .VTT = FW070TFT_WSVGA_MARGIN_UPPER + FW070TFT_WSVGA_HEIGHT + FW070TFT_WSVGA_MARGIN_LOWER,
- },
- .sCRTCDEND =
- {
- /*!< Horizontal Display Enable End */
- .HDEND = FW070TFT_WSVGA_WIDTH,
- /*!< Vertical Display Enable End */
- .VDEND = FW070TFT_WSVGA_HEIGHT,
- },
- .sCRTCHR =
- {
- /*!< Internal Horizontal Retrace Start Timing */
- .HRS = FW070TFT_WSVGA_WIDTH + 1,
- /*!< Internal Horizontal Retrace End Low */
- .HRE = FW070TFT_WSVGA_WIDTH + 5,
- },
- .sCRTCHSYNC =
- {
- /*!< Horizontal Sync Start Timing */
- .HSYNC_S = FW070TFT_WSVGA_WIDTH + FW070TFT_WSVGA_MARGIN_LEFT,
- /*!< Horizontal Sync End Timing */
- .HSYNC_E = FW070TFT_WSVGA_WIDTH + FW070TFT_WSVGA_MARGIN_LEFT + FW070TFT_WSVGA_HSYNC_LEN,
- /*!< Hsync Signal Adjustment For Multi-Cycles Per Pixel Mode Of Sync-Based Unipac-LCD */
- .HSYNC_SHIFT = 0,
- },
- .sCRTCVR =
- {
- /*!< Vertical Internal Retrace Start Timing */
- .VRS = FW070TFT_WSVGA_HEIGHT + FW070TFT_WSVGA_MARGIN_UPPER,
- /*!< Vertical Internal Retrace End Low */
- .VRE = FW070TFT_WSVGA_HEIGHT + FW070TFT_WSVGA_MARGIN_UPPER + FW070TFT_WSVGA_VSYNC_LEN,
- }
- };
- /* LCD build-in support list */
- static VPOST_T *DisplayDevList[DIS_PANEL_CNT] =
- {
- &DEF_E50A2V1,
- &DEF_ILI9341_MPU80,
- &DEF_LSA40AT9001,
- &DEF_FW070TFT,
- &DEF_FW043TFT,
- &DEF_FW070TFT_WSVGA
- };
- static VPOST_T curDisplayDev;
- static OSDFORMATEX curOSDDev = {0};
- static LCDFORMATEX curVADev = {0};
- /// @endcond /* HIDDEN_SYMBOLS */
- /*@}*/ /* end of group N9H30_I2C_EXPORTED_CONSTANTS */
- /** @addtogroup N9H30_LCD_EXPORTED_FUNCTIONS LCD Exported Functions
- @{
- */
- /// @cond HIDDEN_SYMBOLS
- /* For align 32 */
- static uint32_t shift_pointer(uint32_t ptr, uint32_t align)
- {
- uint32_t alignedPTR;
- uint32_t remain;
- //printf("pointer position is %x\n",ptr);
- if ((ptr % align) != 0)
- {
- remain = ptr % align;
- alignedPTR = ptr + (align - remain);
- return alignedPTR;
- }
- return ptr;
- }
- /// @endcond /* HIDDEN_SYMBOLS */
- /**
- * @brief Configure attributes of LCD panel,install interrupt handler and enable LCD engine clock
- * @param[in] u32DisplayPanelID is panel id to configure.
- * @return none
- */
- void vpostLCMInit(uint32_t u32DisplayPanelID)
- {
- // enable lcd engine clock
- outpw(REG_CLK_HCLKEN, inpw(REG_CLK_HCLKEN) | (1 << 25));
- memset((void *)&curDisplayDev, 0, sizeof(curDisplayDev));
- memcpy((void *)&curDisplayDev, DisplayDevList[u32DisplayPanelID], sizeof(curDisplayDev));
- outpw(REG_LCM_DEV_CTRL, curDisplayDev.u32CmdLow
- | curDisplayDev.u32Cmd16t18
- | curDisplayDev.u32CmdBusWidth
- | curDisplayDev.u32DataBusWidth
- | curDisplayDev.u32MPU_Mode
- | curDisplayDev.u32DisplayColors
- | curDisplayDev.u32DevType);
- outpw(REG_LCM_CRTC_SIZE, curDisplayDev.u32Reg_CRTCSIZE);
- outpw(REG_LCM_CRTC_DEND, curDisplayDev.u32Reg_CRTCDEND);
- outpw(REG_LCM_CRTC_HR, curDisplayDev.u32Reg_CRTCHR);
- outpw(REG_LCM_CRTC_HSYNC, curDisplayDev.u32Reg_CRTCHSYNC);
- outpw(REG_LCM_CRTC_VR, curDisplayDev.u32Reg_CRTCVR);
- }
- /**
- * @brief Query LCM capacity and configuration by ID
- * @param[in] u32DisplayPanelID is panel id to configure.
- * @return LCM instance
- */
- VPOST_T *vpostLCMGetInstance(uint32_t u32DisplayPanelID)
- {
- if (u32DisplayPanelID > (sizeof(DisplayDevList) / sizeof(VPOST_T *)))
- return NULL;
- return DisplayDevList[u32DisplayPanelID];
- }
- /**
- * @brief Disable LCD engine
- * @param none
- * @return none
- */
- void vpostLCMDeinit(void)
- {
- // disable lcd engine clock
- outpw(REG_CLK_HCLKEN, inpw(REG_CLK_HCLKEN) & ~(1 << 25));
- //sysDisableInterrupt(LCD_IRQn);
- }
- /**
- * @brief Get the pointer of frame buffer
- * @param none
- * @return pointer of frame buffer
- * @retval NULL fail.
- * @note before calling this function, display width, height and source format must be set first.
- */
- uint8_t *vpostGetFrameBuffer(void)
- {
- uint8_t *u8BufPtr;
- uint8_t u32BytePerPixel;
- if ((curDisplayDev.u32DevWidth == 0) || (curDisplayDev.u32DevHeight == 0))
- return NULL;
- switch (curVADev.ucVASrcFormat)
- {
- case VA_SRC_YUV422:
- case VA_SRC_YCBCR422:
- case VA_SRC_RGB565:
- u32BytePerPixel = 2;
- break;
- case VA_SRC_RGB666:
- case VA_SRC_RGB888:
- u32BytePerPixel = 4;
- break;
- default:
- u32BytePerPixel = 2;
- }
- u8BufPtr = (uint8_t *)malloc((curDisplayDev.u32DevWidth * curDisplayDev.u32DevHeight * u32BytePerPixel) + 32);
- if (u8BufPtr == NULL)
- return NULL;
- u8BufPtr = (uint8_t *)shift_pointer((uint32_t)u8BufPtr, 32);
- outpw(REG_LCM_VA_BADDR0, (uint32_t)((uint32_t)u8BufPtr | 0x80000000));
- outpw(REG_LCM_VA_FBCTRL, inpw(REG_LCM_VA_FBCTRL) & ~(1 << 30) & ~VPOSTB_DB_EN);
- return (uint8_t *)((uint32_t)u8BufPtr | 0x80000000);
- }
- void vpostSetFrameBuffer(uint8_t *pu8BufPtr)
- {
- outpw(REG_LCM_VA_BADDR0, (uint32_t)((uint32_t)pu8BufPtr | 0x80000000));
- outpw(REG_LCM_VA_FBCTRL, inpw(REG_LCM_VA_FBCTRL) & ~(1 << 30) & ~VPOSTB_DB_EN);
- }
- /**
- * @brief Get the pointer of frame buffer
- * @param[in] u32Cnt is the frame buffer count to allocate. Min value is 1.
- * @return pointer of frame buffer
- * @retval NULL fail.
- * @note before calling this function, display width, height and source format must be set first.
- */
- uint8_t *vpostGetMultiFrameBuffer(uint32_t u32Cnt)
- {
- uint8_t *u8BufPtr;
- uint8_t u32BytePerPixel;
- if ((curDisplayDev.u32DevWidth == 0) || (curDisplayDev.u32DevHeight == 0) || (u32Cnt == 0))
- return NULL;
- switch (curVADev.ucVASrcFormat)
- {
- case VA_SRC_YUV422:
- case VA_SRC_YCBCR422:
- case VA_SRC_RGB565:
- u32BytePerPixel = 2;
- break;
- case VA_SRC_RGB666:
- case VA_SRC_RGB888:
- u32BytePerPixel = 4;
- break;
- default:
- u32BytePerPixel = 2;
- }
- u8BufPtr = (uint8_t *)malloc((curDisplayDev.u32DevWidth * curDisplayDev.u32DevHeight * u32BytePerPixel) * u32Cnt + 32);
- if (u8BufPtr == NULL)
- return NULL;
- u8BufPtr = (uint8_t *)shift_pointer((uint32_t)u8BufPtr, 32);
- outpw(REG_LCM_VA_BADDR0, (uint32_t)((uint32_t)u8BufPtr | 0x80000000));
- outpw(REG_LCM_VA_FBCTRL, inpw(REG_LCM_VA_FBCTRL) & ~(1 << 30) & ~VPOSTB_DB_EN);
- return (uint8_t *)((uint32_t)u8BufPtr | 0x80000000);
- }
- /**
- * @brief Set active display window
- * @param[in] u16StartY is y start position
- * @param[in] u16EndY is y end position
- * @param[in] u8BGColorR is background R color
- * @param[in] u8BGColorG is background G color
- * @param[in] u8BGColorB is background B color
- * @return none
- */
- void vpostSetActiveWindow(uint16_t u16StartY, uint16_t u16EndY, uint8_t u8BGColorR, uint8_t u8BGColorG, uint8_t u8BGColorB)
- {
- outpw(REG_LCM_VA_WIN, (u16StartY << 16) | u16EndY);
- outpw(REG_LCM_VA_STUFF, (u8BGColorR << 16) | (u8BGColorG << 8) | u8BGColorB);
- }
- /**
- * @brief Configure LCD display mode
- * @param[in] u8DisplayMode is display mode, value could be
- * - \ref VPOST_DISPLAY_SINGLE
- * - \ref VPOST_DISPLAY_CONTINUOUS
- * @return none
- */
- void vpostSetDisplayMode(uint8_t u8DisplayMode)
- {
- if (u8DisplayMode == 0)
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) & ~(1 << 7)); //clear setting
- else
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) | (u8DisplayMode) << 7);
- }
- /**
- * @brief Configure display attributes of video interface,
- * @param[in] u32VASrcType is display type, value could be
- * - \ref VA_SRC_YUV422
- * - \ref VA_SRC_YCBCR422
- * - \ref VA_SRC_RGB888
- * - \ref VA_SRC_RGB666
- * - \ref VA_SRC_RGB565
- * - \ref VA_SRC_RGB444_LOW
- * - \ref VA_SRC_RGB444_HIGH
- * @return none
- */
- void vpostSetVASrc(uint32_t u32VASrcType)
- {
- uint32_t u32BytePerPixel, VA_FF, VA_Sride;
- curVADev.ucVASrcFormat = u32VASrcType;
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) & ~(7 << 8));
- if (u32VASrcType != 0)
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) | u32VASrcType);
- else
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) & ~(7 << 8));
- if ((u32VASrcType == VA_SRC_RGB888) || (u32VASrcType == VA_SRC_RGB666))
- outpw(REG_LCM_VA_FBCTRL, inpw(REG_LCM_VA_FBCTRL) & ~0x7ff07ff | (curDisplayDev.u32DevWidth << 16) | curDisplayDev.u32DevWidth);
- else
- outpw(REG_LCM_VA_FBCTRL, inpw(REG_LCM_VA_FBCTRL) & ~0x7ff07ff | ((curDisplayDev.u32DevWidth / 2) << 16) | (curDisplayDev.u32DevWidth / 2));
- switch (u32VASrcType)
- {
- case VA_SRC_YUV422:
- case VA_SRC_YCBCR422:
- case VA_SRC_RGB565:
- u32BytePerPixel = 2;
- break;
- case VA_SRC_RGB666:
- case VA_SRC_RGB888:
- u32BytePerPixel = 4;
- break;
- default:
- u32BytePerPixel = 2;
- }
- /* set video stream frame buffer control */
- VA_FF = curDisplayDev.u32DevWidth * u32BytePerPixel / 4;
- VA_Sride = curDisplayDev.u32DevWidth * u32BytePerPixel / 4;
- outpw(REG_LCM_VA_FBCTRL, inpw(REG_LCM_VA_FBCTRL) & ~0x7ff07ff | (VA_FF << 16) | VA_Sride);
- }
- /**
- * @brief Start to display
- * @param none
- * @return none
- */
- void vpostVAStartTrigger(void)
- {
- if ((inpw(REG_LCM_DCCS) & VPOSTB_SINGLE) == VPOSTB_SINGLE)
- while ((inpw(REG_LCM_DCCS) & VPOSTB_VA_EN) == VPOSTB_VA_EN); //wait VA_EN low
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) | VPOSTB_DISP_OUT_EN); //display_out-enable
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) | VPOSTB_VA_EN); //va-enable
- }
- /**
- * @brief Stop to display
- * @param none
- * @return none
- */
- void vpostVAStopTrigger(void)
- {
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) & ~(VPOSTB_DISP_OUT_EN | VPOSTB_VA_EN)); //OSD disable
- }
- /**
- * @brief Configure LCD scaling attribute
- * @param[in] u8HIntegral is horizontal integral
- * @param[in] u16HDecimal is horizontal decimal
- * @param[in] u8VIntegral is vertical integral
- * @param[in] u16VDecimal is vertical decimal
- * @param[in] u32Mode is scale mode, value could be
- * - \ref VA_SCALE_INTERPOLATION
- * - \ref VA_SCALE_DUPLICATION
- * @return none
- */
- void vpostVAScalingCtrl(uint8_t u8HIntegral, uint16_t u16HDecimal, uint8_t u8VIntegral, uint16_t u16VDecimal, uint32_t u32Mode)
- {
- outpw(REG_LCM_VA_SCALE, ((((uint32_t)u8VIntegral << 10) + ((uint32_t)ceil((double)1024 / 10)*u16VDecimal)) << 16)
- | (((uint32_t)u8HIntegral << 10) + ((uint32_t)ceil((double)1024 / 10)*u16HDecimal)) | u32Mode);
- }
- /**
- * @brief Set OSD color key
- * @param[in] u8CKeyColorR is color key R color
- * @param[in] u8CKeyColorG is color key G color
- * @param[in] u8CKeyColorB is color key B color
- * @return none
- */
- void vpostOSDSetColKey(uint8_t u8CKeyColorR, uint8_t u8CKeyColorG, uint8_t u8CKeyColorB)
- {
- outpw(REG_LCM_OSD_OVERLAY, inpw(REG_LCM_OSD_OVERLAY) & ~(VPOSTB_BLI_ON | VPOSTB_CKEY_ON)); //blinking disable, color-key disable
- outpw(REG_LCM_OSD_OVERLAY, inpw(REG_LCM_OSD_OVERLAY) | VPOSTB_CKEY_ON);//color-key enable
- outpw(REG_LCM_OSD_CKEY, ((uint32_t)(u8CKeyColorR << 16) | (uint32_t)(u8CKeyColorG << 8) | u8CKeyColorB));
- }
- /**
- * @brief Set OSD color mask, OSD data only will be displayed if the mask bit is set as 1.
- * @param[in] u8MaskColorR is color key R color
- * @param[in] u8MaskColorG is color key G color
- * @param[in] u8MaskColorB is color key B color
- * @return none
- */
- void vpostOSDSetColMask(uint8_t u8MaskColorR, uint8_t u8MaskColorG, uint8_t u8MaskColorB)
- {
- outpw(REG_LCM_OSD_CMASK, ((u8MaskColorR << 16) | (u8MaskColorG << 8) | u8MaskColorB));
- }
- /**
- * @brief Set OSD blinking function
- * @param[in] u8OSDBlinkVcnt is blinking cycle time, unit is VSync
- * @return none
- */
- void vpostOSDSetBlinking(uint8_t u8OSDBlinkVcnt)
- {
- outpw(REG_LCM_OSD_OVERLAY, inpw(REG_LCM_OSD_OVERLAY) & ~(VPOSTB_BLI_ON | VPOSTB_CKEY_ON)); //blinking disable, color-key disable
- outpw(REG_LCM_OSD_OVERLAY, inpw(REG_LCM_OSD_OVERLAY) | VPOSTB_BLI_ON);
- outpw(REG_LCM_OSD_OVERLAY, inpw(REG_LCM_OSD_OVERLAY) | ((uint32_t)(u8OSDBlinkVcnt) << 16));
- }
- /**
- * @brief Disable OSD blinking function
- * @param none
- * @return none
- */
- void vpostOSDDisableBlinking(void)
- {
- outpw(REG_LCM_OSD_OVERLAY, inpw(REG_LCM_OSD_OVERLAY) & ~ VPOSTB_BLI_ON);
- }
- /**
- * @brief Configure display attributes of OSD
- * @param[in] u32OSDSrcType is display type, value could be
- * - \ref OSD_SRC_YUV422
- * - \ref OSD_SRC_YCBCR422
- * - \ref OSD_SRC_RGB888
- * - \ref OSD_SRC_RGB666
- * - \ref OSD_SRC_RGB565
- * - \ref OSD_SRC_RGB444_LOW
- * - \ref OSD_SRC_RGB444_HIGH
- * - \ref OSD_SRC_RGB332
- * @return none
- */
- void vpostSetOSDSrc(uint32_t u32OSDSrcType)
- {
- uint32_t u32BytePerPixel, VA_FF, VA_Sride;
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) & ~(7 << 12) | u32OSDSrcType);
- curOSDDev.ucOSDSrcFormat = u32OSDSrcType;
- switch (u32OSDSrcType)
- {
- case OSD_SRC_YUV422:
- case OSD_SRC_YCBCR422:
- case OSD_SRC_RGB565:
- u32BytePerPixel = 2;
- break;
- case OSD_SRC_RGB666:
- case OSD_SRC_RGB888:
- u32BytePerPixel = 4;
- break;
- default:
- u32BytePerPixel = 2;
- }
- /* set video stream frame buffer control */
- VA_FF = curOSDDev.nOSDWidth * u32BytePerPixel / 4;
- VA_Sride = curOSDDev.nOSDWidth * u32BytePerPixel / 4;
- outpw(REG_LCM_OSD_FBCTRL, inpw(REG_LCM_OSD_FBCTRL) & ~0x7ff07ff | (VA_FF << 16) | VA_Sride);
- }
- /**
- * @brief Get the pointer of OSD frame buffer
- * @param none
- * @return pointer of OSD frame buffer
- * @retval NULL fail.
- * @note Must call \ref vpostOSDSetWindow and \ref vpostSetOSDSrc before calling this function
- */
- uint8_t *vpostGetOSDBuffer(void)
- {
- uint32_t u32BytePerPixel;
- uint8_t *u8BufPtr;
- if ((curOSDDev.nOSDWidth == 0) || (curOSDDev.nOSDHeight == 0))
- {
- return NULL;
- }
- switch (curOSDDev.ucOSDSrcFormat)
- {
- case OSD_SRC_YUV422:
- case OSD_SRC_YCBCR422:
- case OSD_SRC_RGB565:
- u32BytePerPixel = 2;
- break;
- case OSD_SRC_RGB666:
- case OSD_SRC_RGB888:
- u32BytePerPixel = 4;
- break;
- default:
- u32BytePerPixel = 2;
- }
- u8BufPtr = (uint8_t *)malloc((curOSDDev.nOSDWidth * curOSDDev.nOSDHeight * u32BytePerPixel) + 32);
- if (u8BufPtr == NULL)
- return NULL;
- u8BufPtr = (uint8_t *)shift_pointer((uint32_t)u8BufPtr, 32);
- outpw(REG_LCM_OSD_BADDR, (uint32_t)((uint32_t)u8BufPtr | 0x80000000));
- return (uint8_t *)((uint32_t)u8BufPtr | 0x80000000);
- }
- /**
- * @brief Get the pointer of OSD buffer
- * @param[in] u32Cnt is the frame buffer count to allocate. Min value is 1.
- * @return pointer of frame buffer
- * @retval NULL fail.
- * @note before calling this function, display width, height and source format must be set first.
- */
- uint8_t *vpostGetMultiOSDBuffer(uint32_t u32Cnt)
- {
- uint32_t u32BytePerPixel;
- uint8_t *u8BufPtr;
- if ((curOSDDev.nOSDWidth == 0) || (curOSDDev.nOSDHeight == 0))
- {
- return NULL;
- }
- switch (curOSDDev.ucOSDSrcFormat)
- {
- case OSD_SRC_YUV422:
- case OSD_SRC_YCBCR422:
- case OSD_SRC_RGB565:
- u32BytePerPixel = 2;
- break;
- case OSD_SRC_RGB666:
- case OSD_SRC_RGB888:
- u32BytePerPixel = 4;
- break;
- default:
- u32BytePerPixel = 2;
- }
- u8BufPtr = (uint8_t *)malloc((curOSDDev.nOSDWidth * curOSDDev.nOSDHeight * u32BytePerPixel) * u32Cnt + 32);
- if (u8BufPtr == NULL)
- return NULL;
- u8BufPtr = (uint8_t *)shift_pointer((uint32_t)u8BufPtr, 32);
- outpw(REG_LCM_OSD_BADDR, (uint32_t)((uint32_t)u8BufPtr | 0x80000000));
- return (uint8_t *)((uint32_t)u8BufPtr | 0x80000000);
- }
- void vpostSetOSDBuffer(uint8_t *u8BufPtr)
- {
- outpw(REG_LCM_OSD_BADDR, (uint32_t)((uint32_t)u8BufPtr | 0x80000000));
- }
- /**
- * @brief Enable OSD function
- * @param none
- * @return none
- */
- void vpostOSDEnable(void)
- {
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) | VPOSTB_OSD_EN); //OSD enable
- }
- /**
- * @brief Disable OSD function
- * @param none
- * @return none
- */
- void vpostOSDDisable(void)
- {
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) & ~VPOSTB_OSD_EN); //OSD disable
- }
- /**
- * @brief Configure OSD scaling attribute
- * @param[in] u8HIntegral is horizontal integral
- * @param[in] u16HDecimal is horizontal decimal
- * @param[in] u8VScall is scale mode, value could be
- * - \ref VPOSTB_OSD_VUP_1X
- * - \ref VPOSTB_OSD_VUP_2X
- * - \ref VPOSTB_OSD_VUP_4X
- * @return none
- */
- void vpostOSDScalingCtrl(uint8_t u8HIntegral, uint16_t u16HDecimal, uint8_t u8VScall)
- {
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) & 0xfff0ffff); //clear OSD scaling setting
- if (u8VScall != 0)
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) | (u8VScall << 16));
- outpw(REG_LCM_OSD_SCALE, ((uint32_t)u8HIntegral << 10) | ((uint32_t)ceil((double)1024 / 10 * u16HDecimal)) << 6);
- }
- /**
- * @brief Set OSD display window, including start position, width and height.
- * @param[in] u32XStart is X start position
- * @param[in] u32YStart is Y start position
- * @param[in] u32Width is OSD display width
- * @param[in] u32Height is OSD display height
- * @return none
- */
- void vpostOSDSetWindow(uint32_t u32XStart, uint32_t u32YStart, uint32_t u32Width, uint32_t u32Height)
- {
- outpw(REG_LCM_OSD_WINS, ((u32YStart + 1) << 16) | (u32XStart + 1));
- outpw(REG_LCM_OSD_WINE, ((u32YStart + u32Height) << 16) | (u32XStart + u32Width));
- curOSDDev.nOSDWidth = u32Width;
- curOSDDev.nOSDHeight = u32Height;
- }
- /**
- * @brief Initialize hardware cursor function
- * @param[in] u32CursorBMPBuff is pointer of hardware cursor image
- * @param[in] ucMode is hardware cursor mode, value could be
- * - \ref HC_MODE0
- * - \ref HC_MODE1
- * - \ref HC_MODE2
- * - \ref HC_MODE3
- * - \ref HC_MODE4
- * - \ref HC_MODE5
- * @return none
- */
- void vpostHCInit(uint32_t *u32CursorBMPBuff, VA_HCMODE_E ucMode)
- {
- int bpp = 2;
- int BlockWidth = 32;
- int bpw = 32;
- outpw(REG_LCM_HC_CTRL, inpw(REG_LCM_HC_CTRL) & ~0x003f3f00 | (0x00 << 8) | (0x00 << 16)); //set TIP
- if (ucMode == HC_MODE0)
- {
- bpp = 2;
- BlockWidth = 32;
- outpw(REG_LCM_HC_CTRL, inpw(REG_LCM_HC_CTRL) & ~0x7); //set mode 0 32X32X2bpp 4 color
- }
- else if (ucMode == HC_MODE1)
- {
- bpp = 2;
- BlockWidth = 32;
- outpw(REG_LCM_HC_CTRL, inpw(REG_LCM_HC_CTRL) & ~0x7 | 0x1); //set mode 1 32X32X2bpp 3 color and 1 transparent
- }
- else if (ucMode == HC_MODE2)
- {
- bpp = 2;
- BlockWidth = 64;
- outpw(REG_LCM_HC_CTRL, inpw(REG_LCM_HC_CTRL) & ~0x7 | 0x2); //set mode 2 64X64X2bpp 4 color
- }
- else if (ucMode == HC_MODE3)
- {
- bpp = 2;
- BlockWidth = 64;
- outpw(REG_LCM_HC_CTRL, inpw(REG_LCM_HC_CTRL) & ~0x7 | 0x3); //set mode 3 64X64X2bpp 3 color and 1 transparent
- }
- else if (ucMode == HC_MODE4)
- {
- bpp = 1;
- BlockWidth = 128;
- outpw(REG_LCM_HC_CTRL, inpw(REG_LCM_HC_CTRL) & ~0x7 | 0x4); //set mode 4 128X128X1bpp 2 color
- }
- else if (ucMode == HC_MODE5)
- {
- bpp = 1;
- BlockWidth = 128;
- outpw(REG_LCM_HC_CTRL, inpw(REG_LCM_HC_CTRL) & ~0x7 | 0x5); //set mode 5 128X128X1bpp 1 color and 1 transparent
- }
- outpw(REG_LCM_HC_WBCTRL, ((bpp * BlockWidth / bpw) << 16) | (bpp * BlockWidth / bpw));
- outpw(REG_LCM_HC_BADDR, (uint32_t)u32CursorBMPBuff);
- outpw(REG_LCM_HC_COLOR0, 0x00ff0000); // RED color
- outpw(REG_LCM_HC_COLOR1, 0x0000ff00); // GREEN color
- outpw(REG_LCM_HC_COLOR2, 0x000000ff); // BLUE color
- outpw(REG_LCM_HC_COLOR3, 0x00ffff00); // YELLOW color
- outpw(REG_LCM_DCCS, inpw(REG_LCM_DCCS) | VPOSTB_HC_EN);
- }
- /**
- * @brief Set the position of hardware cursor
- * @param[in] u32CursorX is X position
- * @param[in] u32CursorY is Y position
- * @return none
- */
- void vpostHCPosCtrl(uint32_t u32CursorX, uint32_t u32CursorY)
- {
- outpw(REG_LCM_HC_POS, (u32CursorY << 16) | u32CursorX); //set Cursor position
- }
- /**
- * @brief Set OSD overlay condition
- * @param[in] u8OSDDisplayMatch is display method when mask bit is matched, value could be
- * - \ref DISPLAY_VIDEO
- * - \ref DISPLAY_OSD
- * - \ref DISPLAY_SYNTHESIZED
- * @param[in] u8OSDDisplayUnMatch is display method when mask bit is unmatched
- * - \ref DISPLAY_VIDEO
- * - \ref DISPLAY_OSD
- * - \ref DISPLAY_SYNTHESIZED
- * @param[in] u8OSDSynW is synthesis video weighting, based on match condition
- * @return none
- */
- void vpostOSDSetOverlay(uint8_t u8OSDDisplayMatch, uint8_t u8OSDDisplayUnMatch, uint8_t u8OSDSynW)
- {
- /* clear OCR0 and OCR1 */
- outpw(REG_LCM_OSD_OVERLAY, inpw(REG_LCM_OSD_OVERLAY) & 0xfffffff0);
- /* match condition */
- if (u8OSDDisplayMatch != 0)
- {
- outpw(REG_LCM_OSD_OVERLAY, inpw(REG_LCM_OSD_OVERLAY) | (u8OSDDisplayMatch << 2));
- }
- /* unmatch condition */
- if (u8OSDDisplayUnMatch != 0)
- {
- outpw(REG_LCM_OSD_OVERLAY, inpw(REG_LCM_OSD_OVERLAY) | (u8OSDDisplayUnMatch));
- }
- /* synthesized weight */
- if (u8OSDDisplayMatch == DISPLAY_SYNTHESIZED || u8OSDDisplayUnMatch == DISPLAY_SYNTHESIZED)
- {
- outpw(REG_LCM_OSD_OVERLAY, inpw(REG_LCM_OSD_OVERLAY) | (u8OSDSynW << 4));
- }
- }
- /**
- * @brief Write MPU command
- * @param[in] uscmd MPU command code
- * @return none
- */
- void vpostMPUWriteAddr(uint16_t uscmd)
- {
- outpw(REG_LCM_MPU_CMD, inpw(REG_LCM_MPU_CMD) & ~(1 << 30)); //RS=0
- outpw(REG_LCM_MPU_CMD, inpw(REG_LCM_MPU_CMD) & ~(1 << 29)); //w
- outpw(REG_LCM_DCCS, (inpw(REG_LCM_DCCS) | (1 << 5))); //CMD ON
- outpw(REG_LCM_MPU_CMD, (inpw(REG_LCM_MPU_CMD) & 0xffff0000 | uscmd));
- while (inpw(REG_LCM_MPU_CMD) & (1UL << 31));
- outpw(REG_LCM_DCCS, (inpw(REG_LCM_DCCS) & ~(1 << 5))); //CMD OFF
- }
- /**
- * @brief Write MPU data
- * @param[in] usdata MPU data
- * @return none
- */
- void vpostMPUWriteData(uint16_t usdata)
- {
- outpw(REG_LCM_MPU_CMD, inpw(REG_LCM_MPU_CMD) | (1 << 30)); //RS=1
- outpw(REG_LCM_MPU_CMD, inpw(REG_LCM_MPU_CMD) & ~(1 << 29)); //w
- outpw(REG_LCM_DCCS, (inpw(REG_LCM_DCCS) | (1 << 5))); //CMD ON
- outpw(REG_LCM_MPU_CMD, inpw(REG_LCM_MPU_CMD) & 0xffff0000 | usdata);
- while (inpw(REG_LCM_MPU_CMD) & (1UL << 31));
- outpw(REG_LCM_DCCS, (inpw(REG_LCM_DCCS) & ~(1 << 5))); //CMD OFF
- }
- /**
- * @brief Read MPU data
- * @param none
- * @return MPU data
- */
- uint32_t vpostMPUReadData(void)
- {
- uint32_t udata;
- outpw(REG_LCM_MPU_CMD, inpw(REG_LCM_MPU_CMD) | (1 << 30)); //RS=1
- outpw(REG_LCM_DCCS, (inpw(REG_LCM_DCCS) | (1 << 5))); //CMD ON
- outpw(REG_LCM_MPU_CMD, inpw(REG_LCM_MPU_CMD) | (1 << 29)); //r
- while (inpw(REG_LCM_MPU_CMD) & (1UL << 31));
- udata = inpw(REG_LCM_MPU_CMD) & 0xffff;
- outpw(REG_LCM_DCCS, (inpw(REG_LCM_DCCS) & ~(1 << 5))); //CMD OFF
- return udata;
- }
- /*@}*/ /* end of group N9H30_LCD_EXPORTED_FUNCTIONS */
- /*@}*/ /* end of group N9H30_LCD_Driver */
- /*@}*/ /* end of group N9H30_Device_Driver */
- /*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/
|