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

Полноценный адаптер USB-Serial с 3 UART портами на STM32 Blue Pill

Доброго времени суток,

хотел поделиться своим проектом 3-x портового USB-Serial адаптера для STM32 Blue Pill (STM32F103C8T6).

Зачем все это, есть же куча USB-Serial преобразователей на любой вкус? Во-первых, это дешево. Плата Blue Pill стоит на али порядка 120 руб. Во-вторых, много портов в одном USB устройстве. Не занимаются лишние USB порты, нет нужды использовать USB-хабы. В-третьих, реализованы управляющие сигналы, не каждый USB-Serial преобразователь это умеет. В-четвертых, это гибко уже сейчас минимальным изменением исходного кода можно переключить тип выхода, полярность сигнала и т. п., а в будущем все это будет еще проще (см. ниже). В-пятых, это предсказуемо, повторяемо и документировано. Лично я не раз натыкался на не определяющиеся и некорректно работающие преобразователи c али.

Что реализовано:
- 3 независимых UART;
- поддержка аппаратного флоу контрола (RTS/CTS);
- поддержка DTR/DSR/DCD;
- 7 и 8 бит данных;
- поддержка контроля четности (none, even, odd);
- 1, 1.5, 2 стоповых бита;
- поддержка всех стандартных скоростей;
- поддержка нестандартных скоростей (тестировал до 921600);
- DMA на передачу и прием;
- не требует драйверов, используются CDC Class драйвера встроенные в ОС;
- составное USB устройство, определяется как три COM (tty) порта;
- подписанные драйвера для Win XP, 7, 8 (не требуется для Win 10);

Тестировалось на Win XP, 7, 8, 10, Linux, Mac OS.

Выходные уровни совместимы с TTL 3.3 и 5 вольт. Все входы кроме UART2 RX и CTS толерантны к 5 вольтам.

Маленькая ложка дегтя: по неизвестной причине, на некоторых экземплярах платы Blue Pill установлен некорректный подтягивающий резистор на USB D+. Это приводит к тому, что некоторые компьютеры эту плату не видят. А некоторые другие видят. Лечится заменой подтягивающего резистора на резистор номиналом 1.5 кОм. После этого все прекрасно работает на всех компьютерах.

Проект с открытым исходным кодом, MIT лицензия. Нет зависимостей от HAL или любых других сторонних библиотек кроме CMSIS.

Исходный код и собранная прошивка доступны тут: https://github.com/r2axz/bluepill-serial-monster

Что дальше? В планах добавить возможность конфигурирования типов выходных сигналов (пушпул, открытый сток), типов подтяжки сигнальных линий (floating, up, down) и выбора полярности (active-high / active-low) без пересборки ПО и перепрошивки микроконтроллера. Это позволит более свободно применять устройство с различными схемами развязок, согласования уровней, управления реле, и т.п.

 

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


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

15 hours ago, r2axz said:
...
- поддержка нестандартных скоростей (тестировал до 921600);
...
Выходные уровни совместимы с TTL 3.3 и 5 вольт. Все входы кроме UART2 RX и CTS толерантны к 5 вольтам.

по процитированному выше:

- И что, все три порта в полном дуплексе успевают на 921600  транслировать потоки, без использования flow control?

- TTL уровни в многопортовке не очень интересны. Обычно много портов используется со стандартными уровнями интерфейса.

 

А в-общем, интересно, но непонятно как использовать :)  Как учебный материал- отличная тема.

Для себя лично вижу применение- добавить RS-232/485/422 драйвера, может даже с гальванической развязкой, и тогда будет хорошая штучка.  Коробочка такая с USB хвостом и тремя DB9 разъемами.

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


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

2 hours ago, Ruslan1 said:

- И что, все три порта в полном дуплексе успевают на 921600  транслировать потоки, без использования flow control?

Короткий ответ: успевают, тестировал три порта одновременно в режиме loopback, скорость на каждом порту около 100 килобайт / сек.

Но вопрос не вполне корректный. Дело в том, что все зависит не только от производительности stm32f103c8t6, но еще и от того, насколько бодро хост будет забирать данные из IN эндпоинтов. Последнее же зависит от того, насколько бодро приложение использующее COM порт, будет оттуда эти данные вычитывать. Пример: у программы Tera Term открытие какого-нибудь UI диалога останавливает чтение из COM портов. Если в этот ком порт что-то сыпется снаружи, что остается делать устройству? Правильно, устройство буферизирует пока может, ну а потом дропает буфер и сообщает хосту через Interrupt Endpoint, что извини друг, случился buffer overrun. Все в точности как предусмотрено стандартом USB CDC ACM.

