Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:1
Поисковых ботовПоисковых ботов:3
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:5
Форум » starterkit.ru » Embedded Linux
lcd siemens s65 & linux
sasa
Добавлено 20.05.2009 22:59 Редактировалось 20.05.2009 23:10
0
Сообщение: 1
sasa
5

Регистрация: 20.05.2009
Добил сегодня драйвер для lph88. Как обещал выкладываю исходники. Есть вопросы по работе spi в атмеловских драйверах, у себя в исходниках немного подправил чтобы работало. Не стал разбираться конкретней - видимо все же багрепорт им отправить надо - пока не охота разбираться.

Странный форум - но у меня ничего не происходит при нажатии "загрузить" ...

Код
/*
* 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>

/* lcd resolution */
#define X_RES 176
#define Y_RES 132
#define B_PP 16
#define MEM_LEN (X_RES * Y_RES * B_PP / 8)

static u8 lcd_init_data[] __devinitdata = {0x00,0x00,0x01,
0x07,0x00,0x00, 0x02,0x04,0x00, 0x04,0x00,0x00,
0x0C,0x00,0x01, 0x0D,0x06,0x16, 0x0E,0x10,0x10,
0x03,0x00,0x0C, 0x0E,0x2D,0x1F, 0x0D,0x06,0x16,
0x01,0x03,0x15, 0x0F,0x00,0x00, 0x0B,0x00,0x00,
0x11,0x00,0x00, 0x06,0x00,0x00, 0x05,0x00,0x38,
0x14,0xAF,0x00, 0x15,0x00,0x00, 0x16,0x83,0x00,
0x17,0xAF,0x00, 0x20,0x00,0x00, 0x30,0x00,0x00,
0x31,0x04,0x00, 0x32,0x02,0x07, 0x33,0x07,0x00,
0x34,0x00,0x05, 0x35,0x07,0x03, 0x36,0x07,0x07,
0x37,0x00,0x07, 0x3A,0x12,0x00, 0x3B,0x00,0x09,
0x07,0x00,0x05, 0x07,0x00,0x25, 0x07,0x00,0x27,
0x07,0x00,0x37};

static void lcd_comtype(struct spi_device *spi, u8 type)
{
u8 buff[3];

buff[0] = 0x74;
buff[1] = 0x00;
buff[2] = type;

spi_write(spi, buff, 3);
}

static void lcd_comdata(struct spi_device *spi, u8 data1, u8 data2)
{
u8 buff[3];

buff[0] = 0x76;
buff[1] = data1;
buff[2] = data2;

spi_write(spi, buff, 3);
}

static void lcd_command(struct spi_device *spi, u8 *data)
{
lcd_comtype(spi, data[0]);
lcd_comdata(spi, data[1], data[2]);

switch(data[0]) {
/* Power Control - need delay */
case 0x03:
case 0x04:
case 0x0c:
case 0x0d:
case 0x0e:
mdelay(40);
}
}

struct lph88fb_par {
struct spi_device *spi;
u8 *buffer;
u8 *screen;
struct task_struct *lph88fb_thread_task;
};

static struct fb_fix_screeninfo lph88fb_fix __devinitdata = {
.id = "lph88fb",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
.xpanstep = 0,
.ypanstep = 0,
.ywrapstep = 0,
.line_length = X_RES * B_PP / 8,
.accel = FB_ACCEL_NONE,
};

static struct fb_var_screeninfo lph88fb_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 = B_PP,
.red = { 11, 5, 0 },
.green = { 5, 6, 0 },
.blue = { 0, 5, 0 },
.nonstd = 0,
};

static struct fb_ops lph88fb_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,
};

static int lph88fb_thread(void *param)
{
struct lph88fb_par *par = (struct lph88fb_par *)param;
int i;
u8 *shadow = &par->screen[1];
u8 *buffer = par->buffer;

par->screen[0] = 0x76;

while(!kthread_should_stop()) {
for(i = 0; i < MEM_LEN; i += 2) {
shadow[i] = buffer[i+1];
shadow[i+1] = buffer[i];
}

lcd_comtype(par->spi, 0x21);
lcd_comdata(par->spi, 0x00, 0x00);
lcd_comtype(par->spi, 0x22);
spi_write(par->spi, par->screen, MEM_LEN + 1);
}

return 0;
}

