Skip to content

Add support for multichannel, CAN-FD, and STM32G4#176

Open
pgreenland wants to merge 56 commits into
candle-usb:masterfrom
pgreenland:multichannel
Open

Add support for multichannel, CAN-FD, and STM32G4#176
pgreenland wants to merge 56 commits into
candle-usb:masterfrom
pgreenland:multichannel

Conversation

@pgreenland

Copy link
Copy Markdown
Contributor

Picked up where @marckleinebudde left off.

Resolved the performance issue, which appeared exactly as @fenugrec had described in his comment.

Added support for the STM32G4, specifically the Makerbase MKS Canable2 (which presumably is based on the canable.io Canable 2.0, although I couldn't find a schematic for the canable.io to compare). A bit of scope creep granted, my goals were support for this board and improved performance for my G0 board.

Followed @fenugrec 's tests using:

cangen can1 -g 0 -p 10 -L 0 -I 0x555
canbusload can0@1000000 -e

Along with the following for canfd as canbusload doesn't support fd frames at present:

candump can0 | pv --line-mode --rate --average > /dev/null

Have tested with an F0 based board (DSD_TECH_SH_C30A_fw), G0 based board (my own dual channel adapter) and a G4 based board (CANable2_MKS_fw). Couldn't find anything with an F4 on to test with unfortunately. Although there's only a dev board listed, so may not be too much of an issue?

For reference details of my G0 based adapter can be found on my blog, and board files on a separate branch.

Tested TX and RX performance for each unit, with the same PC/USB controller (and port). Communicating with a Peak PCAN-FD USB adapter, using Linux 6.1.0 on Debian.

Performance is as follows (in frames per second):

MCU CAN 2.0 Mode CAN 2.0 TX CAN 2.0 Mode CAN 2.0 RX CAN FD Mode CAN 2.0 TX CAN FD Mode CAN 2.0 RX CAN FD Mode CAN FD TX CAN FD Mode CAN FD RX
F0 19700 20000 NA NA NA NA
G0 19000 20800 9500 20800 6740 9520
G4 20300 20800 9310 20800 7000 10500

The poor / variable performance in CAN FD mode appears to be partly down to how the gs_usb driver in the Linux kernel behaves.

The MCU (on Linux) during RX sends an appropriately sized frame (either a classic or FD depending on the payload).
As such CAN2.0 RX performance is maintained regardless of operating mode.

The linux driver, in FD mode, appears to always sends FD sized frames, even for CAN2.0 frames, see: https://elixir.bootlin.com/linux/v6.1/source/drivers/net/can/usb/gs_usb.c#L778

The performance issue was found to be the error frame generation. Although it isn't fully clear how its changed the performance so significantly when compared to the master branch. I stopped short of reading through assembly.

Given the main loop coordinates both USB and CAN, I added a simple loop iteration counter. Measuring the number of iterations of the main loop performed per second. I did this on the F0 which is supported by both branches.

multichannel main loop iterations per second
with error checking 121156
without error checking 229495

master main loop iterations per second
with error checking 137564
without error checking 242311

It appears that retrieving a frame from the free pool, partially preparing before usually discarding an error frame on each iteration of the loop is quite time consuming.

As the error parsing / frame generation code looked fairly tidy and tricky to split, I've opted to only run it when there's a change in the controller error status register, for which it might want to generate an error frame.

For the G0 and G4 families I've also added bus-off recovery. Unlike the F0's bx_can module, the m_can module will not perform automatic bus-off recovery. Requiring software to detect its fallen back into initialisation mode in response to bus-off and request it advance back into normal mode. Passed the highly advanced screwdriver between CAN L/H after that.

Found one slightly issue which I haven't been able to resolve with the G4 yet. It has problems with the double buffered USB endpoint used for CAN transmission. It performs as expected in CAN2.0 mode but confuses the kernel in CAN FD mode, eventually causing the gs_usb driver to freeze and stop transmitting (due to its 10 echo IDs being exhaused). Switching it to single buffered mode solves the issue, without a notable performance decrease. I've left double buffering enabled for the other targets which don't appear to suffer from whatever's happening in the stack/hw.

marckleinebudde and others added 30 commits October 20, 2023 22:17
The USBD_GS_CAN_SendToHost() function is used to send to struct
gs_host_frame_object to the host.

Until this patch, after the sending process has been started, the
outgoing frame object is already added to the list of free objects and
the variable USBD_GS_CAN_HandleTypeDef::TxState is used to track if
the transfer to the host is in progress.

Instead, hold the outgoing object in
USBD_GS_CAN_HandleTypeDef::to_host_buf and move it to the free list
after the transfer is finished in USBD_GS_CAN_DataIn(). Use this to
track if a transfer is ongoing.
Add code to support the M_CAN core found on the newer STM32 devices.

Co-developed-by: Ryan Edwards <ryan.edwards@gmail.com>
Co-developed-by: Jonas Martin <j.martin@pengutronix.de>
Co-developed-by: Venelin Efremov <ghent360@iqury.us>
Co-developed-by: Phil Greenland <phil@beamconnectivity.com>
Co-developed-by: Marc Kleine-Budde <mkl@pengutronix.de>
@TheFrog4u

TheFrog4u commented Oct 16, 2025

Copy link
Copy Markdown

Hello, I did some simple testing with this firmware, but run into issues. I am using MKS canable 2 Pro. Compiling, flashing, and configuring worked apparently fine. My problem: Receiving frames with candump works, but sending does not:

$ dmesg -T
[Do Okt 16 14:43:15 2025] usb 1-4: new full-speed USB device number 23 using xhci_hcd
[Do Okt 16 14:43:16 2025] usb 1-4: New USB device found, idVendor=1d50, idProduct=606f, bcdDevice= 0.00
[Do Okt 16 14:43:16 2025] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[Do Okt 16 14:43:16 2025] usb 1-4: Product: CANable2-MKS gs_usb
[Do Okt 16 14:43:16 2025] usb 1-4: Manufacturer: CANable2-MKS
[Do Okt 16 14:43:16 2025] usb 1-4: SerialNumber: 002D004B4D4D501220383834
[Do Okt 16 14:43:16 2025] gs_usb 1-4:1.0: Configuring for 1 interfaces
[Do Okt 16 14:43:16 2025] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready

$ sudo ip link set down can0
$ sudo ip link set can0 type can bitrate 250000
$ sudo ip link set up can0

$ cansend can0 000#0301
write: No buffer space available

It gets more confusing: I actually got it working if I had another gs_usb compatible device (for example MKS canable 2.0 with the old firmware from canable.io (available only in binary)) connected before and than replace it with CANable2-MKS_fw on it. So, if you have can0 working it will continue to work. But if you update the USB adapter with this firmware, it will stop working after a reboot or usbreset.

sudo usbreset 1d50:606f
sudo ip link set down can0
sudo ip link set can0 type can bitrate 250000
sudo ip link set up can0

Now, candump receives frames, cansend will not work anymore and I also see this error in dmesg:

$ dmesg -T
[Do Okt 16 15:55:28 2025] usb 1-4: reset full-speed USB device number 23 using xhci_hcd
[Do Okt 16 15:55:28 2025] gs_usb 1-4:1.0: Configuring for 1 interfaces
[Do Okt 16 15:55:28 2025] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 9
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 8
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 7
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 6
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 5
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 4
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 3
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 2
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 1
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 0

I tried linux kernel 5.15 and 6.12. I also tried #define CONFIG_CANFD 0 in config.h -> BOARD_CANable2_MKS, without success. Is there anything I need to do differently in ifupdown? Because this error doesn't show up when another gs_usb device was connected and working before it might have something to do how gs_usb is initialized in this fw?

EDIT: I also have tried this branch with MKS canable 1.0 (CANable_MKS_fw) and don't see this issue (usbreset and bring it back works fine)

@pgreenland

Copy link
Copy Markdown
Contributor Author

@TheFrog4u Looking back at my emails I created the CANable2_MKS_fw target based on a board from AliExpress that a reader of my website had requested. At the time I tested it with Linux 6.1 and it was seemingly working fine and performing well.

For your particular error, agreed thats very strange, its not something I've seen before.

You should probably treat this PR as abandoned, I invested a lot of time in it at the time, testing the various STM families I had to hand, only for it to sit.

I believe @marckleinebudde 's has continued on his branch. You should be able to port the CANable2_MKS_fw target across quite easily. He also maintains the gs_can kernel driver, so would be in a better position to advice on how you might debug.

I've been using my STM32G0 based dual channel board on and off since creating it without any issues based on this PR, currently using an Ubuntu provided 6.8 kernel. I've had no need to make any further changes to it.

Day to day, the CAN FD enabled projects I've been working on for customers are making use of the higher bandwidth of CAN FD. As such the USB full speed 12Mbit link has become a major bottleneck and my adapter doesn't see all that much use anymore. It's been replaced by a couple of Peak System PCAN-USB FDs.

If I was to pickup development on this again, I'd be looking to switch to an STM32 family with USB high speed. Along with getting the hardware RX timestamping in, which I saw floating around a while ago. This is something I use frequently with the peak to check periodic transmissions are meeting their expected timings.

Sorry I can't be of more assistance.

@ryedwards

Copy link
Copy Markdown
Contributor

I'll add on because I haven't participated in a while.

I can confirm everything @pgreenland has said about the CANFD + USBFS troubles. We ran into the same issue - not as much with the 12Mbps as much as the 1ms USB SOF rate limit. Not sure why STM32 didn't have the foresight to add internal HS PHY to their CANFD silicon. Assume that CANFD is not one of their main business cases (NXP, Renesas and Infineon are the defacto automotive uC suppliers). Also, most higher level tools use FPGAs to handle CAN.

There are no STM32 chips that support CANFD + USBHS internal PHY. The H5/H7 have parts that support external ULPI PHY but almost all of them you lose a CANFD channel when you enable the ULPI pins. The amount of work that would go into implementing HS and CANFD on the STM32 wasn't worth the effort for me. My other plan was to use the RMII Ethernet MAC as my host connection. Issue there is that I'd need to write my own driver. Again, not worth the effort given the other tools on the market that already have drivers.

If you really want CANFD + USBHS the best option is an Atmel SAME70 or iMXRT (Teensy). They support CANFD plus an internal HSPHY. Not sure if any of them have GS-USB ports out there. The Atmel HAL is a joke, though, and wouldn't touch that with a 10ft pole. We have one internal tool that uses it and I spent months battling the HAL and the total lack of documentation. I think the zephyr project has some discussions on a gsusb port (zephyrproject-rtos/zephyr#75207).

Also, the HW timestamp for the STM32 is laughable. It's 16-bit so I haven't tried to do anything to create a secondary wider timer. Most 3rd party tools have 32 or even 64 bit timestamps.

I still use the G0 and G4 for simple tools that don't need to handle high bus loading. Good for diagnostics and busses that are just CAN2.0.

Hope these points help.

@pgreenland

Copy link
Copy Markdown
Contributor Author

@ryedwards Super helpful! I hadn't considered an Ethernet connected adapter until now.....if there was some way to integrate it with socketcan, especially on multiple machines at once that would be the dream. I suppose some sort of host application / SLCAN monstrosity might get it off the ground. Unless a tame kernel developer can be sold the dream too.

Part of my attraction to the candlelight project was the low cost of entry for the hardware. Paying over £300 in the UK for each FD adapter feels like highway robbery, had it not been for work I wouldn't have touched them. For general CAN 2.0 / hobbyist FD use the project still holds a lot of potential.

You've also saved me from the rabbit hole of pin mappings. I've been working on an H7 based project with dual CAN FD and Ethernet at present....I'm amazed I hadn't considered the connection....although had scrolled past the high speed usb section in the manual.

An Ethernet connected adapter might be easier to use from Windows too....gs_can and libusb sounded like a less than fun combination. You could fit 23 FD payloads in a UDP packet....ignoring any headers.

I think I feel a weekend project coming on......time to crash the Linux kernel, I mean....write a new can driver 😅

@TheFrog4u

TheFrog4u commented Oct 23, 2025

Copy link
Copy Markdown

@SebKuzminsky

Failure to boot after a short power cycle

For this i have the firmware flashed on the device and its working well. Unplug USB and reconnect it quickly, < 2 seconds of downtime, and it comes up in bootloader mode (0483:df11). Unplug USB and leave it disconnected for > 3 seconds and it boots the candleLight firmware. This behavior is totally repeatable.

Any thoughts on what's going on here? I'd really like to be able to boot into new firmware right after flashing, and i'd like the device to boot even after a very brief power loss.

Going into boot/dfu mode after short power cycle is a hardware issue in canable2. CAN Rx and Boot0 are the same pin: schematic
I have no idea why they did that, though. According to STM32G431 datasheet there are alternatives that could have been chosen for CAN Rx.

I studied the datasheet and there is a workaround for this issue: You can disable boot function of the PB8-Boot0 pin by setting nBOOT_SEL. When cleared (0), it enables the BOOT0 pin to control the boot mode. When the bit is set (1), it forces the boot mode to be controlled by the BOOT1 option bit and the BOOT0 pin is ignored.

Apparently you can do that with STM32Cube or modifying the firmware. (Also Canable 2.5 has this feature implemented with a special protocol).

To add this to candlelight_fw for this device is probably only a few lines of code but I actually have no idea how to do it (no experience with stm32, I am here for the CAN ) - maybe someone could help me with a code snippet?

Edit: Found an example how to disable BOOT0 pin: See function system_set_option_bytes() here

You should still be able to go into bootloader / dfu mode using dfu-util. I think most people don't know this, but if you have gs_usb compatible firmware running on the device you can do:

#list dfu compliant devices
sudo dfu-util -l

#detach device and jump to boot/dfu mode
sudo dfu-util -e

With that "trick" you can go from normal operation to flashing and back without even touching the device. No setting of boot jumper required (does not work for slcan).

If the device doesn't come back after flashing it is most probably a firmware bug. Worked fine with me when running cable.io precompiled candlelight_fw and than flashing Canable 2.5 firmware.

marckleinebudde added a commit to marckleinebudde/CANable-2.5-firmware-Slcan-and-Candlelight that referenced this pull request Oct 26, 2025
marckleinebudde added a commit to marckleinebudde/CANable-2.5-firmware-Slcan-and-Candlelight that referenced this pull request Oct 26, 2025
barrenechea pushed a commit to barrenechea/CANable-2.5-firmware-Slcan-and-Candlelight that referenced this pull request Nov 3, 2025
barrenechea pushed a commit to barrenechea/CANable-2.5-firmware-Slcan-and-Candlelight that referenced this pull request Nov 3, 2025
marckleinebudde added a commit to marckleinebudde/CANable-2.5-firmware-Slcan-and-Candlelight that referenced this pull request Nov 18, 2025
@chris-dahlberg

chris-dahlberg commented Nov 18, 2025

Copy link
Copy Markdown

@TheFrog4u

So, if you have can0 working it will continue to work. But if you update the USB adapter with this firmware, it will stop working after a reboot or usbreset.

sudo usbreset 1d50:606f
sudo ip link set down can0
sudo ip link set can0 type can bitrate 250000
sudo ip link set up can0

Now, candump receives frames, cansend will not work anymore and I also see this error in dmesg:

$ dmesg -T
[Do Okt 16 15:55:28 2025] usb 1-4: reset full-speed USB device number 23 using xhci_hcd
[Do Okt 16 15:55:28 2025] gs_usb 1-4:1.0: Configuring for 1 interfaces
[Do Okt 16 15:55:28 2025] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 9
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 8
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 7
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 6
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 5
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 4
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 3
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 2
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 1
[Do Okt 16 15:59:11 2025] gs_usb 1-4:1.0 can0: usb xmit fail 0

I tried linux kernel 5.15 and 6.12. I also tried #define CONFIG_CANFD 0 in config.h -> BOARD_CANable2_MKS, without success. Is there anything I need to do differently in ifupdown? Because this error doesn't show up when another gs_usb device was connected and working before it might have something to do how gs_usb is initialized in this fw?

EDIT: I also have tried this branch with MKS canable 1.0 (CANable_MKS_fw) and don't see this issue (usbreset and bring it back works fine)

I've been using firmware from something that should be pretty similar to this PR's and think I can explain this. It doesn't handle USB resets correctly and will stop processing incoming transfers on the bulk endpoint from the USB host after the 2nd reset.

void USBD_GS_CAN_SendReceiveFromHost(USBD_HandleTypeDef *pdev)
{
	USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*)pdev->pClassData;

	if (	(	 (!hcan->to_host_buf && !list_empty(&hcan->list_to_host))
		 	  || (!hcan->from_host_buf && !list_empty(&hcan->list_frame_pool))
	   		)
		 && (pdev->dev_state == USBD_STATE_CONFIGURED)
	   ) {
		// Either nothing being transmitted and frames queued for transmit
		// Or nothing being received and frames queued for receive
		// But the device is fully configured
		bool was_irq_enabled = disable_irq();
		StartNextTransmit(pdev);
		StartNextReceive(pdev);
		restore_irq(was_irq_enabled);
	}
}
...
static void StartNextReceive(USBD_HandleTypeDef *pdev)
{
	USBD_GS_CAN_HandleTypeDef *hcan = (USBD_GS_CAN_HandleTypeDef*)pdev->pClassData;

	if (!hcan->from_host_buf) {
		// Grab a buffer for the next frame from the pool.
		hcan->from_host_buf = list_first_entry_or_null(&hcan->list_frame_pool,
													   struct gs_host_frame_object,
													   list);
		if (hcan->from_host_buf) {
			// Remove buffer from queue
			list_del(&hcan->from_host_buf->list);

			// Get ready to receive from the USB host into it.
			USBD_GS_CAN_PrepareReceive(pdev);
		} else {
			// gs_can has no way to drop packets. If we just drop this one, gs_can
			// will fill up its queue of packets awaiting ACKs and then hang. Instead,
			// wait to call PrepareReceive until we have a frame to receive into.
		}
	}
}

This is called from the main loop and starts new USB transmit/receives whenever the previous one has finished and there's more to send/free buffers available to receive into.

Coming up from a power-on reset, hcan->from_host_buf is initially null, so it gets past the if and starts the first receive once USB is configured, so everything is fine.

On subsequent USB resets, the reset handling from the ISR leaves the endpoint set to NAK all transmissions and from_host_buf is non-null from the pre-reset code. Nothing will ever call USBD_GS_CAN_PrepareReceive(), which is the thing that would normally switch the endpoint status from NAK to VALID after setting up from_host_buf. The board sends NAK ('I'm temporarily busy, try again later') replies to linux whenever it's given a CAN frame to send.

In master in this repository, the code handling the buffers has changed a lot since this PR was forked and it doesn't have the problem anymore. If you're using the PR code for something and just want to fix it in that context, you can edit in USBD_GS_CAN_DeInit() to free any from_host_buf that was previously set up right after the endpoints are switched to DISABLED

static uint8_t USBD_GS_CAN_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
	UNUSED(cfgidx);

	USBD_LL_CloseEP(pdev, GSUSB_ENDPOINT_IN);
	USBD_LL_CloseEP(pdev, GSUSB_ENDPOINT_OUT);

	USBD_GS_CAN_HandleTypeDef* hcan = (USBD_GS_CAN_HandleTypeDef*)pdev->pClassData;
	if (hcan->from_host_buf != NULL)
	{
		const bool was_irq_enabled = disable_irq();
		list_add_tail(&hcan->from_host_buf->list, &hcan->list_frame_pool);
		hcan->from_host_buf = NULL;
		restore_irq(was_irq_enabled);
	}

	return USBD_OK;
}

