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

Programming using pyupdi with 4k7 resistor #119

Closed
HannesBulk opened this issue Apr 7, 2021 · 29 comments
Closed

Programming using pyupdi with 4k7 resistor #119

HannesBulk opened this issue Apr 7, 2021 · 29 comments

Comments

@HannesBulk
Copy link

in the Spencekonde AtmegaTiny core it is possible to program the Attiny0,1 and 2 Series with PYupdi just using a serial adapter and a single resistor. This words fine, even for the DX cores. It should also work withe the mega0 series (at4809 etc), however these processors are not included in his project. since the program protocol is the same protocol as used for the TinyMega Cores, it should also work with the Mega0 series.
My request is to add this pyupdi with a 4k7 resistor programming protocol, to allow programming with a simple usb-serial converter.

@MCUdude
Copy link
Owner

MCUdude commented Apr 7, 2021

This is something that's doable, and as you pointed out, DxCore and megaTinyCore has it already.
@SpenceKonde is it OK if I borrow your implementation? 🙂

@MCUdude
Copy link
Owner

MCUdude commented Apr 7, 2021

I copied the pymcuprog implementation (pyupdi compatible) from megaTinyCore to try it out with MegaCoreX. It works great!
The only thing I had to tweak was the resistor value. For some reason, a 1k resistor was too high for an ATmega3208. A 470R did the trick.

I made a tiny 2x3 pin adapter for this test, so I could use a standard USB to serial adapter. And this got me thinking, it should actually be possible to create a tiny "Pyupdi board" that could automatically switch between UPDI and serial mode!

The screenshot below shows a pyupdi/pymcuprog UPDI init sequence. It starts with a DTR toggle (yellow trace), followed by some data being sent on the Tx pin on the USB to serial adapter. The data is echoed back to the Rx pin through the resistor.

On a custom board, a DTR toggle could switch in the resistor, and if traffic occurred on the Tx pin within ~5ms, stay in UPDI mode until traffic ends or we get another DTR pulse. Else, if no traffic occurs on the Tx pin within 5ms after a DTR pulse, switch to UART mode. I think this could actually work, maybe with just simple digital logic! it would also fit the "microUPDI" pinout quite nicely! Any thoughts @HannesBulk and @SpenceKonde?

DS1Z_QuickPrint1

@MCUdude
Copy link
Owner

MCUdude commented Apr 8, 2021

This is a mockup schematic of what I think might work. The logic happens inside the ATtiny404/414 and switches the RX/TX pins based on what's happening on the RTS and UART TX line:

image

@SpenceKonde
Copy link
Contributor

SpenceKonde commented Apr 8, 2021 via email

@MCUdude
Copy link
Owner

MCUdude commented Apr 8, 2021

I'm planning something much simpler based on the fact that most serial
consoles hold DTR and RTS low.

Wow, I didn't think of this! this means that we can stay in "regular" UARTmode when DTR/RTS is low, and UPDI mode when high. Brilliant! It seems like Avrdude does the same thing with the DTR/RTS pin, so this means the board could also be used to program optiboot-compatible boards. Neat!

About that diode, is it going in serial or parallel with the resistor. If I'm going to create a board around this I'll probably use the BAT54S, my go-to Schottky diode for everything signal-related. BTW, which value do you usually use for the resistor?

Oh, but is it OK for you if I borrow your pymcuprog implementation?

@SpenceKonde
Copy link
Contributor

I think it should be; I want to just check in with Quentin who did a lot of the development work on it. Will let you know,

@SpenceKonde
Copy link
Contributor

I'd go with 470 ohm. heh, that's the same diode I'm using, in the SOT-23 package because I can't stand the SOD signal diode packages.
Resistor in series with diode. The real question is what serial adapter IC; there are no perfect choices... they all suffer disappointing transfer rates due to USB latency - at least the ones I have tried, and I haven't found any I'm fully happy with yet for this sort of programming - CH340's are fine for tinies mostly, but they are mad slow when you start uploading large sketches over UPDI - and even not-so-large ones can be.... really slow. That's another thing I;'m going raise in an email to the the team actually, since I took some data last night that put numbers to my sense of disappointment.

@MCUdude
Copy link
Owner

MCUdude commented Apr 9, 2021

Regarding the Pyupdi programmer, I think the 47HC4053 has a bit too high internal resistance to be a good choice in this application. The 74LVC1G3157 has only 10 ohms, which is an order of magnitude better than the 4053.

