#include "lcd.h" #include "log.h" #define DIV_NUM 10 #define INVERSE 1 #define ST_OFFSET 80 #define BIT(x) (1<dev, ®, 1); } static void write_data(lcd_handle_t *h, uint8_t data) { gpio_set(DC_PIN, 1); rt_spi_send(h->dev, &data, 1); } static void write_cmd_data(lcd_handle_t *h, uint8_t reg, uint16_t data) { write_cmd (h,reg); write_data(h,data); } static void read_data(lcd_handle_t *h, uint8_t *data, int length) { gpio_set(DC_PIN, 1); rt_spi_transfer(h->dev, RT_NULL, data, length); } static void write_16bit(lcd_handle_t *h, uint16_t data) { uint8_t buf[2]; buf[0] = data >> 8; buf[1] = data & 0xff; gpio_set(DC_PIN, 1); rt_spi_send(h->dev, buf, 2); } void st77xx_rotate(lcd_handle_t *h, int rotate) { uint8_t madctl=0,mode=INVERSE?ST77XX_MADCTL_BGR:ST77XX_MADCTL_RGB; switch (rotate) { case 0: madctl = mode; break; case 90: madctl = (ST77XX_MADCTL_MV | ST77XX_MADCTL_MX | mode); break; case 180: madctl = (ST77XX_MADCTL_MX | ST77XX_MADCTL_MY | mode); break; case 270: madctl = (ST77XX_MADCTL_MV | ST77XX_MADCTL_MY | mode); break; default: break; } write_cmd_data(h, ST77XX_MADCTL, madctl); } void st77xx_set_win(lcd_handle_t *hd, uint16_t x, uint16_t y, uint16_t w, uint16_t h) { int x1=x,y1=y; int x2=x+w-1,y2=y+h-1; if(hd->rotate == 0) { }else if(hd->rotate == 90) { }else if(hd->rotate == 180) { y1+=80; y2+=80; }else { x1+=80; x2+=80; } write_cmd (hd,ST77XX_CASET); write_data(hd,x1>>8); write_data(hd,x1); write_data(hd,x2>>8); write_data(hd,x2); write_cmd (hd,ST77XX_RASET); write_data(hd,y1>>8); write_data(hd,y1); write_data(hd,y2>>8); write_data(hd,y2); write_cmd (hd,ST77XX_RAMWR); } void st77xx_refresh(lcd_handle_t *hd, uint16_t x, uint16_t y, uint16_t w, uint16_t h, void *data, uint32_t len) { if(x>=hd->width || y>=hd->height) { return; } st77xx_set_win(hd, x, y, w, h); gpio_set(DC_PIN, 1); rt_spi_send(hd->dev, data, len); } void st77xx_draw_pixel(lcd_handle_t *hd, uint16_t x, uint16_t y, uint32_t color) { st77xx_set_win(hd, x, y, 1, 1); write_16bit(hd, color); } static void st77xx_reg_init(lcd_handle_t *h) { write_cmd (h,0x11); delay_ms(150); write_cmd (h,0xB2); //Porch Setting write_data(h,0x0C); write_data(h,0x0C); write_data(h,0x00); write_data(h,0x33); write_data(h,0x33); write_cmd (h,0x35); write_data(h,0x00); write_cmd (h,ST77XX_MADCTL); write_data(h,0x00); write_cmd (h,ST77XX_PIXEL_FORMAT); write_data(h,0x05); //03=RGB444,05=RGB565,06=RGB666 write_cmd (h,0xb7); //Gate Control write_data(h,0x35); write_cmd (h,0xbb); //VCOM Setting write_data(h,0x2d); write_cmd (h,0xC0); //LCM Control write_data(h,0x2C); write_cmd (h,0xC2); //VDV and VRH Command Enable write_data(h,0x01); write_cmd (h,0xC3); //VRH set write_data(h,0x15); write_cmd (h,0xC4); //VDV set write_data(h,0x20); write_cmd (h,0xC6); //Frame Rate Control write_data(h,0x0F); write_cmd (h,0xD0); //Power Control 1 write_data(h,0xA4); write_data(h,0xA1); write_cmd (h,0xD6); write_data(h,0xA1); write_cmd (h,0xE0); /* set Positive Voltage Gamma */ write_data(h,0x70); write_data(h,0x05); write_data(h,0x0a); write_data(h,0x0b); write_data(h,0x0a); write_data(h,0x27); write_data(h,0x2f); write_data(h,0x44); write_data(h,0x47); write_data(h,0x37); write_data(h,0x14); write_data(h,0x14); write_data(h,0x29); write_data(h,0x2f); write_cmd (h,0xE1); /* set Negative Voltage Gamma */ write_data(h,0x70); write_data(h,0x07); write_data(h,0x0c); write_data(h,0x08); write_data(h,0x08); write_data(h,0x04); write_data(h,0x2f); write_data(h,0x33); write_data(h,0x46); write_data(h,0x18); write_data(h,0x15); write_data(h,0x15); write_data(h,0x2b); write_data(h,0x2d); write_cmd (h,0x21); // Dispaly Inversion On write_cmd (h,0x29); // Display On write_cmd (h,ST77XX_RAMWR); // Memory Write } static void st77xx_reset(lcd_handle_t *h) { gpio_set(RST_PIN, 0); /* LCD Hardware Reset */ delay_ms(100); gpio_set(RST_PIN, 1); delay_ms(120); /* Delay 120ms */ } static void fill_color(lcd_handle_t *h, uint16_t color, int cnt) { int i,cnt2=(cnt<=h->buflen/2)?cnt:h->buflen/2; for(i=0; ibuf[i] = color; } } static void write_color(lcd_handle_t *h, uint16_t color, int cnt) { int i; for(i=0; iheight/DIV_NUM; int i,y1=0,h1=0,times=h/height,left=h%height; times += left?1:0; fill_color(hd, color, hd->buflen/2); for(i=0; ih)?(h-h1):height; st77xx_refresh(hd, x, y1, w, h1, hd->buf, w*h1*2); } } void st77xx_fill(lcd_handle_t *h, uint32_t color) { st77xx_fill_rect(h, 0, 0, h->width, h->height, color); } #define SPI_BUS "spi2" #define SPI_DEV_NAME "spi2.0" int st77xx_init(lcd_handle_t *h) { int r; struct rt_spi_configuration sc; gpio_init(BK_PIN, GPIO_OUT, 0); gpio_init(DC_PIN, GPIO_OUT, 0); gpio_init(RST_PIN, GPIO_OUT, 0); r = rt_hw_spi_device_attach(SPI_BUS, SPI_DEV_NAME, CS_PIN); if(r!=RT_EOK) { return -1; } h->dev = (struct rt_spi_device*)rt_device_find(SPI_DEV_NAME); if(h->dev==NULL) { return -1; } sc.data_width = 8; sc.max_hz = 32 * 1000 * 1000; sc.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB; r = rt_spi_configure(h->dev, &sc); h->buflen = (h->width*h->height*2)/DIV_NUM; h->buf = (uint16_t*)malloc(h->buflen); if (!h->buf) { LOGE("malloc buffer falied\n"); return -1; } st77xx_reset(h); st77xx_reg_init(h); st77xx_rotate(h, h->rotate); gpio_set(BK_PIN, 1); st77xx_fill(h, COLOR_BLACK); return 0; } int st77xx_deinit(lcd_handle_t *h) { gpio_deinit(BK_PIN); gpio_deinit(DC_PIN); gpio_deinit(RST_PIN); free(h->buf); return 0; }