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

 
 
 
Reply to this topicStart new topic
> LPC236x, scmRTOS. Как обработать переполнение UART?
meister
сообщение Nov 24 2008, 11:17
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484



Обработчик прерывания (ниже), если не доставать данные из rx очереди вылетает на

Код
assert(0 == (iir & util::bit<hw::UART::UxIIR_int_status>::value) && "At least one interrupt is pending.");


а должен в
Код
assert(0 && "UART RX FIFO overflow");
или
Код
assert(0 == (lsr & util::bit<hw::UART::UxLSR_RX_OE>::value));


Что я делаю не по мануалу?

Код
OS_INTERRUPT void interrupts::irq_uart2_handler(void)
{
    OS::TISRW ISRW;
    interrupt_leds();
    
    unsigned const iir = U2IIR;
    
    assert(0 == (iir & util::bit<hw::UART::UxIIR_int_status>::value) && "At least one interrupt is pending.");
    
    switch (iir & hw::UART::UxIIR_IRQ_mask)
    {
    default: PANIC("unknown UART interrupt", UART2_FAULT);
    case hw::UART::UxIIR_RLS_bit:
        {
            basic_uart_t::rx_channel_item_t item;
            
            {
                byte const lsr = U2LSR;
                
                if (lsr & util::bit<hw::UART::UxLSR_RX_OE>::value)
                {
                    assert(0 && "UART RX FIFO overflow");
                    item.value = '?';
                }
                else
                {
                    assert(lsr & util::bit<hw::UART::UxLSR_RX_RDR>::value);
                    item.value = U2RBR;
                }
                
                item.lsr = lsr & hw::UART::UxLSR_RX_error_mask;
            }
            
            if (uarts::uart2.rx_.get_free_size() > 0)
            {
                uarts::uart2.rx_.push(item);
            }
            else
            {
                assert(0 && "UART RX queue overflow");
                hw::LEDs::red(config::led_long_flash);
                uarts::uart2.overflow_ = true;
            }
        }
        break;
        
    case hw::UART::UxIIR_RDA_bit:
    case hw::UART::UxIIR_CTI_bit:
        while (uarts::uart2.rx_.get_free_size() > 0)
        {
            byte lsr = U2LSR;
            
            assert(0 == (lsr & util::bit<hw::UART::UxLSR_RX_OE>::value));
            
            if (lsr & util::bit<hw::UART::UxLSR_RX_RDR>::value)
            {
                basic_uart_t::rx_channel_item_t item;
                
                item.lsr = 0;
                item.value = U2RBR;
                
                uarts::uart2.rx_.push(item);
            }
            else
            {
                break;
            }
        }
        break;
        
    case hw::UART::UxIIR_THRE_bit:
        for (unsigned n = util::min_val<unsigned>(hw::UART::tx_batch_max_length, uarts::uart2.tx_.get_count()); n > 0; --n)
        {
            byte b;
            uarts::uart2.tx_.pop(b);
            U2THR = b;
        }
        break;
    }
}
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Nov 25 2008, 10:10
Сообщение #2


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Возможно, дело в том, что в регистре IIR могут быть установлены несколько бит одновременно.
Один из битов вы обработали (сняли флаг), по выходу из прерывания сразу следует второе.
У меня сделано так (подсмотрел):

Код
    iirMask = Reg.IIR_FCR & 0x07;
    while ( iirMask != 1 )
    {
       if()....
       else if()....
       else if()....
       iirMask = Reg.IIR_FCR & 0x07;
    }
Go to the top of the page
 
+Quote Post
meister
сообщение Nov 25 2008, 16:12
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484



Цитата(HARMHARM @ Nov 25 2008, 14:10) *
Возможно, дело в том, что в регистре IIR могут быть установлены несколько бит одновременно.


Я убрал все обращения к UxLSR вне прерывания Receive Line Status (RLS) - теперь работает как надо.
Go to the top of the page
 
+Quote Post
meister
сообщение Dec 11 2008, 16:02
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484



Переполнения я обработал. А как обрабатывать ошибки? В мануале по Framing error написано следующее:

Цитата
When the stop bit of a received character is a logic 0, a framing error occurs. An UnLSR read clears UnLSR[3]. The time of the framing error detection is dependent on UnFCR0. Upon detection of a framing error, the Rx will attempt to resynchronize to the data and assume that the bad stop bit is actually an early start bit. However, it cannot be assumed that the next received byte will be correct even if there is no Framing Error.

Цитата
Note: A framing error is associated with the character at the top of the UARTn RBR FIFO.


Код
    case hw::UART::UxIIR_RLS_bit:
        {
            byte const lsr = U0LSR; // <1>
            
            if (uarts::uart0.rx_.get_free_size() > 0)
            {
                basic_uart_t::rx_channel_item_t item;
                item.value = '?';
                item.lsr = lsr & hw::UART::UxLSR_RX_error_mask;
                uarts::uart0.rx_.push(item);
            }
            else
            {
                uarts::uart0.rx_overflow_ = true;
            }
        }
        break;


В строчке <1> переменная lsr иногда равна 0xE8 - данных в RX FIFO нет, Framing error - есть. Не соответствует Note из мануала.
Go to the top of the page
 
+Quote Post

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

 


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


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