cancel
Showing results for 
Search instead for 
Did you mean: 

Sending Data to TFT/LCD via FMC fails

MGuth.1
Associate III

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? ��

I uploaded the code to my github

Thanks a lot in advance!

18 REPLIES 18

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

Dbl-checked your gpio for control and you have them correct. At least they're same as the FMC example I've passed earlier, of which I know works flawlessly.

 PD4  ------> FMC_NOE/RD

 PD5  ------> FMC_NWE/WR

 PD13 ------> FMC_A18/RS

 PD7  ------> FMC_NE1/CS

 PE2  ------> FMC_RESET

//Confirmed correct.

Really running out of ideas here. Other than perhaps the hardware side of things; those display can be naughty and requires trial & error if not documented, particularly on the pullups/pulldown of pins, some requires to be floating.

Try leaving the SDO pin floating (required on mine here). It bugs me to know that Nucleo/Code side works when scoping the lines, but not when the display is hardwired.

thanks for your time and effort you're putting into this! I highly appreciate it!

Sorry, I missed that. I kept SDO floating as I was instructed to by the manual. But for every other pin that I'm not using I put them to GND (in the manual it says GND or IOVCC).

I think you got me wrong here: When scoping the lines, I don't get valid data:

  • lines 0-7 are oscillating in a way. However I can't find the correct bit sequence (e.g. 00010001 for the command sleepout) but different "random" values.
  • lines 8-15 are always low. When sending a command this might be right as it's an 8-bit command, but they are also low when sending (16-bit) data. Doesn't matter if I send 0xFFFF or 0x00 the output for lines 8-15 are always scoped low.

That's why I was wondering about the address...

When HAL starts misbehaving (rare mind you) I turn to registers and painfully hardcode the thing from scratch. Never done it for the FMC interface though.

I still swear by the GPIO bus sent earlier, over FMC anyway ��

Keep us updated about what it was. gl man

Oh and that 16bits gpio really starts to be half-fun on that ST7789 when this:

0693W00000Nqo2SQAR.jpg

I was told that FMC is much more efficient compared to GPIO Bus. Also I plan to use FMC along with DMA to reduce ​the processor load even more and hence improve battery life for the final product ;)

Back to topic: I don't know what I changed - I didn't change anything at all �� but: I connected the logic analyzer once again to get any hint for the problem. And somehow all 16 lines work perfectly now! ��

I then wired up the LCD again and it at least shows some weird grey pixels. ​0693W00000Nqo6KQAR.jpg

I think the missing link is the timing settings for now. I'll try and hope it won't get worse again ;)

Thanks to both of you for your help today!! I'll update the post as soon as there are news to share :)​

MGuth.1
Associate III

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 ��

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!

camrose00
Associate II

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

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
 * ********************************************************************************************************************************
 */