Jump to content

    

STM32H743 + SDRAM MT48LC32M16A2-75

Вот пытаюсь запустить указанную связку (STM32H743 + SDRAM MT48LC32M16A2-75).

Результат пока хреновый - читается какой-то бред. Не пашет вобщем :(

Если точнее - весь объём памяти (64 MB) доступен, ни в накие xxxHandler проц не вылетает, но с чтением/записью памяти трудности.

После заполнения памяти нулями оттуда читаются слова 0x2004. Казалось бы D13 и D2 где-то коротят на Vcc, но не так-то всё просто - простая запись байтов по адресу 0xC0000000 (у меня банк 0) показывает, что 2-й бит всё же сбрасывается. При этом в MemoryBrowser атоллика видно, что при этом меняются какие-то другие байты по другим адресам - хз почему. Ну и подобные баги.

Все кэши проца выключены, На FMC подаётся 180 МГц, на память - 90. Инициализация FMC+чип:

Spoiler

/**
  * @brief  FMC SDRAM Mode definition register defines
  */
#define SDRAM_MODEREG_BURST_LENGTH_1             ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2             ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4             ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8             ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2              ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3              ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     ((uint16_t)0x0200)

/**
  * @brief  Programs the SDRAM device.
  * @retval None
  */
static void BSP_SDRAM_Initialization_sequence( void )
{
  FMC_SDRAM_CommandTypeDef Command;

  Command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
  Command.AutoRefreshNumber      = 0;
  Command.ModeRegisterDefinition = 0;

  // Запись в регистр FMC_SDCMR

  /* Step 1: Configure a clock configuration enable command */
  Command.CommandMode            = FMC_SDRAM_CMD_CLK_ENABLE;			// 1
//  HAL_SDRAM_SendCommand ( &hsdram1, &Command, SDRAM_TIMEOUT );
  // Send SDRAM command (timeout unused)
  FMC_SDRAM_SendCommand ( FMC_SDRAM_DEVICE, &Command, 0 );
  // Inserted delay is equal to 1 ms due to systick time base unit (ms)
  HAL_Delay(1);

  /* Step 2: Configure a PALL (precharge all) command */
  Command.CommandMode            = FMC_SDRAM_CMD_PALL;					// 2
//  HAL_SDRAM_SendCommand ( &hsdram1, &Command, SDRAM_TIMEOUT );
  // Send SDRAM command (timeout unused)
  FMC_SDRAM_SendCommand ( FMC_SDRAM_DEVICE, &Command, 0 );
  // Inserted delay is equal to 1 ms due to systick time base unit (ms)
  HAL_Delay(1);

  /* Step 3: Configure an Auto Refresh command */
  Command.CommandMode            = FMC_SDRAM_CMD_AUTOREFRESH_MODE;		// 3
//  HAL_SDRAM_SendCommand ( &hsdram1, &Command, SDRAM_TIMEOUT );
// Send SDRAM command (timeout unused)
  FMC_SDRAM_SendCommand ( FMC_SDRAM_DEVICE, &Command, 0 );
  // Inserted delay is equal to 1 ms due to systick time base unit (ms)
  HAL_Delay(1);

  /* Step 4: Program the external memory mode register */
  // // 0x04 - LOAD_MODE --> SDCMR.MRD (bits 22..9)
  Command.CommandMode            = FMC_SDRAM_CMD_LOAD_MODE;				// 4
//  Command.ModeRegisterDefinition = 0x0230;		// From F439
  // 0x0200 | 0x0030
  Command.ModeRegisterDefinition = SDRAM_MODEREG_WRITEBURST_MODE_SINGLE | SDRAM_MODEREG_CAS_LATENCY_3;
//  HAL_SDRAM_SendCommand ( &hsdram1, &Command, SDRAM_TIMEOUT );
  // Send SDRAM command (timeout unused)
  FMC_SDRAM_SendCommand ( FMC_SDRAM_DEVICE, &Command, 0 );
  // Inserted delay is equal to 1 ms due to systick time base unit (ms)
  HAL_Delay(1);

  // Step 5: Set the refresh rate counter
/*
   * Refresh rate = (COUNT+1) * SDRAM clock frequency
   * COUNT = (SDRAM refresh period / Number of rows ) * SDCLK -20  --> FMC_RTR
   * SDRAM refresh period = 64 mc (from SDRAM chip period)
   *  Rows = 8192
   *  COUNT = (64 ms / 8192) - 20 = 0,0078125 ms - 20 = 7.8125mks * 90E6 - 20 = 703,125 - 20 = 683
 */
//  HAL_SDRAM_ProgramRefreshRate ( &hsdram1, 683 );
  FMC_SDRAM_ProgramRefreshRate ( FMC_SDRAM_DEVICE, 683 );  // -> SDRTR = 683 = 0x2AB << 1 = 0x0556

  // Inserted delay is equal to 1 ms due to systick time base unit (ms)
  HAL_Delay(1);
} // BSP_SDRAM_Initialization_sequence

// FMC initialization function
static void MX_FMC_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
//  SDRAM_HandleTypeDef hsdram1;
//  FMC_SDRAM_TimingTypeDef SdramTiming = {0};

  // init FMC pins
  /** FMC GPIO Configuration
  PC2_C  ------> FMC_SDNE0  +
  PD0    ------> FMC_D2     +
  PD1    ------> FMC_D3     +
  PD8    ------> FMC_D13    +
  PD9    ------> FMC_D14    +
  PD10   ------> FMC_D15    +
  PD14   ------> FMC_D0     +
  PD15   ------> FMC_D1     +

  PE0    ------> FMC_NBL0   +
  PE1    ------> FMC_NBL1   +
  PE7    ------> FMC_D4     +
  PE8    ------> FMC_D5     +
  PE9    ------> FMC_D6     +
  PE10   ------> FMC_D7     +
  PE11   ------> FMC_D8     +
  PE12   ------> FMC_D9     +
  PE13   ------> FMC_D10    +
  PE14   ------> FMC_D11    +
  PE15   ------> FMC_D12    +

  PF0    ------> FMC_A0     +
  PF1    ------> FMC_A1     +
  PF2    ------> FMC_A2     +
  PF3    ------> FMC_A3     +
  PF4    ------> FMC_A4     +
  PF5    ------> FMC_A5     +
  PF11   ------> FMC_SDNRAS +
  PF12   ------> FMC_A6     +
  PF13   ------> FMC_A7     +
  PF14   ------> FMC_A8     +
  PF15   ------> FMC_A9     +

  PG0    ------> FMC_A10    +
  PG1    ------> FMC_A11    +
  PG2    ------> FMC_A12    +
  PG4    ------> FMC_BA0    +
  PG5    ------> FMC_BA1    +
  PG8    ------> FMC_SDCLK  +
  PG15   ------> FMC_SDNCAS +

  PH2    ------> FMC_SDCKE0 +
  PH5    ------> FMC_SDNWE  +
  */

  // PC2
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init ( GPIOC, &GPIO_InitStruct );

  // PD0, PD1, PD8..PD10, PD14, PD15
  GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init ( GPIOD, &GPIO_InitStruct );

  // PE0, PE1, PE7..PE15
  GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | 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_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init ( GPIOE, &GPIO_InitStruct );

  // PF0..PF5, PF11..PF15
  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_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init ( GPIOF, &GPIO_InitStruct );

  // PG0..5, PG8, PG15
  GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init ( GPIOG, &GPIO_InitStruct );

  // PH2, PH5
  GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init ( GPIOH, &GPIO_InitStruct );

  // Enable the FMC/FSMC interface clock
  RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN;

/*
                     15  12 11  8 7  4 3  0
FMC_SDCR1 = 0x29DA = 0010   1001 1101 1010:
RPIPE  - bits 14..13 = 01 - 1 cycle delay (+)
RBURST - bit  12     = 0  - disable (+)
SDCLK  - bits 11..10 = 10 - 2xCLK (+)
WP     - bit  9      = 0  - write allowed (+)
CAS    - bits 8..7   = 11 - 3 cycles (+)
NB     - bit  6      = 1  - 4 banks (+)
MWID   - bits 5..4   = 01 - Memory data width (+)
NR     - bits 3..2   = 10 - Row address 13 bits (+)
NC     - bits 1..0   = 10 - Column address 10 bits (+)
 */
  FMC_SDRAM_DEVICE -> SDCR[FMC_SDRAM_BANK1] = 0x29DA;

  // SDRAM timing
/*
                               TRCD  TRP  TWR  TRC TRAS TXSR TMRD
FMC_SDTR1 = 0x02246472 =  0000 0010 0010 0100 0110 0100 0111 0010

TRCD = 2
TRP  = 2
TWR  = 4
TRC  = 6
TRAS = 4
TXSR = 7
TMRD = 2
*/
  FMC_SDRAM_DEVICE -> SDTR[FMC_SDRAM_BANK1] = 0x02246472;

  // Enable FMC Peripheral
  __FMC_ENABLE ( );			// FMC_Bank1_R->BTCR[0] |= FMC_BCR1_FMCEN;

  // init SDRAM chip
  BSP_SDRAM_Initialization_sequence ( );

  // Очищаем SDRAM
  uint32_t tmp;
  uint32_t size_div4 = SDRAM_SIZE / 4;
  for ( tmp = SDRAM_BASE; tmp < (SDRAM_BASE + size_div4); tmp += 4 )
    *((uint32_t *)tmp) = 0x00000000;
} // MX_FMC_Init

 

 

