реклама на сайте
подробности

 
 
> AT91SAM960 - не работает SPI
Pasa
сообщение Nov 21 2009, 08:28
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 107
Регистрация: 4-03-09
Из: Беларусь, Минск
Пользователь №: 45 665



Процессор AT91SAM9260

Из документации ядра 2.6.28 взял пример работы с SPI - spidev_test.c
В конфигурации ядра сделал все как описывали на форуме. Все подключилось.
В /dev появилось устройство spidev. Пример заработал - обращения к драйверу проходят.
Передача вроде должна идти.А вот данных осцилографом не вижу.

Распечатал на консоль значения портов и регистров SPI - режимы вроде установлены верно.
А передачи нет. При этом датафлэш висящая на SPI работает отлично, и когда идет
обращение к ней, то осцилографом все прекрасно видно.

Подскажите в чем тут загвоздка?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Pasa
сообщение Nov 25 2009, 16:17
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 107
Регистрация: 4-03-09
Из: Беларусь, Минск
Пользователь №: 45 665



Эксперименты привели к следующему: вызовы write и read прекрасно работают. А если через ioctl вызывать spidev_ioctl(для полнодуплексного обмена), то из драйвера SPI (atmel_spi.c) идет возврат с ошибкой опций устновленного протокола. И естественно передачи никакой нет. По исходнику посмотрел - там где анализ на нулевую скорость передачи и ноль бит в слове. В уровень spidev.c структура с параметрами доходит нормально(параметры ставятся в верхнем юзерском слое в самой проге). А потом где-то теряются/затираются/обнуляются и до дравера SPI не доходят. Вот счас пробую проследить всю цепочку...

Мда....вот уж не ожидал таких плясок с бубном....не покидает ощущение, что ну не может быть таких ошибок в ядре и я не совсем правильно пользуюсь вызовами ioctl(). Но ведь все взято из примера в документации которая идет с самим ядром. Хотя с другой стороны в этом самом примере сходу нашел одну описку/опечатку/ошибку.

Может кто сталкивался с таким и подскажет что-нибудь дельное? Уж больно не хочется лезть в потроха ядра, править его и с ужасом думать о следущих "танцах", когда придется браться за сокеты и шину I2C
Go to the top of the page
 
+Quote Post
lamination
сообщение Nov 26 2009, 08:56
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 42
Регистрация: 11-04-06
Пользователь №: 16 019



Код
#include <stdio.h>
#include <fcntl.h>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <linux/types.h>
#include <linux/spi/spidev.h>

int main(){
    
    int fd;
    int status;
    unsigned char u8_ret;
    unsigned int u32_ret;
    struct spi_ioc_transfer    xfer[2];
    unsigned char buf[10];
    
    fd = open("/dev/spi1.1",O_RDWR);
    if (fd == -1){
        printf("error on open device,%d\n",fd);
        return -1;
    }
    
    status = ioctl(fd,SPI_IOC_RD_MODE,&u8_ret);
    printf("RD_MODE(%d) :0x%x,",status,u8_ret);
    status = ioctl(fd,SPI_IOC_RD_LSB_FIRST,&u8_ret);
    printf("LSB_FIRST(%d) :0x%x,",status,u8_ret);
    status = ioctl(fd,SPI_IOC_RD_BITS_PER_WORD,&u8_ret);
    printf("BITS_PER_WORD(%d) :0x%x,",status,u8_ret);
    status = ioctl(fd,SPI_IOC_RD_MAX_SPEED_HZ,&u32_ret);
    printf("MAX_SPEED_HZ(%d) :0x%x\n",status,u32_ret);
    
    u8_ret = 8;
    status = ioctl(fd,SPI_IOC_WR_BITS_PER_WORD,&u8_ret);
    printf("set BITS_PER_WORD(%d) :0x%x\n",status,u8_ret);

    u32_ret = 1000000;
    status = ioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,&u32_ret);
    printf("set MAX_SPEED_HZ(%d) :0x%x\n",status,u32_ret);    
    
    memset(xfer, 0, sizeof xfer);
    memset(buf, 0, sizeof buf);     
    
    buf[0] = 0xaa;
    xfer[0].tx_buf = (__u64) buf;
    xfer[0].len = 1;
    
    xfer[1].rx_buf = (__u64) buf;
    xfer[1].len = 4;     

    status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
    printf("ioctl return %d\n",status);
    printf("buf[0]=%d, buf[1]=%d, buf[2]=%d\n",buf[0],buf[1],buf[2]);
    
    return 0;    
}


В board-sam9260ek.c :
Код
.....
static struct spi_board_info ek_spi_devices[] = {
....
    {    /* SPI device 1,CS 0*/
        .modalias    = "spidev",
        .chip_select    = 0,
        .max_speed_hz    = 15 * 1000 * 1000,
        .bus_num    = 1,
    },    
    {    /* SPI device 1, CS 1*/
        .modalias    = "spidev",
        .chip_select    = 1,
        .max_speed_hz    = 15 * 1000 * 1000,
        .bus_num    = 1,
    },    
    {    /* SPI device 1, CS 2*/
        .modalias    = "spidev",
        .chip_select    = 2,
        .max_speed_hz    = 15 * 1000 * 1000,
        .bus_num    = 1,
    },    
    {    /* SPI device 1, CS 3*/
        .modalias    = "spidev",
        .chip_select    = 3,
        .max_speed_hz    = 15 * 1000 * 1000,
        .bus_num    = 1,
    },        
....
}


Ядро версии 2.6.30

Если работают read и write, то вероятней всего вы забыли сделать memset(xfer, 0, sizeof xfer);
Go to the top of the page
 
+Quote Post
Pasa
сообщение Nov 26 2009, 10:05
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 107
Регистрация: 4-03-09
Из: Беларусь, Минск
Пользователь №: 45 665



to lamination:

Ваш пример сразу заработал. Огромное спасибо.

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

Еще раз огромное спасибо. Похоже дело сдвинулось с мертвой точки
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 22:49
Рейтинг@Mail.ru


Страница сгенерированна за 0.01387 секунд с 7
ELECTRONIX ©2004-2016