This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TM4C123GH6PM: QVGA LCD DISPLAY INTERFACE with tiva

Part Number: TM4C123GH6PM

Tool/software: Code Composer Studio

Hello, I hope you all are doing great. I am trying to interface a QVGA TFT display with my board. I am using DRM along with some APIs. I have configured SSI0 module through the same steps mentioned in the datasheet,  with ports A2, A3, A4, A5. 

The connections are as below.

A2 (SCLK) going in the clock pin of LCD

A3 (FSS) going in CS (chip select or slave) of the LCD

A4(RX) going in MISO of LCD

A5(TX) going in the MOSI of LCD

(on the LCD board)DC pin data or command selection I don't know what this does, I am confused about this pin. I remember in the class I was told data is sent by the master to slave on a MOSI line then why this data pin? however, I have included it in the code as an output pin.

(on the LCD board) Reset active low

I also referred to an old post on the same topic tried to implement it but so far I am unsuccessful.   

There is nothing on display, however, I am trying to display a  text. Your help will be greatly appreciated. Thanks 

#include <stdint.h>
#include <stdbool.h>
#include "driverlib/sysctl.h"
#include "tm4c123gh6pm.h"
#include "driverlib/gpio.h"
#include "inc/hw_memmap.h"




// PA 2,3,4,5
void spi_ini(void){

    SYSCTL_RCGCSSI_R = 0x01; //selecting SSI0 module
SYSCTL_RCGC2_R = 0x01; // activating clock for port A
GPIO_PORTA_AFSEL_R = 0x3C; //selecting PA 2,3,4,5 for alternate functionality
GPIO_PORTA_PCTL_R = 0x00222200; // configuring the SSI with relative ports
GPIO_PORTA_DEN_R = 0x3C; //enabling digital mode
GPIO_PORTA_PUR_R= 0x3C; //pullups
SSI0_CR1_R= 0x00; // disabling ssi
SSI0_CC_R=0x00; // using main clock
SSI0_CPSR_R=64; // selecting divisor for clock
SSI0_CR0_R=0x07; // 8 bit data transfer
SSI0_CR1_R=0x02; // enabling SSI SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // PE4 = D/C' , PE5 = RESET
GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_4|GPIO_PIN_5);
GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5,0x20);
SysCtlDelay(SysCtlClockGet()/2);// delay
GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5,0);
SysCtlDelay(SysCtlClockGet()/2); } void send_byte(char data){ SSI0_DR_R=data; while(SSI0_SR_R&0x01==0){}; } void send_str(char*buffer){ while(*buffer!=0){ send_byte(*buffer); buffer++; } } int main(void) { SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); spi_ini(); send_str("hello SPI"); }

  • Hi Raza,
    I am not sure why you are using direct register mode. The use of proven library routines not only reduces your work effort, it reduces the chance for error and increases the likelihood of assistance. First, can you look at the SSI signals with an oscilloscope? If the SSITX, SSIFSS and SSICLK are correct, then your software is doing what you requested.

    You probably need to look deeper into the documentation of your QVGA display. I suspect that it may require more than just an ASCII string sent via SPI, but answering questions about the display is beyond my scope.
  • Part Number: TM4C123GH6PM

    Tool/software: Code Composer Studio

    Hello all, I am trying to interface an LCD with my board. I have adapted an example from the spi folder and used it making little changes. However, I am not able to see any text on the LCD. 

    I have made connections as follows,

    PA2 sclk going in clock pin of LCD

    PA3 going in the chip-select of LCD

    PA4 Rx pin going in MISO of LCD

    PA5 Tx pin going in MOSI of LCD 

    Reset active low

    DC data or command selection, I don't know what this pin does, data being transmitted by master travels on the MOSI pin then why this pin. my code is as follows.

    Your help will be greatly appreciated, I don't have an oscilloscope through which I can see if the data is being transmitted or not, therefore, I cannot figure out if the problem is hardware or software.  

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/ssi.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    //*****************************************************************************
    //
    //! \addtogroup ssi_examples_list
    //! <h1>SPI Master (spi_master)</h1>
    //!
    //! This example shows how to configure the SSI0 as SPI Master.  The code will
    //! send three characters on the master Tx then polls the receive FIFO until
    //! 3 characters are received on the master Rx.
    //!
    //! This example uses the following peripherals and I/O signals.  You must
    //! review these and change as needed for your own board:
    //! - SSI0 peripheral
    //! - GPIO Port A peripheral (for SSI0 pins)
    //! - SSI0Clk - PA2
    //! - SSI0Fss - PA3
    //! - SSI0Rx  - PA4
    //! - SSI0Tx  - PA5
    //!
    //! The following UART signals are configured only for displaying console
    //! messages for this example.  These are not required for operation of SSI0.
    //! - UART0 peripheral
    //! - GPIO Port A peripheral (for UART0 pins)
    //! - UART0RX - PA0
    //! - UART0TX - PA1
    //!
    //! This example uses the following interrupt handlers.  To use this example
    //! in your own application you must add these interrupt handlers to your
    //! vector table.
    //! - None.
    //
    //*****************************************************************************
    
    //*****************************************************************************
    //
    // Number of bytes to send and receive.
    //
    //*****************************************************************************
    #define NUM_SSI_DATA            3
    
    //*****************************************************************************
    //
    // Configure SSI0 in master Freescale (SPI) mode.  This example will send out
    // 3 bytes of data, then wait for 3 bytes of data to come in.  This will all be
    // done using the polling method.
    //
    //*****************************************************************************
    int
    main(void)
    {
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        uint32_t ui32SysClock;
    #endif
    
        uint32_t pui32DataTx[NUM_SSI_DATA];
        uint32_t pui32DataRx[NUM_SSI_DATA];
        uint32_t ui32Index;
    
        //
        // Set the clocking to run directly from the external crystal/oscillator.
        // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
        // crystal on your board.
        //
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_OSC), 25000000);
    #else
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);
    #endif
    
    
        //
        // The SSI0 peripheral must be enabled for use.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
    
        //
        // For this example SSI0 is used with PortA[5:2].  The actual port and pins
        // used may be different on your part, consult the data sheet for more
        // information.  GPIO port A needs to be enabled so these pins can be used.
        // TODO: change this to whichever GPIO port you are using.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // PE4 = D/C' , PE5 = RESET
        GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_4|GPIO_PIN_5);
        GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5,0x20);
        SysCtlDelay(SysCtlClockGet()/2);// delay
        GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5,0);
        SysCtlDelay(SysCtlClockGet()/2);
        GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5,0x20);
    
    
        //
        // Configure the pin muxing for SSI0 functions on port A2, A3, A4, and A5.
        // This step is not necessary if your part does not support pin muxing.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinConfigure(GPIO_PA2_SSI0CLK);
        GPIOPinConfigure(GPIO_PA3_SSI0FSS);
        GPIOPinConfigure(GPIO_PA4_SSI0RX);
        GPIOPinConfigure(GPIO_PA5_SSI0TX);
    
        //
        // Configure the GPIO settings for the SSI pins.  This function also gives
        // control of these pins to the SSI hardware.  Consult the data sheet to
        // see which functions are allocated per pin.
        // The pins are assigned as follows:
        //      PA5 - SSI0Tx
        //      PA4 - SSI0Rx
        //      PA3 - SSI0Fss
        //      PA2 - SSI0CLK
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |
                       GPIO_PIN_2);
    
        //
        // Configure and enable the SSI port for SPI master mode.  Use SSI0,
        // system clock supply, idle clock level low and active low clock in
        // freescale SPI mode, master mode, 1MHz SSI frequency, and 8-bit data.
        // For SPI mode, you can set the polarity of the SSI clock when the SSI
        // unit is idle.  You can also configure what clock edge you want to
        // capture data on.  Please reference the datasheet for more information on
        // the different SPI modes.
        //
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        SSIConfigSetExpClk(SSI0_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_0,
                           SSI_MODE_MASTER, 1000000, 8);
    #else
        SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
                           SSI_MODE_MASTER, 1000000, 8);
    #endif
    
        //
        // Enable the SSI0 module.
        //
        SSIEnable(SSI0_BASE);
    
        //
        // Read any residual data from the SSI port.  This makes sure the receive
        // FIFOs are empty, so we don't read any unwanted junk.  This is done here
        // because the SPI SSI mode is full-duplex, which allows you to send and
        // receive at the same time.  The SSIDataGetNonBlocking function returns
        // "true" when data was returned, and "false" when no data was returned.
        // The "non-blocking" function checks if there is any data in the receive
        // FIFO and does not "hang" if there isn't.
        //
        while(SSIDataGetNonBlocking(SSI0_BASE, &pui32DataRx[0]))
        {
        }
    
        //
        // Initialize the data to send.
        //
        pui32DataTx[0] = 's';
        pui32DataTx[1] = 'p';
        pui32DataTx[2] = 'i';
    
        //
        // Send 3 bytes of data.
        //
        for(ui32Index = 0; ui32Index < NUM_SSI_DATA; ui32Index++)
        {
            // Send the data using the "blocking" put function.  This function
            // will wait until there is room in the send FIFO before returning.
            // This allows you to assure that all the data you send makes it into
            // the send FIFO.
            //
            SSIDataPut(SSI0_BASE, pui32DataTx[ui32Index]);
        }
    
        //
        // Wait until SSI0 is done transferring all the data in the transmit FIFO.
        //
        while(SSIBusy(SSI0_BASE))
        {
        }
        //
        // Receive 3 bytes of data.
        //
        for(ui32Index = 0; ui32Index < NUM_SSI_DATA; ui32Index++)
        {
            //
            // Receive the data using the "blocking" Get function. This function
            // will wait until there is data in the receive FIFO before returning.
            //
            SSIDataGet(SSI0_BASE, &pui32DataRx[ui32Index]);
    
            //
            // Since we are using 8-bit data, mask off the MSB.
            //
            pui32DataRx[ui32Index] &= 0x00FF;
    
        }
    
        //
        // Return no errors
        //
        return(0);
    }
    

      

  • I have started another thread and doing the same thing through API, and encountering the same issue. Your expertise is direly needed there thanks again. 
    e2e.ti.com/.../2470386

  • Hello Raza,

    I have merged your thread with the equivalent post on the same topic you made this morning. Please avoid making duplicate threads when the topic is identical, thank you.

    Bob has offered advice on how to troubleshoot your issue. If you do not have access to an oscilloscope currently, you will need to get access to one somehow, that is a fundamental debugging tool for such an application and we aren't going to be able to offer much advice if we can't even verify your signals are being output correctly.
  • Raza Haider said:
    DC data or command selection, I don't know what this pin does, data being transmitted by master travels on the MOSI pin then why this pin? 

    The "D/C" pin delineates between,  "Writing (or reading) DATA "D" to the Display"  versus "Writing a COMMAND Byte(s) "C" to the Display.    The demand for such "D/C pin" is a "carry-over" from Displays from the 1980's - which (usually) employed,  "8 bit Data AND additional Control Bits."   (Control via your "D/C" (explained above) R/W, Data Strobe etc.)

    Examples of Display Commands include:

    • Setting a display address  (a direct setting of the address - rather than sequential)
    • Clearing the display  (the analog of the far older, CRT "CLS"
    • Certain (sometimes ALL) aspects of  VITAL Display Initialization
    • And surely (many) more ...   It may help by thinking of, "Any Display Interaction - NOT INTENDED to ADD FRESH PIXELS to the Display - as (likely) to fall under, "COMMAND."

    Now it proves unlikely that you've developed this Display Sub-System - by yourself.      Such  "commercial product"  -  surely has a data manual - and spec -  the,  "withhold of the spec/manual - or its link" - deprives your helper crüe (here) of key information - required to (better) assist you.     (See the "TAG" below for dates/times of Forum Psychic...)

    Minus a scope - you may at least verify your connections - and MCU's general output capability - by (temporarily) converting that SPI Port to SIMPLER GPIO Output!     Clearly the display will NOT Work - but you can then employ a DMM - or even current-limited LED(s) - to  "Verify that MCU Data INDEED - reaches to the input pins of your LCD.    

    By "toggling" the key MCU pins (after switching each SPI Pin to GPIO) at slow rates (say 1 Hz) - even a "slow meter" or "not so bright" Led (note "double entendre") can serve as a "General Diagnostic Aid."

    The Quick/Complete arrival - or clear link - to your Display's Manual/Spec - "Speeds, Eases, Enhances" the (further) effectiveness of your (unseen, little loved) support crüe.    Allez!