Поэтому в-целом, работа на высоких скоростях без flow control хоть и возможна (stm32f103c8t6 и моя прошивка тут не являются узким местом), но является сомнительной идеей по причинам изложенным выше.

2 hours ago, Ruslan1 said:

- TTL уровни в многопортовке не очень интересны. Обычно много портов используется со стандартными уровнями интерфейса.

Может быть именно под ваши задачи TTL уровни не интересны. А мне вот как раз интересны именно TTL. А кому-то еще, как вы выше уже заметили, может быть нужна опторазвязка. И так далее... И заранее не угадаешь ведь... Поэтому все эти детали, они out of scope, не являются частью проекта. Проект был о том, чтобы взять самую дешманскую железку и сделать на ней приличного качества преобразователь USB-Serial. А дальше уже подключайте к нему все что угодно, по условиям задачи.

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


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

25 минут назад, r2axz сказал:

Поэтому в-целом, работа на высоких скоростях без flow control хоть и возможна (stm32f103c8t6 и моя прошивка тут не являются узким местом), но является сомнительной идеей по причинам изложенным выше.

Почему "сомнительной"? На тератерм свет клином не сошёлся. Есть множество других терминалок. Да и не обязательно пользоваться чужой прогой, можно и самостоятельно работать с COM-портом через WinAPI и никто не будет ограничивать скорость работы с ним (кроме собственных кривых рук канеш).

Вообще: я например 921600 бод использую по дефолту во всех своих устройствах для отладочного терминала (естественно - за исключением тех редких, где её не позволяют технические возможности аппаратуры).

Цитата

Проект был о том, чтобы взять самую дешманскую железку и сделать на ней приличного качества преобразователь USB-Serial. А дальше уже подключайте к нему все что угодно, по условиям задачи.

Имхо - вполне полезный проект. Кому-то пригодится. И спасибо Вам за труды! :smile: (хотя мне вроде пока это не нужно).

 

PS: Вдогонку (лень гуглить что именно позволяет "MIT лицензия" ;) - можно ли взять Ваши исходники и портировать их под другой компилятор и/или другую плату с STM32F103? Возможно с модификацией кода?

При условии, что результат потом также куда-то выложить.

 

PPS: Из предложений, могу добавить только, что неплохо было бы добавить светодиодную индикацию работы всех UART-ов (TX/RX/подключение_со_стороны_компа на каждый из COM-портов). И настройку с выбором конкретных пинов этого вынести в таблицу где-то в исходниках (чтобы каждый прошивающий мог под себя настроить их). Типа:

//                        порт,пин
#define PIN_LED1_TX       1,   6
#define PIN_LED1_RX       2,   7
#define PIN_LED1_CD       3,   8
#define PIN_LED2_TX       2,   0
#define PIN_LED2_RX       3,   1
#define PIN_LED2_CD       0,   2
#define PIN_LED3_TX       0,   5
#define PIN_LED3_RX       4,   5
#define PIN_LED3_CD       3,   5

 

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


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

42 minutes ago, r2axz said:

Проект был о том, чтобы взять самую дешманскую железку и сделать на ней приличного качества преобразователь USB-Serial. 

Тоже считаю весьма полезным проектом !!!

А вот еще хорошо бы было получить преобразователь Ethernet-Serial и чтобы в компьютере виделся как COM порт или несколько COM портов. :blush:

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


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

5 minutes ago, jcxz said:

Почему "сомнительной"? На тератерм свет клином не сошёлся. Есть множество других терминалок. Да и не обязательно пользоваться чужой прогой, можно и самостоятельно работать с COM-портом через WinAPI и никто не будет ограничивать скорость работы с ним (кроме собственных кривых рук канеш).

Вообще: я например 921600 бод использую по дефолту во всех своих устройствах для отладочного терминала (естественно - за исключением тех редких, где её не позволяют технические возможности аппаратуры).

"Сомнительной" потому, что ничего не мешает операционной системе пойти заниматься своими делами вместо чтения данных из USB. Только поэтому. Я тератерм привел просто в качестве примера. А так, даже самописной терминалке могут просто не дать процессорного времени. Но вы правы в том смысле, что почти всегда будет просто ломовой запас производительности со стороны хоста и проблем никаких не будет. Сквозной flow control приводит ситуацию к виду "всегда все будет в порядке", а его отсутствие оставляет нас в ситуации "почти". Но опять же, я согласен, очень часто (почти ( :) ) всегда) этим можно пренебречь.

13 minutes ago, jcxz said:

Имхо - вполне полезный проект. Кому-то пригодится. И спасибо Вам за труды! :smile: (хотя мне вроде пока это не нужно).

Спасибо за теплые слова!

13 minutes ago, jcxz said:

PS: Вдогонку (лень гуглить что именно позволяет "MIT лицензия" ;) - можно ли взять Ваши исходники и портировать их под другой компилятор и/или другую плату с STM32F103? Возможно с модификацией кода?

При условии, что результат потом также куда-то выложить.

MIT лицензия позволяет вам всё :) Можете копировать, изменять, использовать в других программных проектах или устройствах, продавать, и так далее. Вы не обязаны открывать свой исходный код при этом. Хотите выкладывайте, хотите - нет. Это дело ваше. Единственное, к чему MIT лицензия вас обязывает - это включить текст лицензии в состав дистрибутива и/или исходного кода если вы его распространяете. Потенциально с указанием к какому куску проекта она относится.

27 minutes ago, jcxz said:

PPS: Из предложений, могу добавить только, что неплохо было бы добавить светодиодную индикацию работы всех UART-ов (TX/RX/подключение_со_стороны_компа на каждый из COM-портов). И настройку с выбором конкретных пинов этого вынести в таблицу где-то в исходниках (чтобы каждый прошивающий мог под себя настроить их). Типа:

У меня нет на это свободных ног :) Вот это занято уже сейчас...

| Signal |   Direction   |     UART1     |     UART2     |     UART3     |
|:-------|:-------------:|:--------------|:--------------|:--------------|
|   RX   |      IN       |    **PA10**   |      PA3      |    **PB11**   |
|   TX   |      OUT      |      PA9      |      PA2      |      PB10     |
|   RTS  |      OUT      |      N/A      |      PA1      |      PB14     |
|   CTS  |      IN       |      N/A      |      PA0      |    **PB13**   |
|   DSR  |      IN       |    **PB7**    |    **PB4**    |    **PB6**    |
|   DTR  |      OUT      |      PA4      |      PA5      |      PA6      |
|   DCD  |      IN       |    **PB15**   |    **PB8**    |    **PB9**    |

Подключение ПО со стороны компа в USB CDC ACM в общем случае не определяется. А что касается состояния ног, если надо визуализировать, то что мешает подключить светодиод прямо на интересующую ногу через буфер?

11 minutes ago, dimka76 said:

Тоже считаю весьма полезным проектом !!!

Благодарю!

11 minutes ago, dimka76 said:

А вот еще хорошо бы было получить преобразователь Ethernet-Serial и чтобы в компьютере виделся как COM порт или несколько COM портов. :blush:

Ох... Если делать с нуля, то тут очень приличное количество возни с написанием драйверов. Но вроде гуглятся существующие продукты на эту тему которые могут работать с любым ком портом, просто пробрасывают его по IP и все. Денег правда стоят...

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


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

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

Подключение ПО со стороны компа в USB CDC ACM в общем случае не определяется.

Вероятно, иначе как по DTR это и не сделать...

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

А что касается состояния ног, если надо визуализировать, то что мешает подключить светодиод прямо на интересующую ногу через буфер?

При очень коротких пакетах на большой скорости слишком уж слабая засветка. Но, с другой стороны, аналогичная индикация у FT2232 наоборот, не дает возможности адекватно оценить объем передаваемых/принимаемых данных (хотя это нужно очень изредка). 

Да, а когда совсем уж плохо с ногами под индикацию - 595 очень помогают. Но две-три ноги придется им отдать...

 

 

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


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

8 minutes ago, rx3apf said:

Вероятно, иначе как по DTR это и не сделать...

Ну у меня DTR используется как выходной сигнал, которым предполагается управлять. И предполагается, что ПО может этот сигнал дергать туда сюда по своему усмотрению. Поэтому в качестве индикации именно подключения - так себе получается.

13 minutes ago, rx3apf said:

При очень коротких пакетах на большой скорости слишком уж слабая засветка. Но, с другой стороны, аналогичная индикация у FT2232 наоборот, не дает возможности адекватно оценить объем передаваемых/принимаемых данных (хотя это нужно очень изредка). 

Да, а когда совсем уж плохо с ногами под индикацию - 595 очень помогают. Но две-три ноги придется им отдать...

Да вариантов сделать такую индикацию масса, я понимаю. От чисто схемотехнических (поставить какую-нибудь времязадающую цепь которая даст нужную продолжительность горения светодиода) до программных, со сдвиговым регистром. И тут опять начинается вопрос "что-кому-надо-для-конкретного-проекта". Я все таки думаю не городить огород пока, а оставить индикацию как есть: базово активность по USART можно увидеть с помощью статусного светодиода (он строго говоря показывает активность USB, но одно приводит к другому). Да по всем трем портам вперемешку, да не видно состояния управляющих линий (но вообще их видно в ПО должно быть). Но зато не требует подключения к плате ничего лишнего. Я запишу себе в бэклог вопрос индикации, но вот прям сейчас не вижу как его можно решить именно "универсально".

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


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

13 минут назад, r2axz сказал:

. Поэтому в качестве индикации именно подключения - так себе получается.

Да, само собой. Но если терминалкой (тот же TeraTerm) - DTR поднимается при открытии порта и деактивируется пи закрытии, так что достаточно адекватно.

 

13 минут назад, r2axz сказал:

 Я запишу себе в бэклог вопрос индикации, но вот прям сейчас не вижу как его можно решить именно "универсально".

Да и не надо - если кому так приспичит, пусть сам и дописывает. По возможности SPI зарезервировать бы под индикацию (а то и управление какими-нибудь некритичными по времени сигналами), но и только. И да, аппаратный вариант с одновибратором на RX/TX - вполне годное решение.

Ну, может быть (на будущее) еще подумать на предмет управления трансиверами RS-485 (так, как обычно делают, типично довольно коряво, это лучше иметь на "аппаратном" уровне).

 

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


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

25 minutes ago, rx3apf said:

Ну, может быть (на будущее) еще подумать на предмет управления трансиверами RS-485 (так, как обычно делают, типично довольно коряво, это лучше иметь на "аппаратном" уровне).

Спасибо, запишу тоже в бэклог. Либо в рамках этого проекта, либо на будущее в другом.

У меня сейчас на самом деле в планах выкинуть один UART (это делается исключительно из-за аппаратных ограничений USB в конкретном MCU) и на освободившееся место приделать аудиокарту. На прием - встроенный ADC 12-бит, на передачу - PWM. И получится копеечный, но при этом вполне годный интерфейс для работы с digimodes (FT8 и всякие такое). Собственно этот проект USB-Serial - это побочный продукт большего проекта))) В первую очередь буду занят именно этим. А там поглядим.

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


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

Пожалуй что правильная мысль. Три UART - забавно, конечно, но много ли практического смысла ? Хотя "неполноценный" (под RS-485, RX/TX и направление) UART может быть как-то и смотрелся бы сбоку...

Еще что полезно - USB/I2C, USB/SPI,  менее полезно, но что может встретиться - USB/1-wire, USB/параллельный (но это больше для экспериментов), USB/WS2812 (но это уж совсем специфическое).

 

"В порядке бреда" - если место под код есть, сделать все сразу с по возможности переназначаемыми линиями, и какой-то энергонезависимый конфигуратор, оставив пользователю выбор (с ограничениями). Как вариант - AT-командами на одном из портов, в особом режиме. 

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

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


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

В порядке бреда (а точней - ради разрешения спора) сделал 7 USB-CDC на одном STM32F103. Понятно, что из-за его малюсенького буфера USB, пришлось сильно ограничить буферы CDC. Но оно работало в простых тестах. Другое дело - что не нужно обычно так много.

Вот два CDC на одном МК вполне можно запилить: скажем, один для коммуникации с МК, второй — для каких-либо настроек или отладки.  Вот, кстати, подумал, что в моем переходничке CAN-USB можно было бы именно так разделить собственно работу с шиной и команды (при обильном потоке данных приходится набирать команды вслепую - по крайней мере, команду паузы).

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


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

5 minutes ago, rx3apf said:

 

Пожалуй что правильная мысль. Три UART - забавно, конечно, но много ли практического смысла ? Хотя "неполноценный" (под RS-485, RX/TX и направление) UART может быть как-то и смотрелся бы сбоку...

Еще что полезно - USB/I2C, USB/SPI,  менее полезно, но что может встретиться - USB/1-wire, USB/параллельный (но это больше для экспериментов), USB/WS2812 (но это уж совсем специфическое).

 

