Как работать с SPI

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

В конфигурации ядра должны быть включены:

 

CONFIG_SPI=y

CONFIG_SPI_MASTER=y

 

CONFIG_SPI_ATMEL=y 

 

Если  в описании платы не не указываются SPI устройства, а контроллеры необходимо иметь включёнными, в arch/arm/mach-at91/at91sam9260_devices.c в функции at91_add_device_spi разрешить инициализацию spi шин при запуске ядра, для этого прописать:

 

short enable_spi0 = 1;

short enable_spi1 = 1;

 

Можно это не делать, тогда шину надо будет инициализировать в драйвере, который её использует, следующим кодом:

spi0:

 

at91_set_A_periph(AT91_PIN_PA0, 0);        /* SPI0_MISO */

at91_set_A_periph(AT91_PIN_PA1, 0);        /* SPI0_MOSI */

at91_set_A_periph(AT91_PIN_PA2, 0);        /* SPI1_SPCK */

 

spi1:

 

at91_set_A_periph(AT91_PIN_PB0, 0);        /* SPI1_MISO */

at91_set_A_periph(AT91_PIN_PB1, 0);        /* SPI1_MOSI */

at91_set_A_periph(AT91_PIN_PB2, 0);        /* SPI1_SPCK */

 

Если устройств spi много, может потребоваться увеличить их число в drivers/spi/atmel_spi.c:

 

static int __init atmel_spi_probe(struct platform_device *pdev)

master->num_chipselect = 16;

 

Подключение устройства к шине в модуле:

 

#include <linux/spi/spi.h>

#include <mach/gpio.h>// controller specific GPIO pins

 

#define SPI_1_SPEED 4*1000*1000

#define MYCHIP_CS_PIN AT91_PIN_P...

 

static struct spi_board_info my_spi_device = 

{

    .modalias       = "myspidev",// имя устройства

    .chip_select    = 0,/* абстрактный номер микросхемы,

                           обычно индекс в таблице номеров ног выбора кристалла.

                           используется для присвоения данных параметру .controller_data.

                           если номер контакта указывается сразу, .chip_select выполняет роль номера

                           и используется для контроля занятости данного кристалла */

    .controller_data = (void *) MYCHIP_CS_PIN,// контакт выбора кристалла, если таблица не используется

    .bus_num        = 1,// номер шины SPI

    .max_speed_hz   = SPI_1_SPEED,// максимальная скорость подключения

    .mode           = SPI_MODE_0,// режим работы SPI, поддерживаемый микросхемой

};

 

static int init_and_send_data(void)

{

    static struct spi_device* my_spi_ptr;

    int err = 0;

    struct spi_master* spi = spi_busnum_to_master( my_spi_device.bus_num );

    if( spi == NULL )

    {

        printk("unable to get spi master %d\n", my_spi_device.bus_num);

        return -1;

    }

 

    my_spi_ptr = spi_new_device( spi, my_spi_device );

    if( my_spi_ptr == NULL )

    {

        printk("unable to create my spi device\n");

        return -1;

    }

 

    u8 reg[2];

    reg[0] = 0x00<<1;// адрес, обычно младший бит указывает режим чтение/запись

    reg[1] = 0x00;// данные

    spi_write( my_spi_ptr, reg, sizeof(reg) );

 

out:

    spi_unregister_device( my_spi_ptr );

    return err;

}

 

 

Замечание: код в atmel_spi.c сам настроит указанный контакт для управления выбором кристалла и сам установит требуемые уровни на нём в зависимости от указанного режима spi.

Смотри также

Writing a Linux SPI driver

http://www.jumpnowtek.com/index.php?option=com_content&view=article&id=57&Itemid=62

 

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