Миландр

Ключевым подразделением нашей компании является Центр Проектирования интегральных микросхем
Текущее время: 2018-ноя-20 16:10

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




Начать новую тему Ответить на тему  [ Сообщений: 7 ] 
Автор Сообщение
 Заголовок сообщения: SPI DMA
СообщениеДобавлено: 2015-июн-01 20:35 
Не в сети

Зарегистрирован: 2014-июл-07 17:48
Сообщения: 17
Добрый день.
Интересует вопрос использования DMA для приема и выдачи данных по SPI.
Столкнулся с проблемами при попытке реализовать, хотелось бы прояснить.В примерах было что-то похожее, но выдавалось мало слов.

Есть необходимость выдать, допустим, 512 слов за раз по SPI. Можно сделать цикл для выдачи с проверкой бита буфера передатчика и выдавать, вопросов нет, работает, но как-то некрасиво, а с приемом и того нехорошо с прерываниями. Имеется опыт работы с другим процессором, где можно использовать DMA примерно следующим образом: проинициализировал, запустил и получил прерывание по завершению приема или выдачи. На ВЕ3Т получается DMA контроллер общий для нескольких контроллеров периферии и памяти, поэтому есть арбитраж и все на одном прерывании.

Собственно что получается у меня при выдачи по SPI и какие есть вопросы:
1) SPI контроллер настроен как мастер, в регистре IM ничего не устанавливаем, только в регистре DMACR устанавливаем 2-й бит.Верно ли что в IM ничего не нужно устанавливать или он как-то влияет?

2) Записываем структуру управляющих данных для канала. Из интересного это режим работы DMA основной или авто-запрос (другие не пробовал) и количество передач после которых производится арбитраж. Если арбитраж 8 и более или режим автозапрос, то данные выдаются, но не все, некоторые просто теряются (переполняется буфер видимо). Если арбитраж 2 или 4, то данные выдаются верно, но между выдачами некоторый промежуток(при арбитраже 2 сравнимый со временем передачи). Количество прерываний DMA весьма большое: при выдачи 512 16-битных слов - 257 прерываний. По сути, за те пару миллисекунд выдачи и идут только эти прерывания DMA .

3) Что делать в самом обработчике прерываний DMA? Из примеров видел проверку на окончание выдачи и обнуление DMACR, но при этом в CONTROL управляющих данных для канала записывают выдачу еще раз (для примера?). И еще получается для продолжения выдачи необходимо записывать в регистр CHNL_SW_REQUEST номер канала по которому продолжать выдачу.

4) sreq req ставят немного в ступор... разницы с включенным useburst не заметил или не понял ее

Возможно это самый топорный вариант работы с DMA и есть лучше? Просто не видно выигрыша от использования DMA как такового.
Подскажите правильно ли я понимаю работу DMA на 3T и если есть другие решения, то подскажите с примером на прием и передачу именно больших массивов (по-крайней мере больших чем сам буфер SPI). Сам код при необходимости выложу, просто написано не на Milandr SPL функциях и дефайнах. Приемом пока не занимался, но думаю так так же все специфично.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: SPI DMA
СообщениеДобавлено: 2015-июн-02 09:59 
Не в сети

Зарегистрирован: 2009-май-29 16:09
Сообщения: 590
Откуда: АО "ПКК Миландр"
Очень много есть тем по DMA и SPI а также их комбинации в ветке по 1986ВЕ1Т.
Вот ссылка из одной темы, где реализация DMA+SPI
download/file.php?id=1831


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: SPI DMA
СообщениеДобавлено: 2015-июн-02 21:52 
Не в сети

Зарегистрирован: 2014-июл-07 17:48
Сообщения: 17
Видел этот пример, разбирался на его основе и на других.
Загружал в отладочную плату 1Т - что-то тишина.

Некоторые вещи без которых у меня не работает - там вообще не затронуты, тот же регистр CHNL_SW_REQUEST.

Из непонятного, после окончания выдачи когда уже cycle_ctrl = 0 в управляющей структуре и DMACR = 0 все равно возникают прерывания DMA, где в обработчике опять заход по условию cycle_ctrl = 0.
Про смысл DMA, который каждые 1-4 слова прерывает процессор тоже непонятно. Это так или что-то не так настроено?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: SPI DMA
СообщениеДобавлено: 2015-июн-03 18:56 
Не в сети

Зарегистрирован: 2010-июл-08 08:50
Сообщения: 734
Откуда: АО "ПКК Миландр"
что-то не так настроено. Выложите проект (желательно в среде keil).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: SPI DMA
СообщениеДобавлено: 2015-июн-08 23:29 
Не в сети

Зарегистрирован: 2014-июл-07 17:48
Сообщения: 17
С приемом разобрался, вроде работает нормально. Действительно из сборной солянки проекта не то понабирал при начальной инициализации DMA.
С выдачей проблемы, прерывание все время висит.

Код:
#define DMA_CHAN_TX   4
#define DMA_CHAN_RX   5
//указатель для работы с контроллерами SPI
SSP_t *reg_tx = ARM_SSP2;
SSP_t *reg_rx = ARM_SSP1;
// структура для управления и массивы
DMA_Data_t dma_prim[32] __attribute__((section(".dma_struct")));
uint16_t src_buf[128] __attribute__((section(".dma_struct")));
uint16_t dst_buf[64] __attribute__((section(".dma_struct")));


Таков код на прием, работает, выдает одно прерывание.
Код:
ARM_DMA->ERR_CLR = ARM_DMA_ERR_CLR;
ARM_DMA->CHNL_REQ_MASK_CLR = ARM_DMA_DISABLE_ALL;
ARM_DMA->CHNL_ENABLE_CLR = ARM_DMA_DISABLE_ALL;
ARM_DMA->CTRL_BASE_PTR = (unsigned) dma_prim;
ARM_DMA->CONFIG |= ARM_DMA_ENABLE;
arch_intr_allow (5);
while(1){
    // записываем управляющую структуру
    dma_prim[DMA_CHAN_RX].SOURCE_END_POINTER = (uint32_t)(&(reg_rx->DR));
    dma_prim[DMA_CHAN_RX].DEST_END_POINTER =   (unsigned)dst_buf + sizeof(dst_buf)-2;
    dma_prim[DMA_CHAN_RX].CONTROL = ARM_DMA_DST_INC(ARM_DMA_HALFWORD) |
                     ARM_DMA_DST_SIZE(ARM_DMA_HALFWORD) |
                     ARM_DMA_SRC_INC(ARM_DMA_ADDR_NOINC) |
                     ARM_DMA_SRC_SIZE(ARM_DMA_HALFWORD) |
                     ARM_DMA_RPOWER(ARM_DMA_AFTER2_ARBITR) |
                     ARM_DMA_TRANSFERS(sizeof(dst_buf)/sizeof(dst_buf[0])) |
                     ARM_DMA_BASIC;
   //разрешаем работу канала DMA
    ARM_DMA->CHNL_ENABLE_SET = ARM_DMA_SELECT(DMA_CHAN_RX);
   //разрешаем работу DMA в контроллере SPI
    reg_rx->DMACR = (uint32_t)1;
    while(dma_prim[DMA_CHAN_RX].CONTROL & ARM_DMA_BASIC);
}


Аналогично на передачу, но висит на прерывании.
Код:
ARM_DMA->ERR_CLR = ARM_DMA_ERR_CLR;
ARM_DMA->CHNL_REQ_MASK_CLR = ARM_DMA_DISABLE_ALL;
ARM_DMA->CHNL_ENABLE_CLR = ARM_DMA_DISABLE_ALL;
ARM_DMA->CTRL_BASE_PTR = (unsigned) dma_prim;
ARM_DMA->CONFIG |= ARM_DMA_ENABLE;
arch_intr_allow (5);
for (i = 0; i <(sizeof(src_buf)/sizeof(src_buf[0])); i++){
           src_buf[i] = 0x1000 + i+2;}
while(1){
    dma_prim[DMA_CHAN_TX].SOURCE_END_POINTER = (unsigned)src_buf + sizeof(src_buf)-2;
    dma_prim[DMA_CHAN_TX].DEST_END_POINTER = (uint32_t)(&(reg_tx->DR));
    dma_prim[DMA_CHAN_TX].CONTROL = ARM_DMA_DST_INC(ARM_DMA_ADDR_NOINC) |
                     ARM_DMA_DST_SIZE(ARM_DMA_HALFWORD) |
                     ARM_DMA_SRC_INC(ARM_DMA_HALFWORD) |
                     ARM_DMA_SRC_SIZE(ARM_DMA_HALFWORD) |
                     ARM_DMA_RPOWER(ARM_DMA_AFTER2_ARBITR) |
                     ARM_DMA_TRANSFERS(sizeof(src_buf)/sizeof(src_buf[0])) |
                     ARM_DMA_BASIC;
    ARM_DMA->CHNL_ENABLE_SET = ARM_DMA_SELECT(DMA_CHAN_TX);
    reg_tx->DMACR = (uint32_t)2;
    while(dma_prim[DMA_CHAN_TX].CONTROL & ARM_DMA_BASIC);
}


Сам обработчик прерывания достаточно скромный. Убрал отладочную печать по которой и сужу что висит в прерывании.
Код:
if(!(dma_prim[DMA_CHAN_TX].CONTROL & ARM_DMA_BASIC))
{
  reg_tx->DMACR = (uint32_t)0;
}
if(!(dma_prim[DMA_CHAN_RX].CONTROL & ARM_DMA_BASIC))
{
   reg_rx->DMACR = (uint32_t)0;
}
arch_intr_allow (5);
return 0;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: SPI DMA
СообщениеДобавлено: 2015-июн-11 12:57 
Не в сети

Зарегистрирован: 2010-июл-08 08:50
Сообщения: 734
Откуда: АО "ПКК Миландр"
Попробуйте при инициализации запретить обработку запросов req и sreq от всех каналов (записать 1 во все разряды регистра CHNL_REQ_MASK_SET), разрешить работу всех каналов (записать 1 во все разряды регистра CHNL_ENABLE_SET), далее разрешить обработку запросов только от нужных каналов (записать 1 в разрядах, соответствующих каналам, которые требуется обрабатывать, регистра CHNL_REQ_MASK_CLR).

В разделе описания DMA есть пункт "Правила обмена данным" и далее таблица 394. 19 правило говорит о том, что: "Если dma_req[C] установлен в 1, то контроллер устанавливает dma_done[C] в 1. Это позволяет контроллеру показать центральному процессору запрос готовности, даже если канал выключен (запрещен)", - если dma_done[C] установлен в 1, то инициируется запрос прерывания от DMA. Поэтому предлагаю маскировать запросы от неиспользуемых каналов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: SPI DMA
СообщениеДобавлено: 2015-июн-15 21:34 
Не в сети

Зарегистрирован: 2014-июл-07 17:48
Сообщения: 17
Разобрался, вроде работает. Моя невнимательность была виной. Рекомендация по отключению того что не используется думаю тоже сыграла. Спасибо.


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

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


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

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


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

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB