lpc_lcd.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. /**********************************************************************
  2. * $Id$ lpc_lcd.c 2011-10-14
  3. *//**
  4. * @file lpc_lcd.c
  5. * @brief Contains all functions support for LCD firmware library
  6. * on LPC
  7. * @version 1.0
  8. * @date 14. October. 2011
  9. * @author NXP MCU SW Application Team
  10. *
  11. * Copyright(C) 2011, NXP Semiconductor
  12. * All rights reserved.
  13. *
  14. ***********************************************************************
  15. * Software that is described herein is for illustrative purposes only
  16. * which provides customers with programming information regarding the
  17. * products. This software is supplied "AS IS" without any warranties.
  18. * NXP Semiconductors assumes no responsibility or liability for the
  19. * use of the software, conveys no license or title under any patent,
  20. * copyright, or mask work right to the product. NXP Semiconductors
  21. * reserves the right to make changes in the software without
  22. * notification. NXP Semiconductors also make no representation or
  23. * warranty that such application will be suitable for the specified
  24. * use without further testing or modification.
  25. * Permission to use, copy, modify, and distribute this software and its
  26. * documentation is hereby granted, under NXP Semiconductors'
  27. * relevant copyright in the software, without fee, provided that it
  28. * is used in conjunction with NXP Semiconductors microcontrollers. This
  29. * copyright, permission, and disclaimer notice must appear in all copies of
  30. * this code.
  31. **********************************************************************/
  32. #ifdef __BUILD_WITH_EXAMPLE__
  33. #include "lpc_libcfg.h"
  34. #else
  35. #include "lpc_libcfg_default.h"
  36. #endif /* __BUILD_WITH_EXAMPLE__ */
  37. #ifdef _LCD
  38. #include "lpc_clkpwr.h"
  39. #include "lpc_pinsel.h"
  40. #include "lpc_gpio.h"
  41. #include "lpc_lcd.h"
  42. uint32_t lcd_hsize = 0, lcd_vsize = 0;
  43. uint32_t lcd_cursor_base_addr = 0;
  44. uint32_t lcd_cursor_size = 64;
  45. LCD_Config_Type lcd_config;
  46. static uint8_t bits_per_pixel[] = { 1, 2, 4, 8, 16, 32, 16, 16 };
  47. uint32_t rect[1024];
  48. static void LCD_SetHorizontalTiming(LCD_HConfig_Type* pConfig);
  49. static void LCD_SetVertialTiming(LCD_VConfig_Type* pConfig);
  50. static void LCD_SetPolarity(LCD_TYPES lcd_type, LCD_POLARITY_Type* pConfig);
  51. static void LCD_CtrlSetup(LCD_Config_Type* pConfig);
  52. /** @addtogroup LCD_Private_Functions LCD Private Function
  53. * @ingroup LCD
  54. * @{
  55. */
  56. /*********************************************************************//**
  57. * @brief Init LCD. The input clock is CClk
  58. *
  59. * @param[in] pConfig Configuration Information
  60. *
  61. * @return LCD_FUNC_OK Execute successfully
  62. * LCD_FUNC_ERR Error occurred.
  63. *
  64. **********************************************************************/
  65. LCD_RET_CODE LCD_Init (LCD_Config_Type* pConfig)
  66. {
  67. uint8_t clkdiv;
  68. if(pConfig == NULL)
  69. return LCD_FUNC_ERR;
  70. if(pConfig->big_endian_byte & !pConfig->big_endian_pixel)
  71. return LCD_FUNC_ERR;
  72. lcd_config = *pConfig;
  73. // Assign pins
  74. PINSEL_ConfigPin(0,4,7);
  75. PINSEL_ConfigPin(0,5,7);
  76. PINSEL_ConfigPin(0,6,7);
  77. PINSEL_ConfigPin(0,7,7);
  78. PINSEL_ConfigPin(0,8,7);
  79. PINSEL_ConfigPin(0,9,7);
  80. PINSEL_ConfigPin(1,20,7);
  81. PINSEL_ConfigPin(1,21,7);
  82. PINSEL_ConfigPin(1,22,7);
  83. PINSEL_ConfigPin(1,23,7);
  84. PINSEL_ConfigPin(1,24,7);
  85. PINSEL_ConfigPin(1,25,7);
  86. PINSEL_ConfigPin(1,26,7);
  87. PINSEL_ConfigPin(1,27,7);
  88. PINSEL_ConfigPin(1,28,7);
  89. PINSEL_ConfigPin(1,29,7);
  90. PINSEL_ConfigPin(2,0,7);
  91. PINSEL_ConfigPin(2,1,7);
  92. PINSEL_ConfigPin(2,2,7);
  93. PINSEL_ConfigPin(2,3,7);
  94. PINSEL_ConfigPin(2,4,7);
  95. PINSEL_ConfigPin(2,5,7);
  96. PINSEL_ConfigPin(2,6,7);
  97. #ifdef CORE_M4
  98. PINSEL_ConfigPin(0,10,7);
  99. #else
  100. PINSEL_ConfigPin(2,7,7);
  101. #endif
  102. PINSEL_ConfigPin(2,8,7);
  103. PINSEL_ConfigPin(2,9,7);
  104. PINSEL_ConfigPin(2,11,7);
  105. PINSEL_ConfigPin(2,12,7);
  106. PINSEL_ConfigPin(2,13,7);
  107. PINSEL_ConfigPin(4,28,7);
  108. PINSEL_ConfigPin(4,29,7);
  109. //Turn on LCD clock
  110. CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCLCD, ENABLE);
  111. // Set clock
  112. LPC_LCD->POL &= ~(0x01 << 5);
  113. if( pConfig->panel_clk > 0) {
  114. clkdiv = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU) / pConfig->panel_clk - 1;
  115. LPC_SC->LCD_CFG = clkdiv & 0x1F;
  116. LPC_LCD->POL |=(1<<26);
  117. }
  118. // init Horizontal Timing
  119. LCD_SetHorizontalTiming(&pConfig->hConfig);
  120. // Init Vertical Timing
  121. LCD_SetVertialTiming(&pConfig->vConfig);
  122. // Set Polarity
  123. LCD_SetPolarity(pConfig->lcd_type, &pConfig->polarity);
  124. if(NULL != pConfig->lcd_palette)
  125. {
  126. LCD_SetPalette(pConfig->lcd_palette);
  127. }
  128. // Set Base address
  129. LCD_SetBaseAddress(LCD_PANEL_UPPER, pConfig->lcd_panel_upper);
  130. LCD_SetBaseAddress(LCD_PANEL_LOWER, pConfig->lcd_panel_lower);
  131. // Setup
  132. LCD_CtrlSetup(pConfig);
  133. return LCD_FUNC_OK;
  134. }
  135. /*********************************************************************//**
  136. * @brief Horizontal Timing Setting
  137. *
  138. * @param[in] pConfig Configuration Information
  139. *
  140. * @return None.
  141. *
  142. **********************************************************************/
  143. void LCD_SetHorizontalTiming(LCD_HConfig_Type* pConfig)
  144. {
  145. LPC_LCD->TIMH = 0; //reset TIMH before set value
  146. LPC_LCD->TIMH |= ((pConfig->hbp - 1)& 0xFF)<<24;
  147. LPC_LCD->TIMH |= ((pConfig->hfp - 1)& 0xFF)<<16;
  148. LPC_LCD->TIMH |= ((pConfig->hsw - 1)& 0xFF)<<8;
  149. LPC_LCD->TIMH |= ((pConfig->ppl/16 - 1)& 0x3F)<<2;
  150. lcd_hsize = pConfig->ppl;
  151. }
  152. /*********************************************************************//**
  153. * @brief Vertical Timing Setting
  154. *
  155. * @param[in] pConfig Configuration Information
  156. *
  157. * @return None.
  158. *
  159. **********************************************************************/
  160. void LCD_SetVertialTiming(LCD_VConfig_Type* pConfig)
  161. {
  162. LPC_LCD->TIMV = 0; //reset TIMV value before setting
  163. LPC_LCD->TIMV |= ((pConfig->vbp)& 0xFF)<<24;
  164. LPC_LCD->TIMV |= ((pConfig->vfp)& 0xFF)<<16;
  165. LPC_LCD->TIMV |= ((pConfig->vsw - 1)& 0x3F)<<10;
  166. LPC_LCD->TIMV |= ((pConfig->lpp - 1)& 0x03FF)<<0;
  167. lcd_vsize = pConfig->lpp;
  168. }
  169. /*********************************************************************//**
  170. * @brief Polarity Setting
  171. *
  172. * @param[in] pConfig Configuration Information
  173. * @param[in] lcd_type It can be:
  174. * - LCD_STN_MONOCHROME
  175. * - LCD_STN_COLOR
  176. * - LCD_TFT
  177. *
  178. * @return None.
  179. *
  180. **********************************************************************/
  181. void LCD_SetPolarity(LCD_TYPES lcd_type, LCD_POLARITY_Type* pConfig)
  182. {
  183. // LCDFP pin is active LOW and inactive HIGH
  184. if(pConfig->invert_vsync)
  185. LPC_LCD->POL |= (1<<11);
  186. else
  187. LPC_LCD->POL &= ~(1<<11);
  188. // LCDLP pin is active LOW and inactive HIGH
  189. if(pConfig->invert_hsync)
  190. LPC_LCD->POL |= (1<<12);
  191. else
  192. LPC_LCD->POL &= ~(1<<12);
  193. // data is driven out into the LCD on the falling edge
  194. if(pConfig->invert_panel_clock)
  195. LPC_LCD->POL |= (1<<13);
  196. else
  197. LPC_LCD->POL &= ~(1<<13);
  198. // active high
  199. if(pConfig->active_high) {
  200. LPC_LCD->POL &= ~(1<<14);
  201. }
  202. else
  203. {
  204. LPC_LCD->POL |= (1<<14);
  205. }
  206. LPC_LCD->POL &= ~(0x3FF <<16);
  207. LPC_LCD->POL |= (pConfig->cpl - 1)<<16;
  208. if(lcd_type == LCD_STN_COLOR || lcd_type == LCD_STN_MONOCHROME)
  209. LPC_LCD->POL |= (pConfig->acb & 0x1F) << 6;
  210. }
  211. /*********************************************************************//**
  212. * @brief Set base address of frame buffer
  213. *
  214. * @param[in] panel identify which panel is.
  215. * @param[in] pAddress base address of the inputted panel.
  216. *
  217. * @return None.
  218. *
  219. **********************************************************************/
  220. void LCD_SetBaseAddress(LCD_PANEL panel, uint32_t pAddress)
  221. {
  222. // Frame Base Address doubleword aligned
  223. if(panel == LCD_PANEL_UPPER)
  224. LPC_LCD->UPBASE = pAddress & ~7UL ;
  225. else
  226. LPC_LCD->LPBASE = pAddress & ~7UL ;
  227. }
  228. /*********************************************************************//**
  229. * @brief LCD Setup.
  230. *
  231. * @param[in] pConfig Configuration information.
  232. *
  233. * @return None.
  234. *
  235. **********************************************************************/
  236. void LCD_CtrlSetup(LCD_Config_Type* pConfig)
  237. {
  238. // disable LCD controller
  239. LPC_LCD->CTRL = 0;
  240. // bpp
  241. LPC_LCD->CTRL &= ~(0x07 <<1);
  242. LPC_LCD->CTRL |=((pConfig->lcd_bpp & 0x07)<<1);
  243. if(pConfig->lcd_type == LCD_TFT) {
  244. LPC_LCD->CTRL |= (0x01 << 5); // TFT
  245. }
  246. else {
  247. // Color/Mono
  248. if(pConfig->lcd_type == LCD_STN_COLOR) {
  249. LPC_LCD->CTRL &= ~ (0x01 << 4); // Color
  250. }
  251. else if (pConfig->lcd_type == LCD_STN_MONOCHROME) {
  252. LPC_LCD->CTRL |= (0x01 << 4); // Mono
  253. }
  254. // STN/TFT
  255. LPC_LCD->CTRL &= ~ (0x01 << 5); // STN
  256. // Mono4/8
  257. if(pConfig->lcd_mono8)
  258. LPC_LCD->CTRL |= (0x01 << 6);
  259. else
  260. LPC_LCD->CTRL &= ~(0x01 << 6);
  261. // Single/dual
  262. if(pConfig->lcd_dual)
  263. LPC_LCD->CTRL |= (0x01 << 7);
  264. else
  265. LPC_LCD->CTRL &= ~(0x01 << 7);
  266. }
  267. // notmal output
  268. if(pConfig->lcd_bgr)
  269. LPC_LCD->CTRL |= (1<<8); // BGR
  270. else
  271. LPC_LCD->CTRL &= ~(1<<8); // RGB
  272. // Byte order
  273. if(pConfig->big_endian_byte)
  274. LPC_LCD->CTRL |= (1<<9);
  275. else
  276. LPC_LCD->CTRL &= ~(1<<9);
  277. // Pixel order
  278. if(pConfig->big_endian_pixel)
  279. LPC_LCD->CTRL |= (1<<10);
  280. else
  281. LPC_LCD->CTRL &= ~(1<<10);
  282. // disable power
  283. LPC_LCD->CTRL &= ~(1<<11);
  284. }
  285. /*********************************************************************//**
  286. * @brief Enable/disable LCD Display.
  287. *
  288. * @param[in] bEna 0: disable, 1: enable.
  289. *
  290. * @return None.
  291. *
  292. **********************************************************************/
  293. void LCD_Enable (Bool bEna)
  294. {
  295. volatile uint32_t i;
  296. if (bEna)
  297. {
  298. LPC_LCD->CTRL |= (1<<0);
  299. for(i = LCD_PWR_ENA_DIS_DLY; i; i--);
  300. LPC_LCD->CTRL |= (1<<11);
  301. }
  302. else
  303. {
  304. LPC_LCD->CTRL &= ~(1<<11);
  305. for(i = LCD_PWR_ENA_DIS_DLY; i; i--);
  306. LPC_LCD->CTRL &= ~(1<<0);
  307. }
  308. }
  309. /*********************************************************************//**
  310. * @brief Set palette.
  311. *
  312. * @param[in] bEna 0: disable, 1: enable.
  313. *
  314. * @return None.
  315. *
  316. **********************************************************************/
  317. void LCD_SetPalette (const uint8_t* pPallete)
  318. {
  319. uint32_t i;
  320. uint32_t size = (0x01 << bits_per_pixel[lcd_config.lcd_bpp])/2 ;
  321. uint32_t * pDst = (uint32_t *)LPC_LCD->PAL;
  322. uint32_t * pInput = (uint32_t*) pPallete;
  323. for (i = 0; i < size; i++)
  324. {
  325. *pDst = *pInput;
  326. pDst++;
  327. pInput++;
  328. }
  329. }
  330. /*********************************************************************//**
  331. * @brief Get word offset for the given pixel
  332. *
  333. * @param[in] x x position of input pixel
  334. * @param[in] y y position of input pixel
  335. *
  336. * @return Offset
  337. *
  338. **********************************************************************/
  339. uint32_t LCD_GetWordOffset(uint32_t x, uint32_t y)
  340. {
  341. uint32_t pixel_num = x + y*lcd_hsize;
  342. return (pixel_num * bits_per_pixel[lcd_config.lcd_bpp])/32;
  343. }
  344. /*********************************************************************//**
  345. * @brief Get bit offset for the given pixel
  346. *
  347. * @param[in] x x position of input pixel
  348. * @param[in] y y position of input pixel
  349. *
  350. * @return Offset
  351. *
  352. **********************************************************************/
  353. uint32_t LCD_GetBitOffset(uint32_t x, uint32_t y)
  354. {
  355. uint32_t pixel_num;
  356. uint32_t ofs;
  357. pixel_num = x + y*lcd_hsize;
  358. ofs = (pixel_num * bits_per_pixel[lcd_config.lcd_bpp])%32;
  359. if(lcd_config.big_endian_pixel & lcd_config.big_endian_byte)
  360. {
  361. ofs = 32 - bits_per_pixel[lcd_config.lcd_bpp] - ofs;
  362. }
  363. else if (lcd_config.big_endian_pixel & !lcd_config.big_endian_byte)
  364. {
  365. if(bits_per_pixel[lcd_config.lcd_bpp] < 8)
  366. {
  367. ofs = (ofs/8)*8 + (8 - (ofs%8)-bits_per_pixel[lcd_config.lcd_bpp]);
  368. }
  369. }
  370. return ofs;
  371. }
  372. /*********************************************************************//**
  373. * @brief Copy pixel values from image buffer to frame buffer.
  374. *
  375. * @param[in] panel It can be:
  376. * - LCD_PANEL_UPPER
  377. * - LCD_PANEL_LOWER
  378. * @param[in] pPain point to image buffer.
  379. *
  380. * @return None.
  381. *
  382. **********************************************************************/
  383. void LCD_SetImage(LCD_PANEL panel, const uint8_t *pPain)
  384. {
  385. volatile uint32_t i;
  386. uint32_t * pWordDst = NULL;
  387. uint8_t* pByteDst = NULL;
  388. uint32_t bytes_num;
  389. if(panel == LCD_PANEL_UPPER)
  390. pWordDst = (uint32_t*) LPC_LCD->UPBASE;
  391. else
  392. pWordDst = (uint32_t*) LPC_LCD->LPBASE;
  393. pByteDst = (uint8_t*) pWordDst;
  394. bytes_num = ((lcd_hsize * lcd_vsize) * bits_per_pixel[lcd_config.lcd_bpp]) /8;
  395. if (NULL == pPain)
  396. {
  397. // clear display memory
  398. for( i = 0; bytes_num > i; i++)
  399. {
  400. *pByteDst++ = 0;
  401. }
  402. }
  403. else
  404. {
  405. // set display memory
  406. for(i = 0; bytes_num > i; i++)
  407. {
  408. *pByteDst++ = *pPain++;
  409. }
  410. }
  411. for(i = LCD_PWR_ENA_DIS_DLY; i; i--);
  412. }
  413. /*********************************************************************//**
  414. * @brief Draw a pixel on the given panel.
  415. *
  416. * @param[in] panel It can be:
  417. * - LCD_PANEL_UPPER
  418. * - LCD_PANEL_LOWER
  419. * @param[in] X_Left X position.
  420. * @param[in] Y_Up Y position.
  421. * @param[in] color Color which is placed to the given pixel.
  422. *
  423. * @return None.
  424. *
  425. **********************************************************************/
  426. void LCD_PutPixel (LCD_PANEL panel, uint32_t X_Left, uint32_t Y_Up, LcdPixel_t color)
  427. {
  428. uint32_t k;
  429. uint32_t * pWordData = NULL;
  430. uint8_t* pByteData = NULL;
  431. uint32_t bitOffset;
  432. uint8_t* pByteSrc = (uint8_t*)&color;
  433. uint8_t bpp = bits_per_pixel[lcd_config.lcd_bpp];
  434. uint8_t bytes_per_pixel = bpp/8;
  435. uint32_t start_bit;
  436. if((X_Left >= lcd_hsize)||(Y_Up >= lcd_vsize))
  437. return;
  438. if(panel == LCD_PANEL_UPPER)
  439. pWordData = (uint32_t*) LPC_LCD->UPBASE + LCD_GetWordOffset(X_Left,Y_Up);
  440. else
  441. pWordData = (uint32_t*) LPC_LCD->LPBASE + LCD_GetWordOffset(X_Left,Y_Up);
  442. bitOffset = LCD_GetBitOffset(X_Left,Y_Up);
  443. pByteData = (uint8_t*) pWordData;
  444. pByteData += bitOffset/8;
  445. start_bit = bitOffset%8;
  446. if(bpp < 8)
  447. {
  448. uint8_t bit_pos = start_bit;
  449. uint8_t bit_ofs = 0;
  450. for(bit_ofs = 0;bit_ofs <bpp; bit_ofs++,bit_pos++)
  451. {
  452. *pByteData &= ~ (0x01 << bit_pos);
  453. *pByteData |= ((*pByteSrc >> (k+bit_ofs)) & 0x01) << bit_pos;
  454. }
  455. }
  456. else
  457. {
  458. for(k = 0; k < bytes_per_pixel; k++)
  459. {
  460. *(pByteData+ k) = *pByteSrc++;
  461. }
  462. }
  463. }
  464. /*********************************************************************//**
  465. * @brief Place given image to given position.
  466. *
  467. * @param[in] panel It can be:
  468. * - LCD_PANEL_UPPER
  469. * - LCD_PANEL_LOWER
  470. * @param[in] X_Left Start X position.
  471. * @param[in] Y_Up Start Y position.
  472. * @param[in] pBmp Image information.
  473. * @param[in] Mask Mask on pixel values.
  474. *
  475. * @return None.
  476. *
  477. **********************************************************************/
  478. void LCD_LoadPic (LCD_PANEL panel, uint32_t X_Left, uint32_t Y_Up,
  479. Bmp_t * pBmp, uint32_t Mask)
  480. {
  481. uint32_t i, j, k, inc;
  482. uint32_t * pWordData = NULL;
  483. uint8_t* pByteData = NULL;
  484. uint32_t bitOffset;
  485. uint8_t* pByteSrc = (uint8_t*) pBmp->pPicStream;
  486. uint32_t X_LeftHold = X_Left;
  487. uint8_t bpp = bits_per_pixel[lcd_config.lcd_bpp];
  488. uint8_t bytes_per_pixel = bpp/8;
  489. uint8_t pixels_per_byte = 8/bpp;
  490. uint32_t hsize, vsize;
  491. uint32_t start_bit;
  492. if(pBmp->BytesPP == 0)
  493. pBmp->BytesPP = bytes_per_pixel;
  494. hsize = pBmp->H_Size;
  495. vsize = pBmp->V_Size;
  496. inc = (pixels_per_byte > 0) ? pixels_per_byte:1;
  497. for(i = 0; i < vsize; i++)
  498. {
  499. if(panel == LCD_PANEL_UPPER)
  500. pWordData = (uint32_t*) LPC_LCD->UPBASE + LCD_GetWordOffset(X_Left,Y_Up);
  501. else
  502. pWordData = (uint32_t*) LPC_LCD->LPBASE + LCD_GetWordOffset(X_Left,Y_Up);
  503. bitOffset = LCD_GetBitOffset(X_Left,Y_Up);
  504. pByteData = (uint8_t*) pWordData;
  505. pByteData += bitOffset/8;
  506. start_bit = bitOffset%8;
  507. if(pBmp->BytesPP > 0)
  508. pByteSrc = (uint8_t*) pBmp->pPicStream + i*hsize*pBmp->BytesPP; // storage of each line must be word alignment
  509. else
  510. pByteSrc = (uint8_t*) pBmp->pPicStream + (i*hsize*pBmp->BitsPP + 7)/8; // storage of each line must be word alignment
  511. X_LeftHold = X_Left;
  512. for(j = 0; j <= hsize; j+= inc)
  513. {
  514. if((X_LeftHold >= lcd_hsize) || (X_LeftHold - X_Left >= hsize))
  515. break;
  516. if(bpp < 8)
  517. {
  518. uint8_t bit_pos = start_bit;
  519. uint8_t bit_ofs = 0;
  520. for(k = 0; k < 8; k+= bpp)
  521. {
  522. for(bit_ofs = 0;bit_ofs <bpp; bit_ofs++,bit_pos++)
  523. {
  524. *pByteData &= ~ (0x01 << bit_pos);
  525. *pByteData |= ((*pByteSrc >> (k+bit_ofs)) & 0x01) << bit_pos;
  526. }
  527. if(lcd_config.big_endian_byte && lcd_config.big_endian_pixel)
  528. {
  529. if(bit_pos >= bpp*2)
  530. bit_pos -= bpp*2;
  531. else
  532. {
  533. bit_pos = 8-bpp;
  534. if((((uint32_t)pByteData)%4) == 0)
  535. pByteData += 7; // change to next word
  536. else
  537. pByteData--; // change to previous byte
  538. }
  539. }
  540. else if( !lcd_config.big_endian_byte && lcd_config.big_endian_pixel)
  541. {
  542. if(bit_pos >= bpp*2)
  543. bit_pos -= bpp*2;
  544. else
  545. {
  546. bit_pos = 8-bpp;
  547. pByteData++; // change to next byte
  548. }
  549. }
  550. else
  551. {
  552. if(bit_pos >= 8)
  553. {
  554. bit_pos = 0;
  555. pByteData++; // change to next byte
  556. }
  557. }
  558. X_LeftHold++;
  559. if((X_LeftHold >= lcd_hsize) ||
  560. (X_LeftHold - X_Left >= hsize))
  561. break;
  562. }
  563. pByteSrc++;
  564. continue;
  565. }
  566. else
  567. {
  568. for(k = 0; k < pBmp->BytesPP; k++)
  569. {
  570. *(pByteData+ k) = *pByteSrc++ ^ Mask;
  571. }
  572. if(lcd_config.big_endian_byte)
  573. {
  574. if((uint32_t)pByteData %4 > 0)
  575. pByteData -= bytes_per_pixel;
  576. else
  577. pByteData += 8 - bytes_per_pixel;
  578. }
  579. else
  580. pByteData+= bytes_per_pixel;
  581. X_LeftHold++;
  582. }
  583. }
  584. if(Y_Up++ >= lcd_vsize)
  585. {
  586. break;
  587. }
  588. }
  589. }
  590. /*********************************************************************//**
  591. * @brief Fill a rectangle.
  592. *
  593. * @param[in] panel It can be:
  594. * - LCD_PANEL_UPPER
  595. * - LCD_PANEL_LOWER
  596. * @param[in] startx Start X position.
  597. * @param[in] endy End X position.
  598. * @param[in] starty Start Y position.
  599. * @param[in] endy End Y position.
  600. *
  601. * @return None.
  602. *
  603. **********************************************************************/
  604. void LCD_FillRect (LCD_PANEL panel, uint32_t startx,uint32_t endx,
  605. uint32_t starty, uint32_t endy,
  606. LcdPixel_t color)
  607. {
  608. uint32_t x, xs, xe, ys, ye;
  609. uint8_t bpp, pixels_per_word;
  610. uint32_t word_val, mask;
  611. uint32_t max_vsize = 0;
  612. Bmp_t bitmap;
  613. uint32_t hsize, vsize;
  614. bpp = bits_per_pixel[lcd_config.lcd_bpp];
  615. pixels_per_word = 32/bpp;
  616. mask = 0;
  617. for( x = 0; x < bpp; x++)
  618. mask |= 0x01 << x;
  619. color &= mask;
  620. word_val = 0;
  621. for(x = 0; x < pixels_per_word; x++)
  622. word_val |= color << (x*bpp);
  623. ys = (starty > endy) ? endy : starty;
  624. ye = (starty > endy) ? starty : endy;
  625. xs = (startx > endx) ? endx : startx;
  626. xe = (startx > endx) ? startx : endx;
  627. bitmap.BitsPP = bpp;
  628. bitmap.BytesPP = bpp/8;
  629. hsize = xe - xs + 1;
  630. bitmap.H_Size = hsize;
  631. vsize = ye - ys + 1;
  632. bitmap.pPicStream = (uint8_t*)rect;
  633. max_vsize = ((1024 * 32)/(hsize*bpp));
  634. for( x = 0; x < 1024; x++)
  635. {
  636. rect[x] = word_val;
  637. }
  638. while(1)
  639. {
  640. if(max_vsize >= vsize)
  641. {
  642. bitmap.V_Size = vsize;
  643. LCD_LoadPic(panel,xs,ys, &bitmap, 0);
  644. break;
  645. }
  646. else {
  647. bitmap.V_Size = max_vsize;
  648. vsize -= bitmap.V_Size;
  649. LCD_LoadPic(panel,xs,ys, &bitmap, 0);
  650. ys += max_vsize;
  651. }
  652. }
  653. }
  654. /*********************************************************************//**
  655. * @brief Configure display of cursor.
  656. *
  657. * @param[in] pConfig Configuration information.
  658. *
  659. * @return None.
  660. *
  661. **********************************************************************/
  662. void LCD_Cursor_Cfg(LCD_Cursor_Config_Type* pConfig)
  663. {
  664. if(pConfig->size32) {
  665. LPC_LCD->CRSR_CFG &= ~(0x01 << 0);
  666. lcd_cursor_size = 32;
  667. }
  668. else {
  669. LPC_LCD->CRSR_CFG |= (0x01 << 0);
  670. lcd_cursor_size = 64;
  671. }
  672. if(pConfig->framesync)
  673. LPC_LCD->CRSR_CFG &= ~(0x01 << 1);
  674. else
  675. LPC_LCD->CRSR_CFG |= (0x01 << 1);
  676. lcd_cursor_base_addr = pConfig->baseaddress;
  677. LPC_LCD->CRSR_PAL0 = pConfig->palette[0].Red |
  678. pConfig->palette[0].Green << 8 |
  679. pConfig->palette[0].Blue << 16;
  680. LPC_LCD->CRSR_PAL1 = pConfig->palette[1].Red |
  681. pConfig->palette[1].Green << 8 |
  682. pConfig->palette[1].Blue << 16;
  683. }
  684. /*********************************************************************//**
  685. * @brief Enable/disable cursor display.
  686. *
  687. * @param[in] enable 0: disable, 1: enable.
  688. * @param[in] cursor identify which cursor image is used.
  689. *
  690. * @return None.
  691. *
  692. **********************************************************************/
  693. void LCD_Cursor_Enable(int enable, int cursor)
  694. {
  695. if(enable) {
  696. LPC_LCD->CRSR_CTRL |= (1<<0);
  697. LPC_LCD->CRSR_CTRL |= (cursor<<4);
  698. }
  699. else {
  700. LPC_LCD->CRSR_CTRL &= ~(1<<0);
  701. }
  702. }
  703. /*********************************************************************//**
  704. * @brief move the cursor to the inputted position.
  705. *
  706. * @param[in] x Position in x-direction.
  707. * @param[in] y Position in y-direction.
  708. *
  709. * @return None.
  710. *
  711. **********************************************************************/
  712. void LCD_Move_Cursor(int x, int y)
  713. {
  714. LPC_LCD->CRSR_CLIP = 0;
  715. LPC_LCD->CRSR_XY = 0;
  716. if(0 <= x)
  717. {//no clipping
  718. LPC_LCD->CRSR_XY |= (x & 0x3FF);
  719. }
  720. else
  721. {//clip x
  722. LPC_LCD->CRSR_CLIP |= -x;
  723. }
  724. if(0 <= y)
  725. {//no clipping
  726. LPC_LCD->CRSR_XY |= (y << 16);
  727. }
  728. else
  729. {//clip y
  730. LPC_LCD->CRSR_CLIP |= (-y << 8);
  731. }
  732. }
  733. /*********************************************************************//**
  734. * @brief Set the cursor image.
  735. *
  736. * @param[in] pCursor point to cursor image.
  737. * @param[in] cursor cursor image number. It has no meaning when cursor size is 64x64
  738. * @param[in] cursor cursor size in words.
  739. *
  740. * @return None.
  741. *
  742. **********************************************************************/
  743. void LCD_Cursor_SetImage (const uint32_t *pCursor, int cursor, int size)
  744. {
  745. uint32_t i ;
  746. uint32_t * pDst = (uint32_t *)lcd_cursor_base_addr;
  747. if(lcd_cursor_size == 32)
  748. pDst += cursor*GET_CURSOR_IMG_SIZE(lcd_cursor_size);
  749. for(i = 0; i < size ; i++)
  750. {
  751. *pDst = *pCursor;
  752. pDst++;
  753. pCursor++;
  754. }
  755. }
  756. /**
  757. * @}
  758. */
  759. #endif /*_LCD*/