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

SPI & DMA на UC3

Здравствуйте!

 

Собственно делал ли кто-нибудь связку интерфейса SPI (TWI) с PDCA? Моя реализация работала, но через ... До поры до времени. Теперь нужно сделать всё правильно:) Проблема с чтением dummy- байтов по SPI.

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


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

Да, делал.

 

Чтобы что-то считать с SPI, нужно что-нибудь записать в него. Т.е. отправляешь через один канал DMA буфер в SPI, по второму каналу читаешь буфер из SPI.

Изменено пользователем vibro

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


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

Да, я знаю что нужно передавать так называемые dummy-байты. но у меня возникла проблема с чтением. Для чтения данных я вынужден инициализировать канал приёма данных на число элементов N+1, где N - количество принимаемых байт данных.

Код приёмника у меня получился такой:

pdca_load_channel(PDCA_CHANEL_NANO_SPI_RX, ((unsigned char *)DataStr)-1, anz+1);
pdca_load_channel(PDCA_CHANEL_NANO_SPI_TX, (unsigned char *)ffbyte, anz);

pdca_enable(PDCA_CHANEL_NANO_SPI_RX);  // получить данные
pdca_enable(PDCA_CHANEL_NANO_SPI_TX);  // Передать dummy - байты

// Дождаться окончания передачи по каналу DMA
while (pdca_get_load_size(PDCA_CHANEL_NANO_SPI_TX));
pdca_disable(PDCA_CHANEL_NANO_SPI_TX);  // Disable now the transfer.
pdca_disable(PDCA_CHANEL_NANO_SPI_RX);  // Disable now the transfer.

Всё работало хорошо до тех пор пока я не обнаружил странный баг. Один байт данных в оперативной памяти повреждается после такого вот приёма через DMA. Байт принимает значение 0xff. По всей видимости тот самый лишний байт и пишется туда, куда я не хочу. Если загружать канал DMA на приём без смещения и на длину равную длине пересылки, то принимается количество данных меньшее, чем указано и со смещением. Есть туманные предположения, что это связано с тем, что последний байт из приёмника данных нужно считывать как-то особенно.

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


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

Есть туманные предположения, что это связано с тем, что последний байт из приёмника данных нужно считывать как-то особенно.

Туман надо разогнать:

- передача заканчивается не тогда, когда у PDC TX кончатся данные, а когда эти данные кончатся и в сдвиговом регистре SPI

- если RHR на момент начала передачи полон (например, использовалась только передача без приема), то его нужно предварительно очистить чтением

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


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

Туман надо разогнать:

- передача заканчивается не тогда, когда у PDC TX кончатся данные, а когда эти данные кончатся и в сдвиговом регистре SPI

Поставил проверку на наличие данных в сдвиговом регистре вслед за проверкой данных у PDC TX, и всё равно приём идёт некорректно...

- если RHR на момент начала передачи полон (например, использовалась только передача без приема), то его нужно предварительно очистить чтением

У SPI нет такого регистра. Аналогичный ему регистр Receive Data Register не очищается чтением.

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


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

Поставил проверку на наличие данных в сдвиговом регистре вслед за проверкой данных у PDC TX, и всё равно приём идёт некорректно...

Код приведите.

 

У SPI нет такого регистра. Аналогичный ему регистр Receive Data Register не очищается чтением.

Что значит не очищается? RDRF в SR не сбрасывается? Не верю.

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


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

Решение я нашёл, это радует. НО нашёл его практически методом тыка:) Хотелось бы разобраться в сути. Кода очищения буфера spi не осталось. После предварительного dma- чтения без передачи всё нормализовалось.

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


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

Кода очищения буфера spi не осталось. После предварительного dma- чтения без передачи всё нормализовалось.

Чем "предварительное DMA-чтение без передачи" отличается от "очищения буфера SPI"?

Никаких "хитростей", кроме уже упомянутых, в работе с SPI по DMA нет - так что осталось не понятным?

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


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

Вот отрывок кода предварительного чтения dma-канала:

pdca_channel->mar = (unsigned long)addr;          //загрузка указателя данных
pdca_channel->tcr = size;                                  // длина передачи 
pdca_channel->cr = AVR32_PDCA_TEN_MASK;    // задействовать канал приёма
pdca_channel->cr = AVR32_PDCA_TDIS_MASK;  // отключить канал приёма

Как-то не очень похоже на очищение буфера spi, видимо таким образом очищается буфер dma (какой ещё буфер???) Пока не прочитаю в даташите, что это так, не поверю... В описании регистра PDCA Control Register биты TransferEnable и TransferDisable (AVR32_PDCA_TEN_MASK и AVR32_PDCA_TDIS_MASK в коде) соответственно включают и выключают передачу по DMA. Про очитску буферов ничего нет.

• TEN: Transfer Enable

0 = No Effect.

1 = Enable transfer for DMA channel.

• TDIS: Transfer Disable

0 = No Effect.

1 = Disable transfer for DMA channel.

Хотя, с другой стороны включение dma-передачи разрешает каналу считать данные из регистра данных приёмника SPI. Но тогда и впрямь простое чтение регистра данных должно быть равносильно активации/декативации канала dma! Попробую всё же ещё раз проверить завтра этот вариант на свежую голову.

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


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

Столкнулся с необходимостью использовать DMA для работы с SPI. Никогда ничего подобного раньше не делал, поэтому не знаю с какой стороны подступиться.Мог бы кто нибудь привести пример кода? SPI у меня в режиме ведущего. Как начать прием данных? Надо писать через DMA dummy байты?

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


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

Надо писать через DMA dummy байты?

Надо. Настраиваете два канала DMA, один на прием, второй на передачу. Запускаете сначала прием, затем передачу.

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


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

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

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

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

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

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

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

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

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

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