It probably doesn't come up for most people because most adapters are bus powered, so unplugging will do a power-on-reset anyway, so it will work unless the host is specifically resetting and reconfiguring more than once without unplugging

marckleinebudde added a commit to marckleinebudde/CANable-2.5-firmware-Slcan-and-Candlelight that referenced this pull request Nov 19, 2025
@rdecarreau

Copy link
Copy Markdown

Jumping in here. I recently found the canable 2.0 dongle and also would love to use this (or actually we're going to design our own similar to what @pgreenland did) because we spend a fortune on the $350 CAN-FD dongles.

I just flashed this branch to the G4 and it's working great, we have very low bus load today but my company would love to continue using this solution. Let me know if I can be helpful, otherwise I will be here anxiously awaiting.

@rdecarreau

Copy link
Copy Markdown

A few more details on my setup, we use CAN-FD with nominal rate of 1Mbps and dbitrate of 5Mbps. With this build I can plug into my host and it shows up as a socketcan interface with no issue (so far).

@DanielT

DanielT commented Nov 28, 2025

Copy link
Copy Markdown

I rebased this branch to current master (https://github.com/DanielT/candleLight_fw/tree/stm32g4_canable_20)
It works very well for me

@rdecarreau

Copy link
Copy Markdown

This PR is pretty big, and it's somewhat important to me now. I also found the bug that @chris-dahlberg found and I think can get it into a state where it no longer sends messages; even without a usbreset.
@marckleinebudde @pgreenland any chance we can get this some attention? I might be able to have my team help but it will take time to ramp.

@marckleinebudde marckleinebudde changed the title Add support for multichanne, CAN-FD, and STM32G4 Add support for multichannel, CAN-FD, and STM32G4 Jan 20, 2026
@spnda

spnda commented Mar 20, 2026

Copy link
Copy Markdown

I wanted to use this fork for a custom STM32G0B1 based board I made. However, I cannot get the USB communication to work, at all. I looked into the communcation with Wireshark and I can see that all GET DESCRIPTOR responses are all Protocol error (-EPROTO) (-71) and 0 bytes of data are returned from the STM. Has anybody encountered anything like this before?

The output from dmesg:

[ 7930.136677] usb 1-2: new full-speed USB device number 89 using xhci_hcd
[ 7930.255960] usb 1-2: device descriptor read/64, error -71
[ 7930.479736] usb 1-2: device descriptor read/64, error -71
[ 7930.697699] usb 1-2: new full-speed USB device number 90 using xhci_hcd
[ 7930.817721] usb 1-2: device descriptor read/64, error -71
[ 7931.039690] usb 1-2: device descriptor read/64, error -71
[ 7931.144786] usb usb1-port2: attempt power cycle
[ 7931.523687] usb 1-2: new full-speed USB device number 91 using xhci_hcd
[ 7931.523780] usb 1-2: Device not responding to setup address.
[ 7931.728755] usb 1-2: Device not responding to setup address.
[ 7931.936675] usb 1-2: device not accepting address 91, error -71
[ 7931.936759] usb 1-2: WARN: invalid context state for evaluate context command.
[ 7932.048735] usb 1-2: new full-speed USB device number 92 using xhci_hcd
[ 7932.048823] usb 1-2: Device not responding to setup address.
[ 7932.256920] usb 1-2: Device not responding to setup address.
[ 7932.464768] usb 1-2: device not accepting address 92, error -71
[ 7932.464861] usb 1-2: WARN: invalid context state for evaluate context command.
[ 7932.464937] usb usb1-port2: unable to enumerate USB device

I tried a bit of debugging of the firmware myself and as far as I can tell everything is in order. The only thing that stood out to me was how none of the callbacks passed to the USBD_Init function are being called. I will admit, however, that I am wildly inexperienced with USB and therefore cannot really judge this well. Not even sure if it's related to the PR or not. In my opinion it's sad that this PR has been open for so long even though I think the proposed changes, conceptually at least, are good and it creates quite a bit of confusion for somebody looking for firmware for their custom board.

@marckleinebudde

marckleinebudde commented Mar 20, 2026

Copy link
Copy Markdown
Collaborator

Hey @spnda,

please try my multichannel branch https://github.com/marckleinebudde/candleLight_fw/tree/multichannel, it should work with stm32g0b1, just tested.

#139

@spnda

spnda commented Mar 22, 2026

Copy link
Copy Markdown

@marckleinebudde That branch shows the same behaviour. Could this perhaps be a hardware issue? My USB wiring is... iffy since I did it with copper cables and soldered directly to pins and cut the traces since I fucked up the PCB design. It does negotiate to full-speed USB (in earlier soldering attempts it only negotiated to low-speed USB), which is why I thought I could rule out a hardware problem. I just don't want to re-order a PCB if I cannot be certain that that is the actual issue at hand... I don't want to pollute this thread much more either.
Thank you for the quick response, though.

@marckleinebudde

Copy link
Copy Markdown
Collaborator

@spnda can you check if you've swapped the USB DP and DM lines?

@spnda

spnda commented Mar 24, 2026

Copy link
Copy Markdown

@marckleinebudde My PCB fuckup is that I swapped DP and DM. It would only enumerate as a low-speed device then. I swapped them with some suspicious soldering and copper wires and now it enumerates as a full-speed device but that's the status quo right now where I can't get it to work.

@marckleinebudde

Copy link
Copy Markdown
Collaborator

Ah ok. This still sounds like a HW problem.

@pgreenland

Copy link
Copy Markdown
Contributor Author

@spnda If your hardware config allows it, may be worth trying to enter the integrated bootloader and test USB DFU communications with say ST's STM32CubeProgrammer app.

The stuff on this PR was definitely working on the G0 as my custom board makes use of the same part.

@marckleinebudde 's PR would be the one to run going forwards though as it has many improvements.

@marckleinebudde

Copy link
Copy Markdown
Collaborator

This PR has still some patches for me to pick up.

@spnda

spnda commented Mar 26, 2026

Copy link
Copy Markdown

If your hardware config allows it, may be worth trying to enter the integrated bootloader and test USB DFU communications with say ST's STM32CubeProgrammer app.

I originally flashed the STM through dfu-util after swapping the USB pairs, if I remember correctly, though to be honest I am unsure anymore... It showed up as a STMicroelectronics device under usb-devices, and I am currently not using the same board anymore since I fucked that one afterwards and had to re-do the USB soldering. This is a very good point, though, I will check on this again and try with BOOT0 shorted HIGH to force-enable DFU, and then see if it enumerates. Thank you to both of you for helping me a bit, and I hope to contribute something in the future with my custom board finished.

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

Successfully merging this pull request may close these issues.