| #include "lcd.h" |
| #include "st7735.c" |
| #include "font.c" |
| #include "hal.h" |
| |
| #define NULL 0 |
| #define printf obm_printf |
| #define mdelay(x) Delay((x) * 1000) |
| |
| #ifdef CONFIG_SPI_LCD_3WIRE |
| #define FB_SIZE (CONFIG_SPI_LCD_XRES * CONFIG_SPI_LCD_YRES * 2 * 2) |
| #else |
| #define FB_SIZE (CONFIG_SPI_LCD_XRES * CONFIG_SPI_LCD_YRES * 2) |
| #endif |
| |
| static unsigned char *gFramebuffer = NULL; |
| |
| static inline void LCD_SELECT_DATA_OR_CMD(int a) |
| { |
| #ifndef CONFIG_SPI_LCD_3WIRE |
| gpio_direction_output(CONFIG_SPI_LCD_RS_PIN, a); |
| #endif |
| } |
| |
| void LCD_SEND_DATA(void) |
| { |
| LCD_SELECT_DATA_OR_CMD(1); |
| } |
| |
| void LCD_SEND_CMD(void) |
| { |
| LCD_SELECT_DATA_OR_CMD(0); |
| } |
| |
| void lcd_power(int on) |
| { |
| #ifdef CONFIG_SPI_LCD_POWER_PIN |
| gpio_direction_output(CONFIG_SPI_LCD_POWER_PIN, on); |
| #endif |
| } |
| |
| void lcd_reset(void) |
| { |
| gpio_direction_output(CONFIG_SPI_LCD_RST_PIN, 1); |
| mdelay(50); |
| gpio_direction_output(CONFIG_SPI_LCD_RST_PIN, 0); |
| mdelay(50); |
| gpio_direction_output(CONFIG_SPI_LCD_RST_PIN, 1); |
| mdelay(150); |
| } |
| |
| static void lcd_set_backlight(int on) |
| { |
| gpio_direction_output(CONFIG_SPI_LCD_BL_PIN, on); |
| } |
| |
| static void lcd_spi_write(unsigned int data) |
| { |
| Assert_CS(); |
| SPI_FireUp(); |
| SPI_WriteData(data); |
| SPI_WaitSSPComplete(); |
| SPI_DisableSSP(); |
| Deassert_CS(); |
| } |
| |
| static int lcd_write_cmd(unsigned char cmd) |
| { |
| int ret = 0; |
| unsigned short bits, _data; |
| #ifdef CONFIG_SPI_LCD_3WIRE |
| bits = 9; |
| _data = cmd; |
| #else |
| bits = 8; |
| _data = cmd; |
| LCD_SEND_CMD(); |
| #endif |
| SPI_ConfigDSS(bits); |
| lcd_spi_write(_data); |
| |
| return ret; |
| } |
| |
| static int lcd_write_data(unsigned char data) |
| { |
| int ret = 0; |
| unsigned short bits, _data; |
| #ifdef CONFIG_SPI_LCD_3WIRE |
| bits = 9; |
| _data = 0x100 | data; |
| #else |
| bits = 8; |
| _data = data; |
| LCD_SEND_DATA(); |
| #endif |
| SPI_ConfigDSS(bits); |
| lcd_spi_write(_data); |
| return ret; |
| } |
| |
| static int lcd_write_data16(unsigned short data) |
| { |
| int ret = 0; |
| unsigned int bits, _data; |
| #ifdef CONFIG_SPI_LCD_3WIRE |
| unsigned char h, l; |
| bits = 18; |
| h = (data >> 8) & 0xff; |
| l = data & 0xff; |
| _data = ((0x100 | h) << 9) | (0x100 | l); |
| #else |
| bits = 16; |
| _data = data; |
| LCD_SEND_DATA(); |
| #endif |
| SPI_ConfigDSS(bits); |
| lcd_spi_write(_data); |
| return ret; |
| } |
| |
| static int lcd_set_window(unsigned char xs, unsigned char ys, unsigned char xe, unsigned char ye) |
| { |
| lcd_write_cmd(0x2a); // column addr set |
| lcd_write_data(0x00); |
| lcd_write_data(xs + 2); |
| lcd_write_data(0x00); |
| lcd_write_data(xe + 2); |
| lcd_write_cmd(0x2b); // row addr set |
| lcd_write_data(0x00); |
| lcd_write_data(ys + 3); |
| lcd_write_data(0x00); |
| lcd_write_data(ye + 3); |
| return 0; |
| } |
| |
| static int lcd_write_memory(unsigned char *buf, int cnt) |
| { |
| int i; |
| lcd_write_cmd(0x2c); // memory write command |
| |
| for (i = 0; i < cnt; i++) |
| lcd_write_data(buf[i]); |
| |
| return 0; |
| } |
| |
| static int lcd_fill(unsigned short color) |
| { |
| unsigned char x, y, low, high; |
| unsigned short *buf = (unsigned short *)gFramebuffer; |
| memset(buf, 0, FB_SIZE); |
| |
| lcd_set_window(0, 0, CONFIG_SPI_LCD_XRES - 1, CONFIG_SPI_LCD_YRES - 1); |
| for (x=0; x < CONFIG_SPI_LCD_XRES; x++) |
| for (y=0; y < CONFIG_SPI_LCD_YRES; y++) { |
| low = color & 0xff; |
| high = (color & 0xff00) >> 8; |
| #ifdef CONFIG_SPI_LCD_3WIRE |
| *(buf++) = low; |
| *(buf++) = high; |
| #else |
| *(buf++) = (low << 8) | high; |
| #endif |
| } |
| |
| return lcd_write_memory(gFramebuffer, FB_SIZE); |
| } |
| |
| static int lcd_draw_logo( |
| unsigned char p_x, unsigned char line, |
| unsigned char W, unsigned char H, |
| unsigned char *buf, unsigned short txt_color, unsigned short bg_color) |
| { |
| int i, j, k; |
| unsigned char c; |
| int index, size; |
| unsigned short *buff = (unsigned short *)gFramebuffer; |
| |
| lcd_set_window(line, p_x, (line + H - 1), (p_x + W - 1)); |
| |
| index = 0; |
| for(i = 0; i < W; i++) { |
| for(k = (H / 8 -1); k >= 0; k--) { |
| c = *buf++; |
| for(j = (8 - 1); j >= 0; j--) { |
| if((1 << (7 - j)) & c) |
| *(buff++) = txt_color; |
| else |
| *(buff++) = bg_color; |
| index++; |
| } |
| } |
| } |
| |
| size = index; |
| return lcd_write_memory(gFramebuffer, size * 2); |
| } |
| |
| static void panel_init(void *sequence) |
| { |
| struct lcd_cmd *array = (struct lcd_cmd *)sequence; |
| if (!array) { |
| printf("Warning: null init sequence.\n"); |
| return; |
| } |
| |
| while (array->type != CMD_TYPE_END) { |
| switch (array->type) { |
| case CMD_TYPE_START: |
| break; |
| case CMD_TYPE_CMD: |
| lcd_write_cmd(array->data); |
| break; |
| case CMD_TYPE_DATA: |
| lcd_write_data(array->data); |
| break; |
| case CMD_TYPE_DELAY: |
| mdelay(array->data); |
| break; |
| } |
| array++; |
| } |
| |
| printf("Panel: init done.\r\n"); |
| } |
| |
| int spi_lcd_init(void) |
| { |
| int ret; |
| |
| gFramebuffer = malloc(FB_SIZE); |
| lcd_reset(); |
| |
| panel_init(st7735_init_sequence); |
| |
| lcd_fill(0); // 0: Black, 0xF800: Red, 0x7E0: Green, 0x1F: Blue |
| lcd_set_backlight(1); |
| |
| return 0; |
| } |
| |
| void lcd_display_char(unsigned char x, unsigned char y, const char c) |
| { |
| int i, j, len; |
| unsigned short pos; |
| unsigned char *font; |
| |
| pos = c - ' '; |
| |
| /* font length */ |
| len = (LCD_Currentfonts->width * LCD_Currentfonts->height) / 8; |
| |
| font = (unsigned char *)&LCD_Currentfonts->table[pos * len]; |
| |
| lcd_set_window (x, y, x + LCD_Currentfonts->width - 1, y + LCD_Currentfonts->height - 1); |
| lcd_write_cmd(0x2c); |
| |
| for (i = 0; i < len; i++) { |
| for (j = 0; j < 8; j++) { |
| if (font[i] & (0x80 >> j)) |
| lcd_write_data16(0xffff); |
| else |
| lcd_write_data16(0); |
| } |
| } |
| } |
| |
| void lcd_display_string(unsigned short x, unsigned short y, char *str) |
| { |
| unsigned short x0, y0; |
| x0 = x; |
| y0 = y; |
| |
| while (*str) { |
| if (x > CONFIG_SPI_LCD_XRES) { |
| x = x0; |
| y += LCD_Currentfonts->height; |
| } |
| |
| if (y > CONFIG_SPI_LCD_YRES) { |
| x = x0; |
| y = y0; |
| } |
| |
| lcd_display_char(x, y, *str); |
| str++; |
| x += LCD_Currentfonts->width; |
| } |
| } |