Цитата
DimitryB Дата Сегодня, 05:01
Потому что он у вас уходит в прерывание по END BUS RESET и вы не сбрасываете прерывание В итоге оно все время повторяется и enumeration устройства так и не происходит.
Вы должны знать как использовать прерывание...
То, что вы перечислили все у меня прописано в функции main. Я же взял за основу готовый пример USART_USB, поэтому нумерация у меня проходит нормально. Я говорил о том, что когда добавлял код
Код
#pragma vector = 0x18
__irq __arm void IRQ_Switch()
{
void (*udp_c_irq_handler)() = (void(*)())AT91C_BASE_AIC->AIC_IVR;
udp_c_irq_handler();
AT91C_BASE_AIC->AIC_EOICR = 0; // Reset AIC logic
}
в файл main.c нумерация переставала работать, но это логично, так как в udp_c_irq_handler(); я же не обрабатываю прерывание от ep0. Прерывание от ep0 или от END BUS RESET определяются в функции AT91F_UDP_IsConfigured(AT91PS_CDC pCdc), которая прописана в файле cdc_enumerate.c, там же и происходит нумерация. Я же ожидаю окончание нумерации в функции main файла main.c:
Код
while(!pCDC.IsConfigured(&pCDC));
Только после этого я инициализирую обработчик прерывания от ep2. При этом я сначала сбрасываю (!!!) все прерывания:
Код
pCDC.pUdp->UDP_ICR = 0xff00;
А потом уже произвожу инициализацию прерывания от ep2 и глобально его разрешаю:
Код
AT91F_UDP_DisableIt ( pCDC.pUdp, 0xFFFF);
AT91F_UDP_EnableIt (pCDC.pUdp, AT91C_UDP_EPINT2);
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_UDP, UDP_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_HIGH_LEVEL, udp_c_irq_handler);
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_UDP);
Проблема заключается в том, что в итоге при запросе с компа на чтение данных с моего девайса (функция readfile()) прерывание от ep2 (ep_out) в моем девайсе не возникает, т.е. функция udp_c_irq_handler() не вызывается!
Еще раз привожу функции main и udp_c_irq_handler и обращаю внимание, что нумерация проходит нормально, устройство инициализируется компом, драйвер рабочий, проверяли.
Код
int main ( void )
{
__ramfunc __arm void udp_c_irq_handler(void);
// Enable User Reset and set its minimal assertion to 960 us
AT91C_BASE_RSTC->RSTC_RMR = AT91C_RSTC_URSTEN | (0x4<<8) | (unsigned int)(0xA5<<24);
// Init USB device
AT91F_USB_Open();
// Init USB device
// Wait for the end of enumeration
while(!pCDC.IsConfigured(&pCDC));
pCDC.pUdp->UDP_ICR = 0xff00;
AT91F_UDP_DisableIt ( pCDC.pUdp, 0xFFFF);
AT91F_UDP_EnableIt (pCDC.pUdp, AT91C_UDP_EPINT2);
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_UDP, UDP_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_HIGH_LEVEL, udp_c_irq_handler);
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_UDP);
}
//udp_c_irq_handler
__ramfunc __arm void udp_c_irq_handler(void)
{
int sio = pCDC.pUdp->UDP_ISR&0x7;
if(sio==0x4) //если прерывание от ep2
{
char buff_read[64];
static char buff_write[64];
unsigned int return_val = UDP_Read(&pCDC, buff_read,64);
for(int i=0;i<64;i++)
{
buff_write[i] = i;
}
UDP_Write(&pCDC, buff_write,64);
}
pCDC.pUdp->UDP_ICR = 0xff00;
}