Add support for NT35702 display controller.
This commit is contained in:
@@ -156,6 +156,7 @@ struct gpanel_hw {
|
|||||||
const unsigned short *bits);
|
const unsigned short *bits);
|
||||||
};
|
};
|
||||||
extern void st7781_init_display(struct gpanel_hw *hw);
|
extern void st7781_init_display(struct gpanel_hw *hw);
|
||||||
|
extern void nt35702_init_display(struct gpanel_hw *hw);
|
||||||
|
|
||||||
#endif /* KERNEL */
|
#endif /* KERNEL */
|
||||||
|
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ const struct cdevsw cdevsw[] = {
|
|||||||
#if GPANEL_MAJOR != 16
|
#if GPANEL_MAJOR != 16
|
||||||
# error Wrong GPANEL_MAJOR value!
|
# error Wrong GPANEL_MAJOR value!
|
||||||
#endif
|
#endif
|
||||||
#if defined(HXTFT_ENABLED) || defined(SWTFT_ENABLED)
|
#if defined(HXTFT_ENABLED) || defined(GPANEL_ENABLED)
|
||||||
gpanel_open, gpanel_close, gpanel_read, gpanel_write,
|
gpanel_open, gpanel_close, gpanel_read, gpanel_write,
|
||||||
gpanel_ioctl, nulldev, 0, seltrue,
|
gpanel_ioctl, nulldev, 0, seltrue,
|
||||||
nostrategy, 0, 0,
|
nostrategy, 0, 0,
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ pic32/sysctl.c standard
|
|||||||
pic32/adc.c optional adc
|
pic32/adc.c optional adc
|
||||||
pic32/glcd.c optional glcd
|
pic32/glcd.c optional glcd
|
||||||
pic32/gpanel.c optional gpanel
|
pic32/gpanel.c optional gpanel
|
||||||
|
pic32/gpanel-nt35702.c optional gpanel
|
||||||
pic32/gpanel-st7781.c optional gpanel
|
pic32/gpanel-st7781.c optional gpanel
|
||||||
pic32/gpio.c optional gpio
|
pic32/gpio.c optional gpio
|
||||||
pic32/hx8357.c optional hxtft
|
pic32/hx8357.c optional hxtft
|
||||||
|
|||||||
482
sys/pic32/gpanel-nt35702.c
Normal file
482
sys/pic32/gpanel-nt35702.c
Normal file
@@ -0,0 +1,482 @@
|
|||||||
|
/*
|
||||||
|
* Display driver for NT35702 LCD controller.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Serge Vakulenko <serge@vak.ru>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software
|
||||||
|
* and its documentation for any purpose and without fee is hereby
|
||||||
|
* granted, provided that the above copyright notice appear in all
|
||||||
|
* copies and that both that the copyright notice and this
|
||||||
|
* permission notice and warranty disclaimer appear in supporting
|
||||||
|
* documentation, and that the name of the author not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the
|
||||||
|
* software without specific, written prior permission.
|
||||||
|
*
|
||||||
|
* The author disclaim all warranties with regard to this
|
||||||
|
* software, including all implied warranties of merchantability
|
||||||
|
* and fitness. In no event shall the author be liable for any
|
||||||
|
* special, indirect or consequential damages or any damages
|
||||||
|
* whatsoever resulting from loss of use, data or profits, whether
|
||||||
|
* in an action of contract, negligence or other tortious action,
|
||||||
|
* arising out of or in connection with the use or performance of
|
||||||
|
* this software.
|
||||||
|
*/
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/gpanel.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Display size.
|
||||||
|
*/
|
||||||
|
static int _width, _height;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NT35702 registers.
|
||||||
|
*/
|
||||||
|
#define NT35702_NOP 0x00 /* No Operation */
|
||||||
|
#define NT35702_SWRESET 0x01 /* Software reset */
|
||||||
|
#define NT35702_RDDID 0x04 /* Read Display ID */
|
||||||
|
#define NT35702_RDDST 0x09 /* Read Display Status */
|
||||||
|
#define NT35702_RDDPM 0x0A /* Read Display Power Mode */
|
||||||
|
#define NT35702_RDDMADCTR 0x0B /* Read Display MADCTR */
|
||||||
|
#define NT35702_RDDCOLMOD 0x0C /* Read Display Pixel Format */
|
||||||
|
#define NT35702_RDDIM 0x0D /* Read Display Image Mode */
|
||||||
|
#define NT35702_RDDSM 0x0E /* Read Display Signal Mode */
|
||||||
|
#define NT35702_RDDSDR 0x0F /* Read Display Self-diagnostic result */
|
||||||
|
#define NT35702_SLPIN 0x10 /* Sleep in & booster off */
|
||||||
|
#define NT35702_SLPOUT 0x11 /* Sleep out & booster on */
|
||||||
|
#define NT35702_PTLON 0x12 /* Partial mode on */
|
||||||
|
#define NT35702_NORON 0x13 /* Partial off (Normal) */
|
||||||
|
#define NT35702_DSBCTL 0x15 /* Deep Standby mode control */
|
||||||
|
#define NT35702_INVOFF 0x20 /* Inversion off (normal) */
|
||||||
|
#define NT35702_INVON 0x21 /* Inversion on */
|
||||||
|
#define NT35702_DISPOFF 0x28 /* Display off */
|
||||||
|
#define NT35702_DISPON 0x29 /* Display on */
|
||||||
|
#define NT35702_CASET 0x2A /* Column address set */
|
||||||
|
#define NT35702_RASET 0x2B /* Row address set */
|
||||||
|
#define NT35702_RAMWR 0x2C /* Memory write */
|
||||||
|
#define NT35702_PTLAR 0x30 /* Partial start/end address set */
|
||||||
|
#define NT35702_SCRLAR 0x33 /* Scroll area set */
|
||||||
|
#define NT35702_TEOFF 0x34 /* Tearing effect line off */
|
||||||
|
#define NT35702_TEON 0x35 /* Tearing effect mode set & on */
|
||||||
|
#define NT35702_MADCTL 0x36 /* Memory data access control */
|
||||||
|
#define NT35702_VSCSAD 0x37 /* Scroll start address of RAM */
|
||||||
|
#define NT35702_IDMOFF 0x38 /* Idle mode off */
|
||||||
|
#define NT35702_IDMON 0x39 /* Idle mode on */
|
||||||
|
#define NT35702_COLMOD 0x3A /* Interface pixel format */
|
||||||
|
#define NT35702_WRDISBV 0x51 /* Write Display Brightness */
|
||||||
|
#define NT35702_WRCTRLD 0x53 /* Write CTRL Display */
|
||||||
|
#define NT35702_WRCABC 0x55 /* Write Content Adaptive Brightness Control */
|
||||||
|
#define NT35702_WRCABCMB 0x5E /* Write CABC minimum brightness */
|
||||||
|
#define NT35702_RDPWM 0x6A /* Read CABC Brightness */
|
||||||
|
#define NT35702_WRPWMF 0x6B /* Write the PWM Frequency for CABC */
|
||||||
|
#define NT35702_CABC_FOR_CE 0x77 /* Force CABC PWM in Some Conditions */
|
||||||
|
#define NT35702_CABCDMT 0x79 /* Set Dimming Time Length for CABC */
|
||||||
|
#define NT35702_RDID1 0xDA /* Read IDB */
|
||||||
|
#define NT35702_RDID2 0xDB /* Read ID2 */
|
||||||
|
#define NT35702_RDID3 0xDC /* Read ID3 */
|
||||||
|
|
||||||
|
#define NT35702_INVCTR 0xB4 /* Display inversion control */
|
||||||
|
#define NT35702_DISSET5 0xB6 /* Display function setting */
|
||||||
|
#define NT35702_SDOCTR 0xB7 /* SD output direction control */
|
||||||
|
#define NT35702_GDOCTR 0xB8 /* GD output direction control */
|
||||||
|
#define NT35702_PWCTR1 0xC0 /* Power control setting
|
||||||
|
* VRH: Set the GVDD */
|
||||||
|
#define NT35702_PWCTR2 0xC1 /* Power control setting */
|
||||||
|
#define NT35702_PWCTR3 0xC2 /* In normal mode (Full colors)
|
||||||
|
* AP: adjust the operational amplifier
|
||||||
|
* DC: adjust the booster circuit for normal mode */
|
||||||
|
#define NT35702_PWCTR4 0xC3 /* In Idle mode (8-colors)
|
||||||
|
* AP: adjust the operational amplifier
|
||||||
|
* DC: adjust the booster circuit for Idle mode */
|
||||||
|
#define NT35702_PWCTR5 0xC4 /* In partial mode + Full colors
|
||||||
|
* AP: adjust the operational amplifier
|
||||||
|
* DC: adjust the booster circuit for Idle mode */
|
||||||
|
#define NT35702_VMCTR1 0xC5 /* VMH: VCOMH voltage control
|
||||||
|
* VML: VCOML voltage control */
|
||||||
|
#define NT35702_VMOFCTR 0xC7 /* VMF: VCOM offset control */
|
||||||
|
#define NT35702_RVMOFCTR 0xC8 /* Read the VMOF value form NV memory */
|
||||||
|
#define NT35702_WRID2 0xD1 /* LCM version code
|
||||||
|
* Write ID2 value to NV memory */
|
||||||
|
#define NT35702_WRID3 0xD2 /* Customer Project code
|
||||||
|
* Write ID3 value to NV memory */
|
||||||
|
#define NT35702_RDID4 0xD3 /* ID41: IC vendor code
|
||||||
|
* ID42: IC part number code
|
||||||
|
* ID43 & ID44: chip version code */
|
||||||
|
#define NT35702_MTP 0xD4 /* MTP access program enable */
|
||||||
|
#define NT35702_EPWRITE 0xD5 /* NV write command */
|
||||||
|
#define NT35702_MTPSUP 0xD7 /* MTP speed up */
|
||||||
|
#define NT35702_GAMCTRP1 0xE0 /* Gamma adjustment (+ polarity) */
|
||||||
|
#define NT35702_GAMCTRN1 0xE1 /* Gamma adjustment (- polarity) */
|
||||||
|
#define NT35702_FRMCTR 0xFA /* Frame rate control */
|
||||||
|
#define NT35702_AVDDCLP 0xFD /* AVDD Clamp Voltage */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write a 8-bit value to the NT35702 Command register.
|
||||||
|
*/
|
||||||
|
static void write_command(int cmd)
|
||||||
|
{
|
||||||
|
gpanel_rs_command();
|
||||||
|
gpanel_write_byte(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write a 8-bit value to the NT35702 Data register.
|
||||||
|
*/
|
||||||
|
static void write_data(int cmd)
|
||||||
|
{
|
||||||
|
gpanel_rs_data();
|
||||||
|
gpanel_write_byte(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set address window.
|
||||||
|
*/
|
||||||
|
static void set_window(int x0, int y0, int x1, int y1)
|
||||||
|
{
|
||||||
|
write_command(NT35702_CASET);
|
||||||
|
write_data(x0 >> 8);
|
||||||
|
gpanel_write_byte(x0);
|
||||||
|
gpanel_write_byte(x1 >> 8);
|
||||||
|
gpanel_write_byte(x1);
|
||||||
|
|
||||||
|
write_command(NT35702_RASET);
|
||||||
|
write_data(y0 >> 8);
|
||||||
|
gpanel_write_byte(y0);
|
||||||
|
gpanel_write_byte(y1 >> 8);
|
||||||
|
gpanel_write_byte(y1);
|
||||||
|
|
||||||
|
write_command(NT35702_RAMWR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Draw a pixel.
|
||||||
|
*/
|
||||||
|
static void nt35702_set_pixel(int x, int y, int color)
|
||||||
|
{
|
||||||
|
if (x < 0 || x >= _width || y < 0 || y >= _height)
|
||||||
|
return;
|
||||||
|
gpanel_cs_active();
|
||||||
|
set_window(x, y, x, y);
|
||||||
|
write_data(color >> 8);
|
||||||
|
write_data(color);
|
||||||
|
gpanel_cs_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fast block fill operation.
|
||||||
|
* Requires set_window() has previously been called to set
|
||||||
|
* the fill bounds.
|
||||||
|
* 'npixels' is inclusive, MUST be >= 1.
|
||||||
|
*/
|
||||||
|
static void flood(int color, int npixels)
|
||||||
|
{
|
||||||
|
unsigned blocks, i;
|
||||||
|
unsigned hi = color >> 8,
|
||||||
|
lo = color;
|
||||||
|
|
||||||
|
/* Write first pixel normally, decrement counter by 1. */
|
||||||
|
gpanel_rs_data();
|
||||||
|
gpanel_write_byte(hi);
|
||||||
|
gpanel_write_byte(lo);
|
||||||
|
npixels--;
|
||||||
|
|
||||||
|
/* 64 pixels/block. */
|
||||||
|
blocks = npixels >> 6;
|
||||||
|
if (hi == lo) {
|
||||||
|
/* High and low bytes are identical. Leave prior data
|
||||||
|
* on the port(s) and just toggle the write strobe. */
|
||||||
|
while (blocks--) {
|
||||||
|
/* 64 pixels/block / 4 pixels/pass. */
|
||||||
|
for (i = 16; i > 0; i--) {
|
||||||
|
/* 2 bytes/pixel x 4 pixels. */
|
||||||
|
gpanel_wr_strobe();
|
||||||
|
gpanel_wr_strobe();
|
||||||
|
gpanel_wr_strobe();
|
||||||
|
gpanel_wr_strobe();
|
||||||
|
gpanel_wr_strobe();
|
||||||
|
gpanel_wr_strobe();
|
||||||
|
gpanel_wr_strobe();
|
||||||
|
gpanel_wr_strobe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Fill any remaining pixels (1 to 64). */
|
||||||
|
for (i = npixels & 63; i > 0; i--) {
|
||||||
|
gpanel_wr_strobe();
|
||||||
|
gpanel_wr_strobe();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (blocks--) {
|
||||||
|
/* 64 pixels/block / 4 pixels/pass. */
|
||||||
|
for (i = 16; i > 0; i--) {
|
||||||
|
gpanel_write_byte(hi); gpanel_write_byte(lo);
|
||||||
|
gpanel_write_byte(hi); gpanel_write_byte(lo);
|
||||||
|
gpanel_write_byte(hi); gpanel_write_byte(lo);
|
||||||
|
gpanel_write_byte(hi); gpanel_write_byte(lo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = npixels & 63; i > 0; i--) {
|
||||||
|
gpanel_write_byte(hi);
|
||||||
|
gpanel_write_byte(lo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Switch the screen orientation.
|
||||||
|
*/
|
||||||
|
static void set_rotation(int rotation)
|
||||||
|
{
|
||||||
|
write_command(NT35702_MADCTL);
|
||||||
|
switch (rotation & 3) {
|
||||||
|
case 0: /* Portrait */
|
||||||
|
write_data(0xC8);
|
||||||
|
_width = 240;
|
||||||
|
_height = 320;
|
||||||
|
break;
|
||||||
|
case 1: /* Landscape */
|
||||||
|
write_data(0xA8);
|
||||||
|
_width = 320;
|
||||||
|
_height = 240;
|
||||||
|
break;
|
||||||
|
case 2: /* Upside down portrait */
|
||||||
|
write_data(0x08);
|
||||||
|
_width = 240;
|
||||||
|
_height = 320;
|
||||||
|
break;
|
||||||
|
case 3: /* Upside down landscape */
|
||||||
|
write_data(0x68);
|
||||||
|
_width = 320;
|
||||||
|
_height = 240;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nt35702_clear(struct gpanel_hw *h, int color, int width, int height)
|
||||||
|
{
|
||||||
|
gpanel_cs_active();
|
||||||
|
|
||||||
|
/* Switch screen orientaation. */
|
||||||
|
if (width > height)
|
||||||
|
set_rotation(1); /* Landscape */
|
||||||
|
else if (width < height)
|
||||||
|
set_rotation(0); /* Portrait */
|
||||||
|
|
||||||
|
/* Fill the screen with a color. */
|
||||||
|
set_window(0, 0, _width-1, _height-1);
|
||||||
|
flood(color, _width * _height);
|
||||||
|
gpanel_cs_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill a rectangle with specified color.
|
||||||
|
*/
|
||||||
|
static void nt35702_fill_rectangle(int x0, int y0, int x1, int y1, int color)
|
||||||
|
{
|
||||||
|
if (x0 < 0) x0 = 0;
|
||||||
|
if (y0 < 0) x0 = 0;
|
||||||
|
if (x1 < 0) x1 = 0;
|
||||||
|
if (y1 < 0) x1 = 0;
|
||||||
|
if (x0 >= _width) x0 = _width-1;
|
||||||
|
if (x1 >= _width) x1 = _width-1;
|
||||||
|
if (y0 >= _height) y0 = _height-1;
|
||||||
|
if (y1 >= _height) y1 = _height-1;
|
||||||
|
|
||||||
|
if (x1 < x0) {
|
||||||
|
int t = x0;
|
||||||
|
x0 = x1;
|
||||||
|
x1 = t;
|
||||||
|
}
|
||||||
|
if (y1 < y0) {
|
||||||
|
int t = y0;
|
||||||
|
y0 = y1;
|
||||||
|
y1 = t;
|
||||||
|
}
|
||||||
|
gpanel_cs_active();
|
||||||
|
set_window(x0, y0, x1, y1);
|
||||||
|
flood(color, (x1 - x0 + 1) * (y1 - y0 + 1));
|
||||||
|
gpanel_cs_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill a rectangle with user data.
|
||||||
|
*/
|
||||||
|
static void nt35702_draw_image(int x, int y, int width, int height,
|
||||||
|
const unsigned short *data)
|
||||||
|
{
|
||||||
|
unsigned cnt = width * height;
|
||||||
|
int color;
|
||||||
|
|
||||||
|
gpanel_cs_active();
|
||||||
|
set_window(x, y, x + width - 1, y + height - 1);
|
||||||
|
gpanel_rs_data();
|
||||||
|
while (cnt--) {
|
||||||
|
color = *data++;
|
||||||
|
gpanel_write_byte(color >> 8);
|
||||||
|
gpanel_write_byte(color);
|
||||||
|
}
|
||||||
|
gpanel_cs_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Draw a glyph of one symbol.
|
||||||
|
*/
|
||||||
|
static void nt35702_draw_glyph(const struct gpanel_font_t *font,
|
||||||
|
int color, int background, int x, int y, int width,
|
||||||
|
const unsigned short *bits)
|
||||||
|
{
|
||||||
|
int h, w, c;
|
||||||
|
unsigned bitmask = 0;
|
||||||
|
|
||||||
|
if (background >= 0) {
|
||||||
|
/*
|
||||||
|
* Clear background.
|
||||||
|
*/
|
||||||
|
gpanel_cs_active();
|
||||||
|
set_window(x, y, x + width - 1, y + font->height - 1);
|
||||||
|
gpanel_rs_data();
|
||||||
|
|
||||||
|
/* Loop on each glyph row. */
|
||||||
|
for (h=0; h<font->height; h++) {
|
||||||
|
/* Loop on every pixel in the row (left to right). */
|
||||||
|
for (w=0; w<width; w++) {
|
||||||
|
if ((w & 15) == 0)
|
||||||
|
bitmask = *bits++;
|
||||||
|
else
|
||||||
|
bitmask <<= 1;
|
||||||
|
|
||||||
|
c = (bitmask & 0x8000) ? color : background;
|
||||||
|
gpanel_write_byte(c >> 8);
|
||||||
|
gpanel_write_byte(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gpanel_cs_idle();
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Transparent background.
|
||||||
|
*/
|
||||||
|
/* Loop on each glyph row. */
|
||||||
|
for (h=0; h<font->height; h++) {
|
||||||
|
/* Loop on every pixel in the row (left to right). */
|
||||||
|
for (w=0; w<width; w++) {
|
||||||
|
if ((w & 15) == 0)
|
||||||
|
bitmask = *bits++;
|
||||||
|
else
|
||||||
|
bitmask <<= 1;
|
||||||
|
|
||||||
|
if (bitmask & 0x8000)
|
||||||
|
nt35702_set_pixel(x + w, y + h, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the LCD controller.
|
||||||
|
* Fill the gpanel_hw descriptor.
|
||||||
|
*/
|
||||||
|
void nt35702_init_display(struct gpanel_hw *h)
|
||||||
|
{
|
||||||
|
gpanel_cs_active();
|
||||||
|
gpanel_cs_active();
|
||||||
|
write_command(NT35702_SWRESET);
|
||||||
|
udelay(20000);
|
||||||
|
|
||||||
|
write_command(NT35702_SLPOUT);
|
||||||
|
udelay(120000);
|
||||||
|
|
||||||
|
write_command(NT35702_PWCTR3);
|
||||||
|
write_data(0x05); // APA2 APA1 APA0 Large
|
||||||
|
write_data(0x00); // Step-up cycle in Booster circuit 1
|
||||||
|
// Step-up cycle in Booster circuit 2,3
|
||||||
|
write_command(NT35702_PWCTR4);
|
||||||
|
write_data(0x05); // APA2 APA1 APA0 Large
|
||||||
|
write_data(0x00); // Step-up cycle in Booster circuit 1
|
||||||
|
// Step-up cycle in Booster circuit 2,3
|
||||||
|
write_command(NT35702_PWCTR5);
|
||||||
|
write_data(0x05); // APA2 APA1 APA0 Large
|
||||||
|
write_data(0x00); // Step-up cycle in Booster circuit 1
|
||||||
|
// Step-up cycle in Booster circuit 2,3
|
||||||
|
write_command(NT35702_COLMOD);
|
||||||
|
write_data(0x55);
|
||||||
|
|
||||||
|
write_command(NT35702_MTPSUP);
|
||||||
|
write_data(0x40);
|
||||||
|
write_data(0xE0);
|
||||||
|
|
||||||
|
write_command(NT35702_AVDDCLP);
|
||||||
|
write_data(0x06);
|
||||||
|
write_data(0x11);
|
||||||
|
|
||||||
|
write_command(NT35702_FRMCTR);
|
||||||
|
write_data(0x38);
|
||||||
|
write_data(0x20);
|
||||||
|
write_data(0x1C);
|
||||||
|
write_data(0x10);
|
||||||
|
write_data(0x37);
|
||||||
|
write_data(0x12);
|
||||||
|
write_data(0x22);
|
||||||
|
write_data(0x1E);
|
||||||
|
|
||||||
|
write_command(NT35702_PWCTR1); // Set GVDD
|
||||||
|
write_data(0x05);
|
||||||
|
|
||||||
|
write_command(NT35702_VMCTR1); // Set Vcom
|
||||||
|
write_data(0x60);
|
||||||
|
write_data(0x00);
|
||||||
|
|
||||||
|
write_command(NT35702_VMOFCTR); // Set VCOM-OFFSET
|
||||||
|
write_data(0xA9); // You can fine-tune to improve flicker
|
||||||
|
|
||||||
|
set_rotation(1); /* Landscape */
|
||||||
|
|
||||||
|
write_command(NT35702_GAMCTRP1);
|
||||||
|
write_data(0x23);
|
||||||
|
write_data(0x23);
|
||||||
|
write_data(0x24);
|
||||||
|
write_data(0x02);
|
||||||
|
write_data(0x08);
|
||||||
|
write_data(0x0F);
|
||||||
|
write_data(0x35);
|
||||||
|
write_data(0x7B);
|
||||||
|
write_data(0x43);
|
||||||
|
write_data(0x0E);
|
||||||
|
write_data(0x1F);
|
||||||
|
write_data(0x25);
|
||||||
|
write_data(0x10);
|
||||||
|
write_data(0x16);
|
||||||
|
write_data(0x31);
|
||||||
|
|
||||||
|
write_command(NT35702_GAMCTRN1);
|
||||||
|
write_data(0x0D);
|
||||||
|
write_data(0x28);
|
||||||
|
write_data(0x2E);
|
||||||
|
write_data(0x0B);
|
||||||
|
write_data(0x11);
|
||||||
|
write_data(0x12);
|
||||||
|
write_data(0x3E);
|
||||||
|
write_data(0x59);
|
||||||
|
write_data(0x4C);
|
||||||
|
write_data(0x10);
|
||||||
|
write_data(0x26);
|
||||||
|
write_data(0x2B);
|
||||||
|
write_data(0x1B);
|
||||||
|
write_data(0x1B);
|
||||||
|
write_data(0x1B);
|
||||||
|
|
||||||
|
write_command(NT35702_DISPON);
|
||||||
|
|
||||||
|
write_command(NT35702_RAMWR);
|
||||||
|
gpanel_cs_idle();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill the gpanel_hw descriptor.
|
||||||
|
*/
|
||||||
|
h->name = "Novatek NT35702";
|
||||||
|
h->width = _width;
|
||||||
|
h->height = _height;
|
||||||
|
h->clear = nt35702_clear;
|
||||||
|
h->set_pixel = nt35702_set_pixel;
|
||||||
|
h->fill_rectangle = nt35702_fill_rectangle;
|
||||||
|
h->draw_image = nt35702_draw_image;
|
||||||
|
h->draw_glyph = nt35702_draw_glyph;
|
||||||
|
}
|
||||||
@@ -218,20 +218,17 @@ int gpanel_read_byte()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read device ID code.
|
* Read a 16-bit value from the specified chip register.
|
||||||
*/
|
*/
|
||||||
static unsigned read_device_id()
|
static int read_reg16(int reg)
|
||||||
{
|
{
|
||||||
unsigned value;
|
unsigned value;
|
||||||
|
|
||||||
CS_ACTIVE();
|
CS_ACTIVE();
|
||||||
RS_COMMAND();
|
RS_COMMAND();
|
||||||
gpanel_write_byte(0); // Read register #0
|
//gpanel_write_byte(reg >> 8);
|
||||||
delay100ns();
|
gpanel_write_byte(reg);
|
||||||
WR_ACTIVE();
|
set_read_dir(); // Switch data bus to input
|
||||||
delay100ns();
|
|
||||||
WR_IDLE();
|
|
||||||
set_read_dir(); // Switch data bus as input
|
|
||||||
RS_DATA();
|
RS_DATA();
|
||||||
value = gpanel_read_byte() << 8;
|
value = gpanel_read_byte() << 8;
|
||||||
value |= gpanel_read_byte();
|
value |= gpanel_read_byte();
|
||||||
@@ -240,6 +237,27 @@ static unsigned read_device_id()
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a 32-bit value from the specified chip register.
|
||||||
|
*/
|
||||||
|
static int read_reg32(int reg)
|
||||||
|
{
|
||||||
|
unsigned value;
|
||||||
|
|
||||||
|
CS_ACTIVE();
|
||||||
|
RS_COMMAND();
|
||||||
|
gpanel_write_byte(reg);
|
||||||
|
set_read_dir(); // Switch data bus to input
|
||||||
|
RS_DATA();
|
||||||
|
value = gpanel_read_byte() << 24;
|
||||||
|
value |= gpanel_read_byte() << 16;
|
||||||
|
value |= gpanel_read_byte() << 8;
|
||||||
|
value |= gpanel_read_byte();
|
||||||
|
set_write_dir(); // Restore data bus as output
|
||||||
|
CS_IDLE();
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Draw a line.
|
* Draw a line.
|
||||||
*/
|
*/
|
||||||
@@ -566,27 +584,47 @@ static int probe(config)
|
|||||||
udelay(1000);
|
udelay(1000);
|
||||||
|
|
||||||
/* Read the the chip ID register. */
|
/* Read the the chip ID register. */
|
||||||
_chip_id = read_device_id();
|
_chip_id = read_reg16(0);
|
||||||
switch (_chip_id) {
|
switch (_chip_id) {
|
||||||
|
default:
|
||||||
|
printf("gpanel0: Unknown chip ID0 = 0x%04x\n", _chip_id);
|
||||||
|
goto failed;
|
||||||
|
|
||||||
case 0x7783:
|
case 0x7783:
|
||||||
st7781_init_display(&hw);
|
st7781_init_display(&hw);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case 0:
|
||||||
printf("gpanel0: Unknown chip ID = 0x%x\n", _chip_id);
|
/* Family of ILI9341-alike chips. */
|
||||||
|
_chip_id = read_reg32(4) & 0xffffff;
|
||||||
|
switch (_chip_id) {
|
||||||
|
default:
|
||||||
|
printf("gpanel0: Unknown chip ID4 = 0x%06x\n", _chip_id);
|
||||||
|
goto failed;
|
||||||
|
|
||||||
/* Disable outputs. */
|
case 0x009341:
|
||||||
set_read_dir();
|
//TODO
|
||||||
TRIS_SET(LCD_CS_PORT) = 1 << LCD_CS_PIN;
|
//ili9341_init_display(&hw);
|
||||||
TRIS_SET(LCD_RS_PORT) = 1 << LCD_RS_PIN;
|
break;
|
||||||
TRIS_SET(LCD_WR_PORT) = 1 << LCD_WR_PIN;
|
|
||||||
TRIS_SET(LCD_RD_PORT) = 1 << LCD_RD_PIN;
|
case 0x388000:
|
||||||
TRIS_SET(LCD_RST_PORT) = 1 << LCD_RST_PIN;
|
nt35702_init_display(&hw);
|
||||||
return 0;
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("gpanel0: <%s> display %ux%u\n", hw.name, hw.width, hw.height);
|
printf("gpanel0: <%s> display %ux%u\n", hw.name, hw.width, hw.height);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
/* Disable outputs. */
|
||||||
|
set_read_dir();
|
||||||
|
TRIS_SET(LCD_CS_PORT) = 1 << LCD_CS_PIN;
|
||||||
|
TRIS_SET(LCD_RS_PORT) = 1 << LCD_RS_PIN;
|
||||||
|
TRIS_SET(LCD_WR_PORT) = 1 << LCD_WR_PIN;
|
||||||
|
TRIS_SET(LCD_RD_PORT) = 1 << LCD_RD_PIN;
|
||||||
|
TRIS_SET(LCD_RST_PORT) = 1 << LCD_RST_PIN;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct driver gpaneldriver = {
|
struct driver gpaneldriver = {
|
||||||
|
|||||||
@@ -1,375 +0,0 @@
|
|||||||
// IMPORTANT: Adafruit_ILI9341_8bit_AS LIBRARY MUST BE SPECIFICALLY
|
|
||||||
// CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
|
|
||||||
// DEFAULT IS THE UNO SHIELD
|
|
||||||
// SEE RELEVANT COMMENTS IN Adafruit_ILI9341_8bit_AS.h FOR SETUP.
|
|
||||||
|
|
||||||
#define DEBUG
|
|
||||||
#include <Adafruit_GFX_AS.h> // Core graphics library
|
|
||||||
#include <Adafruit_ILI9341_8bit_AS.h> // Hardware-specific library
|
|
||||||
|
|
||||||
// The control pins for the LCD can be assigned to any digital or
|
|
||||||
// analog pins...but we'll use the analog pins as this allows us to
|
|
||||||
// double up the pins with the touch screen (see the TFT paint example).
|
|
||||||
#define LCD_CS A3 // Chip Select goes to Analog 3
|
|
||||||
#define LCD_CD A2 // Command/Data goes to Analog 2
|
|
||||||
#define LCD_WR A1 // LCD Write goes to Analog 1
|
|
||||||
#define LCD_RD A0 // LCD Read goes to Analog 0
|
|
||||||
|
|
||||||
#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin
|
|
||||||
|
|
||||||
// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
|
|
||||||
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
|
|
||||||
// D0 connects to digital pin 8 (Notice these are
|
|
||||||
// D1 connects to digital pin 9 NOT in order!)
|
|
||||||
// D2 connects to digital pin 2
|
|
||||||
// D3 connects to digital pin 3
|
|
||||||
// D4 connects to digital pin 4
|
|
||||||
// D5 connects to digital pin 5
|
|
||||||
// D6 connects to digital pin 6
|
|
||||||
// D7 connects to digital pin 7
|
|
||||||
// For the Arduino Mega, use digital pins 22 through 29
|
|
||||||
// (on the 2-row header at the end of the board).
|
|
||||||
|
|
||||||
// Assign human-readable names to some common 16-bit color values:
|
|
||||||
#define BLACK 0x0000
|
|
||||||
#define BLUE 0x001F
|
|
||||||
#define RED 0xF800
|
|
||||||
#define GREEN 0x07E0
|
|
||||||
#define CYAN 0x07FF
|
|
||||||
#define MAGENTA 0xF81F
|
|
||||||
#define YELLOW 0xFFE0
|
|
||||||
#define WHITE 0xFFFF
|
|
||||||
|
|
||||||
Adafruit_ILI9341_8bit_AS tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
|
|
||||||
// If using the shield, all control and data lines are fixed, and
|
|
||||||
// a simpler declaration can optionally be used:
|
|
||||||
// Adafruit_ILI9341_8bit_AS tft;
|
|
||||||
|
|
||||||
void setup(void) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.begin(9600);
|
|
||||||
Serial.println("TFT LCD test");
|
|
||||||
Serial.print("TFT size is ");
|
|
||||||
Serial.print(tft.width());
|
|
||||||
Serial.print("x");
|
|
||||||
Serial.println(tft.height());
|
|
||||||
#endif // DEBUG
|
|
||||||
|
|
||||||
tft.reset();
|
|
||||||
delay(10);
|
|
||||||
tft.begin(0x9341);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
Serial.println("Benchmark Time (microseconds)");
|
|
||||||
|
|
||||||
Serial.print("Screen fill ");
|
|
||||||
Serial.println(testFillScreen());
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
Serial.print("Text ");
|
|
||||||
Serial.println(testText());
|
|
||||||
delay(3000);
|
|
||||||
|
|
||||||
Serial.print("Lines ");
|
|
||||||
Serial.println(testLines(CYAN));
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
Serial.print("Horiz/Vert Lines ");
|
|
||||||
Serial.println(testFastLines(RED, BLUE));
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
Serial.print("Rectangles (outline) ");
|
|
||||||
Serial.println(testRects(GREEN));
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
Serial.print("Rectangles (filled) ");
|
|
||||||
Serial.println(testFilledRects(YELLOW, MAGENTA));
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
Serial.print("Circles (filled) ");
|
|
||||||
Serial.println(testFilledCircles(10, MAGENTA));
|
|
||||||
|
|
||||||
Serial.print("Circles (outline) ");
|
|
||||||
Serial.println(testCircles(10, WHITE));
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
Serial.print("Triangles (outline) ");
|
|
||||||
Serial.println(testTriangles());
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
Serial.print("Triangles (filled) ");
|
|
||||||
Serial.println(testFilledTriangles());
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
Serial.print("Rounded rects (outline) ");
|
|
||||||
Serial.println(testRoundRects());
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
Serial.print("Rounded rects (filled) ");
|
|
||||||
Serial.println(testFilledRoundRects());
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
Serial.println("Done!");
|
|
||||||
#endif // DEBUG
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop(void) {
|
|
||||||
for(uint8_t rotation=0; rotation<4; rotation++) {
|
|
||||||
tft.setRotation(rotation);
|
|
||||||
testText();
|
|
||||||
delay(2000);
|
|
||||||
}
|
|
||||||
testFilledRoundRects();
|
|
||||||
testRoundRects();
|
|
||||||
testFilledTriangles();
|
|
||||||
testTriangles();
|
|
||||||
testCircles(10, WHITE);
|
|
||||||
testFillScreen();
|
|
||||||
testText();
|
|
||||||
testLines(CYAN);
|
|
||||||
testFastLines(RED, BLUE);
|
|
||||||
testRects(GREEN);
|
|
||||||
testFilledRects(YELLOW, MAGENTA);
|
|
||||||
testFilledCircles(10, MAGENTA);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testFillScreen() {
|
|
||||||
unsigned long start = micros();
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
tft.fillScreen(RED);
|
|
||||||
tft.fillScreen(GREEN);
|
|
||||||
tft.fillScreen(BLUE);
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
return micros() - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testText() {
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
unsigned long start = micros();
|
|
||||||
tft.setCursor(0, 0);
|
|
||||||
tft.setTextColor(WHITE); tft.setTextSize(1);
|
|
||||||
tft.println("Hello World!");
|
|
||||||
tft.setTextColor(YELLOW); tft.setTextSize(2);
|
|
||||||
tft.println(1234.56);
|
|
||||||
tft.setTextColor(RED); tft.setTextSize(3);
|
|
||||||
tft.println(0xDEADBEEF, HEX);
|
|
||||||
tft.println();
|
|
||||||
tft.setTextColor(GREEN);
|
|
||||||
tft.setTextSize(5);
|
|
||||||
tft.println("Groop");
|
|
||||||
tft.setTextSize(2);
|
|
||||||
tft.println("I implore thee,");
|
|
||||||
tft.setTextSize(1);
|
|
||||||
tft.println("my foonting turlingdromes.");
|
|
||||||
tft.println("And hooptiously drangle me");
|
|
||||||
tft.println("with crinkly bindlewurdles,");
|
|
||||||
tft.println("Or I will rend thee");
|
|
||||||
tft.println("in the gobberwarts");
|
|
||||||
tft.println("with my blurglecruncheon,");
|
|
||||||
tft.println("see if I don't!");
|
|
||||||
return micros() - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testLines(uint16_t color) {
|
|
||||||
unsigned long start, t;
|
|
||||||
int x1, y1, x2, y2,
|
|
||||||
w = tft.width(),
|
|
||||||
h = tft.height();
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
|
|
||||||
x1 = y1 = 0;
|
|
||||||
y2 = h - 1;
|
|
||||||
start = micros();
|
|
||||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
|
||||||
x2 = w - 1;
|
|
||||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
|
||||||
t = micros() - start; // fillScreen doesn't count against timing
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
|
|
||||||
x1 = w - 1;
|
|
||||||
y1 = 0;
|
|
||||||
y2 = h - 1;
|
|
||||||
start = micros();
|
|
||||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
|
||||||
x2 = 0;
|
|
||||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
|
||||||
t += micros() - start;
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
|
|
||||||
x1 = 0;
|
|
||||||
y1 = h - 1;
|
|
||||||
y2 = 0;
|
|
||||||
start = micros();
|
|
||||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
|
||||||
x2 = w - 1;
|
|
||||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
|
||||||
t += micros() - start;
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
|
|
||||||
x1 = w - 1;
|
|
||||||
y1 = h - 1;
|
|
||||||
y2 = 0;
|
|
||||||
start = micros();
|
|
||||||
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
|
||||||
x2 = 0;
|
|
||||||
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
|
|
||||||
|
|
||||||
return micros() - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testFastLines(uint16_t color1, uint16_t color2) {
|
|
||||||
unsigned long start;
|
|
||||||
int x, y, w = tft.width(), h = tft.height();
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
start = micros();
|
|
||||||
for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
|
|
||||||
for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);
|
|
||||||
|
|
||||||
return micros() - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testRects(uint16_t color) {
|
|
||||||
unsigned long start;
|
|
||||||
int n, i, i2,
|
|
||||||
cx = tft.width() / 2,
|
|
||||||
cy = tft.height() / 2;
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
n = min(tft.width(), tft.height());
|
|
||||||
start = micros();
|
|
||||||
for(i=2; i<n; i+=6) {
|
|
||||||
i2 = i / 2;
|
|
||||||
tft.drawRect(cx-i2, cy-i2, i, i, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
return micros() - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
|
|
||||||
unsigned long start, t = 0;
|
|
||||||
int n, i, i2,
|
|
||||||
cx = tft.width() / 2 - 1,
|
|
||||||
cy = tft.height() / 2 - 1;
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
n = min(tft.width(), tft.height());
|
|
||||||
for(i=n; i>0; i-=6) {
|
|
||||||
i2 = i / 2;
|
|
||||||
start = micros();
|
|
||||||
tft.fillRect(cx-i2, cy-i2, i, i, color1);
|
|
||||||
t += micros() - start;
|
|
||||||
// Outlines are not included in timing results
|
|
||||||
tft.drawRect(cx-i2, cy-i2, i, i, color2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
|
|
||||||
unsigned long start;
|
|
||||||
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
start = micros();
|
|
||||||
for(x=radius; x<w; x+=r2) {
|
|
||||||
for(y=radius; y<h; y+=r2) {
|
|
||||||
tft.fillCircle(x, y, radius, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return micros() - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testCircles(uint8_t radius, uint16_t color) {
|
|
||||||
unsigned long start;
|
|
||||||
int x, y, r2 = radius * 2,
|
|
||||||
w = tft.width() + radius,
|
|
||||||
h = tft.height() + radius;
|
|
||||||
|
|
||||||
// Screen is not cleared for this one -- this is
|
|
||||||
// intentional and does not affect the reported time.
|
|
||||||
start = micros();
|
|
||||||
for(x=0; x<w; x+=r2) {
|
|
||||||
for(y=0; y<h; y+=r2) {
|
|
||||||
tft.drawCircle(x, y, radius, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return micros() - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testTriangles() {
|
|
||||||
unsigned long start;
|
|
||||||
int n, i, cx = tft.width() / 2 - 1,
|
|
||||||
cy = tft.height() / 2 - 1;
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
n = min(cx, cy);
|
|
||||||
start = micros();
|
|
||||||
for(i=0; i<n; i+=5) {
|
|
||||||
tft.drawTriangle(
|
|
||||||
cx , cy - i, // peak
|
|
||||||
cx - i, cy + i, // bottom left
|
|
||||||
cx + i, cy + i, // bottom right
|
|
||||||
tft.color565(0, 0, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
return micros() - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testFilledTriangles() {
|
|
||||||
unsigned long start, t = 0;
|
|
||||||
int i, cx = tft.width() / 2 - 1,
|
|
||||||
cy = tft.height() / 2 - 1;
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
start = micros();
|
|
||||||
for(i=min(cx,cy); i>10; i-=5) {
|
|
||||||
start = micros();
|
|
||||||
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
|
||||||
tft.color565(0, i, i));
|
|
||||||
t += micros() - start;
|
|
||||||
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
|
|
||||||
tft.color565(i, i, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testRoundRects() {
|
|
||||||
unsigned long start;
|
|
||||||
int w, i, i2,
|
|
||||||
cx = tft.width() / 2 - 1,
|
|
||||||
cy = tft.height() / 2 - 1;
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
w = min(tft.width(), tft.height());
|
|
||||||
start = micros();
|
|
||||||
for(i=0; i<w; i+=6) {
|
|
||||||
i2 = i / 2;
|
|
||||||
tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return micros() - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long testFilledRoundRects() {
|
|
||||||
unsigned long start;
|
|
||||||
int i, i2,
|
|
||||||
cx = tft.width() / 2 - 1,
|
|
||||||
cy = tft.height() / 2 - 1;
|
|
||||||
|
|
||||||
tft.fillScreen(BLACK);
|
|
||||||
start = micros();
|
|
||||||
for(i=min(tft.width(), tft.height()); i>20; i-=6) {
|
|
||||||
i2 = i / 2;
|
|
||||||
tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return micros() - start;
|
|
||||||
}
|
|
||||||
@@ -1,330 +0,0 @@
|
|||||||
|
|
||||||
#define LCD_RD A0
|
|
||||||
#define LCD_WR A1
|
|
||||||
#define LCD_RS A2
|
|
||||||
#define LCD_CS A3
|
|
||||||
#define LCD_REST A4
|
|
||||||
|
|
||||||
void Lcd_Writ_Bus(unsigned char VH)
|
|
||||||
{
|
|
||||||
unsigned int i,temp,data;
|
|
||||||
data=VH;
|
|
||||||
for (i=8; i<=9; i++) {
|
|
||||||
temp=(data&0x01);
|
|
||||||
if (temp)
|
|
||||||
digitalWrite(i,HIGH);
|
|
||||||
else
|
|
||||||
digitalWrite(i,LOW);
|
|
||||||
data=data>>1;
|
|
||||||
}
|
|
||||||
for (i=2; i<=7; i++) {
|
|
||||||
temp=(data&0x01);
|
|
||||||
if (temp)
|
|
||||||
digitalWrite(i,HIGH);
|
|
||||||
else
|
|
||||||
digitalWrite(i,LOW);
|
|
||||||
data=data>>1;
|
|
||||||
}
|
|
||||||
|
|
||||||
digitalWrite(LCD_WR,LOW);
|
|
||||||
digitalWrite(LCD_WR,HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lcd_Write_Com(unsigned char VH)
|
|
||||||
{
|
|
||||||
digitalWrite(LCD_RS,LOW);
|
|
||||||
Lcd_Writ_Bus(VH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lcd_Write_Data(unsigned char VH)
|
|
||||||
{
|
|
||||||
digitalWrite(LCD_RS,HIGH);
|
|
||||||
Lcd_Writ_Bus(VH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lcd_Write_Com_Data(unsigned char com,unsigned char dat)
|
|
||||||
{
|
|
||||||
Lcd_Write_Com(com);
|
|
||||||
Lcd_Write_Data(dat);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
|
|
||||||
{
|
|
||||||
Lcd_Write_Com_Data(0x2a,x1>>8);
|
|
||||||
Lcd_Write_Com_Data(0x2a,x1);
|
|
||||||
Lcd_Write_Com_Data(0x2a,x2>>8);
|
|
||||||
Lcd_Write_Com_Data(0x2a,x2);
|
|
||||||
Lcd_Write_Com_Data(0x2b,y1>>8);
|
|
||||||
Lcd_Write_Com_Data(0x2b,y1);
|
|
||||||
Lcd_Write_Com_Data(0x2b,y2>>8);
|
|
||||||
Lcd_Write_Com_Data(0x2b,y2);
|
|
||||||
Lcd_Write_Com(0x2c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lcd_Init(void)
|
|
||||||
{
|
|
||||||
digitalWrite(LCD_REST, HIGH);
|
|
||||||
delay(5);
|
|
||||||
digitalWrite(LCD_REST, LOW);
|
|
||||||
delay(15);
|
|
||||||
digitalWrite(LCD_REST, HIGH);
|
|
||||||
delay(15);
|
|
||||||
|
|
||||||
digitalWrite(LCD_CS, HIGH);
|
|
||||||
digitalWrite(LCD_WR, HIGH);
|
|
||||||
digitalWrite(LCD_CS, LOW); //CS
|
|
||||||
Lcd_Write_Com(0x01);// Software Reset
|
|
||||||
delay(20);
|
|
||||||
|
|
||||||
Lcd_Write_Com(0x11);//Sleep Out
|
|
||||||
delay(120);
|
|
||||||
|
|
||||||
Lcd_Write_Com(0xc2);//Power Control 3
|
|
||||||
Lcd_Write_Data(0x05);//APA2 APA1 APA0 Large
|
|
||||||
Lcd_Write_Data(0x00);//Step-up cycle in Booster circuit 1
|
|
||||||
//Step-up cycle in Booster circuit 2,3
|
|
||||||
Lcd_Write_Com(0xc3);//Power Control 4
|
|
||||||
Lcd_Write_Data(0x05);//APA2 APA1 APA0 Large
|
|
||||||
Lcd_Write_Data(0x00);//Step-up cycle in Booster circuit 1
|
|
||||||
//Step-up cycle in Booster circuit 2,3
|
|
||||||
Lcd_Write_Com(0xc4);//Power Control 5
|
|
||||||
Lcd_Write_Data(0x05);//APA2 APA1 APA0 Large
|
|
||||||
Lcd_Write_Data(0x00);//Step-up cycle in Booster circuit 1
|
|
||||||
//Step-up cycle in Booster circuit 2,3
|
|
||||||
Lcd_Write_Com(0x3A);
|
|
||||||
Lcd_Write_Data(0x55);
|
|
||||||
|
|
||||||
Lcd_Write_Com(0xD7);
|
|
||||||
Lcd_Write_Data(0x40);
|
|
||||||
Lcd_Write_Data(0xE0);
|
|
||||||
|
|
||||||
Lcd_Write_Com(0xFD);
|
|
||||||
Lcd_Write_Data(0x06);
|
|
||||||
Lcd_Write_Data(0x11);
|
|
||||||
|
|
||||||
Lcd_Write_Com(0xFA);
|
|
||||||
Lcd_Write_Data(0x38);
|
|
||||||
Lcd_Write_Data(0x20);
|
|
||||||
Lcd_Write_Data(0x1C);
|
|
||||||
Lcd_Write_Data(0x10);
|
|
||||||
Lcd_Write_Data(0x37);
|
|
||||||
Lcd_Write_Data(0x12);
|
|
||||||
Lcd_Write_Data(0x22);
|
|
||||||
Lcd_Write_Data(0x1E);
|
|
||||||
|
|
||||||
Lcd_Write_Com(0xC0);//Set GVDD
|
|
||||||
Lcd_Write_Data(0x05);
|
|
||||||
|
|
||||||
Lcd_Write_Com(0xC5);//Set Vcom
|
|
||||||
Lcd_Write_Data(0x60);
|
|
||||||
Lcd_Write_Data(0x00);
|
|
||||||
|
|
||||||
Lcd_Write_Com(0xC7);//Set VCOM-OFFSET
|
|
||||||
Lcd_Write_Data(0xA9);// 可以微调改善flicker
|
|
||||||
|
|
||||||
Lcd_Write_Com(0x36);//Memory data access control
|
|
||||||
Lcd_Write_Data(0xC8);//MY MX MV ML RGB MH 0 0
|
|
||||||
|
|
||||||
////Gamma//////////////////
|
|
||||||
Lcd_Write_Com(0xE0);//E0H Set
|
|
||||||
Lcd_Write_Data(0x23);
|
|
||||||
Lcd_Write_Data(0x23);
|
|
||||||
Lcd_Write_Data(0x24);
|
|
||||||
Lcd_Write_Data(0x02);
|
|
||||||
Lcd_Write_Data(0x08);
|
|
||||||
Lcd_Write_Data(0x0F);
|
|
||||||
Lcd_Write_Data(0x35);
|
|
||||||
Lcd_Write_Data(0x7B);
|
|
||||||
Lcd_Write_Data(0x43);
|
|
||||||
Lcd_Write_Data(0x0E);
|
|
||||||
Lcd_Write_Data(0x1F);
|
|
||||||
Lcd_Write_Data(0x25);
|
|
||||||
Lcd_Write_Data(0x10);
|
|
||||||
Lcd_Write_Data(0x16);
|
|
||||||
Lcd_Write_Data(0x31);
|
|
||||||
|
|
||||||
Lcd_Write_Com(0xE1);//E1H Set
|
|
||||||
Lcd_Write_Data(0x0D);
|
|
||||||
Lcd_Write_Data(0x28);
|
|
||||||
Lcd_Write_Data(0x2E);
|
|
||||||
Lcd_Write_Data(0x0B);
|
|
||||||
Lcd_Write_Data(0x11);
|
|
||||||
Lcd_Write_Data(0x12);
|
|
||||||
Lcd_Write_Data(0x3E);
|
|
||||||
Lcd_Write_Data(0x59);
|
|
||||||
Lcd_Write_Data(0x4C);
|
|
||||||
Lcd_Write_Data(0x10);
|
|
||||||
Lcd_Write_Data(0x26);
|
|
||||||
Lcd_Write_Data(0x2B);
|
|
||||||
Lcd_Write_Data(0x1B);
|
|
||||||
Lcd_Write_Data(0x1B);
|
|
||||||
Lcd_Write_Data(0x1B);
|
|
||||||
|
|
||||||
Lcd_Write_Com(0x29);//display on
|
|
||||||
|
|
||||||
Lcd_Write_Com(0x2c);//Memory Write
|
|
||||||
}
|
|
||||||
|
|
||||||
void H_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c)
|
|
||||||
{
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
Lcd_Write_Com(0x02c); //write_memory_start
|
|
||||||
digitalWrite(LCD_RS, HIGH);
|
|
||||||
digitalWrite(LCD_CS, LOW);
|
|
||||||
l = l+x;
|
|
||||||
Address_set(x,y,l,y);
|
|
||||||
j = l*2;
|
|
||||||
for(i=1;i<=j;i++)
|
|
||||||
{
|
|
||||||
Lcd_Write_Data(c>>8);
|
|
||||||
Lcd_Write_Data(c);
|
|
||||||
}
|
|
||||||
digitalWrite(LCD_CS, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void V_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c)
|
|
||||||
{
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
Lcd_Write_Com(0x02c); //write_memory_start
|
|
||||||
digitalWrite(LCD_RS, HIGH);
|
|
||||||
digitalWrite(LCD_CS, LOW);
|
|
||||||
l = l+y;
|
|
||||||
Address_set(x,y,x,l);
|
|
||||||
j = l*2;
|
|
||||||
for(i=1;i<=j;i++)
|
|
||||||
{
|
|
||||||
Lcd_Write_Data(c>>8);
|
|
||||||
Lcd_Write_Data(c);
|
|
||||||
}
|
|
||||||
digitalWrite(LCD_CS, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rect(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned int c)
|
|
||||||
{
|
|
||||||
H_line(x , y , w, c);
|
|
||||||
H_line(x , y+h, w, c);
|
|
||||||
V_line(x , y , h, c);
|
|
||||||
V_line(x+w, y , h, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rectf(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned int c)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i=0; i<h; i++) {
|
|
||||||
H_line(x , y , w, c);
|
|
||||||
H_line(x , y+i, w, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int RGB(int r, int g, int b)
|
|
||||||
{
|
|
||||||
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LCD_Clear(unsigned int j)
|
|
||||||
{
|
|
||||||
unsigned int i, m;
|
|
||||||
|
|
||||||
Address_set(0, 0, 320, 240);
|
|
||||||
Lcd_Write_Com(0x02c); //write_memory_start
|
|
||||||
digitalWrite(LCD_RS,HIGH);
|
|
||||||
digitalWrite(LCD_CS,LOW);
|
|
||||||
|
|
||||||
for (i=0; i<320; i++) {
|
|
||||||
for (m=0; m<240; m++) {
|
|
||||||
//ch=((fcolorr&248)|fcolorg>>5);
|
|
||||||
//cl=((fcolorg&28)<<3|fcolorb>>3);
|
|
||||||
|
|
||||||
Lcd_Write_Data(j>>8);
|
|
||||||
Lcd_Write_Data(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
digitalWrite(LCD_CS,HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_Pixel(int x,int y, unsigned int c)
|
|
||||||
{
|
|
||||||
Address_set(x, y, x, y);
|
|
||||||
Lcd_Write_Data(c >> 8);
|
|
||||||
Lcd_Write_Data(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(int x, int y)
|
|
||||||
{
|
|
||||||
int temp = x;
|
|
||||||
x = y;
|
|
||||||
y = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_Hline(int x, int y, int l,unsigned int c)
|
|
||||||
{
|
|
||||||
Address_set(x, y, x+l, y);
|
|
||||||
for (int i=0; i<l+1; i++)
|
|
||||||
{
|
|
||||||
Lcd_Write_Data(c >> 8);
|
|
||||||
Lcd_Write_Data(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_Vline(int x, int y, int l, unsigned int c)
|
|
||||||
{
|
|
||||||
Address_set(x, y, x, y+l);
|
|
||||||
for (int i=0; i<l+1; i++)
|
|
||||||
{
|
|
||||||
Lcd_Write_Data(c);
|
|
||||||
Lcd_Write_Data(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RoundRect(int x1, int y1, int x2, int y2,unsigned int c)
|
|
||||||
{
|
|
||||||
Lcd_Write_Com(0x02c); //write_memory_start
|
|
||||||
digitalWrite(LCD_RS,HIGH);
|
|
||||||
digitalWrite(LCD_CS,LOW);
|
|
||||||
|
|
||||||
int tmp;
|
|
||||||
if (x1 > x2) {
|
|
||||||
swap(x1, x2);
|
|
||||||
}
|
|
||||||
if (y1 > y2) {
|
|
||||||
swap(y1, y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((x2-x1 > 4 && (y2-y1) > 4) {
|
|
||||||
draw_Pixel(x1+1,y1+1,c);
|
|
||||||
draw_Pixel(x2-1,y1+1,c);
|
|
||||||
draw_Pixel(x1+1,y2-1,c);
|
|
||||||
draw_Pixel(x2-1,y2-1,c);
|
|
||||||
draw_Hline(x1+2, y1, x2-x1-4,c);
|
|
||||||
draw_Hline(x1+2, y2, x2-x1-4,c);
|
|
||||||
draw_Vline(x1, y1+2, y2-y1-4,c);
|
|
||||||
draw_Vline(x2, y1+2, y2-y1-4,c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
for (int p=2; p<10; p++)
|
|
||||||
pinMode(p, OUTPUT);
|
|
||||||
|
|
||||||
pinMode(A0, OUTPUT);
|
|
||||||
pinMode(A1, OUTPUT);
|
|
||||||
pinMode(A2, OUTPUT);
|
|
||||||
pinMode(A3, OUTPUT);
|
|
||||||
pinMode(A4, OUTPUT);
|
|
||||||
digitalWrite(A0, HIGH);
|
|
||||||
digitalWrite(A1, HIGH);
|
|
||||||
digitalWrite(A2, HIGH);
|
|
||||||
digitalWrite(A3, HIGH);
|
|
||||||
digitalWrite(A4, HIGH);
|
|
||||||
|
|
||||||
Lcd_Init();
|
|
||||||
//LCD_Clear(RGB(255, 0, 0));
|
|
||||||
//LCD_Clear(RGB(255, 255, 0));
|
|
||||||
//LCD_Clear(RGB(255, 0, 255));
|
|
||||||
//LCD_Clear(RGB(0, 255, 255));
|
|
||||||
//LCD_Clear(RGB(0, 255, 0));
|
|
||||||
}
|
|
||||||
@@ -79,8 +79,8 @@ OBJS = exec_aout.o exec_conf.o exec_elf.o exec_script.o exec_subr.o \
|
|||||||
ufs_namei.o ufs_subr.o ufs_syscalls.o ufs_syscalls2.o \
|
ufs_namei.o ufs_subr.o ufs_syscalls.o ufs_syscalls2.o \
|
||||||
vfs_vnops.o vm_sched.o vm_swap.o vm_swp.o clock.o cons.o devsw.o \
|
vfs_vnops.o vm_sched.o vm_swap.o vm_swp.o clock.o cons.o devsw.o \
|
||||||
exception.o machdep.o mem.o signal.o swap.o sysctl.o adc.o \
|
exception.o machdep.o mem.o signal.o swap.o sysctl.o adc.o \
|
||||||
gpanel.o gpanel-st7781.o gpio.o pwm.o sd.o spi.o spi_bus.o \
|
gpanel.o gpanel-nt35702.o gpanel-st7781.o gpio.o pwm.o sd.o \
|
||||||
uart.o
|
spi.o spi_bus.o uart.o
|
||||||
|
|
||||||
CFILES = $S/kernel/exec_aout.c $S/kernel/exec_conf.c $S/kernel/exec_elf.c \
|
CFILES = $S/kernel/exec_aout.c $S/kernel/exec_conf.c $S/kernel/exec_elf.c \
|
||||||
$S/kernel/exec_script.c $S/kernel/exec_subr.c \
|
$S/kernel/exec_script.c $S/kernel/exec_subr.c \
|
||||||
@@ -106,9 +106,9 @@ CFILES = $S/kernel/exec_aout.c $S/kernel/exec_conf.c $S/kernel/exec_elf.c \
|
|||||||
$S/pic32/devsw.c $S/pic32/exception.c $S/pic32/machdep.c \
|
$S/pic32/devsw.c $S/pic32/exception.c $S/pic32/machdep.c \
|
||||||
$S/pic32/mem.c $S/pic32/signal.c $S/pic32/swap.c \
|
$S/pic32/mem.c $S/pic32/signal.c $S/pic32/swap.c \
|
||||||
$S/pic32/sysctl.c $S/pic32/adc.c $S/pic32/gpanel.c \
|
$S/pic32/sysctl.c $S/pic32/adc.c $S/pic32/gpanel.c \
|
||||||
$S/pic32/gpanel-st7781.c $S/pic32/gpio.c $S/pic32/pwm.c \
|
$S/pic32/gpanel-nt35702.c $S/pic32/gpanel-st7781.c \
|
||||||
$S/pic32/sd.c $S/pic32/spi.c $S/pic32/spi_bus.c $S/pic32/uart.c \
|
$S/pic32/gpio.c $S/pic32/pwm.c $S/pic32/sd.c $S/pic32/spi.c \
|
||||||
swapunix.c
|
$S/pic32/spi_bus.c $S/pic32/uart.c swapunix.c
|
||||||
|
|
||||||
# load lines for config "xxx" will be emitted as:
|
# load lines for config "xxx" will be emitted as:
|
||||||
# xxx: ${SYSTEM_DEP} swapxxx.o
|
# xxx: ${SYSTEM_DEP} swapxxx.o
|
||||||
@@ -346,6 +346,9 @@ adc.o: $S/pic32/adc.c
|
|||||||
gpanel.o: $S/pic32/gpanel.c
|
gpanel.o: $S/pic32/gpanel.c
|
||||||
${COMPILE_C}
|
${COMPILE_C}
|
||||||
|
|
||||||
|
gpanel-nt35702.o: $S/pic32/gpanel-nt35702.c
|
||||||
|
${COMPILE_C}
|
||||||
|
|
||||||
gpanel-st7781.o: $S/pic32/gpanel-st7781.c
|
gpanel-st7781.o: $S/pic32/gpanel-st7781.c
|
||||||
${COMPILE_C}
|
${COMPILE_C}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user