Страниц: 1 [2]
  Печать  
Автор Тема: вызов tti() при поллинге  (Прочитано 11569 раз)
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #15 : Мая 17, 2009, 10:51:49 pm »

А вот и заработало!
Отлично.
Сообщениями с событиями это как ?
MsgDeliverEvent(  ?  , &ttyctrl.event); так ?
Угу.
Таймером, как то не особо красиво, имхо..
Дело на любителя. В своё время разработчики из QSSL посоветовал делать именно через таймер. Но это для эмуляции именно аппаратных прерываний.
Записан

Goofy
Full Member
***
Offline Offline

Сообщений: 122


Просмотр профиля
« Ответ #16 : Мая 18, 2009, 07:40:02 am »

Спасибо за помощь! Всё получилось
Записан
LH
Full Member
***
Offline Offline

Сообщений: 130


Просмотр профиля
« Ответ #17 : Июня 22, 2010, 07:27:13 pm »

Просьба к Goofy опубликовать окончательный вид функции tti_dma_poll ()

Пытаюсь воспроизвести аналогчиную нить и симитировать ввод символов ( без аппаратуры ) с помощью tti().

Пока у меня код, приведенный в начале обсуждения, приводит к остановке драйвера...

Спасибо.
Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #18 : Июня 23, 2010, 12:30:20 pm »

Леонид, у меня последний месяц проблемы с почтой, я только получаю, отправлять ничего не могу, поэтому отвечу тут:

Возврат 1 функцией tti(). На сколько я помню, это просто операция прошла успешно и символ был добавлен.

Залипание ввода символов. tti() это интерфейс для изменения машины состояний. Поэтому Вы должны полностью эмулировать работу последовательной линии, например, задание текущего состояния через вызов tti() с параметром, отвечающим за ввод символа.

Вместе с символом попробуйте добавить флаги управления несущей TTI_CARRIER, tti(dev, current_byte | TTI_CARRIER);

А также проверить установленный режим управление потоком, программный или аппаратный.
Записан

LH
Full Member
***
Offline Offline

Сообщений: 130


Просмотр профиля
« Ответ #19 : Июня 24, 2010, 04:09:37 am »

Cпасибо.
У меня "методом тыка" получился работающий вариант симуляции ввода примерно 100000 символов в сек.

Но почему нужно ставить 0 ( а не 4 или 5 ) в MsgDeliverEvent( 0, &ttyctrl.event );
понимания нет.


Цитировать
void *tti_poll( void *area )
{

   unsigned c = 0x31, ret, i;

   while(1)
   {
      delay(10);                  


      /* Симуляция  */
      for( i=0; i< 1000; i++) {

         if( ++c == 0x40 )
            c=0x31;

            ret = tti( &dev->tty,  c);

      }
      ttyctrl.event_queue[ttyctrl.num_events++] = &dev->tty;
      MsgDeliverEvent( 0, &ttyctrl.event );

   }
}
Записан
Goofy
Full Member
***
Offline Offline

Сообщений: 122


Просмотр профиля
« Ответ #20 : Июня 25, 2010, 09:43:10 am »

Я в конечном счёте отказался от драйвером на поллинге (пока что). Большинство текущих задач требуют максимальной скорости реакции. А тут сразу 10 мс задержка... Ресурсов много, бодрейт невеликий, пускай дёргает по прерыванию.

Код:
int tti_dma_poll (DEV_USART *dev)
{

uint32_t rcr;
uint32_t rcvd_cnt;
unsigned    err_c = 0;
int csr;

delay(400);

out32( dev->pdc_base + AT91PDC_RPR, dev->prx_dma_buf );
out32( dev->pdc_base + AT91PDC_RNPR, dev->prx_dma_buf );
out32( dev->pdc_base + AT91PDC_RCR, dev->rx_dmab_size );
out32( dev->pdc_base + AT91PDC_RNCR, dev->rx_dmab_size );
dev->rx_dmab_cnt = 0;

while (1){
delay(10);
rcr = in32( dev->pdc_base + AT91PDC_RCR );

if ( !in32( dev->pdc_base + AT91PDC_RNCR ) ) {
rcvd_cnt = (dev->rx_dmab_size - dev->rx_dmab_cnt) + (dev->rx_dmab_size - rcr);

out32( dev->pdc_base + AT91PDC_RNPR, dev->prx_dma_buf );
out32( dev->pdc_base + AT91PDC_RNCR, dev->rx_dmab_size );
} else
rcvd_cnt = dev->rx_dmab_size - dev->rx_dmab_cnt  - rcr;


if (!rcvd_cnt) continue;

if ( ( csr =  in32(dev->pdc_base + AT91USART_CSR) ) & USART_RXERR) {
/*
* Save error as out-of-band data which can be read via devctl()
*/
dev->tty.oband_data |= csr;
atomic_set(&dev->tty.flags, OBAND_DATA);

if (csr & AT91USART_INT_RXBRK)
err_c |= TTI_BREAK;
else if (csr & AT91USART_INT_FRAME)
err_c |= TTI_FRAME;
else if (csr & AT91USART_INT_PARE)
err_c |= TTI_PARITY;
else if (csr & AT91USART_INT_OVRE)
err_c |= TTI_OVERRUN;

out32(dev->pdc_base + AT91USART_CR, AT91USART_CR_RSTSTA);
}
while (rcvd_cnt){

if ( tti( &dev->tty, err_c | dev->vrx_dma_buf [ dev->rx_dmab_cnt++ ] ) && ( (dev->tty.flags & EVENT_QUEUED) == 0 ) ){
dev_lock(&ttyctrl);
ttyctrl.event_queue[ttyctrl.num_events++] = &dev->tty;
atomic_set(&dev->tty.flags, EVENT_QUEUED);
dev_unlock(&ttyctrl);

MsgDeliverEvent(0, &ttyctrl.event);
}
err_c = 0;
if ( dev->rx_dmab_cnt >= dev->rx_dmab_size ) dev->rx_dmab_cnt = 0;
rcvd_cnt--;
}
}
}

Работало под 6.3.2
« Последнее редактирование: Июня 25, 2010, 09:45:15 am от Goofy » Записан
Страниц: 1 [2]
  Печать  
 
Перейти в: