Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:3
Поисковых ботовПоисковых ботов:3
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:7
Форум » starterkit.ru » Embedded Linux
spi mmap
lunixoid
Добавлено 12.03.2012 13:29
0
Сообщение: 1
lunixoid
0

Пункты: 1050
Регистрация: 18.01.2012
Пол: Мужчина
Из: Ростов-на-Дону
Плата: SK-AT91SAM9G45-XC6SLX

Написал по подобию gpio структуру для работы с spi:
Код

typedef struct _AT91S_SPI {
AT91_REG SPI_CR; // Control Register
AT91_REG SPI_MR; // Mode Register
AT91_REG SPI_RDR; // Receive Data Register
AT91_REG SPI_TDR; // Transmit Data Register
AT91_REG SPI_SR; // Status Register
AT91_REG SPI_IER; // Interrupt Enable Register
AT91_REG SPI_IDR; // Interrupt Disable Register
AT91_REG SPI_IMR; // Interrupt Mask Register
AT91_REG Reserved0[4]; //
AT91_REG SPI_CSR[4]; // Chip Select Register
AT91_REG Reserved1[48]; //
AT91_REG SPI_RPR; // Receive Pointer Register
AT91_REG SPI_RCR; // Receive Counter Register
AT91_REG SPI_TPR; // Transmit Pointer Register
AT91_REG SPI_TCR; // Transmit Counter Register
AT91_REG SPI_RNPR; // Receive Next Pointer Register
AT91_REG SPI_RNCR; // Receive Next Counter Register
AT91_REG SPI_TNPR; // Transmit Next Pointer Register
AT91_REG SPI_TNCR; // Transmit Next Counter Register
AT91_REG SPI_PTCR; // PDC Transfer Control Register
AT91_REG SPI_PTSR; // PDC Transfer Status Register
} AT91S_SPI, *AT91PS_SPI;

Инициализирую так же через mmap:
Код

void *base;
off_t addr = spibase;

//Задаем размер карты
unsigned long map_size = 4096Ul;
unsigned long map_mask = map_size - 1;
try {
if ( FileMem != -1 )
//Создаем проекцию контроллера на памяти
base =
mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, FileMem,
addr & ~map_mask);
else throw 1;

if (base == (void *) -1) {
throw 1;
}

fprintf(stderr, "SPI: Memory mapped at address %p.\n", base);
//Возвращаем указатель на начало памяти с проекцией
//spi_regs = (AT91S_SPI *) ((uint32_t)base + (addr & map_mask));
spi_regs = (AT91S_SPI *) ((intptr_t)base + (addr & map_mask));
} catch (int val) {
fprintf(stderr, "SPI: Cannot be mapped.\n");
}

Все хорошо инициализируется, если замкнуть мисо на моси, данные передаются. Но тактирование не происходит (SPCK молчит) и не изменяется нога выбора контроллера и, как следствие, все виснет.
Настройки SPI_MR:
0 бит - режим мастера
1 бит - выбор периферии пробовал фиксированный и "варьирующийся"
2 бит - установлено в 0
PCS - 1111 перед включение SPI, 1110 - после включения SPI
Настройки npcs0(ноги выбора):
Clock polarity = 0
Clock phase = 0
CSAAT = 0
BITS = 0000 (8 bit)
Ну и настройки скорости.

Функция записи:
Код

void spi::Write(unsigned int npcs, unsigned short data) {
//Отправка данных
while ( (spi_regs->SPI_SR & 0x1 << 9) == 0 ); // (SPI) TXEMPTY Interrupt
spi_regs->SPI_TDR = data | ((~(1 << npcs) & 0xF) << 16);
while ( (spi_regs->SPI_SR & 0x1 << 1) == 0 ); // (SPI) Transmit Data Register Empty
}


Виснет на проверке spi_regs->SPI_SR & 0x1 << 1) == 0
Вопрос не совсем в том, почему не работает, тонкостей много. Вопрос кто работал с SPI таким способом? Через драйвер для задачи не подходит.
P.S. Может забыл что то еще указать, тонкостей здесь много.
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 12.03.2012 14:43 Сообщение: 2
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
а тактирование самого узла SPI в АРМе разрешено?

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
lunixoid
Добавлено 12.03.2012 15:19 Сообщение: 3
lunixoid
0

Пункты: 1050
Регистрация: 18.01.2012
Пол: Мужчина
Из: Ростов-на-Дону
Цитата
а тактирование самого узла SPI в АРМе разрешено?

Вроде как разрешено.
Для этого нужно в одном из регистров PMC(power manager controller) установить нужный бит в 1 (например для SPI0 это 14). Хотя может я неправильно что то понял.
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 12.03.2012 17:39 Сообщение: 4
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
да, для SPI0 это ID14
имхо, по уму, надо:
настроить ноги интерфейса на альтернативные функции
подать тактовую на модуль (PMC_PCER)
настроить регистры SPI0
разрешить работу модуля

проверим готовность узла
кладем данные в регистр - должны передаться..

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
Lampus
Добавлено 12.03.2012 20:35 Редактировалось 12.03.2012 20:40 Сообщение: 5
Lampus
5

Пункты: 3552
Регистрация: 26.04.2011
Я вот чего только не пойму: чем вас spidev то не устроил?
Ну или что мешает собственный драйвер написать?
Можно поподробнее рассказать что за задача такая специфическая?
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 12.03.2012 21:34 Сообщение: 6
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата
Я вот чего только не пойму: чем вас spidev то не устроил?
Ну или что мешает собственный драйвер написать?

причины могут быть разные, как-то:
- переход в дальнейшем к своему приложению (без линукса и Со)
- пощупать железо напрямую в целях саморазвития или тренировки перед чем то более глобальным
- что-то под свое специфичное железо (у него на ките еще ФПГА есть..)..

в свое время, Саша (sasamy) писал, что реализация SPI у Atmel хреновая - я ему почему то верю..

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
lunixoid
Добавлено 13.03.2012 12:27 Редактировалось 13.03.2012 12:29 Сообщение: 7
lunixoid
0

Пункты: 1050
Регистрация: 18.01.2012
Пол: Мужчина
Из: Ростов-на-Дону
Цитата
да, для SPI0 это ID14
имхо, по уму, надо:
настроить ноги интерфейса на альтернативные функции
подать тактовую на модуль (PMC_PCER)
настроить регистры SPI0
разрешить работу модуля

проверим готовность узла
кладем данные в регистр - должны передаться..

Все эти шаги проделываются. В функции записи после проверки
Код
( (spi_regs->SPI_SR & 0x1 << 9) == 0 )
ложим в регистр
Код
spi_regs->SPI_TDR = data | ((~(1 << npcs) & 0xF) << 16);
после этого в бесконечном цикле не проходит проверку на окончание передачи, соответственно все виснет (Transmit Data Register Empty не устанавливается в 0).
P.S. Eсли устанавливать режим в LLB - замыкаем miso и mosi, то все что я передаю, успешно принимается.
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 13.03.2012 13:58 Сообщение: 8
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
видимо вот это делаете:
Код
After enabling the SPI, a data transfer begins when the processor writes to the SPI_TDR (Trans-
mit Data Register). The written data is immediately transferred in the Shift Register and transfer
on the SPI bus starts. While the data in the Shift Register is shifted on the MOSI line, the MISO
line is sampled and shifted in the Shift Register. Transmission cannot occur without reception.
Before writing the TDR, the PCS field must be set in order to select a slave.

остается немного вариантов:
- неполностью отключили SPI0 из линукса - может ядро мешает работе
- где-то промахнулись с пинами или режимами этих пинов
- горелый пин - проверятся диагностической писулькой "поднять|опустить пин" и просмотром уровня осциллом
- "забыли" выбрать пин слейва (схожий эффект был на Атмеге - пока пином не дернешь, интерфейс не поднимется)

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
lunixoid
Добавлено 13.03.2012 14:17 Сообщение: 9
lunixoid
0

Пункты: 1050
Регистрация: 18.01.2012
Пол: Мужчина
Из: Ростов-на-Дону
Цитата

остается немного вариантов:
- неполностью отключили SPI0 из линукса - может ядро мешает работе
- где-то промахнулись с пинами или режимами этих пинов
- горелый пин - проверятся диагностической писулькой "поднять|опустить пин" и просмотром уровня осциллом
- "забыли" выбрать пин слейва (схожий эффект был на Атмеге - пока пином не дернешь, интерфейс не поднимется)


1e - в /dev не вижу устройств spi;
2е - сверил пины и режимы с даташитом, все правильно;
3е - через pio пины дергаются, получается не горелые;
4е - вот с выбором слейва у меня кажется проблема:

При инициализации я в регистр MR записываю PCS - 1111, непосредственно перед вызовом функции записи я устанавливаю PCS - 1110. Что происходит на осцилле в этот момент:
когда PCS==1111 - все ноги показывают ноль;
когда PCS==1110 - все ноги показывают ноль :о

Пробовал устанавливать ногу с помощью gpio, устанавливается, но spck все равно молчит.
Спуститься к концу Подняться к началу
Персональная информация
Jury093
Добавлено 13.03.2012 17:31 Сообщение: 10
Jury093
4.5

Пункты: 54271
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
селекция PCS зависит от бита PCSDEC
наверно проще показать, что вы пишете в регистры (вроде не военная тайна) и для контроля вывести дамп содержимого блока регистров SPI0..
тогда можно более отчетливо разобраться в ситуации
уверен, что дело в какой-то ерунде..

На любой вопрос есть любой ответ.
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Embedded Linux