Миландр

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

Часовой пояс: UTC+03:00




Начать новую тему  Ответить на тему  [ 17 сообщений ]  На страницу 1 2 »
Автор Сообщение
 Заголовок сообщения: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-16 14:45 
Не в сети

Зарегистрирован: 2021-ноя-09 22:45
Сообщения: 11
Организация: НТЦ Техноцентр ЮФУ
Добрый день! Разбираюсь с работой SpaceWire(SpW) на МК. Для передачи информации на скорости 100мбит, необходимо подключить DMA, но возникла проблема с выбором канала для DMA, в "mdr32f8_dma.h" нет каналов напрямую намекающих что они относятся к SpW, в документации на МК написано в таблице 103 что за SPW отвечает 4 и 6 виртуальные каналы, в "mdr32f8_dma.h" на этих каналах находятся DMA_Channel_SSP1_TX и DMA_Channel_SSP2_TX. Вопрос где искать информацию. Код настройки DMA прикреплен.
Открыть
/* DMA Configuration */
/* Reset all DMA settings */
DMA_DeInit();
DMA_StructInit(&DMA_InitStr);
/* Set Primary Control Data */
DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)(MDR_SPW0->FIFORX);
DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)SPW_Read_FIFORX;
DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
DMA_PriCtrlStr.DMA_DestIncSize = DMA_SourceIncWord;
DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_PriCtrlStr.DMA_Mode = DMA_Mode_AutoRequest;
DMA_PriCtrlStr.DMA_CycleSize = 16;
DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1;
DMA_PriCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged;
DMA_PriCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged;

/* Set Channel Structure */
DMA_InitStr.DMA_PriCtrlData = &DMA_PriCtrlStr;
DMA_InitStr.DMA_AltCtrlData = &DMA_AltCtrlStr;
DMA_InitStr.DMA_Priority = DMA_Priority_Default;
DMA_InitStr.DMA_UseBurst = DMA_BurstClear;
DMA_InitStr.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY;

/* Init DMA_Channel_SW1*/
DMA_Init(DMA_Channel_SW1, &DMA_InitStr);

/* Enable dma_req or dma_sreq to generate DMA request */
MDR_DMA->CHNL_REQ_MASK_CLR = DMA_SELECT(DMA_Channel_TIM1);
MDR_DMA->CHNL_USEBURST_CLR = DMA_SELECT(DMA_Channel_TIM1);

/* Enable DMA_Channel_SW1 */
DMA_Cmd(DMA_Channel_SW1, ENABLE);

MDR_DMA->CHMUX0 = 13;//Set TMR1_REQ to DMA ch0
/* Enable DMA IRQ */
NVIC_EnableIRQ(DMA_DONE0_IRQn);
Закрыть


Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-16 15:04 
Не в сети

Зарегистрирован: 2018-мар-18 15:49
Сообщения: 273
Организация: StartMilandr.ru
В 1986ВЕ8Т каналы DMA не привязаны напрямую к периферийным блокам, а подключаются через мультиплексор MUX.
Это позволяет задать приоритет в обслуживании периферии, что нельзя сделать когда каналы привязаны жестко.
(Младший канал DMA имеет приоритет на обработку при арбитраже.)

Есть 8 регистров MUX, в каждом задается выбор 4-х "виртуальных каналов" для 4-х реальных каналов DMA.
MUX0 = dma_ch3_virt_sel | dma_ch2_virt_sel | dma_ch1_virt_sel | dma_ch0_virt_sel


Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-16 15:36 
Не в сети
Support
Аватара пользователя

Зарегистрирован: 2018-авг-10 23:14
Сообщения: 530
Организация: АО «ПКК Миландр»
Откуда: Зеленоград
Открыть обращение пользователя antonakolzin21
antonakolzin21 писал(а): *
Добрый день! Разбираюсь с работой SpaceWire(SpW) на МК. Для передачи информации на скорости 100мбит, необходимо подключить DMA, но возникла проблема с выбором канала для DMA, в "mdr32f8_dma.h" нет каналов напрямую намекающих что они относятся к SpW, в документации на МК написано в таблице 103 что за SPW отвечает 4 и 6 виртуальные каналы, в "mdr32f8_dma.h" на этих каналах находятся DMA_Channel_SSP1_TX и DMA_Channel_SSP2_TX. Вопрос где искать информацию. Код настройки DMA прикреплен.
Открыть
/* DMA Configuration */
/* Reset all DMA settings */
DMA_DeInit();
DMA_StructInit(&DMA_InitStr);
/* Set Primary Control Data */
DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)(MDR_SPW0->FIFORX);
DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)SPW_Read_FIFORX;
DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
DMA_PriCtrlStr.DMA_DestIncSize = DMA_SourceIncWord;
DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_PriCtrlStr.DMA_Mode = DMA_Mode_AutoRequest;
DMA_PriCtrlStr.DMA_CycleSize = 16;
DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1;
DMA_PriCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged;
DMA_PriCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged;

