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

tud_cdc_send_break_cb not called when Serial break from MacOS #2003

Closed
1 task done
ulften opened this issue Apr 3, 2023 · 15 comments
Closed
1 task done

tud_cdc_send_break_cb not called when Serial break from MacOS #2003

ulften opened this issue Apr 3, 2023 · 15 comments
Labels

Comments

@ulften
Copy link

ulften commented Apr 3, 2023

Operating System

MacOS

Board

Raspberry Pi Pico

Firmware

issue.zip

What happened ?

I was trying to follow along rumbledethumps picocomputer project using MacOS as host and ran into a problem with sending serial break from Mac host to the Raspberry Py pico running an image containing tinyUSB and picoprobe. I have confirmed that break works fine from a Linux host (and I have been told it also works on Windows). Using a USB to Serial adapter (bypassing tinyUSB and going directly from MacOS to the pico UART also works fine. Hence, I suspect an issue in TinyUSB.

To try and simplify, I modified one of the standard examples that comes with the pico software (hello_usb.c) and built an image that demonstrates the problem. The tud_cdc_send_break_cb() never gets called when connected to a MacOS USB port and using minicom to send the Break (ctrl-A F). Using the python scripts from rumbledethumps exhibits the same issue. But switching to a minicom hosted on Linux works as expected. I have created a mostly empty directory tree with the modified hello_usb.c in ./pico-examples/hello_world/usb and the executables in ./pico-examples/build/hello_world/usb/, hoping that this will enable you to test what I have built, and/or replace the standard hello_usb.c with my modified c file and build your own test.

Thanks,
Ulf

How to reproduce ?

  1. flash the included hello_usb.uf2 on a pico, but connecting the USB cable while holding down the BOOTSEL button on the pico
  2. Open a minicom serial terminal on a Linux host towards the /dev/ttyACM0 with speed 115200
  3. type a few characters into minicom and press . Characters should be printed back on the screen
  4. press ctrl-A F to send a break
  5. Again, type a few characters and press enter
  6. After the characters have been printed back, the message "main: 2 BREAK(s) received!" indicating that the call back has been called. It works on Linux
  7. Repeat the same steps on a minicom from a MacOS. The tty port will probably be called something else on the mac (/dev/tty.usbxxxxx). The character echoing works the same, but the break callback function is never called.

Debug Log as txt file

No response

Screenshots

No response

I have checked existing issues, dicussion and documentation

  • I confirm I have checked existing issues, dicussion and documentation.
@ulften ulften added the Bug 🐞 label Apr 3, 2023
@hathach
Copy link
Owner

hathach commented Apr 4, 2023

  • have you double checked that macOS indeed send out BREAK signal ?
  • please test again with cdc_msc example, you will need to add the break callback to main.c. Since that is what I am always testing with.
  • Also enable debug LOG=2 (CFG_TUSB_DEBUG=2) and post your debug log here (please hightlighted line where BREAK signal is sent if possible).

@ulften
Copy link
Author

ulften commented Apr 4, 2023

Thanks for quick response!

  • you double checked that macOS indeed send out BREAK signal ?

    Yes, by way of a USB to Serial adapter board connected to the UART pins on the pico. This board passes the break from both MacOS and Linux minicom.

  • please test again with cdc_msc example, you will need to add the break callback to main.c. Since that is what I am always testing with.
    

    I have now modified hello.c, adding a callback and printing a BREAK message when detecting a break. Running the cdc_msc example produces the same result as my previous test. Issuing a break from minicom and then typing a character will print my BREAK message in minicom on Linux, but not on MacOS.

  • Also enable debug LOG=2 (CFG_TUSB_DEBUG=2) and post your debug log here (please hightlighted line where BREAK signal is sent if possible).
    

    Here is where my novice level of experience blocks me. I tried adding the flag to both tusb_config.h and running make with LOG=2 but could not see any log output (on the pico uart port). I am so far only able to build the example from the pico-examples/build/usb/device/tinyusb_device_examples/cdc_msc directory. Even though I believe that these use the (c)makefiles from tinyusb, I have not been able to turn on debug logging. In the hope that you can run with my modified main.c in your environment, I am attaching it here.
    cdc_msc.zip

@hathach
Copy link
Owner

hathach commented Apr 5, 2023

Yes, by way of a USB to Serial adapter board connected to the UART pins on the pico. This board passes the break from both MacOS and Linux minicom.

Which Serial Adapter, FTDI/CP2104 using different driver than ACM, you need to double check to see if BREAK is indeed sent over ttyACM (not ttyUSB with other device).

I have now modified hello.c, adding a callback and printing a BREAK message when detecting a break. Running the cdc_msc example produces the same result as my previous test. Issuing a break from minicom and then typing a character will print my BREAK message in minicom on Linux, but not on MacOS.

LOG is required, check out getting started guide to enable it. I can't run and test every scenario, please try to troubleshoot at your end as far as you could first.

@ulften
Copy link
Author

ulften commented Apr 14, 2023

OK, I am back. I have now built the modified cdc-msc example in the tinyusb example tree:

make BOARD=raspberry_pi_pico DEBUG=1 LOG=2 all

with my modified main.c, as attached earlier.

But, alas, not much new to report. The break is detected when connected to /dev/ttyACM0, but not when using MacOS, where there is no /dev/ttyACMx, but the pico usb is seen as /dev/tty.usbserial-0001. Logging over the pico UART does not display anything, so I have nothing more to attach, I'm afraid. I will just move on over to Linux, which is a less desirable host in my case. Thx, Ulf

@Kriechi
Copy link

Kriechi commented Apr 15, 2023

I can report the same issue using macOS 13.3.1: the BREAK is not received:

minicom -D /dev/tty.usbmodem14401
# press Meta+F, which shows a visual indication that claims a BREAK has been sent.

Also tried with a self-written tool that holds the BREAK signal for 1sec -- same issue.

It works just fine on Linux kernel 5.15.

@HiFiPhile
Copy link
Collaborator

@Kriechi Could you please upload log with CFG_TUSB_DEBUG=3
I'm highly doubt BREAK is not sent for ttyACM class under MacOS

@Kriechi
Copy link

Kriechi commented Apr 15, 2023

@HiFiPhile I'm actually "only" running this test via CircuitPython 8.0.5 on an RP2040, though I would be even more surprised if there is some host-platform dependency in this code path: https://github.com/adafruit/circuitpython/pull/7227/files

@HiFiPhile
Copy link
Collaborator

though I would be even more surprised if there is some host-platform dependency in this code path

CDC driver of TinyUSB is compliant to ACM specification, and BREAK works on Windows and Linux. So it sounds like MacOS does something funky.

@Kriechi
Copy link

Kriechi commented Apr 15, 2023

Also broken on macOS 12.6.4.
I tried with both the tty and the cu device types under macOS - same issue in both.

@rumbledethumps
Copy link

rumbledethumps commented Apr 15, 2023

The attached image is from Linux and Windows. MacOS didn't display any CFG_TUSB_DEBUG=3 message when sending a break as such:

import serial
s=serial.Serial('/dev/ttyACM1')
s.sendBreak(100)

good

@hathach
Copy link
Owner

hathach commented Apr 16, 2023

I have the same experience with Bluetooth SPP (rfcomm) on macos, basically it ignores some of cotnrol signals. That is why I suspect that macos does not send BREAK signal to acm device at all. Previously, I monitor it with macos console/log (forgot) for kernel/IO log, you may also want to try it out. Though the easiest way is hooking the usb analyzer to see if the control is actually sent via USB bus. When I have time, I will fire up my old macbook and try to capture its USB bus.

@hathach
Copy link
Owner

hathach commented Mar 13, 2024

I guess we can conclude that macos driver does not send BREAK request.

@hathach hathach closed this as completed Mar 13, 2024
@trejan
Copy link
Contributor

trejan commented Apr 30, 2024

This is likely due to the tinyusb ACM device cap not advertising support for serial break. Linux used to ignore it and always send a break but a recent patch has made it check. Patching usbd.h to add the missing cap bit restores the break functionality.

@HiFiPhile
Copy link
Collaborator

tinyusb ACM device cap not advertising support for line break.

Good finding ! You can make a PR if you want.

@hathach
Copy link
Owner

hathach commented Feb 11, 2025

fixed by #2616

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

No branches or pull requests

6 participants