Ник:
Пароль:

Контакты

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
Эмуляция master-контроллера spi через gpio в linux
sasamy
Добавлено 01.06.2010 22:54 Редактировалось 01.06.2010 23:06
0
Сообщение: 1
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Понадобилось на imx233 прикрутить тачскрин - spi аппаратный на разъеме естественно не доступен, но зато Павел предусмотрительно завел его на свободные/доступные пины gpio. Так как изобретать велосипед не хотелось при живом драйвере в ядре для ads7843 - нужно было эмулировать spi контроллер на gpio что linux умеет из коробки. Для этого нужны совсем небольшие усилия:
1 включить поддержку spi bitbang
Location:
-> Device Drivers
-> SPI support (SPI [=y])
Selects: SPI_BITBANG
2 В описании платы (board файл) задать gpio для эмулируемого контроллера, например для imx233:

Код

struct spi_gpio_platform_data sk_spi_gpio_platform_data = {
.sck = PINID_LCD_DOTCK,
.mosi = PINID_GPMI_WPN,
.miso = PINID_GPMI_RDY1,
.num_chipselect = 1,
};

struct platform_device sk_spi_gpio_device = {
.name = "spi_gpio",
.id = 3,
.dev = {
.platform_data = &sk_spi_gpio_platform_data,
},
};


и прописать это устройство:

Код

static struct platform_device *devices[] = {
&stmp3xxx_dbguart,
&stmp3xxx_appuart,
&stmp3xxx_watchdog,
&stmp3xxx_touchscreen,
&stmp3xxx_rtc,
&stmp3xxx_keyboard,
&stmp3xxx_framebuffer,
&stmp3xxx_backlight,
&stmp3xxx_rotdec,
&stmp3xxx_persistent,
&stmp3xxx_dcp_bootstream,
&stmp3xxx_dcp,
&stmp3xxx_battery,
&stmp378x_pxp,
&stmp378x_i2c,
&stmp3xxx_spdif,
&stmp378x_audio,
&stmp3xxx_viim,
#if defined(CONFIG_TOUCHSCREEN_ADS7846)
&sk_spi_gpio_device,
#endif
};


Все - наш новоиспеченный контроллер spi готов к работе - при этом определено для него только 1 устройство (.num_chipselect = 1,) и его идентификатор шины - 3 (.id = 3,)

Для примера - тачскрин описан в таблице ведомых устройств таким образом:

Код

#if defined(CONFIG_TOUCHSCREEN_ADS7846)
[1] = { /* Touchscreen support */
.modalias = "ads7846",
.max_speed_hz = 100 * 1000, /* 100 кГц вполне хватает */
.bus_num = 3, /* этим мы сообщаем что устройство подключено к шине с id = 3 */
.controller_data = (void *) PINID_SSP1_DATA2, /* это описан gpio-пин для cs */
.platform_data = &ads_info,
},
#endif
};


для полноты картины остальные данные которые относятся к драйверу тачскрина:

Код

#define TS_PENIRQ_GPIO PINID_PWM2

static int ads7846_dev_init(void)
{

if (gpio_request(TS_PENIRQ_GPIO, "ADS7846 pendown") < 0)
printk(KERN_ERR "can't get ads7846 pen down GPIO\n");

gpio_direction_input(TS_PENIRQ_GPIO);
set_irq_type(gpio_to_irq(TS_PENIRQ_GPIO), IRQ_TYPE_EDGE_FALLING);

return gpio_to_irq(TS_PENIRQ_GPIO);
}

static int ads7843_pendown_state(void)
{
return !gpio_get_value(TS_PENIRQ_GPIO); /* Touchscreen PENIRQ */
}

static struct ads7846_platform_data ads_info = {
.model = 7843,
.x_min = 150,
.x_max = 3830,
.y_min = 190,
.y_max = 3830,
.vref_delay_usecs = 100,
.x_plate_ohms = 450,
.y_plate_ohms = 250,
.get_pendown_state = ads7843_pendown_state,
};

.................

#if defined(CONFIG_TOUCHSCREEN_ADS7846)
spi_board_info[1].irq = ads7846_dev_init();
#endif

/* register spi devices */
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));

/* add board's devices */
platform_add_devices(devices, ARRAY_SIZE(devices));
.........................


тут irq задается не очень прямым методом - но подругому у меня не получилось так как у imx233 gpio_to_irq не является константой и ее нельзя присвоить статически при описании ads7843 при инициализации массива.

PS драйвер из коробки работает со всеми утилитами tslib, из прикладных программ опробовал его с qt - никаких проблем не заметил. Немножко пришлось подправить драйвер ads7846.c - в обработчике прерываний закоментить проверку условий
// if (likely(get_pendown_state(ts))) {
// if (!ts->irq_disabled) {
возможно это imx233 специфичный ход - на других контроллерах я не проверял иначе не всегда работает подавление дребезга контакта(debounce) заходящего на irq.
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 01.06.2010 23:49 Сообщение: 2
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
отличная работа! все как обычно - просто и доходчиво расписано.
Саш, при случае, потести под иксами - вдруг заведется нормально..
Как я понял используется 3 пина под SPI + 1 пин под прерывание, т.е. есть шанс его запустить на МНУКе?

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 02.06.2010 00:35 Редактировалось 02.06.2010 00:36 Сообщение: 3
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Цитата
при случае, потести под иксами - вдруг заведется нормально..


Что значит вдруг ? :) Я почти уверен что все будет ок - это же из ванильного ядра драйвер, причем достаточно старый/проверенный.

Цитата
Как я понял используется 3 пина под SPI + 1 пин под прерывание, т.е.


Да - cs можно не заводить а просто сделать его на устройстве "всегда выбрано", остаются miso, mosi, clk и penirq от ads7843. При этом вместо .controller_data = (void *) PINID_SSP1_DATA2, /* это описан gpio-пин для cs */ подставить константу SPI_GPIO_NO_CHIPSELECT

Цитата

есть шанс его запустить на МНУКе?


Теоретически должно работать на любой платформе где есть поддержка gpio в ядре, практически - на imx233 с пол пинка завелся - больше возились с пониманием/устранением
причин дребезга от ads7843 по линии penirq и неприятными последствиями этого.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 02.06.2010 11:09 Сообщение: 4
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Цитата
при случае, потести под иксами - вдруг заведется нормально..


При случае собрал в builroot монолитные иксы (kdrive - tinyx) + blackbox, как и ожидалось все завелось без проблем.
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 02.06.2010 11:29 Сообщение: 5
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата
При случае собрал в builroot монолитные иксы (kdrive - tinyx) + blackbox, как и ожидалось все завелось без проблем.

понятно..

попробовал прикрутить вышеописанную радость к МНУКу, сходу получил пару обломов
- не нашел как у NUC950 дефайнятся пины, т.е. у 9260 есть понятие AT91_GPIO_PA25, у iMX - типа PINID_GPMI_RDY1
в принципе, в брюшке драйвера есть место где можно настроить пины штатными средствами, но драйверу все равно надо как-то втолковать - чем надо шевелить для работы..
и второе, при попытке просто прописать твои начальные строки, при сборке вылетает ошибка
unknown field 'num_chipselect' specified..
в хидере присутствуют
#define <linux/spi/spi.h>
#define <linux/spi/spi_bitbang.h>

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 02.06.2010 12:01 Сообщение: 6
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Цитата
при попытке просто прописать твои начальные строки, при сборке вылетает ошибка
unknown field 'num_chipselect' specified..
в хидере присутствуют
#define <linux/spi/spi.h>
#define <linux/spi/spi_bitbang.h>


В инете есть очень удобные ресурсы для типа этого
http://lxr.free-electrons.com/ident
с помощью которых очень удобно бродить по коду и находить практически все. В данном случае нужно добавить хидер
#include <linux/spi/spi_gpio.h>

PS что это за ужас ? :)
>>#define<< <linux/spi/spi.h>
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 02.06.2010 13:01 Сообщение: 7
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата
В инете есть очень удобные ресурсы для типа этого
http://lxr.free-electrons.com/ident
с помощью которых очень удобно бродить по коду и находить практически все. В данном случае нужно добавить хидер
#include <linux/spi/spi_gpio.h>

все бы хорошо, но чего то файла такого нет, возможно в 17-ом ядре его еще не придумали, буду думать и искать..
может из более свежего украсть? :)

Цитата
PS что это за ужас ? :)
>>#define<< <linux/spi/spi.h>

гы! опечатался - я не цитировал, а просто строку набил - голова думала как пины задефайнить - вот и результат :)))

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 02.06.2010 21:08 Сообщение: 8
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
день прошел зря - выхлоп ноль :-/
перед тем, как браться за паяльник решил пробовать на МНУКе поднять это хозяйство в теории..
сейчас логи не показать - в общем итоге драйвер ads7846 зарегистрировался на spi, вроде даже шина SPI делала телодвижения успешно по регистрации, но вот spi_bitbang не регится ни в какую
то ли последовательность загрузки неправильная, то ли еще не хватает чего то объявить..
впечатление, что проще выкусить обращения драйвера по SPI и наклеить свой bitbang

зы есть стойкое подозрение, что если поднять драйвер на 9260.. то все заработает :-/

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 02.06.2010 23:15 Редактировалось 02.06.2010 23:18 Сообщение: 9
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Цитата
вроде даже шина SPI делала телодвижения успешно по регистрации, но вот spi_bitbang не регится ни в какую


Драйвер там называется spi_gpio и потом движение на шине slave устройство создать ну никак не может, только мастер, так что делай выводы :)

PS Посмотрел в свежем 34 ядре вроде для мнуков всего полно, чего нет давно можно было дописать/перенести со старого ядра - чего вы им не пользуеетесь ?
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 02.06.2010 23:33 Сообщение: 10
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата
Драйвер там называется spi_gpio и потом движение на шине slave устройство создать ну никак не может, только мастер, так что делай выводы :)

не, про физическую шину вообще нет речи
при запуске идет активизация spi.c, серия каких-то невнятных регистраций и тишина
чуть раньше запускается регистрация драйвера ads7846 и тишина
я не великий спец, но вероятно алгоритм должен быть такой - на spi.c навешивается spi_bitbang и образует шину SPI, а уж потом запускается _probe драйвера

Цитата
PS Посмотрел в свежем 34 ядре вроде для мнуков всего полно, чего нет давно можно было дописать/перенести со старого ядра - чего вы им не пользуеетесь ?

полно - это только на первый взгляд. из носителей "из коробки" есть только сетевой адаптер..
процесс переноса достаточно мутный и сложный :-/

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Embedded Linux