Тактирование (тут чистый кубовый хал):

  // PLL2R - FMC (180 MHz)
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_USB | RCC_PERIPHCLK_QSPI | RCC_PERIPHCLK_FMC;
  PeriphClkInitStruct.PLL2.PLL2M = 8;
  PeriphClkInitStruct.PLL2.PLL2N = 180;
  PeriphClkInitStruct.PLL2.PLL2P = 2;
  PeriphClkInitStruct.PLL2.PLL2Q = 1;
  PeriphClkInitStruct.PLL2.PLL2R = 1;
  PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;
  PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOMEDIUM;
  PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
  // PLL3Q - LTDC (50 MHz)
  PeriphClkInitStruct.PLL3.PLL3M = 8;
  PeriphClkInitStruct.PLL3.PLL3N = 50;
  PeriphClkInitStruct.PLL3.PLL3P = 2;
  PeriphClkInitStruct.PLL3.PLL3Q = 4;
  PeriphClkInitStruct.PLL3.PLL3R = 1;
  PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_0;
  PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE;
  PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
  PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_PLL2;	// PLL2R
  PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_PLL;
  PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

Кварц 8МГц. (8/8)*180/1=180MHz.

LTDC нету, просто сконфигурено тактирование. Думать о нём без памяти бессмысленно.

