11110011 01110110 (di_halt) wrote in ru_radio_electr,
11110011 01110110
di_halt
ru_radio_electr

Category:

Странные приколы с DMA

STM32F103C8T6

Работает на два канала RS485.

Отправка буфера через ДМА, прием через ДМА. Приемный ДМА работает в кольцо. Все традиционно. Написано вручную, без СПЛ, куба и прочих либ.

Код usart2.c сделан копипастом из usart1.c разумеется поправлены все каналы, адреса и все прочее. Так вот. уарт2 работает отлично. Принимает в буфер, передает из буфера. ВСе как задумано. А вот у уарта1 какие квантовые эффекты с ДМА. Зависимость от наблюдателя.

Т.е. когда я смотрю отладчиком внимательно по брейкпоинтам на настройки ДМА1 канал 5 (прием уарта1), то он принимает в буфер. Все как задумано.

Но стоит переключиться на что-то другое, поставить бряк в задачу, как уже не работает. Без отладчика тоже ничего не работает. Думал копипастнутый уарт2 мешает, где то что то не заметил и дублируется. Убрал его из проекта вообще. Не помогло О_о.

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

Да, вращается все на FREERTOS, но ее апи не задействовано нигде вообще в этом коде.


Апдейт:
Короче, кажись разобрался. У ДМА где то зарыта аппаратная защита(!!!) от неправильных настроек. Есть там регистр CCR вот первый бит его это EN. B вы хрен его поставите если не настроите остальные параметры. Причем если вы запишите остальные биты ВМЕСТЕ с настройками, единым числом. То на одном канале это может прокатить, а на другом нет. Или прокатит, но как то частично и свалится в другом случае. Когда ДМА вдруг поймет, что ее наебали, загрузили все биты сразу и сбросит бит ЕН и даже вручную его взвести будет нельзя пока заново не перенастроишь ВСЕ остальные биты. Вот шиза то...

АПдейт2
Нет, нифига. Дело не в этом. Хм...

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

Т.е.
Channel->CCR |= 1<<5;
и
Channel->CCR |= (uint16_t)(1<<5);

имеют значения. Т.к. важен порядок записи битов в регистр. EN должен сниматься первым и записываться последним. Одновременно нельзя. В результате оптимизатор может решить запихать биты побайтно и перепутает порядок.
Subscribe
  • Post a new comment

    Error

    Comments allowed for members only

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 24 comments