Драйвер для графического ЖКИ [ST7588]
alexvm
Пункты: 2274
Регистрация: 22.05.2009
Добрый день.
Возникла задача - подключить к SK-AT91SAM9G45-XC6SLX графический ЖКИ 13232 на основе контроллера ST7588. Подскажите, пожалуйста, с чего начать? Поиск по данному типу контроллера для Линукс ничего не дает... К плате подключаю по SPI.
Алексей.
Jury093
Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата Возникла задача - подключить к SK-AT91SAM9G45-XC6SLX графический ЖКИ 13232 на основе контроллера ST7588. Подскажите, пожалуйста, с чего начать? Поиск по данному типу контроллера для Линукс ничего не дает... К плате подключаю по SPI.
поищите тут на форуме длинный тред о подключение экранов с SPI. там будет исходник драйвера (несколько вариантов), который написал Саша(sasamy) - на его основе сделаете свой..
google.ru->"pcf8833 site:starterkit.ru"
На любой вопрос есть любой ответ.
alexvm
Пункты: 2274
Регистрация: 22.05.2009
Переделал драйвер, написанный sasamy, (http://www.starterkit.ru/html/index.php?name=forum&op=view&id=3580&num=1), под данный индикатор. Подключил консоль к /dev/fb0, прописал в inittab tty1, но на индикаторе ничего не отображается.
cat test > /dev/fb0 - на индикаторе высвечиваются пиксели, соответствующие ascii кодам символов в файле test (если в файле записан только символ "1", то высвечивается пиксели, соответствующие 0x31, "2" - 0x32).
Соответственно вопросы: почему консоль ничего не кладет в /dev/fb0, и почему cat test > /dev/fb0 пишет в фреймбуфер не графическое представление символа, а ascii код?
драйвер
Код
/*
* Copyright (C) 2009, Alexander Kudjashev <Kudjashev@gmail.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*
* Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven
*
* This driver was written to be used with s65 lph88fb lcd
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/uaccess.h>
#include <mach/gpio.h>
#define X_RES 132
#define Y_RES 32
#define Y_RES_ 4
#define MEM_LEN (X_RES * (Y_RES / 8))
struct lo13232fb_par {
struct spi_device *spi;
u8 *buffer;
u8 *screen;
struct task_struct *lo13232fb_thread_task;
};
static struct fb_fix_screeninfo lo13232fb_fix __devinitdata = {
.id = "lo13232fb",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_MONO01,
.xpanstep = 0,
.ypanstep = 0,
.ywrapstep = 0,
.line_length = X_RES / 8,
.accel = FB_ACCEL_NONE,
};
static struct fb_var_screeninfo lo13232fb_var __devinitdata = {
.xres = X_RES,
.yres = Y_RES,
.xres_virtual = X_RES,
.yres_virtual = Y_RES,
.height = -1,
.width = -1,
.activate = FB_ACTIVATE_NOW,
.vmode = FB_VMODE_NONINTERLACED,
.bits_per_pixel = 1,
.nonstd = 0,
};
static struct fb_ops lo13232fb_ops =
{
.owner = THIS_MODULE,
.fb_read = fb_sys_read,
.fb_write = fb_sys_write,
.fb_fillrect = sys_fillrect,
.fb_copyarea = sys_copyarea,
.fb_imageblit = sys_imageblit,
};
void lcd_wrcmd(struct spi_device *spi, u8 type)
{
at91_set_gpio_output(AT91_PIN_PC12, 0);
//printk("cmd: 0x%x\n", type);
spi_write(spi, &type, 1);
}
void lcd_wrdata(struct spi_device *spi, u8 type)
{
at91_set_gpio_output(AT91_PIN_PC12, 1);
//printk("data: 0x%x\n", type);
spi_write(spi, &type, 1);
}
static int lo13232fb_thread(void *param)
{
struct lo13232fb_par *par = (struct lo13232fb_par *)param;
int i;
u8 *shadow = &par->screen[0];
u8 *buffer = par->buffer;
int flag;
printk("Enter to lo13232fb_thread()\n");
while(!kthread_should_stop())
{
flag = 1;
if(flag)
{
//printk("copy par->buffer to par->screen\n");
//memcpy(par->buffer, par->screen, MEM_LEN);
//memcpy(par->screen, par->buffer, MEM_LEN);
flag = 1;
lcd_wrcmd(par->spi,0x80); lcd_wrcmd(par->spi,0x38);
lcd_wrcmd(par->spi,0x80); lcd_wrcmd(par->spi,0x41);
lcd_wrcmd(par->spi,0x80); lcd_wrcmd(par->spi,0xE0);
lcd_wrcmd(par->spi,0x80); lcd_wrcmd(par->spi,0xF0);
at91_set_gpio_output(AT91_PIN_PC12, 1);
spi_write(par->spi, par->buffer, MEM_LEN);
}
}
return 0;
}
static int __devinit lo13232fb_probe(struct spi_device *spi)
{
struct fb_info *info;
int retval, i;
struct lo13232fb_par *par;
printk("lo13232fb_probe\n");
spi->max_speed_hz = 6 * 1000 * 1000; //12
spi->bits_per_word = 8;
spi->mode = SPI_MODE_0;
retval = spi_setup(spi);
printk("lo13232fb_probe: spi_setup %d\n", retval);
if (retval < 0)
return retval;
/* reset lcd controller */
at91_set_gpio_output(AT91_PIN_PC20, 1);
mdelay(10);
at91_set_gpio_value(AT91_PIN_PC20, 0);
mdelay(2);
at91_set_gpio_value(AT91_PIN_PC20, 1);
mdelay(10);
lcd_wrcmd(spi,0x78);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x39);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x14);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x08);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x38);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x04);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x39);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x9F);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x38);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x05);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x39);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x9F);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x38);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x0C); // 0x0c
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x41);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0xE0);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0xF0);
#if 1
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x3A);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x04);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x81);
lcd_wrcmd(spi,0x80); lcd_wrcmd(spi,0x3B);
lcd_wrcmd(spi,0x40); lcd_wrcmd(spi,0x08);
#endif
retval = -ENOMEM;
printk("Call framebuffer_alloc()\n");
info = framebuffer_alloc(sizeof(struct lo13232fb_par), &spi->dev);
if(!info)
{
printk("lo13232fb_probe: framebuffer_alloc\n");
return retval;
}
par = info->par;
par->spi = spi;
par->buffer = alloc_pages_exact(MEM_LEN, GFP_KERNEL | __GFP_ZERO);
if(!par->buffer)
goto err;
par->screen = kmalloc(MEM_LEN + 1, GFP_KERNEL);
if(!par->screen)
goto err1;
info->screen_base = par->buffer;
info->fbops = &lo13232fb_ops;
info->var = lo13232fb_var;
info->fix = lo13232fb_fix;
info->fix.smem_len = MEM_LEN;
info->fix.smem_start = (unsigned long)virt_to_phys(info->screen_base);
info->screen_size = MEM_LEN;
info->flags = FBINFO_FLAG_DEFAULT;
printk("Call register_framebuffer()\n");
retval = register_framebuffer(info);
printk("register_framebuffer() %d\n", retval);
if (retval < 0)
goto err2;
printk("Call dev_set_drvdata()\n");
dev_set_drvdata(&spi->dev, info);
printk("Call kthread_run()\n");
par->lo13232fb_thread_task = kthread_run(lo13232fb_thread, par, "lo13232fb");
retval = -EIO;
if(IS_ERR(par->lo13232fb_thread_task))
goto err2;
printk(KERN_INFO "fb%d: %s frame buffer device, %d of video memory\n",
info->node, info->fix.id, info->fix.smem_len);
return 0;
err2:
kfree(par->screen);
err1:
printk(KERN_INFO "err1\n");
free_pages_exact(par->buffer, MEM_LEN);
err:
framebuffer_release(info);
return retval;
}
static int __devexit lo13232fb_remove(struct spi_device *spi)
{
struct fb_info *info = dev_get_drvdata(&spi->dev);
if (info)
{
struct lo13232fb_par *par = info->par;
unregister_framebuffer(info);
free_pages_exact(info->screen_base, MEM_LEN);
kfree(par->screen);
framebuffer_release(info);
kthread_stop(par->lo13232fb_thread_task);
}
return 0;
}
/* Power down display on reboot, poweroff or halt */
static void lo13232fb_shutdown(struct spi_device *spi)
{
at91_set_gpio_value(AT91_PIN_PC20, 0);
mdelay(1);
at91_set_gpio_value(AT91_PIN_PC20, 1);
mdelay(10);
}
static struct spi_driver lo13232fb_driver =
{
.driver =
{
.name = "lo13232fb",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = lo13232fb_probe,
.remove = __devexit_p(lo13232fb_remove),
.shutdown = lo13232fb_shutdown,
};
static int __init lo13232fb_init(void)
{
int retval;
printk("lo13232fb spi fb driver\n");
retval = spi_register_driver(&lo13232fb_driver);
printk("lo13232fb_init: spi_register_driver %d\n", retval);
return retval;
}
static void __exit lo13232fb_exit(void)
{
spi_unregister_driver(&lo13232fb_driver);
}
module_init(lo13232fb_init);
module_exit(lo13232fb_exit);
MODULE_AUTHOR("Alexander Kudjashev");
MODULE_DESCRIPTION("lo13232 spi fb driver");
MODULE_LICENSE("GPL");
config
Код
#
# Graphics support
#
CONFIG_HAVE_FB_ATMEL=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not set
# CONFIG_FB_BOOT_VESA_SUPPORT is not set
# CONFIG_FB_CFB_FILLRECT is not set
# CONFIG_FB_CFB_COPYAREA is not set
# CONFIG_FB_CFB_IMAGEBLIT is not set
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_IMAGEBLIT=y
# CONFIG_FB_FOREIGN_ENDIAN is not set
CONFIG_FB_SYS_FOPS=y
# CONFIG_FB_WMT_GE_ROPS is not set
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
#
# Frame buffer hardware drivers
#
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_ATMEL is not set
# CONFIG_FB_UDL is not set
# CONFIG_FB_VIRTUAL is not set
CONFIG_FB_LO13232=y
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
#
# Console display driver support
#
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FONTS=y
# CONFIG_FONT_8x8 is not set
# CONFIG_FONT_8x16 is not set
# CONFIG_FONT_6x11 is not set
# CONFIG_FONT_7x14 is not set
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
CONFIG_FONT_MINI_4x6=y
# CONFIG_FONT_SUN8x16 is not set
Jury093
Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
уже гуд, раз что-то шевелится и отображается!
Цитата Соответственно вопросы: почему консоль ничего не кладет в /dev/fb0, и почему cat test > /dev/fb0 пишет в фреймбуфер не графическое представление символа, а ascii код?
потому что фреймбуфер - это массив памяти и ваш "cat" туда валит бинарные данные, а не битмап символа..
что у вас в логе пишет на тему фреймбуфера и консоли?
попробуйте утилиту
fbset - что она выводит
На любой вопрос есть любой ответ.
Jury093
Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
увы, разрешение 132 не кратно 8, т.е. ничего хорошего не получится, я на эти грабли наступил пару лет назад с разрешением 132х64..
На любой вопрос есть любой ответ.
alexvm
Пункты: 2274
Регистрация: 22.05.2009
Цитата уже гуд, раз что-то шевелится и отображается!
Цитата Соответственно вопросы: почему консоль ничего не кладет в /dev/fb0, и почему cat test > /dev/fb0 пишет в фреймбуфер не графическое представление символа, а ascii код?
потому что фреймбуфер - это массив памяти и ваш "cat" туда валит бинарные данные, а не битмап символа..
что у вас в логе пишет на тему фреймбуфера и консоли?
попробуйте утилиту
fbset - что она выводит
Лог
Код
lo13232fb_probe
lo13232fb_probe: spi_setup
Call framebuffer_alloc()
Call register_framebuffer()
Console: switching to mono frame buffer device 33x5
register_framebuffer()
Call dev_set_drvdata()
Call kthread_run()
fb0: lo13232fb frame buffer device, 528 of video memory
Enter to lo13232fb_thread()
Вроде всё нормально - консоль перключается на фреймбуфер...
alexvm
Пункты: 2274
Регистрация: 22.05.2009
Цитата увы, разрешение 132 не кратно 8, т.е. ничего хорошего не получится, я на эти грабли наступил пару лет назад с разрешением 132х64..
А в чем там может быть затык?
Jury093
Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
вывод более-менее похож..
смущает цифра 528, если 17х32, то д.б. 544, если 16х32=512
есть ли файл и тогда его содержимое
cat /sys/class/graphics/fb0/modes
Цитата прописал в inittab tty1
и вот эту строку..
На любой вопрос есть любой ответ.
Jury093
Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата А в чем там может быть затык?
затык в том, что фреймбуфер не умеет (или я не смог заставить) работать с некратными разрешениями
может конечно я бы не слишком настойчив, но ни 4х6, ни 6х8, ни 8х8 нормально не отображались
первая строка была нормальной пока дело не доходило до символа в последней позиции
На любой вопрос есть любой ответ.
alexvm
Пункты: 2274
Регистрация: 22.05.2009
Цитата вывод более-менее похож..
смущает цифра 528, если 17х32, то д.б. 544, если 16х32=512
есть ли файл и тогда его содержимое
cat /sys/class/graphics/fb0/modes
Цитата прописал в inittab tty1
и вот эту строку..
ЖКИ 132х32/8 = 528, вроде все ок.
# cat /sys/class/graphics/fb0/modes
U:132x32p-0
tty1::respawn:/sbin/getty 38400 tty1 linux