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

 
 
> Вопрос по USART в SAM7X, Непонятки с rx-timeout
Terminator
сообщение Jul 4 2007, 02:21
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 209
Регистрация: 7-12-04
Из: Томск
Пользователь №: 1 382



Пытаюсь сделать приём пакетов с использованием PDC(DMA).
Проблемы с прерыванием "Receiver timeout'. Срабатывает после приёма одного или двух байт.
Специально выставил таймаут на максимум, при скорости 115200 должно получится немного больше 0.5сек и всё равно больше двух байт не принимает.
help.gif

Инициализация
Код
    // Usart Configure
    AT91F_US_Configure (uart->usart, configCPU_CLOCK_HZ, mode, 115200, 0);

    uart->usart->US_RTOR = USART_BITS_TIMEOUT;

    // Enable usart
    uart->usart->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;

    // open Usart interrupt
    AT91F_AIC_ConfigureIt (
            AT91C_BASE_AIC,
            d_id,
            interrupt_level,
            AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,
            USART0_ISR);

    AT91F_AIC_EnableIt (AT91C_BASE_AIC, d_id);
    
    AT91PS_PDC pPDC = ((AT91PS_PDC) &(uart->usart->US_RPR));
    AT91F_PDC_DisableRx(pPDC);
    AT91F_PDC_SetNextRx(pPDC, (char *) 0, 0);
    AT91F_PDC_SetRx(pPDC, (char *) 0, 0);

    AT91F_PDC_SetNextRx(pPDC, (char*)0, 0);
    AT91F_PDC_SetRx(pPDC, (char*)uart->rxbuf, PACKET_MAX_SIZE);
    AT91F_PDC_EnableRx(pPDC);
    
    // перезапускаем таймер таймаута
    uart->usart->US_CR = AT91C_US_STTTO;        

    // разрешаем прерывания по приёму
    uart->usart->US_IER = AT91C_US_ENDRX +
        AT91C_US_OVRE +
        AT91C_US_FRAME +
        AT91C_US_TIMEOUT;
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Terminator
сообщение Jul 4 2007, 09:54
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 209
Регистрация: 7-12-04
Из: Томск
Пользователь №: 1 382



PACKET_MAX_SIZE = 530

Эта функция вызывается из обработчика прерываний
Код
#define USART_RECV_INT     (AT91C_US_ENDRX +    \
                        AT91C_US_OVRE +        \
                        AT91C_US_FRAME +     \
                                                AT91C_US_TIMEOUT)

#define USART_SEND_INT     (AT91C_US_ENDTX)

// обработчик прерывания USART
static portBASE_TYPE usart_isr(tUART *uart)
{
    // смотрим что случилось
    int stat = uart->usart->US_CSR;
    int imr = uart->usart->US_IMR;
    stat &= imr;
    // сбрасываем флаги
    uart->usart->US_CR = AT91C_US_RSTSTA;

    // записываем состояние    
    uart->stat = stat;
    
    portBASE_TYPE xSwitchRequired = pdFALSE;

    if (stat & USART_SEND_INT)
    {
        // закончилась передача
        // запрещаем прерывание на  передачу
        uart->usart->US_IDR = USART_SEND_INT;
        // сигналим задаче
        xSwitchRequired = xSemaphoreGiveFromISR( uart->txsem, xSwitchRequired );
    }
        

    if (stat & USART_RECV_INT)
    {
        // событие по приёму
        // запрещаем прерывания по приёму
        uart->usart->US_IDR = USART_RECV_INT;
        // сигналим задаче
        xSwitchRequired = xSemaphoreGiveFromISR( uart->rxsem, xSwitchRequired );
    }

    /* Clear the interrupt. */
    AT91C_BASE_AIC->AIC_EOICR = 0;
    
    return xSwitchRequired;
}


В задаче обслуживающей приём пакетов, сразу после получания семафора, смотрю stat и регистры PDC.
В stat отмечено, что был timeout, а в регистрах PDC, что получено 2 байта. Что я забыл или неправильно сделал?
Go to the top of the page
 
+Quote Post



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

 


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


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