The website "dmilvdv.narod.ru." is not registered with uCoz.
If you are absolutely sure your website must be here,
please contact our Support Team.
If you were searching for something on the Internet and ended up here, try again:

About uCoz web-service

Community

Legal information

Linux - Доступ к шине SPI из пространства пользователя

Linux - Доступ к шине SPI из пространства пользователя

Предыдущая  Содержание  Следующая V*D*V

http://brew-j2me.blogspot.com/

 

Android Karthik Thursday, May 6, 2010

 

Должен быть способ общения с вашим оборудованием, чтобы написать сложный драйвер устройства. В этой заметке мы увидим, как можно использовать для связи с устройством из пользовательского пространства шину SPI.

 

Чтобы включить взаимодействие с SPI из пользовательского пространства, необходимо его разрешить в ядре.

 

Давайте сначала посмотрим основные настройки ядра, необходимые для включения поддержки SPI.

 

CONFIG_SPI

CONFIG_SPI_MASTER

CONFIG_SPI_SPIDEV

 

CONFIG_SPI_SPIDEV разрешает для нас ядро SPI пользовательского пространства.

 

Большинство процессоров для увеличения производительности и простоты использования имеют встроенный модуль шины SPI. Если ваша платформа имеет соответствующий драйвер устройства Linux, включите соответствующую опцию.

 

Например, для платформы OMAP24xx или OMAP34xx необходимо включить CONFIG_SPI_OMAP24XX, чтобы использовать встроенный в процессор модуль McSPI.

 

Теперь для экспорта шины SPI в пространство пользователя необходимо настроить файл платы.

 

Добавляем этот кусочек кода в файл board*.c.

 

/* Structure for configuing McSPI */

static struct spi_board_info board_spi3_board_info[] = {

    {

        .modalias    = "spidev",/* Представление SPI в пространстве пользователя */

        .max_speed_hz = 500000, /* Скорость SPI. */

        .bus_num     = 3,       /* Номер шины McSPI */

        .chip_select = 0,       /* Выбор кристалла для McSPI */

        .mode        = 0,       /* Режим SPI */

    },

};

 

и добавляем регистрацию шины SPI в функцию board_init файла board*.c.

 

/* Регистрируем SPI устройство */

spi_register_board_info(board_spi3_board_info, ARRAY_SIZE(board_spi3_board_info));

 

Теперь после загрузки системы вы должны увидеть в файловой системе ваше SPI устройство в каталоге /dev, например, /dev/spidev2.0 (2 - номер шины SPI, 0 - выбор кристалла).

 

Для передачи и приёма SPI сообщений устройству /dev/spidevx.y можно использовать стандартные вызовы open, read, write и close.

 

Открыть устройство SPI можно используя следующий вызов:

 

int fd = 0;

fd = open("/dev/spidev2.0", O_RDWR);

if (fd < 0)

{

    printf("SPI : can't open device");

    return -1;

}

 

Теперь, используя вызовы ioctl можно настроить SPI.

 

Установка режима SPI:

 

ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);

if (ret == -1)

{

    printf("SPI : can't set spi mode");

    return 1;

}

 

Запрос режима SPI

 

ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);

if (ret == -1)

{

    printf("SPI : can't get spi mode");

    return 1;

}

 

Другими параметрами шины SPI можно управлять аналогичным способом.

 

Теперь посылаем сообщение через шину SPI, для этого необходимо заполнить структуру сообщения и передать её вниз.

 

struct spi_ioc_transfer mesg[1] = { 0, };

 

mesg[0].tx_buf = (unsigned long)out_buffer;

mesg[0].len = num_out_bytes;

 

ret = ioctl(fd, SPI_IOC_MESSAGE(1), mesg);

To receive SPI message

struct spi_ioc_transfer mesg[1] = { 0, };

 

mesg[0].rx_buf = (unsigned long)out_buffer;

mesg[0].len = num_out_bytes;

 

ret = ioctl(fd, SPI_IOC_MESSAGE(1), mesg);

 

Могут быть требования, чтобы запись, следующая за чтением, происходила без переключения сигнала выбора кристалла. Для обработки таких ситуаций можно сформировать 2 сообщения, как показано ниже.

 

int spidev_if_write_read(unsigned int num_out_bytes,

                         unsigned char *out_buffer,

                         unsigned int num_in_bytes,

                         unsigned char *in_buffer)

{

    struct spi_ioc_transfer mesg[2] = { 0, };

    uint8_t num_tr = 0;

    int ret;

 

    if((out_buffer != NULL) && (num_out_bytes != 0))

    {

        mesg[0].tx_buf = (unsigned long)out_buffer;

        mesg[0].rx_buf = (unsigned long)NULL;

        mesg[0].len = num_out_bytes;

        mesg[0].cs_change = 0;

        num_tr++;

    }

 

    if((in_buffer != NULL) && (num_in_bytes != 0))

    {

        mesg[1].tx_buf = (unsigned long)NULL;

        mesg[1].rx_buf = (unsigned long)in_buffer;

        mesg[1].len = num_in_bytes;

        num_tr++;

    }

 

    if(num_tr > 0)

    {

        ret = ioctl(fd, SPI_IOC_MESSAGE(num_tr), mesg);

        if(ret == 1)

        {

            return 1;

        }

    }

 

    return 0;

}

 

Переменная cs_change=0 запрещает изменение состояния сигнала CS между двумя транзакциями.

 

Предыдущая  Содержание  Следующая