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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Сколько байт можно гарантированно запихивать в UART LPC (UART0 LPC2292) по прерыванию THRE?, Видимо 16
Alex03
сообщение Oct 11 2006, 05:38
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Будем считать что процедура записи в U0THR мгновеная, а скорость передачи сверхнизкая, т.е. байты улетать не успевают smile.gif

16? Или если ещё и LST_TEMP=1 (но это вряд ли) то и 17?

PS Гады. Ну реализовали они 550 UART но могли бы расширить флагами для статуса FIFO, а то и прерыванием по окончанию передачи из сдвигового регистра.
PPS FIFO понятно включен.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 11 2006, 06:17
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Alex03 @ Oct 11 2006, 08:38) *
16? Или если ещё и LST_TEMP=1 (но это вряд ли) то и 17?

Естествено 16, поскольку мгновенным ничего не бывает, и скорость передачи не бесконечно низкая, то и пока будете 16 запихивать первый уже в сдвиговый регистр в большинстве реальных приложений попадет, значит 17. 17-тым не пользуюсь, а 16 загружаю.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 11 2006, 07:29
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(zltigo @ Oct 11 2006, 12:17) *
Естествено 16, поскольку мгновенным ничего не бывает, и скорость передачи не бесконечно низкая, то и пока будете 16 запихивать первый уже в сдвиговый регистр в большинстве реальных приложений попадет, значит 17. 17-тым не пользуюсь, а 16 загружаю.


17 - пожалуй перебор.
Такой ситуации практически не бывает на относительно невысоких скоростях передачи.
Время передачи одного/двух бит (стоповый бит) или 7..11 бит (целого слова) часто довольно большое.
Например для B9600 м.б. ~100..1100мкс.
Да и на макс. скорости для 8N1 у проца есть 10*16 тактов, что вполне соизмеримо с временем записи 16 байтиков в U0THR с учётом хорошей оптимизации, задержек на ISR и тормознутой переферии.

А смутил меня попавшийся в двух примерах такой (псевдо)код в ISR:
Код
while (U0LSR & ULSR_THRE)
{
    U0THR = uart0_tx_buffer[uart0_tx_extract_idx++];
}


Т.е. они там по одному (в лучшем случае два) байту за прерывание отправляли, при активированном FIFO.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 11 2006, 10:24
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Alex03 @ Oct 11 2006, 10:29) *
А смутил меня попавшийся в двух примерах такой (псевдо)код в ISR:
Код
while (U0LSR & ULSR_THRE)
{
    U0THR = uart0_tx_buffer[uart0_tx_extract_idx++];
}


Т.е. они там по одному (в лучшем случае два) байту за прерывание отправляли, при активированном FIFO.
Ну почему же один? U0LSR читается на каждом проходе цикла, пока FIFO не заполнится ULSR_THRE равен 1 и цикл будет выполняться. Т.е. 16-17 легко.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 11 2006, 10:38
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(Сергей Борщ @ Oct 11 2006, 16:24) *
Ну почему же один? U0LSR читается на каждом проходе цикла, пока FIFO не заполнится ULSR_THRE равен 1 и цикл будет выполняться. Т.е. 16-17 легко.


Вот видимо те авторы так-же думали.

THRE - Transmitter Holding Register Empty
0: U0THR contains valid data.
1: U0THR is empty.
THRE is set immediately upon detection of an empty UART0 THR and is cleared on a U0THR write.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 11 2006, 14:43
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Alex03 @ Oct 11 2006, 13:38) *
Цитата(Сергей Борщ @ Oct 11 2006, 16:24) *

Ну почему же один? U0LSR читается на каждом проходе цикла, пока FIFO не заполнится ULSR_THRE равен 1 и цикл будет выполняться. Т.е. 16-17 легко.


Вот видимо те авторы так-же думали.

THRE - Transmitter Holding Register Empty
0: U0THR contains valid data.
1: U0THR is empty.
THRE is set immediately upon detection of an empty UART0 THR and is cleared on a U0THR write.
Так ведь то что в него записано тут же падает в FIFO и пока FIFO не полон THR пуст.
The U0THR is the top byte of the UART0 Tx FIFO. The top byte is the newest character in the Tx FIFO and can be written via
the bus interface. The LSB represents the first bit to transmit.

