Перейти к содержанию
    

Поддержка SPI

Доброго Здоровья!

Стоит задача создать приложение, работающее с устройством, подключенным к процессору AM3354 через интерфейс SPI.

Так как опыт работы с Linux сравнительно небольшой, было принято решение строить взаимодействие с железом через драйвер "spidev".

По этому поводу на хабре наше две статьи:

Обзор шины SPI и разработка драйвера ведомого SPI устройства для embedded Linux (Часть первая, обзорная)

Обзор шины SPI и разработка драйвера ведомого SPI устройства для embedded Linux (Часть вторая, практическая)

 

На первом шаге следует добиться появления в системе устройства /dev/spidevX.Y, для этого в настройках ядра добавляю:

Device Drivers ---> SPI
Device Drivers ---> SPI ---> Atmel SPI Controller
Device Drivers ---> SPI ---> User mode SPI device driver support

Затем в файле arch/arm/mach-omap2/board-am335xevm.c добавляю структуру:

static struct spi_board_info am335x_spi1_master_info[] = {
    {
         .modalias    = "spidev",
        .chip_select    = 2,
        .max_speed_hz    = 6 * 1000 * 1000,
        .mode         = SPI_MODE_0,
        .bus_num    = 1,
    },
};

и "регистрирую эту структуру:

static void spi1_init(int evm_id, int profile)
{
    setup_pin_mux(spi1_pin_mux);
    spi_register_board_info(am335x_spi1_master_info,
            ARRAY_SIZE(am335x_spi1_master_info));
    return;
}

 

Пересобираем ядро, заливаем, загружаемся. В системе нет /dev/spidevX.Y. :(

некоторый оптимизм внушает наличие: /sys/class/spi_master/ и /sys/class/spidev/, причем последняя директория пуста.

root@var-som-am33:~# ls /sys/class/spi_master/
spi1  spi2
root@var-som-am33:~# ls /sys/class/spi_master/spi2
device     power      subsystem  uevent

 

Что может быть? Как получить устройство /dev/spidevX.Y? Складывается впечатление, что бутерброд не правильно ем, или лыжи не едут.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и "регистрирую эту структуру:

    spi_register_board_info(am335x_spi1_master_info, ARRAY_SIZE(am335x_spi1_master_info));
}

Этого недостаточно. Надо еще создать структуру platform_device и зарегистрировать с помощью platform_device_register().

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Этого недостаточно. Надо еще создать структуру platform_device и зарегистрировать с помощью platform_device_register().

Спасибо за ответ, но не помогло. Получился такой код:

/* Module pin mux for SPI */
static struct pinmux_config spi1_pin_mux[] = {
{"mcasp0_aclkx.spi1_sclk", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL
	| AM33XX_INPUT_EN},
{"mcasp0_fsx.spi1_d0", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL
	| AM33XX_PULL_UP | AM33XX_INPUT_EN},
{"mcasp0_axr0.spi1_d1", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL
	| AM33XX_INPUT_EN},
{"mcasp0_ahclkr.spi1_cs0", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL
	| AM33XX_PULL_UP | AM33XX_INPUT_EN},
{NULL, 0},
};

static struct spi_board_info am335x_spi1_master_info[] = {
{
	.modalias	= "spidev",
	.chip_select	= 2,
	.max_speed_hz	= 6 * 1000 * 1000,
	.mode 		= SPI_MODE_0,
	.bus_num	= 1,
},
};	

static struct platform_device am335x_spi1t = {
.name           = "spi1_custom",
.id             = -1,
};

/* setup spi1 */
static void spi1_init(void)
{
int ret;
 	printk("SPI1: init");
setup_pin_mux(spi1_pin_mux);
spi_register_board_info(am335x_spi1_master_info,
		ARRAY_SIZE(am335x_spi1_master_info));
ret = platform_device_register(&am335x_spi1t);
	if (ret)
	pr_err("  failed to register SPI1\n");
return;
}

При загрузке пишет "SPI1: init", "failed to register SPI1" не пишет.

Что делать, куда смотреть?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

было что-то похожее. Проц с несколькими аппаратными SPI контролерами. В ядре линукс все оказались закомментированы кроме нулевого (или просто был описан только нулевой, подробностей не помню). решилось простой правкой ядра.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что делать, куда смотреть?

Хм... А spi_register_board_info() возвращает 0?

А метод probe() Вашего драйвера вызывается? Если да, то что возвращает?

Хотя, насколько я понимаю, если бы он возвращал ошибку, была бы хоть какая-то ругань в логах...

 

Покажите вывод команды ls -l /sys/class/spi_master

Ну и до кучи ls -l /sys/devices/platform

 

И, кстати, почему у Вас в структуре platform_device .id равен -1? Мне казалось, что там должен быть номер шины, то есть в вашем случае 1...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо. Изменил platform_device .id на 1.

initspi_register_board_info возвращает 0.

В /sys/devices/platform есть устройство spi1_custom.1:

root@var-som-am33:~# ls -l /sys/class/spi_master

lrwxrwxrwx 1 root root 0 Jul 5 09:52 spi1 -> ../../devices/platform/omap/omap2_mcspi.1/spi_master/spi1

lrwxrwxrwx 1 root root 0 Jul 5 09:52 spi2 -> ../../devices/platform/omap/omap2_mcspi.2/spi_master/spi2

 

root@var-som-am33:~# ls -l /sys/devices/platform

drwxr-xr-x 3 root root 0 Jul 5 09:52 alarmtimer

drwxr-xr-x 3 root root 0 Jul 5 09:52 cpuidle-am33xx.0

drwxr-xr-x 4 root root 0 Jul 5 09:52 leds-gpio

drwxr-xr-x 3 root root 0 Jul 5 09:52 nop_usb_xceiv.0

drwxr-xr-x 3 root root 0 Jul 5 09:52 nop_usb_xceiv.1

drwxr-xr-x 39 root root 0 Jul 5 09:52 omap

drwxr-xr-x 3 root root 0 Jul 5 09:52 omap2-nand.0

drwxr-xr-x 2 root root 0 Jul 5 09:56 power

drwxr-xr-x 3 root root 0 Jul 5 09:52 pruss_uio

drwxr-xr-x 4 root root 0 Jul 5 09:52 pwm-backlight

drwxr-xr-x 3 root root 0 Jul 5 09:52 reg-dummy

drwxr-xr-x 3 root root 0 Jul 5 09:52 regulatory.0

drwxr-xr-x 3 root root 0 Jul 5 09:52 sgx

drwxr-xr-x 3 root root 0 Jul 5 09:52 spi1_custom.1

-rw-r--r-- 1 root root 4096 Jul 5 09:52 uevent

 

Однако в /dev ничего SPI'йного не появилось. Директория /sys/class/spidev/ пуста (а там должно что-то быть?)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

lrwxrwxrwx 1 root root 0 Jul 5 09:52 spi1 -> ../../devices/platform/omap/omap2_mcspi.1/spi_master/spi1

lrwxrwxrwx 1 root root 0 Jul 5 09:52 spi2 -> ../../devices/platform/omap/omap2_mcspi.2/spi_master/spi2

Стоп. Я, видимо, Вас изначально неправильно понял. Я думал, Вы делаете и хотите использовать свой собственный драйвер (spi1_custom).

Но, насколько я вижу, оба имеющиеся у Вас мастера используют omap2_mcspi. Правильно ли я понял, что Вы хотите использовать уже имеющийся omap2_mcspi?

Если да, то register_platform_device Вам делать не надо, это уже сделано. Надо только зарегистрировать spi-устройства на шине. Вы так и делаете, но результата нет (в /sys/class/spidev/ должно появиться spidev1.2)...

В такой ситуации могу только посоветовать смотреть в spidev_probe() (которая находится в drivers/spi/spidev.c) - именно там регистрируются устройства spidevX.Y. Либо она у Вас вообще по каким-то причинам не выполняется, либо не может создать устройство. Попробуйте понавтыкать туда printk()...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ура! Появился /dev/spidev1.0 !

Итого:

/* Module pin mux for SPI */
static struct pinmux_config spi1_pin_mux[] = {
{"mcasp0_aclkx.spi1_sclk", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL
	| AM33XX_INPUT_EN},
{"mcasp0_fsx.spi1_d0", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL
	| AM33XX_PULL_UP | AM33XX_INPUT_EN},
{"mcasp0_axr0.spi1_d1", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL
	| AM33XX_INPUT_EN},
{"mcasp0_ahclkr.spi1_cs0", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL
	| AM33XX_PULL_UP | AM33XX_INPUT_EN},
{NULL, 0},
};

static struct spi_board_info am335x_spi1_master_info[] = {

{
	.modalias	= "spidev",	
	.chip_select	= 1,
	.max_speed_hz	= 6 * 1000 * 1000,
	.mode 		= SPI_MODE_0,
	.bus_num	= 0,
}, 
{
	.modalias	= "spidev",	/* piggyback  A2 */
	.chip_select	= 0,
	.max_speed_hz	= 6 * 1000 * 1000,
	.mode 		= SPI_MODE_0,
	.bus_num	= 1,
},
};	

static struct platform_device am335x_spi1t = {
.name           = "spi1_custom",
.id             = 1,
};

/* setup spi1 */
static void spi1_init(void)
{
int ret;
 	printk("SPI1: init");
setup_pin_mux(spi1_pin_mux);
ret = spi_register_board_info(am335x_spi1_master_info,
		ARRAY_SIZE(am335x_spi1_master_info));
printk("spi_register_board_info: %d \n", ret);
//	ret = platform_device_register(&am335x_spi1t);
//		if (ret)
//		pr_err("  failed to register SPI1\n");
return;
}

alx2, Спасибо огромное и низкий поклон!

Перехожу на следующий уровень бесконечной игры под названием Embedded Linux. :)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ура! Появился /dev/spidev1.0 !

Правильно ли я понял, что проблема была в chip_select'е (было 2, а теперь Вы сделали 0)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...