Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC1820, проблема с USB Mass Storage
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Harvester
Добрый день.
Имеется устройство на LPC1820 + eMMC.
Устройство представляет собой USB Mass Storage Device ("флешка"), реализованное с использованием фирменной библиотеки LPCUSBlib (чисто программный вариант, без использования функций USB ROM).
Проблема в следующем: часть плат некорректно работают при размере конечных точек больше 128 байт. Некорректность заключается в том, что устройства, судя по снифферу, в какой-то момент перестают отвечать на USB-запросы чтения/записи. Причем этот момент может отличаться для разных устройств, но для каждого конкретного устройства он фиксирован (т.е. одни устройства "виснут" на первой же команде чтения, другие обрабатывают команду чтения нормально, но "виснут" при записи).

Программист, написавший программу, утверждал, что это недокументированный баг в контроллере, который компания NXP не хочет признавать. И указывал на строки, имеющиеся в исходниках использованной им версии библиотеки LPCUSBLib:
Код
/* Max In/Out Packet Size */
#define MSC_FS_MAX_PACKET  128
#define MSC_HS_MAX_PACKET  128 /* < 256 work */

У меня стоит задача реализовать работу со штатным размером EP (512 байт). Я взял последнюю версию библиотеки - проблема не ушла.
Понятно, что теперь мне только остается детально исследовать работу библиотеки и модуля USB - может это все-таки программная бяка?
Но вдруг кто-нибудь сталкивался с подобной ситуацией и решил ее? laughing.gif
Спасибо.
jcxz
Цитата(Harvester @ Aug 24 2016, 22:15) *
Программист, написавший программу, утверждал, что это недокументированный баг в контроллере, который компания NXP не хочет признавать. И указывал на строки, имеющиеся в исходниках использованной им версии библиотеки LPCUSBLib:
Код
/* Max In/Out Packet Size */
#define MSC_FS_MAX_PACKET  128
#define MSC_HS_MAX_PACKET  128 /* < 256 work */

Интересно каким образом эти строки говорят о баге в контроллере??? wacko.gif
Баг определённо в вашем программисте. Так как другие программисты работают с этими контроллерами и не жужжат. wink.gif
На LPC17xx и LPC43xx делал много проектов с USB. Нигде с багами контроллера не сталкивался. Сомневаюсь, что в LPC18xx USB-периферия хуже чем в других семействах LPC.
Я всегда использовал для них USB-стеки из примеров IAR. Использовал bulk- и изохронные передачи - никаких проблем.
Да и определитесь вначале хотя-бы где точно у Вас проблема - с обменом по USB (контроллер там явно не при чём) или с чтением/записью eMMC.
Можно например сделать буфер в ОЗУ вместо eMMC и поработать с ним как с USB-диском.
Либо поработать напрямую с эндпоинтами - погонять данные в них / из них. Без MassStorage. Убедиться в корректности передач с разными размерами.
Harvester
Цитата(jcxz @ Aug 24 2016, 20:23) *
Баг определённо в вашем программисте. Так как другие программисты работают с этими контроллерами и не жужжат. wink.gif

Ну, я как бы тоже больше доверяю NXP, поэтому и решил попробовать исправить ситуацию. sm.gif
Цитата(jcxz @ Aug 24 2016, 20:23) *
Да и определитесь вначале хотя-бы где точно у Вас проблема - с обменом по USB (контроллер там явно не при чём) или с чтением/записью eMMC.

Проблема где-то в обработчике USB - при появлении проблемного запроса callback-функция обработки SCSI-команд не вызывается.
Цитата(jcxz @ Aug 24 2016, 20:23) *
Я всегда использовал для них USB-стеки из примеров IAR. Использовал bulk- и изохронные передачи - никаких проблем.

Спасибо за подсказку, попробую.
Цитата(jcxz @ Aug 24 2016, 20:23) *
Либо поработать напрямую с эндпоинтами - погонять данные в них / из них. Без MassStorage. Убедиться в корректности передач с разными размерами.

А как это сделать? Особенно со стороны ПК.

P.S. Посмотрел примеры IAR - именно этот стек и использовался предыдущим программистом. Файл mscuser.h:
Код
/* Max In/Out Packet Size */
#define MSC_FS_MAX_PACKET  64
#define MSC_HS_MAX_PACKET  224 /* < 256 work */

А Вы точно использовали bulk-передачи с размером конечной точки 512 байт? laughing.gif
GetSmart
Можно сделать хост на другом микроконтроллере (для тестирования девайса на LPC18xx на уровне эндпоинтов USB).

Контроллер USB в LPC18xx скорее всего похож на LPC43xx, но не похож на LPC17xx.
Kabdim
Скорее косяки в библиотеках NXP - они ужасно кривые. Кстати LPCUSBlib уже давным давно deprecated. А стек засунут в USBROM и LPCOpen умеет использовать только его.

Цитата(Harvester @ Aug 24 2016, 20:54) *
А как это сделать? Особенно со стороны ПК.

Берем генертор псевдослучайных чисел. Сид в программе и проишвке один. Итоговая последовательность там и тут должна совпадать. В контроллере что-то делаем с полученными данными, например xor и отправляем назад. В программе проверяем что посчитанное и полученное одно и тоже.
Harvester
Цитата(Kabdim @ Aug 25 2016, 10:09) *
Скорее косяки в библиотеках NXP - они ужасно кривые. Кстати LPCUSBlib уже давным давно deprecated. А стек засунут в USBROM и LPCOpen умеет использовать только его.

Мне кажется, Вы не совсем правы. В библиотеке есть выбор - использовать ROM или программный вариант.
Цитата(Kabdim @ Aug 25 2016, 10:09) *
Берем генертор псевдослучайных чисел. Сид в программе и проишвке один. Итоговая последовательность там и тут должна совпадать. В контроллере что-то делаем с полученными данными, например xor и отправляем назад. В программе проверяем что посчитанное и полученное одно и тоже.

Ну, методов проверки можно много придумать, весь вопрос - как это сделать? Т.е. как работать на ПК с конечными точками USB без использования стандартных классов.

Цитата(GetSmart @ Aug 25 2016, 09:49) *
Контроллер USB в LPC18xx скорее всего похож на LPC43xx, но не похож на LPC17xx.

Именно. Поэтому мне интересно - делал ли кто-нибудь Mass Storage с EP=512байт именно на LPC18xx.

Одно дело, если бы программа просто не работала. Но она же не работает только на части плат!
Беру за основу пример от NXP для отладочной платы с LPC1830 и SD-картой - там работает.
Переписал под отладку для своего устройства - работает.
Зашил в готовое изделие - работает.
Отдал на тестирование, там прошили 10 устройств - 5 работает, 5 нет. Причем не работают по-разному! wacko.gif
Kabdim
Цитата(Harvester @ Aug 25 2016, 10:39) *
Мне кажется, Вы не совсем правы. В библиотеке есть выбор - использовать ROM или программный вариант.

Не укажите где именно в LPCOpen есть возможность такой настройки?
Цитата(Harvester @ Aug 25 2016, 10:39) *
Ну, методов проверки можно много придумать, весь вопрос - как это сделать? Т.е. как работать на ПК с конечными точками USB без использования стандартных классов.

Нужно сделать *.inf для конкретного вида/пида с драйвером winusb(k). И работать WinUsb_*.
Цитата(Harvester @ Aug 25 2016, 10:39) *
Одно дело, если бы программа просто не работала. Но она же не работает только на части плат!
Беру за основу пример от NXP для отладочной платы с LPC1830 и SD-картой - там работает.
Переписал под отладку для своего устройства - работает.
Зашил в готовое изделие - работает.
Отдал на тестирование, там прошили 10 устройств - 5 работает, 5 нет. Причем не работают по-разному! wacko.gif

Глюк забавный, неужто нет возможности взять устройство которое не работает и посмотреть что происоходит под отладкой?
jcxz
Цитата(Harvester @ Aug 25 2016, 13:39) *
Ну, методов проверки можно много придумать, весь вопрос - как это сделать? Т.е. как работать на ПК с конечными точками USB без использования стандартных классов.

Есть драйвера (под винду) позволяющие работать с эндпоинтами с уровня приложения. Я использую один из таких: CypressUSB (из состава "Cypress Suite USB"). Есть ещё libusb.
Как Вам уже объяснили: делаете inf-файл с нужными VID/PID для этого драйвера и дальше работаете через него (т.е. - через его библиотеку).
Даже можно и не писать ничего со стороны ПК: в составе "Cypress Suite USB" есть утилитки, позволяющие передавать кадры произвольных данных через нужные эндпоинты. Либо в окошке их набираете либо из файла.