/* Set Channel Structure */
DMA_InitStr.DMA_PriCtrlData = &DMA_PriCtrlStr;
DMA_InitStr.DMA_AltCtrlData = &DMA_AltCtrlStr;
DMA_InitStr.DMA_Priority = DMA_Priority_Default;
DMA_InitStr.DMA_UseBurst = DMA_BurstClear;
DMA_InitStr.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY;

/* Init DMA_Channel_SW1*/
DMA_Init(DMA_Channel_SW1, &DMA_InitStr);

/* Enable dma_req or dma_sreq to generate DMA request */
MDR_DMA->CHNL_REQ_MASK_CLR = DMA_SELECT(DMA_Channel_TIM1);
MDR_DMA->CHNL_USEBURST_CLR = DMA_SELECT(DMA_Channel_TIM1);

/* Enable DMA_Channel_SW1 */
DMA_Cmd(DMA_Channel_SW1, ENABLE);

MDR_DMA->CHMUX0 = 13;//Set TMR1_REQ to DMA ch0
/* Enable DMA IRQ */
NVIC_EnableIRQ(DMA_DONE0_IRQn);
Закрыть
Закрыть
Здравствуйте!

Обратите, пожалуйста, внимание на ответ пользователя StartMilandr. Дополню, что в микроконтроллере 1986ВЕ8Т действительно используется особая система по разбиению каналов DMA (из описания на регистры CHMUX[x] из спецификации):

- Имеются виртуальные каналы DMA, непосредственно связанные с периферией микроконтроллера (см. таблицу 103 "Виртуальные номера запросов DMA" актуальной версии спецификации ТСКЯ.431296.015СП Версия 2.21.0 от 14.05.2021).

- Есть восемь регистров CHMUX, каждый регистр может конфигурировать по четыре уже реальных канала. Таким образом, CHMUX[0] позволяет настроить первые четыре реальных канала DMA из 32 на определенный запрос виртуального канала (в соответствии с таблицей из пункта выше).

Поэтому в Вашем случае необходимо определиться с номером реального канала для запросов DMA от SpaceWire, а далее на него через необходимый регистр CHMUX[x] назначить виртуальный канал SPW0_RX/TX (4 и 6 виртуальные каналы соответственно - нумерация с нуля).

_________________
Отдел технической поддержки support@milandr.ru

Информационный портал отдела технической поддержки support.milandr.ru


Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-16 16:25 
Не в сети

Зарегистрирован: 2021-ноя-09 22:45
Сообщения: 11
Организация: НТЦ Техноцентр ЮФУ
Спасибо за быстрый ответ! Разобрался с регистром CHMUX[x], для SPW нужно записать в CHMUX0 в CHANNEL0 значение 4 . Чтобы использовать DMA CHANNEL0, но тогда возникает вопрос что писать в DMA_Cmd(DMA_Channel_ххх, ENABLE);??? так как непонятно из "mdr32f8_dma.h"
Открыть
/** @defgroup DMA_valid_channels DMA valid channels
* @{
*/
#define DMA_Channel_UART1_TX ((uint8_t)(0))
#define DMA_Channel_UART1_RX ((uint8_t)(1))
#define DMA_Channel_UART2_TX ((uint8_t)(2))
#define DMA_Channel_UART2_RX ((uint8_t)(3))
#define DMA_Channel_SSP1_TX ((uint8_t)(4))
#define DMA_Channel_SSP1_RX ((uint8_t)(5))
#define DMA_Channel_SSP2_TX ((uint8_t)(6))
#define DMA_Channel_SSP2_RX ((uint8_t)(7))
#define DMA_Channel_ADC1 ((uint8_t)(8))
#define DMA_Channel_ADC2 ((uint8_t)(9))
#define DMA_Channel_TIM1 ((uint8_t)(0))//10
#define DMA_Channel_TIM2 ((uint8_t)(11))
#define DMA_Channel_TIM3 ((uint8_t)(12))
#define DMA_Channel_SW1 ((uint8_t)(13))
#define DMA_Channel_SW2 ((uint8_t)(14))
#define DMA_Channel_SW3 ((uint8_t)(15))
#define DMA_Channel_SW4 ((uint8_t)(16))
#define DMA_Channel_SW5 ((uint8_t)(17))
#define DMA_Channel_SW6 ((uint8_t)(18))
#define DMA_Channel_SW7 ((uint8_t)(19))
#define DMA_Channel_SW8 ((uint8_t)(20))
#define DMA_Channel_SW9 ((uint8_t)(21))
#define DMA_Channel_SW10 ((uint8_t)(22))
#define DMA_Channel_SW11 ((uint8_t)(23))
#define DMA_Channel_SW12 ((uint8_t)(24))
#define DMA_Channel_SW13 ((uint8_t)(25))
#define DMA_Channel_SW14 ((uint8_t)(26))
#define DMA_Channel_SW15 ((uint8_t)(27))
#define DMA_Channel_SW16 ((uint8_t)(28))
#define DMA_Channel_SW17 ((uint8_t)(29))
#define DMA_Channel_SW18 ((uint8_t)(30))
#define DMA_Channel_SW19 ((uint8_t)(31))
Закрыть
или писать просто MDR_DMA->CHMUX0 = 4;//Set SPW0_RX_SREQ_REQ to DMA ch0, но тогда что делать с командой DMA_Cmd(DMA_Channel_ххх, ENABLE) ?


Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-16 16:45 
Не в сети
Support
Аватара пользователя

