Управляю ТФТ дисплем напряую через 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);
// 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");
}
{
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
#define IRQ_TIMER_SUB_PRIO 0
#define IRQ_TFT_DMA_TC_PREEM_PRIO 0
#define IRQ_TFT_DMA_TC_TIMER_SUB_PRIO 0
Буду благодарен за идеи.