Перейти к содержанию
    

Господа, продолжаю бороться со связкой STM32F746+SDRAM MT48LC4M32B2P-6A  +TouchGFX.

C созданием и компиляцией проекта проблем нет. Но при работе есть артефакты.

Вот такие вертикальные полосы сбоку от элементов

renditionDownload?rendition=ORIGINAL_Jpg

 

Избавиться от них удалось лишь тогда, когда я инициализировал память не в 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 */
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если на аппаратные проблемы думать, то тогда напишите, какая длина трасс? какой разброс длин? пробовали паттерны какие-то выводить - может у вас проблема по конкретным линиям данных?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 hours ago, Aaron said:

если на аппаратные проблемы думать, то тогда напишите, какая длина трасс? какой разброс длин? пробовали паттерны какие-то выводить - может у вас проблема по конкретным линиям данных?

Тестировал заполнением псевдослучайной последовательностью.

Мне кажется, если бы проблемы были в том, о чем вы говорите, то есть косяки на конкретных линиях данных, то артефакты были бы привязаны не к месту, а к цвету. И не были бы постоянны. А тут есть элементы интерфейса, которые не подвержены этой проблеме. То есть по проблема возникает при каком-то определенном "спецэффекте" графического движка. Но непонятно, как на это влияет разрядность, если графический движок про память вообще ничего не знает. 

Кстати, еще одна проблема - на круге полосы видите? Так  вот эта проблема решается двумя действиями - переключением цвета в формат rgb565 и пресловутым включением памяти в 16 битный режим.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

у меня вот так прекрасно работает

  SdramTiming.RowCycleDelay = 6;
  SdramTiming.WriteRecoveryTime = 2;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

27 minutes ago, golf2109 said:

у меня вот так прекрасно работает

  SdramTiming.RowCycleDelay = 6;
  SdramTiming.WriteRecoveryTime = 2;

Работает sdram как таковая? Или в связке с touchgfx? Если второе, то какая у вас глубина цвета?

Попробовал на дискавери - там конечно же только 16 битный режим памяти, но артефактов нет даже при rgb888.  А на моей плате, если включаешь 16 бит, то исчезают только те полосы, что сбоку картинок, полосатость же круга остается, чтоб ее убрать, нужно включать  rgb565. Проц и память те же, только в bga. Но с другой стороны, экран меньше. Вот и ищи, блин, отличия...

Может, dma2d чудит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 hours ago, MementoMori said:

Что интересно, похожие вертикальные белые полосы, но не с краю, а внутри картинок появились когда я случайно в одном месте, где инициализируется SDRAM, указал CAS Latency=2, а в другом - 3.  То есть в принципе аппаратная проблема может иметь место. 

Коллега, и всё же предлагаю отмести железобетонно аппаратные проблемы.

Quote

Мне кажется, если бы проблемы были в том, о чем вы говорите, то есть косяки на конкретных линиях данных, то артефакты были бы привязаны не к месту, а к цвету.

Я вижу, что на приведённой картинке линии имеют разный цвет ;)

Как предположение (надо смотреть код touchGFX) - у вас обмен с SDRAM проводится в виде транзакций. Одна строчка изображения - одна транзакция. В промежутках между транзакциями шина может не использоваться. При проблемах в топологии из-за нарушения целостности сигналов могут быть всякие чудеса. Например, при появлении данных на линии первые биты могут портиться, и потом при окончании транзакции последние биты портиться. Может, у вас на линии идёт какая-то наводка извне? При этом, если данные передавать непрерывно, то проблема может не проявляться визуально.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хорошо, вечером приведу длины проводников.

Вообще, я все тестировал в гиперлинксе, глазковая диаграмма более чем хороша, перекрестные помехи имели место лишь где-то на линиях дисплея, но не превышали 200 мВ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Quote

вас обмен с SDRAM проводится в виде транзакций. Одна строчка изображения - одна транзакция. В промежутках между транзакциями шина может не использоваться. 

А нельзя ли поподробнее насчет транзакций? Это нечто конкретное и специфичское или вы под этим понимаете обычную операцию чтения записи?

Я к чему спрашиваю - тестирование у меня ошибок не выявило. Но вы говорите, при непрерывном чтении ошибеа может и не проявиться.

У меня  есть мысль -написать свою собственную функцию вывода картинки на экран, чтобы она создавала условия для возникновения ошибки, о которой вы говорите, те условия, которые, предположительно, создает код touchgfx. Если это получится, то значит с touchgfx обвинения снимаются.

Так вот как это сделать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, MementoMori сказал:

Работает sdram как таковая? Или в связке с touchgfx? Если второе, то какая у вас глубина цвета?

Попробовал на дискавери - там конечно же только 16 битный режим памяти, но артефактов нет даже при rgb888.  А на моей плате, если включаешь 16 бит, то исчезают только те полосы, что сбоку картинок, полосатость же круга остается, чтоб ее убрать, нужно включать  rgb565. Проц и память те же, только в bga. Но с другой стороны, экран меньше. Вот и ищи, блин, отличия...

Может, dma2d чудит?

работает в связке с touchgfx rgb888, 800х480 память в TSSOP 84

проверьте clk дисплея на предмет помех вплоть до перерезания и подключения

отдельным проводом

 

Изменено пользователем golf2109

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

52 minutes ago, golf2109 said:

работает в связке с touchgfx rgb888, 800х480 память в TSSOP 84

Попутный вопрос - а каков пиксельклок у вас? У разработчика touchgfx написано, что более 30 мгц - проблема. У меня как раз на 30 мгц дисплей перестает заводиться.

 

52 minutes ago, golf2109 said:

проверьте clk дисплея на предмет помех

Если с клоком самого дисплея проблема, тогда точно к картинке привязки не будет.

Но попробую проверить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Оно конечно малопонятно, но так, для информации - подсвечены те линии, которые в 16 битном режиме не задействованы, то есть те, которые в 32 битном режиме могут создавать проблемы.

Клок - это идущая отдельно от остальных линия, в левых отделах схемы.  По картинке неясно, но клок идет в отдельном слое, окружен землей.

DgbA1uA5.png?download=1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 hours ago, golf2109 said:

проверьте clk дисплея на предмет помех вплоть до перерезания и подключения

отдельным проводом

Вы, батенька, садист)))

Но я последовал Вашему совету - не помогло.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Наполовину проблему решил!!!

Дело было в 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);

}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот таким тестом долго гонял вчера память

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;    
}

Ошибок нет.

Может есть какой-нибудь более агрессивный тест?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Делал даже так, чтобы каждый при каждом чтении приходилось обращаться в две соседние ячейки, а потом клеить ответ

 

result_byte=*(__IO uint32_t*)(0xD0000000 + 4*uwIndex+1);  - адрес увеличивал на единичку, то есть читались биты 8-31, затем в следующей ячейке 0-7  

ошибок нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...