Зарегистрирован: 2018-авг-10 23:14
Сообщения: 530
Организация: АО «ПКК Миландр»
Откуда: Зеленоград
Открыть обращение пользователя antonakolzin21
antonakolzin21 писал(а): *
Спасибо за быстрый ответ! Разобрался с регистром CHMUX[x], для SPW нужно записать в CHMUX0 в CHANNEL0 значение 4 . Чтобы использовать DMA CHANNEL0, но тогда возникает вопрос что писать в DMA_Cmd(DMA_Channel_ххх, ENABLE);??? так как непонятно из "mdr32f8_dma.h"
Открыть
/** @defgroup DMA_valid_channels DMA valid channels
* @{
*/
#define DMA_Channel_UART1_TX ((uint8_t)(0))
#define DMA_Channel_UART1_RX ((uint8_t)(1))
#define DMA_Channel_UART2_TX ((uint8_t)(2))
#define DMA_Channel_UART2_RX ((uint8_t)(3))
#define DMA_Channel_SSP1_TX ((uint8_t)(4))
#define DMA_Channel_SSP1_RX ((uint8_t)(5))
#define DMA_Channel_SSP2_TX ((uint8_t)(6))
#define DMA_Channel_SSP2_RX ((uint8_t)(7))
#define DMA_Channel_ADC1 ((uint8_t)(8))
#define DMA_Channel_ADC2 ((uint8_t)(9))
#define DMA_Channel_TIM1 ((uint8_t)(0))//10
#define DMA_Channel_TIM2 ((uint8_t)(11))
#define DMA_Channel_TIM3 ((uint8_t)(12))
#define DMA_Channel_SW1 ((uint8_t)(13))
#define DMA_Channel_SW2 ((uint8_t)(14))
#define DMA_Channel_SW3 ((uint8_t)(15))
#define DMA_Channel_SW4 ((uint8_t)(16))
#define DMA_Channel_SW5 ((uint8_t)(17))
#define DMA_Channel_SW6 ((uint8_t)(18))
#define DMA_Channel_SW7 ((uint8_t)(19))
#define DMA_Channel_SW8 ((uint8_t)(20))
#define DMA_Channel_SW9 ((uint8_t)(21))
#define DMA_Channel_SW10 ((uint8_t)(22))
#define DMA_Channel_SW11 ((uint8_t)(23))
#define DMA_Channel_SW12 ((uint8_t)(24))
#define DMA_Channel_SW13 ((uint8_t)(25))
#define DMA_Channel_SW14 ((uint8_t)(26))
#define DMA_Channel_SW15 ((uint8_t)(27))
#define DMA_Channel_SW16 ((uint8_t)(28))
#define DMA_Channel_SW17 ((uint8_t)(29))
#define DMA_Channel_SW18 ((uint8_t)(30))
#define DMA_Channel_SW19 ((uint8_t)(31))
Закрыть
или писать просто MDR_DMA->CHMUX0 = 4;//Set SPW0_RX_SREQ_REQ to DMA ch0, но тогда что делать с командой DMA_Cmd(DMA_Channel_ххх, ENABLE) ?
Закрыть
Спасибо большое за Ваше обращение. В библиотеке DMA для 1986ВЕ8Т действительно имеется множество рудиментов, которые остались в ходе разработки библиотеки внутри компании задолго до того, как со стороны отдела технической поддержки начала производиться реструктуризация всей SPL целиком для комфортного использования, в частности, предложенная Вами под спойлером карта каналов DMA актуальна для другого микроконтроллера компании Миландр и не имеет ничего общего с 1986ВЕ8Т. Обязательно заведу сообщение о проблеме на внутреннем Git, чтобы поправить это. Предметнее по функционированию:

Функция DMA_Cmd() оперирует регистрами CHNL_ENABLE_SET/CLR, получая на вход номер реального канала (соответственно, реальных каналов всего 32, исходя из восьми регистров CHMUX[x]) и действие, которое необходимо совершить с каналом. Чтобы разрешить работу канала DMA, вызов этой функции необходим с аргументом "ENABLE" и в Вашем случае с номером 0x0 в качестве реального канала DMA, так как на него Вы установили виртуальный канал DMA от SpaceWire.

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

_________________
Отдел технической поддержки support@milandr.ru

Информационный портал отдела технической поддержки support.milandr.ru


Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-16 17:02 
Не в сети

Зарегистрирован: 2021-ноя-09 22:45
Сообщения: 11
Организация: НТЦ Техноцентр ЮФУ
Спасибо, буду делать дальше! О результатах отпишусь.


Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-17 13:25 
Не в сети

Зарегистрирован: 2021-ноя-09 22:45
Сообщения: 11
Организация: НТЦ Техноцентр ЮФУ
Продолжил разбираться с DMA и SPW.
1. Непонятно что обозначают строки настройки DMA_PriCtrlStr.DMA_CycleSize = 24; и
DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1; Это означает DMA примет 24 слова и остановится или по другому?
2. При настройки DMA как ниже,
Открыть
/* DMA Configuration */
/* Reset all DMA settings */
DMA_DeInit();
DMA_StructInit(&DMA_InitStr);
/* Set Primary Control Data */
DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)&MDR_SPW0->FIFORX;
DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)SPW_Read_FIFORX;
DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
DMA_PriCtrlStr.DMA_DestIncSize = DMA_SourceIncWord;
DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_PriCtrlStr.DMA_Mode = DMA_Mode_Basic;
DMA_PriCtrlStr.DMA_CycleSize = 24;
DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1;
DMA_PriCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged;
DMA_PriCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged;
/* Set Channel Structure */
DMA_InitStr.DMA_PriCtrlData = &DMA_PriCtrlStr;
DMA_InitStr.DMA_AltCtrlData = &DMA_AltCtrlStr;
DMA_InitStr.DMA_Priority = DMA_Priority_Default;
DMA_InitStr.DMA_UseBurst = DMA_BurstClear;
DMA_InitStr.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY;
MDR_DMA->CHMUX0 = 4;//Set SPW0_RX_SREQ to DMA ch0
/* Init DMA_Channel_SW1*/
DMA_Init(0x0, &DMA_InitStr);
/* Enable DMA IRQ */
NVIC_EnableIRQ(DMA_DONE0_IRQn);
Закрыть

получаем, что после отправки 4 раза по 24 байта в SPW, в буфер для приема по DMA "SPW_Read_FIFORX[16]" после срабатывания прерывания от контроллера DMA по завершению цикла для канала 0, получаю один полный пакет(24 байта), куда теряется первые три пакета? и после этого DMA отказывается работать, прерывания происходят но в буфере для приема ничего нет.


Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-17 14:36 
Не в сети

Зарегистрирован: 2021-ноя-09 22:45
Сообщения: 11
Организация: НТЦ Техноцентр ЮФУ
и еще вопрос зачем во всех примерах после инициализации DMA "DMA_Init (DMA_Channel_0, &DMA_InitStructure);" делать команды
// Снять запрет на запросы и одиночные запросы к DMA
MDR_DMA->CHNL_REQ_MASK_CLR = 1 << DMA_Channel_0;
MDR_DMA->CHNL_USEBURST_CLR = 1 << DMA_Channel_0;
// Разрешить работу DMA
DMA_Cmd (DMA_Channel_0, ENABLE);

эти же команды делаются внутри DMA_Init
Открыть
void DMA_Init(uint8_t DMA_Channel, DMA_ChannelInitTypeDef* DMA_InitStruct)
{
/* Check the parameters */
assert_param(IS_DMA_CHANNEL(DMA_Channel));
assert_param(IS_DMA_AHB_PROT(DMA_InitStruct->DMA_ProtCtrl));
assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority));
assert_param(IS_DMA_BURST(DMA_InitStruct->DMA_UseBurst));
assert_param(IS_DMA_SELECT_DATA_STRUCTURE(DMA_InitStruct->DMA_SelectDataStructure));

/* Check the CTRL_BASE_PTR initialisation */
MDR_DMA->CTRL_BASE_PTR = (uint32_t)DMA_ControlTable;

/* Primary Control Data Init */
if (DMA_InitStruct->DMA_PriCtrlData)
{
DMA_CtrlDataInit(DMA_InitStruct->DMA_PriCtrlData, &DMA_ControlTable[DMA_Channel]);
}