Такой же чип памяти прекрасно работает на Ф439. Здесь нашёл тему

, но ТС так и не отписался, заработало у него что-то или нет, а сама тема укатилась хз куда...

 

Может я чего не понял, как конфигурить это FMC. От Ф4 оно кое-где отличается.

Спасибо.

Share this post


Link to post
Share on other sites

Повключал и настроил всё:

	// Enable I-Cache
	SCB_EnableICache ( );

	// Enable D-Cache
	SCB_EnableDCache();

    MPU_Region_InitTypeDef MPU_InitStruct;
	HAL_MPU_Disable();

	/* Configure the MPU attributes as WT for SDRAM */
//	MPU_Region_InitTypeDef MPU_InitStruct;
	MPU_InitStruct.Enable = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress = SDRAM_BASE;
	MPU_InitStruct.Size = MPU_REGION_SIZE_64MB;
	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
	MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
	MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
	MPU_InitStruct.Number = MPU_REGION_NUMBER1;
	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

	HAL_MPU_ConfigRegion ( &MPU_InitStruct );

	// Enable the MPU
	HAL_MPU_Enable ( MPU_PRIVILEGED_DEFAULT );

Никакой разницы не заметил. Может я FMC/SDRAM неправильно сконфигурил?

Share this post


Link to post
Share on other sites

Где-то читал в теме, что кому-то помогло включить "умощнение" внутреннего генератора частоты для работы.
Но я бы начал с перетягивания кода с рабочего примера, в папке репозитории Куба есть пример для STM32H743I_EVAL.
Там в main.c еще многое чего включается, что Куб не включил...

Share this post


Link to post
Share on other sites

SDRAM на фабричной девборде или самодельная? Что там с трассировкой? Сколько слоёв платы?

 

Очень странно. Запускал SDRAM на C6545 и BF532/533 запускалась с первого раза.  Настройки брал готовые для нужной SDRAM.

Share this post


Link to post
Share on other sites
9 hours ago, __inline__ said:

SDRAM на фабричной девборде или самодельная? Что там с трассировкой? Сколько слоёв платы?

 

Очень странно. Запускал SDRAM на C6545 и BF532/533 запускалась с первого раза.  Настройки брал готовые для нужной SDRAM.

Разводили сами в альтиуме (под Ф439+такой же SDRAM, который с полпинка взлетел тоже также разводили), заказывали в Китае. Дорожки рисовали руками с контролем длины. В принципе могу выложить альтиумные файлы, секретного там ничего нет, по сути макетка для разборок с этим процом.

Плата 6-слойная (Ф439 - 4 слойная была). Настройки чипа взял из того же 439.

18 hours ago, sadat said:

Где-то читал в теме, что кому-то помогло включить "умощнение" внутреннего генератора частоты для работы.
Но я бы начал с перетягивания кода с рабочего примера, в папке репозитории Куба есть пример для STM32H743I_EVAL.
Там в main.c еще многое чего включается, что Куб не включил...

Что такое "умощнение" внутреннего генератора частоты для работы? Приложил схему синхронизации из куба. FMC там виден.

STM32H743I_EVAL вроде смотрел, пересмотрю ещё раз, может прогавил чего.

sync.png

Share this post


Link to post
Share on other sites
On 9/9/2019 at 7:15 PM, hd44780 said:

Вот пытаюсь запустить указанную связку (STM32H743 + SDRAM MT48LC32M16A2-75).

Вот, в приложении рабочая конфигурация для варианта STM32F767 и MT48LC32M16A2-75.

Частота 216 МГц (кварц 25 МГц), память 108 МГц. Если для копирования массивов в/из SDRAM будет использована память DTCM, то MPU можно не трогать.

Tmp.zip

Edited by ksv198

Share this post


Link to post
Share on other sites

Спасибо, гляну.

Я от SDRAM немного отвлёкся, запустил QSPI память w25n01gv, вроде пашет, но частоту выше 16.5 МГц поднять не могу - обмен виснет на опросе какого-то флага. Вожусь пока.

Что касается SDRAM, то нашёл, что нога PC2 (сигнал NE0 - nCS) у этого проца двойным дном, по дефолту там сидит АЦП. Добавил в инит пинов SYSCFG->PMCR |= SYSCFG_PMCR_PC2SO;  перед манипуляциями с GPIO регистрами.

Улучшений пока не заметил.

MPU пока выключил, на простую запись/чтение не влияет, а обо всём остальном говорить пока рано.

Share this post


Link to post
Share on other sites
On 9/14/2019 at 6:30 PM, hd44780 said:

Что такое "умощнение" внутреннего генератора частоты для работы? Приложил схему синхронизации из куба. FMC там виден.

Может некорректно выразился, но вот ссылка... Вдруг поможет.
Ну и, повторюсь, попробуйте скопировать код из примеров от СТ.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now