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.

128x64 oled interface with the TM4C123gxl using SPI

Other Parts Discussed in Thread: EK-LM3S1968

Hello 

I had a good learning with OLED display using Stellaris lm4f232 with this forum.Thanks for the same

Now trying out with the same oled code with TM4C123GXL , the oled I am using is 128x64.I have changed the code according to the Tiva . It is building the code with zero errors. but I am not able to display the data on OLED. 

Can anyone suggest still what I need to concentrate!!!

I am using the same cfal96x64x16.c code for my new oled.

Thank you in advance 

  • nethra patil said:
    I had a good learning with OLED display using Stellaris lm4f232 with this forum.

    That said - how would you effectively employ that (past) "good learning"- to best meet your objectives now?

    Your issue may be hardware, software or both.  Usually "divide & conquer" works well:

    Hardware:

    a) appears that you're NOT using the exact same OLED (past OLED was 96x64) - now you report 128x64!.  Have you added all necessary support components required by this new OLED?  (charge pump caps - especially)  Is the power scheme - and pinout - the same?

    b) Is the SPI port you've chosen "free" from those burdensome "0-ohm" MCU to MCU resistors - which likely erode signal levels?  

    c) have you "ohm'ed out" all connections between MCU & OLED?  Is the OLED being adequately (and properly) powered?  How & where have you measured?

    d) have you access to a scope?  If so - are your SPI clock, FSS, and SPI data arriving @ the OLED?  You may wish to "start" by switching those "chosen" SPI pins into GPIO output - and then toggling each - to insure that they have full output capability.

    e) do any of the OLED pixels reveal - at all - especially when you initialize the OLED?

    Software:

    e) past Stellaris code is (still) what we use - and we succeed with many different displays.  As you report a changed OLED - have you confirmed that the OLED Controller is the same?  And - if it is - how have you accommodated the 32 added rows of the new OLED?

    f) new OLED initialization is sure to change (due to added pixels - for one).  You "must" get the initialization right - especially the charge pump/voltage step-up circuit instructions - or you may damage the OLED.

    g) we find it best to (always) try to get a single pixel to "come to life."  Trying for strings - or images - early is (most always) doomed - just eats time/effort...

    We're not told if your board is L-Pad.  If not - you've got new board, new OLED, new code - and (likely) NO Chance!  We call such situation, "Maximum Randomness" - flies in the face of KISS.  (which dictates ONE new variable added to the mix at a time!)

    Suggest that you obtain an identical OLED (96x64) to the one on your (past) LX232 board.  Add the support components just as is done on that past board - to your new board.  This eliminates any/all variables introduced by the new OLED.

    Once the new OLED's in place - reload your SW and see if pixels emerge - and in the proper screen locations.  

    As with so many forum posts - yours is mightily short of needed data.  Guides above attempt to provide a logical pathway which best enables your (past) "good learning" to resolve your issue...

  • Hello cb1_mobile
    firstly thanks for the good key points .
    I am looking into your above mentioned situiations.
    I had one more doubt.My Past 96x64 oled uses ssd1332 controller, but my new 128x64 oled uses ssd1306 oled. may i know how this effects for my application ! and how i need to proceed now.!
  • Hi Amit ashara

    Can I get few inputs from you too regarding this issue.
  • >>> had one more doubt.My Past 96x64 oled uses ssd1332 controller, but my new 128x64 oled uses ssd1306 oled. may i >>> know how this effects for my application ! and how i need to proceed now.!

    Hi, I fear you have to write a device driver for that display as I wrote for different chip I used. You can leave all graphics as is and display on new one when chip got correct parameter.
  • Hello Roberto

    can u please make little clear please!!!
  • Right, first give us a link to data sheet and model of your display, you MUST change all parameter relative to your panel, controller need to generate correct timing and send data line by line (row by row) according to both controller and panel.
    No data no way to help.
    First step verify mode is same for original Oled, SPI 3 wire I think, then tell us if OLed get sign of life (I doubt due to different parameter.)
    Rename driver to have a the original untouched, make a copy, at first modify resolution from 96 64 to 128 64,
    Then all parameter and command need to be adapted, !332 has only SPI 3 wire mode, 1306 has many mode, 3 4 wire and also I2C you have to select from interface.
    When interface is ok then you have to change commands and value for timing.
    When you are sure interface is right set and all data about PANEL is available we can try more hint.
  • Hi Roberto

    Here is my oled datasheet link "http://www.sunrom.com/media/files/p/257/1258-datasheet.pdf" .Model is 1258. This Oled controller is SSD 1306.


    int main(void)
    {
    tContext sContext;
    tRectangle sRect;

    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
    SYSCTL_OSC_MAIN);
    CFAL96x64x16Init();
    GrContextInit(&sContext, &g_sCFAL96x64x16);

    GrContextForegroundSet(&sContext, ClrWhite);
    GrRectDraw(&sContext, &sRect);
    GrContextFontSet(&sContext, g_pFontCm12);
    GrStringDraw(&sContext, "Tm4c123gxl"-1,1, 10, 0);
    }

    ///////////////////////////////////////////cfal96x64x16.c/////////////////////////////////////////////////////////////////////

    I Below is the ONLY changes i did for the cfal96x64x16.c code , which I found in path "C:\StellarisWare\boards\ek-lm4f232\drivers".
    In which I am trying to use SSI0,A2,A3,A5 majorly.


    //*****************************************************************************
    //
    // Defines the SSI and GPIO peripherals that are used for this display.
    //
    //*****************************************************************************
    #define DISPLAY_SSI_PERIPH SYSCTL_PERIPH_SSI0
    #define DISPLAY_SSI_GPIO_PERIPH SYSCTL_PERIPH_GPIOA
    #define DISPLAY_RST_GPIO_PERIPH SYSCTL_PERIPH_GPIOG

    //*****************************************************************************
    //
    // Defines the GPIO pin configuration macros for the pins that are used for
    // the SSI function.
    //
    //*****************************************************************************
    #define DISPLAY_PINCFG_SSICLK GPIO_PA2_SSI0CLK
    #define DISPLAY_PINCFG_SSIFSS GPIO_PA3_SSI0FSS
    #define DISPLAY_PINCFG_SSITX GPIO_PA5_SSI0TX

    //*****************************************************************************
    //
    // Defines the port and pins for the SSI peripheral.
    //
    //*****************************************************************************
    #define DISPLAY_SSI_PORT GPIO_PORTA_BASE
    #define DISPLAY_SSI_PINS (GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5)

    //*****************************************************************************
    //
    // Defines the port and pins for the display voltage enable signal.
    //
    //*****************************************************************************
    #define DISPLAY_ENV_PORT GPIO_PORTG_BASE
    #define DISPLAY_ENV_PIN GPIO_PIN_0

    //*****************************************************************************
    //
    // Defines the port and pins for the display reset signal.
    //
    //*****************************************************************************
    #define DISPLAY_RST_PORT GPIO_PORTG_BASE
    #define DISPLAY_RST_PIN GPIO_PIN_1

    //*****************************************************************************
    //
    // Defines the port and pins for the display Data/Command (D/C) signal.
    //
    //*****************************************************************************
    #define DISPLAY_D_C_PORT GPIO_PORTA_BASE
    #define DISPLAY_D_C_PIN GPIO_PIN_7

    //*****************************************************************************
    //
    // Defines the SSI peripheral used and the data speed.
    //
    //*****************************************************************************
    #define DISPLAY_SSI_BASE SSI0_BASE
    #define DISPLAY_SSI_CLOCK 4000000
  • Code seems be ok, Datasheet you pointed me is more than a leaflet than datasheet so from provider page take the code 1258.zip and copy all data is in header file lcd_function.h to corresponding header of cfal file you modified, again point to lcd_function.c and copy void lcd_init_1258()
    from // Init sequence for 128x64 OLED module
    lcd_send_command(SSD1306_DISPLAYOFF); // 0xAE
    lcd_send_command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
    lcd_send_command(0x80); // the suggested ratio 0x80
    lcd_send_command(SSD1306_SETMULTIPLEX); // 0xA8
    to end of file into cfalinit you find in that file you touched.
    then change lcd_send_command( with the one is on driver, I don't remember now but simply send that sequence then you have to customize the new send data and send command...
    Another question, how did you connected pin to this OLED? Why are you using SSIOFSS ?
  • Lost in this sequence - but included in very 1st response - is the necessity to supply the correct components & signal routings so that the OLED's required, "high voltage" is properly generated & routed to the correct OLED pins.  

    Indeed there may be SW changes - as 1st my post (and then others) stated - but perhaps of greater importance (to the health/survival of your OLED) is the proper management of the OLED's (likely) charge pump and it's demand for critically placed - and routed, external components.

    Should you mismanage the OLED's HW - no SW in the world will save you.  (and New Year's Day may be without one (very deceased) OLED - due to inattention to this most critical detail...)

    Surgeon (and forum helpers) "Do no harm!"   Getting the display's power right is the very first display requirement - always.  (few other mistakes are likely to "kill" the display - but power surely has that capability...)

  • Hi CB1, Happy new year at first place then,... from what is using vendor supply, someone built the module and set to 4 wire mode, so this need be checked if connection is ok. Original driver was also able to switch on/off display, if this is preserved new timing has to be respected and no datasheet is available of oled, just end user panel mounted on a pcb.
    Forever many of our poster are hobby user than professional and we lose time to "one time makers" than production where we are incline by profession.
  • Hi Roberto,

    And happy (barely managed, wild west, does not work) forum 2015 dittos to you too.

    Most OLEDs that we encounter are bare display w/flex cable - that's it.  OLEDs (thus far) require both logic supply (3V3-5V, usually) as well as a higher voltage (9-20V, often depending upon module size.)  

    For lowest OLED cost - most makers provide just the display & flex cable - it's up to the user to obtain, read, and comply with OLEDs (especially the OLED Controller's data manual) data.   My point - if poster did not correctly implement the (most always) external capacitors required by OLED's charge pump - no visible pixels will be noted!  Indeed (as you note) there often are OLED pins enabling/blanking the screen - but (again) these will not function if the OLED is inadequately powered!

    Poster provides zero detail - this point - which highlights the futility of you/I/poor Amit diagnosing such (unexplained/poorly detailed) issues.  Instead - we (most always) get famed, "Does not work!"  Really?  Can that be - at all - surprising?

    Migrating from one display to another is not trivial - normal/customary detailed procedures must be followed - you've written (often) about such struggles.

    One thing's sure, minus adequate poster investigation and proper implementation - most projects (surely), "Will not work!"  (have we seen that?  could a more "empty" description be chosen?)

  • Hi Roberto and cb1 mobile

    before starting my discussion again,Wishing you both a very happy new year ahead. :)

    @Roberto
    I have no other info of OLED other than I provided. I tried the with 1258 sample code, but not able achieve the display.But I am still trying out with that.

    The OLED I am not mounted on any PCB. I am trying out using jumpper wires.
    FSS I am using as a slave select. Which I am making low during data transmission for particular slave.

  • Yes cb1_mobile , I am providing correct voltage supply. It should be 3.3V.
  • Please also by wording PLEASE publish how it is connected.
    Precisation: The changes to code I seen are ok, this is far from say all code is ok, part transmitting code an data are not visible and can be ok or cannot, ssd as I wrote are different, both are 4 wire SPI mode but please check all is ok.
    example PA3 ssiclk -> OLed CLK and so on...
    If you decide to publish code, please zip it and insert as file than attaching as text, it leave thread more readable.

    Please provide all detail, and try at almost if it initialize inserting init sequance of 1306 instead of 1339 one.
  • nethra patil said:
    I am providing correct voltage supply. It should be 3.3V.

    Don't know if further "repetition" will be read, understood, investigated - but (again) our (extensive) use of OLEDs reveals (vast majority) to require both a logic voltage (usually 3V3 - 5V0) and a, "Boost Voltage" (usually 9V0 - 20V0)!  That Boost Voltage results from a charge pump internal to the OLED controller - and most always requires the addition of multiple (EXTERNAL) capacitors - to be added by the user!

    Unless the OLED (you're now using) incorporates those extra (boost voltage) components (likely on some auxilliary board) I'd be "amazed" if your pixels "come to life."  And - do note that "if" those extra components are embedded upon some auxilliary pcb - the price for that "assembly" is most always drastically higher than the price for OLED alone - and the few extra components to complete it's use...  

    Recall an old adage, "None are so blind as those who (will not) see!"   (cb1 exits (stage left) as other brick walls await his head...)

  • cb1_mobile said:
    Unless the OLED (you're now using) incorporates those extra (boost voltage) components (likely on some auxilliary board) I'd be "amazed" if your pixels "come to life."  And - do note that "if" those extra components are embedded upon some auxilliary pcb - the price for that "assembly" is most always drastically higher than the price for OLED alone - and the few extra components to complete it's use...  

     Hi CB1, from poor information I found the product page:

    http://www.sunrom.com/p/oled-display-graphics-128x64-3-3v-spi-color-yellow-blue

     I also realized NOW (sic) this is not an RGB oled but dual color and color seems to be confined in two area too, no different color where displayed in different area than two rectangular we see... So it probably can be inited but as BW like and this is not usable on graphics library...

    cb1_mobile said:
    Recall an old adage, "None are so blind as those who (will not) see!"   (cb1 exits (stage left) as other brick walls await his head...)

     You have reason and I still quit, it can be inited, but not used due it don't satisfy minimal GRLIB request.

  • @Roberto,

    Thank you Roberto - w/out your link many here would not learn that this OLED (includes) the "auxilliary pcb" to ease display interconnect AND to provide the boost voltage - always required by this type display.

    Thus - issue reduces to proper interconnect and SPI SW - should be straightforward.

    As stated previously (this reporter) potential users of this display will, "Pay thru the nose" for the ease of connection & boost supply components/connections.   (linked web-site indicates ~9 (USD) @ 100 pcs.   "Usual" OLED (this size/type) would cost ~3 (USD) - minus that auxilliary board!  And - of course - the OLED is unlikely to be available (alone, from this linked vendor) which would allow volume users to build the needed/add on components upon their "normal" pcb.

    Thanks Roberto for doing this "digging."   From experience - these are nice OLEDs - packaged as it is provides a convenience - yet users pay dearly...

    *** Note: the NEW forum SW killed the (approximate) symbol - which I placed in front of "9 USD and 3 USD" - replacing it with (unwanted) minus sign...

  • For those (potentially) interested in this/other OLEDs - here find the normal/customary "added component" requirements to generate the necessary boost voltage.

    (credit Sunrom - this diagram)

    Poster did not detail that his was an OLED module - complete w/added pcb.  Those added boost components and routings are resident upon that "extra" pcb. OLEDs will not operate w/out the proper boost voltage.

  • cb1_mobile said:
    As stated previously (this reporter) potential users of this display will, "Pay thru the nose" for the ease of connection & boost supply components/connections.   (linked web-site indicates ~9 (USD) @ 100 pcs.   "Usual" OLED (this size/type) would cost ~3 (USD) - minus that auxilliary board!  And - of course - the OLED is unlikely to be available (alone, from this linked vendor) which would allow volume users to build the needed/add on components upon their "normal" pcb.

     Oh no just one pieces shipped to you module ready ...

    http://www.ebay.com/itm/0-96-Blue-OLED-Display-Screen-Module-SPI-IIC-I2C-for-Arduino-STM32-AVR-Perfect-/131390001453?pt=LH_DefaultDomain_0&hash=item1e9774512d

     China power of VERY LOW COST.. Shipment too!

    and cheapest I found for RGB too

    http://www.ebay.com/itm/Serial-SPI-1-5-Color-OLED-Display-128x128-Graphic-Module-for-Arduino-PIC-AVR-ARM-/291168137879?pt=LH_DefaultDomain_0&hash=item43caf93297

    Inferring shipping cost from this, module cost can be near 1.8US$ qty 1 module. Thats incredible what can be done by these people, this way we have no chance to competition.

  • Hi 

    OLED_2.rar

    I have attached the project rar file. from this I am able to get a random pixels on the oled screen(with 1306 controller), but not the actual characters what I want to display. 

    Do I need to make changes in the grlib? or tcontext and tdisplay?

     (If the file is not able to access for you, please suggest me the way how can I upload my project or code)

  • /**********************************************Code for cfal128x64 init**************************************************/
    
    //*****************************************************************************
    //
    // cfal96x64x16.c - Display driver for the Crystalfontz CFAL9664-F-B1 OLED
    //                  display with an SSD1332.  This version uses an SSI
    //                  interface to the display controller.
    //
    // Copyright (c) 2011-2012 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    // 
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    // 
    // This is part of revision 9453 of the EK-LM4F232 Firmware Package.
    //
    //*****************************************************************************
    
    //*****************************************************************************
    //
    //! \addtogroup display_api
    //! @{
    //
    //*****************************************************************************
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/tm4c123gh6pm.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/ssi.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/rom.h"
    #include "driverlib/pin_map.h"
    #include "grlib/grlib.h"
    #include "cfal96x64x16.h"
    
    //*****************************************************************************
    //
    // Defines the SSI and GPIO peripherals that are used for this display.
    //
    //*****************************************************************************
    #define DISPLAY_SSI_PERIPH          SYSCTL_PERIPH_SSI0
    #define DISPLAY_SSI_GPIO_PERIPH     SYSCTL_PERIPH_GPIOA //SYSCTL_PERIPH_GPIOH
    #define DISPLAY_RST_GPIO_PERIPH     SYSCTL_PERIPH_GPIOA
    
    //*****************************************************************************
    //
    // Defines the GPIO pin configuration macros for the pins that are used for
    // the SSI function.
    //
    //*****************************************************************************
    #define DISPLAY_PINCFG_SSICLK       GPIO_PA2_SSI0CLK //GPIO_PH4_SSI2CLK
    #define DISPLAY_PINCFG_SSIFSS       GPIO_PA3_SSI0FSS//GPIO_PH5_SSI2FSS
    #define DISPLAY_PINCFG_SSITX        GPIO_PA5_SSI0TX//GPIO_PH7_SSI2TX
    
    
    //*****************************************************************************
    //
    // Defines the port and pins for the SSI peripheral.
    //
    //*****************************************************************************
    #define DISPLAY_SSI_PORT            GPIO_PORTA_BASE
    #define DISPLAY_SSI_PINS            (GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5)
    
    //*****************************************************************************
    //
    // Defines the port and pins for the display voltage enable signal.
    //
    //*****************************************************************************
    #define DISPLAY_ENV_PORT            GPIO_PORTA_BASE
    #define DISPLAY_ENV_PIN             GPIO_PIN_4
    
    //*****************************************************************************
    //
    // Defines the port and pins for the display reset signal.
    //
    //*****************************************************************************
    #define DISPLAY_RST_PORT            GPIO_PORTA_BASE
    #define DISPLAY_RST_PIN             GPIO_PIN_6
    
    //*****************************************************************************
    //
    // Defines the port and pins for the display Data/Command (D/C) signal.
    //
    //*****************************************************************************
    #define DISPLAY_D_C_PORT            GPIO_PORTA_BASE
    #define DISPLAY_D_C_PIN             GPIO_PIN_7
    
    //*****************************************************************************
    //
    // Defines the SSI peripheral used and the data speed.
    //
    //*****************************************************************************
    #define DISPLAY_SSI_BASE            SSI0_BASE // SSI2
    #define DISPLAY_SSI_CLOCK           2000000
    
    //*****************************************************************************
    //
    
    // An array that holds a set of commands that are sent to the display when
    // it is initialized.
    //
    //*****************************************************************************
    /*static
    unsigned char g_ucDisplayInitCommands[] =
    {
        0xAE,         // display off
        0x87, 0x07,     // master control current 7/16
        0x81, 0xA0,     // contrast A control
        0x82, 0x60,     // contrast B control
        0x83, 0xB0,     // contrast C control
        0xA0, 0x20,//00 // remap and data format - use 8-bit color mode
        0xBB, 0x1F,     // Vpa
        0xBC, 0x1F,     // Vpb
        0xBD, 0x1F,     // Vpc
      //  0xAD, 0x8E,   // internal Vp, external supply
        0x26, 0x01,     // rectangle fill enabled
        0xAF,          // display on
    	  0xA6 // normal display
    };*/
    unsigned char g_ucDisplayInitCommands[] =
    {
      //0xAE,
    	0xD5,0x80,0xA8,0x3F,0xD3,0x00,(0x40|0x00),0x8D,
    	0x14,
    	0x20,0x00,(0xA0|0x1),0xC8,0xDA,0x12,0x81,
    	0xCF,
    	0xd9,
    	0xF1,
    	0xDB,0x40,0xA4,0xA6,0xAF,0xA6
    	
    };
    #define NUM_INIT_BYTES sizeof(g_ucDisplayInitCommands)
    
    //*****************************************************************************
    //
    // Translates a 24-bit RGB color to a display driver-specific color.
    //
    // \param c is the 24-bit RGB color.  The least-significant byte is the blue
    // channel, the next byte is the green channel, and the third byte is the red
    // channel.
    //
    // This macro translates a 24-bit RGB color into a value that can be written
    // into the display's frame buffer in order to reproduce that color, or the
    // closest possible approximation of that color.
    //
    // \return Returns the display-driver specific color.
    //
    // 24-bit format: XXXX XXXX RRRR RRRR GGGG GGGG BBBB BBBB
    // 16-bit format: ---- ---- ---- ---- RRRR RGGG GGGB BBBB
    //  8-bit format: ---- ---- ---- ---- ---- ---- RRRG GGBB
    //
    //
    //*****************************************************************************
    #define DPYCOLORTRANSLATE16(c)  ((((c) & 0x00f80000) >> 8) |                  \
                                     (((c) & 0x0000fc00) >> 5) |                  \
                                     (((c) & 0x000000f8) >> 3))
    #define DPYCOLORTRANSLATE8(c)   ((((c) & 0x00e00000) >> 16) |                 \
                                     (((c) & 0x0000e000) >> 11) |                 \
                                     (((c) & 0x000000c0) >> 6))
    #define DPYCOLORTRANSLATE DPYCOLORTRANSLATE8
    
    //*****************************************************************************
    //
    //! Write a set of command bytes to the display controller.
    //
    //! \param pcCmd is a pointer to a set of command bytes.
    //! \param ulCount is the count of command bytes.
    //!
    //! This function provides a way to send multiple command bytes to the display
    //! controller.  It can be used for single commands, or multiple commands
    //! chained together in a buffer.  It will wait for any previous operation to
    //! finish, and then copy all the command bytes to the controller.  It will
    //! not return until the last command byte has been written to the SSI FIFO,
    //! but data could still be shifting out to the display controller when this
    //! function returns.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16WriteCommand(const unsigned char *pcCmd, unsigned long ulCount)
    {
        //
        // Wait for any previous SSI operation to finish.
        //
        while(SSIBusy(DISPLAY_SSI_BASE))
        {
        }
    
        //
        // Set the D/C pin low to indicate command
        //
        GPIOPinWrite(DISPLAY_D_C_PORT, DISPLAY_D_C_PIN, 0);
    
    	//making fss pin low
    		    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7, 0);
    
        //
        // Send all the command bytes to the display
        //
        while(ulCount--)
        {
            SSIDataPut(DISPLAY_SSI_BASE, *pcCmd);
            pcCmd++;
        }
    }
    
    //*****************************************************************************
    //
    //! Write a set of data bytes to the display controller.
    //
    //! \param pcData is a pointer to a set of data bytes, containing pixel data.
    //! \param ulCount is the count of command bytes.
    //!
    //! This function provides a way to send a set of pixel data to the display.
    //! The data will draw pixels according to whatever the most recent col, row
    //! settings are for the display.  It will wait for any previous operation to
    //! finish, and then copy all the data bytes to the controller.  It will
    //! not return until the last data byte has been written to the SSI FIFO,
    //! but data could still be shifting out to the display controller when this
    //! function returns.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16WriteData(const unsigned char *pcData, unsigned long ulCount)
    {
        //
        // Wait for any previous SSI operation to finish.
        //
        while(SSIBusy(DISPLAY_SSI_BASE))
        {
        }
    
        //
        // Set the D/C pin high to indicate data
        //
        GPIOPinWrite(DISPLAY_D_C_PORT, DISPLAY_D_C_PIN, DISPLAY_D_C_PIN);
    
        //
        // Send all the data bytes to the display
        //
        while(ulCount--)
        {
            SSIDataPut(DISPLAY_SSI_BASE, *pcData);
            pcData++;
        }
    }
    
    //*****************************************************************************
    //
    //! Draws a pixel on the screen.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param lX is the X coordinate of the pixel.
    //! \param lY is the Y coordinate of the pixel.
    //! \param ulValue is the color of the pixel.
    //!
    //! This function sets the given pixel to a particular color.  The coordinates
    //! of the pixel are assumed to be within the extents of the display.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16PixelDraw(void *pvDisplayData, long lX, long lY,
                          unsigned long ulValue)
    {
        unsigned char ucCmd[8];
    
        //
        // Load column command, start and end column
        //
        ucCmd[0] = 0x15;
        ucCmd[1] = (unsigned char)lX;
        ucCmd[2] = (unsigned char)lX;
    
        //
        // Load row command, start and end row
        //
        ucCmd[3] = 0x75;
        ucCmd[4] = (unsigned char)lY;
        ucCmd[5] = (unsigned char)lY;
    
        //
        // Send the column, row commands to the display
        //
        CFAL96x64x16WriteCommand(ucCmd, 6);
    
        //
        // Send the data value representing the pixel to the display
        //
        CFAL96x64x16WriteData((unsigned char *)&ulValue, 1);
    }
    
    //*****************************************************************************
    //
    //! Draws a horizontal sequence of pixels on the screen.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param lX is the X coordinate of the first pixel.
    //! \param lY is the Y coordinate of the first pixel.
    //! \param lX0 is sub-pixel offset within the pixel data, which is valid for 1
    //! or 4 bit per pixel formats.
    //! \param lCount is the number of pixels to draw.
    //! \param lBPP is the number of bits per pixel; must be 1, 4, or 8.
    //! \param pucData is a pointer to the pixel data.  For 1 and 4 bit per pixel
    //! formats, the most significant bit(s) represent the left-most pixel.
    //! \param pucPalette is a pointer to the palette used to draw the pixels.
    //!
    //! This function draws a horizontal sequence of pixels on the screen, using
    //! the supplied palette.  For 1 bit per pixel format, the palette contains
    //! pre-translated colors; for 4 and 8 bit per pixel formats, the palette
    //! contains 24-bit RGB values that must be translated before being written to
    //! the display.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16PixelDrawMultiple(void *pvDisplayData, long lX, long lY, long lX0,
                                  long lCount, long lBPP,
                                  const unsigned char *pucData,
                                  const unsigned char *pucPalette)
    {
        unsigned long ulByte;
        unsigned char ucCmd[8];
    
        //
        // Load column command.  Use the specified X for the start and just set
        // the end to the rightmost column since we dont know where the data ends.
        //
        ucCmd[0] = 0x15;
        ucCmd[1] = (unsigned char)lX;
        ucCmd[2] = 95;
    
        //
        // Load row command.  Use the specified Y for the start row and just set
        // the end row to the bottom row since we dont know where the data ends.
        //
        ucCmd[3] = 0x75;
        ucCmd[4] = (unsigned char)lY;
        ucCmd[5] = 63;
    
        //
        // Send the column, row commands to the display
        //
        CFAL96x64x16WriteCommand(ucCmd, 6);
    
        //
        // Determine how to interpret the pixel data based on the number of bits
        // per pixel.
        //
        switch(lBPP)
        {
            //
            // The pixel data is in 1 bit per pixel format.
            //
            case 1:
            {
                //
                // Loop while there are more pixels to draw.
                //
                while(lCount)
                {
                    //
                    // Get the next byte of image data.
                    //
                    ulByte = *pucData++;
    
                    //
                    // Loop through the pixels in this byte of image data.
                    //
                    for(; (lX0 < 8) && lCount; lX0++, lCount--)
                    {
                        //
                        // Draw this pixel in the appropriate color.
                        //
                        unsigned char ucBPP = ((unsigned long *)pucPalette)
                                                [(ulByte >> (7 - lX0)) & 1];
                        CFAL96x64x16WriteData(&ucBPP, 1);
                    }
    
                    //
                    // Start at the beginning of the next byte of image data.
                    //
                    lX0 = 0;
                }
    
                //
                // The image data has been drawn.
                //
                break;
            }
    
            //
            // The pixel data is in 4 bit per pixel format.
            //
            case 4:
            {
                //
                // Loop while there are more pixels to draw.  "Duff's device" is
                // used to jump into the middle of the loop if the first nibble of
                // the pixel data should not be used.  Duff's device makes use of
                // the fact that a case statement is legal anywhere within a
                // sub-block of a switch statement.  See
                // http://en.wikipedia.org/wiki/Duff's_device for detailed
                // information about Duff's device.
                //
                switch(lX0 & 1)
                {
                    case 0:
                        while(lCount)
                        {
                            unsigned char ucColor;
    
                            //
                            // Get the upper nibble of the next byte of pixel data
                            // and extract the corresponding entry from the
                            // palette.
                            //
                            ulByte = (*pucData >> 4) * 3;
                            ulByte = (*(unsigned long *)(pucPalette + ulByte) &
                                      0x00ffffff);
    
                            //
                            // Translate this palette entry and write it to the
                            // screen.
                            //
                            ucColor = DPYCOLORTRANSLATE(ulByte);
                            CFAL96x64x16WriteData(&ucColor, 1);
    
                            //
                            // Decrement the count of pixels to draw.
                            //
                            lCount--;
    
                            //
                            // See if there is another pixel to draw.
                            //
                            if(lCount)
                            {
                    case 1:
                                //
                                // Get the lower nibble of the next byte of pixel
                                // data and extract the corresponding entry from
                                // the palette.
                                //
                                ulByte = (*pucData++ & 15) * 3;
                                ulByte = (*(unsigned long *)(pucPalette + ulByte) &
                                          0x00ffffff);
    
                                //
                                // Translate this palette entry and write it to the
                                // screen.
                                //
                                ucColor = DPYCOLORTRANSLATE(ulByte);
                                CFAL96x64x16WriteData(&ucColor, 1);
    
                                //
                                // Decrement the count of pixels to draw.
                                //
                                lCount--;
                            }
                        }
                }
    
                //
                // The image data has been drawn.
                //
                break;
            }
    
            //
            // The pixel data is in 8 bit per pixel format.
            //
            case 8:
            {
                //
                // Loop while there are more pixels to draw.
                //
                while(lCount--)
                {
                    unsigned char ucColor;
    
                    //
                    // Get the next byte of pixel data and extract the
                    // corresponding entry from the palette.
                    //
                    ulByte = *pucData++ * 3;
                    ulByte = *(unsigned long *)(pucPalette + ulByte) & 0x00ffffff;
    
                    //
                    // Translate this palette entry and write it to the screen.
                    //
                    ucColor = DPYCOLORTRANSLATE(ulByte);
                    CFAL96x64x16WriteData(&ucColor, 1);
                }
    
                //
                // The image data has been drawn.
                //
                break;
            }
        }
    }
    
    //*****************************************************************************
    //
    //! Draws a horizontal line.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param lX1 is the X coordinate of the start of the line.
    //! \param lX2 is the X coordinate of the end of the line.
    //! \param lY is the Y coordinate of the line.
    //! \param ulValue is the color of the line.
    //!
    //! This function draws a horizontal line on the display.  The coordinates of
    //! the line are assumed to be within the extents of the display.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16LineDrawH(void *pvDisplayData, long lX1, long lX2, long lY,
                          unsigned long ulValue)
    {
        unsigned char ucLineBuf[16];
        unsigned int uIdx;
    
        //
        // Send command for starting row and column
        //
        ucLineBuf[0] = 0x15;
        ucLineBuf[1] = lX1 < lX2 ? lX1 : lX2;
        ucLineBuf[2] = 95;
        ucLineBuf[3] = 0x75;
        ucLineBuf[4] = lY;
        ucLineBuf[5] = 63;
        CFAL96x64x16WriteCommand(ucLineBuf, 6);
    
        //
        // Use buffer of pixels to draw line, so multiple bytes can be sent at
        // one time.  Fill the buffer with the line color.
        //
        for(uIdx = 0; uIdx < sizeof(ucLineBuf); uIdx++)
        {
            ucLineBuf[uIdx] = ulValue;
        }
    
        uIdx = (lX1 < lX2) ? (lX2 - lX1) : (lX1 - lX2);
        uIdx += 1;
        while(uIdx)
        {
            CFAL96x64x16WriteData(ucLineBuf, (uIdx < 16) ? uIdx : 16);
            uIdx -= (uIdx < 16) ? uIdx : 16;
        }
    }
    
    //*****************************************************************************
    //
    //! Draws a vertical line.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param lX is the X coordinate of the line.
    //! \param lY1 is the Y coordinate of the start of the line.
    //! \param lY2 is the Y coordinate of the end of the line.
    //! \param ulValue is the color of the line.
    //!
    //! This function draws a vertical line on the display.  The coordinates of the
    //! line are assumed to be within the extents of the display.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16LineDrawV(void *pvDisplayData, long lX, long lY1, long lY2,
                          unsigned long ulValue)
    {
        unsigned char ucLineBuf[16];
        unsigned int uIdx;
    
        //
        // Send command for starting row and column.  Also, set vertical
        // address increment.
        //
        ucLineBuf[0] = 0x15;
        ucLineBuf[1] = lX;
        ucLineBuf[2] = 95;
        ucLineBuf[3] = 0x75;
        ucLineBuf[4] = lY1 < lY2 ? lY1 : lY2;
        ucLineBuf[5] = 63;
        ucLineBuf[6] = 0xA0;
        ucLineBuf[7] = 0x21;
        CFAL96x64x16WriteCommand(ucLineBuf, 8);
    
        //
        // Use buffer of pixels to draw line, so multiple bytes can be sent at
        // one time.  Fill the buffer with the line color.
        //
        for(uIdx = 0; uIdx < sizeof(ucLineBuf); uIdx++)
        {
            ucLineBuf[uIdx] = ulValue;
        }
    
        uIdx = (lY1 < lY2) ? (lY2 - lY1) : (lY1 - lY2);
        uIdx += 1;
        while(uIdx)
        {
            CFAL96x64x16WriteData(ucLineBuf, (uIdx < 16) ? uIdx : 16);
            uIdx -= (uIdx < 16) ? uIdx : 16;
        }
    
        //
        // Restore horizontal address increment
        //
        ucLineBuf[0] = 0xA0;
        ucLineBuf[1] = 0x20;
        CFAL96x64x16WriteCommand(ucLineBuf, 2);
    }
    
    //*****************************************************************************
    //
    //! Fills a rectangle.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param pRect is a pointer to the structure describing the rectangle.
    //! \param ulValue is the color of the rectangle.
    //!
    //! This function fills a rectangle on the display.  The coordinates of the
    //! rectangle are assumed to be within the extents of the display, and the
    //! rectangle specification is fully inclusive (in other words, both sXMin and
    //! sXMax are drawn, along with sYMin and sYMax).
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16RectFill(void *pvDisplayData, const tRectangle *pRect,
                         unsigned long ulValue)
    {
        unsigned int uY;
    
        for(uY = pRect->sYMin; uY <= pRect->sYMax; uY++)
        {
            CFAL96x64x16LineDrawH(0, pRect->sXMin, pRect->sXMax, uY, ulValue);
        }
    }
    
    //*****************************************************************************
    //
    //! Translates a 24-bit RGB color to a display driver-specific color.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param ulValue is the 24-bit RGB color.  The least-significant byte is the
    //! blue channel, the next byte is the green channel, and the third byte is the
    //! red channel.
    //!
    //! This function translates a 24-bit RGB color into a value that can be
    //! written into the display's frame buffer in order to reproduce that color,
    //! or the closest possible approximation of that color.
    //!
    //! \return Returns the display-driver specific color.
    //
    //*****************************************************************************
    static unsigned long
    CFAL96x64x16ColorTranslate(void *pvDisplayData, unsigned long ulValue)
    {
        //
        // Translate from a 24-bit RGB color to a 3-3-2 RGB color.
        //
        return(DPYCOLORTRANSLATE(ulValue));
    }
    
    //*****************************************************************************
    //
    //! Flushes any cached drawing operations.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //!
    //! This functions flushes any cached drawing operations to the display.  This
    //! is useful when a local frame buffer is used for drawing operations, and the
    //! flush would copy the local frame buffer to the display.  Since no memory
    //! based frame buffer is used for this driver, the flush is a no operation.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16Flush(void *pvDisplayData)
    {
        //
        // There is nothing to be done.
        //
    }
    
    //*****************************************************************************
    //
    //! The display structure that describes the driver for the Crystalfontz
    //! CFAL9664-F-B1 OLED panel with SSD 1332 controller.
    //
    //*****************************************************************************
    const tDisplay g_sCFAL96x64x16 =
    {
        sizeof(tDisplay),
        0,
        128,
        64,
        CFAL96x64x16PixelDraw,
        CFAL96x64x16PixelDrawMultiple,
        CFAL96x64x16LineDrawH,
        CFAL96x64x16LineDrawV,
        CFAL96x64x16RectFill,
        CFAL96x64x16ColorTranslate,
        CFAL96x64x16Flush
    };
    
    //*****************************************************************************
    //
    //! Initializes the display driver.
    //!
    //! This function initializes the SSD1332 display controller on the panel,
    //! preparing it to display data.
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    CFAL96x64x16Init(void)
    {
        tRectangle sRect;
    
        //
        // Enable the peripherals used by this driver
        //
        SysCtlPeripheralEnable(DISPLAY_SSI_PERIPH);
        SysCtlPeripheralEnable(DISPLAY_SSI_GPIO_PERIPH);
        SysCtlPeripheralEnable(DISPLAY_RST_GPIO_PERIPH);
    
        //
        // Select the SSI function for the appropriate pins
        //
        GPIOPinConfigure(DISPLAY_PINCFG_SSICLK);
        GPIOPinConfigure(DISPLAY_PINCFG_SSIFSS);
    	  GPIOPinConfigure(DISPLAY_PINCFG_SSITX);
    
    
        //
        // Configure the pins for the SSI function
        //
        GPIOPinTypeSSI(DISPLAY_SSI_PORT, DISPLAY_SSI_PINS);
    
        //
        // Configure display control pins as GPIO output
        //
        GPIOPinTypeGPIOOutput(DISPLAY_RST_PORT, DISPLAY_RST_PIN);
        GPIOPinTypeGPIOOutput(DISPLAY_ENV_PORT, DISPLAY_ENV_PIN);
        GPIOPinTypeGPIOOutput(DISPLAY_D_C_PORT, DISPLAY_D_C_PIN);
    
        //
        // Reset pin high, power off
        //
        GPIOPinWrite(DISPLAY_RST_PORT, DISPLAY_RST_PIN, DISPLAY_RST_PIN);
        GPIOPinWrite(DISPLAY_ENV_PORT, DISPLAY_ENV_PIN, 0);
        SysCtlDelay(1000);
    
        //
        // Drive the reset pin low while we do other stuff
        //
        GPIOPinWrite(DISPLAY_RST_PORT, DISPLAY_RST_PIN, 0);
    
        //
        // Configure the SSI port
        //
        SSIDisable(DISPLAY_SSI_BASE);
        SSIConfigSetExpClk(DISPLAY_SSI_BASE, ROM_SysCtlClockGet(),
                               SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER,
                               DISPLAY_SSI_CLOCK, 8);
        SSIEnable(DISPLAY_SSI_BASE);
    
        //
        // Take the display out of reset
        //
        SysCtlDelay(1000);
        GPIOPinWrite(DISPLAY_RST_PORT, DISPLAY_RST_PIN, DISPLAY_RST_PIN);
        SysCtlDelay(1000);
    
        //
        // Enable display power supply
        //
        GPIOPinWrite(DISPLAY_ENV_PORT, DISPLAY_ENV_PIN, DISPLAY_ENV_PIN);
        SysCtlDelay(1000);
    
        //
        // Send the initial configuration command bytes to the display
        //
        CFAL96x64x16WriteCommand(g_ucDisplayInitCommands,
                                 sizeof(g_ucDisplayInitCommands));
        SysCtlDelay(1000);
    
        //
        // Fill the entire display with a black rectangle, to clear it.
        //
        sRect.sXMin = 0;
        sRect.sXMax = 95;
        sRect.sYMin = 0;
        sRect.sYMax = 63;
        CFAL96x64x16RectFill(0, &sRect, 0);
    }
    
    void
    CFAL128x64Init(void)
    {
    	
    	
    tRectangle sRect;
       
        SysCtlPeripheralEnable(DISPLAY_SSI_PERIPH);
        SysCtlPeripheralEnable(DISPLAY_SSI_GPIO_PERIPH);
        SysCtlPeripheralEnable(DISPLAY_RST_GPIO_PERIPH);
    
        GPIOPinConfigure(DISPLAY_PINCFG_SSICLK);
        GPIOPinConfigure(DISPLAY_PINCFG_SSIFSS);
    	  GPIOPinConfigure(DISPLAY_PINCFG_SSITX);
    
        GPIOPinTypeSSI(DISPLAY_SSI_PORT, DISPLAY_SSI_PINS);
    	
    	  //
        // Configure display control pins as GPIO output
        //
        ROM_GPIOPinTypeGPIOOutput(DISPLAY_RST_PORT, DISPLAY_RST_PIN);
        ROM_GPIOPinTypeGPIOOutput(DISPLAY_ENV_PORT, DISPLAY_ENV_PIN);
        ROM_GPIOPinTypeGPIOOutput(DISPLAY_D_C_PORT, DISPLAY_D_C_PIN);
    	
    	    //
        // Reset pin high, power off
        //
        ROM_GPIOPinWrite(DISPLAY_RST_PORT, DISPLAY_RST_PIN, DISPLAY_RST_PIN);
        ROM_GPIOPinWrite(DISPLAY_ENV_PORT, DISPLAY_ENV_PIN, 0);
        ROM_SysCtlDelay(1000);
    
    	  //reset low
        GPIOPinWrite(DISPLAY_RST_PORT, DISPLAY_RST_PIN, 0);
      //  GPIOPinWrite(DISPLAY_ENV_PORT, DISPLAY_ENV_PIN, 0);
        SysCtlDelay(1000);
    	
    	  //disable and enable  ssi
       	SSIDisable(DISPLAY_SSI_BASE);
        SSIConfigSetExpClk(DISPLAY_SSI_BASE, ROM_SysCtlClockGet(),
                               SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER,
                               DISPLAY_SSI_CLOCK, 8);
        SSIEnable(DISPLAY_SSI_BASE);
    		SysCtlDelay(1000);
    	
    	  //Reset high
      	GPIOPinWrite(DISPLAY_RST_PORT, DISPLAY_RST_PIN, DISPLAY_RST_PIN);
       // GPIOPinWrite(DISPLAY_ENV_PORT, DISPLAY_ENV_PIN, 0);
        SysCtlDelay(1000);
    		
        // Enable display power supply
        GPIOPinWrite(DISPLAY_ENV_PORT, DISPLAY_ENV_PIN, DISPLAY_ENV_PIN);
        SysCtlDelay(1000);
    		
    
    		// Send the initial configuration command bytes to the display
        CFAL96x64x16WriteCommand(g_ucDisplayInitCommands,
                                 sizeof(g_ucDisplayInitCommands));
    		                         
        SysCtlDelay(1000);
    
        //
        // Fill the entire display with a black rectangle, to clear it.
        //
        sRect.sXMin = 0;
        sRect.sXMax = 95;
        sRect.sYMin = 0;
        sRect.sYMax = 63;
        CFAL96x64x16RectFill(0, &sRect, 0);
    		
    
    }
    
    
    
    //*****************************************************************************
    //
    // Close the Doxygen group.
    //! @}
    //
    //*****************************************************************************
    

  • void OLED_Initialization( void);
    int main(void)
    { 
    	
    	 
    	
             //Initializes the OLED 
      	  OLED_Initialization();
    
    	  GrContextInit(&sContext, &g_sCFAL96x64x16);
    	  GrContextForegroundSet(&sContext, ClrWhite);
              GrRectDraw(&sContext, &sRect);
    	
    	  GrContextFontSet(&sContext, g_pFontCm12);
              GrStringDrawCentered(&sContext, "Hello", -1,
                             GrContextDpyWidthGet(&sContext) / 2, 6, 0);
    	
    	 	  
    }
    
    /***********************************************************************
    Subroutine:  OLED_Initialization
    
    parameters:  None
    
    Returns:     None
    
    Synopsis:    Oled Initiazation and displays "Testamatic Sys" and "RAS" on Oled
    ************************************************************************/
    
    void OLED_Initialization( void)
    {
    	 
        //System clock set 50MHZ
          SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
                           SYSCTL_OSC_MAIN); 
    
        //SPI initialization
          CFAL128x64Init();
    	
       //Graphical display initialization
         GrContextInit(&sContext, &g_sCFAL96x64x16);
    	    
    }	

  • Hi Nethra, I am sorry say, as we discussed about with CB1,  OLED module you choosed cannot apply minimal GRLIB requirement.

    Your module also if two color "zones" are on display area classify as Black/White or monochrome device. GRLIB require an RGB device and I fear this cannot be attached to GRLIB. I have no experience with and I never plan use Monochrome devices due TFT now  cost less or equals to Monochrome.


    I don't remember where I read it require RGB, from GRLIB driver reference 1bpp can be inmplemented too, funtion translate ccolor must return 1 or 0 if pixel has to be set on or off. Example driver propose use color as threshold so black is black and every color just 1 over black is white, better can be some threshold based on sum of R G B level and set when mid bright trespass.

     http://www.ti.com/lit/an/spma055/spma055.pdf?keyMatch=grlib&tisearch=Search-EN

  • nethra patil said:
    //***************************************************************************** // // Translates a 24-bit RGB color to a display driver-specific color. // // \param c is the 24-bit RGB color. The least-significant byte is the blue // channel, the next byte is the green channel, and the third byte is the red // channel. // // This macro translates a 24-bit RGB color into a value that can be written // into the display's frame buffer in order to reproduce that color, or the // closest possible approximation of that color. // // \return Returns the display-driver specific color. // // 24-bit format: XXXX XXXX RRRR RRRR GGGG GGGG BBBB BBBB // 16-bit format: ---- ---- ---- ---- RRRR RGGG GGGB BBBB // 8-bit format: ---- ---- ---- ---- ---- ---- RRRG GGBB // // //***************************************************************************** #define DPYCOLORTRANSLATE16(c) ((((c) & 0x00f80000) >> 8) | \ (((c) & 0x0000fc00) >> 5) | \ (((c) & 0x000000f8) >> 3)) #define DPYCOLORTRANSLATE8(c) ((((c) & 0x00e00000) >> 16) | \ (((c) & 0x0000e000) >> 11) | \ (((c) & 0x000000c0) >> 6)) #define DPYCOLORTRANSLATE DPYCOLORTRANSLATE8

     Hi, this function need to be customized,

     TI propose on 1bpp example just return 0 if c==0 1 if c!=1, this is an extreme contrast setting, so I try propose use a less extreme solution like:

    #define DPYCOLORTRANSLATE1(c) ( ( (((c) & 0x00ff0000) >> 16) +                  \  // red value +
                                      (((c) & 0x0000ff00) >> 8) |                  \ // green value +
                                     ((c) & 0x000000ff))  \  // blue value
    > 350) ? 0 : 1)

    #define DPYCOLORTRANSLATE DPYCOLORTRANSLATE1



    Drawing function must write 1 bit per pixel instead of one byte/word per pixel.
  • //*****************************************************************************
    //
    // cfal96x64x16.c - Display driver for the Crystalfontz CFAL9664-F-B1 OLED
    //                  display with an SSD1332.  This version uses an SSI
    //                  interface to the display controller.
    //
    // Copyright (c) 2011 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    // 
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    // 
    // This is part of revision 8049 of the EK-LM4F232 Firmware Package.
    //
    //*****************************************************************************
    
    //*****************************************************************************
    //
    //! \addtogroup display_api
    //! @{
    //
    //*****************************************************************************
    #include "inc/tm4c123gh6pm.h"
    #include "inc/hw_memmap.h"
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/ssi.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/rom.h"
    #include "driverlib/pin_map.h"
    #include "grlib/grlib.h"
    #include "utils/uartstdio.h"
    #include "utils/ustdlib.h"
    #include "drivers/cfal96x64x16.h"
    //#include "logo.h"
    //#include "font_small.h"
    
    //*****************************************************************************
    //
    // Defines the SSI and GPIO peripherals that are used for this display.
    //
    //*****************************************************************************
    #define DISPLAY_SSI_PERIPH          SYSCTL_PERIPH_SSI0
    #define DISPLAY_SSI_GPIO_PERIPH     SYSCTL_PERIPH_GPIOA
    #define DISPLAY_RST_GPIO_PERIPH     SYSCTL_PERIPH_GPIOG
    
    //*****************************************************************************
    //
    // Defines the GPIO pin configuration macros for the pins that are used for
    // the SSI function.
    //
    //*****************************************************************************
    #define DISPLAY_PINCFG_SSICLK       GPIO_PA2_SSI0CLK
    #define DISPLAY_PINCFG_SSIFSS       GPIO_PA3_SSI0FSS
    #define DISPLAY_PINCFG_SSITX        GPIO_PA5_SSI0TX
    
    //*****************************************************************************
    //
    // Defines the port and pins for the SSI peripheral.
    //
    //*****************************************************************************
    #define DISPLAY_SSI_PORT            GPIO_PORTA_BASE
    #define DISPLAY_SSI_PINS            (GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5)
    
    //*****************************************************************************
    //
    // Defines the port and pins for the display voltage enable signal.
    //
    //*****************************************************************************
    #define DISPLAY_ENV_PORT            GPIO_PORTA_BASE
    #define DISPLAY_ENV_PIN             GPIO_PIN_4
    
    //*****************************************************************************
    //
    // Defines the port and pins for the display reset signal.
    //
    //*****************************************************************************
    #define DISPLAY_RST_PORT            GPIO_PORTA_BASE
    #define DISPLAY_RST_PIN             GPIO_PIN_6
    
    //*****************************************************************************
    //
    // Defines the port and pins for the display Data/Command (D/C) signal.
    //
    //*****************************************************************************
    #define DISPLAY_D_C_PORT            GPIO_PORTA_BASE
    #define DISPLAY_D_C_PIN             GPIO_PIN_7
    
    //*****************************************************************************
    //
    // Defines the SSI peripheral used and the data speed.
    //
    //*****************************************************************************
    #define DISPLAY_SSI_BASE            SSI0_BASE // SSI2
    #define DISPLAY_SSI_CLOCK           1000000
    
    const  unsigned char font_5x7_data[]={
                             0x00, 0x00, 0x00, 0x00, 0x00, // SPACE
                             0x00, 0x00, 0x5F, 0x00, 0x00, // !
                             0x00, 0x03, 0x00, 0x03, 0x00, // "
                             0x14, 0x3E, 0x14, 0x3E, 0x14, // #
                             0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
                             0x43, 0x33, 0x08, 0x66, 0x61, // %
                             0x36, 0x49, 0x55, 0x22, 0x50, // &
                             0x00, 0x05, 0x03, 0x00, 0x00, // '
                             0x00, 0x1C, 0x22, 0x41, 0x00, // (
                             0x00, 0x41, 0x22, 0x1C, 0x00, // )
                             0x14, 0x08, 0x3E, 0x08, 0x14, // *
                             0x08, 0x08, 0x3E, 0x08, 0x08, // +
                             0x00, 0x50, 0x30, 0x00, 0x00, // ,
                             0x08, 0x08, 0x08, 0x08, 0x08, // -
                             0x00, 0x60, 0x60, 0x00, 0x00, // .
                             0x20, 0x10, 0x08, 0x04, 0x02, // /
                             0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
                             0x00, 0x04, 0x02, 0x7F, 0x00, // 1
                             0x42, 0x61, 0x51, 0x49, 0x46, // 2
                             0x22, 0x41, 0x49, 0x49, 0x36, // 3
                             0x18, 0x14, 0x12, 0x7F, 0x10, // 4
                             0x27, 0x45, 0x45, 0x45, 0x39, // 5
                             0x3E, 0x49, 0x49, 0x49, 0x32, // 6
                             0x01, 0x01, 0x71, 0x09, 0x07, // 7
                             0x36, 0x49, 0x49, 0x49, 0x36, // 8
                             0x26, 0x49, 0x49, 0x49, 0x3E, // 9
                             0x00, 0x36, 0x36, 0x00, 0x00, // :
                             0x00, 0x56, 0x36, 0x00, 0x00, // ;
                             0x08, 0x14, 0x22, 0x41, 0x00, // <
                             0x14, 0x14, 0x14, 0x14, 0x14, // =
                             0x00, 0x41, 0x22, 0x14, 0x08, // >
                             0x02, 0x01, 0x51, 0x09, 0x06, // ?
                             0x3E, 0x41, 0x59, 0x55, 0x5E, // @
                             0x7E, 0x09, 0x09, 0x09, 0x7E, // A
                             0x7F, 0x49, 0x49, 0x49, 0x36, // B
                             0x3E, 0x41, 0x41, 0x41, 0x22, // C
                             0x7F, 0x41, 0x41, 0x41, 0x3E, // D
                             0x7F, 0x49, 0x49, 0x49, 0x41, // E
                             0x7F, 0x09, 0x09, 0x09, 0x01, // F
                             0x3E, 0x41, 0x41, 0x49, 0x3A, // G
                             0x7F, 0x08, 0x08, 0x08, 0x7F, // H
                             0x00, 0x41, 0x7F, 0x41, 0x00, // I
                             0x30, 0x40, 0x40, 0x40, 0x3F, // J
                             0x7F, 0x08, 0x14, 0x22, 0x41, // K
                             0x7F, 0x40, 0x40, 0x40, 0x40, // L
                             0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
                             0x7F, 0x02, 0x04, 0x08, 0x7F, // N
                             0x3E, 0x41, 0x41, 0x41, 0x3E, // O
                             0x7F, 0x09, 0x09, 0x09, 0x06, // P
                             0x1E, 0x21, 0x21, 0x21, 0x5E, // Q
                             0x7F, 0x09, 0x09, 0x09, 0x76, // R
                             0x26, 0x49, 0x49, 0x49, 0x32, // S
                             0x01, 0x01, 0x7F, 0x01, 0x01, // T
                             0x3F, 0x40, 0x40, 0x40, 0x3F, // U
                             0x1F, 0x20, 0x40, 0x20, 0x1F, // V
                             0x7F, 0x20, 0x10, 0x20, 0x7F, // W
                             0x41, 0x22, 0x1C, 0x22, 0x41, // X
                             0x07, 0x08, 0x70, 0x08, 0x07, // Y
                             0x61, 0x51, 0x49, 0x45, 0x43, // Z
                             0x00, 0x7F, 0x41, 0x00, 0x00, // [
                             0x02, 0x04, 0x08, 0x10, 0x20, // slash 
                             0x00, 0x00, 0x41, 0x7F, 0x00, // ]
                             0x04, 0x02, 0x01, 0x02, 0x04, // ^
                             0x40, 0x40, 0x40, 0x40, 0x40, // _
                             0x00, 0x01, 0x02, 0x04, 0x00, // `
                             0x20, 0x54, 0x54, 0x54, 0x78, // a
                             0x7F, 0x44, 0x44, 0x44, 0x38, // b
                             0x38, 0x44, 0x44, 0x44, 0x44, // c
                             0x38, 0x44, 0x44, 0x44, 0x7F, // d
                             0x38, 0x54, 0x54, 0x54, 0x18, // e
                             0x04, 0x04, 0x7E, 0x05, 0x05, // f
                             0x08, 0x54, 0x54, 0x54, 0x3C, // g
                             0x7F, 0x08, 0x04, 0x04, 0x78, // h
                             0x00, 0x44, 0x7D, 0x40, 0x00, // i
                             0x20, 0x40, 0x44, 0x3D, 0x00, // j
                             0x7F, 0x10, 0x28, 0x44, 0x00, // k
                             0x00, 0x41, 0x7F, 0x40, 0x00, // l
                             0x7C, 0x04, 0x78, 0x04, 0x78, // m
                             0x7C, 0x08, 0x04, 0x04, 0x78, // n
                             0x38, 0x44, 0x44, 0x44, 0x38, // o
                             0x7C, 0x14, 0x14, 0x14, 0x08, // p
                             0x08, 0x14, 0x14, 0x14, 0x7C, // q
                             0x00, 0x7C, 0x08, 0x04, 0x04, // r
                             0x48, 0x54, 0x54, 0x54, 0x20, // s
                             0x04, 0x04, 0x3F, 0x44, 0x44, // t
                             0x3C, 0x40, 0x40, 0x20, 0x7C, // u
                             0x1C, 0x20, 0x40, 0x20, 0x1C, // v
                             0x3C, 0x40, 0x30, 0x40, 0x3C, // w
                             0x44, 0x28, 0x10, 0x28, 0x44, // x
                             0x0C, 0x50, 0x50, 0x50, 0x3C, // y
                             0x44, 0x64, 0x54, 0x4C, 0x44, // z
                             0x00, 0x08, 0x36, 0x41, 0x41, // {
                             0x00, 0x00, 0x7F, 0x00, 0x00, // |
                             0x41, 0x41, 0x36, 0x08, 0x00, // }
                             0x02, 0x01, 0x02, 0x04, 0x02,
                             0x00, 0x07, 0x07, 0x07, 0x00, // Degree Symbol esp for A
                             };  // ~
    												
    const  unsigned char picture_tab[]={
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFC,
    0xFC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x8C, 0x8C, 0x00, 0x00, 0xFC, 0xFC, 0xFC,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x3C,
    0x7C, 0xFC, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0xFC, 0xFC, 0xFC,
    0x1C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0xFC, 0xFC, 0xF8, 0x00, 0x00, 0xF8, 0xFC, 0xFC, 0x1C,
    0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0xFC, 0xFC, 0xF8, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x3C,
    0xFC, 0xF8, 0xE0, 0x80, 0x00, 0xE0, 0xF8, 0xFC, 0x3C, 0xFC, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
    0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1D, 0x1F, 0x1F, 0x0F, 0x00, 0x00, 0x0F, 0x1F, 0x1F,
    0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x1F, 0x0F, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x00,
    0x00, 0x00, 0x01, 0x03, 0x0F, 0x1F, 0x1E, 0x1C, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F, 0x1F,
    0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x0F, 0x1D, 0x19, 0x10, 0x10, 0x00, 0x0F, 0x1F, 0x1F, 0x1C,
    0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x1F, 0x0F, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x00,
    0x00, 0x03, 0x0F, 0x1F, 0x1F, 0x0F, 0x03, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFE, 0x07, 0x03,
    0x01, 0x01, 0x61, 0x61, 0xE1, 0xE0, 0x00, 0x00, 0xF8, 0xF8, 0x30, 0x18, 0x18, 0x18, 0x00, 0x00,
    0x98, 0xD8, 0xD8, 0xD8, 0xF8, 0xF0, 0x00, 0x00, 0xF8, 0xF8, 0x18, 0x18, 0x18, 0x38, 0xF0, 0xE0,
    0x00, 0x00, 0xFF, 0xFF, 0x30, 0x18, 0x18, 0x38, 0xF8, 0xF0, 0x00, 0x00, 0x18, 0xF9, 0xF9, 0x00,
    0x00, 0xE0, 0xF0, 0x38, 0x18, 0x18, 0x18, 0x10, 0x00, 0x70, 0x78, 0xD8, 0x98, 0x98, 0x18, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
    0xFE, 0x07, 0x03, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x03,
    0x07, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E,
    0x0C, 0x0C, 0x0C, 0x0C, 0x07, 0x07, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
    0x0F, 0x0C, 0x0C, 0x0C, 0x0F, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0x0C, 0x0C, 0x0C, 0x0E, 0x07, 0x03,
    0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00,
    0x00, 0x03, 0x07, 0x0E, 0x0C, 0x0C, 0x0C, 0x04, 0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0x0F, 0x07, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x01,
    0x03, 0x07, 0x0E, 0x0C, 0x0C, 0x0C, 0x06, 0x06, 0x00, 0x00, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0E,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFE,
    0x7C, 0xE0, 0x80, 0x00, 0x80, 0xE0, 0x7C, 0xFE, 0xF0, 0x00, 0xF0, 0xF8, 0x1C, 0x0E, 0x06, 0x06,
    0x06, 0x0E, 0x1C, 0xF8, 0xF0, 0x00, 0x00, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x0E, 0x1C, 0xF8, 0xF0,
    0x00, 0x00, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x30, 0x18, 0x1C, 0xFC, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x06, 0x06, 0x06, 0x86, 0xFE, 0x3C,
    0x00, 0x00, 0xFE, 0x7E, 0x66, 0x66, 0xE6, 0xC6, 0x80, 0x00, 0x00, 0x3C, 0xFE, 0xC6, 0x86, 0xC6,
    0xFE, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3F, 0x03,
    0x00, 0x03, 0x1F, 0x3C, 0x1F, 0x03, 0x00, 0x03, 0x3F, 0x38, 0x03, 0x0F, 0x1C, 0x38, 0x30, 0x30,
    0x30, 0x38, 0x1C, 0x0F, 0x07, 0x00, 0x00, 0x3F, 0x3F, 0x30, 0x30, 0x30, 0x38, 0x1C, 0x0F, 0x03,
    0x00, 0x00, 0x3F, 0x3F, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x3F, 0x3F, 0x30, 0x30,
    0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x20, 0x38, 0x3C, 0x37, 0x33, 0x30, 0x30,
    0x00, 0x00, 0x10, 0x38, 0x30, 0x30, 0x38, 0x1F, 0x0F, 0x00, 0x00, 0x1F, 0x3F, 0x31, 0x30, 0x31,
    0x3F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    
    //*****************************************************************************
    //
    // An array that holds a set of commands that are sent to the display when
    // it is initialized.
    //
    //*****************************************************************************
    static
    unsigned char g_ucDisplayInitCommands[] =
    {
        //0xAE,         // display off
        0xD5, 0x80,     // master control current 7/16
        0xA8, 0x3F,     // contrast A control
        0xD3, 0x0,     // contrast B control
        (0x40 | 0x0), 0x8D,     // contrast C control
        0x14, 0x20,//00 // remap and data format - use 8-bit color mode
        0x00, (0xA0 | 0x1),     // Vpa
        0xC8, 0xDA,     // Vpb
        0x12, 0x81,     // Vpc
    //    0xAD, 0x8E,   // internal Vp, external supply
        0xCF, 0xd9,     // rectangle fill enabled
        0xF1, 0xDB,            // display on
    	  0x40, 0xA4,
    	  0xA6, 0xAF,
    		0xA6
    };
    #define NUM_INIT_BYTES sizeof(g_ucDisplayInitCommands)
    
    //*****************************************************************************
    //
    // Translates a 24-bit RGB color to a display driver-specific color.
    //
    // \param c is the 24-bit RGB color.  The least-significant byte is the blue
    // channel, the next byte is the green channel, and the third byte is the red
    // channel.
    //
    // This macro translates a 24-bit RGB color into a value that can be written
    // into the display's frame buffer in order to reproduce that color, or the
    // closest possible approximation of that color.
    //
    // \return Returns the display-driver specific color.
    //
    // 24-bit format: XXXX XXXX RRRR RRRR GGGG GGGG BBBB BBBB
    // 16-bit format: ---- ---- ---- ---- RRRR RGGG GGGB BBBB
    //  8-bit format: ---- ---- ---- ---- ---- ---- RRRG GGBB
    //
    //
    //*****************************************************************************
    #define DPYCOLORTRANSLATE16(c)  ((((c) & 0x00f80000) >> 8) |                  \
                                     (((c) & 0x0000fc00) >> 5) |                  \
                                     (((c) & 0x000000f8) >> 3))
    #define DPYCOLORTRANSLATE8(c)   ((((c) & 0x00e00000) >> 16) |                 \
                                     (((c) & 0x0000e000) >> 11) |                 \
                                     (((c) & 0x000000c0) >> 6))
    #define DPYCOLORTRANSLATE DPYCOLORTRANSLATE8
    
    //*****************************************************************************
    //
    //! Write a set of command bytes to the display controller.
    //
    //! \param pcCmd is a pointer to a set of command bytes.
    //! \param ulCount is the count of command bytes.
    //!
    //! This function provides a way to send multiple command bytes to the display
    //! controller.  It can be used for single commands, or multiple commands
    //! chained together in a buffer.  It will wait for any previous operation to
    //! finish, and then copy all the command bytes to the controller.  It will
    //! not return until the last command byte has been written to the SSI FIFO,
    //! but data could still be shifting out to the display controller when this
    //! function returns.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16WriteCommand(const unsigned char *pcCmd, unsigned long ulCount)
    {
        //
        // Wait for any previous SSI operation to finish.
        //
        while(ROM_SSIBusy(DISPLAY_SSI_BASE))
        {
        }
    
        //
        // Set the D/C pin low to indicate command
        //
        ROM_GPIOPinWrite(DISPLAY_D_C_PORT, DISPLAY_D_C_PIN, 0);
    		//cs=0
    		ROM_GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3,0);
        //
        // Send all the command bytes to the display
        //
        while(ulCount--)
        {
            ROM_SSIDataPut(DISPLAY_SSI_BASE, *pcCmd);
            pcCmd++;
        }
    		//cs=1
    		ROM_GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_3);
    }
    
    //*****************************************************************************
    //
    //! Write a set of data bytes to the display controller.
    //
    //! \param pcData is a pointer to a set of data bytes, containing pixel data.
    //! \param ulCount is the count of command bytes.
    //!
    //! This function provides a way to send a set of pixel data to the display.
    //! The data will draw pixels according to whatever the most recent col, row
    //! settings are for the display.  It will wait for any previous operation to
    //! finish, and then copy all the data bytes to the controller.  It will
    //! not return until the last data byte has been written to the SSI FIFO,
    //! but data could still be shifting out to the display controller when this
    //! function returns.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16WriteData(const unsigned char *pcData, unsigned long ulCount)
    {
        //
        // Wait for any previous SSI operation to finish.
        //
        while(ROM_SSIBusy(DISPLAY_SSI_BASE))
        {
        }
    
        //
        // Set the D/C pin high to indicate data
        //
        ROM_GPIOPinWrite(DISPLAY_D_C_PORT, DISPLAY_D_C_PIN, DISPLAY_D_C_PIN);
    		//cs=0
    		ROM_GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3,0);
    
        //
        // Send all the data bytes to the display
        //
        while(ulCount--)
        {
            ROM_SSIDataPut(DISPLAY_SSI_BASE, *pcData);
            pcData++;
        }
    		//cs=1
    		ROM_GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3,GPIO_PIN_3);
    }
    
    //*****************************************************************************
    //
    //! Draws a pixel on the screen.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param lX is the X coordinate of the pixel.
    //! \param lY is the Y coordinate of the pixel.
    //! \param ulValue is the color of the pixel.
    //!
    //! This function sets the given pixel to a particular color.  The coordinates
    //! of the pixel are assumed to be within the extents of the display.
    //!
    //! \return None.
    //
    //*****************************************************************************
    unsigned char demo_screen=0;
    static unsigned char lcd_send_demo[8];
    static unsigned char lcd_send_after_demo[2]={0x00,0x10};
    static unsigned char lcd_send_after_demo1[1]={0xff};
    static unsigned char SSD1306_INVERTDISPLAY[1]={0xA7};
    static unsigned char SSD1306_NORMALDISPLAY[1]={0xA6};
    
    void demo_fill_screen()
    {
    	unsigned char i,j;
    
    	//=====Set internal RAM to FFH=========//
    	for(i=0;i<8;i++)	
    	{
    		//lcd_send_command (0xb0+ i );	 // Set Page
    		lcd_send_demo[i] = (0xb0 + i) ;
    		CFAL96x64x16WriteCommand(lcd_send_demo, sizeof(lcd_send_demo[i]));
    		
    		//lcd_send_command (0x00);
    		//lcd_send_command (0x10);
    		CFAL96x64x16WriteCommand(lcd_send_after_demo, sizeof(lcd_send_after_demo));
    		
    //		for(j=0;j<128;j++)				// data of the page
    //			lcd_send_data(0xFF);
    		for(j=0;j<128;j++)				// data of the page
    			CFAL96x64x16WriteData(lcd_send_after_demo1, sizeof(lcd_send_after_demo1));
    		
    	}		
    }
    void demo_font_small()
    {
    	unsigned char i, j, k;
    	unsigned int x=0;
    	k = 0;
    	for(i=0;i<8;i++)
    	{
    		//lcd_send_command (0xb0+ i );
    	//	lcd_send_command (0x00);
    		//lcd_send_command (0x10);
    		lcd_send_demo[i] = (0xb0 + i) ;
    		CFAL96x64x16WriteCommand(lcd_send_demo, sizeof(lcd_send_demo[i]));
    		CFAL96x64x16WriteCommand(lcd_send_after_demo, sizeof(lcd_send_after_demo));	
    		
    		for(j=0;j<128;j++)
    		{
    			if(k==5)
    			{
    				//lcd_send_data(0);	// put space between characters
    				CFAL96x64x16WriteData(&lcd_send_after_demo[0], sizeof(lcd_send_after_demo[0]));
    				k = 0;
    			} else{
    				//lcd_send_data(pgm_read_byte(&font_5x7_data[x++]));
    				CFAL96x64x16WriteData(font_5x7_data, sizeof(font_5x7_data));
    				if(x==480)	// font table end then repeat characters
    				{
    				x = 0;
    				}
    				k++;
    			}
    			
    		}
    	}		
    }
    
    /*========================================
    // Load the picture on LCD screen
    ========================================*/
    void lcd_test_picture()
    {
    	unsigned char i, j;// k;
    //	unsigned int cnt=0;
    
    	for(i=0;i<8;i++)				//page loop
    	{
    		//lcd_send_command (0xb0+ i );
    		//lcd_send_command (0x00);
    		//lcd_send_command (0x10);
    		lcd_send_demo[i] = (0xb0 + i) ;
    		CFAL96x64x16WriteCommand(lcd_send_demo, sizeof(lcd_send_demo[i]));
    		CFAL96x64x16WriteCommand(lcd_send_after_demo, sizeof(lcd_send_after_demo));
    		
    		for(j=0;j<128;j++)   //column loop, load all 128 bytes
    		{
    			//lcd_send_data(pgm_read_byte(&picture_tab[cnt++]));	// read picture data from array
    			CFAL96x64x16WriteData(picture_tab, sizeof(picture_tab));
    		}
    	}
    }
    /*========================================
    // LCD Clear RAM
    ========================================*/
    void lcd_clear()
    {
    	unsigned char i,j;	
      //=====clear internal RAM to 00H=========//
      for(i=0;i<8;i++)		// Select Page
      {
    	 // lcd_send_command (0xb0+ i );
    	  //lcd_send_command (0x00);
    	  //lcd_send_command (0x10);
    		lcd_send_demo[i] = (0xb0 + i) ;
    		CFAL96x64x16WriteCommand(lcd_send_demo, sizeof(lcd_send_demo[i]));
    		CFAL96x64x16WriteCommand(lcd_send_after_demo, sizeof(lcd_send_after_demo));
    	  	  
    		for(j=0;j<128;j++)	// Set the colum data
    		{
    //			lcd_send_data(0x00);
    			CFAL96x64x16WriteData(&lcd_send_after_demo[0], sizeof(lcd_send_after_demo1[0]));
    		}
    	  
      }
    }
    
    static void
    CFAL96x64x16PixelDraw(void *pvDisplayData, int32_t lX, int32_t lY,
                          uint32_t ulValue)
    {
        unsigned char ucCmd[8];
    
        //
        // Load column command, start and end column
        //
        ucCmd[0] = 0x15;
        ucCmd[1] = (unsigned char)lX;
        ucCmd[2] = (unsigned char)lX;
    
        //
        // Load row command, start and end row
        //
        ucCmd[3] = 0x75;
        ucCmd[4] = (unsigned char)lY;
        ucCmd[5] = (unsigned char)lY;
    
        //
        // Send the column, row commands to the display
        //
        CFAL96x64x16WriteCommand(ucCmd, 6);
    
        //
        // Send the data value representing the pixel to the display
        //
        CFAL96x64x16WriteData((unsigned char *)&ulValue, 1);
    }
    
    //*****************************************************************************
    //
    //! Draws a horizontal sequence of pixels on the screen.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param lX is the X coordinate of the first pixel.
    //! \param lY is the Y coordinate of the first pixel.
    //! \param lX0 is sub-pixel offset within the pixel data, which is valid for 1
    //! or 4 bit per pixel formats.
    //! \param lCount is the number of pixels to draw.
    //! \param lBPP is the number of bits per pixel; must be 1, 4, or 8.
    //! \param pucData is a pointer to the pixel data.  For 1 and 4 bit per pixel
    //! formats, the most significant bit(s) represent the left-most pixel.
    //! \param pucPalette is a pointer to the palette used to draw the pixels.
    //!
    //! This function draws a horizontal sequence of pixels on the screen, using
    //! the supplied palette.  For 1 bit per pixel format, the palette contains
    //! pre-translated colors; for 4 and 8 bit per pixel formats, the palette
    //! contains 24-bit RGB values that must be translated before being written to
    //! the display.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16PixelDrawMultiple(void *pvDisplayData, int32_t lX, int32_t lY, int32_t lX0,
                                  int32_t lCount, int32_t lBPP,
                                  const uint8_t *pucData,
                                  const uint8_t *pucPalette)
    {
        unsigned long ulByte;
        unsigned char ucCmd[8];
    
        //
        // Load column command.  Use the specified X for the start and just set
        // the end to the rightmost column since we dont know where the data ends.
        //
        ucCmd[0] = 0x15;
        ucCmd[1] = (unsigned char)lX;
        ucCmd[2] = 95;
    
        //
        // Load row command.  Use the specified Y for the start row and just set
        // the end row to the bottom row since we dont know where the data ends.
        //
        ucCmd[3] = 0x75;
        ucCmd[4] = (unsigned char)lY;
        ucCmd[5] = 63;
    
        //
        // Send the column, row commands to the display
        //
        CFAL96x64x16WriteCommand(ucCmd, 6);
    
        //
        // Determine how to interpret the pixel data based on the number of bits
        // per pixel.
        //
        switch(lBPP)
        {
            //
            // The pixel data is in 1 bit per pixel format.
            //
            case 1:
            {
                //
                // Loop while there are more pixels to draw.
                //
                while(lCount)
                {
                    //
                    // Get the next byte of image data.
                    //
                    ulByte = *pucData++;
    
                    //
                    // Loop through the pixels in this byte of image data.
                    //
                    for(; (lX0 < 8) && lCount; lX0++, lCount--)
                    {
                        //
                        // Draw this pixel in the appropriate color.
                        //
                        unsigned char ucBPP = ((unsigned long *)pucPalette)
                                                [(ulByte >> (7 - lX0)) & 1];
                        CFAL96x64x16WriteData(&ucBPP, 1);
                    }
    
                    //
                    // Start at the beginning of the next byte of image data.
                    //
                    lX0 = 0;
                }
    
                //
                // The image data has been drawn.
                //
                break;
            }
    
            //
            // The pixel data is in 4 bit per pixel format.
            //
            case 4:
            {
                //
                // Loop while there are more pixels to draw.  "Duff's device" is
                // used to jump into the middle of the loop if the first nibble of
                // the pixel data should not be used.  Duff's device makes use of
                // the fact that a case statement is legal anywhere within a
                // sub-block of a switch statement.  See
                // http://en.wikipedia.org/wiki/Duff's_device for detailed
                // information about Duff's device.
                //
                switch(lX0 & 1)
                {
                    case 0:
                        while(lCount)
                        {
                            unsigned char ucColor;
    
                            //
                            // Get the upper nibble of the next byte of pixel data
                            // and extract the corresponding entry from the
                            // palette.
                            //
                            ulByte = (*pucData >> 4) * 3;
                            ulByte = (*(unsigned long *)(pucPalette + ulByte) &
                                      0x00ffffff);
    
                            //
                            // Translate this palette entry and write it to the
                            // screen.
                            //
                            ucColor = DPYCOLORTRANSLATE(ulByte);
                            CFAL96x64x16WriteData(&ucColor, 1);
    
                            //
                            // Decrement the count of pixels to draw.
                            //
                            lCount--;
    
                            //
                            // See if there is another pixel to draw.
                            //
                            if(lCount)
                            {
                    case 1:
                                //
                                // Get the lower nibble of the next byte of pixel
                                // data and extract the corresponding entry from
                                // the palette.
                                //
                                ulByte = (*pucData++ & 15) * 3;
                                ulByte = (*(unsigned long *)(pucPalette + ulByte) &
                                          0x00ffffff);
    
                                //
                                // Translate this palette entry and write it to the
                                // screen.
                                //
                                ucColor = DPYCOLORTRANSLATE(ulByte);
                                CFAL96x64x16WriteData(&ucColor, 1);
    
                                //
                                // Decrement the count of pixels to draw.
                                //
                                lCount--;
                            }
                        }
                }
    
                //
                // The image data has been drawn.
                //
                break;
            }
    
            //
            // The pixel data is in 8 bit per pixel format.
            //
            case 8:
            {
                //
                // Loop while there are more pixels to draw.
                //
                while(lCount--)
                {
                    unsigned char ucColor;
    
                    //
                    // Get the next byte of pixel data and extract the
                    // corresponding entry from the palette.
                    //
                    ulByte = *pucData++ * 3;
                    ulByte = *(unsigned long *)(pucPalette + ulByte) & 0x00ffffff;
    
                    //
                    // Translate this palette entry and write it to the screen.
                    //
                    ucColor = DPYCOLORTRANSLATE(ulByte);
                    CFAL96x64x16WriteData(&ucColor, 1);
                }
    
                //
                // The image data has been drawn.
                //
                break;
            }
        }
    }
    
    //*****************************************************************************
    //
    //! Draws a horizontal line.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param lX1 is the X coordinate of the start of the line.
    //! \param lX2 is the X coordinate of the end of the line.
    //! \param lY is the Y coordinate of the line.
    //! \param ulValue is the color of the line.
    //!
    //! This function draws a horizontal line on the display.  The coordinates of
    //! the line are assumed to be within the extents of the display.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16LineDrawH(void *pvDisplayData, int32_t lX1, int32_t lX2, int32_t lY,
                          uint32_t ulValue)
    {
        unsigned char ucLineBuf[16];
        unsigned int uIdx;
    
        //
        // Send command for starting row and column
        //
        ucLineBuf[0] = 0x15;
        ucLineBuf[1] = lX1 < lX2 ? lX1 : lX2;
        ucLineBuf[2] = 95;
        ucLineBuf[3] = 0x75;
        ucLineBuf[4] = lY;
        ucLineBuf[5] = 63;
        CFAL96x64x16WriteCommand(ucLineBuf, 6);
    
        //
        // Use buffer of pixels to draw line, so multiple bytes can be sent at
        // one time.  Fill the buffer with the line color.
        //
        for(uIdx = 0; uIdx < sizeof(ucLineBuf); uIdx++)
        {
            ucLineBuf[uIdx] = ulValue;
        }
    
        uIdx = (lX1 < lX2) ? (lX2 - lX1) : (lX1 - lX2);
        uIdx += 1;
        while(uIdx)
        {
            CFAL96x64x16WriteData(ucLineBuf, (uIdx < 16) ? uIdx : 16);
            uIdx -= (uIdx < 16) ? uIdx : 16;
        }
    }
    
    //*****************************************************************************
    //
    //! Draws a vertical line.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param lX is the X coordinate of the line.
    //! \param lY1 is the Y coordinate of the start of the line.
    //! \param lY2 is the Y coordinate of the end of the line.
    //! \param ulValue is the color of the line.
    //!
    //! This function draws a vertical line on the display.  The coordinates of the
    //! line are assumed to be within the extents of the display.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16LineDrawV(void *pvDisplayData, int32_t lX, int32_t lY1, int32_t lY2,
                          uint32_t ulValue)
    {
        unsigned char ucLineBuf[16];
        unsigned int uIdx;
    
        //
        // Send command for starting row and column.  Also, set vertical
        // address increment.
        //
        ucLineBuf[0] = 0x15;
        ucLineBuf[1] = lX;
        ucLineBuf[2] = 95;
        ucLineBuf[3] = 0x75;
        ucLineBuf[4] = lY1 < lY2 ? lY1 : lY2;
        ucLineBuf[5] = 63;
        ucLineBuf[6] = 0xA0;
        ucLineBuf[7] = 0x21;
        CFAL96x64x16WriteCommand(ucLineBuf, 8);
    
        //
        // Use buffer of pixels to draw line, so multiple bytes can be sent at
        // one time.  Fill the buffer with the line color.
        //
        for(uIdx = 0; uIdx < sizeof(ucLineBuf); uIdx++)
        {
            ucLineBuf[uIdx] = ulValue;
        }
    
        uIdx = (lY1 < lY2) ? (lY2 - lY1) : (lY1 - lY2);
        uIdx += 1;
        while(uIdx)
        {
            CFAL96x64x16WriteData(ucLineBuf, (uIdx < 16) ? uIdx : 16);
            uIdx -= (uIdx < 16) ? uIdx : 16;
        }
    
        //
        // Restore horizontal address increment
        //
        ucLineBuf[0] = 0xA0;
        ucLineBuf[1] = 0x20;
        CFAL96x64x16WriteCommand(ucLineBuf, 2);
    }
    
    //*****************************************************************************
    //
    //! Fills a rectangle.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param pRect is a pointer to the structure describing the rectangle.
    //! \param ulValue is the color of the rectangle.
    //!
    //! This function fills a rectangle on the display.  The coordinates of the
    //! rectangle are assumed to be within the extents of the display, and the
    //! rectangle specification is fully inclusive (in other words, both i16XMin and
    //! i16XMax are drawn, along with i16YMin and i16YMax).
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16RectFill(void *pvDisplayData, const tRectangle *pRect,
                         uint32_t ulValue)
    {
        unsigned int uY;
    
        for(uY = pRect->i16YMin; uY <= pRect->i16YMax; uY++)
        {
            CFAL96x64x16LineDrawH(0, pRect->i16XMin, pRect->i16XMax, uY, ulValue);
        }
    }
    
    //*****************************************************************************
    //
    //! Translates a 24-bit RGB color to a display driver-specific color.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //! \param ulValue is the 24-bit RGB color.  The least-significant byte is the
    //! blue channel, the next byte is the green channel, and the third byte is the
    //! red channel.
    //!
    //! This function translates a 24-bit RGB color into a value that can be
    //! written into the display's frame buffer in order to reproduce that color,
    //! or the closest possible approximation of that color.
    //!
    //! \return Returns the display-driver specific color.
    //
    //*****************************************************************************
    static uint32_t
    CFAL96x64x16ColorTranslate(void *pvDisplayData, uint32_t ulValue)
    {
        //
        // Translate from a 24-bit RGB color to a 3-3-2 RGB color.
        //
        return(DPYCOLORTRANSLATE(ulValue));
    }
    
    //*****************************************************************************
    //
    //! Flushes any cached drawing operations.
    //!
    //! \param pvDisplayData is a pointer to the driver-specific data for this
    //! display driver.
    //!
    //! This functions flushes any cached drawing operations to the display.  This
    //! is useful when a local frame buffer is used for drawing operations, and the
    //! flush would copy the local frame buffer to the display.  Since no memory
    //! based frame buffer is used for this driver, the flush is a no operation.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    CFAL96x64x16Flush(void *pvDisplayData)
    {
        //
        // There is nothing to be done.
        //
    }
    
    //*****************************************************************************
    //
    //! The display structure that describes the driver for the Crystalfontz
    //! CFAL9664-F-B1 OLED panel with SSD 1332 controller.
    //
    //*****************************************************************************
    const tDisplay g_sCFAL96x64x16 =
    {
        sizeof(tDisplay),
        0,
        128,
        64,
        CFAL96x64x16PixelDraw,
        CFAL96x64x16PixelDrawMultiple,
        CFAL96x64x16LineDrawH,
        CFAL96x64x16LineDrawV,
        CFAL96x64x16RectFill,
        CFAL96x64x16ColorTranslate,
        CFAL96x64x16Flush
    };
    
    //*****************************************************************************
    //
    //! Initializes the display driver.
    //!
    //! This function initializes the SSD1332 display controller on the panel,
    //! preparing it to display data.
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    CFAL96x64x16Init(void)
    {
        tRectangle sRect;
    
        //
        // Enable the peripherals used by this driver
        //
        ROM_SysCtlPeripheralEnable(DISPLAY_SSI_PERIPH);
        ROM_SysCtlPeripheralEnable(DISPLAY_SSI_GPIO_PERIPH);
        ROM_SysCtlPeripheralEnable(DISPLAY_RST_GPIO_PERIPH);
    
        //
        // Select the SSI function for the appropriate pins
        //
        ROM_GPIOPinConfigure(DISPLAY_PINCFG_SSICLK);
        ROM_GPIOPinConfigure(DISPLAY_PINCFG_SSIFSS);
        ROM_GPIOPinConfigure(DISPLAY_PINCFG_SSITX);
    
    
        //
        // Configure the pins for the SSI function
        //
        ROM_GPIOPinTypeSSI(DISPLAY_SSI_PORT, DISPLAY_SSI_PINS);
    
        //
        // Configure display control pins as GPIO output
        //
        ROM_GPIOPinTypeGPIOOutput(DISPLAY_RST_PORT, DISPLAY_RST_PIN);
        ROM_GPIOPinTypeGPIOOutput(DISPLAY_ENV_PORT, DISPLAY_ENV_PIN);
        ROM_GPIOPinTypeGPIOOutput(DISPLAY_D_C_PORT, DISPLAY_D_C_PIN);
    
        //
        // Reset pin high, power off
        //
        ROM_GPIOPinWrite(DISPLAY_RST_PORT, DISPLAY_RST_PIN, DISPLAY_RST_PIN);
        ROM_GPIOPinWrite(DISPLAY_ENV_PORT, DISPLAY_ENV_PIN, 0);
        ROM_SysCtlDelay(1000);
    
        //
        // Drive the reset pin low while we do other stuff
        //
        ROM_GPIOPinWrite(DISPLAY_RST_PORT, DISPLAY_RST_PIN, 0);
    
        //
        // Configure the SSI port
        //
        ROM_SSIDisable(DISPLAY_SSI_BASE);
        ROM_SSIConfigSetExpClk(DISPLAY_SSI_BASE, ROM_SysCtlClockGet(),
                               SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER,
                               DISPLAY_SSI_CLOCK, 8);
        ROM_SSIEnable(DISPLAY_SSI_BASE);
    
        //
        // Take the display out of reset
        //
        ROM_SysCtlDelay(1000);
        ROM_GPIOPinWrite(DISPLAY_RST_PORT, DISPLAY_RST_PIN, DISPLAY_RST_PIN);
        ROM_SysCtlDelay(1000);
    
        //
        // Enable display power supply
        //
        ROM_GPIOPinWrite(DISPLAY_ENV_PORT, DISPLAY_ENV_PIN, DISPLAY_ENV_PIN);
        ROM_SysCtlDelay(1000);
    
        //
        // Send the initial configuration command bytes to the display
        //
        CFAL96x64x16WriteCommand(g_ucDisplayInitCommands,
                                 sizeof(g_ucDisplayInitCommands));
        ROM_SysCtlDelay(1000);
    
        //
        // Fill the entire display with a black rectangle, to clear it.
        //
      //  sRect.i16XMin = 0;
        //sRect.i16XMax = 95;
        //sRect.i16YMin = 0;
        //sRect.i16YMax = 63;
        //CFAL96x64x16RectFill(0, &sRect, 0);
    		
    		lcd_clear();
    		
    		while(1)
        {			
    			switch(demo_screen)   
    			{
    				case 0:				
    					demo_fill_screen();
    					demo_screen=1;
    					break;
    				case 1:
    					lcd_clear();
    					demo_font_small();
    					demo_screen=2;
    					break;
    				case 2:
    					//lcd_send_command(SSD1306_INVERTDISPLAY);
    					CFAL96x64x16WriteCommand(SSD1306_INVERTDISPLAY, sizeof(SSD1306_INVERTDISPLAY));
    					demo_screen=3;
    					break;
    				case 3:
    					//lcd_send_command(SSD1306_NORMALDISPLAY);
    					CFAL96x64x16WriteCommand(SSD1306_NORMALDISPLAY, sizeof(SSD1306_NORMALDISPLAY));
    					demo_screen=4;
    					break;									
    				case 4:
    					lcd_test_picture();
    					demo_screen=5;
    					break;			
    				case 5:
    					//lcd_send_command(SSD1306_INVERTDISPLAY);
    					CFAL96x64x16WriteCommand(SSD1306_INVERTDISPLAY, sizeof(SSD1306_INVERTDISPLAY));
    					demo_screen=6;
    					break;		
    				case 6:
    					//lcd_send_command(SSD1306_NORMALDISPLAY);
    				  CFAL96x64x16WriteCommand(SSD1306_NORMALDISPLAY, sizeof(SSD1306_NORMALDISPLAY));
    					demo_screen=0;
    					break;				
    			}							
    		//_delay_ms(2000);	// every 2 second the demo screens stays before change
    			ROM_SysCtlDelay(2000);
       }
    }
    
    //*****************************************************************************
    //
    // Close the Doxygen group.
    //! @}
    //
    //*****************************************************************************
    

    Hey Roberto I tried modifying the Example AVR  code to ARM, Its working fine,I am able to get my correct display.The code I pasted above for the same.

    But my doubt is , if I use the TI graphical library (by modifying it) , does it works for the 128x64 OLED (ssd 1306)? Or which routines I need to modify in grlib?

  • Here's a simplifying (one hopes) suggestion:

    Under StellarisWare there was a far simpler Text & Graphic code design for a monochrome OLED.  This appeared for the EK-LM3S1968 - which was released before the arrival of the (rather intense) "Graphic Library."

    The OLED in that EK was monochrome - as is yours.  (while yours has 2 color "zones" - there is no difference in how you address or activate pixels.)

    As always - KISS - widgets have their place - but prepare to spend much more time/effort to "tease out" the (many) necessary details.

    EK-LM3S1968 code examples work well w/mono OLED - and avoid ALL of the complications introduced by the Graphic Library. 

    We see little wrong with your starting w/this more basic OLED programming method. (EK-LM3S1968)  Later - as/if you desire - and if you (still) wish to publish great "code volumes" here - you may (again) wage battle w/Graphic Lib...

  • Thank you cb1_mobile .
    Okay I will try out with your option. But what you suggest for the modifications of TI graphical library? Shall I proceed or any other alternatives , other than the above hopes you reffered?
  • nethra patil said:
    what you suggest for the modifications of TI graphical library?

    Why do you believe that you "need" that (intense) graphic library?  It adds significant code size, demands great study (to successfully deploy) and offers "most benefits " for larger & more colorful displays.  (than yours)

    Our small tech firm has sold many thousands of, "Graphic Display based products" - with NOT one line of code from your quoted library.

    Look up "KISS."  Start w/something that you can make work (i.e. much simpler graphic structure w/in EK-LM3S1968) - later - as/if needed - you can launch (yet more) volume code dumps in the quest to overcome (likely) widget induced, "Does not Work."

    [edit/added] Dawns that your 1st post listed EK-LX4F232 - which also employed a mono, OLED.  (and which you report having "learned well.")  Is it not true that each/every example w/in that EK addressed that OLED?  And - iirc - that EK operated w/out any attachment to Graphic Lib.  So - you've now two (rich) resources which enable you to place pixels, text and (reasonable) images/icons/bar-graphs on display.  And do it all - w/out any resort - to the complexities of Graphic Lib...

  • Hi Nehtra, I see you are a beginner but a strong one, your succes is good, you are under the good way, I am sorry I canont do job for you and tomorrow is my last free day before getting back at work.

    Your tsuccess is a good way so you have a working hardware and tested all is working, I am sure you understood a lot from this huge work but now you have to grasp difference and proceed your way, this is great for your future:

    first piece was suggested from me and is color mapping function, that function return color of picture and in original was RGB work in case of RGB 565 where 5 6 5 are the bit of colors, or 8 bit (one byte per pixel) where this byte represent color from lookup table or packed RRRGGGBB so it take 3 bit from red and green and 2 from Blue.

    TI for monochrome suggested to return 0 (pixel off) for black color or 1 if one of other 16 million color, this in my prespection is wrong so I wrote for you a translating function with threshold of 350.. Adding all 3 color from 0 to 255 result in white 255*3 = 768, middle level is near 350 so I proposed this one instead of insane extreme contrast... (maybe 200 ican be greater to also detect full color, no way to detect half tone and forever this get worst, best nimber and algorithm can be found by experiment).

    So what has to be changed from an RGB to your display? one pixel is just one bit in your device is one or more bytes in an RGB based, your need is to get color from library then pack to one byte... an example just basic color

    KKKBBKKK

    RRBRRGRR

    RBKKKKGR

    RBGGGGGR

    RBKKKKGR

     

    R represent all Red Bit to 1  -> 0xe0

    G represent oone pixel with all Green Bit to 1 -> 0x1c

    B represent one pixel with all Blue bit to 1  -> 0x03

    K represent one pixel with all bit to 0 -> 0

     

    representing this with 8 bit per color result inthis sequence of bytes sent to original rgb OLED

    0x00,0x00,0x00, 0x03,0x03,0x00,0x00,0x00 // Also this sequance  can show you the pattern but not colors are on bits

    0xe0,0xe0,0x03,0xe0,0xe0,0x1c,0xe0,0xe0

    0xe0,0x03,0x00,0x00,0x00,0x00,0x1c,0xe0

    0xe0,0x03,0x1c,0x1c,0x1c,0x1c,0x1c,0xe0

    0xe0,0x03,0x00,0x00,0x00,0x00,0x1c,0xe0

     

    same as image BW pixel

    00011000  -> 0x18

    11111111 -> oxff

    11000011 -> 0xc3

    11111111 -> 0xff

    11000011 -> 0xc3

     sequence to your monochrome Oled is more short just 0x18,0xff,0xc3,0xff,0xc3.... just five bytes not 5 *8 but images has no color just on or off state... you can see image on 0 1 pattern as you can imagine from color byte pattern... I think this help you more than providing code.

     This way your pixel are no more bytes but bit and this can be the sequence .. you have to pack 8 pixel per byte then send to controller..

     I am sure you can have great success yourself..

      To better see pattern copy on a text editor and use system monospaced font.

  • Hello Roberto and cb1_mobile

    Thanks for your timely suggestion , support and for your time.

    Now I am able to display the strings,but not using graphical library. Started implementing my application.

    Regards

    Nethra M Patil

  • Hi Nethra, clear I lost more time doing this hint than tampering code and provide ready solution, but from your progress we seen there I am sure you get a more great satisfaction of yourself modifying a complex environment than having a ready solution. Try your solution and when ready please tell us if success I am near sure it succed you with great satisfaction or ask help again with more hint. Remember we are prone to help but refuse do things for free.
    Have fun and grasp at full how to learn build, is the key to success.
  • Dear Roberto

    Yes for sure I will try with monochore graphical library within a short time, and get back to you if any doubts.
    As I am running out of time , for time sake I need to go with ready solution which I got , for my application.

    Thanks a lot for your great support man.
    Great forum, Great community members.Keep up the good work.
    Talk to you again soon with the doubts.
  • Hello Roberto 

    I have a very simple confirmation regarding SSI module of TM4C1233gh6pz.

    I want to use two/three SSI modules as slave. which SSI module shall I prefer? I guess other than SSI0(with one FSS) , all other three SSI modules( SSI1 , SSI2 , SSI3 )are suitable(as they posses more than one FSS) . 

    Thank you

  • nethra patil said:
    all other three SSI modules( SSI1 , SSI2 , SSI3 )are suitable(as they posses more than one FSS) . 

    Even after my very occasional visits - this forum - I've never noted "any" SSI module to possess more than "one" FSS.  

    Christopher Columbus, Ferdinand Magellan - step aside - new explorer/discoverer appears, "in the midst."  Or not!

    Each/every SSI instantiation (module) includes 4 pins - just one devoted to FSS.   To address multiple, Slave SSI devices - it becomes necessary to employ "standard" (non-SSI) GPIO pins configured to GPIO Outputs.   In this process - you lose the "automatic" toggling of FSS by the SSI module - you must control the GPIO pin (serving now as SSI_FSS) manually - thru your code.  (perhaps read again - so that sentence sinks in)

    Selection of an SSI module then may be based upon the full appearance of all SSI signals @ board header/connector - and freedom of those signals from the (always delightful) burden of 0-ohm resistors - which produce MCU "pin to pin" connections.   Review of your board schematic (under heavy magnification) may find vendor's "effective" (i.e. camouflaged) warning - buried among the mice-type...  (proper use of: red ink, boldface, larger font elude tech writers here)

    Note - when you attach to slave SSI devices you must supply power and ground - ideally the same power source proves sufficient for both your MCU board and slave devices.   (it's your responsibility to confirm that power is adequate...) 

    Many SPI devices are complex - always best to honor KISS - and to choose a simple (likely small EEprom memory) device with which to begin...