dmd_ssd2119_16bit.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  1. /*************************************************************************//**
  2. * @file dmd_ssd2119.c
  3. * @brief Dot matrix display driver for LCD controller SSD2119
  4. * @author Energy Micro AS
  5. ******************************************************************************
  6. * @section License
  7. * <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
  8. ******************************************************************************
  9. *
  10. * Permission is granted to anyone to use this software for any purpose,
  11. * including commercial applications, and to alter it and redistribute it
  12. * freely, subject to the following restrictions:
  13. *
  14. * 1. The origin of this software must not be misrepresented; you must not
  15. * claim that you wrote the original software.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. * 4. The source and compiled code may only be used on Energy Micro "EFM32"
  20. * microcontrollers and "EFR4" radios.
  21. *
  22. * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
  23. * obligation to support this Software. Energy Micro AS is providing the
  24. * Software "AS IS", with no express or implied warranties of any kind,
  25. * including, but not limited to, any implied warranties of merchantability
  26. * or fitness for any particular purpose or warranties against infringement
  27. * of any proprietary rights of a third party.
  28. *
  29. * Energy Micro AS will not be liable for any consequential, incidental, or
  30. * special damages, or any other relief, or for any claim by any third party,
  31. * arising from your use of this Software.
  32. *
  33. *****************************************************************************/
  34. #include <stdint.h>
  35. #include <stdlib.h>
  36. #include <stdio.h>
  37. #include "dmd_ssd2119.h"
  38. #include "dmd_ssd2119_registers.h"
  39. #include "dmdif_ssd2119_ebi.h"
  40. /** Dimensions of the display */
  41. DMD_DisplayGeometry dimensions;
  42. /* Local variables */
  43. static uint32_t initialized = 0;
  44. static uint16_t rcDriverOutputControl;
  45. /* Local function prototypes */
  46. static uint32_t colorTransform24To16bpp( uint8_t red, uint8_t green, uint8_t blue);
  47. static void colorTransform16To24bpp(uint32_t color,
  48. uint8_t *red, uint8_t *green, uint8_t *blue);
  49. /**************************************************************************//**
  50. * @brief
  51. * Initializes the LCD display
  52. *
  53. * @param cmdRegAddr
  54. * The address in memory where data to the command register in the display
  55. * controller are written
  56. * @param dataRegAddr
  57. * The address in memory where data to the data register in the display
  58. * controller are written
  59. *
  60. * @return
  61. * DMD_OK on success, otherwise error code
  62. ******************************************************************************/
  63. EMSTATUS DMD_init(uint32_t cmdRegAddr, uint32_t dataRegAddr){
  64. EMSTATUS stat;
  65. uint16_t data;
  66. /* Initialize register cache variables */
  67. rcDriverOutputControl = 0;
  68. /* Initialize DMD interface */
  69. if ((stat = DMDIF_init(cmdRegAddr, dataRegAddr)) != DMD_OK)
  70. {
  71. return stat;
  72. }
  73. /* Initialization sequence, see UMSH-8252MD-T page 13 */
  74. /* printf("R%x: 0x%x\n", DMD_SSD2119_VCOM_OTP_1, 0x0006); */
  75. DMDIF_writeReg(DMD_SSD2119_VCOM_OTP_1, 0x0006);
  76. /* Start oscillation */
  77. data = DMD_SSD2119_OSCILLATION_START_OSCEN;
  78. /* printf("R%x: 0x%x\n", DMD_SSD2119_OSCILLATION_START, data); */
  79. DMDIF_writeReg(DMD_SSD2119_OSCILLATION_START, data);
  80. /* Exit sleep mode */
  81. data = 0;
  82. /* printf("R%x: 0x%x\n", DMD_SSD2119_SLEEP_MODE_1, data); */
  83. DMDIF_writeReg(DMD_SSD2119_SLEEP_MODE_1, data);
  84. /* Display control */
  85. data = DMD_SSD2119_DISPLAY_CONTROL_DTE;
  86. data |= DMD_SSD2119_DISPLAY_CONTROL_GON;
  87. data |= DMD_SSD2119_DISPLAY_CONTROL_D1;
  88. data |= DMD_SSD2119_DISPLAY_CONTROL_D0;
  89. /* printf("R%x: 0x%x\n", DMD_SSD2119_DISPLAY_CONTROL, data); */
  90. DMDIF_writeReg(DMD_SSD2119_DISPLAY_CONTROL, data);
  91. /* Entry mode */
  92. data = DMD_SSD2119_ENTRY_MODE_DFM_65K << DMD_SSD2119_ENTRY_MODE_DFM_SHIFT;
  93. data |= DMD_SSD2119_ENTRY_MODE_DENMODE;
  94. data |= DMD_SSD2119_ENTRY_MODE_WMODE;
  95. data |= DMD_SSD2119_ENTRY_MODE_NOSYNC;
  96. data |= DMD_SSD2119_ENTRY_MODE_TY_TYPE_B << DMD_SSD2119_ENTRY_MODE_TY_SHIFT;
  97. data |= DMD_SSD2119_ENTRY_MODE_ID1;
  98. data |= DMD_SSD2119_ENTRY_MODE_ID0;
  99. /* printf("R%x: 0x%x\n", DMD_SSD2119_ENTRY_MODE, data); */
  100. DMDIF_writeReg(DMD_SSD2119_ENTRY_MODE, data);
  101. /* LCD AC control */
  102. data = DMD_SSD2119_LCD_AC_CONTROL_BC;
  103. data |= DMD_SSD2119_LCD_AC_CONTROL_EOR;
  104. /* printf("R%x: 0x%x\n", DMD_SSD2119_LCD_AC_CONTROL, data); */
  105. DMDIF_writeReg(DMD_SSD2119_LCD_AC_CONTROL, data);
  106. /* Power control */
  107. data = 0x06 << DMD_SSD2119_POWER_CONTROL_1_DCT_SHIFT;
  108. data |= 0x05 << DMD_SSD2119_POWER_CONTROL_1_BT_SHIFT;
  109. data |= 0x03 << DMD_SSD2119_POWER_CONTROL_1_DC_SHIFT;
  110. data |= 0x04 << DMD_SSD2119_POWER_CONTROL_1_AP_SHIFT;
  111. /* printf("R%x: 0x%x\n", DMD_SSD2119_POWER_CONTROL_1, data); */
  112. DMDIF_writeReg(DMD_SSD2119_POWER_CONTROL_1, data);
  113. /* Driver output control */
  114. data = DMD_SSD2119_DRIVER_OUTPUT_CONTROL_RL;
  115. data |= DMD_SSD2119_DRIVER_OUTPUT_CONTROL_REV;
  116. data |= DMD_SSD2119_DRIVER_OUTPUT_CONTROL_GD;
  117. data |= DMD_SSD2119_DRIVER_OUTPUT_CONTROL_TB;
  118. data |= (DMD_VERTICAL_SIZE - 1) << DMD_SSD2119_DRIVER_OUTPUT_CONTROL_MUX_SHIFT;
  119. rcDriverOutputControl = data;
  120. /* printf("R%x: 0x%x\n", DMD_SSD2119_DRIVER_OUTPUT_CONTROL, data); */
  121. DMDIF_writeReg(DMD_SSD2119_DRIVER_OUTPUT_CONTROL, data);
  122. /* Power Control */
  123. data = 0x05 << DMD_SSD2119_POWER_CONTROL_2_VRC_SHIFT;
  124. /* printf("R%x: 0x%x\n", DMD_SSD2119_POWER_CONTROL_2, data); */
  125. DMDIF_writeReg(DMD_SSD2119_POWER_CONTROL_2, data);
  126. data = 0x0D << DMD_SSD2119_POWER_CONTROL_3_VRH_SHIFT;
  127. /* printf("R%x: 0x%x\n", DMD_SSD2119_POWER_CONTROL_3, data); */
  128. DMDIF_writeReg(DMD_SSD2119_POWER_CONTROL_3, data);
  129. data = DMD_SSD2119_POWER_CONTROL_4_VCOMG;
  130. data |= 0x0D << DMD_SSD2119_POWER_CONTROL_4_VDV_SHIFT;
  131. /* printf("R%x: 0x%x\n", DMD_SSD2119_POWER_CONTROL_4, data); */
  132. DMDIF_writeReg(DMD_SSD2119_POWER_CONTROL_4, data);
  133. data = DMD_SSD2119_POWER_CONTROL_5_NOTP;
  134. data |= 0x3E << DMD_SSD2119_POWER_CONTROL_5_VCM_SHIFT;
  135. /* printf("R%x: 0x%x\n", DMD_SSD2119_POWER_CONTROL_5, data); */
  136. DMDIF_writeReg(DMD_SSD2119_POWER_CONTROL_5, data);
  137. data = 0x0058;
  138. /* printf("R%x: 0x%x\n", DMD_SSD2119_GENERIC_INTERFACE_CONTROL, data); */
  139. DMDIF_writeReg(DMD_SSD2119_GENERIC_INTERFACE_CONTROL, data);
  140. /* Gamma settings */
  141. data = 0x00 << DMD_SSD2119_GAMMA_1_PKP1_SHIFT;
  142. data |= 0x00 << DMD_SSD2119_GAMMA_1_PKP0_SHIFT;
  143. /* printf("R%x: 0x%x\n", DMD_SSD2119_GAMMA_1, data); */
  144. DMDIF_writeReg(DMD_SSD2119_GAMMA_1, data);
  145. data = 0x01 << DMD_SSD2119_GAMMA_2_PKP3_SHIFT;
  146. data |= 0x01 << DMD_SSD2119_GAMMA_2_PKP2_SHIFT;
  147. /* printf("R%x: 0x%x\n", DMD_SSD2119_GAMMA_2, data); */
  148. DMDIF_writeReg(DMD_SSD2119_GAMMA_2, data);
  149. data = 0x01 << DMD_SSD2119_GAMMA_3_PKP5_SHIFT;
  150. data |= 0x00 << DMD_SSD2119_GAMMA_3_PKP4_SHIFT;
  151. /* printf("R%x: 0x%x\n", DMD_SSD2119_GAMMA_3, data); */
  152. DMDIF_writeReg(DMD_SSD2119_GAMMA_3, data);
  153. data = 0x03 << DMD_SSD2119_GAMMA_4_PRP1_SHIFT;
  154. data |= 0x05 << DMD_SSD2119_GAMMA_4_PRP0_SHIFT;
  155. /* printf("R%x: 0x%x\n", DMD_SSD2119_GAMMA_4, data); */
  156. DMDIF_writeReg(DMD_SSD2119_GAMMA_4, data);
  157. data = 0x07 << DMD_SSD2119_GAMMA_5_PKN1_SHIFT;
  158. data |= 0x07 << DMD_SSD2119_GAMMA_5_PKN0_SHIFT;
  159. /* printf("R%x: 0x%x\n", DMD_SSD2119_GAMMA_5, data); */
  160. DMDIF_writeReg(DMD_SSD2119_GAMMA_5, data);
  161. data = 0x03 << DMD_SSD2119_GAMMA_6_PKN3_SHIFT;
  162. data |= 0x05 << DMD_SSD2119_GAMMA_6_PKN2_SHIFT;
  163. /* printf("R%x: 0x%x\n", DMD_SSD2119_GAMMA_6, data); */
  164. DMDIF_writeReg(DMD_SSD2119_GAMMA_6, data);
  165. data = 0x07 << DMD_SSD2119_GAMMA_7_PKN5_SHIFT;
  166. data |= 0x07 << DMD_SSD2119_GAMMA_7_PKN4_SHIFT;
  167. /* printf("R%x: 0x%x\n", DMD_SSD2119_GAMMA_7, data); */
  168. DMDIF_writeReg(DMD_SSD2119_GAMMA_7, data);
  169. data = 0x02 << DMD_SSD2119_GAMMA_8_PRN1_SHIFT;
  170. data |= 0x01 << DMD_SSD2119_GAMMA_8_PRN0_SHIFT;
  171. /* printf("R%x: 0x%x\n", DMD_SSD2119_GAMMA_8, data); */
  172. DMDIF_writeReg(DMD_SSD2119_GAMMA_8, data);
  173. data = 0x12 << DMD_SSD2119_GAMMA_9_VRP1_SHIFT;
  174. data |= 0x00 << DMD_SSD2119_GAMMA_9_VRP0_SHIFT;
  175. /* printf("R%x: 0x%x\n", DMD_SSD2119_GAMMA_9, data); */
  176. DMDIF_writeReg(DMD_SSD2119_GAMMA_9, data);
  177. data = 0x09 << DMD_SSD2119_GAMMA_10_VRN1_SHIFT;
  178. data |= 0x00 << DMD_SSD2119_GAMMA_10_VRN0_SHIFT;
  179. /* printf("R%x: 0x%x\n", DMD_SSD2119_GAMMA_10, data); */
  180. DMDIF_writeReg(DMD_SSD2119_GAMMA_10, data);
  181. /* Set up dimensions of the display */
  182. dimensions.xSize = DMD_HORIZONTAL_SIZE;
  183. dimensions.ySize = DMD_VERTICAL_SIZE;
  184. /* At initialization, the clip is the entire display */
  185. dimensions.xClipStart = 0;
  186. dimensions.yClipStart = 0;
  187. dimensions.clipWidth = dimensions.xSize;
  188. dimensions.clipHeight = dimensions.ySize;
  189. initialized = 1;
  190. /* Fill the entire display with black color */
  191. DMD_writeColor(0, 0, 0x00, 0x00, 0x00, dimensions.xSize * dimensions.ySize);
  192. return DMD_OK;
  193. }
  194. /**************************************************************************//**
  195. * \brief
  196. * Get the dimensions of the display and of the current clipping area
  197. *
  198. * \return
  199. * DMD_Dimensions structure containing the size of the display and the
  200. * clipping area
  201. ******************************************************************************/
  202. EMSTATUS DMD_getDisplayGeometry(DMD_DisplayGeometry **geometry)
  203. {
  204. if (!initialized)
  205. {
  206. return DMD_ERROR_DRIVER_NOT_INITIALIZED;
  207. }
  208. *geometry = &dimensions;
  209. return DMD_OK;
  210. }
  211. /**************************************************************************//**
  212. * @brief
  213. * Sets the clipping area. All coordinates given to writeData/writeColor/readData
  214. * are relative to this clipping area.
  215. *
  216. * @param xStart
  217. * X coordinate of the upper left corner of the clipping area
  218. * @param yStart
  219. * Y coordinate of the upper left corner of the clipping area
  220. * @param width
  221. * Width of the clipping area
  222. * @param height
  223. * Height of the clipping area
  224. *
  225. * @return
  226. * DMD_OK on success, otherwise error code
  227. ******************************************************************************/
  228. EMSTATUS DMD_setClippingArea(uint16_t xStart, uint16_t yStart,
  229. uint16_t width, uint16_t height)
  230. {
  231. uint16_t verticalPos;
  232. uint16_t xEnd;
  233. uint16_t yEnd;
  234. if (!initialized)
  235. {
  236. return DMD_ERROR_DRIVER_NOT_INITIALIZED;
  237. }
  238. /* Check parameters */
  239. if (xStart + width > dimensions.xSize ||
  240. yStart + height > dimensions.ySize)
  241. {
  242. return DMD_ERROR_PIXEL_OUT_OF_BOUNDS;
  243. }
  244. if (width == 0 || height == 0)
  245. {
  246. return DMD_ERROR_EMPTY_CLIPPING_AREA;
  247. }
  248. xEnd = xStart + width - 1;
  249. yEnd = yStart + height - 1;
  250. /* Set the clipping region in the display */
  251. DMDIF_writeReg(DMD_SSD2119_HORIZONTAL_RAM_ADDRESS_START_POS, xStart);
  252. DMDIF_writeReg(DMD_SSD2119_HORIZONTAL_RAM_ADDRESS_END_POS, xEnd);
  253. verticalPos = yEnd << DMD_SSD2119_VERTICAL_RAM_ADDRESS_POS_END_SHIFT;
  254. verticalPos |= yStart << DMD_SSD2119_VERTICAL_RAM_ADDRESS_POS_START_SHIFT;
  255. DMDIF_writeReg(DMD_SSD2119_VERTICAL_RAM_ADDRESS_POS, verticalPos);
  256. /* Update the dimensions structure */
  257. dimensions.xClipStart = xStart;
  258. dimensions.yClipStart = yStart;
  259. dimensions.clipWidth = width;
  260. dimensions.clipHeight = height;
  261. return DMD_OK;
  262. }
  263. /**************************************************************************//**
  264. * @brief
  265. * Set the x and y coordinate of the next pixel to draw
  266. *
  267. * @param x
  268. * X address of the pixel, relative to the current clipping area
  269. * @param y
  270. * Y address of the pixel, relative to the current clipping area
  271. *
  272. * @return
  273. * DMD_OK on success, otherwise error code
  274. ******************************************************************************/
  275. EMSTATUS setPixelAddress(uint16_t x, uint16_t y)
  276. {
  277. /* Check parameters */
  278. if (x > dimensions.clipWidth || y > dimensions.clipHeight)
  279. {
  280. return DMD_ERROR_PIXEL_OUT_OF_BOUNDS;
  281. }
  282. /* Set pixel position */
  283. DMDIF_writeReg(DMD_SSD2119_SET_X_ADDRESS_COUNTER,
  284. x + dimensions.xClipStart);
  285. DMDIF_writeReg(DMD_SSD2119_SET_Y_ADDRESS_COUNTER,
  286. y + dimensions.yClipStart);
  287. return DMD_OK;
  288. }
  289. /**************************************************************************//**
  290. * @brief
  291. * Draws pixels to the display
  292. *
  293. * @param x
  294. * X coordinate of the first pixel to be written, relative to the clipping area
  295. * @param y
  296. * Y coordinate of the first pixel to be written, relative to the clipping area
  297. * @param data
  298. * Array containing the pixel data. Each 8-bit element in the array are one color
  299. * component of the pixel, so that 3 bytes represent one pixel. The pixels are
  300. * ordered by increasing x coordinate, after the last pixel of a row, the next
  301. * pixel will be the first pixel on the next row.
  302. * @param numPixels
  303. * Number of pixels to be written
  304. *
  305. * @return
  306. * DMD_OK on success, otherwise error code
  307. ******************************************************************************/
  308. EMSTATUS DMD_writeData(uint16_t x, uint16_t y, const uint8_t data[],
  309. uint32_t numPixels)
  310. {
  311. uint32_t statusCode;
  312. uint32_t clipRemaining;
  313. uint32_t color;
  314. uint32_t i;
  315. if (!initialized)
  316. {
  317. return DMD_ERROR_DRIVER_NOT_INITIALIZED;
  318. }
  319. /* Set the address of the first pixel */
  320. statusCode = setPixelAddress(x, y);
  321. if (statusCode != DMD_OK)
  322. {
  323. return statusCode;
  324. }
  325. /* Number of pixels from the first pixel (given by x and y) to the end
  326. * of the clipping area */
  327. clipRemaining = (dimensions.clipHeight - y - 1) * dimensions.clipWidth +
  328. dimensions.clipWidth - x;
  329. /* Check that the length of data isn't longer than the number of pixels
  330. * in the rest of the clipping area */
  331. if (numPixels > clipRemaining)
  332. {
  333. return DMD_ERROR_TOO_MUCH_DATA;
  334. }
  335. /* Write data */
  336. DMDIF_prepareDataAccess( );
  337. for (i = 0; i < numPixels; i++)
  338. {
  339. color = colorTransform24To16bpp(data[3 * i], data[3 * i + 1],
  340. data[3 * i + 2]);
  341. DMDIF_writeData(color);
  342. }
  343. return DMD_OK;
  344. }
  345. /**************************************************************************//**
  346. * @brief
  347. * Draws pixels to the display at location x,y, from a source data array in
  348. * GIMP RLE compressed C-format, mixing with another RGB color to create a
  349. * "blended" look or for fading images in and out
  350. * @param x
  351. * X coordinate of the first pixel to be written, relative to the clipping area
  352. * @param y
  353. * Y coordinate of the first pixel to be written, relative to the clipping area
  354. * @param data
  355. * Array containing the pixel data in GIMP RLE compressed format
  356. * @param numPixels
  357. * Number of pixels to be written
  358. * @param red
  359. * Red component of color to mix with orignal
  360. * @param green
  361. * Red component of color to mix with orignal
  362. * @param blue
  363. * Red component of color to mix with orignal
  364. * @param weight
  365. * Ratio to which red/green/blue component and original color should be combined
  366. * @return
  367. * DMD_OK on success, otherwise error code
  368. ******************************************************************************/
  369. EMSTATUS DMD_writeDataRLEFade(uint16_t x, uint16_t y, uint16_t xlen, uint16_t ylen,
  370. const uint8_t *data,
  371. int red, int green, int blue, int weight)
  372. {
  373. uint32_t color = 0;
  374. int xpos, ypos;
  375. const uint8_t *ptr;
  376. int r,g,b;
  377. uint8_t readRGB = 0;
  378. uint8_t copyColor = 0;
  379. ptr = data;
  380. for (ypos = y; ypos < (ylen+y); ypos++){
  381. setPixelAddress(x, ypos);
  382. DMDIF_prepareDataAccess( );
  383. for (xpos = x; xpos < (xlen+x); xpos++){
  384. if ( readRGB ) {
  385. readRGB--;
  386. r = *ptr++;
  387. g = *ptr++;
  388. b = *ptr++;
  389. r = ((r * weight/100) + (red * (100-weight)/100));
  390. g = ((g * weight/100) + (green * (100-weight)/100));
  391. b = ((b * weight/100) + (blue * (100-weight)/100));
  392. color = colorTransform24To16bpp(r,g,b);
  393. DMDIF_writeData(color);
  394. continue;
  395. }
  396. if ( copyColor ) {
  397. copyColor--;
  398. DMDIF_writeData( color );
  399. continue;
  400. }
  401. if ( *ptr & 0x80 ) {
  402. copyColor = (*ptr - 0x80);
  403. ptr++;
  404. r = *ptr++;
  405. g = *ptr++;
  406. b = *ptr++;
  407. r = ((r * weight/100) + (red * (100-weight)/100));
  408. g = ((g * weight/100) + (green * (100-weight)/100));
  409. b = ((b * weight/100) + (blue * (100-weight)/100));
  410. copyColor--;
  411. }
  412. else {
  413. readRGB = *ptr;
  414. ptr++;
  415. r = *ptr++;
  416. g = *ptr++;
  417. b = *ptr++;
  418. r = ((r * weight/100) + (red * (100-weight)/100));
  419. g = ((g * weight/100) + (green * (100-weight)/100));
  420. b = ((b * weight/100) + (blue * (100-weight)/100));
  421. readRGB--;
  422. }
  423. color = colorTransform24To16bpp(r,g,b);
  424. DMDIF_writeData( color );
  425. }
  426. }
  427. return DMD_OK;
  428. }
  429. /**************************************************************************//**
  430. * @brief
  431. * Draws pixels to the display at location x,y, from a source data array in
  432. * GIMP RLE compressed C-format
  433. * @param x
  434. * X coordinate of the first pixel to be written, relative to the clipping area
  435. * @param y
  436. * Y coordinate of the first pixel to be written, relative to the clipping area
  437. * @param data
  438. * Array containing the pixel data in GIMP RLE compressed format
  439. * @param numPixels
  440. * Number of pixels to be written
  441. * @return
  442. * DMD_OK on success, otherwise error code
  443. ******************************************************************************/
  444. EMSTATUS DMD_writeDataRLE(uint16_t x, uint16_t y, uint16_t xlen, uint16_t ylen,
  445. const uint8_t *data)
  446. {
  447. uint32_t color = 0;
  448. int xpos, ypos;
  449. const uint8_t *ptr;
  450. uint8_t r,g,b;
  451. uint8_t readRGB = 0;
  452. uint8_t copyColor = 0;
  453. ptr = data;
  454. for (ypos = y; ypos < (ylen+y); ypos++){
  455. setPixelAddress(x, ypos);
  456. DMDIF_prepareDataAccess( );
  457. for (xpos = x; xpos < (xlen+x); xpos++){
  458. if ( readRGB ) {
  459. readRGB--;
  460. r = *ptr++;
  461. g = *ptr++;
  462. b = *ptr++;
  463. color = colorTransform24To16bpp(r,g,b);
  464. DMDIF_writeData(color);
  465. continue;
  466. }
  467. if ( copyColor ) {
  468. copyColor--;
  469. DMDIF_writeData( color );
  470. continue;
  471. }
  472. if ( *ptr & 0x80 ) {
  473. copyColor = (*ptr - 0x80);
  474. ptr++;
  475. r = *ptr++;
  476. g = *ptr++;
  477. b = *ptr++;
  478. copyColor--;
  479. } else {
  480. readRGB = *ptr;
  481. ptr++;
  482. r = *ptr++;
  483. g = *ptr++;
  484. b = *ptr++;
  485. readRGB--;
  486. }
  487. color = colorTransform24To16bpp(r,g,b);
  488. DMDIF_writeData( color );
  489. }
  490. }
  491. return DMD_OK;
  492. }
  493. /**************************************************************************//**
  494. * @brief
  495. * Reads data from display memory
  496. * WORKING NOW, fixed by onelife
  497. *
  498. * @param x
  499. * X coordinate of the first pixel to be read, relative to the clipping area
  500. * @param y
  501. * Y coordinate of the first pixel to be read, relative to the clipping area
  502. * @param data
  503. * Pointer to where the pixel data will be stored
  504. * @param numPixels
  505. * Number of pixels to be read
  506. *
  507. * @return
  508. * DMD_OK on success, otherwise error code
  509. ******************************************************************************/
  510. EMSTATUS DMD_readData(uint16_t x, uint16_t y,
  511. uint8_t data[], uint32_t numPixels)
  512. {
  513. uint32_t statusCode;
  514. uint32_t clipRemaining;
  515. uint32_t i;
  516. uint32_t color;
  517. uint8_t red, green, blue;
  518. if (!initialized)
  519. {
  520. return DMD_ERROR_DRIVER_NOT_INITIALIZED;
  521. }
  522. /* Set the address of the first pixel */
  523. statusCode = setPixelAddress(x, y);
  524. if (statusCode != DMD_OK)
  525. {
  526. return statusCode;
  527. }
  528. /* Number of pixels from the first pixel (given by x and y) to the end
  529. * of the clipping area */
  530. clipRemaining = (dimensions.clipHeight - y - 1) * dimensions.clipWidth +
  531. dimensions.clipWidth - x;
  532. /* Check that the length of data isn't longer than the number of pixels
  533. * in the rest of the clipping area */
  534. if (numPixels > clipRemaining)
  535. {
  536. return DMD_ERROR_TOO_MUCH_DATA;
  537. }
  538. /* Read data */
  539. DMDIF_prepareDataAccess();
  540. /* Dummy read */
  541. color = DMDIF_readData();
  542. for (i = 0; i < numPixels; i++)
  543. {
  544. /* Read the color value */
  545. color = DMDIF_readData();
  546. /* Transform into 24bpp */
  547. colorTransform16To24bpp(color, &red, &green, &blue);
  548. data[3 * i] = red;
  549. data[3 * i + 1] = green;
  550. data[3 * i + 2] = blue;
  551. }
  552. return DMD_OK;
  553. }
  554. /**************************************************************************//**
  555. * \brief
  556. * Draws a number of pixels of the same color to the display
  557. *
  558. * @param x
  559. * X coordinate of the first pixel to be written, relative to the clipping area
  560. * @param y
  561. * Y coordinate of the first pixel to be written, relative to the clipping area
  562. * @param red
  563. * Red component of the color
  564. * @param green
  565. * Green component of the color
  566. * @param blue
  567. * Blue component of the color
  568. * @param numPixels
  569. * Number of pixels to be written
  570. *
  571. * @return
  572. * DMD_OK on success, otherwise error code
  573. ******************************************************************************/
  574. EMSTATUS DMD_writeColor(uint16_t x, uint16_t y, uint8_t red,
  575. uint8_t green, uint8_t blue, uint32_t numPixels)
  576. {
  577. uint32_t clipRemaining;
  578. uint32_t statusCode;
  579. uint32_t color;
  580. if (!initialized){
  581. return DMD_ERROR_DRIVER_NOT_INITIALIZED;
  582. }
  583. /* Set the address of the first pixel */
  584. statusCode = setPixelAddress(x, y);
  585. if (statusCode != DMD_OK){
  586. return statusCode;
  587. }
  588. /* Number of pixels from the first pixel (given by x and y) to the end
  589. * of the clipping area */
  590. clipRemaining = (dimensions.clipHeight - y - 1) * dimensions.clipWidth +
  591. dimensions.clipWidth - x;
  592. /* Check that the length of data isn't longer than the number of pixels
  593. * in the rest of the clipping area */
  594. if (numPixels > clipRemaining){
  595. return DMD_ERROR_TOO_MUCH_DATA;
  596. }
  597. /* Write data */
  598. DMDIF_prepareDataAccess( );
  599. color = colorTransform24To16bpp(red, green, blue);
  600. DMDIF_writeDataRepeated(color, numPixels);
  601. return DMD_OK;
  602. }
  603. /**************************************************************************//**
  604. * @brief
  605. * Draws a number of pixels of the same color to the display
  606. * This function is added by onelife
  607. *
  608. * @param x
  609. * X coordinate of the pixel to be written, relative to the clipping area
  610. * @param y
  611. * Y coordinate of the pixel to be written, relative to the clipping area
  612. * @param color
  613. * RGB565 format
  614. * @param numPixels
  615. * Number of pixels to be written
  616. *
  617. * @return
  618. * DMD_OK on success, otherwise error code
  619. ******************************************************************************/
  620. EMSTATUS DMD_writePixel(uint16_t x, uint16_t y, uint16_t color,
  621. uint32_t numPixels)
  622. {
  623. uint32_t clipRemaining;
  624. uint32_t statusCode;
  625. if (!initialized){
  626. return DMD_ERROR_DRIVER_NOT_INITIALIZED;
  627. }
  628. /* Set the address of the first pixel */
  629. statusCode = setPixelAddress(x, y);
  630. if (statusCode != DMD_OK){
  631. return statusCode;
  632. }
  633. /* Number of pixels from the first pixel (given by x and y) to the end
  634. * of the clipping area */
  635. clipRemaining = (dimensions.clipHeight - y - 1) * dimensions.clipWidth +
  636. dimensions.clipWidth - x;
  637. /* Check that the length of data isn't longer than the number of pixels
  638. * in the rest of the clipping area */
  639. if (numPixels > clipRemaining){
  640. return DMD_ERROR_TOO_MUCH_DATA;
  641. }
  642. /* Write data */
  643. DMDIF_prepareDataAccess( );
  644. DMDIF_writeDataRepeated((uint32_t)color, numPixels);
  645. return DMD_OK;
  646. }
  647. /**************************************************************************//**
  648. * @brief
  649. * Read the color of a specified pixel
  650. * This function is added by onelife
  651. *
  652. * @param x
  653. * X coordinate of the pixel to be written, relative to the clipping area
  654. * @param y
  655. * Y coordinate of the pixel to be written, relative to the clipping area
  656. * @param color
  657. * RGB565 format
  658. *
  659. * @return
  660. * DMD_OK on success, otherwise error code
  661. ******************************************************************************/
  662. EMSTATUS DMD_readPixel(uint16_t x, uint16_t y, uint16_t *color)
  663. {
  664. uint32_t statusCode;
  665. if (!initialized){
  666. return DMD_ERROR_DRIVER_NOT_INITIALIZED;
  667. }
  668. /* Set the address of the first pixel */
  669. statusCode = setPixelAddress(x, y);
  670. if (statusCode != DMD_OK){
  671. return statusCode;
  672. }
  673. /* Read color */
  674. DMDIF_prepareDataAccess( );
  675. *color = DMDIF_readData() & 0x0000FFFF;
  676. return DMD_OK;
  677. }
  678. /**************************************************************************//**
  679. * @brief
  680. * Turns off the display and puts it into sleep mode
  681. * Does not turn off backlight
  682. *
  683. * @return
  684. * DMD_OK on success, otherwise error code
  685. ******************************************************************************/
  686. EMSTATUS DMD_sleep(void){
  687. uint16_t data;
  688. if (!initialized){
  689. return DMD_ERROR_DRIVER_NOT_INITIALIZED;
  690. }
  691. /* Put into sleep mode */
  692. data = DMD_SSD2119_SLEEP_MODE_1_SLP;
  693. DMDIF_writeReg(DMD_SSD2119_SLEEP_MODE_1, data);
  694. /* Turn off display */
  695. data = 0;
  696. DMDIF_writeReg(DMD_SSD2119_DISPLAY_CONTROL, 0x0000);
  697. /* Delay 1.5 frame */
  698. /*DMDIF_delay((1000 / DMD_FRAME_FREQUENCY) * 3 / 2);*/
  699. return DMD_OK;
  700. }
  701. /**************************************************************************//**
  702. * @brief
  703. * Wakes up the display from sleep mode
  704. *
  705. * @return
  706. * DMD_OK on success, otherwise error code
  707. ******************************************************************************/
  708. EMSTATUS DMD_wakeUp(void){
  709. uint16_t data;
  710. if (!initialized){
  711. return DMD_ERROR_DRIVER_NOT_INITIALIZED;
  712. }
  713. /* Get out of sleep mode */
  714. data = 0;
  715. DMDIF_writeReg(DMD_SSD2119_SLEEP_MODE_1, data);
  716. /* Turn on display */
  717. data = DMD_SSD2119_DISPLAY_CONTROL_DTE;
  718. data |= DMD_SSD2119_DISPLAY_CONTROL_GON;
  719. data |= DMD_SSD2119_DISPLAY_CONTROL_D1;
  720. data |= DMD_SSD2119_DISPLAY_CONTROL_D0;
  721. DMDIF_writeReg(DMD_SSD2119_DISPLAY_CONTROL, 0x0033);
  722. /* Delay 10 frames */
  723. /*DMDIF_delay((1000 / DMD_FRAME_FREQUENCY) * 10);*/
  724. return DMD_OK;
  725. }
  726. /**************************************************************************//**
  727. * @brief
  728. * Transforms a 24bpp pixel data into an 16bpp pixel
  729. *
  730. * @param red
  731. * 8-bit red component of the pixel
  732. * @param green
  733. * 8-bit green component of the pixel
  734. * @param blue
  735. * 8-bit blue component of the pixel
  736. * @return
  737. * 16bpp value of pixel
  738. ******************************************************************************/
  739. static uint32_t colorTransform24To16bpp(uint8_t red, uint8_t green, uint8_t blue){
  740. /* Transform each color into 6 bits by dropping the 2 LSB */
  741. red = (red >> 3) & 0x1F;
  742. green = (green >> 2) & 0x3F;
  743. blue = (blue >> 3) & 0x1F;
  744. /* Put it together to one 16bpp color number */
  745. return (red << 11) | (green << 5) | blue;
  746. }
  747. /**************************************************************************//**
  748. * @brief
  749. * Transforms an 18 bpp pixel into a 24bpp pixel
  750. *
  751. * @param color
  752. * 16bpp color pixel
  753. * @param red
  754. * return value for red component of 24bpp pixel
  755. * @param green
  756. * return value for green component of 24bpp pixel
  757. * @param blue
  758. * return value for blue component of 24bpp pixel
  759. ******************************************************************************/
  760. static void colorTransform16To24bpp(uint32_t color, uint8_t *red,
  761. uint8_t *green, uint8_t *blue){
  762. /* Get the individual colors out of the 16bpp number */
  763. uint8_t redValue = (color & 0x0000F800) >> 11;
  764. uint8_t greenValue = (color & 0x000007E0) >> 5;
  765. uint8_t blueValue = (color & 0x0000001F);
  766. /* Convert each color to 8-bit */
  767. redValue <<= 3;
  768. greenValue <<= 2;
  769. blueValue <<= 3;
  770. *red = redValue;
  771. *green = greenValue;
  772. *blue = blueValue;
  773. return;
  774. }
  775. /**************************************************************************//**
  776. * @brief
  777. * Set horizontal and vertical flip mode of display controller
  778. *
  779. * @param hor
  780. * Set to flip display horizontally
  781. *
  782. * @param ver
  783. * Set to flip display vertically
  784. *
  785. * @return
  786. * Returns DMD_OK is successful, error otherwise.
  787. ******************************************************************************/
  788. EMSTATUS DMD_flipDisplay(int horizontal, int vertical){
  789. uint16_t reg;
  790. reg = rcDriverOutputControl;
  791. if (horizontal) reg &= ~DMD_SSD2119_DRIVER_OUTPUT_CONTROL_RL;
  792. else reg |= DMD_SSD2119_DRIVER_OUTPUT_CONTROL_RL;
  793. if (vertical) reg &= ~DMD_SSD2119_DRIVER_OUTPUT_CONTROL_TB;
  794. else reg |= DMD_SSD2119_DRIVER_OUTPUT_CONTROL_TB;
  795. rcDriverOutputControl = reg;
  796. DMDIF_writeReg(DMD_SSD2119_DRIVER_OUTPUT_CONTROL, rcDriverOutputControl);
  797. return DMD_OK;
  798. }