CFAF2403200x020T initialization issue with MSP432 microcontroller

sanath rai

New member
Hello,

I Interfaced CFAF128128B10145T with my MSP432p401R microcntroller to display characters and images with SPI interface between display and controller.
Now for our application we had to change the display to bit bigger size so we chose CFAF2403200x020T dsiplay which has SPI interface as earlier one.

We have initialized the LCD with required commands but still the LCD is not responding.
Below is the commands and data sent to LCD for initialization

Code:
         HAL_LCD_writeCommand(0x11); // Sleep Out
         // delay 120ms

         HAL_LCD_writeCommand(0x38); // AICI E ADAUGAT DE MINE // IDLE MODE OFF

         HAL_LCD_writeCommand(0x36); // Memory Data Access Controls
         HAL_LCD_writeData(0x00);

         HAL_LCD_writeCommand(0x3A); // Interface Pixel Format
         HAL_LCD_writeData(0x06); //setare noua

         HAL_LCD_writeCommand(0xB2); //: Porch Setting
         HAL_LCD_writeData(0x0C);
         HAL_LCD_writeData(0x0C);
         HAL_LCD_writeData(0x00);
         HAL_LCD_writeData(0x33);
         HAL_LCD_writeData(0x33);

         HAL_LCD_writeCommand(0xB7); //Gate Control
         HAL_LCD_writeData(0x35);

         HAL_LCD_writeCommand(0xBB); //VCOM Setting
         HAL_LCD_writeData(0x1A);

         HAL_LCD_writeCommand(0xC0); // LCM Control
         HAL_LCD_writeData(0x2C);

         HAL_LCD_writeCommand(0xC2); // VDV and VRH Command Enable
         HAL_LCD_writeData(0x01);

         HAL_LCD_writeCommand(0xC3); // VRH Set
         HAL_LCD_writeData(0x0B);

         HAL_LCD_writeCommand(0xC4); // VDV Set
         HAL_LCD_writeData(0x20);

         HAL_LCD_writeCommand(0xC6); //Frame Rate Control in Normal Mode
         HAL_LCD_writeData(0x0F);

         HAL_LCD_writeCommand(0xD0); // Power Control 1
         HAL_LCD_writeData(0xA4);
         HAL_LCD_writeData(0xA1);

         HAL_LCD_writeCommand(0x21); //Display Inversion On

         HAL_LCD_writeCommand(0xE0); //Positive Voltage Gamma Control
         HAL_LCD_writeData(0x00);
         HAL_LCD_writeData(0x19);
         HAL_LCD_writeData(0x1E);
         HAL_LCD_writeData(0x0A);
         HAL_LCD_writeData(0x09);
         HAL_LCD_writeData(0x15);
         HAL_LCD_writeData(0x3D);
         HAL_LCD_writeData(0x44);
         HAL_LCD_writeData(0x51);
         HAL_LCD_writeData(0x12);
         HAL_LCD_writeData(0x03);
         HAL_LCD_writeData(0x00);
         HAL_LCD_writeData(0x3F);
          HAL_LCD_writeData(0x3F);

         HAL_LCD_writeCommand(0x29);
What might be the issue?


Regards,
Sanath Rai
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 
Last edited by a moderator:
I put your code into a "CODE" box and removed the many lines that were commented out, to make it easier to read. Hopefully I didn't mess up the actual code.

It looks like you have taken the Arduino demo code from the product page of the site, but I didn't compare it completely.

The first thing I wonder about is the hardware reset is missing. Are you actually doing that as part of the init, but is just not shown?
Code:
  //Reset the LCD controller
  CLR_RESET;
  delay(1);//10µS min
  SET_RESET;
  // delay 150ms
To really see what you are doing, it might be helpful if you actually attached your source file(s), instead of embedding just a portion of code.
 

sanath rai

New member
Initialization driver

Hello ,

Thank you for the reply.
Below is my initialization code

Code:
[CODE]void CrystalfontzInit(void)
{


    HAL_LCD_PortInit();
    HAL_LCD_SpiInit();

    GPIO_setOutputLowOnPin(LCD_RST_PORT, LCD_RST_PIN);
    HAL_LCD_delay(50);
    GPIO_setOutputHighOnPin(LCD_RST_PORT, LCD_RST_PIN);
    HAL_LCD_delay(150);

    HAL_LCD_writeCommand(CM_SLPOUT);
       HAL_LCD_delay(200);

       // MADCTL (36h): Memory Data Access Control
        // Set the RGB vs BGR order to match a windows 24-bit BMP
       HAL_LCD_writeCommand(0x36);
       HAL_LCD_writeData(0x08);// YXVL RH--

        // COLMOD (3Ah): Interface Pixel Format
        // * This command is used to define the format of RGB picture
        //   data, which is to be transferred via the MCU interface.
        HAL_LCD_writeCommand(0x3A);
        HAL_LCD_writeData(0x06);// Default: 0x06 => 18-bit/pixel

        // PORCTRL (B2h): Porch Setting
        HAL_LCD_writeCommand(0xB2);
        HAL_LCD_writeData(0x0C);   //BPA[6:0]: Back porch setting in normal mode. The minimum setting is 0x01.
        HAL_LCD_writeData(0x0C);   //FPA[6:0]: Front porch setting in normal mode. The minimum setting is 0x01.
        HAL_LCD_writeData(0x00);   //Disable(0) / Enable (1) separate porch control
        HAL_LCD_writeData(0x33);   //(high nibble) BPB[3:0]: Back porch setting in idle mode. The minimum setting is 0x01.
                              //(low nibble)  FPB[3:0]: Front porch setting in idle mode. The minimum setting is 0x01.
        HAL_LCD_writeData(0x33);   //(high nibble) BPB[3:0]: Back porch setting in partial mode. The minimum setting is 0x01.
                              //(low nibble)  FPC[3:0]: Front porch setting in partial mode. The minimum setting is 0x01.

        // GCTRL (B7h): Gate Control
        HAL_LCD_writeCommand(0xB7);
        //O-Film TFT
        HAL_LCD_writeData(0x35);


        // VCOMS (BBh): VCOM Setting
        HAL_LCD_writeCommand(0xBB);

        //O-Film TFT
        HAL_LCD_writeData(0x35);

        // LCMCTRL (C0h): LCM Control
        HAL_LCD_writeCommand(0xC0);
        HAL_LCD_writeData(0x2C);

        // VDVVRHEN (C2h): VDV and VRH Command Enable
        HAL_LCD_writeCommand(0xC2);
        HAL_LCD_writeData(0x01); // CMDEN=”0”: VDV and VRH register value comes from NVM.
                            // CMDEN=”1”, VDV and VRH register value comes from command write.
        HAL_LCD_writeData(0xFF);

        // VRHS (C3h): VRH Set
        HAL_LCD_writeCommand(0xC3);

        //O-Film TFT
        HAL_LCD_writeData(0x11);

        //VDVS (C4h): VDV Set
        HAL_LCD_writeCommand(0xC4);
        HAL_LCD_writeData(0x20);

        //FRCTRL2 (C6h): Frame Rate Control in Normal Mode
        HAL_LCD_writeCommand(0xC6);
        HAL_LCD_writeData(0x0F);
        // PWCTRL1 (D0h): Power Control 1
        HAL_LCD_writeCommand(0xD0);
        HAL_LCD_writeData(0xA4);   //Fixed vector
        HAL_LCD_writeData(0xA1);   //AVDD=6.8V, AVCL=-4.8V, VDS=2.3V

        // PVGAMCTRL (E0h): Positive Voltage Gamma Control
        HAL_LCD_writeCommand(0xE0);
        // Pile of magic numbers :-(
        //O-Film TFT
        HAL_LCD_writeData(0xd0);
        HAL_LCD_writeData(0x00);
        HAL_LCD_writeData(0x06);
        HAL_LCD_writeData(0x09);
        HAL_LCD_writeData(0x0b);
        HAL_LCD_writeData(0x2a);
        HAL_LCD_writeData(0x3c);
        HAL_LCD_writeData(0x55);
        HAL_LCD_writeData(0x4b);
        HAL_LCD_writeData(0x08);
        HAL_LCD_writeData(0x16);
        HAL_LCD_writeData(0x14);
        HAL_LCD_writeData(0x19);
        HAL_LCD_writeData(0x20);

        // NVGAMCTRL (E1h): Negative Voltage Gamma Control
        HAL_LCD_writeCommand(0xE1);
        // Pile of magic numbers :-(
        //O-Film TFT
        HAL_LCD_writeData(0xd0);
        HAL_LCD_writeData(0x00);
        HAL_LCD_writeData(0x06);
        HAL_LCD_writeData(0x09);
        HAL_LCD_writeData(0x0b);
        HAL_LCD_writeData(0x29);
        HAL_LCD_writeData(0x36);
        HAL_LCD_writeData(0x54);
        HAL_LCD_writeData(0x4b);
        HAL_LCD_writeData(0x0d);
        HAL_LCD_writeData(0x16);
        HAL_LCD_writeData(0x14);
        HAL_LCD_writeData(0x21);
        HAL_LCD_writeData(0x20);


        //O-Film TFT
        // INVOFF (20h): Display Inversion Off (correct for X)
        HAL_LCD_writeData(0x20);


        // CASET (2Ah): Column Address Set
        HAL_LCD_writeCommand(0x2A);
        HAL_LCD_writeData(0x00); //Start MSB Start = 0
        HAL_LCD_writeData(0x00); //Start LSB
        HAL_LCD_writeData(0x00); //End MSB End = 249
        HAL_LCD_writeData(0xEF); //End LSB

        // RASET (2Bh): Row Address Set
        HAL_LCD_writeCommand(0x2B);
        HAL_LCD_writeData(0x00); //Start MSB Start = 0
        HAL_LCD_writeData(0x00); //Start LSB
        HAL_LCD_writeData(0x01); //End MSB End = 319
        HAL_LCD_writeData(0x3F); //End LSB

         HAL_LCD_delay(10);
         HAL_LCD_writeCommand(0x29);

}

