SWM341_lcd.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /******************************************************************************************************************************************
  2. * 文件名称: SWM341_lcd.c
  3. * 功能说明: SWM341单片机的LCD功能驱动库
  4. * 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
  5. * 注意事项:
  6. * 版本日期: V1.1.0 2017年10月25日
  7. * 升级记录:
  8. *
  9. *
  10. *******************************************************************************************************************************************
  11. * @attention
  12. *
  13. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
  14. * REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
  15. * FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
  16. * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
  17. * -ECTION WITH THEIR PRODUCTS.
  18. *
  19. * COPYRIGHT 2012 Synwit Technology
  20. *******************************************************************************************************************************************/
  21. #include "SWM341.h"
  22. #include "SWM341_lcd.h"
  23. #include <string.h>
  24. /******************************************************************************************************************************************
  25. * 函数名称: LCD_Init()
  26. * 功能说明: LCD初始化
  27. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  28. * LCD_InitStructure * initStruct 包含LCD相关设定值的结构体
  29. * 输 出: 无
  30. * 注意事项: 无
  31. ******************************************************************************************************************************************/
  32. void LCD_Init(LCD_TypeDef * LCDx, LCD_InitStructure * initStruct)
  33. {
  34. switch((uint32_t)LCDx)
  35. {
  36. case ((uint32_t)LCD):
  37. SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_LCD_Pos);
  38. break;
  39. }
  40. LCDx->CR = ((initStruct->ClkDiv - 2) << LCD_CR_CLKDIV_Pos) |
  41. (initStruct->SampleEdge << LCD_CR_CLKINV_Pos) |
  42. (1 << LCD_CR_CLKALW_Pos) |
  43. ((initStruct->Format & 1) << LCD_CR_FORMAT_Pos) |
  44. ((initStruct->Format >> 1) << LCD_CR_SEREN_Pos) |
  45. (1 << LCD_CR_BURSTEN_Pos) |
  46. (1 << LCD_CR_BURSTLEN_Pos) |
  47. ((1-initStruct->IntEOTEn) << LCD_CR_AUTORESTA_Pos);
  48. LCDx->CRH = ((initStruct->HsyncWidth - 1) << LCD_CRH_HSW_Pos) |
  49. ((initStruct->Hbp - 1) << LCD_CRH_HBP_Pos) |
  50. ((initStruct->HnPixel - 1) << LCD_CRH_PIX_Pos) |
  51. ((initStruct->Hfp - 1) << LCD_CRH_HFP_Pos);
  52. LCDx->CRV = ((initStruct->VsyncWidth - 1) << LCD_CRV_VSW_Pos) |
  53. ((initStruct->Vbp - 1) << LCD_CRV_VBP_Pos) |
  54. ((initStruct->VnPixel - 1) << LCD_CRV_PIX_Pos) |
  55. ((initStruct->Vfp - 1) << LCD_CRV_VFP_Pos);
  56. LCDx->BGC = initStruct->Background;
  57. LCDx->L[0].LCR = (1 << LCD_LCR_EN_Pos) |
  58. (0 << LCD_LCR_CKEN_Pos) |
  59. (0xFF << LCD_LCR_ALPHA_Pos);
  60. LCDx->L[0].WHP = (0 << LCD_WHP_STA_Pos) |
  61. ((initStruct->HnPixel - 1) << LCD_WHP_STP_Pos);
  62. LCDx->L[0].WVP = (0 << LCD_WVP_STA_Pos) |
  63. ((initStruct->VnPixel - 1) << LCD_WVP_STP_Pos);
  64. LCDx->L[0].ADDR = initStruct->DataSource;
  65. LCDx->L[0].LLEN = (initStruct->HnPixel - 1);
  66. LCDx->IF = 1; //清除标志
  67. LCDx->IE = initStruct->IntEOTEn;
  68. switch((uint32_t)LCDx)
  69. {
  70. case ((uint32_t)LCD):
  71. if(initStruct->IntEOTEn) NVIC_EnableIRQ(LCD_IRQn);
  72. break;
  73. }
  74. }
  75. /******************************************************************************************************************************************
  76. * 函数名称: LCD_LayerInit()
  77. * 功能说明: LCD层初始化
  78. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  79. * uint32_t layerx 要初始化的LCD层,取值LCD_LAYER_1、LCD_LAYER_2
  80. * LCD_LayerInitStructure * initStruct 包含LCD层相关设定值的结构体
  81. * 输 出: 无
  82. * 注意事项: 无
  83. ******************************************************************************************************************************************/
  84. void LCD_LayerInit(LCD_TypeDef * LCDx, uint32_t layerx, LCD_LayerInitStructure * initStruct)
  85. {
  86. LCDx->L[layerx].LCR = (1 << LCD_LCR_EN_Pos) |
  87. (0 << LCD_LCR_CKEN_Pos) |
  88. (initStruct->Alpha << LCD_LCR_ALPHA_Pos);
  89. LCDx->L[layerx].WHP = (initStruct->HStart << LCD_WHP_STA_Pos) |
  90. (initStruct->HStop << LCD_WHP_STP_Pos);
  91. LCDx->L[layerx].WVP = (initStruct->VStart << LCD_WVP_STA_Pos) |
  92. (initStruct->VStop << LCD_WVP_STP_Pos);
  93. LCDx->L[layerx].ADDR = initStruct->DataSource;
  94. LCDx->L[layerx].LLEN = (initStruct->HStop - initStruct->HStart);
  95. LCD->CR |= (1 << LCD_CR_VBPRELOAD_Pos);
  96. }
  97. /******************************************************************************************************************************************
  98. * 函数名称: LCD_SetLayerPos()
  99. * 功能说明: LCD层位置设定
  100. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  101. * uint32_t layerx 要设置的LCD层,取值LCD_LAYER_1、LCD_LAYER_2
  102. * uint16_t hstart, uint16_t hstop, uint16_t vstart, uint16_t vstop,详细说明见 LCD_LayerInitStructure
  103. * 输 出: 无
  104. * 注意事项: 无
  105. ******************************************************************************************************************************************/
  106. void LCD_SetLayerPos(LCD_TypeDef * LCDx, uint32_t layerx, uint16_t hstart, uint16_t hstop, uint16_t vstart, uint16_t vstop)
  107. {
  108. LCDx->L[layerx].WHP = (hstart << LCD_WHP_STA_Pos) |
  109. (hstop << LCD_WHP_STP_Pos);
  110. LCDx->L[layerx].WVP = (vstart << LCD_WVP_STA_Pos) |
  111. (vstop << LCD_WVP_STP_Pos);
  112. LCD->CR |= (1 << LCD_CR_VBPRELOAD_Pos);
  113. }
  114. /******************************************************************************************************************************************
  115. * 函数名称: LCD_Start()
  116. * 功能说明: 启动一次数据传输
  117. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  118. * 输 出: 无
  119. * 注意事项: 无
  120. ******************************************************************************************************************************************/
  121. void LCD_Start(LCD_TypeDef * LCDx)
  122. {
  123. LCDx->START |= (1 << LCD_START_GO_Pos);
  124. }
  125. /******************************************************************************************************************************************
  126. * 函数名称: LCD_IsBusy()
  127. * 功能说明: 是否正在进行数据传输
  128. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  129. * 输 出: uint32_t 1 正在传输数据 0 数据传输已完成
  130. * 注意事项: 无
  131. ******************************************************************************************************************************************/
  132. uint32_t LCD_IsBusy(LCD_TypeDef * LCDx)
  133. {
  134. return (LCDx->START & LCD_START_GO_Msk) ? 1 : 0;
  135. }
  136. /******************************************************************************************************************************************
  137. * 函数名称: LCD_INTEn()
  138. * 功能说明: LCD中断使能,完成指定长度的数据传输时触发中断
  139. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  140. * 输 出: 无
  141. * 注意事项: 无
  142. ******************************************************************************************************************************************/
  143. void LCD_INTEn(LCD_TypeDef * LCDx)
  144. {
  145. LCDx->IE = 1;
  146. }
  147. /******************************************************************************************************************************************
  148. * 函数名称: LCD_INTDis()
  149. * 功能说明: LCD中断禁止,完成指定长度的数据传输时不触发中断
  150. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  151. * 输 出: 无
  152. * 注意事项: 无
  153. ******************************************************************************************************************************************/
  154. void LCD_INTDis(LCD_TypeDef * LCDx)
  155. {
  156. LCDx->IE = 0;
  157. }
  158. /******************************************************************************************************************************************
  159. * 函数名称: LCD_INTClr()
  160. * 功能说明: LCD中断标志清除
  161. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  162. * 输 出: 无
  163. * 注意事项: 无
  164. ******************************************************************************************************************************************/
  165. void LCD_INTClr(LCD_TypeDef * LCDx)
  166. {
  167. LCDx->IF = 1;
  168. }
  169. /******************************************************************************************************************************************
  170. * 函数名称: LCD_INTStat()
  171. * 功能说明: LCD中断状态查询
  172. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  173. * 输 出: uint32_t 0 未完成指定长度的数据传输 非0 完成指定长度的数据传输
  174. * 注意事项: 无
  175. ******************************************************************************************************************************************/
  176. uint32_t LCD_INTStat(LCD_TypeDef * LCDx)
  177. {
  178. return (LCDx->IF & 1);
  179. }
  180. /******************************************************************************************************************************************
  181. * 函数名称: MPULCD_Init()
  182. * 功能说明: MPU LCD初始化
  183. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  184. * MPULCD_InitStructure * initStruct 包含MPU LCD相关设定值的结构体
  185. * 输 出: 无
  186. * 注意事项: 无
  187. ******************************************************************************************************************************************/
  188. void MPULCD_Init(LCD_TypeDef * LCDx, MPULCD_InitStructure * initStruct)
  189. {
  190. switch((uint32_t)LCDx)
  191. {
  192. case ((uint32_t)LCD):
  193. SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_LCD_Pos);
  194. __NOP();__NOP();__NOP();
  195. break;
  196. }
  197. LCDx->CR = (1 << LCD_CR_MPUEN_Pos) |
  198. (LCD_FMT_RGB565 << LCD_CR_FORMAT_Pos); //MPU模式只支持RGB565
  199. LCDx->L[0].LCR |= (1 << LCD_LCR_EN_Pos); //MPU模式下需要使能Layer1
  200. LCDx->MPUCR = ((initStruct->RDHoldTime - 1) << LCD_MPUCR_RDHOLD_Pos) |
  201. ((initStruct->WRHoldTime - 1) << LCD_MPUCR_WRHOLD_Pos) |
  202. ((initStruct->CSFall_WRFall - 1) << LCD_MPUCR_CS0WR0_Pos) |
  203. ((initStruct->WRRise_CSRise - 1) << LCD_MPUCR_WR1CS1_Pos) |
  204. ((initStruct->RDCSRise_Fall - 1) << LCD_MPUCR_RCS1_0_Pos) |
  205. ((initStruct->WRCSRise_Fall - 1) << LCD_MPUCR_WCS1_0_Pos);
  206. }
  207. void LCD_WR_REG(LCD_TypeDef * LCDx, uint16_t reg)
  208. {
  209. LCDx->MPUIR = reg;
  210. while(LCD_IsBusy(LCDx)) __NOP();
  211. }
  212. void LCD_WR_DATA(LCD_TypeDef * LCDx, uint16_t val)
  213. {
  214. LCDx->MPUDR = val;
  215. while(LCD_IsBusy(LCDx)) __NOP();
  216. }
  217. void LCD_WriteReg(LCD_TypeDef * LCDx, uint16_t reg, uint16_t val)
  218. {
  219. LCDx->MPUIR = reg;
  220. while(LCD_IsBusy(LCDx)) __NOP();
  221. LCDx->MPUDR = val;
  222. while(LCD_IsBusy(LCDx)) __NOP();
  223. }
  224. uint16_t LCD_ReadReg(LCD_TypeDef * LCDx, uint16_t reg)
  225. {
  226. LCDx->MPUIR = reg;
  227. while(LCD_IsBusy(LCDx)) __NOP();
  228. return LCDx->MPUDR;
  229. }
  230. /******************************************************************************************************************************************
  231. * 函数名称: MPULCD_DMAStart()
  232. * 功能说明: MPU LCD DMA搬运显示数据
  233. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  234. * uint32_t * buff 要搬运的显示数据
  235. * uint16_t hpix 横向像素数,即每行像素数,必须是偶数
  236. * uint16_t vpix 纵向像素数,即行数
  237. * 输 出: 无
  238. * 注意事项: 无
  239. ******************************************************************************************************************************************/
  240. void MPULCD_DMAStart(LCD_TypeDef * LCDx, uint32_t * buff, uint16_t hpix, uint16_t vpix)
  241. {
  242. LCDx->MPUAR = (uint32_t)buff;
  243. LCDx->MPULEN = ((vpix - 1) << LCD_MPULEN_VPIX_Pos) |
  244. ((hpix - 1) << LCD_MPULEN_HPIX_Pos);
  245. LCDx->START |= (1 << LCD_START_GO_Pos);
  246. }
  247. /******************************************************************************************************************************************
  248. * 函数名称: MPULCD_DMABusy()
  249. * 功能说明: MPU LCD DMA搬运显示数据忙查询
  250. * 输 入: LCD_TypeDef * LCDx 指定要被设置的LCD,有效值包括LCD
  251. * 输 出: uint32_t 1 搬运中 0 搬运完成
  252. * 注意事项: 无
  253. ******************************************************************************************************************************************/
  254. uint32_t MPULCD_DMABusy(LCD_TypeDef * LCDx)
  255. {
  256. return (LCDx->START & LCD_START_GO_Msk) ? 1 : 0;
  257. }