Цитата(Harvester @ Aug 25 2016, 13:39) *
Одно дело, если бы программа просто не работала. Но она же не работает только на части плат!
Беру за основу пример от NXP для отладочной платы с LPC1830 и SD-картой - там работает.

Всё-таки: почему Вы подозреваете именно USB, а не работу с eMMC?

Цитата(Harvester @ Aug 24 2016, 23:54) *
А Вы точно использовали bulk-передачи с размером конечной точки 512 байт? laughing.gif

Цитата(GetSmart @ Aug 25 2016, 12:49) *
Контроллер USB в LPC18xx скорее всего похож на LPC43xx, но не похож на LPC17xx.

В LPC43xx именно bulk-передачи не использовал. Только control-передачи. Но с размером кадра до 2048 байт (разные размеры пробовал).
Harvester
Цитата(Kabdim @ Aug 25 2016, 11:12) *
Не укажите где именно в LPCOpen есть возможность такой настройки?
Файл LPCUSBlibConfig.h, дефайн USE_USB_ROM_STACK
Цитата(Kabdim @ Aug 25 2016, 11:12) *
Нужно сделать *.inf для конкретного вида/пида с драйвером winusb(k). И работать WinUsb_*.
Спасибо, буду смотреть
Цитата(Kabdim @ Aug 25 2016, 11:12) *
Глюк забавный, неужто нет возможности взять устройство которое не работает и посмотреть что происходит под отладкой?
Здесь две проблемы:
1. МК в BGA-корпусе, JTAG не выведен. Т.е. подключаться надо к via под МК. Но это, в общем-то решаемо.
2. В готовом изделии запрограммированы OTP-биты. Т.е. сначала из SPI-флеши считывается загрузчик, который уже загружает мою программу по нужному адресу ОЗУ. Честно говоря, не знаю, получится ли при таком сценарии подключиться отладчиком.
jcxz
Цитата(Harvester @ Aug 25 2016, 15:17) *
2. В готовом изделии запрограммированы OTP-биты. Т.е. сначала из SPI-флеши считывается загрузчик, который уже загружает мою программу по нужному адресу ОЗУ. Честно говоря, не знаю, получится ли при таком сценарии подключиться отладчиком.

Если в OTP JTAG не запрещён и если firmware сразу после старта не запрещает JTAG через спец. регистры периферии - получится.
У меня сейчас на LPC4370 именно так и работает. JTAG подключается без проблем, хоть есть прошивка в SPI-флеши, хоть код BootROM работает - без разницы.
Если всё-же будут проблемы, то boot-пинами или в OTP переключитесь на загрузку не с флешки, а с чего-нить другого.
Harvester
Цитата(jcxz @ Aug 25 2016, 12:09) *
Есть драйвера (под винду) позволяющие работать с эндпоинтами с уровня приложения. Я использую один из таких: CypressUSB (из состава "Cypress Suite USB"). Есть ещё libusb.
Как Вам уже объяснили: делаете inf-файл с нужными VID/PID для этого драйвера и дальше работаете через него (т.е. - через его библиотеку).
Даже можно и не писать ничего со стороны ПК: в составе "Cypress Suite USB" есть утилитки, позволяющие передавать кадры произвольных данных через нужные эндпоинты. Либо в окошке их набираете либо из файла.

Спасибо
Цитата(jcxz @ Aug 25 2016, 12:09) *
Всё-таки: почему Вы подозреваете именно USB, а не работу с eMMC?

1. Проблема исчезает при задании в дескрипторе размера EP=128 байт. Эта величина влияет исключительно на работу модуля USB.
2. Я сделал отладочный вывод в callback-функции обработки SCSI-команд, которая вызывается ядром USB. И в проблемном месте вывод информации не происходит. Т.е. до обработки команды (чтения/записи eMMC) дело даже не доходит.



Цитата(jcxz @ Aug 25 2016, 12:30) *
Если в OTP JTAG не запрещён и если firmware сразу после старта не запрещает JTAG через спец. регистры периферии - получится.
У меня сейчас на LPC4370 именно так и работает. JTAG подключается без проблем, хоть есть прошивка в SPI-флеши, хоть код BootROM работает - без разницы.

Спасибо, буду изучать.
Только что посмотрел - программируются только BOOT-биты. Так что надежда есть sm.gif
Kabdim
Цитата(Harvester @ Aug 25 2016, 12:17) *
Файл LPCUSBlibConfig.h, дефайн USE_USB_ROM_STACK

