Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 43

Thread: ILI 9341 Parallel Library

  1. #1

    ILI 9341 Parallel Library

    So I found a library for the STM32 on GitHub that interfaces with the ILI9341 display using the 8080 interface (https://github.com/iwalpola/Adafruit_ILI9341_8bit_STM). I ported this over to the Teensy 3.2 by using Port C bits 0 - 7 for the data bits (LCD_D0 - LCD_D7). This means I used pins 15, 22, 23, 9, 10, 13, 11, 12 for the LCD bits 0, 1, 2, 3, 4, 5, 6, and 7 accordingly; LCD_RD is 21, LCD_WR is 20, LCD_RS is 19, LCD_CS is 18, and LCD_RST is 17. For some reason when I run the example sketch, the display just starts flashing randomly. The Serial Monitor tells the following information:
    Display Power Mode: 0x2
    MADCTL Mode: 0x3
    Pixel Format: 0x2
    Image Format: 0x3
    Device ID: 0x3030303

    Here is my GitHub with the easy-to-understand code for the library and the sketch:
    https://github.com/LudumDareDevelopm...ry/tree/master

    I think I'm really close to getting this to work. If anyone has any suggestions/fixes, feel free to share them.

  2. #2
    Senior Member
    Join Date
    May 2017
    Posts
    208
    First let me say I know little about the teensy and nothing about the LCD, but I did work in the computer industry for 20 years where reading data sheets was an important part of the job.

    Code:
    #define RD_ACTIVE    digitalWriteFast(TFT_RD, HIGH);
    
    #define RD_IDLE      digitalWriteFast(TFT_RD, LOW);
    
    #define WR_ACTIVE    digitalWriteFast(TFT_WR, HIGH);
    
    #define WR_IDLE      digitalWriteFast(TFT_WR, LOW);
    
    #define CD_COMMAND   digitalWriteFast(TFT_RS, HIGH);
    
    #define CD_DATA      digitalWriteFast(TFT_RS, LOW);
    
    #define CS_ACTIVE    digitalWriteFast(TFT_CS, HIGH);
    
    #define CS_IDLE      digitalWriteFast(TFT_CS, LOW);
    These all look inverted from what they should be. They should all idle High. A strobe brings the line low and returns it to high.
    Check page 28 of the data sheet. ( Edit: your cmmand and data are probably correct. I didn't look at those )

    Code:
    GPIOC_PSOR = 0;
      GPIOC_PCOR = 0;
      for (uint8_t b = 0; b < 8; b++) {
    	  if (bitRead(c, b)) {
    		  GPIOC_PSOR |= (1 << b);
    	  } else {
    		  GPIOC_PCOR |= (1 << b);
    	  }
      }
    The whole idea of a parallel interface is to not do things like the above.
    GPIOC_PDOR = c; if no other bits in the C register? Or you could xor your data c with PDOR, mask out any bits you don't want to change and write the toggle register.
    GPIOC_PTOR = (GPIOC_PDOR ^ c ) & 0xff;
    Last edited by rcarr; 06-04-2017 at 08:22 PM. Reason: GPIO not PCIO

  3. #3
    I changed all of the GPIO_PTOR and all that to pinMode() and digitalWriteFast() to try and make it work. Even that didn't work. I read my TFT driver ID and got 0x303, which is not even the ILI9341. I have no idea what controller this LCD is using. Seems like the lied on the product page: https://www.amazon.com/HiLetgo-Displ...ywords=ili9341

  4. #4
    Here is my updated library where I changed everything you mentioned above. I looked at the data sheet and found my data and command defines were also swapped. I fixed everything and it still doesn't work for some reason. Here is my github:
    https://github.com/LudumDareDevelopm...rallel-Library

  5. #5
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    Awesome!! Welcome to pjrc.

    David Prentiss at Arduino has done a ton of work with the MCUfriend 8bit parallel tfts. I opted out of these due to the support and the amount of wiring needed to get it work which is almost double what you need for spi. Plus there are a ton of working spi libraries and gadgets. I would check out the tft's found here at the pjrc store. They are listed at a fair price and there is a ton of support to back them up.

    If you just have to use MCUfriend how ever I will help you set it up like the regular GameRiot libraries for gaming. Its some thing I should do any way if I want every thing to be compatible as promised. Plus I have a couple that aren't being used and a teensy3.2 and esp32.

    First I would try to download the mcu friend library which is teensy compatible and run a couple demos. Get to know how it works. I spent way to much time on that part!!!! Email me if you need me.....

    I got you man!!! Give me a day, two at most. This is the fun part!!
    Last edited by Duhjoker; 06-05-2017 at 02:52 AM.

  6. #6
    Thanks duhjoker. The problem is I think I can get the library working without having to buy another LCD. If it takes too long to get this to work, I'll buy the SPI version. Today I'm going to fix my inverse defines and try to get my TFT ID correctly

  7. #7
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,686
    If it were me, I would probably start of simple and see if that works...
    That is instead of touching the registers directly, just use something like digitalWriteFast, could be something as simplistic as:
    Code:
    digitalWriteFast(TFT_B0, bitRead(c, 0) ? HIGH, LOW);   // may have to change which is high and which is low.
    digitalWriteFast(TFT_B1, bitRead(c, 1) ? HIGH, LOW); 
    ...
    digitalWriteFast(TFT_B7, bitRead(c, 7) ? HIGH, LOW);
    I think there is probably issues with current stuff that looks like:
    Code:
    GPIOC_PSOR = 0;
      GPIOC_PCOR = 0;
      for (uint8_t b = 0; b < 8; b++) {
    	  if (bitRead(c, b)) {
    		  GPIOC_PSOR |= (1 << b);
    	  } else {
    		  GPIOC_PCOR |= (1 << b);
    	  }
      }
    That is you are actually reading and writing to the different port registers for each bit. That is PCOR is setup to clear those bits that are set (1) in the write. The read will always return 0, likewise for PSOR.

    So at a minimum dont use |=, just use =... Also writing the 0 to them does nothing...

    Or maybe you could do some simple bit hacks... something like:
    Code:
    GPIOC_PSOR = c;   
    GPIOC_PCOR = (!c & 0xff);
    Again depending on High vs low... may need to swap PSOR and PCOR in above.


    If you wish to touch all of the pins at one, there is the PDOR register, but that will touch all 32 bits. You can always read, mask or in... But you can run into issues if there are other pins used on that port and interrupts happen...

  8. #8
    I'm not using the hardware registers anymore. I replaced all of them with pinMode and digitalWrite for testing purposes.

  9. #9
    Check my updated Github

  10. #10
    Ok I found an error. In my write8() function I say digitalWrite(D0 + b, HIGH) but that won't work because D0-D7 don't increase by one.

  11. #11
    I got an id of 0x01...
    Last edited by awesome101; 06-05-2017 at 04:54 PM.

  12. #12
    I'm starting to think this is a hardware problem. The MCUFriend LCD is for the Arduino and therefore requires 5V for pin voltage. Would it still work with Teensy 3.2?

  13. #13
    So I'm using David's library and running the register id program which gives me 0 as the id. I think something is wrong with the lcd.

  14. #14
    Yess!!! I finally got the LCD to work! I studied the datasheet on page 31 and realized after the TFT_WR strobe I had to negate all the data bit pins. Now all I have to do is optimize the library by using hardware registers (if someone could help me with that that would be great).

  15. #15
    Thanks rcarr, Duhjoker, and KurtE.
    Here is my working library: https://github.com/LudumDareDevelopm...rallel-Library

  16. #16
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,686
    Took a quick look... Actually downloaded and edited such that all lines are not 3 line between each line.

    As far as speed goes. My earlier stuff might work...
    GPIOC_PSOR = c;
    GPIOC_PCOR = (!c & 0xff);

    vs the 8 digitalWriteFast calls...

    Also wonder why in places like write8special, why after you do the strobe, you set all of the data lines to LOW... Probably could remove those calls and speed some stuff up....
    But if all o fthem are on Port C bits... could do this probably by GPIOC_PCOR = 0xff; // should clear all 8 lower bits (IO pins)

  17. #17
    According to the data sheet on page 31, I have to set the bits to zero because otherwise it won't work. As for speed. the problem is I can't find any documentation for these hardware registers. In addition I've heard that digitalWriteFast is just as fast as hardware registers? Would changing the digitalWrites to hardware boost my performance by a lot?

  18. #18
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,686
    digitalWriteFast with constants will convert each of these accesses to a simple

    Your digitalWriteFast(D0, bitRead(c, 0) ? HIGH: LOW);
    Where D0 is defined as 15

    Will resolve to something like:
    Code:
    if (c&1) 
        CORE_PIN15_PORTSET = CORE_PIN15_BITMASK;
    else
        CORE_PIN15_PORTCLEAR = CORE_PIN15_BITMASK;
    Which since pin15 is C0...
    This translates into
    Code:
    if (c&1) 
        GPIOC_PSOR = 1<<0;
    else
        GPIOC_PCOR = 1<<0;
    So yes it does update one bit the same way as mentioned.
    And assuming D0..D7 maps to C0..C7
    Then the
    Code:
    GPIOC_PSOR = c;
    GPIOC_PCOR = (!c & 0xff);
    Should work...

    I would be surprised if you had to set all B0-B7, my guess is that you might need to do this maybe at the end of when you unassert CS, but... Could be wrong.
    Also for speed, I would probably inline some of the functions like WR_STROBE.

    Edit forgot to mention, you can download the datasheets for all the teensy boards up at: https://pjrc.com/teensy/datasheets.html

  19. #19
    Ok KurtE. I added your code into the library and now for some reason it's not working even though it should be. Any ideas?

  20. #20

  21. #21
    Senior Member
    Join Date
    May 2017
    Posts
    208
    That's great you got it working. In Kurt's code try ~c in place of !c.

  22. #22
    Still not working

  23. #23
    It actually has to be ~ because ! only reverses one bit

  24. #24
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,686
    I assume you left in the code for pinMode? And again I did not walk through all of your IO pins

    Also I may have mistyped... Meant to put: GPIOC_PCOR = (~c & 0xff);

  25. #25
    Ok I changed GPIOC_PCOR = (~c & 0xff); but still doesn't work. As for PinMode I use that for the LCD control pins which are on a different GPIO port. I doubt this would cause it to not work?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •