|
|
  |
Keil & AT91SAM7SXX & USB, USB HID работет и через час -3 часа отваливается. |
|
|
|
Jun 17 2009, 08:25
|

Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 25-02-09
Из: Россия
Пользователь №: 45 369

|
Цитата(KAlex @ Jun 17 2009, 11:45)  Еще какие нибудь прерывания, кроме как для USB, используются? Уже ни каких, но проблема осталась. Ощущение такое, что проходит сообщение по USB и библиотека его не отрабатывает, после чего и вылетает. Использую WinXP лицензионный со всеми паками.
|
|
|
|
|
Jun 17 2009, 10:29
|

Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 25-02-09
Из: Россия
Пользователь №: 45 369

|
Разобрался с зависанием в функции прерывания USB_ISR. Попадая в цикл while (isr = pUDP->UDP_ISR) { висит там до тех пор пока isr != 0 Код void USB_ISR (void) /* __irq */{ DWORD isr, csr, bkm, n;
while (isr = pUDP->UDP_ISR) {
/* End of Bus Reset Interrupt */ if (isr & AT91C_UDP_ENDBUSRES) { USB_Reset(); pUDP->UDP_ICR = AT91C_UDP_ENDBUSRES; } ... } итог5е приходит прерывание AT91C_UDP_WAKEUP, обработки которого нет в цикле и сброса его не ведется, проблема решается добавлением pUDP->UDP_ICR = AT91C_UDP_WAKEUP; AT91C_UDP_WAKEUP - приходит в момент подключения или отключения USB разъёма, но не всегда. Но основная проблема ещё не решена. Тормозит редкость возникновения ошибки. Неужели никто не сталкивался с такой проблемой?
|
|
|
|
|
Jun 17 2009, 11:21
|

Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 25-02-09
Из: Россия
Пользователь №: 45 369

|
Цитата(KAlex @ Jun 17 2009, 14:47)  Что делает "USB_Reset();" А если поменять ресет местами с "pUDP->UDP_ICR = AT91C_UDP_ENDBUSRES;" Вот все тело функции: Код void USB_ISR (void) /* __irq */{ DWORD isr, csr, bkm, n;
while (isr = pUDP->UDP_ISR) {
if (isr & AT91C_UDP_WAKEUP) pUDP->UDP_ICR = AT91C_UDP_WAKEUP;//Это моё
/* End of Bus Reset Interrupt */ if (isr & AT91C_UDP_ENDBUSRES) { USB_Reset(); #if USB_RESET_EVENT USB_Reset_Event(); #endif pUDP->UDP_ICR = AT91C_UDP_ENDBUSRES; }
/* USB Suspend Interrupt */ if (isr & AT91C_UDP_RXSUSP) { USB_Suspend(); #if USB_SUSPEND_EVENT USB_Suspend_Event(); #endif pUDP->UDP_ICR = AT91C_UDP_RXSUSP; }
/* USB Resume Interrupt */ if (isr & AT91C_UDP_RXRSM) { USB_Resume(); #if USB_RESUME_EVENT USB_Resume_Event(); #endif pUDP->UDP_ICR = AT91C_UDP_RXRSM; }
/* External Resume Interrupt */ if (isr & AT91C_UDP_EXTRSM) { USB_WakeUp(); #if USB_WAKEUP_EVENT USB_WakeUp_Event(); #endif pUDP->UDP_ICR = AT91C_UDP_EXTRSM; }
/* Start of Frame Interrupt */ if (isr & AT91C_UDP_SOFINT) { #if USB_SOF_EVENT USB_SOF_Event(); #endif pUDP->UDP_ICR = AT91C_UDP_SOFINT; }
/* Endpoint Interrupts */ for (n = 0; n < USB_EP_NUM; n++) { if (isr & (1 << n)) {
csr = pUDP->UDP_CSR[n];
/* Setup Packet Received Interrupt */ if (csr & AT91C_UDP_RXSETUP) { if (USB_P_EP[n]) { USB_P_EP[n](USB_EVT_SETUP); } /* Setup Flag is already cleared in USB_DirCtrlEP */ /* pUDP->UDP_CSR[n] &= ~AT91C_UDP_RXSETUP; */ }
/* Data Packet Received Interrupt */ bkm = RX_DATA_BK[RxDataBank[n]]; if (csr & bkm) { if (USB_P_EP[n]) { USB_P_EP[n](USB_EVT_OUT); } pUDP->UDP_CSR[n] &= ~bkm; if (DualBankEP & (1 << n)) { RxDataBank[n] ^= 1; } }
/* Data Packet Sent Interrupt */ if (csr & AT91C_UDP_TXCOMP) { // pUDP->UDP_CSR[n] &= ~AT91C_UDP_TXCOMP; if (TxDataBank[n]) { pUDP->UDP_CSR[n] |= AT91C_UDP_TXPKTRDY; TxDataBank[n] = 0; } if (USB_P_EP[n]) { USB_P_EP[n](USB_EVT_IN); } pUDP->UDP_CSR[n] &= ~AT91C_UDP_TXCOMP; }
/* STALL Packet Sent Interrupt */ if (csr & AT91C_UDP_STALLSENT) { if ((csr & AT91C_UDP_EPTYPE) == AT91C_UDP_EPTYPE_CTRL) { if (USB_P_EP[n]) { USB_P_EP[n](USB_EVT_IN_STALL); /* USB_P_EP[n](USB_EVT_OUT_STALL); */ } } pUDP->UDP_CSR[n] &= ~AT91C_UDP_STALLSENT; }
} }
}
*AT91C_AIC_EOICR = 0; /* End of Interrupt */ } А вот Reset Код void USB_Reset (void) { DWORD n;
/* Global USB Reset */ pUDP->UDP_GLBSTATE &= ~(AT91C_UDP_FADDEN | AT91C_UDP_CONFG | AT91C_UDP_RMWUPE); pUDP->UDP_FADDR = AT91C_UDP_FEN; pUDP->UDP_ICR = 0xFFFFFFFF;
/* Reset & Disable USB Endpoints */ for (n = 0; n < USB_EP_NUM; n++) { pUDP->UDP_CSR[n] = 0; RxDataBank[n] = 0; TxDataBank[n] = 0; } pUDP->UDP_RSTEP = 0xFFFFFFFF; pUDP->UDP_RSTEP = 0;
/* Setup USB Interrupts */ pUDP->UDP_IER = AT91C_UDP_RXSUSP | AT91C_UDP_RXRSM | AT91C_UDP_EXTRSM | AT91C_UDP_SOFINT | (2^USB_EP_NUM - 1);
/* Setup Control Endpoint 0 */ pUDP->UDP_CSR[0] = AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL; } Менять их местами смысла не вижу pUDP->UDP_ICR очищает флаги прерываий. Но попробую.
|
|
|
|
|
Jun 17 2009, 21:52
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Sanya_kv @ Jun 17 2009, 15:21)  Код while (isr = pUDP->UDP_ISR) { я вот не до конца уверен в правильности висения в прерывании по такому принципу, те пока не обработаем все полученные и все вновь пришедшие прерывания... Нужно посмотреть еще на Вашу функцию записи, там можно случайно зациклиться...
|
|
|
|
|
Jun 18 2009, 06:28
|

Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 25-02-09
Из: Россия
Пользователь №: 45 369

|
Цитата(singlskv @ Jun 18 2009, 01:52)  Нужно посмотреть еще на Вашу функцию записи, там можно случайно зациклиться... Пример взят стандартный из c:\Keil\ARM\Boards\Atmel\AT91SAM7S-EK\USB\HID\ можите побалываться с ним. Устройство вылетает при интенсивном обмене, примерно 10 посылок в секунду. Опрос HID = 35млСек . В Иар сделано по другому: Код status = AT91C_BASE_UDP->UDP_ISR; status &= AT91C_BASE_UDP->UDP_IMR; ... if (status == AT91C_UDP_RXSUSP) { ...
Сообщение отредактировал Sanya_kv - Jun 18 2009, 06:29
|
|
|
|
|
Jun 18 2009, 13:46
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Sanya_kv @ Jun 18 2009, 10:28)  Пример взят стандартный из c:\Keil\ARM\Boards\Atmel\AT91SAM7S-EK\USB\HID\ можите побалываться с ним. у меня не Keil, поэтому взять его неоткуда, да и незачем... Цитата Устройство вылетает при интенсивном обмене, примерно 10 посылок в секунду. Опрос HID = 35млСек . Ну это разьве интенсивно ? Нагрузите обменом по максимуму, тогда ошибки будут чаще и их проще будет ловить. Цитата В Иар сделано по другому: Код status = AT91C_BASE_UDP->UDP_ISR; status &= AT91C_BASE_UDP->UDP_IMR; ... if (status == AT91C_UDP_RXSUSP) { ... ИМХО, это правильнее
|
|
|
|
|
Jun 18 2009, 17:08
|

Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 25-02-09
Из: Россия
Пользователь №: 45 369

|
Цитата(singlskv @ Jun 18 2009, 17:46)  Ну это разьве интенсивно ? Нагрузите обменом по максимуму, тогда ошибки будут чаще и их проще будет ловить. Windows быстрее не успевает. Код status = AT91C_BASE_UDP->UDP_ISR; status &= AT91C_BASE_UDP->UDP_IMR; ... if (status == AT91C_UDP_RXSUSP) { ... не помагло. Скорей всего дело в обработке. Буду тестировать в IAR.
Сообщение отредактировал Sanya_kv - Jun 18 2009, 17:10
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|