prenticedavid / MCUFRIEND_kbv

MCUFRIEND_kbv Library for Uno 2.4, 2.8, 3.5, 3.6, 3.95 inch mcufriend Shields
Other
357 stars 177 forks source link

Teensy LC not supported (with 8b parrallel interface) #178

Closed DaveLapp closed 3 years ago

DaveLapp commented 3 years ago

I'm posting an issue although I have the solution.

Attempting to use an LCD shield (supported by this library) with a Teensy LC I found the LC is not supported, only the various Teensy 3.x boards are. The LC is fundamentally the same as the 3.x boards but some of the pins used by the shield are connected to different GPIO ports on the SoC.

I added the appropriate check to the #elif covering Teensys and then added some modified macros to read/write the appropriate pins on the LC (versus the 3.x boards.)

Tested and works with an LC and my shield.

This only changes mcufriend_shield.h If appropriate I can do a pull request.

Dave L.

prenticedavid commented 3 years ago

Yes, please. The LC appears to have the same footprint as a 3.2 So it probably has the same official Arduino Dn and An pin numbering.

So it will go into mcufriend_shield.h

David.

prenticedavid commented 3 years ago

I was fed up with what I was doing. I did not see your new code on your Fork. So I did it myself. I had a typo on the //MK20 pin line. And I did not realise that the LC was only 64kB !!

//################################### TEENSY 3.x and LC ############################
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__MKL26Z64__)
#warning regular UNO shield on a Teensy 3.x or LC

//LCD pins  |D7 |D6 |D5 |D4  |D3  |D2 |D1 |D0 | |RD |WR |RS |CS |RST|
//MK20 pin  |PD2|PD4|PD7|PA13|PA12|PD0|PC3|PD3| |PD1|PC0|PB0|PB1|PB3|
//MKL26 pin |PD2|PD4|PD7|PA2 |PA1 |PD0|PC3|PD3| |PD1|PC0|PB0|PB1|PB3|

#if 0
#elif defined(__MKL26Z64__) // TeensyLC 48MHz untested.   delays can possibly be reduced.
#define WRITE_DELAY { WR_ACTIVE; }
#define IDLE_DELAY  { }
#define READ_DELAY  { RD_ACTIVE4; }
#elif defined(__MK20DX128__) || defined(__MK20DX256__) // Teensy3.0 || 3.2 96MHz
#define WRITE_DELAY { WR_ACTIVE2; }
#define IDLE_DELAY  { }
#define READ_DELAY  { RD_ACTIVE8; RD_ACTIVE; }
#elif defined(__MK64FX512__) // Teensy3.5 120MHz thanks to PeteJohno
#define WRITE_DELAY { WR_ACTIVE4; }
#define IDLE_DELAY  { WR_IDLE; }
#define READ_DELAY  { RD_ACTIVE8; }
#elif defined(__MK66FX1M0__) // Teensy3.6 180MHz untested.   delays can possibly be reduced.
#define WRITE_DELAY { WR_ACTIVE8; }
#define IDLE_DELAY  { WR_IDLE2; }
#define READ_DELAY  { RD_ACTIVE16; }
#else
#error unspecified delays
#endif

#define RD_PORT GPIOD
#define RD_PIN 1
#define WR_PORT GPIOC
#define WR_PIN 0
#define CD_PORT GPIOB
#define CD_PIN 0
#define CS_PORT GPIOB
#define CS_PIN 1
#define RESET_PORT GPIOB
#define RESET_PIN 3

// configure macros for the data pins
#if defined(__MKL26Z64__)     //TeensyLC
#define AMASK ((1<<1)|(1<<2))  //PA2,PA1 vs PA13,PA12 on 3.x
#define CMASK ((1<<3))
#define DMASK ((1<<0)|(1<<2)|(1<<3)|(1<<4)|(1<<7))

#define write_8(d) { \
        GPIOA_PCOR = AMASK; GPIOC_PCOR = CMASK; GPIOD_PCOR = DMASK; \
        GPIOA_PSOR = (((d) & (1 << 3)) >> 2) \
                     | (((d) & (1 << 4)) >> 2); \
        GPIOC_PSOR = (((d) & (1 << 1)) << 2); \
        GPIOD_PSOR = (((d) & (1 << 0)) << 3) \
                     | (((d) & (1 << 2)) >> 2) \
                     | (((d) & (1 << 5)) << 2) \
                     | (((d) & (1 << 6)) >> 2) \
                     | (((d) & (1 << 7)) >> 5); \
        }
#define read_8() ((((GPIOD_PDIR & (1<<3)) >> 3) \
                   | ((GPIOC_PDIR & (1 << 3)) >> 2) \
                   | ((GPIOD_PDIR & (1 << 0)) << 2) \
                   | ((GPIOA_PDIR & (1 << 1)) << 2) \
                   | ((GPIOA_PDIR & (1 << 2)) << 2) \
                   | ((GPIOD_PDIR & (1 << 7)) >> 2) \
                   | ((GPIOD_PDIR & (1 << 4)) << 2) \
                   | ((GPIOD_PDIR & (1 << 2)) << 5)))
#else
...
#endif
DaveLapp commented 3 years ago

_**I was fed up with what I was doing. Hope this was a good distraction from whatever that was !

I did not see your new code on your Fork. Yes I intended to push my updates to GitHub when I created the pull request. It is there now

So I did it myself. You work fast!

I had a typo on the //MK20 pin line. And I did not realise that the LC was only 64kB !!**_

Your changes look good. FWIW here is what I had. The only material difference I can see is that I used a longer write delay. (you have better comments :-) I just realized that I was working from an old version. Had you already added this but had an error?

elif defined(MK20DX128) || defined(MK20DX256) || defined(MK64FX512) || defined(MK66FX1M0) || defined(MKL26Z64) // regular UNO shield on a Teensy 3.x

warning regular UNO shield on a Teensy 3.x

//LCD pins |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 | |RD |WR |RS |CS |RST| //MK20 ports |PD2|PD4|PD7|PA13|PA12|PD0|PC3|PD3| |PD1|PC0|PB0|PB1|PB3| //MKL26 ports|PD2|PD4|PD7|PA2 |PA1 |PD0|PC3|PD3| |PD1|PC0|PB0|PB1|PB3| //3.6 pins |7 |6 |5 |4 |3 |2 |9 |8 | |14 |15 |16 |17 |18 |

if defined(MKL26Z64) // TeensyLC

define WRITE_DELAY { WR_ACTIVE2; }

define READ_DELAY { RD_ACTIVE4; }

elif defined(MK20DX128) || defined(MK20DX256) // Teensy3.0 || 3.2 96MHz

define WRITE_DELAY { WR_ACTIVE2; }

define IDLE_DELAY { }

define READ_DELAY { RD_ACTIVE8; RD_ACTIVE; }

elif defined(MK64FX512) // Teensy3.5 120MHz thanks to PeteJohno

define WRITE_DELAY { WR_ACTIVE4; }

define IDLE_DELAY { WR_IDLE; }

define READ_DELAY { RD_ACTIVE8; }

elif defined(MK66FX1M0) // Teensy3.6 180MHz untested. delays can possibly be reduced.

define WRITE_DELAY { WR_ACTIVE8; }

define IDLE_DELAY { WR_IDLE2; }

define READ_DELAY { RD_ACTIVE16; }

else

error unspecified delays

endif

define RD_PORT GPIOD

define RD_PIN 1

define WR_PORT GPIOC

define WR_PIN 0

define CD_PORT GPIOB

define CD_PIN 0

define CS_PORT GPIOB

define CS_PIN 1

define RESET_PORT GPIOB

define RESET_PIN 3

// configure macros for the data pins

if defined(MKL26Z64)

define AMASK ((1<<1)|(1<<2))

define CMASK ((1<<3))

define DMASK ((1<<0)|(1<<2)|(1<<3)|(1<<4)|(1<<7))

define write_8(d) { \

    GPIOA_PCOR = AMASK; GPIOC_PCOR = CMASK; GPIOD_PCOR = DMASK; \
    GPIOA_PSOR = (((d) & (1 << 3)) >> 2) \
                 | (((d) & (1 << 4)) >> 2); \
    GPIOC_PSOR = (((d) & (1 << 1)) << 2); \
    GPIOD_PSOR = (((d) & (1 << 0)) << 3) \
                 | (((d) & (1 << 2)) >> 2) \
                 | (((d) & (1 << 5)) << 2) \
                 | (((d) & (1 << 6)) >> 2) \
                 | (((d) & (1 << 7)) >> 5); \
    }

define read_8() ((((GPIOD_PDIR & (1<<3)) >> 3) \

               | ((GPIOC_PDIR & (1 << 3)) >> 2) \
               | ((GPIOD_PDIR & (1 << 0)) << 2) \
               | ((GPIOA_PDIR & (1 << 1)) << 2) \
               | ((GPIOA_PDIR & (1 << 2)) << 2) \
               | ((GPIOD_PDIR & (1 << 7)) >> 2) \
               | ((GPIOD_PDIR & (1 << 4)) << 2) \
               | ((GPIOD_PDIR & (1 << 2)) << 5)))

else // Teensy 3.x are all the same pin defs

prenticedavid commented 3 years ago

I still don't see a Pull Request.

It is difficult to compare your version to mine. You appear to have delays 2, 0, 4 compared to my suggested 1, 0, 4. Otherwise the difference between LC and 3.x is only the mapping of D4, D3 on the data bus.

Please can you test my code. Does it work? Then investigate whether the delays are sufficient e.g. on a slow controller like SPFD5408 or SSD1289.

I am reluctant to push it into the Master Branch until you have tested it on a real controller(s).

I am also intrigued why you chose the LC instead of the 3.2 I own a 3.2 and a 4.0

David.

DaveLapp commented 3 years ago

I wasn't sure you would want a pull request since you had made the changes already. I've now created the pull request (I think ... please excuse my inexperience if its still not there). I can see that my paste of code didn't format properly and now see how to do it properly.

I grabbed your changes as provided above and tried them out and they work so delays of 1, 0, 4 seem fine at least on the controllers I have. I only have 2 shields. Both are badged as Open Smart. One identifies as an ILI9325. The other is marked as an HX8352B and shows an ID of 0x65. I'm afraid that's all the testing I can do.

Why the LC instead of the 3.2? Because I'm cheap is probably the best answer. I do have a Teensy 3.2 and a 3.6 both of which I have played with but not (yet) built into anything. An LC is 2/3 to 1/2 the price of a 3.2 and so far for the simple projects I've done with them it has been sufficient. I'm also working on a project right now that is using a 4.0 but will probably end up using a 4.1 so I can use a USB host interface.