void Fill_LCD(uint8_t R, uint8_t G, uint8_t B)
  {
  uint32_t
    i;
  Set_LCD_for_write_at_X_Y(240, 320);

  //Fill display with a given RGB value
  for (i = 0; i < (76800); i++)
    {

	  HAL_LCD_writeData(0x00);
	  //HAL_LCD_writeData(B); //Blue
	  //HAL_LCD_writeData(G); //Green
	  //HAL_LCD_writeData(R); //Red
    }
  }
void Set_LCD_for_write_at_X_Y(uint16_t x, uint16_t y)
  {
  //CASET (2Ah): Column Address Set
  // * The value of XS [15:0] and XE [15:0] are referred when RAMWR
  //   command comes.
  // * Each value represents one column line in the Frame Memory.
  // * XS [15:0] always must be equal to or less than XE [15:0]
	HAL_LCD_writeCommand(0x2A); //Column address set
  //Write the parameters for the "column address set" command
	HAL_LCD_writeData(x>>8);     //Start MSB = XS[15:8]
	HAL_LCD_writeData(x&0x00FF); //Start LSB = XS[ 7:0]
	HAL_LCD_writeData(0);        //End MSB   = XE[15:8] 240-1
	HAL_LCD_writeData(240);      //End LSB   = XE[ 7:0]
  //Write the "row address set" command to the LCD
  //RASET (2Bh): Row Address Set
  // * The value of YS [15:0] and YE [15:0] are referred when RAMWR
  //   command comes.
  // * Each value represents one row line in the Frame Memory.
  // * YS [15:0] always must be equal to or less than YE [15:0]
  HAL_LCD_writeCommand(0x2B); //Row address set
  //Write the parameters for the "row address set" command
  //Use 1st quadrant coordinates: 0,0 is lower left, 239,319 is upper right.
  y=319-y;
  HAL_LCD_writeData(y>>8);     //Start MSB = YS[15:8]
  HAL_LCD_writeData(y&0x00FF); //Start LSB = YS[ 7:0]
  HAL_LCD_writeData(0x01);     //End MSB   = YE[15:8] 320-1
  HAL_LCD_writeData(0x3F);     //End LSB   = YE[ 7:0]
  //Write the "write data" command to the LCD
  //RAMWR (2Ch): Memory Write
  HAL_LCD_writeCommand(0x2C); //write data
  }


Above is the audrino code for fill lcd which i am using just to initialize and fill colour
but niether is happening.
Our hardware connections are fine we have cross checked which is 4 line serial ineterface same as for earlier LCD.
Why LCD is not initializing?







I put your code into a "CODE" box and removed the many lines that were commented out, to make it easier to read. Hopefully I didn't mess up the actual code.

It looks like you have taken the Arduino demo code from the product page of the site, but I didn't compare it completely.

The first thing I wonder about is the hardware reset is missing. Are you actually doing that as part of the init, but is just not shown?
Code:
  //Reset the LCD controller
  CLR_RESET;
  delay(1);//10µS min
  SET_RESET;
  // delay 150ms
To really see what you are doing, it might be helpful if you actually attached your source file(s), instead of embedding just a portion of code.
 
Hmm, your code looks just like the demo code, as far as I can see. The next question: is the backlight powered on?

I do not have this display, so I can't try to run your code on any of my dev boards.

Can you check, via oscilloscope, that your signal timing is greater than the minimum speeds in the data sheet?

Did your previous (128x128) display function correctly?

At this point, there is nothing else I can suggest to try because I don't have enough information, sorry. Maybe you can send an email to CFA tech support with a link to this thread.
 

CF Tech

Administrator
Thanks for looking the code, @cosmicvoid.

@sanath rai:

The posted demo code is intended to run on the CFA-10080 0v2 hardware. I have attached the schematic (downloaded from here: https://www.crystalfontz.com/product/cfaf240320x0020te11-2inch-color-tft-carrier-board ).

Can you verify that all your connections are identical?

Please make sure that the M0, M1 and M2 interface mode lines are set correctly.

And the backlight as cosmicvoid suggested.

The ST7789V LCD controller does specify that unused lines should be tied to ground. The demo board uses some 100K resistor arrays for that.
 

Attachments

sanath rai

New member
Hello Sir,

The back light is powered on.
We have look into speeds as in datasheet.
Our old LCD 128x128 worked perfectly.
the timings of spi lines are identical so that should not be any problem.
Only initialization is the problem i guess

Regards,
Sanath Rai
 
Sanath Rai,

CFA tech support has notified me that they are sending me some display hardware so that I can try to duplicate your problem. This will probably arrive beginning of next week, so I can continue troubleshooting then.
 

sanath rai

New member
Hello Sir,


Thank you .
In the mean time i will try to resolve the problem .


Sanath Rai,

CFA tech support has notified me that they are sending me some display hardware so that I can try to duplicate your problem. This will probably arrive beginning of next week, so I can continue troubleshooting then.
 
Thank you .
In the mean time i will try to resolve the problem .
I have working hardware now... a CFAF240320X0020 and an arduino clone board, connected using 4-wire SPI. The CFA demo code runs fine.

I could try running your init code, but you have to supply the source for the "HAL_LCD_xxx()" functions.
 

sanath rai

New member
Code:
//
//*****************************************************************************


#include "grlib.h"
#include "driverlib.h"
#include <stdint.h>

void HAL_LCD_PortInit(void)
{
    // LCD_SCK
    GPIO_setAsPeripheralModuleFunctionOutputPin(LCD_SCK_PORT, LCD_SCK_PIN, GPIO_PRIMARY_MODULE_FUNCTION);
    // LCD_MOSI
    GPIO_setAsPeripheralModuleFunctionOutputPin(LCD_MOSI_PORT, LCD_MOSI_PIN, GPIO_PRIMARY_MODULE_FUNCTION);
    // LCD_RST
    GPIO_setAsOutputPin(LCD_RST_PORT, LCD_RST_PIN);
    // LCD_RS
    GPIO_setAsOutputPin(LCD_DC_PORT, LCD_DC_PIN);
    // LCD_CS
    GPIO_setAsOutputPin(LCD_CS_PORT, LCD_CS_PIN);
}

void HAL_LCD_SpiInit(void)
{
    eUSCI_SPI_MasterConfig config =
        {
            EUSCI_B_SPI_CLOCKSOURCE_SMCLK,
            LCD_SYSTEM_CLOCK_SPEED,
            LCD_SPI_CLOCK_SPEED,
            EUSCI_B_SPI_MSB_FIRST,
            EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT,
            EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW,
            EUSCI_B_SPI_3PIN
        };
    SPI_initMaster(LCD_EUSCI_BASE, &config);
    SPI_enableModule(LCD_EUSCI_BASE);

    GPIO_setOutputLowOnPin(LCD_CS_PORT, LCD_CS_PIN);

    GPIO_setOutputHighOnPin(LCD_DC_PORT, LCD_DC_PIN);
}


//*****************************************************************************
//
// Writes a command to the CFAF128128B-0145T.  This function implements the basic SPI
// interface to the LCD display.
//
//*****************************************************************************
void HAL_LCD_writeCommand(uint8_t command)
{
    // Set to command mode
    GPIO_setOutputLowOnPin(LCD_DC_PORT, LCD_DC_PIN);

    // USCI_B0 Busy? //
    while (UCB0STATW & UCBUSY);

    // Transmit data
    UCB0TXBUF = command;

    // Set back to data mode
    GPIO_setOutputHighOnPin(LCD_DC_PORT, LCD_DC_PIN);
}


//*****************************************************************************
//
// Writes a data to the CFAF128128B-0145T.  This function implements the basic SPI
// interface to the LCD display.
//
//*****************************************************************************
void HAL_LCD_writeData(uint8_t data)
{
    // USCI_B0 Busy? //
    while (UCB0STATW & UCBUSY);

    // Transmit data
    UCB0TXBUF = data;
}

//*****************************************************************************
//
//! Provides a small delay.
//!
//! \param ui32Count is the number of delay loop iterations to perform.
//!
//! This function provides a means of generating a delay by executing a simple
//! 3 instruction cycle loop a given number of times.  It is written in
//! assembly to keep the loop instruction count consistent across tool chains.
//!
//! It is important to note that this function does NOT provide an accurate
//! timing mechanism.  Although the delay loop is 3 instruction cycles long,
//! the execution time of the loop will vary dramatically depending upon the
//! application's interrupt environment (the loop will be interrupted unless
//! run with interrupts disabled and this is generally an unwise thing to do)
//! and also the current system clock rate and flash timings (wait states and
//! the operation of the prefetch buffer affect the timing).
//!
//! For best accuracy, a system timer should be used with code either polling
//! for a particular timer value being exceeded or processing the timer
//! interrupt to determine when a particular time period has elapsed.
//!
//! \return None.
//
//*****************************************************************************
#if defined(ewarm) || defined(DOXYGEN)
void
SysCtlDelay(uint32_t ui32Count)
{
    __asm("    subs    r0, #1\n"
          "    bne.n   SysCtlDelay\n"
          "    bx      lr");
}
#endif
#if defined(codered) || defined(gcc) || defined(sourcerygxx)
void __attribute__((naked))
SysCtlDelay(uint32_t ui32Count)
{
    __asm("    subs    r0, #1\n"
          "    bne     SysCtlDelay\n"
          "    bx      lr");
}
#endif
#if defined(rvmdk) || defined(__ARMCC_VERSION)
__asm void
SysCtlDelay(uint32_t ui32Count)
{
    subs    r0, #1;
    bne     SysCtlDelay;
    bx      lr;
}
#endif



I have working hardware now... a CFAF240320X0020 and an arduino clone board, connected using 4-wire SPI. The CFA demo code runs fine.

I could try running your init code, but you have to supply the source for the "HAL_LCD_xxx()" functions.
 
I have reformatted your code into a CODE box again. It looks like you inserted a CODE wrapper without highlighting the code text.

Since I don't have access to a MSP432 cpu, I cannot run your code directly, especially without the #include files and library code. But, I took your display init routine and substituted it into the CFA demo code, and it works OK.
I used the AVR SPI calls by using macros.
Code:
#define HAL_LCD_writeCommand	SPI_sendCommand
#define HAL_LCD_writeData	SPI_sendData
Looking at your SPI Command write function makes me wonder if there is a timing issue with the Command/Data port pin vs the SPI bit-stream output. I see that you set Command mode, wait for the SPI status to go 'ready', then you load the buffer with data, then change the D/C pin without waiting for the byte to be shifted out. Try adding another busy check before switching the D/C pin back to data mode.
Code:
void HAL_LCD_writeCommand(uint8_t command)
{
    // check USCI_B0 Busy before changing D/C  //
    while (UCB0STATW & UCBUSY);

    // Set to command mode only when not busy
    GPIO_setOutputLowOnPin(LCD_DC_PORT, LCD_DC_PIN);

    // Transmit data
    UCB0TXBUF = command;

    // USCI_B0 still Busy shifting? //
    while (UCB0STATW & UCBUSY);

    // Set back to data mode after byte is sent
    GPIO_setOutputHighOnPin(LCD_DC_PORT, LCD_DC_PIN);
}
I don't see any code to control the ChipSelect pin on the display. Are you taking the CS pin high between each SPI byte?
That's all I can think of for now. What things have you tried?
 

sanath rai

New member
Hello Sir,

The SPI source code is the working driver of CFAF128128B1-0145T LCD which i was using earlier which worked fine for that display.
The chip select pin is made low initially at the beginning will be always low.

I have tried changing the init commands still no outcome.


I have reformatted your code into a CODE box again. It looks like you inserted a CODE wrapper without highlighting the code text.

Since I don't have access to a MSP432 cpu, I cannot run your code directly, especially without the #include files and library code. But, I took your display init routine and substituted it into the CFA demo code, and it works OK.
I used the AVR SPI calls by using macros.
Code:
#define HAL_LCD_writeCommand	SPI_sendCommand
#define HAL_LCD_writeData	SPI_sendData
Looking at your SPI Command write function makes me wonder if there is a timing issue with the Command/Data port pin vs the SPI bit-stream output. I see that you set Command mode, wait for the SPI status to go 'ready', then you load the buffer with data, then change the D/C pin without waiting for the byte to be shifted out. Try adding another busy check before switching the D/C pin back to data mode.
Code:
void HAL_LCD_writeCommand(uint8_t command)
{
    // check USCI_B0 Busy before changing D/C  //
    while (UCB0STATW & UCBUSY);

    // Set to command mode only when not busy
    GPIO_setOutputLowOnPin(LCD_DC_PORT, LCD_DC_PIN);

    // Transmit data
    UCB0TXBUF = command;

    // USCI_B0 still Busy shifting? //
    while (UCB0STATW & UCBUSY);

    // Set back to data mode after byte is sent
    GPIO_setOutputHighOnPin(LCD_DC_PORT, LCD_DC_PIN);
}
I don't see any code to control the ChipSelect pin on the display. Are you taking the CS pin high between each SPI byte?
That's all I can think of for now. What things have you tried?
 
The SPI source code is the working driver of CFAF128128B1-0145T LCD which i was using earlier which worked fine for that display.
The chip select pin is made low initially at the beginning will be always low.
You may notice that both the CFAF128128 and CFAF240320 datasheets show the CS signal being switched for each byte in SPI mode, as also do both demo code SPI_send..() functions. Please try adding the code to dynamically switch the LCD_CS_PIN in both write functions to see if it changes the result.
Code:
void HAL_LCD_writeCommand(uint8_t command)
{
    // check USCI_B0 Busy before changing D/C  //
    while (UCB0STATW & UCBUSY);

    // Set to command mode only when not busy
    GPIO_setOutputLowOnPin(LCD_DC_PORT, LCD_DC_PIN);
[COLOR="#0000FF"]    [B]GPIO_setOutputLowOnPin(LCD_CS_PORT, LCD_CS_PIN);[/B][/COLOR]

    // Transmit data
    UCB0TXBUF = command;

    // USCI_B0 still Busy shifting? //
    while (UCB0STATW & UCBUSY);

    // Set back to data mode after byte is sent
[COLOR="#0000FF"]    [B]GPIO_setOutputHighOnPin(LCD_CS_PORT, LCD_CS_PIN);[/B][/COLOR]
    GPIO_setOutputHighOnPin(LCD_DC_PORT, LCD_DC_PIN);
}
I have tried changing the init commands still no outcome.
I am not sure what you mean. The commands in the init function, or the code in both HAL_LCD_write..() functions?
The idea here is to copy what is in the demo code as closely as you can.

Also, the pin connections in the CFAF240320 are greatly different than CFAF128128. On the CFAF240320:
pin 8, labelled "CS" is the chip select
pin 9, labelled "DC" is the SPI clock input
pin 10, labelled "WR" is the 4-wire SPI data/command input
pin 16, labelled "SDA" is the serial I/O
so please check to be sure your display is connected correctly.

Are you using the 45-pin flex tail directly, or is your display mounted to a breakout board?
 
I did some experimentation this weekend with the CFA demo code regarding whether to use CS dynamically or to leave CS set low always.

I found that if the CFAF240320 is reset with CS low, the display becomes completely unresponsive to SPI commands/data. The CS must be set high before you reset the display. After the reset is done, the CS can be set low and remain low.

I notice in your HAL_LCD_PortInit() function that you set the pins as output, but you do not set the pins to a specific starting state. Then in the SPIInit() you set CS low before the LCD init.

Your port init:
Code:
void HAL_LCD_PortInit(void)
{
    // LCD_SCK
    GPIO_setAsPeripheralModuleFunctionOutputPin(LCD_SCK_PORT, LCD_SCK_PIN, GPIO_PRIMARY_MODULE_FUNCTION);
    // LCD_MOSI
    GPIO_setAsPeripheralModuleFunctionOutputPin(LCD_MOSI_PORT, LCD_MOSI_PIN, GPIO_PRIMARY_MODULE_FUNCTION);
    // LCD_RST
    GPIO_setAsOutputPin(LCD_RST_PORT, LCD_RST_PIN);
    // LCD_RS
    GPIO_setAsOutputPin(LCD_DC_PORT, LCD_DC_PIN);
    // LCD_CS
    GPIO_setAsOutputPin(LCD_CS_PORT, LCD_CS_PIN);
}

void HAL_LCD_SpiInit(void)
{
    // code snipped here

[B][COLOR="#0000FF"]    GPIO_setOutputLowOnPin(LCD_CS_PORT, LCD_CS_PIN);[/COLOR][/B]
    GPIO_setOutputHighOnPin(LCD_DC_PORT, LCD_DC_PIN);
}
The demo code does this:
Code:
  //Set up port B
  DDRB |= 0x2F;

  //Drive the ports to a reasonable starting state.
  CLR_RESET;
  CLR_RS;
[COLOR="#0000FF"]  [B]SET_CS;[/B][/COLOR]
  CLR_MOSI;
  CLR_SCK;
So this may be a reason that the display is not responding.

Afterthought: when the CS input is HIGH. it re-initializes the SPI state. When CS goes low, then the SCK starts to sample the SDA pin. If you are only sending, theoretically everything can remain synchronized; but, if you are sending long packets of command/data, it would be wise to put CS high between packets to guarantee SCK and SDA sync. If you are performing a read command, then it is mandatory to put CS high after the data is read, before putting CS low for the following command.
 
Top