#if (DMA_AlternateData == 1)
/* Alternate Control Data Init */
if (DMA_InitStruct->DMA_AltCtrlData)
{
uint32_t ptr = (MDR_DMA->ALT_CTRL_BASE_PTR + (DMA_Channel * sizeof(DMA_CtrlDataTypeDef)));
DMA_CtrlDataInit(DMA_InitStruct->DMA_AltCtrlData, (DMA_CtrlDataTypeDef *)ptr);
}
#endif

/* DMA configuration register */
MDR_DMA->CONFIG = DMA_CFG_MASTER_ENABLE | DMA_InitStruct->DMA_ProtCtrl;

/* Burst mode */
if (DMA_InitStruct->DMA_UseBurst == DMA_BurstSet)
{
MDR_DMA->CHNL_USEBURST_SET = (1 << DMA_Channel);
}
else
{
MDR_DMA->CHNL_USEBURST_CLR = (1 << DMA_Channel);
}

/* Channel mask clear */
MDR_DMA->CHNL_REQ_MASK_CLR = (1 << DMA_Channel);

/* Enable channel */
MDR_DMA->CHNL_ENABLE_SET = (1 << DMA_Channel);

/* Primary - Alternate control data structure selection */
if (DMA_InitStruct->DMA_SelectDataStructure == DMA_CTRL_DATA_PRIMARY)
{
MDR_DMA->CHNL_PRI_ALT_CLR = (1 << DMA_Channel); /* Use Primary */
}
else
{
MDR_DMA->CHNL_PRI_ALT_SET = (1 << DMA_Channel); /* Use Alternate */
}

/* Channel priority set */
if (DMA_InitStruct->DMA_Priority == DMA_Priority_High)
{
MDR_DMA->CHNL_PRIORITY_SET = (1 << DMA_Channel); /* High priority */
}
else
{
MDR_DMA->CHNL_PRIORITY_CLR = (1 << DMA_Channel); /* Default priority */
}
}
Закрыть
или так нужно? просто эффекта от этого нет.


Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-17 17:07 
Не в сети

Зарегистрирован: 2021-ноя-09 22:45
Сообщения: 11
Организация: НТЦ Техноцентр ЮФУ
С работой DMA кое как разобрался, нужно после возникновения прерывания заново инициализировать DMA(вычитал на форуме по другому МК 1986ВЕ9).
Вот что добавил в обработчик прерывания для работы:
Открыть
DMA_PriCtrlStr.DMA_CycleSize = 24;
DMA_InitStr.DMA_PriCtrlData = &DMA_PriCtrlStr;
DMA_Init(0x0, &DMA_InitStr);
Закрыть
Но теперь другая проблема, для проверки работы SPW, включил прерывание MDR_SPW0->CONTROL = 0x50D; // SPWEN, LNKSTART, AUTOSTART,DMARXEN,INTERXF, для того чтобы посмотреть как заполняется FIFORX. Появилась проблема, ввиде того что в обработчике прерывания по SPW добавил чтение из FIFORX в буфер packet_buff[j]
Открыть
void INT_SPW0_Handler(void)
{
status = MDR_SPW0->STATUS;
PORT_SetBits(PORTE, VD1);

for(uint8_t j=0; j<16; j++)
packet_buff[j] = MDR_SPW0->FIFORX; // Считать данные в массив
}
Закрыть

получается что прерывания не происходит(на точке останова не тормозит в обработчике) а данные в packet_buff[j] записыаются, на картинке показано. Как быть? Прерывание после окончания цикла DMA работают, на картинке момент срабатывания.


Вложения:
Комментарий к файлу: данные в packet_buff[j]
[ attachment ]
Снимок.JPG [ 101.2 КБ | 198 просмотров ]
Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-18 11:04 
Не в сети
Support
Аватара пользователя

