Перейти к содержанию
    

Драйвер SPORT для Blackfin/uClinux

В связи с переводом проекта под Blackfin/uClinux понадобился драйвер SPORT-порта, обеспечивающий непрерывную прием/передачу.

Нашел bfin_sport (2D-DMA, Autobuffering, MDMA Transfers to userspace).

 

В кратце посмотрев, пришел к выводу:

При установке режима DMA=2, используется 2-мерная DMA-передача. Два буфера (длиной не обязательно кратной степени 2).

Считывать надо буфер целиком. Считывание синхронное (read уходит в спячку). После завершения read() как можно быстрее надо запустить повторный read(), чтобы не "пропустить" буфер (максимальная длина буфера DMA-передачи 64К слов). То же самое относится к write().

Конфигурирование DMA для автобуферинга происходит только один раз, после этого тут-же запускается прием/передача. Вызов IOCTL для конфигурирования SPORT возвращает -EBUSY, если включена прием и/или передача.

 

В общем, для моих целей наверное подойдет (64К слов вычитываются за 400 мс - должно хватить на обработку в user-spaсe и повторный запуск read()

 

Тем не менее, может кому попадались другие варианты (для PXA я использовал самописный драйвер SPI с использованием связного списка DMA-дескрипторов).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Идея у драйвера на мой взгляд неплохая. Но косяков там немеряно. Сейчас тестирую и пытаюсь бороться по мере сил.

Кстати, максимально возможный размер буфера приема/передачи у исходного драйвера <32кБ. Сейчас расширяю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ребята весьма вольно работают с указателями. Как результат, при конфигурировании SPORT с длиной передаваемого/принимаемого слова менее 17 бит,, DMA - пересылка dma_memcpy() идет совсем не туда:

 

...

static unsigned int *data_rx;

static unsigned int *data_tx;

static short pinpon_rx;

static short pinpon_tx;

static short pinpon_old;

...

static ssize_t sport_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)

{

...

dma_memcpy((void *)(data_tx+pinpon_tx), (const void *)buf, count);

...

}

...

static irqreturn_t dma_tx_irq_handler(int irq, void *dev_id)

{

...

/* Index jump for pinpon_tx */

pinpon_tx ^= dev->config.tx_data_len;

...

}

...

static int sport_configure(struct sport_dev *dev, struct sport_config *config)

{

...

int word_bytes = (config->word_len + 7) / 8;

if (word_bytes == 3) word_bytes = 4;

...

if ((data_tx = kmalloc (config->tx_data_len*word_bytes*2, __GFP_DMA)) == NULL) {

...

/* Initialize pinpon index */

pinpon_rx = config->rx_data_len;

pinpon_tx = config->tx_data_len;

pinpon_old = -1;

...

}

...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Запостил свои предложения по bag-fix на суд мировой общественности: http://blackfin.uclinux.org/gf/tracker/4589

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...