drv_lcd_mipi.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-05-23 WillianChan first version
  9. */
  10. #include <board.h>
  11. #include <rtconfig.h>
  12. #ifdef BSP_USING_LCD_MIPI
  13. #include <lcd_port.h>
  14. #include <string.h>
  15. DSI_HandleTypeDef hdsi;
  16. DSI_VidCfgTypeDef hdsi_video;
  17. LTDC_HandleTypeDef hltdc;
  18. struct stm32_lcd
  19. {
  20. struct rt_device parent;
  21. struct rt_device_graphic_info info;
  22. };
  23. struct stm32_lcd lcd;
  24. extern void stm32_mipi_lcd_init(void);
  25. extern void stm32_mipi_lcd_config(rt_uint32_t pixel_format);
  26. extern void stm32_mipi_display_on(void);
  27. extern void stm32_mipi_display_off(void);
  28. rt_err_t ltdc_init(void)
  29. {
  30. uint32_t lcd_clock = 27429;
  31. uint32_t lanebyte_clock = 62500;
  32. uint32_t HSA = LCD_HSYNC, HFP = LCD_HFP, HBP = LCD_HBP, HACT = LCD_WIDTH;
  33. uint32_t VSA = LCD_VSYNC, VFP = LCD_VFP, VBP = LCD_VBP, VACT = LCD_HEIGHT;
  34. stm32_mipi_lcd_init();
  35. __HAL_RCC_LTDC_CLK_ENABLE();
  36. __HAL_RCC_LTDC_FORCE_RESET();
  37. __HAL_RCC_LTDC_RELEASE_RESET();
  38. __HAL_RCC_DSI_CLK_ENABLE();
  39. __HAL_RCC_DSI_FORCE_RESET();
  40. __HAL_RCC_DSI_RELEASE_RESET();
  41. RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
  42. PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
  43. PeriphClkInitStruct.PLLSAI.PLLSAIN = 384;
  44. PeriphClkInitStruct.PLLSAI.PLLSAIR = 7;
  45. PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
  46. HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
  47. HAL_NVIC_SetPriority(LTDC_IRQn, 3, 0);
  48. HAL_NVIC_SetPriority(DSI_IRQn, 3, 0);
  49. HAL_NVIC_EnableIRQ(LTDC_IRQn);
  50. HAL_NVIC_EnableIRQ(DSI_IRQn);
  51. DSI_PLLInitTypeDef dsi_pll;
  52. hdsi.Instance = DSI;
  53. hdsi.Init.NumberOfLanes = DSI_TWO_DATA_LANES;
  54. hdsi.Init.TXEscapeCkdiv = lanebyte_clock / 15620;
  55. dsi_pll.PLLNDIV = 125;
  56. dsi_pll.PLLIDF = DSI_PLL_IN_DIV2;
  57. dsi_pll.PLLODF = DSI_PLL_OUT_DIV1;
  58. HAL_DSI_DeInit(&hdsi);
  59. HAL_DSI_Init(&hdsi, &dsi_pll);
  60. hdsi_video.VirtualChannelID = 0;
  61. hdsi_video.ColorCoding = DSI_RGB565;
  62. hdsi_video.VSPolarity = DSI_VSYNC_ACTIVE_HIGH;
  63. hdsi_video.HSPolarity = DSI_HSYNC_ACTIVE_HIGH;
  64. hdsi_video.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
  65. hdsi_video.Mode = DSI_VID_MODE_BURST;
  66. hdsi_video.NullPacketSize = 0xFFF;
  67. hdsi_video.NumberOfChunks = 0;
  68. hdsi_video.PacketSize = HACT;
  69. hdsi_video.HorizontalSyncActive = (HSA * lanebyte_clock) / lcd_clock;
  70. hdsi_video.HorizontalBackPorch = (HBP * lanebyte_clock) / lcd_clock;
  71. hdsi_video.HorizontalLine = ((HACT + HSA + HBP + HFP) * lanebyte_clock) / lcd_clock;
  72. hdsi_video.VerticalSyncActive = VSA;
  73. hdsi_video.VerticalBackPorch = VBP;
  74. hdsi_video.VerticalFrontPorch = VFP;
  75. hdsi_video.VerticalActive = VACT;
  76. hdsi_video.LPCommandEnable = DSI_LP_COMMAND_ENABLE;
  77. hdsi_video.LPLargestPacketSize = 16;
  78. hdsi_video.LPVACTLargestPacketSize = 0;
  79. hdsi_video.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE;
  80. hdsi_video.LPHorizontalBackPorchEnable = DSI_LP_HBP_ENABLE;
  81. hdsi_video.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE;
  82. hdsi_video.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE;
  83. hdsi_video.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE;
  84. hdsi_video.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE;
  85. HAL_DSI_ConfigVideoMode(&hdsi, &hdsi_video);
  86. DSI_PHY_TimerTypeDef dsi_phy;
  87. dsi_phy.ClockLaneHS2LPTime = 35;
  88. dsi_phy.ClockLaneLP2HSTime = 35;
  89. dsi_phy.DataLaneHS2LPTime = 35;
  90. dsi_phy.DataLaneLP2HSTime = 35;
  91. dsi_phy.DataLaneMaxReadTime = 0;
  92. dsi_phy.StopWaitTime = 10;
  93. HAL_DSI_ConfigPhyTimer(&hdsi, &dsi_phy);
  94. hltdc.Instance = LTDC;
  95. hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
  96. hltdc.Init.HorizontalSync = (HSA - 1);
  97. hltdc.Init.AccumulatedHBP = (HSA + HBP - 1);
  98. hltdc.Init.AccumulatedActiveW = (LCD_WIDTH + HSA + HBP - 1);
  99. hltdc.Init.TotalWidth = (LCD_WIDTH + HSA + HBP + HFP - 1);
  100. hltdc.LayerCfg->ImageWidth = LCD_WIDTH;
  101. hltdc.LayerCfg->ImageHeight = LCD_HEIGHT;
  102. hltdc.Init.Backcolor.Blue = 0x00;
  103. hltdc.Init.Backcolor.Green = 0x00;
  104. hltdc.Init.Backcolor.Red = 0x00;
  105. HAL_LTDCEx_StructInitFromVideoConfig(&hltdc, &(hdsi_video));
  106. HAL_LTDC_Init(&(hltdc));
  107. HAL_DSI_Start(&(hdsi));
  108. stm32_mipi_lcd_config(RTGRAPHIC_PIXEL_FORMAT_RGB565);
  109. return RT_EOK;
  110. }
  111. void ltdc_layer_init(uint16_t index, uint32_t framebuffer)
  112. {
  113. LTDC_LayerCfgTypeDef layer_cfg;
  114. layer_cfg.WindowX0 = 0;
  115. layer_cfg.WindowX1 = LCD_WIDTH;
  116. layer_cfg.WindowY0 = 0;
  117. layer_cfg.WindowY1 = LCD_HEIGHT;
  118. layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
  119. layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
  120. layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
  121. layer_cfg.Alpha = 255;
  122. layer_cfg.Alpha0 = 0;
  123. layer_cfg.ImageWidth = LCD_WIDTH;
  124. layer_cfg.ImageHeight = LCD_HEIGHT;
  125. layer_cfg.Backcolor.Blue = 0;
  126. layer_cfg.Backcolor.Green = 0;
  127. layer_cfg.Backcolor.Red = 0;
  128. layer_cfg.FBStartAdress = framebuffer;
  129. HAL_LTDC_ConfigLayer(&hltdc, &layer_cfg, index);
  130. }
  131. void LTDC_IRQHandler(void)
  132. {
  133. rt_interrupt_enter();
  134. HAL_LTDC_IRQHandler(&hltdc);
  135. rt_interrupt_leave();
  136. }
  137. static rt_err_t stm32_lcd_init(rt_device_t device)
  138. {
  139. lcd.info.width = LCD_WIDTH;
  140. lcd.info.height = LCD_HEIGHT;
  141. lcd.info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565;
  142. lcd.info.bits_per_pixel = 16;
  143. lcd.info.framebuffer = (void *)rt_malloc_align(LCD_WIDTH * LCD_HEIGHT * (lcd.info.bits_per_pixel / 8), 32);;
  144. memset(lcd.info.framebuffer, 0, LCD_WIDTH * LCD_HEIGHT * (lcd.info.bits_per_pixel / 8));
  145. ltdc_init();
  146. ltdc_layer_init(0, (uint32_t)lcd.info.framebuffer);
  147. return RT_EOK;
  148. }
  149. static rt_err_t stm32_lcd_control(rt_device_t device, int cmd, void *args)
  150. {
  151. switch(cmd)
  152. {
  153. case RTGRAPHIC_CTRL_RECT_UPDATE:
  154. break;
  155. case RTGRAPHIC_CTRL_POWERON:
  156. stm32_mipi_display_on();
  157. break;
  158. case RTGRAPHIC_CTRL_POWEROFF:
  159. stm32_mipi_display_off();
  160. break;
  161. case RTGRAPHIC_CTRL_GET_INFO:
  162. rt_memcpy(args, &lcd.info, sizeof(lcd.info));
  163. break;
  164. case RTGRAPHIC_CTRL_SET_MODE:
  165. break;
  166. case RTGRAPHIC_CTRL_GET_EXT:
  167. break;
  168. }
  169. return RT_EOK;
  170. }
  171. int rt_hw_lcd_init(void)
  172. {
  173. rt_err_t ret;
  174. rt_memset(&lcd, 0x00, sizeof(lcd));
  175. lcd.parent.type = RT_Device_Class_Graphic;
  176. lcd.parent.init = stm32_lcd_init;
  177. lcd.parent.open = RT_NULL;
  178. lcd.parent.close = RT_NULL;
  179. lcd.parent.read = RT_NULL;
  180. lcd.parent.write = RT_NULL;
  181. lcd.parent.control = stm32_lcd_control;
  182. lcd.parent.user_data = (void *)&lcd.info;
  183. ret = rt_device_register(&lcd.parent, "lcd", RT_DEVICE_FLAG_RDWR);
  184. return ret;
  185. }
  186. INIT_DEVICE_EXPORT(rt_hw_lcd_init);
  187. rt_weak void stm32_mipi_lcd_init(void)
  188. {
  189. rt_kprintf("please Implementation function %s\n", __func__);
  190. }
  191. rt_weak void stm32_mipi_lcd_config(rt_uint32_t pixel_format)
  192. {
  193. rt_kprintf("please Implementation function %s\n", __func__);
  194. }
  195. rt_weak void stm32_mipi_display_on(void)
  196. {
  197. rt_kprintf("please Implementation function %s\n", __func__);
  198. }
  199. rt_weak void stm32_mipi_display_off(void)
  200. {
  201. rt_kprintf("please Implementation function %s\n", __func__);
  202. }
  203. #endif /* BSP_USING_LCD_MIPI */