Easyelectronics.ru

Электроника для всех
Текущее время: 29 окт 2020, 22:40

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 4 ] 
Автор Сообщение
 Заголовок сообщения: DMA для SPI в коротких сессиях
СообщениеДобавлено: 08 авг 2012, 17:37 
Старожил
Аватара пользователя

Зарегистрирован: 14 окт 2011, 15:46
Сообщения: 221
Откуда: Новосибирск
посматривая примеры (скажем для nRF24L01+) смотрю что мало кто пользуется DMA.
с другой стороны, там DMA само по себе эффективно только для приема посылки, а при настройке или скажем переключении приема/передачи или еще чего - там получается кидаешь по 1 байту по SPI и ждешь ответа, потом снова байт-два.
более того, каждая новая сессия должна начинаться с дрыганья ножкой nCS.

вопрос: как эффективно в таких ситуациях использовать DMA?
у меня ничего умнее, чем дернул ногой, настроил DMA на передачу скажем 2 байт и ждешь в цикле окончания, потом снова дернул и т.д. (даже если ответы не обрабатывать).
в идеале, было бы накидать пачку запросов, байт 10, но к DMA еще приделать сбоку "дергалку" ножкой nCS.
или так нереально сделать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA для SPI в коротких сессиях
СообщениеДобавлено: 08 авг 2012, 21:04 
Только пришел

Зарегистрирован: 26 дек 2010, 01:06
Сообщения: 21
kab писал(а):
в идеале, было бы накидать пачку запросов, байт 10


По моему можно сделать так:
Настроить один канал DMA чтоб запысывал "запросы" с кругового буффера в SPI
Настроить другой канал DMA kot. загонял данные с кругового буффера длиной 2 байта (содержаящего 0x00 и 0x01) в "bit band" регион GPIO nCS
Настроить два модуля захвата таимера: один в "Edge-aligned PWM mode" кот. запускает DMA "запросов" a второй модуль захвата в "PWM center-aligned mode" кот. запускат DMA "nCS" (два раза за одно переполнение таймера - по счету Up и Down)

Чтоб коерктно работало, надо чтоб сначало сработало DMA "nCS", потом DMA "запросов" и было достаточно времени чтоб сам SPI выстрелил биты наружу, потом уже сработал DMA "nCS" чтоб деактивировать "nCS".

После окончания передачи N запросов генерировать прерывание DMA "запросов", в кот. останавливать таймер.

Сам етого не делал, думаю должно получится.
У меня работает отправка буффер строки через DMA на медленное SPI LCD по запросу таймера (на каждые 30ms).Если надо, поделюсь кодом.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA для SPI в коротких сессиях
СообщениеДобавлено: 08 авг 2012, 23:43 
Старожил
Аватара пользователя

Зарегистрирован: 14 окт 2011, 15:46
Сообщения: 221
Откуда: Новосибирск
да, в принципе так можно, но что-то шибко сложно получается...плюс там еще анализ внутри... я пробовал protothreads, чтобы высвободить процик для полезных дел, но что-то профита не много...

для примера - типовая функция передачи пакета:
Код:
void vNrfSend(uint8_t * addr, uint8_t *data, uint8_t len)
{
   uint8_t status;
   static uint8_t last_addr[NRF_ADR_LEN];

   while (g_uNrfTx)   // this should be never executed code!
   {
      status = uNrfReadReg(STATUS); // читаем 2 байта через SPI
      if (status & ( (1 << TX_DS) | (1 << MAX_RT) ) )
      {
         uNrfWriteReg(STATUS, (1 << TX_DS) | (1 << MAX_RT)); // пишем 2 байта по SPI
         g_uNrfTx=0;
         break;
      }
   }

   if (memcmp(last_addr, addr, 5)!=0)
   {
      memcpy(last_addr, addr, 5);
      uNrfWriteBuf(TX_ADDR, addr, NRF_ADR_LEN); // пишем 1+5 байт
      uNrfWriteBuf(RX_ADDR_P0, addr, NRF_ADR_LEN); // пишем 1+5 байт
   }

   CE_L();
   vNrfPowerUpTx();  // внутри дерганье ножкой + 3 посылки по 2 байта
   vNrfFlushTx(); // посылка 1 байт по SPI
   uNrfWriteBuf(W_TX_PAYLOAD, data, len); // до 32 байт посылка по SPI
   CE_H();
}


любое xNrfWriteXXX/xNrfReadXXX по сути или передача 2 байтов по SPI или большего количества (для адреса - 1+5, для буфера до 32).
в итоге профит видится только в посылке буфера, но опять же, я не могу сделать следующий шаг (PowerUpTx), до того, как закончится передача предыдущего... поэтому и пытаюсь придумать как сделать вариабельные посылки с одновременным дрыганьем ножкой, но что-то в голову идет только сложная схема с кучей interrupt-ов и сложной структурой. проще уж тогда просто последовательно передавать...

p.s. за пример и совет спасибо, логику понял, может на досуге займусь. примеров DMA у мя много, опять же спасибо. лучше всего DMA получается использовать для usart.
p.p.s. как вариант - *rtos, но что-то у меня с ними нелады - не, все работает нормально, но не нравится сама схема rtos + на переключение контекстов время уходит... проще уж protothreads...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: DMA для SPI в коротких сессиях
СообщениеДобавлено: 09 авг 2012, 22:29 
Старожил

Зарегистрирован: 25 апр 2010, 10:13
Сообщения: 1927
Откуда: Томск
разбираюсь с таймерами в STM32, так вот, там есть режим burst DMA, теоретически(еще не пробовал) позволяющий заливать настройки таймера из памяти, т.е. подготовил несколько настроек таймеров в памяти, пнул - и DMA по сигналу от update таймера эти шаблоны последовательно заливает в таймер. Возможно можно так запрограммировать управление протоколом по SPI.

_________________
Какое небо голубое....(с) лиса Алиса


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 4 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB