211 lines
5.3 KiB
C
211 lines
5.3 KiB
C
/* Copyright 2018 Canaan Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#include <string.h>
|
|
#include "lcd.h"
|
|
#include "nt35310.h"
|
|
#include "font.h"
|
|
#include "common.h"
|
|
#include "sleep.h"
|
|
|
|
static lcd_ctl_t lcd_ctl;
|
|
|
|
void lcd_polling_enable(void)
|
|
{
|
|
lcd_ctl.mode = 0;
|
|
}
|
|
|
|
void lcd_interrupt_enable(void)
|
|
{
|
|
lcd_ctl.mode = 1;
|
|
|
|
}
|
|
|
|
void lcd_init(void)
|
|
{
|
|
uint8_t data = 0;
|
|
|
|
tft_hard_init();
|
|
/*soft reset*/
|
|
tft_write_command(SOFTWARE_RESET);
|
|
msleep(100);
|
|
/*exit sleep*/
|
|
tft_write_command(SLEEP_OFF);
|
|
msleep(100);
|
|
/*pixel format*/
|
|
tft_write_command(PIXEL_FORMAT_SET);
|
|
data = 0x55;
|
|
tft_write_byte(&data, 1);
|
|
lcd_set_direction(DIR_XY_RLUD);
|
|
/*display on*/
|
|
tft_write_command(DISPALY_ON);
|
|
lcd_polling_enable();
|
|
}
|
|
|
|
void lcd_set_direction(enum lcd_dir_t dir)
|
|
{
|
|
lcd_ctl.dir = dir;
|
|
if (dir & DIR_XY_MASK)
|
|
{
|
|
lcd_ctl.width = LCD_Y_MAX - 1;
|
|
lcd_ctl.height = LCD_X_MAX - 1;
|
|
}
|
|
else
|
|
{
|
|
lcd_ctl.width = LCD_X_MAX - 1;
|
|
lcd_ctl.height = LCD_Y_MAX - 1;
|
|
}
|
|
|
|
tft_write_command(MEMORY_ACCESS_CTL);
|
|
tft_write_byte((uint8_t *)&dir, 1);
|
|
}
|
|
|
|
void lcd_set_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
|
|
{
|
|
uint8_t data[4] = {0};
|
|
|
|
data[0] = (uint8_t)(x1 >> 8);
|
|
data[1] = (uint8_t)(x1);
|
|
data[2] = (uint8_t)(x2 >> 8);
|
|
data[3] = (uint8_t)(x2);
|
|
tft_write_command(HORIZONTAL_ADDRESS_SET);
|
|
tft_write_byte(data, 4);
|
|
|
|
data[0] = (uint8_t)(y1 >> 8);
|
|
data[1] = (uint8_t)(y1);
|
|
data[2] = (uint8_t)(y2 >> 8);
|
|
data[3] = (uint8_t)(y2);
|
|
tft_write_command(VERTICAL_ADDRESS_SET);
|
|
tft_write_byte(data, 4);
|
|
|
|
tft_write_command(MEMORY_WRITE);
|
|
}
|
|
|
|
void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color)
|
|
{
|
|
lcd_set_area(x, y, x, y);
|
|
tft_write_half(&color, 1);
|
|
}
|
|
|
|
void lcd_draw_char(uint16_t x, uint16_t y, char c, uint16_t color)
|
|
{
|
|
uint8_t i = 0;
|
|
uint8_t j = 0;
|
|
uint8_t data = 0;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
data = ascii0816[c * 16 + i];
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
if (data & 0x80)
|
|
lcd_draw_point(x + j, y, color);
|
|
data <<= 1;
|
|
}
|
|
y++;
|
|
}
|
|
}
|
|
|
|
void lcd_draw_string(uint16_t x, uint16_t y, char *str, uint16_t color)
|
|
{
|
|
while (*str)
|
|
{
|
|
lcd_draw_char(x, y, *str, color);
|
|
str++;
|
|
x += 8;
|
|
}
|
|
}
|
|
|
|
void lcd_ram_draw_string(char *str, uint32_t *ptr, uint16_t font_color, uint16_t bg_color)
|
|
{
|
|
uint8_t i = 0;
|
|
uint8_t j = 0;
|
|
uint8_t data = 0;
|
|
uint8_t *pdata = NULL;
|
|
uint16_t width = 0;
|
|
uint32_t *pixel = NULL;
|
|
|
|
width = 4 * strlen(str);
|
|
while (*str)
|
|
{
|
|
pdata = (uint8_t *)&ascii0816[(*str) * 16];
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
data = *pdata++;
|
|
pixel = ptr + i * width;
|
|
for (j = 0; j < 4; j++)
|
|
{
|
|
switch (data >> 6)
|
|
{
|
|
case 0:
|
|
*pixel = ((uint32_t)bg_color << 16) | bg_color;
|
|
break;
|
|
case 1:
|
|
*pixel = ((uint32_t)bg_color << 16) | font_color;
|
|
break;
|
|
case 2:
|
|
*pixel = ((uint32_t)font_color << 16) | bg_color;
|
|
break;
|
|
case 3:
|
|
*pixel = ((uint32_t)font_color << 16) | font_color;
|
|
break;
|
|
default:
|
|
*pixel = 0;
|
|
break;
|
|
}
|
|
data <<= 2;
|
|
pixel++;
|
|
}
|
|
}
|
|
str++;
|
|
ptr += 4;
|
|
}
|
|
}
|
|
|
|
void lcd_clear(uint16_t color)
|
|
{
|
|
uint32_t data = ((uint32_t)color << 16) | (uint32_t)color;
|
|
|
|
lcd_set_area(0, 0, lcd_ctl.width, lcd_ctl.height);
|
|
tft_fill_data(&data, LCD_X_MAX * LCD_Y_MAX / 2);
|
|
}
|
|
|
|
void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t width, uint16_t color)
|
|
{
|
|
uint32_t data_buf[640] = {0};
|
|
uint32_t *p = data_buf;
|
|
uint32_t data = color;
|
|
uint32_t index = 0;
|
|
|
|
data = (data << 16) | data;
|
|
for (index = 0; index < 160 * width; index++)
|
|
*p++ = data;
|
|
|
|
lcd_set_area(x1, y1, x2, y1 + width - 1);
|
|
tft_write_word(data_buf, ((x2 - x1 + 1) * width + 1) / 2, 0);
|
|
lcd_set_area(x1, y2 - width + 1, x2, y2);
|
|
tft_write_word(data_buf, ((x2 - x1 + 1) * width + 1) / 2, 0);
|
|
lcd_set_area(x1, y1, x1 + width - 1, y2);
|
|
tft_write_word(data_buf, ((y2 - y1 + 1) * width + 1) / 2, 0);
|
|
lcd_set_area(x2 - width + 1, y1, x2, y2);
|
|
tft_write_word(data_buf, ((y2 - y1 + 1) * width + 1) / 2, 0);
|
|
}
|
|
|
|
void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr)
|
|
{
|
|
lcd_set_area(x1, y1, x1 + width - 1, y1 + height - 1);
|
|
tft_write_word(ptr, width * height / 2, lcd_ctl.mode ? 2 : 0);
|
|
}
|
|
|