static int __devinit lph88fb_probe(struct spi_device *spi)
{
struct fb_info *info;
int retval, i;
struct lph88fb_par *par;

spi->max_speed_hz = 20 * 1000 * 1000;
spi->bits_per_word = 8;
spi->mode = SPI_MODE_0;

retval = spi_setup(spi);
if(retval < 0)
return retval;

/* reset lcd controller */
at91_set_gpio_output(AT91_PIN_PB4, 1);
mdelay(10);
at91_set_gpio_value(AT91_PIN_PB4, 0);
mdelay(1);
at91_set_gpio_value(AT91_PIN_PB4, 1);
mdelay(10);

for(i = 0; i < sizeof(lcd_init_data); i += 3)
lcd_command(spi, &lcd_init_data[i]);

retval = -ENOMEM;

info = framebuffer_alloc(sizeof(struct lph88fb_par), &spi->dev);
if(!info)
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 = &lph88fb_ops;
info->var = lph88fb_var;
info->fix = lph88fb_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;

retval = register_framebuffer(info);
if (retval < 0)
goto err2;

dev_set_drvdata(&spi->dev, info);

par->lph88fb_thread_task = kthread_run(lph88fb_thread, par, "lph88fb");
retval = -EIO;
if(IS_ERR(par->lph88fb_thread_task))
goto err2;

printk(KERN_INFO "fb%d: %s frame buffer device, %dK of video memory\n",
info->node, info->fix.id, info->fix.smem_len >> 10);

return 0;

err2:
kfree(par->screen);
err1:
free_pages_exact(par->buffer, MEM_LEN);
err:
framebuffer_release(info);

return retval;
}

static int __devexit lph88fb_remove(struct spi_device *spi)
{
struct fb_info *info = dev_get_drvdata(&spi->dev);

if (info) {
struct lph88fb_par *par = info->par;

unregister_framebuffer(info);
free_pages_exact(info->screen_base, MEM_LEN);
kfree(par->screen);
framebuffer_release(info);
kthread_stop(par->lph88fb_thread_task);
}
return 0;
}

/* Power down display on reboot, poweroff or halt */
static void lph88fb_shutdown(struct spi_device *spi)
{
at91_set_gpio_value(AT91_PIN_PB4, 0);
mdelay(1);
at91_set_gpio_value(AT91_PIN_PB4, 1);
mdelay(10);
}

static struct spi_driver lph88fb_driver = {
.driver = {
.name = "lph88fb",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = lph88fb_probe,
.remove = __devexit_p(lph88fb_remove),
.shutdown = lph88fb_shutdown,
};

static int __init lph88fb_init(void)
{
printk("lph88fb spi fb driver\n");
return spi_register_driver(&lph88fb_driver);
}

static void __exit lph88fb_exit(void)
{
spi_unregister_driver(&lph88fb_driver);
}

module_init(lph88fb_init);
module_exit(lph88fb_exit);

MODULE_AUTHOR("Alexander Kudjashev");
MODULE_DESCRIPTION("lph88 spi fb driver");
MODULE_LICENSE("GPL");
Спуститься к концу Подняться к началу
Персональная информация
sasa
Добавлено 20.05.2009 23:23 Сообщение: 2
sasa
5

Регистрация: 20.05.2009
Похоже форум такой же глюкавый как драйверы атмел :) но сейчас загрузка заработала :) Чтобы драйвер работал я исправил в файле atmel_spi.c

#define BUFFER_SIZE PAGE_SIZE * 16

В общем если кратко - когда в сообщении spi для передачи не определен буфер для приема сообщений (а это штатная ситуация - см например spi_write) то для приема назначается свой маленький dma буфер размером со страницу памяти (4096 байт) в то же время буфер для передачи урезается до этой длины и исходное сообщение бъется на куски но как-то неправильно - в результате в очереди оказывается куча одинаковых сообщений - что дальше происходит не стал разбираться, просто увеличил буфер до размера чтобы поместился весь экран.
Спуститься к концу Подняться к началу
Персональная информация
sasa
Добавлено 20.05.2009 23:33 Редактировалось 20.05.2009 23:42 Сообщение: 3
sasa
5

Регистрация: 20.05.2009
Не понимаю - куда файлы прикрепленные деваются ? Файл загружается, пришет complete а после отправки сообщение без вложений... Где искать вложения ?
Спуститься к концу Подняться к началу
Персональная информация
Pavel Ivanchenko
Добавлено 21.05.2009 08:11 Сообщение: 4
Pavel Ivanchenko
Admin
4.39

Пункты: 92788
Регистрация: 24.03.2009
Пол: Мужчина
C прикреплением файлов есть глюки, попробуйте из под IE прикрепить, должно работать ...
Спуститься к концу Подняться к началу
Персональная информация
sasa
Добавлено 21.05.2009 11:57 Сообщение: 5
sasa
5

Регистрация: 20.05.2009
Павел - это смешно :) В ветке про linux предложить пользоваться IE :) Кстати - что с тегом code ? Он все пробелы и табы съел - в чем тогда его глубокий смысл - в рамке и надписи код ? Это же вроде платный движок - неужели все так плохо что ничего не работает ?
Спуститься к концу Подняться к началу
Персональная информация
Pavel Ivanchenko
Добавлено 21.05.2009 18:04 Редактировалось 21.05.2009 18:05 Сообщение: 6
Pavel Ivanchenko
Admin
4.39

Пункты: 92788
Регистрация: 24.03.2009
Пол: Мужчина
Вот так и живем, в надежде, что скоро исправят :) ...
Спуститься к концу Подняться к началу
Персональная информация
sasa
Добавлено 21.05.2009 19:57 Редактировалось 21.05.2009 20:19 Сообщение: 7
sasa
5

Регистрация: 20.05.2009
Мне вообще-то все равно - свое обещание я выполнил, кому нужно разберутся и с таким текстом. А в ветке про linux принципиально из-под IE не буду работать :) Для полноты картины, в своем файле board-sam9260ek.c добавил после описания аудиокодека новый элемент:

Цитата
.mode = SPI_MODE_1,
.platform_data = &at73c213_data,
},
#endif
#if defined(CONFIG_FB_LPH88) || defined(CONFIG_FB_LPH88_MODULE)
{ /* s65 lcd */
.modalias = "lph88fb",
.bus_num = 1,
.chip_select = 0,
},
#endif


и в drivers/video/Makefile, drivers/video/Kconfig добавил записи для своего драйвера по аналогии с другими - там все просто. Если у кто-то использует аудиокодек - не забывайте учитывать CS - они должны быть разные и садите lcd на свободный канал.
PS жидал большего от этого дисплея - неудобно у него сделано управление, думаю с ls020 круче получится :) Там можно spi в 16 битный режим перевести - у меня не позволяет один единственный байт который нарушает выравнивание на границе полуслова, как ни крутил - не смог обойти это - в результате 8 битный режим и дурацкий цикл
for(i = 0; i < MEM_LEN; i += 2) {
shadow[i] = buffer[i+1];
shadow[i+1] = buffer[i];
как расплата за несовпадение endian lcd и процессора.

Еще забыл - чтобы упростить жизнь - лучше сразу включить в конфиге (это в файле Kconfig) поддержку FB_SYS... :

config FB_LPH88
tristate "lph88 Frame Buffer support"
depends on FB && ARCH_AT91SAM9260
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
help
Support for the s65 lph88 lcd controller.
Спуститься к концу Подняться к началу
Персональная информация
Lavin (Guest)
Добавлено 21.05.2009 23:08 Сообщение: 8
Lavin (Guest)

Наконец то достал экран только с контроллером LS020xxx начал рыть форум и что то не нашел драйвера.Если кто может объяснить новичку как его прикрутить к плате SKMAT91SAM9260.С линухом меньше месяца знаком(
Спуститься к концу Подняться к началу
sasa
Добавлено 21.05.2009 23:44 Сообщение: 9
sasa
5

Регистрация: 20.05.2009
Цитата
экран только с контроллером LS020xxx начал рыть форум и что то не нашел драйвера

Насколько я знаю его нет. Там протокол совсем другой - нужно смотреть у суперкранца инициализацию и изученные команды и переделать. У меня вслепую не получится переписать, хотя если честно общие изменения небольшие - массив инициализации другой, добавляется еще одна линия gpio для сигнала RS и сответственно команды другие. Единственно - я не видел нигде - как там поменять направление хотя бы одной оси а то точка отсчета (0,0) там поумолчанию не в том углу - без этого ничего не получится - на экране будет зеркальное отражение :)
Спуститься к концу Подняться к началу
Персональная информация
Guest (Guest)
Добавлено 22.05.2009 00:03 Сообщение: 10
Guest (Guest)

Я форум смотрел как то и наткнулся что в теме lcd второй заход уважаемый susamy кажется написал драйвер именно дл ls020 но не успел скачать,решил пока созреет продукт и воспользоваться а щас я этой темы не нахожу((.Насчет зеркального отображения-там с координатами и режимом заполнения практически что угодно творить можно)
У вас как успехи?консоль уже выводит?
Спуститься к концу Подняться к началу
Форум » starterkit.ru » Embedded Linux