cancel
Showing results for 
Search instead for 
Did you mean: 

How to get a TouchGFX demo working in DSI Video Mode

OLync.1
Associate III

I want to verify that the STM32L4R9 discovery kit can work in DSI video mode so that I can port the application to use a display driver that does not have a graphics buffer. I started with the TouchGFXWatch example and have that working. I then used TouchGFX Generator to change the Display Interface to Parallel RCB (LTDC) (per advice from the forum). This resulted in the initial display but no update. I then changed DSIHost to Video Mode which resulted in stripy noise being displayed. I believe I am using the latest versions of all the tools: TouchGFX 4.19, CubeMX 6.5.0, STM32CubeIDE 1.8.0.

My forum reading suggests that this is hard, but possible. Can anyone enlighten me on what I need to modify under the hood to get this to work?

14 REPLIES 14
OLync.1
Associate III

This is the conflict STM32CubeMX reports when I try to enable FMC (for external ram), with OCTOSPI (for external flash) configured per the example code for this board. It suggests that external ram cannot be used if external flash is in use, but that can't be right.

OLync.1
Associate III

This is the generated code when I enable PSRAM via FMC:

static void MX_FMC_Init(void)
{
 
  /* USER CODE BEGIN FMC_Init 0 */
 
  /* USER CODE END FMC_Init 0 */
 
  FMC_NORSRAM_TimingTypeDef Timing = {0};
 
  /* USER CODE BEGIN FMC_Init 1 */
 
  /* USER CODE END FMC_Init 1 */
 
  /** Perform the SRAM1 memory initialization sequence
  */
  hsram1.Instance = FMC_NORSRAM_DEVICE;
  hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
  /* hsram1.Init */
  hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
  hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  hsram1.Init.MemoryType = FMC_MEMORY_TYPE_PSRAM;
  hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_ENABLE;
  hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
  hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram1.Init.WriteBurst = FMC_WRITE_BURST_ENABLE;
  hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
  hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
  hsram1.Init.NBLSetupTime = 0;
  hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
  /* Timing */
  Timing.AddressSetupTime = 15;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 255;
  Timing.DataHoldTime = 0;
  Timing.BusTurnAroundDuration = 15;
  Timing.CLKDivision = 2;
  Timing.DataLatency = 2;
  Timing.AccessMode = FMC_ACCESS_MODE_A;
  /* ExtTiming */
 
  if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
  {
    Error_Handler( );
  }
 
  /* USER CODE BEGIN FMC_Init 2 */
 
  /* USER CODE END FMC_Init 2 */
}

And this is the display when I set the GFXMMU to point to the external ram - I'm pretty sure that the image is there, buried in the noise

OLync.1
Associate III

Things have substantially improved - I found settings from a HAL file for the board and the display is almost there. FMC settings:

  hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
  hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  hsram1.Init.MemoryType = FMC_MEMORY_TYPE_PSRAM;
  hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
  hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_HIGH;
  hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
  hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
  hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;
  hsram1.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;
  hsram1.Init.NBLSetupTime = 0;
  hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;

Timings:

   Timing.AddressSetupTime   = 1;
   Timing.AddressHoldTime    = 0;
   Timing.DataSetupTime     = 5;
   Timing.BusTurnAroundDuration = 1;
   Timing.CLKDivision      = 2;
   Timing.DataLatency      = 2;
   Timing.AccessMode    = FMC_ACCESS_MODE_A;

But I don't think they match the device timings (attached). I've experimented with many values and what I have is close to working but not quite there. Can anyone with a better understanding of PSRAM timings advise?

RetroInTheShade
Associate III

Hi Olync,

I'm not an expert on PSRAM but digging around, there does look to be an example FMC project for your disco on the ST repository.

The example uses the following timing:

  SRAM_Timing.AddressSetupTime       = 5;
  SRAM_Timing.AddressHoldTime        = 1;      /* Min value, Don't care on SRAM Access mode A */
  SRAM_Timing.DataSetupTime          = 3;
  SRAM_Timing.BusTurnAroundDuration  = 1; 
  SRAM_Timing.CLKDivision            = 2;     /* Min value, Don't care on SRAM Access mode A */
  SRAM_Timing.DataLatency            = 2;     /* Min value, Don't care on SRAM Access mode A */

The clock is the example is configured at 80MHz or (12.5ns period) so these settings seem reasonable compared to datasheet specifications.

Cheers.

OLync.1
Associate III

Thanks all for your help, I finally got it working with double buffering in PSRAM. The last hurdle was annoying full screen glitches periodically. I tracked it down to this framework-generated code:

void TouchGFXHAL::setTFTFrameBuffer(uint16_t* adr)
{
    if (doubleBufferingEnabled)
    {
        HAL_DSI_Stop(&hdsi);
 
        currFbBase = adr;
 
        /* Update LTDC layers base address */
        if (HAL_LTDC_SetAddress(&hltdc, (uint32_t)currFbBase, 0) != HAL_OK)
        {
            while (1);
        }
        __HAL_LTDC_LAYER_ENABLE(&hltdc, 0);
        __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hltdc);
 
        HAL_DSI_Start(&hdsi);
    }
}

I commented out the HAL_DSI_Stop and HAL_DSI_Start - hey presto, no flicker! Not sure how legit it is but it's working!