Home > ARM > STM32 and 7" Display

STM32 and 7" Display

A couple of weeks ago I recieved an SSD1963 evaluation board and a 7″ display.

The SSD1963 chip makes it possible to control a 7″ display with a regular microcontroller or microprocessor, which haven’t got enough memory and power to control it itself, as it’s a normal display with vSync and hSync and so on.
So after a couple of hours I got it running with my STM32 board and a touch screen controller.

Please take a look at the video below to see some of the things I can show/do.


Edit, 11. October 2014:
Another updated version of the SSD1963 library, with transparent fonts, support for larger fonts and drawing routines for Bitmap images from SD card, was used in the IOT Football Table Project whose code is published here: https://github.com/TKJElectronics/IoT_Football/tree/master/LCD/src


Edit, 21. February 2011:
I’ve now uploaded the source code for the driver of SSD1963, using the STM32.
You can download the “library” here: SSD1963_STM32_Driver.zip

Categories: ARM Tags:
  1. Carmine Ruotolo
    June 9th, 2010 at 23:51 | #1

    Where have you bought both SSD1963 board + TFT Display? Are you running on STM32F103B? Thanks.

  2. Aleksander Nokolik
    July 30th, 2010 at 21:51 | #3

    Hi ! Very nice project !
    So, i’m very interesting by this project. I purchase the SSD1963 borad and the 7″ TFT from techtoys, but it’s very difficult to me to port the “techtoys sample” to my lpc2138 board… do you publish your source code ?
    Thanx for reply
    Regards
    Alek

  3. September 8th, 2010 at 21:47 | #4

    Hi,

    how did you interface the 1963 from the STM32? I’m thinking about doing something very similiar.

    Best
    Tom

  4. September 12th, 2010 at 10:26 | #5

    @Tom Bennett
    I connected the SSD1963 different lines for simple 8080 communication, this includes:
    CS, RS, WR, RD, Reset and of course the 16-bit data line.

    Thomas

  5. Marty McLeod (micro_engineer)
    September 19th, 2010 at 22:50 | #6

    I recently used the SSD1963 with a Stellaris Cortex microcontroller. (using Newhaven Display 5.7″ w/ controller board)

    I had issues with the SSD1963 not updating single-pixel writes correctly. There was an odd problem where every other pixel would not appear until the next write was done.

    I.e., I could write a pixel, but it only every other would would appear.

    This was resolved by writing another command after writing pixel data to the SSD163 current buffer location.

    For example, when you want to do a single-pixel write:
    1. Write new x, y addresses
    2. Write memory start command ” WriteCommandByte(WRITE_MEMORY_START);”
    3. Write consecutive pixel color data.
    -> 4. TERMINATE using another command of some type, instead of nothing.
    I used WriteCommandByte(WRITE_MEMORY_START); for consistency.

  6. September 21st, 2010 at 17:51 | #7

    @Marty McLeod (micro_engineer)
    Hi Marty.
    I can do single pixel writes without any problems. I’m doing exactly as you do, by first setting area, then entering Memory-mode, but then I CLEAR the CS line, write the color data, and SETs the CS line to put the pixel!
    Would you mind trying to do this, and tell me if it solves your problem?

  7. September 23rd, 2010 at 19:32 | #8

    Hi Thomas. Actually, I recall trying just about everything exaustively to figure out what was going on.

    I never noticed it until I was stepping through single-pixel operations, in which (I believe it was) odd-numbered pixel writes did not result in a visible pixel until the next pixel write completed. Until I used the other method…

    I’ll have to drag my Stellaris ARM board out of storage (I’ve relocated) and give it a shot, not too long from now I hope.

    Thanks.

  8. Jeff
    February 8th, 2011 at 07:03 | #9

    Hi
    So your project are quite terrefic. Pretty great. So about the Techtoy.. basically i gab 2 of these and since 1 month around i can’t have them working properly. I’m running the SSD1963 with an arduino mega. I can initialize the display and all signal and clock seem fine. It’s also in 8bit mode. So when the code boot, i just can have a kind of snow picture. I can’t put a black picture or anything.. So if you can help me a little about this one.. Thanks

  9. February 8th, 2011 at 18:40 | #10

    @Jeff
    Dear Jeff.
    Are you using the proper initialization commands, and do you remember to set the correct startup registers? I used the Microchip SSD1963 example as a reference, when making the code for the STM32 processor, as you can see the correct Startup commands and register setups in the Microchip example.
    You also have to take care of the specific display registers, where you have to enter the properties of the connected display (the setup commands isn’t the same whether you use a 3.5″ or 7″ display)

    Btw. It took me quite a while to get it working too!

    Best Regards
    Thomas Jespersen

  10. Axel
    February 18th, 2011 at 10:41 | #11

    Hi,
    I have to use the SSD1963 on an STM32 (F207), dou you distribut you coude source of you SSD1963 driver? This could help me a lot.
    Thanks

  11. February 21st, 2011 at 19:46 | #12

    @Axel
    I have now uploaded the driver/library for the control of the SSD1963 chip!

    Best Regards
    Thomas Jespersen

  12. Ralf
    May 31st, 2011 at 06:20 | #13

    Hi Thomas,

    I have use Atmel AVR32 (EVK1105 development kit) to drive a 3.2″ TFT LCD (16 bit data bus). It works well and we can display any image loaded in an USB memory stick on-board.

    Now I consider to use the same board to drive a 4.3″ TFT LCD (24 bit RGB). It seems SSD1963 is the most suitable.

    I have searched and see New Heaven Display provide a DEV kits to start with:

    http://www.newhavendisplay.com/index.php?main_page=index&cPath=372

    http://www.newhavendisplay.com/index.php?main_page=product_info&cPath=372&products_id=2657

    http://www.newhavendisplay.com/index.php?main_page=product_info&cPath=372&products_id=2093

    But unfortunately, they use only 8 bit data bus to interface and control a 4.3″ TFT LCD.

    I have followed your post on SparkFun and in your blog. It’s quite impressive. I would be able to get the kit from “techtoy”.

    Could you please give me some advice for that? I could send you the datasheet of the 3.2″ TFT LCD I use and a propose 4.3″ TFT LCD.

    Thanks a lot in advance, Thomas.

    Best regards,
    Ralf

  13. June 6th, 2011 at 19:39 | #14

    @Ralf
    Dear Ralf.
    Sorry for the late response.
    The SSD1963 is a great chip for a big variety of displays, fx 4.3″ TFT’s.
    I can recommend the TechToys evaluation board, as this board makes it possible to test different displays together with the SSD1963 without having to buy multiple display boards. Though you have to make sure the LCD connections are correct, and matches the FPC-connector.

    The library I’ve made will be easily portable for you to use it with the AVR32, so no problem there. If you are interested I could also do some of the development and testing for you.

    Best Regards
    Thomas Jespersen

  14. Ralf
    June 28th, 2011 at 06:38 | #15

    Hi Thomas,

    I am sorry to get back to this post lately.

    Yes, I did buy the following parts from Techtoys:

    ;—————————————————————-
    1. SSD1963 demo kit:

    http://techtoys.com.hk/Displays/SSD1963EvalRev3B/SSD1963%20Eval%20Board%20Rev3B.htm

    2. PIC2432 EVK RD4 kit (PIC32MX360F512L):

    http://techtoys.com.hk/PIC_boards/PIC2432EVK-RD4/PIC2432%20EVK%20RD4.htm

    3. 4.3″ TFT LCDs
    ;—————————————————————-

    Thanks a lot for your advice.

    I have also downloaded SSD1963 – microchip driver + demo firmware from the website as well.

    I do run a simplified example of AVR32 on EVK1105 kit (3.2″ TFT LCD, AVR studio compiler) as well as a basic firmware to show some displays on PIC2432 EVK RD4 kit (4.3″ TFT LCD, microchip, MPLAB IDE V8.7). Both of the kits work well and I have been able to make any change on each kit’s TFT LCD.

    However, I have still not been able to modified the code of the AVR32 to drive the SD1963 and 4.3″ TFT LCD.

    I wonder if you can give me some helps. Please send your contact to my email, I’ll email you the wiring details in between AVR32 board & SSD1963 as well as the firmware works with 3.2″” TFT LCD.

    Thanks a lot for your support and I am looking forward to hear from you soon.

    Best regards,
    Ralf

  15. July 18th, 2011 at 19:09 | #16

    @Ralf
    Dear Ralf.
    Great that you got it working and that you are able to modify the examples – this is also how I make progress most of the times, when playing with new development boards.
    I used the Microchip Graphics Library as the base for my SSD1963 library for the STM32. And with enough time it will also be easily ported to the AVR32!

    Please use the “Contact Us” link on our main page so we can get in touch.

    Best Regards
    Thomas Jespersen

  16. November 15th, 2011 at 14:30 | #17

    Hi, i looked at your example for the SSD1963 and it is very good, thank you very much!

    The font that you have in your example, where can I get more fonts? I can not get the standard fonts of the STM32 working with your PutChar function…

  17. November 25th, 2011 at 11:14 | #18

    @Justus
    Hi Justus.
    The fonts I am using have been generated using the free font creator by MikroElektronika: http://www.mikroe.com/eng/products/view/683/glcd-font-creator/
    Then I made my own displaying routine for decoding these fonts and putting the right pixels to the display.

    You can do the same by finding the pattern in the generated font C-files, which is actually just the pixel bits putted together in bytes.

    Best Regards
    Thomas Jespersen

  18. Kim Petersen
    March 9th, 2012 at 16:12 | #19

    Hi,
    i looked at your library too.
    But it doesn’t work. I use the STM32F103, the SSD1963 and a 4,3″ display with 480*272 and 16 Bit.
    The GPIO signals work perfect (controlled with the scope). Are there any timinigs i have to consider? It is possible to check, that the display receive my send commands and data?

    Best regards
    Kim Petersen

  19. March 25th, 2012 at 01:46 | #20

    @Kim Petersen
    Dear Kim.
    The library I have posted was made for my specific 7″ display with it’s timing parameters etc.
    You should change the SSD1963_Configuration.h file appropriately to your display configuration.

    Here is the test configuration I have been using for my 4.3″ display, also with a resolution of 480×272 pixels. Maybe it will fit your display too.

    You should add this code below the /* End of definition for DISPLAY_PANEL == TY700TFT800480 */ line but before the #else in the SSD1963_Configuration.h file.
    To enable the display you should remember to define its’ use in the top of the file too, by adding “#define DISPLAY_PANEL TY430TFT480272” and uncommenting the other (TY700TFT800480)

    #elif (DISPLAY_PANEL == TY430TFT480272)
        /*********************************************************************
        * Overview: Horizontal and vertical display resolution
        *                  (from the glass datasheet).
        *********************************************************************/

        #define DISP_HOR_RESOLUTION             480
        #define DISP_VER_RESOLUTION             272
        /*********************************************************************
        * Overview: Image orientation (can be 0, 90, 180, 270 degrees).
        *********************************************************************/

        #define DISP_ORIENTATION                0
        /*********************************************************************
        * Overview: Panel Data Width
        *********************************************************************/

        #define DISP_DATA_WIDTH                 24
        /*********************************************************************
        * Overview: LSHIFT Polarity Swap
        * If defined LSHIFT is a falling trigger
        *********************************************************************/

        //#define DISP_INV_LSHIFT
        /*********************************************************************
        * Overview: Horizontal synchronization timing in pixels
        *                  (from the glass datasheet).
        *********************************************************************/

        #define DISP_HOR_PULSE_WIDTH        41
        #define DISP_HOR_BACK_PORCH         2
        #define DISP_HOR_FRONT_PORCH        2
        /*********************************************************************
        * Overview: Vertical synchronization timing in lines
        *                  (from the glass datasheet).
        *********************************************************************/

        #define DISP_VER_PULSE_WIDTH        10
        #define DISP_VER_BACK_PORCH         2
        #define DISP_VER_FRONT_PORCH        2

        /*********************************************************************
        * Definition for SPI interface for SSD1963
        * Hardware dependent!
        *********************************************************************/

        #define GPIO3 3
        #define GPIO2 2
        #define GPIO1 1
        #define GPIO0 0
        #define LCD_RESET (1<<GPIO0)        //LCD Reset signal (Reset for display panel, NOT ssd1963)
        #define LCD_SPENA   0
        #define LCD_SPCLK   0
        #define LCD_SPDAT   0
        /* End of definition for DISPLAY_PANEL == TY430TFT480272 */
  20. Shem
    April 18th, 2012 at 23:04 | #21

    Hi. Your project looks great.

    Just wondering what sort of refresh rate you are getting now?

    Since you are using a modified version of the Microchip Graphics Library, do you think using a PIC32 of similar specs will give you similar results? (Am concerned about the latency for the transfer between the microcontroller and the SSD1963.)

  21. April 19th, 2012 at 10:23 | #22

    @Shem
    In the demonstration video I’ve currently uploaded the SSD1963 is simply connected to some of the GPIOs on the STM32-STAMP board. As the STM32-STAMP board does only contain the STM32F103RET6 it doesn’t have any FSMC port.
    With this setup I am only able to get around 6FPS of full resolution images (800×480, 16BPP).

    I have also been connecting this 7″ display with the SSD1963 to the STM3210E-EVAL board which contains the STM32F103ZGT6 (1MB flash, 144-pins) which has a full FSMC port.
    With that setup I am able to get much faster clock rates giving me up to 20FPS – so that’s a good increase.

    I decided to use the Microchip Graphics Library as inspiration to the making of the display library for the STM32 device as Microchip had already interfaced with the SSD1963 and made the low level driver commands.
    So instead of having to look in the SSD1963 datasheet a lot more these example codes saved me a lot of time.

    I have worked with the PIC32 and I like it for sure. Though I like the ARM family more and I think I will continue them rather than the PIC32s.

    Best Regards
    Thomas Jespersen

  22. brano
    May 17th, 2012 at 07:31 | #23

    Hi Thomas,
    i just played a bit with GPIO functions on STM32 and found that e.g. GPIO_SetBits is far slower (close to 10x) than writing to register directly. e.g.
    GPIO_SetBits(GPIOD, GPIO_Pin_15); vs GPIOD->BSRRL=GPIO_Pin_15;
    So for your lcd driver using direct registry access instead of stdperiph lib(in your case e.g. Clr_Cs; Clr_nWr; Set_nWr; Set_Cs) would make lcd access even faster.
    I am using same lcd with fsmc interface for which is this not matter.

    regards
    Brano
    Brano

  23. May 23rd, 2012 at 15:34 | #24

    @brano
    Dear Brano.
    Yes you are definitely right. We have also been proving that the built in bits writing functions are very slow due to some extra checking (if the IO exists and the parameters are correct).
    In the case where FSMC isn’t supported or not used setting and clearing the IOs would be much faster with direct register writes – that is for sure.

    Thank you for the reminder – it is always good to see other smart brains out there 🙂

    Best Regards
    Thomas Jespersen

  24. Simon
    July 10th, 2012 at 15:56 | #25

    Does sommebody code and experience with FSMC and direct register writing on STM32F207? Beacause of the fire up i failed. With GPIO works SSD perfect with Pic24, 32 dsPIC33EP (both GPIO and PMP) and STM32 (only GPIO). But now my brain is smoking… 😛

  25. July 18th, 2012 at 22:30 | #26

    @Simon
    Dear Simon.
    We have experience in the FSMC bus interfacing and succeeded in using it for together with the SSD1963 controller.
    Please see my reply to your mail.

    Regards Thomas

  26. Jonne Valola
    October 6th, 2012 at 20:10 | #27

    Hi Thomas !

    I have a 5″ TFT with SSD1963 up and running through FSMC on a STM32F4Discovery board.

    Thank you for your code, it helped me through as well as http://en.radzio.dxp.pl/ssd1963/

    Still having some bugs, for example some color and artifact issues due to timing.

    I’d like to point out that in your very helpful driver code is hidden a very nasty typo that can cause a lot of headache, and maybe you’d want to fix it for other poor souls before they spend a day looking for it.

    SSD1963.c line 427:

    LCD_WriteData(0x04);

    This should be 0x03 because the value were trying to set for LCDC_FPR is 0x3FFFF !

    As this throws timing completely off I wanted to alert others to the bug.

    Thanks ! Jonne from Finland

  27. October 17th, 2012 at 11:31 | #28

    The SSD1963 datasheet shows 8080 mode CS# signal activating WITHIN the WE# or RD# signal activation period. STM32 FSMC signals have CS# asserted first and then then WE or RD are toggled. Is this an issue in interfacing/bus control?

  28. October 17th, 2012 at 12:19 | #29

    @Andrew Spencer
    No, there doesn’t seem to be any problems with the FSMC interface on the STM32 when using it with a SSD1963.
    The most correct 8080 way is also to set the Chip select first and then toggle the write or read signals.

  29. November 4th, 2012 at 14:13 | #30

    @Jonne Valola
    Dear Jonne.
    Thanks for pointing it out – odd that the project has been working at our end then.
    Maybe the 7″ display we have been using hasn’t been that time critical.

    Btw. Nice page you are having with the different GLCD libraries.

    Regards Thomas

  30. Thomas
    January 8th, 2013 at 21:29 | #31

    @Jonne Valola
    Hi all,

    since I am also fiddling around some nights now with the FSMC interface, is there anybody who provides the FSMC Code also? Until now I have only seen GPIO solutions so far.
    Thanks a lot.

  31. January 8th, 2013 at 21:44 | #32

    @Thomas
    When you first get a good feeling of the memory environment and the Flexible Static Memory Controller of the STM32, these are actually quite easy to get running.
    In the LVDS video we have uploaded we are using FSMC too.

    You can find the LCD driver used to control our own LVDS display board but with both GPIO and FSMC options here: TKJ_STM32_LCD_FSMC_Driver.zip
    You should definitely be able to use that as a ground level for adding the initialization register writes etc. for the SSD1963, which you already have within your current GPIO driver.

    We do also have these drivers with FSMC but these are under an NDA so I can’t share them.

    Regards Thomas

  32. March 7th, 2013 at 09:33 | #33

    Hello Thomas,
    I am working on STM32F103ZT6 and with SSD1963. I have connected 480X272 and 320X240 LCD’s. I am initializing SSD1963 with the Init Commands on same pins as you use, but in GPIO mode & not in FSMC mode. The Clock Freq from Crystal is 8MHz and in STM32 acitvating PLL is made to 72MHz. So, Clk Freq for SSD1963 is 8MHz. Hope we should configure the PLL in SSD1963. So below is my Initialisation Sequence details.
    Please check it and let me know whether everything is proper.

    //Hardware Reset
    GPIOD->BSRR = GPIO_Pin_6;
    millisecond_delay(1);
    GPIOD->BRR = GPIO_Pin_6;
    millisecond_delay(5);
    GPIOD->BSRR = GPIO_Pin_6;
    millisecond_delay(1);

    // Software Reset
    LCD_Cmd(0x01);
    millisecond_delay(5);
    LCD_Cmd(0x01);
    millisecond_delay(5);
    // Set PLL
    LCD_Cmd(0xE0);
    // Before the start, the system was operated with the crystal oscillator or clock input.
    // A[1] : Lock PLL. After PLL enabled for 100us, can start to lock PLL
    // 0 Use reference clock as system clock, 1 Use PLL output as system clock
    // A[0] : 0 Disable PLL, 1 Enable PLL
    LCD_Data(0x01);
    millisecond_delay(10);
    LCD_Data(0x03);

    // Set LCD Mode
    LCD_Cmd(0xB0);
    // Bits settings
    // 5 : TFT panel data width, 0 18-bit, 1 24-bit
    // 4 : TFT color depth enhancement, 0 Disable FRC or dithering, 1 Enable FRC or dithering
    // 3 : TFT FRC enable, 0 TFT dithering enable, 1 TFT FRC enable
    // 2 : LSHIFT (dot clock) polarity, 0 Rising edge, 1 Falling edge
    // 1 : LLINE (horizontal sync pulse) polarity, 0 Active low, 1 Active high
    // 0 : LFRAME (vertical sync pulse) polarity, 0 Active low, 1 Active high
    LCD_Data(0x23);
    // Bits settings
    // 7 : LCD panel mode, 0 Hsync+Vsync+DE mode, 1 TTL mode
    // 6:5 : TFT type, 00, 01 TFT mode, 10 Serial RGB mode, 11 Serial RGB+dummy mode
    LCD_Data(0x00);
    // Horizontal panel size = (HPS + 1) pixels
    // HPS[10:8] : Set the horizontal panel size
    LCD_Data((GuiConst_DISPLAY_WIDTH – 1)>>8);
    // HPS[7:0] : Set the horizontal panel size
    LCD_Data((GuiConst_INT8U)(GuiConst_DISPLAY_WIDTH – 1));
    // Vertical panel size = (VPS + 1) lines
    // VPS[10:8] : Set the vertical panel size
    LCD_Data((GuiConst_BYTE_LINES – 1)>>8);
    // VPS[7:0] : Set the vertical panel size
    LCD_Data((GuiConst_INT8U)(GuiConst_BYTE_LINES – 1));
    // Bits settings
    // 5:3 : Even line RGB sequence, 000 RGB, 001 RBG, 010 GRB, 011 GBR, 100 BRG, 101 BGR
    // 2:1 : Odd line RGB sequence, 000 RGB, 001 RBG, 010 GRB, 011 GBR, 100 BRG, 101 BGR
    LCD_Data(0x00);

    // Set Pixel Data Interface
    LCD_Cmd(0xF0);
    // A[2:0] : 0: 8-bit, 1: 12-bit, 2: 16-bit packed, 3: 16-bit (565 format),
    // 4: 18-bit, 5: 24-bit, 6: 9-bit
    #ifdef 8BIT_BUS
    LCD_Data(0x00);
    #else
    LCD_Data(0x03);
    #endif

    // Set Pixel Format
    LCD_Cmd(0x3A);
    // A[6:4] : 001: 3-bit/pixel, 010: 8-bit/pixel, 011: 12-bit/pixel,
    // 101: 16-bit/pixel,110: 18-bit/pixel,111: 24-bit/pixel
    LCD_Data(0x20);

    // Set PLL MN
    // N[7:0] : Multiplier (N) of PLL.
    // M[3:0] : Divider (M) of PLL.
    // C[2] : Effectuate MN value,
    // 0 Ignore the multiplier (N) and divider (M) values in A[7:0] and B[7:0]
    // 1 Effectuate the multiplier and divider value
    // Example For a 10MHz reference clock to obtain 115MHz PLL frequency
    //Sha – To acheive 120Mhz, Considering 119MHz, 119*6/8 (8.0MHz) = 89.25.. Rounding to 89*8/6 = 118.66MHz
    LCD_Cmd(0xE2);
    LCD_Data(0x59); // (N=34)
    LCD_Data(0x06); // (M=3)
    LCD_Data(0x04); // (Dummy Byte)

    // Set LSHIFT Frequency
    LCD_Cmd(0xE6);
    // Configure the pixel clock to PLL freq x ((LCDC_FPR + 1) / 2 on 20)
    // Example to obtain PCLK = 5.3MHz with PLL Frequency = 120MHz,
    //Sha – 4.0 Mhz with PLL Freq = 72MHz
    //LCDC_FPR[19:16]
    LCD_Data(0x00);
    // LCDC_FPR[15:8]
    LCD_Data(0xE3);
    // LCDC_FPR[7:0]
    LCD_Data(0x8E);

    // Set Horizontal Period
    LCD_Cmd(0xB4);
    // Horizontal total period = (HT + 1) pixels
    // HT[10:8]
    LCD_Data((GuiConst_DISPLAY_WIDTH + 0x30)>>8);
    // HT[7:0]
    LCD_Data((GuiConst_INT8U)(GuiConst_DISPLAY_WIDTH + 0x30));
    // Horizontal Sync Pulse Start Position = (HPS + 1) pixels
    // HPS[10:8]
    LCD_Data(0x00);
    // HPS[7:0]
    LCD_Data(0x10);
    // (LLINE) Horizontal Sync Pulse Width = (HPW + 1) pixels
    // HPW[6:0]
    LCD_Data(0x20);
    // Horizontal Display Period Start Position = LPS pixels
    // LPS[10:8]
    LCD_Data(0x00);
    // LPS[7:0]
    LCD_Data(0x20);
    // LPSPP[1:0] : Set the horizontal sync pulse subpixel start position
    LCD_Data(0x00);

    // Set Vertical Period
    LCD_Cmd(0xB6);
    // Vertical Total = (VT + 1) lines
    // VT[10:8]
    LCD_Data((GuiConst_BYTE_LINES + 0x10)>>8);
    // VT[7:0]
    LCD_Data((GuiConst_INT8U)(GuiConst_BYTE_LINES + 0x10));
    // Vertical Sync Pulse Start Position = VPS lines
    // VPS[10:8]
    LCD_Data(0x00);
    // VPS[7:0]
    LCD_Data(0x04);
    // (LFRAME)Vertical Sync Pulse Width = (VPW + 1) lines
    // VPW[6:0]
    LCD_Data(0x01);
    // Vertical Display Period Start Position = FPS lines
    // FPS[10:8]
    LCD_Data(0x00);
    // FPS[7:0]
    LCD_Data(0x06);

    /***************************************/
    // Set Address Mode
    LCD_Cmd(0x36);
    // A[7] : Page address order, 0 Top to bottom, 1 Bottom to top
    // A[6] : Column address order, 0 Left to right, 1 Right to left
    // A[5] : Page / Column order, 0 Normal mode, 1 Reverse mode
    // A[4] : Refresh line address order, 0 from top to bottom, 1 from bottom to top
    // A[3] : RGB / BGR order, 0 RGB, 1 BGR
    // A[2] : Display data refresh, 0 from left to right side, 1 from right to left side
    // A[1] : Flip Horizontal, 0 Normal, 1 Flipped
    // A[0] : Flip Vertical, 0 Normal, 1 Flipped
    LCD_Data(0x00);

    // Set GPIO Configuration
    LCD_Cmd(0xB8);
    // A[7] – A[4] : GPIO3 configuration, 0 GPIO is controlled by host, 1 GPIO is controlled by LCDC
    LCD_Data(0xF0);
    // B[0] : GPIO0 direction
    // 0 GPIO0 is used to control the panel power with Enter or Exit Sleep Mode
    // 1 GPIO0 is used as normal GPIO
    LCD_Data(0x00);

    // Set Post Proc
    LCD_Cmd(0xBC);
    // A[7:0] : Set the contrast value
    // B[7:0] : Set the brightness value
    // C[7:0] : Set the saturation value
    // D[0] : 0 Disable the postprocessor, 1 Enable the postprocessor
    LCD_Data(0x40);
    LCD_Data(0x40);
    LCD_Data(0x40);
    LCD_Data(0x00);

    // Set Gamma Curve
    LCD_Cmd(0x26);
    // 0 – No gamma curve, 1 – Gamma curve 0, 2 – Gamma curve 1, 4 – Gamma Curve 2, 8 – Gamma curve 3
    LCD_Data(0x08);

    // Set Column Address
    LCD_Cmd(0x2A);
    // Start column
    LCD_Data(0x00);
    LCD_Data(0x00);
    // End column
    LCD_Data(GuiConst_DISPLAY_WIDTH>>8);
    LCD_Data((GuiConst_INT8U)GuiConst_DISPLAY_WIDTH);

    // Set Page Address
    LCD_Cmd(0x2B);
    // Start row
    LCD_Data(0x00);
    LCD_Data(0x00);
    // End row
    LCD_Data(GuiConst_BYTE_LINES>>8);
    LCD_Data((GuiConst_INT8U)GuiConst_BYTE_LINES);

    // Enter Normal Mode
    LCD_Cmd(0x13);

    // Set display on
    LCD_Cmd(0x29);

    // Clear display memory
    LCD_Cmd(0x2C);

    for (i = 0; i < (GuiConst_DISPLAY_BYTES/2); i++);
    LCD_Data(0x0000);

    //Transfer some color codes.
    while(1)
    {
    k++;
    SSD1963_FillArea(k);
    millisecond_delay(1);
    }

    I am not able to get any kind of Signals at LFRAME, LLINE, LSHIFT, LDEN. I dont know how to use GAMAS0 pin and where. If required I will send you the Schematic also later.

    Thanks
    Shankar

  33. March 7th, 2013 at 11:53 | #34

    @Thomas Jespersen
    Hello Thomas,
    I am able to get something on LCD now.. But when I send the color code in Fill Color Function, I am always getting Grey Code Colors only. Not any color like Red, Blue , Green..

    I am also not getting how does SSD1396 will convert it to 24bit Color Code to LCD, with 16Bit Color code from MicroController as Input.

    Thanks in advance..

    Rgds
    Shankar

  34. March 7th, 2013 at 18:24 | #35

    @Shankar
    Hi Shankar.
    I have just briefly checked your code, and I’m not sure that you are doing the same initializations as me – but yet again they can and also needs to vary a bit from display to display.
    Here is my register initialization for a 480×272 LCD:

        LCD_WriteCommand(0xE0);             // Start PLL command
        LCD_WriteData(0x01);                // enable PLL

        LCD_Delay(10000);                       // wait stablize
        LCD_WriteCommand(0xE0);             // Start PLL command again
        LCD_WriteData(0x03);                // now, use PLL output as system clock

        LCD_WriteCommand(0x01);             // Soft reset
        LCD_Delay(50000);

        //Set LSHIFT freq, i.e. the DCLK with PLL freq 120MHz set previously
        //Typical DCLK for display is between 9MHz and 15MHz
        //10MHz = 120MHz*(LCDC_FPR+1)/2^20
        //LCDC_FPR = 87380 (0x15554)
        LCD_WriteCommand(0xE6);
        LCD_WriteData(0x03);
        LCD_WriteData(0x33);
        LCD_WriteData(0x33);

        //Set panel mode, varies from individual manufacturer
        LCD_WriteCommand(0xB0);
        LCD_WriteData(0x00);
        LCD_WriteData(0x00);                // set TTL mode
        LCD_WriteData((HDP>>8)&0X00FF);  //Set HDP
        LCD_WriteData(HDP&0X00FF);
        LCD_WriteData((VDP>>8)&0X00FF);  //Set VDP
        LCD_WriteData(VDP&0X00FF);
        LCD_WriteData(0x0000);          //RGB sequence

        //Set horizontal period
        LCD_WriteCommand(0xB4); //HSYNC -> Set HT
        LCD_WriteData((HT>>8)&0X00FF);
        LCD_WriteData(HT&0X00FF);
        LCD_WriteData((HPS>>8)&0X00FF);  //Set HPS
        LCD_WriteData(HPS&0X00FF);
        LCD_WriteData(HPW);            //Set HPW
        LCD_WriteData((LPS>>8)&0X00FF);  //Set HPS
        LCD_WriteData(LPS&0X00FF);
        LCD_WriteData(0x0000);

        //Set vertical period
        LCD_WriteCommand(0xB6); //VSYNC -> //Set VT
        LCD_WriteData((VT>>8)&0X00FF);
        LCD_WriteData(VT&0X00FF);
        LCD_WriteData((VPS>>8)&0X00FF);  //Set VPS
        LCD_WriteData(VPS&0X00FF);
        LCD_WriteData(VPW);            //Set VPW
        LCD_WriteData((FPS>>8)&0X00FF);  //Set FPS
        LCD_WriteData(FPS&0X00FF);

        LCD_WriteCommand(0x0036);
        LCD_WriteData(ORIENTATION_REGISTER);

        //Set pixel data interface
        LCD_WriteCommand(0xF0);
        LCD_WriteData(0x03);                //16-bit(565 format) data for 16bpp PIC32MX only
        //LCD_WriteData(0x00);              //8-bit data for 16bpp, PIC24 series

        LCD_WriteCommand(0x29);             // Turn on display; show the image on display

    Here are my display settings variables:

    #define DISP_HOR_RESOLUTION 480
    #define DISP_VER_RESOLUTION 272

    #define HDP 479

    #define HT 531
    #define HPS 43
    #define LPS 8
    #define HPW 1

    #define VDP 271

    #define VT 288
    #define VPS 12
    #define FPS 4
    #define VPW 10

    Please be aware that I’m using an 10MHz crystal connected to the SSD1963 chip, instead of the 8MHz in your case.
    You would have to change the PLL settings accordingly.

    Though in your code you have made a mistake with the for loop, writing the 0x0000 color data.
    You have made a semicolor after the for loop, which means that it will simply execute itself, and no code – so the following LCD_Data line will only be executed once!
    Instead it should say:

    for (i = 0; i < (GuiConst_DISPLAY_BYTES/2); i++) LCD_Data(0x0000);

    Regarding the color conversion you can decide which mode to use: 8-bit, 16-bit, 18-bit or 24-bit.
    Whatever mode you decide to use you will simply have to clock in the color data, either by a single cycle clock operation or by multiple.
    For 24-bit displays used in 16-bit mode, the lower bits is simply not used.

    Good luck.

    Kind regards
    Thomas Jespersen

  35. Steffen Strueber
    March 10th, 2013 at 05:49 | #36

    Hi everybody,

    I am trying the same like most of you: Connecting the SSD1963 with a STM32 (F4-Discovery Board). I am very very new with microcontrollers.

    I think it is clear how to connect the SSD1963 to the STM32. All but the clock.

    The clock speed of STM32 is set up by “GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz”, isnt it? Ok good so far.

    If I understood right, the SSD1963 can either generate its own clock signal or use an external clock. What is better? Should (can) I use any clock signal from STM?
    Which timings should I setup with the SSD 0xE2 command? The higher the better? Or must it match somehow the display or STM or anything else?

    Thanks & Kind regards,
    Steffen Strueber

  36. March 10th, 2013 at 12:00 | #37

    @Steffen Strueber
    Hi Steffen.
    I would definitely recommend to have a crystal or oscillator on the SSD1963 board and drive the display controller in that way.
    The GPIO_Speed you set within the code is simply to tell the processor which rise and fall times to expect – it has nothing to do with clock generation on the GPIO outputs.
    You could of course also decide to get the main processor oscillator output (probably 8MHz) on one of the GPIO pins, but this would require some very short shielded cables to avoid emission and noise on the other cables.

    The 0xE2 command is used to set the Multiplier and Divider of the internal PLL of the SSD1963 to generate an internal frequency between 250MHz and 800MHz.
    You would have to set this setting accordingly to the input clock frequency used (the crystal on the SSD1963 board).

    Regards Thomas

  37. March 13th, 2013 at 11:46 | #38

    @Thomas Jespersen
    Hello Thomas,

    Thanks a lot, Now I am able to display colors and whatever I want on TFT (480X272).

    Now I am facing some problem with the display buffer initialization in STM32.
    In STM32F103ZGT6, SRAM size is 96K, and I need Display Buffer size of ((480X272) X 2) = 261120 bytes. I am using 16 bit Color Coding.

    The fact is, 261120 bytes cant fit in STM32 SRAM now. So I want to configure the FSMC bank location 0x60000000 location for storing this Display Buffer data. F.Y.I
    typedef union
    {
    GuiConst_INT8U Bytes[GuiConst_BYTE_LINES][GuiConst_BYTES_PR_LINE];
    GuiConst_INT16U Words[GuiConst_BYTE_LINES][GuiConst_BYTES_PR_LINE / 2];
    }DisplayBufUnion;
    extern DisplayBufUnion GuiLib_DisplayBuf __attribute__((at(0x60020000)));

    At present, I am not able to write into this buffer. It has 0x002C as data into all the locations of Buffer. If I cahnge the content of this location or buffer using Debugger or in software, it is writing anything into this buffer, always it has data 0x002C.

    Can you please tell me, how to take control of this FSMC Bank location by doing the required configurations. I went through the examples mentioned by you before my first comment. “TKJ_DISP.c” & “TKJ_DISP.h”, but didnt get how can we send the commands to SSD1963 of X1, Y1, X2 & Y2 positions to write the data into that location.
    The function “LCD_WriteReg(reg,data)” is sending only one byte of data, but actually SSD1963 Command “0x2B” needs four bytes of data to be sent (Start Row and End Row), and it is same for Command “0x2A”. Can you tell me, how is this FSMC taking care regarding this.

    Thanks
    Shankar

  38. March 13th, 2013 at 18:58 | #39

    @Shankar
    Hello Thomas,

    I can see in File “TKJ_DISP.c” line 1263, that you are writing the Command and Data,
    LCD_REG = LCD_Reg;
    /* Write 16-bit Reg */
    LCD_RAM = LCD_RegValue;

    I dont know abt how FSMC works, but please clarify, whether just by writing on location 0x60000000, the command will be sent?..and Just by writing on location 0x60020000, the data is written to SSD1963.. ?..

    I know that, SSD1963 works with only 16Bit of Command and Data. No addressing required. So when I write on any Location between, 0x60000000 & 0x6FFFFFFF (Not considering Banks at present), I can be sure that, Command or Data is written on Data lines of SSD1963 (or on STM32 FSMC data lines)..

    I am quite confused..

    Rgds
    Shankar

  39. March 13th, 2013 at 23:17 | #40

    @Shankar
    Hi Shankar.

    Your discoveries in the TKJ_DISP.c is completely right and I will try to explain what is going on with the FSMC interface.
    As you say too, the SSD1963 doesn’t have any address lines for control, though the FSMC interface does.
    Instead the SSD1963 has a Register Select pin, which the FSMC interface unfortunately doesn’t have.

    So to fix this issue we are simply just using one of the Address pins and connect that to the RS pin on the SSD1963.
    In the TKJ_DISP project we have connected A16 (GPIOD.11) to the RS pin.

    Whenever we need to write some 16-bit data to the command register of the SSD1963 the RS pin has to be low (0). This is done by writing to the currently configured NOR/SRAM FSMC memory area at adress 0x60000000, as the address is then 0x00000.
    Finally when we need to write to some data to the SSD1963 the RS pin has to be high (1). This is then done by setting this appropriate address (writing to this address) which sets that bit high.
    In this case it is 0x6002000 as this turns into an address of 0x10000 which is equal to bit 16 set (1 << 16). So whenever you write to the FSMC address 0x60000000 you will be writing to the command register of the SSD1963 - in the code named LCD_REG. And whenever you write to the FSMC address 0x60020000 you will be writing to the data memory of the SSD1963 - in the code named LCD_RAM. I hope this gave you some basic understanding of how the FSMC periphiral is implemented and used to control 16-bit LCDs. Kind regards Thomas Jespersen

  40. March 14th, 2013 at 09:07 | #41

    Hello Thoma

    @Thomas Jespersen
    Hello Thomas,

    I was wondering, this could be the reason, before seeing your comment.. Even in my Hardware PD11 is connected to RS pin of SSD1963.

    But have small confusion now..

    0x60020000, when I take only 0x20000, in binary it will be 0010 0000 0000 0000 0000.. How can this become address 0x10000, on address lines of FSMC.. Where did one “0” miss in Binary.

    Please explain me
    “In this case it is 0x60020000 as this turns into an address of 0x10000 which is equal to bit 16 set (1 << 16)."

    Thanks
    Shankar

  41. March 14th, 2013 at 11:07 | #42

    @Shankar
    Considering 0x20000 (0x60020000)

    A19A18A17A16 A15A14A13A12 A11A10A9A8 A7A6A5A4 A3A2A1A0

    0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

    (1 is coming at A17 and not at A16)

    How can this value become 0x10000

    0001 0000 0000 0000 0000
    So that I can get 1 at A16, Please explain.

    Thanks
    Shankar

  42. March 14th, 2013 at 11:52 | #43

    @Thomas Jespersen
    Hello Thomas,

    Thanks a lot for your support.. I am able to get the TFT working with FSMC settings.
    But still, please clarify my above doubt..

    Please let me also know, how safe it is with “Donate” button above to the right. I know Paypal process, but my currency is INR (India), I will check with my bank of how much service charge do they take for Currency conversion after Donation..

    Thanks a lot..

    Shankar

  43. Aman
    January 5th, 2014 at 11:20 | #44

    Hi Thomas,

    I am interfacing 5″ Kentec display (800×480) driver SSD1963. But the screen shows only blueish color, not even any other color changing as i am trying to fill it with other colors. I also download code from techtoys. Please suggest some solution. already checked all signals & timing.
    Source Code for SSD1963

    /****************************************************************************/
    void delay(uint32_t delay_counts_val){
    uint32_t delay_counts;
        delay_counts_val *= 1000;
        for(delay_counts = 0; delay_counts &lt; delay_counts_val; delay_counts++);

    }
    /************************************************************************//**
    *                               void glcd_data_write(void)
    *
    * @brief            Graphical LCD Write.

    ****************************************************************************/

    void command_data_write_gpio(uint16_t command){
    uint8_t data_val, val = 0;
    uint16_t temp_command;

        temp_command = command;
            for(data_val = 0; data_val &gt; data_val);
                val = temp_command &amp; 0x0001;
                temp_command = command;
                    switch(data_val){
                        case 0:
                            if(val == LCD_TRUE)
                                DATA_L0_HIGH;
                            else
                                DATA_L0_LOW;
                        break;
                        case 1:
                            if(val == LCD_TRUE)
                                DATA_L1_HIGH;
                            else
                                DATA_L1_LOW;
                        break;
                        case 2:
                            if(val == LCD_TRUE)
                                DATA_L2_HIGH;
                            else
                                DATA_L2_LOW;
                        break;
                        case 3:
                            if(val == LCD_TRUE)
                                DATA_L3_HIGH;
                            else
                                DATA_L3_LOW;
                        break;
                        case 4:
                        if(val == LCD_TRUE)
                                DATA_L4_HIGH;
                            else
                                DATA_L4_LOW;
                        break;
                        case 5:
                        if(val == LCD_TRUE)
                                DATA_L5_HIGH;
                            else
                                DATA_L5_LOW;
                        break;
                        case 6:
                            if(val == LCD_TRUE)
                                DATA_L6_HIGH;
                            else
                                DATA_L6_LOW;
                        break;
                        case 7:
                            if(val == LCD_TRUE)
                                DATA_L7_HIGH;
                            else
                                DATA_L7_LOW;
                        break;
                        case 8:
                            if(val == LCD_TRUE)
                                DATA_L8_HIGH;
                            else
                                DATA_L8_LOW;
                        break;
                        case 9:
                            if(val == LCD_TRUE)
                                DATA_L9_HIGH;
                            else
                                DATA_L9_LOW;
                        break;
                        case 10:
                            if(val == LCD_TRUE)
                                DATA_L10_HIGH;
                            else
                                DATA_L10_LOW;
                        break;
                        case 11:
                            if(val == LCD_TRUE)
                                DATA_L11_HIGH;
                            else
                                DATA_L11_LOW;
                        break;
                        case 12:
                            if(val == LCD_TRUE)
                                DATA_L12_HIGH;
                            else
                                DATA_L12_LOW;
                        break;
                        case 13:
                            if(val == LCD_TRUE)
                                DATA_L13_HIGH;
                            else
                                DATA_L13_LOW;
                        break;
                        case 14:
                            if(val == LCD_TRUE)
                                DATA_L14_HIGH;
                            else
                                DATA_L14_LOW;
                        break;
                        case 15:
                            if(val == LCD_TRUE)
                                DATA_L15_HIGH;
                            else
                                DATA_L15_LOW;
                        break;
                    }
            }
    }

    /************************************************************************//**
    *                               void glcd_data_write(uint16_t)
    *
    * @brief            Graphical LCD Data Write.

    ****************************************************************************/

    void glcd_command_write(uint16_t command){
    uint16_t x_cordinates = 0, color = 0, temp_loop = 0;

        LCD_CS_LOW;
        LCD_RS_LOW;                                             //for Command RS = 0
        command_data_write_gpio(command);   //Write command
        DATA_WR_LOW;
        DATA_WR_HIGH;                                           //To Write Operation L - H Transition
        LCD_CS_HIGH;                                            // Latched into the system on Rising Edge of CS
    }
    /************************************************************************//**
    *                               void glcd_data_write(uint16_t)
    *
    * @brief            Graphical LCD command Write.

    ****************************************************************************/

    void glcd_data_write(uint16_t data){

        LCD_RS_HIGH;                                                //for Command RS = 1
        DATA_WR_LOW;
        command_data_write_gpio(data);  //Write command
        DATA_WR_HIGH;                                           //To Write Operation L - H Transition
    }

    WindowSet(unsigned int s_x,unsigned int e_x,unsigned int s_y,unsigned int e_y)
    {
    glcd_command_write(0x2a); //SET page address
        LCD_CS_LOW;
    glcd_data_write((s_x)&gt;&gt;8); //SET start page address=0
    glcd_data_write((e_x)); //SET end page address=320
        LCD_CS_HIGH;
    glcd_command_write(0x2b); //SET column address
        LCD_CS_LOW;
    glcd_data_write((s_y)&gt;&gt;8); //SET start column address=0
    glcd_data_write((e_y)); //SET end column address=240
        LCD_CS_HIGH;
    }

    void SendData(int color)
    {
    glcd_data_write((color)); // color is red
    }


    void FULL_ON(int dat){
    unsigned int x,y;
    WindowSet(0,DISP_HOR_RESOLUTION-1, 0, DISP_VER_RESOLUTION-1);
    glcd_command_write(0x2c);
        LCD_CS_LOW;
    for (x=0;x&lt;480;x++)
    {
            for (y= 0;y&gt;8);              //HT - Horizontal Total Period
        glcd_data_write(HT-1);
        glcd_data_write((HPS-1)&gt;&gt;8);              //HPS - HSYNC (Non_Display Area) to Start Pixel
        glcd_data_write(HPS-1);             //HPS: non-display period between the start of the horizontal sync (LLINE) signal and the first display data
        glcd_data_write((DISP_HOR_PULSE_WIDTH-1));              //HSYNC Pulse Width
        glcd_data_write(0x00);              //LPS: horizontal sync pulse (LLINE) start location in pixel clocks
        glcd_data_write(0x00);
        glcd_data_write(0x00);
        LCD_CS_HIGH;
        //Set Vertical Period (VSYNC + V Front Porch + V Back Porch)
        glcd_command_write(LCD_SET_VERT_PERIOD);        //0xB6
        LCD_CS_LOW;
        glcd_data_write((VT-1)&gt;&gt;8);               //VT - Horizontal Total Period
        glcd_data_write(VT-1);
        glcd_data_write((VSP-1)&gt;&gt;8);              //VPS - VSYNC (Non_Display Area) to Start Pixel
        glcd_data_write(VSP-1);             //VPS: non-display period between the start of the Vertical sync (LLINE) signal and the first display data

        glcd_data_write(DISP_VER_PULSE_WIDTH-1);                //VSYNC Pulse Width
        glcd_data_write(0x00);              //VPS: Vertical sync pulse (LLINE) start location in pixel clocks
        glcd_data_write(0x00);
        LCD_CS_HIGH;

        //Set Column Address
        glcd_command_write(LCD_SET_COLUMN_ADDRESS);

        LCD_CS_LOW;
        glcd_data_write(0x00);              //Start of Column
        glcd_data_write(0x00);
        glcd_data_write(0x03);              //End of Column 0x01DF - 480 Pixels
        glcd_data_write(0x1F);
            LCD_CS_HIGH;

        //Set Page Address
        glcd_command_write(LCD_SET_PAGE_ADDRESS);

        LCD_CS_LOW;
        glcd_data_write(0x00);              //Start of Page Number
        glcd_data_write(0x00);
        glcd_data_write(0x01);              //End of Page Number 0x010F - 272 Pixels
        glcd_data_write(0xDF);
        LCD_CS_HIGH;
        glcd_command_write(LCD_ENTER_NORMAL_MODE);              //Enter Normal Mode
        delay(10);

        glcd_command_write(0x36);               //Set Address Mode
        LCD_CS_LOW;
        glcd_data_write(0x00);
        LCD_CS_HIGH;
        delay(10);

            glcd_command_write(0x3A);

        LCD_CS_LOW;
        glcd_data_write(0x55);              //Pixel Data Interface - 16-bit 565
        LCD_CS_HIGH;

        glcd_command_write(LCD_SET_INTERFACE);

        LCD_CS_LOW;
        glcd_data_write(PIXEL_DATA_16B_565);                //Pixel Data Interface - 16-bit 565
        LCD_CS_HIGH;

            glcd_command_write(0xB8);

        LCD_CS_LOW;
        glcd_data_write(0x0F);
        glcd_data_write(0x01);
        LCD_CS_HIGH;

        glcd_command_write(LCD_SET_DISPLAY_ON);             //Set Display On

    }
  44. January 6th, 2014 at 00:48 | #45

    @Aman
    Dear Aman.
    Have you confirmed that the 16-bit interface is working properly – like trying and probing all 16 lines when writing a specific data-byte?

    I have one question about your “for”-loop in “command_data_write_gpio”: why do you have a semicolon afterwards? This makes the loop not execute anything, which means in your case the code below, is only executed ONCE!

    Best regards
    Thomas Jespersen

  45. Aman
    January 6th, 2014 at 05:28 | #46

    Hi Thomas

    It was the mistake when i posted, but it not in the code. There is no semicolon after for loop.Yes i had tested all data lines status, every line is responding as i sent data.

    for(data_val = 0; data_val > data_val);
    val = temp_command & 0x0001;
    temp_command = command;

  46. Aman
    January 6th, 2014 at 09:33 | #47

    Hi Thomas,

    Please can you make sure one thing about the LCD module data for DB0 & DB9. In hardware schematic i had seen so many schematics in which DB0 & DB9 is connected to GND to make it as 18-bit mode.
    Is it required to connect DB0 & DB9 to GND?

  47. Aman
    January 7th, 2014 at 03:38 | #48

    Hey Thomas,

    LCD is running now, found one issue in the hardware. RST & CS both sorted due to loose connector. Now fixed.

    Thanks

  48. January 18th, 2014 at 10:52 | #49

    @Aman
    Perfect. I am glad that you found the issue.
    For me it is very difficult to debug these kind of issues without having the hardware 😉

  49. Julien
    September 29th, 2014 at 13:30 | #50

    Dear Thomas,

    I found your source code very helpful. With the actual displaying routine for decoding fonts, it is not possible to display font bigger than the 16×16 (width and height) one. Do you have a displaying routine for decoding until 32×32 fonts ?

    Best regards,
    Julien

  50. September 29th, 2014 at 21:53 | #51

    @Julien
    Hi Julien.
    I am aware that this released version of my SSD1963 graphics drivers doesn’t support larger fonts than 16×16.
    It was a relatively easy fix to implement, which only included changing the font width algorithm within the char printing function.
    Furthermore I’ve also implemented the capability of individual varying character widths to make the text flow look a bit better.

    Unfortunately I can’t release this update as I’ve been using this for commercial purposes within TKJ Electronics. Though I hope with the above mentioned changes that you are able to implement it yourself.
    Thank you for your understanding.

    Best regards
    Thomas Jespersen

  51. Julien
    September 30th, 2014 at 07:34 | #52

    Hi Thomas,

    Thanks a lot for your help. The font generated by sotware is as follows:

    const unsigned char const MyFont[] = {
    109, // Size of one char (number of bytes)
    27, // Font Width
    31, // Font Height
    ……

    i tried fixing your algorithm for that kind of font:

    void LCD_PutChar(uint16_t x, uint16_t y, uint8_t Character, uint16_t ForeColor, uint16_t BackColor)
    {
    int row = 0;
    int column = 0;
    int offset = Character * MyFont[0];

    GLCD_SetArea(x, y, x+MyFont[1]-1, y+MyFont[2]-1);
    GLCD_WriteCommand(CMD_WR_MEM_START);

    for (row = 0; row < MyFont[2]; row++)
    {
    for (column = 0; column 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if (row > 0 && row 0) // Math.Pow = ^ (opløftet i)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if (row == 8)
    {
    if ((MyFont[2 * column + 2 + 3+offset] & 1) > 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if (row > 8 && row 0) // Math.Pow = ^ (opløftet i)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if (row == 16)
    {
    if ((MyFont[2 * column + 3 + 3+offset] & 1) > 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if ( row > 16 && row 0) // Math.Pow = ^ (opløftet i)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if (row == 24)
    {
    if ((MyFont[2 * column + 4 + 3+offset] & 1) > 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if ( row > 24 && row 0) // Math.Pow = ^ (opløftet i)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    }
    }
    }

    However, that does not work. Can you just give me a piece of advice please ?

    Best regards,
    Julien

  52. Julien
    September 30th, 2014 at 07:41 | #53

    Sorry for that indentation. Correct code is the following:

    void LCD_PutChar(uint16_t x, uint16_t y, uint8_t Character, uint16_t ForeColor, uint16_t BackColor)
    {
    int row = 0;
    int column = 0;
    int offset = Character * MyFont[0];

    GLCD_SetArea(x, y, x+MyFont[1]-1, y+MyFont[2]-1);
    GLCD_WriteCommand(CMD_WR_MEM_START);

    for (row = 0; row < MyFont[2]; row++)
    {
    for (column = 0; column 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if (row > 0 && row 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if (row == 8)
    {
    if ((MyFont[2 * column + 2 + 3+offset] & 1) > 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if (row > 8 && row 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if (row == 16)
    {
    if ((MyFont[2 * column + 3 + 3+offset] & 1) > 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if ( row > 16 && row 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if (row == 24)
    {
    if ((MyFont[2 * column + 4 + 3+offset] & 1) > 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    if ( row > 24 && row 0)
    {
    GLCD_WriteData(ForeColor);
    } else {
    GLCD_WriteData(BackColor);
    }
    }

    }
    }
    }

  53. October 11th, 2014 at 19:59 | #54

    @Julien
    Hi Julien.
    I have just realised that I used a minimized but still very functional version of the SSD1963 library in our IOT Football table project, which has been published on both our Blog and Github.
    So to help you out with the specific Font size problem, I would refer to the updated PutChar function: https://github.com/TKJElectronics/IoT_Football/blob/master/LCD/src/SSD1963_api.c#L313

    I hope this help you.

  54. September 29th, 2017 at 15:54 | #55

    hi thanx for your website
    could you pleas send me a schematic of interfasing STM32F4xx to SSD1963?
    thanx

  1. No trackbacks yet.