Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Дырка в UART NIOS
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Saray_Babki_Olega
Не нашел данную проблему в описанных проблемах uart`a в NIOS, поэтому ...
Опишу ситуацию:
- есть железка(на ней стоит cyclone, а в нем есть nios), которая постоянно принимает/посылает данные по UART (Modbus) – использовал FIFOedAvalonUart
- при приеме данных железкой время от времени появлялись ошибки в полученных данных
- был подключен SignalTab и обнаружилось, что после передачи в железку на линии RX(железки) появляется единичный выброс (в 0), откуда эти выбросы - это тоже очень хороший вопрос.
Как этот выброс влиял на прием? Оказывается приемник uart`a ничем не защищен от помех на линии - он просто защелкивает приходящие к нему биты по счетчику-таймеру, настроенного на скорость передачу, и отсчет этот идет после того как к нему придет нулевой старт-бит, т.е. получается так, что если на линии RX вдруг образовался выброс в 0 - приемник воспримет этот спад за старт-бит.
Так вот и получалось, что UART поэтому гличу по сути был готов принимать байт, которого в реальности нет, но правда для захлопывания битов по RX нужны определенные условия (определнным образом выставлены его внутренние регистры/флаги/биты) и тут в работу UART`а включается теория Вероятности – луна в нужной фазе – прием нормально, иначе неверный прием.
Отмоделировал данную ситуацию в modelsim`е с обычным ниосовским uart`ом– и действительно проблема существует. Заинтересовавшиеся могут открыть прилогаемый проект моделсима. Модуль UART`a (uart.v – где приемник uart_rx), сгенерированный SoPC или Qsys, без разницы и там и там одно и тоже. В модели посылаю 4 байта, после второго байта запускаю глич по линии rxd. Данный глич - спад в 0 - выставляет сигнал do_start_rx (приемник готов принимать биты), в результате чего, если получится так, что тик baud_clk_en(или sample_enable) попадает между ниспадающим фронтом реального стартового бита(по линии rxd) и установкой счетчика baud_rate_counter(значением baud_load_value), а это всего пара клоков (клоков заведенного на приемника), то приемник воспринимает этот стартовый бит, как бит данных, в результате байт будет принят не верно (со сдвигом влево – смотри 3 байт – по линии rx_data) и от этого никто не застрахован, если у него в проекте с ниосом есть родной uart.
Поэтому, была сделана доработка приемника uart.v (модуль uart_rx)- "самопальными" шаблонными вставками, которые не исправляют логику работы, а добавляют контроль и которые можно посмотреть в прилагаемом файле uart_ispravl.v и если что применить в своем проекте для защиты от ненужных выбросов на линии RX.
vetal
Можно поставить на верхнем уровне доп синхронизатор + фильтр помех. Сгенерированные файлы лучше не редактировать.
Wic
хорошо бы это в альтеру отправить, может они поправят...
Копейкин
очень интересно!
Какая версия Квартуса?
Какая длительность импулься/глича?
При какой скорости обмена?

vetal
Чтобы синхронизатор на верхнем уровне поставить, нужно тактовую частоту UART вывести, а это затруднительно.
И потом, если импульс помехи длинный, длинеее периода тактовой частоты, то синхронизатор не спасёт.
Saray_Babki_Olega
Версия квартуса 10.0sp1 и 11.0sp1. В десятом uart был сгенерирован в SоPC, в одиннадцатом в Qsys - модули во всяком случае приемника (uart_rx) у того и у другого получаются одинаковые - и тот и другой прогонялся - ошибка и там и там проявлялась. Длительность глича была порядка 80-100 нс, на сам ниос заведено 50MHz (20нс, естественно ей же тактируется и uart). Было обнаружено на скорости 921600 бит/с, но ставил и обычные скорости типо 115200, 9600.
Про фильтр на входе тоже думал, но это не интересно, можно не угодать.
iosifk
Цитата(Saray_Babki_Olega @ Oct 25 2012, 08:49) *
Как этот выброс влиял на прием? Оказывается приемник uart`a ничем не защищен от помех на линии - он просто защелкивает приходящие к нему биты по счетчику-таймеру, настроенного на скорость передачу, и отсчет этот идет после того как к нему придет нулевой старт-бит, т.е. получается так, что если на линии RX вдруг образовался выброс в 0 - приемник воспримет этот спад за старт-бит.

Вообще то это не проблема UARTа, это Ваша проблема.

UART может работать по следующим правилам.
Либо импульс определяется в середине битового интервала,
либо за битовый интервал берутся 3 отсчета на скорости в 16 раз выше битовой и они мажоритируются,
либо на входе UARTа ставится фильтр. Причем этот фильтр может быть либо цифровым, либо аналоговым. Частота работы UARTа всегда известна, а потому "промахнуться" с параметрами фильтра невозможно...
Далее в ход идет экранирование кабеля и устранение помех, вплоть до гальванической развязки. Т.е. от линиии связи "по напряжению" переходят к токовым сигналам...
И далее от неправильного приема данных защищаются программно, при помощи пакетизации данных и контрольных сумм. Делается программый интерфейс обмена верхнего уровня с перезапросами данных в случае приема ошибок.
Все это известно, ничего нового здесь нет...
Если у Вас на входе UARTа возникают ложные импульсы, длительностью соизмеримые с битовым интервалом, значит это Ваша проблема и ее надо решать Вам. При правильно работающей линии таких ложных импульсов быть не должно.
Удачи!
juvf
Цитата(iosifk @ Oct 25 2012, 16:45) *
Вообще то это не проблема UARTа, это Ваша проблема.

Эта проблема именно UART-а. Эту тему уже обсуждали.
Цитата
Либо импульс определяется в середине битового интервала,
либо за битовый интервал берутся 3 отсчета на скорости в 16 раз выше битовой и они мажоритируются,
Да, вот именно.... старт импульс должен определятся либо в середине битового импульса, либо из 3-х выборок в середине бита. Но УАРТ альтеры начинает принимать после отрицательного фронта. Достаточно ложного импульса в 1 такт на 50 МГц. Причем ладно бы уарт по ложному импульсу принял бы ложный байт. Но альтеровский уарт по ложному импульсу кагбэ подвисает. может прийти иголка и уарт стартанёт, но байт он не примет. потом в линии будет тишина 1 час. Потом придет первый байт и будет ошибка кадрирования, хотя по осциллографу на входе уарта картинка эталонная - все времена выдержаны, все уровни, фронты.... всё ОК.
Цитата
либо на входе UARTа ставится фильтр. Причем этот фильтр может быть либо цифровым, либо аналоговым. Частота работы UARTа всегда известна, а потому "промахнуться" с параметрами фильтра невозможно...
Ни разу в жизни не видел фильтр на вход уарта.
Все эти, как вы говорите "фильтры" делаются в контроллере. в авр, мсп430, мк51, пик и т.п.
Цитата
Далее в ход идет экранирование кабеля и устранение помех, вплоть до гальванической развязки. Т.е. от линиии связи "по напряжению" переходят к токовым сигналам...
Посмотрите мою тему по этому поводу. См в ней осциллограммы. Ни какой экран не поможет защитится от этих помех. Помеха возникает при переключении драйвера. ваши экраны, гальваническая развязка и т.п. - не помогут. К тому же RS-485 это витая пара, а витая пара как известно более устойчива к помехам.
Цитата
Если у Вас на входе UARTа возникают ложные импульсы, длительностью соизмеримые с битовым интервалом, значит это Ваша проблема и ее надо решать Вам.
Я написал тестовый проект, в котором имитировал ложный импульс в 1 такт. И альтеровский уарт улетел от этой "иголки". Тестовый проект и картинки результата в сигналтабе см в моей теме.

Я отписал багрепорт в Альтеру. Сказали что разберутся. прошло.... уже полгода - тишина!
iosifk
Еще раз Вам объясняю. Если на входе УАРТа возникает отрицательный перепад напрядения, то он обязан начинать определять стартовый бит. Так он устроен и другого быть не должно!
Если у Вас сигналы на входе имеют иголки, то Вы их должны сами убрать.
Какой смысл для Альтеры дорабатывать УАРТ, а значит делать его более сложным и затратным, если иголки возникают только в Вашем случае? А в десятках и сотнях других случаев все и так работает.
А уж как это делать - я написал. А то, что Вы об этом не имеете сведений - это Ваша проблема.
Я же это лет 30 назад точно выучил, когда ни "авр, мсп430, мк51, пик и т.п." и в помине не было, а линии связи уже были... А потому у меня и проблем таких давно уже нет...
juvf
Цитата(iosifk @ Oct 31 2012, 23:56) *
Еще раз Вам объясняю. Если на входе УАРТа возникает отрицательный перепад напрядения, то он обязан начинать определять стартовый бит. Так он устроен и другого быть не должно!
Ну и спор!!! Говорим об одном и томже.
Я, Еще раз Вам объясняю. Если на входе УАРТа возникает отрицательный перепад напрядения, то он обязан начинать определять стартовый бит. Так он устроен и другого быть не должно! .
и ещё раз
Если на входе УАРТа возникает отрицательный перепад напрядения, то он обязан начинать определять стартовый бит.
Именно ОБЯЗАН НАЧИНАТЬ, а не должен определить. в этом часть проблемы.

во первых - по иголке уарт не должен определять стартовый бит. И давайте об этом спорить не будем. Если Вы считаете что должен - флаг вам в руки. Я считаю что не должен. Я написал свой уарт который, как Вы гоыорите, за битовый интервал берутся 3 отсчета ... и они мажоритируются и проблем с иголками нет. И в этом меня не надо переубежнать и я вас не собираюсь. останимся при своих. НО
во-вторых: пришла иголка и после неё уровень лог "1" в течении длительного времени, допустим в течении ОДНОГО часа. Если по этой иголке, уарт должен решить что пришол старт бит. Пусть будет так. Тогда уарт через длительность одного байта должен принять байт, и это должен быть 0xff. Пришол стартовы бит - приняли байт. Но в случае альтеровского уарта этого не происходит. после иголки уарт не дает ни прирывания, не меняет свои статусные регистры, не меняет приемный регистр. У него меняются внутренние регистры и он переходит в говносотояние, которое можно определить только сигналтабом. И в этом говносотоянии он будет находится вплоть до следующего байта на RxD, а это может быть 1мс, 1минута, 1 час, 3 дня.... И с высокой вероятностью альтеровский уарт находясь в говносотоянии не примет нормальный байт.

ps вот вариант реализации уарта.
Цитата
Приемник и передатчик тактируются, как правило, с 16-кратной частотой относительно бодрейта. Это нужно для сэмплирования сигнала. Приемник, поймав падающий фронт старт-бита, отсчитывает несколько тактов и следующие три такта считывает (семплирует) порт RX. Это как раз середина старт-бита. Если большинство значений семплов - "0", старт-бит считается состоявшимся, иначе приемник принимает его за шум и ждет следующего падающего фронта.
Ни каких вопросов, ни каких говносотояний. Так он устроен и другого быть не должно!

Цитата
Я же это лет 30 назад точно выучил, когда ни "авр, мсп430, мк51, пик и т.п." и в помине не было
Ну мк51 уже был.

x736C
Цитата(Копейкин @ Oct 25 2012, 12:46) *
vetal
Чтобы синхронизатор на верхнем уровне поставить, нужно тактовую частоту UART вывести, а это затруднительно.
И потом, если импульс помехи длинный, длинеее периода тактовой частоты, то синхронизатор не спасёт.


Не совсем понятно, зачем?
Мажоритарный фильтр-синхронизатор наподобие того, который по ссылке должен избавить от подобных помех. Даже если их длительность более одного периода тактовой частоты. Он не привязан к UART непосредственно (поэтому не понятно, зачем нужна частота из UART, достаточно системной) и, таким образом, фильтрует сигнал не на алгоритмическом уровне, как в схеме у ув. juvf и не по трем расставленным по битовому интервалу отсчетам, а по n рядом стоящим. Ширину фильтра можно варьировать. Одинокий «пичок» он не пропускает.
Копейкин
Цитата(x736C @ Nov 1 2012, 11:19) *
Не совсем понятно, зачем?
Мажоритарный фильтр-синхронизатор наподобие того, ... Одинокий «пичок» он не пропускает.

Извиняюсь, неточно выразился.
Я имел в виду, что желательно вывести частоту семплирования (не частоту обмена!) UART,
чтобы фильтровать на ней.
Системную частоту (частоту процессора и шины), скорее всего придётся, для фильтра, делить.
Слишком большой оверсэмплинг тоже нехорошо.
А так, да, приведённый алгоритм, должен спасти.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.