Setting fuses on UNO using manifest file

Greetings people.

I’m progamming an UNO R3 using a AVRISP mkII. The purpose of this exercise is I’m trying to learn about setting fuses for a barebones atmega328p.

I’m running PlatformIO, version 3.3.0 on a mac. platformio has been working wonderfully for quite a while with USB uploads to teensys and unos.

So the approach is create a directory called “boards” in the root directory of my project. Put in a manifest file, change the fuses, upload with the AVRISP. Here we go.

Make a boards directory, put a file in there called boards_test.json with the following:

{
  "build": {
    "core": "arduino",
    "extra_flags": "-DARDUINO_ARCH_AVR -DARDUINO_AVR_UNO",
    "f_cpu": "16000000L",
    "hwids": [
      [
        "0x2341",
        "0x0043"
      ],
      [
        "0x2341",
        "0x0001"
      ],
      [
        "0x2341",
        "0x0243"
      ],
      [
        "0x2A03",
        "0x0043"
      ]
    ],
    "mcu": "atmega328p",
    "variant": "standard"
  },
  "frameworks": [
    "arduino",
    "simba"
  ],
  "fuses": {
    "efuse": "0x05",
    "hfuse": "0xDE",
    "lfuse": "0xFF",
    "lock": "0x3F"
  },
  "name": "board_test",
  "upload": {
    "maximum_ram_size": 2048,
    "maximum_size": 32256,
    "protocol": "arduino",
    "require_upload_port": true,
    "speed": 115200
  },
  "url": "https://www.arduino.cc/en/Main/ArduinoBoardUno",
  "vendor": "Arduino"
}

Test if I can find it.

$ platformio boards | grep board_test
board_test            ATMEGA328P     16Mhz     31kB    2kB    board_test
board_test            ATMEGA328P     16Mhz     31kB    2kB    board_test
board_test            ATMEGA328P     16Mhz     31kB    2kB    board_test

no idea why I get three hits but there we go.

also in the root directory I have the following platformio.ino file:

# fuse testing 
[env:board_test]
platform = atmelavr
framework = arduino
board = board_test
upload_protocol = stk500v2
upload_flags = -Pusb

So.

when I run: $ pio run --target program -v I get it to load. But changing the fuses in the manifest file does nothing. I figure, that’s because fuses has to be a target. So

$ pio run --target fuses -v 
[Sun Sep 24 09:39:42 2017] Processing board_test (upload_protocol: stk500v2, platform: atmelavr, upload_flags: -Pusb, board: board_test, framework: arduino)
-----------------------------------------------------------------------------------------------------------------------
avr-g++ -o "/Users/owhite/uno/board_test/src/blink.ino.cpp" -x c++ -fpreprocessed -dD -E "/var/folders/p8/m441knk55_94tz2zwckt5mqr0000gp/T/tmpuSSXZi"
Collected 31 compatible libraries
Looking for dependencies...
Project does not have dependencies
BeforeUpload(["fuses"], [])
Auto-detected: /dev/cu.usbmodem1421
avrdude -v -p atmega328p -C /Users/owhite/.platformio/packages/tool-avrdude/avrdude.conf -c stk500v2 -Pusb -b 115200 -P "/dev/cu.usbmodem1421" -e -Ulock:w:0x3F:m -Uhfuse:w:0xDE:m -Uefuse:w:0x05:m -Ulfuse:w:0xFF:m

avrdude: Version 6.3, compiled on Jan 17 2017 at 12:01:35
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch

System wide configuration file is "/Users/owhite/.platformio/packages/tool-avrdude/avrdude.conf"
User configuration file is "/Users/owhite/.avrduderc"
User configuration file does not exist or is not a regular file, skipping

Using Port                    : /dev/cu.usbmodem1421
Using Programmer              : stk500v2
Overriding Baud Rate          : 115200

and it hangs. I’m looking for suggestions of what to try next. And, wouldnt I want to be able to program and -then- set the fuses? Or should I just set the fuses and program?

On that topic, I tried having more than one target by using the .ini file. As in:

targets = program, fuses

or even

targets = program, clean

and it only handles the second target, it does not do both.

I have also tried the extra_script method as described here link

in that case the UNO had a bootloader, target = upload, but it did not change the fuses.

avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: safemode: Fuses OK (E:00, H:00, L:00)

Well okay, not a lot of support on this forum I take it. So after a bunch of research what I know so far is despite documentation that I’ve seen it does not appear to be possible to get platformio to use a different manifest. This -might- be only true when targets = program.

So skip messing with manifests in the boards directory and just use the .ini file below.

Here’s what it’s doing. One issue is you need to pass avrdude a -u directive so it doesn’t use safe mode. In addition to that you’ll want to pass it the fuse settings shown below. Be advised this is what I used for an external crystal at 8mHz.

#
# program a barebones atmega328p, fuse settings for external crystal
#   using an AVRISP mkII

[env:autogen_uno]
platform = atmelavr
framework = arduino
board = uno
upload_protocol = stk500v2
upload_flags = -Pusb -u -Ulock:w:0xCF:m -Uhfuse:w:0xDA:m -Uefuse:w:0xFD:m -Ulfuse:w:0xFF:m
board_f_cpu = 8000000L
targets = program

hope this helps someone.

3 Likes

Thanks for coming back to share.

I appreciate your description and not simply saying do this.

Regards,
John

Thank you very much, this was really helpful!