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

 
 
 
Reply to this topicStart new topic
> STM32F429 - FMC с дисплеем и SDRAM
VHEMaster
сообщение Dec 13 2015, 20:13
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 28-08-15
Пользователь №: 88 191



Доброго времени суток! На STM32F429 пытаюсь запустить LCD дисплей на ILI9325 через FMC вместе с SDRAM - IS42S16400-7TL на 64 Мбита.
Данные с внутреннего буфера контроллера пересылаются в дисплей через DMA, и одновременно с этим происходят операции с SDRAM. Проблема в том, если в этот момент происходит запись в SDRAM, то на дисплее появляются артефакты, и при чтении данных с SDRAM получаются совсем не те данные, которые были записаны. Если отключить дисплей программно, то всё работает отлично. Никаких ошибок нет. Вообще, моя цель такова. Переместить видеобуфер в SDRAM, и оттуда перебрасывать данные в дисплей с помощью DMA. Возможно ли это оформить без артефактов?

Код инициализации дисплея:
CODE

GPIO_InitTypeDef GPIO_InitStruct;
__GPIOE_CLK_ENABLE();
__GPIOD_CLK_ENABLE();
__FMC_CLK_ENABLE();

GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);


GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);


FMC_NORSRAM_TimingTypeDef Timing;

hsram1.Instance = FMC_NORSRAM_DEVICE;
hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
/* hsram1.Init */
hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
hsram1.Init.WrapMode = FMC_WRAP_MODE_DISABLE;
hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
/* Timing */
Timing.AddressSetupTime = 10;
Timing.DataSetupTime = 20;
Timing.AddressHoldTime = 0;
Timing.BusTurnAroundDuration = 0;
Timing.CLKDivision = 0;
Timing.DataLatency = 0;
Timing.AccessMode = FMC_ACCESS_MODE_A;
/* ExtTiming */

HAL_SRAM_Init(&hsram1, &Timing, NULL);


HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_SET);
DelayMs(1);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_RESET);
DelayMs(10);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_SET);
DelayMs(50);

//************* Start Initial Sequence **********//
graph_command(0x00E3, 0x3008); // Set internal timing
graph_command(0x00E7, 0x0012); // Set internal timing
graph_command(0x00EF, 0x1231); // Set internal timing
graph_command(0x0001, 0x0100); // set SS and SM bit
graph_command(0x0002, 0x0700); // set 1 line inversion
//graph_command(0x0003, 0x1030); // ВЕР ОРИЕН, >
graph_command(0x0003, 0x1018); // ГОР ОРИЕН, >
graph_command(0x0004, 0x0000); // Resize register
graph_command(0x0008, 0x0207); // set the back porch and front porch
graph_command(0x0009, 0x0000); // set non-display area refresh cycle ISC[3:0]
graph_command(0x000A, 0x0000); // FMARK function
graph_command(0x000C, 0x0000); // RGB interface setting
graph_command(0x000D, 0x0000); // Frame marker Position
graph_command(0x000F, 0x0000); // RGB interface polarity
//*************Power On sequence ****************//
graph_command(0x0010, 0x0000); // SAP, BT[3:0], AP, DSTB, SLP, STB
graph_command(0x0011, 0x0007); // DC1[2:0], DC0[2:0], VC[2:0]
graph_command(0x0012, 0x0000); // VREG1OUT voltage
graph_command(0x0013, 0x0000); // VDV[4:0] for VCOM amplitude
DelayMs(200); // Dis-charge capacitor power voltage
graph_command(0x0010, 0x1490); // SAP, BT[3:0], AP, DSTB, SLP, STB
graph_command(0x0011, 0x0227); // DC1[2:0], DC0[2:0], VC[2:0]
DelayMs(50); // Delay 50ms
graph_command(0x0012, 0x001C); // Internal reference voltage= Vci;
DelayMs(50); // Delay 50ms
graph_command(0x0013, 0x1A00); // Set VDV[4:0] for VCOM amplitude
graph_command(0x0029, 0x0025); // Set VCM[5:0] for VCOMH
graph_command(0x002B, 0x000E); // Set Frame Rate
DelayMs(50); // Delay 50ms
graph_command(0x0020, 0x0000); // GRAM horizontal Address
graph_command(0x0021, 0x0000); // GRAM Vertical Address
// ----------- Adjust the Gamma Curve ----------//
graph_command(0x0030, 0x0000);
graph_command(0x0031, 0x0506);
graph_command(0x0032, 0x0104);
graph_command(0x0035, 0x0207);
graph_command(0x0036, 0x000F);
graph_command(0x0037, 0x0306);
graph_command(0x0038, 0x0102);
graph_command(0x0039, 0x0707);
graph_command(0x003C, 0x0702);
graph_command(0x003D, 0x1604);
//------------------ Set GRAM area ---------------//
graph_command(0x0050, 0x0000); // Horizontal GRAM Start Address
graph_command(0x0051, 0x00EF); // Horizontal GRAM End Address
graph_command(0x0052, 0x0000); // Vertical GRAM Start Address
graph_command(0x0053, 0x013F); // Vertical GRAM Start Address
graph_command(0x0060, 0xA700); // Gate Scan Line
graph_command(0x0061, 0x0001); // NDL,VLE, REV
graph_command(0x006A, 0x0000); // set scrolling line
//-------------- Partial Display Control ---------//
graph_command(0x0080, 0x0000);
graph_command(0x0081, 0x0000);
graph_command(0x0082, 0x0000);
graph_command(0x0083, 0x0000);
graph_command(0x0084, 0x0000);
graph_command(0x0085, 0x0000);
//-------------- Panel Control -------------------//
graph_command(0x0090, 0x0010);
graph_command(0x0092, 0x0600);

