Положу ещё и сюда, на память. WCH CH32V317. Ещё один нюанс с
UARTом. Не исключаю, что такое будет и у STM32F1xx: Если вручную
положить в DATAR символ на передачу, и быстро (по крайней мере у
меня получается до завершения передачи первого бита) включить DMA
для продолжения передачи в автоматическом режиме, то не всегда,
чуть более, чем в половине случаев (но не всегда!) DMA перебивает
ранее записанный в DATAR символ. Мои выводы и предположения по наблюдениям с осциллографом:
1. Передача, начало стартового бита, начинается не в момент записи DATAR (без разницы чем, "вручную" или DMA), а в дискретные моменты времени, связанные с внутрениим тактовым генератором модуля. Если сравнивать передачу разных модулей, видно, что у них такты бит передачи совпадают по времени, но вот сама передача, при близкой по времени записи в DATAR, может начаться или одновременно, или со сдвигом на один битовый интервал. Другими словами, моменты начала передачи - дискретны и привязаны к вунтеннему битовому интервалу модуля UART.
2. Похоже что до наступления очередного битового интервала UART, символ, записанный в DATAR, лежит в этом регистре и не переносится в сдвиговый регистр, чтобы освободить DATAR для следующего символа.
3. При передаче "только вручную" или только с DMA, проблем нет. Запрос на следующий символ не поступает до того, как предыдущий не будет перенесён в свдвиговый регистр передачи. Таким образом, коллизии не происходит.
4. Если же, при установленном в настройках UART бите "DMA transmission enable", записать в DATAR символ "вручную", то, ранее взведённый запрос для DMA не снимается - он не был "потрачен" для записи в DATAR и на момент записи, сдвиговый ргистр пуст, место для двух символов есть и нет резона снимать запрос DMA для следующего символа. ОК.
5. Из-за п.2, записанный вручную в DATAR символ не переносится в сдвиговый регистр. А из-за п.4, сохраняется активный запрос на DMA. И в такой ситации, включение канала DMA Tx, сразу зашлёт в DATAR следующий символ уже через DMA. А так как первый символ, если не попал на нужный такт битового интервала, может ещё лежать в DATAR, он оказывается затёрт и потерян!
На практике, получил потери первых символов (которые с адресом и адресным битом, отправленные "вручную"). Кадр передавался, в от 1/3 до 3/4 случаев, без первого символа и на один символ короче, чем загружено данных.