STM32 новичку в ARM что к чему

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3664043#p3664043"]Я особо с DMA не работал, но простая логика подсказывает, что ждать (цикл while) нужно не после spi_send_dma(), а до её вызова.[/uquote]
Естественно.
Разве что ещё проследить, чтобы никто в буфер не писал (подготовка новой передачи), пока он по DMA занят.
Если хочется быстро, то лучше сразу сделать два буфера.
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 354
Зарегистрирован: Чт июл 24, 2014 23:09:23
Откуда: Киев

Сообщение hosturik »

Да я понимаю что так делать не правильно, но по другому у меня не получилось заставить заработать.

Вы имеете ввиду вот так?

Код: Выделить всё

void Spi_Write_Data(uint8_t *data, uint16_t size){
  while(LL_SPI_IsActiveFlag_BSY(SPI1)){}
  spi_send_dma(data, size);
}
Так не работает

Мне наверное нужно не ждать сброса флага в бесконечном цикле, а делать проверку установки пользовательского флага через if,
который я буду устанавливать в прерывании передачи DMA (transfer complete) и только после этого делать повторную отправку. Но
у меня такой вариант почему то не заработал.
Или мне не прерывание DMA нужно ждать в прерывании SPI? Что то я запутался

Вот так я делал. Но не заработало. И я догадываюся почему. Данные для инициализации дисплея к напримеру пытаются отправиться, но я их попросту игнорирую,
если флаг не установился, из за чего не проходит даже инициализация.

Код: Выделить всё

uint8_t flag = 0;

// Функция отправки данных по SPI
void Spi_Write_Data(uint8_t *data, uint16_t size){
	if(flag == 0){
		spi_send_dma(data, size);
		flag = 1;
	}
}

//  Обработчик прерывания DMA
void DMA1_Channel1_IRQHandler(void)
{
	if(LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_3) && LL_DMA_IsActiveFlag_TC3(DMA1)) { // флаг окончания передачи через DMA
		LL_DMA_ClearFlag_TC3(DMA1);          
		flag = 0;                    
	}
}
  
Последний раз редактировалось hosturik Ср июл 10, 2019 11:19:02, всего редактировалось 1 раз.
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="hosturik",url="/forum/viewtopic.php?p=3664047#p3664047"]Вот так я делал. Но не заработало.[/uquote]
Как минимум нужен volatile для flag. Только зачем так делать, если можно проверять флаг и без прерывания...
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

[uquote="rai17",url="/forum/viewtopic.php?p=3663950#p3663950"]dosikus, Конечно прочел, притом внимательно...
-таймер фризился надо конфигурировать Debug MCU configuration register-
Это видимо имеется ввиду. Читал, сравнивал, работаю над этим.
Кажет ерунду, это когда ожидаешь увидеть в счетчике 0x0000, а видишь совершенно различные варианты, чередующиеся по непредсказуемому порядку...
////////
Так вот (опять же повторяюсь), при установки breakpoint на вход в ISR TIM1 в симуляторе (Use Simulator) всё отлично - вижу 0х0000, а вот при подключении платы с прошитым камнем STM32F103С8Т6 по SWD через ST-Link V2 (Use: ST-Link Debugger) – получаются вообще случайные значения в View-System Viewer-TIM-TIM1-CNT.
Буду разбираться...[/uquote]

Еще раз- счетчик таймера не останавливается при бряках...
Реклама
Эиком - электронные компоненты и радиодетали
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 354
Зарегистрирован: Чт июл 24, 2014 23:09:23
Откуда: Киев

Сообщение hosturik »

Так тоже пробовал

Код: Выделить всё

// Функция отправки данных по SPI
void Spi_Write_Data(uint8_t *data, uint16_t size){
  if(!LL_SPI_IsActiveFlag_BSY(SPI1)){
	spi_send_dma(data, size);
  }
}
 
Но как я выше написал, такой вариант не работает, потому что я просто пропускаю необходимые данные, например для инициализации дисплея
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="hosturik",url="/forum/viewtopic.php?p=3664061#p3664061"]Но как я выше написал, такой вариант не работает, потому что я просто пропускаю необходимые данные, например для инициализации дисплея[/uquote]
Не нужно пропускать, нужно ждать. Смысл DMA в том, что запустил отправку и что-то делаешь, например, заполняешь данными другой буфер, а когда опять нужна запись в SPI, то уже ждешь завершения предыдущей передачи.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

hosturik, в F0 у SPI есть FIFO , есть нюансы с обращением к буферу. Все это не расскажет вам калокуб...
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 354
Зарегистрирован: Чт июл 24, 2014 23:09:23
Откуда: Киев

Сообщение hosturik »

А как мне выйти с положения, может есть какое то решение?
[uquote="hosturik",url="/forum/viewtopic.php?p=3663997#p3663997"]Мне нужно добиться быстрое выполнение программы в главном цикле где вызываются все функции работы с дисплеем.
Сейчас главный цикл крутится всего 10 раз в секунду примерно, что очень мало.[/uquote]
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пн дек 07, 2009 16:00:31

Сообщение rai17 »

[uquote="dosikus",url="/forum/viewtopic.php?p=3664059#p3664059"]Еще раз- счетчик таймера не останавливается при бряках...[/uquote]

Всё равно не ясно, в первом случае "останавливается" строго по плану, а во втором тож вроде "останавливается" (цифирьки перестают бежать).
В любом случае, спасибо за помощь.
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Вам jcxz уже отписался как надо смотреть подобные вещи. А ранее я писал о том как фризить таймер.
Но, подобные вещи отлаживать лучше лог.анализатором, выводя маркеры на пины
Последний раз редактировалось dosikus Ср июл 10, 2019 11:43:22, всего редактировалось 1 раз.
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="hosturik",url="/forum/viewtopic.php?p=3664073#p3664073"]А как мне выйти с положения, может есть какое то решение?[/uquote]
Для начала вынеси проверку вперед и добавь второй буфер... И что там вообще на дисплей выводится, раз такой фпс? Дисплей 320x240 можно за ~80ms полностью текстом забить при 48 тактовой, без DMA, но не делать же это каждый кадр...
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 354
Зарегистрирован: Чт июл 24, 2014 23:09:23
Откуда: Киев

Сообщение hosturik »

Выводится текст, картинки-пиктограммы и фигуры, типа прямоугольников и линий.
Ну у меня примерно так и есть, примерно ~100ms обновление экрана, SPI по даташиту в нем максимум 10 мегагерц, хотя я передаю на 12.
Хоть с DMA хоть без него, на скорость обновления это не влияет
Это теоретический предел обновления обновления для этой частоты.
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="hosturik",url="/forum/viewtopic.php?p=3664093#p3664093"]Выводится текст, картинки-пиктограммы и фигуры, типа прямоугольников и линий.
Ну у меня примерно так и есть, примерно ~100ms обновление экрана[/uquote]
Зачем это все выводить постоянно?
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

hosturik, а DMA еще и в циркулярном режиме поди?
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 354
Зарегистрирован: Чт июл 24, 2014 23:09:23
Откуда: Киев

Сообщение hosturik »

dosikus Да нет, в обычном режиме, без кольцевого буфера

Reflector Как вариант, можно некоторые элементы вывести один раз и больше не выводить, а таких элементов половина от общего количества, это раза в два повысит скорость обновления,
Можно подробнее про второй буфер, как его нужно использовать?
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="hosturik",url="/forum/viewtopic.php?p=3664110#p3664110"]Reflector Как вариант, можно некоторые элементы вывести один раз и больше не выводить, а таких элементов половина от общего количества, это раза в два повысит скорость обновления[/uquote]
А что с оставшейся половиной? Неужели эти элементы меняются десятки раз в секунду? Это уже какая-то игра должна быть или демка...
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 354
Зарегистрирован: Чт июл 24, 2014 23:09:23
Откуда: Киев

Сообщение hosturik »

Мониторинг различных параметров: тока, напряжения, мощности и графики для отображения всего этого.
Выводить обновленные цифры только тогда, если данные изменились, по мере необходимости?
Хорошая идея, нужно будет попробовать, по идее это должно прилично увеличить скорость выполнения программы в главном цикле.
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="hosturik",url="/forum/viewtopic.php?p=3664110#p3664110"]Можно подробнее про второй буфер, как его нужно использовать?[/uquote]
Просто чередуешься два буфера, пока из одного идет отправка заполняется второй, потом отправляешь из него, а заполняешь первый. Если время заполнения достаточно велико, то и экономия может быть существенной.

[uquote="hosturik",url="/forum/viewtopic.php?p=3664117#p3664117"]Выводить обновленные цифры только тогда, если данные изменились, по мере необходимости?[/uquote]
Конечно, даже может реже, все равно бессмысленно обновлять данные 10 раз в секунду.
Мудрый кот
Сообщения: 1846
Зарегистрирован: Вт авг 15, 2017 10:51:13

Сообщение jcxz »

[uquote="rai17",url="/forum/viewtopic.php?p=3663950#p3663950"]Смотрю в View-System Viewer-TIM-TIM1-CNT (повторюсь, пользуюсь Keil).
Так вот (опять же повторяюсь), при установки breakpoint на вход в ISR TIM1 в симуляторе (Use Simulator) всё отлично - вижу 0х0000, а вот при подключении платы с прошитым камнем STM32F103С8Т6 по SWD через ST-Link V2 (Use: ST-Link Debugger) – получаются вообще случайные значения в View-System Viewer-TIM-TIM1-CNT.[/uquote]
Вот именно поэтому и не нужно использовать симулятор. Сами видите же - что толку от него ==0 при отладке работы с периферией.
Скопируйте нужный периферийный регистр в локальную переменную (static int volatile var) на входе в ISR до брекпоинта. И смотрите эту переменную.

Добавлено after 12 minutes 31 second:
[uquote="hosturik",url="/forum/viewtopic.php?p=3664073#p3664073"]А как мне выйти с положения, может есть какое то решение?[/uquote]
Вообще по уму DMA-транзакции с SPI-шиной завершают не по завершению передачи, а по завершению приёма. Если конечно знать - что такое SPI и что на ней передача идёт почти одновременно с приёмом. Тогда и FIFO любой глубины не страшно :kill:
Если только конечно не используете однопроводный (2-направленный по одному проводу SPI). В этом случае сложнее: тогда завершение TX-DMA без поллинга можно ждать зарядив таймер на некоторую выдержку после уведомления от TX-DMA-канала о завершении передачи блока. Выдержку посчитать исходя из размера FIFO. Ну или завести низкоприоритетную задачу и поллить в ней, не мешая работе полезных задач.

Добавлено after 5 minutes 56 seconds:
[uquote="hosturik",url="/forum/viewtopic.php?p=3664093#p3664093"]Ну у меня примерно так и есть, примерно ~100ms обновление экрана, SPI по даташиту в нем максимум 10 мегагерц, хотя я передаю на 12.[/uquote]
Не верь даташиту! У меня LCD на ILI9341 320x240 в проекте работает с SCLK <= 45МГц. 8)

[uquote="hosturik",url="/forum/viewtopic.php?p=3664093#p3664093"]Это теоретический предел обновления обновления для этой частоты.[/uquote]
Нет конечно. На STM32F429 на 180МГц у меня обновляется хоть на полной скорости 45МГц. Хотя сейчас стоит 160МГц тактовая и соответственно - SCLK=40МГц.

Добавлено after 9 minutes 22 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3664121#p3664121"]Конечно, даже может реже, все равно бессмысленно обновлять данные 10 раз в секунду.[/uquote]
Если есть какая-то динамика и графические элементы её отображающие - то нормально. Например если график или какой-то линейный/круговой индикатор - выше частота - плавнее двигается.
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пн дек 07, 2009 16:00:31

Сообщение rai17 »

[uquote="jcxz",url="/forum/viewtopic.php?p=3664249#p3664249"]Скопируйте нужный периферийный регистр в локальную переменную (static int volatile var) на входе в ISR до брекпоинта. И смотрите эту переменную.[/uquote]
Ок, буду пробовать.
Ответить

Вернуться в «ARM»