Микроконтроллеры

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Микроконтроллеры » Архив » Подключение/отключение USB-устройства


Подключение/отключение USB-устройства

Сообщений 1 страница 30 из 47

1

Есть USB HID устройство, сделанное "по мотивам" описанного здесь  "USB в STM32F0" (https://mcu.goodboard.ru/viewtopic.php?id=68). Сделано на F072, питается от собственного источника, VBUS заведен на одну из ног и отслеживается программой. Код уважаемого sobs работает на ура, но есть проблема с выниманием/втыканием кабеля. Первое втыкание после включения питания (либо включение питание со вставленным кабелем) происходит успешно - устройство определилось, данные пошли, а вот повторные "фокусы" уже не проходят - в диспетчере Unknown device, в системном трее "устройство не опознано" (система Win7 64). Пробовал

Код:
 	USB->CNTR = USB_CNTR_FRES;
	USB->CNTR = USB_CNTR_PWDN|USB_CNTR_FRES;
	USB->BCDR = 0;

а после появления VBUS - повторный USB_Init(), пробовал вообще ничего не делать (в надежде на прерывание RESET после повторного подключения), но результат всегда один, впору хоть системный Reset делать  :angry: , но это в моем случае не вариант. Что я делаю не так и как надо правильно? Буду признателен за любые полезные советы или ссылки, проверю на железе любые предположения.

2

Я тоже на основе его кода делал HID.
Там главное - прерывания обработать. Но у меня вроде код sobs'а почти один-в-один. И работает без проблем...
Может ты где-то опечатку сделал?
Как только получаем USB_ISTR_RESET, сбрасываем инициализацию всех точек и инициализируем EP0.
Проверь: у тебя вообще вход в это прерывание после переподключения кабеля есть?

3

Eddy_Em написал(а):

Но у меня вроде код sobs'а почти один-в-один. И работает без проблем...
Может ты где-то опечатку сделал?

Так и у меня практически один-в-один, и тоже работает пока кабель не выдернешь.

Eddy_Em написал(а):

Как только получаем USB_ISTR_RESET, сбрасываем инициализацию всех точек и инициализируем EP0.

Так вроде бы USB_ISTR_RESET в USB_IRQHandler() уже обрабатывается. Или при отключении кабеля надо дополнительно что-то сбрасывать?

Eddy_Em написал(а):

Проверь: у тебя вообще вход в это прерывание после переподключения кабеля есть?

Я решил, что если обмен идет, то прерывания точно работают... Сейчас "отладочными" выводами пошевелю и осциллографом гляну.

4

Eddy_Em написал(а):

Как только получаем USB_ISTR_RESET, сбрасываем инициализацию всех точек и инициализируем EP0.

И точно так же как у GaryK с внешним питанием работать не будет
Вы бы вместо того чтоб копипастить друг у друга лучше б рм читали или хотя бы мой опус про usb и-фейс

5

Ну, не знаю... А почему у меня работает с внешним питанием?
Вот, только что проверил контроллер термодатчиков:

Код:
[2130186.587996] usb 1-1: new full-speed USB device number 25 using xhci_hcd
[2130186.715250] usb 1-1: New USB device found, idVendor=067b, idProduct=2303
[2130186.715251] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[2130186.715252] usb 1-1: Product: USB-Serial Controller
[2130186.715252] usb 1-1: Manufacturer: Prolific Technology Inc.
[2130186.715682] pl2303 1-1:1.0: pl2303 converter detected
[2130186.716636] usb 1-1: pl2303 converter now attached to ttyUSB0
[2130200.844714] usb 1-1: USB disconnect, device number 25
[2130200.844822] pl2303 ttyUSB0: pl2303 converter now disconnected from ttyUSB0
[2130200.844830] pl2303 1-1:1.0: device disconnected
[2130205.177278] usb 1-1: new full-speed USB device number 26 using xhci_hcd
[2130205.304114] usb 1-1: New USB device found, idVendor=067b, idProduct=2303
[2130205.304115] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[2130205.304115] usb 1-1: Product: USB-Serial Controller
[2130205.304116] usb 1-1: Manufacturer: Prolific Technology Inc.
[2130205.304572] pl2303 1-1:1.0: pl2303 converter detected
[2130205.305449] usb 1-1: pl2303 converter now attached to ttyUSB0

Питается от внешнего источника, а я тупо втыкаю/вытыкаю шнурок. Все нормально работает. Исходники у меня на гитхабе (tsys01)

6

Eddy_Em написал(а):

Ну, не знаю... А почему у меня работает с внешним питанием?

Да потому что на самом деле ты делаешь не так как пишешь
[с помощью костыля под названием usb_proc] )

7

Это - не костыль! Просто нет необходимости в прерывании вызывать длинные функции инициализации. Поэтому я просто выставляю флаг, а уже потом эти функции вызываю. Да и инициализацию надо производить уже после стадии конфигурирования.
Так что, все правильно сделано же!

8

Да ладно, чем больше магии, тем больше магов )
Скажи лучше, ты как к stm32f070 относишься?

GaryK, все регистры epnr сбрасываются по usb-ресету и их все [а не только ep0r] надо снова выставлять так или иначе

9

F070 не пробовал. Есть у меня F072 — те же F042. Я особо не вчитывался в даташит, чтобы разницу понять. По цене как-то 072 дешевле...

10

vt написал(а):

Вы бы вместо того чтоб копипастить друг у друга лучше б рм читали или хотя бы мой опус про usb и-фейс

С удовольствием прочту сей опус если подскажете где искать. Тема "USB интерфейс в STM32F103" - это оно?

Отредактировано GaryK (2019-10-10 08:49:22)

11

vt написал(а):

Да ладно, чем больше магии, тем больше магов )
GaryK, все регистры epnr сбрасываются по usb-ресету и их все [а не только ep0r] надо снова выставлять так или иначе

Я с USB только начинаю работать, поэтому мне нужно все объяснять чуть подробнее  8-) . Я периодически (раз в 3.3 мс) отслеживаю VBus. Надо ли мне по факту пропадания VBus что-то делать (сбрасывать/выключать USB-модуль или отключать подтяжку линии)? Что мне делать после появления VBus обратно (какие регистры сбрасывать/инитить и т.д.)?

12

GaryK написал(а):

все объяснять

Прочитай статью sobs про usb на cxem.net или мой топик про usb и-фейс здесь

13

vt написал(а):

Прочитай статью sobs про usb на cxem.net или мой топик про usb и-фейс здесь

Так по статье sobs и его здешней теме "USB в STM32F0" я все и сделал. А топик про usb и-фейс - это "USB интерфейс в STM32F103"?

14

Прочел тему "USB интерфейс в STM32F103" (информационную часть) и составил себе следующую картину:
При выдергивании кабеля хост не видит подтяжки линии данных и отключает устройство. При повторном втыкании кабеля хост начинает заново процедуру подключения и выдает на шину RESET, по которому "все регистры EPnR автоматически сбрасываются", а в библиотеке sobs'а (usb_lib.c) в прерывании по RESET настраивается нулевая точка:

Код:
	if(USB->ISTR & USB_ISTR_RESET) {
    // Переинициализируем регистры
    USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
    USB->ISTR = 0;

    // Создаем 0 конечную точку, типа CONTROL
    EP_Init(0, EP_TYPE_CONTROL, 128, 256, Enumerate_Handler);

    // Обнуляем адрес устройства
    USB->DADDR = USB_DADDR_EF;

    // Присваиваем состояние в DEFAULT (ожидание энумерации)
    USB_Dev.USB_Status = USB_DEFAULT_STATE;
	}

после чего достаточно сделать (из примера stm32f0_usb_hid_termo):

Код:
	while (USB_GetState() != USB_CONFIGURE_STATE);
	EP_Init(1, EP_TYPE_INTERRUPT, 384, 512, EP1_Handler);

и все должно быть "в ажуре".

Я все правильно понял или чего-то не учел?

15

Ну так проверь теперь на практике правильно ли ты всё понял и так ли у тебя всё это в реальности работает

16

vt написал(а):

Ну так проверь теперь на практике правильно ли ты всё понял и так ли у тебя всё это в реальности работает

Увы, при повторном включении: "Устройство не опознано".

17

GaryK, ты точно EP1 инициализируешь в уже сконфигурированном состоянии? Потому что когда я ковырялся методом тыка в этом коде, инициализация концевых точек до процесса конфигурации иной раз вообще к зависанию приводила... Хотя, это могло быть вызвано и другими косяками.

Кстати, никто не снимал случаем дамп с "оригинального" PL2303? А то что-то моя подделка китайского не очень хорошо работает. А последнее время перестала работать в андроиде (подозреваю, что гугол раскурочил линуксовый модуль PL2303 под "оригинальные" PL2303, чтобы оно с китайскими подделками не работало).
Похоже, придется-таки делать стандартный CDC ACM, как она ни плакала...

18

vt, ты в своем опусе пишешь:
"FRES - запись нуля ресетит USB-контроллер, единицу после этого записывать не надо, контроллер сделает это сам",

а Referens Manual (и на F103 и на F072) говорят нам:
"Bit 0 FRES: Force USB Reset
0: Clear USB reset.
1: Force a reset of the USB peripheral, exactly like a RESET signalling on the USB. The
USB peripheral is held in RESET state until software clears this bit. A “USB-RESET”
interrupt is generated, if enabled."

или по-нашему:
"Bit 0 FRES: Принудительный сброс USB
0: Отключить USB-сброс.
1: Принудительный сброс периферии USB, аналогично сигналу RESET на USB-шине. Периферия USB удерживается в состоянии RESET, до программного сброса этого бита. Прерывание «USB-RESET» генерируется, если разрешено."

У кого-то из вас ошибка.

19

Eddy_Em написал(а):

GaryK, ты точно EP1 инициализируешь в уже сконфигурированном состоянии?

Кусок кода:

