Skip to main content
MGuth.1
Associate III
May 27, 2022
Solved

Sending Data to TFT/LCD via FMC fails

  • May 27, 2022
  • 6 replies
  • 7895 views

Hi

I'm struggling with a TFT Display and a Nucleo U575 board. The Display is a 320x240px Display that I want to control with a 16 bit FMC interface.

As the Display doesn't show anything, I connected my Logic analyzer to the Nucleo's FMC Pins.

Result: It seems, that the commands (8-bit) are sent correctly to the TFTs D0:D7 pins. However when I try to send data (e.g. a 16 bit color) to the display it's also just D0:D7 that turn high/low. D8:D15 are always low when data is sent and are always high wen nothing is sent.

I followed this guide by NickNagy on github. He's using a 8-bit interface. However I changed to the 16-bit command for sending data and I can't find the mistake I obviously made.

Can someone help me please? :sleepy_face:

I uploaded the code to my github

Thanks a lot in advance!

Best answer by MGuth.1

Gooood news!

The screen is running now! It shows different colors and I'm even able to display a jpg image that I converted to a hex-array :smiling_face_with_heart_eyes:

As I said above, I can't really tell what made the FMC work.It just worked from one second to the other.

After adjusting the timing settings, everything is displayed correctly on the LCD.

Things to do:

  • optimize the functions to manipulate the screen. e.g. drawing squares, circles, lines, ... in different colors
  • adjust gama settings and so on as the colors shown right now are not really what they should look like
  • add DMA support to decrease processor load

For everyone who's in trouble like I was: feel free to check out the Github repo. I'll continue to work on it until it works properly :)

Thanks again @Mecanix​ and @Community member​ for your help!

6 replies

Mecanix
Associate III
May 27, 2022

Any reason why you need to use the FMC for that TFT/ST7789? Versus 16-bits gpio bus...

Mecanix
Associate III
May 27, 2022

Here's a 16b FMC for the same screen which I've once used to test performance. Works great however the gpio bus wins hands down (my 2c). See if you can find clues in there...

MGuth.1
MGuth.1Author
Associate III
May 28, 2022

Hi Mecanix

Thanks for sharing your code! I checked it and the only difference in the code that I can see is that you're handling the writedata() and writecommand() functions slightly different to my approach.

I just ported your project to my Nucleo board and I can see a very clean output on my logic analyzer on all 16 data lines. However when wiring up my display I don't get to see anything...

I also used your way of handling the writedata() and writecommand() in my original project but I still get the same output. commands are sent on lines D0:D7 but not with the correct values. Also when sending data with 16 bit length only lines D0:D7 are oscilating high/low. Lines D8:D15 are always low when sending data.

Is the address I used wrong? I'm using 0x6000 0000 for commands - using Bank1 (0x60) NOR/PSRAM 1 (00) with A18 and 16 bits (0000?!)

Mecanix
Associate III
May 28, 2022
//FMC Write addresses (16bits)
//A18
#define ST7789_REG *(__IO uint16_t *)(((uint32_t)0x60000000))
#define ST7789_RAM *(__IO uint16_t *)(((uint32_t)0x60000000) + (1 << (18+1))) 

waclawek.jan
Super User
May 28, 2022

Have you set FMC to non-multiplexed 16-bit mode? Have you set properly GPIO for D9-D15? Read out and check/post content of FMC and GPIO registers.

JW

MGuth.1
MGuth.1Author
Associate III
May 28, 2022

Thanks for your input!

I can't decide between multiplexed or non-multiplexed mode. I just chose LCD interface, CS = NE1, LCD Register Select = A18 and 16 bits Data width.

All FMC pins (D0-D15 as well as NOE, NE1, NWE,...) are set with:

  • GPIO mode: Alternate Function Push Pull
  • GPIO Pull-up/Pull-down: No pull-up and no pull-down
  • Maximum output speed: Very High

FMC Settings:

  • Memory type: LCD interface
  • Bank: Bank 1 NOR/PSRAM 1
  • Write operation: Enabled
  • Write FIFO: Disabled
  • Extended mode: Disabled
  • Address setup time: 15 HCLK clock cycles
  • Data setup time : 255 HCLK clock cycles
  • Data hold time: 2 HCLK clock cycles
  • Bus turn around: 15 HCLK clock cycles

For the FMC_Reset Pin I chose PE2 with

  • GPIO output level: low
  • GPIO mode: Output Push Pull
  • GPIO Pull-up/Pull-down: No pull-up and no pull-down
  • Maximum output speed: low
waclawek.jan
Super User
May 28, 2022

> I can't decide between multiplexed or non-multiplexed mode.

It depends on the actual hardware. Unless you have an address latch (which you probably don't have, otherwise you would have known), you use non-multiplexed mode.

Read out and check/post content of FMC and GPIO registers.

JW

MGuth.1
MGuth.1Author
Associate III
May 28, 2022

I'm not quite sure if I got the things you mean as I'm quite new to the Cube environment, but I hope I found the correct data :) If not, please let me know...

0693W00000Nqo0MQAR.jpg0693W00000Nqo0CQAR.jpg

MGuth.1
MGuth.1AuthorBest answer
Associate III
May 28, 2022

Gooood news!

The screen is running now! It shows different colors and I'm even able to display a jpg image that I converted to a hex-array :smiling_face_with_heart_eyes:

As I said above, I can't really tell what made the FMC work.It just worked from one second to the other.

After adjusting the timing settings, everything is displayed correctly on the LCD.

Things to do:

  • optimize the functions to manipulate the screen. e.g. drawing squares, circles, lines, ... in different colors
  • adjust gama settings and so on as the colors shown right now are not really what they should look like
  • add DMA support to decrease processor load

For everyone who's in trouble like I was: feel free to check out the Github repo. I'll continue to work on it until it works properly :)

Thanks again @Mecanix​ and @Community member​ for your help!

Visitor II
September 10, 2024

Hello all,

I am struggling with a similar issue.  I have a STM32F407 trying to use a ST7789V TFT display in 16 bit parallel mode.  I have had no success in using FSMC with any drivers I've found online, even MXCube generated drivers.  So far, I haven't had any success communicating with the device, even simply trying to read the device ID.  I verified all 16 data lines are sending data but still get no response from the ST7789V.

 

I am transitioning a project from a Himax HX8347-D controller display TFT to a ST7789V controller display, so I know the FSMC works at least with the Himax.

I am trying the GPIO bus solution posted by @Mecanix and am having trouble with the DATAOUT function.  Could you post your GPIO configuration?  In the end, my project needs to use FSMC so timing help and tips are very appreciated, but for now any working solution will do.

 

FSMC Init Code:

 FSMC_NORSRAM_TimingTypeDef Timing = {0};

 /* USER CODE BEGIN FSMC_Init 1 */

 /* USER CODE END FSMC_Init 1 */

 /** Perform the SRAM1 memory initialization sequence
 */
 hsram1.Instance = FSMC_NORSRAM_DEVICE;
 hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
 /* hsram1.Init */
 hsram1.Init.NSBank = FSMC_NORSRAM_BANK4;
 hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
 hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
 hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
 hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
 hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
 hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
 hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
 hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
 hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
 hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
 hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
 hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
 hsram1.Init.PageSize = FSMC_PAGE_SIZE_NONE;
 /* Timing */
 Timing.AddressSetupTime = 15;
 Timing.AddressHoldTime = 15;
 Timing.DataSetupTime = 255;
 Timing.BusTurnAroundDuration = 15;
 Timing.CLKDivision = 16;
 Timing.DataLatency = 17;
 Timing.AccessMode = FSMC_ACCESS_MODE_A;
 /* ExtTiming */

 if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
 {
 Error_Handler( );
 } }

 GPIO Bus File:

#ifndef INC_ST7789V_16BITS_H_
#define INC_ST7789V_16BITS_H_

#include "main.h"


#define	USE_HORIZONTAL 2 // Change Orientation Modes (0,1,2,3)

#if USE_HORIZONTAL == 0 || USE_HORIZONTAL == 1
	#define LCD_W 240
	#define LCD_H 320
#else
	#define LCD_W 320
	#define LCD_H 240
#endif

/*
 * 16bITS BUS
 * ********************************************************************************************************************************
 * D0		D1		D2		D3		D4		D5		D6		D7		D8		D9		D10		D11		D12		D13		D14		D15
 * PA0		PA1		PA2		PA3		PA4		PA5		PA6		PA7		PB8		PB9		PB10	PB11	PA12*	PB13	PB14	PB15
 * ********************************************************************************************************************************
 */
static void DATAOUT(uint32_t i) {
GPIOE->BSRR = 0b1111111110000000 + 0xff; //setting reset mask for E7-E15
GPIOE->BSRR = ((((i) & (1<<7)) << 0)
			 | (((i) & (1<<8)) << 0)
			 | (((i) & (1<<9)) << 0)
			 | (((i) & (1<<10)) << 0)
			 | (((i) & (1<<11)) << 0)
			 | (((i) & (1<<12) << 0)
			 | (((i) & (1<<13)) << 0)
			 | (((i) & (1<<14)) << 0)
			 | (((i) & (1<<15)) << 0)));
GPIOD->BSRR = 0b1100011100110011<<16; //setting reset bits for D0-D1, D4-D5, D8-D10, D14-D15
GPIOD->BSRR = (((i) & (1<<0)) << 0)
			 | (((i) & (1<<1)) << 0)
			 | (((i) & (1<<4)) << 0)
			 | (((i) & (1<<5)) << 0)
			 | (((i) & (1<<8)) << 0)
			 | (((i) & (1<<9)) << 0)
			 | (((i) & (1<<10)) << 0)
			 | (((i) & (1<<14)) << 0)
			 | (((i) & (1<<15)) << 0);
}

// Set pins
#define LCD_RST_SET		//GPIOB->ODR |= ( 1<<1 );//NRST
#define LCD_CS_SET		HAL_GPIO_WritePin(GPIOG, GPIO_PIN_12, GPIO_PIN_SET);
#define LCD_DC_SET		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_SET);//
#define LCD_WR_SET		HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_SET);//PD5
#define LCD_RD_SET		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_SET);//PD4

// Reset pins
#define LCD_RST_CLR		//GPIOB->ODR &= ~( 1<<1 );//NRST
#define LCD_CS_CLR		HAL_GPIO_WritePin(GPIOG, GPIO_PIN_12, GPIO_PIN_RESET);
#define LCD_DC_CLR		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_RESET);
#define LCD_WR_CLR		HAL_GPIO_WritePin(GPIOF, GPIO_PIN_0, GPIO_PIN_RESET);
#define LCD_RD_CLR		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET);//PD4


void LCD_Init			(void);
void LCD_Address_Set	(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void LCD_Clear			(uint16_t Color);

#endif
Visitor II
September 10, 2024

Edit:

I am using GPIO Bus right now without FSMC, but I could still use help with FSMC which is why I included them both.

16 Bit Bus config:

/*
 * 16bITS BUS
 * ********************************************************************************************************************************
 * D0		D1		D2		D3		D4		D5		D6		D7		D8		D9		D10		D11		D12		D13		D14		D15
 * PD14		PD15	PD0		PD1		PE7		PE8		PE9		PE10	PE11	PE12	PE13	PE14	PE15	PD8		PD9		PD10
 * ********************************************************************************************************************************
 */