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

Printer demo needs a little further help #2

Open
ralphrmartin opened this issue Jun 14, 2022 · 5 comments
Open

Printer demo needs a little further help #2

ralphrmartin opened this issue Jun 14, 2022 · 5 comments

Comments

@ralphrmartin
Copy link

With the printer demo, it seems if you try to print just a fixed string like "hello world" instead of a line read from Serial, the program crashes, because PrinterOut is a null pointer.

I guess some extra logic is needed to check for PrinterOut being null, and it would be most instructive and helpful if you could add this.

Or perhaps a better approach would use some callback to tell when the printer is ready to accept data?

@touchgadget
Copy link
Owner

With the printer demo, it seems if you try to print just a fixed string like "hello world" instead of a line read from Serial, the program crashes, because PrinterOut is a null pointer.

PrintOut is initialized as follows so is not NULL.

    err = usb_host_transfer_alloc(endpoint->wMaxPacketSize*PRINTER_OUT_BUFFERS, 0, &PrinterOut);
    if (err != ESP_OK) {
      PrinterOut = NULL;
      Dbg_printf("usb_host_transfer_alloc Out fail: %x", err);
      return;
    }

The following is a an older version of the program that prints "Hello" instead of reading from terminal.

@ralphrmartin
Copy link
Author

ralphrmartin commented Jun 15, 2022

"The following" seems to be missing...

Maybe there is a race condition?
I was trying this on an ESP32S3 and v 3.0.2 of the Arduino ESP32 package.

If I use this modification of the loop, printing basically works, but if I leave out the test for PrinterOut being Null, the program just crashes with an illegal memory access exception and restarts, over and over again.

int times = 0;

void loop()
{
  usbh_task();
  
  if ( (PrinterOut != NULL) && (times < 5) ) {
    String aLine = String(times)+"\n";  // Read line ending with newline
    Serial.printf("%d\n",times);
    // readStringUntil removes the newline so add it back
    PrinterOut->num_bytes = aLine.length();
    memcpy(PrinterOut->data_buffer, aLine.c_str(), PrinterOut->num_bytes);
    esp_err_t err = usb_host_transfer_submit(PrinterOut);
    if (err != ESP_OK) {
      ESP_LOGI("", "usb_host_transfer_submit Out fail: %x", err);
    }
    times++;
  } 
}

@touchgadget
Copy link
Owner

@ralphrmartin
Copy link
Author

I note that older version also has a test (PrinterOut != NULL) in it. My example is pretty much the same, except that it prints several lines using a counter, rather than a Boolean flag. If you remove the test for PrinterOut being Null, your old program also crashes.

It seems that, from start up, it takes a time for PrinterOut to become non-Null, and essentially, we must wait for this before trying to print.

@touchgadget
Copy link
Owner

Of course, there must be a check for NULL. The printer may be unplugged on power up. The Arduino sketch runs as a freeRTOS task. The USB host stack is interfaced with another task. If you like, you can create semaphores to sync the tasks.

Prerequisite: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/peripherals/usb_host.html

The ESP-IDF has USB host examples using one more task for the client/class driver and semaphores to sync main, usb host lib task, and usb client/class tasks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants