1 /**************************************************************************/
7 Is written for MI0283QT-2 LCD from watterott.com
8 More infos: http://www.watterott.com/de/MI0283QT-2-Adapter
9 Based on Watterott C Lib for MI0283QT-2
10 http://www.watterott.com/index.php?page=product&info=1597&dl_media=3202
14 Software License Agreement (BSD License)
16 Copyright (c) 2010, microBuilder SARL
19 Redistribution and use in source and binary forms, with or without
20 modification, are permitted provided that the following conditions are met:
21 1. Redistributions of source code must retain the above copyright
22 notice, this list of conditions and the following disclaimer.
23 2. Redistributions in binary form must reproduce the above copyright
24 notice, this list of conditions and the following disclaimer in the
25 documentation and/or other materials provided with the distribution.
26 3. Neither the name of the copyright holders nor the
27 names of its contributors may be used to endorse or promote products
28 derived from this software without specific prior written permission.
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
31 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 /**************************************************************************/
42 #include "drivers/displays/tft/hw/hx8347d.h"
45 #define LCD_DATA ((0x72)|(LCD_ID<<2))
46 #define LCD_REGISTER ((0x70)|(LCD_ID<<2))
48 #define LCD_BACK_LIGHT 6
52 // Macros for control line state
53 #define LCD_CS_ENABLE() GPIO_GPIO2DATA &= ~0x10 // gpioSetValue(2, 4, 0)
54 #define LCD_CS_DISABLE() GPIO_GPIO2DATA |= 0x10 // gpioSetValue(2, 4, 1)
55 #define LCD_RST_ENABLE() GPIO_GPIO2DATA &= ~0x20 // gpioSetValue(2, 5, 0)
56 #define LCD_RST_DISABLE() GPIO_GPIO2DATA |= 0x20 // gpioSetValue(2, 5, 1)
59 #define Display_Mode_Control 0x01
61 #define Column_Address_Start_2 0x02
62 #define Column_Address_Start_1 0x03
63 #define Column_Address_End_2 0x04
64 #define Column_Address_End_1 0x05
66 #define Row_Address_Start_2 0x06
67 #define Row_Address_Start_1 0x07
68 #define Row_Address_End_2 0x08
69 #define Row_Address_End_1 0x09
71 #define Partial_Area_Start_Row_2 0x0A
72 #define Partial_Area_Start_Row_1 0x0B
73 #define Partial_Area_End_Row_2 0x0C
74 #define Partial_Area_End_Row_1 0x0D
76 #define TFA_REGISTER 0x0E
77 #define VSA_REGISTER 0x10
78 #define BFA_REGISTER 0x12
79 #define VSP_REGISTER 0x14
82 #define OSC_Control_1 0x18
83 #define OSC_Control_2 0x19
84 #define Power_Control_1 0x1A
85 #define Power_Control_2 0x1B
86 #define Power_Control_3 0x1C
87 #define Power_Control_4 0x1D
88 #define Power_Control_5 0x1E
89 #define Power_Control_6 0x1F
90 #define VCOM_Control_1 0x23
91 #define VCOM_Control_2 0x24
92 #define VCOM_Control_3 0x25
93 #define Display_Control_1 0x26
94 #define Display_Control_2 0x27
95 #define Display_Control_3 0x28
96 #define Source_OP_Control_Normal 0xE8
97 #define Source_OP_Control_IDLE 0xE9
98 #define Power_Control_Internal_1 0xEA
99 #define Power_Control_Internal_2 0xEB
100 #define Source_Control_Internal_1 0xEC
101 #define Source_Control_Internal_2 0xED
103 #define OSC_Control_2_OSC_EN 0x01
104 #define Display_Control_3_GON 0x20
105 #define Display_Control_3_DTE 0x10
106 #define Display_Control_3_D0 0x04
107 #define Display_Control_3_D1 0x08
108 #define Power_Control_6_STB 0x01
109 #define Display_Mode_Control_DP_STB_S 0x40
110 #define Display_Mode_Control_DP_STB 0x80
113 /*************************************************/
114 /* Private Methods */
115 /*************************************************/
116 void lcd_drawstart(void);
117 void lcd_cmd(unsigned int reg
, unsigned int param
);
118 void lcd_clear(unsigned int color
);
119 void lcd_draw(unsigned int color
);
120 void lcd_drawstart(void);
121 void lcd_drawstop(void);
122 void hx8347d_DisplayOnFlow(void);
123 void hx8347d_DisplayOffFlow(void);
124 void lcd_area(unsigned int x0
, unsigned int y0
, unsigned int x1
, unsigned int y1
);
127 void hx8347d_Scroll(uint16_t tfa
,uint16_t vsa
,uint16_t bfa
, uint16_t vsp
)
129 lcd_cmd(TFA_REGISTER
, tfa
>> 8);
130 lcd_cmd(TFA_REGISTER
+ 1, tfa
& 0xFF);
132 lcd_cmd(VSA_REGISTER
, vsa
>> 8);
133 lcd_cmd(VSA_REGISTER
+ 1, vsa
& 0xFF);
135 lcd_cmd(BFA_REGISTER
, bfa
>> 8);
136 lcd_cmd(BFA_REGISTER
+ 1, bfa
& 0xFF);
138 lcd_cmd(VSP_REGISTER
, vsp
>> 8);
139 lcd_cmd(VSP_REGISTER
+ 1, vsp
& 0xFF);
140 lcd_cmd(0x01, 0x08); //scroll on
143 void displayOnFlow(void)
145 lcd_cmd(Display_Control_3
, 0x0038);
147 lcd_cmd(Display_Control_3
, 0x003C);
149 void displayOffFlow(void)
151 lcd_cmd(Display_Control_3
, Display_Control_3_GON
| Display_Control_3_DTE
| Display_Control_3_D1
);
153 lcd_cmd(Display_Control_3
, Display_Control_3_D0
);
156 void lcd_cmd(unsigned int reg
, unsigned int param
)
162 b_first
[0] = LCD_REGISTER
;
165 sspSend(0, b_first
, 2);
172 sspSend(0, b_sec
, 2);
177 void lcd_clear(unsigned int color
)
181 lcd_area(0, 0, (hx8347dProperties
.width
-1), (hx8347dProperties
.height
-1));
184 for(i
=(hx8347dProperties
.width
*hx8347dProperties
.height
/8); i
!=0; i
--)
200 void lcd_draw(unsigned int color
)
202 // Writing data in 16Bit mode for saving a lot of time
203 /* Move on only if NOT busy and TX FIFO not full. */
204 while ((SSP_SSP0SR
& (SSP_SSP0SR_TNF_NOTFULL
| SSP_SSP0SR_BSY_BUSY
)) != SSP_SSP0SR_TNF_NOTFULL
);
207 while ( (SSP_SSP0SR
& (SSP_SSP0SR_BSY_BUSY
|SSP_SSP0SR_RNE_NOTEMPTY
)) != SSP_SSP0SR_RNE_NOTEMPTY
);
208 /* Whenever a byte is written, MISO FIFO counter increments, Clear FIFO
209 on MISO. Otherwise, when SSP0Receive() is called, previous data byte
210 is left in the FIFO. */
211 uint8_t Dummy
= SSP_SSP0DR
;
215 void lcd_drawstop(void)
217 while ((SSP_SSP0SR
& SSP_SSP0SR_TFE_MASK
) != SSP_SSP0SR_TFE_EMPTY
);
220 // init 8Bit SPI Mode
221 SSP_SSP0CR0
&= ~SSP_SSP0CR0_DSS_MASK
;
222 SSP_SSP0CR0
|= SSP_SSP0CR0_DSS_8BIT
;
226 void lcd_drawstart(void)
231 b_first
[0] = LCD_REGISTER
;
233 sspSend(0, b_first
, 2);
238 sspSend(0, b_sec
, 1);
241 // Assign config values to SSP0CR0
242 // init 16Bit SPI Mode for fast data transmitting
243 SSP_SSP0CR0
&= ~SSP_SSP0CR0_DSS_MASK
;
244 SSP_SSP0CR0
|= SSP_SSP0CR0_DSS_16BIT
;
250 void lcd_area(unsigned int x0
, unsigned int y0
, unsigned int x1
, unsigned int y1
)
252 y0
= ((320-offset
)+ y0
) % 320;
253 y1
= ((320-offset
)+ y1
) % 320;
254 lcd_cmd(Column_Address_Start_1
, (x0
>>0)); //set x0
255 lcd_cmd(Column_Address_Start_2
, (x0
>>8)); //set x0
256 lcd_cmd(Column_Address_End_1
, (x1
>>0)); //set x1
257 lcd_cmd(Column_Address_End_2
, (x1
>>8)); //set x1
258 lcd_cmd(Row_Address_Start_1
, (y0
>>0)); //set y0
259 lcd_cmd(Row_Address_Start_2
, (y0
>>8)); //set y0
260 lcd_cmd(Row_Address_End_1
, (y1
>>0)); //set y1
261 lcd_cmd(Row_Address_End_2
, (y1
>>8)); //set y1
265 void lcd_cursor(unsigned int x
, unsigned int y
)
267 lcd_area(x
, y
, x
, y
);
270 void lcd_data(unsigned int c
)
285 void fillRect(uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
303 if(x1
>= hx8347dProperties
.width
)
305 x1
= hx8347dProperties
.width
-1;
307 if(y1
>= hx8347dProperties
.height
)
309 y1
= hx8347dProperties
.height
-1;
312 lcd_area(x0
, y0
, x1
, y1
);
315 size
= (uint32_t)(1+(x1
-x0
)) * (uint32_t)(1+(y1
-y0
));
319 for(i
=tmp
; i
!=0; i
--)
330 for(i
=size
-tmp
; i
!=0; i
--)
337 for(i
=size
; i
!=0; i
--)
347 /*************************************************/
349 /*************************************************/
351 /**************************************************************************/
353 @brief Configures any pins or HW and initialises the LCD controller
355 /**************************************************************************/
360 gpioSetDir(2, LCD_CS
, gpioDirection_Output
);
361 gpioSetDir(2, LCD_RST
, gpioDirection_Output
);
362 gpioSetDir(2, LCD_BACK_LIGHT
, gpioDirection_Output
);
373 lcd_cmd(Power_Control_Internal_1
, 0x0000);
374 lcd_cmd(Power_Control_Internal_2
, 0x0020);
375 lcd_cmd(Source_Control_Internal_1
, 0x000C);
376 lcd_cmd(Source_Control_Internal_2
, 0x00C4);
377 lcd_cmd(Source_OP_Control_Normal
, 0x0040);
378 lcd_cmd(Source_OP_Control_IDLE
, 0x0038);
379 lcd_cmd(0xF1, 0x0001);
380 lcd_cmd(0xF2, 0x0010);
381 lcd_cmd(0x27, 0x00A3);
384 lcd_cmd(Power_Control_2
, 0x001B);
385 lcd_cmd(Power_Control_1
, 0x0001);
386 lcd_cmd(VCOM_Control_2
, 0x002F);
387 lcd_cmd(VCOM_Control_3
, 0x0057);
390 lcd_cmd(VCOM_Control_1
, 0x008D); //for flicker adjust
393 lcd_cmd(OSC_Control_1
, 0x0036);
394 lcd_cmd(OSC_Control_2
, 0x0001); //start osc
395 lcd_cmd(Display_Mode_Control
, 0x0000); //wakeup
396 lcd_cmd(Power_Control_6
, 0x0088);
398 lcd_cmd(Power_Control_6
, 0x0080);
400 lcd_cmd(Power_Control_6
, 0x0090);
402 lcd_cmd(Power_Control_6
, 0x00D0);
406 lcd_cmd(COLMOD
, 0x0005); //0x0005=65k, 0x0006=262k
408 //panel characteristic
409 lcd_cmd(0x36, 0x0000);
412 lcd_cmd(0x28, 0x0038);
414 lcd_cmd(0x28, 0x003C);
416 lcdSetOrientation(hx8347dPOrientation
);
419 /**************************************************************************/
421 @brief Enables or disables the LCD backlight
423 /**************************************************************************/
424 void lcdBacklight(bool state
)
426 gpioSetValue(2, LCD_BACK_LIGHT
, state
);
429 /**************************************************************************/
431 @brief Renders a simple test pattern on the LCD
433 /**************************************************************************/
436 lcdFillRGB(COLOR_CYAN
);
440 /**************************************************************************/
442 @brief Fills the LCD with the specified 16-bit color
444 /**************************************************************************/
445 void lcdFillRGB(uint16_t data
)
450 /**************************************************************************/
452 @brief Draws a single pixel at the specified X/Y location
454 /**************************************************************************/
455 void lcdDrawPixel(uint16_t x
, uint16_t y
, uint16_t color
)
457 if((x
>= hx8347dProperties
.width
) ||
458 (y
>= hx8347dProperties
.height
))
463 fillRect(x
,y
,x
,y
,color
);
468 /**************************************************************************/
470 @brief Draws an array of consecutive RGB565 pixels (much
471 faster than addressing each pixel individually)
473 /**************************************************************************/
474 void lcdDrawPixels(uint16_t x
, uint16_t y
, uint16_t *data
, uint32_t len
)
476 lcd_area(x
, y
, x
+ len
, y
);
479 for(i
= 0; i
< len
; i
++)
488 /**************************************************************************/
490 @brief Optimised routine to draw a horizontal line faster than
491 setting individual pixels
493 /**************************************************************************/
494 void lcdDrawHLine(uint16_t x0
, uint16_t x1
, uint16_t y
, uint16_t color
)
506 if(x0
>= hx8347dProperties
.width
)
508 x0
= hx8347dProperties
.width
-1;
510 if(x1
>= hx8347dProperties
.width
)
512 x1
= hx8347dProperties
.width
-1;
514 if(y
>= hx8347dProperties
.height
)
516 y
= hx8347dProperties
.height
-1;
519 fillRect(x0
, y
, x1
, y
, color
);
523 /**************************************************************************/
525 @brief Optimised routine to draw a vertical line faster than
526 setting individual pixels
528 /**************************************************************************/
529 void lcdDrawVLine(uint16_t x
, uint16_t y0
, uint16_t y1
, uint16_t color
)
541 if(x
>= hx8347dProperties
.width
)
543 x
= hx8347dProperties
.width
-1;
546 if(y0
>= hx8347dProperties
.height
)
548 y0
= hx8347dProperties
.height
-1;
550 if(y1
>= hx8347dProperties
.height
)
552 y1
= hx8347dProperties
.height
-1;
555 fillRect(x
, y0
, x
, y1
, color
);
558 /**************************************************************************/
560 @brief Gets the 16-bit color of the pixel at the specified location
562 /**************************************************************************/
563 uint16_t lcdGetPixel(uint16_t x
, uint16_t y
)
567 /**************************************************************************/
569 @brief Sets the LCD orientation to horizontal and vertical
571 /**************************************************************************/
572 void lcdSetOrientation(lcdOrientation_t orientation
)
574 if(orientation
== LCD_ORIENTATION_LANDSCAPE
)
576 lcd_cmd(0x16, 0x00A8); //MY=1 MX=0 MV=1 ML=0 BGR=1
577 hx8347dProperties
.width
= 320;
578 hx8347dProperties
.height
= 240;
582 //lcd_cmd(0x16, 0x0008); //MY=0 MX=0 MV=0 ML=0 BGR=1
583 lcd_cmd(0x16, 0x00C8); //MY=1 MX=0 MV=1 ML=0 BGR=1
584 hx8347dProperties
.width
= 240;
585 hx8347dProperties
.height
= 320;
587 hx8347dPOrientation
= orientation
;
588 lcd_area(0, 0, (hx8347dProperties
.width
-1), (hx8347dProperties
.height
-1));
591 /**************************************************************************/
593 @brief Gets the current screen orientation (horizontal or vertical)
595 /**************************************************************************/
596 lcdOrientation_t
lcdGetOrientation(void)
598 return hx8347dPOrientation
;
601 /**************************************************************************/
603 @brief Gets the width in pixels of the LCD screen (varies depending
604 on the current screen orientation)
606 /**************************************************************************/
607 uint16_t lcdGetWidth(void)
609 return hx8347dProperties
.width
;
612 /**************************************************************************/
614 @brief Gets the height in pixels of the LCD screen (varies depending
615 on the current screen orientation)
617 /**************************************************************************/
618 uint16_t lcdGetHeight(void)
620 return hx8347dProperties
.height
;
623 /**************************************************************************/
625 @brief Scrolls the contents of the LCD screen vertically the
626 specified number of pixels using a HW optimised routine
628 /**************************************************************************/
630 void lcdScroll(int16_t pixels
, uint16_t fillColor
)
633 hx8347d_Scroll(0,320,0,(offset
+ pixels
) % 320);
634 if(hx8347dPOrientation
== LCD_ORIENTATION_PORTRAIT
)
636 fillRect(0, hx8347dProperties
.height
-pixels
, hx8347dProperties
.width
, hx8347dProperties
.height
, fillColor
);
640 fillRect(hx8347dProperties
.width
-pixels
, 0, hx8347dProperties
.width
, hx8347dProperties
.height
, fillColor
);
642 offset
= (offset
+ pixels
) % 320;
644 /**************************************************************************/
646 @brief Set LCD into standby
647 In deep standby: LCD has lower power consumption
649 /**************************************************************************/
650 void hx8347d_Standby(bool deep
)
653 lcd_cmd(Power_Control_6
, Power_Control_6_STB
);
656 lcd_cmd(Display_Mode_Control
,Display_Mode_Control_DP_STB_S
);
657 lcd_cmd(Display_Mode_Control
, Display_Mode_Control_DP_STB
);
659 lcd_cmd(OSC_Control_2
, ~OSC_Control_2_OSC_EN
);
661 /**************************************************************************/
663 @brief Wakeup LCD from standby
664 Wakeup from deep standby you need min. 20ms
666 /**************************************************************************/
667 void hx8347d_Wakeup(bool deep
)
669 lcd_cmd(OSC_Control_2
, OSC_Control_2_OSC_EN
);
673 lcd_cmd(Display_Mode_Control
,0x0000);
675 lcd_cmd(Display_Mode_Control
, 0x0000);
682 lcd_cmd(Power_Control_6
, 0x00D0);
686 /**************************************************************************/
688 @brief Gets the controller's 16-bit (4 hexdigit) ID
690 /**************************************************************************/
691 uint16_t lcdGetControllerID(void)
696 /**************************************************************************/
698 @brief Returns the LCDs 'lcdProperties_t' that describes the LCDs
699 generic capabilities and dimensions
701 /**************************************************************************/
702 lcdProperties_t
lcdGetProperties(void)
704 return hx8347dProperties
;