реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> STM32f407 DMA2 M2M, не работает передача
Kalyan
сообщение May 22 2018, 10:22
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 108
Регистрация: 4-11-10
Пользователь №: 60 656



Добрый день.
Управляю ТФТ дисплем напряую через FSMS. Заполняю буфер и через DMA2 M2M передаю его в FSMS. По окончанию передачи получаю прерывание TC, генерирую новый буфер и опять передаю через DMA. Все работает пока не вызываться обработчик прерывания от таймера. Если этот обработчик занимает определенное время то прерывание TC от дма не вызывается никогда, прерывания ошибок от дма тоже не приходят. В регистрах дма наблюдаю след состояния:
LISR - флажков прерываний нету
CR - EN включен и прерывание TC тоже включено.
NDTR - количество байт уменьшилось на 20. то есть дма передало 20 байт
FCR - FS (FIFO status) == 5 что означает что FIFO полная.
Собственно не понятно почему дма перестает отправлять данные и заполняется его FIFO.

Инит дма
CODE
DMA_InitTypeDef DMA_InitStructure;

// Deinitialize DMA Streams
DMA_DeInit(DMA2_Stream0);

// half_word_cntr*2 - size in byte
// memory it is FSMC, DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord, 16b bus
// Peripheral it is img frame buff, DMA_PeripheralDataSize_Byte - need for little endianformat on FSMC bus

// Configure DMA Initialization Structure
DMA_InitStructure.DMA_BufferSize = half_word_cntr*2;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)data_p;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;

// Configure TX DMA
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)TFT_FSMC_BASE_ADDRESS;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);

DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0);
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);



// Transfer error
DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TEIF0);
DMA_ClearITPendingBit(DMA2_Stream0, DMA_FLAG_TEIF0);

// Direct mode error
DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_DMEIF0);
DMA_ClearITPendingBit(DMA2_Stream0, DMA_FLAG_DMEIF0);

//FIFO overrun/underrun
DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_FEIF0);
DMA_ClearITPendingBit(DMA2_Stream0, DMA_FLAG_FEIF0);

DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);

DMA_ITConfig(DMA2_Stream0, DMA_IT_TE, ENABLE);
DMA_ITConfig(DMA2_Stream0, DMA_IT_DME, ENABLE);
DMA_ITConfig(DMA2_Stream0, DMA_IT_FE, ENABLE);


и вот обработчик прерывания от таймера из за которого перестает работать дма (исключительно в целях отладки)
Код
static inline void timer_1ms_handler(void)
{
  status_led_time_proc();

  for (uint8_t i = 0; i < 45; i++)
    asm("nop");

}


приоритеты прерываний
Код
#define IRQ_TIMER_PREEM_PRIO              15
#define IRQ_TIMER_SUB_PRIO                0

#define IRQ_TFT_DMA_TC_PREEM_PRIO               0
#define IRQ_TFT_DMA_TC_TIMER_SUB_PRIO           0


Буду благодарен за идеи.

Сообщение отредактировал IgorKossak - May 22 2018, 10:43
Причина редактирования: [codebox] для длинного кода. [code]-для короткого!!!
Go to the top of the page
 
+Quote Post
VladislavS
сообщение May 22 2018, 10:33
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



В прерывании от таймера не вижу очистки бита вызвавшего прерывание.
Go to the top of the page
 
+Quote Post
Kalyan
сообщение May 22 2018, 10:36
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 108
Регистрация: 4-11-10
Пользователь №: 60 656



Очистка на уровень выше, в самом хендлере

Код
void TIMIMER_IRQ_Handler(void)
{
  if (TIM_GetITStatus(DELAY_TIMER, TIM_IT_Update) != RESET)
  {
    timer_1ms_handler();
    TIM_ClearITPendingBit(DELAY_TIMER, TIM_IT_Update);
  }
}
Go to the top of the page
 
+Quote Post
adnega
сообщение May 22 2018, 12:34
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Kalyan @ May 22 2018, 13:36) *
Код
void TIMIMER_IRQ_Handler(void)}

Нет такого названия обработчика прерывания.

Цитата(Kalyan @ May 22 2018, 13:36) *
Код
TIM_ClearITPendingBit(DELAY_TIMER, TIM_IT_Update);

Лучше сброс флага производить не в конце прерывания, т.к. можно словить повторные вхождения.
Или ставить барьер.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 03:05
Рейтинг@Mail.ru


Страница сгенерированна за 0.01881 секунд с 7
ELECTRONIX ©2004-2016