|
Как правильно забивать FIFO UART, например в LPC213x |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 24)
|
Nov 20 2010, 11:28
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
half-duplex, RS-485. Цитата(kovigor @ Nov 20 2010, 16:15)  Код if (U1LCR && 0x20) // transmit FIFO empty ? Отменный код  Хорошо, что не читал. Но текстом там указано, что никак не узнать когда буфер полный. В то же время если THR пуст, то фифо тоже полностью пусто. Для меня это очень плохо! А всего-то надо было ввести битик полного фифо.
Сообщение отредактировал GetSmart - Nov 21 2010, 01:20
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Nov 20 2010, 11:36
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(GetSmart @ Nov 20 2010, 14:28)  half-duplex, RS-485. Тогда, если драйвер 485 позволяет, можно сделать эхо на время посылки, и заполнение буфера на передачу делать в прерывании приема по нужному уровню срабатывания. Только в такой схеме обязательно нужно предусмотреть механизм таймаутов, т.к. из-за конфликтов на шине RS-485 можно наловить и мусора.
|
|
|
|
|
Nov 20 2010, 11:45
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(singlskv @ Nov 20 2010, 16:36)  Только в такой схеме обязательно нужно предусмотреть механизм таймаутов, т.к. из-за конфликтов на шине RS-485 можно наловить и мусора. Таймауты есть, 10-20 символов. Однако текущая схема не позволяет такое дублирование. Понимаю, что дарёному коню в зубы не сомтрят. Но неужели это самое лучшее решение? ЗЫ. По таймеру забивать тоже не получается, т.к. непонятно сколько уарт выплюнул за какой-то промежуток времени. Во всяком случае легко сбиться.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Nov 20 2010, 11:58
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(GetSmart @ Nov 20 2010, 14:45)  Но неужели это самое лучшее решение? Понятно что самое простое это лить по 16байт в FIQ, но он ведь наверняка занят под что-то более важное... А так, это видимо вообще единственное решение если поток нужно иметь относительно непрерывным. З.Ы. Вот по-этому не люблю процы от NXP с их 16550 уартами, очень не удобно на них делать RS-485 с протоколами типа модбас, а у нас такое в каждой первой разработке.
|
|
|
|
|
Nov 20 2010, 12:04
|
Частый гость
 
Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425

|
Цитата(GetSmart @ Nov 20 2010, 13:28)  В то же время если THRE пуст, то фифо тоже полностью пуст. а так ли это ? Цитата The U0THR is the top byte of the UART0 TX FIFO. Цитата Writing to the UART0 Transmit Holding Register causes the data to be stored in the UART0 transmit FIFO. The byte will be sent when it reaches the bottom of the FIFO and the transmitter is available. стр 95 мануала Цитата TEMT is set when both U0THR and U0TSR are empty; TEMT is cleared when either the U0TSR or the U0THR contain valid data. вот по этому прерыванию у Вас таки все плохо... сейчас работаю c LPC1114 - там тоже уарт копаю... так в кейле в файле описания регистров УАРТа в конце есть регистр типа FIFOLVL - в мануале про него ничего...может и тут что есть... ЗЫ все предполагаю проверить не на чем...
|
|
|
|
|
Nov 20 2010, 12:15
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(singlskv @ Nov 20 2010, 16:58)  З.Ы. Вот по-этому не люблю процы от NXP с их 16550 уартами, очень не удобно на них делать RS-485 с протоколами типа модбас, а у нас такое в каждой первой разработке. А в компьютерном 16550 такая же кривизна что ли? Вообще-то в новых LPC там уже есть чтение уровня фифо. Вот со старыми приходится мучиться. Цитата(swisst @ Nov 20 2010, 17:04)  вот по этому прерыванию у Вас таки все плохо... Я отрабатываю прерывание с кодом 0xC2. Это "THRE Interrupt". Это не TEMT. Цитата а так ли это ? Я проверял это так. Сначала просто записал байт в THR. Потом залетел в прерывание с кодом 0xC2. В нём смотрел на флаг 0x20 внутри LSR. После записи одного (!) байта он сразу обнулялся. Я выходил из прерывания. И далее прерывание по кругу. В любой момент в прерывании можно ничего не записать в THR и прерывания с таким кодом больше не будет. Так вот, если бы THR (точнее его флаг 0x20 в LSR) был самым старшим (то есть 16-ым) то после записи первого байта в THR у меня бы в прерывании с кодом 0xC2 забилось сразу 15 (или 16) байт, а не 1.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Nov 20 2010, 12:25
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(GetSmart @ Nov 20 2010, 15:15)  А в компьютерном 16550 такая же кривизна что ли? В компьютерных 16550A еще хуже, каждый производитель чипсетов немного по-разному понимает вопрос совместимости с 16550А, ну и есть много других вариантов типа надстроек над 16550A, и еще бывают чипсеты с известными багами 16550А. Посмотрите исходники линукса на предмет работы с ком портами, душераздирающее зрелище... Цитата Вообще-то в новых LPC там уже есть чтение уровня фифо. Вот со старыми приходится мучиться. Надо будет посмотреть.
|
|
|
|
|
Nov 20 2010, 12:34
|
Частый гость
 
Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425

|
Цитата(GetSmart @ Nov 20 2010, 14:15)  Я отрабатываю прерывание с кодом 0xC2. Это "THRE Interrupt". Это не TEMT. в коде 0xC2 нет флага прерывания THRE Interrupt. но есть TEMT.
|
|
|
|
|
Nov 20 2010, 12:40
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(swisst @ Nov 20 2010, 17:34)  в коде 0xC2 нет флага прерывания THRE Interrupt. но есть TEMT. Да? У меня в мануале на LPC213x именно так "THRE Interrupt" написано (описание регистра U1IIR). А где написано что это TEMT? В описании регистра U1IIR вообще нет упоминания TEMT. В моём мануале.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Nov 20 2010, 12:52
|
Частый гость
 
Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425

|
Цитата(GetSmart @ Nov 20 2010, 14:40)  В описании регистра U1IIR вообще нет упоминания TEMT. В моём мануале. совершенно верно - TEMT упоминается в описании LSR. виноват, попутал...
|
|
|
|
|
Nov 20 2010, 13:19
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(GetSmart @ Nov 20 2010, 16:10)  Не особо и надобно. У меня сделано так. Когда возникает 0xC2 и буфер вывода закончился, то таймером задаётся пауза перед переключением (а она нужна) с учётом того, что ещё выводится один последний символ. И уже в прерывании таймера переключается RTS/DE. Вот это как раз жутко и не удобно, - лишний таймер + лишнее прерывание от него - по условию Вашей задачи, есть длинные прерывания (до 5 символов), то есть пауза после окончания передачи (TEMT) и до переключения RTS может сильно затянуться что не всегда хорошо, например если ответ на запрос будет начинаться быстрее чем 5 символов
|
|
|
|
|
Nov 21 2010, 10:30
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(zltigo @ Nov 21 2010, 11:23)  Не надо - лучше прочитайте. Тема большая и про заполнение FIFO там есть. Конечно я был слишком резок... и FIFO там упоминается, но по теме данного топика там нет ничего... Цитата(GetSmart @ Nov 21 2010, 12:46)  Но если бы была возможность читать уровень фифо, либо задавать уровень срабатывания THRE, то был бы идеальный 16550 (с буквой B  ). Буквально мелочи не хватает для полного счастья. И еще добавить прерывание по TEMT, и еще регулируемую софтом паузу в прерывании таймаут, и хардовое руление RTS. И получится почти также хорошо как в уартах у атмеля...
|
|
|
|
|
Nov 21 2010, 10:47
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(GetSmart @ Nov 21 2010, 13:34)  Почитайте описание LPC1114 уарт. Там столько всего есть. Может быть почти всё перечисленное. Даже аппаратное дрыгание RTS/DE. Почитал. Улучшили. Пока еще не все... Ждемс дальше... Цитата А у атмеля есть фифо и чтение его указателей? У него есть ДМА на почти всю переферию, причем с двойной буферизацией, и аппаратный RTS, и прерывание по уходу всего в линию(TEMT в LPC) и настраиваемый таймаут. Поэтому там таких проблем вообще нет. ИМХО, это вообще лучшая реализация уартов в МК. Слабое место атмеловских АРМ это I2C, хотя в новых чипах это вроде подправили.
|
|
|
|
|
Dec 8 2010, 14:34
|
Участник

Группа: Участник
Сообщений: 23
Регистрация: 14-08-06
Пользователь №: 19 528

|
Цитата(GetSmart @ Nov 21 2010, 12:46)  Есть только простое забивание всего фифо в прерывании по THRE. У меня щас так и сделано, но могут происходить паузы в потоке символов, хотя и в несколько раз с меньшей вероятностью чем когда совсем без фифо. Но если бы была возможность читать уровень фифо, либо задавать уровень срабатывания THRE, то был бы идеальный 16550 (с буквой B  ). Буквально мелочи не хватает для полного счастья. А что бы дал вам уровень FIFO ? Ваша проблема как я понял в том, что взведенное прерывание по опустошению FIFO передатчика не обрабатывается с должной скоростью. В результате паузы. Это от того, что кто-то запрещает прерывания надолго. Но это проблема проектирования конкретного софта, и периферийный UART не виноват. Мой совет: используйте вложенные прерывания, или измените код так, чтоб никто не работал в режиме запрета прерываний дольше времени передачи одного символа по UART. Или заассайните FIQ для UARTа. Из былого, бились несколько дней с такой же проблемой, Rowley CrossWorks + CTL на LPC2387. Оказалось реализованная в CTL байтовая очередь была "слишком безопасной", и на все время копирования данных запрещала IRQ. Теперь пользуем самописную очередь.
|
|
|
|
|
Dec 8 2010, 14:45
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Perepic @ Dec 8 2010, 19:34)  Мой совет: используйте вложенные прерывания, или измените код так, чтоб никто не работал в режиме запрета прерываний дольше времени передачи одного символа по UART. Или заассайните FIQ для UARTа. Я вас умаляю. Я фанат вложенных прерываний  У меня FIQ блокирует остальные прерывания на 5-6 символов уарта. А на FIQе мне нужен нулевой джиттер (он собсно и сделан) и переносить его на IRQ тем более вложенный я не могу. Уровень фифо мне бы помог так, что в периодическом прерывании от таймера (ну скажем в районе 8 символов уарта) я бы его читал и дозабивал фифо до максимума. То есть даже не в прерывании от уарта. Вобщем-то серьёзной проблемы нет. Всё работает и малые паузы не смертельны. Но лучше было бы без них.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|