-
Notifications
You must be signed in to change notification settings - Fork 311
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
UF2 Bootloader UART Support #42
Comments
This was merged from https://github.com/adafruit/uf2-samd21, so we (Adafruit) will look at this. This looks a debugging leftover. @MartinL1, feel free to submit issues there related to SAMD51. I'll create new issues for us in our repo. |
@MartinL1 If you can continue to look at the timing issues, that would be very helpful. We don't normally use the UART support. |
I ran into the same issue but with the SAMD21 chip. Making the code change that @MartinL1 recommended does get it to work but only on the second attempt which obviously isn't optimal. I discovered the first attempt to communicate with the chip over UART fails no matter what you ask it to do (info, read, erase, write). As a temporary work around I'm doing two info requests and then doing the write.
|
Updated VID/PID for SparkFun SAMD21 Dev breakout
How is #if USE_UART
usart_putdata("ready", 5); // My debugging addition
/* Check if a '#' has been received */
if (!main_b_cdc_enable && usart_sharp_received()) {
RGBLED_set_color(COLOR_UART);
sam_ba_monitor_init(SAM_BA_INTERFACE_USART);
/* SAM-BA on UART loop */
while (1) {
sam_ba_monitor_run();
}
}
#endif This spits out "ready" over and over again until USB enumerates. With the original line,
I get an output at 476baud. With the new line from above,
that drops to 78baud. I'm quite certain my system clock is at 48MHz, as that was a whole other thing. |
The asynchronous arithmetic baud rate is calculated as follows: baud rate = (f(ref) / s) * (1 - BAUD/65536) where: baud rate = (48MHz / 16) * (1 - 63018 / 65536) = 115264bps = approx. 115200bps The calculation is detailed on page 459 of the SAMD21 datasheet, or page 931 on the SAMD51's. |
@alexwhittemore The Atmel ASF framework calculates it like this:
That 50436 value was hard coded based on the clock running at 8MHz. It wasn't updated when the bootloader was changed to run at 48MHz. |
Thank you for the super detailed responses! The Arduino core code has the same lines in it, with a bit more in the way of comments including those formulas, which I noticed right before bed last night. Of course, the values above calculate out correctly. Being unable to achieve expected output baud rate, I just started stabbing in the dark. I eventually tried Of course, the reason I'm interested at all is to get serial upload working on my SAMD21. There's a confounding variable that it seems PlatformIO is handling my serial adapter badly and I'm not sure why. I've verified my uploader never actually sends anything when it starts an upload (I think it's supposed to send a '#' to start the FW transaction?). So serial upload is probably not working for me because the baud rate is still very incorrect, but also it's probably not working for me because my uploader simply isn't doing the right thing. Oh - no. Update: I was getting no output on my FTDI because it was open in a serial monitor I was unaware of, and PIO doesn't complain about being unable to open the port - that's just a silent failure. That said, now that I have output, I'm getting framing errors from both Arduino and PlatformIO, and no apparent '#' start byte. So I'm still not sure that the computer-side of this transaction is working right. |
@alexwhittemore I would recommend you try using the BOSSA utility to confirm that serial firmware uploads work. That way you aren't troubleshooting your IDE at the same time. I would just try doing a --info and see if you can talk to the bootloader:
The other problem that @MartinL1 was reporting in this issue is that even with the uart baud set correctly the first request to the bootloader always fails. Subsequent requests will work. If you send two --info requests to the board you should get back info on the second try. Another thing I ran into - I'm using an Adafruit ItsyBitsy M0 board right now and I'm powering it through its USB connector. If the USB is connected to a port on my computer the UART bootloader communication on the SAMD21 will not work. If I power the board with a power only USB port (like a phone charger) the UART bootloader works fine. |
@matt448 Thanks once again for the extremely useful suggestion! I'm doing some experimenting with bossa right now to test theories and baselines. That's extremely interesting that your board of choice though is the ItsyBitsy M0 since it suffers most of the same problems/required modifications as my board. For instance - it looks like uf2, by default, uses SERCOM3 pads 1+2 for UART. So either you reconfigured the SERCOM with something like (from my board_config.h): #define BOOT_USART_MODULE SERCOM0
#define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2
#define BOOT_USART_PAD3 PINMUX_PA11C_SERCOM0_PAD3
#define BOOT_USART_PAD2 PINMUX_PA10C_SERCOM0_PAD2
#define BOOT_USART_PAD1 PINMUX_UNUSED
#define BOOT_USART_PAD0 PINMUX_UNUSED or you did the bare minimum to enable UART bootloading and you're using the ItsyBitsyM0's SDA+SCL pins (PA22+PA23, the default from uf2 |
@alexwhittemore I reconfigured to use different pins. They are alternate SERCOM0 pins. I created a fork with my changes if you want to check it out: https://github.com/matt448/uf2-samdx1 If you pull down my fork and run
|
You're the best! If this doesn't completely solve my problem, it'll at least get me super far.
That sure looks suspicious. I noticed those lines in the SAMD51 |
@matt448 Sorry for repaying your kindness with an inbox flood ;) So I went through your examples with a fine-toothed comb until they all worked and I understood each change pretty well. Then I adapted them to my own bootloader repo and... EXACT same behavior. 78baud output from the microcontroller in BL mode. Then I figured, the only reason I have my own clone of the repo in the first place was to add a boards/myvariant, so I just copied that folder into my clone of YOUR repo, and lo and behold, works perfectly. No idea what changed since I first cloned, but it works now. EDIT: As an aside, I have no idea what the line |
@dhalbert FWIW, this issue seems pretty well characterized at this point and I'm quite confident the original correction is accurate and adequate. I'm seeing the same first-attempt-failure as @matt448 and don't quite know what's going on there, but I'm also pretty comfortable by now with this subsystem. Is resolution waiting only on a pull request? I'd love to put one together to fix this, and add some tested template code (built on Matt's work) for enabling serial on other SAMD boards. Now that I'm all set, it's outside the scope of my client work, but I could probably get it out this weekend if that's all the issue needs. |
@alexwhittemore Feel free to submit a PR either to our fork or microsoft/uf2-samdx1. We try to keep in sync with each other. Thanks to you and @mat448 for your thorough investigation. |
I'm using uf2-samdx1 on a Sodaq Explorer, testing bootloader firmware upload via the UART. This is to make sure everything works before finalising the schematic of my own custom SAMD21 based board.
Also applied the patch to
After a manual double-tap reset I can upload firmware using Bossac. It's not that stable and a few retries are necessary. I also noted that the uart bootloader does not work when usb is enumerated. Another issue I am stuck with now is that it does not seem like Bossac resets the board and does not put it into bootloader mode my itself. I expected Bossac to toggle the DTR line on my FTDI breakout so that a reset can be done via a capacitor, just like the Arduino Uno does. Is there a way to tell Bossac to reset the board, so that I do not need to manually double-tap reset the board every time I want to upload firmware? My other 2 cents: |
I also have a custom board with SAMD21 that I Want to program through Uart interface. I modified the bootloader to enable Uart in the correct pins and changed it to single press reset (have a look here @jpmeijers) with the idea to use the traditional arduino Uno reset method with the CTS/DTR signal from the FTDI. So when Bossac will open the serial port to talk to the bootloader will trigger a reset and bring the board to boot mode. The Idea works so it resets when bossac starts but unfortunately bossac is too early in trying to connect so it fails. |
Thank you to everyone for the work on the UF2 bootloader.
I'm using a SAMD51 (SAMD51J20A) custom board. The USB CDC works perfectly with the Arduino IDE, however I've been having some trouble getting the UART support to work.
I powered the board without the native USB connection to prevent enumeration, put my custom board into bootloader mode with a double tap of the reset button, then attempted to upload a Blink sketch with the Arduino IDE, using an FTDI USB to serial board on a spare UART port, (in my case SERCOM5).
After looking at the code, I believe that line 128 of the "usart_sam_ba.c" file needs to be changed from:
to:
This is to account for GCLK0 now being set to 48MHz. The replacement line is taken from the Arduino Zero bootloader.
After this modification I'm now able to upload the sketch using the FTDI board, unfortunately though some timing issues still persist, as this only works on every second attempt.
The text was updated successfully, but these errors were encountered: