Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SPI драйвер
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
Dubov
Нужно забирать в драйвере данные по SPI по прерыванию от внешнего устройства. Нашёл классную статью(http://habrahabr.ru/post/123145/), но нигде невстречал примера забора данных по прерыванию.
cpl
Цитата(Dubov @ May 28 2012, 22:17) *
Нужно забирать в драйвере данные по SPI по прерыванию от внешнего устройства. Нашёл классную статью(http://habrahabr.ru/post/123145/), но нигде невстречал примера забора данных по прерыванию.

Что значит по прерыванию ?
Из пользовательского пространства нет возможности работать с аппаратурой на прямую, только через драйвер.
Dubov
Цитата(cpl @ May 29 2012, 12:42) *
Что значит по прерыванию ?
Из пользовательского пространства нет возможности работать с аппаратурой на прямую, только через драйвер.

вот и я о том же. Вот и задаю вопрос как написать такой драйвер
dch
В ликусксе 2.6 есть примеры драйверов SPI, например ядно 2.6.x поддерживает SPI для Atmel-овского проца AT91RM9200, в Development Kit от Atmel-а на один из SPI интерфесвов повешена SPI флэш типа AT45DB321/AT45DB642 , которая может использоваться в качестве диска.
Dubov
Цитата(dch @ May 29 2012, 17:21) *
В ликусксе 2.6 есть примеры драйверов SPI, например ядно 2.6.x поддерживает SPI для Atmel-овского проца AT91RM9200, в Development Kit от Atmel-а на один из SPI интерфесвов повешена SPI флэш типа AT45DB321/AT45DB642 , которая может использоваться в качестве диска.

но память не посылает сигнал прерывания.
kurtis
Что такое "внешнее устройство"? как оно подключено к Linux-устройству? каким образом оно собирается прерывать Linux-устройство? Если я ничего не путаю, то SPI это master-slave интерфейс, и slave не может просто так начать слать мастеру пакеты.
Dron_Gus
Видимо помимо SPI от устройства к хост-процессору идет еще и сигнал IRQ.
Посмотрите, например, как это сделано в drivers/net/can/mcp251x.c .
Dubov
Цитата(kurtis @ May 30 2012, 20:00) *
Что такое "внешнее устройство"? как оно подключено к Linux-устройству? каким образом оно собирается прерывать Linux-устройство? Если я ничего не путаю, то SPI это master-slave интерфейс, и slave не может просто так начать слать мастеру пакеты.

прерывание - это сигнал готовности данных с внешнего АЦП. По этому сигналу мастер забирает данные со слейва.
cpl
Цитата(Dubov @ May 31 2012, 15:07) *
прерывание - это сигнал готовности данных с внешнего АЦП. По этому сигналу мастер забирает данные со слейва.

Сразу могли бы сказать что и как у вас подключено, а то поди угадай зачем прерывание к SPI??? laughing.gif
В драйвере устройства заведите обработчик прерывания, в обработчике прерывания считывайте данные с АЦП складывайте в промежуточный буфер например, затем по запросу пользователя отдавайте содержимое буфера.
Drozd2
Есть еще вариант вообще не трогать драйвер. Ногу процессора, на которой висит сигнал готовности, объявить входом для кнопки. В пользовательском приложении создать обработчик событий по нажатию на эту кнопку. В нем считывать данные с АЦП.
Dubov
Спасибо.
Мне очень нужно чтобы драйвер отобразился в /sys/device/platform
как это сделать?
Хотелось бы пример увидеть или литературу толковую где написано как регистрировать драйвера.
Ато читаю рекомендации с сайта Analog Devices:
http://wiki.analog.com/resources/tools-sof.../iio-adc/ad7606

и в моей системе вот это появляется:
Код
root:/> cd /sys/bus/iio/devices/
root:/sys/bus/iio/devices> ls
device0                  trigger0


а этого не вижу

Код
root:/sys/devices/platform/ad7606-8.0


Dron_Gus
В бордовом файле вы делаете platform_add_devices(...) для своего устройства? struct platform_device ...{} для своенго устройства заполнили? Драйвер вкомпилировали?
Dubov
Цитата(Dron_Gus @ Jun 1 2012, 12:59) *
В бордовом файле вы делаете platform_add_devices(...) для своего устройства? struct platform_device ...{} для своенго устройства заполнили? Драйвер вкомпилировали?

Я делаю at91_add_device_spi(...), аргументом которого служит указатель на массив структур SPI устройств, где и описаны параметры йстройства(номер шины, чипселект, имя)
При всём при этом при инициализации драйвера функция probe проходит нормально, регистрируя драйвер толкьо в /sys/bus/iio/devices
xor.kruger
Попробуйте указать в своей структуре, в которой "описано" ваше устройство, что то наподобие этого
Код
.irq = gpio_to_irq(AT91_PIN_PA31)
Dubov
Цитата(xor.kruger @ Jun 2 2012, 14:16) *
Попробуйте указать в своей структуре, в которой "описано" ваше устройство, что то наподобие этого
Код
.irq = gpio_to_irq(AT91_PIN_PA31)

с прерыванием разобрался.
теперь проблема прописать устройство в /sys/devices/platform/
для инициализации устройства вызывается функция at91_add_device_spi(...), которая вызывает функции:
1) spi_register_board_info(), на входе которой структура с МОИМ устройством
2) platform_device_register(), а она в свою очередь регистрирует только atmel_spi1 в /sys/devices/platform/

при этом на входе platform_device_register() ВСЕГДА:

Код
static struct platform_device at91sam9260_spi1_device = {
       .name           = "atmel_spi",      
  .id             = 1,
         .dev            = {
                                .dma_mask               = &spi_dmamask,
                                .coherent_dma_mask      = DMA_BIT_MASK(32),
        },
        .resource       = spi1_resources,
       .num_resources  = ARRAY_SIZE(spi1_resources),
};


Получается что независимо от того какое устройство я регистрирую в
Код
/sys/devices/platform/
будет всегда
Код
atmel_spiX

НО! На входе at91_add_device_spi(...) у меня структура, где прописано устройство с другим именем (.name = SPI_device) и я никак не могу увидеть его в
Код
/sys/devices/platform/
Dron_Gus
Вероятно он "внутри" SPI, т.к. является устройством на шине. (например на моей железке это выглядит так /sys/devices/platform/s3c64xx-spi.0/spi_master/spi0/spi0.0/)
Dubov
Цитата(Dron_Gus @ Jun 4 2012, 10:06) *
Вероятно он "внутри" SPI, т.к. является устройством на шине. (например на моей железке это выглядит так /sys/devices/platform/s3c64xx-spi.0/spi_master/spi0/spi0.0/)

Дело в том, что я объявляю в массиве устройств SPI устройство с именем SPI_device (.modalias = "SPI_device"), затем указываю массив всех SPI устройств в at91_add_device_spi(), откуда вызывается spi_register_board_info(), где аргумент моё устройство, и функция platform_device_register() где аргумент устройство atmel_spi.
В итоге устройство с именем "SPI_device" не появляется.

не могли бы вы привести код как у вас регистрируется устройство "s3c64xx-spi.0" ?
Dron_Gus
Код
static struct spi_board_info crux_spi_devices[] = {
    {       /* CAN */
        .modalias        = "mcp2515",
        .bus_num        = 0,
        .chip_select    = 0,
        .max_speed_hz    = 10 * 1000 * 1000,
        .irq            = CAN_IRQ,
        .platform_data    = &mcp251x_info,
        .controller_data= &crux_mcp_cs,
    },
};

Код
struct platform_device s3c2416_device_spi = {
    .name            = "s3c64xx-spi",
    .id                = 0,
    .num_resources    = ARRAY_SIZE(s3c2416_spi_resource),
    .resource        = s3c2416_spi_resource,
    .dev = {
        .dma_mask            = &spi_dmamask,
        .coherent_dma_mask    = DMA_BIT_MASK(32),
        .platform_data        = &s3c2416_spi0_pdata,
    },
};

Код
static struct platform_device *crux_devices[] __initdata = {
...
    &s3c2416_device_spi,
...
};

Код
static void __init crux_machine_init(void)
{
    ...
    spi_register_board_info(crux_spi_devices, ARRAY_SIZE(crux_spi_devices));
    ...
    platform_add_devices(crux_devices, ARRAY_SIZE(crux_devices));
    ...
}

А драйвер для Вашего "SPI_device" написан? Зарегистрирован (spi_register_driver)?
Dubov
спасибо, для полноты картины не могли бы вы выложить что у вас лежит в s3c2416_spi_resource.
Драйвер написан и зарегистрирован
Dron_Gus
Код
static struct resource s3c2416_spi_resource[] = {
    [0] = {
        .start = S3C2416_PA_SPI,
        .end   = S3C2416_PA_SPI + 0x100 - 1,
        .flags = IORESOURCE_MEM,
    },
    [1] = {
        .start = DMACH_SPI0_TX,
        .end   = DMACH_SPI0_TX,
        .flags = IORESOURCE_DMA,
    },
    [2] = {
        .start = DMACH_SPI0_RX,
        .end   = DMACH_SPI0_RX,
        .flags = IORESOURCE_DMA,
    },
    [3] = {
        .start = IRQ_SPI0,
        .end   = IRQ_SPI0,
        .flags = IORESOURCE_IRQ,
    },
};

struct s3c64xx_spi_info s3c2416_spi0_pdata = {
    .src_clk_nr        = 0,    /* PCLK */
    .fifo_lvl_mask    = 0x7f,
    .rx_lvl_offset    = 13,
    .tx_st_done        = 21,
    .high_speed        = 1,
    .cfg_gpio         = s3c2416_spi0_cfg_gpio,
};
Dubov
Я вот что использую для своего устройства:
Код
static struct resource spi1_resources[] = {
559         [0] = {
560                 .start  = AT91SAM9260_BASE_SPI1,
561                 .end    = AT91SAM9260_BASE_SPI1 + SZ_16K - 1,
562                 .flags  = IORESOURCE_MEM,
563         },
564         [1] = {
565                 .start  = AT91SAM9260_ID_SPI1,
566                 .end    = AT91SAM9260_ID_SPI1,
567                 .flags  = IORESOURCE_IRQ,
568         },
569 };
Dron_Gus
Это платформ дата для контроллера SPI, но как я понимаю с самим контроллером SPI у Вас проблем нет, он пробится и появляется?
Dubov
Да он появляется. не появляется устройство имя которого я задаю через modalias. Устройство висит на SPI1.0
Dron_Gus
Выложите полную spi_board_info для вашего устройства. А так же вывод "ls /sys/devices/platform/". А то я уже запутался. sm.gif
Dubov
Код
static struct spi_board_info ek_spi_devices[] = {

#if defined(CONFIG_AD7606) || \
    defined(CONFIG_AD7606_MODULE)
    {
        /* the modalias must be the same as spi device driver name */
        .modalias = "ad7606-8", /* Name of spi_driver for this device */
        .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
        .bus_num = 1, /* Framework bus number */
        .chip_select = 0, /* Framework chip select */
        .platform_data = &ad7606_pdata,
        //.controller_data = (void *) AT91_PIN_PB3, /* Blackfin only */
                .irq = AT91SAM9260_ID_IRQ2,     
                .mode = SPI_MODE_3,
    },
#endif
};


а вот вывод
Код
root:/sys/devices/platform# ls
alarmtimer  at91_rtt.0   atmel_tcb.1    atmel_usart.2          power
at91_mci    atmel_spi.1  atmel_usart.0  iio-trigger-hrtimer.0  uevent
at91_ohci   atmel_tcb.0  atmel_usart.1  macb

Хотя ожидалось увидеть здесь AD7606-8.0

вот ещё интересный вывод
Код
root@starterkit:/sys/devices/platform/atmel_spi.1/spi1.0# ls
driver  iio:device0  modalias  power  subsystem  uevent

iio:device0 - это по всей видимости моё устройство, но почему не ad7606-8 ?
Dron_Gus
Сделайте в /sys/devices/platform/atmel_spi.1/spi1.0 "cat modalias"
Dubov
Цитата(Dron_Gus @ Jun 4 2012, 15:50) *
Сделайте в /sys/devices/platform/atmel_spi.1/spi1.0 "cat modalias"

сделал...
да! Получил AD7606-8
значит ли это что драйвер установился нормально?
Dron_Gus
По крайней мере probe отработал и вернул 0. Но все может сломаться в процессе работы. sm.gif
Dubov
Цитата(Dron_Gus @ Jun 5 2012, 09:40) *
По крайней мере probe отработал и вернул 0. Но все может сломаться в процессе работы. sm.gif

спасибо за советы.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.