cancel
Showing results for 
Search instead for 
Did you mean: 

LCD on STMf4xx using FSMC

Shane Gingell
Associate II
Posted on July 09, 2018 at 09:04

I have been teaching myself to user the STM32 MCUs.

I have done the usual blink and LED and create a Delay timer, setup a UART as a serial console for debugging.

I did also write a I2C software slave using and interrupt on the SDA line to detect the master sending a start condition.

I am now tring to use a LCD TFT in parallel using FSMC. I have tried both a ST7781 in 8 bit parallel and now a HX8357 in 16 bit parallel.

The FSCM seems to be working correctly as if I out my scope on any of the pins I see the output that I would expect but nothign shows up on the screen.

here's my code

#include 'stm32f4xx.h'

//used for coutn down in Delay

__IO uint32_t TimmingDelay;

void SysTick_Handler(void)

{

  if(TimmingDelay !=0)

  {

    TimmingDelay --;

  }

}

void Delay(__IO uint32_t time)

{

  TimmingDelay = time;

  while(TimmingDelay !=0);

}

//pointer used to write to start address of FSMC

volatile uint16_t* fsmc = (uint16_t*)0x60000000;

void FSMC_setup(void){

    //enable RCC for FSMC and both GPIO ports

    RCC->AHB3ENR |= RCC_AHB3ENR_FSMCEN;

    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN;

    //setup RS (PD13)  and RST (PD12) pin as output

    GPIOD->MODER |= GPIO_MODER_MODER13_0 | GPIO_MODER_MODER12_0;

    //setup other pins as AF

    GPIOD->MODER |= GPIO_MODER_MODER0_1 | GPIO_MODER_MODER1_1 | GPIO_MODER_MODER4_1 | GPIO_MODER_MODER5_1 | GPIO_MODER_MODER7_1 | GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1 | GPIO_MODER_MODER14_1 | GPIO_MODER_MODER15_1;

    GPIOE->MODER |= GPIO_MODER_MODER7_1 | GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1  | GPIO_MODER_MODER11_1 | GPIO_MODER_MODER12_1 | GPIO_MODER_MODER13_1 | GPIO_MODER_MODER14_1 |  GPIO_MODER_MODER15_1;

    //setup pins as PP

    GPIOD->OTYPER = 0x00000000;

    GPIOE->OTYPER = 0x00000000;

    //set speed to 100MHz

    GPIOD->OSPEEDR = 0xFFFFFFFF;

    GPIOE->OSPEEDR = 0xFFFFFFFF;

    //set NO pull-up or pull-down

    GPIOD->PUPDR = 0x00000000;

    GPIOE->PUPDR = 0x00000000;

    //set other pins to AF12 i.e as FSMC pins

    GPIOD->AFR[0] |= (GPIO_AF12_FSMC << (0 * 4)) | (GPIO_AF12_FSMC << (1 * 4)) | (GPIO_AF12_FSMC << (4 * 4)) | (GPIO_AF12_FSMC << (5 * 4)) | (GPIO_AF12_FSMC << (7 * 4));

    GPIOD->AFR[1] |= (GPIO_AF12_FSMC << ((8 - 8) * 4)) | (GPIO_AF12_FSMC << ((9 - 8) * 4)) | (GPIO_AF12_FSMC << ((10 - 8) * 4)) | (GPIO_AF12_FSMC << ((14 - 8) * 4)) | (GPIO_AF12_FSMC << ((15 - 8) * 4));

    GPIOE->AFR[0] |= (GPIO_AF12_FSMC << (7 * 4));

    GPIOE->AFR[1] |= (GPIO_AF12_FSMC << ((8 - 8) * 4)) | (GPIO_AF12_FSMC << ((9 - 8) * 4)) | (GPIO_AF12_FSMC << ((10 - 8) * 4)) | (GPIO_AF12_FSMC << ((11 - 8) * 4)) | (GPIO_AF12_FSMC << ((12 - 8) * 4)) | (GPIO_AF12_FSMC << ((13 - 8) * 4)) | (GPIO_AF12_FSMC << ((14 - 8) * 4)) | (GPIO_AF12_FSMC << ((15 - 8) * 4));

    //setup FSMC on Bank1 NORSRAM1

    //disable ASYNCWAIT:

    FSMC_Bank1->BTCR[0] &= ~FSMC_BCR1_ASYNCWAIT;

    //disable Extended mode

    FSMC_Bank1->BTCR[0] &= ~FSMC_BCR1_EXTMOD;

    //disable the wait for NWAIT signal

    FSMC_Bank1->BTCR[0] &= ~FSMC_BCR1_WAITEN;

    //write enable

    FSMC_Bank1->BTCR[0] |= FSMC_BCR1_WREN;

    //disable wrap mode

    FSMC_Bank1->BTCR[0] &= ~FSMC_BCR1_WRAPMOD;

    //disable Burst mode

    FSMC_Bank1->BTCR[0] &= ~FSMC_BCR1_BURSTEN;

    //enable Flash access

    FSMC_Bank1->BTCR[0] |= FSMC_BCR1_FACCEN;

    //set data bus width to 16 bit

    FSMC_Bank1->BTCR[0] |= FSMC_BCR1_MWID_0;

    //set to SRAM type

    FSMC_Bank1->BTCR[0] &= ~FSMC_BCR1_MTYP;

    //disable Address/data multiplexing

    FSMC_Bank1->BTCR[0] &= ~FSMC_BCR1_MUXEN;

    //enable Memory bank

    FSMC_Bank1->BTCR[0] |= FSMC_BCR1_MBKEN;

    //setup timings

    //set access mode A

    FSMC_Bank1->BTCR[1] &= ~FSMC_BTR1_ACCMOD;

    //set short bus turn around

    FSMC_Bank1->BTCR[1] &= ~(FSMC_BTR1_BUSTURN_0 | FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_2 |FSMC_BTR1_BUSTURN_3);

}

void TFT_write_cmd(uint16_t command){

    //set RS pin low

    GPIOD->ODR &= ~GPIO_ODR_ODR_13;

    Delay(10);

    *fsmc = command;

    //set RS pin high

    GPIOD->ODR |= GPIO_ODR_ODR_13;

    Delay(10);

}

//sets up a HX8357B TFT

void TFT_setup(void){

    //hardware reset

    GPIOD->ODR &= ~GPIO_ODR_ODR_12;

    Delay(200);

    GPIOD->ODR |= GPIO_ODR_ODR_12;

    Delay(120);

    //software reset

    TFT_write_cmd(0x01);

    Delay(120);

    //sleep out

    TFT_write_cmd(0x11);

    Delay(120);

    //Normal Display Mode On)

    TFT_write_cmd(0x13);

    //Display On

    TFT_write_cmd(0x29);

    //CASET (Column Address Set)

    TFT_write_cmd(0x2A);

    *fsmc = 0000;

    *fsmc = 320;

    //PASET (Page Address Set)

    TFT_write_cmd(0x2B);

    *fsmc = 0000;

    *fsmc = 320;

    //Exit_idle_mode

    TFT_write_cmd(0x38);

    //Set_pixel_format RGR565 16 bit

    TFT_write_cmd(0x3A);

    *fsmc = 0b01010101;

    //RAMWR (Memory Write)

    TFT_write_cmd(0x2C);

}

void main(void){

  // At this stage the system clock should have already been configured

  // at high speed.

    //set systick for 1 MS used in Delay interrupt

    SysTick_Config(SystemCoreClock/1000);

    FSMC_setup();

    TFT_setup();

    for (uint32_t i = 0; i < 102400; ++i ){

        *fsmc = 0xff00;

        fsmc += 2;

    }

  // Infinite loop

  while (1){

       // Add your code here.

    }

}

1 REPLY 1
Shane Gingell
Associate II
Posted on July 12, 2018 at 11:42

I have found solution to my setup FSMC problem.

Here is working setup

    //setup timings of FSCM

    FSMC_Bank1->BTCR[1] = FSMC_BTR1_ADDSET_1 | FSMC_BTR1_DATAST_1;

    // Bank1 NOR/SRAM control register configuration

    FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;