I don't have much experience with Pyupdi in general, so I can't say too much about upload speed. But the CH330N/CH340G have been reasonably quick for "regular" Optiboot uploads. Not as fast as the Silabs CP2102, but good enough. I believe UPDI will be much slower since it is a half-duplex protocol.

How about something like this?
image

@SpenceKonde
Copy link
Contributor

I have the PCBs on hand so as soon as I have time to assemble some I'll try it out

But yeah for general programming, you want to grab what's in /megaavr/tools from DxCore (megatinycore is functionally the same, but if there's a readme in tools, its a sentence or two instead of a longform essay with ASCII-art schematics of every plausible configuration and tables of speed recorded as well as the relevant parts of platform.txt and programmers.txt (and note the editing of platform.txt my release scripts have to do to deal with the path to python being different for board manager vs normal installs), and you'll need to have it pull in python in the board manager json tool.

The adapter IC question has been rendered largely a moot issue with software improvements. No matter what adapter you use, even @ 460800baud, reads aren't far below the wire speed! and with nvm v0 w/128b pages, writes are the same bulk speed as a 32k tinyAVR, that is 7.5k/s or so with ch340 at 230400, 10k/s @ 460800. those numbers are 10k and 15k on FT232RL (with the correct setting as noted in that readme - the default is for it to use a 16-ms latency timer which results in it spending less than 15% of the time communicating, and the rest sitting around in latency waiting for the next USB transaction). But yeah. you;'re looking at full write+verify time of 9s @230400 or 7@460800 w/ch340, or like 8 and 5 w/ft232 for full 48k flash, which I think is pretty good. Way better than jtag2updi will do. For equal baud rate, Optiboot should win narrowly (largely because optiboot uses no parity and 1 stop bit, while UPDI has parity and 2 stop bits, and hence is 20% slower for a given baud even if everything went at the speed of the wire.

@SpenceKonde
Copy link
Contributor

SpenceKonde commented May 19, 2021

To compare, prior rto this optimization round, the times for a CH340 class would be like... 600b/s write 6.5k/s read @ 115200 baud, so you;d have been looking at like 8 sec for verify and maybe 80-90 to write... so like 90-100 seconds total? I hope you now understand why I was advocating you hold off getting this into MegaCore X

@MCUdude
Copy link
Owner

MCUdude commented May 23, 2021

@SpenceKonde I finally have the time to pick this up. I'd like to be able to use Pymcuprog with the MPLAB Snap and PICkit4 from withing Arduino IDE, but when I try to do anything with these programmers, I get the following error:

Connecting to any snap
Traceback (most recent call last):
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/libs/pyedbglib/hidtransport/cyhidapi.py", line 4, in <module>
    import hid
ModuleNotFoundError: No module named 'hid'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/prog.py", line 266, in <module>
    main()
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/prog.py", line 121, in main
    return_code = pymcuprog_basic(args, fuses_dict)
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/prog.py", line 163, in pymcuprog_basic
    backend.connect_to_tool(toolconnection)
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/libs/pymcuprog/backend.py", line 150, in connect_to_tool
    self.transport = hid_transport()
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/libs/pyedbglib/hidtransport/hidtransportfactory.py", line 46, in hid_transport
    from .cyhidapi import CyHidApiTransport
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/libs/pyedbglib/hidtransport/cyhidapi.py", line 9, in <module>
    raise ImportError(MSG)
ImportError: This transport class requires cython and hidapi to be installed:
> pip install cython
> pip install hidapi

Do you know if there is possible (and how) to bundle the cython and hidapi packages with the Pymcuprog installation?

@MCUdude
Copy link
Owner

MCUdude commented May 23, 2021

I tried to install cython and hidapi manually, just to see if it would work or not. Got this error with the MPLAB SNAP:

ersion 1.1.0 - May 2021
Using serial port  at 115200 baud.
Target: atmega4809
Set fuses: ['0:0x00', '1:0x54', '2:0x01', '4:0x00', '5:0xC9', '6:0x06', '7:0x00', '8:0x00']
Action: write
File: /var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_1089/Blink.ino.hex
Connecting to any snap
Pinging device...
Ping response: 1E9651
Setting fuse 0x0=0x0
Writing literal values...
Verifying literal values...
Action took 0.02s
Setting fuse 0x1=0x54
Writing literal values...
Verifying literal values...
Action took 0.03s
Setting fuse 0x2=0x1
Writing literal values...
Verifying literal values...
Action took 0.02s
Setting fuse 0x4=0x0
Writing literal values...
Verifying literal values...
Action took 0.02s
Setting fuse 0x5=0xc9
Writing literal values...
Verifying literal values...
Action took 0.02s
Setting fuse 0x6=0x6
Writing literal values...
Verifying literal values...
Action took 0.02s
Setting fuse 0x7=0x0
Writing literal values...
Verifying literal values...
Action took 0.02s
Setting fuse 0x8=0x0
Writing literal values...
Verifying literal values...
Action took 0.02s
Finished writing fuses.
Chip/Bulk erase,
Memory type eeprom is conditionally erased (depending upon EESAVE fuse setting)
Memory type flash is always erased
Memory type internal_sram is always erased
Memory type lockbits is always erased
...
Erased.
Action took 0.01s
Writing from hex file...
Writing flash...
Traceback (most recent call last):
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/prog.py", line 266, in <module>
    main()
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/prog.py", line 121, in main
    return_code = pymcuprog_basic(args, fuses_dict)
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/prog.py", line 234, in pymcuprog_basic
    run_pymcu_action(pymcu._action_write, backend,
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/prog.py", line 131, in run_pymcu_action
    status = func(backend, *args, args_pymcu)
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/libs/pymcuprog/pymcuprog_main.py", line 341, in _action_write
    _write_memory_segments(backend, result, args.verify, blocksize=args.blocksize)
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/libs/pymcuprog/pymcuprog_main.py", line 392, in _write_memory_segments
    backend.write_memory(segment.data, memory_name, segment.offset, blocksize=blocksize)
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/libs/pymcuprog/backend.py", line 526, in write_memory
    self.programmer.write_memory(data=data, memory_name=memory_name, offset=offset_byte, blocksize=blocksize)
  File "/Users/hans/Documents/Arduino/hardware/MegaCoreX/megaavr/tools/libs/pymcuprog/programmer.py", line 190, in write_memory
    self.device_model.write(memory, offset, data, blocksize=blocksize)
An error occurred while uploading the sketch
TypeError: write() got an unexpected keyword argument 'blocksize'

@SpenceKonde
Copy link
Contributor

SpenceKonde commented May 23, 2021 via email

@SpenceKonde
Copy link
Contributor

SpenceKonde commented May 23, 2021 via email

@SpenceKonde
Copy link
Contributor

SpenceKonde commented May 24, 2021 via email

@MCUdude
Copy link
Owner

MCUdude commented May 24, 2021

Quentin said to open an issue in the repo once we make it public

Which repo? You mean the Pymcuprog repo here? https://github.com/microchip-pic-avr-tools/pymcuprog

Just for fun I also installed "the real" Pymcuprog from Pip, but I couldn't get it to do anything (burn fuses, write hex). It seems like it has different flags than your prog.py script has, and it's difficult to figure out how to really use Pymcuprog since there is no user manual like Avrdude has.

@SpenceKonde
Copy link
Contributor

No the repo that is currrently a private repo under his control that we will announce when it is made public

@MCUdude
Copy link
Owner

MCUdude commented May 24, 2021

No the repo that is currently a private repo under his control that we will announce when it is made public

So what is the difference between his repo and Pymcuprog/Pyupdi? And what is it that his program can do that Pymcuprog/Pyupdi can't?

@SpenceKonde
Copy link
Contributor

he wrote the wrapper that lets you pass all the information that you need to in one command from platform.txt, and I aggressively optimized for performance over a serial port to make it upload fast rather than mindnumblingly slowly

@MCUdude
Copy link
Owner

MCUdude commented Dec 6, 2021

It looks like Avrdude is getting pyupdi/SerialUPDI style programming!

A bunch of patches and bug fixes has been applied to Avrdude recently, and SerialUPDI is being worked on. Screw pymcuprog, I'm waiting for the Avrdude implementation!

https://savannah.nongnu.org/bugs/?61624

@SpenceKonde
Copy link
Contributor

SpenceKonde commented Dec 6, 2021 via email

@SpenceKonde
Copy link
Contributor

And to expand on that point - in my view, the possibly the best thing about SerialUPDI was that it didn't involve avrdude. I wanted to get the Microchip USB programming tools moved over to it, and am planning to look for python replacements for stk500/arduino protocols so we could have them give people sensible messages instead of displaying values foir oparameters with no basis in reality, and telling people who softbrick their chip by setting it to use a non-present clock source that -f might fix it... That's a 5 minute fix. Nobody has done it in over a decade I could do it - but I don;'t have the build environments needed to compile it for all 6-7 platforms that it would need to be compiled for.... There is a huge barrier to entry with patching or modifying something like that, because ti do anything with it, you need to make a shitload of versions of it. I don't know how to crosscompile for windows, much less darwin/mac. but a fixed version doesn;t mean shit if people can't use it.

Avrdude suffers from one of the worst cases of kitchensinkism I have seen, Every dumbass programming method ever combined into one giant, poorly organized mess.

If I had more time to work on this, I would strip out every trace of avrdude from my cores. It is an abomination.

@MCUdude
Copy link
Owner

MCUdude commented Dec 6, 2021

I wanted to get the Microchip USB programming tools moved over to it, and am planning to look for python replacements for stk500/arduino protocols so we could have them give people sensible messages instead of displaying values foir oparameters with no basis in reality, and telling people who softbrick their chip by setting it to use a non-present clock source that -f might fix it... That's a 5 minute fix. Nobody has done it in over a decade I could do it

Really, is these error messages the reason why you want to ditch Avrdude? So submit an issue then! There are developers working on it right now, use your opportunity!

Avrdude suffers from one of the worst cases of kitchensinkism I have seen, Every dumbass programming method ever combined into one giant, poorly organized mess.

I have no idea what kitchensinkism means, but I don't really care what the source code looks like as long as I have a binary that works and is reliable. And I have yet to experience Avrdude as unreliable for the programmers I use with it.

@SpenceKonde
Copy link
Contributor

It means that they have thrown "everything but the kitchen sink" in, haphazardly and without a coherent plan, the documentation is terse at best, and comprehensive documentation (the source code, often the only documentation there is) is awful.
Despite it having such a proliferation of options, we still end up telling it that our bootloaders are an stk500 programmer (out of production for got only knows how long) so it sends back bogus information that would have made sense if it were an stk500 programmer.
And there's a barrier to entry for building and distributing it because you need to be able to generate binaries for multiple platforms - The arduino packages support 6 platforms. With python, you just distribute it, and there's a ready made package you can point to to get the python interpreter. With avrdude you need to set up a build environment that can cross-compile for 32-bit arm linux, 64-bit arm linux, 32-bit x86 linux, x64 linux, windows, and mac.... So even if you get through the impenetrable code, and make the changes you need to, that doesn't get you a binary to test with (I imagine it's fairly easy to build on x64 linux, but I run windows, and every time I've been involved in something beingbuilt for windows it's been a mess). So there's a level of exclusivity around it that isn't an issue with with python tooling.

@SpenceKonde
Copy link
Contributor

SpenceKonde commented Dec 11, 2021

Well, because I must have been doing something wrong when I was trying to do it with references, and once I made it work with pointers, I didn't go backl to references and try to figure out why it wasn't working for me., and I just didn't think of testing them directly.

I think in the case of the TCB'sthe sort of trickery I use could reduce code size a tiny bit, but I'm not certain, and for the parts that care (which only have 2 TCBs at most), it won't save space.

But yeah, that alternative never crossed my mind. If that works and is the same or smaller compiled, than by all means!

If that works, then the best implementation I think would be this - no part-specific knowledge is needed whatsoever. All it needs to know is if AC0, AC1 and AC2 exist, and the only assumption it makes is that for ACn, n < 3 and there is an ACn-1 and so on.


gen::generator_t Event::gen_from_peripheral(AC_t& comp)
{
#if defined(AC0)
  #if defined(AC1) ||  defined(AC2)
    if (&comp == &AC0) 
  #endif
    return gen::ac0_out;
  else 
  #if defined(AC1)
    if (&comp == &AC1) 
  #endif
    return gen::ac1_out;
  else 
  #if defined(AC2)
    if(&comp == &AC2)
      return gen::ac2_out;
  #endif
  else 
#endif
    return (gen::generator_t) -1; //is there a better way to indicate something that will be rejected by anything that takes a generayor?
}

@m12lrpv
Copy link

m12lrpv commented Apr 15, 2022

I copied the pymcuprog implementation (pyupdi compatible) from megaTinyCore to try it out with MegaCoreX. It works great!
The only thing I had to tweak was the resistor value. For some reason, a 1k resistor was too high for an ATmega3208. A 470R did the trick

Is there any progress on this.

Given you have said that you were able to copy the implementation and it worked... How do the rest of us do the same.

I'm trying to program using your core and choosing the megaTinyCore SerialUPDI as the programmer and getting errors...

I'm presently updating arduino to the megaTinyCore recommended version and will try again but i'm asking now in case there's something arduino ide requires that i'm not aware of or alternatively if there's a manual way to do the programming.

@MCUdude
Copy link
Owner

MCUdude commented Apr 15, 2022

Avrdude 7.0 will soon be released and has native support for SerialUPDI, including the speed optimizations megaTinyCore and DxCore has. Avrdude 7.0 will be bundled with MegaCoreX as soon as it has been released.

https://github.com/avrdudes/avrdude

@m12lrpv
Copy link

m12lrpv commented Apr 15, 2022

Thanks. But I got it working. To anyone else... Copy the 2 tools folders from megaTinyCore to MegaCoreX

Arduino 1.8.13
megaTinyCore 2.5.11
MegaCoreX 1.0.10

Add these to your boards.txt for any chips you want to program. In my case it was the 4809

# SerialUPDI hack
4809.upload.workaround=
4809.upload.prog_interlock=

Add this to MegaCoreX programmers.txt

serialupdi57k.name=SerialUPDI - SLOW: 57600 baud, any platform, any voltage, any adapter.
serialupdi57k.protocol=uart
serialupdi57k.program.extra_params=-u {serial.port} -b 57600
serialupdi57k.program.protocol=uart
serialupdi57k.program.tool=serialupdi
serialupdi57k.bootloader.tool=serialupdi

Add this to the MegaCoreX platform.txt

##############################################################
# Serial UPDI - UPDI uploads using a serial adapter directly #
##############################################################
# Board manager installations have the python executable in  #
# different location than a manual installation. The package #
# build script deletes the line starting with                #
# tools.serialupdi.cmd                                       #
# and the #REMOVE#, leaving the correct path.                #
##############################################################

#tools.serialupdi.cmd={runtime.platform.path}/tools/python3/python3
tools.serialupdi.cmd={runtime.tools.python3.path}/python3

## Unused Parameters.
# SerialUPDI has only one level of verbosity.
# There's an *actual* internal verbose mode, but it is WAY too verbose and results >500kb log files which are mostly useless.
# Verification is not optional as there are no guardrails against unsuccessful uploads other than protocol failures
# Upload is only for uploading through a bootloader, and erase is not used anywhere.
tools.serialupdi.bootloader.params.noverify=
tools.serialupdi.bootloader.params.quiet=
tools.serialupdi.bootloader.params.verbose= -v
tools.serialupdi.bootloader.verify=
tools.serialupdi.erase.params.quiet=
tools.serialupdi.erase.params.verbose= -v
tools.serialupdi.erase.pattern=
tools.serialupdi.program.params.noverify=
tools.serialupdi.program.params.quiet=
tools.serialupdi.program.params.verbose= -v
tools.serialupdi.program.verify=
tools.serialupdi.upload.params.noverify=
tools.serialupdi.upload.params.quiet=
tools.serialupdi.upload.params.verbose= -v
tools.serialupdi.upload.verify=
tools.serialupdi.upload.pattern=echo "This can't happen, but has to be here or automated tests fail"

## Tools -> Burn Bootloader pattern
# write fuses 0, 1, 2, 4 (1-series only), 5, 6, 7, 8.
# If fuse 4 (TCD0CFG) is written, it is always written to 0

tools.serialupdi.bootloader.pattern="{cmd}" -u "{runtime.platform.path}/tools/prog.py"  -t {protocol} {program.extra_params} -d {build.mcu}{upload.workaround} --fuses 0:{bootloader.WDTCFG} 1:{bootloader.BODCFG} 2:{bootloader.OSCCFG} {bootloader.TCD0CFG_serialupdi} 5:{bootloader.SYSCFG0} 6:{bootloader.SYSCFG1} 7:{bootloader.APPEND} 8:{bootloader.BOOTEND} {bootloader.serialupdistring} {bootloader.verbose}

## Program pattern (all uploads through SerialUPDI)
# Program will set fuses 2, 6 and 8 only. Fuses 0 and 4 are not written because the core never configures that.
# If a user went and set that themselvesm we shouldn't undo it.
# Fuse 1 is the BOD configuration, which could "brick" the chip if set for a higher voltage than the power rail.
# Fuse 5 is SYSCFG0 which could disable UPDI and leave the board programmable without HV programming.
# That leaves OSCCFG to choose 16 vs 20 MHz clock, and SYSCFG1 (for startup time and stuff) and BOOTEND,
# ensuring that a part previously set to use a bootloader will be unbootloaded cleanly, instead of the
# bootloader being erased but no sketches working)

tools.serialupdi.program.pattern={upload.prog_interlock}"{cmd}" -u "{runtime.platform.path}/tools/prog.py"  -t {protocol} {program.extra_params} -d {build.mcu}{upload.workaround} --fuses 2:{bootloader.OSCCFG} 6:{bootloader.SYSCFG1} 8:{bootloader.BOOTEND} "-f{build.path}/{build.project_name}.hex" -a write {program.verbose}


##############################################################
# Serial UPDI - UPDI uploads using a serial adapter directly #
##############################################################
# Board manager installations have the python executable in  #
# different location than a manual installation. The package #
# build script deletes the line starting with                #
# tools.serialupdi.cmd                                       #
# and the #REMOVE#, leaving the correct path.                #
##############################################################

#tools.serialupdi.cmd={runtime.platform.path}/tools/python3/python3
tools.serialupdi.cmd={runtime.tools.python3.path}/python3

## Unused Parameters.
# SerialUPDI has only one level of verbosity.
# There's an *actual* internal verbose mode, but it is WAY too verbose and results >500kb log files which are mostly useless.
# Verification is not optional as there are no guardrails against unsuccessful uploads other than protocol failures
# Upload is only for uploading through a bootloader, and erase is not used anywhere.
tools.serialupdi.bootloader.params.noverify=
tools.serialupdi.bootloader.params.quiet=
tools.serialupdi.bootloader.params.verbose= -v
tools.serialupdi.bootloader.verify=
tools.serialupdi.erase.params.quiet=
tools.serialupdi.erase.params.verbose= -v
tools.serialupdi.erase.pattern=
tools.serialupdi.program.params.noverify=
tools.serialupdi.program.params.quiet=
tools.serialupdi.program.params.verbose= -v
tools.serialupdi.program.verify=
tools.serialupdi.upload.params.noverify=
tools.serialupdi.upload.params.quiet=
tools.serialupdi.upload.params.verbose= -v
tools.serialupdi.upload.verify=
tools.serialupdi.upload.pattern=echo "This can't happen, but has to be here or automated tests fail"

## Tools -> Burn Bootloader pattern
# write fuses 0, 1, 2, 4 (1-series only), 5, 6, 7, 8.
# If fuse 4 (TCD0CFG) is written, it is always written to 0

tools.serialupdi.bootloader.pattern="{cmd}" -u "{runtime.platform.path}/tools/prog.py"  -t {protocol} {program.extra_params} -d {build.mcu}{upload.workaround} --fuses 0:{bootloader.WDTCFG} 1:{bootloader.BODCFG} 2:{bootloader.OSCCFG} {bootloader.TCD0CFG_serialupdi} 5:{bootloader.SYSCFG0} 6:{bootloader.SYSCFG1} 7:{bootloader.APPEND} 8:{bootloader.BOOTEND} {bootloader.serialupdistring} {bootloader.verbose}

## Program pattern (all uploads through SerialUPDI)
# Program will set fuses 2, 6 and 8 only. Fuses 0 and 4 are not written because the core never configures that.
# If a user went and set that themselvesm we shouldn't undo it.
# Fuse 1 is the BOD configuration, which could "brick" the chip if set for a higher voltage than the power rail.
# Fuse 5 is SYSCFG0 which could disable UPDI and leave the board programmable without HV programming.
# That leaves OSCCFG to choose 16 vs 20 MHz clock, and SYSCFG1 (for startup time and stuff) and BOOTEND,
# ensuring that a part previously set to use a bootloader will be unbootloaded cleanly, instead of the
# bootloader being erased but no sketches working)

tools.serialupdi.program.pattern={upload.prog_interlock}"{cmd}" -u "{runtime.platform.path}/tools/prog.py"  -t {protocol} {program.extra_params} -d {build.mcu}{upload.workaround} --fuses 2:{bootloader.OSCCFG} 6:{bootloader.SYSCFG1} 8:{bootloader.BOOTEND} "-f{build.path}/{build.project_name}.hex" -a write {program.verbose}

Now commit them to your own repo so that when they get overwritten by an update you can diff them and restore the change.

Happy programming everyone.

@MCUdude
Copy link
Owner

MCUdude commented Jun 18, 2022

SerialUPDI is now supported in the latest boards manager release thanks to Avrdude 7.0!

@MCUdude MCUdude closed this as completed Jun 18, 2022
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

No branches or pull requests

4 participants