STM32F429i LTDC + SDRAM Buffer Issue

0

He estado tratando de aprender lo básico del periférico STM32 LTDC para manejar un LCD de 4.3 "480 x 272 usando STM32F429IG mcu. Estoy usando el kit de desarrollo Open429i de Wavehshare ( enlace ) que también tiene una SDRAM de 64 Mbit (IS42S16400J).

Como paso 1, conseguí que la pantalla LCD funcionara con el controlador LTDC y puedo mostrar imágenes con el formato adecuado (RGB565) apuntando el búfer a una matriz de imágenes en mi código, como a continuación

Porlotanto,séquemiLCDesbuenoyqueheconfiguradoLTDCcorrectamentecon1capa

Segundopaso,intentéinteractuarconelSDRAMintegradoutilizandoelbancodeSDRAMperiféricoFMC2yapuntandoelframebufferLTDCaestadirección.

Sinembargo,cuandohagoesto,obtengoestasrayasdecoloresextrañosqueparecendesplazarsehorizontalmente.LoqueesperabaeraquelapantallaestuvieracompletamenteenblancocuandoestoylimpiandoeláreadeSDRAMLTDCatodoslos0xFF.

Unvideoquemuestraloanteriorenacciónes aquí

Siento que es algo que ver con la sincronización de mi SDRAM, pero no estoy seguro de dónde buscar y para qué. Como prueba escribí una matriz en la SDRAM y la leí para verificarla, lo que tuvo éxito.

El código inicial de FMC es

void MX_FMC_Init(void)
{
  FMC_SDRAM_TimingTypeDef SdramTiming;

  /** 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_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_2;
  hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
  hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
  /* SdramTiming */
  SdramTiming.LoadToActiveDelay = 2;
  SdramTiming.ExitSelfRefreshDelay = 7;
  SdramTiming.SelfRefreshTime = 4;
  SdramTiming.RowCycleDelay = 7;
  SdramTiming.WriteRecoveryTime = 2;
  SdramTiming.RPDelay = 2;
  SdramTiming.RCDDelay = 2;

  if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

Inic de SDRAM

#define SDRAM_DEVICE_ADDR  ((uint32_t)0xD0000000)
#define SDRAM_DEVICE_SIZE  ((uint32_t)0x800000)  /* SDRAM device size in MBytes */ 
#define REFRESH_COUNT      ((uint32_t)0x0569)   /* SDRAM refresh counter (90Mhz SD clock) */
#define SDRAM_TIMEOUT     ((uint32_t)680) 

void EXTERAL_SDRAM_Initialization_sequence(uint32_t RefreshCount)
{
    __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(100);

    /* 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;
    //Command.ModeRegisterDefinition = 0x231;

    /* 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, RefreshCount); 

    uint32_t ptr; 
    for(ptr = SDRAM_DEVICE_ADDR; ptr < (SDRAM_DEVICE_ADDR + 65280); ptr += 4)
    *((uint32_t *)ptr) = 0xffffffff;
    return 0;

}
    
pregunta Ankit

0 respuestas

Lea otras preguntas en las etiquetas