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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> LPC4337, DMA + SSP, В редких случаях приём не завершается полностью
haker_fox
сообщение Feb 13 2018, 09:08
Сообщение #1


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



Добрый день, коллеги!
Есть связка на приём и передачу через SSP + DMA в упомянутом микроконтроллере. В некоторый момент при тестировании обнаружил, что иногда канал DMA оставляет 4 непринятых байта в регистре CONTROL в поле size. При этом контроллер DMA не выставляет ни одного флага ошибки. Соответственно бит ENABLE этого канала остаётся в единице.

Как устроены транзакции? Есть два канала dma. Канал 2 обслуживает передачу через SSP, канал 0 - приём через SSP (более приоритетный канал на приём). Далее, программируем одинаковое количество байт на передачу, соответственно и на приём тоже. Сначал включаем канал приёма. Затем - канал передачи, и именно по нему ждём завершения транзакции. Подразумевается, что канал приёма их завершит тоже, т.к. шина SSP - синхронная.

В целом всё работает. Запускаю циклический тест (на шине висит флешка). Флешку пишу и читаю из неё. Соответственно адреса буферов всегда одни и теже. На 1000, скажем, транзакций в очень редких случаях происходит описанная проблема.

Я уже умотался искать проблему. Несколько минимизировал её появление, установив burst size в 1 байт на приём и передачу. Если сделать 4 байта, то ошибка проявляется значительно чаще. Коллеги, я просто не понимаю источник ошибки, т.к. не один флаг не взводится. Флаги переполнения FIFO RX у SSP тоже обнулены. Из-за чего так может вести себя дмашник?

Что особенно печалит: я не могу воспроизвести ошибку, и нет флагов ошибки...

P.S. SSP - мастер. CS дёргаю программно, т.к. нужно выдерживать времянки.

P.S.S. 4 байта остатка вовсе не обязательно. Сейчас поймал 3 и 7.
P.S.S.S. Есть зависимость от оптимизации компилятора. Можно сказать, что ошибка не появляется, или слииишком редка, если оптимизация 0. И чуть чаще на максимальном уровне оптимизации.


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 13 2018, 10:52
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(haker_fox @ Feb 13 2018, 11:08) *
Сначал включаем канал приёма. Затем - канал передачи, и именно по нему ждём завершения транзакции. Подразумевается, что канал приёма их завершит тоже, т.к. шина SSP - синхронная.

Вроде как должно быть очевидным, что ждать завершения нужно по каналу приёма, но никак не передачи. wacko.gif

Цитата(haker_fox @ Feb 13 2018, 11:08) *
Подразумевается, что канал приёма их завершит тоже, т.к. шина SSP - синхронная.

Шина синхронная и что с того? Данные на передачу надо сперва записать, а потом они начнут выдвигаться, а на приём наоборот - сперва вдвигаются, а потом появляются в регистре приёма.

Цитата(haker_fox @ Feb 13 2018, 11:08) *
Коллеги, я просто не понимаю источник ошибки, т.к. не один флаг не взводится. Флаги переполнения FIFO RX у SSP тоже обнулены. Из-за чего так может вести себя дмашник?

Как можно не понимать очевидного??? wacko.gif Вы же сами пишете про FIFO.
Записали Вы в TX.FIFO последние данные - данных по TX у Вас больше нет, Вам приходит событие о завершении TX DMA-пересылки. Вы режете канал. А в это время SSP продолжает передачу из TX.FIFO находящихся там данных (ну и соответственно - приём в RX.FIFO).
Вроде должно быть очевидным, что работу с SSP нужно всегда завершать по завершению RX блока. Даже без FIFO.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Feb 13 2018, 12:30
Сообщение #3


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (jcxz @ Feb 13 2018, 18:52) *
Вроде должно быть очевидным, что работу с SSP нужно всегда завершать по завершению RX блока. Даже без FIFO.

ОК! Но почему же тогда это проявляется очень редко? И зависит от burst size? Я действительно не понимаю, возможно от сильной усталости... Спасибо! Завтра на работе попробую следовать вашему совету!


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 13 2018, 12:38
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(haker_fox @ Feb 13 2018, 14:30) *
ОК! Но почему же тогда это проявляется очень редко? И зависит от burst size? Я действительно не понимаю, возможно от сильной усталости... Спасибо! Завтра на работе попробую следовать вашему совету!

Потому что выключаете SSP Вы видимо в ISR, который активизируется завершением DMA? Из-за задержки входа в ISR (наложения других более приоритетных ISR или участков с запрещёнными прерываниями), иногда все данные из TX.FIFO успевают уйти (а в RX - все прийти). На эту задержку будет влиять и оптимизация и размер burst.
Тогда, уменьшив SCLK, получите в среднем более частое возникновение бага.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Feb 13 2018, 12:53
Сообщение #5


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (jcxz @ Feb 13 2018, 20:38) *
Потому что выключаете SSP Вы видимо в ISR, который активизируется завершением DMA?

Я не выключаю SSP. SSP всегда включен. Перед транзакцией разрешатся всегда передача через DMA. А вот канал приёма DMA включатся только в том случае, если принятые данные нужны. Иногда же данные достаточно просто передать, а ничего вычитывать из слейва не требуется. В начале каждой транзакции через шину я вычитываю FIFO буфер SSP, т.к. там есть данные, если в предыдущей транзакции мы не использовали данные от слейва. Также очищаю флаг OVERRUN. В связи с этим понимаю, что зря NXP не сделала возможность отключить приёмник SSP. И всегда приходится вычитывать его FIFO.
Ну и включив передающий канал ДМА (предварительно включив, если требуется принимающий), я разу же жду события от прерывания TC (по передаче). Как только оно наступает, я читаю, что все транзакции на шине закончились.


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 13 2018, 13:19
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(haker_fox @ Feb 13 2018, 14:53) *
Я не выключаю SSP. SSP всегда включен.
...
я разу же жду события от прерывания TC (по передаче). Как только оно наступает, я читаю, что все транзакции на шине закончились.

Под выключением я имел в виду вот именно это. Назовите это хоть остановом хоть ещё как.
Неправильно считаете. Прерывание об окончании передачи TX.DMA говорит только о том, что закончена передача данного блока DMA из памяти в целевую периферию (в целевой адрес периферии было записано последнее слово из FIFO DMA-канала). Вы же получаете прерывание о завершении от DMA, а не от SSP, с чего тогда Вы решили что SSP закончил свою работу???
Если Вы запишете слово в выходной TX-буфер SSP процессором без DMA, Вы тоже будете считать что передача по SPI закончилась в момент завершения выполнения команды записи?
Она ещё может даже не начаться. Точно так же - и в момент завершения передачи TX-DMA блока передача по SPI ещё может даже не начаться.
Поэтому судить можно только по завершению RX.DMA.
Именно поэтому и NXP не сделала отключения приёмника ибо - нафиг это не нужно. Потому что приёмный канал в любом случае нужен для нормального обнаружения завершения транзакции.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Feb 13 2018, 13:25
Сообщение #7


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (jcxz @ Feb 13 2018, 21:19) *
Она ещё может даже не начаться. Точно так же - и в момент завершения передачи TX-DMA блока передача по SPI ещё может даже не начаться.

Кажется начинаю понимать rolleyes.gif Спасибо, вам, уважаемый jcxz! Завтра аппробирую! Лишь бы получилось!

З.Ы. Мне одному кажется, что из одного только юзер мануала на микроконтроллер не следует всего того, что вы сказали? Что это? Многолетний опыт работы с различными микроконтроллерами? Или я за соснами леса не вижу? rolleyes.gif


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 13 2018, 13:45
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(haker_fox @ Feb 13 2018, 15:25) *
З.Ы. Мне одному кажется, что из одного только юзер мануала на микроконтроллер не следует всего того, что вы сказали? Что это? Многолетний опыт работы с различными микроконтроллерами? Или я за соснами леса не вижу? rolleyes.gif

Честно говоря - не знаю. Я конечно много лет работал с разными LPC - от LPC23xx (старых ещё), до LPC43xx. И ничего кроме мануалов на них не читал.
Но впрочем это ведь касается не только NXP: такой алгоритм работы, он справедлив для всех МК с SPI, везде аналогично - что у TI, что у STM, что у Infenion, .... Это вытекает из принципа работы самого SPI: чтобы что-то передать, надо вначале это что-то записать в буферный регистр, а чтобы что-то принять нужно сначала чтобы прошло нужное число клоков SCLK. Т.е. - события записи передаваемого слова в TX-буфер и появления принятого слова в RX-буфере - никак не могут быть одновременными явлениями. И FIFO тут не при чём.
Даже собственно на уровне одного бита - нужно его сперва выставить на шину и только потом - сэмплировать приёмником.
Поэтому и писал, что эти вещи мне кажутся очевидными.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Feb 13 2018, 14:03
Сообщение #9


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (jcxz @ Feb 13 2018, 21:45) *
Поэтому и писал, что эти вещи мне кажутся очевидными.

Чтож, я тоже для себя ещё сегодня утром думал, что SPI это что-то вроде сдвиговых регистров. Но не учёл некоторые моменты) ещё раз искренне благодарен!!!


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 13 2018, 14:19
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(haker_fox @ Feb 13 2018, 16:03) *
Чтож, я тоже для себя ещё сегодня утром думал, что SPI это что-то вроде сдвиговых регистров. Но не учёл некоторые моменты) ещё раз искренне благодарен!!!

Пожалуйста. sm.gif
И не забывайте про команды синхронизации шины (DMB/DSB) между записями в регистры DMA и регистры SSP и прочие периферийные регистры. Их отсутствие тоже иногда приводит к неожиданным эффектам. Особенно на таких довольно мощных МК с разными доменами тактирования как LPC43xx.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Feb 13 2018, 14:34
Сообщение #11


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (jcxz @ Feb 13 2018, 22:19) *
И не забывайте про команды синхронизации шины (DMB/DSB) между записями в регистры DMA и регистры SSP и прочие периферийные регистры.

Ну воот smile3046.gif Про это мне совсем не известно... нужно, значит, ещё и команды дополнительные вставлять... если не сложно, можете чуть по-подробнее рассказать?


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 13 2018, 16:07
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(haker_fox @ Feb 13 2018, 16:34) *
Ну воот smile3046.gif Про это мне совсем не известно... нужно, значит, ещё и команды дополнительные вставлять... если не сложно, можете чуть по-подробнее рассказать?

Если Вы записали что-то в регистры некоей периферии, а затем - в регистры другой периферии. И вторая запись - запускает взаимодействие 2-й периферии с первой, то между первой записью и 2-й записью необходимо вставить DMB. Иначе будет то работать, то глючить.
Если к примеру какая-то запись в регистр периферии включает её работу, и эта периферия сразу посылает запрос DMA-каналу. А до этого вы конфигурили данный DMA-канал, и в процессе конфигурирования очистили регистр DMA-запросов, то возможна ситуация, что конфигурация DMA-канала запишется в него после того, как включится периферия его использующая. И например запрос к DMA от периферии потеряется и она вечно будет ждать обслуживания со стороны DMA-канала.
DMB устраняет эту проблему.
Ну или другой вариант: Вы в регистре флагов запросов прерываний некоей периферии почистили флажки, потом почистили их в NVIC (перед тем как размаскировать), а потом размаскировали данное прерывание в NVIC. И оно тут же произошло (прерывание). Хотя ещё никакой активности с периферией не было. Просто Ваша команда очистки флажков дошла до периферии позже чем команда очистки флажков в NVIC. И NVIC успел опять защёлкнуть запрос прерывания.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Feb 14 2018, 04:41
Сообщение #13


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (jcxz @ Feb 14 2018, 00:07) *
Если Вы записали что-то в регистры некоей периферии, а затем - в регистры другой периферии.

Вот и тема для моего лично роста)

Кстати, попробывал ожидать окончания транзакции по приёму - стало значительно лучше. Но вот с чистой передачей остаются проблемы. Приём мы не ведём. А как вы уже сказали, DMA при передаче лишь только отрапортует, что данные сброшены в регистры FIFIO, не более. Следовательно как гарантированно дождаться завершения именно передачи (без приёма) я пока не знаю. Прерывания от SSP соответствующих не нашёл(((


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 14 2018, 15:14
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(haker_fox @ Feb 14 2018, 06:41) *
Следовательно как гарантированно дождаться завершения именно передачи (без приёма) я пока не знаю. Прерывания от SSP соответствующих не нашёл(((

Никак. Всегда программировать RX-DMA-канал.
Не понимаю - а зачем Вы упорно пытаетесь обойтись без приёма? 1 DMA канал сэкономить? Так их там много вроде. Пропускную способность шины сэкономить? Так её ещё постараться надо чтобы загрузить.
И приоритет RX-DMA-канала всегда должен быть выше чем у TX-DMA.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Feb 15 2018, 00:13
Сообщение #15


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (jcxz @ Feb 14 2018, 23:14) *
Никак. Всегда программировать RX-DMA-канал.
Не понимаю - а зачем Вы упорно пытаетесь обойтись без приёма? 1 DMA канал сэкономить?

Нет. Сложновато получается. Допустим, мне надо только передать 10 кб по связанному списку. Значит приём "холостых" байт нужно вести в какой-то закольцованный связным списком буфер?! Вот мне это и кажется избыточным. Видимо придётся делать.
QUOTE (jcxz @ Feb 14 2018, 23:14) *
И приоритет RX-DMA-канала всегда должен быть выше чем у TX-DMA.

Да-да, это я уже сделал)

Стоп!!! Это что же такое я говорю, совсем заработался. Не надо на приём делать холостой связный списко. Можно просто не инкрементировать адрес приёмника в дма, и лишь хоть весь объём Вселенной в буфер из одного байта))))))


--------------------
Выбор.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 17th June 2025 - 17:32
Рейтинг@Mail.ru


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