Вообще встречаются такие проекты. Правда и проект с тремя последовательными портами был на GitHub тоже (https://github.com/satoshinm/pill_serial), но мама дорогая, какое же это говно... Во-первых, кроме RX/TX ничего нету, а во-вторых, там блокирующая работа с USART, карл! То есть, пока один порт пишет/читает, остальные ждут. Ну и ошибок там полно. Хотя последнее - беда общая, уверен, и у меня найдутся.

11 minutes ago, rx3apf said:

"В порядке бреда" - если место под код есть, сделать все сразу с по возможности переназначаемыми линиями, и какой-то энергонезависимый конфигуратор, оставив пользователю выбор (с ограничениями). Как вариант - AT-командами на одном из портов, в особом режиме. 

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

/*  rx */ { .port = GPIOA, .pin =  3, .dir = gpio_dir_input,  .pull = gpio_pull_up, .polarity = gpio_polarity_high },
/*  tx */ { .port = GPIOA, .pin =  2, .dir = gpio_dir_output, .speed = gpio_speed_medium, .func = gpio_func_alternate, .output = gpio_output_pp, .polarity = gpio_polarity_high },
/* rts */ { .port = GPIOA, .pin =  1, .dir = gpio_dir_output, .speed = gpio_speed_medium, .func = gpio_func_general, .output = gpio_output_pp, .polarity = gpio_polarity_low},
/* cts */ { .port = GPIOA, .pin =  0, .dir = gpio_dir_input,  .pull = gpio_pull_down, .polarity = gpio_polarity_low },
/* dsr */ { .port = GPIOB, .pin =  4, .dir = gpio_dir_input,  .pull = gpio_pull_up, .polarity = gpio_polarity_low },
/* dtr */ { .port = GPIOA, .pin =  5, .dir = gpio_dir_output, .speed = gpio_speed_medium, .func = gpio_func_general, .output = gpio_output_pp, .polarity = gpio_polarity_low },
/* dcd */ { .port = GPIOB, .pin =  8, .dir = gpio_dir_input,  .pull = gpio_pull_up, .polarity = gpio_polarity_low },

И поменять его может даже не умеющий программировать человек. А через конфигуратор можно задать тип подтяжки (вверх/вниз/без подтяжки), полярность сигнала (активный высокий/низкий) и тип выхода (пушпул/открытый сток). Конфигуратор доступен в виде шелла на первом порту когда PB5 замкнут на землю. Выглядит это так:

*******************************
* Configuration Shell Started *
*******************************

>help
help    - shows this help message, use "help command-name" to get command-specific help
config  - save and reset configuration paramters in the device flash memory
uart    - set and view UART parameters
>help uart
uart: set and view UART parameters
Usage: uart port-number|all show|signal-name-1 param-1 value-1 ... [param-n value-n] [signal-name-2 ...]
Use "uart port-number|all show" to view current UART configuration.
Use "uart port-number|all signal-name-1 param-1 value-1 ... [param-n value-n] [signal-name-2 ...]"
to set UART parameters, where signal names are rx, tx, rts, cts, dsr, dtr, dcd,
and params are:
  output        [pp|od]
  active        [low|high]
  pull          [floating|up|down]
Example: "uart 1 tx output od" sets UART1 TX output type to open-drain
Example: "uart 3 rts active high dcd active high pull down" allows to set multiple parameters at once.
>uart 1 tx output od
>config save
>

 

Кстати, установив uart 1 tx output od и соединив RX c TX получаешь халявный CI/V для ICOM (проверял с 706).

Возможно я не прав и стоит сделать переназначение для ног из конфигуратора. Я еще подумаю. Ну и RX/TX/CTS особо не переназначишь. Что-то конечно с remap можно придумать. Но это имхо оверкил.

Just now, r2axz said:

Как вариант - AT-командами на одном из портов, в особом режиме.

C ними как раз решил не связываться. Все равно стандартных AT эквивалентов для этих настроек нет, а человек должен общаться с компьютером на понятном человеку языке, это пусть компьютер напрягается.

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


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

59 minutes ago, rx3apf said:

Три UART - забавно, конечно, но много ли практического смысла ?

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

Вот пример

https://moxa.pro/catalog/nport5650-16

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


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

53 минуты назад, r2axz сказал:

Все равно стандартных AT эквивалентов для этих настроек нет, а человек должен общаться с компьютером на понятном человеку языке, это пусть компьютер напрягается.

Но не делать же ради этого полноценный встроенный конфигуратор a la ANSI терминал ? (Было бы красиво, но очень уж избыточно). Можно же тупо регистр = значение. Прочитать/записать/справка по синтаксису (без подробностей). Впрочем, это дело совершенно "хозяйское" (потому и говорю - в порядке бреда ;)

22 минуты назад, dimka76 сказал:

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

 

Да, само собой. Да хоть бы и FT4232 на четыре порта. Но три - ни то, ни се, да и в повседневной жизни редко может пригодиться. А вот два - нужно часто. Два плюс RS485 - тоде вполне представляю применение. Ну, тут у каждого свое видение, по своим задачам....

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


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

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

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

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

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

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

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

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

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

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