Спасибо, учтём в следующей версии описанияdezna писал(а): ↑05 фев 2025, 16:27 тогда можете так же отметить:
1. стр 102, п13.5 TMR32 с какого то в разделе TMR
2. в руководстве арифметика с плавающей запятой не описана практически никак, за исключением упоминания о ней как таковой.
3. на страницах 44 и 45 таблицы инструкций содержат одно и то же
это на вскидку, что помню
К1921ВГ015 DMA+TMR
Модераторы: ea, dav, bkolbov, Alis, pip, _sva_
Re: К1921ВГ015 DMA+TMR
Re: К1921ВГ015 DMA+TMR
не удалось запустить циклический режим при основном режиме работы DMA.dezna писал(а): ↑05 фев 2025, 09:05 буду пробовать настроить 2 канала DMA на программный запрос и по флагу прерывания CAP0 дергать программный запрос.
только не из прерывания, а попробую вставить в vApplicationIdleHook от ОС. тогда не будут вызываться сохранение/восстановление регистров в стэк, что должно сэкономить время.
DMA сделать зацикленным, тогда и перезапускать не понадобится, только 1 раз настроить и дергать запрос.
вроде можно DMA дергать руками вместо периферии? никогда так не делал еще.
приходится по прерыванию DMA переинициализировать канал, иначе доходит до конца и выключается. ошибок нет.
Код: Выделить всё
#define DMA_CH_CFG_INIT_Const ( \
(DMA_CHANNEL_CFG_DST_INC_None << DMA_CHANNEL_CFG_DST_INC_Pos) | \
(DMA_CHANNEL_CFG_SRC_INC_Word << DMA_CHANNEL_CFG_SRC_INC_Pos) | \
(DMA_CHANNEL_CFG_DST_SIZE_Halfword << DMA_CHANNEL_CFG_DST_SIZE_Pos) | \
(DMA_CHANNEL_CFG_SRC_SIZE_Halfword << DMA_CHANNEL_CFG_SRC_SIZE_Pos) | \
(0<<DMA_CHANNEL_CFG_R_POWER_Pos) | \
((CurrOut_NSD-1) << DMA_CHANNEL_CFG_N_MINUS_1_Pos) | \
(1<<DMA_CHANNEL_CFG_CYCLE_CTRL_Pos) \
)
//configure DMA
DMA_CONFIGDATA.PRM_DATA.CH[DMA_CH_TMR1].SRC_DATA_END_PTR = (uint32_t)&Buf[100-1][0];
DMA_CONFIGDATA.PRM_DATA.CH[DMA_CH_TMR2].SRC_DATA_END_PTR = (uint32_t)&Buf[100-1][1];
DMA_CONFIGDATA.PRM_DATA.CH[DMA_CH_TMR1].DST_DATA_END_PTR = (uint32_t)&CurrOutTIM->CAPCOM[2].VAL;
DMA_CONFIGDATA.PRM_DATA.CH[DMA_CH_TMR2].DST_DATA_END_PTR = (uint32_t)&CurrOutTIM->CAPCOM[3].VAL;
DMA_CONFIGDATA.PRM_DATA.CH[DMA_CH_TMR1].CHANNEL_CFG =
DMA_CONFIGDATA.PRM_DATA.CH[DMA_CH_TMR2].CHANNEL_CFG = DMA_CH_CFG_INIT_Const;
DMA->REQMASKCLR = 1<<DMA_CH_TMR1 | 1<<DMA_CH_TMR2;
DMA->PRIALTCLR = 1<<DMA_CH_TMR1 | 1<<DMA_CH_TMR2; //en prim struct
DMA->CIRCULARSET = 1<<DMA_CH_TMR1 | 1<<DMA_CH_TMR2; //en cycle
DMA->ENSET = 1<<DMA_CH_TMR1 | 1<<DMA_CH_TMR2;
//обновление регистров по переполнению CAP0
if(CurrOutTIM->RIS & TMR_RIS_CAP0_Pos){
CurrOutTIM->IC = 0x1F;
DMA->SWREQ = 1<<DMA_CH_TMR1 | 1<<DMA_CH_TMR2;
}
//работает только если перевключать DMA руками
if(DMA->IRQSTAT & ((1<<DMA_CH_TMR1) | (1<<DMA_CH_TMR2))){
DMA->IRQSTATCLR = (1<<DMA_CH_TMR1) | (1<<DMA_CH_TMR2);
DMA_CONFIGDATA.PRM_DATA.CH[DMA_CH_TMR1].CHANNEL_CFG =
DMA_CONFIGDATA.PRM_DATA.CH[DMA_CH_TMR2].CHANNEL_CFG = DMA_CH_CFG_INIT_Const;
DMA->ENSET = 1<<DMA_CH_TMR1 | 1<<DMA_CH_TMR2;
}
Re: К1921ВГ015 DMA+TMR
детская ошибка...
Код: Выделить всё
if(CurrOutTIM->RIS & (1<<TMR_RIS_CAP0_Pos)){
вроде заработал циклический режим, но как-то странно работает.
включил защиту конфига в DMA.
получается 3 канала
1. вход GPIO (вместо него пока SWREQ с периодом 0.2с )
2. TMR1 SWREQ
3. TMR2 SWREQ
2 и 3 производится проверка RIS_CAP0 с частотой 2МГц.
прерывание происходит приметно с частотой 300Гц.
так вот...
в таком режиме каналы 2 и 3 перезагружают количество транзакций как положено при инициализации конфига, пока канал 1 не дойдет до конца...
далее какая-то ерунда... перезагрузка с количеством N-1 = 1 во всех 3х каналах...
если 2 и 3 вытащить в период обновления 0,2с как первый, то все работает корректно.
что не так делаю?
приоритеты не задавал, т.к. всего 3 канала...
чтение из MTIME все так же дает ошибку и прекращается работа канала, так что все эксперименты с переменной в памяти...
Re: К1921ВГ015 DMA+TMR
при этом, такое ощущение что количество N-1 для каналов 2 и 3 берется из текущего значения канала 1...
какая то ерунда...
видео во вложении. обновление экрана 0,5с, потому так дискретно
- Вложения
-
- video_2025-02-06_12-07-14.mpeg
- формат mp4. не давало загрузить, потому поменял. VLC и так проигрывает без переименования
- (11.15 МБ) 407 скачиваний
-
- Сообщения: 225
- Зарегистрирован: 14 дек 2015, 08:21
- Предприятие: АО НИИЭТ
- Откуда: АО НИИЭТ, Воронеж
Re: К1921ВГ015 DMA+TMR
Доброго времени суток!dezna писал(а): ↑05 фев 2025, 15:14 DMA вылетает с ошибкой канала, если пытаюсь читать значение MTIME...
адрес проверил, корректный 0x0200BFF8.
если заменяю адрес источника на созданную переменную, то все работает.
что делать?
так же пришлось включить в канале все защиты, тоже вылетал с ошибкой не сделав ни одной операции.
с комбинациями не экспериментировал, включил сразу все.
Согласно схеме коммутации периферийных блоков микроконтроллера (рисунок 3.1 руководства пользователя) DMA не имеет доступ к системной памяти, в которой расположен регистр MTIME. Есть доступ только к ОЗУ0, ОЗУ1 и периферийным блокам.
Re: К1921ВГ015 DMA+TMR
Добрый день!
ясно, спасибо. минус еще одна возможность. а так хорошо все начиналось... могли продублировать в регистровое пространство перифирии... хотя бы на чтение... но это лирика...
если что, то там системная память вообще никак не обозначена и нужно догадываться что это так... у меня вот не получилось...
Re: К1921ВГ015 DMA+TMR
DMA в циклическом режиме работает корректно, только если 1 канал включен.
пробовал отключать каналы в разных комбинациях...
возможно я что-то не так делаю, но уже перечитал все что мог, перепробовал все комбинации которые смог придумать...
ничего не помогает! возможно косяк все-таки в кристалле?
ну, или в где нить в хидере... все объявления из хидера на мк, своего не писал...
объявление структуры настроек DMA из вашего примера.
порядок инициализации тоже вроде как в РП...
настройки все в предыдущих постах...
уж и не знаю куда еще смотреть!
Re: К1921ВГ015 DMA+TMR
из K1921VG015.h
DMA_Channel_TypeDef CH[32] /*!< Control structure channels */
/*!< WARNING: struct should be 1024 byte aligned! Allowed addresses 0xXXXXX000, 0xXXXXX400, 0xXXXXX800, etc */
вы уверены что структура из 32 конфигов нужна?
в РП совсем другое говорится:
каналов 24
32*16 = 512 = 0x200 байт PRM структура.
PRM+ALT = 512+512 = 0x200+0x200 = 1024 = 0x400
из РП
PRM+ALT = 384+384 = 0x180+0x180 = 768 = 0x300
PRM = 0x300/2= 0x180 = 384
384/16 = 24 канала...
так где все-таки правильно?
PS... поменял на 24 - не помогло...
Код: Выделить всё
/*-- DMA channel structure --------------------------------------------------*/
typedef struct
{
__IO uint32_t SRC_DATA_END_PTR; /*!< Source data end pointer */
__IO uint32_t DST_DATA_END_PTR; /*!< Destination data end pointer */
union {
__IO uint32_t CHANNEL_CFG; /*!< Channel configure word */
__IO _CHANNEL_CFG_bits CHANNEL_CFG_bit; /*!< channel configure word: bit access */
};
__IO uint32_t RESERVED;
} DMA_Channel_TypeDef;
/*-- DMA control structure --------------------------------------------------*/
typedef struct
{
DMA_Channel_TypeDef CH[32]; /*!< Control structure channels */
} DMA_CtrlStruct_TypeDef;
#define DMA_CH_GPIOA 0 /*!< GPIOA DMA channel */
**********
**********
#define DMA_CH_HASH 22 /*!< HASH DMA channel */
/*-- DMA control data summary -----------------------------------------------*/
/*!< WARNING: struct should be 1024 byte aligned! Allowed addresses 0xXXXXX000, 0xXXXXX400, 0xXXXXX800, etc */
typedef struct
{
DMA_CtrlStruct_TypeDef PRM_DATA; /*!< Primary control structure */
DMA_CtrlStruct_TypeDef ALT_DATA; /*!< Alternative control structure */
} DMA_CtrlData_TypeDef;
DMA_Channel_TypeDef CH[32] /*!< Control structure channels */
/*!< WARNING: struct should be 1024 byte aligned! Allowed addresses 0xXXXXX000, 0xXXXXX400, 0xXXXXX800, etc */
вы уверены что структура из 32 конфигов нужна?
в РП совсем другое говорится:
каналов 24
т.о. из хидераОбъем структуры, показанной на рисунке 10.1, составляет 768 байт. Контроллер использует младшие разряды адреса для доступа ко всем элементам структуры управляющих данных, и поэтому разрешенные значения базового адреса для первичной структуры управляющих данных – XXXX_X000h, XXXX_X300h, XXXX_X600h и т. д.
32*16 = 512 = 0x200 байт PRM структура.
PRM+ALT = 512+512 = 0x200+0x200 = 1024 = 0x400
из РП
PRM+ALT = 384+384 = 0x180+0x180 = 768 = 0x300
PRM = 0x300/2= 0x180 = 384
384/16 = 24 канала...
так где все-таки правильно?
PS... поменял на 24 - не помогло...
Re: К1921ВГ015 DMA+TMR
из РП
BASEPTR = xxxxx400, ALTBASEPTR = xxxxx600
получается кратно 0x200, значит РП врет.
прочитал из мкНе обязательно вычислять базовый адрес альтернативной структуры управляющих
данных, он вычисляется автоматически и помещается в регистр ALTBASEPTR.
BASEPTR = xxxxx400, ALTBASEPTR = xxxxx600
получается кратно 0x200, значит РП врет.
Re: К1921ВГ015 DMA+TMR
работа таймера в режиме "вверх 0x01", режим выхода CAPCOM[2] "установка сброс" / "переключние сброс".
при CAPCOM[2].VAL = 0 происходит кратковременная установка выхода в момент COUNT = CAPCOM[2].VAL = 0
при изменении CAPCOM[2].VAL от 1 до CAPCOM[0].VAL - 1, работает корректно.
при CAPCOM[2].VAL = CAPCOM[0].VAL устанавливается и не сбрасывается.
при попытке последовательно по прерыванию писать в CAPCOM[2].VAL (CAPCOM[0].VAL - 1, CAPCOM[0].VAL) происходит сброс только при CAPCOM[0].VAL - 1.
т.е. получается переключение (визуально по осциллографу) через CAPCOM[0].VAL.
по DMA будут какие-нибудь предложения или комментарии? может я чего не так делаю?
при CAPCOM[2].VAL = 0 происходит кратковременная установка выхода в момент COUNT = CAPCOM[2].VAL = 0
при изменении CAPCOM[2].VAL от 1 до CAPCOM[0].VAL - 1, работает корректно.
при CAPCOM[2].VAL = CAPCOM[0].VAL устанавливается и не сбрасывается.
отрабатывется только условие "устанавливается, когда таймер отсчитывает значение CAPCOM[n].VAL".Выходной сигнал устанавливается, когда таймер отсчитывает значение CAPCOM[n].VAL. Он сбрасывается, когда таймер отсчитывает значение CAPCOM[0].VAL
при попытке последовательно по прерыванию писать в CAPCOM[2].VAL (CAPCOM[0].VAL - 1, CAPCOM[0].VAL) происходит сброс только при CAPCOM[0].VAL - 1.
т.е. получается переключение (визуально по осциллографу) через CAPCOM[0].VAL.
по DMA будут какие-нибудь предложения или комментарии? может я чего не так делаю?