Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Bubble в UART LPC2148
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
3m-soft
Работаю с LPC2148, но никак не могу решить проблему с UART. Осциллятор у меня на 12Мгц из-за USB модуля, второй осциллятор часовой. Понятное дело что битрейт на UART с нулевой ошибкой выставить невозможно. На UART0 реализован обычный текстовый терминал. На UART1 рабочее устройство с которым ведется обмен данными. Так вот в зависимости от степени расхождения в битрейте с устройством на длинных пакетах может произойти какой-то срыв в мозгах у LPC и он начинает "базарить" (bubble) на оба UART как наружу так и вовнутрь, т.е. в течение нескольких секунд я наблюдаю на экране терминала как быстро быстро прет всякая х...ня, тоже самое происходит и вовнутрь, т.е. в течение этого же времени оба модуля активно принимают "левые" данные в основном просто нули. Подчеркиваю, что базарит он на оба модуля одновременно, и так посрет посрет данными и успокаивается и продолжает работать. Раньше bubble вызывал вообще зависание, да такое что внешний ресет не помогал, а помогало только выключение питание или сторожевой таймер, но я поиграл с таймингами MAM и теперь он не всегда зависает. Плюс к этому я выяснил что если во время работы с PLL, устройство что-нибудь ответит в UART, то это bubble с последующим гарантированным зависанием. Раньше эта прога работала на LPC2194 с осциллятором 11059200 и таких проблем не было. Кстати терминал параллельно продублирован на логический канал USB и когда UART0 гадит мусором с свою терминальную программу, то в специальной терминальной программе подключенной через USB в это время все в порядке, так что это точно модуль UART0 сам что-то гонит, а не моя прога что-то сдуру посылает.
zltigo
Цитата(3m-soft @ Sep 25 2007, 12:59) *
Понятное дело что битрейт на UART с нулевой ошибкой выставить невозможно.

С нулевой и не надо, а с достаточной - воспользуйтесь fractional baud rate generator
Цитата
срыв в мозгах у LPC и он начинает "базарить" (bubble) на оба UART как наружу так и вовнутрь

Поверьте моему опыту, что срыв не в мозгах LPC, а у Вас в программе.
alexander55
Цитата(3m-soft @ Sep 25 2007, 13:59) *
Работаю с LPC2148, но никак не могу решить проблему с UART. Осциллятор у меня на 12Мгц из-за USB модуля, второй осциллятор часовой. Понятное дело что битрейт на UART с нулевой ошибкой выставить невозможно. На UART0 реализован обычный текстовый терминал. На UART1 рабочее устройство с которым ведется обмен данными. Так вот в зависимости от степени расхождения в битрейте с устройством на длинных пакетах может произойти какой-то срыв в мозгах у LPC и он начинает "базарить" (bubble) на оба UART как наружу так и вовнутрь, т.е. в течение нескольких секунд я наблюдаю на экране терминала как быстро быстро прет всякая х...ня, тоже самое происходит и вовнутрь, т.е. в течение этого же времени оба модуля активно принимают "левые" данные в основном просто нули. Подчеркиваю, что базарит он на оба модуля одновременно, и так посрет посрет данными и успокаивается и продолжает работать. Раньше bubble вызывал вообще зависание, да такое что внешний ресет не помогал, а помогало только выключение питание или сторожевой таймер, но я поиграл с таймингами MAM и теперь он не всегда зависает. Плюс к этому я выяснил что если во время работы с PLL, устройство что-нибудь ответит в UART, то это bubble с последующим гарантированным зависанием. Раньше эта прога работала на LPC2194 с осциллятором 11059200 и таких проблем не было. Кстати терминал параллельно продублирован на логический канал USB и когда UART0 гадит мусором с свою терминальную программу, то в специальной терминальной программе подключенной через USB в это время все в порядке, так что это точно модуль UART0 сам что-то гонит, а не моя прога что-то сдуру посылает.

Я читал, читал - так и не понял (часовой кварц, USB. bubble, зависание, 2 UART ...).
В правильно заданном вопросе - половина ответа (афоризм).
Русский матрос задать умеет правильный вопрос (Чиж).
Наконец дошло.
При каких ошибках по частоте возможна работа UART ?
Если такой вопрос отвечаю. 4,5 %
3m-soft
Fractional baud rate generator я использую с самого начала, хотя пробовал и без него.

Параллельный логический канал по USB для того и сделал чтобы разобраться в проблеме, так вот учитывая на каком уровне происходит параллелизация, то в том то и дело что не может программа посылать эти данные сама иначе это дублировалось бы и в USB канал. Конечно есть там пара строк кода после узла распараллеливания, которые отвечают уже непосредственно за передачу в UART0, но всё уже несколько раз перепроверено.

Извините, что написал в вопросе так много, но просто проблема настолько глубокая что блин не знаю как в двух словах описать. Я же описывал и то что уже предпринял.
alexander55
Цитата(3m-soft @ Sep 25 2007, 14:21) *
Fractional baud rate generator я использую с самого начала, хотя пробовал и без него.

Параллельный логический канал по USB для того и сделал чтобы разобраться в проблеме, так вот учитывая на каком уровне происходит параллелизация, то в том то и дело что не может программа посылать эти данные сама иначе это дублировалось бы и в USB канал. Конечно есть там пара строк кода после узла распараллеливания, которые отвечают уже непосредственно за передачу в UART0, но всё уже несколько раз перепроверено.

Извините, что написал в вопросе так много, но просто проблема настолько глубокая что блин не знаю как в двух словах описать. Я же описывал и то что уже предпринял.

Краткость- сестра таланта (афоризм).
Как же тебе ответить, если ты ничего не говоришь (Иван Васильевич меняет профессию).
3m-soft
Дело ещё в том, что разных устройств таких для UART1 много и у каждого свой разработчик и своя ошибка в битрейте, бывает нулевая, бывает большая. Вот сейчас лежит одно и разница у нас с ним в 4%, пока он посылает мне пакеты-ответы длиной в 4 байта всё в порядке, когда длиной в 19 байт, то либо я получаю дополнительный странный довесок в несколько байт, либо в течение 2-3 секунд получаю максимум данных на этом битрейте, но так как дальше 128 байт у меня уже откидывается, то я не знаю сколько точно. Есть другое устройство с точно таким же протоколом связи, только ошибка гораздо меньше, так вот с ним все отрабатывает по протоколу нормально. Кстати это проблемное устройство прекрасно работает по этому протоколу с ПК, а со мной не хочет.
alexander55
Цитата(3m-soft @ Sep 25 2007, 14:41) *
Дело ещё в том, что разных устройств таких для UART1 много и у каждого свой разработчик и своя ошибка в битрейте, бывает нулевая, бывает большая. Вот сейчас лежит одно и разница у нас с ним в 4%, пока он посылает мне пакеты-ответы длиной в 4 байта всё в порядке, когда длиной в 19 байт, то либо я получаю дополнительный странный довесок в несколько байт, либо в течение 2-3 секунд получаю максимум данных на этом битрейте, но так как дальше 128 байт у меня уже откидывается, то я не знаю сколько точно. Есть другое устройство с точно таким же протоколом связи, только ошибка гораздо меньше, так вот с ним все отрабатывает по протоколу нормально. Кстати это проблемное устройство прекрасно работает по этому протоколу с ПК, а со мной не хочет.

Если обмениваются устройства с ошибками по скорости - ошибка суммируется.
Решение - снижать скорость передачи.
3m-soft
Цитата(alexander55 @ Sep 25 2007, 15:49) *
Если обмениваются устройства с ошибками по скорости - ошибка суммируется.
Решение - снижать скорость передачи.


Дело в том что и скорость и протокол стандартизированы и не могут быть изменены и пока это единственное устройство с которым я не могу связаться на длинных пакетах. С другими, у которых нет такой ошибки битрейта по этому протоколу и на этой скорости я работаю.
Просто я уже усвоил несколько правил: не менять частоту ядра пока есть вероятность что устройство что-то ответит и держать включенным сторожевой таймер. Кстати мой LPC когда начинает базарить умудряется перепрошить микроконтролллер в одном из таких устройств, вот каждый раз смеху то когда у него слетает прошивка. Так как с другими устройствами это случается эпизодически, то я пока особо не паниковал, но вот теперь мне срочно нужно решение проблемы. Я конечно не ругаю мозги LPC и всё таки думаю что это проблема моей проги, но вот только найти причину никак не могу.
_basile
Цитата(3m-soft @ Sep 25 2007, 14:41) *
Дело ещё в том, что разных устройств таких для UART1 много и у каждого свой разработчик и своя ошибка в битрейте, бывает нулевая, бывает большая. Вот сейчас лежит одно и разница у нас с ним в 4%, пока он посылает мне пакеты-ответы длиной в 4 байта всё в порядке, когда длиной в 19 байт, то либо я получаю дополнительный странный довесок в несколько байт, либо в течение 2-3 секунд получаю максимум данных на этом битрейте, но так как дальше 128 байт у меня уже откидывается, то я не знаю сколько точно. Есть другое устройство с точно таким же протоколом связи, только ошибка гораздо меньше, так вот с ним все отрабатывает по протоколу нормально. Кстати это проблемное устройство прекрасно работает по этому протоколу с ПК, а со мной не хочет.


В UART побайтовая синхронизация. Для этого вначале каждого байта посылается стартовый бит, а в конце - стоповый. Соответственно, отдельные байты никак по времени между собой не связаны (в том числе и внутри пакета). Ищи жопу в программе.
alexander55
Цитата(3m-soft @ Sep 25 2007, 15:07) *
Дело в том что и скорость и протокол стандартизированы и не могут быть изменены и пока это единственное устройство с которым я не могу связаться на длинных пакетах. С другими, у которых нет такой ошибки битрейта по этому протоколу и на этой скорости я работаю.
Просто я уже усвоил несколько правил: не менять частоту ядра пока есть вероятность что устройство что-то ответит и держать включенным сторожевой таймер. Кстати мой LPC когда начинает базарить умудряется перепрошить микроконтролллер в одном из таких устройств, вот каждый раз смеху то когда у него слетает прошивка. Так как с другими устройствами это случается эпизодически, то я пока особо не паниковал, но вот теперь мне срочно нужно решение проблемы. Я конечно не ругаю мозги LPC и всё таки думаю что это проблема моей проги, но вот только найти причину никак не могу.

Еще решение.
Для LPC частоту периферии можно можно поднять (если есть такая возможность) и тем увеличить точность.
У меня уже заболела голова от разгадывания головоломок.
3m-soft
За счет Fractional baud rate у меня ошибка 0,0006%, так что большая ошибка не у меня, а у устройства, а оно куплено, а директор мне я..ца оторвет если деньги уплачены зря. Мне надо как-то подогнаться к нему по битрейту чтобы работать, я пробовал уже ставить битрейт который примерно у него, тем самым сократив ошибку между нами, но все равно косяки те же. Не пойму откуда появляются лишние байты, ведь в работе с ПК их нет. Приходит ровно 19 байт, а в LPC либо появляются лишние байты, либо bubble. И повторяю что с другими устройствами на LPC лишних байт нет, лишь совсем изредка bubble бывает.
3m-soft
Не согласится ли кто из умных форума сего посмотреть на мой модуль для работы с UART? 05.gif
amw
Вероятно порблема в том, что передача или прием данных происходит в момент перенастройки PLL.
По USB изменение частоты (читай искажения сигнала на шине) при перестройке PLL просто отсеется на уровне HOST контроллера аппаратно.
В UART синхронизация идет поБИТно. Именно потому что по старт БИТу определяется начало байта. Именно к этому старт БИТу привязывается защелкивание остальных битов.
И если стоп бит придет не вовремя, то и будет описанная ситуация.
Особенно сказывается при ошибке в скорости и именно таким образом.
Проверяйте в UART биты ошибок приема. И при изменениях PLL вообще отключайте UART.
3m-soft
Цитата(amw @ Sep 25 2007, 20:17) *
Вероятно порблема в том, что передача или прием данных происходит в момент перенастройки PLL.
По USB изменение частоты (читай искажения сигнала на шине) при перестройке PLL просто отсеется на уровне HOST контроллера аппаратно.
В UART синхронизация идет поБИТно. Именно потому что по старт БИТу определяется начало байта. Именно к этому старт БИТу привязывается защелкивание остальных битов.
И если стоп бит придет не вовремя, то и будет описанная ситуация.
Особенно сказывается при ошибке в скорости и именно таким образом.
Проверяйте в UART биты ошибок приема. И при изменениях PLL вообще отключайте UART.


Я конечно понимаю, что рассказываю фантастические вещи, но во время перенастройки PLL (а это не часто бывает) я конечно отключаю UART вплоть до того, что питание от UART отрубаю, но когда включаю потом обратно то и возникает зависание вот в этом куске кода:

__irq void uart1_irq(void)
{
......
// Узнать статус
unsigned char status=U1LSR;
while ((status & (1<<0))!=0) // Есть входные данные
{
// Получить байт и узнать статус
unsigned char ch=U1RBR; status=U1LSR;
....
}
.....
}

Вы скажете что этого не может быть, я тоже так думаю, но это так и из этого кстати выручает сторожевой таймер.

Хотя меня больше волнует проблема того что он двунаправленно спамит по двум модулям UART одновременно.

P.S. Кстати почему никто не думает что это может быть проблема компилятора или компиляции.
_basile
Цитата(3m-soft @ Sep 25 2007, 15:51) *
За счет Fractional baud rate у меня ошибка 0,0006%, так что большая ошибка не у меня, а у устройства, а оно куплено, а директор мне я..ца оторвет если деньги уплачены зря. Мне надо как-то подогнаться к нему по битрейту чтобы работать, я пробовал уже ставить битрейт который примерно у него, тем самым сократив ошибку между нами, но все равно косяки те же. Не пойму откуда появляются лишние байты, ведь в работе с ПК их нет. Приходит ровно 19 байт, а в LPC либо появляются лишние байты, либо bubble. И повторяю что с другими устройствами на LPC лишних байт нет, лишь совсем изредка bubble бывает.

А значение 19-ти байт, которые приходят в LPC те же, что и отправленные "устройством" и принятые РС, только к ним добавляются лишние байты? Или первые 19 байт тоже не совпадают с отправленными "устройством"?
И еще. Как я понял, информация передается пакетами. Т.е. в пакете должны быть байты, определяющие начало и конец пакета (ну, и контрольная сумма пакета при нормальном протоколе). В таком случае, отделить пакет от мусора - не проблема.

Цитата(3m-soft @ Sep 25 2007, 19:40) *
Я конечно понимаю, что рассказываю фантастические вещи, но во время перенастройки PLL (а это не часто бывает) я конечно отключаю UART вплоть до того, что питание от UART отрубаю, но когда включаю потом обратно то и возникает зависание вот в этом куске кода:

__irq void uart1_irq(void)
{
......
// Узнать статус
unsigned char status=U1LSR;
while ((status & (1<<0))!=0) // Есть входные данные
{
// Получить байт и узнать статус
unsigned char ch=U1RBR; status=U1LSR;
....
}
.....
}

Вы скажете что этого не может быть, я тоже так думаю, но это так и из этого кстати выручает сторожевой таймер.

Хотя меня больше волнует проблема того что он двунаправленно спамит по двум модулям UART одновременно.

P.S. Кстати почему никто не думает что это может быть проблема компилятора или компиляции.


Посмотрел исходник, и вот чего скажу, хоть сами мы не местные.
Выкинь нафиг FIFO. Ты же разборку пакета все равно где-то в основном цикле программы делаешь,
выковыривая принятые байты через receive0(). Сделай для приема обычный массив со счетчиком принятых байт. А протокол реализуй прямо в обработчике прерывания.
А в основном цикле просто опрашивай состояние (пакет принят/не принят). Если пакет принят - делаешь его разборку, обнуляешь счетчик принятых байт, сбрасываешь статус.
Сергей Борщ
Цитата(3m-soft @ Sep 25 2007, 18:40) *
P.S. Кстати почему никто не думает что это может быть проблема компилятора или компиляции.
По следующим причинам:
1) До вас этим компилятором пользовалась туева хуча народа (в том числе и здесь на форуме) и никто таких глюков не обнаруживал.
2) Компилятор про UART знать не знает, для него это обычные регистры.
3) В 99.9% "ошибки" компилятора оказывались ошибками писателя программы.
4) Если вы покажете в листинге место, где компилятор ошибся - будем обсуждать. Пока видно, что в листинг вы не заглядывали.

Можно телепатически сделать следующие предположения:
1) Мало выделили стека. Во время прерываний стек наползает на данные со всеми вытекающими.
2) Если у вас есть кольцевые буфера - указатель на голову обгоняет указатель на хвост (или наоборот) с вытекающим выводом всего буфера.
3m-soft
Осенило меня совсем отключить MAM, а не как прежде подбирать тайминги и всё заработало. Даже 4% ошибка в битрейте не мешает. Только нафиг оно мне нужно без MAM работать. Теперь опять в тупике.
zltigo
Цитата(3m-soft @ Sep 26 2007, 14:38) *
Теперь опять в тупике.

Банально этим все тормознули и оно где-то разминулось и "заработало". Поллагаю, что подобного эффекта можно попробовать достичь оставив MAM, но сбросив в пару раз частоту процессора.
Alechek
Цитата(3m-soft @ Sep 25 2007, 21:40) *
Я конечно понимаю, что рассказываю фантастические вещи, но во время перенастройки PLL (а это не часто бывает) я конечно отключаю UART вплоть до того, что питание от UART отрубаю, но когда включаю потом обратно то и возникает зависание

Не очень понятно, зачем перенастраивать PLL.. Сменить частоту ядра (CCLK)? Я меняю. Только после этого заново инициализирую UART, так как тактирование оного осуществляется от PCLK которое <= CCLK. Естественно, одному NXP известно, что там с UART происходит при смене частоты тактирования, и как она меняется
Zdrav
Посмотрел исходник. У вас каждьй spurrious IRQ тригерирует передача(bubble). Когда у вас ест ошибка и CTI IRQ одновременно, очистка буфера(запис в UхFCR) тригерирует spurrious IRQ которьй ведет за себя ...
Совет:
- Проверяйте interrupt_source не только для ошибки, но и чтоб определит типа прерьвание(RDA, CTI, THRE);
- Ваша очистка буфера не очишает CTI IRQ только делает его демон в кастроле;


ПС: Руский ето для меня не матерньй язик. Будте снизходительнье к правопис и граматика. laughing.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.