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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Не срабатывает прерывание при чтении по DMA
avg33
сообщение Aug 21 2018, 18:22
Сообщение #1





Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564



Я общаюсь с SPI флэшкой через USART в синхронном режиме. Передача и прием организованы по DMA каналам. Посылки фиксированной длины (1024 байта).
Алгоритм обмена выглядит так:
1. Активирую флэш (CS=0)
2. Настраиваю DMA канал на прием 1024 байт. Разрешаю прерывание по чтению IRQ_RX
3. Настраиваю другой DMA канал на передачу 1024 байт. Разрешаю прерывание по передаче IRQ_TX - в этот момент начинается передача/прием
4. В обработчике IRQ_TX очищаю флаг разрешения прерывания, отключаю DMA канал передачи
5. В обработчике IRQ_RX очищаю флаг разрешения прерывания, отключаю DMA канал чтения + деактивирую флэш (CS=1)

Ну то есть стандартный SPI обмен: посылаю 1024 байта - одновременно принимаю 1024 байта. По окончанию передачи/приема обрабатываю прерывания.

И все вроде бы работает. Но иногда (очень и очень редко) бывает ситуация, когда прерывание по передаче срабатывает, а прерывание по чтению нет!
Что я вижу в дебагере в этот момент:
1. Счетчик DMA по передаче равен 0, а по чтению 1. То есть DMA отправил 1024 байта, а прочитал почему-то только 1023. Соответственно, прерывание по чтению не сработает никогда.
2. Ошибки переполнения при чтении (overrun error) нет. Все флаги ошибок равны 0.
3. В регистре чтения USART лежит последний байт посылки (0x89). То есть последний (1024-й) байт посылки похоже таки пришел в регистр. Но счетчик не обнулился
4. Аппаратный флаг прерывания по чтению равен 0. То есть, последний байт был вычитан из регистра буфер. Либо он даже не устанавливался в 1, когда последний байт пришел в регистр

Не могу понять чем это все вызвано. Ведь если отправлено 1024 байта, то и прочитать шина должна была 1024 байта. Байт ведь не мог "потеряться". Или мог? В чем может быть причина такого поведения?
Повторюсь, ошибка проявляется крайне редко, в остальном алгоритм четко работает

Сообщение отредактировал avg33 - Aug 21 2018, 18:24
Go to the top of the page
 
+Quote Post
zombi
сообщение Aug 21 2018, 18:42
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(avg33 @ Aug 21 2018, 21:22) *
Я общаюсь с SPI флэшкой через USART в синхронном режиме.

В Вашем теле есть усарт да еще и синхронный? biggrin.gif
А так то да. Телепаты вот вот подтянутся.
Без DMA пробовали гонять?
Go to the top of the page
 
+Quote Post
avg33
сообщение Aug 21 2018, 18:55
Сообщение #3





Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564



Цитата(zombi @ Aug 21 2018, 21:42) *
В Вашем теле есть усарт да еще и синхронный? biggrin.gif
А так то да. Телепаты вот вот подтянутся.
Без DMA пробовали гонять?


Всмысле телепаты?)) Если вы про код, то он простейший, алгоритм описан выше. А контроллер специфический, вряд ли кто-то будет разбираться в тамошних регистрах и тд

Без DMA делал только отправку на этапе отладки (читаю всегда по DMA). Подобных ошибок не замечал
Вообще много раз читал что-то без DMA - никогда не было подобных проблем
Go to the top of the page
 
+Quote Post
zombi
сообщение Aug 21 2018, 19:13
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(avg33 @ Aug 21 2018, 21:22) *
В регистре чтения USART лежит последний байт посылки (0x89). То есть последний (1024-й) байт посылки похоже таки пришел в регистр. Но счетчик не обнулился

Раз знаете что должно прочитаться попробуйте выяснить какой именно байт из пачки теряется.
Может это прояснит ситуацию.
Цитата
(очень и очень редко)

раз в час? в столетие? или реже?
Go to the top of the page
 
+Quote Post
controller_m30
сообщение Aug 21 2018, 19:15
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 24-02-09
Пользователь №: 45 309



В чём может быть дело не знаю. Тем более не известно какой контроллер laughing.gif

Мои варианты:
1. Попробуйте поменять местами каналы DMA: тот что был для RX сделать для TX, и наоборот. Если каналов DMA больше 2-х, попробуйте и остальные.
(что-то, где-то читал, про приоритет каналов DMA на доступ к внутренней шине данных).
2. Уменьшите скорость SPI - например в 2 раза. Может пары дополнительных тактов хватит для "разруливания" ситуации? Также увеличьте скорость SPI ещё больше (если настройки позволяют) - не будет ли ошибка проявляться ещё чаще?
3. Попробуйте для режима чтения оставить прерывание только по RX, а для записи только по TX. Всё равно сразу два прерывания в каждом из режимов лишние, но вдруг это тоже что-то выявит.
Go to the top of the page
 
+Quote Post
avg33
сообщение Aug 21 2018, 19:57
Сообщение #6





Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564



Цитата(zombi @ Aug 21 2018, 22:13) *
Раз знаете что должно прочитаться попробуйте выяснить какой именно байт из пачки теряется.
Может это прояснит ситуацию.

раз в час? в столетие? или реже?

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

пока что я читаю только при включении девайса. можно много раз включать/выключать пока ошибка не появится. последний раз мне вообще не удалось отловить этот момент


Цитата(controller_m30 @ Aug 21 2018, 22:15) *
В чём может быть дело не знаю. Тем более не известно какой контроллер laughing.gif

Мои варианты:
1. Попробуйте поменять местами каналы DMA: тот что был для RX сделать для TX, и наоборот. Если каналов DMA больше 2-х, попробуйте и остальные.
(что-то, где-то читал, про приоритет каналов DMA на доступ к внутренней шине данных).
2. Уменьшите скорость SPI - например в 2 раза. Может пары дополнительных тактов хватит для "разруливания" ситуации? Также увеличьте скорость SPI ещё больше (если настройки позволяют) - не будет ли ошибка проявляться ещё чаще?
3. Попробуйте для режима чтения оставить прерывание только по RX, а для записи только по TX. Всё равно сразу два прерывания в каждом из режимов лишние, но вдруг это тоже что-то выявит.

1. Да, чем ниже номер канала, тем выше приоритет доступа. Читаю я по 2 каналу, передаю по 3. По идее, у чтения приоритет выше
2. Увеличить уже никак. Скорость 4 млн бод. Попробую уменьшить
3. Обработчик прерывания по передаче по идее мне вообще не нужен. Из флэш я просто читаю) Но если его выкинуть, то придется очищать флаг разрешения прерывания TX и отключать соответствующий канал в обработчике прерывания по RX. Это нормально?

Сообщение отредактировал avg33 - Aug 21 2018, 20:01
Go to the top of the page
 
+Quote Post
controller_m30
сообщение Aug 21 2018, 20:43
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 24-02-09
Пользователь №: 45 309



Цитата(avg33 @ Aug 21 2018, 22:57) *
3. Обработчик прерывания по передаче по идее мне вообще не нужен. Из флэш я просто читаю) Но если его выкинуть, то придется очищать флаг разрешения прерывания TX и отключать соответствующий канал в обработчике прерывания по RX. Это нормально?

Да, попробуйте убрать прерывание для TX канала DMA совсем. Флаг TX USART в режиме DMA обычно сбрасывается автоматически, поэтому дублировать его сброс программно не нужно. Зато есть такой нюанс:
В большинстве известных мне контроллеров, прерывание USART TX происходит в начале передачи байта (буфер TX переписали в регистр сдвига - и тут же прерывание TX), а прерывание USART RX происходит в конце приёма байта (из регистра сдвига переписали в буфер RX - и только тогда прерывание RX). Если USART отключить по прерыванию TX, то прерывание на приём последнего байта пакета может не наступить. И канал DMA RX, соответственно, запрос на последний байт не получит.

Сообщение отредактировал controller_m30 - Aug 21 2018, 20:50
Go to the top of the page
 
+Quote Post
avg33
сообщение Aug 22 2018, 20:23
Сообщение #8





Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564



Цитата(controller_m30 @ Aug 21 2018, 23:43) *
Да, попробуйте убрать прерывание для TX канала DMA совсем. Флаг TX USART в режиме DMA обычно сбрасывается автоматически, поэтому дублировать его сброс программно не нужно

Убрать похоже что не получится, без него DMA не начнет передачу. Можно только обработчик оставить пустым, но это бессмысленно. Сейчас в обработчике я сбрасываю флаг разрешения прерывания, иначе обработчик будет вызываться вечно
Как это работает (как я понял из даташита):
1. Аппаратный флаг TX USART по умолчанию равен 1 - он инициирует запрос на прерывание. если оно разрешено
2. Настраиваю DMA на передачу
3. Устанавливаю в 1 флаг разрешения прерывания по TX
4. Флаг TX USART инициирует запрос на прерывание, который пинает DMA. DMA начинает передачу и после обнуления счетчика передает запрос на прерывание контроллеру, запускается обработчик
5. В обработчике вручную сбрасывается флаг разрешения прерывания, чтобы запрос на прерывание больше не возникал (иначе после выхода из обработчика я снова в него попаду). И выключается DMA канал

То есть максимум, что можно сделать - это убрать из обработчика IRQ TX отключение канала DMA по передаче и вынести это в обработчик IRQ RX.

Цитата(controller_m30 @ Aug 21 2018, 23:43) *
Зато есть такой нюанс:
В большинстве известных мне контроллеров, прерывание USART TX происходит в начале передачи байта (буфер TX переписали в регистр сдвига - и тут же прерывание TX), а прерывание USART RX происходит в конце приёма байта (из регистра сдвига переписали в буфер RX - и только тогда прерывание RX). Если USART отключить по прерыванию TX, то прерывание на приём последнего байта пакета может не наступить. И канал DMA RX, соответственно, запрос на последний байт не получит.

В моем контроллере прерывания USART TX и USART RX устроены точно так же. Почему-то не предусмотрел этот момент)) Возможно, дело именно в этом.
Сейчас почитал даташит, оказывается есть возможность инициировать прерывание USART TX после передачи последнего бита байта из сдвигового регистра на шину.

Попробую поэкспериментировать с обработчиком, потом с механизмом прерывания и посмотреть, что происходит. Спасибо за помощь, мне как-то даже не пришла в голову эта версия))

Сообщение отредактировал avg33 - Aug 22 2018, 20:44
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Aug 23 2018, 08:21
Сообщение #9


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

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



Почитайте мои пути про SPI + DMA. Там LPC4337, но вдруг поможет. Логика, в целом, одинаковая.
1. https://electronix.ru/forum/index.php?showt...=145765&hl=
2. https://electronix.ru/forum/index.php?showt...=146837&hl=

В кратце: приоритет канала на приём (RX) должен быть выше (выше!!!), чем приоритет канала на передачу!


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
avg33
сообщение Sep 12 2018, 15:36
Сообщение #10





Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564



Цитата(haker_fox @ Aug 23 2018, 11:21) *
Почитайте мои пути про SPI + DMA. Там LPC4337, но вдруг поможет. Логика, в целом, одинаковая.
1. https://electronix.ru/forum/index.php?showt...=145765&hl=
2. https://electronix.ru/forum/index.php?showt...=146837&hl=

В кратце: приоритет канала на приём (RX) должен быть выше (выше!!!), чем приоритет канала на передачу!

спасибо, с интересом почитал. но сколько не бился ничего не помогает. приоритет на чтение у меня, кстати, выше. не пойму в чем может быть дело
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 12 2018, 19:34
Сообщение #11


Гуру
******

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



Цитата(avg33 @ Sep 12 2018, 18:36) *
спасибо, с интересом почитал. но сколько не бился ничего не помогает. приоритет на чтение у меня, кстати, выше. не пойму в чем может быть дело

Значит Вы чего-то не понимаете в работе периферии своего МК. И не зная Ваш МК никто тут не сможет помочь.
Кстати, непонятно - зачем и TX-прерывания и RX? При работе с SPI обычно достаточно или того или другого (обычно RX), но никак не вместе.
Да и судя по сообщениям, Вы путаете прерывания с DMA-запросами. Это вообще то совершенно разные вещи.
Go to the top of the page
 
+Quote Post
avg33
сообщение Sep 12 2018, 20:31
Сообщение #12





Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564



Цитата(jcxz @ Sep 12 2018, 22:34) *
Значит Вы чего-то не понимаете в работе периферии своего МК. И не зная Ваш МК никто тут не сможет помочь.
Кстати, непонятно - зачем и TX-прерывания и RX? При работе с SPI обычно достаточно или того или другого (обычно RX), но никак не вместе.
Да и судя по сообщениям, Вы путаете прерывания с DMA-запросами. Это вообще то совершенно разные вещи.

Да, видимо что-то делаю не так. Буду признателен, если покажете рабочий пример SPI обмена по DMA. Любого контроллера. Хочу понять принцип.
Вы не первый кто пишет, что TX прерывание не нужно. Но я не могу начать передачу по DMA, не разрешив TX прерывание.
После отправки последнего байта DMA передает пришедший запрос на прерывание контроллеру - вот и вызывается обработчик. Как же от этого уйти?
Go to the top of the page
 
+Quote Post
V_G
сообщение Sep 12 2018, 23:44
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Цитата(avg33 @ Sep 13 2018, 06:31) *
Буду признателен, если покажете рабочий пример SPI обмена по DMA. Любого контроллера. Хочу понять принцип.

Может не помочь, если речь конкретно о прерывании. Если не знаешь тип контроллера.
У меня была похожая ситуация с миландровским Кортексом, он по SPI управляет DDSом. По итогу отказался обрабатывать прерывания от DMA в их контроллере. Описание там очень плохое, и непонятно, глюк в самом контроллере или в моем понимании работы этого контроллера.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 13 2018, 05:46
Сообщение #14


Гуру
******

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



Цитата(avg33 @ Sep 12 2018, 23:31) *
Да, видимо что-то делаю не так. Буду признателен, если покажете рабочий пример SPI обмена по DMA. Любого контроллера. Хочу понять принцип.

А чем Вам поможет как это сделано в каком-то левом МК? Если даже разберётесь в десятках КБ кода...
В разных МК работа DMA-периферия организована по-своему.

Цитата(avg33 @ Sep 12 2018, 23:31) *
Вы не первый кто пишет, что TX прерывание не нужно. Но я не могу начать передачу по DMA, не разрешив TX прерывание.

Вы опять путаете и себя и всех. Прерывания (от периферийного блока) к работе DMA имеют очень мало отношения. Прерывание - это сигнал идущий от периферийного блока к контроллеру прерываний, запрос DMA - сигнал идущий от периферийного блока к DMA-контроллеру. И это как правило - разные сигналы. Более того - в некоторых МК есть несколько разных DMA-запросов (single- и burst-).
Во многих МК прерывания от периферии (если она работает через DMA) вообще следует запрещать (например так в LPC, XMC4xxx), а обрабатывать прерывания от DMA-канала.
Единственное - что на работу DMA-канала могут влиять сигналы прерываний от самого DMA-контроллера (замораживать работу DMA-канала до обработки прерывания от этого канала).

Цитата(avg33 @ Sep 12 2018, 23:31) *
После отправки последнего байта DMA передает пришедший запрос на прерывание контроллеру

Пришедший откуда и куда? На какой контроллер передаёт? У Вас каша в голове, Вы не понимаете как работает система прерываний и DMA в вашем МК. Читайте мануал на МК.
В большинстве МК, с которыми я работал, при работе некоей периферии через DMA, прерывания от неё запрещались, а разрешалось прерывание от DMA-канала, о завершении пересылки блока (или очередного блока).
В этом прерывании или завершалась работа с периферией, или обрабатывалась текущая порция данных от неё и DMA-канал программировался на новый блок пересылки.
Это - штатный механизм работы через DMA.
И поищите примеры работы с DMA для своего секретного МК.
Go to the top of the page
 
+Quote Post
avg33
сообщение Sep 13 2018, 13:18
Сообщение #15





Группа: Участник
Сообщений: 12
Регистрация: 7-08-18
Пользователь №: 106 564



Цитата
Прерывания (от периферийного блока) к работе DMA имеют очень мало отношения.

Очень мало - это сколько?))))

Цитата
Прерывание - это сигнал идущий от периферийного блока к контроллеру прерываний, запрос DMA - сигнал идущий от периферийного блока к DMA-контроллеру. И это как правило - разные сигналы

Вы с кем общаетесь? Сам с собой?) Объясняю еще раз.
В моем контроллере периферия запрашивает передачу DMA путем установки прерывания. Не знаю, как это устроено в других контроллерах - в моем именно так. Чтобы начать DMA передачу нужен запрос прерывания от периферии. Если канал DMA включен и настроен на прерывание, то запрос этого прерывания заставляет DMA начать передачу. После передачи элемента (байт/слово) возможны ситуации:
1. Счетчик переданных данных > 0 - DMA очищает запрос прерывания от периферии и ждет нового
2. Счетчик ==0 - DMA передает запрос прерывания контроллеру прерываний. Вызывается обработчик.
То есть, если надо отправить байты - я должен настроить DMA канал на прерывание TX и разрешить его (прерывание). Как только прерывание TX разрешено - возникает запрос на TX прерывание и начинается передача. После передачи блока вызовется обработчик прерывания TX. Аналогично с чтением.
Стоит ли объяснять как я организую SPI обмен? Я настраиваю один канал на передачу, другой на чтение и разрешаю прерывания RX и TX. Как только передано/прочитано нужное число байт вызываются обработчики прерываний TX/RX.
Это к вашему вопросу "а зачем вам TX прерывание". Если знаете как запустить передачу без него в текущих условиях - поделитесь примером

Цитата
Пришедший откуда и куда? На какой контроллер передаёт?

Я обмениваюсь информацией с флэшкой. Об этом было написано в самом начале.
Цитата
Это - штатный механизм работы через DMA.
И поищите примеры работы с DMA для своего секретного МК.

Ну в чем-то штатный, а в чем-то нет. Ну либо разрабы этого камня дураки и вообще все организовали не правильно (судя по вашим словам).
Я в общем-то и делаю по примерам. Не надо меня держать за дурака. Просто примера SPI обмена через DMA нет. Есть только пример передачи. От него и отталкиваюсь в написании кода

Цитата( @ Sep 13 2018, 02:44) *
Может не помочь, если речь конкретно о прерывании. Если не знаешь тип контроллера.
У меня была похожая ситуация с миландровским Кортексом, он по SPI управляет DDSом. По итогу отказался обрабатывать прерывания от DMA в их контроллере. Описание там очень плохое, и непонятно, глюк в самом контроллере или в моем понимании работы этого контроллера.

Видимо точно что-то с прерываниями. Выше писали, что приоритет канала RX должен быть выше, чем канала TX. Потому что запросы DMA по RX должны обрабатываться в первую очередь. У меня так и было сделано.
Но вот вчера вечером уже от безысходности поменял DMA каналы местами. Теперь у чтнения приоритет ниже, чем у отправки. И вот уже несколько часов непрерывного чтения и ни одной ошибки (раньше хватало на несколько минут или даже секунд). Понять бы природу странности, ведь по опыту людей все должно быть ровно наоборот. В даташите толком ничего не написано и примеров нет

Сообщение отредактировал avg33 - Sep 13 2018, 13:19
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 16th April 2024 - 04:08
Рейтинг@Mail.ru


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