Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F0 и FT232
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Wasserati
Есть МК STM32F030C8 подключенный к ПК через FT232.
Настройки USART: 8 бит данных, 2 стоп бита, скорость - 3М, RTS/CTS включены.

Чего я ожидал от Flow Control.
USART принимает байт, устанавливает флаг RXNE, устанавливает на выходе RTS 1. FT232 приостанавливает передачу пока на линии RTS не установится 0.

Что получается в действительности.
USART принимает байт, устанавливает флаг RXNE, устанавливает на выходе RTS 1. FT232 передает еще один байт, а уже потом приостанавливает передачу пока на линии RTS не установится 0. Как итог, USART ловит overrun ошибку. DMA, который работает с RX линией, по этой причине, периодически виснет.

Скриншот этой ситуации из лог. анализатора.
Нажмите для просмотра прикрепленного файла

1. Flow Control так и должен работать, или где-то есть ошибка?
2. Как избежать потери данных в этом случае? Вручную забирать данные из RX регистра, пока DMA неактивен?
jcxz
Цитата(Wasserati @ Aug 30 2017, 10:52) *
2. Как избежать потери данных в этом случае? Вручную забирать данные из RX регистра, пока DMA неактивен?

Очевидно - искать грабли своём коде.
Как у Вас так работает DMA, что не успевает считать байт до прихода следующего, если учесть, что на скорости 3 Мбод между символами > 3 мкс???
Видимо DMA у вас работает не в режиме "двойного буфера"? Тогда надо переделать на "двойной буфер".
Wasserati
Буферов на прием у меня и так несколько.
DMA копирует данные в один из них. По заполнению буфера происходит перезагрузка DMA. Данные начинают копироваться уже в другой буфер.
Проблема возникает как раз в при перезагрузке, так как она может произойти прямо в момент приема данных.
Например, в текущем буфере есть 2 свободных байта места, а нужно принять данных на 10 байт. DMA принимает 2 байта в текущий буфер. Перезагружается. Принимает еще 8 байт в другой буфер. За время перезагрузки, USART ловит overrun. То есть сигнал RTS нужного эффекта не дает.
На скриншоте именно момент перезагрузки показан.
HardEgor
А у вас RTS/CTS случайно не инвертированы? Посмотрите настройки FT232 с помощью MProg.
За 3 мкс можно 5 раз переключить DMA. Используете Cube, StdPeriph или прямо пишите в регистры? Или у вас системная частота слишком низкая.
aaarrr
Цитата(Wasserati @ Aug 30 2017, 10:52) *
1. Flow Control так и должен работать, или где-то есть ошибка?
2. Как избежать потери данных в этом случае? Вручную забирать данные из RX регистра, пока DMA неактивен?


Из FAQ от FTDI:
Цитата
If CTS# is logic 1 it is indicating the external device cannot accept more data. the FTxxx will stop transmitting within 0~3 characters, depending on what is in the buffer. This potential 3 character overrun does occasionally present problems. Customers shoud be made aware the FTxxx is a USB device and not a "normal" RS232 device as seen on a PC. As such the device operates on a packet basis as opposed to a byte basis.


Скажите спасибо STM за UART без FIFO.
Baser
Цитата(Wasserati @ Aug 30 2017, 10:52) *
1. Flow Control так и должен работать, или где-то есть ошибка?
2. Как избежать потери данных в этом случае? Вручную забирать данные из RX регистра, пока DMA неактивен?

1. В общем случае зависит от реализации UARTа на передающем контроллере. Как правило, при активации внешнего RTS передатчик УАРТа все равно передает байт, который у него уже загружен в сдвиговый регистр УАРТа. Кроме того, часто, если есть ФИФО на передачу, то передается и все, что уже лежит в ФИФО. Это известная засада, на это часто обращают внимание.
2. Нужно реализовывать алгоритм, который это учитывает.
Если ФИФО у передатчика нет и может прийти только один дополнительный байт, то я просто запрещаю прерывание на прием после взведения RTS. Этот байт приходит и принимается сдвиговым регистром приемного УАРТа и там себе лежит, пока не снят RTS и не разрешены прерывания. Обычно так работает.
Tanya
Цитата(Wasserati @ Aug 30 2017, 11:46) *
Буферов на прием у меня и так несколько.

Один кольцевой буфер и два прерывания - на полузаполнение и полное заполнение.

Цитата(aaarrr @ Aug 30 2017, 12:24) *
Скажите спасибо STM за UART без FIFO.

Да, хочется сказать.
Wasserati
Спасибо всем за советы.
Проблему пока что решил использовав кольцевой буфер.
Изначально я использовал более запутанную схему буферов, поэтому перезагрузка DMA занимала довольно много времени, за которое USART успевал принять 2 лишних байта и поймать overrun.

Неприятно что ST такую ситуацию не предусмотрело.
jcxz
Цитата(Wasserati @ Aug 30 2017, 16:53) *
Изначально я использовал более запутанную схему буферов, поэтому перезагрузка DMA занимала довольно много времени, за которое USART успевал принять 2 лишних байта и поймать overrun.

А какая у Вас системная частота? 1 МГц? Уже при паре десятков МГц тактовой 3 мкс должно с лихвой хватать на любые перезагрузки DMA.
А насчёт ST: более важно если бы оно предусмотрело возможность задания приоритета доступа к шине для DMA-контроллера выше чем у CPU. Это решило бы все проблемы.
"Неуспевание" перезагрузки DMA может быть следствие как раз например того, что CPU крутится в цикле в коде, находящемся в том же банке ОЗУ (или очень часто выбирает данные из этого банка) и без кеша. И имеет приоритет доступа к шине выше чем у DMA. Вследствие чего происходит постоянное обращение CPU к памяти и занятие им шины. Некоторые МК позволяют задать приоритеты доступа разных bus-master-ов к шине.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.