Перейти к содержанию
    

Как отправить управляющую передачу (control transfer) устройству USB?

Добрый день!

У меня есть микросхема XR21V1410, которая является мостом USB-UART. Согласно даташиту, она способна работать в обычном режиме (с 7, либо 8 информационными битами в символе UART), а также в расширенном режиме (wide mode), который поддерживает 9 информационных бит - 9N1. Согласно даташиту, для включения этого режима необходимо через USB сконфигурировать регистр UART CUSTOM REGISTER. А для этого нужно отправить команду XR_SET_REG.

Согласно спецификации устройств CDC-ACM, к которым причисляются мосты USB-UART, минимально необходимым набором поддерживаемых команд является SET_LINE_CODING, GET_LINE_CODING и SET_CONTROL_LINE_STATE. Первые две для отправки и приёма символов, последняя - для отправки в мост конфигурации (битрейт, количество стоп-битов наличие/отсутствие бита паритета).

Функции WinAPI для работы с мостами USB-UART прячут всё "под капот" - есть готовая функция SetCommState(), пользуйтесь ею, а про control transfer SET_CONTROL_LINE_STATE не думайте. Оно - хорошо, но как настроить на 9N1 мост XR21V1410?

Я погуглил и нашёл такой пример, где используется XR_SET_REG. В этом примере XR_SET_REG подсовывается в функцию usb_control_msg. Проблема в том, что пример написан для Линукса. Я начал гуглить, есть ли в WinAPI функция, аналогичная usb_control_msg. Все примеры вели к библиотеке libusb. И действительно, в файле libusb_dyn.c данной библиотеки я нашёл следующую реализацию функции usb_control_msg:

int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
                    int value, int index, char *bytes, int size,
                    int timeout)
{
    if (_usb_control_msg)
        return _usb_control_msg(dev, requesttype, request, value, index, bytes,
                                size, timeout);
    else
        return -ENOFILE;
}

Поискав по файлу, что же такое "_usb_control_msg" я нашёл это:

static usb_control_msg_t _usb_control_msg = NULL;

И, честно говоря, встал в тупик - как же именно на чистом WinAPI отправить control transfer мосту XR21V1410. Может быть кто-нибудь подскажет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, flammmable сказал:

И, честно говоря, встал в тупик - как же именно на чистом WinAPI отправить control transfer мосту XR21V1410. Может быть кто-нибудь подскажет?

Взять libusb/libusbK/winusb/etc., прописать .inf-файл устройству для работы через эту библиотеку и отправить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 4/14/2023 at 12:59 PM, jcxz said:

Взять libusb/libusbK/winusb/etc., прописать .inf-файл устройству для работы через эту библиотеку и отправить.

Как отправить управляющую передачу (control transfer) устройству USB на чистом WinAPI?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для Windows там же ставится драйвер от производителя, он и должен включить этот режим. Если в поле ByteSize структуры DCB установить 9, не работает?

https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-dcb

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 4/14/2023 at 3:41 PM, deni said:

Для Windows там же ставится драйвер от производителя, он и должен включить этот режим. Если в поле ByteSize структуры DCB установить 9, не работает?

https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-dcb

 

Как говорит даташит на XR21V1410

Quote

The transmitter can be configured for 7 or 8 data bits with or without parity or 9 data bits without parity.
If 9 bit data is selected without wide mode, the 9th bit will always be ’0’.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если драйвер от производителя не умеет этот режим включать, то скорее всего он и байт размером 9 бит не сможет передавать в устройство.

Цитата

The XR21V1410 device can be used with either a standard CDC-ACM driver or a custom driver. When the CDC-ACM driver is used, the driver has no capability to read or write the XR21V1410 device registers

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 4/14/2023 at 4:40 PM, deni said:

The XR21V1410 device can be used with either a standard CDC-ACM driver or a custom driver. When the CDC-ACM driver is used, the driver has no capability to read or write the XR21V1410 device registers

Я так понимаю, что под "standard CDC-ACM driver" подразумевается usbser.sys. Там есть вариант подключить к XR21V1410 внешнюю конфигурационную память и, как я это понимаю, можно залить в неё такую конфигурацию, что тип устройства XR21V1410 определиться не как MISC(так он определяется без внешней памяти и подхватывается драйвером MaxLinear), а как CDC-ACM. Соответственно, виндовыц usbser.sys может его подхватить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 минут назад, flammmable сказал:

Я так понимаю, что под "standard CDC-ACM driver" подразумевается usbser.sys. Там есть вариант подключить к XR21V1410 внешнюю конфигурационную память и, как я это понимаю, можно залить в неё такую конфигурацию, что тип устройства XR21V1410 определиться не как MISC(так он определяется без внешней памяти и подхватывается драйвером MaxLinear), а как CDC-ACM. Соответственно, виндовыц usbser.sys может его подхватить.

У меня нет такого устройства, но если поискать в интернете дамп USB дескрипторов этого USB-UART, там CDC-ACM, то usbser должен с ним работать

Изменено пользователем deni

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 4/14/2023 at 6:22 PM, deni said:

У меня нет такого устройства, но если поискать в интернете дамп USB дескрипторов этого USB-UART, там CDC-ACM, то usbser должен с ним работать

 

Я к тому, что у данного устройства два варианта работы: с драйвером usbser.sys и с драйвером производителя. И если используется драйвер производителя, то там возможен обычный режим и wide mode - расширенный режим. И в расширенном режиме возможна конфигурация символа 9N1. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если реально нужны 9 битные данные, т.е например адрес на шине устанавливается при 9 бите в 1 а данные идут при нуле ( есть такие протоколы) то единственное рабочее решение для USB- делать аппартаный враппер. Т.е устройство, которе видно на USB как КОМ порт, но данные не передаются на UART 1 к однмоу, а например по USB принимается пакет адресс, данные, Кс если надо в обычном 8 битном формате, а на UART выходит преобразованная информация, где 9 бит устанавливается - снимается там где надо. Обмен данными UART возможно надо делать по прерываниям и без FIFO т.к иначе установка 9 бита и данные могут рассинхронизироваться если 9 бит не идет в общем потоке данных, а устанавливается через отдельный регистр.

Имел когда то большие проблемы с заменой контроллера на USB в системе на базе Intel51 контроллеров, где 9 бит легко обратабывается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, khach сказал:

Если реально нужны 9 битные данные, т.е например адрес на шине устанавливается при 9 бите в 1 а данные идут при нуле ( есть такие протоколы) то единственное рабочее решение для USB- делать аппартаный враппер. Т.е устройство, которе видно на USB как КОМ порт, но данные не передаются на UART 1 к однмоу, а например по USB принимается пакет адресс, данные, Кс если надо в обычном 8 битном формате, а на UART выходит преобразованная информация, где 9 бит устанавливается - снимается там где надо.

Да, примерно так... Есть различные варианты реализации, в зависимости от используемого протокола. Вплоть, до режима, который используется в "кривом мосту" USB-COM, предложенном ТС... Все реализуется специальными конверторами, через стандартные преобразователи USB-COM... В частности, когда-то, для решения подобной проблемы, мне пришлось лишь заменить стандартную прошивку в повторителе RS485-RS485 на специализированную...
Но, ТС у нас легких путей не ищет. И продолжает трахаться с WinAPI и нестандартными драйверами.
Флаг ему в руки...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 часов назад, quark сказал:

ТС у нас легких путей не ищет. И продолжает трахаться с WinAPI и нестандартными драйверами.

Ну под WinAPI тоже можно это релизовать, но в одном случае- если 9 битовый режим использует 2 байтную передачу по USB на один 9-битный обмен и этот режим можно включить аппаратно, например прописав что то в конфигурационный еепром интерфейса. Тогда со стороны компа мы будет отправлять- принимать в 2 раза больше символов чем по последовательной шине и такой режим для WinAPI будет прозрачным.

Но хочу предупредить ТС- у меня была проблема в том, что FIFO после использования WinAPI клеило байты и высылало их друг за другом. А как оказалось приемникам на шине нужно было дать задержку между адресным байтом с установленным 9 битом и байтами данных хотя бы в пол- слова. Когда фирмварь клиентов отдизасмили оказалось, что прерывание приема адресного байта требует больше времени на реакцию. И эта грабля долго портила нам жизнь, т.к в описании протокола ничего про это не было сказано, осциллограф показывал нормальные датаграммы, а система вешалась в неопределенное состояние.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 часов назад, khach сказал:

Ну под WinAPI тоже можно это релизовать...

Но хочу предупредить ТС...

Собственный конвертор, для таких задач, во-первых, не требует специального моста USB-COM или специального драйвера к нему. Все работает по стандартным каналам, без каких-либо дополнительных настроек и других "костылей". Тем не менее, он позволяет, при необходимости, эмулировать любой специальный режим работы канала.
Во-вторых, если в ПО оконечного устройства обнаружатся какие-то "особенности" (по сути, ошибки), как в приведенном выше случае, то их легко можно обойти, модифицируя программу конвертора. Не факт, что это удастся сделать путем настройки нестандартного моста USB-COM или его нестандартного драйвера. Поэтому, даже добившись работоспособности вашего нестандартного оборудования, возможно, все равно, придете к необходимости конвертора. Так что, лучше сразу начать с него.
В-третьих, если делать конвертор, то стоит сразу реализовать полноценный конвертор протоколов. Выбрать для обмена с ПК какой-то более удобоваримый протокол - тот же MODBUS, например. Это позволит не тащить в  компьютер "кривые" 9-битные протоколы. Либо другие, зачастую, "самопальные" протоколы внешних устройств, с заранее неизвестными "особенностями".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 часов назад, quark сказал:

Выбрать для обмена с ПК какой-то более удобоваримый протокол - тот же MODBUS, например. Это позволит не тащить в  компьютер "кривые" 9-битные протоколы. 

ага - заменить одну кривулину на другую.  :vava:

Вот после таких советчиков и рождаются потом подобные темы....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

31 minutes ago, jcxz said:

ага - заменить одну кривулину на другую

Не кривых протоколов, кажется, вообще не бывает.

Но бывает, что кривизна протокола идеально соответствует кривизне софта и железа. 🙂

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...