Код:
while (USB_GetState() != USB_CONFIGURE_STATE);
EP_Init(1, EP_TYPE_INTERRUPT, 384, 512, EP1_Handler);

Как бы обещает нам это.

20

Сегодня меня нагрузили другими задачами (на столе другая железка), а завтра вернусь к USB, подключу осциллограф и буду твердо уверен, что тот или иной кусок софта сработал.

21

GaryK написал(а):

У кого-то из вас ошибка.

Исправил, спасибо
Удивительно, что это всплыло только через два года

22

vt написал(а):

Исправил, спасибо

Не за что.

vt написал(а):

Удивительно, что это всплыло только через два года

Лучше поздно, чем никогда. (с) народное.

23

Eddy_Em написал(а):

F070 не пробовал. Есть у меня F072 — те же F042. Я особо не вчитывался в даташит, чтобы разницу понять.

У f070 общий рм с f030, а f030 по факту народный мк номер два после f103
То что там якобы кварц для usb нужен - фигня, и без кварца нормально, как и f103
И вот я думаю - не зайти ли тут на второй круг с stm32, но не растекаясь, а только с одними f0x0

24

А я хочу всецело на STM32F0x2 перейти: мне очень нравится, что там CAN одновременно с USB работает. Теперь не нужно будет извраты всякие с UART устраивать, чтобы несколько устройств на одну шину воткнуть. Давно уже назрел вопрос изготовления драйверов ШД, которые "подключил - и работай". Задолбался уже под каждый прибор (где непременно есть шаговики) индивидуальную систему управления всякий раз лепить. А так - один МК с одним ШД, энкодером и несколькими концевиками в легкую справится... Цепляем USB к любому драйверу на шине и управляем всеми.

P.S. Глянул на сайте ST таблички на F070, F072 и F042. На али они все одинаково стоят. Однако, у F070 нет CAN. Конечно, по количеству таймеров он круче 042. Но, скажем, у 072 есть 7 каналов ПДП (супротив 5 для остальных), есть ЦАП и аналоговый компаратор. Ну и тач-сенсоры у 0x2 есть (мне, правда, они не нужны как-то).

25

Про f0x2 весомые аргументы конечно, а главное, что ты их уже реально используешь
К тому же jlink есть на f072
Надо подумать )

26

У 070 USB только от 64 ног и выше. А как по мне так F0 все одинаковые. Переделывал пример Досикуса под F0 для L0 так все работает 1 в 1, только различия в начальной инициализации и не получилось работать от RC, т.к. у меня все-равно кварц не разбирался особо. Да и блюпил с F103c8 легко переделать под F072с8, это тоже в пользу 072) Если что есть f030, f070, f072. мб смогу немного поучаствовать.

27

MasterElectric написал(а):

У 070 USB только от 64 ног и выше.

Выше некуда )
Во всех корпусах есть usb
http://s3.uploads.ru/5si2u.png

28

Все прояснилось. В библиотеке sobs'а в обработчике прерывания USB_ISTR_RESET:

Код:
	if(USB->ISTR & USB_ISTR_RESET) {
    // Переинициализируем регистры
    USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
    USB->ISTR = 0;

    // Создаем 0 конечную точку, типа CONTROL
    EP_Init(0, EP_TYPE_CONTROL, 128, 256, Enumerate_Handler);

    // Обнуляем адрес устройства
    USB->DADDR = USB_DADDR_EF;

    // Присваиваем состояние в DEFAULT (ожидание энумерации)
    USB_Dev.USB_Status = USB_DEFAULT_STATE;
	}

достаточно добавить одну строку:

Код:
    USB_Dev.USB_Addr   = 0;

и все встает на свои места и начинает исправно работать.
После сброса чипа все поля USB_Dev инициализируются нулями, поэтому при питании от шины все работает. А вот для самопитаемых устройств после передергивания кабеля приходится обнулять вручную, так как далее "по ходу пьесы" это значение используется в конфигураторе устройства.

Код:
    // Если полученный от хоста адрес не совпадает с адресом устройства
    if((USB->DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr) {
    	// Присваиваем новый адрес устройству
    	USB->DADDR = USB_DADDR_EF | USB_Dev.USB_Addr;

    	// Устанавливаем состояние в "Адресованно"
    	USB_Dev.USB_Status = USB_ADRESSED_STATE;
    }

Всем откликнувшимся большое спасибо за участие. Вопрос закрыт.

Отредактировано GaryK (2019-10-16 10:55:21)

29

Странно как-то: а у меня без обнуления USB_Dev.USB_Addr работает. Даже на игровых приставках...
Хотя, конечно, ты прав: надо это обнулять, а то мало ли...

30

Всю эту хрень с самопридуманными флажками [как я понимаю ноги растут от st-шной spl] по-хорошему надо бы выкинуть, а не тиражировать
Есть стандартный автомат control транзакций - setup-data-status stages, подробно пересказанный Axelson в её книжке про usb и разжёванный до манной каши в http://www.usbmadesimple.co.uk/


Вы здесь » Микроконтроллеры » Архив » Подключение/отключение USB-устройства