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

"Add" support for gd32f10x board #109

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

dmlambo
Copy link

@dmlambo dmlambo commented Aug 28, 2023

Don't merge, please! This is for discussion of adding the F10x boards to the Arduino core!

Sorry for the mess, not my best work, but these are some hacks and required changes to get a build compiling for a gd32f103rc (specifically. you may have to add your own variant directories from your platform-gd32 build to get the others to work).

cores/arduino/analog.cpp Outdated Show resolved Hide resolved
@dmlambo
Copy link
Author

dmlambo commented Aug 28, 2023

Assume everything is done just for getting the one board compiling. I posted this at the behest of @maxgerhardt just to get the ball rolling. Best thing to do would be to ignore the logic, but note the requirement.

@dmlambo
Copy link
Author

dmlambo commented Sep 7, 2023

Another little update. The USBD implementation for the F103 is subtly different from other MCUs. In the end there are only a handful of changes required to get CDC/Serial to work, but the amount of work to find those changes was soul-crushing. Before I push the changes I'm just going to describe what I did real quick:

  • On my board there is an open-drain software controlled disconnect connected to D+. It's connected through a 150ohm resistor. This overpowers the 1.5k pullup that's in place to bring the D+ low. usb.c assumes this to be a push-pull behind a 1.5k pullup, so I had to mess around a bit to get it to behave.
  • Thus I had to add some definitions to variant.h (USB_PULLUP, etc.) and/or add some ifdef guards around the errant code. This might need to be moved to the boards generator and added in platformbuild.py.
  • I had to disable the USB peripheral clock before init, since the bootloader was using a different PLL clock multiplier, and changing it didn't seem to take effect without first turning off the clock.
  • Finally, and most importantly, I had to mess with the usbd state machine from USBCore.c. There's an additional field, ctl_state, which is usually set just before returning filling out the ep0 buffers and returning from the ISR. Normally done in usb_setup_transc (which has been superseded by USBCore::transcSetup). If this isn't set then the host doesn't get responses to ZLPs, and ep0 stalls.

The real bugger was Windows (or maybe my USB host) was clever enough to read the device descriptor and continue onto reading the config descriptor, which failed... so from my perspective the device was "behaving" up until config when it really wasn't. Thank god for Raspberry Pis, I was able to use one to debug the packets that the Windows USBPcap wasn't showing me.

Now that it's working, I'll need to take a pass at cleaning up the code and making more other-MCU friendly. 😄

@obra
Copy link
Contributor

obra commented Sep 7, 2023 via email

@dmlambo
Copy link
Author

dmlambo commented Sep 7, 2023

Nice. At first glance it looks quite a bit cleaner. It may be worth pulling the code in before I mangle what's currently there. I don't have any other gd32 devices though so I can only test so much, unfortunately.

@dmlambo
Copy link
Author

dmlambo commented Sep 8, 2023

Alright, well, I bit the bullet and just made changes to USBCore. I had to add some delays here and there, and importantly I also need to define some things in platformio.ini:

build_flags = 
  -DPIO_FRAMEWORK_ARDUINO_ENABLE_CDC 
  -DUSB_PULLUP=GPIOA 
  -DUSB_PULLUP_PIN=GPIO_PIN_12 
  -DUSB_PULLUP_PIN_MODE=GPIO_MODE_OUT_OD 
  -DRCC_AHBPeriph_GPIO_PULLUP=RCU_GPIOA

There is a pulldown IO pin on my board, but the bootloader I'm using (stm32duino) doesn't actually use it, and seems to work fine. They instead set PA12 (D+) to PP output, pull it low, then reconfigure to floating. So I tried doing the same to force a reconnect, and it works (in OD or PP, doesn't matter). The only thing is, I needed to add a delay after setting the gpio to open-drain to allow the host to catch the disconnect, since if we enable the peripheral too soon it forces the IO line high before the host realizes anything happened.

Similarly, I had to add a delay after usb_init (there's a note about adding a delay... without a delay) to allow the USB peripheral to... do... something? If we don't wait, I'm thinking the ISR fires too quickly and we change some values before the peripheral is ready. Anyway, it's only adding probably some microseconds to milliseconds to startup, so I don't feel too bad about it.

@dmlambo
Copy link
Author

dmlambo commented Sep 11, 2023

Additional changes added to support the new changes for pin remapping on F10x boards. Keep in mind I only added the GD32F103RC_GENERIC variant to keep the change reasonable.

I also added 36-pin boards, which I had forgotten in the previous change, but again, the variants aren't checked in yet.

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.

2 participants