Вы про LPCUSBlib, я про LPCOpen.
Цитата(Harvester @ Aug 25 2016, 12:17) *
1. МК в BGA-корпусе, JTAG не выведен. Т.е. подключаться надо к via под МК. Но это, в общем-то решаемо.

Это вы себе здорово в ногу выстрелили. Кмк выводить отладку хоть как-то нужно везде. Даже если она в устройстве будет отключаться.
Harvester
Цитата(Kabdim @ Aug 25 2016, 12:54) *
Вы про LPCUSBlib, я про LPCOpen.

Ну так LPCUSBLib - стек USB, используемый в LPCOpen.
Как я понимаю, сначала была библиотека NXPUSB. Потом ее улучшили, обозвали LPCUSBLib и включили в состав LPCOpen.
Цитата(Kabdim @ Aug 25 2016, 12:54) *
Это вы себе здорово в ногу выстрелили. Кмк выводить отладку хоть как-то нужно везде. Даже если она в устройстве будет отключаться.

Я это понимаю. Но в данном случае все случилось задолго до моего появления. laughing.gif
Kabdim
Цитата(Harvester @ Aug 25 2016, 13:01) *
Ну так LPCUSBLib - стек USB, используемый в LPCOpen.
Как я понимаю, сначала была библиотека NXPUSB. Потом ее улучшили, обозвали LPCUSBLib и включили в состав LPCOpen

Следующим шагом вырезали из получившегося вариант использования без USB ROM'а.
Harvester
Цитата(Kabdim @ Aug 25 2016, 13:19) *
Следующим шагом вырезали из получившегося вариант использования без USB ROM'а.

Уговорили. :D Попробую еще раз воспользоваться ROM API.
GetSmart
Заодо сравните версию ботлоадера у рабочих и глючных процессоров.

Вообще, имея глючную плату нужно на ней проводить опыты. Чтобы вероятность ухватывания бага за хвост была максимальной. Обычно это делается удалением из проекта всего кода, выше BBB (MSC-SCSI). Тест только USB-стека и даже на чтение-запись секторов ставится пустышка.

Для чистоты эксперимента лучше иметь не один компьютерный HS-хост, а ещё на микроконтроллере.

Теоретически, бага в LPC для длинных пакетов может быть при отсутствии в нём (или кривом) USB-ФАПЧ (не USB-PLL). Тогда немного отличающиеся клоки хоста и девайса (или болтанка) будут ограничивать длину безошибочно принимаемых пакетов. Или может быть какой-то баг PLL. Я в LPC43xx видел странность, когда флаг стабилизации PLL постоянно устанавливался и сбрасывался при вполне допустимом диапазоне частоты. Иногда вообще не устанавливался, но клок был. Чистоту спектра не измерял никогда.
jcxz
Цитата(GetSmart @ Aug 25 2016, 20:40) *
Я в LPC43xx видел странность, когда флаг стабилизации PLL постоянно устанавливался и сбрасывался при вполне допустимом диапазоне частоты. Иногда вообще не устанавливался, но клок был. Чистоту спектра не измерял никогда.

Я в LPC43xx после старта PLL, больше на его флаги не смотрю. Хотя наверное нужно сделать ISR. Но пока проблем в работе не наблюдается, а работаю давно и на разных частотах.
Для USB использую CGU.PLL0USB.
Harvester
Цитата(GetSmart @ Aug 25 2016, 17:40) *
Вообще, имея глючную плату нужно на ней проводить опыты. Чтобы вероятность ухватывания бага за хвост была максимальной. Обычно это делается удалением из проекта всего кода, выше BBB (MSC-SCSI). Тест только USB-стека и даже на чтение-запись секторов ставится пустышка.

С горем пополам подпаял к нерабочей плате JTAG. А она взяла и заработала, даже без отладчика. laughing.gif
Проверил 4 другие имеющиеся нерабочие платы - две работают, как ни в чем не бывало. wacko.gif
Мистика какая-то.
Alechek
Видимо, все-таки дело в частоте USB.. Точнее, в ее погрешности.
jcxz
Цитата(Alechek @ Aug 26 2016, 16:37) *
Видимо, все-таки дело в частоте USB.. Точнее, в ее погрешности.

Тогда попробовать затактировать не от кварца, а от генератора.
Harvester
Цитата(jcxz @ Aug 26 2016, 14:31) *
Тогда попробовать затактировать не от кварца, а от генератора.

Увы, вход GP_CLKIN не выведен на плате crying.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.