реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> DAC + DMA в STM32F2xx
Acvarif
сообщение Feb 22 2012, 07:58
Сообщение #16


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(scifi @ Feb 22 2012, 11:44) *
Что-то не сходится: 120000 Гц * 16 бит = 1.92 Мбит/с.
У меня гонял данные с частотой 20 МГц из буфера в памяти на GPIO (внешний DAC). Если умножить на 16 бит, то это 320 Мбит/с.

Виноват.
Еще * на 48 каналов - 120 000*16*48 = 92.16 Мбит/сек
Надеюсь stm32 справится.

Цитата
Вот с DMA:

Спасибо.
Попробую.

Сообщение отредактировал Acvarif - Feb 22 2012, 08:02
Go to the top of the page
 
+Quote Post
uriy
сообщение Feb 22 2012, 08:21
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



Как это понимать?
Код
TIM2->CR1 = 0;                  // count up, no divisor
TIM6->PSC = timer_prescaler;    // prescaler

Сперва TIM2 потом TIM6
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 22 2012, 08:29
Сообщение #18


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Опечатка, должно быть TIM6.
Но и так будет работатьsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 22 2012, 08:34
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Acvarif @ Feb 22 2012, 11:39) *
(92.16 Мбит/сек) c дальнейшей их передачей по Ethernet на ПК
Похоже, что должен справиться.

Я думаю, собрать данные удастся. А вот прокачать 92 Мбит/с на ПК - нетривиальная задача. Даже не всякий ПК справится. Внутренней памяти МК хватает на буферизацию всего нескольких миллисекунд. Я думаю, не всякий сетевой стек потянят: нужно будет оптимизировать под задачу. Возможно, следует сразу отказаться от TCP и делать на UDP.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Feb 22 2012, 08:39
Сообщение #20


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(scifi @ Feb 22 2012, 12:34) *
Я думаю, собрать данные удастся. А вот прокачать 92 Мбит/с на ПК - нетривиальная задача. Даже не всякий ПК справится. Внутренней памяти МК хватает на буферизацию всего нескольких миллисекунд. Я думаю, не всякий сетевой стек потянят: нужно будет оптимизировать под задачу. Возможно, следует сразу отказаться от TCP и делать на UDP.

Ну конечно UDP.
Уже проверялось UDP + LwIP. Вроде тянет 95.
Буду пытаться сделать качели - пока первая половина буфера заполняется, другая передается.
DMA вроде так позволяет (прерывания по заполнению пол.. всего буфера).
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 22 2012, 08:42
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Acvarif @ Feb 22 2012, 12:39) *
Уже проверялось UDP + LwIP. Вроде тянет 95.
Буду пытаться сделать качели - пока первая половина буфера заполняется, другая передается.
DMA вроде так позволяет (прерывания по заполнению пол.. всего буфера).

Шансы есть. Если Ethernet драйвер там правильный, то будет zero-copy. Должен потянуть.
Go to the top of the page
 
+Quote Post
uriy
сообщение Feb 22 2012, 10:56
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



AHTOXA спасибо! Все заработало проблема была в том что я пытался использовать DMA1. Похоже копипастом натыкал.
Go to the top of the page
 
+Quote Post
Sekat
сообщение Mar 4 2012, 11:33
Сообщение #23


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 13-02-12
Пользователь №: 70 242



Цитата(scifi @ Feb 22 2012, 11:23) *
Конечно заработает. И не такое работало.
Предвидя дальнейшие вопросы, даю подсказку: таймеры могут формировать запросы DMA по событию Capture, которое может вызываться фронтом на входе таймера.
И вообще таймеры в STM32 весьма мощные и позволяют творить чудеса. При условии, что не запутаетесь и правильно их запрограммируете.

Вопрос не имеет смысла и вскрывает глубинное непонимание принципа работы DMA.
Номер стрима определяет выбор источников сигнала запроса DMA. Он не определяет адрес источника и приёмника данных.


Добрый день всем!

Мучаюсь с обратной задачей. Из памяти вывести поток данных на параллельный порт с помощью DMA.
Конструкция TIM6 + DMA1 Stream1 Channel7 формирует Event. DMA начинает выводить полуслово в порт E (GPIOE_ODR) после первой же попытки (видно, что DMA_S1NDTR декрементировался) все заканчивается с флагом Stream 1 transfer error interrupt.

Прямой вывод данных в GPIOE_ODR из тела программы при этом дает отличный результат!

В чем грабли?
Go to the top of the page
 
+Quote Post
Sekat
сообщение Mar 4 2012, 13:31
Сообщение #24


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 13-02-12
Пользователь №: 70 242



Цитата(Sekat @ Mar 4 2012, 15:33) *
В чем грабли?


Подробности к проблеме из предыдущего поста.
1. Процессор - STM32F407 .
2. Инициализация GPIO для вывода в порт Е:

Код
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
  GPIO_InitStructure.GPIO_Pin = 0xffff;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOE, &GPIO_InitStructure);


3. Инициализация таймера TIM6:
Код
  TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Period = 0x200;    
  TIM_TimeBaseStructure.TIM_Prescaler = 0;      
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;    
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
  TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);

  TIM_Cmd(TIM6, ENABLE);