Зарегистрирован: 2018-авг-10 23:14
Сообщения: 530
Организация: АО «ПКК Миландр»
Откуда: Зеленоград
Открыть обращение пользователя antonakolzin21
antonakolzin21 писал(а): *
Продолжил разбираться с DMA и SPW.
1. Непонятно что обозначают строки настройки DMA_PriCtrlStr.DMA_CycleSize = 24; и
DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1; Это означает DMA примет 24 слова и остановится или по другому?
2. При настройки DMA как ниже,
Открыть
/* DMA Configuration */
/* Reset all DMA settings */
DMA_DeInit();
DMA_StructInit(&DMA_InitStr);
/* Set Primary Control Data */
DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)&MDR_SPW0->FIFORX;
DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)SPW_Read_FIFORX;
DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
DMA_PriCtrlStr.DMA_DestIncSize = DMA_SourceIncWord;
DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_PriCtrlStr.DMA_Mode = DMA_Mode_Basic;
DMA_PriCtrlStr.DMA_CycleSize = 24;
DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1;
DMA_PriCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged;
DMA_PriCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged;
/* Set Channel Structure */
DMA_InitStr.DMA_PriCtrlData = &DMA_PriCtrlStr;
DMA_InitStr.DMA_AltCtrlData = &DMA_AltCtrlStr;
DMA_InitStr.DMA_Priority = DMA_Priority_Default;
DMA_InitStr.DMA_UseBurst = DMA_BurstClear;
DMA_InitStr.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY;
MDR_DMA->CHMUX0 = 4;//Set SPW0_RX_SREQ to DMA ch0
/* Init DMA_Channel_SW1*/
DMA_Init(0x0, &DMA_InitStr);
/* Enable DMA IRQ */
NVIC_EnableIRQ(DMA_DONE0_IRQn);
Закрыть

получаем, что после отправки 4 раза по 24 байта в SPW, в буфер для приема по DMA "SPW_Read_FIFORX[16]" после срабатывания прерывания от контроллера DMA по завершению цикла для канала 0, получаю один полный пакет(24 байта), куда теряется первые три пакета? и после этого DMA отказывается работать, прерывания происходят но в буфере для приема ничего нет.
Закрыть
Здравствуйте!

Обратите, пожалуйста, вновь внимание на статью "Начальные сведения о DMA" с информационного портала отдела технической поддержки компании Миландр, в составе статьи приведены основные положения по функционированию блока, а также представлены ответы на ряд Ваших вопросов (ссылка на статью приводилась в прошлом ответном посте).
antonakolzin21 писал(а):
1. Непонятно что обозначают строки настройки DMA_PriCtrlStr.DMA_CycleSize = 24; и
DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1; Это означает DMA примет 24 слова и остановится или по другому?
Параметр DMA_CycleSize указывает на количество передач DMA (параметр N_minus_1 в управляющей структуре), когда как параметр DMA_NumContinuous (параметр R_power в управляющей структуре) указывает на количество передач (степень двойки) до проведения процедуры арбитража. Для Ваших настроек DMA данные параметры указывают на то, что по факту поступления запросов с блока SpaceWire по адресу DMA_DestBaseAddr, где расположен Ваш буфер, каждый запрос из суммарных 24 (параметр N_minus_1) будут производиться пословные записи из регистра MDR_SPW0->FIFORX.
antonakolzin21 писал(а):
2. При настройки DMA как ниже,
Открыть
/* DMA Configuration */
/* Reset all DMA settings */
DMA_DeInit();
DMA_StructInit(&DMA_InitStr);
/* Set Primary Control Data */
DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)&MDR_SPW0->FIFORX;
DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)SPW_Read_FIFORX;
DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
DMA_PriCtrlStr.DMA_DestIncSize = DMA_SourceIncWord;
DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_PriCtrlStr.DMA_Mode = DMA_Mode_Basic;
DMA_PriCtrlStr.DMA_CycleSize = 24;
DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1;
DMA_PriCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged;
DMA_PriCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged;
/* Set Channel Structure */
DMA_InitStr.DMA_PriCtrlData = &DMA_PriCtrlStr;
DMA_InitStr.DMA_AltCtrlData = &DMA_AltCtrlStr;
DMA_InitStr.DMA_Priority = DMA_Priority_Default;
DMA_InitStr.DMA_UseBurst = DMA_BurstClear;
DMA_InitStr.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY;
MDR_DMA->CHMUX0 = 4;//Set SPW0_RX_SREQ to DMA ch0
/* Init DMA_Channel_SW1*/
DMA_Init(0x0, &DMA_InitStr);
/* Enable DMA IRQ */
NVIC_EnableIRQ(DMA_DONE0_IRQn);
Закрыть

получаем, что после отправки 4 раза по 24 байта в SPW, в буфер для приема по DMA "SPW_Read_FIFORX[16]" после срабатывания прерывания от контроллера DMA по завершению цикла для канала 0, получаю один полный пакет(24 байта), куда теряется первые три пакета? и после этого DMA отказывается работать, прерывания происходят но в буфере для приема ничего нет.
Обратите, пожалуйста, внимание, что поскольку DMA работает в базовом режиме, где не требуется альтернативная управляющая структура, то конфигурацию параметра DMA_AltCtrlData можно не производить.

