Closed ulrichloose closed 9 months ago
The fuses are correct. The Urboot bootloader is a Vector bootloader, which means that it doesn't need a boot sector. The reset vector is patched by Avrdude to always point to the bootloader when uploading using the urclock
programmer option in Avrdude. Read about the Urboot bootloader here. It's a very refined bootloader solution for AVRs created by @stefanrueger.
If the bootloader only work once, it may be an issue with the auto reset circuity. What does your hardware look like? Is it a DIY solution? And it does work flawless with the Optiboot bootloader?
I apologize for my ignorance regarding urboot...
I use some Arduino mini pro clones that are largely the same as the original, only equipped with a 328 PB. I am well aware of the reset problem; there are apparently problems with various USB serial adapters. However, not with my CH340 - in contrast to a CP2102 which doesn't work at all.
Long story short - I first provided the six boards I have with MiniCore's urboot bootloader in the IDE - which is a bit complicated since there is no header - and then loaded a simple double blink program serially so that I know that the bootloaders are up to date.
The "crazy" thing then follows - when I want to program a "real" program via the bootloader, the only thing that follows is a sync error. Of course I thought it was a mistake on my part and re-burned the bootloader and then the actual program. That worked again... The next time I changed the program, there was a sync error again.
I replaced MiniCore with the older optiboot version and reprogrammed the bootloader and the double blink program again. This works absolutely reliably and I have been able to load updates to the program serially several times, and sync errors have not occurred again.
Of course I have no explanation for the behavior - it's simple for me as a layman. Optiboot works, urboot causes problems (;-)
Of course, I don't know for sure - the clones bought from Amazon were so cheap (https://www.amazon.de/dp/B0CLY1Q3N1) that there is a possibility that they are not original 328PBs. An indication of this would probably be the fact that significantly more power is consumed in power-down mode than stated in the data sheet...
Anyway - I'm very happy with the Optiboot version and glad that MiniCore is available...
Can you turn on verbose output in the IDE settings and paste the entire output when you burn the bootloader and when you're trying to upload using the bootloader? Hopefully, that might reveal what the issue might be. Thanks!
BTW are the laster print on the chip just as monkey as in the pictures from Amazon? The Atmel logo looks like someone hand-wrote it!
I didn't take my own photo, but I found one online that corresponds 100% to the actual labeling of my chips. Found in a thread about - how could it be otherwise - counterfeit chips.
I won't submit the output of the IDE messages until tomorrow...
Attached are the two logs
Versions 3.01 and 2.2.2
Each from the bootloader and from the serially loaded sketch....
Thanks! Can you try to upload using the 250000 baud option as well when using Urboot?
In the meantime I get it running....
I compiled avrdude in version 7.3 by myself und have overwritten the two files avrdude and avrdude.conf in the minicore tools folder...
Now everything works like a charm... (:-)) avrdude7.3.txt
It looks like you're using macOS, which I'm also using. And I've never had any issues with the Avrdude version MiniCore bundles. But I'll update to Avrdude 7.3 as soon as Arduino themselves provides a statically linked binary. It usually takes a few weeks.
But did you manage to get it to work using Avrdude 7.2 and 250000 baud? The reason why I stress this is because 250000 baud results in a 0% error when the microcontroller is running at 8 or 16 MHz. So if 250000 baud doesn't work, it means that it's guaranteed to be an AVRdude/PC related issue.
Thanks!
Optiboot works, urboot causes problems
The log files show actually three things changed:
avrdude | bootloader | programmer |
---|---|---|
v7.1 | optiboot | -c arduino |
v7.2 | urboot | -c urclock |
What's Vcc? If > 5.5 V then this could result in a > 11 V peak on certain boards without a RESET clamp diode to Vcc using a pre-v7.3 -c urclock
instance; the > 11 V peak might have triggered HV programming causing the observed time-out behaviour. If so, this is a hardware problem, but v7.3 changed -c urclock so that there would be no such drastic peak in boards that miss the clamp diode.
() actually three* things changed apart from the fuse change that is necessary when switching between the two bootloaders
My last "Log" was generated with 250000 baud... I have measured the Resonator via "Clock output on PORTB0" and it is stable at 15,975 Mhz.
I have now tried pretty much everything in terms of hardware, including the diode, a 1K resistor from the capacitor to ground like with the UNO and also reducing the capacitor to 10 nF as described by Microchip. This was not crowned with success. In the course of using different USB to serial adapters, I also checked the generated reset pulses using an oscilloscope. There are big differences in timing between, for example, the CH340 and the CP2102 chipset. But that's primarily due to the drivers that are outside of avrdude's "responsibility". The board is powered for programming via the USB port and the voltage is on the lower end at just over 4.75 volts.
It seems obvious to me that it is due to the reset. From purely practical empirical observation: I had programmed all of my boards with a bootloader and a small blink sketch and when I serially wrote a "real" program, the LED flashed happily in the 10 attempts to synchronize. From this I conclude that no reset impulses are recognized.
The 328PB - and probably even more so with counterfeits - seems to be a real mimosa when it comes to resetting compared to the 328P.
Current situation for my 328PB boards: MiniCore 2.2.2 with Optiboot and avrdude 7.1 doesn't cause any problems, MiniCore with urboot and avrdude 7.2 is "stuck" and MiniCore with urboot and avrdude 7.3 works as it should.
A last question:
avrdude avr_get_mem_type() warning: avr_mem_order[] does not know data; add to array and recompile
Can this simply be ignored or suppressed?
What's Vcc? If > 5.5 V then this could result in a > 11 V peak on certain boards without a RESET clamp diode to Vcc using a pre-v7.3 -c urclock instance; the > 11 V peak might have triggered HV programming causing the observed time-out behaviour. If so, this is a hardware problem, but v7.3 changed -c urclock so that there would be no such drastic peak in boards that miss the clamp diode.
I didn't know Avrdude 7.3 also dealy with accidentaly entering HV programming. Neat!
My last "Log" was generated with 250000 baud... I have measured the Resonator via "Clock output on PORTB0" and it is stable at 15,975 Mhz.
Yes, but that was with Avrdude 7.3; The known working one. I'd be interested to see the same upload procedure (250000 baud, 16 MHz resonator), but with Avrdude 7.2 (The one that MiniCore originally uses).
Most issues that's being reported here are ATmega328PB related. It's a much more flakey chip compared to the ATmega328P. The reset voltage threshold are different, and the most annoying thing is the lack of "power" to drive a crystal or resonator. The ATmega328P could practivally drive any crystal with the "full-swing oscillator" fuse option, but Atmel replaced this with a low-power mode instead. It saved about 1mA of current, but causes a whole lot of trouble if your crystal/capacitor combination is too capacitive.
I've designed a board around an ATmega324PB (very, very similar to the 328PB), and I had to rework the frist 200 boards that were manufactured, because they just stopped working after a few days, and sometimes, weeks. After some investigation, the SMT house had soldered an 8 MHz resonator with 33pF internal capacitance instead of 10pF. After replacing the resonator with the correct one, the board worked perfectly.
avrdude avr_get_mem_type() warning: avr_mem_order[] does not know data; add to array and recompile
This is most likely caused by the fact that the avrdude.conf fine you're using was generated for Avrdude 7.2, but you used it with Avrdude 7.3. It can safely be ignored.
Bottom line: I'll upgrade MiniCire to use Avrdude 7.3 as soon as statically linked binaries are available.
Thanks for reporting back on your findings!
avr_mem_order[] does not know data; add to array and recompile
The data
memory (which only served to provide the offset of sram in linear address space for modern devices) was withdrawn in v7.3 in favour of newer and expressive proper memories sram
and io
. This warning indicates that either the used avrdude.conf belongs to an older version of avrdude or that your private .avrduderc
or similar utilises a data memory, which will no longer serve a purpose as the offset is now computed by https://github.com/avrdudes/avrdude/blob/0179026e09d19833e7dea06ed8db19f971138e4b/src/avrpart.c#L480-L483
I suggest using a new avrdude.conf (that belongs to v7.3) and/or remove data memories in privately defined parts.
I have now tried pretty much everything in terms of hardware
So, seeing that v7.3 works but v7.2 doesn't has made me curious: is there a way to figure out what made the difference?
The 250000 bps doesn't work on my boards under avrdude 7.2 either. But they would have to, since the resonator is stable and very close to 16 MHz. It looks like it's the reset and not a deviation in the baud rate...
I will now compile version 7.2 locally again and test it... In the end it is due to the avrdude version supplied?....
In the end it is due to the avrdude version supplied?....
This issue has never been reported before, so I don't know. Yesterday I flashed a genuine ATmega328PB, running at 16 MHz, with the Urboot bootloader using MiniCore v3.0.1 and Arduino IDE. It worked flawlessly on my Mac using a CH340 USB to serial adapter. And this was with Avrdude 7.2.
@stefanrueger made some changes to the auto-reset procedure in October. These changes are present in Avrdude 7.3, but not in 7.2. https://github.com/avrdudes/avrdude/commit/aa2f45111b2aa833fa88e5b185cced5917fbd982
@ulrichloose if the auto-reset capacitor or the reset pullup resistor has "abnormal values", this might cause the reset line on the microcontroller to not get pulled down to perform a reset. I recommend a 100nF capacitor + a 10k pullup. I think 1uF should also work, but then a protection diode on the reset line is a must, to prevent voltage doubling.
EDIT: again, thank you @ulrichloose for your time and help! information like this is very useful to us and is exactly what we need in order to harden both MiniCore and the overall bootloader/avrdude implementation. The goal is always to support a wide variety of hardware, even the flakey and poorly designed ones. The reason why I replaced the trusty Optiboot bootloader with Urboot is to provide more functionality for the end user. Optiboot is proven, but it has its limitations and flaws; flaws that are usually covered up by the limited Arduino IDE.
Urboot is a much more modern implementation, where the protocol spoken between Avrdude and the microcontroller is written specifically to be as efficient as possible for a bootloader. Optiboot speaks the stk500v1 protocol, which isn't designed to be a bootloader protocol, but rather a protocol between the host and an ISP programmer.
I think that Urboot is too good to not be widely used. And by pushing Urboot, we also get lots and lots of testers. And that's a good thing for both Avrdude and the Urboot bootloader.
I was able to narrow down the "problem" a bit by compiling various commits:
Commit 9735789c214e0786766fec35c7c29f986691a56b -> works
Commit 8ed9615f867ae460b3187da560b425c6cdc3ca5f -> doesn't work
Of course I'm not a professional, but it seems to me that the timing was worked on in the intervening commits and that solved the problem.
I was able to narrow down the "problem" a bit by compiling various commits:
Bingo! The DTR/RTS timing was changed between these two commits; that explains the issue. But that means that the reset pullup resistor on your board, or the auto reset capacitor probably isn't 10k or 100nF. Or maybe there already is an auto-reset capacitor on your USB to serial adapter?
If it's the timing bit in commit aa2f451 that made the difference for v7.2 work then a scope should display a marked difference for the reset signal: v7.2 before this commit should give a Reset spike of nearly 2 Vcc (ie, some 9.5 V), while from that commit onwards there should be no discernable spike above Vcc.
And if it's above what made the difference then a clamp diode between reset and Vcc should also resolve the issue. The ATmega328PB requires as Enter HV programming condition Reset above 11.5 V, but if the chip enters HV programming at 9 V then this would explain the behaviour.
The original Arduino Pro Mini board doesn't have a protection diode on the reset line, but the Amazon URL he linked to shows a board where a diode has been added where the "PRO MINI" text previously was.
A lot of boards actually don't have reset/Vcc clamping diodes probably to not disable HV programming. The diode near the Promini text could be protection against voltage reversal for Vin/Gnd or a fuse to protect against over-current...
To visualize the difference:
7.2 doesn't work
7.3 works
Thanks for the OSCI pictures - first reset caused by driver/OS twiddling with DTR/RTS on avrdude entry or port open. Second one should be the intended one by these lines. However, I think the behaviour should be the other way round (only a tiny almost indiscernible above-Vcc peak with v7.3 on second reset).
| programmed all of my boards with a bootloader and a small blink sketch
This wouldn't work if the bootloader urboot.hex
and the application blink.hex
were programmed at the same time with an external ISP programmer such as usbasp because the application's reset vector and another one need patching on upload, which is done by -c urclock
. Your log files don't show that an application was burned together with the bootloader, so good.
The strange thing was that at the beginning I managed to provide all boards with the urboot bootloader via ISP and then in a second step I wrote a small blink script serial as feedback to me that the boards were "ready for use". However, later on in real use there were only sync errors.
Found from another post online:
...wait a while (~20s after burning bootloader) I can't upload any sketch on it ... got avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() error (that normally comes when the MCU isn 't responding to the programmer or false reset)...
In my opinion, the fact that the optiboot bootloader works with avrdude version 7.2 and earlier, i.e. the versions that produce a large overshoot during reset, speaks against a problem with overshoot. My attempts to insert a clamp diode with version 7.2 and earlier also had no success in urboot.
I think it has less to do with the overshoot and more to do with the width of the actual reset pulse. It is possible that urboot reacts significantly faster than other bootloaders and reports its readiness at a time when avrdude does not yet expect a response...
If I interpret the data sheet for the 328pb correctly, then the falling edge of the reset pulse causes the "internal reset" and from that point on "the timing clock starts running". I am assuming that avrdude does not expect a reaction from the bootloader during the reset pulse it generates up to the low high edge, but only after the reset pulse is complete.
This would be supported by the fact that shortening the reset pulse ensures that arvdude notices the (quick) reaction of urboot. The question now is whether you can simply delay the reaction to a reset a little with urboot, or let avrdude wait for a response at an earlier point in time...
I have no idea how this works exactly, but I suspect that the bootloader is sending some kind of response serially to indicate its readiness. After the complete reset, avrdude deletes the receive buffer to remove possible garbage and then waits in vain for the answer, which it has already removed as garbage from the fast urboot... As a non-expert, this is roughly how I imagine the problem (;-)
If I interpret the data sheet for the 328pb correctly, then the falling edge of the reset pulse causes the "internal reset" and from that point on "the timing clock starts running". I am assuming that avrdude does not expect a reaction from the bootloader during the reset pulse it generates up to the low high edge, but only after the reset pulse is complete.
The clock starts ticking from the rising edge of reset. Depending on fuse settings the MCU waits a relatively long time so it can assume the clock has settled. I am using the fuse settings from your urclock log file:
$ avrdude -qq -patmega328pb -cdryrun \
-Ulock:w:0xff:m -Uefuse:w:0b11110111:m -Uhfuse:w:0xdf:m -Ulfuse:w:0b11111111:m \
-T config
config sut_cksel=extxosc_8mhz_xx_16kck_14ck_65ms # 63
config ckout=co_disabled # 1
config ckdiv8=by_1 # 1
config bootrst=application # 1
config bootsz=bs_256w # 3
config eesave=ee_erased # 1
config wdton=wdt_programmable # 1
config spien=isp_enabled # 0
config dwen=dw_off # 1
config rstdisbl=external_reset # 1
config bodlevel=bod_disabled # 7
config cfd=cfd_disabled # 0
config lb=no_lock # 3
config blb0=no_lock_in_app # 3
config blb1=no_lock_in_boot # 3
So, with your sut_cksel
the wait is 65 ms + 16000 ck (@ 16 MHz?) + 14 ck, which I make some 66 ms. The 65 ms will be some imprecise internal clock (the same as for the WDT?) so let's just say 60 - 72 ms. Then the MCU jumps to the reset vector as bootrst=application
. The urboot bootloaders then wait up to WDTO (probably 1 s if you downloaded the urboot bootloader from Minicore) for a command sequence from the uploader -c urclock
. Actually, if it's an autoaud bootloader (look at the output of -curclock -xshowall
, if there is an a
in the capabilities string then it is autobaud) then the bootloader determines the baudrate based on the timing of the bit pattern of the first byte that -c urclock
sends. And then they get in sync by sending "the right" bytes back and forth.
It is crucial that avrdude's -c urclock
does not send its first command sequence too early. That's unlikely in your case, as -c urclock
waits 120 ms per default before doing so. You can lengthen and shorten this time by the option -xdelay=...
(in ms). So you can check your hypothesis by playing with -xdelay=-30
... -xdelay=100
in v7.2. I'd be interested to know whether it's just a matter of delay with your board/MCU/...
optiboot bootloader works with avrdude version 7.2 and earlier, i.e. the versions that produce a large overshoot during reset, speaks against a problem with overshoot.
You are probably right. One can use either -c urclock
or -c arduino
for optiboot. If you used -c arduino
in v7.2 it is a different code. It could be that there is less overshoot? Not sure here.
However, I think the behaviour should be the other way round
On second thoughts, v7.2 does wait 20 ms before DTR/RTS is set back to Vcc pushing the fully charged reset cap voltage on top of Vcc. This overshoot would appear outside the captured oscilloscope image (to the right), and I would expect the excess to be the full Vcc (or whatever voltage span DTR/RTS runs).
... and seeing that the overshoot in the second image is ca 2 V then the 100 µs charging time means that your reset cap and/or reset pullup resistor are way smaller than I normally see them (10k, 100n). With RC = 10k⋅100n = 1 ms the overshoot would probably be some 0.1 V
So, I no longer think the pictures are mixed up, just that we don't see the overshoot of v7.2 because the time axis has too high a granularity
I take everything back and claim the opposite...
I just used a logic analyzer to find out the differences... 7.2 has a 20 mS wide reset and 7.3 has a 0.5 mS wide one. Then used the soldering iron again and inserted a diode to suppress the overshoots and lo and behold - it also works with version 7.2 with this diode...
So all my assumptions were simply wrong and it is actually due to the overshoots.
I apologize if I have caused any unnecessary confusion.
7.2 without diode
7.2 with diode
7.3 without diode
actually due to the overshoots
I am glad we have gotten to the bottom of things. Thanks for your perseverance. You will note the absence of TX signals in the v7.2 and 328PB w/out diode. This is b/c the part has entered HV programming and waits for twiddling of the associated pins. If you measure the overshoot it should by right only be 2 Vcc = 9.5 V in your case unless the USB/Serial chip involves higher external voltages. This is 2 V below the voltage that should trigger HV programming according to the data sheet:
Could it be the MCU is counterfeit and just enters HV programming at way less voltage?
I disagree with the logic analyser re the reset width. The reset width should always be RC (and the scope agrees with me here). It is only later, after the 20 ms wait, that a positive overshoot is created on top of Vcc, which ought to be ignored if less than 11.5 V.
There is still the question why -c arduino
works in v7.2. One difference is that -c arduino
waits 50 ms (not 20 ms) before pulling DTR/RTS high again (creating the overshoot). Maybe it is that the MCU only enters HV programming if the high voltage happens within a certain time window after (proper) reset? Guessing here!
BTW, I recommend 10k/100n for a reset circuit:
It's similar to the reference reset circuit except for the external clamping diode (that prevents HV programming).
... and I think you use an autobaud bootloader b/c the analyzer clearly shows that the first AVRDUDE command sequence is eaten up by the bootloader to measure and set its baudrate. Neat!
... and I think you use an autobaud bootloader b/c the analyzer clearly shows that the first AVRDUDE command sequence is eaten up by the bootloader to measure and set its baudrate. Neat!
Correct. MiniCore only bundles autobaud bootloaders. This makes the logic in boards.txt a whole lot easier, and it also allows for a dedicated baud rate menu option in the IDE, something that was unheard of before.
I'm glad the issue could be traced down to an HV spike on the RST pin!
I really like the logical analyzer images. They also show in the case of 7.2 without diode that AVRDUDE -c urclock
increases the delays between sending sync commands; this is to catch various optiboot bootloder versions that in the past have used different length blink-LED-concerts before(!) checking whether an uploader wants to speak to the bootloader complicating the protocol.
Of course I can't set my hand on fire for the Saleae Analyzer, but it actually shows it that way and several times in a row without any deviations. A CH340 G USB to serial adapter with the drivers supplied by Apple is in use. Of course measured in front of the capacitor...
7.2:
measured in front of the capacitor...
OK, this is DTR/RTS and not reset, and that explains the output of the analyzer. Fun fact: v7.2 onwards allows a direct DTR/RTS connection to reset, and this code is what originally created the overshoots (when used with a cap instead of direct connection) that brought about the problems with this (out of specs) MCU. It was only later that we sussed out the overshoot problem and changed the code to dampen it (v7.3).
My last "summary... (;-)
7.1 sets DTR to low before transmission and only goes back to high after complete programming. On my 328PB board this results in a reset pulse of 0.35 mS. minicore 2.2.2 with optiboot works perfectly even without a diode.
7.2 sets DTR low for 20 mS before transmission. Here the reset pulse is also 0.35 ms, but sync errors occur.
7.3 sets DTR to low for 0.5 mS before transmission and this also works on my 328PB, although the reset pulse here is also 0.35 mS.
Now my last attempt - minicore 3.01 with avrdude 7.1 in which the DTR line remains low during the entire transmission: This also works without errors with urboot without a diode.
The problem seems to occur during the transition from 7.1 to 7.2, i.e. after switching from DTR Low during the entire transfer to a complete reset pulse before the transfer.
Maybe that's of interest. I don't know why the reset was changed after 7.1.
Thanks for the summary. Great illustrations with the logic analyser.
I can illuminate the reason why v7.2 changed the reset code: we wanted to enable direct connections between DTR/RTS and reset to reset boards without reset circuits as well. So rather than pulling DTR/RTS high after programming it was pulled high some time after it was pulled low. Unfortunately, the chosen low-time of DTR/RTS was too long: the reset cap would be fully charged and when DTR/RTS was put high again the voltage of the fully charged cap (Vcc) was pushed onto Vcc of RTS/DTR causing the 2 Vcc spike at the reset pin.
Now, this doesn't matter on boards with Microchip's recommended reset circuit owing to the Vcc/reset clamp diode.
It also doesn't matter for genuine parts, where V(HP) ≥ 11.5 V, that are run within the prescribed specs of Vcc ≤ 5.5 V.
Your case is unfortunate in that a peak of 9.5 V triggered HV programming, which it shouldn't according to the data sheet.
The right thing to do from a software pov, though, is to drastically reduce the low-period of RTS/DTR so that the reset cap wouldn't be fully charged. Reset only needs to be low for a few µs to be recognised by the MCU. This is what v7.3 does.
avrdude is of course such a comprehensive program and for the Arduino IDE environment with a relatively limited selection of different boards, it is almost overkill. For professionals there is certainly no way around the current version. In the hobby area of the Arduino IDE, in this case of minicore an older version would have been the better choice - especially since counterfeit chips have actually been in circulation in the hobby area for a long time. This probably won't happen in the professional sector a la Mouser, DigiKey & Co....
But now everything is perfect for everyone and it runs completely problem-free...
I would like to take this opportunity to thank everyone who makes their work available to the general public! Without this work, the hobby of “programming and development” would hardly be possible.
I'm no expert, but in my opinion there's something wrong with the fuses since switching to urboot...
I use an Atmega328PB. When the bootloader is burned in IDE, the entry "Boot Reset Vevtor enabled" is not activated since Urboot and the bootloader happens to work exactly once.
In the older version 2.2.2, which I now prefer, the boot vector is set and everything works as it should and is extremely stable.
Am I making a mistake in my thinking and or is there an error that no one has noticed yet?