Сообщение отредактировал Сергей Борщ - Oct 11 2006, 14:47


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 12 2006, 03:18
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(Сергей Борщ @ Oct 11 2006, 20:43) *
Так ведь то что в него записано тут же падает в FIFO и пока FIFO не полон THR пуст.
The U0THR is the top byte of the UART0 Tx FIFO. The top byte is the newest character in the Tx FIFO and can be written via the bus interface. The LSB represents the first bit to transmit.


Вы ж сами сказали
Цитата
The U0THR is the top byte of the UART0 Tx FIFO.

Т.е. U0THR это голова FIFO, а не отдельный регистр. И если в FIFO чтото есть то THR не пуст.

ИМХО у Филипса тут дока кривоватая. Все эти THRE (как прерывание и как бит в LSR) THR (как U0THR) и т.д. Вроде всё просто, но понимание приходит со временем.

В общем я уже на практике убедился в своих словах.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 12 2006, 06:52
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Код
__irq __arm void uart_isr( void )
{
register int ii;
char ch;
    while( !((ch = (U0IIR&IIR_MASK)) & IIR_IP) )        // Check Pending Bit
    {    // What caused the interrupt?
        switch( ch )
        {
        case IIR_THRE:    // The THR+FIFO is empty. If there is another
                    //    characters in the TX buffer, load its now to FIFO->THR.
            for( ii=0; ( tbuf.tail != tbuf.head )&&( ii < TR_FIFO_SIZE ); ii++ )
                U0THR = tbuf.buf[(tbuf.head++)&(TBUF_SIZE_MSK)];
            break;

        case IIR_RX_TIMEOUT:
           case IIR_RX:
                  ..............


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 12 2006, 07:09
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Alex03 @ Oct 12 2006, 06:18) *
Цитата(Сергей Борщ @ Oct 11 2006, 20:43) *

Так ведь то что в него записано тут же падает в FIFO и пока FIFO не полон THR пуст.
The U0THR is the top byte of the UART0 Tx FIFO. The top byte is the newest character in the Tx FIFO and can be written via the bus interface. The LSB represents the first bit to transmit.


Вы ж сами сказали
Цитата
The U0THR is the top byte of the UART0 Tx FIFO.

Т.е. U0THR это голова FIFO, а не отдельный регистр. И если в FIFO чтото есть то THR не пуст.
Именно, голова а не хвост. И с точностью до наоборот - пока в FIFO есть место THR пуст.

Цитата(Alex03 @ Oct 12 2006, 06:18) *
В общем я уже на практике убедился в своих словах.
т.е. скорость небольшая (за время записи байта в FIFO он не успевает передаться), вы забили в пустой FIFO 16 байт, вышли из прерывания, получили прерывание THE и снова "не глядя" запихнули в FIFO 16 байт, а на второй стороне шнурка UART вывалилось 32 байта?
"Не верю!" (с)Станиславский.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 12 2006, 08:49
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(Сергей Борщ @ Oct 12 2006, 13:09) *
Именно, голова а не хвост.


По поводу головы я видимо погорячился. Байт который пишут в U0THR конечно же попадает в хвост FIFO.

Цитата
т.е. скорость небольшая (за время записи байта в FIFO он не успевает передаться), вы забили в пустой FIFO 16 байт, вышли из прерывания, получили прерывание THE и снова "не глядя" запихнули в FIFO 16 байт, а на второй стороне шнурка UART вывалилось 32 байта?
"Не верю!" (с)Станиславский.


Верить или нет - это проблемы Станиславского! smile.gif
Поглядите на код zltigo
Попробуйте без всяких прерываний выполнить такой код:

Код
    int n = 0;
    while(U0LSR & ULSR_THRE)
    {
        U0THR = n++;
    }
    printf("n=%d", n);


Думаю результат будет 2. smile.gif
Ну а в прерывании 1.


2 zltigo
Код
    for( ii=0; ( tbuf.tail != tbuf.head )&&( ii < TR_FIFO_SIZE ); ii++ )
        U0THR = tbuf.buf[(tbuf.head++)&(TBUF_SIZE_MSK)];

А tbuf.tail также растёт до бесконечности ( ну или там 2^(8*sizeof(tbuf.tail)) ) ?
Типа задумка такая - чтобы голова и хвост отражали реальное кол-во (по модулю 2^(8*sizeof(tbuf.tail))) прошедших через FIFO данных?

PS. А я что то всегда их циклю! smile.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 12 2006, 12:01
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Alex03 @ Oct 12 2006, 11:49) *
А tbuf.tail также растёт до бесконечности ( ну или там 2^(8*sizeof(tbuf.tail)) ) ?

Сравнение и занесение всегда производится по маскированным значениям, а сами указатели
растут "до бесконечности".
Цитата
Типа задумка такая - чтобы голова и хвост отражали реальное кол-во (по модулю 2^(8*sizeof(tbuf.tail))) прошедших через FIFO данных?

И что еще, что много более полезно - отражали факт переполнения буфера и работали быстрее, нежели в случае:
Цитата
PS. А я что то всегда их циклю! smile.gif

Недостаток всего один - размер степень двойки.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 12 2006, 12:41
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(zltigo @ Oct 12 2006, 18:01) *
Сравнение и занесение всегда производится по маскированным значениям, а сами указатели
растут "до бесконечности".

Наверное вытаскивание и занесение?

Цитата(zltigo @ Oct 12 2006, 18:01) *
И что еще, что много более полезно - отражали факт переполнения буфера и работали быстрее


В каком смысле "факт переполнения буфера"?
Код засовывания примерно тако?
Код
    if((tbuf.tail - tbuf.head) <= (TBUF_SIZE_MSK))
        tbuf.buf[(tbuf.tail++)&(TBUF_SIZE_MSK)] = X;
    else
        ...


Ну и не вижу великой разницы по быстродействию (при размере буфера = 2^x), хотя возможно есть. Будем иметь ввиду! smile.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 12 2006, 12:55
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Alex03 @ Oct 12 2006, 15:41) *
В каком смысле "факт переполнения буфера"?

В самом прямом.
Цитата
Код засовывания примерно тако?
Код
    if((tbuf.tail - tbuf.head) <= (TBUF_SIZE_MSK))
        tbuf.buf[(tbuf.tail++)&(TBUF_SIZE_MSK)] = X;
    else
        ...

Разумеется нет :-)
Код
      tbuf.buf[(bp.tail++)&(TBUF_SIZE_MSK)] = X;

И все!
Прочувствовали разницу и про переполнение стало яснее?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 13 2006, 07:37
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(zltigo @ Oct 12 2006, 18:55) *
Цитата

Код засовывания примерно тако?
Код
    if((tbuf.tail - tbuf.head) <= (TBUF_SIZE_MSK))
        tbuf.buf[(tbuf.tail++)&(TBUF_SIZE_MSK)] = X;
    else
        ...

Разумеется нет :-)
Код
      tbuf.buf[(bp.tail++)&(TBUF_SIZE_MSK)] = X;

И все!
Прочувствовали разницу и про переполнение стало яснее?


Не почуствовал.
Не вижу никакого контроля факта переполнения буфера.

Давайте на примере.
Допустим буфер 16 байт, TBUF_SIZE_MSK=0x0F

Запихиваем больше 16-ти байт, например 17 байт такие 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
Легко, контроля то нет. 17-ый лёг на место первого.

Читающий процесс (как в прерываннии вверху треда) также легко их достаёт, но достаёт он такую последовательнось:
16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16

И чё тут клёвого?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Oct 13 2006, 07:58
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Alex03 @ Oct 13 2006, 10:37) *
Не почуствовал.

Странно, Вы написали 'кучу' строчек в стиле
"А я что то всегда их циклю.." а тут одна :-)
Цитата
Не вижу никакого контроля факта переполнения буфера.

В расхождение старших (маскируемых) битов полного 'указателя' отражает
и факт переполнения и количество потерянных буферов/байтов. Причем это может быть проконтролировано в любой момент времени а не только в момент занесения, как в случае принудительного зацикливания.
Цитата
И чё тут клёвого?

Если скорость работы и контроль за фактом переполнения без дополнительных наворотов еще более снижающих скорость не важны, то "ничего клевого".


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th June 2025 - 10:01
Рейтинг@Mail.ru


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