st7735.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088
  1. /**
  2. ******************************************************************************
  3. * @file st7735.c
  4. * @author MCD Application Team
  5. * @brief This file includes the driver for ST7735 LCD mounted on the Adafruit
  6. * 1.8" TFT LCD shield (reference ID 802).
  7. ******************************************************************************
  8. * @attention
  9. *
  10. * <h2><center>&copy; Copyright (c) 2018 STMicroelectronics.
  11. * All rights reserved.</center></h2>
  12. *
  13. * This software component is licensed by ST under BSD 3-Clause license,
  14. * the "License"; You may not use this file except in compliance with the
  15. * License. You may obtain a copy of the License at:
  16. * opensource.org/licenses/BSD-3-Clause
  17. *
  18. ******************************************************************************
  19. */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include <rtthread.h>
  22. #include <rtdevice.h>
  23. #include <board.h>
  24. #include "st7735.h"
  25. #define DRV_DEBUG
  26. #define LOG_TAG "st7735"
  27. #include <drv_log.h>
  28. #define IS_BOE_PANEL (0)
  29. /** @addtogroup BSP
  30. * @{
  31. */
  32. /** @addtogroup Components
  33. * @{
  34. */
  35. /** @addtogroup ST7735
  36. * @brief This file provides a set of functions needed to drive the
  37. * ST7735 LCD.
  38. * @{
  39. */
  40. /** @defgroup ST7735_Private_Types Private Types
  41. * @{
  42. */
  43. typedef struct
  44. {
  45. uint32_t Width;
  46. uint32_t Height;
  47. uint32_t Orientation;
  48. } ST7735_Ctx_t;
  49. /**
  50. * @}
  51. */
  52. /** @defgroup ST7735_Private_Variables Private Variables
  53. * @{
  54. */
  55. ST7735_LCD_Drv_t ST7735_LCD_Driver =
  56. {
  57. ST7735_Init,
  58. ST7735_DeInit,
  59. ST7735_ReadID,
  60. ST7735_DisplayOn,
  61. ST7735_DisplayOff,
  62. ST7735_SetBrightness,
  63. ST7735_GetBrightness,
  64. ST7735_SetOrientation,
  65. ST7735_GetOrientation,
  66. ST7735_SetCursor,
  67. ST7735_DrawBitmap,
  68. ST7735_FillRGBRect,
  69. ST7735_DrawHLine,
  70. ST7735_DrawVLine,
  71. ST7735_FillRect,
  72. ST7735_GetPixel,
  73. ST7735_SetPixel,
  74. ST7735_GetXSize,
  75. ST7735_GetYSize,
  76. };
  77. /* The below table handle the different values to be set to Memory Data Access Control
  78. depending on the orientation and pbm image writing where the data order is inverted
  79. */
  80. static uint32_t OrientationTab[4][2] =
  81. {
  82. {0x48U , 0xC8U}, /* Portrait orientation choice of LCD screen */
  83. {0x88U , 0x08U}, /* Portrait rotated 180° orientation choice of LCD screen */
  84. {0x28U , 0x68U}, /* Landscape orientation choice of LCD screen */
  85. {0xE8U , 0xA8U} /* Landscape rotated 180° orientation choice of LCD screen */
  86. };
  87. static ST7735_Ctx_t ST7735Ctx;
  88. /**
  89. * @}
  90. */
  91. /** @defgroup ST7735_Private_FunctionsPrototypes Private Functions Prototypes
  92. * @{
  93. */
  94. static int32_t ST7735_SetDisplayWindow(ST7735_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t Width, uint32_t Height);
  95. static int32_t ST7735_ReadRegWrap(void *Handle, uint8_t Reg, uint8_t* pData);
  96. static int32_t ST7735_WriteRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint32_t Length);
  97. static int32_t ST7735_SendDataWrap(void *Handle, uint8_t *pData, uint32_t Length);
  98. static int32_t ST7735_RecvDataWrap(void *Handle, uint8_t *pData, uint32_t Length);
  99. static int32_t ST7735_IO_Delay(ST7735_Object_t *pObj, uint32_t Delay);
  100. /**
  101. * @}
  102. */
  103. /** @addtogroup ST7735_Exported_Functions
  104. * @{
  105. */
  106. /**
  107. * @brief Register component IO bus
  108. * @param pObj Component object pointer
  109. * @param pIO Component IO structure pointer
  110. * @retval Component status
  111. */
  112. int32_t ST7735_RegisterBusIO (ST7735_Object_t *pObj, ST7735_IO_t *pIO)
  113. {
  114. int32_t ret;
  115. if(pObj == NULL)
  116. {
  117. ret = ST7735_ERROR;
  118. }
  119. else
  120. {
  121. pObj->IO.Init = pIO->Init;
  122. pObj->IO.DeInit = pIO->DeInit;
  123. pObj->IO.Address = pIO->Address;
  124. pObj->IO.WriteReg = pIO->WriteReg;
  125. pObj->IO.ReadReg = pIO->ReadReg;
  126. pObj->IO.SendData = pIO->SendData;
  127. pObj->IO.RecvData = pIO->RecvData;
  128. pObj->IO.GetTick = pIO->GetTick;
  129. pObj->Ctx.ReadReg = ST7735_ReadRegWrap;
  130. pObj->Ctx.WriteReg = ST7735_WriteRegWrap;
  131. pObj->Ctx.SendData = ST7735_SendDataWrap;
  132. pObj->Ctx.RecvData = ST7735_RecvDataWrap;
  133. pObj->Ctx.handle = pObj;
  134. if(pObj->IO.Init != NULL)
  135. {
  136. ret = pObj->IO.Init();
  137. }
  138. else
  139. {
  140. ret = ST7735_ERROR;
  141. }
  142. }
  143. return ret;
  144. }
  145. /**
  146. * @brief Initialize the st7735 LCD Component.
  147. * @param pObj Component object
  148. * @param ColorCoding RGB mode
  149. * @param Orientation Display orientation
  150. * @retval Component status
  151. */
  152. int32_t ST7735_Init(ST7735_Object_t *pObj, uint32_t ColorCoding, uint32_t Orientation)
  153. {
  154. uint8_t tmp;
  155. int32_t ret;
  156. if(pObj == NULL)
  157. {
  158. ret = ST7735_ERROR;
  159. }
  160. else
  161. {
  162. /* Out of sleep mode, 0 args, delay 120ms */
  163. tmp = 0x00U;
  164. ret = st7735_write_reg(&pObj->Ctx, ST7735_SW_RESET, &tmp, 0);
  165. (void)ST7735_IO_Delay(pObj, 120);
  166. /* Out of sleep mode, 0 args, no delay */
  167. tmp = 0x00U;
  168. ret += st7735_write_reg(&pObj->Ctx, ST7735_SLEEP_OUT, &tmp, 1);
  169. /* Frame rate ctrl - normal mode, 3 args:Rate = fosc/(1x2+40) * (LINE+2C+2D)*/
  170. ret += st7735_write_reg(&pObj->Ctx, ST7735_FRAME_RATE_CTRL1, &tmp, 0);
  171. tmp = 0x01U;
  172. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  173. tmp = 0x2CU;
  174. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  175. tmp = 0x2DU;
  176. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  177. /* Frame rate control - idle mode, 3 args:Rate = fosc/(1x2+40) * (LINE+2C+2D) */
  178. tmp = 0x01U;
  179. ret += st7735_write_reg(&pObj->Ctx, ST7735_FRAME_RATE_CTRL2, &tmp, 1);
  180. tmp = 0x2CU;
  181. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  182. tmp = 0x2DU;
  183. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  184. /* Frame rate ctrl - partial mode, 6 args: Dot inversion mode, Line inversion mode */
  185. tmp = 0x01U;
  186. ret += st7735_write_reg(&pObj->Ctx, ST7735_FRAME_RATE_CTRL3, &tmp, 1);
  187. tmp = 0x2CU;
  188. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  189. tmp = 0x2DU;
  190. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  191. tmp = 0x01U;
  192. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  193. tmp = 0x2CU;
  194. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  195. tmp = 0x2DU;
  196. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  197. /* Display inversion ctrl, 1 arg, no delay: No inversion */
  198. tmp = 0x07U;
  199. ret += st7735_write_reg(&pObj->Ctx, ST7735_FRAME_INVERSION_CTRL, &tmp, 1);
  200. /* Power control, 3 args, no delay: -4.6V , AUTO mode */
  201. tmp = 0xA2U;
  202. ret += st7735_write_reg(&pObj->Ctx, ST7735_PWR_CTRL1, &tmp, 1);
  203. tmp = 0x02U;
  204. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  205. tmp = 0x84U;
  206. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  207. /* Power control, 1 arg, no delay: VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD */
  208. tmp = 0xC5U;
  209. ret += st7735_write_reg(&pObj->Ctx, ST7735_PWR_CTRL2, &tmp, 1);
  210. /* Power control, 2 args, no delay: Opamp current small, Boost frequency */
  211. tmp = 0x0AU;
  212. ret += st7735_write_reg(&pObj->Ctx, ST7735_PWR_CTRL3, &tmp, 1);
  213. tmp = 0x00U;
  214. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  215. /* Power control, 2 args, no delay: BCLK/2, Opamp current small & Medium low */
  216. tmp = 0x8AU;
  217. ret += st7735_write_reg(&pObj->Ctx, ST7735_PWR_CTRL4, &tmp, 1);
  218. tmp = 0x2AU;
  219. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  220. /* Power control, 2 args, no delay */
  221. tmp = 0x8AU;
  222. ret += st7735_write_reg(&pObj->Ctx, ST7735_PWR_CTRL5, &tmp, 1);
  223. tmp = 0xEEU;
  224. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  225. /* Power control, 1 arg, no delay */
  226. tmp = 0x0EU;
  227. ret += st7735_write_reg(&pObj->Ctx, ST7735_VCOMH_VCOML_CTRL1, &tmp, 1);
  228. #if IS_BOE_PANEL
  229. /* Not Invert display, no args, no delay */
  230. ret += st7735_write_reg(&pObj->Ctx, ST7735_DISPLAY_INVERSION_OFF, &tmp, 0);
  231. #else
  232. /* Invert display, no args, no delay */
  233. ret += st7735_write_reg(&pObj->Ctx, ST7735_DISPLAY_INVERSION_ON, &tmp, 0);
  234. #endif
  235. /* Set color mode, 1 arg, no delay */
  236. ret += st7735_write_reg(&pObj->Ctx, ST7735_COLOR_MODE, (uint8_t*)&ColorCoding, 1);
  237. /* Magical unicorn dust, 16 args, no delay */
  238. tmp = 0x02U;
  239. ret += st7735_write_reg(&pObj->Ctx, ST7735_PV_GAMMA_CTRL, &tmp, 1);
  240. tmp = 0x1CU;
  241. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  242. tmp = 0x07U;
  243. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  244. tmp = 0x12U;
  245. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  246. tmp = 0x37U;
  247. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  248. tmp = 0x32U;
  249. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  250. tmp = 0x29U;
  251. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  252. tmp = 0x2DU;
  253. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  254. tmp = 0x29U;
  255. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  256. tmp = 0x25U;
  257. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  258. tmp = 0x2BU;
  259. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  260. tmp = 0x39U;
  261. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  262. tmp = 0x00U;
  263. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  264. tmp = 0x01U;
  265. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  266. tmp = 0x03U;
  267. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  268. tmp = 0x10U;
  269. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  270. /* Sparkles and rainbows, 16 args, no delay */
  271. tmp = 0x03U;
  272. ret += st7735_write_reg(&pObj->Ctx, ST7735_NV_GAMMA_CTRL, &tmp, 1);
  273. tmp = 0x1DU;
  274. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  275. tmp = 0x07U;
  276. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  277. tmp = 0x06U;
  278. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  279. tmp = 0x2EU;
  280. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  281. tmp = 0x2CU;
  282. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  283. tmp = 0x29U;
  284. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  285. tmp = 0x2DU;
  286. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  287. tmp = 0x2EU;
  288. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  289. tmp = 0x2EU;
  290. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  291. tmp = 0x37U;
  292. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  293. tmp = 0x3FU;
  294. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  295. tmp = 0x00U;
  296. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  297. tmp = 0x00U;
  298. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  299. tmp = 0x02U;
  300. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  301. tmp = 0x10U;
  302. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  303. /* Normal display on, no args, no delay */
  304. tmp = 0x00U;
  305. ret += st7735_write_reg(&pObj->Ctx, ST7735_NORMAL_DISPLAY_OFF, &tmp, 1);
  306. /* Main screen turn on, no delay */
  307. ret += st7735_write_reg(&pObj->Ctx, ST7735_DISPLAY_ON, &tmp, 1);
  308. /* Set the display Orientation and the default display window */
  309. ret += ST7735_SetOrientation(pObj, Orientation);
  310. }
  311. if(ret != ST7735_OK)
  312. {
  313. LOG_E("error %d", ret);
  314. ret = ST7735_ERROR;
  315. }
  316. return ret;
  317. }
  318. /**
  319. * @brief De-Initialize the st7735 LCD Component.
  320. * @param pObj Component object
  321. * @retval Component status
  322. */
  323. int32_t ST7735_DeInit(ST7735_Object_t *pObj)
  324. {
  325. (void)(pObj);
  326. return ST7735_OK;
  327. }
  328. /**
  329. * @brief Get the st7735 ID.
  330. * @param pObj Component object
  331. * @param Id Component ID
  332. * @retval The component status
  333. */
  334. int32_t ST7735_ReadID(ST7735_Object_t *pObj, uint32_t *Id)
  335. {
  336. int32_t ret;
  337. uint8_t tmp[3];
  338. if(st7735_read_reg(&pObj->Ctx, ST7735_READ_ID1, &tmp[0]) != ST7735_OK)
  339. {
  340. ret = ST7735_ERROR;
  341. }
  342. else if(st7735_read_reg(&pObj->Ctx, ST7735_READ_ID2, &tmp[1]) != ST7735_OK)
  343. {
  344. ret = ST7735_ERROR;
  345. }
  346. else if(st7735_read_reg(&pObj->Ctx, ST7735_READ_ID3, &tmp[2]) != ST7735_OK)
  347. {
  348. ret = ST7735_ERROR;
  349. }
  350. else
  351. {
  352. *Id = ((uint32_t)tmp[2])<<0| ((uint32_t)tmp[1])<<8 | ((uint32_t)tmp[0])<<16;
  353. //*Id = __rbit(*Id);
  354. ret = ST7735_OK;
  355. }
  356. return ret;
  357. }
  358. /**
  359. * @brief Enables the Display.
  360. * @param pObj Component object
  361. * @retval The component status
  362. */
  363. int32_t ST7735_DisplayOn(ST7735_Object_t *pObj)
  364. {
  365. int32_t ret;
  366. uint8_t tmp = 0;
  367. ret = st7735_write_reg(&pObj->Ctx, ST7735_NORMAL_DISPLAY_OFF, &tmp, 0);
  368. (void)ST7735_IO_Delay(pObj, 10);
  369. ret += st7735_write_reg(&pObj->Ctx, ST7735_DISPLAY_ON, &tmp, 0);
  370. (void)ST7735_IO_Delay(pObj, 10);
  371. ret += st7735_write_reg(&pObj->Ctx, ST7735_MADCTL, &tmp, 0);
  372. tmp = (uint8_t)OrientationTab[ST7735Ctx.Orientation][1];
  373. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  374. if(ret != ST7735_OK)
  375. {
  376. ret = ST7735_ERROR;
  377. }
  378. return ret;
  379. }
  380. /**
  381. * @brief Disables the Display.
  382. * @param pObj Component object
  383. * @retval The component status
  384. */
  385. int32_t ST7735_DisplayOff(ST7735_Object_t *pObj)
  386. {
  387. int32_t ret;
  388. uint8_t tmp = 0;
  389. ret = st7735_write_reg(&pObj->Ctx, ST7735_NORMAL_DISPLAY_OFF, &tmp, 0);
  390. (void)ST7735_IO_Delay(pObj, 10);
  391. ret += st7735_write_reg(&pObj->Ctx, ST7735_DISPLAY_OFF, &tmp, 0);
  392. (void)ST7735_IO_Delay(pObj, 10);
  393. ret += st7735_write_reg(&pObj->Ctx, ST7735_MADCTL, &tmp, 0);
  394. tmp = (uint8_t)OrientationTab[ST7735Ctx.Orientation][1];
  395. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  396. if(ret != ST7735_OK)
  397. {
  398. ret = ST7735_ERROR;
  399. }
  400. return ret;
  401. }
  402. /**
  403. * @brief Set the display brightness.
  404. * @param pObj Component object
  405. * @param Brightness display brightness to be set
  406. * @retval Component status
  407. */
  408. int32_t ST7735_SetBrightness(ST7735_Object_t *pObj, uint32_t Brightness)
  409. {
  410. (void)(pObj);
  411. (void)(Brightness);
  412. /* Feature not supported */
  413. return ST7735_ERROR;
  414. }
  415. /**
  416. * @brief Get the display brightness.
  417. * @param pObj Component object
  418. * @param Brightness display brightness to be returned
  419. * @retval Component status
  420. */
  421. int32_t ST7735_GetBrightness(ST7735_Object_t *pObj, uint32_t *Brightness)
  422. {
  423. (void)(pObj);
  424. (void)(Brightness);
  425. /* Feature not supported */
  426. return ST7735_ERROR;
  427. }
  428. /**
  429. * @brief Set the Display Orientation.
  430. * @param pObj Component object
  431. * @param Orientation ST7735_ORIENTATION_PORTRAIT, ST7735_ORIENTATION_PORTRAIT_ROT180
  432. * ST7735_ORIENTATION_LANDSCAPE or ST7735_ORIENTATION_LANDSCAPE_ROT180
  433. * @retval The component status
  434. */
  435. int32_t ST7735_SetOrientation(ST7735_Object_t *pObj, uint32_t Orientation)
  436. {
  437. int32_t ret;
  438. uint8_t tmp;
  439. if((Orientation == ST7735_ORIENTATION_PORTRAIT) || (Orientation == ST7735_ORIENTATION_PORTRAIT_ROT180))
  440. {
  441. ST7735Ctx.Width = ST7735_WIDTH;
  442. ST7735Ctx.Height = ST7735_HEIGHT;
  443. }
  444. else
  445. {
  446. ST7735Ctx.Width = ST7735_HEIGHT;
  447. ST7735Ctx.Height = ST7735_WIDTH;
  448. }
  449. ST7735Ctx.Orientation = Orientation;
  450. ret = ST7735_SetDisplayWindow(pObj, 0U, 0U, ST7735Ctx.Width, ST7735Ctx.Height);
  451. tmp = (uint8_t)OrientationTab[Orientation][1];
  452. ret += st7735_write_reg(&pObj->Ctx, ST7735_MADCTL, &tmp, 1);
  453. if(ret != ST7735_OK)
  454. {
  455. ret = ST7735_ERROR;
  456. }
  457. return ret;
  458. }
  459. /**
  460. * @brief Set the Display Orientation.
  461. * @param pObj Component object
  462. * @param Orientation ST7735_ORIENTATION_PORTRAIT, ST7735_ORIENTATION_LANDSCAPE
  463. * or ST7735_ORIENTATION_LANDSCAPE_ROT180
  464. * @retval The component status
  465. */
  466. int32_t ST7735_GetOrientation(ST7735_Object_t *pObj, uint32_t *Orientation)
  467. {
  468. *Orientation = ST7735Ctx.Orientation;
  469. return ST7735_OK;
  470. }
  471. /**
  472. * @brief Set Cursor position.
  473. * @param pObj Component object
  474. * @param Xpos specifies the X position.
  475. * @param Ypos specifies the Y position.
  476. * @retval The component status
  477. */
  478. int32_t ST7735_SetCursor(ST7735_Object_t *pObj, uint32_t Xpos, uint32_t Ypos)
  479. {
  480. int32_t ret;
  481. uint8_t tmp;
  482. /* Cursor calibration */
  483. if(ST7735Ctx.Orientation <= ST7735_ORIENTATION_PORTRAIT_ROT180)
  484. {
  485. #if IS_BOE_PANEL
  486. Xpos += 24;
  487. Ypos += 0;
  488. #else
  489. Xpos += 26;
  490. Ypos += 1;
  491. #endif
  492. }
  493. else
  494. {
  495. #if IS_BOE_PANEL
  496. Xpos += 0;
  497. Ypos += 24;
  498. #else
  499. Xpos += 1;
  500. Ypos += 26;
  501. #endif
  502. }
  503. ret = st7735_write_reg(&pObj->Ctx, ST7735_CASET, &tmp, 0);
  504. tmp = (uint8_t)(Xpos >> 8U);
  505. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  506. tmp = (uint8_t)(Xpos & 0xFFU);
  507. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  508. ret += st7735_write_reg(&pObj->Ctx, ST7735_RASET, &tmp, 0);
  509. tmp = (uint8_t)(Ypos >> 8U);
  510. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  511. tmp = (uint8_t)(Ypos & 0xFFU);
  512. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  513. ret += st7735_write_reg(&pObj->Ctx, ST7735_WRITE_RAM, &tmp, 0);
  514. if(ret != ST7735_OK)
  515. {
  516. ret = ST7735_ERROR;
  517. }
  518. return ret;
  519. }
  520. /**
  521. * @brief Displays a bitmap picture.
  522. * @param pObj Component object
  523. * @param Xpos Bmp X position in the LCD
  524. * @param Ypos Bmp Y position in the LCD
  525. * @param pBmp Bmp picture address.
  526. * @retval The component status
  527. */
  528. int32_t ST7735_DrawBitmap(ST7735_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint8_t *pBmp)
  529. {
  530. int32_t ret = ST7735_OK;
  531. uint32_t index, size, width, height, y_pos;
  532. uint8_t pixel_val[2], tmp;
  533. uint8_t *pbmp;
  534. uint32_t counter = 0;
  535. /* Get bitmap data address offset */
  536. index = (uint32_t)pBmp[10] + ((uint32_t)pBmp[11] << 8) + ((uint32_t)pBmp[12] << 16) + ((uint32_t)pBmp[13] << 24);
  537. /* Read bitmap width */
  538. width = (uint32_t)pBmp[18] + ((uint32_t)pBmp[19] << 8) + ((uint32_t)pBmp[20] << 16) + ((uint32_t)pBmp[21] << 24);
  539. /* Read bitmap height */
  540. height = (uint32_t)pBmp[22] + ((uint32_t)pBmp[23] << 8) + ((uint32_t)pBmp[24] << 16) + ((uint32_t)pBmp[25] << 24);
  541. /* Read bitmap size */
  542. size = (uint32_t)pBmp[2] + ((uint32_t)pBmp[3] << 8) + ((uint32_t)pBmp[4] << 16) + ((uint32_t)pBmp[5] << 24);
  543. size = size - index;
  544. pbmp = pBmp + index;
  545. /* Remap Ypos, st7735 works with inverted X in case of bitmap */
  546. /* X = 0, cursor is on Top corner */
  547. y_pos = ST7735Ctx.Height - Ypos - height;
  548. if(ST7735_SetDisplayWindow(pObj, Xpos, y_pos, width, height) != ST7735_OK)
  549. {
  550. ret = ST7735_ERROR;
  551. }
  552. else
  553. {
  554. /* Set GRAM write direction and BGR = 0 */
  555. tmp = (uint8_t)OrientationTab[ST7735Ctx.Orientation][0];
  556. if(st7735_write_reg(&pObj->Ctx, ST7735_MADCTL, &tmp, 1) != ST7735_OK)
  557. {
  558. ret = ST7735_ERROR;
  559. }/* Set Cursor */
  560. else if(ST7735_SetCursor(pObj, Xpos, y_pos) != ST7735_OK)
  561. {
  562. ret = ST7735_ERROR;
  563. }
  564. else
  565. {
  566. do
  567. {
  568. pixel_val[0] = *(pbmp + 1);
  569. pixel_val[1] = *(pbmp);
  570. if(st7735_send_data(&pObj->Ctx, pixel_val, 2U) != ST7735_OK)
  571. {
  572. ret = ST7735_ERROR;
  573. break;
  574. }
  575. counter +=2U;
  576. pbmp += 2;
  577. }while(counter < size);
  578. tmp = (uint8_t)OrientationTab[ST7735Ctx.Orientation][1];
  579. if(st7735_write_reg(&pObj->Ctx, ST7735_MADCTL, &tmp, 1) != ST7735_OK)
  580. {
  581. ret = ST7735_ERROR;
  582. }
  583. else
  584. {
  585. if(ST7735_SetDisplayWindow(pObj, 0U, 0U, ST7735Ctx.Width, ST7735Ctx.Height) != ST7735_OK)
  586. {
  587. ret = ST7735_ERROR;
  588. }
  589. }
  590. }
  591. }
  592. return ret;
  593. }
  594. /**
  595. * @brief Draws a full RGB rectangle
  596. * @param pObj Component object
  597. * @param Xpos specifies the X position.
  598. * @param Ypos specifies the Y position.
  599. * @param pData pointer to RGB data
  600. * @param Width specifies the rectangle width.
  601. * @param Height Specifies the rectangle height
  602. * @retval The component status
  603. */
  604. int32_t ST7735_FillRGBRect(ST7735_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint8_t *pData, uint32_t Width, uint32_t Height)
  605. {
  606. int32_t ret = ST7735_OK;
  607. static uint8_t pdata[640];
  608. uint8_t *rgb_data = pData;
  609. uint32_t i, j;
  610. if(((Xpos + Width) > ST7735Ctx.Width) || ((Ypos + Height) > ST7735Ctx.Height))
  611. {
  612. ret = ST7735_ERROR;
  613. }/* Set Cursor */
  614. else
  615. {
  616. for(j = 0; j < Height; j++)
  617. {
  618. if(ST7735_SetCursor(pObj, Xpos, Ypos+j) != ST7735_OK)
  619. {
  620. ret = ST7735_ERROR;
  621. }
  622. else
  623. {
  624. for(i = 0; i < Width; i++)
  625. {
  626. pdata[2U*i] = (uint8_t)(*(rgb_data));
  627. pdata[(2U*i) + 1U] = (uint8_t)(*(rgb_data + 1));
  628. rgb_data +=2;
  629. }
  630. if(st7735_send_data(&pObj->Ctx, (uint8_t*)&pdata[0], 2U*Width) != ST7735_OK)
  631. {
  632. ret = ST7735_ERROR;
  633. }
  634. }
  635. }
  636. }
  637. return ret;
  638. }
  639. /**
  640. * @brief Draw Horizontal line.
  641. * @param pObj Component object
  642. * @param Xpos specifies the X position.
  643. * @param Ypos specifies the Y position.
  644. * @param Length specifies the Line length.
  645. * @param Color Specifies the RGB color in RGB565 format
  646. * @retval The component status
  647. */
  648. int32_t ST7735_DrawHLine(ST7735_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t Length, uint32_t Color)
  649. {
  650. int32_t ret = ST7735_OK;
  651. uint32_t i;
  652. static uint8_t pdata[640];
  653. if((Xpos + Length) > ST7735Ctx.Width)
  654. {
  655. ret = ST7735_ERROR;
  656. }/* Set Cursor */
  657. else if(ST7735_SetCursor(pObj, Xpos, Ypos) != ST7735_OK)
  658. {
  659. ret = ST7735_ERROR;
  660. }
  661. else
  662. {
  663. for(i = 0; i < Length; i++)
  664. {
  665. /* Exchange LSB and MSB to fit LCD specification */
  666. pdata[2U*i] = (uint8_t)(Color >> 8);
  667. pdata[(2U*i) + 1U] = (uint8_t)(Color);
  668. // pdata[(2U*i) + 1U] = (uint8_t)(Color >> 8);
  669. // pdata[2U*i] = (uint8_t)(Color);
  670. }
  671. if(st7735_send_data(&pObj->Ctx, (uint8_t*)&pdata[0], 2U*Length) != ST7735_OK)
  672. {
  673. ret = ST7735_ERROR;
  674. }
  675. }
  676. return ret;
  677. }
  678. /**
  679. * @brief Draw vertical line.
  680. * @param pObj Component object
  681. * @param Color Specifies the RGB color
  682. * @param Xpos specifies the X position.
  683. * @param Ypos specifies the Y position.
  684. * @param Length specifies the Line length.
  685. * @retval The component status
  686. */
  687. int32_t ST7735_DrawVLine(ST7735_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t Length, uint32_t Color)
  688. {
  689. int32_t ret = ST7735_OK;
  690. uint32_t counter;
  691. if((Ypos + Length) > ST7735Ctx.Height)
  692. {
  693. ret = ST7735_ERROR;
  694. }
  695. else
  696. {
  697. for(counter = 0; counter < Length; counter++)
  698. {
  699. if(ST7735_SetPixel(pObj, Xpos, Ypos + counter, Color) != ST7735_OK)
  700. {
  701. ret = ST7735_ERROR;
  702. break;
  703. }
  704. }
  705. }
  706. return ret;
  707. }
  708. /**
  709. * @brief Fill rectangle
  710. * @param pObj Component object
  711. * @param Xpos X position
  712. * @param Ypos Y position
  713. * @param Width Rectangle width
  714. * @param Height Rectangle height
  715. * @param Color Draw color
  716. * @retval Component status
  717. */
  718. int32_t ST7735_FillRect(ST7735_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t Width, uint32_t Height, uint32_t Color)
  719. {
  720. int32_t ret = ST7735_OK;
  721. uint32_t i, y_pos = Ypos;
  722. for(i = 0; i < Height; i++)
  723. {
  724. if(ST7735_DrawHLine(pObj, Xpos, y_pos, Width, Color) != ST7735_OK)
  725. {
  726. ret = ST7735_ERROR;
  727. break;
  728. }
  729. y_pos++;
  730. }
  731. return ret;
  732. }
  733. /**
  734. * @brief Write pixel.
  735. * @param pObj Component object
  736. * @param Xpos specifies the X position.
  737. * @param Ypos specifies the Y position.
  738. * @param Color the RGB pixel color in RGB565 format
  739. * @retval The component status
  740. */
  741. int32_t ST7735_SetPixel(ST7735_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t Color)
  742. {
  743. int32_t ret = ST7735_OK;
  744. uint16_t color;
  745. /* Exchange LSB and MSB to fit LCD specification */
  746. color = (uint16_t)((uint16_t)Color << 8);
  747. color |= (uint16_t)((uint16_t)(Color >> 8));
  748. if((Xpos >= ST7735Ctx.Width) || (Ypos >= ST7735Ctx.Height))
  749. {
  750. ret = ST7735_ERROR;
  751. }/* Set Cursor */
  752. else if(ST7735_SetCursor(pObj, Xpos, Ypos) != ST7735_OK)
  753. {
  754. ret = ST7735_ERROR;
  755. }
  756. else
  757. {
  758. /* Write RAM data */
  759. if(st7735_send_data(&pObj->Ctx, (uint8_t*)&color, 2) != ST7735_OK)
  760. {
  761. ret = ST7735_ERROR;
  762. }
  763. }
  764. return ret;
  765. }
  766. /**
  767. * @brief Read pixel.
  768. * @param pObj Component object
  769. * @param Xpos specifies the X position.
  770. * @param Ypos specifies the Y position.
  771. * @param Color the RGB pixel color in RGB565 format
  772. * @retval The component status
  773. */
  774. int32_t ST7735_GetPixel(ST7735_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t *Color)
  775. {
  776. int32_t ret;
  777. uint8_t pixel_lsb, pixel_msb;
  778. uint8_t tmp;
  779. /* Set Cursor */
  780. ret = ST7735_SetCursor(pObj, Xpos, Ypos);
  781. /* Prepare to read LCD RAM */
  782. ret += st7735_read_reg(&pObj->Ctx, ST7735_READ_RAM, &tmp); /* RAM read data command */
  783. /* Dummy read */
  784. ret += st7735_recv_data(&pObj->Ctx, &tmp, 1);
  785. /* Read first part of the RGB888 data */
  786. ret += st7735_recv_data(&pObj->Ctx, &pixel_lsb, 1);
  787. /* Read first part of the RGB888 data */
  788. ret += st7735_recv_data(&pObj->Ctx, &pixel_msb, 1);
  789. *Color = ((uint32_t)(pixel_lsb)) + ((uint32_t)(pixel_msb) << 8);
  790. if(ret != ST7735_OK)
  791. {
  792. ret = ST7735_ERROR;
  793. }
  794. return ret;
  795. }
  796. /**
  797. * @brief Get the LCD pixel Width.
  798. * @param pObj Component object
  799. * @retval The Lcd Pixel Width
  800. */
  801. int32_t ST7735_GetXSize(ST7735_Object_t *pObj, uint32_t *XSize)
  802. {
  803. (void)pObj;
  804. *XSize = ST7735Ctx.Width;
  805. return ST7735_OK;
  806. }
  807. /**
  808. * @brief Get the LCD pixel Height.
  809. * @param pObj Component object
  810. * @retval The Lcd Pixel Height
  811. */
  812. int32_t ST7735_GetYSize(ST7735_Object_t *pObj, uint32_t *YSize)
  813. {
  814. (void)pObj;
  815. *YSize = ST7735Ctx.Height;
  816. return ST7735_OK;
  817. }
  818. /**
  819. * @}
  820. */
  821. /** @defgroup ST7735_Private_Functions Private Functions
  822. * @{
  823. */
  824. /**
  825. * @brief Sets a display window
  826. * @param Xpos specifies the X bottom left position.
  827. * @param Ypos specifies the Y bottom left position.
  828. * @param Height display window height.
  829. * @param Width display window width.
  830. * @retval Component status
  831. */
  832. static int32_t ST7735_SetDisplayWindow(ST7735_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t Width, uint32_t Height)
  833. {
  834. int32_t ret;
  835. uint8_t tmp;
  836. /* Cursor calibration */
  837. if(ST7735Ctx.Orientation <= ST7735_ORIENTATION_PORTRAIT_ROT180)
  838. {
  839. #if IS_BOE_PANEL
  840. Xpos += 24;
  841. Ypos += 0;
  842. #else
  843. Xpos += 26;
  844. Ypos += 1;
  845. #endif
  846. }
  847. else
  848. {
  849. #if IS_BOE_PANEL
  850. Xpos += 0;
  851. Ypos += 24;
  852. #else
  853. Xpos += 1;
  854. Ypos += 26;
  855. #endif
  856. }
  857. /* Column addr set, 4 args, no delay: XSTART = Xpos, XEND = (Xpos + Width - 1) */
  858. ret = st7735_write_reg(&pObj->Ctx, ST7735_CASET, &tmp, 0);
  859. tmp = (uint8_t)(Xpos >> 8U);
  860. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  861. tmp = (uint8_t)(Xpos & 0xFFU);
  862. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  863. tmp = (uint8_t)((Xpos + Width - 1U) >> 8U);
  864. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  865. tmp = (uint8_t)((Xpos + Width - 1U) & 0xFFU);
  866. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  867. /* Row addr set, 4 args, no delay: YSTART = Ypos, YEND = (Ypos + Height - 1) */
  868. ret += st7735_write_reg(&pObj->Ctx, ST7735_RASET, &tmp, 0);
  869. tmp = (uint8_t)(Ypos >> 8U);
  870. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  871. tmp = (uint8_t)(Ypos & 0xFFU);
  872. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  873. tmp = (uint8_t)((Ypos + Height - 1U) >> 8U);
  874. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  875. tmp = (uint8_t)((Ypos + Height - 1U) & 0xFFU);
  876. ret += st7735_send_data(&pObj->Ctx, &tmp, 1);
  877. if(ret != ST7735_OK)
  878. {
  879. ret = ST7735_ERROR;
  880. }
  881. return ret;
  882. }
  883. /**
  884. * @brief Wrap component ReadReg to Bus Read function
  885. * @param Handle Component object handle
  886. * @param Reg The target register address to write
  887. * @param pData The target register value to be written
  888. * @retval Component error status
  889. */
  890. static int32_t ST7735_ReadRegWrap(void *Handle, uint8_t Reg, uint8_t* pData)
  891. {
  892. ST7735_Object_t *pObj = (ST7735_Object_t *)Handle;
  893. return pObj->IO.ReadReg(Reg, pData);
  894. }
  895. /**
  896. * @brief Wrap component WriteReg to Bus Write function
  897. * @param handle Component object handle
  898. * @param Reg The target register address to write
  899. * @param pData The target register value to be written
  900. * @param Length buffer size to be written
  901. * @retval Component error status
  902. */
  903. static int32_t ST7735_WriteRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint32_t Length)
  904. {
  905. ST7735_Object_t *pObj = (ST7735_Object_t *)Handle;
  906. return pObj->IO.WriteReg(Reg, pData, Length);
  907. }
  908. /**
  909. * @brief Wrap component SendData to Bus Write function
  910. * @param handle Component object handle
  911. * @param pData The target register value to be written
  912. * @retval Component error status
  913. */
  914. static int32_t ST7735_SendDataWrap(void *Handle, uint8_t *pData, uint32_t Length)
  915. {
  916. ST7735_Object_t *pObj = (ST7735_Object_t *)Handle;
  917. return pObj->IO.SendData(pData, Length);
  918. }
  919. /**
  920. * @brief Wrap component SendData to Bus Write function
  921. * @param handle Component object handle
  922. * @param pData The target register value to be written
  923. * @retval Component error status
  924. */
  925. static int32_t ST7735_RecvDataWrap(void *Handle, uint8_t *pData, uint32_t Length)
  926. {
  927. ST7735_Object_t *pObj = (ST7735_Object_t *)Handle;
  928. return pObj->IO.RecvData(pData, Length);
  929. }
  930. /**
  931. * @brief ST7735 delay
  932. * @param Delay Delay in ms
  933. * @retval Component error status
  934. */
  935. static int32_t ST7735_IO_Delay(ST7735_Object_t *pObj, uint32_t Delay)
  936. {
  937. rt_thread_mdelay(Delay);
  938. return ST7735_OK;
  939. }
  940. /**
  941. * @}
  942. */
  943. /**
  944. * @}
  945. */
  946. /**
  947. * @}
  948. */
  949. /**
  950. * @}
  951. */
  952. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/