Attempting to connect LCD to Teensy (Pin Current Issue?)

Status
Not open for further replies.

haswek

New member
Hello,

I am attempting to connect this display to a Teensy 4.0 over SPI.

The development kit I was using to test this display includes a Seeeduino, an Arduino Uno clone that can switch between 5 and 3.3V logic level. Each pin can provide up to 40mA of current.

From this thread, I see that the Teensy 3.0 has a recommended max pin current of 9mA and absolute max pin current of 25mA. When I tried connecting the display breakout directly to the Teensy, the display does not power on. I think the reason is due to high current draw.

I took measurements of the voltage and current through the pins in both configurations, shown below:
Seeeduino:
20210527_151959.jpg

Teensy:
20210527_153344.jpg

I tried using the seeeduino for 3.3V power, with shared ground between it and the Teensy. However, it still did not work. I'm thinking each pin individually must be driven at a higher current to enable communication with the display.

To achieve this, I tried connecting the SCK, MOSI, MISO, and !CS pins of the display breakout to the collector of BC547B transistors. 3.3V is applied to the collector, the control pins (13, 11, 12, 9) on the Teensy are connected to the base of each transistor through 1kOhm resistors, and the emitter is connected to ground. The remaining pins are connected from the Seeeduino, 3.3V, shared common ground, !INT (which is a constant HIGH), and !PD(which is a constant HIGH).

This method does not work either. If anyone else has had success driving this type of display, or can provide advice on how I would be able to boost the output current, I would be very appreciative.
 
3.3V logic signals like SCLK/MOSI/MISO/#CS will be completely fine driven from any 3.3V microcontroller or any 3.3V CMOS logic family,
logic signals are designed to interwork universally like this. CMOS logic signals carry no DC current, only short pulses during transitions
when the capacitances have to charge/discharge.

Trying to measure the current of a logic signal with a multimeter is fraught with difficulty, not least the massive extra loop area
you'll create in the signal (acts as a magnetic antenna).

The problem is something else - alas there are many many issues that could cause the module not to behave, from wrong software
driver to failed backlight.

Does it work with the Seeeduino?
 
Can you post the code you are using?

Pete
Here is the link to the test code I am using: https://github.com/crystalfontz/CFAF480128A0-039Tx-A1/tree/master/CFA10099

This entire codebase compiles correctly when sent to the Seeeduino, but when compiling to the Teensy, I get this error:

Code:
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/WProgram.h:41:0,
                 from C:\Users\user\AppData\Local\Temp\arduino_build_414598\pch\Arduino.h:6:
EVE_base.cpp: In function 'void Force_Touch_Matrix()':
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/avr/pgmspace.h:30:52: error: section attribute cannot be specified for local variables
 #define PROGMEM __attribute__((section(".progmem")))
                                                    ^
C:\Users\user\AppData\Local\Temp\arduino_build_414598\sketch\EVE_base.cpp:1035:36: note: in expansion of macro 'PROGMEM'
   const int32_t touch_transform[6] PROGMEM =
                                    ^
Error compiling for board Teensy 4.0.

In EVE_base.cpp, I commented out lines 1035 to 1050 (the screen I'm using has no touch functionality anyways):
Code:
#if ((EVE_TOUCH_TYPE!=EVE_TOUCH_NONE) && (0 == EVE_TOUCH_CAL_NEEDED))
void Force_Touch_Matrix(void)
  {
//  const int32_t touch_transform[6] PROGMEM =
//    {
//    0x00010000, // [A] =     1.0000
//    0x00000000, // [B] =     0.0000
//    0x00000000, // [C] =     0.0000
//    0x00000000, // [D] =     0.0000
//    0x00010000, // [E] =     1.0000
//    0x00000000  // [F] =     0.0000
//    };
//
//  EVE_REG_Write_32(EVE_REG_TOUCH_TRANSFORM_A,touch_transform[0]);
//  EVE_REG_Write_32(EVE_REG_TOUCH_TRANSFORM_B,touch_transform[1]);
//  EVE_REG_Write_32(EVE_REG_TOUCH_TRANSFORM_C,touch_transform[2]);
//  EVE_REG_Write_32(EVE_REG_TOUCH_TRANSFORM_D,touch_transform[3]);
//  EVE_REG_Write_32(EVE_REG_TOUCH_TRANSFORM_E,touch_transform[4]);
//  EVE_REG_Write_32(EVE_REG_TOUCH_TRANSFORM_F,touch_transform[5]);
  }
#endif // ((EVE_TOUCH_TYPE!=EVE_TOUCH_NONE) && (0 == EVE_TOUCH_CAL_NEEDED))

With this block of code commented out, the code does compile and upload to the Teensy. However, the display does not function.



3.3V logic signals like SCLK/MOSI/MISO/#CS will be completely fine driven from any 3.3V microcontroller or any 3.3V CMOS logic family,
logic signals are designed to interwork universally like this. CMOS logic signals carry no DC current, only short pulses during transitions
when the capacitances have to charge/discharge.

Trying to measure the current of a logic signal with a multimeter is fraught with difficulty, not least the massive extra loop area
you'll create in the signal (acts as a magnetic antenna).

The problem is something else - alas there are many many issues that could cause the module not to behave, from wrong software
driver to failed backlight.

Does it work with the Seeeduino?
Yes, it does work with the Seeeduino. Thank you for clarifying about the digital logic currents.
 
Likely the issues are going to mostly come from the CFA10099_defines.h file in this library. The Teensy is compatible with the Arduino libraries, but this is using header files with definitions to ports that are AVR specific. The Teensy is not an AVR, unlike the Seeeduino, it has a much more advanced ARM processor and the port defines are not the same.

If you want to do a project with an OLED screen and just have it automatically work with whichever development board you're using then it's better to choose an OLED that is already fully supported on the Teensy, unless you are ready to jump into the datasheets and libraries and start re-writing the files to get everything working properly. If someone on these forums has the time and know-how to look through this crystal fonts libraries they might be able to tell you which lines of code that need to be altered, but depending on the library that may or may not be trivial.

Here's a color graphic display that might be an alternate option that is Teensy supported:

https://www.pjrc.com/store/display_ili9341_touch.html
 
Ah, I see. Thank you for explaining, I am a novice so I didn't realize the difference in the libraries. Since the display I'm using is in a specific form factor that I need, I'll stick to the Seeduino for this project, and save the Teensies I have for other projects. Thank you all for your help!
 
Never mind all that, I got it to work with the Teensy!

At lemmings' suggestion, I took a closer look at the CFA10099_defines.h file:
Code:
//Faster direct port access (specific to AVR)
#define CLR_EVE_PD_NOT        (PORTB &= ~(0x01))
#define SET_EVE_PD_NOT        (PORTB |=  (0x01))
#define CLR_EVE_CS_NOT        (PORTB &= ~(0x02))
#define SET_EVE_CS_NOT        (PORTB |=  (0x02))
#define CLR_SD_CS_NOT         (PORTB &= ~(0x04))
#define SET_SD_CS_NOT         (PORTB |=  (0x04))
#define CLR_MOSI              (PORTB &= ~(0x08))
#define SET_MOSI              (PORTB |=  (0x08))
#define CLR_MISO              (PORTB &= ~(0x10))
#define SET_MISO              (PORTB |=  (0x10))
#define CLR_SCK               (PORTB &= ~(0x20))
#define SET_SCK               (PORTB |=  (0x20))
#define CLR_DEBUG_LED         (PORTD &= ~(0x08))
#define SET_DEBUG_LED         (PORTD |=  (0x08))

These definitions allow the pins to be set faster by directly accessing the registers associated with the pins we want to access.
By replacing these definitions with simple digitalWrite() calls, the same effect can be replicated:
Code:
////Faster direct port access (specific to AVR)
//#define CLR_EVE_PD_NOT        (PORTB &= ~(0x01))
//#define SET_EVE_PD_NOT        (PORTB |=  (0x01))
#define CLR_EVE_PD_NOT        (digitalWrite(EVE_PD_NOT, LOW))
#define SET_EVE_PD_NOT        (digitalWrite(EVE_PD_NOT, HIGH))
//#define CLR_EVE_CS_NOT        (PORTB &= ~(0x02))
//#define SET_EVE_CS_NOT        (PORTB |=  (0x02))
#define CLR_EVE_CS_NOT        (digitalWrite(EVE_CS_NOT, LOW))
#define SET_EVE_CS_NOT        (digitalWrite(EVE_CS_NOT, HIGH))
//#define CLR_SD_CS_NOT         (PORTB &= ~(0x04))
//#define SET_SD_CS_NOT         (PORTB |=  (0x04))
#define CLR_SD_CS_NOT        (digitalWrite(SD_CS, LOW))
#define SET_SD_CS_NOT        (digitalWrite(SD_CS, HIGH))
//#define CLR_MOSI              (PORTB &= ~(0x08))
//#define SET_MOSI              (PORTB |=  (0x08))
//#define CLR_MISO              (PORTB &= ~(0x10))
//#define SET_MISO              (PORTB |=  (0x10))
//#define CLR_SCK               (PORTB &= ~(0x20))
//#define SET_SCK               (PORTB |=  (0x20))
//#define CLR_DEBUG_LED         (PORTD &= ~(0x08))
//#define SET_DEBUG_LED         (PORTD |=  (0x08))

Only the PD_NOT, CS_NOT, and SD_CS_NOT definitions need to be modified, as the rest of the definitions are not called in the test code.
In addition, the setup() method in CFA10099.ino must be modified:
Code:
  //Initialize port directions
  // EVE interrupt output (not used in this example)
  pinMode(EVE_INT, INPUT_PULLUP);
  // EVE Power Down (reset) input
  pinMode(EVE_PD_NOT, OUTPUT);
  // EVE SPI bus CS# input
  pinMode(EVE_CS_NOT, OUTPUT);
  // USD card CS
  pinMode(SD_CS, OUTPUT);
  // Optional pin used for LED or oscilloscope debugging.
  pinMode(DEBUG_LED, OUTPUT);

//Initialize GPIO port states
  // Set CS# high to start - SPI inactive
  SET_EVE_CS_NOT;
  // Set PD# high to start
  SET_EVE_PD_NOT;
  SET_SD_CS_NOT;

With the pin direction initializations above the pin state initializations.
But overall, this is great! Again, thanks all for the help!
 
Status
Not open for further replies.
Back
Top