|
Контроллер повисает после перезапуска приложения, если при этом происходила передача данных по USB от контроллера приложению, at91sam7s |
|
|
|
Jun 24 2010, 11:30
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Девайс принимает данные по некому протоколу, преобразует их в нужный формат и передает по USB на ПК. Если прекратить передавать по этому протоколу данные девайсу, а затем закрыть приложение на ПК, то при следующем запуске приложения девайс нормально определяется и работает. Но, если во время приема девайсом данных и, соответственно, передачей их по USB на ПК выйти из приложения, то девайс повисает и при следующем запуске приложения уже не определяется. Приходится передергивать USB-кабель девайса и еще раз перезапускать приложение. Только после этого девайс начинает работать. Получается в FIFO UDP девайса остаются непрочитанные приложением данные. При закрытии приложения девайсу посылается команда Turn off. Чтобы очистить FIFO использовал сброс конечной точки по команде Turn off: Код AT91C_BASE_UDP->UDP_RSTEP |= AT91C_UDP_EPINT1; AT91C_BASE_UDP->UDP_RSTEP &= ~(AT91C_UDP_EPINT1); ... не помогает. По этой же команде Turn off пробовал производить программный сброс процессора и периферии 2-мя способами: 1. Код ((void (*)())0x0000)(); 2. Код #define AT91C_RSTC_KEY_MY ((unsigned int) 0xA5 << 24) // (RSTC) Password AT91C_BASE_RSTC->RSTC_RCR = AT91C_RSTC_KEY_MY | AT91C_RSTC_PROCRST | AT91C_RSTC_PERRST; ... тоже не помогло. Какие еще возможны решения этой проблемы? Заранее благодарен!
|
|
|
|
|
Jun 24 2010, 11:55
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(aaarrr @ Jun 24 2010, 17:43)  А контроллер ее точно принимает и обрабатывает, или зависает еще раньше, потому что его перестали читать? Точно принимает, потому что, если его даже перестанут читать, он не зависнет. Опрос битов TXCOMP и TXPKTRDY происходит в основном цикле программы (без прерываний от ендпоинтов и ожиданий TXCOMP), то есть если даже эти биты не выставлены, то контроллер продолжает работать дальше и опрашивает ендпоинт с входящими данными, среди которых и приходит Turn off.
|
|
|
|
|
Jun 24 2010, 12:06
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Bulat @ Jun 24 2010, 15:55)  Точно принимает, потому что, если его даже перестанут читать, он не зависнет. А из первого сообщения картина складывается противоположная: Цитата если во время приема девайсом данных и, соответственно, передачей их по USB на ПК выйти из приложения, то девайс повисает Попробуйте описать ситуацию более подробно: как происходит "определение" устройства в программе, что именно зависает - обмен по USB, или процессор в неопределенной точке программы.
|
|
|
|
|
Jun 24 2010, 12:46
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(aaarrr @ Jun 24 2010, 18:06)  А из первого сообщения картина складывается противоположная: Цитата если во время приема девайсом данных и, соответственно, передачей их по USB на ПК выйти из приложения, то девайс повисает
При выходе из приложения девайсу по USB посылается команда Turn off. Он ее никак не избежит. Я проверял, команда выполняется. Цитата(aaarrr @ Jun 24 2010, 18:06)  Попробуйте описать ситуацию более подробно: как происходит "определение" устройства в программе, что именно зависает - обмен по USB, или процессор в неопределенной точке программы. Устройство в приложении открывается стандартно по Guid с помощью API функций. Вот скелет основного цикла прошивки: CODE _ramfunc int main(void) { AT91F_USB_Open(); // CDC USB_init(); PIO_ini(); AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ; Receiver_ini(); AT91F_SSC_Conf ();
//Основной цикл программы while(1) { if(recA_1) //если есть данные для передачи по USB { if(!(regUDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY)) { //Заполнение FIFO UDP unsigned int rec = recA_1; regUDP->UDP_FDR[AT91C_EP_IN] = 11; regUDP->UDP_FDR[AT91C_EP_IN] = rec&0xff; unsigned int m_stat = rec>>8; regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff; m_stat = rec>>16; regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff; m_stat = rec>>24; regUDP->UDP_FDR[AT91C_EP_IN] = m_stat&0xff; kA++; }//if(!(regUDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY)) recA_1 = 0; //Если в буфер FIFO записано 12 слов по 5 байт = 60 байт, то отправляем if(kA==12) { regUDP->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY; kA=0;}
}//if(recA_1)
if(length == 0) //Если буфер, принятых по USB даных пуст { if((AT91C_BASE_UDP->UDP_ISR) & AT91C_UDP_EPINT2) //в буфере EP2 новые данные { if(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] & pCDC.currentRcvBank) { AT91F_disable_interrupt(); length = regUDP->UDP_CSR[AT91C_EP_OUT]>>16; //Считываем размер принятых по USB данных AT91F_enable_interrupt(); } }//if((AT91C_BASE_UDP->UDP_ISR) & AT91C_UDP_EPINT2) }
if(length != 0) //если буфер принятых по USB данных не пуст { if(jj==0) { unsigned int com = regUDP->UDP_FDR[AT91C_EP_OUT]; //считываем команду switch(com) { case 0x1 : {Turn_off(); break;} case 0x2 : {Turn_on(); break;} case 0x5 : {Reset(); break;} ... default: {length--;} }//switch }//if(jj == 0) if(length == 0) { AT91F_disable_interrupt(); Udp_ep_clr_flag(regUDP,AT91C_EP_OUT, pCDC.currentRcvBank); if(pCDC.currentRcvBank == AT91C_UDP_RX_DATA_BK0)pCDC.currentRcvBank = AT91C_UDP_RX_DATA_BK1; else pCDC.currentRcvBank = AT91C_UDP_RX_DATA_BK0; AT91C_BASE_UDP->UDP_ICR = 0xFFFFFFFF; AT91F_enable_interrupt(); } }// if(length != 0)
if(regUDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP) { AT91F_disable_interrupt(); regUDP->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP); AT91F_enable_interrupt(); }
}//while(1) }//main
По идее, по команде Turn off нужно сделать полный сброс процессора и периферии, но после этого контроллер не определяется приложением при повторном запуске. В приложении при закрытии все потоки завершаются и все хендлы закрываются. Такая ситуация возникает только в ситуации, когда буфер FIFO UDP не пуст. Видимо контроллер повисает во время работы модуля UDP, когда то передает данные на шину. Потому что где он может зависнуть в прошивке я не вижу.
|
|
|
|
|
Jun 24 2010, 13:23
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(aaarrr @ Jun 24 2010, 19:11)  Еще раз: какой механизм используется для "определения"? Почему его может сломать не пустой буфер UDP? Вы имеете в виду как открывается девайс в приложении? Вот код CODE HDEVINFO hDevInfo; GUID Nguid = {0xCCC207C0, 0x8CBD, 0x437A, { 0x97, 0xD1, 0xB5, 0x14, 0xF3, 0x50, 0x40, 0x40 } }; GUID *guid = &Nguid; hDevInfo = SetupDiGetClassDevs (guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); PSP_DEVICE_INTERFACE_DATA devInfoData = (PSP_DEVICE_INTERFACE_DATA)malloc(sizeof(SP_DEVICE_INTERFACE_DATA)); devInfoData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); BOOL en = 0; while(en == 0 ) en = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guid, 0, devInfoData); SetupDiGetDeviceInterfaceDetail(hDevInfo, devInfoData, NULL, 0, &requiredlength, NULL); PSP_DEVICE_INTERFACE_DETAIL_DATA DevInfoDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredlength); DevInfoDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); SetupDiGetInterfaceDeviceDetail (hDevInfo, devInfoData, DevInfoDetail, requiredlength, &requiredlength, NULL); TCHAR devNameOut[MAX_PATH]; strcpy( devNameOut, DevInfoDetail->DevicePath ); strcat( devNameOut, _T( "\\PIPE01" ) ); TCHAR devNameIn[MAX_PATH]; strcpy( devNameIn, DevInfoDetail->DevicePath ); strcat( devNameIn, _T( "\\PIPE00" ) ); PipeOut = CreateFile(devNameOut, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL,//FILE_FLAG_OVERLAPPED, NULL);
PipeIn = CreateFile(devNameIn, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL,//FILE_FLAG_OVERLAPPED, NULL);
Цитата(aaarrr @ Jun 24 2010, 19:11)  Выполняется ли отключение pull-up резистора на D+ при перезапуске контроллера? По команде Turn off, когда я пытаюсь сделать программный сброс? Нет, в этом случае отключение pull-up резистора не происходит.
|
|
|
|
|
Jun 24 2010, 13:40
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Bulat @ Jun 24 2010, 17:23)  Вы имеете в виду как открывается девайс в приложении? Я имею в виду механизм. На основании чего программа решает, что устройство не функционирует. Цитата(Bulat @ Jun 24 2010, 17:23)  По команде Turn off, когда я пытаюсь сделать программный сброс? Нет, в этом случае отключение pull-up резистора не происходит. Тогда естественно ничего функционировать не будет: МК будет ждать энумерации, а со стороны хоста отключение не зафиксируется.
|
|
|
|
|
Jun 24 2010, 13:53
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(aaarrr @ Jun 24 2010, 19:40)  Тогда естественно ничего функционировать не будет: МК будет ждать энумерации, а со стороны хоста отключение не зафиксируется. Мой девайс принимает данные от некого источника по определенному протоколу, обрабатывает эти данные и посылает их по USB на ПК. Так вот, если выключить этот "некий источник", то после перезапуска приложения девайс нормально определяется и позволяет возобновить работу, а если не отключать этот источник и перезапустить приложение, то девайс уже нереагирует не на какие команды от приложения. Поэтому я и подумал, что в первом случае приложение считает все данные из FIFO UDP девайса и после перезапуска продолжит нормально работать с девайсом и переподключение резистора не требуется в этом случае.
|
|
|
|
|
Jun 24 2010, 14:24
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(aaarrr @ Jun 24 2010, 20:01)  Три раза перечитал и ничего ровным счетом не понял. Откуда получается столь парадоксальный вывод про резистор? И как именно может помешать заполненное FIFO?
Вы пытаетесь сразу "решить" проблему, тогда как на самом деле она даже еще не локализована. Нарисовал структурную схему, чтобы было наглядно (см. прикрепленный файл). Изначально S1 замкнут и данные от источника данных передаются на мое устройство, а оттуда на ПК. Если сначало разомкнуть S1, а затем закрыть приложение (не отключаю USB-кабеля), а затем опять запустить приложение, то с устройством можно продолжать работать. То есть я резистор не отключал и приложение нормально повторно открыло драйвер и возобновило прием и передачу данных по USB. Если же S1 не размыкать и перезапустить приложение, то устройство перестает реагировать на запросы приложения.
Сообщение отредактировал Bulat - Jun 24 2010, 14:26
Эскизы прикрепленных изображений
|
|
|
|
|
Jun 24 2010, 14:46
|
Местный
  
Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241

|
Цитата(aaarrr @ Jun 24 2010, 20:27)  Сбрасывать процессор (и, соответственно, модуль UDP) без отключения резистора нельзя. а что вы посоветуете делать в моем случае, когда я не могу отключать подтягивающий резистор?
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|