STM32F072 USB wont connect with CAN connected SOLVED! - Page 1
Forum section: electronics / general

author: jacky4566
author_rank: Newbie
timestamp: April 13, 2023, 12:47:47 am
content: Struggling with a rather weird problemI am using the STM32F072 in an application that needs both USB CDC and CAN.Currently the peripherals are working as expected. However, if the USB is connected after the CANBUS, USB wont initialize. If I connect USB first then CAN, both work fine.USB has the higher priority (lower number) , interrupts all appear to be working. No hard faults. I know these devices share a buffer so I set the USB CDC buffer to half the default, 256B for each TX and RX.Where do i start to debug this?

author: wek
author_rank: Frequent Contributor
timestamp: April 13, 2023, 07:14:26 am
content: Any error returned by the init functions?Read out and check content of USB and relevant (e.g. RCC, GPIO) registers content, compare between working and non-working.Add links to cross-posts in other fora.JW

author: Jeroen3
author_rank: Super Contributor
timestamp: April 13, 2023, 07:18:07 am
content: In earlier STM32 parts like the F103 you can't use USB and CAN together because the peripheral memory would overlap. They sorta fixed this for the 072..."Up to 1024 bytes of dedicated packet buffer memory SRAM (last 256 Bytes are exclusively shared with CAN peripheral)"

author: voltsandjolts
author_rank: Unknown
timestamp: April 13, 2023, 07:26:24 am
content: Beware that USB peripheral needs minimum APB clock frequency of 10 MHz.Although don't see why that would cause your symptoms, but it's all I got

author: tszaboo
author_rank: Super Contributor
timestamp: April 13, 2023, 07:31:53 am
content: Quote from: Jeroen3 on April 13, 2023, 07:18:07 amI've run into this problem when designing a product. The fact that they don't work together was hidden on page ~1356/2100 in the reference manual.The other issue I saw, why CAN wasn't working was due to bad clock PLL settings. The clock was off by very little, something like 1.5% and the damn thing wasn't working anymore.

author: wek
author_rank: Frequent Contributor
timestamp: April 13, 2023, 08:49:28 am
content: Quote from: tszaboo on April 13, 2023, 07:31:53 amOn 'F103 or 'F072?Quote from: tszaboo on April 13, 2023, 07:31:53 amBoth the 'F1 and 'F0 manuals are only a tad bit longer than 1000 pages... ;-)Quote from: tszaboo on April 13, 2023, 07:31:53 amGood point, and USB is even more sensitive to clock than CAN is. So, question to OP, how is USB clock set, exactly?Also, can't the problem be trivial, e.g. short between CAN and USB pins?Also, which package and which pins are used for CAN and USB?JW

author: PCB.Wiz
author_rank: Super Contributor
timestamp: April 13, 2023, 09:07:23 am
content: Quote from: jacky4566 on April 13, 2023, 12:47:47 amDoes [USB then CAN] pass extensive tests ? ie it is not just 'almost' working ?Did you check other combinations ?If you disconnect CAN, does USB then work ?If you have a working [USB then CAN], if you remove/connect USB, does that continue to work, or does that break ?

author: jacky4566
author_rank: Newbie
timestamp: April 13, 2023, 02:23:40 pm
content: Fantastic, thanks for all the responses guys.Yes I am aware of the issues with the F1 series but the F0 should work. They have a shared RAM but my application only needs a small CDC buffer.If you disconnect CAN, does USB then work?No. USB will not initialize or re-initialize while CAN is connected. Without CAN, I can plug and unplug USB all i want.With USB initialized we can connect CAN which is the only winning combo right now.I have attached screenshots of the pin setup and clock tree.However i have tried all three combinations of- Running the Core and USB from PLL- Running the Core from PLL an USB from HSI48- Running the Core and USB from HSI48No change in results from these clock source changes.I also tried starting a 10 second timer where i alternate betweenMX_USB_DEVICE_Init();andUSBD_Stop(&hUsbDeviceFS);just to see if it would re-initialize. Again no. This works without CAN, every 10 seconds i get a connect or disconnect. But with CAN connected, nothing..Almost like whatever interrupt needs to happen for initialize/ connecting isn't happening with CAN, possible due to the shared buffer?My debug hardware isn't accessible just right this second to look into the registers but ill do a deep dive on the weekend.

author: darkspr1te
author_rank: Frequent Contributor
timestamp: April 13, 2023, 02:44:14 pm
content: I see from your post with "MX_USB_DEVICE_Init()" in it I am going to assume you are using STMCube back end ,I would look further into sth stmcube sources as I know from past experience they will often treat each system as seperate , eg the can MX cube code does not know or care you have USB running, this leads to problems where you might have a register used by both USB and CAN that can will change to it's liking not caring about other bit values that are not related but get changed anyway, a example is the JTAG/SWD registers which for raw stm32f103 projects get turned off by default in the cubemx code?!?this means you may have to call HAL_Init() again not just MX_USB_DEVICE_init();*Edit* I also have to point out there is a difference between MX_USB_DEVICE_Init() and HAL_USB_Mspinit() , one contains the values you set in CubeMX, the other is called at the end of setting the values , i cant remember right, but i think its Mspinit set the values and then calls MX init to reset the device but it's important to check which one is calling the otherAlso a quick google with this chip+CAN list 3 firmwares out there that have source code ,CAnable/CandleLight/Klipper worth a look at those to see how they do init of both.It is worth digging into how CUBMX initializes devices every revision as there's often bugs ahoy , the JTAG/SWD switch was just one example , I've seen others where datasheet init does not match the cubmx, patching to match the datasheet fixes it .if you are not stuck on cubemx (i highley advice you consider init routine to be in seperate groups so you can swap them out for other backends) there are others.darkspr1te

author: darkspr1te
author_rank: Frequent Contributor
timestamp: April 13, 2023, 03:56:19 pm
content: Quote from: jacky4566 on April 13, 2023, 12:47:47 amI wanted to ask question on this separate."However, if the USB is connected after the CANBUS, USB wont initialize" , am assuming the device in powered on already for some time doing CAN bus things and you need to plug in USB while running to do things like change values etc.Are you doing full bring up of the USB even though it's not connected at the time or do you have a trigger mechanism to initialize USB? or is a hybrid of "set registers then do init when required" in which case maybe the register need to be set later on just before init ? I personally have often had issue with cubemx and not doing full init of USB right at the start as if connected and powered by USB.Now in a lot of canbus related stm reverse engineering i've done of OBD devices i've noticed that on many the device is vector reset on USB connect and is still present in the stm clones like gd32f0x chip code. Most devices with a display would just now show text "USB connected" an show you the first menu(reset) , A good example here would be the MKS robin, BTT lcd devices where they reset the device but saved info to skip the logo and just displayed the text then main menu (sources on github)You can save registers and then do reset and initialize as well , you can also force stack memory locations so they are kept too between reset (trick used by official STM DFU software+h/w firmware tool allowing full dump of any dfu based STM/GD/AIR devices because of this quirk ) , But the vector table can be your friend too , I heavily use it for crash tracing and as well as bootloader tricks and hacking stm32 devices (eg adding functions to a obd reader or causing it to spill its nand via uart/usb etc)Another thing i ran into but i'am afraid i cant explain as i switched IDE's then was that in cubemx i would have to sometimes switch build type (debug, platform, production) , clean, rebuild, clean and switch back to original build type because some how a peripheral would just not start up right, It was mentioned once in one page that was due to windows AV scanning files so could not be cleared after code change and another said the was a no save bug and only way past was switch build type and back. this ment code changes were not applied and lots of wasted time.I switched to VS Code and custom Make files after this as at the time I could not trace the issue in any way. I also started to use more device headers and custom written full inits for such,this has given me more flexibility in writing code for me as most of my work was on stm 0xx,103 ,407, and the register styles are very different between them forcing me to write a more common layer between them , a example would be on 0xx device you may set a high and then a low register for clock where as on a 4xx you set one registerOne final tip i would also give is whatever system you are using you must setup a good planned debug path so you can real time see registers and set breakpoints through out your code, in most case when i write something quick/simple as test or example i dont care about backend and whatever is stm cubemx/arduino/cm3 system around i will use, but when i am writing something more solid then my device folder is including all the code base used and does not change , normally here I force a makefile (can be done in windows too ) , this is from too many times i've left the backend up to my ide to update and something has changed in code or build system , stm once missed out a makefile statement that included a .o file but as there was a prior header declaring those calls __weak so it would still compile to a flashable file that "kinda worked" , this was around the time they took over providing the arduino interface (which fair call to STM was well done by them and they did the current maintainers well , even the passing of the domains to stm was well handled and no complaints about the fair treament on the stm32duino.com site owners/mods/users, i've not been banned for discussing RDP bypass techniques!)Anywaysdarkspr1te

author: jacky4566
author_rank: Newbie
timestamp: April 13, 2023, 11:05:47 pm
content: darkspr1te thank you for the in depth chat. There is always many layers to these kinds of things and moving from STM HAL /LL may be in my future but the benefits for a small developer still out weigh these kinds of bugs.I did make a revelation however. The USB peripheral is going into suspend mode which happens after 3 missed SOF frames.My application relies on using an Android device and its Serial drivers. This is for a motorcycle application so having your phone for debug and configuration is a key feature.I noticed the suspend problem after some power testing. Then i tried plugging the device into a windows PC.This problem only occurs with Android and not Windows!I can plug and unplug all I want with Windows. I suspect this has to do with how Android negotiates the Serial ports and USB-C Power delivery.My board has the required 5.1k resistors to act as a power sink but not a full PD controller.Not really sure how to proceed from here. It would be great to have the android connection so perhaps I needs to do a full reset of the USB peripheral on USB connect. I don't have a USB Voltage sense line on this PCB but the next version will.Ill post an updated once we have an updated board.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: April 13, 2023, 11:54:07 pm
content: Suspend is a software-assisted feature (hw detects the idle condition, signals an interrupt, sw sets the peripheral to suspend state), so you can find that code and disable it.

author: darkspr1te
author_rank: Frequent Contributor
timestamp: April 14, 2023, 06:03:10 am
content: As soon as the mention of USB sleep it reminded me of a issue i had seen on micropython forums,Quotealso check the codeCode:uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev,uint8_t epnum)to see if the !=NULL check is implemented for sleep mode check , this should report back that USB is asleep or suspended.darkspr1te

author: peter-h
author_rank: Super Contributor
timestamp: April 14, 2023, 10:23:16 am
content: QuoteFWIW I can confirm the above is not the case for a 32F417. De-init does get called when you unplug the cable. I am using ST Cube USB code from around 2019.There is however a bug: it calls free() to deallocate some buffer on the heap, and after Windoze has gone to sleep a few hundred times, your product crashes due to heap fragmentationThat code needs to use a static buffer, and then de-init does basically nothing.The product I have nearly finished has USB (CDC & MSC) and that all works, but it also has CAN and no software has been done for that. I will just leave it and see if anybody wants it. Hopefully this issue won't occur...

author: jacky4566
author_rank: Newbie
timestamp: April 21, 2023, 06:18:59 pm
content: Got my next PCB revision. This one added a diode for the USB 5v and a 1k pulldown before the diode. Since the device is normally powered by the throttle 5V line and my previous version tied this with the USB5V directly.As I suspected, the Android USB host won't connect unless there is sufficient load on the USB. So problem solved and lesson learned.