| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- #include "lcd.h"
- #include "log.h"
- #define COL_ADDR_SET 0x2A
- #define ROW_ADDR_SET 0x2B
- #define MEMORY_WRITE 0x2C
- /**
- * MADCTL(36H):
- * +---------------------------------------+
- * | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
- * | MY | MX | MV | ML | RGB| MH | - | - |
- * +---------------------------------------+
- * [3] 0=RGB,1=BGR
- */
- #define DATA_ACCESS 0x36
- /**
- * COLMOD(3AH):
- * +---------------------------------------+
- * | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
- * | 0 | D6 | D5 | D4 | 0 | D2 | D1 | D0 |
- * +---------------------------------------+
- * [6:4] RGB interface Color format:
- * 101=65K RGB
- * 110=262K RGB
- * [2:0] Control interface color format:
- * 011=12bit/pixel
- * 101=16bit/pixel
- * 110=18bit/pixel
- * 111=16M truncated
- */
- #define PIXEL_FORMAT 0x3A
- static int lcd_hw_init(lcd_handle_t *h)
- {
- h->dev = rt_device_find("lcd");
- if (h->dev < 0) {
- LOGE("___ open %s failed\n", DEV_PATH);
- return -1;
- }
-
- h->buflen = h->width*h->height/8;
- h->buf = (uint8_t*)calloc(1, h->buflen);
- if (!h->buf) {
- LOGE("malloc buffer falied\n");
- return -1;
- }
- return 0;
- }
- static void write_reg(lcd_handle_t *h, uint8_t reg)
- {
- LCD_DC_CLR;
- rt_spi_send(h->dev, ®, 1);
- }
- static void write_data(uint8_t data)
- {
- LCD_DC_SET;
- rt_spi_send(h->dev, &data, 1);
- }
- static void write_reg_data(lcd_handle_t *h, uint8_t reg, uint16_t data)
- {
- write_reg(reg);
- write_data(data);
- }
- static void read_data(lcd_handle_t *h, uint8_t *data, int length)
- {
- LCD_DC_SET;
- rt_spi_transfer(lcd_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;
-
- LCD_DC_SET;
- rt_spi_send(h->dev, buf, 2);
- }
- void st7789_rotate(lcd_handle_t *h, int rotate)
- {
- switch (rotate)
- {
- case rotate:
- lcddev.width = LCD_W;
- lcddev.height = LCD_H;
- LCD_WriteReg(DATA_ACCESS, (0 << 3) | (0 << 5) | (0 << 6) | (0 << 7)); /* BGR==0,MV==0,MX==0,MY==0 */
- break;
-
- case 90:
- lcddev.width = LCD_H;
- lcddev.height = LCD_W;
- LCD_WriteReg(DATA_ACCESS, (0 << 3) | (1 << 5) | (1 << 6) | (0 << 7)); /* BGR==0,MV==1,MX==0,MY==1 */
- break;
-
- case 180:
- lcddev.width = LCD_W;
- lcddev.height = LCD_H;
- LCD_WriteReg(DATA_ACCESS, (0 << 3) | (0 << 5) | (1 << 6) | (1 << 7)); /* BGR==0,MV==0,MX==1,MY==1 */
- break;
-
- case 270:
- lcddev.width = LCD_H;
- lcddev.height = LCD_W;
- LCD_WriteReg(DATA_ACCESS, (0 << 3) | (1 << 5) | (0 << 6) | (1 << 7)); /* BGR==0,MV==1,MX==0,MY==1 */
- break;
-
- default:
- break;
- }
- }
- void st7789_set_win(lcd_handle_t *h, int x, int y, int w, int h)
- {
- write_reg(COL_ADDR_SET);
- write_data(x>>8);
- write_data(x&0xff);
- write_data((x+w-1)>>8);
- write_data((x+w-1)&0xff);
- write_reg(ROW_ADDR_SET);
- write_data(y>>8);
- write_data(y&0xff);
- write_data((y+h-1)>>8);
- write_data((y+h-1)&0xff);
- write_reg(MEMORY_WRITE);
- }
- void st7789_refresh(lcd_handle_t *h, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
- {
- uint16_t i, j;
- LCD_SetWindows(x, y, x + w - 1, y + h - 1);
- LCD_DC_SET;
- for (i = 0; i < h; i++)
- {
- rt_spi_send(h->dev, (uint8_t *)h->buf, w * 2);
- }
- }
- static void reg_init(lcd_handle_t *h)
- {
- write_reg(h, DATA_ACCESS);
- write_data(h, 0x00);
- LCD_WR_REG(h, PIXEL_FORMAT);
- LCD_WR_DATA(h, 0X05); //03=RGB444,05=RGB565,06=RGB666
- LCD_WR_REG(h, 0xB2); //Porch Setting
- LCD_WR_DATA(h, 0x0C);
- LCD_WR_DATA(h, 0x0C);
- LCD_WR_DATA(h, 0X00);
- LCD_WR_DATA(h, 0X33);
- LCD_WR_DATA(h, 0X33);
- LCD_WR_REG(h, 0xB7); //Gate Control
- LCD_WR_DATA(h, 0x46);
- LCD_WR_REG(h, 0xBB); //VCOM Setting
- LCD_WR_DATA(h, 0x1B);
- LCD_WR_REG(h, 0xC0); //LCM Control
- LCD_WR_DATA(h, 0x2C);
- LCD_WR_REG(h, 0xC2); //VDV and VRH Command Enable
- LCD_WR_DATA(h, 0x01);
- LCD_WR_REG(h, 0xC3); //VRH set
- LCD_WR_DATA(h, 0x0F);
- LCD_WR_REG(h, 0xC4); //VDV set
- LCD_WR_DATA(h, 0x20);
- LCD_WR_REG(h, 0xC6); //Frame Rate Control
- LCD_WR_DATA(h, 0x0F);
- LCD_WR_REG(h, 0xD0); //Power Control 1
- LCD_WR_DATA(h, 0xA4);
- LCD_WR_DATA(h, 0xA1);
- LCD_WR_REG(h, 0xD6);
- LCD_WR_DATA(0xA1);
- LCD_WR_REG(h, 0xE0); /* set Positive Voltage Gamma */
- LCD_WR_DATA(h, 0xF0);
- LCD_WR_DATA(h, 0x00);
- LCD_WR_DATA(h, 0x06);
- LCD_WR_DATA(h, 0x04);
- LCD_WR_DATA(h, 0x05);
- LCD_WR_DATA(h, 0x05);
- LCD_WR_DATA(h, 0x31);
- LCD_WR_DATA(h, 0x44);
- LCD_WR_DATA(h, 0x48);
- LCD_WR_DATA(h, 0x36);
- LCD_WR_DATA(h, 0x12);
- LCD_WR_DATA(h, 0x12);
- LCD_WR_DATA(h, 0x2B);
- LCD_WR_DATA(h, 0x34);
- LCD_WR_REG(h, 0xE1); /* set Negative Voltage Gamma */
- LCD_WR_DATA(h, 0XF0);
- LCD_WR_DATA(h, 0X0B);
- LCD_WR_DATA(h, 0X0F);
- LCD_WR_DATA(h, 0X0F);
- LCD_WR_DATA(h, 0X0D);
- LCD_WR_DATA(h, 0X26);
- LCD_WR_DATA(h, 0X31);
- LCD_WR_DATA(h, 0X43);
- LCD_WR_DATA(h, 0X47);
- LCD_WR_DATA(h, 0X38);
- LCD_WR_DATA(h, 0X14);
- LCD_WR_DATA(h, 0X14);
- LCD_WR_DATA(h, 0X2C);
- LCD_WR_DATA(h, 0X32);
- LCD_WR_REG(h, 0x21); // Dispaly Inversion On
- LCD_WR_REG(h, 0x29); // Display On
- LCD_WR_REG(MEMORY_WRITE); // Memory Write
- }
- static void Lcd_pin_init(void)
- {
- rt_pin_mode(PKG_ST_7789_DC_PIN, PIN_MODE_OUTPUT);
- rt_pin_mode(PKG_ST_7789_RES_PIN, PIN_MODE_OUTPUT);
- rt_pin_mode(PKG_ST_7789_BLK_PIN, PIN_MODE_OUTPUT);
- }
- static void LCD_Init(void)
- {
- Lcd_pin_init();
- LCD_RESET(); /* LCD Hardware Reset */
- DELAY(120); /* Delay 120ms */
- LCD_WR_REG(0x11); /* Sleep out */
- DELAY(120); /* Delay 120ms */
- _st7789_init(); /* IlI9341 init */
- LCD_BLK_CLR; /* Open Backlight */
- LCD_direction(USE_DIRECTION);
- }
- rt_err_t spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin)
- {
- RT_ASSERT(bus_name != RT_NULL);
- RT_ASSERT(device_name != RT_NULL);
- rt_err_t result = RT_EOK;
- struct rt_spi_device *spi_device;
- /* attach the device to spi bus*/
- spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
- RT_ASSERT(spi_device != RT_NULL);
- result = rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, cs_pin, RT_NULL);
- if (RT_EOK != result)
- {
- LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
- }
- else
- {
- LOG_I("%s attach to %s done", device_name, bus_name);
- }
- return result;
- }
- rt_err_t spi_lcd_init(uint32_t freq)
- {
- rt_err_t res = RT_EOK;
- spi_device_attach(PKG_ST_7789_SPI_BUS_NAME, PKG_ST_7789_SPI_DEVICE_NAME, PKG_ST_7789_CS_PIN);
- lcd_dev = (struct rt_spi_device *)rt_device_find(PKG_ST_7789_SPI_DEVICE_NAME);
- if (lcd_dev != RT_NULL)
- {
- struct rt_spi_configuration spi_config;
- spi_config.data_width = 8;
- spi_config.max_hz = freq * 1000 * 1000;
- spi_config.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
- rt_spi_configure(lcd_dev, &spi_config);
- }
- else
- {
- res = -RT_ERROR;
- }
- LCD_Init();
- return res;
- }
- static void lcd_ops_blit_line(const char *pixel, int x, int y, rt_size_t size)
- {
- LCD_SetWindows(x, y, x + size, y);
- rt_spi_send(lcd_dev, pixel, size * 2);
- }
- struct rt_device_graphic_ops lcd_graphic_ops =
- {
- .set_pixel = RT_NULL,//lcd_ops_set_pixel ,
- .get_pixel = RT_NULL,//lcd_ops_get_pixel ,
- .draw_hline = RT_NULL,//lcd_ops_draw_hline,
- .draw_vline = RT_NULL,//lcd_ops_draw_vline,
- .blit_line = lcd_ops_blit_line ,
- };
- static int st7789_dev_init(void)
- {
- #ifdef RT_USING_DEVICE_OPS
- lcddev.parent.ops = &lcd_dev_ops;
- #else
- lcddev.parent.init = lcd_dev_ops_init ;
- lcddev.parent.open = lcd_dev_ops_open ;
- lcddev.parent.close = lcd_dev_ops_close ;
- lcddev.parent.read = lcd_dev_ops_read ;
- lcddev.parent.write = lcd_dev_ops_write ;
- lcddev.parent.control = lcd_dev_ops_control;
- #endif
- lcddev.parent.type = RT_Device_Class_Graphic;
- lcddev.parent.user_data = &lcd_graphic_ops;
- rt_device_register(&lcddev.parent, "lcd", RT_DEVICE_FLAG_RDWR);
- return RT_EOK;
- }
|