fsl_elcdif.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Copyright (c) 2017, NXP Semiconductors, Inc.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "fsl_elcdif.h"
  31. /*******************************************************************************
  32. * Prototypes
  33. ******************************************************************************/
  34. /*!
  35. * @brief Get instance number for ELCDIF module.
  36. *
  37. * @param base ELCDIF peripheral base address
  38. */
  39. static uint32_t ELCDIF_GetInstance(LCDIF_Type *base);
  40. /*******************************************************************************
  41. * Variables
  42. ******************************************************************************/
  43. /*! @brief Pointers to ELCDIF bases for each instance. */
  44. static LCDIF_Type *const s_elcdifBases[] = LCDIF_BASE_PTRS;
  45. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  46. /*! @brief Pointers to eLCDIF apb_clk for each instance. */
  47. static const clock_ip_name_t s_elcdifApbClocks[] = LCDIF_CLOCKS;
  48. #if defined(LCDIF_PERIPH_CLOCKS)
  49. /*! @brief Pointers to eLCDIF pix_clk for each instance. */
  50. static const clock_ip_name_t s_elcdifPixClocks[] = LCDIF_PERIPH_CLOCKS;
  51. #endif
  52. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  53. /*! @brief The control register value to select different pixel format. */
  54. elcdif_pixel_format_reg_t s_pixelFormatReg[] = {
  55. /* kELCDIF_PixelFormatRAW8 */
  56. {/* Register CTRL. */
  57. LCDIF_CTRL_WORD_LENGTH(1U),
  58. /* Register CTRL1. */
  59. LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
  60. /* kELCDIF_PixelFormatRGB565 */
  61. {/* Register CTRL. */
  62. LCDIF_CTRL_WORD_LENGTH(0U),
  63. /* Register CTRL1. */
  64. LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
  65. /* kELCDIF_PixelFormatRGB666 */
  66. {/* Register CTRL. */
  67. LCDIF_CTRL_WORD_LENGTH(3U) | LCDIF_CTRL_DATA_FORMAT_24_BIT(1U),
  68. /* Register CTRL1. */
  69. LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)},
  70. /* kELCDIF_PixelFormatXRGB8888 */
  71. {/* Register CTRL. 24-bit. */
  72. LCDIF_CTRL_WORD_LENGTH(3U),
  73. /* Register CTRL1. */
  74. LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)},
  75. /* kELCDIF_PixelFormatRGB888 */
  76. {/* Register CTRL. 24-bit. */
  77. LCDIF_CTRL_WORD_LENGTH(3U),
  78. /* Register CTRL1. */
  79. LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
  80. };
  81. /*******************************************************************************
  82. * Codes
  83. ******************************************************************************/
  84. static uint32_t ELCDIF_GetInstance(LCDIF_Type *base)
  85. {
  86. uint32_t instance;
  87. /* Find the instance index from base address mappings. */
  88. for (instance = 0; instance < ARRAY_SIZE(s_elcdifBases); instance++)
  89. {
  90. if (s_elcdifBases[instance] == base)
  91. {
  92. break;
  93. }
  94. }
  95. assert(instance < ARRAY_SIZE(s_elcdifBases));
  96. return instance;
  97. }
  98. void ELCDIF_RgbModeInit(LCDIF_Type *base, const elcdif_rgb_mode_config_t *config)
  99. {
  100. assert(config);
  101. assert(config->pixelFormat < ARRAY_SIZE(s_pixelFormatReg));
  102. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  103. uint32_t instance = ELCDIF_GetInstance(base);
  104. /* Enable the clock. */
  105. CLOCK_EnableClock(s_elcdifApbClocks[instance]);
  106. #if defined(LCDIF_PERIPH_CLOCKS)
  107. CLOCK_EnableClock(s_elcdifPixClocks[instance]);
  108. #endif
  109. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  110. /* Reset. */
  111. ELCDIF_Reset(base);
  112. base->CTRL = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl | (uint32_t)(config->dataBus) |
  113. LCDIF_CTRL_DOTCLK_MODE_MASK | /* RGB mode. */
  114. LCDIF_CTRL_BYPASS_COUNT_MASK | /* Keep RUN bit set. */
  115. LCDIF_CTRL_MASTER_MASK;
  116. base->CTRL1 = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl1;
  117. base->TRANSFER_COUNT = ((uint32_t)config->panelHeight << LCDIF_TRANSFER_COUNT_V_COUNT_SHIFT) |
  118. ((uint32_t)config->panelWidth << LCDIF_TRANSFER_COUNT_H_COUNT_SHIFT);
  119. base->VDCTRL0 = LCDIF_VDCTRL0_ENABLE_PRESENT_MASK | /* Data enable signal. */
  120. LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT_MASK | /* VSYNC period in the unit of display clock. */
  121. LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT_MASK | /* VSYNC pulse width in the unit of display clock. */
  122. (uint32_t)config->polarityFlags | (uint32_t)config->vsw;
  123. base->VDCTRL1 = config->vsw + config->panelHeight + config->vfp + config->vbp;
  124. base->VDCTRL2 = ((uint32_t)config->hsw << LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_SHIFT) |
  125. ((uint32_t)(config->hfp + config->hbp + config->panelWidth + config->hsw))
  126. << LCDIF_VDCTRL2_HSYNC_PERIOD_SHIFT;
  127. base->VDCTRL3 = (((uint32_t)config->hbp + config->hsw) << LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_SHIFT) |
  128. (((uint32_t)config->vbp + config->vsw) << LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_SHIFT);
  129. base->VDCTRL4 = LCDIF_VDCTRL4_SYNC_SIGNALS_ON_MASK |
  130. ((uint32_t)config->panelWidth << LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_SHIFT);
  131. base->CUR_BUF = config->bufferAddr;
  132. base->NEXT_BUF = config->bufferAddr;
  133. }
  134. void ELCDIF_RgbModeGetDefaultConfig(elcdif_rgb_mode_config_t *config)
  135. {
  136. assert(config);
  137. config->panelWidth = 480U;
  138. config->panelHeight = 272U;
  139. config->hsw = 41;
  140. config->hfp = 4;
  141. config->hbp = 8;
  142. config->vsw = 10;
  143. config->vfp = 4;
  144. config->vbp = 2;
  145. config->polarityFlags = kELCDIF_VsyncActiveLow | kELCDIF_HsyncActiveLow | kELCDIF_DataEnableActiveLow |
  146. kELCDIF_DriveDataOnFallingClkEdge;
  147. config->bufferAddr = 0U;
  148. config->pixelFormat = kELCDIF_PixelFormatRGB888;
  149. config->dataBus = kELCDIF_DataBus24Bit;
  150. }
  151. void ELCDIF_Deinit(LCDIF_Type *base)
  152. {
  153. ELCDIF_Reset(base);
  154. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  155. uint32_t instance = ELCDIF_GetInstance(base);
  156. /* Disable the clock. */
  157. #if defined(LCDIF_PERIPH_CLOCKS)
  158. CLOCK_DisableClock(s_elcdifPixClocks[instance]);
  159. #endif
  160. CLOCK_DisableClock(s_elcdifApbClocks[instance]);
  161. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  162. }
  163. void ELCDIF_RgbModeStop(LCDIF_Type *base)
  164. {
  165. base->CTRL_CLR = LCDIF_CTRL_DOTCLK_MODE_MASK;
  166. /* Wait for data transfer finished. */
  167. while (base->CTRL & LCDIF_CTRL_DOTCLK_MODE_MASK)
  168. {
  169. }
  170. }
  171. void ELCDIF_Reset(LCDIF_Type *base)
  172. {
  173. volatile uint32_t i = 0x100;
  174. /* Disable the clock gate. */
  175. base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK;
  176. /* Confirm the clock gate is disabled. */
  177. while (base->CTRL & LCDIF_CTRL_CLKGATE_MASK)
  178. {
  179. }
  180. /* Reset the block. */
  181. base->CTRL_SET = LCDIF_CTRL_SFTRST_MASK;
  182. /* Confirm the reset bit is set. */
  183. while (!(base->CTRL & LCDIF_CTRL_SFTRST_MASK))
  184. {
  185. }
  186. /* Delay for the reset. */
  187. while (i--)
  188. {
  189. }
  190. /* Bring the module out of reset. */
  191. base->CTRL_CLR = LCDIF_CTRL_SFTRST_MASK;
  192. /* Disable the clock gate. */
  193. base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK;
  194. }
  195. #if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
  196. void ELCDIF_SetAlphaSurfaceBufferConfig(LCDIF_Type *base, const elcdif_as_buffer_config_t *config)
  197. {
  198. assert(config);
  199. base->AS_CTRL = (base->AS_CTRL & ~LCDIF_AS_CTRL_FORMAT_MASK) | LCDIF_AS_CTRL_FORMAT(config->pixelFormat);
  200. base->AS_BUF = config->bufferAddr;
  201. base->AS_NEXT_BUF = config->bufferAddr;
  202. }
  203. void ELCDIF_SetAlphaSurfaceBlendConfig(LCDIF_Type *base, const elcdif_as_blend_config_t *config)
  204. {
  205. assert(config);
  206. uint32_t reg;
  207. reg = base->AS_CTRL;
  208. reg &= ~(LCDIF_AS_CTRL_ALPHA_INVERT_MASK | LCDIF_AS_CTRL_ROP_MASK | LCDIF_AS_CTRL_ALPHA_MASK |
  209. LCDIF_AS_CTRL_ALPHA_CTRL_MASK);
  210. reg |= (LCDIF_AS_CTRL_ROP(config->ropMode) | LCDIF_AS_CTRL_ALPHA(config->alpha) |
  211. LCDIF_AS_CTRL_ALPHA_CTRL(config->alphaMode));
  212. if (config->invertAlpha)
  213. {
  214. reg |= LCDIF_AS_CTRL_ALPHA_INVERT_MASK;
  215. }
  216. base->AS_CTRL = reg;
  217. }
  218. #endif /* FSL_FEATURE_LCDIF_HAS_NO_AS */
  219. #if (defined(FSL_FEATURE_LCDIF_HAS_LUT) && FSL_FEATURE_LCDIF_HAS_LUT)
  220. status_t ELCDIF_UpdateLut(
  221. LCDIF_Type *base, elcdif_lut_t lut, uint16_t startIndex, const uint32_t *lutData, uint16_t count)
  222. {
  223. volatile uint32_t *regLutAddr;
  224. volatile uint32_t *regLutData;
  225. uint32_t i;
  226. /* Only has 256 entries. */
  227. if (startIndex + count > ELCDIF_LUT_ENTRY_NUM)
  228. {
  229. return kStatus_InvalidArgument;
  230. }
  231. if (kELCDIF_Lut0 == lut)
  232. {
  233. regLutAddr = &(base->LUT0_ADDR);
  234. regLutData = &(base->LUT0_DATA);
  235. }
  236. else
  237. {
  238. regLutAddr = &(base->LUT1_ADDR);
  239. regLutData = &(base->LUT1_DATA);
  240. }
  241. *regLutAddr = startIndex;
  242. for (i = 0; i < count; i++)
  243. {
  244. *regLutData = lutData[i];
  245. for (volatile uint32_t j = 0; j < 0x80; j++)
  246. {
  247. }
  248. }
  249. return kStatus_Success;
  250. }
  251. #endif /* FSL_FEATURE_LCDIF_HAS_LUT */