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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Как правильно забивать FIFO UART, например в LPC213x
GetSmart
сообщение Nov 20 2010, 10:39
Сообщение #1


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



В приёмнике уарта при включенном фифо есть уровень срабатывания. А в передатчике аналогичного уровня нет (?). Поэтому когда возникает прерывание от уарта с кодом 0xC2 сколько нужно пихать байт в THR ? Когда я контролирую бит 0x20 внутри LSR то только один байт запихивается и сразу он обнуляется. Хотя на передачу фифо тоже 16 символьное. Если прерывание возникает только когда передаётся последний байт (когда фифо опустело), то при мегабоде скорости и длительных прерываниях от других источников (до 5 символов уарта) могут происходить нежелательные паузы в передаче. Неужели нет аппаратного "прямого" способа вызывать прерывание пораньше?

Есть конечно кривоватый другой способ забивания данных в уарт - по таймеру. Но в нём непонятно сколько данных забивать, т.к. я не вижу флага заполненности фифо. Может кто-нить его видет? Или есть идеи по выходу из моего тупика?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
kovigor
сообщение Nov 20 2010, 11:15
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(GetSmart @ Nov 20 2010, 14:39) *
Или есть идеи по выходу из моего тупика?


Вот это читали ?

http://www.nxp.com/acrobat_download2/vario...PC2000_UART.pdf
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 20 2010, 11:16
Сообщение #3


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Передача full-duplex или half-duplex ?
чисто UART или к примеру RS-485 ?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 20 2010, 11:28
Сообщение #4


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



half-duplex, RS-485.

Цитата(kovigor @ Nov 20 2010, 16:15) *

Код
if (U1LCR && 0x20)        // transmit FIFO empty ?

Отменный код smile.gif Хорошо, что не читал.

Но текстом там указано, что никак не узнать когда буфер полный. В то же время если THR пуст, то фифо тоже полностью пусто. Для меня это очень плохо! А всего-то надо было ввести битик полного фифо.

Сообщение отредактировал GetSmart - Nov 21 2010, 01:20


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 20 2010, 11:36
Сообщение #5


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(GetSmart @ Nov 20 2010, 14:28) *
half-duplex, RS-485.
Тогда, если драйвер 485 позволяет, можно сделать эхо на время посылки,
и заполнение буфера на передачу делать в прерывании приема по нужному уровню срабатывания.
Только в такой схеме обязательно нужно предусмотреть механизм таймаутов, т.к. из-за
конфликтов на шине RS-485 можно наловить и мусора.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 20 2010, 11:45
Сообщение #6


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(singlskv @ Nov 20 2010, 16:36) *
Только в такой схеме обязательно нужно предусмотреть механизм таймаутов, т.к. из-за
конфликтов на шине RS-485 можно наловить и мусора.

Таймауты есть, 10-20 символов. Однако текущая схема не позволяет такое дублирование.
Понимаю, что дарёному коню в зубы не сомтрят. Но неужели это самое лучшее решение?

ЗЫ. По таймеру забивать тоже не получается, т.к. непонятно сколько уарт выплюнул за какой-то промежуток времени. Во всяком случае легко сбиться.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 20 2010, 11:58
Сообщение #7


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(GetSmart @ Nov 20 2010, 14:45) *
Но неужели это самое лучшее решение?
Понятно что самое простое это лить по 16байт в FIQ, но он ведь наверняка занят
под что-то более важное...

А так, это видимо вообще единственное решение если поток нужно иметь относительно непрерывным.

З.Ы. Вот по-этому не люблю процы от NXP с их 16550 уартами, очень не удобно на них делать
RS-485 с протоколами типа модбас, а у нас такое в каждой первой разработке.
Go to the top of the page
 
+Quote Post
swisst
сообщение Nov 20 2010, 12:04
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 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 - в мануале про него ничего...может и тут что есть...

ЗЫ все предполагаю проверить не на чем...
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 20 2010, 12:15
Сообщение #9


.
******

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


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 20 2010, 12:25
Сообщение #10


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(GetSmart @ Nov 20 2010, 15:15) *
А в компьютерном 16550 такая же кривизна что ли?
В компьютерных 16550A еще хуже, каждый производитель чипсетов немного по-разному
понимает вопрос совместимости с 16550А, ну и есть много других вариантов типа надстроек над 16550A,
и еще бывают чипсеты с известными багами 16550А.
Посмотрите исходники линукса на предмет работы с ком портами, душераздирающее зрелище...
Цитата
Вообще-то в новых LPC там уже есть чтение уровня фифо. Вот со старыми приходится мучиться.
Надо будет посмотреть.
Go to the top of the page
 
+Quote Post
swisst
сообщение Nov 20 2010, 12:34
Сообщение #11


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425



Цитата(GetSmart @ Nov 20 2010, 14:15) *
Я отрабатываю прерывание с кодом 0xC2. Это "THRE Interrupt". Это не TEMT.


в коде 0xC2 нет флага прерывания THRE Interrupt. но есть TEMT.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 20 2010, 12:40
Сообщение #12


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(swisst @ Nov 20 2010, 17:34) *
в коде 0xC2 нет флага прерывания THRE Interrupt. но есть TEMT.

Да?
У меня в мануале на LPC213x именно так "THRE Interrupt" написано (описание регистра U1IIR). А где написано что это TEMT?

В описании регистра U1IIR вообще нет упоминания TEMT. В моём мануале.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
swisst
сообщение Nov 20 2010, 12:52
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425



Цитата(GetSmart @ Nov 20 2010, 14:40) *
В описании регистра U1IIR вообще нет упоминания TEMT. В моём мануале.


совершенно верно - TEMT упоминается в описании LSR. виноват, попутал...
Go to the top of the page
 
+Quote Post
singlskv
сообщение Nov 20 2010, 12:55
Сообщение #14


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(GetSmart @ Nov 20 2010, 15:40) *
В описании регистра U1IIR вообще нет упоминания TEMT. В моём мануале.
Нету прерывания по TEMT, и это еще одно неудобство при необходимости
ручного управления RTS в RS-485 сети.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 20 2010, 13:10
Сообщение #15


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(singlskv @ Nov 20 2010, 17:55) *
Нету прерывания по TEMT, и это еще одно неудобство при необходимости
ручного управления RTS в RS-485 сети.

Не особо и надобно. У меня сделано так. Когда возникает 0xC2 и буфер вывода закончился, то таймером задаётся пауза перед переключением (а она нужна) с учётом того, что ещё выводится один последний символ. И уже в прерывании таймера переключается RTS/DE.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 16:52
Рейтинг@Mail.ru


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