amiller 2 20 января, 2023 Опубликовано 20 января, 2023 (изменено) · Жалоба Столкнулся с интересной штукой. Если разрешаю transfer complete interrupt, то сразу после разрешения канала DMA улетаю в прерывание. Какие бы флаги не сбрасывал и задержки не вставлял. А если сначала разрешаю прерывание по половине буфера, а потом до конца, то всё ок. Кто нибудь сталкивался и как объехать? Код прерывания сейчас такой: void DMA1_Stream0_IRQHandler(void) { int32u temp; temp = DMA1->LISR; DMA1->LIFCR = 0x0000003D; // Clear Flags for Stream if (temp & DMA_LISR_HTIF0) { setmask(DMA1_Stream0->CR, DMA_SxCR_TCIE); clrmask(DMA1_Stream0->CR, DMA_SxCR_HTIE); } else { clrmask(DMA1_Stream0->CR, DMA_SxCR_TCIE); setmask(DMA1_Stream0->CR, DMA_SxCR_HTIE); Prn.dma_reset = true; } } А перезапуск происходит так: clrmask(DMA1_Stream0->CR, DMA_SxCR_EN); DMA1_Stream0->NDTR = Prn.size; DMA1_Stream0->M0AR = (int32u)Prn.ptr_x; DMA1->LIFCR = 0x0000003D; // Clear Flags for Stream setmask(DMA1_Stream0->CR, DMA_SxCR_EN); Изменено 20 января, 2023 пользователем haker_fox Пользуйтесь инструментом для оформления кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Variant99 7 20 января, 2023 Опубликовано 20 января, 2023 · Жалоба А какой флаг у прерывания выставляется при возникновении прерывания? Возможно, фраг ошибки конфигурации? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amiller 2 21 января, 2023 Опубликовано 21 января, 2023 · Жалоба Нет, именно TCIF. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 22 января, 2023 Опубликовано 22 января, 2023 · Жалоба В 20.01.2023 в 17:01, amiller сказал: Код прерывания сейчас такой: void DMA1_Stream0_IRQHandler(void) { int32u temp; temp = DMA1->LISR; DMA1->LIFCR = 0x0000003D; // Clear Flags for Stream if (temp & DMA_LISR_HTIF0) { setmask(DMA1_Stream0->CR, DMA_SxCR_TCIE); clrmask(DMA1_Stream0->CR, DMA_SxCR_HTIE); } else { clrmask(DMA1_Stream0->CR, DMA_SxCR_TCIE); setmask(DMA1_Stream0->CR, DMA_SxCR_HTIE); Prn.dma_reset = true; } } Не знаю как там в STMH743, но в предыдущих STM32F4 в мануале был явный запрет на модификацию битов регистра CR при включенном DMA-канале. В STMH743 такого запрета нет? Или вы просто не читали мануал? Советую всё же прочитать его, до того как начинать быдлокодить. Да и вообще - на кой тут все эти игры с запретом/разрешением TCIE, HTIE??? В нормальном коде нужные прерывания разрешают перед разрешением DMA-канала и больше их не трогают до останова работы DMA-канала. Также - очень полезно разрешать прерывание по ошибке DMA-канала (TEIE или как там оно называется в STMH743). И обрабатывать его в ISR. Чтобы хотя-бы быть в курсе возникающих ошибок. В 20.01.2023 в 17:01, amiller сказал: А перезапуск происходит так: clrmask(DMA1_Stream0->CR, DMA_SxCR_EN); DMA1_Stream0->NDTR = Prn.size; DMA1_Stream0->M0AR = (int32u)Prn.ptr_x; DMA1->LIFCR = 0x0000003D; // Clear Flags for Stream setmask(DMA1_Stream0->CR, DMA_SxCR_EN); Во-первых: Запрет работающего DMA-канала - само по себе крайне плохое решение. И не следует такое делать без реальной необходимости. Во-вторых: Не знаю, что у вас делается внутри clrmask(), но думается, что вы также не прочитали мануал на предмет правильной последовательности зпрета работающего DMA-канала (опять-же - сужу по мануалу на STM32F4; на STMH743 не читал, но вряд-ли там сделано иначе). В 20.01.2023 в 17:01, amiller сказал: Если разрешаю transfer complete interrupt, то сразу после разрешения канала DMA улетаю в прерывание. Что у вас там происходит - тут нет телепатов угадывать ваш код инициализации и запуска DMA-передачи. Видимо делаете это криво. PS: И если задаёте вопрос, то правило хорошего тона: Приводить исходный код всех используемых функций/макросов и типы всех переменных вашего кода. Ещё раз - телепатов тут нет это угадывать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться