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

 
 
> Не срабатывает прерывание при чтении по 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
 
Start new topic
Ответов
zombi
сообщение Aug 21 2018, 19:13
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 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
avg33
сообщение Aug 21 2018, 19:57
Сообщение #3





Группа: Участник
Сообщений: 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
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 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
Сообщение #5





Группа: Участник
Сообщений: 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

Сообщений в этой теме
- avg33   Не срабатывает прерывание при чтении по DMA   Aug 21 2018, 18:22
- - zombi   Цитата(avg33 @ Aug 21 2018, 21:22) Я обща...   Aug 21 2018, 18:42
|- - avg33   Цитата(zombi @ Aug 21 2018, 21:42) В Ваше...   Aug 21 2018, 18:55
- - controller_m30   В чём может быть дело не знаю. Тем более не извест...   Aug 21 2018, 19:15
- - haker_fox   Почитайте мои пути про SPI + DMA. Там LPC4337, но ...   Aug 23 2018, 08:21
|- - avg33   Цитата(haker_fox @ Aug 23 2018, 11:21) По...   Sep 12 2018, 15:36
|- - jcxz   Цитата(avg33 @ Sep 12 2018, 18:36) спасиб...   Sep 12 2018, 19:34
|- - avg33   Цитата(jcxz @ Sep 12 2018, 22:34) Значит ...   Sep 12 2018, 20:31
|- - V_G   Цитата(avg33 @ Sep 13 2018, 06:31) Буду п...   Sep 12 2018, 23:44
|- - jcxz   Цитата(avg33 @ Sep 12 2018, 23:31) Да, ви...   Sep 13 2018, 05:46
|- - avg33   ЦитатаПрерывания (от периферийного блока) к работе...   Sep 13 2018, 13:18
|- - HardEgor   Цитата(avg33 @ Sep 13 2018, 20:18) Очень ...   Sep 14 2018, 08:43
||- - avg33   Цитата(HardEgor)Возможно при переводе перепутали п...   Sep 16 2018, 12:24
||- - jcxz   Цитата(avg33 @ Sep 16 2018, 15:24) А поци...   Sep 16 2018, 13:16
||- - HardEgor   Цитата(avg33 @ Sep 16 2018, 19:24) F2MC-1...   Sep 16 2018, 16:41
|- - jcxz   Цитата(avg33 @ Sep 13 2018, 16:18) Очень ...   Sep 14 2018, 10:02
|- - HardEgor   Цитата(jcxz @ Sep 14 2018, 17:02) Не обяз...   Sep 15 2018, 09:09
- - Herz   Господа! Прошу без грубостей. Если есть какие-...   Sep 16 2018, 14:06


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

 


RSS Текстовая версия Сейчас: 21st August 2025 - 09:45
Рейтинг@Mail.ru


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