3. Инициализация DMA:

Код
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);
  DMA_DeInit(DMA1_Stream1);
  DMA_InitTypeDef DMA_InitStructure;
  DMA_InitStructure.DMA_Channel = DMA_Channel_7;  
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) GPIOE_ODR;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&Sine12bit;
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
  DMA_InitStructure.DMA_BufferSize = 32;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;        
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA1_Stream1, &DMA_InitStructure);
  DMA_Cmd(DMA1_Stream1, ENABLE);
  TIM_DMACmd(TIM6, TIM_DMA_Update, ENABLE);


Этот код слегка переделанный пример от IAR вывода во внутренний DAC.

4. Что удивительно. Если подставить вместо GPIOE_ODR например адрес встроенного DAC, то DMA начинает пересылать данные без ошибки.
5. Что примечательно. Если реверсировать передачу данных (поменять направление - от порта в память, естественно память разместить в RAM), результат тот же - ошибка передачи DMA!

Пункты 4 и 5 внушают пессимизм. Неужели обращение DMA к параллельному порту в STM32F посредством DMA невозможно?

Надеюсь все же, что это мои грабли

Сообщение отредактировал Sekat - Mar 4 2012, 13:34
Go to the top of the page
 
+Quote Post
Sekat
сообщение Mar 6 2012, 06:15
Сообщение #25


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 13-02-12
Пользователь №: 70 242



Цитата(Sekat @ Mar 4 2012, 17:31) *
4. Что удивительно. Если подставить вместо GPIOE_ODR например адрес встроенного DAC, то DMA начинает пересылать данные без ошибки.
5. Что примечательно. Если реверсировать передачу данных (поменять направление - от порта в память, естественно память разместить в RAM), результат тот же - ошибка передачи DMA!

Пункты 4 и 5 внушают пессимизм. Неужели обращение DMA к параллельному порту в STM32F посредством DMA невозможно?

Надеюсь все же, что это мои грабли


Пока нет обсуждения, продолжаю излагать хронологию борьбы с проблемой.
По пунктам 4,5 выяснилось, что в этой ситуации вся периферия с адресами < 0x40010000 работает без ошибок, в частности и встроенный DAC. Ага, подумал я. И поменял DMA2 на DMA1, таймер6 на таймер8. Заработало с GPIO. Сколько не искал ссылок на эти ограничения в "RM0090 Reference manual" так и не смог найти. Видимо плохо искал, что не мудрено - легко заблудиться в почти полутора тысячах страниц.

Как бы то ни было - теперь работает с параллельным выводом в GPIO. Однако борюсь со следующей проблемой; - ко всей этой конструкции хочу прикрутить FIFO с Burst. Возможно ли в принципе учинить такое для параллельного порта?

Пока что картина следующая. Фифо с берстом работают исправно по таймеру, пересылая заданную пачку байтов. Однако в параллельный порт эта вся пачка пересылается очень быстро - похоже, что с максимально возможной скоростью шины, а вовсе не по EVENT таймера.

Хотелось бы, что бы данные пересылались в параллельный порт по EVENTу, а буфер фифо обновлялся бы берстом по мере необходимости. Как такое сделать???
Go to the top of the page
 
+Quote Post
Flexz
сообщение Mar 6 2012, 06:28
Сообщение #26


Местный
***

Группа: Свой
Сообщений: 252
Регистрация: 9-10-08
Из: Московская обл.
Пользователь №: 40 797



По неработающей периферии - посмотрите раздел "2.1 System architecture". У DMA1 не упоминается периферийная шина и на схеме он не соединен с AHB-периферией, вероятно, причина в этом.

А фифо как настраиваете? там же отдельно есть настроки Memory burst и Peripheral burst.
Go to the top of the page
 
+Quote Post
Sekat
сообщение Mar 6 2012, 12:03
Сообщение #27


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 13-02-12
Пользователь №: 70 242



Цитата(Flexz @ Mar 6 2012, 10:28) *
По неработающей периферии - посмотрите раздел "2.1 System architecture". У DMA1 не упоминается периферийная шина и на схеме он не соединен с AHB-периферией, вероятно, причина в этом.

А фифо как настраиваете? там же отдельно есть настроки Memory burst и Peripheral burst.


Да, действительно, согласно этому разделу DMA2 peripheral bus есть, а такой же для DMA1 нет. Однако, заработало то у меня именно с DMA1. К тому же DMA2 замечательно работает с адресами меньше 0x40010000 - есть пример от IAR с DAC. Не проверял работу DMA1 с адресами <0x40010000, но не удивлюсь, если окажется, что не работает. Такое своеобразное разделение между двумя DMA по адресному пространству. Однако обнаружить эти особенности в каких-либо руководствах не удалось.

Настройки фифо и бёрст достаточно тривиальны, здесь сложно сильно ошибиться:
Код
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;        
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC8;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC8;

Настораживает то, что GPIO нет специальных настроек разрешения работы с DMA, как например есть у другой периферии.

Сообщение отредактировал Sekat - Mar 6 2012, 12:05
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 6th July 2025 - 21:02
Рейтинг@Mail.ru


Страница сгенерированна за 0.01484 секунд с 7
ELECTRONIX ©2004-2016