drv_slcd.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2020-11-11 Wayne First version
  10. *
  11. ******************************************************************************/
  12. #include <rtconfig.h>
  13. #if defined(BSP_USING_SLCD)
  14. #include <rtdevice.h>
  15. #include <rthw.h>
  16. #include "NuMicro.h"
  17. #include <drv_slcd.h>
  18. /* Private define ---------------------------------------------------------------*/
  19. #define DBG_ENABLE
  20. #define DBG_LEVEL DBG_LOG
  21. #define DBG_SECTION_NAME "slcd"
  22. #define DBG_COLOR
  23. #include <rtdbg.h>
  24. enum
  25. {
  26. SLCD_START = -1,
  27. SLCD_IDX,
  28. SLCD_CNT
  29. };
  30. #define LCD_ALPHABET_NUM 7
  31. /* Private typedef --------------------------------------------------------------*/
  32. struct nu_slcd
  33. {
  34. struct rt_device dev;
  35. char *name;
  36. LCD_T *base;
  37. uint32_t rst;
  38. rt_mutex_t lock;
  39. };
  40. typedef struct nu_slcd *nu_slcd_t;
  41. /* Private functions ------------------------------------------------------------*/
  42. /* Public functions ------------------------------------------------------------*/
  43. /* Private variables ------------------------------------------------------------*/
  44. static struct nu_slcd nu_slcd_arr [] =
  45. {
  46. {
  47. .name = "slcd",
  48. .base = LCD,
  49. .rst = LCD_RST,
  50. }
  51. }; /* nu_slcd_arr */
  52. static S_LCD_CFG_T g_SLCDCfg =
  53. {
  54. __LXT, /*!< LCD clock source frequency */
  55. LCD_COM_DUTY_1_8, /*!< COM duty */
  56. LCD_BIAS_LV_1_4, /*!< Bias level */
  57. 64, /*!< Operation frame rate */
  58. LCD_WAVEFORM_TYPE_A_NORMAL, /*!< Waveform type */
  59. LCD_DISABLE_ALL_INT, /*!< Interrupt source */
  60. LCD_LOW_DRIVING_AND_BUF_ON, /*!< Driving mode */
  61. LCD_VOLTAGE_SOURCE_VLCD, /*!< Voltage source */
  62. };
  63. static rt_err_t nu_slcd_open(struct rt_device *dev, rt_uint16_t oflag)
  64. {
  65. if (dev->ref_count == 0)
  66. {
  67. nu_slcd_t psNuSLcd = (nu_slcd_t)dev;
  68. /* Reset LCD module */
  69. SYS_ResetModule(psNuSLcd->rst);
  70. uint32_t u32ActiveFPS = LCD_Open(&g_SLCDCfg);
  71. /* LCD Initialize and calculate real frame rate */
  72. LOG_I("Working frame rate is %dHz on Type-%c.\n\n", u32ActiveFPS, (g_SLCDCfg.u32WaveformType == LCD_PCTL_TYPE_Msk) ? 'B' : 'A');
  73. /* Enable LCD display */
  74. LCD_ENABLE_DISPLAY();
  75. }
  76. return RT_EOK;
  77. }
  78. static rt_err_t nu_slcd_close(struct rt_device *dev)
  79. {
  80. if (dev->ref_count == 0)
  81. {
  82. /* Disable LCD display */
  83. LCD_DISABLE_DISPLAY();
  84. }
  85. return RT_EOK;
  86. }
  87. static rt_size_t nu_slcd_write(struct rt_device *dev,
  88. rt_off_t pos,
  89. const void *buffer,
  90. rt_size_t size)
  91. {
  92. nu_slcd_pixel_t psSlcdPixel;
  93. nu_slcd_t psNuSLCD = (nu_slcd_t)dev;
  94. RT_ASSERT(buffer != RT_NULL);
  95. RT_ASSERT(size == sizeof(struct nu_slcd_pixel));
  96. psSlcdPixel = (nu_slcd_pixel_t)buffer;
  97. /* Critical section */
  98. rt_mutex_take(psNuSLCD->lock, RT_WAITING_FOREVER);
  99. LCD_SetPixel(psSlcdPixel->m_u32Com, psSlcdPixel->m_u32Seg, psSlcdPixel->m_u32OnFlag);
  100. rt_mutex_release(psNuSLCD->lock);
  101. return size;
  102. }
  103. static rt_err_t nu_slcd_control(struct rt_device *dev,
  104. int cmd,
  105. void *args)
  106. {
  107. rt_err_t ret = RT_EOK;
  108. switch (cmd)
  109. {
  110. case NU_SLCD_CMD_SET_LCD_CFG:
  111. {
  112. S_LCD_CFG_T *psLCDCfg;
  113. RT_ASSERT(args != RT_NULL);
  114. psLCDCfg = (S_LCD_CFG_T *)args;
  115. rt_memcpy((void *)&g_SLCDCfg, (void *)psLCDCfg, sizeof(S_LCD_CFG_T));
  116. }
  117. break;
  118. case NU_SLCD_CMD_SET_CP_VOLTAGE:
  119. {
  120. /*
  121. LCD_CP_VOLTAGE_LV_0 2.6 V
  122. LCD_CP_VOLTAGE_LV_1 2.8 V
  123. LCD_CP_VOLTAGE_LV_2 3.0 V
  124. LCD_CP_VOLTAGE_LV_3 3.2 V
  125. LCD_CP_VOLTAGE_LV_4 3.4 V
  126. LCD_CP_VOLTAGE_LV_5 3.6 V
  127. */
  128. uint32_t u32CPVol;
  129. RT_ASSERT(args != RT_NULL);
  130. u32CPVol = *((uint32_t *)args) ;
  131. if ((u32CPVol >> LCD_PCTL_CPVSEL_Pos) <= (LCD_CP_VOLTAGE_LV_5 >> LCD_PCTL_CPVSEL_Pos))
  132. {
  133. LCD_SET_CP_VOLTAGE(u32CPVol);
  134. }
  135. else
  136. {
  137. ret = -RT_ERROR;
  138. }
  139. }
  140. break;
  141. default:
  142. return -RT_EINVAL;
  143. }
  144. return ret;
  145. }
  146. #ifdef RT_USING_DEVICE_OPS
  147. const static struct rt_device_ops slcd_ops =
  148. {
  149. RT_NULL,
  150. nu_slcd_open,
  151. nu_slcd_close,
  152. RT_NULL,
  153. nu_slcd_write,
  154. nu_slcd_control
  155. };
  156. #endif
  157. rt_err_t rt_hw_slcd_register(struct rt_device *device,
  158. const char *name,
  159. rt_uint32_t flag,
  160. void *data)
  161. {
  162. RT_ASSERT(device != RT_NULL);
  163. device->type = RT_Device_Class_Char;
  164. device->rx_indicate = RT_NULL;
  165. device->tx_complete = RT_NULL;
  166. #ifdef RT_USING_DEVICE_OPS
  167. device->ops = &slcd_ops;
  168. #else
  169. device->init = RT_NULL;
  170. device->open = nu_slcd_open;
  171. device->close = nu_slcd_close;
  172. device->read = RT_NULL;
  173. device->write = nu_slcd_write;
  174. device->control = nu_slcd_control;
  175. #endif
  176. device->user_data = data;
  177. /* register a character device */
  178. return rt_device_register(device, name, flag);
  179. }
  180. /**
  181. * Hardware SLCD Initialization
  182. */
  183. static int rt_hw_slcd_init(void)
  184. {
  185. int i;
  186. rt_err_t ret = RT_EOK;
  187. for (i = (SLCD_START + 1); i < SLCD_CNT; i++)
  188. {
  189. ret = rt_hw_slcd_register(&nu_slcd_arr[i].dev, nu_slcd_arr[i].name, RT_DEVICE_FLAG_RDWR, NULL);
  190. RT_ASSERT(ret == RT_EOK);
  191. nu_slcd_arr[i].lock = rt_mutex_create(nu_slcd_arr[i].name, RT_IPC_FLAG_PRIO);
  192. RT_ASSERT(nu_slcd_arr[i].lock != RT_NULL);
  193. }
  194. return (int)ret;
  195. }
  196. INIT_DEVICE_EXPORT(rt_hw_slcd_init);
  197. #endif //#if defined(BSP_USING_SLCD)