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

 
 
 
Reply to this topicStart new topic
> Почему первое прерывание возникает от ep2?, at91sam7s256
Bulat
сообщение Dec 12 2007, 12:20
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



При подключеннии контроллера к усб порту первое прерывание возникает от ep2, а ep2 у меня настроена на передачу данных хосту. По идее первое прерывание должно прийти от ep0, так как через нее происходит первичная конфигурация устройства. Но от ep0 прерывания не возникает. Почему?
Заранее благодарен!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 12 2007, 12:44
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Bulat @ Dec 12 2007, 15:20) *
При подключеннии контроллера к усб порту первое прерывание возникает от ep2... Но от ep0 прерывания не возникает. Почему?

Хоть бы написали, что Вы видите в UDP_ISR. Прерываний от EP2 быть не должно.
Выложите исходник, тогда можно будет что-то посоветовать.
Go to the top of the page
 
+Quote Post
Bulat
сообщение Dec 12 2007, 18:53
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(aaarrr @ Dec 12 2007, 17:44) *
Хоть бы написали, что Вы видите в UDP_ISR. Прерываний от EP2 быть не должно.
Выложите исходник, тогда можно будет что-то посоветовать.

Часть кода, отвечающая за инициализацию UDP (USB_ini()) и программа обработки прерываний от UDP (irq_USB()). Прверял, что прерывание возникло именно от ep2 таким образом: к выводам контроллерам прицепил светодиоды, а программу - "мигалку" вставлял после условий if, определяющих чему равен UDP_ISR.
Код
//Программа обработки прерывания от USB-модуля
unsigned int irq_USB()
{
  int sio;//источник прерывания (ep0,1,2)
  sio=regUDP->UDP_ISR&0x7;
  if(sio==0x1){enumer();}//если прерывание возникло от ep0
  else {
          if(sio==0x2) //если прерывание возникло от ep1
          {            
            if(rt==0)//начальная посылка от хоста(рег. режима и ком. слова)
            {  
              read_FIFO();
              rt++;  
            }
            else {  //передача данных от хоста устройству
                    read_FIFO();                  
                    if(rt==12) //если принято все 12 пакетов с данными, то
                               //необходимо начать передачу данных ОУ
                    {
                      trans_RT();//передача данных ОУ
                    }
                    rt++; //подсчитываем количество пакетов с данными от хоста,
                          //их д.б. 12 по количеству подадресов ОУ
                 }
            
            if(TMode<=8) {Mmode = 1;}
            Mmode=TMode;
            switch (mode)
            {
              case 1: rec_RT(); break; //прием данных от ОУ
              case 256: MT(); break;  //Монитор
              default:  break;
            }  
          }
          else {regUDP->UDP_CSR[2]=0; ct=0;}//если прерывание возникло от ep2
                           //- подтвержение, что хост принял данные
       }
  return(0);      
}

//------------------------------------------------------------------------------
//Инициализация UDP
void USB_ini()
{
  AT91C_BASE_AIC->AIC_IECR |= (1<<AT91C_ID_UDP);
  regUDP->UDP_IER=0x7;//разрешение прерывания от EP0...EP2
  regUDP->UDP_TXVC=0x0;//разрешение работы трансивера UDP
  regUDP->UDP_CSR[0]=regUDP->UDP_CSR[0]&0x8000;//ep0 - control,on,DIR=0(in)
  regUDP->UDP_CSR[1]=regUDP->UDP_CSR[1]&0x8200;//ep1 - bulk in,on
  regUDP->UDP_CSR[2]=regUDP->UDP_CSR[2]&0x8600;//ep2 - bulk out,on
  AT91C_BASE_AIC->AIC_SVR[AT91C_ID_UDP] = (unsigned int)irq_USB();//Запись адр. ф-ии обр. прерыв.
                                                    //от USB  
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void main()
{  
  clock_ini();
  PIO_ini();
  rt=0;
  ct=0;
  USB_ini();  
  while(1){} //ожидание прерывания от USB-модуля  
}
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 12 2007, 22:17
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Код странноватый:

Код
  regUDP->UDP_CSR[0]=regUDP->UDP_CSR[0]&0x8000;//ep0 - control,on,DIR=0(in)
  regUDP->UDP_CSR[1]=regUDP->UDP_CSR[1]&0x8200;//ep1 - bulk in,on
  regUDP->UDP_CSR[2]=regUDP->UDP_CSR[2]&0x8600;//ep2 - bulk out,on

& и | не перепутали?

Разрешать ненулевые ендпоинты и их прерывания нужно в Configured State, обрабатывать ENDBUSRES нужно в обязательном порядке. Внимательно прочитайте раздел Controlling Device States в документации.

Код
  sio=regUDP->UDP_ISR&0x7;
  if(sio==0x1){enumer();}//если прерывание возникло от ep0
  else {

Прерывания могут приходить от нескольких источников одновременно.

Код
AT91C_BASE_AIC->AIC_IECR |= (1<<AT91C_ID_UDP);
...
  AT91C_BASE_AIC->AIC_SVR[AT91C_ID_UDP] = (unsigned int)irq_USB();//Запись адр. ф-ии обр. прерыв.

Эти действия нужно совершать в обратном порядке.

Возможно, я что-то пропустил, но указанного вполне достаточно для полной неработоспособности.
Go to the top of the page
 
+Quote Post

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

 


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


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