This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

usbd_hid_composite not working on Mac?

Hi
my USB keyboard application works on Windows and Linux but not on a MacBook Air with
macOS Sierra 10.12.6. So I did step back and tried the combined HID example
nRF5_SDK_16.0.0_98a08e2/examples/peripheral/usbd_hid_composite/hex/usbd_hid_composite_pca10056.hex
with md5sum 6ffe5856a45b765a6ecf10ec0e348cdc
surprise: it does not work either

what I did:
flash the example hex file on PCA10056  version 2.0.1
connect the board to the MacBook Air

result:
mouse works perfectly as expected
keyboard is visible in the OS settings dialog for keyboards
no reaction at all on button3 (SHIFT) and button4 (letter G)
unexpected behaveour of LED3  - the picture below shows the LED timing on an oscilloscope:
stable for about 20ms then 4 toggles in row

led3 toggle timing

I look at the code and from this point I'm guessing:
the LED might get inverted in APP_USBD_HID_USER_EVT_OUT_REPORT_READY
is the OS asking for information?
or trying to discover the type of the keyboard by provoking a reaction (which is not delivered by the example code)?

I'm aware that the OS does not recognize the type of the keyboard and it asks me to press the button right of LEFT-SHIFT.
This button might be 'Z' on an standard US keyboard or the additional "NON-US-KEY" (keycode 100 decimal) on non-US keyboards.
The DevKit is not a real keyboard so I can't press this key and I skip this step and set the european keyboard type later manually.
But this does not help - the keyboard part of the DevKit example is still stuck.

I'm new to USB and HID. And I don't know how to low level debug USB/HID on a Mac.
So I tried comparing USB descriptors of the example with a Holtek keyboard which works fine.
But I couldn't find a notable difference.
Just one detail - it could be a hint or spurious neglectable glitch:
when I compared descriptors on Linux I saw an empty (all zeroes) IN report coming from the Holtek keyboard at the beginning.
I didn't expect this report and I don't know if I should pay attention to it.

question:
are you able to reproduce the problem connecting the composite HID example to a Mac?

despite searching forums a lot I have no clue yet what to look for.
suggestions are welcome - for example: should I dive into USB spec to find if an OS can ask questions to a keyboard and the example does not cover this dialog?

best regards
Peter

  • Hi Einar

    do you get the same result?
    The usbd_hid_composite example from SDK 14 works fine with macOS.
    The same example from SDK 15 fails.

    best regards
    Peter

  • Hi Peter,

    I am sorry for the late reply. Yes, I get the same results. The example from SDK 14 works (including 14.2). I am not close to properly understanding the issue, though.

    Br,

    Einar

  • Hi Einar

    the results I get make me think of timing and race conditions. I would like to add some debug output messages with high resolution timestamps. What can I use as reference timer, is there something like System.getTimeMicroseconds() ?

    best regrads
    Peter

  • Hi Peter,

    peterz said:
    the results I get make me think of timing and race conditions. I would like to add some debug output messages with high resolution timestamps.

    That seems sensible.

    peterz said:
    What can I use as reference timer, is there something like System.getTimeMicroseconds() ?

    The easiest is to use the RTC, and just start it and read the COUNTER register to get a timestamp. However, this is only 32.768 kHz. Since the example already uses the app_timer, all you need to do in this case is to modify sdk_config.h so that APP_TIMER_CONFIG_RTC_FREQUENCY is 0 (to get a higher accuracy), and set APP_TIMER_KEEPS_RTC_ACTIVE to 1. Then you can call app_timer_cnt_get() to get the counter value.

    If you need higher accuracy than what you get with the RTC, then you must use a TIMER. In that case, you cannot read the counter register directly, so you need to capture it to a CC register, and read it from there.

    Einar

  • Hi Einar

    the code in SDK 16 compared to SDK 14 is a complete rewrite, adding timestamp makes little sense.

    I compiled usbd_hid_composite example from nRF5_SDK_16.0.0_98a08e2 modifying sdk_config.h to get RTT debug output. Below to find the debug output when I connect to Windows 8.1, Linux, MacBook.

    The sequences are quite different, depending on OS. Looking at the code I'm surprised most of the seuqnece
    APP_USBD_EVT_DRV_RESET
    APP_USBD_EVT_DRV_RESET
    APP_USBD_EVT_DRV_RESET
    APP_USBD_EVT_DRV_RESET
    APP_USBD_EVT_DRV_RESET
    APP_USBD_EVT_STATE_CHANGED
    APP_USBD_EVT_STATE_CHANGED
    is this the consequence of (unwanted?) recursion?

    usbd_core_state_set(app_usbd_state_t state) does more than it says

    I'm stuck on this for 2 weeks now and the more I dig into it the less I think this is a Mac issue.
    Peter

    here comes the debug RTT output when I just connect the devkit (no buttons pressed)

    debug output when plugged into Windows 8.1
    00> <info> app: USBD HID composite example started.
    00> <info> app: enter main loop
    00> <info> app: USB power detected
    00> <info> app: USB ready
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: usbd_user_ev_handler STARTED
    00> <info> app: usbd_user_ev_handler SUSPEND
    00> <info> app: usbd_user_ev_handler RESUME
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_DRV_RESET
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_DRV_RESET
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_DRV_RESET
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: hid_kbd_user_ev_handler OUT report


    debug output when plugged into a Linux machine
    00> <info> app: USBD HID composite example started.
    00> <info> app: enter main loop
    00> <info> app: USB power detected
    00> <info> app: USB ready
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: usbd_user_ev_handler STARTED
    00> <info> app: usbd_user_ev_handler SUSPEND
    00> <info> app: usbd_user_ev_handler RESUME
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_DRV_RESET
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_DRV_RESET
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: hid_kbd_user_ev_handler OUT report


    debug output when plugged into a old, slow MacBook Air with El Capitan
    00> <info> app: USBD HID composite example started.
    00> <info> app: enter main loop
    00> <info> app: USB power detected
    00> <info> app: USB ready
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: usbd_user_ev_handler STARTED
    00> <info> app: usbd_user_ev_handler SUSPEND
    00> <info> app: usbd_user_ev_handler RESUME
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_DRV_RESET
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: usbd_user_ev_handler SUSPEND
    00> <info> app: usbd_user_ev_handler RESUME
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_DRV_RESET
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_DRV_RESET
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_DRV_RESET
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_DRV_RESET
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_DRV_RESET
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: usbd_user_ev_handler APP_USBD_EVT_STATE_CHANGED
    00> <info> app: hid_kbd_user_ev_handler IN report
    00> <info> app: hid_kbd_user_ev_handler IN report
    00> <info> app: hid_kbd_user_ev_handler IN report
    ......... same line repeated many times per second .......

Related