MementoMori 4 16 февраля, 2020 Опубликовано 16 февраля, 2020 · Жалоба Господа, продолжаю бороться со связкой STM32F746+SDRAM MT48LC4M32B2P-6A +TouchGFX. C созданием и компиляцией проекта проблем нет. Но при работе есть артефакты. Вот такие вертикальные полосы сбоку от элементов Избавиться от них удалось лишь тогда, когда я инициализировал память не в 32, а в 16-битном режиме. И это, если честно, вызвало удивление. С одной стороны, SDRAM проецируется в единое адресное пространство и TouchGFX работает с ней, даже не зная, что это SDRAM. Для системы - что 16 бит, что 32 - без разницы. То есть проблема должна быть с аппаратной частью SDRAM. но с другой стороны - я неоднократно тестировал SDRAM - ошибок нет. А вот в работе с TouchGFX появляются артефакты. Что интересно, похожие вертикальные белые полосы, но не с краю, а внутри картинок появились когда я случайно в одном месте, где инициализируется SDRAM, указал CAS Latency=2, а в другом - 3. То есть в принципе аппаратная проблема может иметь место. Смех в том, что когда я еще прорабатывал архитектуру и думал, стоит ли заморачиваться с 32 бит, один товарищ здесь на форуме написал, что у него с 16 бит были артефакты, которые исчезли, когда он поставил 32 бит. Может есть какие тонкости в работе с 32 битной SDRAM? Кто-нибудь сталкивался с подобной проблемой? Вот так я ее инициализирую Spoiler static void MX_FMC_Init(void) { /* USER CODE BEGIN FMC_Init 0 */ /* USER CODE END FMC_Init 0 */ FMC_SDRAM_TimingTypeDef SdramTiming = {0}; /* USER CODE BEGIN FMC_Init 1 */ /* USER CODE END FMC_Init 1 */ /** Perform the SDRAM1 memory initialization sequence */ hsdram1.Instance = FMC_SDRAM_DEVICE; /* hsdram1.Init */ hsdram1.Init.SDBank = FMC_SDRAM_BANK2; 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_32; 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_2; hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE; hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0; /* SdramTiming */ SdramTiming.LoadToActiveDelay = 2; SdramTiming.ExitSelfRefreshDelay = 7; SdramTiming.SelfRefreshTime = 4; SdramTiming.RowCycleDelay = 7; SdramTiming.WriteRecoveryTime = 3; SdramTiming.RPDelay = 2; SdramTiming.RCDDelay = 2; if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK) { Error_Handler( ); } /* USER CODE BEGIN FMC_Init 2 */ __IO uint32_t tmpmrd = 0; /* Step 1: Configure a clock configuration enable command */ Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0; /* Send the command */ HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); /* Step 2: Insert 100 us minimum delay */ /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */ HAL_Delay(1); /* Step 3: Configure a PALL (precharge all) command */ Command.CommandMode = FMC_SDRAM_CMD_PALL; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0; /* Send the command */ HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); /* Step 4: Configure an Auto Refresh command */ Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 8; Command.ModeRegisterDefinition = 0; /* Send the command */ HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); /* Step 5: Program the external memory mode register */ tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | \ SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | \ SDRAM_MODEREG_CAS_LATENCY_3 | \ SDRAM_MODEREG_OPERATING_MODE_STANDARD | \ SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = tmpmrd; /* Send the command */ HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); /* Step 6: Set the refresh rate counter */ /* Set the device refresh rate */ HAL_SDRAM_ProgramRefreshRate(&hsdram1, REFRESH_COUNT); //Deactivate speculative/cache access to first FMC Bank to save FMC bandwidth FMC_Bank1->BTCR[0] = 0x000030D2; /* USER CODE END FMC_Init 2 */ } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aaron 1 16 февраля, 2020 Опубликовано 16 февраля, 2020 · Жалоба если на аппаратные проблемы думать, то тогда напишите, какая длина трасс? какой разброс длин? пробовали паттерны какие-то выводить - может у вас проблема по конкретным линиям данных? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 17 февраля, 2020 Опубликовано 17 февраля, 2020 · Жалоба 6 hours ago, Aaron said: если на аппаратные проблемы думать, то тогда напишите, какая длина трасс? какой разброс длин? пробовали паттерны какие-то выводить - может у вас проблема по конкретным линиям данных? Тестировал заполнением псевдослучайной последовательностью. Мне кажется, если бы проблемы были в том, о чем вы говорите, то есть косяки на конкретных линиях данных, то артефакты были бы привязаны не к месту, а к цвету. И не были бы постоянны. А тут есть элементы интерфейса, которые не подвержены этой проблеме. То есть по проблема возникает при каком-то определенном "спецэффекте" графического движка. Но непонятно, как на это влияет разрядность, если графический движок про память вообще ничего не знает. Кстати, еще одна проблема - на круге полосы видите? Так вот эта проблема решается двумя действиями - переключением цвета в формат rgb565 и пресловутым включением памяти в 16 битный режим. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
golf2109 0 17 февраля, 2020 Опубликовано 17 февраля, 2020 · Жалоба у меня вот так прекрасно работает SdramTiming.RowCycleDelay = 6; SdramTiming.WriteRecoveryTime = 2; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 17 февраля, 2020 Опубликовано 17 февраля, 2020 · Жалоба 27 minutes ago, golf2109 said: у меня вот так прекрасно работает SdramTiming.RowCycleDelay = 6; SdramTiming.WriteRecoveryTime = 2; Работает sdram как таковая? Или в связке с touchgfx? Если второе, то какая у вас глубина цвета? Попробовал на дискавери - там конечно же только 16 битный режим памяти, но артефактов нет даже при rgb888. А на моей плате, если включаешь 16 бит, то исчезают только те полосы, что сбоку картинок, полосатость же круга остается, чтоб ее убрать, нужно включать rgb565. Проц и память те же, только в bga. Но с другой стороны, экран меньше. Вот и ищи, блин, отличия... Может, dma2d чудит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aaron 1 17 февраля, 2020 Опубликовано 17 февраля, 2020 · Жалоба 12 hours ago, MementoMori said: Что интересно, похожие вертикальные белые полосы, но не с краю, а внутри картинок появились когда я случайно в одном месте, где инициализируется SDRAM, указал CAS Latency=2, а в другом - 3. То есть в принципе аппаратная проблема может иметь место. Коллега, и всё же предлагаю отмести железобетонно аппаратные проблемы. Quote Мне кажется, если бы проблемы были в том, о чем вы говорите, то есть косяки на конкретных линиях данных, то артефакты были бы привязаны не к месту, а к цвету. Я вижу, что на приведённой картинке линии имеют разный цвет ;) Как предположение (надо смотреть код touchGFX) - у вас обмен с SDRAM проводится в виде транзакций. Одна строчка изображения - одна транзакция. В промежутках между транзакциями шина может не использоваться. При проблемах в топологии из-за нарушения целостности сигналов могут быть всякие чудеса. Например, при появлении данных на линии первые биты могут портиться, и потом при окончании транзакции последние биты портиться. Может, у вас на линии идёт какая-то наводка извне? При этом, если данные передавать непрерывно, то проблема может не проявляться визуально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 17 февраля, 2020 Опубликовано 17 февраля, 2020 · Жалоба Хорошо, вечером приведу длины проводников. Вообще, я все тестировал в гиперлинксе, глазковая диаграмма более чем хороша, перекрестные помехи имели место лишь где-то на линиях дисплея, но не превышали 200 мВ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 17 февраля, 2020 Опубликовано 17 февраля, 2020 · Жалоба Quote вас обмен с SDRAM проводится в виде транзакций. Одна строчка изображения - одна транзакция. В промежутках между транзакциями шина может не использоваться. А нельзя ли поподробнее насчет транзакций? Это нечто конкретное и специфичское или вы под этим понимаете обычную операцию чтения записи? Я к чему спрашиваю - тестирование у меня ошибок не выявило. Но вы говорите, при непрерывном чтении ошибеа может и не проявиться. У меня есть мысль -написать свою собственную функцию вывода картинки на экран, чтобы она создавала условия для возникновения ошибки, о которой вы говорите, те условия, которые, предположительно, создает код touchgfx. Если это получится, то значит с touchgfx обвинения снимаются. Так вот как это сделать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
golf2109 0 17 февраля, 2020 Опубликовано 17 февраля, 2020 (изменено) · Жалоба 2 часа назад, MementoMori сказал: Работает sdram как таковая? Или в связке с touchgfx? Если второе, то какая у вас глубина цвета? Попробовал на дискавери - там конечно же только 16 битный режим памяти, но артефактов нет даже при rgb888. А на моей плате, если включаешь 16 бит, то исчезают только те полосы, что сбоку картинок, полосатость же круга остается, чтоб ее убрать, нужно включать rgb565. Проц и память те же, только в bga. Но с другой стороны, экран меньше. Вот и ищи, блин, отличия... Может, dma2d чудит? работает в связке с touchgfx rgb888, 800х480 память в TSSOP 84 проверьте clk дисплея на предмет помех вплоть до перерезания и подключения отдельным проводом Изменено 17 февраля, 2020 пользователем golf2109 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 17 февраля, 2020 Опубликовано 17 февраля, 2020 · Жалоба 52 minutes ago, golf2109 said: работает в связке с touchgfx rgb888, 800х480 память в TSSOP 84 Попутный вопрос - а каков пиксельклок у вас? У разработчика touchgfx написано, что более 30 мгц - проблема. У меня как раз на 30 мгц дисплей перестает заводиться. 52 minutes ago, golf2109 said: проверьте clk дисплея на предмет помех Если с клоком самого дисплея проблема, тогда точно к картинке привязки не будет. Но попробую проверить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 17 февраля, 2020 Опубликовано 17 февраля, 2020 · Жалоба Оно конечно малопонятно, но так, для информации - подсвечены те линии, которые в 16 битном режиме не задействованы, то есть те, которые в 32 битном режиме могут создавать проблемы. Клок - это идущая отдельно от остальных линия, в левых отделах схемы. По картинке неясно, но клок идет в отдельном слое, окружен землей. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 17 февраля, 2020 Опубликовано 17 февраля, 2020 · Жалоба 4 hours ago, golf2109 said: проверьте clk дисплея на предмет помех вплоть до перерезания и подключения отдельным проводом Вы, батенька, садист))) Но я последовал Вашему совету - не помогло. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 17 февраля, 2020 Опубликовано 17 февраля, 2020 · Жалоба Наполовину проблему решил!!! Дело было в MPU_Config() Оказывается куб сгенерировал автоматом настройки только для QSPI, то есть для адреса 0x90000000. Я настроил согласно AN4861, поменяв только адреса и размеры буферов - изображения всех виджетов пришли в норму - проблемы были со многими, на картинке я привел лишь сектор, он теперь без полосок. Но полосы в начале и в конце некоторых виджетов и в текстовых элементах все равно остались. Посмотрите как я настроил - может у меня все еще что-то не так? Для справки - у меня SDRAM по адресу 0xD0000000, буферизация двойная, второй буфер по адресу 0x90200000 (размер буфера 0x1C2000). void MPU_Config(void) { MPU_Region_InitTypeDef MPU_InitStruct = {0}; /* Disables the MPU */ HAL_MPU_Disable(); /** Initializes and configures the Region and the memory to be protected */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.BaseAddress = 0xD0000000; MPU_InitStruct.Size = MPU_REGION_SIZE_16MB; MPU_InitStruct.SubRegionDisable = 0x0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /** Initializes and configures the Region and the memory to be protected */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.BaseAddress = 0xD0000000; MPU_InitStruct.Size = MPU_REGION_SIZE_2MB; MPU_InitStruct.SubRegionDisable = 0x0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /** Initializes and configures the Region and the memory to be protected */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER2; MPU_InitStruct.BaseAddress = 0xD0200000; MPU_InitStruct.Size = MPU_REGION_SIZE_2MB; MPU_InitStruct.SubRegionDisable = 0x0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /** Initializes and configures the Region and the memory to be protected */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER3; MPU_InitStruct.BaseAddress = 0x90000000; MPU_InitStruct.Size = MPU_REGION_SIZE_256MB; MPU_InitStruct.SubRegionDisable = 0x0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /** Initializes and configures the Region and the memory to be protected */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER4; MPU_InitStruct.BaseAddress = 0x90000000; MPU_InitStruct.Size = MPU_REGION_SIZE_16MB; MPU_InitStruct.SubRegionDisable = 0x0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.AccessPermission = MPU_REGION_PRIV_RO; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* Enables the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 18 февраля, 2020 Опубликовано 18 февраля, 2020 · Жалоба Вот таким тестом долго гонял вчера память Quote srand(1); for (uwIndex = 0; uwIndex < 4194304; uwIndex++) { *(__IO uint32_t*)(SDRAM_BANK_ADDR + 4*uwIndex) = rand(); } srand(1); for (uwIndex = 0; uwIndex < 4194304; uwIndex++) if (*(__IO uint32_t*)(SDRAM_BANK_ADDR + 4*(uwIndex))!=rand()) err=1; } Ошибок нет. Может есть какой-нибудь более агрессивный тест? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MementoMori 4 18 февраля, 2020 Опубликовано 18 февраля, 2020 · Жалоба Делал даже так, чтобы каждый при каждом чтении приходилось обращаться в две соседние ячейки, а потом клеить ответ result_byte=*(__IO uint32_t*)(0xD0000000 + 4*uwIndex+1); - адрес увеличивал на единичку, то есть читались биты 8-31, затем в следующей ячейке 0-7 ошибок нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться