Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Поддержка SPI
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
shamrel
Доброго Здоровья!
Стоит задача создать приложение, работающее с устройством, подключенным к процессору 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. sad.gif
некоторый оптимизм внушает наличие: /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? Складывается впечатление, что бутерброд не правильно ем, или лыжи не едут.

alx2
Цитата(shamrel @ Jul 2 2013, 07:14) *
и "регистрирую эту структуру:
Код
    spi_register_board_info(am335x_spi1_master_info, ARRAY_SIZE(am335x_spi1_master_info));
}

Этого недостаточно. Надо еще создать структуру platform_device и зарегистрировать с помощью platform_device_register().
shamrel
Цитата(alx2 @ Jul 2 2013, 09:04) *
Этого недостаточно. Надо еще создать структуру platform_device и зарегистрировать с помощью platform_device_register().

Спасибо за ответ, но не помогло. Получился такой код:
CODE
/* 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" не пишет.
Что делать, куда смотреть?
ZASADA
было что-то похожее. Проц с несколькими аппаратными SPI контролерами. В ядре линукс все оказались закомментированы кроме нулевого (или просто был описан только нулевой, подробностей не помню). решилось простой правкой ядра.
alx2
Цитата(shamrel @ Jul 4 2013, 06:56) *
Что делать, куда смотреть?

Хм... А spi_register_board_info() возвращает 0?
А метод probe() Вашего драйвера вызывается? Если да, то что возвращает?
Хотя, насколько я понимаю, если бы он возвращал ошибку, была бы хоть какая-то ругань в логах...

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

И, кстати, почему у Вас в структуре platform_device .id равен -1? Мне казалось, что там должен быть номер шины, то есть в вашем случае 1...
shamrel
Спасибо. Изменил 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/ пуста (а там должно что-то быть?)
alx2
Цитата(shamrel @ Jul 5 2013, 08:14) *
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()...
shamrel
Ура! Появился /dev/spidev1.0 !
Итого:
CODE
/* 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. sm.gif
alx2
Цитата(shamrel @ Jul 8 2013, 13:30) *
Ура! Появился /dev/spidev1.0 !

Правильно ли я понял, что проблема была в chip_select'е (было 2, а теперь Вы сделали 0)?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.