Вот архив, если кому интересно:
Нажмите для просмотра прикрепленного файла
Так вот, в некоторых местах кода озадачила обработка нештатных ситуаций и ошибок при проверке данных на уровне класса MSC.
К примеру, часто встречающаяся последовательность:
Код
USB_SetStallEP(MSC_EP_IN);
USB_SetStallEP(MSC_EP_OUT);
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
USB_SetStallEP(MSC_EP_OUT);
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
то есть устанавливаются флаги STALL для обоих конечных точек bulk, а затем подготавливаются данные статуса CSW для последующей отправки хосту. Вроде всё правильно.
Но! Функция MSC_SetCSW() вызывает WriteEP, которая копирует данные в SRAM буфер конечной точки и затем перезаписывает её статус как VALID, то есть записанный перед этим STALL совершенно затирается!
Ну не бред ли??
В результате получится вместо STALL обычный ACK, данные статуса CSW уйдут как обычный пакет данных... что будет дальше, можно уже не разбираться - просто хаос...
В основном код написан вроде бы правильно, с верной обработкой протокола, но вот это место ставит меня в тупик - может быть я тут что-то недопонимаю?
Всё таки первый раз имею дело с USB и MSC...
Ещё хотел спросить - каким образом хост определяет конец фазы передачи данных в режиме Mass Storage?
Если последний пакет данных будет меньше максимально допустимого для данной конечной точки?
Или как-то по другому?
А то сижу сейчас и думаю, как мне обрабатывать неподдерживаемые моим девайсом SCSI команды.
К примеру, приходит CBW с какой нибудь SCSI_MODE_SELECT10, по идее я должен обработать фазу передачи данных для этой команды (если она есть), и уже затем отправить CSW с флагом CSW_CMD_FAILED.
То есть, если фаза данных будет состоять из 1000 байт, будет ли хост слать IN пакеты, пока не будут переданы все 1000 байт, или передача прекратится на первом же пакете нулевой (или любой другой, меньшей MAX_PACKET_SIZE) длины?