Заголовок сообщения: Re: Stm32 с чего начать изучение...
Добавлено: Ср мар 04, 2026 10:04:53
Мучитель микросхем
Карма: 2
Рейтинг сообщений: 19
Зарегистрирован: Пн сен 15, 2025 08:43:23 Сообщений: 499 Откуда: Маленький СССР посреди шариатской республики
Рейтинг сообщения:0
Ну, естественно, это я нарукожопил! Полез в табличку "STM32G0x1 peripheral register boundary addresses", а там:
Цитата:
0x4000 9800 - 0x4000 9BFF | 1 KB | USB RAM1
А не как у всех остальных, где было 0x4000 6000. Ну, оно, в принципе, и понятно: 2кБ в месте для 1кБ не запихнешь. Т.е. сами регистры USB на старом месте (0x4000 5C00), поэтому начальное конфигурирование мне хардфолты не давало, а вот непосредственно ОЗУ конечных точек…
если вы посмотрите на флагмана от Artery, то там FIFO нет ни в SPI, ни в USART, ни в DMA.
Отсутствие упоминания о FIFO в DMA не означает его отсутствия. При приближении к частоте транзакций в 4 раза меньшей, чем частота шины, внезапно обнаруживается, что FIFO там есть. FIFO в UART и SPI - такое себе "удобство"... Фактически имеется FIFO глубиной 2. Буферный регистр и сдвиговый регистр. Если их не хватает, нужно использовать DMA, а не ходить по краю.
... на AT32F ... Основное отличие SDK - все регистры периферии определены как битовые структуры и потому маски в хедерах не определены.
Купил несколько типов Geehy APM32 для тестирования. В Keil: то же самое как STM32. Kое-где чего-то не хватает из regs, а что-то сделано по-другому. Практически идентичны. CMSIS. Особых трудностей нет. Нравятся. Куплю и AT32. Спасибо за идею.
Отсутствие упоминания о FIFO в DMA не означает его отсутствия. При приближении к частоте транзакций в 4 раза меньшей, чем частота шины, внезапно обнаруживается, что FIFO там есть.
Т.е. китайцы в RM про FIFO в DMA ничего не написали, на диаграмме его не нарисовали, при этом DMA полностью содран с ST-го, если DMAMUX не трогать, просто имена полей другие, а у ST есть аппноут где для этого DMA тайминги расписаны и тоже никакой FIFO не упоминается, но вы вывели его наличие опытным путем? ) Можно еще глянуть для STM32 "Migration Guide", там в табличках четко видно, что у одной серии FIFO у DMA было, а у другой его нет, или наоборот. Спойлер У F2 DMA как у F4, с FIFO, а у L4 DMA как у Artery, без FIFO.
Именно так. И это очень просто. При превышении 1/4 от частоты шины DMA уходит в ошибку и видно сколько транзакций он успевает совершить до этой ошибки. Это и есть глубина FIFO плюс два. Успевает сделать 6 транзакций.
Извините, но это очень не очевидно ) Для начала, FIFO - это хорошо. Если FIFO есть, но было бы очень странно об этом не написать, а если его нет, то тут как раз ничего странного учитывая, что его нет даже в SPI/USART. И посмотрите вот на что... У STM32 все DMA без FIFO однопортовые, а все DMA c FIFO - двухпортовые. Двухпортовый может читать из памяти и накапливать данные в FIFO, потом из него передавать дальше. Однопортовые так не могут даже если бы FIFO в них было, т.к. из-за системы рукопожатий следующая транзакция не может начаться пока не завершилась предыдущая. Читаем, пишем через тот же порт, только потом опять читаем, FIFO здесь практически бесполезно.
Заголовок сообщения: Re: Stm32 с чего начать изучение...
Добавлено: Ср мар 04, 2026 21:49:43
Мучитель микросхем
Карма: 2
Рейтинг сообщений: 19
Зарегистрирован: Пн сен 15, 2025 08:43:23 Сообщений: 499 Откуда: Маленький СССР посреди шариатской республики
Рейтинг сообщения:0
В общем, не без помощи дипсика (он мне пару косяков указал, на которых у меня "глаз замылился") USB таки у меня заработал. Как вылижу код, выложу сниппет на гитхаб (ну и прочие кодохранилища, у меня зеркала на: битбакете, сосфорже, гитлабе, гитфлике, нашем обсерваторском gitea-сервере и рабочем git-сервере).
Это конечно замечательно. Осталось узнать область использования. Не абстрактно, а конкретно. На более-менее актуальном примере задачи. Есть смутное подозрение, что столь замечательное свойство не может всерьез определять выбор чипа в 99,99(9)% проектов
Совершенно не согласен. Множество раз использовал SPI и UART с FIFO без DMA (в тех МК где FIFO имеются). И это очень удобно. Нужно передать например кадр по SPI: Просто записываю его в FIFO SPI и стартую трансфер. Всё! Не нужно никаких буферов в ОЗУ (для DMA), не нужно программировать DMA, никаких задержек между словами (как в случае использования DMA для загрузки/выгрузки слов из/в ОЗУ). Кадр передаётся без разрывов и на максимальной скорости. А если после завершения транзакции, принятый блок данных не нужен - просто делаю flush FIFO и всё - без доп.буферов и ненужной загрузки шины.
Фактически имеется FIFO глубиной 2. Буферный регистр и сдвиговый регистр. Если их не хватает, нужно использовать DMA, а не ходить по краю.
Вы видимо никогда не работали с МК, имеющими нормальное FIFO в UART/SPI. Поэтому не догадываетесь о преимуществах его перед DMA (или перед связкой: DMA+FIFO+SPI). Элементарный пример: Имеется некая система с master-SPI (МК). Требуется генерация SPI-транзакций с точно выдерживаемой времянкой. Времянка должна выдерживаться с точностью до такта МК. Тогда сигнал CS формируем таймером (CS - от ноги таймера). Высокую частоту (с запасом) по SCLK поставить нельзя (slave не умеет). Но если аккуратно вставить кадр внутрь интервала CS=low, выдерживая минимально допустимые задержки от краёв CS=low до битов данных, то будет работать. Но как тут быть если нет FIFO в SPI, а есть только DMA? Ведь в системе есть другие DMA-пересылки и есть CPU (который тоже занимает шину). А значит - будут неизбежные задержки выборки DMA из/в ОЗУ и задержки между словами на MOSI/MISO. И трансфер будет иногда (изредка) вылетать за пределы окна CS=low. А если есть FIFO в SPI, то можно в него загрузить данные предварительно (до CS=low) и также выгрузить - после установки CS=high. А стартовать SPI-трансфер внутри интервала CS=low можно от аппаратного сигнала таймера с точностью до такта CPU. Тогда все тайминги по SPI будут выдержаны идеально точно, с точностью до такта.
Ещё в нормальных МК с FIFO в SPI программа может в SPI записать сразу несколько транзакций: указав границы CS=low, данные, интервалы между переключениями CS и данными и т.п. И стартануть эту пачку транзакций сразу всю. Получив в конце одно единственное прерывание. Это полезно при работе с SPI слэйвами, требующими множество отдельных мелких SPI-кадров для выполнения какой-то одной операции с чипом. Например: радио-чипы (типа SX127x) - часто требуют перепрограммирования нескольких разных регистров с несмежными адресами в процессе работы (при переключении приём<->передача, считывании и загрузке данных, ...). Или например DW1000 - тоже нужно писать/читать множество регистров (и на макс. скорости). Пишу сразу всю пачку транзакций в FIFO и получаю одно единственное прерывание после выполнения их всех. Вместо множества прерываний.
Также полезно FIFO в UART. В одном проекте например требовалось от одного МК к другому передать по UART не только данные, но также и сигнал синхронизации. Для синхронизации работы внутренней периферии ведомых МК с ведущим. Требовалась синхронизировать работу ШИМ-ов управляющих мощными моторами от разных МК как можно точнее. Желательно - с точностью до такта CPU. И желательно - с минимумом проводов (по одному UART и данные и синхро-сигнал). Любое рассогласование работы ШИМ - резкое снижение КПД системы и опасность выхода из строя. И в том МК имелось нормальное FIFO в UART с возможностью аппаратного старта передачи UART от сигнала таймера. Поэтому: предварительно загружал передаваемый кадр данных в FIFO UART, а потом стартовал передачу UART.TX от аппаратного сигнала таймера. Таким образом - положение первого старт-бита этого кадра было идеально точно синхронизировано с работой внутреннего таймера МК. Без влияния задержек из-за доступа DMA к шине данных. И ведомые МК могли точно (до такта) синхронизировать работу своих внутренних таймеров с UART.RX.
PS: К сожалению - ничего подобного STM32 не умеют.
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения