AT90USB647. Не получается bulk передача. Ситуация следующая, написал код под ЮСБ контроллер AT90USB647, устройство нормально распознается, отвечат на все стандартные запрсы. Но при этом есть еще две конечные точки типа BULK_IN и BULK_OUT соответственно. Пытаюсь осуществить передачу или прием данных с них при помощи утилиты WinDriver и при помощи WinUSB драйвера. Происходит следующее, при попытки записать данны в точку Bulk_out, выдается ошибка, что устройство не отвечает, но при этом один раз пакет доставляется (вижу jtag отладчиком) на этом все, больше ничего записать в это точку ничего нельзя, так как просто не возникает прерывание. Тоже самое и при чтении из Bulk_IN, один раз получается прочитать пакет, а потом прерывание тоже не возникает и больше ничего читать не хочет. Отправляю специально 56 байт, а не 64, чтобы не дополнять пакетом-0й длинны, бо и без этого не могу разобратся...
Я бы согласился с ходу с тем, что я что-то не дописал и у меня где-то ошибки, еслиб не одно но! Если в дескрипторах конечных точек заменить Bulk на Interrup, и тоже самое сделать при инициализации в usb контроллере, то все работает змечательно в обоих направления. Поэтому нужна помощь, может естькакая-то особенность при работе с Bulk конечными точками. Ниже непосредственно привожу пример кода чтения и записи, а в архиве полностью весь проект под IAR. Отладку веду при помощи JTAGICEmkII.
Прерывание и чтение/запись с конечных точек:
//------------------------------------------------------------------------------
/*
* Обработка прерывания от USB (Конечная точка)
*/
#pragma vector = USB_Endpoint_Pipe_vect //Вектор перывания от USB конечной точки;
__interrupt void usb_endpoint_pipe_vect (void)
{
uint16 wRequest = 0;//Переменная с кодом запроса
//Если произошло прерывание от 0-й конечной точики
if (Usb_EPINT0())
{
//Выбираем 0-ю конечную точку
Usb_select_ep(0);
//Если прерывание вызвано пакетом SETUP
if(Usb_RXSTPI())
{
//Получаем пакет SETUP
user_usb_request.bmRequestType = Usb_read_fifo();//Тип запроса
user_usb_request.bRequest = Usb_read_fifo();//Код запроса
user_usb_request.wValue = Usb_read_fifo();//Параметр запроса
user_usb_request.wValue |= (Usb_read_fifo() << 8);
user_usb_request.wIndex = Usb_read_fifo();//Индекс смещения
user_usb_request.wIndex |= (Usb_read_fifo() << 8);
user_usb_request.wLength = Usb_read_fifo();//Число байт данных в передаче
user_usb_request.wLength |= (Usb_read_fifo() << 8);
//Сбрасываем флаги прерываний (указываем, что они обработаны)
Usb_clr_RXSTPI();
//Получаем полный код запроса
wRequest = user_usb_request.bmRequestType << 8;
wRequest |= user_usb_request.bRequest;
//Ищем обработчик запроса
switch (wRequest)
{
//Если спрашиваю дескриптор устройства
case GET_DESCRIPTOR_DEVICE:
usb_get_descriptor();
break;
//Если получили запрос установки адресса
case SET_ADDRESS:
usb_set_address();
break;
//Если получили запрос установки конфигурации
case SET_CONFIGURATION:
usb_set_configuration();
break;
//Если получили запрос статуса устройства
case GET_STATUS_DEVICE:
usb_get_status_device();
break;
//Если получили запрос статуса интерфейса
case GET_STATUS_INTERF:
usb_get_status_interface();
break;
//Если получили запрос статуса конечной точки
case GET_STATUS_ENDPNT:
usb_get_status_endpoint();
break;
//Если получили запрос CLEAR_FEATURE_ENDPNT
//case CLEAR_FEATURE_ENDPNT:
//usb_clear_feature_endpoint();
//break;
//Если код запрос неизвестный, то передаем STALL;
default:
STALL();
}
}
}
//Если произошло прерывание от 1-й конечной точики
if (Usb_EPINT1())
{
//Выбираем 1-ю конечную точку
Usb_select_ep(1);
//Если это прерывание по приему данных
if (Usb_RXOUTI())
{
//Подтверждаем прерывание;
Usb_clr_RXOUTI();
//Считываем данные из буффера
while(usb_cnt_byte_in_fifo())
{
//Читаем байт
wRequest = Usb_read_fifo();
if(wRequest == 0x0055)
{
wRequest = 0x00;
}
}
//Освобождаем банк;
Usb_clr_FIFOCON();
}
}
//Если произошло прерывание от 2-й конечной точики
if (Usb_EPINT2())
{
//Выбираем 2-ю конечную точку
Usb_select_ep(2);
//Если это прерывание по опустошению банка
if (Usb_TXINI())
{
//Подтверждаем прерывание(производим передачу);
Usb_clr_TXINI();
//Записываем данные в буффер
for (wRequest = 0; wRequest < 7; wRequest++)
{
Usb_write_fifo('V');
Usb_write_fifo('o');
Usb_write_fifo('s');
Usb_write_fifo('t');
Usb_write_fifo('o');
Usb_write_fifo('k');
Usb_write_fifo('-');
Usb_write_fifo(wRequest + 0x30);
}
//Освобождаем банк;
Usb_clr_FIFOCON();
}
}
}
//------------------------------------------------------------------------------
Вообщем выручайте кто знает или подозревает, а то уже неделю мучаюсь, незнаю что делать. Если найдем причину, то реализацию под AT90USB647 вылажу для всех желающих с понятными комментариями в хорошо читаемом коде, вообщем смотрим архив.