graph_command(0x0007, 0x0133); // 262K color and display ON


DelayMs(50); // Delay 50ms
graph_command(32, 0);
graph_command(33, 0);
graph_command(34, 0);

//for (i = 0; i < 153280; i++)
// graph_data(0);

uint32_t i,j;


for(i=0;i<Y_SIZE;i++)
for(j=0;j<X_SIZE;j++)
LCD_GRAM[i][j] = 0;

LCD_DAT = (volatile uint16_t*)LCD_GRAM;


__DMA2_CLK_ENABLE();
hdma_memtomem_dma2_stream0.Instance = DMA2_Stream0;
hdma_memtomem_dma2_stream0.Init.Channel = DMA_CHANNEL_0;
hdma_memtomem_dma2_stream0.Init.Direction = DMA_MEMORY_TO_MEMORY;
hdma_memtomem_dma2_stream0.Init.PeriphInc = DMA_PINC_ENABLE;
hdma_memtomem_dma2_stream0.Init.MemInc = DMA_MINC_DISABLE;
hdma_memtomem_dma2_stream0.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_memtomem_dma2_stream0.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_memtomem_dma2_stream0.Init.Mode = DMA_NORMAL;
hdma_memtomem_dma2_stream0.Init.Priority = DMA_PRIORITY_LOW;
hdma_memtomem_dma2_stream0.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_memtomem_dma2_stream0.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
hdma_memtomem_dma2_stream0.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_memtomem_dma2_stream0.Init.PeriphBurst = DMA_MBURST_SINGLE;
HAL_DMA_Init(&hdma_memtomem_dma2_stream0);

HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 4, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

dma_pool = 1;
ILI_TIME = Delay_Tick;
tp_step = 0;
HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream0, (uint32_t)LCD_DAT+640, 0x60020000, 38080);



Код инициализации SDRAM
CODE

GPIO_InitTypeDef GPIO_InitStruct;


GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_11|GPIO_PIN_12
|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5
|GPIO_PIN_8|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14
|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

__FMC_CLK_ENABLE();


FMC_SDRAM_TimingTypeDef SdramTiming;
FMC_SDRAM_CommandTypeDef SdramCommand;

/** Perform the SDRAM1 memory initialization sequence
*/
hsdram1.Instance = FMC_SDRAM_DEVICE;
/* hsdram1.Init */
hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_3;
hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_2;
/* SdramTiming */
SdramTiming.LoadToActiveDelay = 2;
SdramTiming.ExitSelfRefreshDelay = 7;
SdramTiming.SelfRefreshTime = 4;
SdramTiming.RowCycleDelay = 7;
SdramTiming.WriteRecoveryTime = 2;
SdramTiming.RPDelay = 2;
SdramTiming.RCDDelay = 2;

HAL_SDRAM_Init(&hsdram1, &SdramTiming);


SdramCommand.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
SdramCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
SdramCommand.AutoRefreshNumber = 1;
SdramCommand.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &SdramCommand,1000);

SdramCommand.CommandMode = FMC_SDRAM_CMD_PALL;
SdramCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
SdramCommand.AutoRefreshNumber = 1;
SdramCommand.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &SdramCommand,1000);

SdramCommand.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
SdramCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
SdramCommand.AutoRefreshNumber = 8;
SdramCommand.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &SdramCommand,1000);

SdramCommand.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
SdramCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
SdramCommand.AutoRefreshNumber = 1;
SdramCommand.ModeRegisterDefinition = (uint32_t)0x0230;
HAL_SDRAM_SendCommand(&hsdram1, &SdramCommand,1000);

SDRAM_8 = (volatile uint8_t *)((uint32_t)0xC0000000);
SDRAM_16 = (volatile uint16_t *)((uint32_t)0xC0000000);
SDRAM_32 = (volatile uint32_t *)((uint32_t)0xC0000000);


Обработчик прерывания DMA дисплея:
CODE

HAL_DMA_IRQHandler(&hdma_memtomem_dma2_stream0);
hdma_memtomem_dma2_stream0_state = HAL_DMA_GetState(&hdma_memtomem_dma2_stream0);
if(hdma_memtomem_dma2_stream0_state == HAL_DMA_STATE_READY_MEM0)
{
if(dma_pool == 0)
{
graph_fps = Delay_Tick-ILI_TIME;
ILI_TIME = Delay_Tick;

if(tp_step == 4) { TP_Get(); tp_step = 0; }
else tp_step++;

graph_command(32, 0);
graph_command(33, 0);
*(volatile uint16_t *)((uint32_t)0x60000000) = 34;
HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream0, (uint32_t)LCD_DAT+638, 0x60020000, 38081);
dma_pool = 1;

}
else if(dma_pool == 1)
{
//HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream0, (uint32_t)LCD_DAT+76800, 0x60020000, 38400);
HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream0, (uint32_t)LCD_DAT, 0x60020000, 38400);
dma_pool = 2;
}
else if(dma_pool == 2)
{
HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream0, (uint32_t)LCD_DAT, 0x60020000, 319);
dma_pool = 0;
}
}


Сообщение отредактировал VHEMaster - Dec 13 2015, 20:18
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 14 2015, 07:13
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Еррату на этот МК читали? Там много фееричного про SDRAM написано.
Go to the top of the page
 
+Quote Post
VHEMaster
сообщение Dec 14 2015, 19:06
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 28-08-15
Пользователь №: 88 191



Цитата(scifi @ Dec 14 2015, 09:13) *
Еррату на этот МК читали? Там много фееричного про SDRAM написано.


Там нашëл следующее:
Цитата
2.9.7 FMC dynamic and static bank switching Description The dynamic and static banks cannot be accessed concurrently. Workaround Do not use dynamic and static banks at the same time. The SDRAM device must be in selfrefresh before switching to the static memory mapped on the NOR/PSRAM or NAND/PCCard controller. Before switching from static memory to SDRAM, issue a Normal command to wake-up the device from self-refresh mode. This limitation is fixed in silicon revision “3”.

Если не ошибаюсь, у меня ревизия Y. Т.е. возле логотипа ST написана буква Y. Это означает, что я не смогу использовать SDRAM и дисплей одновременно?(


Сообщение отредактировал VHEMaster - Dec 14 2015, 19:30
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 14 2015, 20:05
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(VHEMaster @ Dec 14 2015, 22:06) *
Это означает, что я не смогу использовать SDRAM и дисплей одновременно?(

Почему же? Можно построить программу так, чтобы обойти это ограничение. Некий программный арбитр доступа к внешней шине.
Go to the top of the page
 
+Quote Post
VHEMaster
сообщение Dec 14 2015, 20:36
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 28-08-15
Пользователь №: 88 191



Цитата(scifi @ Dec 14 2015, 22:05) *
Почему же? Можно построить программу так, чтобы обойти это ограничение. Некий программный арбитр доступа к внешней шине.

Я хочу подбрасывать данные с SDRAM в дисплей через DMA... Или предлагаете сначала переписать некоторую часть видеобуфера в ОЗУ МК, затем из него в дисплей и так далее? А если нужно ещё дополнительно поюзать SDRAM, хотя-бы для того чтобы заполнить видеобуфер?...
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 15 2015, 10:06
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(VHEMaster @ Dec 14 2015, 23:36) *
Или предлагаете сначала переписать некоторую часть видеобуфера в ОЗУ МК, затем из него в дисплей и так далее?

Получается так.

Цитата(VHEMaster @ Dec 14 2015, 23:36) *
А если нужно ещё дополнительно поюзать SDRAM, хотя-бы для того чтобы заполнить видеобуфер?...

Разделять по времени дисплей и SDRAM. Арбитр, как и сказано выше.
Геморрой, да. А что делать, кому сейчас легко? laughing.gif
Go to the top of the page
 
+Quote Post
Rash
сообщение Dec 15 2015, 11:57
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231



или заменить контролер на ревизию Z судя по эррате или STM32F469 поставить, сам не пользовался, но думаю должны исправить в новых контроллерах.
Go to the top of the page
 
+Quote Post
VHEMaster
сообщение Dec 24 2015, 13:40
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 28-08-15
Пользователь №: 88 191



Короче, так и не получилось нифига адекватно разделить по времени эти два девайса.. В конечном итоге решил взять VGA монитор bb-offtopic.gif
Go to the top of the page
 
+Quote Post
SpyBot
сообщение Jan 17 2016, 13:59
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 285
Регистрация: 5-11-05
Пользователь №: 10 491



А почему вы выбрали вариант подключения дисплея через FMC?
Go to the top of the page
 
+Quote Post

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

 


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


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