После функции DMA_Init() необходимо также сконфигурировать регистры CHNL_REQ_MASK_CLR и CHNL_USEBURST_CLR для выбранного канала (включение dma_req блочных или dma_sreq одиночных запросов генерации DMA). Соответственно, после конфигурации необходимо включить DMA функцией DMA_Cmd() (см. прошлый ответный пост). По факту прихода каждого запроса с блока SpaceWire (в Вашем случае запрос RX на приём данных - можно также выставлять запрос программно для контроля в регистре CHNL_SW_REQUEST), пословно будет производиться запись в объявленный буфер.
antonakolzin21 писал(а):
и еще вопрос зачем во всех примерах после инициализации DMA "DMA_Init (DMA_Channel_0, &DMA_InitStructure);" делать команды
// Снять запрет на запросы и одиночные запросы к DMA
MDR_DMA->CHNL_REQ_MASK_CLR = 1 << DMA_Channel_0;
MDR_DMA->CHNL_USEBURST_CLR = 1 << DMA_Channel_0;
// Разрешить работу DMA
DMA_Cmd (DMA_Channel_0, ENABLE);

эти же команды делаются внутри DMA_Init
Это базовая инициализация контроллера DMA для гарантированной работы.
antonakolzin21 писал(а):
С работой DMA кое как разобрался, нужно после возникновения прерывания заново инициализировать DMA(вычитал на форуме по другому МК 1986ВЕ9).
Вот что добавил в обработчик прерывания для работы:
Всё верно, по факту окончания работы DMA (выполнение 24 циклов обмена) будет вызвано прерывание DMA. Внутри прерывания необходимо обязательно переинициализировать структуру, так как если Вы посмотрите по адресу 0x20000400 (стандартный адрес, где лежит структура, соответственно по этому адресу настройки первого реального канала DMA, и первое слово содержит адрес источника данных, второе слово конечный адрес назначения данных, третье же слово содержит заполнение части Control DMA), то обнаружите, что в ходе отработки всех транзакций DMA, поле N_minus_1 будет равно нулю, и в этот момент как раз будет вызвано прерывание. Поэтому чтобы DMA продолжал дальше работать, необходимо снова перенастроить структуру DMA в прерывании.
antonakolzin21 писал(а):
Но теперь другая проблема, для проверки работы SPW, включил прерывание MDR_SPW0->CONTROL = 0x50D; // SPWEN, LNKSTART, AUTOSTART,DMARXEN,INTERXF, для того чтобы посмотреть как заполняется FIFORX. Появилась проблема, ввиде того что в обработчике прерывания по SPW добавил чтение из FIFORX в буфер packet_buff[j]

получается что прерывания не происходит(на точке останова не тормозит в обработчике) а данные в packet_buff[j] записыаются, на картинке показано. Как быть? Прерывание после окончания цикла DMA работают, на картинке момент срабатывания.
Постараемся посмотреть, с чем может быть связано такое поведение. При этом, работая с запросами DMA со стороны контроллера SpaceWire, проблем с запросами RX быть не должно, когда как с запросами TX связана аппаратная ошибка 0068 "Зависание запроса DMA на передачу от блока SPW" из документа errata - обратите, пожалуйста, на это внимание.

Спасибо.

_________________
Отдел технической поддержки support@milandr.ru

Информационный портал отдела технической поддержки support.milandr.ru


Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-18 14:32 
Не в сети

Зарегистрирован: 2021-ноя-09 22:45
Сообщения: 11
Организация: НТЦ Техноцентр ЮФУ
Добрый день! Спасибо за разъяснение работы по DMA. DMA работает. Немного не понятна работа SPW, я хочу получить прерывание по полной заполненности FIFO, флаг RXF в регистре STATUS. Настроил SPW MDR_SPW0->CONTROL = 0x40D; // SPWEN, LNKSTART, AUTOSTART,INTERXF и получается при отправке трех посылок по 24байта(72 байта) а у нас FIFO 64байта, прерывания по полному FIFO не происходит, это ошибка или если в FIFO нет свободного места для приема посылки из 24 байт, контроллер SPW не будет принимать вообще ничего?
Если настроить прерывание по заполненности 3/4 FIFO приёмника, то прерывание срабатывает. Получается, что нужно организовывать побайтные посылки или пакетами по 64 байта, или я чтото неправильно понимаю? Спасибо!


Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-18 16:00 
Не в сети

Зарегистрирован: 2021-ноя-09 22:45
Сообщения: 11
Организация: НТЦ Техноцентр ЮФУ
Немного поспешил сказав что DMA работает. Настраиваем DMA как и раньше на 16 циклов, по настройкам DMA должен забрать с FIFORX SPW, 16 слов. Но по факту окончания цикла DMA, считывает 16 байт. Где проблема? и было замечено что при настройках параметров DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo; DMA_PriCtrlStr.DMA_DestIncSize = DMA_SourceIncNo; все точно также работает.
Я отправляю в SPW посылку 32 байта "01 02 03 04 05 06 07 08 09 10 ab ad ac af ff 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32", если поставить в параметр цикла 32, то после второй посылки HardFault_Handler, после первой прерывания по DMA не срабатывает, и остается проблема описанная выше про пропажу первых трех пакетов.


Вложения:
[ attachment ]
DMA_16.JPG [ 134.83 КБ | 138 просмотров ]
Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-18 16:19 
Не в сети

Зарегистрирован: 2020-дек-10 09:35
Сообщения: 58
Организация: Startex
Не погружался в переписку, но раньше нельзя было в DMA_DestIncSize писать DMA_SourceIncWord. Совсем другая маска.

Начало памяти, откуда начинает читать DMA рассчитывается от конца данных. Количетсво данных 16, но длина байт, вот первая часть массива и пролетела.
Вру, видимо длина слова получилась два байта.


Последний раз редактировалось AndOrFin 2021-ноя-18 16:36, всего редактировалось 2 раза.

Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-18 16:33 
Не в сети
Support
Аватара пользователя

Зарегистрирован: 2018-авг-10 23:14
Сообщения: 530
Организация: АО «ПКК Миландр»
Откуда: Зеленоград
Открыть сообщение пользователя AndOrFin
AndOrFin писал(а): *
Не погружался в переписку, но раньше нельзя было в DMA_DestIncSize писать DMA_SourceIncWord. Совсем другая маска.
Закрыть
Спасибо за замечание, оно действительно имеет вес.

antonakolzin21, обратите, пожалуйста, внимание на замечание пользователя AndOrFin, а также на заполнение контрольной управляющей структуры DMA, конфигурация полей DMA_SourceIncSize и DMA_DestIncSize производится в разных битах структурного слова, соответственно, директивы DMA_SourceInc* должны относиться строго к полю DMA_SourceIncSize, а директивы DMA_DestInc* к полю DMA_DestIncSize (биты [27:26] и [31:30] соответственно). Как и сообщалось ранее, Вы можете проконтролировать правильную настройку в ходе выполнения программы, обратившись к адресу расположения управляющих структур DMA, в данном случае для первого реального канала структура лежит по адресу 0x20000400, интересует третье слово, начиная с этого адреса, которое и относится к контрольному в рамках канала (в нем содержится информация о dst_inc, src_inc, N_minus_1, R_power, а также о многих других параметрах - в качестве проверки для удобства можете использовать таблицу 2 статьи "Начальные сведения о DMA")

_________________
Отдел технической поддержки support@milandr.ru

Информационный портал отдела технической поддержки support.milandr.ru


Вернуться к началу
 Заголовок сообщения: Re: SpaseWire DMA 1986ВЕ81Т
СообщениеДобавлено: 2021-ноя-19 12:03 
Не в сети

Зарегистрирован: 2021-ноя-09 22:45
Сообщения: 11
Организация: НТЦ Техноцентр ЮФУ
Добрый день! Спасибо за замечание от
AndOrFin писал(а): *
Не погружался в переписку, но раньше нельзя было в DMA_DestIncSize писать DMA_SourceIncWord. Совсем другая маска.

Начало памяти, откуда начинает читать DMA рассчитывается от конца данных. Количетсво данных 16, но длина байт, вот первая часть массива и пролетела.
Вру, видимо длина слова получилась два байта.
не понятно в какой момент изменил на неправильное значение. Исправил, теперь принимает по 16 слов, при такой настройке
Открыть
/* Set Primary Control Data */
DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)&MDR_SPW0->FIFORX;
DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)SPW_Read_FIFORX;
DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
DMA_PriCtrlStr.DMA_DestIncSize = DMA_DestIncWord;
DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_PriCtrlStr.DMA_Mode = DMA_Mode_Basic;
DMA_PriCtrlStr.DMA_CycleSize = 16;
Закрыть
срабатывает прерывание и в считываемом буфере то что нужно. Но немного не понятно, в Начальные сведения о DMA сказано что "Размерность данных приемника всегда должна быть равна размерности данных источника: src_size == dst_size " но если я ставлю одинаковое значение в SourceIncSize и DestIncSize, то работает неадекватно. Вопрос, если ставить одинаковые значения нужно чтот-о делать с адресами приемника и передатчика, или оставить как есть в источнике DMA_SourceIncNo, а в приемнике DMA_DestIncWord, так же работает как нужно???
По адресу 0х20000400, третье слово это 00 68 00 28, и видимо это что-то не то.

Спасибо!


Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 17 сообщений ]  На страницу 1 2 »

Часовой пояс: UTC+03:00


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

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


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

Перейти: 

cron
Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB