Skip to content

NXP MCXA156 USB Driver Bugs - usb_dc_kinetis.c does not broadcast SOF events #88981

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

Open
ehughes opened this issue Apr 23, 2025 · 1 comment
Open
Assignees
Labels
area: USB Universal Serial Bus bug The issue is a bug, or the PR is fixing a bug priority: low Low impact/importance bug

Comments

@ehughes
Copy link

ehughes commented Apr 23, 2025

While doing some testing with a very simple USB audio configuration, I found issues with the underlying USB driver implementation with MCXA156 but would affect any platform with the same IP.

I am using the the FRDM MCXA156 as a test platform. I also used an nRF52840DK as a secondary test platform to validate my test program.

Bug Description:

This is focused on an USB audio, but I think there is an underlying issue with the USB driver implemenation for MCX A. The USB Audio example just helps show the issue.

Setup:

Project:

yoshi.zip

I modified the microphone_headset example to only have 1 single channel microhone. 16-bit 8KHz. I am generating a known, fixed data pattern for testing.

I am using Audacity to do a test record to valid the data stream.

Issue:

A.

If appears that USB SOF events are not being correctly broadcast on MCXA to the device class handlers.

For a USB microphone, there is data request callback that can be registered. This should align to the SOF.

On MCX A, it never fires. I places a volatile test variable in the handler in never increments when I start a recording.

However, on other platforms (such as the nRF52), this works as expected. the requests variable incremenets. I monitor the variable using the Segger Ozone Debugger.

static void data_request(const struct device *dev)
{
    /*
        Ideally, we want to to do our Tx here, not in the main loop.

        This never fires on MCXA
    */
    requests++;
}

static const struct usb_audio_ops mic_ops = {.feature_update_cb = feature_update,
                                             .data_written_cb   = mic_data_sent,
                                             .data_request_cb   = data_request};

B.)

To get data moving on MCXA and see what is going on, I created a simple test in the main loop:

      k_sleep(K_MSEC(1));

       usb_buf = net_buf_alloc(&usb_pool, K_MSEC(1));

       for (int i = 0; i < USB_TX_LEN; i++)
       {
           net_buf_add_le16(usb_buf, (sine_table[idx]));

           idx++;
           if (idx >= 32)
               idx = 0;
       }

       send_status = usb_audio_send(mic_dev, usb_buf, USB_TX_BUF_SIZE);

       if (send_status)
       {
           // Deallocate the buffer if there is an error as we won't get the tx callback
           net_buf_unref(usb_buf);
       }

This is not the ideal place to do this, but it helps show the issue.

The MCXA156 version will partially work. I can start a recording, see correct data. However, if I stop and restart, the underlying USB driver will lock up.

Note: This code also works fine on my reference platform (nRF52)

I disable optimizations and enabled the thread monitor so I could see the issue.

There is a USB servicing thread for the kinetis_dc driver and I can see it sometimes get locked up here:

Image

It is stuck in the while loop and there is no timeout, etc.

I also see it get stuck here:

Image

The usb audio class handler doesn't handle this error condition (but is the subject of another bug report)

Image

All of the behavior seems related to A. There is nothing that can ever reset the state of the buffer desciptors / ownership if the underlying SOF callbacks aren't working. It isn't even possible to know when to transmit audio as most USB audio implementations from device to host use SOF

I set a breakpoint on audio_dc_sof and it is never called. After searching through usb_dc_kinetis.c, it does not appear that SOF has ever been handled.

This problem is easy to trigger. You just need to start/stop recording a few times.

On the reference platform, the attach code works fine (I can record, start/stop at will and I get the SOF callback

I think solving A will solve B. However, I do think the driver should have some timeouts, etc and never spin indefinitely.

I am working from the main branch of Zephyr. commit hash c2c3f75

@ehughes ehughes added the bug The issue is a bug, or the PR is fixing a bug label Apr 23, 2025
@ehughes ehughes changed the title NXP MCXA156USB Driver Bugs - usb_dc_kinetis.c does not broadcast SOF events NXP MCXA156 USB Driver Bugs - usb_dc_kinetis.c does not broadcast SOF events Apr 23, 2025
@ehughes
Copy link
Author

ehughes commented Apr 23, 2025

Some more details:

I was able to patch in SOF support

by adding this to the usb_kinetis_irq_handler:

	if (istatus & USB_ISTAT_SOFTOK_MASK) {
		msg.ep = 0U;
		msg.cb = USB_DC_SOF;
		k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
	}

and a case handler in usb_kinetis_thread_main:

			switch (msg.cb) {
			case USB_DC_SOF:
				dev_data.status_cb(USB_DC_SOF, NULL);
				break;
			case USB_DC_RESET:
				dev_data.status_cb(USB_DC_RESET, NULL);
				break;

This allows the data_request audio handler to work, but the initial issue remains. Once a recording starts and then stops, the driver will lock

I also found

case USB_DC_ERROR: dev_data.status_cb(USB_DC_ERROR, NULL); errors++;

appeared to be called every other transfer on the 1st recording. I traced it back to this:

	if (istatus == USB_ISTAT_ERROR_MASK) {
		error_stat = USB0->ERRSTAT;
		USB0->ERRSTAT = 0xFF;
		msg.ep = 0U;
		msg.type = USB_DC_CB_TYPE_MGMT;
		msg.cb = USB_DC_ERROR;
		k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
	}

in the IRQ handler. I added the error_stat variable.

It is constantly being set to 0x40

Image

This feels like there there is still some underlying issue w/ this driver.

@henrikbrixandersen henrikbrixandersen added the area: USB Universal Serial Bus label Apr 25, 2025
@danieldegrasse danieldegrasse added the priority: low Low impact/importance bug label Apr 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: USB Universal Serial Bus bug The issue is a bug, or the PR is fixing a bug priority: low Low impact/importance bug
Projects
None yet
Development

No branches or pull requests

5 participants