Миландр

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

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




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
СообщениеДобавлено: 2017-янв-23 18:13 
Не в сети

Зарегистрирован: 2016-янв-22 15:45
Сообщения: 21
Здравствуйте. Работаю с микроконтроллером 1986ВЕ91Т.
Последовательный порт SSP2 работает в режиме ведомого устройства.
Задача в том, чтобы по последовательному порту принимать и передавать по 64 байта данных 8000 раз в секунду.
Использую контроллер прямого доступа в память DMA.
Использую режим PingPong, 2 канала DMA: 1 - DMA_Channel_SSP2_RX - на приём данных по порту, другой - DMA_Channel_SSP2_TX - на передачу.
У каждого канала по 2 структуры управляющих данных канала.
После включения последовательного порта командой SSP_Cmd(MDR_SSP2, ENABLE)
происходит передача данных и прием, но только 1 раз.
А надо, чтобы 8000 раз в секунду этот процесс происходил.
Желательно, чтобы это происходило в фоне, без прерываний. 1 раз запустил и всё.

Если с прерываниями, то прерывание почему-то не 8000 раз вызывается, а намного меньше.
Код:
DMA_DeInit();
      DMA_StructInit(&DMA_InitStrRcv);

      /* Disable all DMA request */
      MDR_DMA->CHNL_REQ_MASK_SET = 0xFFFFFFFF;
      MDR_DMA->CHNL_USEBURST_SET = 0xFFFFFFFF;
      
      /* Disable all interrupt */
      NVIC->ICPR[0] = 0xFFFFFFFF;
      NVIC->ICER[0] = 0xFFFFFFFF;

      SPI1->SSPx_DMACR=0;
      SPI2->SSPx_DMACR=0;

      /* DMA_Channel_SSP2_ТX configuration ---------------------------------*/
      /* Set Primary Control Data */

      DMA_PriCtrlStrSnd.DMA_SourceBaseAddr = (uint32_t)SrcBuf1;
      DMA_PriCtrlStrSnd.DMA_DestBaseAddr = (uint32_t)(&(MDR_SSP2->DR));
      DMA_PriCtrlStrSnd.DMA_SourceIncSize = DMA_SourceIncByte;
      DMA_PriCtrlStrSnd.DMA_DestIncSize = DMA_DestIncNo;
      DMA_PriCtrlStrSnd.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
      DMA_AltCtrlStrSnd.DMA_Mode = DMA_Mode_PingPong;
      DMA_PriCtrlStrSnd.DMA_CycleSize = 64;
      DMA_PriCtrlStrSnd.DMA_NumContinuous = 7;
      DMA_PriCtrlStrSnd.DMA_SourceProtCtrl = DMA_SourceBufferable;
      DMA_PriCtrlStrSnd.DMA_DestProtCtrl = DMA_DestBufferable;

      DMA_AltCtrlStrSnd.DMA_SourceBaseAddr = (uint32_t)SrcBuf2;
      DMA_AltCtrlStrSnd.DMA_DestBaseAddr = (uint32_t)(&(MDR_SSP2->DR));
      DMA_AltCtrlStrSnd.DMA_SourceIncSize = DMA_SourceIncByte;
      DMA_AltCtrlStrSnd.DMA_DestIncSize = DMA_DestIncNo;
      DMA_AltCtrlStrSnd.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
      DMA_AltCtrlStrSnd.DMA_Mode = DMA_Mode_PingPong;
      DMA_AltCtrlStrSnd.DMA_CycleSize = 64;
      DMA_AltCtrlStrSnd.DMA_NumContinuous = 7;
      DMA_AltCtrlStrSnd.DMA_SourceProtCtrl = DMA_SourceBufferable;
      DMA_AltCtrlStrSnd.DMA_DestProtCtrl = DMA_DestBufferable;

      /* Set Channel Structure */
      DMA_InitStrSnd.DMA_PriCtrlData = &DMA_PriCtrlStrSnd;
      DMA_InitStrSnd.DMA_AltCtrlData = &DMA_AltCtrlStrSnd;
      DMA_InitStrSnd.DMA_Priority = DMA_Priority_High;
      DMA_InitStrSnd.DMA_UseBurst = DMA_BurstClear;
      DMA_InitStrSnd.DMA_ProtCtrl = DMA_AHB_Privileged;
      DMA_InitStrSnd.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY;

      /* Init DMA channel */
      DMA_Init(DMA_Channel_SSP2_TX, &DMA_InitStrSnd);

      DMA_Cmd(DMA_Channel_SSP2_TX,ENABLE);

      /* DMA_Channel_SSP2_RX configuration ---------------------------------*/
      /* Set Primary Control Data */
      
      DMA_PriCtrlStrRcv.DMA_SourceBaseAddr = (uint32_t)(&(MDR_SSP2->DR));
      DMA_PriCtrlStrRcv.DMA_DestBaseAddr = (uint32_t)DstBuf1;
      DMA_PriCtrlStrRcv. DMA_SourceIncSize = DMA_SourceIncNo;
      DMA_PriCtrlStrRcv.DMA_DestIncSize = DMA_DestIncByte;
      DMA_PriCtrlStrRcv.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
      DMA_PriCtrlStrRcv.DMA_Mode = DMA_Mode_PingPong;
      DMA_PriCtrlStrRcv.DMA_CycleSize = 64;
      DMA_PriCtrlStrRcv.DMA_NumContinuous = 7;
      DMA_PriCtrlStrRcv.DMA_SourceProtCtrl = DMA_SourceBufferable;
      DMA_PriCtrlStrRcv.DMA_DestProtCtrl = DMA_DestBufferable;                 

      DMA_AltCtrlStrRcv.DMA_SourceBaseAddr = (uint32_t)(&(MDR_SSP2->DR));
      DMA_AltCtrlStrRcv.DMA_DestBaseAddr = (uint32_t)DstBuf2;
      DMA_AltCtrlStrRcv.DMA_SourceIncSize = DMA_SourceIncNo;
      DMA_AltCtrlStrRcv.DMA_DestIncSize = DMA_DestIncByte;
      DMA_AltCtrlStrRcv.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
      DMA_AltCtrlStrRcv.DMA_Mode = DMA_Mode_PingPong;
      DMA_AltCtrlStrRcv.DMA_CycleSize = 64;
      DMA_AltCtrlStrRcv.DMA_NumContinuous = 7;
      DMA_AltCtrlStrRcv.DMA_SourceProtCtrl = DMA_SourceBufferable;
      DMA_AltCtrlStrRcv.DMA_DestProtCtrl = DMA_DestBufferable;

      /* Set Channel Structure */
      DMA_InitStrRcv.DMA_PriCtrlData = &DMA_PriCtrlStrRcv;
      DMA_InitStrRcv.DMA_AltCtrlData = &DMA_AltCtrlStrRcv;
      DMA_InitStrRcv.DMA_Priority = DMA_Priority_High;
      DMA_InitStrRcv.DMA_UseBurst = DMA_BurstSet;
      DMA_InitStrRcv.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY;

      /* Init DMA channel */
      DMA_Init(DMA_Channel_SSP2_RX, &DMA_InitStrRcv);//
      
      DMA_Cmd(DMA_Channel_SSP2_RX,ENABLE);

      /* Enable SSP2 DMA Rx and Tx request */
      SSP_DMACmd(MDR_SSP2,(SSP_DMA_RXE | SSP_DMA_TXE), ENABLE);
      
      SSP_Cmd(MDR_SSP2, ENABLE);


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2017-янв-24 11:58 
Не в сети

Зарегистрирован: 2010-сен-21 12:57
Сообщения: 613
Откуда: г. Санкт-Петербург
lindstorm писал(а):
...
Желательно, чтобы это происходило в фоне, без прерываний. 1 раз запустил и всё...

По моему мнению без прерываний не получится.
Для непрерывной работы в режиме пинг-понг нужно после приема/передачи очередных 64 байт обрабатывать 2 запроса прерывания от DMA(одно по приему, другое по передачи), в которых обновлять данные (channel_cfg) в управляющей структуре (pri/alt) с которой закончил работу контроллер DMA. т.о. в Вашем случае нужно будет успевать обрабатывать 2 прерывания каждые 125 мкс.
P.S. регистр данных SSP (DR) описан как 32-х битный, можно ли со стороны контроллера DMA обращаться к нему как к 8-ми битному из описания не известно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2017-фев-22 10:52 
Не в сети

Зарегистрирован: 2016-мар-26 12:46
Сообщения: 19
Добрый день.
Опишу мою проблему. Master 1986ВЕ92 SPI1 - > подключен к slave 1986ВЕ4У SPI.
Настройка SPI 1986ВЕ92:
SSP_BRGInit(spi->SPIx, SSP_HCLKdiv4);

spi->SPIx->CPSR = 2;
spi->SPIx->CR0= ((SSP_SPO_Low)
| SSP_SPH_1Edge
| (8 << 8)
| SSP_FRF_SPI_Motorola
| SSP_WordLength8b);
spi->SPIx->CR1= (SSP_ModeMaster | SSP_HardwareFlowControl_SSE);
SPI_init_DMA(spi);

Настройка SPI 1986ВЕ4У:

SSP_BRGInit(MDR_SSP1, SSP_HCLKdiv1);
spi->SPIx->CPSR = 12;
spi->SPIx->CR0 = (SSP_SPO_Low
| SSP_SPH_1Edge
| (8 << 8)
| SSP_FRF_SPI_Motorola
| SSP_WordLength8b);
spi->SPIx->CR1 = (SSP_ModeSlave | SSP_HardwareFlowControl_SSE);
SPI_init_DMARX(spi);
SPI_init_DMATX(spi);

ВЕ4 передает массив 32 байта (числа от 1 до 31). ВЕ92 принимает (порядок в принятом массиве)

0x18
0x19
0x1A
0x1B
0x1C
0x1D
0x1E
0x1F
0x01
0x02
0x03
0x04
0x05
0x06
0x07
0x08
0x09
0x0A
0x0B
0x0C
0x0D
0x0E
0x0F
0x10
0x11
0x12
0x13
0x14
0x15
0x16
0x17
0x00

1) принятые данные перетасованны;
2) в конце 0 (не передается).

Смотрю на шину осцилом - порядок данных соблюдается, т.е., что-то происходит на стороне ВЕ92.
Посоветуйте, что мне делать. Спасибо и Всех с Наступающим праздником.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2017-фев-27 07:47 
Не в сети

Зарегистрирован: 2010-авг-30 19:12
Сообщения: 361
1.Передача данных однократная или циклическая?
Если циклическая - то обычная рассинхронизация. Ведомый опаздывает на прием, поэтому фиксирует данные с середины буфера.
2.
Цитата:
32 байта (числа от 1 до 31) ... 2) в конце 0 (не передается).

от 1 до 31 это 31 байт. Если буфер на 32 байта, то 0 в конце буфера - закономерность, этот байт ведь не инициализирован.

_________________
О сколько нам открытий чудных
Готовит просвященья дух,
И опыт - сын ошибок трудных ... (Пушкин)

Пергаменты не утоляют жажду ("Фауст",Гете)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2017-фев-28 11:41 
Не в сети

Зарегистрирован: 2016-мар-26 12:46
Сообщения: 19
С настройками частот похоже все нормально (были подозрения). Еще раз, что я делаю в программе.
ВЕ92 - мастер, ВЕ4У - ведомый. Режим опроса - полудуплекс. ВЕ92 посылает байт - ВЕ4У принимает (нормально) и после анализа отвечает (для простоты оставил в ответе 5 байт). Что вижу на осцилографе: ВЕ4У начинает отвечать в момент когда должен принимать, и только, байт посланный ВЕ92. Похоже проблема в этом, но где подправить?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2017-фев-28 17:31 
Не в сети

Зарегистрирован: 2016-мар-26 12:46
Сообщения: 19
Получил следующий результат:
ВЕ92 запрашивает пакет
SPI_Recv_Data(&spi1, tst, 8);
SPI_Send_Data(&spi1, RdCMD, 8);
ВЕ4У передает пакет
SPI_Recv_Data(spi, &cmd, 1);
osSemaphoreWait(spi->sem_rxrdy, osWaitForever);
switch (cmd){
case 0x80:
SPI_Send_Data(&spi1, test, 8);
break;
}
Тестовый пакет размера 8 байт пролетает нормально. Если я увеличиваю размер (9,10,...,32) то пакет передается не верно. Куда нужно смотреть?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2017-мар-01 08:32 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 968
Откуда: Тула
Видимо пишите в fifo не учитывая что оно всего на 8 элементов.

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2017-мар-01 10:21 
Не в сети

Зарегистрирован: 2016-мар-26 12:46
Сообщения: 19
Я указываю адрес массива на передачу и его размер DMA и запускаюего. В примере из SPL по моему также.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2017-мар-01 12:19 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 968
Откуда: Тула
Не учёл DMA. Возможно нужно проверить и откорректировать значение полей настройки ДМА (чтобы одна передача билась на несколько по 8 байт, возможно что-то типа R_power = 3 или DMA_CycleSize = 8;).

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2017-мар-03 15:25 
Не в сети

Зарегистрирован: 2016-мар-26 12:46
Сообщения: 19
Не знаю как решить данную проблему, но обошел, ограничил посылку пакетом 8x16 битных слов. Пока так, потом, возможно, вернусь.


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

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


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

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


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

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