Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru
Партнеры:
otladka.com.ua - г.Киев

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

User Info


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

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

Ник:
Пароль:

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

ОбновитьПодробнееВсегоВсего:12
Форум » starterkit.ru » Embedded Linux
lcd siemens s65 & linux
Vadim
Добавлено 08.06.2009 22:50 Сообщение: 41
Vadim
5

Пункты: 1032
Регистрация: 30.05.2009
Пол: Мужчина
Да, хорошо кони бегут!
А я только начал задумываться о том, какой бы недорогой дисплей можно было бы подключить к 9260.
Мне кажется, что MI0220PT маловат размером, при том же разрешении можно и более 3 дюймов, например MI0320FT (3,2").
Цена в два раза выше, но в наличии.
Спуститься к концу Подняться к началу
Персональная информация
sasa
Добавлено 09.06.2009 00:29 Сообщение: 42
sasa
5

Регистрация: 20.05.2009
На контроллер ssd1289z я не нашел информации в открытом доступе, если найдете - киньте линк откуда можно его скачать.
Спуститься к концу Подняться к началу
Персональная информация
sasa
Добавлено 09.06.2009 22:43 Редактировалось 09.06.2009 22:46 Сообщение: 43
sasa
5

Регистрация: 20.05.2009
Неожиданно нашлось решение проблемы с тормозным звуком в mplayer :) Вот тут
http://www.at91.com/samphpbb/viewtopic.php?f=12&t=18156&sid=7c84afb4b1b89a1f5bfef485bb877e6b

Не дошло же до меня самого что mplayer-у можно явно указать декодер для звука :) Сказал я ему использовать mad и чудеса - больше 50% загрузка процессора на фильме не была. Пора распаивать кодек и переписать атмеловский драйвер чтобы отвязаться от spi на звуке :) а то с ним экран иногда подергивается.
Вот так я перекодировал видео
# mencoder pobeg.avi -oac mp3lame -ovc lavc -lavcopts vcodec=mpeg4:vhq:vqmin=2:vqmax=20:vmax_b_frames=2:vbitrate=256 -vf scale=176:128 -ofps 25 -lameopts cbr:br=96:aq=5:mode=3 -o 2.avi
Вот так запускал mplayer
# mplayer -ac mad 2.avi
а вот такой максимум был при воспроизведении

Цитата

Mem: 28792K used, 976K free, 0K shrd, 624K buff, 15904K cached
CPU: 50.8% usr 2.3% sys 0.0% nic 45.3% idle 0.3% io 0.0% irq 0.9% sirq
Load average: 0.48 0.41 0.21 3/22 347
PID PPID USER STAT VSZ %MEM CPU %CPU COMMAND
343 326 root R 16556 55.5 0 52.1 mplayer -ac mad 2.avi
347 329 root R 1416 4.7 0 1.1 top
Спуститься к концу Подняться к началу
Персональная информация
Lavin (Guest)
Добавлено 16.06.2009 15:40 Сообщение: 44
Lavin (Guest)

Разобрался с драйверами.Переписал под ls020 Ваш драйвер.Начал прицеплять и понял что у меня свободен только SPI1.Все бы ничего но единственный вывод CS отдан аудио-кодеку(такая вот плата) остальные 2 отданы оперативке.Хочу сделать через драйвер.Так и не понял какой вывод использовать как выбор чипа? что тогда написать в board-sam9260ek.c?
Типо:
{
.modalias ="ls020_lcd",
.chip_select =?????,
.max_speed_hz=200000,
.bus_num=1,
},
что в моем случае писать вместо вопросиков,
плата SK-MAT91SAM9260 аудио кодек скоро придет-распаяю.Так что у него CS отбирать не вариант(
Спуститься к концу Подняться к началу
sasa
Добавлено 16.06.2009 21:17 Редактировалось 16.06.2009 21:54 Сообщение: 45
sasa
5

Регистрация: 20.05.2009
В атмеловских драйверах используется програмное управление cs через gpio. В файле
arch/arm/mach-at91/at91sam9260_devices.c
есть такой массив, вкотром прописаны стандартные пины (как если бы cs управлялись аппаратно по даташиту) так вот мне кажется если вместо тех cs которые заняты памятью подствить любоые свободные gpio то все будет прекрасно работать
static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PC5, AT91_PIN_PC4, AT91_PIN_PC3 };
Например, есть свободный gpio AT91_PIN_PB5 и занят SPI1_NPCS1=AT91_PIN_PC5 под память, вписываем место AT91_PIN_PC5 в массив AT91_PIN_PB5 и указываем в описании соответствующий chip_select

static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB5, AT91_PIN_PC4, AT91_PIN_PC3 };

{
.modalias ="ls020_lcd",
.chip_select =1,
.max_speed_hz=200000,
.bus_num=1,
},

соответственно подключаем cs на lcd к AT91_PIN_PB5.

При инициализации он вытряхивает номер пина из массива и переводит его в режит gpio-вывод

/* Choose SPI chip-selects */
for (i = 0; i < nr_devices; i++) {
if (devices[i].controller_data)
cs_pin = (unsigned long) devices[i].controller_data;
else if (devices[i].bus_num == 0)
cs_pin = spi0_standard_cs[devices[i].chip_select];
else
>>> cs_pin = spi1_standard_cs[devices[i].chip_select]; <<<<<

if (devices[i].bus_num == 0)
enable_spi0 = 1;
else
enable_spi1 = 1;

/* enable chip-select pin */
>>>> at91_set_gpio_output(cs_pin, 1); <<<<<

/* pass chip-select pin to driver */
devices[i].controller_data = (void *) cs_pin;
}

так что ему по барабану чего у него там в массиве и какой аппаьатный пин должен быть.

ps .max_speed_hz=200000 - маловато помоему :)
Спуститься к концу Подняться к началу
Персональная информация
Lavin (Guest)
Добавлено 16.06.2009 23:08 Сообщение: 46
Lavin (Guest)

Спасибо.Буду пробовать.
.max_speed_hz=20 100 100 - смайлы единички съели(
Спуститься к концу Подняться к началу
Tyug
Добавлено 18.06.2009 00:35 Сообщение: 47
Tyug
0

Регистрация: 21.05.2009
sasa, а не могли бы вы выложить ключи конфигурации которые использовали при сборке mplayer'a?
Спуститься к концу Подняться к началу
Персональная информация
sasa
Добавлено 18.06.2009 10:42 Сообщение: 48
sasa
5

Регистрация: 20.05.2009
Цитата
не могли бы вы выложить ключи конфигурации которые использовали при сборке mplayer'a?


Я собирал в buildroot с внешним тулчайном с uclibc и eabi, так что смотрите если что в package/multimedia/mplayer патчи лежат в этой же директории, ключи можно посмотреть в mplayer.mk. Пробовал сам собрать версию посвежее - не получилось, так что как говорится от добра добра не ищут - зачем новое если старое отлично работает :)
Спуститься к концу Подняться к началу
Персональная информация
Lavin
Добавлено 18.06.2009 13:42 Редактировалось 18.06.2009 15:30 Сообщение: 49
Lavin
2.4

Пункты: 1267
Регистрация: 22.05.2009
Пол: Мужчина
Из: Москва
Не судите строго.Первая попытка драйвера для ls020.Взял свой проект для Mega32 и драйвер от sasa.Вот что получилось.
Код
/*
* Copyright (C) 2009, Alexander Kudjashev <Kudjashev@gmail.com> and Dmitri Zavrazhnov <mesh3d@mail.ru>
*
* 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 ls020 lcd using source of driver lph88fb
*/

#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 INIT1[24]={
0xFD, 0xFD, 0xFD, 0xFD, 0xEF, 0x00, 0xEE, 0x04, 0x1B, 0x04, 0xFE, 0xFE,
0xFE, 0xFE, 0xEF, 0x90, 0x4A, 0x04, 0x7F, 0x3F, 0xEE, 0x04, 0x43, 0x06};
static u8 INIT2[40]={
0xEF, 0x90, 0x09, 0x83, 0x08, 0x00, 0x0B, 0xAF, 0x0A, 0x00, 0x05, 0x00, 0x06, 0x00,
0x07, 0x00, 0xEF, 0x00, 0xEE, 0x0C, 0xEF, 0x90, 0x00, 0x80, 0xEF, 0xB0, 0x49, 0x02,
0xEF, 0x00, 0x7F, 0x01, 0xE1, 0x81, 0xE2, 0x02, 0xE2, 0x76, 0xE1, 0x83};

void lcd_wrcmd(struct spi_device *spi, u8 type)
{
at91_set_gpio_output(LCD_RS,1);
mdelay(5);
spi_write(spi, &type, 1);
//PORTB&=~(1<<LCD_CS);
//PORTB|=(1<<LCD_RS);
//SPCR|=(1<<SPE);
//SPDR=sData;
//while(!(SPSR & (1<<SPIF)));
//PORTB|=(1<<LCD_CS);
}

void lcd_wrdata(struct spi_device *spi, u8 type)
{
at91_set_gpio_output(LCD_RS,0);
mdelay(5);
spi_write(spi, &type, 1);
//PORTB&=~(1<<LCD_CS);
//PORTB&=~(1<<LCD_RS);
//SPCR|=(1<<SPE);
//SPDR=sData;
//while(!(SPSR & (1<<SPIF)));
//PORTB|=(1<<LCD_CS);
}

struct ls020fb_par {
struct spi_message msg;
struct spi_transfer xfer;
struct spi_device *spi;
struct task_struct *ls020fb_thread_task;
u8 *buffer;
u8 *screen;
u8 *rx;
u32 pseudo_palette[16];
};

static struct fb_fix_screeninfo ls020fb_fix __devinitdata = {
.id = "ls020fb",
.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 ls020fb_var __devinitdata = {
.xres = X_RES,
.yres = Y_RES,
.xres_virtual = X_RES,
.yres_virtual = Y_RES,
.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 int ls020fb_setcolreg(unsigned regno, unsigned r, unsigned g,
unsigned b, unsigned transp,
struct fb_info *info)
{

if (regno >= 16)
return -EINVAL;

((u32 *) info->pseudo_palette)[regno] =
(r & 0xf800) | (g & 0xfc00) >> 5 | (b & 0xf800) >> 11;

return 0;
}


static struct fb_ops ls020fb_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = ls020fb_setcolreg,
.fb_read = fb_sys_read,
.fb_write = fb_sys_write,
.fb_fillrect = sys_fillrect,
.fb_copyarea = sys_copyarea,
.fb_imageblit = sys_imageblit,
};

void lcd_wrcmd16(struct spi_device *spi,uint16_t dat)
{
lcd_wrcmd(spi,u8(dat>>8));
lcd_wrcmd(spi,u8(dat));
}

static int ls020fb_thread(void *param)
{
struct ls020fb_par *par = (struct ls020fb_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);
lcd_wrcmd16(par->spi,0x0504);
lcd_wrcmd16(par->spi,0x0800+0);
lcd_wrcmd16(par->spi,0x0A00+0);
lcd_wrcmd16(par->spi,0x0900+176);
lcd_wrcmd16(par->spi,0x0B00+132);

spi_sync(par->spi, &par->msg);
}
return 0;
}

static int __devinit ls020fb_probe(struct spi_device *spi)
{
struct fb_info *info;
struct ls020fb_par *par;
struct spi_message *m;
struct spi_transfer *x;
int retval, i;

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(LCD_RESET, 1);
mdelay(10);
at91_set_gpio_value(LCD_RESET, 0);
mdelay(5);
at91_set_gpio_value(LCD_RESET, 1);
mdelay(10);

for(i = 0; i < 24;i++)
lcd_wrcmd(spi,INIT1[i]);
mdelay(7);
for(i = 0; i < 40; i++)
lcd_wrcmd(spi,INIT2[i]);
mdelay(50);
lcd_wrcmd(spi,0x80);//init3
lcd_wrcmd(spi,0x01);
//PORTB&=~(1<<LCD_CS);
lcd_wrcmd(spi,0xEF);
lcd_wrcmd(spi,0x90);
lcd_wrcmd(spi,0x00);
lcd_wrcmd(spi,0x00);

retval = -ENOMEM;

info = framebuffer_alloc(sizeof(struct ls020fb_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;

par->rx = kmalloc(MEM_LEN + 1, GFP_KERNEL);
if(!par->rx)
goto err2;

info->screen_base = par->buffer;
info->fbops = &ls020fb_ops;
info->var = ls020fb_var;
info->fix = ls020fb_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;
info->pseudo_palette = par->pseudo_palette;

retval = fb_alloc_cmap(&(info->cmap), 256, 0);
if (retval < 0)
goto err3;

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

dev_set_drvdata(&spi->dev, info);

m = &par->msg;
x = &par->xfer;

spi_message_init(m);

x->tx_buf = par->screen;
x->rx_buf = par->rx;
x->len = MEM_LEN + 1;

spi_message_add_tail(x, m);

par->ls020fb_thread_task = kthread_run(ls020fb_thread, par, "ls020fb");
retval = -EIO;
if(IS_ERR(par->ls020fb_thread_task))
goto err5;

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;

err5:
unregister_framebuffer(info);
err4:
fb_dealloc_cmap(&info->cmap);
err3:
kfree(par->rx);
err2:
kfree(par->screen);
err1:
free_pages_exact(par->buffer, MEM_LEN);
err:
framebuffer_release(info);

return retval;
}

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

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

kthread_stop(par->ls020fb_thread_task);
unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap);
kfree(par->rx);
kfree(par->screen);
free_pages_exact(par->buffer, MEM_LEN);
framebuffer_release(info);
}
return 0;
}

/* Power down display on reboot, poweroff or halt */
static void ls020fb_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 ls020fb_driver = {
.driver = {
.name = "ls020fb",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = ls020fb_probe,
.remove = __devexit_p(ls020fb_remove),
.shutdown = ls020fb_shutdown,
};

static int __init ls020fb_init(void)
{
printk("ls020fb spi fb driver\n");
return spi_register_driver(&ls020fb_driver);
}

static void __exit ls020fb_exit(void)
{
spi_unregister_driver(&ls020fb_driver);
}

module_init(ls020fb_init);
module_exit(ls020fb_exit);

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

Регистрация: 20.05.2009
Цитата
void lcd_wrcmd(struct spi_device *spi, u8 type)
{
at91_set_gpio_output(LCD_RS,1);

void lcd_wrdata(struct spi_device *spi, u8 type)
{
at91_set_gpio_output(LCD_RS,1);


что-то тут не так - в какойто из них должно быть
at91_set_gpio_output(LCD_RS,0) как я понимаю

Цитата
mdelay(5);


для чего такая длительаня задержка ?


Цитата
spi_write(spi, type, 1);


неправильно - нужно передать адес а не значение, правильно будет

spi_write(spi, &type, 1);


Цитата
void lcd_wrcmd16(struct spi_device *spi,uint16_t dat)
{
lcd_wrcmd(spi,u8(dat>>8));
lcd_wrcmd(spi,u8(dat));
}


Можно сразу перевести spi в 16 битный режим, в ls020 нет префиксного байта для команды или данных - там все передачи чисто 16 битные, надо только массивы инициализации скорректировать под 16 битные данные. Например вместо

static u8 INIT1[24]={
0xFD, 0xFD, 0xFD, 0xFD, 0xEF, 0x00, 0xEE, 0x04, 0x1B, 0x04, 0xFE, 0xFE,
0xFE, 0xFE, 0xEF, 0x90, 0x4A, 0x04, 0x7F, 0x3F, 0xEE, 0x04, 0x43, 0x06};

переделать на

static u16 INIT1[12]={
0xFDFD, 0xFDFD, 0xEF00, 0xEE04, 0x1B04, 0xFEFE,
0xFEFE, 0xEF90, 0x4A04, 0x7F3F, 0xEE04, 0x4306};
и тд - все команды в этом lcd 16 битные. Потом в probe вместо spi->bits_per_word = 8; заменить на spi->bits_per_word = 16;
при не нужно будет делать этот цикл

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

он съедает много от процессора а сразу передавать сам буфер - при этом нужно подругому выделить память под буфер - нужен когеретный с dma - чтобы был одновременный доступ и pdc и процессора к этому буферу, смотрите мой последний вариант. При этом нужен буфер в два раза больше - еще такой же для приема из-за глюка в атмеловском драйвере spi - он неправильно разбивает на куски буфер длинней страницы памяти в 4 кб - это все нужно чтобы сообщить драйверу spi что наш буфер уже смапен на dma и передать ему физические адреса этих буферов - через spi_write это невозможно сделать, только через spi_sync которому передается не просто адрес буфера а полная информация в структуре spi_transfer. Это то что с наскоку разглядел - к сожаление в этом форуме не работает форматирование кода.
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Embedded Linux