Jump to content

    

STM32H743II + HY57V64820HG(SDRAM) - не могу запустить

Recommended Posts

kostya-m

Получил из производства пару новоразработанных плат с озвученными чипами. Остальное не важно. Не могу запустить это 8-и битный SDRAM на FMC. 

Смотрю четырехканальным осциллоскопом, вроде все команды и временные диаграммы в порядке. Специально сделал после записи долгий цикл на чтение и заметил, что шина данных не управляется чипом. Если взять резистором и сделать подтяжку к земле или плюсу, то этот бит утягивается туда же, за исключением коротких моментов autorefresh. Я ожидаю, что шина должны управляться, когда nSC=0 nCAS=0 nRAS=1 nWE=1. Сочетание этих битиков проверено на осциллограммах, но шина не управляется чипом ОЗУ. Можно ли считать, что чип попался битый (на обоих платах) или надо бы еще что проверить? Тайминги, частоты и т.п. менял. Инициализация как положено с записью в регистры. В т.ч. собственно запись в регистр в режиме пошаговой отладки проверена на осциллограмме. Есть странная нога DQM у этого чипа, которая не имеет смысла для 8-и битного чипа и FMC под нее ничего не назначает. Пробовал ее и в 0 и 1 - не повлияло.

Share this post


Link to post
Share on other sites

aaarrr
19 minutes ago, kostya-m said:

Есть странная нога DQM у этого чипа, которая не имеет смысла для 8-и битного чипа

То есть как не имеет? А если 8-битными корпусами 64-битная шина набрана?

Share this post


Link to post
Share on other sites

kostya-m
1 minute ago, aaarrr said:

То есть как не имеет? А если 8-битными корпусами 64-битная шина набрана?

Только в даташите про нее нормально ничего не сказано. Сделал возможность подать и 0 и 1. Но это не изменяет ситуации.

Share this post


Link to post
Share on other sites

kostya-m
3 hours ago, Arlleex said:

А на CKE и CLK что при этом?

На CKE постоянно 1. На CLK клок. Сначала сделал на 100 МГц. Потом для упрощения отладки сделал 50 МГц, но с сохранением интервала ауторефреша 64 мс / 4096

17 hours ago, kostya-m said:

Сделал возможность подать и 0 и 1. Но это не изменяет ситуации.

Не совсем. Если DQM = 0, то в момент ауторефреш идет выброс на шине, а если =1, то шина висит постоянно. Собственно наличие выбросов в момент ауторефреша и говорит, что, в принципе, микросхема умеет работать с шиной.

Edited by kostya-m

Share this post


Link to post
Share on other sites

kostya-m

Нашел, явно не указано, но косвенно стало понятно, что этот чип SDRAM умеет читать только пакетами (burst). Включил в настройке регистров чипа чтение всей страницы. Теперь он действительно читает много. Но вот незадача. В момент, когда происходит autorefresh, чип прекращает читать, а STMка и далее дергает CASом и думать, что ей будут давать данные, страница то не менялась.

Share this post


Link to post
Share on other sites

kostya-m

Нашел опечатку. Все заработало. Появился код с работой этой SDRAM на 125 МГц. Если кому потребуется.

Кварц 24 МГц

static void HAL_FMC_MspInit(void){
  /* USER CODE BEGIN FMC_MspInit 0 */

  /* USER CODE END FMC_MspInit 0 */
  GPIO_InitTypeDef GPIO_InitStruct ={0};
  if (FMC_Initialized) {
    return;
  }
  FMC_Initialized = 1;
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

  /** Initializes the peripherals clock
  */
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC;
    PeriphClkInitStruct.PLL2.PLL2M = 6;
    PeriphClkInitStruct.PLL2.PLL2N = 125;
    PeriphClkInitStruct.PLL2.PLL2P = 2;
    PeriphClkInitStruct.PLL2.PLL2Q = 2;
    PeriphClkInitStruct.PLL2.PLL2R = 2;
    PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_2;
    PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
    PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_PLL2;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
      Error_Handler();
    }

  /* Peripheral clock enable */
  __HAL_RCC_FMC_CLK_ENABLE();

  /** FMC GPIO Configuration
  PF0   ------> FMC_A0
  PF1   ------> FMC_A1
  PF2   ------> FMC_A2
  PF3   ------> FMC_A3
  PF4   ------> FMC_A4
  PF5   ------> FMC_A5
  PC2_C   ------> FMC_SDNE0
  PC3_C   ------> FMC_SDCKE0
  PH5   ------> FMC_SDNWE
  PF11   ------> FMC_SDNRAS
  PF12   ------> FMC_A6
  PF13   ------> FMC_A7
  PF14   ------> FMC_A8
  PF15   ------> FMC_A9
  PG0   ------> FMC_A10
  PG1   ------> FMC_A11
  PE7   ------> FMC_D4
  PE8   ------> FMC_D5
  PE9   ------> FMC_D6
  PE10   ------> FMC_D7
  PD14   ------> FMC_D0
  PD15   ------> FMC_D1
  PG4   ------> FMC_BA0
  PG5   ------> FMC_BA1
  PG8   ------> FMC_SDCLK
  PD0   ------> FMC_D2
  PD1   ------> FMC_D3
  PG15   ------> FMC_SDNCAS
  */
  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);

  GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
  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);

  GPIO_InitStruct.Pin = 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);

  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_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_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_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);

  GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
  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);

  /* USER CODE BEGIN FMC_MspInit 1 */

  /* USER CODE END FMC_MspInit 1 */
}

void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef* hsdram){
  /* USER CODE BEGIN SDRAM_MspInit 0 */

  /* USER CODE END SDRAM_MspInit 0 */
  HAL_FMC_MspInit();
  /* USER CODE BEGIN SDRAM_MspInit 1 */

  /* USER CODE END SDRAM_MspInit 1 */
}
static void MX_FMC_Init(void)
{

  /* USER CODE BEGIN FMC_Init 0 */
#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)0x0003)
#define SDRAM_MODEREG_BURST_LENGTH_FULL          ((uint16_t)0x0007)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_1              ((uint16_t)0x0010)
#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)
  FMC_SDRAM_CommandTypeDef SdramCommand;
  /* 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_BANK1;
  hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
  hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
  hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_8;
  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 = 4;
  SdramTiming.ExitSelfRefreshDelay = 1;
  SdramTiming.SelfRefreshTime = 6;
  SdramTiming.RowCycleDelay = 9;
  SdramTiming.WriteRecoveryTime = 3;
  SdramTiming.RPDelay = 3;
  SdramTiming.RCDDelay = 3;

  if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
  {
    Error_Handler( );
  }

  /* USER CODE BEGIN FMC_Init 2 */
  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);
  HAL_Delay( 1 );

  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);
  HAL_Delay( 1 );

  SdramCommand.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
  SdramCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  SdramCommand.AutoRefreshNumber = 1;
  SdramCommand.ModeRegisterDefinition = 
     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;
  HAL_SDRAM_SendCommand(&hsdram1, &SdramCommand,1000);
  
  hsdram1.Instance->SDRTR |= (1933<<1);

//  unsigned int i=0, j;
//  static unsigned long t[256];
//  unsigned long c = 0, q = 777; 
//  //p = (void *)0xC0000000;
//  while( 1 ) {
//    for( i=0; i < 256; i++ ) {p[i*q] = c++; t[i] = p[i*q];}
//    for( i=0; i < 256; i++ ) {p[i] = c++;} //t[i & 0xff] = p[i];}
//    for( i=0; i < 256; i++ ) t[i] = p[i];
//    for( i=0; i < 2*1024*1024; i++ ) {p[i] = c++;} //t[i & 0xff] = p[i];}
//    //c=(c==0xaaaaaaaa)?0x55555555:0xaaaaaaaa;
//   for( i=0; i < 2*1024*1024; i++ ) t[i & 0xff] = p[i];
//  }
  /* USER CODE END FMC_Init 2 */
}

В конце закомментированные тесты для проверки работы.

Теперь взялся запускать эзернет с LAN8720A. В примерах идет LAN8742 , но я посмотрел что код не использует то, чем они отличаются программно.

Использую FreeRTOS 10, тот что куб вложил. MPU не активирую, нужды вроде нет. Но вопрос в том, что писали про то, как правильно настроить MPU, а если я его не активирую вообще?

Проблема в том, что пакеты приходят, что видно по ножкам RXD0/1 RS_DV. Но вот прерывание если и случается, то только один раз после инициализации. DMA буфера смотрят на 0x3000, как завещают на ST. Результаты инициализации проверил по регистрам, вроде все в порядке. Все остальные переменные и буфера живут в области 0х2400. Пните меня, чего проверить, что упустил. Схема соответствует NUCLEO-734VI REF_CLK идет из физики.

Share this post


Link to post
Share on other sites

ksv198
On 4/5/2022 at 7:28 PM, kostya-m said:

MPU не активирую, нужды вроде нет. Но вопрос в том, что писали про то, как правильно настроить MPU, а если я его не активирую вообще?

Привет! Без MPU не сделаете. Читайте примеры в CubeMX пакете для STM32H7xxx.

Share this post


Link to post
Share on other sites

Arlleex
28 минут назад, ksv198 сказал:

Привет! Без MPU не сделаете. Читайте примеры в CubeMX пакете для STM32H7xxx.

Без MPU "не сделаете" что? И как быть с тем фактом, что ТС, судя по всему, уже сделал?:prankster2:

Share this post


Link to post
Share on other sites

ksv198
27 minutes ago, Arlleex said:

Без MPU "не сделаете" что? И как быть с тем фактом, что ТС, судя по всему, уже сделал?:prankster2:

Речь шла про Ethernet в цитируемой фразе.

Share this post


Link to post
Share on other sites

kostya-m
On 4/8/2022 at 5:04 PM, ksv198 said:

Привет! Без MPU не сделаете. Читайте примеры в CubeMX пакете для STM32H7xxx.

Спасибо, попробую.

Да, в примерах MPU включен и делаются соответствующие настройки. Я как бы понимал, что если нужно с MPU, то надо делать так. Указали бы сразу, что Ethernet требует обязательно MPU и вопросов бы не было.

А второе, это то, что проблема не в перекачке данных, а в отсутствии прерывания по приходу пакета.

Share this post


Link to post
Share on other sites

kostya-m

Попробовал. Да, действительно теперь не только первое прерывание проходит на прием. Но пакет обрабатывается и отправляется ответ, что регистрируется в статистике роутера. После чего от роутера посылаются очередные пакеты, а прерывание на прием больше не происходит. Хотя прерывание на отправку прошло нормально и отработалось корректно. Но дальнейшего приема нет и флаг RI в DMACSR не поднимается, хотя пакеты приходят, что видно по ногам RMII.

Share this post


Link to post
Share on other sites

backa

не могли бы Вы приложить кусочек схемы: как именно подключена память к ножкам ( я видел распиновку в коде  ) - я про всякие там терминальные резисторы и питание : только связку STM32 & SDRAM

Давно хочу сделать типпа демоборда под себя - и чипы все имеются ... Хотелось бы как рефернс дизайн на реально рабочем коде и схеме использовать!

Заранее спасибо

Share this post


Link to post
Share on other sites

kostya-m
On 4/29/2022 at 11:25 PM, backa said:

не могли бы Вы приложить кусочек схемы: как именно подключена память к ножкам ( я видел распиновку в коде  ) - я про всякие там терминальные резисторы и питание : только связку STM32 & SDRAM

Давно хочу сделать типпа демоборда под себя - и чипы все имеются ... Хотелось бы как рефернс дизайн на реально рабочем коде и схеме использовать!

Заранее спасибо

Извините, был очень занят и не увидел просьбы. Никаких терминальных или согласующих резисторов. Но стоит минимизировать расстояние от процессора до памяти

image.thumb.png.a043afb4f0625eea64be0942f70d8448.png

Edited by kostya-m

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.