Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USB_Host_Shield_Library_2.0 SPI issue in combination with TFT_eSPI #3151

Closed
Paulsburg opened this issue Feb 2, 2024 · 11 comments
Closed

USB_Host_Shield_Library_2.0 SPI issue in combination with TFT_eSPI #3151

Paulsburg opened this issue Feb 2, 2024 · 11 comments

Comments

@Paulsburg
Copy link

Paulsburg commented Feb 2, 2024

Hardware: esp32 dev kit
Compiler: Arduino IDE 2.2.1
TFT_eSPI Version: 2.5.34
TFT Display: ILI9488
Host Shield Lib 2.0: Version 1.6.2

Overview of the problem:
The acm_terminal example doesn't run together with the TFT_eSPI library. Each of them is running without any problems, but together the acm_terminal responds to Acm.isReady() with Zero.

In detail:
If added some software lines to the acm_terminal example, to test the HostShield-Lib running together with the TFT_eSPI-Lib. Goal is to program a smart USB-terminal to observe the output of all of my esp32 applications without using my laptop. I only want to display the serial datastream, no inputs, no further controls as inputs.

With the switch <with_tft = true> I can initialize the TFT and can draw some retangles on the TFT. Thats running perfect, but I can't receive serial data from the USB interface.
If I switch the init/drawing of the TFT off <with_tft = false> I can receive my serial test data from the USB interface without any problem.

Info:

The serial buffer to realize the scrolling on the TFT is not part of this test setup.
The TFT ist using the HSPI (CS=GPIO15 and the HostShield SPI-chipselect is using VSPI (CS = GPIO5) on my esp32 testboard.

To get a endless serial stream of characters, another esp32 is producing incrementing textlines. You can see them at the end of the serial output.

What might be the problem? I am really helpless.

@Paulsburg
Copy link
Author

// basing on the <acm_terminal.ino> of the <\USB_Host_Shield_Library_2.0>

#include <cdcacm.h>
#include <usbhub.h>

#include "pgmstrings.h"

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif

#include <SPI.h>

class ACMAsyncOper : public CDCAsyncOper {
public:
uint8_t OnInit(ACM *pacm);
};

uint8_t ACMAsyncOper::OnInit(ACM *pacm) {
uint8_t rcode;
// Set DTR = 1 RTS=1
rcode = pacm->SetControlLineState(3);

if (rcode) {
ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
return rcode;
}

LINE_CODING lc;
lc.dwDTERate = 115200;
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;

rcode = pacm->SetLineCoding(&lc);

if (rcode)
ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);

return rcode;
}

USB Usb;
//USBHub Hub(&Usb);
ACMAsyncOper AsyncOper;
ACM Acm(&Usb, &AsyncOper);

// ----------------------------- TFT ---------------------------------------------
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
#define TFT_GREY 0x5AEB // New colour
unsigned long testRects(uint16_t color);
// -----------------------------------------------------------------------------------

// ############################################# SETUP ######################################
void setup() {
// ########################################################################################
Serial.begin(115200);

#if !defined(MIPSEL)
while (!Serial)
; // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
Serial.println("Start");

if (Usb.Init() == -1)
Serial.println("OSCOKIRQ failed to assert");

delay(200);

// ----------------- Init_display -------------------
#define with_tft true
//
if (with_tft) {
Serial.println("TESTAUSGABE: TFT_CS: " + String(TFT_CS));
tft.init();
testRects(TFT_WHITE);
delay(200);
}
}

// ############################################### LOOP ######################
void loop() {
// ###########################################################################
Usb.Task();

if (Acm.isReady()) {
uint8_t rcode;
// -------------------------------------------------------
// reading the keyboard
if (Serial.available()) {
uint8_t data = Serial.read();
// sending to the phone
rcode = Acm.SndData(1, &data);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SndData"), rcode);
} //if(Serial.available()...
// -------------------------------------------------------

/* reading the serial interface */
/* buffer size must be greater or equal to max.packet size */
/* it it set to 64 (largest possible max.packet size) here, can be tuned down
    for particular endpoint */
uint8_t buf[64];
uint16_t rcvd = 64;
rcode = Acm.RcvData(&rcvd, buf);
if (rcode && rcode != hrNAK)
  ErrorMessage<uint8_t>(PSTR("Ret"), rcode);

if (rcvd) {  //more than zero bytes received
  for (uint16_t i = 0; i < rcvd; i++) {
    Serial.print((char)buf[i]);  //printing on the screen
  }
}

} //if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
}

unsigned long testRects(uint16_t color) {
unsigned long start;
int n, i, i2,
cx = tft.width() / 2,
cy = tft.height() / 2;

tft.fillScreen(TFT_BLACK);
n = min(tft.width(), tft.height());
start = micros();
for (i = 2; i < n; i += 6) {
i2 = i / 2;
tft.drawRect(cx - i2, cy - i2, i, i, color);
}

return micros() - start;
}

@Paulsburg
Copy link
Author

@Paulsburg
Copy link
Author

And here is the SPI-connection of the USB_HostShield
avrpins.zip

@Paulsburg
Copy link
Author

For easy reuse, I add the full sketch as a zip file...
TEST_GitHub_acm_terminal_bodmer.zip

@Paulsburg
Copy link
Author

Paulsburg commented Feb 2, 2024

Output with using tft...

/* -------------------- #define with_tft true ----------------------------
15:11:34.353 -> ets Jun 8 2016 00:22:57
15:11:34.353 ->
15:11:34.353 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
15:11:34.353 -> configsip: 0, SPIWP:0xee
15:11:34.353 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
15:11:34.353 -> mode:DIO, clock div:1
15:11:34.353 -> load:0x3fff0030,len:1344
15:11:34.353 -> load:0x40078000,len:13964
15:11:34.353 -> load:0x40080400,len:3600
15:11:34.353 -> entry 0x400805f0
15:11:34.556 -> Start
15:11:34.556 -> TESTAUSGABE: USB HOST SetDirWrite() pinMode(5, OUTPUT)
15:11:34.556 -> TESTAUSGABE: USB HOST SetDirWrite() pinMode(5, OUTPUT)
15:11:34.556 -> TESTAUSGABE: USB HOST SetDirRead() pinMode(17, INPUT)
15:11:34.715 -> TESTAUSGABE: TFT_CS: 4

... and now the loop is running without any serial output, because Acm.isReady() is responding with Zero....
*/

@Paulsburg
Copy link
Author

Output without using tft..
/* -------------------- #define with_tft false ----------------------------
14:41:04.363 -> ets Jun 8 2016 00:22:57
14:41:04.363 ->
14:41:04.363 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
14:41:04.363 -> configsip: 0, SPIWP:0xee
14:41:04.363 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
14:41:04.363 -> mode:DIO, clock div:1
14:41:04.363 -> load:0x3fff0030,len:1344
14:41:04.363 -> load:0x40078000,len:13964
14:41:04.400 -> load:0x40080400,len:3600
14:41:04.400 -> entry 0x400805f0
14:41:04.583 -> Start
14:41:04.583 -> TESTAUSGABE: USB HOST SetDirWrite() pinMode(5, OUTPUT)
14:41:04.583 -> TESTAUSGABE: USB HOST SetDirWrite() pinMode(5, OUTPUT)
14:41:04.583 -> TESTAUSGABE: USB HOST SetDirRead() pinMode(17, INPUT)
14:41:08.410 -> {13}1234567890<0>||
14:41:08.510 -> {26}1234567890<0>1234567890<1>||
14:41:08.653 -> {39}1234567890<0>1234567890<1>1234567890<2>||
14:41:08.740 -> {52}1234567890<0>1234567890<1>1234567890<2>1234567890<3>||
14:41:08.812 -> {65}1234567890<0>1234567890<1>1234567890<2>1234567890<3>1234567890<4>||
14:41:08.912 -> {78}1234567890<0>1234567890<1>1234567890<2>1234567890<3>1234567890<4>1234567890<5>||
...
*/

@Paulsburg
Copy link
Author

I postet this issue even to the HostShield chat, without getting any help...
felis/USB_Host_Shield_2.0#802

@Paulsburg
Copy link
Author

Result of Read_User_Setup()

[code]
TFT_eSPI ver = 2.5.34
Processor = ESP32
Frequency = 240MHz
Transactions = Yes
Interface = SPI
Display driver = 9488
Display width = 320
Display height = 480

MOSI = GPIO 13
MISO = GPIO 12
SCK = GPIO 14
TFT_CS = GPIO 15
TFT_DC = GPIO 4

Font GLCD loaded
Font 2 loaded
Font 4 loaded
Font 6 loaded
Font 7 loaded
Font 8 loaded
Smooth font enabled

Display SPI frequency = 55.00
[/code]

@Bodmer
Copy link
Owner

Bodmer commented Feb 5, 2024

The problem is that both libraries use the SPI port. and maybe the host shield library uses interrupts.

The only way around this is to use separate SPI ports for the display and host board.

@Bodmer Bodmer closed this as completed Feb 5, 2024
@Bodmer Bodmer added the answered label Feb 5, 2024
@Paulsburg
Copy link
Author

Thank you for your answer.

In my case the host shield and the tft are just using different SPI ports pins (VSPI_pins for the TFT_eSPI and HSPI-pins for the host shield).

But you are right, I have not defined to use the HSPI-port. Its still set to VSPI-port. I will try to change and report the result.

@Paulsburg
Copy link
Author

Hi Bodmer,

just uncommenting the <#define USE_HSPI_PORT> in my user_setup.h solved the problem.

Many thanks for your help.

@Bodmer Bodmer added the Solved label Feb 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants