Как стать автором
Обновить
20
0

Пользователь

Отправить сообщение

Используется, PA15 – это UART1 RTS (см. README.md), в device_config он тоже упоминается.

Да, все максимально допустимое. SYSCLK = 72 МГц. APB1(PCLK1) = 36 МГц, APB2(PCLK2) = 72 МГц.

Прерывание TXC сигнализирует о том, что отправка текущего байта завершена. Оно будет вызываться всегда, когда завершается отправка очередного байта.

Нет. Из Reference Manual на STM32F103:

TXE interrupt. A USART interrupt is generated whenever TC=1 in the USART_SR register (RM0008, p. 821)

TC: Transmission complete. This bit is set by hardware if the transmission of a frame containing data is complete and if TXE is set. (RM0008, p. 818)

Поэтому не всегда, а только если USART больше нечего отправлять. Как следствие, достаточно разрешить в обработчике DMA прерывание по TC и по нему сбросить DE. Именно это тогда и было сделано. Корректность работы я проверил осциллографом и им же померил задержку.

Исправлено в версии 2.3.3, пожалуйста, обновитесь.

Повторил под Win.

Мне интересно именно ADC и ШИМ попробовать. Может и не заработают. Посмотрим. По поводу зависания — интересно, попробую повторить. А на какой ОС вы работаете?

Кстати, по поводу ваших "граблей" в статье. Я посмотрел ваш код на GitHub и мне бросилось в глаза, что у вас USART RX настроен как floating. А он должен быть подтянут к Vcc. И тогда все будет хорошо, не будет никакого "мусора" и не надо будет запрещать прием на время передачи.

Я не остановился и довел задержку до 0.6 мкс. Вот на этом пока остановлюсь :)

Я вряд ли буду это делать. У меня в планах выкинуть один из последовательных портов и попробовать добавить туда простенькую аудиокарту: один вход с использованием ADC, один выход с использованием таймера в режиме ШИМ. И тогда получится интерфейс для радиолюбительских трансиверов, для работы во всяких цифровых модах типа FT8. Но пока сложно сказать, когда я это сделаю.

Да, я несколько некорректно выразился. Хотел подчеркнуть, что это IN endpoint. Естественно, в USB инициатором любого обмена выступает хост.

Довел время сброса TXA до 0.6 мкс применив bit banding. Теперь еще больше шансов, что все заработает на 460 кБод на трех портах одновременно.

Я постарался (и продолжаю стараться) сделать обработчик прерывания от USART как можно более коротким, и с хорошей вероятностью все будет работать на 460 кБод на 3-х портах одновременно. Но мне всё-таки нужно больше обратной связи от тех, кто будет это использовать в реальной жизни. Просили сделать RS-485 — я сделал. Теперь я, в свою очередь, прошу протестировать результат :)


<зануда моде он>
Бод = это бит/с, поэтому бод/с — это не скорость, это ускорение :)
</зануда моде офф>

Добавил поддержку RS-485, обновил статью.

У STM32F072 и STM32F103C8T6 разные USART. У первого есть режим в котором сигнал RTS может управлять DE(/RE) RS-485, а у второго — нет. В целом, USART на STM32F072 более продвинутый. Но что поделать, ведь STM32F103C8T6 гораздо более распространен и дешев, поэтому выбор очевиден.


Что касается граблей, то насколько я понял все грабли у вас заключались в том, что 5-ти вольтовый MAX485 то ли работал, то ли нет с 3.3 вольтовыми уровнями (или питанием?). Или я что-то пропустил? Может в комментариях?


В-общем, я пока работаю над софтовым управлением TXA (DE, /RE). Пришлось перепахать всю прошивку, отказаться от прерываний USB в пользу поллинга, задействовать вытесняющие прерывания и много всего по мелочи. Когда-нибудь потом напишу статью об этом.


А пока задержка переключения TXA по окончанию передачи составляет менее 1 мкс. Измерено осциллографом на одном из портов на фоне занятых постоянной передачей двух других. Это позволяет работать с RS-485 на скоростях не менее 460 кБод и на мой взгляд, это очень прилично. Хотя я собираюсь еще немного ужаться.

Сделал экспериментальную версию, обновил статью.

Спасибо, не знал про U-620. Мощная штука! Но мне не подходит: мне в первую очередь требуются TTL уровни.

Спасибо! Я не стал выделять конфигурацию в один порт для того, чтобы не терять в производительности. Хотя, здесь есть пространство для дебатов. Дело в том, что в stm32f103c8t6 размер USB packet buffer memory равен 512 байтам. 112 из них заняты buffer description table (для 7 endpoints), сами endpoints занимают еще 384 байта. При этом, уже даже тут пришлось несколько ужаться, и размеры BULK IN/OUT endpoints для порта 1 сделать равными 32 байтам против 64 байт у остальных портов. Это несколько ограничивает производительность первого порта. Таким образом, у нас осталось всего 16 байт, которые все и уйдут на дескриптор 8-го endpoint. Надо откуда-то взять еще хотя бы 16 байт. В принципе, можно уменьшить два из трех INTERRUPT IN endpoints до 8 байт и передавать уведомления о состоянии порта за два «захода». Но мне не захотелось так делать вот почему: конфигурационный порт нужен далеко не всем и используется относительно редко. Я не захотел выделять для него на постоянной основе ресурсы, которые могут помочь увеличить производительность при нормальной работе.


Кроме этого, при некоторых применениях, конфигурационный порт может оказаться даже вредным. Мне не хотелось бы, чтобы у конечного пользователя в системе постоянно болтался порт с помощью, которого он может легко «выстрелить себе в ногу». Поэтому я сознательно усложнил доступ к этому порту.


С другой стороны, пока я все это писал, я понял, что у меня есть аж 16 свободных байт, а текущий размер control EP0 – 8 байт. Будет лучше инвестировать эти свободные байты туда.

Софтовая реализация RS-485 могла бы быть отличными упражнением, но для практического применения боюсь будет слишком медленно. Особенно, если надо сделать больше одного порта.

Есть разница между конструктивной критикой и "бла-бла-бла, в вашем коде не хватает комментариев, поймет только компилятор, а автор все забудет через год". Первое — приветствуется, второе — неприемлемо. А комментарии в стиле: "но с указателями и типами данных у вас помойка в коде. Ищите сами." — это вообще ни о чем. Однако, если бы вы написали что-то в стиле: "вот тут сделано неправильно потому-то и потому-то", то я сказал бы вам огромное спасибо. Если бы вы написали "в таких условиях возникает вот такая ошибка, повторять так", я бы вообще прыгал до потолка от радости. Конечно, если бы это было действительно неправильно и у меня не было бы причины сделать именно так.


  1. Валить все на конфигуратор не стоит, CubeMX и не такую еще дичь генерит, но это не значит что его использование является обязательным. А в WinAPI как раз очень разумная, не близкая мне лично, но разумная политика названия переменных;
  2. Правильно, но не в том месте в котором она вызывается. Кончится это тем, что один программист поправит функцию инициализации, а вот про все места из которых она вызывается даже не подумает. А другой программист потом будет очень рад, потратив пару часов на осознание того факта что в комментарии написано одно, а функция делает другое.
  3. Традиция, так традиция. Но мне-то какое дело до ваших традиций?
  4. Опять же, тот факт, что у вас что-то оформлено в стиле SiLabs никак не делает ваши дескрипторы более читаемыми. Хотя да, я понимаю, есть еще возможные ограничения компилятора.

А камень в ваш огород я не кидал, я просто указал на конкретные проблемы вашего стиля кода и комментирования, со ссылками на конкретные места в вашем коде, объяснил к чему это потенциально приводит.


И я правда не считаю ценными советы по оформлению кода от человека с таким качеством кода как у вас. Покажите пример, а если нет — тогда действительно, вы все сделали правильно удалившись из темы.

Ага, понял, спасибо!

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность