hpm_lcdc_drv.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /*
  2. * Copyright (c) 2021 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_LCDC_DRV_H
  8. #define HPM_LCDC_DRV_H
  9. #include "hpm_display_common.h"
  10. #include "hpm_soc_feature.h"
  11. #include "hpm_lcdc_regs.h"
  12. /**
  13. *
  14. * @brief LCD driver APIs
  15. * @defgroup lcd_interface LCD driver APIs
  16. * @ingroup io_interfaces
  17. * @{
  18. */
  19. #define LCDC_TEST_MODE_DISABLE (0U)
  20. #define LCDC_TEST_MODE_BACKGROUND (1U)
  21. #define LCDC_TEST_MODE_COLOR_BAR_COL (2U)
  22. #define LCDC_TEST_MODE_COLOR_BAR_ROW (3U)
  23. /* @brief LCD driver specific status */
  24. enum {
  25. status_lcdc_no_active_layer_yet = MAKE_STATUS(status_group_lcdc, 1),
  26. status_lcdc_layer_not_supported = MAKE_STATUS(status_group_lcdc, 2),
  27. };
  28. /* @brief LCD line pattern */
  29. typedef enum lcdc_line_pattern {
  30. lcdc_line_pattern_rgb = 0,
  31. lcdc_line_pattern_rbg,
  32. lcdc_line_pattern_gbr,
  33. lcdc_line_pattern_grb,
  34. lcdc_line_pattern_brg,
  35. lcdc_line_pattern_bgr,
  36. } lcdc_line_pattern_t;
  37. /* @brief LCD display mode */
  38. typedef enum lcdc_display_mode {
  39. lcdc_display_mode_normal = 0,
  40. lcdc_display_mode_test_mode_1,
  41. lcdc_display_mode_test_mode_2,
  42. lcdc_display_mode_test_mode_3,
  43. } lcdc_display_mode_t;
  44. /* @brief LCD layer transfer max bytes */
  45. typedef enum lcdc_layer_max_bytes_per_transfer {
  46. lcdc_layer_max_bytes_64 = 0,
  47. lcdc_layer_max_bytes_128,
  48. lcdc_layer_max_bytes_256,
  49. lcdc_layer_max_bytes_512,
  50. lcdc_layer_max_bytes_1024,
  51. } lcdc_layer_max_bytes_per_transfer_t;
  52. /* @brief LCD control */
  53. typedef struct lcdc_control {
  54. lcdc_line_pattern_t line_pattern; /**< Line pattern setting */
  55. lcdc_display_mode_t display_mode; /**< Display mode setting */
  56. bool invert_pixel_data; /**< Invert pixel data level */
  57. bool invert_pixel_clock; /**< Invert pixel clock level */
  58. bool invert_href; /**< Invert href level */
  59. bool invert_vsync; /**< Invert vsync level */
  60. bool invert_hsync; /**< Invert hsync level */
  61. } lcdc_control_t;
  62. /* @brief LCD hsync/vsync config */
  63. typedef struct lcdc_xsync_config {
  64. uint16_t front_porch_pulse; /**< Front porch pulse */
  65. uint16_t back_porch_pulse; /**< Back porch pulse */
  66. uint16_t pulse_width; /**< Pulse width */
  67. } lcdc_xsync_config_t;
  68. /* @brief LCD config */
  69. typedef struct lcdc_config {
  70. uint16_t resolution_x; /**< Horizontal resolution in pixel */
  71. uint16_t resolution_y; /**< Vertial resolution in pixel */
  72. lcdc_xsync_config_t hsync; /**< Hsync config */
  73. lcdc_xsync_config_t vsync; /**< Vsync config */
  74. display_color_32b_t background; /**< Background color */
  75. lcdc_control_t control; /**< LCD control */
  76. } lcdc_config_t;
  77. /* @brief LCD layer config */
  78. typedef struct lcdc_layer_config {
  79. uint8_t max_ot; /**< Maximum outstanding transfer */
  80. display_byteorder_t byteorder; /**< Byte order */
  81. display_yuv_format_t yuv; /**< YUV format */
  82. display_pixel_format_t pixel_format; /**< Pixel format */
  83. display_alphablend_option_t alphablend; /**< Alphablending option */
  84. display_yuv2rgb_config_t csc_config; /**< Color space conversion config */
  85. lcdc_layer_max_bytes_per_transfer_t max_bytes; /**< Layer max transfer bytes */
  86. uint16_t height; /**< Layer height in pixel */
  87. uint16_t width; /**< Layer width in pixel */
  88. uint16_t position_x; /**< Layer output position X coord */
  89. uint16_t position_y; /**< Layer output position Y coord */
  90. display_color_32b_t background; /**< Background color */
  91. uint32_t buffer; /**< Pointer of layer display buffer */
  92. uint32_t stride; /**< stride of lines in bytes. stride is calculated by driver if stride == 0. */
  93. } lcdc_layer_config_t;
  94. #ifdef __cplusplus
  95. extern "C" {
  96. #endif
  97. /**
  98. *
  99. * @brief Layer config
  100. *
  101. * @param[in] ptr LCD base address
  102. */
  103. static inline void lcdc_software_reset(LCDC_Type *ptr)
  104. {
  105. ptr->CTRL |= LCDC_CTRL_SW_RST_MASK;
  106. ptr->CTRL &= ~LCDC_CTRL_SW_RST_MASK;
  107. }
  108. /**
  109. *
  110. * @brief Enable interrupt according to the given mask
  111. *
  112. * @param[in] ptr LCD base address
  113. * @param[in] interrupt_mask Mask of interrupts to be enabled
  114. */
  115. static inline void lcdc_enable_interrupt(LCDC_Type *ptr, uint32_t interrupt_mask)
  116. {
  117. ptr->INT_EN |= interrupt_mask;
  118. }
  119. /**
  120. *
  121. * @brief Disable interrupt according to the given mask
  122. *
  123. * @param[in] ptr LCD base address
  124. * @param[in] interrupt_mask Mask of interrupts to be disabled
  125. */
  126. static inline void lcdc_disable_interrupt(LCDC_Type *ptr, uint32_t interrupt_mask)
  127. {
  128. ptr->INT_EN &= ~interrupt_mask;
  129. }
  130. /**
  131. *
  132. * @brief Clear specific status according to the given mask
  133. *
  134. * @param[in] ptr LCD base address
  135. * @param[in] mask Status mask of status to be cleared
  136. */
  137. static inline void lcdc_clear_status(LCDC_Type *ptr, uint32_t mask)
  138. {
  139. ptr->ST = mask;
  140. }
  141. /**
  142. *
  143. * @brief Make layer control shadow registers take effect
  144. *
  145. * @param[in] ptr LCD base address
  146. * @param[in] layer_index Index of layer to be controlled
  147. */
  148. static inline bool lcdc_layer_control_shadow_loaded(LCDC_Type *ptr, uint8_t layer_index)
  149. {
  150. return !(ptr->LAYER[layer_index].LAYCTRL & LCDC_LAYER_LAYCTRL_SHADOW_LOAD_EN_MASK);
  151. }
  152. /**
  153. *
  154. * @brief Get DMA status
  155. *
  156. * @param[in] ptr LCD base address
  157. * @retval DMA status
  158. */
  159. static inline uint32_t lcdc_get_dma_status(LCDC_Type *ptr)
  160. {
  161. return ptr->DMA_ST;
  162. }
  163. /**
  164. *
  165. * @brief Check DMA status against the given mask
  166. *
  167. * @param[in] ptr LCD base address
  168. * @param[in] mask Mask of expected DMA status
  169. * @retval true if all bits set to 1 in mask are set
  170. * @retval false if any bit set to 1 in mask is not set
  171. */
  172. static inline bool lcdc_check_dma_status(LCDC_Type *ptr, uint32_t mask)
  173. {
  174. return ((ptr->DMA_ST & mask) == mask);
  175. }
  176. /**
  177. *
  178. * @brief Clear DMA status according to the given mask
  179. *
  180. * @param[in] ptr LCD base address
  181. * @param[in] mask Mask of expected DMA status
  182. */
  183. static inline void lcdc_clear_dma_status(LCDC_Type *ptr, uint32_t mask)
  184. {
  185. ptr->DMA_ST = mask;
  186. }
  187. /**
  188. *
  189. * @brief Get status
  190. *
  191. * @param[in] ptr LCD base address
  192. * @retval current status
  193. */
  194. static inline uint32_t lcdc_get_status(LCDC_Type *ptr)
  195. {
  196. return ptr->ST;
  197. }
  198. /**
  199. *
  200. * @brief Check status against the given mask
  201. *
  202. * @param[in] ptr LCD base address
  203. * @param[in] mask Mask of expected status
  204. * @retval true if all bits set to 1 in mask are set
  205. * @retval false if any bit set to 1 in mask is not set
  206. */
  207. static inline bool lcdc_check_status(LCDC_Type *ptr, uint32_t mask)
  208. {
  209. return (ptr->ST & mask) == mask;
  210. }
  211. /**
  212. *
  213. * @brief Set next buffer for certain layer
  214. *
  215. * @param[in] ptr LCD base address
  216. * @param[in] layer_index target layer to be configured
  217. * @param[in] buffer display buffer to be set
  218. */
  219. static inline void lcdc_layer_set_next_buffer(LCDC_Type *ptr, uint32_t layer_index, uint32_t buffer)
  220. {
  221. ptr->LAYER[layer_index].START0 = LCDC_LAYER_START0_ADDR0_SET(buffer);
  222. ptr->LAYER[layer_index].LAYCTRL |= LCDC_LAYER_LAYCTRL_SHADOW_LOAD_EN_MASK;
  223. }
  224. /**
  225. *
  226. * @brief Update specific layer background
  227. *
  228. * @param[in] ptr LCD base address
  229. * @param[in] layer_index target layer to be configured
  230. * @param[in] background color to be set as background
  231. */
  232. static inline void lcdc_layer_update_background(LCDC_Type *ptr,
  233. uint8_t layer_index, display_color_32b_t background)
  234. {
  235. ptr->LAYER[layer_index].BG_CL = LCDC_LAYER_BG_CL_ARGB_SET(background.u);
  236. ptr->LAYER[layer_index].LAYCTRL |= LCDC_LAYER_LAYCTRL_SHADOW_LOAD_EN_MASK;
  237. }
  238. /**
  239. *
  240. * @brief Update specific layer position
  241. *
  242. * @param[in] ptr LCD base address
  243. * @param[in] layer_index target layer to be configured
  244. * @param[in] x Position X coord
  245. * @param[in] y Position Y coord
  246. */
  247. static inline void lcdc_layer_update_position(LCDC_Type *ptr,
  248. uint8_t layer_index, uint16_t x, uint32_t y)
  249. {
  250. ptr->LAYER[layer_index].LAYPOS = LCDC_LAYER_LAYPOS_X_SET(x)
  251. | LCDC_LAYER_LAYPOS_Y_SET(y);
  252. ptr->LAYER[layer_index].LAYCTRL |= LCDC_LAYER_LAYCTRL_SHADOW_LOAD_EN_MASK;
  253. }
  254. /**
  255. *
  256. * @brief Update specific layer dimension
  257. *
  258. * @param[in] ptr LCD base address
  259. * @param[in] layer_index target layer to be configured
  260. * @param[in] width Width in pixel
  261. * @param[in] height Height in pixel
  262. */
  263. static inline void lcdc_layer_update_dimension(LCDC_Type *ptr,
  264. uint8_t layer_index, uint8_t width, uint8_t height)
  265. {
  266. ptr->LAYER[layer_index].LAYSIZE = LCDC_LAYER_LAYSIZE_WIDTH_SET(width)
  267. | LCDC_LAYER_LAYSIZE_HEIGHT_SET(height);
  268. ptr->LAYER[layer_index].LAYCTRL |= LCDC_LAYER_LAYCTRL_SHADOW_LOAD_EN_MASK;
  269. }
  270. /**
  271. *
  272. * @brief Update specific layer region
  273. *
  274. * @param[in] ptr LCD base address
  275. * @param[in] layer_index target layer to be configured
  276. * @param[in] x1 X coord of the top left pixel
  277. * @param[in] y1 Y coord of the top left pixel
  278. * @param[in] x2 X coord of the bottom right pixel
  279. * @param[in] y2 Y coord of the bottom right pixel
  280. */
  281. static inline void lcdc_layer_set_region(LCDC_Type *ptr, uint8_t layer_index,
  282. uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
  283. {
  284. ptr->LAYER[layer_index].LAYPOS = LCDC_LAYER_LAYPOS_X_SET(x1)
  285. | LCDC_LAYER_LAYPOS_Y_SET(y1);
  286. ptr->LAYER[layer_index].LAYSIZE = LCDC_LAYER_LAYSIZE_WIDTH_SET(x2 - x1 + 1)
  287. | LCDC_LAYER_LAYSIZE_HEIGHT_SET(y2 - y1 + 1);
  288. ptr->LAYER[layer_index].LAYCTRL |= LCDC_LAYER_LAYCTRL_SHADOW_LOAD_EN_MASK;
  289. }
  290. /**
  291. *
  292. * @brief Update specific layer configuration
  293. *
  294. * @param[in] ptr LCD base address
  295. * @param[in] layer_index target layer to be configured
  296. */
  297. static inline void lcdc_layer_update(LCDC_Type *ptr, uint8_t layer_index)
  298. {
  299. ptr->LAYER[layer_index].LAYCTRL |= LCDC_LAYER_LAYCTRL_SHADOW_LOAD_EN_MASK;
  300. }
  301. /**
  302. *
  303. * @brief Enable specific layer
  304. *
  305. * @param[in] ptr LCD base address
  306. * @param[in] layer_index target layer to be configured
  307. */
  308. static inline void lcdc_layer_enable(LCDC_Type *ptr, uint32_t layer_index)
  309. {
  310. ptr->LAYER[layer_index].LAYCTRL |=
  311. (LCDC_LAYER_LAYCTRL_EN_MASK | LCDC_LAYER_LAYCTRL_SHADOW_LOAD_EN_MASK);
  312. }
  313. /**
  314. *
  315. * @brief Disable specific layer
  316. *
  317. * @param[in] ptr LCD base address
  318. * @param[in] layer_index target layer to be configured
  319. */
  320. static inline void lcdc_layer_disable(LCDC_Type *ptr, uint32_t layer_index)
  321. {
  322. ptr->LAYER[layer_index].LAYCTRL =
  323. (ptr->LAYER[layer_index].LAYCTRL & (~LCDC_LAYER_LAYCTRL_EN_MASK))
  324. | LCDC_LAYER_LAYCTRL_SHADOW_LOAD_EN_MASK;
  325. }
  326. /**
  327. *
  328. * @brief Set test mode
  329. *
  330. * @param[in] ptr LCD base address
  331. * @param[in] test_mode target test mode to be enabled
  332. */
  333. static inline void lcdc_set_testmode(LCDC_Type *ptr, uint8_t test_mode)
  334. {
  335. ptr->CTRL = ((ptr->CTRL & ~LCDC_CTRL_DISP_MODE_MASK))
  336. | LCDC_CTRL_DISP_MODE_SET(test_mode)
  337. | LCDC_CTRL_DISP_ON_MASK;
  338. }
  339. /**
  340. *
  341. * @brief Set background
  342. *
  343. * @param[in] ptr LCD base address
  344. * @param[in] color background color
  345. */
  346. static inline void lcdc_set_background(LCDC_Type *ptr,
  347. display_color_32b_t color)
  348. {
  349. ptr->BGND_CL = LCDC_BGND_CL_R_SET(color.r)
  350. | LCDC_BGND_CL_G_SET(color.g)
  351. | LCDC_BGND_CL_B_SET(color.b);
  352. }
  353. /**
  354. *
  355. * @brief enable background on alpha blender
  356. *
  357. * @note it not depend the background color of the layer itself. it can be used with lcdc_set_background API
  358. *
  359. * @param[in] ptr LCD base address
  360. */
  361. static inline void lcdc_enable_background_in_alpha_blender(LCDC_Type *ptr)
  362. {
  363. ptr->CTRL |= LCDC_CTRL_BGDCL4CLR_MASK;
  364. }
  365. /**
  366. *
  367. * @brief disable background on alpha blender
  368. *
  369. * @note if not use background but want depend the the background color of the layer itself, can be use the API
  370. *
  371. * @param[in] ptr LCD base address
  372. */
  373. static inline void lcdc_disable_background_in_alpha_blender(LCDC_Type *ptr)
  374. {
  375. ptr->CTRL &= ~LCDC_CTRL_BGDCL4CLR_MASK;
  376. }
  377. /**
  378. *
  379. * @brief Get default layer configuration value
  380. *
  381. * @param[in] ptr LCD base address
  382. * @param[out] layer Pointer of layer configuration struct buffer
  383. * @param[in] pixel_format Pixel format to be used for this layer
  384. * @param[in] layer_index target layer to be configured
  385. */
  386. void lcdc_get_default_layer_config(LCDC_Type *ptr,
  387. lcdc_layer_config_t *layer, display_pixel_format_t pixel_format, uint8_t layer_index);
  388. /**
  389. *
  390. * @brief Get default configuration value
  391. *
  392. * @param[in] ptr LCD base address
  393. * @param[out] config Pointer of configuration struct buffer
  394. */
  395. void lcdc_get_default_config(LCDC_Type *ptr, lcdc_config_t *config);
  396. /**
  397. *
  398. * @brief Initialize LCD controller
  399. *
  400. * @param[in] ptr LCD base address
  401. * @param[in] config Pointer of configuration struct buffer
  402. */
  403. void lcdc_init(LCDC_Type *ptr, lcdc_config_t *config);
  404. /**
  405. *
  406. * @brief Configure specific layer
  407. *
  408. * @param[in] ptr LCD base address
  409. * @param[in] layer_index target layer to be configured
  410. * @param[in] layer_config Pointer of layer configuration struct buffer
  411. * @param[in] enable_layer Set true if the layer needs to be enabled right after being configured
  412. */
  413. hpm_stat_t lcdc_config_layer(LCDC_Type *ptr, uint8_t layer_index,
  414. lcdc_layer_config_t *layer_config, bool enable_layer);
  415. /**
  416. *
  417. * @brief Turn on display
  418. *
  419. * @param[in] ptr LCD base address
  420. */
  421. void lcdc_turn_on_display(LCDC_Type *ptr);
  422. /**
  423. *
  424. * @brief Turn off display
  425. *
  426. * @param[in] ptr LCD base address
  427. */
  428. void lcdc_turn_off_display(LCDC_Type *ptr);
  429. #ifdef __cplusplus
  430. }
  431. #endif
  432. /**
  433. * @}
  434. */
  435. #endif /* HPM_LCDC_DRV_H */