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

 
 
 
Reply to this topicStart new topic
> Вопрос по 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
a3r3
сообщение Jul 4 2007, 03:23
Сообщение #2


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

Группа: Новичок
Сообщений: 84
Регистрация: 24-05-07
Пользователь №: 27 947



Нормально у него тайм-аут работает. Что записывается в US_RTOR (число)?
Go to the top of the page
 
+Quote Post
Terminator
сообщение Jul 4 2007, 03:28
Сообщение #3


Местный
***

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



65000
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 4 2007, 09:39
Сообщение #4


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

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



Цитата(Terminator @ Jul 4 2007, 09:28) *
А чему равно PACKET_MAX_SIZE? Неплохо бы увидеть еще функцию обработки прерывания.
Go to the top of the page
 
+Quote Post
Terminator
сообщение Jul 4 2007, 09:54
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 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
Terminator
сообщение Jul 5 2007, 10:28
Сообщение #6


Местный
***

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



Заработало когда на передающем конце(комп) сделал 2 стоп бита 07.gif
Я чтото пропустил в доке? cranky.gif
Go to the top of the page
 
+Quote Post
a3r3
сообщение Jul 5 2007, 11:48
Сообщение #7


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

Группа: Новичок
Сообщений: 84
Регистрация: 24-05-07
Пользователь №: 27 947



М.б. четность забыли выключить при конфигурировании USART? 0 - это even parity.

Сообщение отредактировал a3r3 - Jul 5 2007, 11:48
Go to the top of the page
 
+Quote Post
Terminator
сообщение Jul 6 2007, 04:13
Сообщение #8


Местный
***

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



Цитата(a3r3 @ Jul 5 2007, 18:48) *
М.б. четность забыли выключить при конфигурировании USART? 0 - это even parity.

Перепроверил ещё раз. Явно указал AT91C_US_PAR_NONE.
Go to the top of the page
 
+Quote Post
Timofey
сообщение Jul 6 2007, 04:18
Сообщение #9


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

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



Цитата(a3r3 @ Jul 5 2007, 17:48) *
М.б. четность забыли выключить при конфигурировании USART? 0 - это even parity.
Смотрите что вы передаете в функции AT91F_US_Configure ( ) Чему у вас равна mode. Если функцию размотать, то видно что именно эта переменная настраивает порт. Может быть из-за неё вы пишите в регистр US_MR в биты 12 и 13 числа 1 и 0 соответственно?



Сообщение отредактировал Timofey - Jul 6 2007, 04:21
Go to the top of the page
 
+Quote Post
Terminator
сообщение Jul 6 2007, 04:31
Сообщение #10


Местный
***

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



Ошибка найдена.
mode передаётся в функцию в виде
AT91C_US_USMODE_NORMAL | AT91C_US_PAR_NONE
Код
    mode &= AT91C_US_USMODE | AT91C_US_PAR;

Нехватало "| AT91C_US_PAR"
Код
    mode |= (
        AT91C_US_CLKS_CLOCK +
        AT91C_US_CHRL_8_BITS +
        //AT91C_US_NBSTOP_2_BIT +
        AT91C_US_CHMODE_NORMAL);


Посыпаю голову пеплом ...
Два дня потерял sad.gif
Go to the top of the page
 
+Quote Post

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

 


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


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